Legal Information

DirectX Driver Development Kit

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document, including URL and other Internet Web site references, is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. Unless otherwise noted, the example companies, organizations, products, people and events depicted herein are fictitious and no association with any real company, organization, product, person or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Unpublished work © 1995 – 2000 Microsoft Corporation. All rights reserved.

ActiveX, BackOffice, Direct3D, DirectDraw, DirectInput, DirectMusic, DirectPlay, DirectShow, DirectSound, DirectX, JScript, Microsoft, Microsoft Press, MS-DOS, MSN, Natural, NetShow, Visual Basic, Visual C++, WebTV, Win32, Win32s, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

Macintosh and TrueType are registered trademarks of Apple Computer, Inc.

Kodak is a registered trademark of Eastman Kodak Company.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

Built on Sunday, March 11, 2001


DirectDraw DDI

[This is preliminary documentation and subject to change.]

The Microsoft® DirectDraw® DDI is a graphics interface that allows vendors to provide hardware acceleration for DirectDraw. It can be an integral part of the display driver or a separate dynamic-link library (DLL) that communicates with the display driver through a private interface defined by the driver’s creator. On Microsoft® Windows® 2000 and later, a DirectDraw driver must be a 32-bit implementation.

This section describes the DirectDraw architecture and interface, and provides implementation guidelines for DirectDraw driver writers. The guidelines are specifically written for Windows 2000 and later. However, where possible, the differences for Windows 98/Me implementations have been pointed out. The reader should be familiar with the DirectDraw APIs, and have a firm grasp of the Windows 2000 display driver model. For more information about DirectDraw, see the Platform SDK.


DirectDraw Driver Header Files, Sample Code, and References

Microsoft® Windows® 2000 and later DirectDraw® driver writers use the following header files:

  • ddrawint.h contains the basic types, constants, and structures for DirectDraw drivers.
  • ddraw.h contains the basic types, constants, and structures used by both applications and drivers.
  • dvp.h is used when the driver supports the DirectDraw video port extensions (VPE).
  • dxmini.h is used when the driver includes miniport support for kernel-mode video transport.
  • ddkmapi.h is used when the driver wants to access the kernel-mode DirectDraw support for the DxApi function.
  • dmemmgr.h is used when the driver wants to perform its own memory management instead of relying on the DirectDraw run-time.
  • ddkernel.h is used when the driver includes kernel-mode support.
  • dx95type.h allows driver writers to easily port existing Windows 98/Me drivers to Windows 2000 and later. This header file maps names that are different on the two platforms.

With the exception of ddraw.h, all other header files are shipped with the Windows DDK. The ddraw.h header file is shipped with the Platform SDK.

The Windows DDK also provides sample code for a DirectDraw driver in the p3samp video display directory.

Reference pages for DirectDraw driver functions, callbacks, and structures can be found in DirectDraw Driver Functions and DirectDraw Driver Structures.

SDK-related aspects of the DirectDraw interface are covered in the Platform SDK.

DirectDraw driver writers can send questions and comments by e-mail to directx@microsoft.com.


DirectDraw Architectural Overview

Microsoft® DirectDraw® includes the following components:

  • User-mode DirectDraw (ddraw.dll) is a system-supplied dynamic-link library (DLL) that is loaded and called by DirectDraw applications. This component provides hardware emulation, manages the various DirectDraw objects, and provides display memory and display hardware management services.
  • Kernel-mode DirectDraw is an integral part of win32k.sys, which is the system-supplied graphics engine that is loaded by a kernel-mode display driver. This portion of DirectDraw performs parameter validation for the driver, making it easier to implement more robust drivers. This is a critical design goal since display drivers are trusted components of the Windows® 2000 and later operating systems. Kernel-mode DirectDraw also handles synchronization with GDI and all cross-process state.
  • The DirectDraw portion of the display driver, along with the rest of the display driver, is implemented by graphics hardware vendors. This component is referred to as the DirectDraw driver in this document. Other portions of the display driver handle GDI and other non-DirectDraw related calls.

This document generically refers to both of the system-supplied components as DirectDraw.

The following figure shows a block diagram of the DirectDraw driver architecture.

DirectDraw Driver Architecture

As shown in the preceding figure, an application accesses the display card through GDI (user and kernel-mode portions) and the display driver. The display driver will always support GDI calls and usually DirectDraw and Direct3D calls. The device independent bitmap (DIB) engine portion of GDI emulates functionality when it is not supported by the display driver.

When DirectDraw is invoked, it accesses the graphics card directly through the DirectDraw driver. Unlike GDI, DirectDraw is informed of the capabilities of a DirectDraw enabled driver. DirectDraw calls the DirectDraw driver for supported hardware functions, or the hardware emulation layer (HEL) for functions that must be emulated in software. Rather than calling the driver for requests it can't support, as GDI does, DirectDraw calls the driver for hardware supported requests and the DirectDraw HEL for requests that are not hardware supported. GDI calls, on the other hand, are sent to the driver, which must then call back into the DIB engine if the call is unsupported.

Note If the DirectDraw driver fails an operation, DirectDraw does not pass the operation to the DirectDraw HEL, but instead passes the DirectDraw driver's error code back to the application.

At initialization time and during mode changes, the display driver returns capability (caps) bits to DirectDraw. This enables DirectDraw to access information about the available driver functions, their addresses, and the capabilities of the display card and driver (such as stretching, transparent blits, display pitch, and other advanced characteristics). Once DirectDraw has this information, it can use the DirectDraw driver to access the display card directly, without making GDI calls or using the GDI specific portions of the display driver.


About DirectDraw

Microsoft DirectDraw is the display component of DirectX® that allows software designers to directly manipulate display memory, hardware blitters, hardware overlays, and flipping surfaces. DirectDraw provides a device-independent way for games and Windows subsystem software, such as 3D graphics packages and digital video codecs, to gain access to the features of specific display devices.

DirectDraw provides device-independent access to the device-specific display functionality in a direct 32-bit path. It accesses important functions in a driver that accesses the card directly, without the intervention of the Windows graphics device interface (GDI) or the device-independent bitmap (DIB) engine.

By taking advantage of this direct path, games and other display-intensive applications run faster and avoid tearing. A tear is a screen flicker caused by an image displayed and written to at the same time. Direct access often allows game performance to be limited solely by display card performance. DirectDraw also uses page flipping to provide smooth animation.

The rapid motion and ever-changing screens of many games and multimedia applications put a heavy burden on the display process and tend to exacerbate tearing. Although GDI is very fast at drawing spreadsheets, graphs, TrueType font rendering, and so on, it is not meant to be a real-time graphics API. DirectDraw augments GDI by handling the device-dependent hardware accelerator functions in a 32-bit driver.


DirectDraw Drivers

DirectDraw provides device independence through the DirectDraw driver. The DirectDraw driver is a device-specific interface usually provided by the display hardware manufacturer. DirectDraw exposes methods to the application and uses the DirectDraw portion of the display driver to work directly with the hardware. Applications never call the display driver directly.

Under Windows 2000 and later, the DirectDraw driver is always implemented as 32-bit code. The DirectDraw driver can be part of the display driver or a separate DLL that communicates with the display driver through a private interface defined by the driver writer. On Windows 2000 and later, the DirectDraw driver is assumed to be part of the display driver.

Note for Windows 98/Me: When the DirectDraw driver is a separate DLL, it is loaded by ddhelp.exe. This occurs when DirectDraw is invoked.

DirectDraw still uses the non-DirectDraw specific portions of the Windows 98/Me display driver for BIOS calls (which must be 16-bit) and mode changes (which are not time-critical). DirectDraw hooks into the mode-changing process to update itself and to provide support for modes that GDI cannot support. For example, GDI does not operate well in modes below 640 X 480.

The DirectDraw driver contains only device-dependent code and performs no emulation. If a function is not performed by the hardware, the DirectDraw driver does not report it as a hardware capability. Additionally, the DirectDraw driver does not validate parameters because the DirectDraw run-time does this before the driver is invoked.


First Steps For DirectDraw Drivers

A good way to begin implementing DirectDraw functionality is to modify an existing driver. If no driver is available, start with the sample code in the DirectDraw portion of the DDK and get driver initialization, lock, and flip working. This will get a driver up and running as quickly as possible. From that base functionality, more powerful functionality can be added that will continue to improve display performance.

The DirectX Software Development Kit (SDK), which can be found in the Platform SDK, includes useful help and readme files, sample code, and tools such as DirectDraw Test that allows monitoring and testing of driver capabilities during the development process. A remote terminal in conjunction with the kernel debugger and debug printf statements are indispensable tools for verifying each action the driver takes.

Microsoft has tried to make developing a DirectDraw-enabled driver as easy as possible. However, as in all things made simple for the end user, the complexity is hidden under the hood. Because it is impossible to anticipate all the myriad hardware innovations and competing standards that will continue to emerge, a degree of complexity must be left to driver writers, who must adapt the technology to their unique hardware.

The minimum driver functionality DirectDraw requires is the ability to lock, unlock, and flip a surface. Assuming the hardware supports the related operations, driver support should also be added for blts (including transparent blts, which are important for speed in games), stretching, and overlays (critical for video playback).


Creating Device Drivers for Windows 98/Me that Work with DirectX

Microsoft® DirectX® is the high-performance game and multimedia API. The DirectX subsystem includes a new set of audio and display drivers that have been extended to support DirectX.

This topic contains important instructions on how OEMs and IHVs can install newer versions of these drivers and ensure a correct version number for the drivers. For the most up-to-date information, please see http://microsoft.com/hwdev/devdes/dll_dx5.htm.

Important The new release of DirectX 6.0 is the only vehicle that should be used by hardware vendors who ship DirectX components to their customers. The methods summarized in this article for ensuring correct version numbers and installing drivers must be followed to ensure a good experience for end users.


Overview

This topic applies only to Windows 98/Me.

The following summarizes what the vendor must do to ensure that a DirectX driver is registered and will work correctly with DirectX DLLs:

  1. Ensure that all file names provided with the device driver are unique to the vendor, as described in Naming Windows 98/Me Device Drivers.
  2. Ensure that the device driver version number is correct for the Microsoft Windows® version and DirectX version, as described in the section Ensuring Correct Version Numbers for Windows 98/Me Drivers.
  3. Ensure that your DirectX driver is registered by completing Windows Hardware Quality Labs (WHQL) testing and acceptance, as described in Testing DirectX Device Drivers.

DirectX Setup will not recognize an installed driver as newer unless it is registered and versioned as a DirectX driver.

Note A "registered" driver is one for which the driver has been tested and accepted by WHQL with additional testing for DirectX compatibility. An "unregistered" driver is one that has not been tested and accepted by WHQL for DirectX compatibility. A registered DirectX driver is one that is provided by Microsoft or that has successfully passed WHQL testing, including validation that the driver correctly provides a version number as described in this topic.


Naming Windows 98/Me Device Drivers

This topic applies only to Windows 98/Me.

Microsoft has reserved certain file names for its default device driver suite. Device drivers from other vendors must not use these reserved file names. Vendors should use unique file names for all files that make up their driver, even if some of the components of the driver are identical to the components shipped by Microsoft.

Providing unique names for components ensures that end users can easily switch between device drivers from different manufacturers for a specific device. This ensures that no permanent loss of functionality occurs, regardless of version numbers, when a DirectX application installs its device drivers or when an upgrade of Windows is installed.

The current list of reserved driver filenames is available on the Microsoft Hardware Development web site at http://microsoft.com/hwdev.


Ensuring Correct Version Numbers for Windows 98/Me Drivers

This topic applies only to Windows 98/Me.

With DirectX, version numbers have become very important for Windows 98/Me device drivers. If a device driver is shipped with the wrong version number or a version number that uses the wrong format, the end user will encounter difficulties when any DirectX application is installed.

Note Setup for Windows 98/Me now supports the DriverVer directive in INF files. This directive provides a way to add version information for the driver package, including the driver file and the INF file itself, to the INF file. By using and updating the DriverVer directive, driver packages can be safely and definitively replaced by future versions of the same package. For more information on this directive, see http://microsoft.com/hwdev/wdm/DrvVer.htm.

The following table gives the range of version numbers appropriate for IHV- or OEM-supplied Windows 98/Me drivers for compatibility with various versions of DirectX.

Target System | Version Number From: | Version Number Up Through:
Windows 98-only drivers (DirectX5) | 4.05.00.0000 | 4.05.00.9999
DirectX 1.0-compatible drivers | 4.02.00.0095 | 4.03.00.1096
DirectX 2.0-compatible drivers | 4.03.00.1096 | 4.03.00.2030
DirectX 3.0-compatible drivers | 4.03.00.2030 | 4.04.00.0000
DirectX 5.0-compatible drivers | 4.10.01.0000 | 4.10.01.9999
DirectX 6.0-compatible drivers | 4.11.01.0000 | 4.11.01.9999
Windows 98/Me DirectX 7.0-compatible drivers | 4.12.01.0000 | 4.12.01.9999
Windows 2000 and later DirectX 7.0-compatible drivers | 5.12.01.0000 | 5.12.01.9999
Windows 98/Me DirectX 8.0-compatible drivers | 4.13.01.0000 | 4.13.01.9999
Windows 2000 and later DirectX 8.0-compatible drivers | 5.13.01.0000 | 5.13.01.9999

For device drivers that do not support DirectX, the version number must be greater than 4.00.00.0095 and less than 4.02.00.0095. For example, if a display device driver is a Windows 3.1 display driver or a Windows 95-only display driver, a version number of 4.01.00.0000 would be correct.

Conversely, a version number of 4.03.00.0000 for this driver would be incorrect. Device drivers that support DirectX on Windows 95 only should have a version number equal to or greater than 4.02.00.0095 and less than 4.04.00.0000.

Device drivers that support DirectX and are compatible with Windows 98/Me should have a version number equal to or greater than 4.10.01.0000 and less than 4.10.02.0000.

Using version numbers equal to or greater than 4.10.02.0000 will have unpredictable results on future versions of Windows and DirectX.

Storing Internal Version Numbers

In addition to the format that Microsoft requires for the version number, many vendors have expressed the desire to store an internal version number for product support and testing purposes. Every DirectX driver has one version number that is stored in duplicate: one binary version stored as two DWORDs, and one string version. The binary version cannot be modified.

The string version, however, can be appended in the following way:

  1. The vendor creates a version number, as described earlier in this article. This version number will be used "as is" in the binary version number.
  2. The vendor uses this version number as the basis for the string version number. If desired, a vendor-specific version string can be appended to the existing version number to form the complete string version number. The vendor-specific string and the version number will be separated by a "-" (hyphen character).

For example, if "4.03.00.2100" is the version number for a DirectX-compliant display driver, and the vendor uses the "xx.xx.xx" number format internally, then the combined string version number in the driver will be "4.03.00.2100-xx.xx.xx".

When the customer checks the version number of the driver (by selecting the file in Windows Explorer, choosing Properties, and then clicking the Version tab), Windows displays the string version. The vendor's product support should be able identify the vendor-specific portion of the version number if it exists and take appropriate action.


Installing DirectX Drivers

This topic applies only to Windows 98/Me.

Creating Installation Files for Driver-Only Installation

In this scenario, the hardware vendor will provide in the distribution package all the driver files that make up the device driver, including the device's INF file.

DirectX does not provide a method for hardware vendors to distribute the runtime. For information about IHV redistribution, please send e-mail to directx@microsoft.com.

Using DirectX Setup

During the end-user installation process, DirectX Setup is executed to install the DirectX subsystem. DirectX Setup installs the entire DirectX subsystem, consisting of Microsoft DirectDraw®, DirectSound®, DirectPlay®, Direct3D®, and DirectInput®; there is no option for partial installation. When redistributed by ISVs and on the web, DirectX Setup will also upgrade drivers if necessary. The IHV redistribution (available by sending e-mail to directx@microsoft.com) installs only the runtime components.

DirectX Setup for DirectX uses version numbering and detection of registered drivers to decide whether a driver will be updated. To determine a driver's version number, DirectX Setup examines the version numbers of all files composing the device driver and uses the highest as the version number for the entire driver.

In DirectX, the Setup application backs up any driver that is replaced during installation, and also installs dxsetup.exe as a part of the DirectX subsystem. In addition, the capability for uninstalling DirectX drivers is registered with Add/Remove Programs in Control Panel.


Testing DirectX Device Drivers

This topic applies only to Windows 98/Me.

Device drivers should be registered with Microsoft through testing and acceptance by WHQL, because by default DirectX Setup will replace registered drivers only with other registered drivers that have higher version numbers. Unregistered drivers can be replaced during application installation at the discretion of the end user or application. Note that if all of the rules in this article are followed, because none of the files will have been overwritten, the end user can easily switch back to previously used device drivers using Device Manager.

To become a registered DirectX driver, the device driver must first pass the standard WHQL tests for Windows 98/Me, and then pass an additional set of DirectX-specific tests. If the driver passes all of these tests, WHQL will link the code into the new device driver that allows DirectX to determine whether the driver is registered, and a registered version number is also assigned. The registered binary version of the driver is then returned to the vendor.


Troubleshooting with Dxsetup.exe

This topic applies only to Windows 98/Me.

Dxsetup.exe, which is installed in the \Program Files\DirectX\Setup directory by DirectX Setup, has these functions:

  • Dxsetup.exe can be used to determine the version of the DirectX components installed, including whether the device drivers support DirectX and whether they are registered.
  • Dxsetup.exe can restore previously installed drivers.

Caution When using dxsetup.exe for troubleshooting, always run the utility from the user's hard disk rather than from the DirectX distribution disk. Running dxsetup.exe from the DirectX distribution disk under or later 2000 will cause the system to stall.

When dxsetup.exe is run, it presents the current status of all of the DirectX components, including device drivers, plus three options: Quit, Restore Audio Drivers, and Restore Display Drivers. Unless the user selects Quit, dxsetup.exe forces a reboot after it has performed the requested function.


References

This topic applies only to Windows 98/Me.

  • To obtain a copy of the license agreement and DirectX binaries, please send e-mail to directx@microsoft.com with Request DirectX in the Subject line.
  • If you have questions about DirectX, please contact directx@microsoft.com.
  • For information about WHQL and testing, please go to http://microsoft.com/hwtest.
  • Microsoft DirectX DDK and SDK (next-generation cross-platform multimedia support for Windows 98/Me and Windows 2000 and later): http://msdn.microsoft.com/directx, the Microsoft DirectX Multimedia Expo.
  • For the most up-to-date information on creating Windows 98/Me device drivers that work with DirectX, see http://microsoft.com/hwdev/devdes/dll_dx5.htm.
  • The current list of reserved driver filenames is available on the Microsoft Hardware Development web site, at http://microsoft.com/hwdev.


Hardware Emulation Layer

The DirectDraw driver does not do emulation. Therefore, any DirectDraw functionality not handled by the driver is handled by the DirectDraw hardware emulation layer (HEL). The HEL (written by Microsoft as part of DirectDraw) emulates the driver in software and does whatever DirectDraw needs that is not handled by the DirectDraw driver. This emulation is done in user mode.

For instance, if the DirectDraw driver has capability (caps) bits set for blts but not for transparent blts, the DirectDraw driver is called for blts and the HEL for transparent blts. In the case of a transparent blt, the HEL is passed a display memory pointer and it compares each byte from a backing surface to the color key. If the byte does not match the color key, the HEL copies it to the destination surface using the CPU. Emulation also occurs for other unsupported operations or if the card is out of display memory.

It is important to note that DirectDraw does not pass failed DirectDraw driver operations to the HEL. Instead, it returns the DirectDraw driver's error code to the application. DirectDraw determines which component to call based on the capability bits. If either the HEL or the DirectDraw driver fails a particular operation, an error code is returned to the application.

Note for Windows 98/Me On a small number of low-end cards that don't have DirectDraw-capable drivers, DirectDraw can access the card using the generic frame buffer (Framebuf) display driver. This driver can only lock, unlock, and flip. If there is no DirectDraw driver, and Framebuf does not work on the card, DirectDraw uses the HEL for everything, which is still much faster than running all operations through the GDI and the DIB engine. The HEL can also use the display control interface (DCI) support in the driver to access the primary surface in the absence of DirectDraw support.


DirectDraw Driver Fundamentals

This section contains general information about the design of display drivers for DirectDraw. Information is organized in the following groups:

DirectDraw Surfaces

Display Memory

Memory Configuration Examples

Flipping

Blitting

Drivers That Assume State Information

Turning On a Display Card and Changing Modes on Windows 98/Me


DirectDraw Surfaces

The Microsoft® DirectDraw® Surface is the basic image unit in Microsoft DirectX® graphics. It is either a rectangular collection of pixels of a particular width, height, and pixel format; or a buffer containing commands or vertices for Microsoft Direct3D®. Surfaces have bits associated with them that denote their behavior and usage. These bits are called surface capability bits (or caps bits for short). Caps bits denote intended usages such as holding texels for rendering (the DDSCAPS_TEXTURE caps bit), being the target for 3D rendering (DDSCAPS_3DDEVICE), and many others. See the reference section under the DDSCAPS structure for more information on surface caps bits.

The primary surface is the surface that is currently being scanned out to the monitor by the display card. Much more will be said about the primary surface throughout this document.


Complex Surfaces and Attachments

Surfaces can also be complex, which means that they are part of a larger collection of associated surfaces. Examples of complex surfaces include the front buffer and associated back buffers, the various levels of a MIP map, and the various faces of a cube map.

The DirectDraw run-time uses a concept known as surface attachments to manage the linking of different simple surfaces into complex surfaces. Surfaces can be attached implicitly, as when the application makes one call to IDirectDraw7::CreateSurface to build a flipping chain (front buffer and back buffers with possible Z-buffer); or explicitly, as when the application associates a Z-buffer with a render target by calling IDirectDrawSurface7::AddAttachedSurface.


Creating and Destroying DirectDraw Surfaces

Direct Draw surfaces are created in a four-stage process. These stages are:

  1. DdCanCreateSurface. The run-time calls the driver’s DdCanCreateSurface to see if the driver will allow the creation of surface of this type, size, and format. The driver can return a failure code that will be propagated to the application.
  2. DdCreateSurface. The driver creates the surface in question, potentially allocating memory for the contents of the surface. Complex surfaces can be created all at once, with one call to DdCreateSurface. Thus the driver may be required to create many surfaces in one call.
  3. Memory Allocation. The DirectDraw run-time will allocate memory for any surface not allocated by the driver in response to the DdCreateSurface call. This process is covered in more detail in the following sections.
  4. D3dCreateSurfaceEx. This call is new for the DirectX 7.0 DDI. This function associates a handle with the surface in question for later use in the Direct3D D3dDrawPrimitives2 token stream. The driver also creates its own copy of the surface structure maintained by DirectDraw at this time. See the Direct3D DDK documentation for more information regarding D3dCreateSurfaceEx.

Surfaces are destroyed by a single call to the driver’s DdDestroySurface entry point.

Surfaces persist only as long as the mode in which they are created persists. Where there is a mode change, all the surfaces under the driver’s control are destroyed, as far as the driver is concerned. There are also other events that can cause all surfaces to be destroyed in this way. It is not necessary for the driver to determine the cause of a DdDestroySurface call.


Lost Surfaces and Atomic Restoration

Surface object lifetimes are longer for the run-time’s surface objects than they are for the driver’s surface objects. In a few situations, most notably mode changes, surfaces become lost. This means that the driver’s surface object is destroyed when DdDestroySurface is called, but the run-time’s surface object is merely placed into a suspended state, called “lost.” Later, the run-time object can be restored, which corresponds to a DdCreateSurface call at the driver level.

Normally, drivers do not have to be aware of this intermediate lost state. However, there are some cases where an understanding of this process will help the driver writer.

Before the release of the DirectX 7.0 DDI, surfaces were always restored one at a time, even if they were originally created in a group as part of a complex creation. As of the DirectX 7.0 DDI, driver writers can elect to handle complex surface restoration in one atomic call. At surface restoration time, the DirectDraw run-time examines the driver’s D3dCreateSurfaceEx entry point. If this entry point is defined, then the DirectDraw run-time will restore all complex surfaces in one call to DdCreateSurface. The driver will most likely not be able to differentiate between the original creation and the creation caused by restoring a surface.


Losing Driver-Managed Textures

Driver-managed surfaces also need the ability to be placed in a suspended state (lost), since they also consume video memory, which is a scarce resource. Since the driver controls the allocation of video memory for driver-managed surfaces, a method is required to notify the driver when such surfaces need to be lost. This notification has been added to the DirectX 7.0 DDI through an extension to the DdDestroySurface call.

When a driver-managed surface (marked with the DDSCAPS2_TEXTUREMANAGE flag) is lost, the driver will receive a special DdDestroySurface call with DDRAWISURF_INVALID specified in the dwFlags member of the surface structure. The driver should free video memory associated with the managed surface, but should not free any other private surface information including the backing surface copy. There will be no new DdCreateSurface call to restore the lost driver-managed surfaces since they are not really lost from the driver's point of view. For the most part, this special DdDestroySurface call is used specifically to inform the driver that it should evict its video memory copy.


Display Memory

Using a back buffer that can be flipped with a front buffer is the best way to take advantage of DirectDraw. Page flipping is essential for smooth, tear-free animation in games and video playback. In general, allocating as much display memory as possible to DirectDraw increases display performance and allows games and other DirectDraw applications to run faster, with a better quality visual image.

Note for Windows 98/Me When DirectDraw is initiated, the non-DirectDraw specific portion of the display driver must be informed which memory is being used by DirectDraw, so it can avoid writing to that memory while DirectDraw is in use. This is required for DirectDraw compatibility, and is done in the non-DirectDraw specific portion of the display driver.

When allocating memory for DirectDraw use, the virtual display driver (VDD) memory must be preserved to shell out to MS-DOS®. Caches for Windows pens, fonts, brushes, and so on can also be preserved. By going through the non-DirectDraw specific portions of the display driver code to see where VDD memory is allocated, you can determine what memory can be used. It is best to give Windows 98/Me a little extra memory, for example 32 KB, and make sure the memory is aligned on a four-byte boundary. That resulting address is used for the display pointer to the scratch area (the fpStart member of the VIDEOMEMORY structure in the sample code).

Usually, display cards will have the pitch set to the width of the display so that no memory is wasted to the right (conceptually) of the front buffer. This leaves one scratch area at the conceptual bottom that can be used for other surfaces. Memory access is very straightforward in this case because one pointer can reference the entire area of accessible display memory.

If the pitch is greater than the width of the primary surface, memory to the conceptual right of the front buffer is wasted. This has to be reclaimed as a separate rectangular heap, regardless of whether the memory on the card is linear or rectangular. (Even if the memory is linear, some display drivers fix the pitch to speed up the blitter. Rather than rewrite the driver, the memory can simply be reclaimed as a separate heap.)


Memory Heap Allocation

To allocate a surface, DirectDraw scans through the display memory heaps, in the order they were specified by the drivers. Heaps are specified in an array of VIDEOMEMORY structures. DirectDraw visits the heaps in the order of the VIDEOMEMORY structures in the array. The VIDEOMEMORY structure sets up certain metrics of the heap, such as: the starting and ending memory addresses, flags describing the heap access and what types of usage are restricted for the surface placed in this heap. DirectDraw manages the heap by suballocating and deallocating memory, that is, by creating and destroying surfaces under each heap's jurisdiction. Physical limits determine how to set up these attributes.

DirectDraw's heap manager makes two passes through the VIDEOMEMORY structures when attempting to allocate memory in response to a surface creation or restoration. The ddsCaps member of the VIDEOMEMORY structure informs DirectDraw what the memory in the heap cannot be used for on the first pass. For example, if the heap is just big enough for a back buffer, sprites can be excluded from being allocated on the first pass by setting the DDSCAPS_OFFSCREENPLAIN flag. That way, other heaps fill up with off-screen plain surfaces, while preserving the back buffer for page flipping.

The ddsCapsAlt member of the VIDEOMEMORY structure can be set to allow sprites on the second pass. That way, the heap in question can allow sprites, but only if the sprite could not be created in any other heap. Do not specify the DDSCAPS_OFFSCREENPLAIN flag in ddsCapsAlt. This allows heaps to be used preferentially for their highest and best use, without ruling out alternative uses.

Display memory heaps can be either linear or rectangular, depending on the blitter or the needs of an existing display driver. The dwFlags member of the VIDEOMEMORY structure are used to specify the memory allocation type. Linear heaps describe regions of memory where the pitch of each surface can be different. Rectangular heaps describe regions of memory where the pitch of each surface is fixed. These heaps can be mixed and matched within the same display card, if necessary (see Memory Configuration Examples for more information).

Pixel depth varies depending on the display mode. Pitch (sometimes known as stride or offset) is the number of bytes added to get from one column of display memory to the same column on the row below it (as shown as shown in the following figure). With 8-bit pixels there is one byte per pixel across the entire horizontal length of memory.

Pitch

As shown in the preceding figure, pitch is the entire horizontal stretch of display memory in bytes. In linear memory it is the same as the width of the front buffer, modulo word alignment restrictions. In rectangular memory, it is the width of the front buffer, plus whatever memory is left over to the conceptual right of the front buffer. In either case, pitch is the number of bytes added to the beginning address of one scan line to reach the beginning address of the next scan line below it.


Memory Configuration Examples

The following sections contain three different types of memory configurations: linear, rectangular, and mixed display memory allocation. Each example includes sample code that can be modified to fit the physical characteristics of the card, and can be added to the HAL to allocate display memory heaps.


Linear Memory Allocation

Display memory is considered linear whenever the pitch can be changed to match the surface width, modulo word alignment restrictions (as shown in the following figure). For example, if the blitter can only hit 8-byte strides, and a 31-pixel sprite is used, each line of display needs to be adjusted by one to align the next line on an 8-byte boundary.

Word alignment restrictions can apply to any of the three types of memory configuration. Linear memory is generally used more efficiently by the application than rectangular memory because the rows are stored sequentially. Any location can be accessed easily by moving forward or backward along this linear range.

The pitch is determined by the pixel depth and surface width, modulo word alignment restrictions. If the display is 640 8-bit pixels across, then the pitch is 640. If the pixels are 16-bit and there is a 640 X 480 screen, then the pitch is 1280. Likewise 640 wide, 32-bit pixel screens have a pitch of 2560 in linear display memory.

Linear Memory Heap Allocation

The preceding figure shows an example of a linear memory heap allocation with one primary surface and one scratch area. The pointer to the start of the primary surface is fpPrimary, a member of the VIDEOMEMORYINFO structure. The size of the primary surface and the various Windows caches are added to this to give a pointer to the beginning of the scratch area, indicated by the fpStart member of the VIDEOMEMORY structure. The end point, indicated by the fpEnd member of the VIDEOMEMORY structure, is calculated by adding the size of the remaining memory minus one.

The VIDEOMEMORY structure holds the information that manages the display memory heap(s). This sample has only one element in the array of VIDEOMEMORY structures because there is only one heap. VIDMEM_ISLINEAR is a flag in the dwFlags member of the VIDEOMEMORY structure, that denotes this as linear memory.

The following pseudo code shows how a VIDEOMEMORY structure is set up for linear memory:

/*
 * video memory pool usage
 */
static VIDEOMEMORY vidMem [] = {
    { VIDMEM_ISLINEAR, 0x00000000, 0x00000000,
           { 0 }, { 0 } },
};/*

The following pseudo code shows how linear memory heaps are set up:

/*
 * video memory pool information
 */

/* Calculate the number of video memory heaps */
    ddHALInfo.vmiData.dwNumHeaps = sizeof ( vidMem ) / sizeof ( vidMem [ 0 ] );

/* set up the pointer to the first available video memory after the primary surface */
    ddHALInfo.vmiData.pvmList     = vidMem;

/*
 * remainder of screen memory
 */

    VideoHeapBase = ddHALInfo.vmiData.fpPrimary + dwPrimarySurfaceSize + dwCacheSize;
    VideoHeapEnd = VideoHeapBase + dwDDOffScreenSize - 1;

    vidMem[ 0 ].fpStart = VideoHeapBase;
    vidMem[ 0 ].fpEnd = VideoHeapEnd;

The beginning of the first available scratch area is calculated by adding the beginning of the GDI primary surface to the size of the primary surface and the size of the Windows brush, pen, and VDD caches. The result is used to set the starting point in the first element of the VIDEOMEMORY structure to the beginning of the scratch area.

The end of the scratch area is found by adding the beginning of the scratch area to the size of the scratch area and subtracting one to make it inclusive. The result is used to set the end point of the first (and, in this case, only) element of the VIDEOMEMORY structure to the end of the scratch area. If there is more than one heap, the end point is set to the end of this heap and the next heap starts where this one leaves off.


Rectangular Memory Allocation

Display memory is considered rectangular whenever the pitch is fixed to a particular size for all the surfaces within a given heap.

With rectangular display memory, the layout is two-dimensional, with a finite width and height. This width is not always the same as the width of the screen. Because display memory must account for different display resolutions and design considerations, the actual horizontal width might span a much larger region than what is currently displayed on the monitor.

For example, even though a screen might be displaying 640 pixels across, if the rectangular display memory is 1280 bytes across, the pitch is 1280 (not 640). The pitch across a 1280-pixel horizontal stretch of memory with 16-bit pixels is 2560 (remember, the pitch is based on the number of bytes to add to get from the beginning of one scan line to the next). The pitch for 32-bit pixels is quadruple what it is for 8-bit pixels, so if the display is 1280 32-bit pixels across, the pitch is 5120.

The main problem with rectangular memory is that it rarely mimics the size of the auxiliary data that an application wants to store in it. Therefore, it may waste display memory and should be avoided wherever possible. DirectDraw allows this space to be accessed on a first-come, first-served basis. The use of these regions is sometimes limited by their awkward shape and size. Left over areas of rectangular memory are often only useful as space in which to store small sprites.

A rectangular heap can be as large as a contiguous region of available memory, but it can't be L-shaped since its size is measured in X by Y coordinates. If the rectangular heap is not tall enough and wide enough to hold a primary surface, then it cannot be a back buffer. If the pitch of the primary surface is not equal to the display width of the primary surface, a rectangular block of memory to the conceptual right of the display is left over (Heap 1 in the following figure). This block is as wide as the pitch minus the width of the display. Leftover memory to the right can also happen in linear cards if the existing display driver assumes a fixed pitch. Rectangular or linear memory may also be left over below the primary surface (but not in this example).

Rectangular Memory Allocation

In the preceding figure, the starting point (indicated by the fpStart member of the VIDEOMEMORY structure) of the rectangular heap is calculated by adding the width of the primary surface to the starting address of the primary surface. The width and height are also calculated to give the dimensions of the rectangular heap. A heap could also be created below the Windows caches, if memory is leftover there.

The following pseudo code shows how a VIDEOMEMORY structure is set up for rectangular memory:

/*
 * video memory pool usage
 */
static VIDEOMEMORY vidMem [] = {
    { VIDMEM_ISRECTANGULAR, 0x00000000, 0x00000000,
           { 0 }, { 0 } },
};

The only difference between the code for rectangular memory and its linear counterpart is the VIDMEM_ISRECTANGULAR flag, which indicates that this is rectangular memory

The following pseudo code shows how rectangular memory heaps are set up:

/*
 * video memory pool information
 */

/* set up the pointer to the first available video memory after the primary surface */
    ddHALInfo.vmiData.pvmList      = vidMem;

/* this is set to zero because there may only be one heap depending on the pitch
    ddHALInfo.vmiData.dwNumHeaps      = 0;

/*
 *  Compute the Pitch here ...
 */

    vidMem[0].fpStart  = ddHALInfo.vmiData.fpPrimary + dwPrimarySurfaceWidth;
    vidMem[0].dwWidth  = dwPitch - dwPrimarySurfaceWidth;
    vidMem[0].dwHeight = dwPrimarySurfaceHeight;
    vidMem[0].ddsCaps.dwCaps = 0;      // surface has no use restrictions

The memory heap starting point is set to the starting address of the primary surface plus the width of the primary surface. The width is determined by the pitch minus the width of the primary surface. The height is set to the height of the primary surface. The surface capabilities are set to zero to indicate that there are no imposed surface use restrictions (therefore, the surface can be used for sprites or any other type of surface).


Mixed Memory Allocation

Linear and rectangular memory heaps can be mixed and matched in any fashion, provided the hardware allows it. For instance, if a front buffer has a fixed pitch, the DirectDraw-capable driver can allocate a rectangular heap to the right of it. As shown in the following figure, if memory is also left over below the primary surface, this area can be made into a linear heap that can be used for a back buffer (that is, if it is large enough).

Mixed Memory Allocation

The preceding figure shows a linear piece of memory below the primary surface (Heap 1) and a rectangular piece of memory that is reclaimed by DirectDraw to the right of the primary surface (Heap 2).

The following pseudo code shows how a VIDEOMEMORY structure is set up for a mix of linear and rectangular memory:

/*
 * video memory pool usage
 */
static VIDEOMEMORY vidMem [] =
{
  { VIDMEM_ISRECTANGULAR, 0x00000000, 0x00000000,
            { 0 }, { 0 } },
  { VIDMEM_ISLINEAR, 0x00000000, 0x00000000,
            { 0 }, { 0 } },
};

Two areas of display memory can be allocated in this instance. The area to the conceptual right of the primary surface is necessarily rectangular, and is indicated by the VIDMEM_ISRECTANGULAR flag. The area conceptually below the primary surface can be linear, and is indicated by the VIDMEM_ISLINEAR flag.

The following pseudo code shows how a mix of rectangular and linear memory heaps are set up:

/*
 * video memory pool information
 */

/* set up the pointer to the first available video memory after the primary surface */
    ddHALInfo.vmiData.pvmList       = vidMem;

/* how many heaps are there
     ddHALInfo.vmiData.dwNumHeaps       = 2;

/* The linear piece:  */

/*
 * remainder of screen memory
 */

    VideoHeapBase = ddHALInfo.vmiData.fpPrimary + dwPrimarySurfaceSize
                    + dwCacheSize;
    VideoHeapEnd = VideoHeapBase + dwDDOffScreenSize - 1;
    vidMem[0].fpStart = VideoHeapBase;
    vidMem[0].fpEnd = VideoHeapEnd;

/* The rectangular piece:  */

/* set up the pointer to the next available video memory */
    ddHALInfo.vmiData.pvmList     = vidMem[1];

/*
 *  Compute the Pitch here ...
 */

    vidMem[1].fpStart  = ddHALInfo.vmiData.fpPrimary +
                        dwPrimarySurfaceWidth;
    vidMem[1].dwWidth  = dwPitch - dwPrimarySurfaceWidth;
    vidMem[1].dwHeight = dwPrimarySurfaceHeight;
    vidMem[1].ddsCaps.dwCaps = 0;  // surface has no use restrictions

A linear memory heap is set up by determining the start and end points of the scratch area below the primary surface, indicated by the fpStart and fpEnd members of the linear VIDEOMEMORY structure (vidMem[0]). The rectangular piece is set up using the starting point, indicated by the fpStart member of the rectangular VIDEOMEMORY structure (vidMem[1]), width, indicated by the dwWidth member, and height, indicated by the dwHeight member, of the primary surface. The pitch (the dwPitch member) must be calculated before the rectangular piece can be set up. This is the same as in the previous rectangular example, except in this case the pitch is the second element of the VIDEOMEMORY structure instead of the first. Each new heap requires a new VIDEOMEMORY structure.

In some cases, the flip register can handle only 256 KB boundaries. In these instances, a small heap can use up the space between the bottom of the caches and the start of the back buffer, allowing the back buffer to begin on a 256 KB boundary. This example is not shown, but it could be implemented by adding another element to the VIDEOMEMORY structure and setting the starting point just beyond the caches and the ending point just before the 256 KB boundary. Such a heap should be flagged with DDSCAPS_BACKBUFFER so that it can be skipped over when the heap manager looks for a back buffer. This back buffer heap (the one aligned) would also be marked with DDSCAPS_OFFSCREENPLAIN to keep sprites and textures from using this heap until no other memory is available in other heaps for off-screen plain surfaces.


Bank-Switched Memory Addressing on Windows 98/Me

Windows 2000 and later drivers do not need to support bank-switched memory. This section applies only to Windows 98/Me drivers.

If linear memory addressing is supported, use it. If the hardware or driver can only use bank switching, then you must use the virtual flat-frame buffer device VflatD.

VflatD helps manage the frame buffer for a display driver. To overcome the problem of addressing more than 64 KB of display memory, VflatD virtualizes the buffer for display cards that use bank-switching techniques. It does this by mapping display memory to a smaller block of memory addresses. Thereafter, whenever a page fault occurs during a drawing operation, VflatD calls the bank-switch procedure, directing it to map a block of display data into the physical frame buffer.

If bank switching is used, DirectDraw gets this information from the display driver and sets the DDCAPS_BANKSWITCHED flag. This indicates that display memory is presented to the hardware through a memory window. The memory is made to appear flat with VflatD.

With bank-switched memory, only a small window of memory (usually 64 KB) is visible to the application at any given time. When the application reaches the end of the window, a page fault is generated. VflatD traps the page fault and moves the memory pointer so a new window is visible to the application, as shown in the following figure.

Bank Switched Memory

As illustrated in the preceding figure, bank-switched memory exposes one 64K window of visible memory at a time. Make sure that heap start addresses are at least DWORD aligned because not doing so may slow performance, and can even cause system crashes. VflatD hangs the system if a bank switch occurs within a chunk of memory that is not DWORD aligned. This is because the processor instruction being executed cannot be broken into smaller pieces. For instance, the instruction might be to read in 4-byte increments of memory. Only one page of memory is in the window at a time, so a 4-byte chunk of an instruction that straddles a page boundary will cause the fault handler to endlessly bank switch back and forth between the two memory windows. Also, standard copy operations are up to three times faster when the data is properly aligned.

Writing aligned data means that the destination address is 4-byte aligned (PTR==PTR & 0xFFFFFFFC).

Word alignment restrictions can be handled with a simple adjustment, as shown in the following pseudo code:

 /*
  * required alignments of the scan lines for each kind of memory
  */
    ddHALInfo.vmiData.dwOffscreenAlign = AlignTbl[ wBpp >> 2 ];
    ddHALInfo.vmiData.dwOverlayAlign = AlignTbl[ wBpp >> 2 ];
    ddHALInfo.vmiData.dwTextureAlign = AlignTbl[ wBpp >> 2 ];
    ddHALInfo.vmiData.dwAlphaAlign = AlignTbl[ wBpp >> 2 ];
    ddHALInfo.vmiData.dwZBufferAlign = AlignTbl[ wBpp >> 2 ];

Note The preceding sample shows pitch alignments only; these alignments do not control the alignment of the start of surface memory.


Using VflatD

This topic applies only to Windows 98/Me.

VflatD is a page-switching DLL that changes an internal pointer when a bank boundary is crossed. VflatD is not necessary unless the memory on your graphics card is bank-switched. When a bank boundary is crossed, a page fault triggers a fault handler that causes VflatD to carry a bank switch, which exposes a new page of memory. Even though a new bank has been shifted to, the memory appears to the applications as linear addressable space. Memory simply continues from a new origin that is tracked by the VflatD memory manager. Normally this happens in the background, without error.

To use VflatD, the driver must

  1. Call VflatD_Query, which verifies that the correct version of VflatD has been loaded.
  2. Call VflatD_Create_Virtual_Frame_Buffer, which registers the driver, returns a selector identifying the logical frame buffer, and specifies a bank-switch procedure to VflatD.
  3. Call VflatD_Begin_Linear_Access, which provides access to a linear addressable frame buffer. This function should be used when initializing DirectDraw with DDCreateDriverObject.
  4. Call VflatD_End_Linear_Access. Use this function when exiting DirectDraw with HALDestroyDriver.

The bank-switch procedure must be written using 32-bit code and must be no more than 100 bytes in length. When the procedure is called, the EAX register identifies the new bank to be swapped into the physical frame buffer. The procedure must save all registers except EAX and EDX and must not return a value (that is, EAX and EDX must be the same on exit as they were on entry).

VflatD_Begin_Linear_Access starts linear access to the frame buffer. The frame buffer can be accessed through its linear address (by default the frame buffer must be accessed with the default selector). The frame buffer will remain in linear access mode until VflatD_End_Linear_Access is called. This call can be nested.

VflatD returns the access count in EAX and clears the carry flag if successful. The access count is incremented each time VflatD_Begin_Linear_Access is called, and is decremented with each call to VflatD_End_Linear_Access. Linear access mode is turned off when the access count is zero.

For more information about VflatD and the VflatD functions, see the reference section of the Windows DDK documentation.


Flipping

The primary surface is the area of memory which is being read from to draw the screen that is currently being displayed. If a primary surface has one or more attached back buffers, it is a flippable surface.

Flipping structures are used to page flip in DirectDraw. Conceptually, they can be thought of as linked lists made of surfaces. The front buffer is the "visible" buffer. The back buffer and all attached flippable surfaces must be the same size and pixel depth as the front buffer. Most modern graphics cards have enough memory for flippable front and back buffers in high resolution modes.

All types of surfaces can be flipped in DirectDraw; page flipping is the common special case. For instance, flipping is not limited to the primary surface on cards that support overlays, or on 3D capable display cards that have texture memory. In these cases, overlays and textures can be flipped in the same way as the primary surface, with the same driver entry point.

Surfaces which are not used for flipping can have any dimension and can store non-flippable objects such as image data. Image data may also be stored in system memory, but in that case DirectDraw may use the hardware emulation layer (HEL) because hardware blitters cannot normally reach system memory to blit the image data. Some cards allow hardware blitters to have direct memory access (DMA) to system memory, so DirectDraw performs a check for DMA.

The following figure illustrates the relationship between two flippable surfaces.

Flipping

If a front buffer has one or more back buffers attached, it is a flippable surface, as shown in the preceding figure. The back buffer and all attached flippable surfaces must be the same size and pixel depth as the front buffer. A back buffer surface becomes the primary surface using a flip. A flip simply changes a pointer so it points to a different flippable surface, thereby displaying the new surface . The front buffer (which is no longer the primary surface) then becomes accessible, and can have new data written to it.

Done properly, flipping solves most screen flicker problems. The ability to render to a surface that is not being displayed allows smooth, tear-free animation for game play and video playback.


Tearing

As discussed in the Flipping section, a flip essentially changes a memory pointer so that it points to a new region of display memory (see the Permedia2 sample code for example). The surface being flipped away from must be finished being displayed before the application can lock, blt, or alter that memory, or a tear may result (as shown in the following figure). A tear may also occur if the surface being flipped to is having data written to it during the flip. Tearing is universal and may happen any time an image is being drawn and displayed at the same time. Faster frame rates do not solve this problem. Since primary surfaces, overlays, and textures are all DirectDraw surfaces, they can all be flipped the same way to prevent tearing.

Tearing

A tear will occur when a page flip or blt happens at the wrong time. If a page flips while the monitor scan line is in the middle of displaying a surface, as represented by the dashed line in the preceding figure, a tear will occur. The tear can be avoided by timing the flip to occur only after the entire surface has been displayed (as in the lower example of the figure). A tear can also occur when blitting to a surface that is in the process of being displayed.


Triple Buffering

Increasing the number of buffers that can hold a primary surface increases display performance. It is preferable to have at least three flippable surfaces (some games utilize five or more). When there are only two surfaces and a page flip occurs, the display delays until the monitor's vertical retrace is finished. The delay is necessary to ensure that the back buffer isn't written on before it is finished being displayed. With triple buffering, the third surface is always writable; since it is a back buffer and available to draw on immediately (as shown in the following figure). In a game that does not use sprite memory, 3D rendering using triple buffering is 20 to 30 percent faster than double buffering.

Triple Buffering

The flipping structures in the preceding figure are the same as those in Tearing, only now three buffers are utilized. Because one buffer is almost always writable (because it is not involved in a flip) the driver does not have to wait for the display scan to finish before allowing the back buffer to be written to again.

The following is a brief explanation of flipping and blitting in a triple-buffered system, using the labels from the preceding figure. The example begins with surface pixel memory 11 being displayed. This is the primary surface pointed to by the front buffer (fpVidMem in the sample code supplied with the Windows DDK). At some point, it becomes desirable to blt to the surface at pixel memory 22. Since fpVidMem points to the surface beginning at 11 (not 22) and the flip status is false (no flip is occurring on the requested surface), the blt can proceed. The driver locks the surface, writes to it, and then unlocks it. To display that surface, a flip must occur. The DirectDraw front buffer object can now change fpVidMem (the display memory pointer) to make the surface at 22 the primary surface. Since no flip is pending, the display pointers are exchanged (see the bottom half of the preceding figure), and the flip status is set to TRUE. The front buffer now points to surface pixel memory 22, the back buffer points to surface pixel memory 33, and the third buffer object points to surface pixel memory 11 (the old primary surface). Unlike with double buffering, DirectDraw is free to write to the back buffer at this time. In other words, DirectDraw can write to surface pixel memory 33 because no flip is pending. This circular flipping process continues endlessly to provide smooth animation and faster game play and video playback for applications that utilize DirectDraw.


Timing a Flip

Timing a flip is very easy if a flip register is available and the scan line is known. Simply check the flip register to see whether the last flip has occurred, then make sure the scan line is not in the vertical blank before doing the flip. If the scan line and flip register are not available, however, you will have to use one or more of the algorithms described in the following paragraphs.

  • If the hardware does not have a bit for checking whether the scan line has been through a refresh cycle, more than one method should be used to time the flip. The alternative method is based on elapsed time. It is okay to flip if adequate time for drawing the entire surface has elapsed since the last flip. This amount of time is determined empirically (unless the monitor refresh rate is known) at driver initialization and on mode changes by polling until the display is in vertical sync, and then polling until it is not in vertical sync. This is done for 20 iterations, with the thread execution priority set to maximum. The result is divided by 20 to give display duration. This is the maximum time to wait before allowing access to the back buffer. (If the display duration is already known, it does not need to be calculated.) In most cases, a much shorter period is required before doing a flip, but display duration is used as a fallback because it is completely reliable.
  • If only the line number of the scan line is available, the fastest method is to record the time and scan line. Then, when the scan line is less than it was before, it has been through a refresh cycle. For instance, if the scan line is at line 300 the first time it is polled and at line 50 the next time, then the entire surface has been displayed at least once. However, the scan line is not completely reliable on all display cards. In some cases a register can be read from and written to at the same time, giving half of two different numbers. In these cases, the register needs to be read twice to verify that it isn't reporting an incorrect number. In some cases the scan line may be inaccurate as it passes through the horizontal sync. The flag that indicates whether the scan line is currently in display often returns a false negative result while the scan line is in horizontal blank.
  • If the line number of the scan line is not available, it may be possible to verify that the scan line has passed from display through vertical blank and back into display. By tracking when the scan line passes into and out of display, you can determine when an entire refresh cycle has been completed. The ability to check whether the scan line is in display or in vertical blank should be available on all display cards, but the scan line may not be. (In either case, display duration is still the fallback.)

A few adjustments may be required to get the last bit of flicker out of the display, such as making sure no calculations are occurring after the address is read (that is, shifting right two places to get the true address because the address is on a DWORD boundary, etc.). To avoid tearing, make sure the scan line is not in vertical blank, and just above the vertical sync. In the case of one driver, this problem caused a tear once every seven minutes, so be careful here. These problems are easily remedied by making sure the scan line is in display before writing to the flip register.

Although display cards are based on the original IBM video graphics card (VGA) specifications, super VGAs vary considerably (see Programmer's Guide to the EGA, VGA, and Super VGA Cards by Richard F. Ferraro - Addison-Wesley, © 1990). Some cards provide no straightforward way of determining whether the scan line is in vertical blank, or if it is even in display. These deficiencies will become more important as the competition to meet the demand for advanced display capabilities increases. In the meantime, driver writers must use creativity to compensate for these deficiencies.

Once it is okay to flip, the reference to the surface to display next is loaded in the flip register. Nothing happens until the scan line gets past the vertical sync and is back into the display area. Then the flip register is read once. If something else is stored in the flip register before that time, or if the surface is being written to at the same time it is being read, a tear will occur. Once the register is read, the surface should not be locked or written to while it is still being drawn.

Checking whether the register has been read is just a matter of checking a flag in most newer cards. In older cards, however, a hardware interrupt was often used for this purpose. When a certain point was crossed that read in the flip register, whatever function was hooked to that interrupt would be called. The problem is that this interrupt may be used for other purposes in some newer hardware.


Flip Intervals

Beginning with DirectX 6.0, DirectDraw adds the ability for an application to determine when a flip command is performed. Support for these new features can be added to an existing driver, depending on the hardware capabilities.

The following terms are used when describing the timing related to the application's call to Flip:

Posted
The time at which the application calls Flip and DirectDraw calls the driver's DdFlip entry point.
Retired
The time at which the hardware begins displaying from the new surface.

In previous versions of DirectDraw, flips were always retired on or near the vertical sync following when they were posted. With DirectX 6.0 and later versions, applications can specify that the flip be retired immediately, that is, exactly when posted, or at some set number of vertical syncs after the flip is posted. DirectX 6.0 specified two new capability bits (DDCAPS2_FLIPNOVSYNC and DDCAPS2_FLIPINTERVAL in the DDCORECAPS structure) and four new flags (DDFLIP_NOVSYNC, DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 in the DD_FLIPDATA structure) to enable these features.

If your driver sets DDCAPS2_FLIPNOVSYNC, it will receive the DDFLIP_NOVSYNC flag in the dwFlags member of the DD_FLIPDATA structure. The DDCSAPS2_FLIPNOVSYNC flag indicates that the flip should be retired as soon as it is posted. However, in this case, your hardware must be able to switch buffers on at least a per-scan line basis. It is not considered legal for the driver to accept or advertise support for DDCAPS2_FLIPNOVSYNC if the display does not actually retire the flip until the next vertical sync, even if the driver returns immediately.

The number at the end of the DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 flags denotes how many vertical syncs the hardware should wait before retiring a posted flip. For example, DDFLIP_INTERVAL2 means that the hardware should count two vertical syncs, then retire the flip on or near the second vertical sync.

If your driver exposes DDCAPS2_FLIPINTERVAL, then DirectDraw places the number of vertical syncs to delay a flip by, into the most significant byte of the dwFlags member of the DD_FLIPDATA structure. Since the DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 flags are defined to make this true, the driver should not treat these three flags as bit flags. Additionally, if the driver exposes DDCAPS2_FLIPINTERVAL, DirectDraw ensures that the most significant byte of the dwFlags member is set accordingly when the DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 flags are not set. DDFLIP_NOVSYNC will cause a zero to be placed in the most significant byte, and the default value of the most significant byte becomes one since the default behavior of a flip call is to retire the flip on or near the first vertical sync after it is posted.

Since DirectX 1.0, drivers have been required to return DDERR_WASSTILLDRAWING whenever a flip was pending (that is, when the flip had been posted but not yet retired). This requirement is extended for flip intervals. Since DDFLIP_NOVSYNC flips are retired when they are posted, the driver should never return DDERR_WASSTILLDRAWING as a result of such a flip (since it will never be pending). Conversely, using one of the DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, or DDFLIP_INTERVAL4 flags means that the driver needs to return DDERR_WASSTILLDRAWING for a long period of time, since the period between posting and retiring a flip is extended.

DirectDraw does not preclude the use of these flags with overlay surfaces, but drivers are not required to respect them, even if they do set the DDCAPS2_FLIPINTERVAL or DDCAPS2_FLIPNOVSYNC capability bits. Drivers may choose to respect these flags for overlays if they have the capability, but applications are unlikely to exploit this feature.

Note The DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 flags are intended to exploit hardware capabilities. Drivers should not attempt to emulate these flags by looping in the driver until the flip can be retired as requested. Since important operating system mutexes are held while calling a DirectDraw driver, such an implementation can have serious deleterious effects on system performance.


Overlay support

DirectDraw also supports overlays. An overlay surface is one that can be displayed on top of the primary surface without altering the physical bits in the surface underneath it. With an overlay, registers are set that define a rectangle on the primary surface that will contain the overlay surface. The digital-to-analog converter (DAC) changes the location of the rectangles. The scan line reads data in primary surface memory until it reaches the rectangle that is set aside for the overlay. It reads from the overlay surface until that line in the overlay is finished, then continues with the original primary surface image. This switching from primary surface to the overlay and back happens on every pass of the scan line and continues until the overlay is completely displayed.

The overlay surface can have a different pixel depth than the primary surface. For example, while 8 bits per pixel (bpp) may look fine for the primary surface, a video clip may need 16 bpp to display acceptably. The pixel depth switches seamlessly between the primary surface and the overlay. For more information about overlays with DirectDraw, see the Video Port Extensions to DirectX section.

Overlays flip in exactly the same way as the primary surface. The DirectDraw surface objects swap pointers so that the new overlay surface is read when the scan line reaches the rectangle bounding the overlay. The same flipping algorithm described in Timing a Flip prevents tearing.


Texture support

A texture in 3D space flips the same way as any other surface. A texture is just a flat image that has bits set to specify that it can be transformed (texture mapped) onto a 3D surface. A texture can be mapped onto a 3D surface and the motion can be rendered smoothly by page flipping the texture. Flip waits for the renderer to finish reading (like waiting for the scan line). If the flipping driver supports textures, it must be able to recognize and handle them appropriately. See Direct3D Texture Management in the Direct3D DDK documentation for more detail on textures.


Blitting

If a blt is happening within one surface and the source and destination areas overlap, the proper direction must be determined to avoid overwriting part of the source before it is copied. This can be accomplished with just two potential starting points at opposite corners of the surface. All the blt engine needs are the location and dimensions for each image.

Everything possible should be done to speed up the actual blt. Duplicating sections of code to avoid an IF statement may make the driver go faster, for example. Perhaps the best implementation of this technique would be to put the code in a macro and use that in different places rather than making function calls. This is absolutely the right place to optimize for speed. See DdBlt in the reference section.


Transparent Blt

In a transparent blt, a color key normally specifies the color(s) that will not be moved. The source color key is analogous to the blue screen used in motion pictures. The color is compared to each pixel and if they match, the pixel is not copied. If they do not match, the pixel is copied. DirectDraw also supports color keys that are ranges.

In some cases, a transparent blt may be only partially supported by the hardware. This is probably still faster than doing it in software. The DDCAPS_COLORKEYHWASSIST flag should be set in these cases.

An example of a partially supported transparent blt is a display card that requires a bit mask, instead of just using a color key. In this case, rather than comparing each pixel with the color key to determine whether to copy it, a monochrome mask is built. That is, all of the pixels are compared with the color key and the entire surface is converted to a bit mask (usually one bit per byte, depending on color depth). When using DirectDraw, this is done when the surface is unlocked.

Once the alpha mask is built, it is compared to the source surface. Everything that is not set on the alpha mask is copied to the destination surface. This accomplishes the same effect as a source color key, but requires a mask to be built first, rather than comparing and copying at the same time. The mask must be rebuilt any time the color key is set. It also must be checked whenever a blt occurs because a color key override can be specified at that time. When the application's Blt function is called, check that the color key override (the only color key passed to the blt) is the same as the color key that is set on the surface. If they are the same, it is not really an override and the mask does not need to be rebuilt. If they are different, then the mask does need to be rebuilt. (The driver's DdBlt function always sees the color key as an override.)


Clip Lists

Clipped blts are never passed to the driver on Microsoft Windows 2000 and later. The IsClipped member of DD_BLTDATA will always be FALSE, and the clipped list will always be NULL.

Note for Windows 98/Me On Windows 98/ Me, DirectDraw supports passing an entire clip list to the driver (if the driver supports this) rather than calling the driver multiple times, once for each rectangle in the clip list. If the driver can take a list of rectangles and blt them all in a FOR loop, then the driver should set the DDCAPS_CANCLIPSTRETCHED and DDCAPS_CANCLIP flags in the DDCORECAPS structure.

In DdBlt, if a clipper is attached to the destination surface and the clipper indicates that the destination rectangle is occluded, DirectDraw will break the blt into a list of simple unoccluded rectangles. If the driver sets the DDCAPS_CANCLIPSTRETCHED and DDCAPS_CANCLIP flags, DirectDraw calls the driver once, only expecting it to run through the list of rectangles described in the DD_BLTDATA structure. If the driver doesn't set these flags, then DirectDraw calls the driver once for each unoccluded rectangle, setting the DD_BLTDATA so it contains only one rectangle at a time.


Color Fills and Pattern Fills

A color fill, as described by a rectangle, fills an area of the screen with a particular color. On most cards, the address of display memory, the dimensions of the rectangle, and the color are all that is needed. Some cards require beginning and ending X and Y coordinates. Be aware that Windows automatically drops the last line of these coordinates. For example, when they are numbered from 0 to 640, Windows drops line 640.

Some cards use a pattern fill, which can accomplish the same thing as a color fill. An 8 × 8 region of pixels (the pattern) makes up the desired color, and that pattern is used to fill the specified area. The pattern is set to equal the color desired and filled in the same as a color fill. A pattern fill takes four separate colors which can be blended, reducing the number of necessary instructions.


DirectDraw and Color Space Conversion

DirectDraw allows surfaces to be created and stored in YUV formats. Four Character Codes (FourCC) denote what color space conversions are being used. Then, during the overlay process, the image is converted to 16-bit RGB. YUV 4:2:2 is effectively the same density as 16 bits per pixel (bpp), but the color fidelity is better. The image can be written in as YUV and go into display memory as RGB, but normally the translation is done as it is read out of display memory so that the compression is maintained. This saves display memory and speeds up playback. For Windows 2000 and later, some YUV formats (UYVY and YUY2 – both types of 4:2:2) are emulated, but only when used as textures. Note that unsupported YUV format surfaces cannot be created in system memory.

Three common YUV color spaces (of which there are many types) are:

  • 4:2:2 (standard television is of this type)
  • 4:1:1 (more compressed)
  • 4:4:4 (similar to RGB)

There are many varieties of these color spaces and many other YUV formats in use today. Summarizing these is beyond the scope of this document, but an excellent resource for FOURCC information can be found at http://www.webartz.com/fourcc.


Drivers That Assume State Information

Most display drivers set up the state of the blitter when they do an operation. However, some display drivers expect the blitter to be in a known state. For example, some display drivers assume that the origin is set to do a standard blt rather than a transparent blt, and so on. In these cases, the state has to be reset after DirectDraw uses it.

For example, blts between two surfaces can be accomplished either with a fixed origin or with a separate origin for source and destination surfaces. If the display driver expects the origin to remain constant and DirectDraw changes it to access a secondary surface, the old pointer must be saved and restored when the operation is finished.

If this forces DirectDraw to wait while operations are being done so it can restore registers to their previous state, performance will suffer. This is because DirectDraw's speed comes from being asynchronous.

Care must be taken in these cases to minimize the changes being made to the display state. Moving the origin in this scenario also wastes room on the stack that could otherwise be used for passing parameters.


Turning On a Display Card and Changing Modes on Windows 98/Me

The following functions are used to turn on the display card, and also to change the mode of the display card on Windows 98/Me:

Enable

ReEnable


Enable

UINT FAR PASCAL _loadds Enable(
  LPVOID  lpDevice,
  UINT  style,
  LPSTR  lpDeviceType,
  LPSTR  lpOutput,
  LPVOID  lpStuff
  );

Enable is called to turn the display card on, or can be called through ReEnable to change the display mode. Enable is a function in the 16-bit portion of the display driver.


ReEnable

UINT FAR PASCAL _loadds ReEnable(
  DIBENGINE FAR  *lpPDevice,
  GDIINFO FAR  *lpGDIInfo
  )
{
    DPF("ReEnable");

    if (Enable(lpPDevice, EnableDevice, NULL, NULL, NULL))
    {
        Enable(lpGDIInfo, InquireInfo, NULL, NULL, NULL);
        return TRUE;
    }

    return FALSE;
}

ReEnable is called every time the display mode changes. In turn, ReEnable calls Enable with parameters to reinitialize the driver object. Enable can either turn the display card on, or it can change the display mode depending on the parameters sent to it when it is called. So, when Enable is called through ReEnable (which is about all that ReEnable does), the mode is changed, but no other object structure is created. DDCreateDriverObject is called in Enable, but the bReset parameter is set to one, which just resets the mode.

ReEnable returns TRUE if successful, or FALSE otherwise.


DirectDraw Driver Initialization

This section provides information about the driver initialization process, as it relates to Windows 98/Me, as well as to Windows 2000 and later.

Windows 2000 Driver Initialization

Windows 98/Me Driver Initialization


Windows 2000 Driver Initialization

On Microsoft® Windows® 98/Me, and on Windows® 2000 and later, driver information is only retrieved when requested by an application. In other words, in response to a DirectDraw® application's request to create an instance of a DirectDraw object, the graphics engine calls the driver functions to initialize a DirectDraw driver.

Starting with Windows 2000, this sequence is done at boot time and after each mode change. This has a side effect. On Windows 98/Me, drivers typically have two modes of operation – GDI mode and DirectDraw mode. If DirectDraw is running, it won't let GDI cache bitmaps, and so on - instead giving all of the memory to DirectDraw (and visa versa when in GDI mode). This behavior caused windowed applications (such as web pages that use DirectX) to suffer. Therefore, on Windows 2000 and later, GDI and DirectDraw are required to cooperate about how memory is used. The Permedia3 sample driver that ships with the Windows DDK has excellent examples of how to do this.

The driver initialization sequence is achieved by calling the following functions:

  • DrvGetDirectDrawInfo to retrieve information about the hardware's capabilities. GDI calls this function twice:
    • The first call determines the size of the display memory heap and the number of FOURCCs that the driver supports. GDI passes NULL for both pvmList and pdwFourCC parameters. The driver should initialize and return pdwNumHeaps and pdwNumFourCC parameters only.
    • The second call is made after GDI allocates display memory and FOURCC memory based on the values returned from the first call in pdwNumHeaps and pdwNumFourCC parameters. In the second call, the driver should initialize and return pdwNumHeaps, pvmList, pdwNumFourCC, and pdwFourCC parameters.

    GDI allocates and zero-initializes the DD_HALINFO structure to which pHalInfo points. DrvGetDirectDrawInfo function should fill in the pertinent members of the DD_HALINFO structure with driver-specific information:

    • The driver should initialize the appropriate members of the VIDEOMEMORYINFO structures to describe the general format of the display's memory. See Display Memory.
    • The driver should initialize the appropriate members of the DDCORECAPS structure to describe the driver's core capabilities to DirectDraw.
    • If the driver supports any of the DirectX features that are queried by sending a GUID to the driver's DdGetDriverInfo callback, the driver must initialize the GetDriverInfo member to point to the driver's DdGetDriverInfo callback and set the DDHALINFO_GETDRIVERINFOSET bit in dwFlags.
    • The driver must set dwSize to the size, in bytes, of the DD_HALINFO structure.
  • DrvEnableDirectDraw is used by the run-time to enable the DirectDraw hardware and determine some of the driver's callback support. GDI allocates and zero-initializes the DD_CALLBACKS, DD_SURFACECALLBACKS, and DD_PALETTECALLBACKS parameter structures. The driver should do the following for each of these callbacks that it implements:
    • Set the corresponding member of the appropriate structure to point to the callback.
    • Set the corresponding DDHAL_XXX_XXX bit in the dwFlags member of the appropriate structure.

    A driver’s DrvEnableDirectDraw implementation can also dedicate hardware resources such as display memory for use by DirectDraw only.

    If it is not NULL, the GetDriverInfo callback is returned in the DD_HALINFO structure by the driver's DrvGetDirectDrawInfo. GDI allocates and initializes the DD_GETDRIVERINFODATA structure and calls DdGetDriverInfo for each of the GUIDs described in the DdGetDriverInfo reference section. All GUIDs are defined in ddrawint.h.

Locking the surface memory (whether the whole surface or part of a surface) ensures that an application and the hardware cannot obtain access to the surface memory at the same time. This prevents errors from occurring while an application is writing to surface memory. In addition, an application cannot page flip until the surface memory is unlocked.


Windows 98/Me Driver Initialization

This section describes how to modify your Windows 98/Me display miniport driver to include the DirectDraw initialization process. The following topics are discussed in this section:

DirectDraw Driver Initialization Components

Initialization Procedure

Calling the HAL Function

Updating Information About the Driver


DirectDraw Driver Initialization Components

This topic applies only to Windows 98/Me.

Ddraw.dll, ddraw16.dll, and ddhelp.exe are all components of DirectDraw involved in DirectDraw driver initialization:

  • Ddraw.dll is the 32-bit DirectDraw component that contains the DirectDraw code.
  • Ddraw16.dll is the 16-bit DirectDraw component that handles thunking to the DirectDraw portion of the GDI driver, receiving mode information from the GDI driver, dynamic color changing, and ModeX information.
  • Ddhelp.exe is a helper process that loads the ddraw.dll and the 32-bit DirectDraw driver DLL into its process space. This ensures that ddraw.dll and the 32-bit DLL always remain loaded. Ddhelp.exe has a thread blocked on all processes that enables ddraw.dll and dsound.dll to do cleanup when a process is killed or exits.


Initialization Procedure

This topic applies only to Windows 98/Me.

This section describes the code required for your driver to properly initialize for DirectDraw support. The functions are described in the order they participate in the initialization process. Consequently, the discussion begins with the defines and the Control function. The Control function calls your 32-bit HAL entry point in your driver (DriverInit in the sample), which in turn calls the functions that fill in the DDHALINFO structure with the information about your driver (buildDDHALInfo32, DDCreateDriverObject, and buildDDHALInfo16 in the sample).

Note For clarity, the sample initialization functions in this section are written in C++. For an example of an optimized version of the initialization procedure, see the sample code included in the DirectX DDK (in \src\video\miniport\p3samp).

The following topics explain the initialization procedure in detail:

Querying DCICOMMAND Support

Getting the DirectDraw Version Information

Getting the 32-bit Enhanced Driver Name

Getting the 16-bit Entry Points

Getting the DirectDraw Data


Querying DCICOMMAND Support

This topic applies only to Windows 98/Me.

DirectDraw driver initialization occurs the first time the application's DirectDrawCreate function is called (see the reference section of the DirectX Software Development Kit (SDK) for more information on DirectDrawCreate). DirectDraw handles initialization communication using the standard GDI Escape function mechanism. Escape 3075 (the old DCICOMMAND escape) is used, with the dwVersion member of the DCICMD structure set to 0x200 to indicate DCI version 2.0. (The DCICMD structure is used for backward compatibility.)

The display miniport driver for Windows 98/Me begins the DirectDraw initialization as soon as DirectDraw sends a QUERYESCSUPPORT escape to the 16-bit driver Control function. The miniport driver's Control function then checks for the DCICOMMAND escape, which is also sent by DirectDraw. If the DCICOMMAND escape was sent, the miniport driver responds with DD_HAL_VERSION (the DirectDraw HAL version supported). If DD_HAL_VERSION is not returned, DirectDraw assumes that extended DirectDraw HAL functionality is not available and will use the HEL for all DirectDraw functions. This initialization process is shown as a conceptual diagram in the following figure. IHV-provided parts in this diagram are shown shaded.

Starting DirectDraw Initialization

The following sample code shows how QUERYESCSUPPORT can be handled by your Control function:

/***********************************************************************
 *
 * Control
 *
 * This is what GDI calls when an app calls Escape or ExtEscape.
 * If you don't handle an escape make sure to pass it to the DIBENG.
 ************************************************************************/

LONG FAR PASCAL _loadds Control(
    DIBENGINE FAR * lpDevice,
    UINT            function,
    LPVOID          lpInput,
    LPVOID          lpOutput)
{
    DCICMD FAR *pdci;

    DPF("Control");  // debug message to show we are in control function

    switch (function)
    {
        case QUERYESCSUPPORT:
            //
            // QUERYESCSUPPORT is sent to ask
            // "do you support this?" lpInput points
            // to the function code to query
            //
            switch (*(UINT FAR *)lpInput)
            {
                case DCICOMMAND:
                    return DD_HAL_VERSION;
            }
            break;
        case MOUSETRAILS:
            //
            // Keep track of state of mouse trails.
            // We need to know if mouse trails are on
            // so we can turn off our hardware cursor.
            //
            if (lpInput && *(UINT FAR *)lpInput > 1)
                DriverData.fMouseTrailsOn = TRUE;
            else
                DriverData.fMouseTrailsOn = FALSE;
            break;
        case DCICOMMAND:
            pdci = (DCICMD FAR *)lpInput;
            if (pdci == NULL || pdci->dwVersion != DD_VERSION)
            {
                break;
            }


Getting the DirectDraw Version Information

This topic applies only to Windows 98/Me.

The DDVERSIONINFO escape is sent next. As of DirectDraw 5.0, the DDVERSIONINFO escape call was added to allow DirectDraw to tell the driver which DirectDraw version is currently being run. This is useful for the HAL to know because sometimes it may want to report capabilities — such as AGP, video ports, and so on — that are not supported in older versions of DirectDraw. This also allows the HAL to tell DirectDraw which version of ddrawi.h was used to compile the driver.

Most older HALs fail if the DirectDraw version (DD_VERSION in ddrawi.h) does not match the version they are expecting. Therefore, DD_VERSION cannot change if DirectX 5.0 and above are to run on DirectX 2.0 or DirectX 3.0 HALs. For this reason, a new version call was added that allows the HAL to know the real version of DirectDraw, which is equal to DD_RUNTIME_VERSION (also in ddrawi.h). However, DD_RUNTIME_VERSION is for informational purposes only. HALs should not fail DirectDraw if they receive an unknown DirectDraw run time.

HALs should check this version before accessing members of the internal DirectDraw structures (DDRAWI_DIRECTDRAW_GBL, DDRAWI_DIRECTDRAW_LCL, DDRAWI_DDRAWSURFACE_LCL, DDRAWI_DDRAWSURFACE_GBL, DDRAWI_DDVIDEOPORT_LCL, and so on) that have been added after DirectX 3.0 because nothing guarantees that the driver will run only on DirectDraw versions greater than or equal to the version with which it was compiled. For example, it may run fine on DirectX 3.0 but cause severe problems when accessing a structure member added for DirectX 5.0.

The following sample shows how the Control function in a display miniport driver for Windows 98/Me should use the version information:

else if( pcmd->dwCommand == DDVERSIONINFO )
{
    LPDDVERSIONDATA pddver;

    dwDirectDrawVersion = pcmd->dwParam;
    pddver = (LPDDVERSIONDATA) pout;
    if( !pddver )
        return 0;
    pddver->dwHALVersion = DD_RUNTIME_VERSION;
}


Getting the 32-bit Enhanced Driver Name

This topic applies only to Windows 98/Me.

The DDGET32BITDRIVENAME escape is sent after getting the DirectDraw version information. The code you add to the Windows 98/Me display miniport driver returns the name of your 32-bit driver DLL (szName), the name of the entry point (szEntryPoint, which is set to "DriverInit" in the sample code), and a pointer to a region of shared data between the 16- and 32-bit address space (dwContext). Once DirectDraw has this information, it loads the 32-bit DLL (indicated by szName), calls DriverInit (as indicated by szEntryPoint), and passes dwContext (containing a memory block shared between the 16- and 32-bit side of the driver) to it. These steps are shown in the following sample code (once again, a continuation of the Control function):

/*
* return information about our 32-bit DLL
*
* we pass a pointer to our shared global Data
* to the 32-bit driver so we can talk to each
* other by reading each others mind.
*/
else if (pdci->dwCommand == DDGET32BITDRIVERNAME)
{
    LPDD32BITDRIVERDATA p32dd = (LPDD32BITDRIVERDATA)lpOutput;

    DPF("DDGET32BITDRIVERNAME");
    lstrcpy(p32dd->szName, DIRECTDRAW_DLLNAME);
    lstrcpy(p32dd->szEntryPoint, "DriverInit");
    p32dd->dwContext = (DWORD)(LPVOID)&DriverData;

    return TRUE;
}

DriverInit (which was loaded in szEntryPoint) uses the standard Windows function MapSLFix to convert the dwContext 16-bit pointers to a 32-bit pointer, which is accessed like this:

      pDriverData = MapSLFix(dwDriverData);

The entry point indicated by szEntryPoint (DriverInit in the sample) is called only once when the DLL is loaded.

In the sample functions documented here, the buildDDHALInfo32 function is called by DriverInit to modify the structures in the shared 16- and 32-bit memory window (contained in the DDHALINFO structure). This is the unchanging data passed to DirectDraw and includes the main driver callback functions, surface callbacks, and palette callbacks. It also fills out FourCCs supported, the DLL instance handle, the physical device pointer, capabilities supported, raster operations (ROPs) supported, and the required alignments of the scan lines for each kind of memory.

The 32-bit DLL must be in shared address space. That is, it must reside above the 2 gigabyte address space so that memory can be shared with the 16-bit components. The base 0xb00b0000 is used as a linker option. DirectDraw invokes ddhelp.exe to load the 32-bit DLL and to call the entry point with the shared data pointer. The 32-bit DLL fills in shared data such as the addresses of all the 32-bit HAL functions.

The following figure shows the process for querying the 32-bit enhanced driver name and loading the 32-bit HAL function addresses to the shared 16- and 32-bit address space:

Querying the 32-bit Enhanced Driver Name and Loading the 32-bit HAL Function Addresses


Getting the 16-bit Entry Points

This topic applies only to Windows 98/Me.

The DDNEWCALLBACKFNS escape is sent next (this name is a misnomer and exists only for historical reasons). This escape gives the driver the addresses of key helper functions for use on the 16-bit side. These include the DDHAL_SetInfo, DDHAL_VidMemAlloc, and DDHAL_VidMemFree functions. However, DDHAL_SetInfo is usually the only one needed by your Windows 98/Me display miniport driver.

The lpSetInfo member of the DDHALDDRAWFNS structure is the 16-bit entry point to the DDHAL_SetInfo function in ddraw16.dll. Calling the DDHAL_SetInfo function tells DirectDraw that the shared memory region between 16- and 32-bit address space has new data in it regarding a mode change or initialization. Again, the 16-bit code is necessary because of the existing 16-bit display driver. For more information about using DDHAL_SetInfo, see Updating Information About the Driver.

Calling SetInfo for Initialization or Mode Change

The following code shows how to use the DDNEWCALLBACKFNS escape (which is included as a continuation of the Control function in a display miniport driver for Windows 98/Me):

/*
* this request gives us our DirectDraw routines to call
*/
if (pdci->dwCommand == DDNEWCALLBACKFNS)
{
    DPF("DDNEWCALLBACKFNS");
    DriverData.HALCallbacks = *((LPDDHALDDRAWFNS)pdci->dwParam1);
    return TRUE;
}

The following code from the ddrawi.h header shows the ddraw16.dll entry points and the DDHALDDRAWFNS structure:

/*
 * DDRAW16.DLL entry points
 */
typedef BOOL (DDAPI *LPDDHAL_SETINFO)( LPDDHALINFO lpDDHalInfo, BOOL reset );
typedef FLATPTR (DDAPI *LPDDHAL_VIDMEMALLOC)( LPDDRAWI_DIRECTDRAW_GBL lpDD, int heap, DWORD dwWidth, DWORD dwHeight );
typedef void (DDAPI *LPDDHAL_VIDMEMFREE)( LPDDRAWI_DIRECTDRAW_GBL lpDD, int heap, FLATPTR fpMem );

extern BOOL DDAPI DDHAL_SetInfo( LPDDHALINFO lpDDHALInfo, BOOL reset );
extern FLATPTR DDAPI DDHAL_VidMemAlloc( LPDDRAWI_DIRECTDRAW_GBL lpDD, int heap, DWORD dwWidth, DWORD dwHeight );
extern void DDAPI DDHAL_VidMemFree( LPDDRAWI_DIRECTDRAW_GBL lpDD, int heap, FLATPTR fpMem );

typedef struct
{
    DWORD                  dwSize;
    LPDDHAL_SETINFO        lpSetInfo;
    LPDDHAL_VIDMEMALLOC    lpVidMemAlloc;
    LPDDHAL_VIDMEMFREE     lpVidMemFree;
} DDHALDDRAWFNS;
typedef DDHALDDRAWFNS FAR *LPDDHALDDRAWFNS;


Getting the DirectDraw Data

This topic applies only to Windows 98/Me.

The DDCREATEDRIVEROBJECT escape is sent after the DDGET32BITDRIVENAME escape has been sent. The DDCREATEDRIVEROBJECT escape calls the same internal function that reinitializes DirectDraw in the Enable and ReEnable calls (DDCreateDriverObject). If bank switching is necessary, DDCreateDriverObject invokes VflatD. Then it calls buildDDHALInfo16, which fills out the 16-bit information that goes into the DDHALINFO structure. This includes mode change information and any data required to communicate with the 16-bit display driver, such as the mode table, current display mode, primary surface address, pixel format, display heap information, and any 16-bit callback functions (there is typically only one, HALDestroyDriver). (Since DriverInit — which calls buildDDHALInfo32 — has already been called, the 32-bit information is already present.) The driver then calls the DDHAL_SetInfo function with DDHALINFO. DirectDraw thunks to the 16-bit side to retrieve the DDHALINFO structure. Ddhelp.exe is instructed to create a thread and to block on a special shared event. This event is signaled by ddraw16.dll at some point.

Getting DirectDraw Information from the Driver

The following code sample shows how to use the DDCREATEDRIVEROBJECT escape. (Note that any escape codes that are not handled in the Control function are passed on to the DIB engine.)

            /*
             * handle the request to create a driver
             * NOTE we must return our HINSTANCE in *lpOutput
            */
            else if (pdci->dwCommand == DDCREATEDRIVEROBJECT)
            {
                DPF("DDCREATEDRIVEROBJECT");
                DDCreateDriverObject(FALSE);
                *(DWORD FAR *)lpOutput = DriverData.HALInfo.hInstance;
                return TRUE;
            }

            break;
    }

    return DIB_Control(lpDevice,function,lpInput,lpOutput);
}


Calling the HAL Function

This topic applies only to Windows 98/Me.

When a HAL function is invoked, DirectDraw tests to determine whether the function is 16- or 32-bit. If the HAL function is 32-bit, the 32-bit DirectDraw driver DLL (ddraw.dll) is called directly. If the HAL function is 16-bit, the pointers are aliased, ddraw16.dll is thunked to, and ddraw16.dll calls the 16-bit function. After that occurs, the pointer aliases are freed.

Calling the HAL Function

Built on Sunday, March 11, 2001


Updating Information About the Driver

This topic applies only to Windows 98/Me.

Every time the GDI driver needs to update information about the driver, DDHAL_SetInfo must be called. This is done in response to DDCreateDriverObject, Enable, ReEnable, and ResetHiResMode (in DirectDraw for DirectX 3.0 and above). (Information about ResetHiResMode can be found in the Windows 95 DDK documentation.) The driver fills in a DDHALINFO structure and calls DDHAL_SetInfo (the driver saves the DDHAL_SetInfo callback address at DDNEWCALLBACKFNS escape time). In response to DDHAL_SetInfo, ddraw16.dll triggers an event. A real-time priority thread in ddhelp.exe is blocked on the event. Ddhelp.exe calls a special entry point in ddraw.dll, which then thunks to ddraw16.dll and retrieves information. If this is a mode set, all surfaces are marked as lost. Mode setting is summarized in the following figure.

Updating Driver Information


Surface Structure Members Reserved for Drivers

This topic applies only to Windows 98/Me.

DirectDraw provides two members in its surface structures in which drivers can store any data they want. These fields are the dwReserved1 member in the surface global structure (DDRAWI_DDRAWSURFACE_GBL) and the dwDriverReserved member in the surface global more structure (DDRAWI_DDRAWSURFACE_GBL_MORE). Given a local surface pointer (lpddSurfLcl, for example), the first field can be accessed as in the following expression:

lpddSurfLcl->lpGbl->dwReserved1

Accessing the second field is more complex, so the GET_LPDDRAWSURFACE_GBL_MORE macro from ddrawi.h should be used as follows:

GET_LPDDRAWSURFACE_GBL_MORE(lpddsurfLcl->lpGbl)->dwDriverReserved

The dwReserved1 member is available for driver use for display memory surfaces only. The driver should not read from or write to this field if the surface is in system memory. This is not normally an issue because system memory surfaces are not normally seen by the driver. However, Direct3D drivers see system memory texture surfaces and DirectDraw drivers capable of system-to-display memory transfers can also be passed system memory surfaces. If a driver needs to store information with a surface regardless of whether it is in system or display memory, it should use the new dwDriverReserved member. Note that a driver is not notified of the creation or destruction of system memory surfaces, so dynamically allocated resources should not be referenced by the dwDriverReserved member. The exception to this is system memory texture surfaces in Direct3D drivers. A Direct3D driver will get create and destroy texture calls in its HAL for system memory surfaces, and can therefore use these entry points to dynamically allocate and free resources.


An Example of Different Hardware Versions Using the Same Driver

This topic applies only to Windows 98/Me.

Generally your driver will work on a family of cards. Because each card has different capabilities that must be supported, query the type of card you are using to determine which features you can access. Each subsequent card adds new functionality, which could be supported by adding more cases to a switch statement like the example shown below. (This is not meant to be working code and should not be included as-is in your driver.)

switch( lpSData->ChipType )
{
    case CARD_VERSION_1:
       ddHALInfo.ddCaps.dwCaps =  0;
       ddHALInfo.ddCaps.dwCKeyCaps = 0;
       break;
    case CARD_VERSION_2
       ddHALInfo.ddCaps.dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL;
       ddHALInfo.ddCaps.dwCKeyCaps = 0;
       break;
    case CARD_VERSION_3
       ddHALInfo.ddCaps.dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL |
                        DDCAPS_COLORKEY | DDCAPS_COLORKEYHWASSIST;
       ddHALInfo.ddCaps.dwCKeyCaps =  DDCKEYCAPS_SRCBLT;
       break;
    default:
       ddHALInfo.ddCaps.dwCaps         =  0;
       ddHALInfo.ddCaps.ddsCaps.dwCaps =  0;
       ddHALInfo.ddCaps.dwCKeyCaps     = 0;
       break;
}


Using GetDriverInfo

This topic applies only to Windows 98/Me.

Beginning with DirectX 5.0, the GetDriverInfo callback function gave device drivers a new mechanism for providing driver-specific information, such as pointers to driver callbacks, to the DirectDraw runtime. To preserve compatibility with Windows 2000 and later, there are no plans to furnish this mechanism at the application level. GetDriverInfo is provided to help minimize changes to HAL-related DirectDraw structures in the future.

The pointer to this callback replaces the hWndListBox member that was part of the DDHALINFO structure (although it was never used) in versions of DirectDraw earlier than 5.0. This structure member has been renamed GetDriverInfo and points to a callback function with the following prototype:

DWORD __stdcall GetDriverInfo(LPDDHAL_GETDRIVERINFODATA lpData);

To inform DirectDraw that the GetDriverInfo member has been set correctly, the driver must also set the DDHALINFO_GETDRIVERINFOSET bit of dwFlags in the DDHALINFO structure.

Drivers must use the GetDriverInfo callback if any of the following DirectX features are implemented:

DirectDraw functionality:

  • Video port extensions
  • Color control
  • Windows 98/Me and Windows 2000 and later kernel-mode
  • Advance graphics port (AGP)

Direct3D functionality:

  • SetRenderTarget
  • D3dDrawPrimitives2 functions

The prototype to GetDriverInfo is similar to those of all DirectDraw callbacks. For now, the function should always set the ddRVal member of the input structure and return DDHAL_DRIVER_HANDLED, because there is no way to emulate its functionality.

The input for this callback function specifies a globally unique identifier (GUID) that determines what information DirectDraw wants. The behavior of this function is determined by which GUID is specified. The GUID points to a GUID instance defined in ddrawi.h that typically corresponds to a callback structure. The amount of data expected by DirectDraw depends on the value of this GUID. DirectDraw informs the driver of the expected amount of data in the dwExpectedSize member of the DDHAL_GETDRIVERINFODATA structure. The driver must not fill in more data than dwExpectedSize bytes. The driver should also fill in the dwActualSize member of the structure with the number of bytes known by the driver.

This flexible handshaking procedure is important for forward and backward compatibility with DirectX versions. Assuming that callback structures will get bigger with future versions of DirectX, the following scenarios apply if there is a mismatch between the callback structure sizes expected by the DirectX runtime and the sizes implemented by the Driver:

  • Under versions earlier than DirectX 5.0, DirectDraw does not attempt to call GetDriverInfo. The driver functionality is not exploited because it is not supported by these versions of DirectDraw.

    Otherwise, DirectDraw asks for a smaller callback structure than the driver wants to provide. The driver copies only the callbacks expected by DirectDraw and reports the size it expects (which is higher). It is possible but unlikely that DirectDraw will take into account that it is running on a driver designed for a more recent version.

  • If the driver is written for any release of DirectX earlier than version 5.0, it will not set the DDHALINFO_GETDRIVERINFOSET bit, and DirectX will not attempt to call GetDriverInfo.

    Otherwise, the driver implements a callback structure that is smaller than what DirectDraw expects. In this case, the driver copies its complete callback structure into the buffer provided by DirectDraw and reports the buffer size in dwActualSize. DirectDraw then knows how many callbacks are implemented by the driver and might implement different policies for the legacy driver than it would if the driver reported the entire callback structure.

To avoid problems using GetDriverInfo:

  • Do not implement dependencies based on the order in which GetDriverInfo is called. For example, avoid hooking driver initialization steps into GetDriverInfo.
  • Do not try to ascertain the DirectDraw version based on calls to GetDriverInfo.
  • Do not assume anything about the number of times DirectDraw will call the driver, or the number of times DirectDraw will query a given GUID. It is possible that DirectDraw will probe the driver repeatedly with the same GUID. Implementing assumptions about this in the driver hampers its compatibility with future runtimes.

To help avoid these problems, use the sample driver source code as a base for your implementation. The sample 32-bit callback function is defined as follows:

DWORD __stdcall GetDriverInfo32(LPDDHAL_GETDRIVERINFODATA lpData)
{
    lpData->ddRVal = DDERR_CURRENTLYNOTAVAIL;

    if (IsEqualIID(&(lpData->guidInfo),
        &GUID_MiscellaneousCallbacks) )
    {
    }
    if (IsEqualIID(&(lpData->guidInfo),
        &GUID_VideoPortCallbacks) )
    {
        DDHAL_DDVIDEOPORTCALLBACKS vpCB;
        DWORD dwSize = lpData->dwExpectedSize;
        if ( sizeof(vpCB) < dwSize )
            dwSize = sizeof(vpCB);
        lpData->dwActualSize = sizeof(vpCB);
        memcpy(lpData->lpvData, &vpCB, dwSize );
        lpData->ddRVal = DD_OK;
    }
    if (IsEqualIID(&(lpData->guidInfo),
        &GUID_ColorControlCallbacks) )
    {
        DDHAL_DDCOLORCONTROLCALLBACKS ccCB;
        DWORD dwSize = lpData->dwExpectedSize;
        if ( sizeof(ccCB) < dwSize )
            dwSize = sizeof(ccCB);
        lpData->dwActualSize = sizeof(ccCB);
        memcpy(lpData->lpvData, &ccCB, dwSize );
        lpData->ddRVal = DD_OK;
    }
    if (IsEqualIID(&(lpData->guidInfo), &GUID_VideoPortCaps) )
    {
        if (lpData->dwExpectedSize != sizeof(VideoPortCaps) )
            return DDHAL_DRIVER_HANDLED;
        lpData->dwActualSize = sizeof(VideoPortCaps);
        memcpy(lpData->lpvData, VideoPortCaps,
            sizeof(VideoPortCaps) );
        lpData->ddRVal = DD_OK;
    }
    if (IsEqualIID(&(lpData->guidInfo), &GUID_KernelCallbacks) )
    {
        DDHAL_DDKERNELCALLBACKS kCB;
        DWORD dwSize = lpData->dwExpectedSize;
        if ( sizeof(kCB) < dwSize )
            dwSize = sizeof(kCB);
        lpData->dwActualSize = sizeof(kCB);
        memcpy(lpData->lpvData, &kCB, dwSize );
        lpData->ddRVal = DD_OK;
    }
    if (IsEqualIID(&(lpData->guidInfo), &GUID_KernelCaps) )
    {
        if (lpData->dwExpectedSize != sizeof(DDKERNELCAPS) )
            return DDHAL_DRIVER_HANDLED;
        lpData->dwActualSize = sizeof(DDKERNELCAPS);
        memcpy(lpData->lpvData, &KernelCaps,
            sizeof(DDKERNELCAPS) );
        lpData->ddRVal = DD_OK;
    }
    return DDHAL_DRIVER_HANDLED;
}


Windows Drop-down Menus

This topic applies only to Windows 98/Me.

When Windows 98/Me uses a drop-down menu, it saves the area under it in a special part of display memory so that it can restore it quickly. A flag described in the Windows Device Driver Kit (the RC_SAVEBITMAP bit in the flRaster member of the GDIINFO structure) must be set to stop Windows 98/Me from saving the area under the menu. The area also can be stored elsewhere while the game is running, and restored to its original condition before Windows 98/Me takes control of the screen again, but this is not mandatory.


Asynchronous DMA Support in DirectDraw

This topic applies only to Windows 98/Me.

Versions of DirectDraw before DirectX 5.0 did not support asynchronous direct memory access (DMA) operations. This was due to the lack of a mechanism whereby the DirectDraw runtime and the driver could maintain consistent knowledge about the status of a given DMA operation. As of DirectX 5.0, DirectDraw offers such a mechanism using the GetSysmemBltStatus HAL callback.


Overview of DMA Operations

This topic applies only to Windows 98/Me.

When DirectDraw receives a blt request, it consults the blt capabilities of the device to see if it can perform the required blt. In cases involving at least one system memory surface, DirectDraw checks the DDCAPS_CANBLTSYSMEM flag and, if it is set, further consults the appropriate caps fields in the driver's DDCORECAPS structure. To review, these fields are as follows (as extracted from the DDCORECAPS structure definition in ddrawi.h):

DWORD    dwSVBCaps;
DWORD    dwSVBCKeyCaps;
DWORD    dwSVBFXCaps;
DWORD    dwSVBRops[DD_ROP_SPACE];
DWORD    dwVSBCaps;
DWORD    dwVSBCKeyCaps;
DWORD    dwVSBFXCaps;
DWORD    dwVSBRops[DD_ROP_SPACE];
DWORD    dwSSBCaps;
DWORD    dwSSBCKeyCaps;
DWORD    dwSSBFXCaps;
DWORD    dwSSBRops[DD_ROP_SPACE];

Once the driver has received the DMA blt request, it can set up the DMA operation and immediately return to DirectDraw. DirectDraw then decides if the DMA operation can be completed asynchronously by checking whether the driver has exposed the new GetSysmemBltStatus HAL callback. If the driver offers this function, DirectDraw tags the system memory surfaces to indicate that they have taken part in a DMA operation and returns immediately to the caller, typically before the DMA transfer has completed. If the driver does not offer this callback, then DirectDraw does not return to the caller until the driver reports through GetBltStatus that the destination surface is no longer involved in a blt. This behavior is required to ensure backwards compatibility with pre-DirectX 5.0 drivers.

Additionally, DirectDraw does not allow asynchronous DMA (that is, DirectDraw spins on GetBltStatus after setting up a blt) if any involved system memory surface has not been page locked by the application. A driver that does not require page locks to perform a transfer involving system memory surfaces can set the DDCAPS2_NOPAGELOCKREQUIRED flag. DirectDraw ignores the page lock status of system memory surfaces if this flag is set.

Because DirectDraw tags system memory surfaces that have taken part in a DMA operation, it knows to check with the driver before allowing any access or changes to such surfaces. If DirectDraw is asked to Lock, Blt, GetDC, PageUnlock, or Release a system memory surface, it first calls the driver's GetSysmemBltStatus function to determine whether the prior DMA operation has been completed. If the operation has not been completed, DirectDraw repeatedly calls GetSysmemBltStatus until the driver reports that the DMA operation has finished. The application-requested operation is then allowed to begin.


Responsibilities of DMA Drivers

This topic applies only to Windows 98/Me.

Drivers must expose GetSysmemBltStatus to enable asynchronous DMA. If drivers do not expose this callback, then, as explained in the previous section, DirectDraw repeatedly calls GetBltStatus until the operation is completed, even though DMA operations may still be scheduled. This fails to exploit the parallelism offered by using the processor and the DMA controller to do useful work at the same time.

DirectDraw does not call the HAL prior to scheduling a second DMA request on the same surface. This is the one scenario in which DirectDraw does not call GetSysmemBltStatus to ensure that DMA operations have been completed before allowing further requests to proceed. This design choice aims to reduce the number of DirectDraw-to-driver transitions required on a blt, but requires that the driver's Blt routine check for existing pending DMA operations on system memory surfaces before scheduling further operations.

Driver writers should also take care to ensure that any interdependencies between their accelerators and DMA controllers are reflected in their driver's behavior with respect to scheduling new blts. If an asynchronous DMA operation is scheduled, for instance, and a second video-to-video blt is requested, the driver should check that the DMA operation and the Blt operation do not intersect. In such a case the driver returns DDERR_WASSTILLDRAWING.

For more information, see the GetSysmemBltStatus callback and the DDHAL_GETBLTSTATUSDATA structure in the DirectDraw Driver Reference section. In addition, the following members of the DDRAWI_DDRAWSURFACE_GBL_MORE structure are of interest to writers of drivers of DMA-capable hardware:

dwPhysicalPageTable
Is a physical pointer to the page table. The format of the physical page table is made up of one DWORD per page. Each DWORD holds the physical address of the page. The first DWORD may not point to the beginning of a page, but each subsequent DWORD holds a pointer that is aligned on a 4K page boundary.
pPageTable
Is a linear pointer to the page table.
fpPhysicalVidMem
Is a physical pointer to the surface contents.
cPages
Specifies the number of entries in the page table.
cPageUnlocks
Is incremented on every page unlock. A driver can cache page table information and only update its cache if the cPageUnlocks value has changed since the page table was cached.

Note DirectDraw insulates the driver from the need to know about an application's nested PageLock/PageUnlock calls by referring to the dwPageLockCount value. This value is incremented whenever the application calls PageLock and decremented whenever it calls PageUnlock. Only the transitions to and from zero cause an actual page lock/page unlock operation to be performed.

Since all these fields reside in the DDRAWI_DDRAWSURFACE_GBL_MORE structure, driver writers should use the GET_LPDDRAWSURFACE_GBL_MORE macro from ddrawi.h to traverse from a pointer in a DDRAWI_DDRAWSURFACE_GBL structure to a DDRAWI_DDRAWSURFACE_GBL_MORE structure.


Surface and Palette Access Counts

This topic applies only to Windows 98/Me.

Under DirectX 5.0 and later, DirectDraw has the ability to inform your driver whether the original surface has been updated if the driver creates a copy of the surface in a local display memory cache. This lets you determine whether to update the cached surface. Whenever DirectDraw determines that a particular surface has been updated, it increments the access count in the dwContentsStamp member of the DDRAWI_DDRAWSURFACE_GBL_MORE structure. Your driver can check the dwContentsStamp member at any time; if the access count has been incremented, you should update your cache.

DirectDraw also has the ability to inform your driver whether the palette for a particular surface has changed, using the dwContentsStamp member of the DDRAWI_DDRAWPALETTE_GBL structure. This member is incremented each time the palette changes.

Additionally, the count in the dwContentsStamp members may also be set to zero. In this case, DirectDraw is unable to determine the contents of the surface. This value is set for DDSCAPS_VIDEOPORT, DDSCAPS_OWNDC, and surfaces whose display memory pointer has been changed by SetSurfaceDesc. If this is the case, you should not cache the contents of that surface.

DirectDraw increments the dwContentsStamp member of the DDRAWI_DDRAWSURFACE_GBL_MORE structure when:

  • An application calls Unlock.
  • An application calls ReleaseDC.
  • An application calls Blt.
  • An application calls Flip.
  • An application calls SetPalette.
  • An application calls SetSurfaceDesc, but the display memory pointer doesn't change.
  • Surfaces are lost.

DirectDraw increments the dwContentsStamp member of the DDRAWI_DDRAWPALETTE_GBL structure when an application calls SetEntries.

The following sample shows how to check whether a cached surface needs updating:

/*
 * Given a surface local pointer, is my private cache of the surface out of date?
 *
 * I cache a pointer to my private surface data inside the surface global more's
 * dwDriverReserved field. I keep a private copy of the surface access count in there,
 * and compare it against the incoming access count. If they are different or the
 * access counter is zero, then my cache is stale.
 * I also check the palette and update if necessary.
 */

if (ddVersion >= 0x500) //Check DDraw runtime version as passed in at initialization time
{
    LPDDRAWI_DDRAWSURFACE_GBL_MORE  lpSurfMore = GET_LPDDRAWSURFACE_GBL_MORE(lpSurfGbl);
    LPMYPRIVATEPALETTEEDATA  lpMyPerPaletteData;
    LPMYPRIVATESURFACEDATA   lpMyPerSurfaceData  = (LPMYPRIVATESURFACEDATA)lpSurfMore->dwDriverReserved;

    if( lpSurfMore->dwContentsStamp == 0 ||
            lpSurfMore->dwContentsStamp != lpMyPerSurfaceData->dwContentsStamp)
    {
        /*
         * My surface cache is stale. Update it.
         */
        lpMyPerSurfaceData->dwContentsStamp = lpSurfMore->dwContentsStamp;

        UpdateMyCache(lpSurfLcl); //copy surface to my cache.
    }

    /*
     * If there is a palette associated with the surface, did it change?
     */
    if ( lpSurfLcl->lpDDPalette )
    {
        /*
         * There is a palette associated with this surface
         */
        LPDDRAWI_DDRAWPALETTE_GBL lpPaletteGbl = lpSurfLcl->lpDDPalette->lpLcl->lpGbl;

        lpMyPerPaletteData = (LPMYPRIVATEPALETTEEDATA) lpPaletteGbl->dwDriverReserved;

        if (lpPaletteGbl->dwContentsStamp == 0 ||
            lpMyPerPaletteData->dwContentsStamp != lpPaletteGbl->dwContentsStamp )
        {
            /*
             * Palette has changed
             */
            lpMyPerPaletteData->dwContentsStamp = lpPaletteGbl->dwContentsStamp;

            UpdateMyPaletteForThisSurface(lpSurfLcl); //Update my palette table
        }
    }
}
else
{
    /*
     * Runtime less than 5.0 means I can't cache
     */
    UpdateMyCache(lpSurfLcl); //copy surface to my cache.
    UpdateMyPaletteForThisSurface(lpSurfLcl); //Update my palette table
}


Video Port Extensions to DirectX

Driver developers for devices with a hardware video port should implement the video port extensions (VPE) to Microsoft® DirectX®. The hardware video port on a VGA graphics controller provides a fast mechanism for getting data to the frame buffer. The hardware video port is a dedicated connection between video devices, typically between a hardware Moving Pictures Experts Group (MPEG) device or National Television Standards Committee (NTSC) decoder and the video card. This dedicated connection carries horizontal sync (H-sync) and vertical sync (V-sync) information with the video data. The hardware video port and overlay can use this sync information to flip automatically between multiple buffers, writing to one surface while the overlay displays another. This allows tear-free video without burdening the application.

VPE allows the client — typically Microsoft DirectShow® — to negotiate the connection between the MPEG or NTSC decoder and the hardware video port. VPE also allows the client to control effects in the video stream, including cropping, scaling, and so on. A VPE implementation should do only what is requested of it by the client; for example, it should crop only when the client requests cropping.

Microsoft DirectDraw® VPE objects do not control the video decoder, because it provides services of its own, nor does DirectDraw control the video source; it is beyond the scope of VPE. Rather, a DirectDraw VPE object represents the hardware video port itself. It monitors the incoming signal and passes image data to the frame buffer, using parameters set though its interface methods to modify the image, perform flipping, or carry out other services.

The video port extensions (VPE) are not associated with the Microsoft Windows® 2000 and later video port system module, videoprt.sys.


Video Port Extensions Background

The video port extensions (VPE) technology is a DirectDraw extension that supports direct hardware connections from a video decoder and autoflipping in the graphics frame buffer.

When video data is placed in the frame buffer, a video overlay can be used to display it. The video overlay in the graphics system tells the digital-to-analog converter (DAC) to show data in regions it would not ordinarily show. The use of overlays is efficient because blitting is not required to make the data visible, and because the video data can be viewed in a higher color depth than the visible frame buffer.

The hardware video port is a video stream delivery option that can be used instead of the PCI or AGP bus. For applications that are expected to run concurrently with other applications that require PCI bandwidth, it is advantageous to use the hardware video port to ensure low-latency video transmission between the decoder and the VGA graphics controller. This route is not as flexible as a PCI bus solution, because it ties the decoder to a particular graphics chip set, but it yields an opportunity to bypass the PCI bus if necessary.

The kernel-mode video transport capabilities, described in the Kernel-Mode Video Transport section, also provide support for VPE to ensure enhanced video playback quality and enhanced video capture support. The driver must support Kernel-Mode Video Transport in order to support VPE under Windows 2000 and later.

Note for Windows 98/Me Kernel-Mode Video Transport functionality is optional under Windows 98/Me, but is not supported under Windows 95. This is because it requires operating system support for the Microsoft Win32® Driver Model.

VPE supports only hardware-based data connections. Kernel-Mode Video Transport supports direct access for data transfer.

VPE is not a WDM technology. Under Windows 98/Me and Windows 2000 and later, WDM is used for other peripherals, but not for the display driver.

Because VPE support is part of DirectX 5.0 and later versions, and because it is supported in both operating systems, an application can take advantage of these capabilities with the assurance that the solution works on any graphics card that supports VPE under Windows 2000 and later, or Windows 98/Me.


Display Problems for Video

For the following two scenarios, interlaced video must be integrated for playback under Windows 2000 and later, or Windows 98/Me:

  • Interlaced content that is authored for display on an interlaced television and a computer with an interlaced monitor (NTSC/PAL).
  • Existing interlaced content that is authored for display on an interlaced television, which also needs to be displayed with the best-possible quality on a progressive scan (proscan) computer monitor.


NTSC and Interlaced Data

The National Television Systems Committee (NTSC) standard provides a series of 59.94 interlaced fields per second, each separated by 1/59.94 of a second. The scan lines of the even-numbered fields fall spatially halfway between the scan lines of the odd-numbered fields. However, because of the phosphor persistence of the television monitor, two fields are never displayed on a television screen at the same time. The viewer always sees either an even field or an odd field, but never at both.

A frame in NTSC is an arbitrary grouping of two sequential fields which are completely unrelated. That is, the first field in a frame is no more related to the second field in the same frame than it is to the second field in the previous frame. The Phase Alternation Line (PAL) format and the Sequential Color with Memory (SECAM) standard work identically at about 50 fields per second.

If the video contains high-motion content, the data in the odd field could be different from that in the even field. This does not cause a problem on a television monitor because you are never looking at both fields at the same time and the eye does a good job integrating the data. On a computer, however, this interlaced data is often interleaved into a single buffer and then displayed using progressive scan. This means that both fields are visible at the same time, with a high potential for motion artifacts.

The process of putting video onto a digital video disc (DVD) and then replaying it is complex. Typically, the source material being put on the disk was created for television, so each frame has two fields that are interlaced. Film shot at 24 frames per second (fps), however, must be converted to 59.94 fields per second to be compatible with a television display.


NTSC/PAL Conversion

Conversion from NTSC to PAL is done by simply playing the film a little too fast — at 25 fps. Two sequential fields are created from the same frame and displayed 1/50th of a second apart. Conversion from PAL to NTSC is done by repeating every fifth video field with a process called 3:2 pulldown. A first film frame is used to create two video fields, and then a second film frame is used to create three video fields. This process is repeated so that odd and even fields are sent in the order Ao Ae Ao Be Bo Ce Co Ce.

Therefore, an interlaced video created from a film contains pairs of fields. But unlike a standard television signal where each field is 1/60th or 1/50th of a second apart; many of these field pairs contain data from the same frame of film. Displaying these field pairs at the same time does not cause any artifacts and provides better results than television monitors can provide. However, any field pairs not from the same frame will be 1/24 of a second apart and could potentially cause greater artifacts.

When the interlaced video is encoded, a flag is set to indicate how the stream should be decoded. In a perfect world, this would be enough information to decode and optimally display the decoded pictures because the output of an MPEG-2 or NTSC decoder for DVD or DSS is theoretically always 50 or 60 interlaced fields per second. However, older films and some newer films often have a break in the flag cadence, especially at film reel changeover points. This requires a method for identifying such progressive content in order to select the proper method for displaying the information on a frame-by-frame basis.


MPEG and Progressive Content

MPEG-2 syntax provides the information necessary to identify progressive content and 3:2 pulldown. This information is stored in the header for each frame in the following 1-bit flags:

  • PROGRESSIVE_FRAME: When TRUE, this indicates that the two fields (of the frame) are actually from the same time instant (progressive film). When FALSE, this indicates that the fields might be one-half of a frame time apart (interlaced video).
  • TOP_FIELD_FIRST: Indicates which field comes first in time.
  • REPEAT_FIRST_FIELD: Indicates whether a field should be repeated for 3:2 pulldown.

With VPE and DirectDraw under DirectX 5.0 or later versions, video can always be displayed with the best-possible quality if these flags or a signal derived from these flags can be conveyed to the system on a per-field basis. Interlaced video can also be supported by DirectShow, with new flags in the media sample to indicate whether an uncompressed video media sample is either a full frame or a field, plus any other information. As described in the following sections, DirectShow can be instructed to switch between display modes on a per-frame basis by using either frame-based media samples or field-based media samples.


Progressive Scan Monitors and Interleaved Data

On a proscan monitor, the lines are displayed as a frame — that is, line 1 is displayed, then line 2, then line 3, and so on. The typical television set displays a 2:1 raster — that is, it displays the first field of a frame on the odd lines, and then it displays the second field of the frame on the even lines. Any material meant to be played on a television must be processed before being displayed on a proscan monitor.


Displaying Interleaved Video with VPE: Bob and Weave

Many expensive and imperfect methods exist for deinterlacing. Professional television producers use devices such as line doublers when deinterlacing for large-size rear-projection display, and effects systems with motion-adaptive filters when creating zooms and slow-motion sequences.

Two simple methods are available for displaying interlace on a progressive computer monitor: bob and weave. These terms are used here for simplicity, since computer and television industry terms are different.


Bob Method

The bob method of displaying data shows each field individually (similar to a television) using an overlay. The resulting image is half the normal height, so it must be zoomed 200 percent in the vertical direction using an interpolated overlay stretch. However, if this were all the bob algorithm did, the resulting image would jitter up and down because the odd field and the even field are offset by one line. Adding one line to the overlay start address on the odd fields solves this problem, as long as the vertical stretch is performed using an interpolator.

The bob method produces 60 (NTSC) progressive frames per second and retains all temporal information from an interlaced source. If a video was created with a video camera and the image contains motion, bob is the best low-cost display process for a progressive monitor. The bob method works for all sources of interlaced video data, but the weave method produces a crisper image.

By default, DirectShow uses the bob method for correcting interlaced display.


Weave Method

The weave method displays data using the hardware video port to interleave the interlaced fields into an overlay surface and then shows both fields at the same time. If this were all the weave algorithm did, however, motion artifacts would appear. The weave algorithm also relies on the MPEG driver to recognize the 3:2 pattern and then undoes it using functions in the kernel-mode video transport. The kernel-mode video transport may cause the hardware video port to discard the repeat fields, causing all field pairs to come from the same frame. The result is full-framed video displayed at 24 frames per second, just as it was originally sampled using film.

Each source-film frame is represented in the NTSC signal by two or three fields. This can be looked at as two A fields that make up the A frame. Each sequence of four film frames is converted to five television frames. Film frames A, B, C, and D become five television frames with the field pattern AA, BB, BC, CD, and DD. When the REPEAT_FIELD flag is used to encode this pattern in an MPEG stream, the MPEG data payload contains only four frames, but the field order of all five television frames is preserved.

The weave method produces 24 progressive frames per second and retains the full vertical resolution from an interlaced source. If a video was created from film using a 3:2 pulldown, or if it contains no motion, weave is the best affordable display process for a progressive monitor.


Mode Indicator and Anamorphic Format

Good driver design calls for a combination of bob, weave, and edge-adaptive filtering. Motion-detection circuitry can dynamically control the degree to which each technique is used on a pixel-by-pixel basis. Unfortunately, display logic to accomplish this is difficult to implement unless some additional data is made available. With the increasing availability of large computer-grade displays, the operating system needs this additional data to assure that basic graphics circuitry can reliably deliver an optimal picture.

In the world of DVD, it can be expected that many formats will be combined on one disk. There might be 24-frames per second film edited to 525/60 video, and then edited to 30-frames per second film. Each time such an edit takes place, it potentially changes how the data is best displayed. The current DVD specification does not ensure good performance for handling this mix of formats in a display system.

Another possible scenario is the display of a film where the REPEAT_FIELD flag is irregular or absent because of an error. When the encoder tries to interpret an irregular 3:2 pattern, it attempts to reacquire synchronization, but this can be messy. It is entirely possible for a display that follows the REPEAT_FIELD flag to change from weave mode to bob mode, or vice versa, literally in the middle of a shot. This would look very bad to the viewer.

A good way to display a film that has an occasional 3:2 pattern irregularity is to switch from weave mode to bob mode and back at the shot cuts that surround the irregularity. In other cases, it may be best to specifically identify the first field pair of a new pattern and maintain weave mode.

One can imagine many content scenarios. Some automatic display schemes work better than others depending on the particular content involved. It is likely that only some content providers will see a need to guarantee optimal results on the widest range of playback platforms. DirectShow gives these content authors a method for judging the impact of display mode on their titles and transmits their preferences.


VPE Functions in DirectDraw API and Driver

The video port extensions in DirectX 5.0 and later versions are low-level extensions to the DirectDraw API. VPE allows the client—usually DirectShow—to negotiate the connection between the MPEG or NTSC decoder and the hardware video port. VPE also allows the client to control effects in the video stream, including cropping, scaling, and so on.

VPE is not a high-level API designed for broad use by applications. Applications should use DirectShow, which provides free support for VPE. The following figure shows a simple view of the VPE and kernel-mode architecture; for more information, see the Kernel-mode Video Transport section.

Video Port Extensions and Kernel-Mode Architecture

The preceding figure shows VPE in relation to other components of DirectDraw architecture. DirectShow uses VPE to negotiate the connection, which provides information about how data and V-sync and H-sync information are transferred. This information can be an APIC connection (ITU 656), external data lines with extra pins, or proprietary data streams such as those implemented by Brooktree and Philips.

In the negotiation for the connection, the VGA hardware indicates what connections can be supported, and the MPEG or NTSC decoder indicates its preferences. DirectShow negotiates the best connection between the two. The connection is described as a globally unique identifier (GUID), with flags to describe other parameters, such as double clocking, video active, and so on.


DirectX VPE Initialization

To enable VPE functionality, the driver must do the following:

  • When DrvGetDirectDrawInfo is called, initialize the following members of the DDCORECAPS structure embedded in the DD_HALINFO structure to which the pHalInfo parameter points:
    • Set the DDCAPS2_VIDEOPORT flag in dwCaps2 to indicate that the display hardware contains a hardware video port. The driver should also set any other hardware video-port-related DDCAPS2_Xxx flags to describe the VPE support that the device is capable of.
    • Set dwMaxVideoPorts to the number of hardware video ports supported by the device.
    • Initialize dwCurrVideoPorts to zero.
  • Implement a DdGetDriverInfo function and set the GetDriverInfo member of the DD_HALINFO structure to point to this function when DrvGetDirectDrawInfo is called. The driver's DdGetDriverInfo function must parse the GUID_VideoPortCallbacks and GUID_VideoPortCaps GUIDs.
  • When DdGetDriverInfo is called with the GUID_VideoPortCallbacks GUID, fill in a DD_VIDEOPORTCALLBACKS structure with the appropriate driver callbacks and flags set. The driver must then copy this initialized structure into the DirectDraw-allocated buffer to which the lpvData member of the DD_GETDRIVERINFODATA structure points, and return the number of bytes written into the buffer in dwActualSize.
  • When DdGetDriverInfo is called with the GUID_VideoPortCaps GUID, fill in the array of DDVIDEOPORTCAPS structures with the capabilities of each hardware video port. Each hardware video port has an entry in the array, with hardware video port zero specified first, hardware video port one specified next, and so on. If the device supports only one hardware video port, there will only be one DDVIDEOPORTCAPS structure in the array. The driver must then copy this data to the DirectDraw-allocated buffer to which the lpvData member of the DD_GETDRIVERINFODATA structure points and return the number of bytes written into the buffer in dwActualSize.


DirectDraw Interfaces for Kernel-Mode Video Transport Support

The kernel-mode video transport must keep track of surface information for each surface it uses, and for each VPE object. This information must be updated every time DdUpdateOverlay or DdVideoPortUpdate is called for the surface or hardware video port. Before DirectDraw sends this information to the kernel mode video transport, it calls one of two driver functions: DdSyncSurfaceData or DdSyncVideoPortData. These functions allow the driver to fill in or modify some of the structure information and to use four dwDriverReserved N members of the DD_SYNCSURFACEDATA or three dwDriverReserved N members of the DD_SYNCVIDEOPORTDATA structure for its own purposes. These driver functions are required for the kernel-mode video transport support to work correctly.

A good example of how a driver can use these dwDriverReserved N members is to set a flag indicating which physical overlay an overlay surface is using if the hardware supports more than one physical overlay.


Color Control Initialization

DdControlColor, was added for Microsoft® DirectX® 5.0 to control the luminance/brightness controls of an overlay and/or primary surface. To enable color control functionality, the Microsoft DirectDraw® HAL must do the following at initialization time:

  • If the overlay and/or primary surface contains color controls, set the DDCAPS2_COLORCONTROLOVERLAY and/or DDCAPS2_COLORCONTROLPRIMAY flags in the dwCaps2 member of the DDCORECAPS structure that is embedded in the DD_HALINFO structure.
  • The driver must specify a function in the DD_HALINFO structure that DirectDraw can call to get additional information. This is described in DdGetDriverInfo.
  • The DdGetDriverInfo callback must be called with the GUID_ColorControlCallbacks GUID specified. The driver must fill in a DD_COLORCONTROLCALLBACKS structure with the appropriate driver callbacks and flags set, then copy this structure to the lpvData member of the input structure.


AGP Support

Microsoft® DirectDraw® treats advanced graphics port (AGP) memory as a subclass of display memory. This memory type is referred to as nonlocal display memory. The terms AGP memory and nonlocal display memory are synonymous from the perspective of DirectDraw and DirectDraw drivers.

AGP memory is considered a pure subclass of display memory. That is, if a driver indicates it supports AGP memory, in most cases it must have the same functional capabilities for local and nonlocal display memory, although performance differences are permitted. The exception is if the DDCAPS2_NONLOCALVIDMEMCAPS flag is set, in which case the blt capabilities for nonlocal display memory can differ from local display memory.

For example, if a driver states that it can texture from display memory, it must be able to texture from both local and nonlocal display memory. Blitting is treated similarly. A driver that exports the source color key blt capability must be able to do a source color keyed blt both to and from nonlocal display memory. The one exception to this rule is that it is possible to preclude certain surface types from ever being allocated in nonlocal display memory. For example, it is possible to use heaps to prevent overlay surfaces from ever being allocated in AGP memory.

Because AGP memory is treated as a subclass of display memory, DirectDraw has no separate set of display driver entry points for AGP memory. The existing display driver calls are used for both AGP surfaces and local display memory surfaces. An AGP-compatible driver must check incoming surfaces to see if they are in nonlocal or local display memory, and take the appropriate action. Blts from system to AGP (and vice versa) go through DirectDraw emulation layer as normal, unless a driver supports system-to-display memory blts (in which case it must support system-to-AGP transfers as well).

Drivers should set the DDCAPS2_TEXMANINNONLOCALVIDMEM flag as much as possible since the Direct3D texture manager will keep its backing surface in AGP memory when this is the case.

The remainder of this section discusses the steps necessary to modify your existing driver to support AGP memory using DirectDraw nonlocal display memory features.


Flagging Support for Nonlocal Display Memory

A driver must inform DirectDraw (and hence DirectDraw applications) that it is AGP-compatible. This is accomplished by specifying the capability bit DDCAPS2_NONLOCALVIDMEM in the dwCaps2 member of the DDCORECAPS structure, which is part of the DD_HALINFO structure passed to DirectDraw.

If running on an operating system that does not support AGP services, DirectDraw turns off the DDCAPS2_NONLOCALVIDMEM capability bit and all associated nonlocal heaps.


Specifying Nonlocal Display Memory Heaps

A DirectDraw driver controls how much AGP memory is available and to which surfaces by returning heaps in the DD_HALINFO structure that is passed back to DirectDraw. The driver identifies nonlocal heaps by specifying the VIDMEM_ISNONLOCAL flag in the dwFlags member of the VIDEOMEMORY data structure that describes the heap. Furthermore, a driver can choose to enable combining of memory writes on a nonlocal heap by specifying the VIDMEM_ISWC flag in addition to VIDMEM_ISNONLOCAL (however, the VIDMEM_ISWC flag is not currently implemented in DirectDraw).

It is the responsibility of an AGP-compatible DirectDraw driver to describe to DirectDraw the size (linear or rectangular), attributes (write combining), and surface types the heap should not and cannot be used for. However, it is not the driver's responsibility to actually reserve address space for the heap or commit memory to it. This is handled by DirectDraw on the driver's behalf. DirectDraw hides the details of managing AGP memory from the driver.

When specifying a nonlocal display memory heap, the start address specified by the driver has no meaning. The start address, both graphic address remapping table (GART) linear and physical, of a nonlocal heap is determined by the operating system when DirectDraw requests that a heap be created. Therefore, the driver can return any value for the start address. For a rectangular heap, this start address is ignored by DirectDraw. The specified width and height are all DirectDraw needs to determine memory requirements. For a linear heap, the start address has a meaning, but only to the extent that it is used to compute the size of the heap.

DirectDraw determines the size of a linear heap by (fpEnd - fpStart) + 1 (note that the specified end address is the last byte in the heap, not the first byte after the end of the heap). As such, any start address can be specified as long as when DirectDraw subtracts that address from the end address and adds 1, the result is the maximum size of the heap.

Although physical memory is only committed to the AGP heap when it is needed (that is, as surfaces are allocated), it is important not to specify very large nonlocal heaps. Such heaps consume shared address space and other important resources even before physical memory is committed.

It is also important to note that DirectDraw and the Windows® operating system impose policy limits on the amount of AGP memory that can be committed at any given time. This is necessary to prevent resource starvation for the rest of the system. Therefore, it is quite possible for a request for a nonlocal display memory surface to fail even though the nonlocal heaps are not fully committed.

When DirectDraw has determined the correct addresses (linear and physical) of the heap, it stores them in its heap descriptors. DirectDraw also provides a mechanism to notify a driver at initialization time of these addresses. How this is done is platform specific:

  • On Microsoft® Windows® 2000 and later, this is done with a DdGetDriverInfo call with the GUID_UpdateNonLocalHeap. When this GUID is passed to DDGetDriverInfo the UpdateNonLocalHeap data is passed in the data structure.
  • On Windows 98/Me this is done with DD_MISCELLANEOUSCALLBACKS.UpdateNonLocalHeap. The DD_MISCELLANEOUSCALLBACKS structure is retrieved from the driver with the DDGetDriverInfo call. At initialization time, the DirectDraw run-time goes through a FOR loop, calling the callback specified by the UpdateNonLocalHeap member. DirectDraw then invokes the driver-supplied function for each heap and passes the function a heap number and the linear and high physical address of the start of the heap.


Notification of Actual Heap Base Addresses

A driver might need to know the linear and physical address of the base of the heap at DirectDraw initialization time (for example, during mode changes) rather than waiting for a surface creation request and looking at the heaps in the global DirectDraw surface object. To support this, DirectDraw calls the driver-supplied DdGetDriverInfo callback function with a globally unique identifier (GUID) that identifies the information to be returned by the driver. If the driver recognizes the GUID and has information to return, it copies this information into the supplied data structure and passes it back to DirectDraw.

The driver uses two GUIDs to gather and offer further information regarding Direct Draw heaps:

  • GUID_GetHeapAlignment
  • GUID_UpdateNonLocalHeap

GUID_GetHeapAlignment signals to the driver to gather heap alignment information about any DirectDraw heaps that are passed to it. The heap information is passed to the driver using the DD_GETHEAPALIGNMENTDATA structure. GUID_GetHeapAlignment is defined as:

DEFINE_GUID( GUID_GetHeapAlignment,
    0x42e02f16, 0x7b41, 0x11d2, 0x8b, 0xff, 0x0, 0xa0, 0xc9, 0x83, 0xea, 0xf6);

GUID_UpdateNonLocalHeap signals the driver to update its internal state with the heap information with the nonlocal heap structures supplied by DirectDraw. This information is contained in the DD_UPDATENONLOCALHEAPDATA structure. GUID_UpdateNonLocalHeap is defined as:

DEFINE_GUID( GUID_UpdateNonLocalHeap,
           0x42e02f17, 0x7b41, 0x11d2, 0x8b, 0xff, 0x0, 0xa0, 0xc9, 0x83, 0xea, 0xf6);

If the driver must allocate memory for AGP surfaces by itself, but has exposed heaps to DirectDraw, then HeapVidMemAllocAligned is exposed as an Eng function for this purpose. HeapVidMemAllocAligned only deals with heap addresses so it returns an offset. The driver must do whatever memory mapping work it needs to do to turn the information returned from HeapVidMemAllocAligned into a virtual address.


Callback Handling Of Nonlocal Display Memory Surfaces

Nonlocal display memory surfaces are treated in exactly the same way as local display memory surfaces in terms of driver callbacks. For example, a driver's DdCanCreateSurface callback is invoked when attempting to create nonlocal (as well as local) display memory surfaces, DdBlt is called when blitting between local and nonlocal display memory surfaces, and DdDestroySurface is called when the surface memory is being discarded.

Since the same driver functions are used for both local and nonlocal display memory surfaces, drivers must explicitly check the memory type of incoming surfaces. The memory type can be identified by checking the ddsCaps.dwCaps member of the local surface object DD_SURFACE_LOCAL passed to the driver against the capability bits DDSCAPS_LOCALVIDMEM and DDSCAPS_NONLOCALVIDMEM.

Applications and AGP hardware access the bits of a DirectDraw surface using two different addresses. Applications use a virtual address that is translated through the operating system's page table to a portion of physical address space. This physical address space is mapped by the GART hardware to appear contiguous. Hardware accesses this physical linear address (again remapped to real, discontinuous pages of memory by the GART). The fpVidMem member of the DD_SURFACE_GLOBAL structure holds the virtual linear address useful to applications (and, potentially some driver operations). The device-side physical address can be found from:

fpStartOffset = pSurface->fpHeapOffset - pSurface->lpVidMemHeap->fpStart;

This offset is then added to the device's GART physical base address (contained in the liPhysAGPBase member of the VMEMHEAP structure).

In all other respects, nonlocal display memory surfaces behave exactly like local display memory surfaces. The driver receives lock requests when an application is trying to access the surface data of nonlocal display memory surfaces. Operations such as blts between nonlocal display memory and local display memory can be asynchronous, just as they can be between local display memory surfaces. Attempts to lock nonlocal display memory surfaces when operations involving those surfaces are still pending should be failed by the driver with DDERR_WASSTILLDRAWING error code in the usual way.

Furthermore, although DirectDraw manages the allocation and freeing of nonlocal display memory surfaces on behalf of the driver, the driver is still notified of the creation and destruction of surfaces in nonlocal display memory. When a nonlocal display memory surface is destroyed, the driver should not return until the surface is no longer in use.

Nonlocal display memory is lost in exactly the same way as local display memory, that is, when a mode switch occurs or when exclusive mode changes, all local and nonlocal display memory surfaces are lost and the DdDestroySurface driver callback is invoked for each surface. However, DirectDraw does not guarantee that the actual reserved address ranges and committed memory will be preserved. DirectDraw may choose to discard all committed memory and the reserved address ranges, or it may choose to de-commit memory but preserve the address range. It may also preserve both and simply mark the surfaces as lost. A driver should not make assumptions based on any one of these scenarios.


Reordering Textures In Nonlocal Display Memory

There are special cases where the driver writer might want to re-order textures in AGP memory to allow more efficient texture management. The DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL flag signals that the driver can support blts from backing surfaces to nonlocal video memory using all the same caps that were specified for backing surface memory to local video memory blts.

The DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL flag is valid only if the DDCAPS2_NONLOCALVIDMEMCAPS flag is set. If DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL is set, then the DDCAPS_CANBLTSYSMEM flag must be set by the driver and all the associated backing surface blt caps must be correct. DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL signifies that the backing surface to video memory DDCAPS blt caps also apply to backing surface to nonlocal video memory blts. For example, the dwSVBCaps, dwSVBCKeyCaps, dwSVBFXCaps, and dwSVBRops members of the DDCORECAPS structure are assumed to be filled in correctly. Any blt from a backing surface to nonlocal memory that matches these caps bits will be passed to the driver.

Note This feature is intended to enable the driver itself to do efficient reordering of textures. This is not meant to imply that hardware can write into AGP memory. Hardware writing directly into AGP memory is not currently supported.


Handling DMA-style AGP

An AGP-compatible display card can use AGP memory in one of two ways: using the execute model or the direct memory access (DMA) model.

  • In the execute model, if there is a texture in nonlocal video memory, the card accesses AGP memory directly. That is, if a card is textured from AGP memory it reads texel data directly from a backing surface.
  • In the DMA model, the contents of the surfaces must be explicitly moved to local display memory on the card before a texturing operation can be performed.

It is important to note that the model refers to how a client of the display card sees the transfer. For example, a display card may automatically move texel data from a backing surface to a small local display memory cache when texturing. This may seem like the DMA model. However, because the client application has no information about this transfer taking place, the display card is, in fact, exposing an execute model. Only when the client application has to take explicit action to move the contents of a backing surface to local display memory is the display card considered to be exposing the DMA model.

The previous sections that dealt with AGP memory described how a driver can enable and expose the execute model of AGP usage. This section describes the additional steps a driver must take to expose use of DMA model AGP to the application. Note that the driver writer must decide whether to expose the execute model or the DMA model when writing the driver. The driver should expose one model or the other, but not both.

Before exposing the DMA model from a driver, it is important to consider the implications of the DMA model to the application writer. If a driver exposes execute model AGP support, DirectDraw assumes that surfaces in AGP (nonlocal display memory) and local display memory are functionally identical. Thus the display card can texture either from nonlocal or local display memory without any additional actions by the application. When setting a render state, an application can specify the handle to a texture surface directly, regardless of whether the surface is in nonlocal or local display memory.

However, if a driver exposes the DMA model, surfaces in nonlocal display memory may have different capabilities from those in local display memory. Therefore, before attempting to texture from a nonlocal display memory surface, the application must check whether the hardware is capable of texture from nonlocal display memory. This is accomplished by examining the capabilities exposed by the driver. The same is true for blitting.

An application explicitly requests AGP memory by specifying DDSCAPS_VIDEOMEMORY ORed with DDSCAPS_NONLOCALVIDMEM. If an application does not specify a memory type or only specifies DDSCAPS_VIDEOMEMORY, nonlocal display memory is not considered. Also, if the call does not specify local or nonlocal display memory, the surface is a texture, and the device sets the D3DDEVCAPS_TEXTURENONLOCALVIDEOMEMORY flag, then the surface can be allocated in AGP memory.

This means that if a driver exposes the DMA model, surfaces are not allocated from AGP memory. This is in contrast to a driver that exposes execute model, in which AGP memory is allocated even if the application does not explicitly request it. Drivers that expose the execute model are therefore much simpler for applications to use. Furthermore, an execute model driver allows a legacy application to gain the benefits of AGP, whereas a DMA model driver only accelerates new applications written explicitly for AGP. This should be considered when deciding whether to expose the execute or DMA models.


Flagging Support for DMA Model Nonlocal Display Memory

In addition to specifying the DDCAPS2_NONLOCALVIDMEM flag to report AGP support, a DMA model driver must export the capability flag DDCAPS2_NONLOCALVIDMEMCAPS. This flag indicates that nonlocal (AGP) memory has different capabilities than local display memory.


Reporting DirectDraw Capabilities for DMA Model Nonlocal Display Memory

A DMA model driver has different capabilities for nonlocal display memory than for local display memory. For example, a display card may be able to stretch blit local display memory surfaces but not nonlocal display memory surfaces. If the driver specifies the DDCAPS2_NONLOCALVIDMEMCAPS flag, the driver is probed for the DirectDraw capabilities of nonlocal display memory surface by the DdGetDriverInfo driver entry point. The GUID that identifies this probe is GUID_NonLocalVidMemCaps.

It is important to note that for this release of DirectDraw, a driver can only specify the capabilities for blts from nonlocal display memory to local display memory. Transfers from local display memory to nonlocal display memory, and from nonlocal display memory to nonlocal display memory, are always emulated by the DirectDraw HEL. This restriction may be relaxed in a future release.


Reporting Direct3D Capabilities for DMA Model Nonlocal Display Memory

A DMA model driver must also export the Direct3D® capabilities for nonlocal display memory surfaces. This is significantly simpler than reporting DirectDraw capabilities. The only capability affected is D3DDEVCAPS_TEXTURENONLOCALVIDEOMEMORY. If a display card exporting the DMA model can texture directly from nonlocal display memory, it should set this capability in its Direct3D device description. If it cannot, and the application must explicitly load or blt the nonlocal display memory surface to a local display memory surface before performing texturing, it should not set this capability. For completeness, an execute model driver should always set this capability bit.


Kernel-Mode Video Transport

This topic describes kernel-mode video transport as it exists on the Windows 98/Me and Windows 2000 and later operating systems.

Windows 98/Me

Kernel-mode video transport refers to a new DirectDraw component in ring 0 (kernel mode) that enhances video functionality. The HAL for this interface is added to the virtual display miniport driver (miniVDD) in Windows 98/Me, and to the miniport driver under Windows 2000 and later.

A primary role of this new functionality is to hook an IRQ generated by the video port when V-sync occurs, and then to call the miniVDD to tell it to perform video port and overlay flips. This capability can support up to ten buffers without encountering hardware limitations, as long as the video port supports the V-sync IRQ. This capability is used automatically by the versions of DirectDraw supplied with DirectX 5.0 and above when autoflipping is specified by the client and the hardware cannot autoflip.

The need for this capability stems in part from the current limitations on hardware solutions, which typically support only two buffers, with no support for the new bob and weave quality algorithms tied to the video port IRQ. If the video port supports a V-sync IRQ, then this new DirectX capability can emulate autoflipping and field skipping, greatly enhancing the quality of video needed to support DVD and other video playback requirements.

The kernel-mode video transport also ensures enhanced capture support. Under Windows 98/Me and Windows 2000 and later, the WDM-based video capture driver runs in kernel mode, with direct access to the frame buffer. The capture driver can "manually" flip overlays. The kernel-mode video transport HAL can provide V-sync notification from the video port or display; it can also get field polarities, which can be useful when capturing vertical blanking interval (VBI) data.

Although the primary purpose of the kernel-mode HAL is to enhance VPE autoflipping capabilities, it also supports video bus masters, which can write data while in kernel mode. The bus master can be notified before losing the surface because of a mode change, or because a full-screen MS-DOS instance is launched. Because the new HAL support allows a bus master to be called before the changes occur, the bus master can shut off without causing a problem.

Windows 2000 and Later

Kernel-mode video transport refers to a Microsoft® DirectDraw® component that a client, such as Microsoft DirectShow®, can use to enhance video functionality. A primary role of this functionality is to call the miniport driver to tell it to perform hardware video port and overlay flips when V-sync occurs. This capability can support up to ten buffers without encountering hardware limitations, as long as the hardware video port supports the V-sync interrupt request (IRQ). This capability is used automatically by the versions of DirectDraw supplied with Microsoft DirectX® 5.0 and later versions when autoflipping is specified by the client and the hardware cannot autoflip.

The kernel-mode video transport also ensures enhanced capture support. Under Microsoft Windows® 98/Me and Microsoft Windows® 2000 and later, the WDM-based video capture driver runs in kernel mode, with direct access to the frame buffer. The capture driver can "manually" flip overlays. The Windows 2000 and later miniport video transport driver can provide V-sync notification from the hardware video port or display; it can also get field polarities, which can be useful when capturing vertical blanking interval (VBI) data.

Although the primary purpose of the kernel-mode driver is to enhance hardware video port autoflipping capabilities, it also supports video bus masters, which can write data while in kernel mode. The bus master can be notified before losing the surface because of a mode change, or because a full-screen Command Prompt instance is launched. Because the new driver support allows a bus master to be called before the changes occur, the bus master can shut off without causing a problem.


VPE and Kernel-Mode Video Transport Architecture

This section provides some details about the Windows 98/Me and Windows 2000 and later architectures for the video port extensions (VPE) and kernel-mode video transport in DirectX 5.0 and later versions. The architecture for kernel-mode video transport is the same under Windows 98/Me and Windows 2000 and later, based on new functions that Microsoft added as device-independent code. Kernel-mode video transport consists of a DxApi function that is supplied as part of DirectDraw, the DxApi callbacks supplied in the miniport by the driver, and the COM interface methods supplied as part of DirectDraw.

Windows 98/Me

In Windows 98/Me, the DxApi callbacks are added to the miniVDD, which contains the device-specific code for the graphics device.

In Windows 98/Me, as shown in the following figure, the kernel-mode device support is added to the miniVDD, which contains the device-specific code for the graphics device. In Windows 2000 and later, the kernel-mode video transport (HAL) portion is part of the Windows 2000 miniport driver.

Windows 98/Me Kernel-mode Video Transport Architecture

Note This architecture also supports using the PCI bus for data flow between the MPEG device and VGA device; however, using PCI never results in high-quality output.

In this architecture, DirectShow (or another ring 3 client) calls the new DirectDraw interfaces to get handles to the DirectDraw object and surface objects. The client passes these handles to the kernel-mode driver. These handles are specified in the calls to the kernel-mode video transport. The following figure shows a simple version of this.

Handle Passing in Windows 98/Me Video Transport

Windows 2000 and Later

In Windows 2000 and later, as shown in the following figure, the DxApi callbacks are part of the Windows 2000 miniport. For more information about the DxApi callbacks, see DxApi Miniport Functions for Windows 2000.

Windows 2000 Kernel-Mode Video Transport Architecture

The preceding figure shows the kernel-mode video transport architecture in relation to other kernel-mode and user-mode components (the dashed line denotes the kernel transition). In this architecture, DirectShow (or another user mode client) calls the IDirectDrawKernel and IDirectDrawSurfaceKernel DirectDraw COM interfaces to get handles to the DirectDraw object and surface objects.

Note This architecture also supports using the PCI bus for data flow between the MPEG device and VGA device.

In Windows 2000 and later, the client then passes these handles to the miniport driver. These handles are specified in the calls to the kernel-mode video transport. The following figure shows a simple version of how the handles are passed.

Handle Passing in Windows 2000 Video Transport

The preceding figure shows how handles are passed in user- and kernel-mode video transport.


Using Kernel-Mode Video Transport

This information presented in this topic is separated into two parts: the first part is intended for those developing Windows 98/Me drivers; the second part is intended for those developing Windows 2000 and later drivers.

Windows 98/Me

The kernel-mode video transport provides helper functions that allow Windows 2000/WDM-style kernel-mode drivers to take advantage of VGA capabilities. These include various video port related features, the ability to reliably access the VGA frame buffer, and the ability to flip an overlay. This functionality is accessed by the kernel-mode driver linking with dxapi.lib, which allows it to later call dxapi.sys. This functionality is available only when DirectDraw is loaded.

The DxApi function is the single entry point that accepts a function identifier, an input buffer and size, and an output buffer and size. The behavior of this function and the size and format of the input and output buffers depend on the specified function identifier.

To use the DxApi interface, the kernel-mode driver must receive ring 3 handles for each DirectDraw object, surface, and video port that it needs to use. For the capture and MPEG models, these handles are passed down using their existing APIs. If a driver wants to use this functionality but it has not been passed these handles already, a ring 3 component can retrieve the handles and pass them down to the driver.

Windows 2000 and Later

Kernel-mode video transport functionality is accessed by the miniport driver linking with dxapi.lib, which allows it to later call dxapi.sys. This functionality is available only when DirectDraw is loaded.

A hardware decoder uses the DxApi function supplied with kernel-mode DirectDraw to access the DxApi miniport callback functions. The DxApi function is a single entry point that accepts a function identifier, an input buffer and size, and an output buffer and size. The behavior of this function and the size and format of the input and output buffers depend on the specified function identifier. The DxApi function and its function identifiers are defined in ddkmapi.h.

DirectShow or another client accesses the DxApi miniport callback functions supplied by the driver through DirectDraw. The DxApi miniport functions are defined in dxmini.h.

To use the kernel-mode video transport interface, the miniport driver must first receive user-mode handles for each DirectDraw object, surface, and VPE object that it needs to use. For the capture and MPEG models, these handles are passed down using their existing APIs. If a driver requires this functionality but is not a stream-class driver, a user-mode component can retrieve the handles using the IDirectDrawKernel and IDirectDrawSurfaceKernel COM interfaces and pass them down to the driver. The COM interfaces and their methods are identified in ddkernel.h.


Getting the User-Mode Handles

The following procedures show how to obtain the user-mode (ring 3) handles. These procedures apply to drivers for the Windows 98/Me and Windows 2000 and later operating systems.

To get the DirectDraw handle

  1. Call QueryInterface( lpDD, &IID_IDirectDrawKernel, &pNewInterface) on the DirectDraw interface.
  2. Call the IDirectDrawKernel::GetKernelHandle method on the new interface.

The IDirectDrawKernel::GetKernelHandle method returns a kernel-mode handle for the DirectDraw driver. To release the handle, use the IDirectDrawKernel::ReleaseKernelHandle method.

Code Sample

ddRVal = IDirectDraw_QueryInterface( lpDD, &IID_IDirectDrawKernel, &pDDK );
if( ( ddRVal == DD_OK ) && ( pDDK != NULL ) )
{
    dwDirectDrawHandle = 0;
    IDirectDrawKernel_GetKernelHandle( pDDK, dwDirectDrawHandle );
    if( dwDirectDrawHandle == 0 )
    {
        // error
    }
}

To get the DirectDrawSurface handle

  1. Call QueryInterface( lpSurface, &IID_IDirectDrawSurfaceKernel, &pDDSK) on the DirectDrawSurface interface.
  2. Call the IDirectDrawSurfaceKernel::GetKernelHandle method on the new interface.

The IDirectDrawSurfaceKernel::GetKernelHandle method returns a kernel-mode handle for the DirectDrawSurface driver. To release the handle, use the IDirectDrawSurfaceKernel::ReleaseKernelHandle method.

Code Sample

ddRVal = IDirectDraw_QueryInterface( lpSurface,
             &IID_IDirectDrawSurfaceKernel, &pDDSK );
if( ( ddRVal == DD_OK ) && ( pDDK != NULL ) )
{
    dwSurfaceHandle = 0;
    IDirectDrawSurfaceKernel_GetKernelHandle( pDDSK, dwSurfaceHandle );
    if( dwSurfaceHandle == 0 )
    {
        // error
    }
}


DxApi Miniport Functions For Windows 2000

DxApi miniport driver support is only available using Windows 2000 and later because it requires changes to the operating system.

DxApi miniport driver support is very useful for the following applications:

  • Autoflipping using an IRQ for devices that do not support hardware autoflipping or that have limitations that make it undependable. This allows DirectDraw to always revert to software autoflipping when hardware autoflipping is unavailable.
  • Field skipping using an IRQ to support MPEG drivers that can undo the 3:2 pulldown of MPEG data originally sampled from film.
  • Busmastering for devices that want to continuously busmaster data without having to call DdLock / DdUnlock every frame. This is especially useful in the miniport since the drivers for these devices are WDM drivers.
  • Video and VBI capture. In the miniport driver it is easy to capture video based on a hardware video port IRQ or graphics IRQ.

Support for this API is added into the Windows 2000 miniport driver.


DxApi Miniport Initialization

To enable DxApi miniport driver functionality, the DirectDraw driver must perform the following tasks at initialization time:

  1. The driver must specify a DdGetDriverInfo function in the DD_HALINFO structure that DirectDraw can call to get additional information.
  2. The DdGetDriverInfo callback is called with the GUID_KernelCallbacks GUID specified. The driver must fill in a DD_KERNELCALLBACKS structure with the appropriate callbacks and flags set. The driver then copies this structure to the lpvData member of the DD_GETDRIVERINFODATA structure.
  3. The DdGetDriverInfo callback is called with GUID_KernelCaps GUID specified. The driver must fill in a DDKERNELCAPS structure. The driver then copies this structure to the lpvData member of the DD_GETDRIVERINFODATA structure.
  4. The kernel calls the miniport driver IOCTL handler with MajorFunction = IRP_MJ_PNP, MinorFunction = IRP_MN_QUERY_INTERFACE, and InterfaceType = GUID_DxApi. This allows the miniport driver to fill in the DXAPI_INTERFACE structure with pointers to miniport driver functions that DirectDraw can call.

The miniport driver can specify a value in the Context member of the DXAPI_INTERFACE structure that will be passed to the miniport driver each time one of these functions is called.


Video VBI Capture

DirectX 5.2 introduced two DirectDraw driver functions for video vertical blanking interval (VBI) capture. These functions are DxTransfer and DxGetTransferStatus.

The DxTransfer function facilitates video and VBI capture. Since this function is called at IRQ time, the driver must call DxTransfer and return as quickly as possible. If the display hardware is not ready to do a busmaster at the time DxTransfer is called, then the driver should keep an internal queue of a number of bus masters (the actual number of bus masters saved in the queue is up to the driver developer). This allows the hardware to perform the busmaster when the hardware is ready. In other words, the driver should not poll and wait for the bus master to complete.

When DirectDraw calls the DxTransfer function, it returns a transfer ID in the dwTransferID member of the DDTRANSFERININFO structure. The driver can then use this identification when calling the DxGetTransferStatus function.

When the bus master completes, the driver must generate an IRQ. The driver must then call the IRQCallback function specified in DxEnableIRQ and specify the DDIRQ_BUSMASTER flag. DirectDraw then calls the DxGetTransferStatus function to determine which busmaster completed. The driver must return the transfer ID (dwTransferID) that DirectDraw passed to the driver earlier. In this way, if the driver has five busmasters in the queue, DirectDraw can determine which one completed most recently.


Kernel-mode API Support (Windows 98/Me)

Note Kernel-mode support is only available using Windows 98/Me because it requires changes to the Main VDD.

Kernel-mode support is very useful for the following applications:

  • Autoflipping using an IRQ for devices that do not support hardware autoflipping or that have limitations that make it undependable. This allows DirectDraw to always revert to software autoflipping when hardware autoflipping is unavailable.
  • Field skipping using an IRQ to support MPEG drivers that can undo the 3:2 pulldown of MPEG data originally sampled from film.
  • Busmastering for devices that want to continuously busmaster data without having to call Lock / Unlock on every frame. This is especially useful in kernel mode since the drivers for these devices exist in kernel mode in WDM.
  • Video and VBI capture. In kernel mode it is easy to capture video based on a video port IRQ or graphics IRQ.

Support for this API is added into the miniVDD.


Kernel-mode Initialization

This topic applies only to Windows 98/Me.

To enable kernel-mode functionality, the DirectDraw HAL must do the following at initialization time:

  1. The HAL must specify a 32-bit function in the DDHALINFO structure that DirectDraw can call to get additional information. This is described in GetDriverInfo.
  2. The 32-bit GetDriverInfo callback is called with the GUID_KernelCallbacks GUID specified. The HAL must fill in a DDHAL_DDKERNELCALLBACKS structure with the appropriate 32-bit HAL callbacks and flags set, then copy this structure to the lpvData member of the input structure.
  3. The 32-bit GetDriverInfo callback is called with the GUID_KernelCaps GUID specified. The HAL must fill in a DDKERNELCAPS structure, then copy this structure to the lpvData member of the input structure.
  4. The miniVDD must support an input/output control (IOCTL) interface. This is done by adding the following code to the control procedure:
    Begin_Control_Dispatch  MiniVDD
    Control_Dispatch W32_DEVICEIOCONTROL, ctrlDeviceIoControl
End_Control_Dispatch MiniVDD

;**************************************************************
;
;   ctrlDeviceIoControl
;
;   DESCRIPTION: This function called to perform Device IO
; for a 32 bit process that has opened this device with
; CreateFile.
;
;   ENTRY:
;        ESI    Ptr to DIOCParams
;        ESI+8  Io control code
;
;   EXIT:
;        EAX    As determined by function or 1 for an
; invalid IOCTL
;
;**************************************************************
public  ctrlDeviceIoControl
BeginProc ctrlDeviceIoControl, RARE

    mov    ecx, [esi+0Ch]
    cmp    ecx, VDD_IOCTL_GET_DDHAL
    jnz    @F
    call   GetDDHAL
@@:
    sub    eax, eax
    ret

EndProc ctrlDeviceIoControl
  5. When DirectDraw is initialized, it sends a VDD_IOCTL_GET_DDHAL IOCTL to the miniVDD. This allows the miniVDD to fill in the provided function table with pointers to functions that kernel-mode DirectDraw can call. The following structure is passed to the miniVDD, which fills it in:
    typedef struct _DDMINIVDDTABLE
{
    DWORD       dwMiniVDDContext;
    MINIPROC    vddGetIRQInfo;
    MINIPROC    vddIsOurIRQ;
    MINIPROC    vddEnableIRQ;
    MINIPROC    vddSkipNextField;
    MINIPROC    vddBobNextField;
    MINIPROC    vddSetState;
    MINIPROC    vddLock;
    MINIPROC    vddFlipOverlay;
    MINIPROC    vddFlipVideoPort;
    MINIPROC    vddGetPolarity;
    MINIPROC    vddSetSkipPattern;
    MINIPROC    vddGetCurrentAutoflip;
    MINIPROC    vddGetPreviousAutoflip;
    MINIPROC    vddTransfer;
    MINIPROC    vddGetTransferStatus;
} DDMINIVDDTABLE;

    The miniVDD can specify a value in the dwMiniVDDContext member that will be passed to the miniVDD each time one of these functions is called. For some miniVDDs, this is useful for multiple monitor support. The following code example could be used to fill in this structure:

    ;************************************************************
;
;   GetDDHAL
;
;   DESCRIPTION: This function fills in the function
;     table supplied by DDRAW with functions that their VxD
;     can call for kernel mode DirectDraw support.  The
;     MiniVDD can fill in the dwMiniVDDContext field with a
;     value that will always be passed back when called.
;
;   ENTRY:
;      ESI      Ptr to DIOCParams
;      ESI+18h  Ptr to output buffer
;      ESI+1Ch  Size of output buffer
;      ESI+20h  Amount of data we write into output buffer
;
;   EXIT:
;      EAX      0 = success
;
;***********************************************************

BeginProc GetDDHAL, RARE

    mov    eax, SIZE _DDMINIVDDTABLE
    cmp    eax, [esi+1Ch]
    jg     GetDDHAL_Error

    mov    ebx, [esi+18h]
    mov    eax, 27h
    mov    [ebx._DDMINIVDDTABLE.dwMiniVDDContext], eax
    mov    eax, OFFSET32 DDGetIRQInfo
    mov    [ebx._DDMINIVDDTABLE.vddGetIRQInfo], eax
    mov    eax, OFFSET32 DDIsOurIRQ
    mov    [ebx._DDMINIVDDTABLE.vddIsOurIRQ], eax
    mov    eax, OFFSET32 DDEnableIRQ
    mov    [ebx._DDMINIVDDTABLE.vddEnableIRQ], eax
    mov    eax, OFFSET32 DDSkipNextField
    mov    [ebx._DDMINIVDDTABLE.vddSkipNextField], eax
    mov    eax, OFFSET32 DDBobNextField
    mov    [ebx._DDMINIVDDTABLE.vddBobNextField], eax
    mov    eax, OFFSET32 DDSetState
    mov    [ebx._DDMINIVDDTABLE.vddSetState], eax
    mov    eax, OFFSET32 DDLock
    mov    [ebx._DDMINIVDDTABLE.vddLock], eax
    mov    eax, OFFSET32 DDFlipOverlay
    mov    [ebx._DDMINIVDDTABLE.vddFlipOverlay], eax
    mov    eax, OFFSET32 DDFlipVideoPort
    mov    [ebx._DDMINIVDDTABLE.vddFlipVideoPort], eax
    mov    eax, OFFSET32 DDGetFieldPolarity
    mov    [ebx._DDMINIVDDTABLE.vddGetPolarity], eax
    mov    eax, OFFSET32 DDSetSkipPattern
    mov    [ebx._DDMINIVDDTABLE.vddSetSkipPattern], eax
    mov    eax, OFFSET32 DDGetCurrentAutolfip
    mov    [ebx._DDMINIVDDTABLE.vddGetCurrentAutoflip], eax
    mov    eax, OFFSET32 DDGetPreviousAutoflip
    mov    [ebx._DDMINIVDDTABLE.vddGetPreviousAutoflip], eax
    mov    eax, OFFSET32 DDTransfer
    mov    [ebx._DDMINIVDDTABLE.vddTransfer], eax
    mov    eax, OFFSET32 DDGetTransferStatus
    mov    [ebx._DDMINIVDDTABLE.vddGetTransferStatus], eax

    mov    ebx, [esi+20h]
    mov    eax, SIZE _DDMINIVDDTABLE
    mov    [ebx], eax

    sub    eax, eax
    ret

GetDDHAL_Error:
    mov    eax, 1
    ret

EndProc GetDDHAL

For reference information on the kernel-mode DirectDraw functions, see Kernel-mode MiniVDD Functions.


Windows 98/Me Video VBI Capture

This topic applies only to Windows 98/Me.

Beginning with DirectX 5.2, DirectDraw contains two new HAL functions for Windows 98/Me in the miniVDD for video vertical blanking interval (VBI) capture: vddTransfer and vddGetTransferStatus.

The vddTransfer function facilitates video and VBI capture. Because this function is called at IRQ time, the driver must call vddTransfer and return as quickly as possible. If the display hardware is not ready to do a bus master at the time vddTransfer is called, then the driver should keep an internal queue of a number of bus masters (the actual number of bus masters saved in the queue is up to the driver developer). This allows the hardware to perform the bus master when the hardware is ready. In other words, the driver should not poll and wait for the bus master to complete.

When DirectDraw calls the vddTransfer function, it returns a transfer ID in the dwTransferID member of the DDTRANSFERININFO structure. The driver can then use this identification when calling the vddGetTransferStatus function.

When the bus master completes, the driver must generate an IRQ. DirectDraw then calls an IRQ handler that calls the vddIsOurIRQ function. The driver must then return a DDIRQ_BUSMASTER flag. This indicates that it is indeed the driver's IRQ and it is a bus master completion IRQ. DirectDraw then calls the vddGetTransferStatus function to determine which bus master completed. The driver must return the transfer ID (dwTransferID) that DirectDraw passed to the driver earlier. In this way, if the driver has five bus masters in the queue, DirectDraw can determine which one completed most recently.


Extended Surface Alignment

Microsoft® DirectDraw® supports surface alignment requirements on a per-heap basis. This support was introduced in Microsoft DirectX® 5.0. The driver can specify X and Y alignments for rectangular heaps, and pitch and start-offset alignments for linear heaps. These alignments can vary for different surface types.

Some display hardware cannot set its start-of-display offset in an atomic operation. At the beginning of a display period, it is possible for such hardware to latch a new start-of-display offset when the driver is only halfway through setting the value. DirectDraw now allows the driver to specify alignment requirements for visible back buffers. Some hardware may be able to express alignment requirements for potentially visible back buffers that force the start-of-display offset to be a value that requires only one register write. This technique can help avoid the occasional flicker that would otherwise be visible when the primary surface is flipped at a high frequency.


Review of the Older Alignment Method

Versions of DirectDraw before DirectX 5.0 allowed the driver to express pitch alignment requirements for linear heaps. For the purposes of this discussion, use of these alignment requirements by DirectDraw can be seen in three steps:

  1. Create the surface and fill in an aligned lPitch member based on the driver's global alignment requirements (as returned in the VIDEOMEMORYINFO structure) and the surface's ddsCaps member. This pitch is increased until it is a multiple of the appropriate alignment requirement.
  2. Call the driver's DdCreateSurface callback, if defined. The driver can modify the lPitch value, but this change will be ignored by Microsoft® Windows® 2000 and later.
  3. If the driver call is not handled, or if it requests allocation, allocate display memory for the surface from one of the driver's heaps. The width of the allocated surface is taken to be the aligned pitch determined in step 1, unless modified by the driver in step 2.

If a driver implemented the DdCreateSurface callback, it could be assured that any incoming surface would have its lPitch member set to an aligned value. For backward-compatibility, this behavior still exists. Step three maintains exactly the same behavior, unless the driver has exposed a GetHeapAlignment entry point. If, and only if, this entry point is defined, the previously calculated lPitch alignment is discarded, and all surface alignment conforms to the requirements reported using GUID_GetHeapAlignment. Drivers can keep their VIDEOMEMORYINFO structure alignment requirements as they are, and expect the same alignment behavior when run on older DirectDraw run-times. This alignment behavior has been completely replaced for new (DirectX 5.0 and later versions) DirectDraw run-times. It should be noted that exposing GetHeapAlignment turns off this legacy alignment procedure for all heaps, not just those for which GUID_GetHeapAlignment reports alignment requirements.


Using Extended Surface Alignment

To enable the extended surface alignment functionality, the DirectDraw driver must perform the following tasks at initialization time:

  • The driver must specify a DdGetDriverInfo function in the DD_HALINFO structure that DirectDraw can call to get additional information.
  • The DdGetDriverInfo callback is called with the GUID_GetHeapAlignment GUID specified. The driver must fill in a DD_GETHEAPALIGNMENTDATA structure, then copy this structure to the lpvData member of the DD_GETDRIVERINFODATA structure.

The driver should fill in the DDSCAPS structure pointed to in the HEAPALIGNMENT structure with the logical OR of the DDSCAPS_xxxx flags for any type of surface that requires alignment in this heap. If a bit in DDSCAPS is set, then DirectDraw will abide by the alignment restrictions expressed in the appropriate SURFACEALIGNMENT structure member. The DDSCAPS_FLIP bit and the FlipTarget member apply to surfaces that are back buffers in the primary flipping chain, that is, a potentially primary (visible) surface. The following list shows the currently allowed set of surface capabilities for which alignment can be specified:

  • DDSCAPS_OFFSCREENPLAIN
  • DDSCAPS_EXECUTEBUFFER
  • DDSCAPS_OVERLAY
  • DDSCAPS_TEXTURE
  • DDSCAPS_ZBUFFER
  • DDSCAPS_ALPHA
  • DDSCAPS_FLIP

Note DirectDraw compares a new surface's capabilities against the entries in the HEAPALIGNMENT structure in the order in which they are specified. For example, a surface with DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_FLIP set is aligned according to the Texture member of the HEAPALIGNMENT structure, since this is the first applicable capabilities bit for which an alignment is specified (that is, Texture appears before FlipTarget in the HEAPALIGNMENT structure). The FlipTarget member is not considered in this example. Since back buffers in a primary flipping chain are marked with DDSCAPS_FLIP and no other bit for which an alignment can be specified, such surfaces are aligned according to the FlipTarget member. Surfaces that could potentially become members of a primary flipping chain (those with the same pixel format and size as the primary surface) are also aligned according to the FlipTarget member.


Extended Surface Capabilities

Beginning with Microsoft® DirectX® 6.0, Microsoft DirectDraw® contains surface capabilities beyond those found in previous versions. These extended capabilities require the addition of several new structures, specifically the DDSCAPS2 and DD_MORESURFACECAPS structures. The DDSCAPS2 structure contains the dwCaps member originally found in the DDSCAPS structure, but also contains three new members: dwCaps2, dwCaps3, and dwCaps4. Only dwCaps2 is used in DirectDraw for DirectX 6.0. The last three members of the DDSCAPS2 structure are also identically arranged in the DDSCAPSEX structure.


New Surface Capabilities

The new surface capabilities added to DirectDraw in DirectX 6.0 and above are made visible to the driver when the application sets the appropriate flags in the dwCaps2 member of the DDSCAPS2 structure.

Applications can only set the DDSCAPS2_HARDWAREDEINTERLACE flag in conjunction with the DDSCAPS_OVERLAY flag. If a driver sees this flag set at CreateSurface time, it means that DirectDraw expects that the driver will do whatever is necessary to match the hardware video port frame rate with the device frame rate.

The DDSCAPS2_HINTDYNAMIC, DDSCAPS2_HINTSTATIC, and DDSCAPS2_OPAQUE flags are hints set by the application at CreateSurface time that inform the driver what the application plans to do with the surface. The DDSCAPS2_HINTDYNAMIC flag means that the application will be updating the surface frequently. The DDSCAPS2_HINTSTATIC flag means that the application will be updating the surface rarely, but still requires access. This means the driver must be able to allow locks on the surface, which may involve some hidden decompression and compression steps. The DDSCAPS2_OPAQUE flag means that the application will never lock, blt, or update the surface for the rest of that surface's lifetime. The driver is free to compress or reorder the surface without having to ever decompress it.

Note The driver does not need to set these flags to enable them. DirectDraw merely passes these bits to the driver when DdCreateSurface is called.

Driver writers might want to use the extended heap restriction features (described in Extended Heap Restrictions) of DirectDraw to automatically place DDSCAPS2_OPAQUE textures in optimized heaps. This is entirely up to the driver developer.

The DDSCAPS2_HINTDYNAMIC, DDSCAPS2_HINTSTATIC, and DDSCAPS2_OPAQUE flags are described in more detail in the Microsoft Direct3D® DDK documentation.

The DDSCAPS2_TEXTUREMANAGE flag is not relevant to drivers. This flag informs the Direct3D run-time that it is responsible for moving the surface from a backing surface to display memory, as appropriate, to enable accelerated 3D texturing.


Exposing the Extended Surface Capabilities

The DDCORECAPS structure contains a DDSCAPS field which drivers fill in to indicate what types of surfaces they support. When these caps are reported to the application, a slightly different structure, DDCAPS, is returned. This DDCAPS structure is built from the driver's DDCORECAPS and other structures which are queried using the DdGetDriverInfo interface. For DirectX 6.0, the application-visible DDCAPS contains a DDSCAPS2 member. This DDCAPS2 member is constructed from the DDSCAPS member in the DDCORECAPS structure, and the ddsCapsMore member of the DD_MORESURFACECAPS structure.

The DD_MORESURFACECAPS structure is queried from the driver at driver initialization time using the DdGetDriverInfo call. The appropriate GUID, as defined in ddrawint.h, is GUID_DDMoreSurfaceCaps.

Responding to the GUID_DDMoreSurfaceCaps query is entirely optional. It is intended to allow drivers to do two distinct things:

  • Expose new surface capabilities that the driver can create in display memory.
  • Express to DirectDraw new heap restrictions for these new surface capabilities.

The first item has been covered in the previous section and is fairly self-explanatory. The second item is more complex, and readers should be familiar with the significance of the ddsCaps and ddsCapsAlt members of the VIDEOMEMORY structure, described in Memory Heap Allocation, before reading the next section.


Extended Heap Restrictions

The DD_MORESURFACECAPS structure is of variable size. It always has a ddsCapsMore member, but it may have zero or more ddsExtendedHeapRestrictions entries. If the driver responds to the GUID_DDMoreSurfaceCaps query, it should return a DD_MORESURFACECAPS structure that contains as many ddsExtendedHeapRestrictions entries as it returned display memory heaps in the DD_HALINFO structure (DirectDraw guarantees that the GUID_DDMoreSurfaceCaps query is made after the driver reports DD_HALINFO.)

The driver should also fill in an appropriate dwSize value in the DD_MORESURFACECAPS structure. The value of dwSize is calculated in this way:

DDMORESURFACECAPS.dwSize =
          (DWORD) (sizeof(DDMORESURFACECAPS)
        + (((signed int)DDHALINFO.vmiData.dwNumHeaps) - 1)
        * sizeof(DDSCAPSEX)*2 );

Note that subtracting 1 from the value of dwNumHeaps is necessary to account for the fact that the DD_MORESURFACECAPS structure has a ddsExtendedHeapRestrictions member that is a one-element array. Only those array elements after the first (that is, from ddsExtendedHeapRestrictions[1] on) should be counted in calculating the total size of the DD_MORESURFACECAPS structure.

The ddsCapsEx and ddsCapsExAlt members are exactly analogous to the ddsCaps and ddsCapsAlt members of the array of VIDEOMEMORY structures returned in the pvmList member of the VIDEOMEMORYINFO structure, which is contained as a member of the DD_HALINFO structure. Any bit set in ddsCapsEx means that surface with that bit set must not be placed in that heap. Any bit set in the ddsCapsExAlt member means that the surface cannot be placed in that heap. When allocating surfaces, DirectDraw first passes through all heaps, and if it finds any heap for which no capability bits in the ddsCaps member of the VIDEOMEMORY structure match with the DDSCAPS bits of the surface, it will allocate the surface in that heap. If this pass finds no such heaps, then DirectDraw will make the same pass but check the ddsCapsEx field. If this pass fails to find any heaps, then the surface cannot be created in any heap.


Extended Surface Description Structure

The extended DirectDraw surface description structure, DDSURFACEDESC2, is identical to the DDSURFACEDESC structure, except that the pointer to the DDSCAPS structure at the end of the structure has been replaced with a pointer to a DDSCAPS2 structure.

The data blocks for the DdCreateSurface and DdCanCreateSurface driver calls each contain a pointer to a DDSURFACEDESC structure. As of DirectX 6.0, these pointers might actually point to a DDSURFACEDESC2 structure, even though the pointers remain typed as LPDDSURFACEDESC. If a driver chooses, it can examine the dwSize member of the DDSURFACEDESC pointer, and thereby decide if the pointer actually points to a DDSURFACEDESC2 structure. If your driver must run on pre-DirectX 6.0 installations, it must make this check.

If the size returned is sizeof(DDSURFACEDESC2), the driver can then examine the dwCaps2, dwCaps3, and dwCaps4 members of the DDSCAPS2 structure.


Compressed Texture Surfaces

A surface can contain a bitmap to be used for texturing 3D objects. To reduce the amount of memory consumed by textures, Microsoft® DirectDraw® supports the compression of texture surfaces.

Note No new callbacks have been added to support compressed texture surfaces. DirectDraw passes information about compressed texture surfaces to the driver through the existing driver callbacks.

FOURCC | Description | Alpha premultiplied?
DXT1 | Opaque / one-bit alpha | N/A
DXT2 | Explicit alpha | Yes
DXT3 | Explicit alpha | No
DXT4 | Interpolated alpha | Yes
DXT5 | Interpolated alpha | No

The preceding shows the five types of compressed textures that drivers should support.

For more information on the format of compressed textures, see the heading, Compressed Texture Formats, in the DirectDraw SDK documentation.


Enumerating DXT Formats

In Microsoft DirectX®, there are two ways for your driver to enumerate pixel formats. The first method enumerates formats that can be used for textures. This method is implemented using the lpTextureFormats member of the D3DHAL_GLOBALDRIVERDATA structure. The second method enumerates formats that can be used for either DDSCAPS_OVERLAY surfaces or DDSCAPS_OFFSCREENPLAIN surfaces. The second method uses the dwNumFourCCCodes member of the DDCORECAPS structure included in the DD_HALINFO structure and the lpdwFourCC array that is also included in the DD_HALINFO structure.

Since DXT formats are primarily intended to be used as textures, your driver will enumerate DXT formats only through the first method. There is no need to add DXT formats to the lpdwFourCC array.


Creating the Compressed Texture Surface

Whenever DirectDraw requests the driver to create a surface, the driver must determine whether it is being asked to create a compressed texture surface. To determine this, the driver must check for information that has previously been set by DirectDraw in the DDSURFACEDESC2 structure for the surface being created. Your driver must include the following verification steps (as with any surface):

  • Check for the DDSCAPS_TEXTURE flag in the dwFlags member of the DDSCAPS structure.
  • Check for the DDPF_FOURCC flag in the dwFlags member of the DDPIXELFORMAT structure for the surface being created. This check should before the following dwFourCC check.
  • Check for one of the DXT codes in the dwFourCC member of the DDPIXELFORMAT structure for the surface being created.
  • Check the width and height members (dwWidth and dwHeight) of the DDSURFACEDESC2 structure. DirectDraw sets these members to multiples of 4 pixels.


Using Compressed Texture Surfaces

DirectDraw will only call the driver to do a blt between two surfaces of the same DXT type if the DDCAPS2_COPYFOURCC flag is set in the dwCaps2 member of the DDCORECAPS structure. If this flag is not set, the DirectDraw HEL will perform the blt. This is most important for backing surface-to-display copy blts, since this is the mechanism whereby textures are downloaded from backing surfaces to display memory. Thus, exposing DXT texture surfaces effectively requires your driver to support the DDCAPS2_COPYFOURCC flag.

The DDCAPS2_COPYFOURCC flag has some additional implications. Your driver must be able to execute a blt between FourCC formats having at least these attributes:

  • The source and destination formats are the same FourCC format.
  • The source and destination surfaces are different.
  • The source and destination rectangles both make up the entire surface (that is, there is no stretching, and there are no sub-rectangles).
  • Both surfaces are in display memory.
  • The driver must be able to perform these blts for every FourCC format it supports in display memory.

Note Microsoft® DirectShow® uses the DDCAPS2_COPYFOURCC flag to accelerate some video functionality, hence the requirement for this flag implies that all FourCC formats can be copied.

If a blt operation requires compression to a DXT format, the DirectDraw HEL always performs the blt. This means that DirectDraw will never request the driver to perform a blt for which:

  • The destination surface has a DXT format.
  • The formats for the source and destination surfaces are not the same.

The semantics of the DirectDraw DDCAPS_CANBLTSYSMEM capability bit imply that the display driver will be called for all blts from system memory to display memory. Consequently, the driver may be called for such blts from DXT surfaces to non-DXT surfaces. The only requirement in this case is that the driver return DDHAL_DRIVER_NOTHANDLED if it cannot perform the decompression. This will cause DirectDraw to propagate a DDERR_UNSUPPORTED error code to the application. It is acceptable to implement decompression for blts from system memory to display memory in your driver, but this is not required for DirectX 6.0.

DirectDraw display memory allocation routines do not handle pixel format considerations. HeapVidMemAllocAligned, for instance, expects a count of bytes as its input parameter. Likewise, DDHAL_PLEASEALLOC_BLOCKSIZE (see the fpVidMem member of the DD_SURFACE_GLOBAL structure) signifies that the dwBlockSizeX and dwBlockSizeY members of the DD_SURFACE_GLOBAL structure are counts of bytes and lines, respectively. Consequently, if your driver uses either of these mechanisms to allocate display memory through DirectDraw allocators, your driver needs to be able to calculate the memory consumption, in bytes, of a DXT surface by itself. The following sample shows one way to perform this calculation:

DWORD dx, dy;
DWORD blksize, surfsize;
LPVOID pmem;

/*
 * Determine how much memory to allocate for the FourCC format.
 */
switch ((int)pDDPF->dwFourCC)
{
  case MAKEFOURCC('D','X','T','1'):
    blksize = 8; // The size of a DXT1 4x4 pixel block.
    break;
  case MAKEFOURCC('D','X','T','2'):    // premultiplied alpha
  case MAKEFOURCC('D','X','T','3'):    // non-premultiplied alpha
    blksize = 16; //The size of a DXT2,3 4x4 pixel block
    break;
  case MAKEFOURCC('D','X','T','4'):    // premultiplied alpha
  case MAKEFOURCC('D','X','T','5'):    // non-premultiplied alpha
    blksize = 16; //The size of a DXT4,5 4x4 pixel block.
    break;

  default:
    DDASSERT(0);
}

/*
 * Calculate the number of blocks in the x and y dimensions.
 */
dx = (nWidth  + 3) >> 2;
dy = (nHeight + 3) >> 2;
surfsize = dx * dy * blksize;

When the application calls the IDirect3DVertexBuffer7::Lock or IDirectDrawSurface7::GetSurfaceDesc methods (described in the Direct3D and DirectDraw SDK documentation sets, respectively) on a compressed surface, the driver must set the DDSD_LINEARSIZE flag in the dwFlags member of the DDSURFACEDESC2 structure. In addition, the driver must set the number of bytes allocated to contain the compressed surface data in the dwLinearSize member of the same structure. (The dwLinearSize member resides in a union with the lPitch member, so these members are mutually exclusive, as are the DDSD_LINEARSIZE and DDSD_PITCH flags.)

Your hardware or driver can convert and store the compressed texture in any format you choose (typically a reordering into a more hardware-efficient layout). However, your hardware or driver must be able to convert the compressed texture back to its original DXT code format whenever DirectDraw requires it; that is, whenever the application calls the IDirect3DVertexBuffer7::Lock method.

Windows® 2000 Note

Under Windows 2000, system memory DXT surfaces will have had some of their fields mapped for memory allocation purposes. The mapping is:

wWidth = lPitch = dx * blksize;
wHeight         = dy;
dwRGBBitCount   = 8;

When the driver encounters a system memory DXT surface, for example in D3dCreateSurfaceEx, it must map the fields back before making use of them. The back mapping is:

realWidth        = (wWidth  << 2) / blksize;
realHeight       =  wHeight << 2;
realLinearSize   = dwLinearSize * wHeight;
realRGBBitCount  = 0

RefRast Notes

In the past there has been some disagreement between the reference rasterizer (RefRast) and this documentation. This has shown up in three areas:

  1. The DXT4 and DXT5 formats in the RefRast ramped the Alpha values in the opposite order as shown in the documentation. Note that the section entitled 3-Bit Linear Alpha Interpolation (DXT4 and DXT5 format) in the DirectDraw SDK documentation is correct.
  2. The RefRast did not have the following logic guarding the color comparison logic. This was an error in RefRast.
    if ((color_0 > color_1) OR !DXT1) {
/*  color comparison logic */
}
  3. The RefRast added rounding to the calculations in order to better approximate the original value. Since then, several hardware implementations have performed the rounding in slightly different ways. Since this was not previously clarified, testing should allow for slight variations in the color and alpha values obtained from the decompression logic.


DirectX Compressed VolumeTexture Formats

Volume textures maps are digitized images that are generated periodically through a true 3D region of space. For example, a ball of fire may be sampled and the “amount” of flame within a slice can be accounted for. In this sense, the amount of flame would mean a set of values for the Alpha, Red, Green and Blue components at each pixel in the image. The entire flame would be represented by a series of these slices.

Before going into details of DirectX volume rendering, it is important to clarify some terminology. It should be noted that there are two common methods used in computer graphics to represent volume data sets. One is to sample the image at each location and store the appropriate ARGB values. For example, data for the flame could be stored as a 256 X 256 X 256 three-dimensional array. This would require about 64MB to store a 32 bit value at each location in the array. (Some applications, such as medical imaging, may require this amount of data!) However, “slicing” the flame into 4 or 8 slabs can make a very good approximation. Each slab would store 256X256 elements, where each element would represent a region of data within the slab. If we assume an array of size 256 X 256 X 4 is reasonable, then storing a 32-bit value at each location would require only 1MB of storage (less if the data is compressed). The reason to talk about these two different methods is that if you want anything in your image that is behind the flame to be hidden, then the data value stored at each location would be different. In the full 256 X 256 X 256 data set, any one element may contribute about 1/256 of the final alpha and color. In the slicing method, an element could contribute anywhere from 0 up to the final alpha and color used for that pixel. The problem is that sometimes the term “voxel” is used to describe both types of sampling. Care should be taken to realize that starting with DirectX 8, the slicing method, often called “Volume Texturing” is the only method supported. The idea is to reduce the volume data set to a reasonable size. With some minor modifications to the texturing hardware, the DirectX graphics API can expose high-performance volumetric rendering.

Up to this point, most of this section has focused on DXTN compressed surface formats. These formats work well for 2D textures. They are inefficient, however, when you are working with a volume data set. The inefficiency is due to the fact that volume data sets would be stored in separate surfaces that would require extra hardware cycles to access. To address this issue, DirectX 8 supports a set of Volume surface formats.

The idea is to take the volume slices and compress then using DXTN. Then, instead of storing the completed surfaces sequentially in memory, the DXTN data blocks are reordered. The reordering is done so that the small 4X4 texel blocks form data cubes. They can be 4X4X1, 4X4X2, 4X4X3, or 4X4X4. Note that the 4X4X1 ordering is exactly the same as that used in DXT1 through DXT5. The important point is:

Volume surfaces are slices of data that are compressed using DXTN and then reordered to account for the 3D locality of data. These reordered data structures are referred to by the FOURCC codes of DXV1,..., DXV5 (or just DXVN to describe the general case). Note that a DXV1 data structure would hold a set of reordered DXT1 surfaces, DXV2 would hold a set of DXT2 surfaces, and so on.

DXVN Details

A DXVN surface stored in the 1-deep arrangement contains one set of 4x4 DXTN subblocks (in effect it is just a DXTN surface). The DXVN 4x4x2 block format structure contains two 4x4 DXTN subblocks, one taken from each of two adjacent data slices. Using this method it is obvious that a DXVN 4x4x4 block format structure contains four 4x4 DXTN subblocks taken from 4 data slices. Note that in all cases the N in DXVN is used to match it to the corresponding DXTN type used for compression. (Note that DXTN blocks can be stored as 64 bits (color and 1-bit alpha, or 128 bits with additional alpha information.) So the DXVN subblocks will have the same possible sizes based on the type N. (That is, DXT1 and DXV1 use 64 bit subblocks, while DXT2,..,DXT5 and DXV2,..,DXV5 use 128 bit subblocks.)

Given a texel coordinate (u, v, p) where u {0,1,…,width-1}, v {0, 1, …, height-1}, and p {0, 1, …, depth-1}, the following can be used to compute the corresponding address of the compressed block and subblock in memory containing that texel. As mentioned above, the subblock format matches the existing DXTN format;

subblock_size = 8 (for DXT1)
subblock_size = 16 (for DXT2,...,DXT5)
block_size = MIN(p, 4) * subblock_size
horiz_stride = (width + 3) >> 2
planar_stride = ( (height + 3) >> 2) * horiz_stride
block_byte_address = block_size *
    ( (p >> 2) * planar_stride + (v >> 2) * horiz_stride + (u >> 2) )
subblock_byte_address = block_byte_address + ((p & 3) * subblock_size)


Motion Compensation

If two successive frames of video data display essentially the same picture, only shifted horizontally or vertically, then there is an enormous compression gain by simply shifting the first frame and then describing the other changes that happen in addition to that shift to arrive at the second frame. This is what motion compensation does.

Motion compensation is the final stage of the MPEG decode process and many display devices implement some level of support for this in hardware. In addition to motion compensation, some devices perform IDCT (Inverse Discrete Cosine Transformation) and other hardware functions that a software MPEG decoder can use to accelerate the decode process. The motion compensation device driver interface is flexible enough to handle these devices as well.

The input data to a software MPEG decoder is well defined. That is, if the decoder is designed for MPEG-2, the input is in MPEG-2 format. The output of the decoder is also well defined — uncompressed frame in a variety of formats. However, the interim formats between the software decoders and the display devices are not well defined, with many devices requiring their own proprietary data formats. Therefore, the motion compensation device driver interface is flexible and the interim formats are described as GUIDs. The display driver reports the GUIDs that represent the capabilities it supports, and the software decoder chooses the GUID which best matches its requirements.

To enable motion compensation functionality, the driver must do the following:

  • Implement a DdGetDriverInfo function and set the GetDriverInfo member of the DD_HALINFO structure to point to this function when DrvGetDirectDrawInfo is called. The driver's DdGetDriverInfo function must parse the GUID_MotionCompCallbacks GUID.
  • When DdGetDriverInfo is called with the GUID_MotionCompCallbacks GUID, fill in a DD_MOTIONCOMPCALLBACKS structure with the appropriate driver callbacks and flags set. The driver must then copy this initialized structure into the Microsoft® DirectDraw®-allocated buffer to which the lpvData member of the DD_GETDRIVERINFODATA structure points, and return the number of bytes written into the buffer in dwActualSize.

DirectX Video Acceleration is a technology that aids in the acceleration of digital video decoding processing. Please see DirectX Video Acceleration for more details about accelerating digital video decoding processing.


DirectX Video Acceleration

DirectX Video Acceleration makes use of the Motion Compensation callbacks provided in DirectDraw drivers for acceleration of digital video decoding processing, with support of alpha blending for such purposes as DVD subpicture support.

This section contains a description of the Motion Compensation device driver side of the DirectX VA interface. The following items refer to entries accessed through the DD_MOTIONCOMPCALLBACKS structure:

  1. At the start of the relevant processing, the device driver’s DdMoCompCreate is used to notify the driver that the software decoder will start using a video acceleration object.
  2. GUIDs received from IAMVideoAccelerator::GetVideoAcceleratorGUIDs originate from the device driver’s DdMoCompGetGUIDs.
  3. A call to the downstream input pin’s IAMVideoAccelerator::GetUncompFormatsSupported returns data from the device driver’s DdMoCompGetFormats.
  4. The DXVA_ConnectMode data structure from the decoder’s IAMVideoAcceleratorNotify::GetCreateVideoAcceleratorData is passed to the device driver's DdMoCompCreate.
  5. Data returned from IAMVideoAccelerator::GetCompBufferInfo originates from the device driver’s DdMoCompGetBuffInfo.
  6. Buffers sent using IAMVideoAccelerator::Execute are received by the device driver’s DdMoCompRender.
  7. Use of IAMVideoAccelerator::QueryRenderStatus invokes the device driver’s DdMoCompQueryStatus. A return code of DDERR_WASSTILLDRAWING from DdMoCompQueryStatus will be seen by the host decoder as a return code of E_PENDING from IAMVideoAccelerator::QueryRenderStatus.
  8. Data sent to IAMVideoAccelerator::BeginFrame are received by the device driver’s DdMoCompBeginFrame. A return code of E_PENDING is needed from DdMoCompBeginFrame in order for E_PENDING to be seen by the host decoder in response to IAMVideoAccelerator::BeginFrame.
  9. Data sent to IAMVideoAccelerator::EndFrame are received by the device driver’s DdMoCompEndFrame.
  10. At the end of the relevant processing, the device driver’s DdMocompDestroy is used to notify the driver that the current video acceleration object will no longer be used, so that the driver can perform any necessary cleanup.

Please see the DirectX Video Acceleration topic in the DirectShow portion of the DirectX SDK documentation for more detailed information about DXVA.


Gamma Control

Beginning with DirectX 6.0, DirectDraw offers applications a way of specifying gamma tables that are applied to the DirectDraw device. Gamma ramp support was added to Windows 98/Me so that applications can modify the device color mapping in HiColor and TrueColor modes. Driver writers are encouraged to add this facility to their drivers, because it can be used by both DirectDraw and advanced gamma-correcting software.

Note Gamma ramp capabilities are implemented as part of the GDI display driver, not the 32-bit HAL. In addition, the information provided here applies only to Windows 98/Me, but not to Windows 2000 and later.

DirectDraw calls the driver through the SetDeviceGammaRamp SDK function. If the call is successful, DirectDraw sets the DDCAPS2_PRIMARYGAMMA flag in the dwCaps2 member of the DDCORECAPS structure.

Your display driver needs to perform the following steps:

  1. Set the C1_GAMMA_RAMP flag in the dpCaps1 member of the GDIINFO structure. C1_GAMMA_RAMP and GDIINFO are both defined in the Windows DDK, in file \winddk\inc\win_me\inc16\gdidefs.inc.
  2. Write an OEMGammaRamp function, which is prototyped as follows (you do not need to call it OEMGammaRamp; this is a pseudoname used in this documentation):
cProc   OEMGammaRamp,<FAR,PUBLIC,WIN,PASCAL>,<es,si,di>
        parmD   lpDev
        parmW   fGetSet          ;determine get/set flag
        parmD   lpGammaRamp      ;pointer to a set of three arrays

The lpDev parameter is used in all other exports and is documented elsewhere.

The fGetSet parameter determines whether you should return the current gamma ramp or set a new one. If fGetSet == 0, then set the gamma ramp specified in lpGammaRamp; otherwise, return the current gamma ramp in lpGammaRamp.

The lpGammaRamp parameter is a pointer to an array of 768 16-bit WORDs containing the new gamma ramp values, or a buffer to return the current values (depending on the value of fGetSet). The first 256 entries define the red gamma values, the next 256 define the green gamma values, and the last 256 entries define the blue gamma values. The gamma values range between 0 and 65535.

  3. Export the OEMGammaRamp function as ordinal 32 in the display driver .DEF file.

The OEMGammaRamp function returns a WORD containing either 1 for success or 0 for an error. This value is returned directly to the application. The function cannot return -1 for simulation; there is no simulation.

Note DIBENG does not implement this function, so do not try to pass it on.

Your driver must ensure that this device driver interface is safe to call between BeginScene and EndScene calls. Do not let the system stall waiting for the 3-D hardware. If necessary, fail the call.

DirectX 6.0 handles saving and restoring the gamma values for full-screen applications; your driver should not do this. However, your driver (and miniVDD) needs to restore the gamma ramp values when an MS-DOS box is deactivated (ResetHiResMode). Your driver also needs to restore the gamma values to appropriate defaults when a full-screen VM gets the focus.

Your driver does not need to set the DDCAPS2_PRIMARYGAMMA flag. DirectDraw will detect your driver's support for OEMGammaRamp and set this flag automatically.

The DDCAPS2_CANCALIBRATEGAMMA flag is not directly relevant to display drivers. This bit means that DirectDraw can modify gamma ramp tables to account for the physical responses of the display subsystem. The driver may see modified gamma ramps, but it needs to take no special action (and in fact will not have any way to know that these ramps have been modified).


Implementing Gamma Ramp Support in a Microsoft Windows Display Driver

OEMs and IHVs who write display drivers can provide a more accurate and positive end-user experience by incorporating support for downloadable gamma ramps. Reasons to support downloadable gamma ramps include:

  • User enjoyment ISVs who create games want the user to have a consistent visual experience regardless of the system being used. Without color management and downloadable gamma ramps, the user is forced to tweak brightness settings, contrast settings, or color adjustments, while hoping to find settings that provide an appealing color environment. Top-tier game ISVs have asked for programmable gamma ramps so their games can appear as intended, including flare effects in games such as the red flash that occurs when the player gets hit in Quake.
  • Accurate online color representation With the strong growth of e-commerce, companies making products available through online catalogs will require color management capabilities so that online customers can see a product's true colors, minimizing losses due to returns.
  • Color consistency across devices Users want the output of their color images to look very similar to the image on the monitor. Graphics boards with downloadable gamma ramps are a much-needed component of a good color management system.

To improve the customer's color experience on the PC, downloadable gamma ramp support is a requirement for the Microsoft® Windows® Logo Program for hardware. (See the guidelines in PC 98:14.11, "Adapter supports downloadable RAMDAC entries for image color matching.") Both graphics board drivers and the graphics adapters are required to support downloadable gamma ramps, so the original level of red, green, and blue color components for all pixels in a frame buffer can be replaced with calibrated values.

As systems evolve and need to use both 2D and 3D graphics for applications, they will require multiple gamma ramps to provide an enjoyable and repeatable experience. Traditional 3D has a gamma of 1.0, while most images have a range of gammas from 1.8, for Macintosh and Adobe PhotoShop, to 2.2, for standard red, green, blue, (sRGB). When these are mixed on the multimedia desktop, at least two gammas are needed. Microsoft encourages vendors to support multiple programmable gamma ramps.


DirectDraw Support for Gamma Ramps

To allow easier software support for downloadable gamma ramps on the Microsoft Windows 98/Me and Windows 2000 and later operating systems, a gamma interface called IDirectDrawGammaControl has been added to Microsoft DirectDraw®. Available in Microsoft DirectX® 6.0 and later versions, this interface enables game developers to manipulate gamma ramp levels and to tell the system what the perceived gamma on the primary surface in full screen exclusive mode should be. As a result, applications can quickly change the red, green, and blue color components of pixels before they are sent to the digital-to-analog converter (DAC) for display.

You can use either the Microsoft Win32® application programming interface (API) or the IDirectDrawGammaControl interface. There are three significant differences between SetDeviceGammaRamp and the DirectDraw API:

  • SetDeviceGammaRamp does not allow all gamma ramps. It checks the gamma ramp; if it is too complex, such as the red flash when the player is shot in Quake, it rejects the gamma ramp.
  • SetDeviceGammaRamp will not currently make use of a gamma calibrator. This may change in future versions of Image Color Management (ICM), but for Windows 2000, only the DirectDraw API supports the gamma calibrators.
  • The gamma ramp set by DirectDraw is guaranteed to clean up correctly when the application is closed. If an application calls SetDeviceGammaRamp and does not restore the old gamma ramp, it is not automatically cleaned up.

The existing gamma entry points are already used by GetDeviceGammaRamp and SetDeviceGammaRamp. Therefore, the display driver doesn't need to do anything special to support this new interface, as long as it already supports the Win32 Get/SetDeviceGammaRamp functions.

In addition to getting and setting gamma ramps, the new DirectDraw interface allows the new gamma ramp to be calibrated, provided that a gamma calibrator is installed. The mechanism that DirectDraw uses to register and communicate with the gamma calibrator is an interim mechanism that will be changed in future releases.

DirectDraw looks for an installed software calibrator and passes the gamma value to the software calibrator; the software calibrator in turn adjusts the gamma ramp according to the measured response of the monitor. The calibrator passes the gamma ramp back to DirectDraw, which passes it to the SetDeviceGammaRamp device driver interface (DDI). The result is that the game looks as intended.

For DirectDraw to use the gamma calibrator, the calibrator must register itself with DirectDraw using a registry key; DirectDraw will call it if the application wants the gamma ramp to be calibrated.

In the future, both the method by which DirectDraw communicates with the gamma calibrator, through the DDI, and the method gamma calibrators use to register themselves in the registry will change. But every part of the DirectDraw API is permanent.

ICM is the color management system in Windows; all system level color management should be handled by ICM. For this reason, downloadable gamma ramp support will be rolled into ICM in the future, making current solutions for gamma calibrators obsolete. Until such time, we have provided a method by which applications can take advantage of the installed base of software calibrators and graphics adapters that support downloadable gamma ramps.


Using Gamma Controls

To determine whether a specific graphics card and monitor support gamma calibration, call IDirectDraw7::GetCaps and examine the dwCaps2 member of the associated DDCAPS structure. If the DDCAPS2_CANCALIBRATEGAMMA capability flag is present, then gamma calibration is supported.

You can retrieve the IDirectDrawGammaControl interface by querying the surface with the IID_IDirectDrawGammaControl reference identifier. The IDirectDrawGammaControl::GetGammaRamp method retrieves the red, green, and blue gamma ramps for the primary surface.


Setting and Retrieving Gamma Ramp Levels

Gamma ramp levels are effectively lookup tables that DirectDraw uses to map the frame buffer color components to new levels that will be displayed. You set and retrieve ramp levels for the primary surface by calling the IDirectDrawGammaControl::SetGammaRamp and IDirectDrawGammaControl::GetGammaRamp methods.

The first parameter is the pointer to the IDIRECTDRAWGAMMACONTROL structure. The next parameter specifies the flags, which for the IDirectDrawGammaControl::GetGammaRamp call must be 0. For the IDirectDrawGammaControl::SetGammaRamp call, this parameter may be DDSGR_CALIBRATE. If this flag is set, then DirectDraw calibrates the gamma ramp; otherwise, it sets the gamma ramp without calibrating it. The last parameter is the pointer to the DDGAMMARAMP structure that contains three 256-element arrays of WORDs, one array each to contain the red, green, and blue gamma ramps.

Games that use this function should always provide values ranging between 0 and 0xFFFF. DACs vary in resolution; DACs that support fewer than 16 bits will ignore the least significant bits of the gamma ramp entries.

The gamma ramp values that the application calls should range between 0 and 0xFFFF, just as in the SetDeviceGammaRamp and GetDeviceGammaRamp calls. The driver may need to perform some additional converting. For all, the covered range is the same with only a difference in accuracy.


DDIs and APIs Related to Gamma Ramp Support

To add gamma ramp support to your Windows 98/Me driver:

  1. Export DDIGammaRamp as ordinal 32.
  2. Set the C1_GAMMA_RAMP bit in dpCaps1.
  3. Implement DDIGammaRamp.

The functions, methods, and structure in the following list play roles in gamma ramp support.

DDIGammaRamp

GetDeviceGammaRamp

SetDeviceGammaRamp

IDirectDrawGammaControl::GetGammaRamp

IDirectDrawGammaControl::SetGammaRamp

DDGAMMARAMP


DDIGammaRamp

DDIGammaRamp sets the gamma ramp on direct color display boards. The export ordinal for this function is 32.

BOOL
  DDIGammaRamp(
    LPDEVICE  lpDev,
    BOOL  fGetSet,
    LPARAM  lpGammaRamp
    );

Parameters

lpDev
Points to the physical device.
fGetSet
Specifies whether the gamma ramp will be read from or written to. A value of TRUE denotes that the gamma ramp will be written to; a value of FALSE denotes it will be read from.
lpGammaRamp
Points to a set of three arrays, each consisting of 256 WORD (16 bit) elements. These arrays are the mapping between RGB values in the frame buffer and DAC values. The first array holds the red values, the second holds the green values, and the third holds the blue values.

Return Value

DDIGammaRamp returns TRUE if the function is successful. Otherwise, it returns NULL.

Comments

For display adapters that only have 8-bit DACs, the high byte of a given WORD is to be loaded. For adapters that have 12-bit DACs, the high-order 12 bits are used. For 16-bit DACs, the entire WORD is loaded.

Direct color display modes do not use color lookup tables to translate between pixel values and colors, the pixel value is fed directly to the DACs. The direct color modes are usually 16, 24, or 32 bits deep. The display adapter must have hardware to support loadable gamma ramps for the driver to support this function. If the driver does support this function, it must also set the C1_GAMMA_RAMP bit in dpCaps1.

The setting of the display gamma ramp acts globally across all tasks. The gamma ramp is not maintained on a per-application basis. Once set, the gamma ramp does not change until the next set call made by an application. It is expected that users will run a calibration utility to set the gamma ramps when they boot Windows. Arbitrary applications must not set it independently of each other.


GetDeviceGammaRamp

The GetDeviceGammaRamp function gets the gamma ramp on direct color display boards whose drivers support downloadable gamma ramps in hardware.

BOOL WINAPI
  GetDeviceGammaRamp(
    IN HDC  hDC,
    OUT LPVOID  lpRamp
    );

Parameters

hDC
Specifies the device context of the direct color display board in question.
lpRamp
Points to a buffer where the function can place the current gamma ramp of the color display board. The gamma ramp is specified in three arrays of 256 WORD elements each, which contain the mapping between RGB values in the frame buffer and digital-analog-converter (DAC) values. The sequence of the arrays is red, green, blue.

Return Value

GetDeviceGammaRamp returns TRUE if it succeeds, and FALSE otherwise.

Comments

Direct color display modes do not use color lookup tables and are usually 16-, 24-, or 32-bit. Not all direct color video boards support loadable gamma ramps. GetDeviceGammaRamp succeeds only for devices with drivers that support downloadable gamma ramps in hardware.


SetDeviceGammaRamp

SetDeviceGammaRamp sets the gamma ramp on direct color display boards whose drivers support downloadable gamma ramps in hardware.

BOOL WINAPI
  SetDeviceGammaRamp(
    IN HDC  hDC,
    IN LPVOID  lpRamp
    );

Parameters

hDC
Specifies the device context of the direct color display board in question.
lpRamp
Points to a set of three arrays, each consisting of 256 WORD (16 bit) elements. These arrays are the mapping between RGB values in the frame buffer and DAC values. The first array holds the red values, the second holds the green values, and the third holds the blue values.

Return Value

SetDeviceGammaRamp returns TRUE if it succeeds, and FALSE otherwise.

Comments

Direct color display modes do not use color lookup tables and are usually 16-, 24-, or 32-bit. Not all direct color video boards support loadable gamma ramps. SetDeviceGammaRamp succeeds only for devices with drivers that support downloadable gamma ramps in hardware.


IDirectDrawGammaControl::GetGammaRamp

The IDirectDrawGammaControl::GetGammaRamp method retrieves the red, green, and blue gamma ramps for the primary surface.

HRESULT
  IDirectDrawGammaControl::GetGammaRamp(
    THIS_
    DWORD  dwFlags,
    LPDDGAMMARAMP  lpRampData
    ) PURE;

Parameters

dwFlags
Is not currently used and is set to 0.
lpRampData
Address of a DDGAMMARAMP structure to be filled with the new red, green, and blue gamma ramp entries. Each array maps color values in the frame buffer to the color values that will be passed to the DAC.

Return Value

IDirectDrawGammaControl::GetGammaRamp returns DD_OK if it succeeds in retrieving the gamma ramp. If this method fails, it returns one of the following values:

  • DDERR_EXCEPTION
  • DDERR_INVALIDOBJECT
  • DDERR_INVALIDPARAMS


IDirectDrawGammaControl::SetGammaRamp

The IDirectDrawGammaControl::SetGammaRamp method sets the red, green, and blue gamma ramps for the primary surface.

HRESULT
  IDirectDrawGammaControl::SetGammaRamp(
    THIS_
    DWORD  dwFlags,
    LPDDGAMMARAMP  lpRampData
    ) PURE;

Parameters

dwFlags
Indicates whether gamma calibration is desired. Set this parameter to DDSGR_CALIBRATE to request that the calibrator adjust the gamma ramp according to the physical properties of the display, making the result identical on all systems. If calibration is not needed, set this parameter to 0.
lpRampData
Address of a DDGAMMARAMP structure that contains the new red, green, and blue gamma ramp entries. Each array maps color values in the frame buffer to the color values that will be passed to the DAC.

Return Value

IDirectDrawGammaControl::SetGammaRamp returns DD_OK if it succeeds in setting the gamma ramp. If this method fails, it returns one of the following values:

  • DDERR_EXCEPTION
  • DDERR_INVALIDOBJECT
  • DDERR_INVALIDPARAMS
  • DDERR_OUTOFMEMORY

Comments

IDirectDrawGammaControl::SetGammaRamp is a DirectX 6.0 API.

Not all systems support gamma calibration. To determine whether gamma calibration is supported, call IDirectDraw7::GetCaps, and examine the dwCaps2 member of the associated DDCAPS structure after the method returns. If the DDCAPS2_CANCALIBRATEGAMMA capability flag is present, then gamma calibration is supported.

Calibrating gamma ramps incurs some processing overhead and should not be used frequently.

Including the DDSGR_CALIBRATE flag in the dwFlags parameter when running on systems that do not support gamma calibration will not cause this method to fail. The method succeeds, setting new gamma ramp values without calibration.


DDGAMMARAMP

The DDGAMMARAMP structure contains red, green, and blue ramp data for the IDirectDrawGammaControl::GetGammaRamp and IDirectDrawGammaControl::SetGammaRamp methods.

typedef struct _DDGAMMARAMP {
  WORD  red[256];
  WORD  green[256];
  WORD  blue[256];
} DDGAMMARAMP, FAR * LPDDGAMMARAMP;

Members

red, green, blue
Are arrays of 256 WORD elements that describe the red, green, and blue gamma.


Mapping Gamma Ramp Values to RAMDACs

The RAMDAC uses the buffer (or gamma ramp) as a lookup table before mapping gamma ramp data into the most significant bits of the words. The gamma ramp always expects values in the range 0x0000 to 0xFFFF.

ICM 3.0: The Long-term Solution

As a long-term solution for gamma ramp support, Microsoft plans to add the functionality of the DirectDraw call into the next version of ICM, version 3.0. DirectDraw will continue to support this feature, but when the next version of ICM is complete, ICM will be used for this function instead of the current method of loading the gamma calibrator. Applications won't be affected, but gamma calibrators will.

ICM will be able to control the gamma ramp process without allowing other applications to intercept the gamma ramp adjustment; this will make it easier to display accurate gamma ramps.


Windows Millennium Hibernate Feature

In the process of developing the Windows® Millennium (Windows Me) hibernate feature, Microsoft found that many display adapters did not correctly support the D3 state. Some display adapters had problems in the BIOS, others had drivers that did not correctly restore register set, and others relied on Vaux current to maintain the state.

To distinguish newer display adapter drivers and devices that have been modified and tested to support hibernation, Windows Me has added a new flag to Get_Adapter_Power_State_Caps and Set_Adapter_Power_State calls. If a system's display adapter drivers do not export these calls or do not implement the new flag, the system will not be placed in S4 (hibernate) state, and the hibernation feature UI will be disabled.

Shortly after the display driver is loaded, Windows Me tests to determine whether the driver has exported the Get_Adapter_Power_State_Caps function. If this function is exported, Windows Me will call this function and examine its return value to determine the power states that the device supports. Drivers indicate supported power states by ORing one or more of the following flags and returning this value in the Get_Adapter_Power_State_Caps call.

Flag | Value (hexadecimal)
CM_POWERSTATE_D0 | 0x00000001
CM_POWERSTATE_D1 | 0x00000002
CM_POWERSTATE_D2 | 0x00000004
CM_POWERSTATE_D3 | 0x00000008
CM_POWERSTATE_HIBERNATE | 0x00000010

Note This implementation is required for drivers to accurately indicate supported power states.

Do not indicate support of CM_POWERSTATE_D3 unless your device has been thoroughly tested on a bus that loses both Vcc and Vaux power when the system is placed in S3. Likewise, do not set the CM_POWERSTATE_HIBERNATE flag unless your device has undergone thorough hibernation testing.

If the display driver does not export the Get_Adapter_Power_State_Caps call or does not set the CM_POWERSTATE_HIBERNATE bit in the return value, Windows Me will disable the hibernation feature. Because older Windows 98 display drivers did not implement the CM_POWERSTATE_HIBERNATE flag, Windows Me will disable hibernation for these older devices and drivers.

Windows Me also uses the same bits for the Set_Adapter_Power_State call. Before placing the system in a new power state, Windows Me calls the driver's Set_Adapter_Power_State function with the appropriate CM_POWERSTATE_HIBERNATE flag. Before returning from this call, drivers must perform any necessary actions to prepare their device to enter the new power state.

For example, if Set_Adapter_Power_State is called with either CM_POWERSTATE_D3 or CM_POWERSTATE_HIBERNATE flags, the driver must save its device's register values to prepare for power loss. Subsequently, when power is restored, Windows Me will call Set_Adapter_Power_State with CM_POWERSTATE_D0. In response, the driver must restore its device's registers so the device is returned to the same state it was in before the sleep or hibernate request.

In addition, drivers must be designed to handle the Set_Adapter_Power_State CM_POWERSTATE_D0 command while resuming even though the BIOS might have initiated a re-POST or other display activity. A device must not enable its IRQ until the Set_Adapter_Power_State CM_POWERSTATE_D0 command is received. In other words, do not allow a display device to generate interrupts before its driver receives the Set_Adapter_Power_State CM_POWERSTATE_D0 command. Although the system can reflect display adapter interrupts to real mode while booting, interrupts cannot be reflected to real mode while resuming because Plug and Play might have changed the interrupt.

Likewise, regardless of what the BIOS does to the display adapter during resume, the driver is responsible for putting the device back into the same state it was in before it received the Set_Adapter_Power_State CM_POWERSTATE_D3 command.

Windows Millennium Power Management Configuration


SET_ADAPTER_POWER_STATE

This topic applies only to Windows Me.

The SET_ADAPTER_POWER_STATE function saves and restores whatever state is necessary to place the device into the power state specified in the PowerState parameter.

DWORD
  __cdecl SetAdapterPowerState(
    DEVNODE  devnode,
    DWORD  PowerState
    );

Parameters

devnode
Specifies the device node for the device.
PowerState
Specifies the power state into which to place the device. This parameter can be one those shown in the following table. Note that the CM_POWERSTATE_HIBERNATE flag is new, and is used to indicate support for the Hibernate feature.
State | Value (hexadecimal)
CM_POWERSTATE_D0 | 0x00000001
CM_POWERSTATE_D1 | 0x00000002
CM_POWERSTATE_D2 | 0x00000004
CM_POWERSTATE_D3 | 0x00000008
CM_POWERSTATE_HIBERNATE | 0x00000010

Return Value

SET_ADAPTER_POWER_STATE returns one of the following values:

Value | Description
CR_DEFAULT | Operating system should perform its default action for the power state transition. (That is, re-POST for D3 to D0. Otherwise, it should do nothing.) This should also be returned if PowerState is something other than one of the four CM_POWERSTATE_DN values.
CR_SUCCESS | Power state was changed successfully. No further action needs to be taken by the operating system.

Comments

The driver remains in memory at all times. Display memory contents do not need to be saved because the operating system resets the display mode during a return to the D0 state.

The default action defined by CR_DEFAULT is to re-POST the device if it is going from D3 to D0. Any other state transition results in no action. If the display driver is capable of initializing the device from a power-off without a POST, then this function returns CR_SUCCESS during the D3 to D0 transition.

SET_ADAPTER_POWER_STATE

Entry | Meaning
ESP+4 | Device node.
ESP+8 | Power state to set. One of: CM_POWERSTATE_D0 CM_POWERSTATE_D1 CM_POWERSTATE_D2 CM_POWERSTATE_D3 CM_POWERSTATE_HIBERNATE

Exit | Meaning
EAX | CR_DEFAULT Routine did nothing. CR_SUCCESS Routine set the appropriate power state for the adapter/display chip set.


GET_ADAPTER_POWER_STATE_CAPS

This topic applies only to Windows Me.

The GET_ADAPTER_POWER_STATE_CAPS function should return the power states supported by the display adapter.

DWORD
  cdecl GetAdapterPowerStateCaps(
    DEVNODE  devnode
    );

Parameters

devnode
Specifies the device node for the device.

Return Value

GET_ADAPTER_POWER_STATE_CAPS returns a bitmask containing an ORed combination of the following flags. Note that the CM_POWERSTATE_HIBERNATE flag is a new flag that is used to indicate support for the Hibernate feature.

Flag | Value (hexadecimal)
CM_POWERSTATE_D0 | 0x00000001
CM_POWERSTATE_D1 | 0x00000002
CM_POWERSTATE_D2 | 0x00000004
CM_POWERSTATE_D3 | 0x00000008
CM_POWERSTATE_HIBERNATE | 0x00000010


Writing a Windows MiniVDD for a Secondary Display

This topic applies only to Windows Me.

The main job of a miniVDD is VGA virtualization. Secondary displays are not VGA devices, however, so most miniVDD code is not needed for a secondary display. You should use a secondary miniVDD only if you really need it.

The miniVDD for a secondary display is stored in the registry as Minivdd2. When a secondary miniVDD is used, the operating system does not load cardVDD2. Only a single copy of the VxD is used.

The driver should implement PNP_NEW_DEVNODE and should use CM_Set_Driver_Private_DWORD for instance data. A user-mode (ring 3) driver must use VDD_REGISTER_DISPLAY_DRIVER_INFO to communicate with the miniVDD.

VDD_Get_DisplayINFO gets the device node handle and uses the device node to get its resource assignment. On secondary devices, DEVICE_IS_NOT_VGA is set in diInfoFlags.

Do not hook VGA functions on non-VGA devices. Only the following miniVDD calls, listed in alphabetic order, should be hooked:

  • DISPLAY_DRIVER_DISABLING
  • GET_ADAPTER_POWER_STATE_CAPS
  • GET_MONITOR_POWER_STATE_CAPS
  • GET_NUM_UNITS
  • GET_TOTAL_VRAM_SIZE
  • MAKE_HARDWARE_NOT_BUSY
  • POST_CRTC_MODE_CHANGE
  • PRE_CRTC_MODE_CHANGE
  • PRE_INT_10_MODE_SET
  • REGISTER_DISPLAY_DRIVER
  • SET_MONITOR_POWER_STATE
  • TURN_VGA_OFF
  • TURN_VGA_ON
  • VESA_CALL_POST_PROCESSING
  • VESA_SUPPORT


Interface Between BaseVDD/MiniVDD/Display Drivers

This topic applies only to Windows Me.

The following table indicates the functions that must be supported by each display driver/miniVDD for the primary and secondary display adapters or usable services.

MiniVDD Functions

baseVDD —> miniVDD

No. | Function |  | Pri | Sec | Notes
1 | REGISTER_DISPLAY_DRIVER | Interface between miniVDD and driver | 2 | 2 |
2 | PRE_HIRES_TO_VGA | Switch to core graph | 1 | 3 |
3 | SAVE_REGISTERS | Save registers | 2 | 3 |
4 | RESTORE_REGISTERS | Restore registers | 2 | 3 |
5 | ENABLE_TRAPS | Enable I/O traps | 2 | 3 |
6 | DISABLE_TRAPS | Disable I/O traps | 2 | 3 |
7 | DISPLAY_DRIVER_DISABLING | Disable display | 1 | 1 |
8 | ENABLE_ACCELERATER | Enable display | 1 | 3 |
9 | DISABLE_ACCELERATER |  | 3 | 3 | Not Used
10 | CHECK_UPDATE |  | 3 | 3 | Not Used
11 | CHECK_WINDOWED |  | 3 | 3 | Not Used
12 | ACC_VBE_PM | VBE/PM | 2 | 2 |
13 | ACC_VBE_DDC | VBE/DDC | 2 | 2 |
14 | ACC_INT_10 | ESA BIOS (VGA BIOS) | 4 | 3 |
15 | ACC_GET_CAPABILITIES | Accelerator BIOS | 4 | 3 |
16 | ACC_GET_EXT_MODE_INFO | Accelerator BIOS | 4 | 3 |
17 | ACC_GET_FLAT_SELECTOR | Accelerator BIOS | 4 | 3 |
18 | ACC_ENABLE_BIOS | Accelerator BIOS | 4 | 3 |
19 | ACC_DISABLE_BIOS | Accelerator BIOS | 4 | 3 |
20 | ACC_SET_PALETTE | Accelerator BIOS | 4 | 3 |
21 | ACC_GET_PALETTE | Accelerator BIOS | 4 | 3 |
22 | ACC_SET_CURSOR | Accelerator BIOS | 4 | 3 |
23 | ACC_SHOW_CURSOR | Accelerator BIOS | 4 | 3 |
24 | ACC_HIDE_CURSOR | Accelerator BIOS | 4 | 3 |
26 | ACC_GET_CURSOR_POS | Accelerator BIOS | 4 | 3 |
27 | GET_NUM_UNITS | Obtain number of monitor units available for connection | 2 | 2 | New Feature (not yet supported)
28 | SET_ADAPTER_POWER_STATE |  | 2 | 2 | New Feature (not yet supported)
29 | GET_ADAPTER_POWER_ STATE_CAPS |  | 2 | 2 | New Feature
30 | SET_MONITOR_POWER_STATE |  | 2 | 2 | New Feature
31 | GET_MONITOR_POWER_ STATE_CAPS |  | 2 | 2 | New Feature
32 | ET_MONITOR_INFO |  | 2 | 2 | New Feature
33 | I2C_OPEN |  | 2 | 2 | New Feature
34 | I2C_ACCESS |  | 2 | 2 | New Feature
35 | GPIO_OPEN |  | 2 | 2 | New Feature
36 | GPIO_ACCESS |  | 2 | 2 | New Feature
37 | COPYPROTECTION_ACCESS |  | 2 | 2 | New Feature
1: Support is necessary 2: Support may be necessary 3: Support is unnecessary (not in use) 4: Necessary for accelerator BIOS support (this function may not be supported in the future)

Protected Mode API Functions

Display driver (Windows kernel) —> baseVDD

The following miniVDD-related protected mode API call interface will be changed partially.

Display drivers to be created in the future must follow these guidelines.

Multimonitor support does not function — even if a candidate for the secondary display adapter exists — if a display driver that does not meet the following calling guidelines is set as the primary. (nor can it be used as a secondary.

No | Function |  | Pri | Sec | Notes
1 | VDD_DRIVER_REGISTER | Register VDD driver | 1 | 1 |
2 | VDD_DRIVER_UNREGISTER | Unregister VDD driver | 1 | 1 |
3 | VDD_SAVE_DRIVER_STATE |  | 3 | 3 | Not Used
4 | VDD_REGISTER_DISPLAY_ DRIVER_INFO | Interface between miniVDD and driver | 2 | 2 |
5 | VDD_REGISTER_SSB_FLAGS |  | 3 | 3 | Not Used
6 | VDD_GET_DISPLAY_CONFIG | Obtain display settings | 2 | 2 |
7 | VDD_PRE_MODE_CHANGE |  | 3 | 3 | Not Used
8 | VDD_POST_MODE_CHANGE |  | 3 | 3 | Not Used
9 | VDD_SET_USER_FLAGS |  | 3 | 3 | Not Used
10 | VDD_SET_BUSY_FLAG_ADDR |  | 3 | 3 | Not Used
11 | VDD_VBE_PM | Power management (—> ACC_VBE_PM) | 2 | 2 |
12 | VDD_ENABLE | Resource control | 3 | 3 | New Feature
13 | VDD_GETMEMBASE | Obtain memory address | 3 | 3 | New Feature
14 | VDD_OPEN | Open device | 2 | 2 | New Feature
15 | VDD_CLOSE | Close device | 2 | 2 | New Feature
16 | VDD_OPEN_KEY | Open settings key | 2 | 2 | New Feature
17 | VDD_SET_POWER_STATE | Power management (—> ACC_VBE_PM) | 2 | 2 | New Feature
1: Support is necessary 2: Can be used 3: Cannot be used

VDD Service Functions

miniVDD —> baseVDD

No | Function | Pri | Sec | Notes | Notes
1 | VDD_Get_Special_VM_IDs | Obtain Message VM ID | 1 | 1 |
2 | VDD_Register_Mini_VDD | Register miniVDD | 1 | 1 | Modified
3 | VDD_Install_IO_Handler | I/O trap | 3 |  |
4 | VDD_Install_Mult_IO_Handlers | I/O trap | 3 |  |
5 | VDD_Enable_Local_Trapping | I/O trap | 3 |  |
6 | VDD_Disable_Local_Trapping | I/O trap | 3 |  |
7 | Test_Vid_VM_Handle | Display owner VM check | 1 | 1 |
8 | VDD_Trap_Suspend | Interrupt process | 1 | 1 |
9 | VDD_Map_VRAM | Accelerator BIOS | 3 | 2 |
1: Can be used 2: Cannot be used 3: Cannot be used due to possible discontinuation of support in the future (supported in Windows 98 for compatibility with current drivers)


32-bit Code Samples

This section applies only to Windows 98/Me.

This section provides samples of 32-bit code, including 32-bit functions, 32-bit callback routines, and 32-bit structures.

32-bit Function Samples

32-bit Callback Samples

32-bit Structure Samples


32-bit Function Samples

This topic applies only to Windows 98/Me.

The following helper functions should be implemented in the 32-bit portion of the HAL:

buildDDHALInfo32

DllMain

DPF

DriverInit

getDisplayDuration

updateFlipStatus


buildDDHALInfo32

This topic applies only to Windows 98/Me.

The buildDDHALInfo32 function sample shows how to collect the information about the 32-bit HAL for DirectDraw in the shared memory window with the 16-bit portion of the HAL.

The 16-bit analog to buildDDHALInfo32 is buildDDHALInfo16. The 16-bit version shows how to fill in information that is specific to the HAL table but can only be obtained from the 16-bit side, such as from the mode table.

The sample buildDDHALInfo32 function included here shows how to fill in the function names, capabilities, and pointers needed by DirectDraw to drive the display card. These are filled in both at initialization time and during mode changes. The buildDDHALInfo32 function is called to modify the structures in the shared 16- and 32-bit memory window (DDHALINFO) that resides above the 2 gigabyte boundary and is accessible from 16- and 32-bit pointers. All of the HAL information is stored in the DDHALINFO structure so it can be accessed easily by DirectDraw. Delete any HAL entries you don't need, and instead put NULL in the entry table.

In this sample, the main driver, surface, and palette callback function names are filled in with aliases of their respective structures (cbDDCallbacks, cbDDSurfaceCallbacks, and cbDDPaletteCallbacks). The DirectDraw callbacks used in this sample are WaitForVerticalBlank32 and GetScanLine32. Flags are set in the dwFlags member of the cbDDCallbacks structure alias to indicate that they are implemented in 32-bit code. For example, the DDHAL_CB32_WAITFORVERTICALBLANK flag indicates that a WaitForVerticalBlank callback is implemented in 32-bit code. If it were implemented in 16-bit code, the name of the 16-bit function would be filled in by buildDDHALInfo16 and the flag that specified it as 32-bit implementation would be left out.

This buildDDHALInfo32 sample also fills in the DirectDrawSurface callbacks with the following functions: Blt32, Flip32, Lock32, GetBltStatus32, and GetFlipStatus32. As with WaitForVerticalBlank and GetScanLine32 in the previous paragraph, each of these functions is flagged as a 32-bit implementation in the dwFlags member. If, for some reason, one or more of these was implemented in 16-bit code, the 32-bit flag would be left out for that function and the buildDDHALInfo16 function would fill in the name of the 16-bit function.

In this sample, there are no DirectDrawPalette callbacks to fill in, but the size of the structure is still filled in and the dwFlags member is explicitly set to 0. Then the DDHALINFO structure is filled in with all information of the above callback structures.

The FourCC codes (four character codes for color space conversions) are filled out in the order of preference. The one with the highest quality for your device should go first, and so on (see DirectDraw and Color Space Conversion for a description of common FourCC code formats). The driver instance (hInstance) is filled in with the instance of the 32-bit DLL. The pdevice parameter is the pointer to the device structure for the display miniport driver.

All of the capabilities supported by this HAL are filled in the dwCaps member of the DDCORECAPS structure included in the DDHALINFO structure. In this sample, DDCAPS_BLT indicates there is a blitter so the HAL can blt, DDCAPS_BLTQUEUE indicates the HAL is capable of queuing up blts, DDCAPS_BLTCOLORFILL indicates the HAL can do color fills, and DDCAPS_COLORKEY means the HAL can do transparent blts. (For a list of the capabilities flags, see the DDCORECAPS structure.)

As far as surface capabilities go, the sample indicates the driver can support flipping, off screen plain, and primary surfaces (DDSCAPS_FLIP, DDSCAPS_OFFSCREENPLAIN, DDSCAPS_PRIMARYSURFACE). The color key capabilities include source blt and destination blt.

The supported raster operations (ROPs) are filled in (see the Win32 SDK for a list of standard raster operations) and the display mode (indicated by the dwModeIndex parameter of the DDHALINFO structure) is temporarily set to DDUNSUPPORTEDMODE (buildDDHALInfo16 fills this in for real). The required alignments of the scan lines (specified in terms of bits) for each kind of memory are filled in.

/*
 * buildDDHALInfo32
 *
 * Build a DDHALInfo structure
 */
static BOOL buildDDHALInfo32()
{
    /*
     * Modify the structures in our shared window with the 16-bit driver
     */
    #define cbDDCallbacks        pDriverData->DDCallbacks
    #define cbDDSurfaceCallbacks pDriverData->DDSurfaceCallbacks
    #define cbDDPaletteCallbacks pDriverData->DDPaletteCallbacks
    #define ddHALInfo            pDriverData->HALInfo

    /*
     * Fill in the main driver callbacks
     */
    memset(&cbDDCallbacks, 0, sizeof(DDHAL_DDCALLBACKS));
    cbDDCallbacks.dwSize                = sizeof(DDHAL_DDCALLBACKS);
    cbDDCallbacks.WaitForVerticalBlank  = WaitForVerticalBlank32;
    cbDDCallbacks.GetScanLine           = GetScanLine32;
    cbDDCallbacks.dwFlags               =
                        DDHAL_CB32_WAITFORVERTICALBLANK |
                        DDHAL_CB32_GETSCANLINE;

    /*
     * Fill in the surface callbacks
     */
    memset(&cbDDSurfaceCallbacks, 0, sizeof(DDHAL_DDSURFACECALLBACKS));
    cbDDSurfaceCallbacks.dwSize         =
                  sizeof(DDHAL_DDSURFACECALLBACKS);
    cbDDSurfaceCallbacks.Blt            = Blt32;
    cbDDSurfaceCallbacks.Flip           = Flip32;
    cbDDSurfaceCallbacks.Lock           = Lock32;
    cbDDSurfaceCallbacks.GetBltStatus   = GetBltStatus32;
    cbDDSurfaceCallbacks.GetFlipStatus  = GetFlipStatus32;
    cbDDSurfaceCallbacks.dwFlags        = DDHAL_SURFCB32_BLT |
                                          DDHAL_SURFCB32_FLIP |
                                          DDHAL_SURFCB32_LOCK |
                                          DDHAL_SURFCB32_GETBLTSTATUS |
                                          DDHAL_SURFCB32_GETFLIPSTATUS;

    /*
     * Fill in the palette callbacks
     */
    memset(&cbDDPaletteCallbacks, 0, sizeof(DDHAL_DDPALETTECALLBACKS));
    cbDDPaletteCallbacks.dwSize  = sizeof(DDHAL_DDPALETTECALLBACKS);
    cbDDPaletteCallbacks.dwFlags = 0;

    /*
     * Fill in the HALINFO
     */
    memset(&ddHALInfo, 0, sizeof(DDHALINFO));
    ddHALInfo.dwSize = sizeof(DDHALINFO);

    /*
     * Callback functions
     */
    ddHALInfo.lpDDCallbacks        = &cbDDCallbacks;
    ddHALInfo.lpDDSurfaceCallbacks = &cbDDSurfaceCallbacks;
    ddHALInfo.lpDDPaletteCallbacks = &cbDDPaletteCallbacks;

    /*
     *  FOURCCs supported
     */
    ddHALInfo.ddCaps.dwNumFourCCCodes = 0;
    ddHALInfo.lpdwFourCC = NULL;

    /*
     * Return our HINSTANCE
     */
    ddHALInfo.hInstance = (DWORD)hInstance;

    /*
     * PDevice
     */
    ddHALInfo.lpPDevice = (LPVOID)pDriverData->lpPDevice;

    /*
     * Capabilities supported
     */
    ddHALInfo.ddCaps.dwCaps = DDCAPS_BLT |
                              DDCAPS_BLTQUEUE |
                              DDCAPS_BLTCOLORFILL |
                              DDCAPS_COLORKEY;

    ddHALInfo.ddCaps.ddsCaps.dwCaps = DDSCAPS_FLIP |
                                      DDSCAPS_OFFSCREENPLAIN |
                                      DDSCAPS_PRIMARYSURFACE;

    ddHALInfo.ddCaps.dwCKeyCaps = DDCKEYCAPS_SRCBLT |
                                  DDCKEYCAPS_DESTBLT;

    ddHALInfo.ddCaps.dwFXCaps = 0x00000000;

    /*
     * Fill in ROPs supported
     */
    ddHALInfo.ddCaps.dwRops[0] =0x00000001;
            // BLACKNESS - 0x00 / 32 = 0 + 0 remainder - DWORD 0, bit 0
    ddHALInfo.ddCaps.dwRops[1] =0x00000000;
    ddHALInfo.ddCaps.dwRops[2] =0x00000000;
    ddHALInfo.ddCaps.dwRops[3] =0x00000000;
    ddHALInfo.ddCaps.dwRops[4] =0x00000000;
    ddHALInfo.ddCaps.dwRops[5] =0x00000000;
    ddHALInfo.ddCaps.dwRops[6] =0x00001000;
            // WHITENESS - 0xff / 32 = 7 + 31 remainder - DWORD 7,bit 31
    ddHALInfo.ddCaps.dwRops[7] =0x80000000;
            // SRCCOPY   - 0xcc / 32 = 6 + 12 remainder - DWORD 6,bit 12

    /*
     * Current video mode, the 16-bit driver will fill this out for real.
     */
    ddHALInfo.dwModeIndex = DDUNSUPPORTEDMODE;

    /*
     *  Required alignments of the scan lines for each kind of memory
     *  (specified in terms of bits - DWORD alignment is used in this
     *  driver)
     */
    ddHALInfo.vmiData.dwOffscreenAlign = 32;
    ddHALInfo.vmiData.dwOverlayAlign   = 32;
    ddHALInfo.vmiData.dwTextureAlign   = 32;
    ddHALInfo.vmiData.dwAlphaAlign     = 32;
    ddHALInfo.vmiData.dwZBufferAlign   = 32;

    return TRUE;

} /* buildDDHALInfo32 */


DllMain

This topic applies only to Windows 98/Me.

The DllMain function is called when the driver DLL first starts up and must be replicated exactly.

This function starts by setting hInstance to hModule, which is the instance of the driver DLL. Then it begins a switch statement on the input parameter dwReason. If dwReason is DLL_PROCESS_ATTACH, the DLL is being mapped into the process's address space and the DisableThreadLibraryCalls Win32 function is called with hModule as the parameter. This tells the system that the DLL_THREAD_ATTACH and DLL_THREAD_DETACH modifications should not be sent to the specified DLL's DllMain function. If the case is DLL_PROCESS_DETACH, the DLL is being unmapped from the process's address space. If it is DLL_THREAD_ATTACH, a thread is being created; if it is DLL_THREAD_DETACH, a thread is exiting cleanly.

Parameters

hModule
Specifies the instance of this DLL.
dwReason
Specifies the reason for calling this DLL. One of the following values can be selected:
Flag | Meaning
DLL_PROCESS_ATTACH | A new process is attempting to access the DLL; one thread is assumed.
DLL_PROCESS_DETACH | A process is detaching from the DLL.
DLL_THREAD_ATTACH | A new thread of an existing process is attempting to access the DLL; this call is made beginning with the second thread of a process attaching to the DLL.
DLL_THREAD_DETACH | One of the additional threads (not the first thread) of a process is detaching from the DLL.

lpvReserved
Is unused.

Return Value

DllMain always returns TRUE.

/*
 * DllMain
 */
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason,
                        LPVOID lpvReserved)
{
    hInstance = hModule;

    switch( dwReason ) {

    case DLL_PROCESS_ATTACH:  // The DLL is being mapped into the
                              // process's address space
        DisableThreadLibraryCalls( hModule );
                              // This tells the system we don't want
                              // DLL_THREAD_ATTACH and DLL_THREAD_DETACH
                              // modifications sent to the specified
                              // DLL's DllMain function
  break;

    case DLL_PROCESS_DETACH:  // The DLL is being unmapped from the
                              // process address space
        break;

    case DLL_THREAD_ATTACH:  // A thread is being created
        break;

    case DLL_THREAD_DETACH:  // A thread is exiting cleanly
        break;

    default:
        break;
    }

    return TRUE;

} /* DllMain */


DPF

This topic applies only to Windows 98/Me.

The DPF function sends messages to a debug terminal.

This function is simply a way to send messages to a remote debug terminal using the Win32 OutputDebugString function. Whenever a debug printf statement is inserted into the code, it calls this function. This can be duplicated in each file or be made into an include statement. Some developers have a version that allows different priority levels to be set for each message. It is called with a string to be displayed and mimics the function of a printf statement, except that the output is to the debug terminal.(In this sample, each string will begin with "DDDRV32:" and end with a carriage return.)

/*
 * DPF debug stuff
 */
#ifdef DEBUG

#define START_STR       "DDDRV32: "
#define END_STR         "\r\n"

/*
 * DPF
 */
void __cdecl DPF(LPSTR szFormat, ...)
{
    char str[256];

    lstrcpy(str, START_STR);
    wvsprintf(str+lstrlen(str), szFormat, (LPVOID)(&szFormat+1));
    lstrcat(str, END_STR);
    OutputDebugString(str);    // Sends message to debug terminal
}
#endif


DriverInit

This topic applies only to Windows 98/Me.

The DriverInit function is a sample entry point called by DirectDraw to initialize the 32-bit driver. The entry point is called after your Control function receives QUERYESCAPESUPPORT with DDGET32BITDRIVERNAME escapes and returns the entry point (szEntryPoint). (For this sample, the entry point is named DriverInit.) DriverInit is called only once during driver initialization; it is not called on mode changes.

The dwDriverData parameter in the DriverInit sample code points to a region of shared data between the 16- and 32-bit address space. It is aliased through MapSLFix (a standard Windows driver routine), which converts it to a 32-bit pointer, pDriverData. MapSLFix creates a 32-bit pointer for a 16-bit selector, so you can use what it returns from the 16-bit side. A 16:16 pointer is used to point to the needed 32-bit objects, so a 64 KB block of memory is shared between 16- and 32-bit sides. Since only 64 KB of linear address space is accessible with a 16:16 pointer, any objects larger than 64 KB require two 16:16 pointers tiled together (most objects should be smaller than 64 KB). The pointer is used to set the fReset flag to TRUE because the display parameters are being reset. The buildDDHALInfo32 sample function is called from this function to fill out all of the 32-bit function names and driver information.

Parameters

dwDriverData
Points to a shared memory region between 16- and 32-bit address space.

Return Value

DriverInit always returns 1.

/*
 * DriverInit
 *
 * This is the entry point called by DirectDraw
 * to initialize the 32-bit driver.
 */
DWORD _stdcall DriverInit( DWORD dwDriverData )
{
    extern LPVOID _stdcall MapSLFix( DWORD );      // 16:16->0:32
    pDriverData = MapSLFix( dwDriverData );
    buildDDHALInfo32();
    pDriverData->fReset = TRUE;
    return 1;

} /* DriverInit */


getDisplayDuration

This topic applies only to Windows 98/Me.

The getDisplayDuration sample function obtains the length of a refresh cycle, measured in performance ticks.

This function does not need to be called if the monitor refresh rate is known (or you can modify this sample to use that information). If the monitor refresh rate is known, the performance ticks (thousandths of a second) can be calculated based on the known frequency in hertz. That number can then be put in the dwFlipDuration member of the FLIPRECORD sample structure, rather than running this function (unless you modify this sample to use that information). The method described in this paragraph should be more accurate than the empirical method employed by getDisplayDuration.

Assuming the monitor refresh rate is not known, getDisplayDuration should be called on every mode change. This will not affect performance because the monitor is synching at this time. First, getDisplayDuration takes control of the CPU with the Win32 SetPriorityClass function. When the CRT is freshly in display after being in vertical blank, the counter is started. The counter keeps track of the elapsed time, measured in ticks, through 20 display cycles. This elapsed time is divided by 20 to give the average number of ticks per display cycle and the result is stored in the dwFlipDuration member of the FLIPRECORD structure. It is a good idea to check the result with a debug statement, as in the sample shown here. The macros IN_VBLANK and IN_DISPLAY included in this sample can be written to test whether the CRT is in vertical blank or in display, respectively (for more information, see 32-bit Macros).

This function has no parameters and does not return a value.

/*
 * getDisplayDuration
 *
 * Get the length (in ticks) of a refresh cycle
 */
static void getDisplayDuration( void )
{
    int         I;            // Counter
    __int64     start, end;   // 64 bit pointer to hold ticks counted
    DWORD       oldclass;     // Variable to save our priority class
    HANDLE      hprocess;     // Our process handle

    memset( &flipRecord, 0, sizeof( flipRecord ) );
                  // Set memory to size of flipRecord structure
    hprocess = GetCurrentProcess();
                  // Get our current process
    oldclass = GetPriorityClass( hprocess );
                  // Save our old priority class
    SetPriorityClass( hprocess, REALTIME_PRIORITY_CLASS );
                  // Keeps out interruptions as we measure display time
    while(IN_VBLANK);  // Uses macro to wait until out of vertical blank
    while(IN_DISPLAY); // Uses macro to wait until no longer in display
    QueryPerformanceCounter((LARGE_INTEGER*)&start);  // Start counter
    #define LOOP_CNT    20  // We want 20 iterations
    for( i=0;i<LOOP_CNT;i++ )
    {
        while(IN_VBLANK);
        while(IN_DISPLAY);
    }
    QueryPerformanceCounter((LARGE_INTEGER*)&end);
                  // Read counter at the end of 20 cycles
    SetPriorityClass( hprocess, oldclass );
                  // Restore our old priority class
    flipRecord.dwFlipDuration = ((DWORD)(end-start) +
                  LOOP_CNT/2)/LOOP_CNT;
                  // Calculate flip duration
#ifdef DEBUG
    QueryPerformanceFrequency((LARGE_INTEGER*)&start);

    DPF( "Duration = %d ticks, %dms, %dHz",
        flipRecord.dwFlipDuration,
        flipRecord.dwFlipDuration * 1000 / (DWORD)start,
        (DWORD)start / flipRecord.dwFlipDuration);
#endif

} /* getDisplayDuration */


updateFlipStatus

This topic applies only to Windows 98/Me.

The updateFlipStatus sample function determines whether the most recent flip has occurred. This sample function should be modified to match the characteristics of your particular card.

The sample code for updateFlipStatus represents a good default implementation of the flipping algorithm. Care should be exercised in making alterations to this routine, but such alterations may be necessary, nonetheless (see Timing a Flip for other useful algorithms). In addition to modifying the flipping algorithm in some cases, the sample code needs to be modified if the driver is to support flipping overlays. The code must be able to scan through a chain of FLIPRECORD structures to find the correct fpVidMem pointer; therefore, multiple FLIPRECORD structures can be used in that case.

If the input parameter, fpVidMem, is set to zero then updateFlipStatus checks to see whether a flip is being processed on any surface (for a description of a flip being processed, see Flipping and Flip32). If fpVidMem points to a surface, then updateFlipStatus determines whether that surface is being flipped from. If fpVidMem does point to a surface that is being flipped from, it determines whether that surface has been completely displayed. If the display device is in the vertical blank, the time is checked to see whether enough time has passed to complete a flip. (This is because many cards cannot report the scan line while the gun is in the vertical blank.) If not enough time has passed, DDERR_WASSTILLDRAWING is returned. If enough time has passed, the bFlipFlag member of the FLIPRECORD structure is set to FALSE and DD_OK is returned, indicating the surface is available.

If display isn't in vertical blank, the scan line can be used to determine whether the entire screen has been displayed. If the scan line is above where it was previously, the flip flag is set to FALSE (meaning that the flip is not pending on that surface) and DD_OK is returned to indicate that it is okay to proceed with operations on that surface. If the scan line is not above the previous measurement, the time is checked again to see whether it is greater than the display duration. If not enough time has elapsed, DDERR_WASSTILLDRAWING is returned to indicate that the surface is not yet available.

The IN_VBLANK and CURRENT_VLINE macros can be written to test whether the CRT is in vertical blank and to read the current scan line, respectively (for more information, see 32-bit Macros).

Parameters

fpVidMem
Points to the beginning of a particular surface in display memory. Declared in ddrawi.h.

Return Value

updateFlipStatus returns DD_OK if the flip has occurred and DDERR_WASSTILLDRAWING if not.

/*
 * updateFlipStatus
 *
 * Checks to see if the most recent flip has occurred
 */
static __inline HRESULT updateFlipStatus( FLATPTR fpVidMem )
{
    /*
     * See if a flip has happened recently
     */
    if( flipRecord.bFlipFlag && ((fpVidMem == 0)||
                        (fpVidMem == flipRecord.fpFlipFrom) ) )
    {
        __int64 ttime;        //64 bit pointer - measures time in ticks

        /*
         * If we aren't in the vertical blank, we can use the scan line
         * to help decide on what to do
         */
        if(!(IN_VBLANK))
        {
            if( (CURRENT_VLINE >= flipRecord.wFlipScanLine) )
            {
                QueryPerformanceCounter((LARGE_INTEGER*)&ttime);
                if( (DWORD)(ttime-flipRecord.liFlipTime) <=
                  flipRecord.dwFlipDuration )
                {
                    return DDERR_WASSTILLDRAWING;  // Not done flipping
                }
            }
        }
        /*
         * In the vertical blank, scan line is useless
         */
        else
        {
            QueryPerformanceCounter((LARGE_INTEGER*)&ttime);
            if( ((DWORD)(ttime-flipRecord.liFlipTime) <=
                        flipRecord.dwFlipDuration) )
            {
                return DDERR_WASSTILLDRAWING;     // Not done flipping
            }
        }
        flipRecord.bFlipFlag = FALSE;
                        // A flip is not pending on this surface
    }
    return DD_OK;       // OK to do a flip or blt on this surface
} /* updateFlipStatus */


32-bit Callback Samples

This section applies only to Windows 98/Me.

Callback routines should be implemented in the 32-bit portion of the HAL. If, for some reason, a particular callback cannot be implemented in 32-bit, it can be written in 16-bit instead. If it is written in 16-bit, do not set the bit in the callback table that specifies it is a 32-bit callback function. This way, the callback is called from the 16-bit side by default (it still must be listed in the DDHALINFO structure). When that is done, ddraw16.dll calls the callback function rather than ddraw.dll, and the callback function is run on the 16-bit side.

The following sample 32-bit HAL callbacks are discussed in this section:

Blt32

Flip32

GetBltStatus32

GetFlipStatus32

GetScanLine32

Lock32

WaitForVerticalBlank32


Blt32

This topic applies only to Windows 98/Me.

Blt32 is called for every DirectDraw blt operation. Blts to surfaces that are being flipped from must not happen until the flip is completed. If a blt happens on the same surface that is being displayed, a tear can occur. This type of tear looks like the screen jerked upwards briefly.

This callback should be optimized for the following three operations: source copy, transparent blt, and color fill. The optimization should include making a single test to determine whether the operation is a source copy, followed by a single test to see whether it is a transparent blt, followed by a single test to see whether it is a color fill, followed by code that handles any other permutations the driver supports. The first three are most critical to display performance because they are used most often (and are all that is covered in this sample). Obviously, handling more cases is preferable, but make sure the code to handle these cases does not interfere with the speed of the execution of source copy, transparent blt, and color fill.

Local surface objects are passed in to Blt32. You must retrieve the pointer to the global surface object by referencing the surface object's lpGbl pointer. This happens in the first part of Blt32 because the global surface pointer is what actually points to display memory. The DirectDraw object thinks the local surface pointer is the display memory pointer. However, because multiple DirectDraw objects may exist, this DirectDraw object is not guaranteed to have the input focus. The global surface pointer is guaranteed to correspond to the DirectDraw object that has the input focus.

Before blitting to a flippable surface, call updateFlipStatus with a pointer to the display memory of the destination surface to see if that surface is involved in a flip. The blt cannot be done on a surface that is flipping because this will cause a tear. The updateFlipStatus function is called with the fpVidMem member of the DDRAWI_DDRAWSURFACE_GBL structure (representing the destination surface) passed as a parameter to specify the surface of interest. If the return value is not DD_OK, then the ddRVal member of the DDHAL_BLTDATA structure is set to the value of the ddrval parameter and DDHAL_DRIVER_HANDLED is returned. This gives up control to DirectDraw and passes it the return value, that is, DDERR_WASSTILLDRAWING. If the return value is DD_OK, the dwFlags parameter is set equal to the dwFlags member of the DDHAL_BLTDATA structure (the latter half of this sample contains the code for the flags that are used), which specifies what kind of blt to do. If the dwFlags parameter is DDBLT_ASYNC, and there is enough FIFO memory to do a blt, the blt is done asynchronously through the FIFO, in the order received. If there is not enough FIFO memory, a message is sent out for debugging purposes to indicate that the asynchronous blt failed, the ddRVal member of the DDHAL_BLTDATA structure is set to DDERR_WASSTILLDRAWING, and DDHAL_DRIVER_HANDLED is returned.

All of the information needed to do a blt is contained in the bltFX member of the DDHAL_BLTDATA structure. The dwFlags member of the DDHAL_BLTDATA structure determines what kind of blt is being done (see the latter half of the sample code for these flags). The color key always comes in the DDBLTFX structure; it does not have to be looked up in the surface.

If the dwFlags member is DDBLT_ASYNC, the sample checks to see whether the FIFO has enough room for a blt. If there is not enough room, return immediately. Otherwise, get the offset, width, and height for the blt, and check dwFlags to determine whether it is a raster operation (DDBLT_ROP). If it is a raster operation and the dwROP member of the DDBLTFX structure pointed to by the bltFX member of the DDHAL_BLTDATA structure is SRCCOPY, then the operation is a standard copy operation (for more information, see the DDBLTFX structure). The destination offset, source data, source offset, source width, source height, and color key (if one exists) are then determined in the sample. There may be a color key override (DDBLT_KEYSRCOVERRIDE) if it is a transparent blt. If no color key exists, the same information is set up without the color key. This double checks how the blt is set up.

When performing a color fill instead of a raster operation (dwFlags == DDBLT_COLORFILL), the dwFillColor parameter in the sample is set equal to the dwFillColor member of the DDBLTFX structure pointed to by the bltFX member of the DDHAL_BLTDATA structure. A debug message is sent out to verify that the correct fill color, destination height, and width have been selected. If this is not a raster operation or color fill (or other implemented function), then return DDHAL_DRIVER_NOTHANDLED so this unsupported request can be passed on to the DIB engine. Otherwise the ddRVal member of the DDHAL_BLTDATA structure is set to DD_OK and DDHAL_DRIVER_HANDLED is returned.

/*
 * Blt32
 *
 * 32-bit blt routine.
 */
DWORD __stdcall Blt32( LPDDHAL_BLTDATA pbd )
{
    HRESULT     ddrval;     // DirectDraw return value
    DWORD       dwFlags;    // For specifying the type of blt

    DWORD dwFillColor;      // Used to specify the RGB color to fill with
    DWORD dwColorKey;       // Holds our color key for a transparent blt

    DWORD dwDstOffset;      // Offset to beginning of destination surface
    DWORD dwDstWidth;       // Width of destination surface (in pixels)
    DWORD dwDstHeight;      // Height of destination surface (in rows)

    DWORD dwSrcOffset;      // Offset to the beginning of source surface
    DWORD dwSrcWidth;       // Width of source surface (in pixels)
    DWORD dwSrcHeight;      // Height of source surface (in rows)

    LPDDRAWI_DDRAWSURFACE_LCL  srcx;
                            // Local pointer to source surface
    LPDDRAWI_DDRAWSURFACE_LCL  dstx;
                            // Local pointer to destination surface
    LPDDRAWI_DDRAWSURFACE_GBL  src;
                            // Global pointer to source surface
    LPDDRAWI_DDRAWSURFACE_GBL  dst;
                            // Global pointer to destination surface
    dstx = pbd->lpDDDestSurface;      // Destination surface
    dst = dstx->lpData;               // Destination data

    /*
     * NOTES:
     *
     * Everything you need is in pdb->bltFX.
     * Look at pdb->dwFlags to determine what kind of blt you are doing,
     * DDBLT_xxxx are the flags.
     *
     * COLORKEY NOTES:
     *
     * ColorKey ALWAY comes in BLTFX. You don't have to look it up in
     * the surface.
     */

    /*
     * Is a flip pending on our destination surface?  If so, pass
     * ddrval return value and exit
     */
    ddrval = updateFlipStatus(dst->fpVidMem);
    if( ddrval != DD_OK )
    {
        pbd->ddRVal = ddrval;          // Pass the return value
        return DDHAL_DRIVER_HANDLED;   // Can't blt now, exit function
    }

    /*
     * If async, then only work if blitter isn't busy
     * This should probably be a little more specific to each call, but
     * this is pretty close
     */
    dwFlags = pbd->dwFlags;
    if( dwFlags & DDBLT_ASYNC )
    {
        if( !ENOUGH_FIFO_FOR_BLT )
        {
            DPF("ASYNC FAILED");
            pbd->ddRVal = DDERR_WASSTILLDRAWING;// Pass the return value
            return DDHAL_DRIVER_HANDLED;        // Not enough FIFO, exit
        }
    }

    /*
     * Get offset, width, and height for destination
     */
    dwDstOffset = dst->fpVidMem     - pDriverData->ScreenAddress;
    dwDstWidth  = pbd->rDest.right  - pbd->rDest.left;
    dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;

    /*
     * Handle ROPs such as copy, transparent blts and color fills
     */
    if (dwFlags & DDBLT_ROP)
    {
        if (pbd->bltFX.dwROP == SRCCOPY)
        {
            srcx = pbd->lpDDDestSurface;
            src = srcx->lpData;

            dwSrcOffset = src->fpVidMem    - pDriverData->ScreenAddress;
            dwSrcWidth  = pbd->rSrc.right  - pbd->rSrc.left;
            dwSrcHeight = pbd->rSrc.bottom - pbd->rSrc.top;
            dwColorKey  =
                pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;

            if (dwFlags & DDBLT_KEYSRCOVERRIDE)
                DPF("Blt32: TransBlt from %08X %dx%d -> %08X %dx%d
                    key=%08X", dwSrcOffset, dwSrcWidth, dwSrcHeight,
                    dwDstOffset, dwDstWidth, dwDstHeight, dwColorKey);
            else
                DPF("Blt32: Blt from %08X %dx%d -> %08X %dx%d",
                    dwSrcOffset, dwSrcWidth, dwSrcHeight, dwDstOffset,
                    dwDstWidth, dwDstHeight);
        }
    }
    else if (dwFlags & DDBLT_COLORFILL)
    {
        dwFillColor = pbd->bltFX.dwFillColor;
        DPF("Blt32: fill %08X %08X %dx%d", dwFillColor, dwDstWidth,
            dwDstHeight);
    }
    else
    {
                     // This is where you would handle extra ROPs
   return DDHAL_DRIVER_NOTHANDLED;
                     // We couldn't handle the blt, pass it on to HEL
    }

    pbd->ddRVal = DD_OK;         // Pass the return value
    return DDHAL_DRIVER_HANDLED; // Blt successful, exit function

} /* Blt32 */


Flip32

This topic applies only to Windows 98/Me.

The Flip32 callback handles flipping of surfaces, including primary surfaces, overlays and textures.

When a flip occurs in DirectDraw, the front buffer object remains the front buffer object; only the surface memory to which it points changes. The key issue is to eliminate tearing. The surface being displayed is indicated by the lpSurfCurr member of the DDHAL_FLIPDATA structure and the surface that should be displayed next is indicated by the lpSurfTarg member of the same structure. Don't flip while any flips involving this surface chain are pending (typically if a flip is pending, updateFlipStatus code handles this). In addition, don't flip if the blitter is busy; if it is blitting to the target surface this could result in a tear (the macro in this sample, DRAW_ENGINE_BUSY, handles this test). The DRAW_ENGINE_BUSY macro in this sample can be written to test whether your blitter is busy (for more information, see 32-bit Macros).

When the hardware registers are pointed at the new surface, the surface that was flipped away from needs to be tracked. One possible method of tracking the surface is by using a FLIPRECORD structure. If the user tries to lock the surface, it is possible to verify whether it has finished being displayed. The FLIPRECORD structure itself is not mandatory, but you need a way to keep track of the surface. If you can have multiple flips (that is, flipping overlays and flipping textures), you need to have more than one FLIPRECORD structure (or an analog to it).

Flip32 sends out a debug message to verify the current and target surfaces and the fpVidMem pointers that correspond to each. (Of course, the debug messages in the sample code are merely suggestions and are purely up to the discretion of the driver writer.) The updateFlipStatus function is called with a 0 parameter to see whether a flip is pending.

If the return value from updateFlipStatus is not equal to DD_OK, a flip cannot happen at this time. The return value is passed by setting the ddRVal member of the DDHAL_FLIPDATA structure to the value returned from the updateFlipStatus function (ddrval), and DDHAL_DRIVER_HANDLED is returned from Flip32 because the request has been processed.

If the return value is equal to DD_OK, and the blit engine is not busy, it is okay to flip. (You may want to write a macro called SET_FLIP_REGISTER or just add the code that sets the register, which is read when the next surface is to be displayed.) If the blitter is busy, the flip can't be done at this time, DDERR_WASSTILLDRAWING is passed in the ddRVal member of the DDHAL_FLIPDATA structure, and DDHAL_DRIVER_HANDLED is returned. The updateFlipStatus function does not work unless one or more FLIPRECORD structures are maintained properly.

If all of the conditions for allowing a flip are met, you can check the bit that tells whether the flip has occurred (assuming the hardware has such a bit). If your hardware does not have such a bit, the QueryPerformanceCounter Win32 function is called to set the beginning flip time. This can be polled later to see whether enough time has elapsed to go through an entire refresh cycle. The bFlipFlag member of the FLIPRECORD structure is set to TRUE to indicate a pending flip. Then the fpFlipFrom member of the same structure is set to the value of the fpVidMem member of the DDRAWI_DDRAWSURFACE_GBL structure that is contained in the DDRAWI_DDRAWSURFACE_LCL structure (lpGbl) that is pointed to by the lpSurfCurr member of the DDHAL_FLIPDATA structure. In addition, the bHaveEverCrossedVBlank member of the FLIPRECORD structure is reset to FALSE (to verify whether the surface has been completely displayed—for more information, see Timing a Flip).

If the scan line is in vertical blank, the dwFlipScanLine member of the FLIPRECORD structure is set to 0 and the bWasEverInDisplay member is set to FALSE. If you have a multiregister flip (that is, more than one register must be changed to do a flip), do not do this when the scan line is in the vertical blank. In that case, if the DDFLIP_WAIT flag is not set, return out of Flip32 with the DDERR_WASSTILLDRAWING error, and avoid doing the flip while in vertical blank. If the DDFLIP_WAIT flag is set, wait until the scan line is out of vertical blank and then do the flip. That is the only way to be sure not to tear when you have multiregister flips. Otherwise the dwFlipScanLine member is set to the result of the CURRENT_VLINE (an implementation-specific macro that determines the scan line), and the bWasEverInDisplay member of the FLIPRECORD structure is set to TRUE. Again, this is to keep track of where you are in the display cycle. DD_OK is passed as the return value in the ddRVal member of the DDHAL_FLIPDATA structure, and DDHAL_DRIVER_HANDLED is returned after a successful flip.

/*
 * Flip32
 */
DWORD __stdcall Flip32( LPDDHAL_FLIPDATA pfd )
{
    HRESULT     ddrval;       // DirectDraw return value

    /*
     * NOTES:
     *
     * This callback is invoked whenever we are about to flip from
     * one surface to another. pfd->lpSurfCurr is the surface we were
     * at; pfd->lpSurfTarg is the one we are flipping to.
     *
     * You should point the hardware registers at the new surface, and
     * also keep track of the surface that was flipped away from, so
     * that if the user tries to lock it, you can be sure that it is
     * done being displayed.
     */
    DPF( "Flip32: curr=%08lx, targ=%08lx", pfd->lpSurfCurr,
                              pfd->lpSurfTarg );
    DPF( "        vidmem ptrs change: %08lx->%08lx",
                        pfd->lpSurfCurr->lpGbl->fpVidMem,
                        pfd->lpSurfTarg->lpGbl->fpVidMem );

    ddrval = updateFlipStatus(0);   // Are there any flips pending?

    if (ddrval != DD_OK)
    {
        pfd->ddRVal = ddrval;       // Pass the return value
        return DDHAL_DRIVER_HANDLED;// Exit function without flipping
    }

    /*
     * Is the blitter busy right now?
     */
    if (DRAW_ENGINE_BUSY)
    {
        pfd->ddRVal = DDERR_WASSTILLDRAWING; // Pass the return value
        return DDHAL_DRIVER_HANDLED;    // Draw engine busy, exit
    }

    /*
     *  Everything is OK, do the flip here. Suggest writing a
     *  SET_FLIP_REGISTER macro to use here.
     */

    /*
     * Remember where/when we were when we did the flip
     * (Only required if we have a piece of hardware that doesn't have
     * a bit that is set when a flip occurs.)
     */
    QueryPerformanceCounter((LARGE_INTEGER*)&flipRecord.liFlipTime);
    flipRecord.bFlipFlag = TRUE;
    flipRecord.fpFlipFrom = pfd->lpSurfCurr->lpGbl->fpVidMem;
    flipRecord.bHaveEverCrossedVBlank = FALSE;

    /*
     * Update flipRecord structure so updateFlipStatus can determine
     * whether we have been through a complete
     * display cycle later
     */
    if (IN_VBLANK)
    {
        flipRecord.dwFlipScanLine = 0;
        flipRecord.bWasEverInDisplay = FALSE;
    }
    else
    {
        flipRecord.dwFlipScanLine = CURRENT_VLINE;
        flipRecord.bWasEverInDisplay = TRUE;
    }

    pfd->ddRVal = DD_OK;
    return DDHAL_DRIVER_HANDLED;

} /* Flip32 */


GetBltStatus32

This topic applies only to Windows 98/Me.

The GetBltStatus32 callback checks whether the blitter queue has room for more blts and whether the blitter is busy.

GetBltStatus32 first checks the dwFlags member of the DDHAL_GETBLTSTATUSDATA structure to see whether blts are supported. If they are, it makes sure any flips away from the destination surface have been completed. If no flip is pending, GetBltStatus32 checks to see whether there is room in the FIFO or if the FIFO is as empty as it can be. If there is not enough room for the blt parameters, the return value (the ddRVal member of the DDHAL_GETBLTSTATUSDATA structure) is set to DDERR_WASSTILLDRAWING. If there is enough FIFO to do a blt, the return value is set to DD_OK. If a blt cannot be added, the draw engine is checked and the return value is set to DDERR_WASSTILLDRAWING if it is busy or DD_OK if not. In either case, DDHAL_DRIVER_HANDLED is returned. This simply means the call has been dealt with successfully, not that any specific action has been performed.

The ENOUGH_FIFO_FOR_BLT and DRAW_ENGINE_BUSY macros in this sample can be written to test whether the hardware FIFO has enough room for a blt and whether the blitter is busy, respectively. These macros are implementation-specific (for more information, see 32-bit Macros).

/*
 * GetBltStatus32
 */
DWORD __stdcall GetBltStatus32(
        LPDDHAL_GETBLTSTATUSDATA lpGetBltStatus )
{
    /*
     * CANBLT: can we add a blt?
     */
    if( lpGetBltStatus->dwFlags == DDGBS_CANBLT )
    {
        /*
         * Make sure that we've flipped away from the destination
         * surface
         */
        lpGetBltStatus->ddRVal = updateFlipStatus(
                        lpGetBltStatus->lpDDSurface->lpGbl->fpVidMem );
        if( lpGetBltStatus->ddRVal == DD_OK )
        {
            /*
             * There was no flip going on. Is there room in the FIFO
             * to add a blt?
             */
            if( !ENOUGH_FIFO_FOR_BLT )
            {
                lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
            }

else
            {
                lpGetBltStatus->ddRVal = DD_OK;
            }
        }
    }
    /*
     * DONEBLT: Is a blt in progress?
     */
    else
    {
        if( DRAW_ENGINE_BUSY )
        {
            lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
        }
        else
        {
            lpGetBltStatus->ddRVal = DD_OK;
        }
    }
    return DDHAL_DRIVER_HANDLED;

} /* GetBltStatus32 */


GetFlipStatus32

This topic applies only to Windows 98/Me.

The GetFlipStatus32 callback determines whether a previously requested flip has occurred and whether it is okay to do a flip.

To perform a flip, the previous flip must be completed and the blitter cannot be busy. If the display has been through one refresh cycle since the previous flip, DD_OK is returned. If it has not been through a refresh cycle, DDERR_WASSTILLDRAWING is returned to indicate that this surface is still busy "drawing" the flipped page. DDERR_WASSTILLDRAWING is also returned if the blitter is busy and the caller is asking whether it is okay to flip.

GetFlipStatus32 first checks to see whether a flip is pending by calling updateFlipStatus. If no flip is pending, it checks the blt engine to make sure that a blt is not being processed on the surface to which it is being flipped. Since it is not known for certain which surface is being targeted, the flip cannot occur until the blt engine is done. If a flip is pending, GetFlipStatus32 sets the ddRVal member of the DDHAL_GETFLIPSTATUSDATA structure to the return value of updateFlipStatus . The value 0 is passed to updateFlipStatus to find out if a flip is pending on any surface. If the dwFlags member of the DDHAL_GETFLIPSTATUSDATA structure is set to DDGFS_CANFLIP and the ddRVal member (of the same structure) is DD_OK, then check to see whether the blt engine is busy, by using the DRAW_ENGINE_BUSY macro. If it is, the ddRVal member is changed to DDERR_WASSTILLDRAWING. Once these return values are set, DDHAL_DRIVER_HANDLED is returned because the request has been dealt with successfully. If the blitter is not busy, it continues with DDGFS_CANFLIP and returns DDHAL_DRIVER_HANDLED.

The DRAW_ENGINE_BUSY macro in this sample can be written to test whether your blitter is busy. This is implementation-specific (for more information, see 32-bit Macros).

/*
 * GetFlipStatus32
 *
 * If the display has gone through one refresh cycle since the flip
 * occurred we return DD_OK. If it has not been through one refresh
 * cycle we return DDERR_WASSTILLDRAWING to indicate that this surface
 * is still busy "drawing" the flipped page. We also return
 * DDERR_WASSTILLDRAWING if the blitter is busy and the caller wanted
 * to know if a flip could be performed.
 */
DWORD __stdcall GetFlipStatus32(
        LPDDHAL_GETFLIPSTATUSDATA lpGetFlipStatus )
{
    lpGetFlipStatus->ddRVal = updateFlipStatus( 0 );
                              // Is a flip happening on any surface?

    /*
     * Check to see whether the blitter is busy, if someone wants to
     * know if a flip can be performed
     */
    if( lpGetFlipStatus->dwFlags == DDGFS_CANFLIP )
    {
        if( (lpGetFlipStatus->ddRVal == DD_OK) && DRAW_ENGINE_BUSY )
        {
            lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
        }
    }
    return DDHAL_DRIVER_HANDLED;

} /* GetFlipStatus32 */


GetScanLine32

This topic applies only to Windows 98/Me.

The GetScanLine32 callback returns the physical scan line, if it can be determined. If the hardware does not have the ability to read the scan line, then put NULL in this function's entry point in buildDDHALInfo32.

If a vertical blank is in progress, the scan line is indeterminate; therefore the ddRVal member of the DDHAL_GETSCANLINEDATA structure is set to DDERR_VERTICALBLANKINPROGRESS and DDHAL_DRIVER_HANDLED is returned. If the scan line is not in vertical blank, it is read into the dwScanLine member of the DDHAL_GETSCANLINEDATA structure with the CURRENT_VLINE macro. CURRENT_VLINE is an implementation-specific macro that reads the scan line register(s) and reports the scan line (see 32-bit Macros for more information). The DD_OK return value is passed in the ddRVal member of the DDHAL_GETSCANLINEDATA structure and DDHAL_DRIVER_HANDLED is returned.

/*
 * GetScanLine32
 */
DWORD __stdcall GetScanLine32(
        LPDDHAL_GETSCANLINEDATA lpGetScanLine )
{
    /*
     * If a vertical blank is in progress, the scan line is
     * indeterminate. If the scan line is indeterminate we return
     * the error code DDERR_VERTICALBLANKINPROGRESS.
     * Otherwise we return the scan line and a success code.
     */
    if( IN_VBLANK )
    {
        lpGetScanLine->ddRVal = DDERR_VERTICALBLANKINPROGRESS;
                        // Can't get the scan line
    }
    else
    {
        lpGetScanLine->dwScanLine = CURRENT_VLINE;
                        // Read current scan line
        lpGetScanLine->ddRVal = DD_OK;
                        // We got the scan line successfully
    }
    return DDHAL_DRIVER_HANDLED; // We dealt with the call

} /* GetScanLine32 */


Lock32

This topic applies only to Windows 98/Me.

The Lock32 callback locks a surface so that only the user can access it. It is invoked whenever a surface is about to be directly accessed by the host CPU.

The sole purpose of Lock32 is to provide a display memory pointer to DirectDraw. If Lock32 returns DDHAL_DRIVER_NOTHANDLED, DirectDraw gets that pointer from the surface structure. If you want to use a pointer other than the one DirectDraw uses to point to the surface memory (passed in by the lpSurface member of the DDHAL_LOCKDATA structure), return that pointer in the lpSurfData member of the DDHAL_LOCKDATA structure, and specify DDHAL_DRIVER_HANDLED.

Before allowing a lock, it must be verified that a surface can be safely accessed by the user. If the memory cannot be accessed while in accelerator mode, the card should be taken out of accelerator mode or the driver should return DDERR_SURFACEBUSY. If the surface being accessed was just flipped away from, it must finish displaying before it can be locked. If a mode reset has occurred (pDriverData->fReset is set to TRUE), getDisplayDuration is called and pDriverData->fReset is set to FALSE (pDriverData->fReset is TRUE when the display duration for this mode hasn't been calculated yet). This is because the display duration is different in different modes. The getDisplayDuration function only needs to be called if the monitor refresh rate is not known, otherwise it can be calculated by converting the frequency (in hertz) to performance ticks (thousandths of a second) and filled into the dwFlipDuration member of the FLIPRECORD structure. This should be more accurate than the sampling method that getDisplayDuration uses in the following sample code. Another method is to alter getDisplayDuration to do this anyway (provided the refresh rate is known).

Before an actual lock can occur, any pending physical flip must have been processed. This is checked by calling updateFlipStatus with the pointer to the fpVidmem member of the DDRAWI_DDRAWSURFACE_GBL structure that is contained in the DDRAWI_DDRAWSURFACE_LCL structure (lpGbl) that is pointed to by the lpDDSurface member of the DDHAL_LOCKDATA structure as the input parameter. If the return value is not equal to DD_OK, the ddRVal member of the DDHAL_LOCKDATA structure is set to DDERR_WASSTILLDRAWING (because the lock cannot be done) and DDHAL_DRIVER_HANDLED is returned.

If a lock cannot be done while a blt is in progress (this depends on the hardware requirements), check whether the draw engine is busy doing a blt. If it is, set the ddRVal member of the DDHAL_LOCKDATA structure to DDERR_WASSTILLDRAWING (because the surface can't be locked right now) and return DDHAL_DRIVER_HANDLED. Otherwise, returning DDHAL_DRIVER_NOTHANDLED effectively locks the surface.

/*
 * Lock32
 */
DWORD __stdcall Lock32( LPDDHAL_LOCKDATA lpLockData )
{
    HRESULT     ddrval;             // DirectDraw return value

    /*
     * NOTES:
     *
     * This callback is invoked whenever a surface is about to be
     * directly accessed by the user. This is where you need to make
     * sure that a surface can be safely accessed by the user.
     *
     * If your memory cannot be accessed while in accelerator mode, you
     * should take either take the card out of accelerator mode or else
     * return DDERR_SURFACEBUSY
     *
     * If someone is accessing a surface that was just flipped away
     * from, make sure that the old surface (what was the primary) has
     * finished being displayed.
     */

    /*
     * Get the monitor frequency after a mode reset
     */
    if( pDriverData->fReset )
    {
        getDisplayDuration();
        pDriverData->fReset = FALSE;
    }

    /*
     * Check to see if any pending physical flip has occurred
     */
    ddrval = updateFlipStatus(lpLockData->
                              lpDDSurface->lpGbl->fpVidMem);
    if( ddrval != DD_OK )
    {
        lpLockData->ddRVal = DDERR_WASSTILLDRAWING;   // Can't lock
        return DDHAL_DRIVER_HANDLED;      // We dealt with the request
    }

    /*
     * Don't allow a lock if a blt is in progress (only do this if your
     * hardware requires it)
     */
    if(DRAW_ENGINE_BUSY)
    {
        lpLockData->ddRVal = DDERR_WASSTILLDRAWING;
                        // Can't lock during a blt
        return DDHAL_DRIVER_HANDLED;
                        // Request handled
    }

    return DDHAL_DRIVER_NOTHANDLED;
                        // Request not handled, let the lock proceed

} /* Lock32 */


WaitForVerticalBlank32

This topic applies only to Windows 98/Me.

The WaitForVerticalBlank32 callback handles requests for vertical blank status. If WaitForVerticalBlank32 does not return DDHAL_DRIVER_HANDLED, DirectDraw returns an error to the application because DirectDraw cannot emulate this function.

WaitForVerticalBlank32 determines why the function was called based on which flag it was passed. The three options are: DDWAITVB_I_TESTVB, DDWAITVB_BLOCKBEGIN, and DDWAITVB_BLOCKEND.

  • The DDWAITVB_I_TESTVB flag means the vertical blank status is all that is wanted. The status of the vertical blank in this sample is tested with the IN_VBLANK macro and the bIsInVB member of the DDHAL_WAITFORVERTICALBLANKDATA structure is set accordingly. The function then returns DDHAL_DRIVER_HANDLED.
  • If the case is DDWAITVB_BLOCKBEGIN, the WaitForVerticalBlank32 sample looks for the beginning of the vertical blank. To do this, the IN_VBLANK macro is used to wait until the scan line leaves the vertical blank and the IN_DISPLAY macro is used to wait until the scan line pops out of display. This indicates that the scan line is at the very start of vertical blank. At this time, the ddRVal member of the DDHAL_WAITFORVERTICALBLANKDATA structure is set to DD_OK and DDHAL_DRIVER_HANDLED is returned.
  • If the case is DDWAITVB_BLOCKEND, the WaitForVerticalBlank32 sample looks for the end of the vertical blank interval. If the scan line is currently in vertical blank, the IN_VBLANK macro is used to wait until the scan line is no longer in vertical blank. Then the bFlipFlag member of the FLIPRECORD structure is set to FALSE (since a display cycle has been completed), the ddRVal member of the DDHAL_WAITFORVERTICALBLANKDATA structure is set to DD_OK and DDHAL_DRIVER_HANDLED is returned. If the scan line is not currently in vertical blank, the IN_DISPLAY macro is used to wait until the scan line is no longer in display. Then, as before, the IN_VBLANK macro is used to wait until the scan line is no longer in vertical blank. The bFlipFlag member of the FLIPRECORD structure is set to FALSE, the ddRVal member of the DDHAL_WAITFORVERTICALBLANKDATA structure is set to DD_OK, and DDHAL_DRIVER_HANDLED is returned.

If none of the preceding cases occurs, WaitForVerticalBlank32 returns DDHAL_DRIVER_NOTHANDLED because the request cannot be processed correctly, and DirectDraw returns an error to the application.

IN_VBLANK is an implementation-specific macro that reads hardware register(s) to determine whether the scan line is in vertical blank. It returns immediately with a positive value if the scan line is in vertical blank and with zero if not. Likewise, IN_DISPLAY returns a positive value if the scan line is in display and returns zero if it is not. These macros must be defined before WaitForVerticalBlank32 can work correctly (see 32-bit Macros for more information).

/*
 * WaitForVerticalBlank32
 */
DWORD __stdcall WaitForVerticalBlank32(
        LPDDHAL_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank )
{

    switch( lpWaitForVerticalBlank->dwFlags )
    {
    case DDWAITVB_I_TESTVB:
        /*
         * If testvb is just a request for the current vertical blank
         * status
         */
        lpWaitForVerticalBlank->ddRVal = DD_OK;
                                   // We got the vertical blank status
        lpWaitForVerticalBlank->bIsInVB = IN_VBLANK;
                                   // Are we in vertical blank?
        return DDHAL_DRIVER_HANDLED;// Request dealt with

    case DDWAITVB_BLOCKBEGIN:
        /*
         * If blockbegin is requested we wait until the vertical blank
         * is over, and then wait for the display period to end.
         */
        while(IN_VBLANK);     // Wait until we are not in vertical blank
        while(IN_DISPLAY);    // Wait until we leave display
        lpWaitForVerticalBlank->ddRVal = DD_OK;
                              //We got waited until block begin
        return DDHAL_DRIVER_HANDLED;
                              // Request dealt with

    case DDWAITVB_BLOCKEND:
        /*
         * If blockend is requested we wait for the vblank interval to
         * end.
         */
        if( IN_VBLANK )
        {
            while( IN_VBLANK );//Wait until we are not in vertical blank
        }
        else
        {
            while(IN_DISPLAY); // Wait until we are not in display
            while(IN_VBLANK);  // Wait until we leave vertical blank
        }
        flipRecord.bFlipFlag = FALSE;
                               // No longer need to wait for flip
        lpWaitForVerticalBlank->ddRVal = DD_OK;
                               // We successfully reached blockend
        return DDHAL_DRIVER_HANDLED;// Request handled
    }

    return DDHAL_DRIVER_NOTHANDLED; // Unable to handle request

} /* WaitForVerticalBlank32 */


32-bit Structure Samples

This section applies only to Windows 98/Me.

The following structure can be implemented in the 32-bit HAL as a means of keeping track of the surface after a flip has occurred:

  • FLIPRECORD


FLIPRECORD

This topic applies only to Windows 98/Me.

The FLIPRECORD structure sample keeps track of all the information pertinent to managing a surface after a flip has occurred. It is not defined by DirectDraw and its use is not strictly required. However, it contains all the information needed to perform a flip. It is used in the sample code by updateFlipStatus, getDisplayDuration, Flip32, and WaitForVerticalBlank32.

typedef struct
{
  FLATPTR  fpFlipFrom;
  __int64  liFlipTime;
  DWORD  dwFlipDuration;
  BOOL  bFlipFlag;
  BOOL  bHaveEverCrossedVBlank;
  BOOL  bWasEverInDisplay;
  UINT  dwFlipScanLine;
} FLIPRECORD;

Members

fpFlipFrom
Points to the surface being flipped from.
liFlipTime
Is a 64-bit pointer to the hold time, in milliseconds.
dwFlipDuration
Indicates how long a flip takes in milliseconds (measured during initialization).
bFlipFlag
Indicates whether the driver has been asked to do a flip.
bHaveEverCrossedVBlank
Indicates whether the driver has ever crossed vertical blank.
bWasEverInDisplay
Indicates whether the driver has ever been in display.
dwFlipScanLine
Indicates the scan line being displayed.

Comments

FLIPRECORD keeps track of when it is all right to let an operation proceed against a back buffer. When an operation is requested against the surface specified by the fpFlipFrom member, you need to check the rest of the structure. The liFlipTime member is not needed if a bit exists to tell you when the refresh has occurred. The duration of a flip, in performance ticks, (dwFlipDuration) is not needed in this case either. If liFlipTime is needed, is set with the Win32 QueryPerformanceCounter function, which sets the beginning flip time and the future comparisons which determine the time elapsed. Likewise, if dwFlipDuration is needed, it is set when getDisplayDuration is called at mode change.

The bFlipFlag member keeps track of when a flip has been requested on a surface (setting this flag to TRUE indicates a pending flip). It is changed in updateFlipStatus and WaitForVerticalBlank32, based on the algorithm that determines whether a surface being flipped to has finished being displayed. If the flip has been requested, but the surface has not yet been through a refresh cycle, bFlipFlag is set to TRUE. The bHaveEverCrossedVBlank (filled in by the IN_VBLANK macro), bWasEverInDisplay (filled in by the IN_DISPLAY macro), and dwFlipScanLine (filled in by the CURRENT_VLINE macro) members are all involved in the algorithm that times a flip to avoid tearing (as explained in the updateFlipStatus reference section). The macros just mentioned are implementation-specific (for more information about implementing macros, see 32-bit Macros).


16-bit DirectDraw HAL Samples

This section contains general information about implementing a 16-bit DirectDraw HAL extension to the display miniport driver for Windows 98/Me.

The following functions are the only ones that may need to be included in the 16-bit HAL (depending on the capabilities of your display hardware):

buildDDHALInfo16

DDCreateDriverObject

HALDestroyDriver

Note Although any of the callback functions of the 32-bit DirectDraw HAL can be implemented in 16-bit code, in the interest of speed — and, potentially, forward compatibility — it is wisest to leave them in the 32-bit HAL.


buildDDHALInfo16

This topic applies only to Windows 98/Me.

The buildDDHALInfo16 function collects information about the 16-bit HAL for DirectDraw in the DDHALINFO structure.

Most of the DDHALINFO structure is filled out by the 32-bit HAL. The buildDDHALInfo16 function only fills out 16-bit information and information that changes during a mode switch. This includes the mode table, current display mode, primary surface address, pixel format, display heap information (see Memory Heap Allocation for more detail), and any 16-bit callback functions (typically there is only one, HALDestroyDriver).

/***********************************************************************
 *
 * buildDDHALInfo16
 *
 * Fills in the 16-bit side of the HALINFO structure. Most of the
 * structure has been filled in by our 32-bit driver.
 *
 * This function fills in only 16-bit-specific stuff, or things that
 * change on every mode switch.
 *
 ***************************************************************************/

BOOL buildDDHALInfo16()
{
    int                 i;
    LPDDHALMODEINFO     lpMode;

    /*
     * Modify the structures in our shared window with the 32-bit driver
     */
    #define cbDDCallbacks        DriverData.DDCallbacks
    #define cbDDSurfaceCallbacks DriverData.DDSurfaceCallbacks
    #define cbDDPaletteCallbacks DriverData.DDPaletteCallbacks
    #define ddHALInfo            DriverData.HALInfo

    /*
     * Count the number of modes in the mode table. The table lives in
     * Setmode.c, not this file.
     */
    for (i=0; ModeList[i].dwWidth != 0; i++)
        ;

    ddHALInfo.dwNumModes = i;
    ddHALInfo.lpModeInfo = ModeList;

    /*
     * Current video mode
     */
    ddHALInfo.dwModeIndex = DriverData.ModeNumber;
    lpMode = &ModeList[ddHALInfo.dwModeIndex];

    /*
     * Current primary surface attributes
     */
    ddHALInfo.vmiData.fpPrimary = DriverData.ScreenAddress;

    /*
     * Fill in the pixel format
     */
    ddHALInfo.vmiData.ddpfDisplay.dwSize  = sizeof (DDPIXELFORMAT);
    ddHALInfo.vmiData.ddpfDisplay.dwFlags = DDPF_RGB;
    ddHALInfo.vmiData.ddpfDisplay.dwRGBBitCount = lpMode->dwBPP;

    ddHALInfo.vmiData.dwDisplayWidth  = lpMode->dwWidth;
    ddHALInfo.vmiData.dwDisplayHeight = lpMode->dwHeight;
    ddHALInfo.vmiData.lDisplayPitch   = lpMode->lPitch;

    if (lpMode->dwFlags & DDMODEINFO_PALETTIZED )
    {
        ddHALInfo.vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
    }

    ddHALInfo.vmiData.ddpfDisplay.dwRBitMask = lpMode->dwRBitMask;
    ddHALInfo.vmiData.ddpfDisplay.dwGBitMask = lpMode->dwGBitMask;
    ddHALInfo.vmiData.ddpfDisplay.dwBBitMask = lpMode->dwBBitMask;
    ddHALInfo.vmiData.ddpfDisplay.dwRGBAlphaBitMask = lpMode->dwAlphaBitMask;

    /*
     * figure out where to put the video heap:
     *
     *  ScreenAddress ----> +----------------+
     *                      |                |
     *                      |                |
     *                      |                |
     *                      |   visible      |
     *                      |   screen       |
     *                      +----------------+
     *                      | non visible    |
     *                      | "scratch" area |
     *                      +----------------+
     *  VideoHeapBase ----> |                |
     *                      |   extra video  |
     *                      |   memory       |
     *                      |                |
     *                      |                |
     *                      ~~~~~~~~~~~~~~~~~~
     *                      ~~~~~~~~~~~~~~~~~~
     *                      |                |
     *                      |                |
     *                      +----------------+
     */
#define WORK_AREA_SIZE   0

    DriverData.VideoHeapBase  = DriverData.ScreenAddress;
    DriverData.VideoHeapBase += lpMode->dwHeight * lpMode->lPitch;
    DriverData.VideoHeapBase += WORK_AREA_SIZE;
    DriverData.VideoHeapEnd   = DriverData.ScreenAddress + DriverData.TotalVRAM;

    ddHALInfo.vmiData.dwNumHeaps = sizeof(DriverData.vidMem) / sizeof(DriverData.vidMem[0]);
    ddHALInfo.vmiData.pvmList    = DriverData.vidMem;

    DriverData.vidMem[0].dwFlags = VIDMEM_ISLINEAR;
    DriverData.vidMem[0].ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    DriverData.vidMem[0].fpStart = DriverData.VideoHeapBase;
    DriverData.vidMem[0].fpEnd   = DriverData.VideoHeapEnd;

    DPF("TotalVRAM     = %08lX", DriverData.TotalVRAM);
    DPF("ScreenAddress = %08lX", DriverData.ScreenAddress);
    DPF("ScreenSize    = %08lX", lpMode->dwHeight * lpMode->lPitch);
    DPF("VideoHeapBase = %08lX", DriverData.VideoHeapBase);
    DPF("VideoHeapEnd  = %08lX", DriverData.VideoHeapEnd);
    DPF("VideoHeapSize = %08lX", DriverData.VideoHeapEnd - DriverData.VideoHeapBase);

    /*
     * callback functions (give DDRAW 16:16 pointers)
     */
    ddHALInfo.lpDDCallbacks        = &cbDDCallbacks;
    ddHALInfo.lpDDSurfaceCallbacks = &cbDDSurfaceCallbacks;
    ddHALInfo.lpDDPaletteCallbacks = &cbDDPaletteCallbacks;

    /*
     * This is the only 16-bit callback, all the others are either
     * undefined or 32-bit.
     */
    cbDDCallbacks.DestroyDriver = HALDestroyDriver;

    return TRUE;

} /* buildDDHALInfo16 */


DDCreateDriverObject

This topic applies only to Windows 98/Me.

The DDCreateDriverObject function creates a driver object and registers it with DirectDraw. If the driver object is created during a mode change, this function re-registers the driver and driver capabilities with DirectDraw.

During initialization (see Driver Initialization), DirectDraw issues a GDI escape call asking this function to create a driver object and register it with DirectDraw. In this case it is called with bReset set to 0. When this function is called from Enable or ReEnable, bReset is set to 1 to indicate a mode change. When this happens, DDCreateDriverObject has to reregister the mode and driver capabilities with DirectDraw. In both cases the driver object has to be registered with DirectDraw. The function called to register with DirectDraw comes from the DDNEWCALLBACKFNS escape (see the buildDDHALInfo32 description). If this escape has not been received, it cannot register.

If the HAL is using VflatD, DDCreateDriverObject starts VflatD. Otherwise it sets up for linear memory access (for more information, see VflatD). DDCreateDriverObject also calls buildDDHALInfo16, which fills in the rest of the DDHALINFO structure (most of DDHALINFO has already been filled in by the 32-bit counterpart to this function, buildDDHALInfo32).

/*
 * DDCreateDriverObject
 *
 * DDCREATEDRIVEROBJECT handler.
 *
 * Called at ESCAPE time or when the mode is set.
 *
 * When called from ESCAPE,
 * DirectDraw issues a GDI Escape call asking us to create a driver
 * object and register it with DirectDraw.
 *
 *     bReset           will be 0
 *
 * When called from Enable,
 * the display driver calls this function internally, every time the
 * display mode has changed. In this case we need to reregister
 * the mode and driver caps with DirectDraw.
 *
 *     bReset           will be 1
 *
 * In both cases we need to call DirectDraw to register our driver
 * object. The function we need to call to register with DirectDraw is
 * given to us with the DDNEWCALLBACKFNS escape (see DDNewCallbackFns).
 * If we have not received this escape we should not register.
 *
 */
BOOL DDCreateDriverObject(BOOL bReset)
{
    DPF("DDCreateDriverObject(%d)", bReset);

    /*
     * Do we have the function we need to call to register ourself?
     */
    if (DriverData.HALCallbacks.lpSetInfo == NULL)
    {
        DPF("DDCreateDriverObject: failing because lpSetInfo == NULL");
        return FALSE;
    }

    /*
     * If we have not connected with our 32-bit alter ego, don't
     * register.
     */
    if (DriverData.HALInfo.dwSize != sizeof(DDHALINFO))
    {
        DPF("DDCreateDriverObject: failing because 32-bit driver did not fill in stuff");
        return FALSE;
    }

    /*
     * Do we need VflatD for access to the frame buffer?
     */
#ifdef VFLATD
    if (!bReset && DriverData.ScreenAddress == 0 &&
        DriverData.ScreenSel == VFDQuerySel())
    {
        if (VFDBeginLinearAccess())
        {
            DriverData.RealScreenAddress = VFDQueryBase();
            DPF( "Using VFLATD, addr=%08lx", DriverData.RealScreenAddress);
        }
    }
    else
    {
        DriverData.RealScreenAddress = DriverData.ScreenAddress;
        DPF( "RealScreenAddress=%08lx", DriverData.RealScreenAddress);
    }
#endif

    /*
     * Set up 16-bit HAL info
     */
    buildDDHALInfo16();

    /*
     * Call DirectDraw to register our driver object.
     */
    return DriverData.HALCallbacks.lpSetInfo(&DriverData.HALInfo, bReset);

} /* DDCreateDriverObject */


HALDestroyDriver

This topic applies only to Windows 98/Me.

The HALDestroyDriver function destroys the DirectDraw driver object. This frees up shared resources and turns off VflatD (if bank switching is enabled).

/***************************************************************************
 * HALDestroyDriver
 ***************************************************************************/

DWORD __loadds CALLBACK HALDestroyDriver(LPDDHAL_DESTROYDRIVERDATA p)
{
    DPF("DDHALDestroyDriver");

    DriverData.HALCallbacks.lpSetInfo = 0; // Makes this function
                               // unavailable

    //
    // If we are using VflatD, turn off linear mode.
    //
#ifdef VFLATD
    if (DriverData.ScreenAddress == 0)
    {
        DPF("Done using VflatD");
        DriverData.RealScreenAddress = 0;
        VFDEndLinearAccess();
    }
#endif

    p->ddRVal = DD_OK;
    return DDHAL_DRIVER_HANDLED;

} /* HALDestroyDriver */


Return Values for DirectDraw and Direct3D

Errors are represented by negative values and cannot be combined. The following lists some values that can be returned by the Microsoft® DirectDraw® and Direct3D® functions that are described in the Windows® DDK documentation. For a list of the error codes that each function can return, see the function descriptions in the reference section. Refer to DirectDraw header file ddraw.h for a complete listing of error codes and return values.

A DirectDraw driver must return one of the two return codes: DDHAL_DRIVER_HANDLED or DDHAL_DRIVER_NOTHANDLED. If the driver returns DDHAL_DRIVER_HANDLED, then it must also return either DD_OK or one of the error codes listed in ddraw.h.

Return Code | Meaning
DD_OK | The request completed successfully.
DDHAL_DRIVER_HANDLED | The driver has performed the operation and returned a valid return code for that operation in the ddrval member of the structure passed to the driver's callback. If this code is DD_OK, DirectDraw or Direct3D proceeds with the function. Otherwise, DirectDraw or Direct3D returns the error code provided by the driver and aborts the function.
DDHAL_DRIVER_NOCKEYHW | The display driver couldn't handle the call because it ran out of color key hardware resources.
DDHAL_DRIVER_NOTHANDLED | The driver has no comment on the requested operation. If the driver is required to have implemented a particular callback, DirectDraw or Direct3D reports an error condition. Otherwise, DirectDraw or Direct3D handles the operation as if the driver callback had not been defined by executing the DirectDraw or Direct3D device-independent implementation. DirectDraw and Direct3D typically ignore any value returned in the ddrval member of that callback's parameter structure.
DDERR_UNSUPPORTED | The operation is not supported.
DXERR_GENERIC | There is an undefined error condition.
DXERR_OUTOFCAPS | The hardware needed for the requested operation has already been allocated.
DXERR_UNSUPPORTED | The operation is not supported.


Direct3D DDI

The Microsoft® Direct3D® device driver interface (DDI) is a graphics interface that allows vendors to provide hardware acceleration for Direct3D. The interface is flexible, allowing vendors to provide Direct3D acceleration according to hardware capabilities. Driver writers implement the Direct3D DDI as an integral part of the display driver.

This section describes the Direct3D architecture and interface, and provides implementation guidelines for Direct3D driver writers. It is assumed that the reader is familiar with the Direct3D and Microsoft DirectDraw® APIs, and that the reader has a firm grasp of the Windows® 2000 display driver model, including the DirectDraw DDI.

All Direct3D drivers for Windows 2000 and later must conform to the Microsoft DirectX® 7.0 or later Direct3D driver model. The DirectX 8.0 driver model will be supported in the released version of Microsoft Windows Codename Whistler.


Direct3D DDI Header Files, Sample Code, and References

Microsoft® Windows® 2000 and later driver writers should reference the following header files when developing a Microsoft Direct3D® driver:

d3dnthal.h
Contains prototypes for callbacks that are implemented by the driver and definitions for driver-level structures. The D3DHAL_DP2OPERATION enumerated type is defined in this file. This header is included in winddi.h, which must be included in all Windows 2000 and later display drivers.
d3dtypes.h
Contains Direct3D type definitions used by both applications and drivers. Except for D3DHAL_DP2OPERATION, all other Direct3D enumerated types are defined in this header.
d3dcaps.h
Contains structures and definitions that describe capabilities of various aspects of Direct3D drivers.
dx95type.h
Allows driver developers to write driver code that is portable between Windows 2000 and later and Windows 98/Me.
ddrawint.h
This header file is required to develop the Microsoft DirectDraw® portion of a display driver. This header is included in winddi.h.

All of these header files are shipped with the Windows DDK. The Windows DDK also provides sample code for a Direct3D driver in the perm3 video display directory.

Reference pages for Direct3D DDI functions, structures, and enumerations can be found in Direct3D Driver Functions, Direct3D Driver Structures, and Direct3D Driver Enumerations.

The primary reference for SDK-related aspects of the Direct3D interface is the Platform SDK documentation.

Less-experienced graphics programmers might find Computer Graphics: Principles and Practice by Foley, van Dam, Feiner, and Hughes published by Addison-Wesley 1990, to be a useful general graphics reference.


Cross Platform Direct3D Driver Development

The Microsoft® Windows® 2000 and later and Windows 98/Me Direct3D® DDI types are not directly compatible when compiling, due to naming differences and some type changes of members. Logically however, all members serve the same purpose.

A utility file, dx95type.h, is provided with the Windows DDK to assist with writing code intended to be portable between Windows 2000 and later and Windows 98/Me. It contains a set of type definitions and macros that map some naming differences that occur between the Windows 98/Me and Windows 2000 and later platforms, enabling some common driver code to be used between them.


Direct3D Implementation Requirements

The purpose of this section and the following subsections is to provide detailed descriptions of the requirements for hardware certification with respect to exposed features. This section does not specifically require features; rather it defines how features that are exposed (via the capabilities) must be implemented in order to conform to the standard (or, reference) implementation. This section includes, but is not limited to, detailed descriptions of features that are present in the PC2001 Design Guide. As always, the reference rasterizer is the final authority on what is and is not a compliant image. Ultimately, a compliant feature is one that behaves as the reference rasterizer does.

For each of the following features, if it is implemented, it must conform to the reference as described below. Compliance will generally be assured by comparing a scene rasterized by the hardware to an identical scene rasterized by the reference rasterizer. Some features also list additional requirements beyond simple reference comparisons.

Render Target Requirements

Point, Line, and Triangle Filling Requirements

Shading Requirements

Texturing Requirements


Render Target Requirements

This section lists requirements for color buffers and depth buffers.

Color Buffers

If the hardware is unable to support a render target that is also to be used as a texture (that is, the device cannot “render to a texture”), the device must fail calls to the IDirect3DDevice7::SetRenderTarget and IDirect3D7::CreateDevice methods on such surfaces. These methods are described in the Direct3D SDK documentation. The fact that a render target is to be used as a texture is signified by the presence of the DDSCAPS_TEXTURE flag in the surface description (see the dwCaps member of the DDSCAPS structure).

Depth Buffers

If the hardware is unable to support a particular combination of render target and depth-buffers, then the device must fail any API calls that would cause this invalid scenario to occur, and where this mismatch can be detected, such as in calls to the IDirect3D7::CreateDevice and IDirectDrawSurface7::AddAttachedSurface methods. These methods are described in the Direct3D and DirectDraw SDK documentation sets, respectively. An example of such a mismatch might be when the render target and depth buffer are of different bit depths. It is not acceptable to transparently alter the format of either the render target or the depth-buffer to cause an invalid combination to work properly.

It is acceptable to silently increase the precision of the depth buffer.


Point, Line, and Triangle Filling Requirements

This section lists requirements for filling points, lines, and triangles.

Points

The point fill and rasterization rules are identical to the triangle fill rules. All flags and capabilities that apply to triangles also apply to points, and vice-versa. The reference implementation expands a point into a rectangle and applies the triangle fill rules to the result.

Given a point with coordinates P0(x,y), generate four new points P1, P2, P3, and P4 as follows:

P1(x,y) = (x – 0.5, y – 0.5)
P2(x,y) = (x – 0.5, y + 0.5)
P3(x,y) = (x + 0.5, y + 0.5)
P4(x,y) = (x + 0.5, y – 0.5)

The rectangle is then generated as two triangles, such as (P1, P2, P3) and (P1, P3, P4). You may also examine the reference rasterizer implementation in the source files setup.cpp and scancnv.cpp.

Lines

Line fill rules are documented in the DirectX DDK in the reference rasterizer source files setup.cpp and scancnv.cpp.

Triangles

Triangle fill rules are documented in the DirectX DDK in the reference rasterizer source files setup.cpp and scancnv.cpp.

Hardware should supply the culling caps and properly implement the three culling modes. The following code fragment determines whether to cull the current triangle:

if (CurrentCullMode != D3DCULL_NONE) {
    int ccw = (((v[0]->sx - v[2]->sx) *
                (v[1]->sy - v[2]->sy)) <
               ((v[1]->sx - v[2]->sx) *
                (v[0]->sy - v[2]->sy)));
if ((CurrentCullMode == D3DCULL_CW && (ccw == 0)) ||
        (CurrentCullMode == D3DCULL_CCW && (ccw != 0))) {
        // Current triangle is culled, move onto
        // next triangle.
    }
}
// Current triangle is not culled, render it

The preceding code sample tests to determine which way the triangle is facing. The triangle is defined 0,1,2 and tested for being counter-clockwise in screen space. If it is not, and there is clockwise culling, then that triangle will not be drawn because the vertices go in clockwise order.


Shading Requirements

This section lists requirements for flat shading, Gouraud shading, specular highlighting, alpha blending, dithering, and color-key.

Flat Shading

The D3DPSHADECAPS_COLORFLATRGB bit in the dwShadeCap member of the D3DPRIMCAPS structure must be set for the appropriate primitive type (line or triangle) in order to indicate that flat shading is supported for that primitive type.

For all primitive types except triangle fans, the color, specular (if supported) and alpha data come from the first vertex of each primitive. For triangle fans, the second vertex is used. These colors remain constant across the entire triangle (that is, they are not interpolated).

Gouraud Shading

The dwShadeCaps member of the D3DPRIMCAPS structure must have the D3DPSHADECAPS_COLORGOURAUDRGB bit set for the appropriate primitive type (line or triangle) to indicate that Gouraud interpolation of colors is supported. The color and specular components are both linearly interpolated between vertices.

For all primitives, the color data must use linear interpolation between the vertices of the primitive, and must conform to an image generated by the reference rasterizer. Furthermore, all color and alpha components must be interpolated in the same fashion if they are present. For example, it is not valid to use Gouraud interpolation of the RGB components of a color while using flat shading for the alpha component. An exception is the special case of the fog component transmitted via the alpha component of the specular color, which should never be flat shaded.

Perspective correction of iterated color components is encouraged. Note that the reference rasterizer in DirectX 7.0 already does perspective correction of color components. This is taken into account in current testing procedures.

Specular Highlighting

If specular highlighting support is to be exposed, then one or both of the following flags must be set in the dwShadeCaps member of the D3DPRIMCAPS structure for the appropriate primitive type (line or triangle):

  • D3DPSHADECAPS_SPECULARFLATRGB must be set if flat shading is supported.
  • D3DPSHADECAPS_SPECULARGOURAUDRGB must be set if Gouraud shading is supported.

If specular highlighting is supported, then it must be possible to enable or disable it by setting the appropriate value of the D3DRENDERSTATE_SPECULARENABLE render state.

Specular highlighting must be full color, and must be capable of producing the full range of colors available for the render target, per the reference rasterizer. Monochromatic specular highlighting is not sufficient to meet this requirement.

The D3DPSHADECAPS_SPECULARFLATMONO and D3DPSHADECAPS_SPECULARGOURAUDMONO flags are not to be used to indicate monochromatic specular highlighting. They indicate only that specular highlighting is supported in RAMP mode. There is no cap that can indicate that an adapter supports only monochromatic specular highlights in RGB mode. If your adapter supports only monochromatic specular highlights in RGB mode, you should not set the SPECULARFLATRGB or SPECULARGOURAUDRGB caps. With the mono modes, the hardware should just interpolate the blue channel of the specular components as a white intensity. This is controlled by the D3DRENDERSTATE_MONOENABLE render state.

To properly implement specular highlights, a second set of interpolants is required. However, hardware parts that support z-buffering and blending can often emulate specular highlights by doing a second blending pass over the triangle with the z comparison function set to D3DCMP_EQUAL (see the D3DCMPFUNC enumerated type in the DirectX SDK documentation). This second pass would do a blend to add the interpolated specular component to the pixel written during the first pass; values that exceed the maximum should saturate to white.

Alpha Blending

To expose support for alpha blending, the following flags must be set in the dwShadeCaps member of the D3DPRIMCAPS structure for the appropriate primitive type (line or triangle):

  • D3DPSHADECAPS_ALPHAFLATBLEND must be set if flat shading is supported with alpha.
  • D3DPSHADECAPS_ALPHAGOURAUDBLEND must be set if Gouraud shading is supported with alpha.

If alpha blending is supported, it must be possible to enable or disable it by setting the appropriate value of the D3DRENDERSTATE_ALPHABLENDENABLE render state.

Alpha blending, or true transparency (from the 3D space), is the process of modulating incoming color by the value of the data that is already located in the frame buffer. This render state has modes that can be set by the D3DRENDERSTATE_SRCBLEND and D3DRENDERSTATE_DESTBLEND render states.

When the alpha value for a blending operation is not available, it must be assumed to be 1.0 (opaque). An example of when this is possible is blending with textures that have no alpha channel.

If the target to which the resultant pixel will be written contains an alpha channel, the alpha value resulting from any alpha blending operation must be written to that channel, allowing proper accumulation of transparency.

Dithering

If dithering is supported on a particular primitive type (line or triangle), the dwRasterCaps member of the D3DPRIMCAPS structure must have the D3DPRASTERCAPS_DITHER flag set. The feature must be controllable by means of the D3DRENDERSTATE_DITHERENABLE render state.

If dithering is supported, it may not default to always off or always on.

Color-key

Color-key is related to texture transparency and the D3DPTEXTURECAPS_TRANSPARENCY cap (see the dwTextureCaps member of the D3DPRIMCAPS structure).

Color-key transparency (used to create 2D sprites) replaces some colors of an object with the colors that are beneath them in the frame buffer. The driver should make it possible for an application to enable color-key for an entire scene, but only use the color-key on certain surfaces with the attached color-key values (instead of turning the color-key on and off for each surface).

Color-key is enabled with the AND of the render state enable and the DDRAWISURF_HASCKEYSRCBLT bit in the surface. (See the dwFlags member of the DD_SURFACE_LOCAL structure for more information.) Applications will create a texture surface that uses DDSD_CKSRCBLT and then call the IDirect3DDevice7::SetRenderState method (described in the Direct3D SDK documentation) with D3DRENDERSTATE_COLORKEYENABLE and TRUE. Both of these must be true for color-key to occur, and applications must be permitted to leave the render state TRUE all the time and still selectively use color-key for a subset of a frame's textures (i.e., those that have the DDRAWISURF_HASCKEYSRCBLT bit set). It is up to the driver to correctly handle this behavior.


Texturing Requirements

This section lists requirements for texture sizes and texture filtering. There are also texture-related requirements for the IDirect3DDevice7::ValidateDevice method.

Texture Sizes

The following are requirements for texture sizes.

  1. The driver must expose its minimum and maximum texture dimensions through the dwMinTextureWidth, dwMinTextureHeight, dwMaxTextureWidth, and dwMaxTextureHeight members of the D3DDEVICEDESC7 structure. This structure is defined in the Direct3D SDK documentation.
  2. If the hardware has an aspect ratio restriction on its textures, that ratio must be present in the dwMaxTextureAspectRatio member of the D3DDEVICEDESC7 structure.
  3. If the device supports only texture dimensions that are powers of two, then it must set the dwTextureCaps member of the D3DPRIMCAPS structure to contain the D3DPTEXTURECAPS_POW2 flag for the appropriate primitive type (line or triangle).
  4. If the device can support textures of an arbitrary size when the texture addressing mode for the texture stage is set to D3DTADDRESS_CLAMP, and the texture wrapping for the texture stage is disabled (D3DRENDERSTATE_WRAPn set to 0), and MIP mapping is not in use, then it must set the D3DPTEXTURECAPS_NONPOW2CONDITIONAL flag.
  5. If the device only supports textures whose dimensions are equal, then it must set the dwTextureCaps member of the D3DPRIMCAPS structure to contain the D3DPTEXTURECAPS_SQUAREONLY flag for the appropriate primitive type (line or triangle).

If the device supports textures of an arbitrary size without restrictions other than those described in the first and second requirement, then it must not set any of the flags described in third, fourth, and fifth requirements.

Texture Filtering

Texture magnification and minification filters must be enabled and disabled through the D3DTSS_MAGFILTER and D3DTSS_MINFILTER texture stage states. (See the D3DTEXTURESTAGESTATETYPE enumerated type in the Direct3D SDK documentation for more information about the D3DTSS_Xxx texture stage states.) This filtering must not be performed automatically when these states are disabled.

Texture MIP mapping must be enabled and disabled through the D3DTSS_MIPFILTER texture stage state. If this state is disabled, but the texture was created as a MIP map, the device must use only the top level of the MIP map. MIP mapped filtering must not be performed when this state is disabled.

If the device supports anisotropic filtering, the maximum anisotropy level must be exported through the value of the dwMaxAnisotropy member of the D3DDEVICEDESC7 structure (defined in the Direct3D SDK documentation) value. Furthermore, the device must accept any setting from 1 through dwMaxAnisotropy in the D3DTSS_MAXANISOTROPY texture stage state.

The device must be able to apply all supported filter modes to textures of any supported format. For example, if MIP mapping is supported with other texture formats, MIP map filtering of YUV textures should be able to be performed.

IDirect3DDevice7::ValidateDevice

If a device supports a particular combination of texture stage state blending operations and operands in a single pass, then the device must return DD_OK from a call to the IDirect3DDevice7::ValidateDevice method (described in the Direct3D SDK documentation) for each such combination.

If a device does not support a particular combination of texture stage state blending operations in a single pass, or does not support one or more of the blending operations or operands, then it must return one of the error codes allowable for the IDirect3DDevice7::ValidateDevice method. Invalid blending operations cannot silently fail the IDirect3DDevice7::ValidateDevice method.


Direct3D Driver Callbacks and Functions

The following subsections list the callbacks that comprise the Windows® 2000 and later Direct3D® DDI. Some callbacks are required, while others are optional and their inclusion in a Direct3D driver depends on the hardware capabilities.

The Direct3D DDI callbacks are prototyped as follows:

typedef DWORD (APIENTRY *LPD3DHAL_MYFUNCTIONCB) (LPD3DHAL_MYFUNCTIONDATA);

where:

  • LPD3DHAL_MYFUNCTIONCB points to a driver-implemented callback that can be called MyFunction. All callback names are pseudo-names decided upon by the display driver writer.
  • LPD3DHAL_MYFUNCTIONDATA is a pointer to a D3DHAL_MYFUNCTIONDATA structure being passed to the callback. Callback parameter structures are characterized as follows:
    • The first member of every structure, dwhContext, is the context handle that describes the 3D context in which the callback should operate. The only exception to this rule is the D3DHAL_CONTEXTCREATEDATA structure.
    • The last member of every structure is ddrval. This member is used to pass the callback's return value back to Direct3D so it can be returned to the calling application.

See Direct3D Driver Initialization to determine how to initialize Direct3D callbacks.


Required Direct3D Driver Callbacks and Functions

The following table lists the Direct3D callback functions that must be implemented in a Direct3D driver.

Required Callback | Description
D3dContextCreate | Creates a context.
D3dContextDestroy | Destroys a context.
D3dCreateSurfaceEx | Creates an association between a texture handle and a surface.
D3dDestroyDDLocal | Destroys all the Direct3D surfaces previously created by D3dCreateSurfaceEx that belong to the same given local DirectDraw object.
D3dDrawPrimitives2 | Renders primitives and returns updated state to Direct3D.
D3dGetDriverState | Returns state information about the driver to DirectDraw and Direct3D run-times.
D3dValidateTextureStageState | Performs texture stage state validation which is required for all drivers that support texturing.

In order to support Direct3D, a driver must minimally support Microsoft DirectDraw® and must also implement certain DirectDraw DDI functions and callbacks. Those pertinent to Direct3D support are listed in the following table:

DDI Function | Description
DrvGetDirectDrawInfo | This function retrieves the capabilities of the graphics hardware. In this initialization function the driver indicates that it supports Direct3D.
DdGetDriverInfo | The run-time queries this callback with GUIDs for additional information about the driver. Several GUIDs pertain specifically to the driver's Direct3D support.

DirectDraw function and callback implementation details are discussed in DirectDraw DDI.


Operation Code Handling

In order to support the Microsoft® DirectX® 7.0 Direct3D driver model, driver writers need to make their drivers respond to a number of new operation codes in their implementation of D3dDrawPrimitives2. Some of these operation codes replace callbacks that were formerly required or conditionally required, and others provide new functionality. The most important new operation codes are summarized in the following table, beginning with those that replace callbacks:

Operation Code | Condition/Description
D3DDP2OP_SETRENDERTARGET | Always required. Maps a new rendering target surface and depth buffer in the current context. Replaces D3dSetRenderTarget.
D3DDP2OP_CLEAR | Always required. Used to clear the context's render target, Z-buffer. Replaces D3dClear2. Also used to clear hardware stencil buffers, and depth buffers that cannot be cleared properly by a depth fill bit-block transfer.
D3DDP2OP_SETPALETTE | Used to map an association between a palette handle and a surface handle, and specify the characteristics of the palette. Only needed for drivers that support paletted textures; otherwise this should be a NOP.
D3DDP2OP_UPDATEPALETTE | Used to make alterations to a texture palette, for drivers that support paletted textures. Otherwise, this should be a NOP.
D3DDP2OP_TEXBLT | Specifies a blt operation from a source texture to a destination texture.

Other useful operation codes are summarized in the D3DHAL_DP2OPERATION description in the reference section.


Return Codes for Direct3D Driver Callbacks

The return value for all driver callbacks must always be one of the following values:

Value | Meaning
D3DHAL_CONTEXT_BAD | The context that was passed in was not valid.
DDHAL_DRIVER_HANDLED | The driver has performed the operation and returned a valid return code for that operation in the ddrval member of the structure passed to the driver's callback. If this code is DD_OK, Direct3D proceeds with the function. Otherwise, Direct3D returns the error code provided by the driver and aborts the function.
DDHAL_DRIVER_NOTHANDLED | The driver has no comment on the requested operation. If the driver is required to have implemented a particular callback, Direct3D reports an error condition. Otherwise, Direct3D handles the operation as if the driver callback had not been defined by executing the Direct3D device-independent implementation. Direct3D typically ignores any value returned in the ddrval member of that callback's parameter structure.
D3DHAL_OUTOFCONTEXTS | There are no more contexts are left in this process.


Direct3D Driver Initialization

When the driver's DrvGetDirectDrawInfo function is called by the Microsoft® DirectDraw® run-time to initialize DirectDraw support, the driver must do the following to indicate its Microsoft® Direct3D® capabilities:

  • Set the DDCAPS_3D flag in the ddCaps.dwCaps member of the DD_HALINFO structure to indicate that the driver's hardware has 3D acceleration.
  • Set any of the following DDSCAPS_Xxx flags in the ddCaps.ddsCaps member of the DD_HALINFO structure that describe the 3D capabilities of a driver's video memory surface:
Flag | Meaning
DDSCAPS_3DDEVICE | Indicates that a driver's surface can be used as a destination for 3D rendering.
DDSCAPS_TEXTURE | Indicates that a driver's surface can be used for 3D texture mapping.
DDSCAPS_ZBUFFER | Indicates that a driver's surface can be used as a Z-buffer.

  • Set the GetDriverInfo member of the DD_HALINFO structure to point to the driver's DdGetDriverInfo callback. The driver must also set the DDHALINFO_GETDRIVERINFOSET flag in the dwFlags member of the DD_HALINFO structure to indicate that it has implemented the DdGetDriverInfo callback.
  • Allocate and initialize the members of the D3DHAL_CALLBACKS structure and return this structure in the lpD3DHALCallbacks member of the DD_HALINFO structure.
  • Allocate and initialize the members of the D3DHAL_GLOBALDRIVERDATA structure and return this structure in the lpD3DGlobalDriverData member of the DD_HALINFO structure.

To indicate that the driver is capable of working with Microsoft DirectX® 7.0 it should do the following:

  • Include the D3DDEVCAPS_DRAWPRIMITIVES2EX flag in the devCaps member of the D3DDEVICEDESC_V1 structure which is reported during Microsoft Direct3D® driver initialization.
  • Respond to the GUID_Miscellaneous2Callbacks GUID in DdGetDriverInfo callback by setting the GetDriverState, CreateSurfaceEx, and DestroyDDLocal members of the DD_MISCELLANEOUS2CALLBACKS structure. These are set to point to the appropriate callbacks for the Direct3D driver and OR'd in the dwFlags member with the DDHAL_MISC2CB32_CREATESURFACEEX, DDHAL_MISC2CB32_GETDRIVERSTATE and DDHAL_MISC2CB32_DESTROYDDLOCAL bits, respectively.

After DrvGetDirectDrawInfo returns, GDI calls the driver's DdGetDriverInfo callback several times for different GUIDs to complete the driver's initialization. The DdGetDriverInfo callback must respond to the following GUIDs to support Direct3D:

GUID_D3DCallbacks3
The driver should allocate and initialize the members of the D3DHAL_CALLBACKS3 structure and return this structure in the lpvData member of the DD_GETDRIVERINFODATA structure.
GUID_Miscellaneous2Callbacks
The driver should allocate and initialize the members of the DD_MISCELLANEOUS2CALLBACKS structure and return this structure in the lpvData member of the DD_GETDRIVERINFODATA structure.
GUID_D3DExtendedCaps
The driver should allocate and initialize the appropriate members of the D3DHAL_D3DEXTENDEDCAPS structure and return this structure in the lpvData member of the DD_GETDRIVERINFODATA structure.
GUID_ZPixelFormats
The driver should allocate and initialize the appropriate members of a DDPIXELFORMAT structure for every Z-buffer format that the driver supports and return these structure(s) in the lpvData member of the DD_GETDRIVERINFODATA structure. The driver must respond to this GUID if it supports the D3DDP2OP_CLEAR operation code in its implementation of D3dDrawPrimitives2.
GUID_D3DParseUnknownCommandCallback
The driver should store the pointer to the Direct3D run-time's D3DParseUnknownCommand callback. The pointer is passed to the driver in the lpvData member of the DD_GETDRIVERINFODATA structure. The driver's D3dDrawPrimitives2 callback will call the D3DParseUnknownCommand callback to parse commands that the driver does not recognize.

See DirectDraw Driver Initialization for details on initializing a DirectDraw driver.


Direct3D Context Management

A context encapsulates all the state information for an application-created Microsoft® Direct3D® hardware abstraction layer (HAL) device; that is, a context describes how the driver should draw. State includes information such as the surface being rendered to, the depth surface, shading information, and texture information.

A Direct3D driver is responsible for creating and managing its own rendering contexts.


Creating a Context

A driver must create and initialize a device-specific context that encapsulates all of the state information it requires to perform rendering. State is not shared between contexts; so the driver must maintain full state information for each context that it creates.

To create a context, the driver should do the following:

  • Allocate the device-specific context and zero-initialize it.
  • See D3DContextCreate for additional steps to be done within that callback. The D3dContextCreate callback is invoked when an application creates a Direct3D HAL device. The driver must implement this callback.

The driver must be able to reference all texture handles created by D3dCreateSurfaceEx within a created context. This enables the driver to clean up all driver-specific data related to textures created within this context when a call to D3dContextDestroy is made.


Deleting a Context

Direct3D calls the D3dContextDestroy callback when an application requests that a Direct3D HAL device be destroyed. The driver should free all resources it allocated to the specified context.


Maintaining State Within a Context

A driver updates its internal state associated with a context when its D3dDrawPrimitives2 callback is called. This callback must also return the updated context's public state to Direct3D. See D3dDrawPrimitives2 for more information about processing and updating state.


Overview of Direct3D Surface Handles

The Microsoft® DirectX® 7.0 device driver interface (DDI) is designed to promote a model whereby the Direct3D run-time components parse as little of the command stream as possible before handing the commands to the driver. Additionally, the command stream should be formatted so that it can be directly consumed by future hardware.

One important change directed towards these goals is the movement of all surface-related data out of intermediate structures owned by the Direct3D/DirectDraw® run-time into structures owned, updated, and formatted by the driver.

Surfaces are referred to by handles embedded in the command stream. In these high-frequency operations, the driver can look up its own representation of a surface from the handle, without resorting to locking a surface via helper functions such as EngLockDirectDrawSurface.

The mechanism for assigning these handles is a new driver entry point called D3dCreateSurfaceEx. This entry point is called directly after calls to the existing DdCanCreateSurface and DdCreateSurface entry points, and after a video memory address and handle have been assigned to a surface. At D3dCreateSurfaceEx time, the driver can copy all pertinent information out of the DirectDraw run-time’s copy of the surface structure and into its own surface structure. Surface data such as size, format, and fpVidMem (a member of the DD_SURFACE_GLOBAL structure) are obvious candidates for which driver-side copies would be required.

Handles are guaranteed by the run-time to be unique per device and per process. Handles are not guaranteed to be unique per context, and this has some implications for drivers that will be discussed in greater detail in Creating Driver-Side Surface Structures.

There is no corresponding DestroySurfaceEx call, so driver-side surface structures are destroyed at DdDestroySurface time.


Creating Driver-Side Surface Structures

The DirectDraw run-time will call the driver’s D3dCreateSurfaceEx entry point after it has called the DdCreateSurface entry point and allocated memory for the surface. The run-time calls D3dCreateSurfaceEx only for those surfaces tagged with DDSCAPS_TEXTURE, DDSCAPS_EXECUTEBUFFER, DDSCAPS_3DDEVICE, or DDSCAPS_ZBUFFER flags.

Before calling D3dCreateSurfaceEx, the run-time will assign an integer value as a handle to the surface. This value will be stored in the dwSurfaceHandle member of the DDRAWI_DDSURFACE_MORE structure (as pointed to by the lpSurfMore member of the DDRAWI_DDSURFACE_LCL structure). See DD_SURFACE_MORE and DD_SURFACE_LOCAL, which are aliases for the DDRAWI_DDSURFACE_MORE and DDRAWI_DDSURFACE_LCL structures.

These integer values start at one and are kept as small as possible. (Zero is a guaranteed invalid value for a surface handle.) The intention is that a driver can keep an array of pointers into its own structures. As soon as it receives a handle (when D3dCreateSurfaceEx is called) that is beyond the end of the array, it can reallocate the array and continue. The Direct3D run-time will pass no handle value to the driver before that handle is shown to the driver via D3dCreateSurfaceEx. However, the driver should be robust enough to handle values that are out-of-range, or that refer to a slot in the handle table that has been freed (that is a handle for which DdDestroySurface has been called). Note that since zero is a guaranteed invalid value, the zero entry in the handle table can be reused for other purposes. The perm3 sample driver uses the zero entry to store the current length of the array.


Pointers to DirectDraw Surfaces

Driver writers might be tempted to keep just a pointer to the DirectDrawSurface data structures inside their private driver-side surface structures. This practice will not succeed on Microsoft® Windows® 2000 and later, since access to DirectDraw’s kernel-side data structures is mediated through a management scheme that insulates these structures from user mode and from drivers. This is why EngLockDirectDrawSurface exists: it provides a pointer to the structure that is valid for a brief time; until the EngUnlockDirectDrawSurface routine is called.

Outside of this lock/unlock pair, the structure is not guaranteed to reside at the same location, nor even to exist. Additionally, these lock/unlock pairs impede performance. If the driver keeps its own copies of the surface structures, then the locks are not needed. Updates to data within the driver-side surface structures are made during low-frequency calls like D3dCreateSurfaceEx. The result is that less code must be executed during high-frequency calls like D3dDrawPrimitives2.


D3dCreateSurfaceEx Handles

Certain situations can cause D3dCreateSurfaceEx to be called for an invalid, destroyed surface. Drivers can robustly handle this case by simply ignoring any D3dCreateSurfaceEx call for a video memory surface that has an fpVidMem (a member of the DD_SURFACE_GLOBAL structure) of zero. However, a driver can get a D3dCreateSurfaceEx call with a system memory surface which has an fpVidMem value of zero, which means that the system memory surface is in the process of being destroyed. The driver should then free any existing driver-side data related to this surface.


D3dCreateSurfaceEx and Backing Surfaces

D3dCreateSurfaceEx is also called for backing surfaces. This allows the driver to allocate a driver-side structure for the surface and thus respond to the D3DDP2OP_TEXBLT token for a system to video texture download.

It is very important that the driver not fail D3dCreateSurfaceEx for backing surface formats for which it does not support the pixel format. Such surfaces may be created for use with the software rasterizer. The driver should simply ignore backing surfaces it does not support. (Alternatively, the driver can create a driver-side structure, but the corresponding handle will never subsequently be sent to the driver.) Failing D3dCreateSurfaceEx for these surfaces will cause a failure code to be propagated to the application and the driver can potentially affect an emulation-only application. A driver’s response to such situations can be tested by running the ddtest.exe application on the DirectX 7.0 SDK. Run the program and try to create a backing surface texture of a format unsupported by the driver, but supported by the DirectDraw emulation layer (a list of these formats can be found in the DirectDraw SDK documentation).


D3dCreateSurfaceEx and Complex Surfaces

As explained in Creating and Destroying DirectDraw Surfaces in the DirectDraw DDK documentation, creation of a complex surface causes an array of surfaces to be passed to DdCreateSurface. However, even in complex cases, only a pointer to the root surface is passed to D3dCreateSurfaceEx. It is necessary for the driver to go through the attachment lists of the root surface and create driver-side copies for all attached surfaces. This can be a tricky operation if the driver is attempting to handle creations for cube maps, MIP maps, and so on.

There are two types of DirectDraw surface attachments, implicit and explicit. An implicit attachment is formed during a complex surface creation. For example, when creating a primary flipping chain, the primary and back buffer are created by a single CreateSurface API call and they are attached to one another implicitly by the CreateSurface call. Another example is a MIP map chain where a series of MIP maps are created by a single CreateSurface API call. An explicit attachment is formed when surfaces created from different CreateSurface calls are attached explicitly by AddAttachedSurface.

The style of attachment has an implication for D3dCreateSurfaceEx processing. When two surfaces are explicitly attached, then both of those surfaces were created by separate calls to CreateSurface and each surface will have resulted in a call to D3dCreateSurfaceEx before the surface attachment was made. However, in the case of an implicitly attached surface, only a single CreateSurface and D3dCreateSurfaceEx call is made for the entire chain of surfaces. Therefore, when processing a D3dCreateSurfaceEx call a driver must run the attached list of surfaces to identify handles, and create driver side data structures for each attached surface. However, the attached surface list may contain a mixture of implicitly and explicitly attached surfaces. The driver will already have been notified of explicitly attached surfaces by D3dCreateSurfaceEx and probably will not want to process such surfaces again.

The driver can distinguish between implicit and explicit attachments by means of the DDAL_IMPLICIT flag stored in the dwFlags field of the DD_ATTACHLIST data structure. If DDAL_IMPLICIT is set in the dwFlags field the attachment is implicit and no separate D3dCreateSurfaceEx call will be seen for the attached surface. If this flag is not set the attachment is explicit and the attached surface will result in its own D3dCreateSurfaceEx call. By examining this flag, the driver can determine whether it needs to process an attached surface as part of the parent surface's D3dCreateSurfaceEx call or whether a separate D3dCreateSurfaceEx call will have been made for the attached surface.

For more information, see the section on surface attachments in DirectDraw Driver Fundamentals, and see the sample code included in D3dCreateSurfaceEx.


D3dCreateSurfaceEx and MIP Maps

Each level in a MIP map is associated with a different handle value. There is no guarantee that these handles will be consecutive, however. The Direct3D DDI is designed so that only the top-level surface’s handle is passed as an argument in the IDirect3DDevice7::SetTexture API method (described in the Direct3D SDK documentation), and then the current level-of-detail is specified by a texture stage state (D3DTSS_MAXMIPLEVEL). The most natural way to work with MIP maps is to build one driver-side structure that represents the entire MIP map.


D3dCreateSurfaceEx Handles and Flip

DirectDraw’s surface structures are designed to represent conceptual surfaces, not necessarily specific locations in video memory. The main usage of this abstraction is in a primary flipping chain, where the application uses one constant surface object to represent the back buffer, even though the back buffer may be moving around in video memory as a result of the DdFlip operation.

The DdFlip method takes a ring of surfaces, and rotates (sequentially reassigns) their video memory pointers around this ring. In the particular case of two surface objects, the process is reduced to trading their video memory pointers. In addition, the DirectDraw run-time also rotates the D3dCreateSurfaceEx handles associated with each surface, and the driver-owned contents of the dwReserved1 members of each surface. This behavior has some interesting consequences for a DirectX 7.0 driver, and effectively rules out the embedding of pointers to DirectDraw’s surface structures inside the driver’s own surface structures.

Consider two surface objects A and B that have associated handles HA and HB, and fpVidMem (a member of the DD_SURFACE_GLOBAL structure) values of FA and FB. Further, suppose that the application is using surface structure A to refer to the back buffer of a flipping chain. At DdFlip time, the handles and both fpVidmem values are swapped, so that surface A has HB and FB, and surface B has HA and FA. The application now tries to draw to the back buffer, surface A, which should represent the video memory at FB (because the application called DdFlip).

A drawing command is issued to the driver, which looks up the handle associated with that surface (which is now HB, not HA). What would happen if the driver merely stored a pointer to the DirectDraw surface structure? The driver would look up HB, then follow the stored pointer to surface B, which now has an fpVidMem value of FA. Drawing would begin on the video memory at FA. This is not what the application is expecting. If, on the other hand, the driver were to store surface data in its own structures, rather than following a pointer to DirectDraw’s surface structure, then HB would still resolve to FB, and drawing would occur on the correct surface. This latter case is the way the current DDI is implemented.


D3dCreateSurfaceEx Handles and DirectDraw DDIs

Handles do not completely insulate a DirectX 7.0 driver from the DirectDraw-managed DDRAWI_DDSURFACE_MORE and DDRAWI_DDSURFACE_LCL structures. These structure names are essentially aliases for the structures DD_SURFACE_MORE and DD_SURFACE_LOCAL. In DirectDraw DDIs, such as DdBlt, DdFlip, the driver will still be passed surface structure pointers, and still must be able to use these structures instead of its private representations.


Points to Consider when Restoring Complex Flipping Chains

When a complex primary surface is created, it might or might not have an attached Z-buffer. When a surface is restored, it is possible that the application has added an attachment to a Z-buffer. Driver writers should be mindful of these different scenarios when going through surface attachment lists in D3dCreateSurfaceEx. A typical technique, presented in the perm3 sample driver, is to mark a surface’s dwReserved1 field when D3dCreateSurfaceEx is called for that surface. The driver only marks the surface if fpVidMem (a member of the DD_SURFACE_GLOBAL structure) is not equal to zero. This is because fpVidMem could be zero because the application restored a primary surface that had a back buffer with an explicitly attached Z-buffer, but the Z-buffer had not yet been restored. At some later time, the application will restore the Z-buffer, and the driver can then mark it. Note that if the application restores the Z-buffer before restoring the primary chain, the driver may receive the Z-buffer, already marked, attached to the back buffer when D3dCreateSurfaceEx is called.


Lost Surfaces, Surface Handles, and Contexts

The concept of lost surfaces was introduced in the DirectDraw SDK documentation. Lost surfaces have some implications in the DirectX 7.0 DDI model. See Lost Surfaces and Atomic Restoration for more details.

It is necessary for some surfaces to be referred to in a context (such as the render target, Z-buffer, or a texture), typically by storing the handles for those surfaces in the driver’s context. These surfaces may become lost, which means destroyed, as far as the driver is concerned. The context itself may survive, but may now have “stale” (invalid) handles to destroyed surfaces. The run-time guarantees that no rendering commands will be passed to the context while it is in this state, but there is still the problem of how to re-associate the context with restored surfaces before rendering can begin again. The run-time guarantees that the handles for lost surfaces do not change. This in turn guarantees that if a context keeps handles to its surfaces (render target, Z, and textures), then it need not worry that the surface objects referred to by these handles have been destroyed. These surfaces will always be recreated (restored) with the same handle values before rendering can resume on this context.

Some driver writers may wish to optimize the state of a context by storing surface data directly in the context, rather than doing the work of dereferencing the handles on every D3dDrawPrimitives2 call. Since the cost of this dereference is likely to be very small compared to the cost of executing a batch of D3dDrawPrimitives2 tokens, this optimization is not encouraged. However, if driver writers wish to do so, then they must be aware that surfaces may move when they are restored. This means that while the handle may be the same, there is no guarantee that a surface will be restored with the same fpVidMem (a member of the DD_SURFACE_GLOBAL structure) pointer with which it was created. Contexts that are optimized in this way may end up with “stale” (invalid) video memory pointers, and have no information that the surface has moved. Dealing with this can be fairly tricky, but several methods are possible. One method to deal with this is that the driver may tag any surface when it is associated with a context (as render target, Z-buffer, or texture). Then at D3dCreateSurfaceEx time, it can search for any context that refers to this surface and then update that context.

It is not recommended that a surface keep a pointer to a context, since one surface may be associated with more than one context.


Direct3D Texture Management

Although texture support is optional, most of today's drivers are capable of supporting it. Drivers that support texture mapping must respond to all of the texture-related operation codes in the Microsoft® Direct3D® DDI.

Drivers must also validate the texture stage states with the D3dValidateTextureStageState callback.


Multitexturing

Direct3D drivers can support the simultaneous use of multiple textures. This multiple texture support is enabled in the driver using texture stage state types (D3DTEXTURESTAGESTATETYPE, described in the DirectX SDK documentation). These allow all the properties of a texture to be defined and combined with vertex extensions that specify independent sets of texture coordinate data.

Adding multitexture support for Direct3D drivers requires setting the correct capability bits (Caps), implementing texture blending, and implementing D3dValidateTextureStageState.

To be compliant with DirectX 6.0 and later versions, a driver is required to properly parse up to eight texture coordinate sets, even if the device can only iterate and use the number or coordinates defined in dwFVFCaps (a member of the D3DHAL_D3DEXTENDEDCAPS structure). The driver uses D3DTSS_TEXCOORDINDEX(s) to get the correct coordinates to use for texturing.

Flexible vertex formats (FVF) allow multitexturing because they make it possible to pass more than one texture coordinate in the vertex structure. Multiple textures can then be blended together in an iterated process and applied to a piece of geometry.

Texture handles are no longer generated by Direct3D drivers. Instead, the texture handles are generated by the Direct3D run-time. Texture cache management is done completely by the Direct3D run-time so that, to the driver, textures always appear to come from the application itself. All texture state is sent to the driver in the D3dDrawPrimitives2 command stream.

With the addition of multitexture, the methods for blending and texture filtering have also been refined to make possible a much clearer and well-defined mechanism for blending. For more information on these blending and texture filtering mechanisms, see the Microsoft DirectX® SDK documentation.


Texture Stages

The texture stage indicates the location of the texture in the texture pipeline. The position with the highest non-NULL texture is closest to the frame buffer. Each stage is a texture blending unit that performs the operation used to combine an associated texture onto a polygon, as shown in the following figure.

A Single Texture Stage

The current texture enters the stage and is blended with another texture and a diffuse component with the result being passed forward to the next stage in the texture pipeline (or frame buffer if this is the last stage).

There are eight texture stages, numbered zero through seven, with zero being furthest to the frame buffer, and corresponding to the render state texture handle D3DRENDERSTATE_TEXTUREHANDLE, described in the DirectX SDK documentation. The driver must handle up to eight texture coordinates, even if the hardware does not support that many.

In multiple texture rendering, the lower-numbered texture stages are farther away from the frame buffer. The lowest texture stage in the cascade is picked up and filtered to get a texel, or texture element. A blending operation occurs between that texel and the next as it cascades down the texture pipeline toward the frame buffer.

For example, if two textures, Texture0 and Texture1, are blended together, the resulting texel enters the rasterization pipeline just as a single texture would using legacy texturing. With three textures, Texture0 gets blended with Texture1. The resulting texel is then blended with Texture2 according to some (programmable) weight. This means that Texture0 cannot influence Texture2 directly; it can only do so by proxy, by being blended with Texture1. This latter example is illustrated in the following figure.

A Three Stage Texture Pipeline

Each texture stage introduces no more than one texture into the pipeline. The pixel pipeline is separate and comes after multitexture operations. This may include fog application or frame buffer alpha blending.


Command Stream

At the driver level, instructions come in the form of calls to D3dDrawPrimitives2. The input structure D3DHAL_DRAWPRIMITIVES2DATA contains a pointer into a command buffer. This is a sequence of D3DHAL_DP2COMMAND structures. Each of these structures contains a bCommand member which specifies what type of data follows it in the buffer. This specification comes in the form of a D3DHAL_DP2OPERATION enumerated type, such as D3DDP2OP_INDEXEDTRIANGLESTRIP or, in the case of setting up texture states, D3DDP2OP_TEXTURESTAGESTATE. (See D3DHAL_DP2OPERATION for a complete listing of these enumerators.)

In other words, the D3DHAL_DP2OPERATION operation code simply specifies what type of structures follow it in the command buffer. The number of structures to follow is specified by either wPrimitiveCount or wStateCount, members of a union that is in turn a member of the D3DHAL_DP2COMMAND structure. The wPrimitiveCount member keeps track of the number of graphics primitives to render, while the wStateCount member keeps track of the number of state changes to process.

For example, if the operation code is D3DDP2OP_TEXTURESTAGESTATE, and the value of wStateCount is seven, then seven D3DHAL_DP2TEXTURESTAGESTATE structures will follow before the next D3DHAL_DP2COMMAND instruction is reached. To carry this example to completion, each D3DHAL_DP2TEXTURESTAGESTATE structure contains a dwStage member that specifies which stage of the texture blending pipeline needs to have a texture state change. The TSState member of the same structure specifies which state of the D3DTEXTURESTAGESTATETYPE enumerated type to set, and the dwValue member of the D3DHAL_DP2TEXTURESTAGESTATE structure contains the value to which the specified state should be set.

The process is the same for all render states, or any other type of instruction. If the bCommand member of the D3DHAL_DP2COMMAND structure is D3DDP2OP_RENDERSTATE, then the structure to follow is a D3DHAL_DP2RENDERSTATE structure and the information in that structure is used to set the render state accordingly.

Rather than using distinct Boolean-valued render states to control the coordinates, each render state value is a set of flags composed with the D3DWRAP_U and D3DWRAP_V flags (defined in d3dtypes.h). This change was made for compatibility with higher-dimensional textures.

Other useful information pertaining to multitexture implementation can be found in the DirectX SDK documentation, in the sections covering blend equations, semantics of per-texture states, color operations, and alpha operations. For more information about the texture stage state types enabled for DirectX 6.0 and later versions, see the D3DTEXTUREOP, D3DTEXTUREMAGFILTER, D3DTEXTUREMINFILTER, and D3DTEXTUREMIPFILTER enumerated types.


Texture Addressing and Filtering Operations

In Direct3D, texture addressing, filtering, and blending operations are performed by a separate logical unit called a texture stage. Addressing and filtering operations are described here because they form a logical grouping independent of the blending operations. For further information about texture operations, see the D3DTEXTUREOP enumerated type in the DirectX SDK documentation.

Although addressing and sampling operations are defined in conjunction with blending operations in DirectX 6.0 and later versions, in later releases of DirectX they are likely to be independent of the blending operations. The following texture stage states are used to set up texture addressing and filtering operations for each stage in the texture pipeline:

Operation | Description
D3DTSS_ANISOTROPY | Specifies the anisotropic filtering ratio limit. It specifies the maximum aspect ratio of anisotropic filtering to be applied during sampling of this texture.
D3DTSS_MAGFILTER | Defines the type of filter used to sample textures when they are being magnified (that is, when one texel is getting stretched onto multiple rendering surface pixels). The filters that can be used for texture magnification are enumerated in D3DTEXTUREMAGFILTER.
D3DTSS_MAXMIPLEVEL | Specifies the maximum MIP map level to be used. It indicates that this texture should never sample MIP map levels that are larger that the one indicated. Therefore, the maximum dimension is 2 MAXMIPLEVEL. Zero indicates that there is no limit.
D3DTSS_MINFILTER | Defines the type of filtering that is used to sample textures when they are being minified, that is, one texel is mapped onto less than one screen pixel. The filters that can be used for texture minification are enumerated in D3DTEXTUREMINFILTER.
D3DTSS_MIPFILTER | Defines the type of filtering that is used to sample between layers of a MIP map. The filters that can be used for this are enumerated in D3DTEXTUREMIPFILTER.
D3DTSS_MIPLEVEL | Allows application to set the MIP level when hardware cannot. This is overridden when the MIP level is determined by hardware.
D3DTSS_MIPMAPLODBIAS | Is a D3DVALUE that specifies the MIP map level of detail (LOD) bias. This bias affects the MIP map level calculation, allowing more or less blurring of textures (and more aliasing) as desired. Units are in MIP levels. Current WHQL/DCT tests require the MIP map LOD bias to operate in the range -3.0 to 3.0.
D3DTSS_TEXCOORDINDEX | Specifies the index of a texture coordinate set. This integer indicates the index of the set of texture coordinates from which the addressing unit should sample. These coordinates are listed in the incoming flexible vertex format (FVF) vertex data in numerical order, with zero being the standard DirectX set of texture coordinates, one being a second texture coordinate set, and so on. This allows textures to share sets of texture coordinates as desired.

Important To be Direct3D-compliant, drivers are required to properly parse up to eight texture coordinate sets, even if the device can only iterate and use the number of coordinates defined in dwFVFCaps. The driver must use D3DTSS_TEXCOORDINDEX(s) to grab the right coordinates to use for texturing.


Texture Stage Operations

An application performs blending operations for texture stages by calling the IDirect3DDevice7::SetTextureStageState method (described in the Direct3D SDK documentation). Multitexture blending operations are performed by a set of texture blending unit stages. Each of these can be individually programmed to carry out a variety of texture blending operations, selected by a parameter.

Direct3D does not provide a mechanism for specifying more than one texture being introduced at each blending stage. Saturation is defined to occur between texture stages in the pipeline, but it should occur as late as possible within each stage.

The set of legal operations is enumerated in D3DTEXTUREOP. These operations are required for PC98 compatibility compliance:

  • D3DTOP_DISABLE
  • D3DTOP_SELECTARG1, D3DTOP_SELECTARG2
  • D3DTOP_MODULATE
  • D3DTOP_ADD
  • D3DTOP_BLENDTEXTUREALPHA

The default values are D3DTOP_MODULATE for stage one, and D3DTOP_DISABLE for all other stages. D3DTOP_MODULATE is used for stage one for backwards compatibility, but by default all texturing should be disabled.


Texture Stage Arguments

Each of the multitexture blending operations combines two inputs. These can be selected by calling the IDirect3DDevice7::SetTextureStageState method (described in the Direct3D SDK documentation) and specifying one of the following members of the D3DTEXTURESTAGESTATETYPE enumerated type:

Enumerator | Meaning
D3DTSS_ALPHAARG1 | Controls first input to alpha operation.
D3DTSS_ALPHAARG2 | Controls second input to alpha operation.
D3DTSS_COLORARG1 | Controls first input to color operation.
D3DTSS_COLORARG2 | Controls second input to color operation.

Texture Argument Flags

At each texture stage, any of the preceding four parameters can be set using the following texture argument flags:

Flag | Meaning
D3DTA_CURRENT | The texture argument is the result of the previous blending stage. In the first texture stage (stage zero), this argument is equivalent to D3DTA_DIFFUSE. This can be thought of as the current color of the polygon as each texture is composited onto it. If the previous blending stage uses a bump-map texture (the D3DTOP_BUMPENVMAP operation), the system chooses the texture from the stage before the bump-map texture. (If s represents the current texture stage, and s - 1 contains a bump-map texture, this argument becomes the result output by texture stage s - 2.)
D3DTA_DIFFUSE | The iterated color data obtained from the Gouraud interpolators. This is often used as the ARG2 on the first texture, since there is no D3DTA_CURRENT texture color at that point.
D3DTA_TEXTURE | The texture bound to this texture stage using the IDirect3DDevice7::SetTexture(n, lpTex3) method (described in the Direct3D SDK documentation), where n is the stage number. IDirect3DDevice7::SetTexture defines which texture object to use for the texture in this stage when D3DTA_TEXTURE is one of the arguments. D3DTA_TEXTURE can only be present in D3DTSS_ALPHAARG1 and D3DTSS_COLORARG1, but not in D3DTSS_ALPHAARG1 and D3DTSS_COLORARG2.
D3DTA_TFACTOR | A value set in Direct3D with D3DRENDERSTATE_TEXTUREFACTOR. Note: Some implementations may not be able to simultaneously use both D3DTA_TFACTOR and a D3DTA_DIFFUSE color.

Modifier Flags

These two values should be combined with one of the preceding flags using the bit-wise OR operator.

Value | Meaning
D3DTA_ALPHAREPLICATE | Indicates that this argument should have its alpha channel replicated to all color channels before use in this operation. If this is a texture with only one component, it is automatically replicated to all color channels for these operations. This flag need not be specified for the ALPHA_ARGs, but using it does not produce an error.
D3DTA_COMPLEMENT | Indicates that this argument should be inverted for the operation.

Defaults

The following default values are used if a state is not filled in by the application. While these default values have been defined to make multitexture operations more convenient, robust code always fully specifies the desired state.

D3DTSS_COLORARG1 and D3DTSS_ALPHAARG1 both default to D3DTA_TEXTURE, if the corresponding texture has been set. If no texture has been set for this stage, then these both default to D3DTA_DIFFUSE.

D3DTSS_COLORARG2 and D3DTSS_ALPHAARG2 default to D3DTA_CURRENT. Note that D3DTA_CURRENT defaults to D3DTA_DIFFUSE on the first stage (except as noted in the description of D3DTA_CURRENT).

ARG2 defaults to D3DTA_DIFFUSE, but is ignored because the operation defaults to D3DTOP_SELECTARG1.

D3DTA_DIFFUSE defaults to 0xFFFFFFF if no diffuse color is specified in the flexible vertex format (FVF) data.

D3DTA_SPECULAR defaults to 0x00000000 if no specular color is specified in the FVF data.

D3DTA_CURRENT defaults to D3DTA_DIFFUSE if this is the first stage except when the previous blending stage is a D3DTOP_BUMPENVMAP or D3DTOP_BUMPENVMAPLUMINANCE color operation. In this case, the following occurs:

  • If the previous stage is D3DTOP_BUMPENVMAP or D3DTOP_BUMPENVMAPLUMINANCE, then this argument is the result of the stage before the previous stage.
  • In the second texture stage (stage one), this argument defaults to D3DTA_DIFFUSE.

D3DTA_TEXTURE is a value for a D3DTSS_COLORARG1 or D3DTSS_ALPHAARG1 state of any stage, or defaults to 0x0 if no texture is bound to this stage.


Multitexture Validation

Current hardware does not necessarily implement everything that Direct3D can express. The application determines whether a particular blending operation can be performed by first setting up the desired blending mode, and then calling the IDirect3DDevice7::ValidateDevice method (described in the Direct3D SDK documentation). The driver must accurately report its capabilities at initialization time and support D3DValidateTextureStageState to allow its capabilities to be validated. Validation also covers operations specified at the TBLEND level.

IDirect3DDevice7::ValidateDevice Return Codes

Return Code | Meaning
CONFLICTINGTEXTUREFILTER | The hardware cannot do trilinear filtering and multitexture at the same time.
TOOMANYOPERATIONS | The hardware cannot handle the specified number of options.
UNSUPPORTEDALPHAARG | The specified alpha argument is unsupported.
UNSUPPORTEDALPHAOPERATION | The specified alpha operation is unsupported.
UNSUPPORTEDCOLORARG | The specified color argument is unsupported.
UNSUPPORTEDCOLOROPERATION | The specified color operation is unsupported.
UNSUPPORTEDFACTORVALUE | The hardware cannot support D3DTA_TFACTOR greater than 1.0.
WRONGTEXTUREFORMAT | The hardware cannot support the current state in the selected texture format.


Paletted Textures

Direct3D also allows palettes to be used with textures. A palette can be attached to a texture, just as it can to any other DirectDrawSurface object. To support paletted textures, drivers must respond to the D3DDP2OP_SETPALETTE and D3DDP2OP_UPDATEPALETTE operation codes in their implementation of D3dDrawPrimitives2. These operation codes are followed by D3DHAL_DP2SETPALETTE and D3DHAL_DP2UPDATEPALETTE structures, respectively, in the command stream. D3DDP2OP_SETPALETTE creates an association between a palette handle to be used and a surface handle (already created by D3DCreateSurfaceEx). Later, D3DDP2OP_UPDATEPALETTE can be sent multiple times to set the values of the palette entries to be used for this texture.


Texture Blitting

An important change to the Direct3D DDI, which takes effect as of DirectX 7.0, is that textures are blitted - not by a direct call to DdBlt - but by embedding a new token in the D3dDrawPrimitives2 command stream. This new token is D3DDP2OP_TEXBLT, and it signals the driver that a texture has to be transferred from a backing surface into local or non-local video memory.

Also, instead of the driver being responsible for creating internal handles for textures through the legacy D3dTextureCreate and D3dTextureDestroy callbacks, the run-time now assigns a handle number to each DirectDrawSurface object that is created within the Direct3D context. The driver is signaled about this handle number through the D3dCreateSurfaceEx callback.

D3dCreateSurfaceEx is called after every hardware abstraction layer (HAL) DDCreateSurface call is finished. D3dCreateSurfaceEx is also called after every internal hardware emulation layer (HEL) CreateSurface call is finished. The HEL call usually occurs when a backing DirectDrawSurface object is created. These calls may occur before and after a Direct3D context is created with D3dContextCreate.

Also, when the application is running, a call is made to D3dDestroyDDLocal to clean up and destroy any driver data created explicitly for these surfaces. This call is also made before a Direct3D context is created. This is done to ensure that there are no dirty handles associated with any contexts that have not been cleaned up. This is simply a preventative measure which should not actually destroy anything if contexts are properly cleaned up after use.


Driver-Managed Textures

The driver can optionally manage textures which have been marked as manageable. These DirectDrawSurface objects are marked as manageable with the DDSCAPS2_TEXTUREMANAGE flag in the dwCaps2 member of the structure referred to by lpSurfMore->ddCapsEx. (lpSurfMore and ddCapsEx are members of the DD_SURFACE_LOCAL and DD_SURFACE_MORE structures, respectively.)

The driver makes explicit its support for driver-managed textures by setting the dwCaps2 member of the DD_HALINFO structure to DDCAPS2_CANMANAGETEXTURE. DD_HALINFO is returned by DrvGetDirectDrawInfo in response to the initialization of the DirectDraw component of the driver.

The driver can then create the necessary surfaces in video or non-local memory in a "lazy" fashion. That is, the driver leaves the textures in backing surfaces until it requires them, which is just before rasterizing a primitive that makes use of the texture.

Surfaces should be evicted primarily by their priority assignment. The driver should respond to the D3DDP2OP_SETPRIORITY operation code in the D3dDrawPrimitives2 command stream. This opcode sets the priority for a given surface. As a secondary measure, it is expected that the driver will use a least-recently-used (LRU) scheme. This scheme should be used as a tie breaker, whenever the priority of two or more textures is identical in a particular scenario. Logically, any surface that is in use should not be evicted at all.

If a driver supports managed surfaces, then the driver may receive a special DdDestroySurface call for a managed surface in the case where video memory is lost, such as when a mode switch occurs. In this case the DRAWISURF_INVALID flag is set and the driver should simply evict the video memory copy of this managed surface and keep other structures intact. Otherwise, the driver should perform a regular destroy surface call.

The driver must be cautious of honoring DdBlt and DdLock calls when managing textures. This is because any change to the backing surface image must be propagated into the video memory copy of the surface before the texture is used again. The driver should determine if it is better to update just a portion of the surface or all of it.

The driver is allowed to perform texture management in order to perform optimization transformations on the textures or to decide for itself where and when to transfer textures in memory.


Primitive Drawing and State Changes

All Microsoft® Direct3D® primitives and state are passed to the D3dDrawPrimitives2 callback in command and vertex buffers. The driver is responsible for parsing these buffers and processing all drawing and state change requests.

The sections that follow discuss the layout of command and vertex buffers and describe how the driver should process them.


Command and Vertex Buffers

The D3dDrawPrimitives2 DDI uses two types of buffers: command buffers and vertex buffers. (See D3DHAL_DRAWPRIMITIVES2DATA for a description of the main input structure.) Command buffers contain instructions followed by data in a structure similar to that of execute buffers. Command buffers might contain indexed and non-indexed primitives and, occasionally, inline vertex data. Command buffers can be either API-level execute buffers or Direct3D internal command buffers.

With internal command buffers, the driver allocates the memory and may do multi-buffering. Internal command buffers are write-only. The instruction format can be seen in D3DHAL_DP2COMMAND.

If the D3DHALDP2_USERMEMVERTICES flag is set, the vertex buffer is specified by a user-memory pointer. Otherwise the vertex buffer is a DirectDrawSurface which can be an API-level execute buffer, an internal implicit vertex buffer, or an API-level vertex buffer.

The vertex buffer API can create, destroy, lock and unlock vertex buffers, and can use the IDirect3DVertexBuffer7::ProcessVertices method to process vertices from source to destination buffers. The IDirect3DDevice7::DrawPrimitiveVB and IDirect3DDevice7::DrawIndexedPrimitiveVB methods are the primary API-level calls. Vertex buffers can also be optimized, but optimized vertex buffers cannot be locked. See the Direct3D SDK documentation for descriptions of these three methods.

Note to Windows 98/Me Driver Writers

When you place a vertex buffer in video memory, it must be located in one of the heaps you reported to the DirectDraw/Direct3D runtime at initialization time. If the vertex buffer (whose pointer you return to the runtime) does not lie in one of the reported heap ranges, the runtime will deallocate the vertex buffer and create a new one in system memory.

The reason for this requirement is that on Windows 98/Me, the runtime holds the Win16Lock on the vertex buffer at all times. (If the runtime constantly locked and unlocked the vertex buffer, performance would suffer.). However , to ensure that the operating system works correctly, the Win16Lock can be held only for relatively short periods of time.

The only way to avoid the runtime holding the Win16Lock for video memory surfaces is to use virtual memory aliasing of the video memory, in particular the heaps. It is these heaps that are aliased by the runtime. Therefore, only video memory that lies in one of these heaps can be locked without holding the Win16Lock. It is important to note that this check for video memory pointers that can be aliased occurs when command and vertex buffers are swapped in response to a D3dDrawPrimitives2 call to your driver, as well as at the time they are created.

This requirement does not apply to Windows 2000 and later. The Win16Lock and the video memory aliasing to avoid locking are specific to Windows 98/Me.


Command and Vertex Buffer Allocation

There are three types of buffers used in Direct3D:

  • Implicit vertex buffers (IVBs) are created for internal use only; that is, applications are unaware of IVBs. One IVB is always created after context creation. Direct3D stores vertex data in IVBs.
  • Explicit vertex buffers (EVBs) are created only in response to an application request. Direct3D then stores vertex data in EVBs.
  • Command buffers are created for internal use only; that is, applications are unaware of command buffers. Direct3D stores command data in command buffers.

Implicit vertex buffers are special vertex buffers used internally by Direct3D for batching. They are created during device initialization and can be multibuffered. They are always read/write so they should not be put in video memory (for Microsoft DirectX® 6.0 and the later versions). This type of buffer is marked by the absence of both the DDSCAPS2_VERTEXBUFFER and DDSCAPS2_COMMANDBUFFER flags.

Explicit vertex buffers are created and controlled by the application. These cannot be multibuffered and cannot be put into local or non-local video memory unless the DDSCAPS_WRITEONLY flag is set. Explicit vertex buffers are marked with DDSCAPS_VERTEXBUFFER.

Command buffers are used by Direct3D to batch commands. They can be multibuffered and are used for all APIs except for TLVERTEX or unclipped execute-buffer API calls. This type of buffer is marked by the flag DDSCAPS2_COMMANDBUFFER. They are always write-only, though no explicit flag is set and they never contain invalid instructions.

By default, the Direct3D run-time allocates all of these buffers. IVBs and command buffers are accessed through the surfaces with which they are associated. All buffers are passed to the driver's D3dDrawPrimitives2 callback.

Driver-Allocated Vertex and Command Buffers

A Direct3D driver can optionally perform the allocation of vertex and command buffers. This is done by fielding a DD_D3DBUFCALLBACKS structure and pointing the lpD3DBufCallbacks member of the DD_HALINFO structure at it. The callbacks reported in the DD_D3DBUFCALLBACKS structure include:

CanCreateD3dBuffer

CreateD3dBuffer

DestroyD3dBuffer

LockD3dBuffer

UnlockD3dBuffer

These functions are called in the same way as the Dd Xxx Surface callbacks (such as DdCanCreateSurface) and only when the DDSCAPS_EXECUTEBUFFER flag is set. The buffer creation flags are DDSCAPS_WRITEONLY, DDSCAPS2_VERTEXBUFFER, and DDSCAPS2_COMMANDBUFFER.

Drivers determine the type of buffer being requested by checking the ddsCaps member of the DD_SURFACE_LOCAL structure passed to the CanCreateExecuteBuffer and CreateExecuteBuffer callback for the following flags:

  • DDSCAPS_VERTEXBUFFER indicates that the driver should allocate an explicit vertex buffer.
  • DDSCAPS_COMMANDBUFFER indicates that the driver should allocate a command buffer.
  • If neither flag is set, the driver should allocate an implicit vertex buffer.

Drivers can allocate vertex buffers and command buffers using existing execute buffer callbacks. The driver should expose video memory heaps, even if they do their own heap management. This can be done by exposing a "dummy heap" which reports the appropriate size. Direct3D will assume the driver can blt with outstanding locks to video memory.

The driver can internally allocate N vertex and command buffers and cycle through these buffers. Direct3D fills a given pair while the hardware asynchronously renders from the other queued buffers. This is very useful with direct memory access (DMA).

Buffers in a multibuffering set can be in different memory types. To do this, the driver is called to create the first buffer. It can create the set immediately and return the first buffer in the set to Direct3D. For each call to D3dDrawPrimitives2, if the D3DHALDP2_SWAPVERTEXBUFFER or D3DHALDP2_SWAPCOMMANDBUFFER flag is set, the driver should return a new buffer. If the returned buffer is in video memory, the corresponding D3DHALDP2_VIDMEMVERTEXBUF or D3DHALDP2_VIDMEMCOMMANDBUF flag should be set.

Occasionally, Direct3D will request the minimum size for the next buffer. If the size is too large, the driver should allocate the buffer in a backing surface. If the size is too small, the driver is permitted to provide a larger buffer. The driver should keep track of how many buffers and what memory types they are and clean up everything on exit.


Direct3D Command Buffers

The following figure shows portions of a sample logical command buffer. The driver's D3dDrawPrimitives2 callback receives a pointer to a command buffer in the lpDDCommands member of the D3DHAL_DRAWPRIMITIVES2DATA structure. The command buffer is always processed sequentially.

Sample Command Buffer

As shown in the preceding figure, a command buffer contains an unspecified number of D3DHAL_DP2COMMAND structures, where the bCommand member of each structure identifies one of the following commands:

  • D3DDP2OP_RENDERSTATE indicates that there are wStateCount D3DHAL_DP2RENDERSTATE structures that follow in the command buffer. The driver should parse the state from each of these structures and update its private driver state accordingly. The driver should also update the appropriate state in the array to which lpdwRStates points. If the driver does not support the state requested in the command buffer, the driver should override the requested value with one that it supports.
  • D3DDP2OP_TEXTURESTAGESTATE indicates that there are wStateCount D3DHAL_DP2TEXTURESTAGESTATE structures that follow in the command buffer. The driver should parse the state from each of these structures and update the driver's texture state associated with the specified texture stage accordingly. The driver does not report texture stage state back to the Direct3D run-time.

    A driver is required to properly parse up to eight texture coordinate sets regardless of how many coordinate sets it actually uses.

  • D3DDP2OP_VIEWPORTINFO indicates that there is one D3DHAL_DP2VIEWPORTINFO structure that follows in the command buffer. The driver should parse this structure and update the viewport information stored in the driver's internal rendering context.
  • D3DDP2OP_WINFO indicates that there is one D3DHAL_DP2WINFO structure that follows in the command buffer. The driver should parse this structure and update the w-buffer information stored in the driver's internal rendering context.
  • Any of the remaining D3DDP2OP_Xxx commands indicate that there is enough data following in the command buffer to render wPrimitiveCount (a member of the D3DHAL_DP2COMMAND structure) primitives. Depending on the primitive command, the driver should parse D3DHAL_DP2Xxx structures from the command buffer and vertex-associated data from either or both the vertex buffer and command buffer. The driver must attempt to process all valid D3DDP2OP_Xxx commands; that is, the driver cannot choose to ignore certain defined primitive types. See the individual D3DHAL_DP2Xxx structure reference pages for details.

Depending on the current command, the following additional information is stored in the command buffer:

  • Index information for all D3DDP2OP_INDEXEDXxx primitive commands.
  • Vertex data for the D3DDP2OP_TRIANGLEFAN_IMM and D3DDP2OP_LINELIST_IMM primitive commands.
  • Additional operations are also defined as D3DDP2OP_Xxx opcodes in the D3DHAL_DP2OPERATION structure. These are equivalent to D3DDP2OP_Xxx commands with the same names.

The command buffer occasionally contains commands that are understood only by Direct3D. If the driver's D3dDrawPrimitives2 callback does not recognize the command, the driver should call Direct3D's D3dParseUnknownCommand callback to attempt to parse it. When D3dParseUnknownCommand returns successfully, the driver should continue parsing and processing the command buffer. If D3dParseUnknownCommand fails by returning D3DERR_COMMAND_UNPARSED, D3dDrawPrimitives2 should set the following members of the D3DHAL_DRAWPRIMITIVES2DATA structure and return:

  • In dwErrorOffset, write the offset of the first unhandled D3DHAL_DP2COMMAND structure into the buffer to which lpDDCommands points.
  • Set ddrval to D3DERR_COMMAND_UNPARSED.

See Direct3D Driver Initialization for details on how to initialize the D3dParseUnknownCommand callback.

To simplify implementation of D3dDrawPrimitives2, driver writers can copy the parsing code from the perm3 sample code and write driver-specific rendering and state update code only.

Direct3D is not always informed of the current render states. For example, execute buffers are not inspected by the run-time before they reach the driver. The driver can keep track of the render state array with the lpdwRStates member in the D3DHAL_DRAWPRIMITIVES2DATA structure. This is a pointer to the internal render states array which the driver keeps up to date as state changes occur.


Direct3D Vertex Buffers

A vertex buffer contains the vertex data associated with a command buffer's primitives in a call to D3dDrawPrimitives2. Vertices are represented using the flexible vertex format (FVF), where each vertex can have the following data associated with it:

  • Position (x,y,z, and optional w) (required)
  • Diffuse color (optional)
  • Specular color (optional)
  • Texture coordinates (optional). Direct3D can send up to a maximum of eight sets of (u,v) values.

Drivers must provide FVF support.

The actual vertices and the order in which they should be processed depends on the D3DDP2OP_Xxx primitive command just parsed from the command buffer. See the individual D3DHAL_DP2Xxx structure reference pages for details.


Accelerated State Management

Accelerated state management is a mechanism for communicating large state changes across the API and DDI in a single call. This scheme allows an application to define a collection of state-set calls as a state block defined by a single integer. Sending this integer as a render state executes all the state changes in one call.

This reduces API overhead by reducing the number of IDirect3DDevice7::SetRenderState method (described in the Direct3D SDK documentation) calls required, and can improve the efficiency of drivers by allowing them to “precompile” stage changes into their own hardware-specific format upon a state block define, instead of on execution of each state change.

Most applications render in only a handful of states, so having fine-grained state transitions is seldom important. What is more important is being able to define blocks of state that can be interchanged as the driver switches between common rendering scenarios. This is the whole point of state block management.

State-set tokens are used to record the states in the driver. A handle refers to a collection of states. The D3DHAL_DP2STATESET structure is used to inform the driver about state-set operations to perform.

If the dwOperation member of the D3DHAL_DP2STATESET structure is set to D3DHAL_STATESETBEGIN, the driver begins recording the states for the handle contained in the dwParam member. When the driver receives a dwOperation of D3DHAL_STATESETEND, it stops recording state.

If the dwOperation member is D3DHAL_STATESETDELETE, the state-set referred to by the dwParam handle should be deleted.

If the dwOperation member is D3DHAL_STATESETEXECUTE, the state block referred to by the dwParam handle should be applied in the device.

If the dwOperation member is D3DHAL_STATESETCAPTURE, the current state in the driver should be captured in a specific way, giving a snapshot of the current states defined in the state block. That is, only states that are already in the state block are captured. Thus, the state block acts as a sort of mask, only recording states that are defined in it. For example, if there is a D3DRENDERSTATE_ZENABLE render state in the state block, then the current state for D3DRENDERSTATE_ZENABLE is captured and put in the state block. If there is no D3DRENDERSTATE_ZENABLE in the state block, then that state is not captured.

Groupings of states are used to make generic state blocks which can be modified slightly for different rendering scenarios. These pre-defined groupings (enumerated in D3DSTATEBLOCKTYPE in the DirectX SDK documentation) define generic state blocks which can be subsequently modified with state changes to accommodate anticipated recurring rendering scenarios. For example, the driver might create 100 generic predefined state blocks and then modify each slightly to accommodate a different rendering scenario. The state block type is passed in the sbType member of the D3DHAL_DP2STATESET structure.

The sbType member is only valid for D3DHAL_STATESETBEGIN and D3DHAL_STATESETEND and specifies the pre-defined state block type with one of the following D3DSTATEBLOCKTYPE enumerated types: NULL for no state, D3DSBT_ALL for all state, D3DSBT_PIXELSTATE for pixel state, and D3DSBT_VERTEXSTATE for vertex state.

The driver should ignore the sbType member unless it implements render state extensions. If the driver implements extended render states; that is, render states beyond those the Direct3D run-time supplies, it can use sbType to determine what type of pre-defined render states are being used. From this information it can determine how to append the state block appropriately, to support its extensions.


FVF (Flexible Vertex Format)

The driver's D3dDrawPrimitives2 callback receives vertex data in a flexible vertex format (FVF). Because the vertex format is flexible, there is no comprehensive data structure defined for this data. Drivers must implement full FVF functionality.

Note that there was an FVF update for Microsoft® DirectX® 7.0 which included 1D, 3D, and 4D textures in addition to the usual 2D textures. See the perm3 sample driver and Platform SDK documentation for more information about these topics.


Determining the Vertex Buffer Data Format

To identify the format of the data in the vertex buffer, a driver should determine the following information:

  • The dimension of the textures (1D, 2D, 3D, or 4D)
  • The components that are present in the FVF data
  • The ordering of the components that are present

FVF Texture Dimension

The driver should determine the dimension of the textures from the D3DTEXTURETRANSFORMFLAGS texture coordinate count flags (D3DTTFF_COUNTn, described in the DirectX SDK documentation). The number of the count flag signals how many texture coordinates will be present. Note that this does not necessarily equate to the dimension of the textures themselves, as explained below.

Non-Projected Textures

  • D3DTTFF_COUNT1 indicates that the rasterizer should expect 1D texture coordinates.
  • D3DTTFF_COUNT2 indicates that the rasterizer should expect 2D texture coordinates.
  • D3DTTFF_COUNT3 indicates that the rasterizer should expect 3D texture coordinates.
  • D3DTTFF_COUNT4 indicates the rasterizer should expect 4D texture coordinates.

Projected Textures

If projected textures are being used, the D3DTTFF_PROJECTED flag is set to indicate that the texture coordinates are to be divided by the last (COUNTth) element of the texture coordinate set. Thus, for a 2D projected texture, the count would be three, since the first two elements are divided by the third, resulting in two floats for a 2D texture lookup. That is, both D3DTTFF_COUNT2 and D3DTTFF_COUNT3 | D3DTTFF_PROJECTED reference a 2D texture.

FVF Vertex Data Components

The driver determines which components are present by analyzing the flags specified in the dwVertexType member of the D3DHAL_DRAWPRIMITIVES2DATA structure. Specifically, the following table indicates the possible bit fields that can be set in dwVertexType and the component(s) that they identify:

Value | Meaning
D3DFVF_DIFFUSE | Each vertex has a diffuse color.
D3DFVF_SPECULAR | Each vertex has a specular color.
D3DFVF_TEX0 | No texture coordinates are provided with the vertex data.
D3DFVF_TEX1 | Each vertex has one set of texture coordinates.
D3DFVF_TEX2 | Each vertex has two sets of texture coordinates.
D3DFVF_TEX3 | Each vertex has three sets of texture coordinates.
D3DFVF_TEX4 | Each vertex has four sets of texture coordinates.
D3DFVF_TEX5 | Each vertex has five sets of texture coordinates.
D3DFVF_TEX6 | Each vertex has six sets of texture coordinates.
D3DFVF_TEX7 | Each vertex has seven sets of texture coordinates.
D3DFVF_TEX8 | Each vertex has eight sets of texture coordinates.
D3DFVF_XYZRHW | Each vertex has x, y, z, and w coordinates.

Only one of the D3DFVF_TEXn flags will be set.

FVF Vertex Component Ordering

The components that comprise the vertex data are strictly ordered. Specifically, Microsoft Direct3D® will only supply the driver with vertex data that is ordered as shown in the following figure. Note that this diagram assumes 2D texture coordinates, although 1D, 3D, and 4D textures are also valid for DirectX 7.0 and later versions.

Flexible Vertex Format

As shown in the preceding figure, Direct3D always sends x,y,z, and w values; the remaining data is sent only as required by an application. Specifically, vertex data consists of the following components:

  1. Location (x,y,z,w) (required)

    The first vertex component is four D3DVALUEs that identify the position of the vertex. Direct3D always sets the D3DFVF_XYZRHW bit in dwVertexType.

  2. Diffuse Color (optional).

    If present, this component is a D3DCOLOR value that specifies the diffuse color for this vertex. Direct3D sets the D3DFVF_DIFFUSE bit in dwVertexType when this component is present.

  3. Specular Color (optional).

    If present, this component is a D3DCOLOR value that specifies the specular color for this vertex. Direct3D sets the D3DFVF_SPECULAR bit in dwVertexType when this component is present.

  4. Texture Data (optional).

    This part will vary based on the dimension of the texture. For each dimension in the texture, a D3DVALUE specifies each of the u, v, w, or q components (see explanation of FVF Texture Dimension). For example, if 2D non-projected textures are being used, two D3DVALUEs per texture are needed to specify the vertex's u,v values for each texture up to eight textures total. The number of u,v pairs present is n, where n corresponds to the D3DFVF_TEXn flag set in dwVertexType. For example, if D3DFVF_TEX3 is set in dwVertexType, then three u,v pairs are supplied with each vertex.

FVF data is always tightly packed; that is, no memory is wasted on components that are not explicitly specified in the vertex buffer. For example, when dwVertexType is (D3DFVF_XYZRHW | D3DFVF_TEX2), and the texture dimension is 2D, each vertex in the buffer consists of eight tightly packed D3DVALUEs. These specify the location (x,y,z,w) and texture coordinates for two textures (tu0,tv0, tu1,tv1) as shown in the following figure.

Vertex Buffer

Note that in the preceding figure it is assumed that there are only two texture coordinates. The vertex data supplied to the driver is always transformed and lit. The driver never receives normals. All data in the FVF texture coordinate sets are single precision IEEE floats. See the perm3 sample driver for implementation details. See the Platform SDK documentation for more details about FVF.


Advanced Direct3D Driver Topics

This section describes Microsoft® Direct3D® specialty topics and optimizations. These features are not central to implementing core functionality in a Direct3D driver; they should be implemented later in the driver development process, after core driver functionality is completed.

The topics described in this section are:

Optimized Textures

Stencil Planes

Guard Band Clipping

Extents Adjustment

W-Buffering

Bump Mapping

Hardware Transform and Lighting


Optimized Textures

In order to increase performance, some hardware vendors have changed their texture formats from the standard Microsoft DirectDraw® surface format. One approach is to tile the pixels so they are arranged in memory with 2D locality of reference. For example, instead of arranging the pixels scan line by scan line like this:

0 | 1 | 2 | 3 | … width
width+1 | width+2 | width+3 | width+4 | …

pixels are arranged in 4x8 blocks of DWORDs:

0 | 1 | 2 | 3
4 | 5 | 6 | 7

Thus, a single contiguous 32-byte memory reference pulls in a 4x8 block of pixels for use by the rasterizer. This layout maps much better to the pattern of memory references typically generated by the rasterizer than does the standard DirectDraw layout. Such schemes are referred to as ‘swizzling’ or ‘patching’ the texture. These operations are relatively more rapid to perform, and do not affect the size of the memory surface allocated. However, there is still significant latency introduced by this operation that applications need to control.

Another approach is to compress the texture into video memory and decompress it into a local cache on the accelerator. This decreases the video memory bandwidth required to keep the rasterizer running at full speed. In DirectX 5.0, drivers could do this as well, but it is a much slower operation that affects the application's view of video memory allocation due to the resulting texture being smaller.

To accommodate hardware vendors, DirectX 6.0 and later versions enable “optimized” textures that give the driver an opportunity to translate the surface into a proprietary format when the texture is used. Once optimized, the surface cannot be locked and may be smaller or larger than the original.

Many 3D accelerator chipsets on the market have a proprietary format that cannot be described with the standard DirectDraw mechanisms. This feature is intended to cover all hardware with such surface types.

Currently applications have some textures that need to be updated frequently, and others that can be left alone for the duration of the application. These latter benefit from patching due to improved resulting fill rate. The flags shown in the Optimized Texture API section allow the application to specify this usage scenario to the driver so it can optimize performance accordingly.


Optimized Texture API

Three new capabilities indicate the level of optimization that can be applied to a DirectDrawSurface object. In DirectX 6.0 and beyond, only textures can be marked with these caps bits. The optimized surface paradigm may be extended in the future to cover other types of surfaces, although the semantics may not be the same as for textures.

To address these issues as cleanly as possible, three new flags are provided in the DirectDrawSurface7:: Create method. When none of these three flags is specified, the decision whether to patch or swizzle is left entirely up to the driver. These flags are as follows:

DDSCAPS2_HINTDYNAMIC
Indicates to the driver that this surface will be locked very frequently, (for example, once per frame) for use such as streaming video or procedural textures. This cap should work for all driver-enumerated texture surface formats. The driver should avoid any transformation for these textures, especially if it requires some overhead.
DDSCAPS2_HINTSTATIC
This indicates to the driver that the surface can be reordered/retiled/swizzled in the IDirect3DDevice7::Load and IDirectDrawSurface7::Blt methods (described in the Direct3D SDK and DirectDraw SDK documentation, respectively). This operation will not change the size of the texture. It is relatively fast, and symmetrical, since the application may still lock these bits (although it will take a performance hit when doing so). Drivers are not allowed to fail locks on these surfaces and therefore cannot use lossy compression techniques. MIP map surfaces can be interleaved in this case.

This cap is not intended to force swizzling under any circumstances, especially those in which no performance benefit will arise. In particular, some texel formats may silently fail to swizzle.

DDSCAPS2_OPAQUE
This indicates to the driver that this surface will not be accessed by the application again. This flag behaves like the DDSCAPS2_HINTSTATIC flag, but with the addition of allowing actual compression using a hardware-specific compression scheme. This operation is relatively slow, but should allow simple, symmetric compression schemes (such as YUV 4:2:0, or color cell compression) to be used, providing compression ratios from 2 to 6x. Asymmetric schemes such as VQ should not be used here because they will result in unacceptable benchmarks.

MIP map textures can be interleaved arbitrarily by the driver. This technique should probably only be requested outside of internal rendering loops such as when textures are loaded from disk. Heap size reports after such a texture is loaded will reflect the reduced memory consumption if compression was applied. It should be remembered that there is additional header overhead on textures and therefore compressing many small textures will not save as much memory as might be expected.

In general, there is no guarantee about texture compression ratio, or compression quality implied by this flag.

Surfaces created with this flag will fail in the following cases:

Calls to the IDirectDrawSurface7::Lock method will fail.

Calls to the IDirectDrawSurface7::GetDC method will fail. Both methods are described in the DirectDraw SDK documentation.

Subrectangle blts to such surfaces will fail.

All blts from such surfaces will fail.

The only way to put data into such surfaces is with the IDirect3DDevice7::Load method (described in the Direct3D SDK documentation), or a full surface blt call.


Stencil Planes

Stencil planes enable and disable drawing on a per-pixel basis. They are typically used in multi-pass algorithms to achieve special effects, such as decals, outlining, shadows, and constructive solid geometry rendering.

Some hardware designed to accelerate Direct3D implements stencil planes. The special effects enabled by stencil planes are useful for entertainment applications.

Stencil planes are assumed to be embedded in the z-buffer data.

In DirectX 5.0, applications found the available z-buffer bit depths using the DDBD_Xx flags set in the dwDeviceZBufferBitDepth member of the D3DDEVICEDESC_V1 structure. To support z-buffers with stencil and z-buffer bit depths that cannot be represented using the existing DDBD_Xx flags, DirectX 6.0 and later versions have a new API entry point, IDirect3D7::EnumZBufferFormats (described in the Direct3D SDK documentation), which returns an array of DDPIXELFORMAT structures describing the possible z-buffer/stencil pixel formats. The DDPIXELFORMAT structure has been augmented to include three new z-buffer-related fields: dwStencilBitDepth, dwZBitMask, and dwStencilBitMask. A new flag, DDPF_STENCILBUFFER, indicates the presence of stencil bits within the z-buffer. The dwZBufferBitDepth member, which existed previously; gives the total number of z-buffer bits including the stencil bits. The new members of the DDPIXELFORMAT structure are as follows:

dwStencilBitDepth
Specifies the number of stencil bits (as an integer, not as a DDBD_Xx flag value).
dwZBitMask
Specifies which bits the z-value occupies. If nonzero, this mask means that the z-buffer is a standardized unsigned integer z-buffer format.
dwStencilBitMask
Specifies which bits the stencil value occupies.

DirectX 6.0 and later versions drivers should still set the appropriate DDBD_Xx flags in dwDeviceZBufferBitDepth for the z-only z-buffer formats they support. If stencil planes are not supported and the DDBD_Xx flags can represent all available z-buffer formats, then setting these flags is sufficient, as they will be translated into DDPIXELFORMAT by IDirect3D7::EnumZBufferFormats. Otherwise, the Direct3D driver must respond to a DdGetDriverInfo query that uses the GUID_ZPixelFormats GUID by returning a buffer in which the first DWORD indicates the number of valid z-buffer DDPIXELFORMAT structures, followed by the DDPIXELFORMAT structures themselves.

See DDPIXELFORMAT in the DirectDraw DDK reference documentation for more information.

New render states associated with stencil planes are shown in the following table, which lists the render state, the type associated with the render state's value, and a description. See the DirectX SDK documentation for more details.

Render State | Type | Description
D3DRENDERSTATE_STENCILFUNC | D3DCMPFUNC | Comparison function. The test passes if the following expression is true: (ref & mask) OPERATION (stencil & mask) where ref is the reference value, stencil is the value in the stencil buffer, and mask is the value of D3DRENDERSTATE_STENCILMASK.
D3DRENDERSTATE_STENCILREF | DWORD | Reference value used in the stencil test.
D3DRENDERSTATE_STENCILMASK | DWORD | Mask value used in the stencil test.
D3DRENDERSTATE_STENCILWRITEMASK | DWORD | Write mask applied to any values written to the stencil buffer.
D3DRENDERSTATE_STENCILFAIL D3DRENDERSTATE_STENCILZFAIL D3DRENDERSTATE_STENCILPASS | D3DSTENCILOP | See the explanation in the following paragraph.

Three new render states, D3DRENDERSTATE_STENCILFAIL, D3DRENDERSTATE_STENCILZFAIL, and D3DRENDERSTATE_STENCILPASS, are defined, respectively, to inform the hardware about what to do when the stencil test fails, when the stencil test passes but the z-test fails, and when both the stencil and z-tests pass. The values of these new render states can be set to enumerators of the D3DSTENCILOP enumerated type.


Stencil Operation Codes

The D3DSTENCILOP enumerated type, described in the DirectX SDK documentation, contains members that are used to specify the desired stencil operation to be performed.


Guard Band Clipping

The driver signals that is supports guard band clipping when it fields the GUID_D3DExtendedCaps GUID in DdGetDriverInfo. A guard band is a rectangle that is potentially larger than the viewport (and even the render target), to which vertices can be clipped automatically by the driver. The Direct 3D clipping code clips to this rectangle instead of to the viewport. By allowing the driver to specify potentially large guard band rectangles, the need to generate new vertices due to clipping is reduced.

A reasonable real-world example is a hardware device that can correctly render as long as screen x and y coordinates fall in the range -2048 through 2047.

Guard band clipping is also beneficial for antialiasing hardware, because the filter area can extend outside the rendering surface extent. This reduces filtering errors that can be introduced if primitives are geometrically clipped to this extent.

To do the correct clipping, the driver is passed the viewport information. This specifies the actual viewport that the application requires the geometry to be clipped to. Driver writers who do not want to implement guard band clipping can ignore this information. It is recommended that drivers do not use this data to implement clipping through scissor or masking operations since these are likely to be slower than letting Direct3D do the clipping.


Extents Adjustment

Some hardware uses an antialiasing kernel that influences pixels outside the extents rectangle defined by the screen-space vertices. Applications that use the extents rectangle in the D3DCLIPSTATUS structure (defined in d3dtypes.h) for dirty rectangle processing might experience rendering artifacts because the extents rectangle does not cover the pixels modified by the hardware.

Direct3D addresses this problem by enabling hardware drivers to request that the extents rectangle be adjusted outward by a specified number of pixels in the dvExtentsAdjust member of the D3DHAL_D3DEXTENDEDCAPS structure. This member is filled in response to the GUID_D3DExtendedCaps GUID in DdGetDriverInfo. The extents rectangle will be clipped to the extents of the render target surface for the device. The default is zero.


W-Buffering

Normally, z-buffering uses perspective-correct z for depth comparison and storage in the z-buffer, as this is the z that the rasterizer iterators must generate in order to maintain planar polygons. Some implementations can perform hidden surface elimination by filling the z-buffer with depth information expressed as w, or z relative to the eye. This is what is referred to as w-buffering in this documentation. This can be achieved by linearly interpolating the vertex 1/w term specified in the classic transformed and lit vertex structure (TLVERTEX - defined in the Direct3D SDK documentation), computing its reciprocal per pixel, and then using this w value for the depth comparison and conditionally storing it into the depth buffer.

Typically, the hardware stores a floating point value in the buffer. The following precision formats are common:

Size | Format
16 bits | 12.4
24 bits | IEEE single-precision float with no low byte of mantissa.
32 bits | Standard IEEE single-precision float.

Conventional z-buffering was developed for the technical markets that use CAD or authoring tools, in which the viewing volume/workspace is of known and limited extent. The range of depth values stored can therefore be of limited extent, allowing the ratio of far/near (the distances to the far and near clip planes) to be on the order of two to ten.

Typical hardware designed for such applications iterates perspective-correct z and stores it directly into the z-buffer. Due to the mathematics involved, this perspective-correct z is not distributed evenly within the z-buffer range. Using a far/near ratio of 100 results in 90 percent of the depth buffer range being used on the first 10 percent of the scene depth range. While this may be sufficient for tools, typical applications for entertainment or visual simulations with exterior scenes require far/near ratios of 1000 to 1 or 10000 to 1. At a ration of 1000 to 1, 98 percent of the range is used on the first two percent of the depth. This can cause hidden surface artifacts in distant objects, especially when using 16-bit depth buffers.

By contrast, when w (or eye-relative z) is used, the buffer bits can be more evenly allocated between the near and far clip planes in world space. The key benefit is that the ratio of far to near is no longer an issue, allowing applications to support a maximum range of miles, yet still get reasonably accurate depth buffering within inches of the eye point.


W-Buffering API

The D3DRENDERSTATE_ZENABLE render state supports three settings from the D3DZBUFFERTYPE enumerated type. See the DirectX SDK documentation for more details.

Value | Meaning
D3DZB_FALSE | Disables all depth buffering.
D3DZB_TRUE | Enables z-buffer using perspective correct z.
D3DZB_USEW | Disables z-buffering but enables w-buffering, which is eye-relative z.

Because the exact format used for storing w varies widely, it should be assumed to be opaque.

Surface allocations and depth-fill operations work identically when using w-buffering. All z-buffer compare modes work identically in either case.


W-Buffering DDI

The driver supports w-buffering by enabling the D3DPRASTERCAPS_WBUFFER cap in the dwRasterCaps member of the D3DPRIMCAPS structure. The D3DRENDERSTATE_ZENABLE render state is passed to the driver to enable or disable w-buffering or z-buffering.

The D3DHAL_DP2VIEWPORTINFO structure supports fields that correspond to world-space front and back clip planes (hither and yon respectively). This information can be used to adjust fog tables as well.


Bump Mapping

Bump mapping is an elegant technique that enables a surface to appear wrinkled or dimpled without the need to model these depressions geometrically.

Bump mapping in the usual sense involves perturbing the angles of the surface normals according to information given in a two-dimensional "bump map." This tricks the local reflection model, where intensity is mainly a function of the surface normal, into producing local variations on a smooth surface. This deception is evident only when silhouetted, because in that case the perturbations will no longer be visible at the edges. That is, the silhouette follows the line of the model and is therefore not perturbed. This is an important technique because it appears to add texture to a surface, rather than modulating the color of a flat surface.

Because bump mapping for Direct3D is done by texturing a surface in the rendering phase without perturbing the geometry, it bypasses serious modeling problems that would otherwise occur. If the object is polygonal, the mesh has to be fine enough to receive the perturbations from the texture map. This is a serious drawback, if the texture is to be an option.

Bump mapping is perturbed environment mapping that allows an arbitrary number, shape, and color of lights to be specified. DirectDraw specifies new pixel formats for bumps: DDPF_DU and DDPF_UV. These are integrated with multitexture blending through the D3DTEXTURESTAGESTATETYPE enumerated type, described in the DirectX SDK documentation. Environment mapping can be done by the application.

Bump mapping in this case is more accurately described as per-pixel texture coordinate perturbation by rasterizers for diffuse and specular environment maps. This capability is integrated with Direct3D multitexture support. Bump mapping is performed in the local surface coordinate system (texture coordinates (u, v)).

This technique allows the lighting environment of the scene to be represented in an image environment map (either for diffuse or specular effects). It permits the lights to be of any number, shape, color, or intensity distribution that can be represented in such a map. These maps can be created in advance for static cases, or easily updated on the fly for changing light sources, using blts.

Conventional bump mapping schemes derived from Phong shading are limited to spherical light sources of constant color and fixed fall-off curve. These do not require the additional texture addressing capabilities of per-pixel environment mapping and can work well for diffuse lighting effects, but cannot produce the visually structured specular highlights required for photorealism. In the future, use of such techniques will be facilitated by the integration of environment mapping calculations directly into the Direct3D geometry pipeline.

Bump mapping is commonly provided in photorealistic renderers. It can be used to drastically increase surface detail effects, without tessellating the surface into large numbers of small triangles. When used with specular effects, bump maps can simulate reflective yet rough surfaces, such as wet stone or pavement. When supported by 3D accelerators, such effects can be performed in real time, allowing dynamic light source changes. Direct3D's support of bump mapping eliminates one of the few remaining barriers to representing surfaces and environments with photorealistic quality.

When a DirectDrawSurface object is created with a bump-map format, that texture is considered to be a bump map. This object can be bound into the Direct3D device using any of the textures bound to the texture stages. A programmed texture blending stage can be set to perform the bump map operation by setting D3DTOP_BUMPENVMAP. The texture defined for this stage is a DirectDrawSurface object with a bump-map format. It will use the texture coordinates of the flexible vertex format specified by this stage’s texture coordinate identifier to position itself on the rendered objects. It will also respect the specified texture stage's controlling filtering, wrapping, and so on.

The bump values in this texture will perturb the texture coordinates used by the immediately following texture, which should be considered a specular or diffuse environment map.

Emulation

This methodology can be emulated on any hardware that supports an 8-bit paletted texture mode. The restriction is that the environment map used (the texture immediately following the bump texture map) must have a resolution of exactly 16X16 texels, and no filtering. This is indicated by the D3DTEXOPCAPS_MAXBUMPENVMAP16X16 flag. Other parts will have no limits on the size of the environment map that the bump map can perturb.

More general methods for bump-mapped environment mapping will be supported in future versions of DirectX, when additional information, such as normal vector data, is provided in the DDI.

Bump mapping is enabled with the multitexture blending operations D3DTOP_BUMPENVMAP and D3DTOP_BUMPENVMAPPREMODULATE. The latter operation is a combination of bump mapping and gloss mapping that allows the specular reflection intensity to be encoded in the same surface as the bump map data.

There are now four additional texture states provided at each stage:

D3DTS_BUMPENVMAT00

D3DTS_BUMPENVMAT01

D3DTS_BUMPENVMAT10

D3DTS_BUMPENVMAT11


Hardware Transform and Lighting

Hardware acceleration of geometry operations, such as lighting and transformation, has been enabled with modifications to the D3dDrawPrimitives2 DDI for DirectX 7.0. At the API level, devices that support vertex operations in hardware will be enumerated separately from those that do rasterization only.

The existing caps structures have been extended to indicate features that may be present on a hardware-accelerated transform device. For example, the number of supported light sources is set with the dwNumLights member of the D3DLIGHTINGCAPS structure which is reported with the D3DDEVICEDESC_V1 structure.

Other flags of note are:

Flag | Meaning
D3DDEVCAPS_CANBLTSYSTONONLOCAL | The device supports a texture blt from system memory to non-local video memory.
D3DDEVCAPS_DRAWPRIMITIVES2EX | The driver is DirectX 7.0-compliant by supporting extended D3dDrawPrimitives2 capabilities.
D3DDEVCAPS_HWRASTERIZATION | The device has hardware acceleration for rasterization.
D3DDEVCAPS_HWTRANSFORMANDLIGHT | The device can support both hardware transform and lighting in hardware.
D3DDEVCAPS_SEPARATETEXTUREMEMORIES | The device is texturing from separate memory pools.
D3DTRANSFORMCAPS_CLIP | The hardware can clip while transforming.

Since the feature sets of hardware geometry accelerators may differ (such as the number of light sources supported), the caps structures indicate which subset of geometry operations this device performs. Zero is a valid value for the number of light sources supported, indicating that the hardware does transformations only.

Only vertices that include a vertex normal are properly lit; for vertices that do not contain a normal, a dot product of 0 is employed in all lighting calculations.

All the key state and data structures used by the software implementation of the geometry pipeline are made available at the DDI level. Some display cards will implement only lighting in hardware, and do transformation and clipping on the host processor.

The following render state types pertain only to devices that accelerate transform and lighting:

D3DRENDERSTATE_AMBIENT
D3DRENDERSTATE_AMBIENTMATERIALSOURCE
D3DRENDERSTATE_CLIPPING
D3DRENDERSTATE_CLIPPLANEENABLE
D3DRENDERSTATE_COLORVERTEX
D3DRENDERSTATE_DIFFUSEMATERIALSOURCE
D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
D3DRENDERSTATE_EXTENTS
D3DRENDERSTATE_FOGVERTEXMODE
D3DRENDERSTATE_LIGHTING
D3DRENDERSTATE_LOCALVIEWER
D3DRENDERSTATE_NORMALIZENORMALS
D3DRENDERSTATE_SPECULARMATERIALSOURCE
D3DRENDERSTATE_VERTEXBLEND


Vertex Blending

Vertex blending operations are supported for DirectX 7.0. Vertex blending works in this way: an object from modeling space is multiplied by a 4X4 world matrix, placing the model's origin in a particular world space, relative to the origin of that world space. One part of the matrix does orientation and another part does the position. There can be up to three world matrices applied, allowing objects to be "bent" by blending the vertices with different weighting over the span of the object. A sample of a bending banana can be found in the Windows® DDK.

Next, the view matrix is applied, which effectively compresses the space relative to a particular viewpoint; much like a camera compresses the real world onto a two-dimensional picture.


Multimatrix Vertex Blending

Multimatrix vertex blending is a technique for rendering objects with smoothly blended skin joints. While this particular technique is not common in current software, some kind of smooth-skinning is currently used by most games involving animated characters.

There are a variety of geometry blending techniques. The technique described here is a form of geometry blending. This technique blends vertices across the joints of segmented articulated models, providing increased realism with reduced polygon count. As the joint changes in each frame, the geometry pipeline updates the positions of nearby vertices to smoothly blend between the segments at that joint. This capability can operate between segments that are related by joint types other than rotations, such as translations, scales, shears, or any combination that is representable by a 4X4 transformation matrix.

The general principle is to extend the typical segmented character by blending mesh vertices at joints.

Segmented models are considered to be built up from segments, or coordinate systems, each defined by a transformation matrix. Traditionally, each vertex of a mesh is considered to belong to only a single segment. This paradigm has been extended to allow vertices to have partial membership in other segments. Each vertex near the joint between two or more segments can have a skin weight Beta value, representing the proportion by which it actually belongs to the other segments.

When used in classic hierarchical modeling, the root segment gets no blending. It is always a rigid body since there is no other transform with which to blend. The skin weight Beta is defined as the proportion of the parent coordinate system that is to be used. This will be 0.0 over the entire object if it is entirely rigid-body (as is always the case for pre-DirectX 7.0 implementations).

The Beta will be 1.0 for those portions that are rigidly attached to the parent segment. This will drop as the proportion of the parent segment's contribution to the blend drops. There must be some set of points with 1.0 in them (and 0.0) in order to maintain geometric continuity between several segments.

Multimatrix vertex blending allows smooth skin blending to be performed by updating the position of each vertex, without requiring a separate 4X4 transform to be specified for each vertex. It addresses the common case of a continuous smooth surface and yet requires only one additional value —the skin weight Beta — per vertex, minimizing additional bandwidth requirements.

The specified vertex position data is transformed by all active world matrices, and the results are blended together using corresponding vertex weights.

The same steps are performed for any normal present in the vertex. This produces a single vertex (with position and normal) which is then fed into the rest of the pipeline for conventional lighting and clipping. See Multimatrix Vertex Blending Algorithm for more detail.

Characters can often contain the majority of the polygons in a scene, and are a key performance issue. Geometry pipelines that do not handle smooth-skinning well will have difficulty with a majority of the content.

Furthermore, the number of characters visible is one of the most highly variable components of the scene. This has serious impact on frame-rate leveling behavior. For interactive applications, level frame rate is more important than high average frame rate, making efficient character rendering a very critical feature.

Vertex blending must be performed after transformations. If blending is not integrated into the rendering pipeline, the transformations must be performed twice: once for skinning and once for rendering.

Integrating vertex blending into the geometry pipeline allows this case to be handled with a single traversal of the vertex data, which makes it just as fast as unblended vertices in bandwidth limited cases.


Multimatrix Vertex Blending Algorithm

This algorithm assumes only two matrices are being used.

On matrix change, update the following four matrices:

Matrix | Computation
Current Transform Matrix (CTM) | CTM = WORLD * VIEW * PROJ
Secondary CTM (parent coordinates) | CTM2 = WORLD1 * VIEW * PROJ
Inverse transpose of CTM | ITCTM = (CTMT)-1
Inverse transpose of CTM2 (required if lighting) | ITCTM2 = (CTM2T)-1

Note that in some cases it may be more efficient to blend the matrices first using the vertex’s weights, and then do only one (matrix)X(vertex) multiplication.

FVF Code Changes

The key API impact of multimatrix vertex blending is the addition of the vertex blending weight parameters to the position component of the flexible vertex format (FVF). These parameters are stored as 32-bit IEEE single precision floats. They are indicated as present in the input vertex data by the addition of four new bit patterns for the FVF code: D3DVFV_XYZB2, D3DVFV_XYZB3, D3DVFV_XYZB4, and D3DVFV_XYZB5.

Note that these codes identify extra DWORDs of space that may alternatively be allocated to other uses, such as particle radius or fog parameter, depending on which features are enabled.

Note If the number of blend weights specified is one less than the number of matrices currently being blended, then the weight assigned to the last matrix is defined to be (1.0 - Bt), where Bt is the total of the other weights for that vertex.

D3DTRANSFORMSTATE Changes

Multimatrix blending also requires the specification of three additional world transform matrices.

In addition to the original world transform matrices, D3DTRANSFORMSTATE_WORLD (which might be thought of as "D3DTRANSFORMSTATE_WORLD0"), D3DTRANSFORMSTATE_VIEW, and D3DTRANSFORMSTATE_PROJECTION, there are now the following world transform matrices, described in the DirectX SDK documentation:

  • D3DTRANSFORMSTATE_WORLD1, the second matrix to blend
  • D3DTRANSFORMSTATE_WORLD2, the third matrix to blend
  • D3DTRANSFORMSTATE_WORLD3, the fourth matrix to blend

Note that these are not consecutively enumerated after the original D3DTRANSFORMSTATE_WORLD.

Matrices that are not defined by this call, but are enabled for blending, are assumed to default to identity matrices.

D3DRENDERSTATETYPE Changes

A new render state has been defined to enable and control multimatrix vertex blending operations: D3DRENDERSTATE_VERTEXBLEND, described in the DirectX SDK documentation. The value of this render state can be one of the following D3DVERTEXBLENDFLAGS enumerators:

  • D3DVBLEND_DISABLE (use only the world matrix specified by the D3DTRANSFORMSTATE_WORLD transformation state)
  • D3DVBLEND_1WEIGHT (blend between the two world matrices specified by the D3DTRANSFORMSTATE_WORLD and D3DTRANSFORMSTATE_WORLD1 transformation states)
  • D3DVBLEND_2WEIGHTS (blend between the three world matrices specified by the D3DTRANSFORMSTATE_WORLD, D3DTRANSFORMSTATE_WORLD1, and D3DTRANSFORMSTATE_WORLD2 transformation states)
  • D3DVBLEND_3WEIGHTS (blend between four world matrices specified by the D3DTRANSFORMSTATE_WORLD, D3DTRANSFORMSTATE_WORLD1, D3DTRANSFORMSTATE_WORLD2, and D3DTRANSFORMSTATE_WORLD3 transformation states)

For a description of the D3DTRANSFORMSTATE_WORLDn transformation states, see D3DTRANSFORMSTATETYPE in the DirectX SDK documentation.

Even though additional blending world matrices may have been defined with the IDirect3DDevice7::SetTransform method (described in the Direct3D SDK documentation), the contributions (that is, weights) of any matrices beyond the number specified in this render state are set to zero.


User Clip Planes

User-defined clip planes are enabled for DirectX 7.0. These work just like other clip planes but they are settable by the application. The driver must handle these planes by responding to the D3DDP2OP_SETCLIPPLANE operation code in D3dDrawPrimitives2.


Texture Coordinate Transformations

Texture coordinate transformations are enabled for DirectX 7.0.

Texture transforms are vertex-level transformation operations. These operations can be performed by any transform and lighting-enabled HAL driver and by any HAL device type.

Texture transforms are enabled by defining 4X4 matrices associated with each texture stage. All of the key state and data structures used by the software implementation of the geometry pipeline are available at the DDI level.

Using texture transformations, texture coordinates can be moved, relative to the vertices they are being drawn from. The texture transform describes how the texture coordinates are moved inside the texture map. Every time a texture transform is applied, the matrix changes the coordinates of the texture. The standard world matrix is used in these transformations.

At the API level, the IDirect3DDevice7::SetTransform method (described in the Direct3D SDK documentation) defines the texture transform matrix associated with the texture currently bound to the i-th texture stage. This matrix should be applied to the texture coordinates of that texture during rendering. Note that the same vertex-level texture coordinate set can be used at different stages with a separate texture transform matrix which may apply different textures.

The operation of the texture transform is controlled by the IDirect3DDevice7::SetTextureStageState method (described in the Direct3D SDK documentation) using the D3DTSS_TEXTURETRANSFORMFLAGS flag.

The D3DTEXTURETRANSFORMFLAGS enumerated type, described in the DirectX SDK documentation, is used to control the dimension of the texture coordinate set that is generated by the texture coordinate transformation operation, and to control whether any perspective division should be applied to it.

D3DTTFF_DISABLE indicates that the texture coordinates are passed directly to the hardware.

The number of the D3DTTFF_COUNTn flag signals how many texture coordinates are going to be present. Note that this does not necessarily equate to the dimension of the textures themselves, if projected textures are used.

If projected textures are used, the D3DTTFF_PROJECTED flag is set to indicate that the texture coordinates are to be divided by the last (COUNTth) element of the texture coordinate set. Thus, for a 2D projected texture, the count would be three, since the first two elements are divided by the third, resulting in two floats for a 2D texture lookup. That is, both D3DTTFF_COUNT2 and D3DTTFF_COUNT3 | D3DTTFF_PROJECTED refer to a 2D texture.

For non-projected textures:

  • D3DTTFF_COUNT1 indicates that the rasterizer should expect 1D texture coordinates.
  • D3DTTFF_COUNT2 indicates that the rasterizer should expect 2D texture coordinates.
  • D3DTTFF_COUNT3 indicates that the rasterizer should expect 3D texture coordinates.
  • D3DTTFF_COUNT4 indicates the rasterizer should expect 4D texture coordinates.

The first byte encodes a count of texture coordinates expected to be used by the texture at a particular stage. Setting this to zero causes no texture transformation to be applied even if one was defined by the IDirect3DDevice7::SetTransform method. This is the number that will be output from the texture coordinate transform stage.

The number of texture coordinates passed into the texture transform is defined by the Direct3D API FVF code.

D3DTSS_TEXTURETRANSFORMFLAGS defaults to D3DTFF_DISABLED with no D3DTTFF_PROJECTED flag set. The texture transform matrices default to 4X4 identity matrices.

On non-transform-and-lighting HAL devices (that is, those that require transformation operations on the host processor), the output vertices will be provided to the driver with the appropriate DDI-level FVF code that may differ from the one specified at the API level. Devices that do not support hardware-accelerated transform and lighting may still do projected textures, and therefore the drivers must still respond to the D3DTSS_TEXTURETRANSFORMFLAGS.


Cube Environment Map Support

Multiple texture support in Direct3D allows the use of environment maps for lighting and reflections. However, single-map 360-degree solutions like circular or spherical maps aren’t robust enough to be widely used in real time. The most suitable solution for real-time generation and addressing of a 360-degree environment is a cubical map, composed of six textures (faces). Each face can be generated by pointing a camera with a 90-degree field-of-view in the appropriate direction. Per-vertex vectors (normal, reflection, or refraction) are provided to the rasterization hardware which then iterates them across the polygon and calculates the intersections of the interpolated vectors with the faces of the cube map. If the application or API generates the cube environment map, the driver does not require the information about the transformation matrix or coordinate space in which the per-vertex vectors are defined. This is because the vectors are used only to address the environment map, which is logically in the same coordinate space.

Addressing of a circular map involves vector normalization; addressing of a spherical map requires the use of trigonometric functions. All types of single-map environments are nonlinear: a circular map is extremely distorted and anisotropic near its periphery, while a spherical map has large distortions near its poles. This makes it necessary to re-create the environment map every time the viewpoint changes in such a way that the central view area becomes distorted.

Cubical environment maps, formed by pointing a real or simulated camera with 90-degree field-of-view in six different directions, are free of these disadvantages. They can be generated faster but need to be updated less frequently, have fewer distortions, and can be addressed by using equations similar to the ones already used for perspective-correct texture mapping.

In general, cube maps are the best choice to provide real-time environment mapping for complex lighting and reflections. Several hardware vendors support, or have plans to support, cube maps in silicon. The most widely used approach is described in Siggraph 94 by D.Voorhies and J.Foran, pages 163-166.

The cube map enables are passed to the driver using the D3dDrawPrimitives2 render state mechanism. FVF texture coordinates are passed with FVF code 01 for that texture coordinate set.

The cube map is defined in world coordinates; that is, its world transform matrix is the identity matrix. The cube map can appear to be in a different space if texture transforms are used on the corresponding texture coordinate indexes. These texture coordinate indexes will be looking directly at face four, the +z face. Y is up by default. The origin of the (u,v) texel grid is at the upper left corner of each face, in order to allow creation of the face without any additional transformations by pointing camera from the center of the cube.

DirectDrawCreateEx (described in the DirectDraw SDK documentation) takes a flag that indicates a cube map is to be created. Some faces need not be allocated at the API level, although drivers may pad as required. The surface descriptor contains a bit field with six bits indicating the faces that the application expects to use. When faces are attained with the IDirectDrawSurface7::GetAttachedSurface method (described in the DirectDraw SDK documentation), the NULL faces will be skipped. The dimensions of each face are available from its surface descriptor, and the face bitcode field will indicate which face it is.

The pointer returned from DirectDrawCreate is actually a pointer to the first non-NULL face in the cube. The face identifier can be obtained by taking the surface’s bitcode. This is the pointer that is passed to the IDirect3DDevice7::SetTexture method (described in the Direct3D SDK documentation) to make this map available in the multitexture pipeline.

If any of the surfaces are intended to be rendered to, the cube map must be created with the D3DPTEXTURECAPS_CUBEMAP cap flag set.

Any faces not created by the call are assumed to be filled with the color specified in the surface descriptor's dwEmptyFaceColor member. (See the DDSURFACEDESC2 structure.)

Current restrictions: All cube faces must be the same size and must be square. Cube face widths must be a power of two. The cube faces can be MIP mapped. No color keying is supported with cube map textures. As with other textures, alpha channels and alpha palettes are supported.


Integration of Environment Mapping with Standard Diffuse Lighting

Standard diffuse lighting calculations for Gouraud shading of diffuse components can be performed in the geometry pipeline. However, for best realism, the specular component could be generated by cube environment mapping. When both are in operation, the FVF specified by the application should contain one vector in the position for the lighting computation, and a separate 3D texture coordinate set for use as the vector into the cube map.


Vertex and Pixel Fogging

Fog has three main profile types: linear, exponential, and exponential squared. There are also two main implementation methods: vertex fog (also known as iterated or local fog) and pixel fog (also known as table or global fog).

In monochromatic (ramp) lighting mode, fog can work properly onlywhen the fog color is black. (If there is no lighting, any fog color will work since it is rendered as black.) Fog can be considered a measure of visibility — the lower the fog value, the greater the fog effect and the less visible the object will be.

The fog blending factor f is used in all fog calculations. It stands for the proportion of fog color versus object color. The final color is determined by the following formula:

Color = f * objColor + (1.0 - f) * fogColor

Therefore, a fog blending factor of 0.0 is full fog color and a fog blending factor of 1.0 is full object color. Typically, f decreases with distance.

Linear Fog

As the preceding figure shows, linear fog density increases in a linear fashion as the distance increases. This differs from exponential fog where the fog density increases exponentially. A linear fog profile might be set up as follows: the D3DRENDERSTATE_FOGSTART render state is set to ZFront and f = 1.0; the D3DRENDERSTATE_FOGEND render state is set to ZBack and f = 0.0. The D3DRENDERSTATE_FOGDENSITY render state is ignored.


Vertex Fog

Vertex fog is enabled using the D3DRENDERSTATE_FOGENABLE render state. Vertex fog can be made perspective-correct. For scenes with large polygons, vertex fog might not be the better choice, because the vertices are farther apart.

Vertex fog can be used in two ways:

  1. Make use of Direct3D lighting code using D3DVERTEX structures (described in the Direct3D SDK documentation) to define the fog blending factor.
  2. Make use of D3DLVERTEX or D3DTLVERTEX structures (both are described in the Direct3D SDK documentation). This is useful for doing custom fog effects such as layered fog, range-based fog, volume fog, and others.

When using fog with the D3DVERTEX structure, PRIMCAPS.dwRasterCaps has the D3DPRASTERCAPS_FOGVERTEX flag set. Individual calls to the IDirect3DDevice7::SetRenderState method (described in the Direct3D SDK documentation) are used to set D3DRENDERSTATE_FOGENABLE to TRUE, and D3DRENDERSTATE_FOGCOLOR to a 24-bit RGB color. For linear fog, the IDirect3DDevice7::SetRenderState method is used to set D3DRENDERSTATE_FOGSTART and D3DRENDERSTATE_FOGEND. For exponential and exponential squared fog, the D3DRENDERSTATE_FOGDENSITY render state is set with D3DLIGHTSTATETYPE, described in the Direct3D SDK documentation.

When using fog with the D3DTLVERTEX structure, the IDirect3DDevice7::SetRenderState method is used to set D3DRENDERSTATE_FOGENABLE to TRUE, set the color of the fog in D3DRENDERSTATE_FOGCOLOR, and set D3DRENDERSTATE_FOGTABLEMODE to D3DFOG_NONE (this is set in the D3DTLVERTEX structure itself). A fog blend factor f is defined at each vertex. This is the alpha component of the specular RGBA.

The following figure illustrates a sample relationship between altitude and fog density in a Layered Atmosphere Model.

Layered Atmosphere Model

The fog blending factor is calculated during the lighting phase and is placed in the alpha component of the specular color value in the vertex. This should then be interpolated according to the current shade mode set up by the D3DRENDERSTATE_SHADEMODE render state.

The fog blending factors for vertices v1, v2, and v3 are calculated by:

f1, f2, and f3 are interpolated across the triangle based on the current shade mode.

The new color, C, is obtained from the following formula:

C = (1 - f) * fog_color + f * src_color

In this formula,

  • f is the source, interpolated fog blending factor
  • fog_color is the current fog color (set by the render state D3DRENDERSTATE_FOGCOLOR)
  • src_color is the source, interpolated, textured color

If f, the fog blending factor, is 0.0, C will be set to a value identical to the fog color. If f is 1.0 there will be no fog effect.

Fog factor in a vertex is a function of the distance from the camera position to the vertex. This distance could be approximated by taking only Z value in camera space. For per-vertex fog we compute (Xc,Yc,Zc) in camera space by transforming the vertex using Mworld*Mview and then compute the distance to the vertex.

In RGB mode, fog factor f is scaled to be in the range 0 through 255, and is written to the alpha component of the specular output color.

In Ramp mode, diffuse and specular components are multiplied by the fog factor f and are clamped to be in the range 0.0 through 1.0.


Pixel Fog

Pixel fog is similar to vertex fog, but the fog blending factor, f, is calculated at rasterization time rather than at lighting time. Pixel fog is more accurate than vertex fog. The fog blending factor specified in the LVERTEX or D3DTLVERTEX structures (described in the Direct3D SDK documentation) is ignored. Pixel fog is limited to the three fog profile types (linear fog, exponential fog, and exponential squared fog). For pixel fog, the hardware does a table look-up on the depth value interpolated at each pixel. There is no need for 256 table entries if they are being interpolated linearly in-between. Future releases of DirectX may provide compensation for nonlinear z-distribution. ZFront and ZBack have values in the interval [0.0, 1.0]. Pixel fog is used by setting the PRIMCAPS.dwPRasterCaps to D3DPRASTERCAPS_FOGTABLE. The D3DDevice7::SetRenderState method sets the D3DRENDERSTATE_FOGENABLE render state to TRUE; the D3DRENDERSTATE_FOGCOLOR render state to 24-bit RGB; and the D3DRENDERSTATE_FOGTABLEMODE render state to one of D3DFOG_LINEAR, D3DFOG_EXP, or D3DFOG_EXP2. Here, the fog blending factor is calculated according to the three render states as follows:

fStart is determined by the render state D3DRENDERSTATE_FOGSTART and is in the interval [0.0, 1.0].

fEnd is determined by the render state D3DRENDERSTATE_FOGEND and is in the interval [0.0, 1.0].

fDensity is determined by the render state D3DRENDERSTATE_FOGDENSITY and is in the interval [0.0, 1.0].

The calculation of the fog blending factor f is based on z and the three fog render states just described. The actual calculation depends on the render state D3DRENDERSTATE_FOGTABLEMODE. Only D3DFOGMODE_LINEAR uses the fog start and end values.

  • D3DFOGMODE_NONE

    No pixel fog is applied.

  • D3DFOGMODE_LINEAR

    Linear fog growth.

  • D3DFOGMODE_EXP

    Exponential fog growth.

  • D3DFOGMODE_EXP2

    Exponential squared fog growth.

Typically exponential and exponential squared fog are too expensive to do directly. Instead, look-up tables are precalculated for a number of z values in the interval [0.0, 1.0] using the current fog density. The nearest table entry can then be used for the current z value, or an interpolating value between the two surrounding z values can be used to get the appropriate fog factor.

The final fogged color C is then calculated in the same manner as vertex fog as follows:

C = (1-f) * fog_color + f * src_color

In this formula,

  • f is the fog blending factor
  • fog_color is the current fog color (set by the render state D3DRENDERSTATE_FOGCOLOR)
  • src_color is the source, interpolated, textured color

If f, the fog blending factor, is 0.0, the final fogged color will be identical to the fog color. If f is 1.0, there will be no fog effect.


Range Based Fog

Fog can also be range-based. Range-based fog is useful because with normal z, or depth-based fog an object can appear at the side of the view, but then as the viewer rotates toward it, the object disappears back into the fog because its z-value changes. This is illustrated in the following figure. If fog is based on range instead of depth, it does not vary as the viewer rotates in place. This is compelling for flight simulators, tank games, and other applications where it is undesirable to have objects disappearing and reappearing in the distance as the viewer rotates. To set up fog to be range-based, D3DPRASTERCAPS_FOGRANGE and the D3DRENDERSTATE_RANGEFOGENABLE render state should be set. This render state works only with D3DVERTEX vertices. When the application specifies D3DLVERTEX or D3DTLVERTEX vertices, the F (fog) component of the RGBF fog value should already be corrected for range. The D3DVERTEX, D3DLVERTEX, and D3DTLVERTEX structures are defined in the Direct3D SDK documentation.

Range Based Fog

Note that if only fog within a specified range is visible, the viewer can rotate without objects coming in and out of the fog as with normal z or depth-based fog. That is, objects that were visible, remain visible, regardless of the rotation.


DirectX 7.0 Release Notes

The following subsections contain update information for DirectX 7.0, concerning flexible vertex format (FVF), the rasterizer, and MIP Map surface creation.

FVF Update

Rasterizer Update

MIP Map Surface Creation Update


FVF Update

The FVF codes originally defined in DirectX 6.0 now support the specifications for texture coordinate sets in DirectX 7.0.

In addition to the normal 2D textures, supported in DirectX 6.0, DirectX 7.0 supports 1D, 3D, and 4D textures. In addition, the textures may be projected. The dwVertexType member of D3DHAL_DRAWPRIMITIVES2DATA can be examined when D3dDrawPrimitives2 is called, to determine the dimensionality of each texture coordinate set.

For example, if there is a vertex with five texture coordinate sets, each one of these textures can be 1D, 2D, 3D, or 4D and they may be projected textures. Each texture stage is independent, so the dimensionality can be different for each set of coordinates. The upper 16 bits of the FVF flag contained in dwVertexType can be examined to determine the dimensionality of the texture coordinates.

The texture coordinate count is a 4-bit field that can range from zero through eight. This gives the number of texture coordinate sets given in the upper 16 bits of the word. The upper 16 bits of the FVF code are allocated as two bits each for each of eight texture coordinate sets. The meaning of the texture coordinate bits is as follows:

Bit Pattern | Decimal Value | Meaning
00 | 0 | Two-dimensional texture coordinate pair, (u, v) as in DirectX 6.0
01 | 1 | Three-dimensional texture coordinate triple, (u, v, q)
10 | 2 | Four-dimensional texture coordinate quadruple, (u, v, w, q)
11 | 3 | One-dimensional texture coordinate, u

3D texture coordinate sets can be used for any of three different purposes: projected textures (signaled by D3DTTFF_PROJECTED - see D3DTEXTURETRANSFORMFLAGS in the DirectX SDK documentation), volume textures, or cube map vector textures, as determined by a set of render states analogous to the D3DRENDERSTATE_WRAP0 to D3DRENDERSTATE_WRAP7 modes that are already specified on a texture coordinate set basis.

The flags used with the D3DRENDERSTATE_WRAPn render states for 1D through 4D texture coordinates, respectively, are as follows: D3DWRAPCOORD_0 (same as D3DWRAP_U, which specifies wrapping in the u coordinate direction), D3DWRAPCOORD_1 (same as D3DWRAP_V, which specifies wrapping in the v coordinate direction), D3DWRAPCOORD_2 (specifies wrapping in the w coordinate direction), and D3DWRAPCOORD_3 (specifies wrapping in the q coordinate direction).

When projected textures are in use, they take the RHW value from the corresponding texture coordinate field, instead of from the position field. However, the position field’s RHW is still used for both w-buffering and fog calculations, and therefore must be provided when either of these is in use.


Rasterizer Update

The reference rasterizer has been extracted into a separate DLL to enable additional WHQL tests to be added asynchronously of normal DirectX ship cycles (quarterly is typical). It has been updated to support any of the rasterizer-level operations added to the API either in the core or as extensions that require guaranteed consistency of implementation.

The production rasterizer may well not be updated to support these techniques, since environment mapping at the vertex level is likely to be faster than at the pixel level when running in software.

This rasterizer is likely to be upgraded in terms of performance on key cases that are identified.


MIP Map Surface Creation Update

Prior to DirectX 7.0, it was a safe assumption that the attachment chain for a MIP map consisted only of the sub-levels of that MIP map. With the advent of cubic environment maps, this is no longer the case. Each face of a cubic environment may itself be a MIP map and, as such, the attachment chain of a surface forming one face of a cubic environment map can consist of links to the other faces of the cube map as well as links to sub-levels of the MIP map. Care must therefore be taken when creating MIP map and cubic environment map surfaces.

As the attachment chain of a MIP map surface can now contain links to surfaces other than simply a lower level MIP map, a new capability bit has been introduced, DDSCAPS2_MIPMAPSUBLEVEL (see the DDSCAPS2 structure for this and the following flags). This bit is set for all but the top-level surface of a MIP map chain. Thus, given the top-level surface of a MIP map chain you can find the surface representing the next lowest level of the MIP map chain by traversing the attachment list of the top-level surface looking for a surface with the DDSCAPS2_MIPMAPSUBLEVEL capability bit set.

To determine if a surface is a face of a cubic environment map, check for the surface capability bit DDSCAPS2_CUBEMAP. If the DDSCAPS_MIPMAP capability bit is not set, the attachment list of this surface consists of the other faces of the cube map which are being created (check for the capability bits DDSCAPS2_CUBEMAP_POSITIVEX, DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY, DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ). If the DDSCAPS_MIPMAP capability bit is set then the attached surface list of the cube map surface consists of links to the other faces of the cube map as above but also to the next level of the MIP map for this face. The sub-level of the MIP map can be identified via the DDSCAPS2_MIPMAPSUBLEVEL bit described above.

D3DRENDERSTATE_MIPMAPLODBIAS

Although this render state is obsolete, its functionality has simply been moved into the texture stage states, that is, D3DRENDERSTATE_MIPMAPLODBIAS is exactly equivalent to the D3DTSS_MIPMAPLODBIAS enumerator in the D3DTEXTURESTAGESTATETYPE enumerated type for texture stage zero. On receiving the D3DRENDERSTATE_MIPMAPLODBIAS render state through a legacy interface, your driver should simply map this to the same code that handles D3DTSS_MIPMAPLODBIAS for texture stage zero.

The MIP map LOD bias is a floating-point value used to change the level of detail (LOD) bias. This value offsets the value of the MIP map level that is computed by trilinear texturing. It is usually in the range -1.0 to 1.0; the default value is 0.0. Current WHQL/DCT tests require the MIP map LOD bias to operate in the range -3.0 to 3.0.

Each unit bias (+/-1.0) biases the selection by exactly one MIP map level. A negative bias will cause the use of larger MIP map levels, resulting in a sharper but more aliased image. A positive bias will cause the use of smaller MIP map levels, resulting in a blurrier image. Applying a negative bias also results in the referencing of a smaller amount of texture data, which can boost performance on some systems.


DirectX 8.0 Release Notes

The following section contains update information for DirectX 8.0 and it focuses on those areas of the DDI that have been modified or extended for DirectX 8.0.


DDK Header File and Naming Issues

In order to simplify the task of having a single code base for the DirectX portion of your display driver for both Windows 98/Me and Windows 2000 and later, changes have been made to the naming conventions used for DDI data structures. Previously, d3dnthal.h contained definitions of the Direct3D DDI data structures with a naming convention that included the letters "NT." For example, on Windows 2000 the data structure associated with the D3dDrawPrimitives2 token to set a palette was called D3DNTHAL_DP2SETPALETTE. In d3dhal.h for Windows 98/Me, the equivalent data structure was called D3DHAL_DP2SETPALETTE.

For DirectX 8.0, we have changed this naming scheme to use only the Windows 98/Me naming style. d3dnthal.h as shipped with the DDK no longer contains the Windows 2000 style names. Currently, this rationalization applies to Direct3D data structures only and not DirectDraw DDI data structures. See D3DNTHAL_Xxx Structures for a list of structures affected by the change.

The DirectX 8.0 DDK introduces a new DDI-only header file called d3dhalex.h. This header file contains optional helper definitions and macros. Currently, this header contains some macros to assist with reporting D3DCAPS8 to the runtime.


DIRECT3D_VERSION

A DirectX display driver must support legacy (DirectX 7.0 and earlier) versions of the DirectX runtime. In order to do that, it is necessary to include both old and new DirectX headers, for example d3d.h and d3d8.h. However, this can cause a problem with the definition of the pre-processor symbol DIRECT3D_VERSION. This pre-processor symbol is used in the header files to indicate which structures and functions should be included. If the DIRECT3D_VERSION has not already been defined, the DirectX header files will set the value of DIRECT3D_VERSION to the most recent version they were designed for. Thus, d3d.h sets DIRECT3D_VERSION to 0x0700 and d3d8.h sets DIRECT3D_VERSION to 0x0800. If d3d.h is included in your source before d3d8.h, new Direct3D 8.0 features will not be defined and compiler errors will result.

To avoid this, define DIRECT3D_VERSION to 0x0800 before including any header files. Define DIRECT3D_VERSION to 0x0800 in either a master include file or as a standard command line parameter.


Minimal DirectX 8.0 DDI Support

DirectX 8.0 will provide hardware acceleration by DirectX 7.0 level drivers. However, for a driver to expose any of the new features of DirectX 8.0 such as multiple vertex streams, index buffers, or vertex and pixel shaders, it must identify itself by reporting DirectX 8.0 style capabilities and support the new D3dDrawPrimitives2 rendering tokens. In order to support the new D3dDrawPrimitives2 rendering tokens the driver is required to provide basic support for vertex streams and fixed function vertex shaders.

Reporting DirectX 8.0 style capabilities involves the following steps:

  • Handling the new GetDriverInfo2 variant of the existing DdGetDriverInfo entry point.
  • Returning a D3DCAPS8 structure containing the capabilities of the device when requested.
  • Ensuring that defined fields of that structure have certain minimum values.
  • Returning a texture format list that includes DirectX 8.0 style surface format descriptions.

These various requirements are discussed in the following sections.


Supporting GetDriverInfo2

The DirectX 8.0 DDI introduces a new mechanism for querying the driver for information. This mechanism extends the existing DdGetDriverInfo entry point to query for additional information from the driver. Currently, this mechanism is only used for querying for DX8 style D3D caps.

Note As you read the following you may be confused as to why the GetDriverInfo2 mechanism is necessary at all. It would seem preferable to simply define a new GetDriverInfo GUID that the driver would handle by returning a D3DCAP8 structure. GetDriverInfo2, introduced in the following paragraphs, is a mechanism to minimize the changes required to the Windows Operating Systems to enable DirectX 8.0 level functionality and thus make redistributing the DirectX 8.0 runtime practical.

This extension to GetDriverInfo takes the form of a DdGetDriverInfo call with GUID_GetDriverInfo2. When a DdGetDriverInfo call with that GUID is received by the driver, it must examine the data structure passed in the lpvData field of the DD_GETDRIVERINFODATA data structure to see what information is being requested. As described below, lpvData can point to either a DD_GETDRIVERINFO2DATA or DD_STEREOMODE structure.

The GUID_GetDriverInfo2 is the same GUID value as GUID_DDStereoMode. If your driver does not handle GUID_DDStereoMode, this is not an issue. However, if your DirectX 8.0 driver will handle GUID_DDStereoMode, please note that when a call to DdGetDriverInfo with the GUID_GetDriverInfo2(GUID_DDStereoMode) is made, the runtime sets the dwHeight field of the DD_STEREOMODE structure to the special value D3DGDI2_MAGIC. This field corresponds to the dwMagic field of the DD_GETDRIVERINFO2DATA structure. Therefore, by casting the lpvData pointer to either a pointer to a DD_STEREOMODE structure or a pointer to a DD_GETDRIVERINFO2DATA structure and checking the value of the corresponding field (dwHeight or dwMagic) for the value D3DGDI2_MAGIC, you can distinguish between a call to determine stereo mode capabilities or a request of Direct3D 8.0 capabilities.

Once the driver has determined that this is a call to GetDriverInfo2 it must then determine the type of information being requested by the runtime. This type is contained in the dwType field of the DD_GETDRIVERINFO2DATA data structure.

Finally, the driver copies the requested data into the supplied buffer. It is important to note that the lpvData field of the DD_GETDRIVERINFODATA data structure points to the buffer to which to copy the requested data. lpvData also points to the DD_GETDRIVERINFO2DATA structure. This means that the data returned by the driver will overwrite the DD_GETDRIVERINFO2DATA structure (and, therefore, that the DD_GETDRIVERINFO2DATA structure occupies the first few DWORDs of the buffer).

In order to be called with GetDriverInfo2, and report DirectX 8.0 capabilities, it is necessary for the driver to set the new flag DDHALINFO_GETDRIVERINFO2 in the dwFlags field of the DD_HALINFO structure returned by the driver. If this flag is not set, the runtime will not send GetDriverInfo2 calls to the driver and the driver will not be recognized as a DirectX 8.0 level driver.

The runtime uses GetDriverInfo2 with type D3DGDI2_TYPE_DXVERSION to notify the driver of the current DX runtime version being used by the application. The runtime provides a pointer to a DD_DXVERSION structure in the lpvData field of DD_GETDRIVERINFODATA.


Reporting DirectX 8.0 Style Direct3D Capabilities

In response to a GetDriverInfo2 query with type D3DGDI2_TYPE_GETD3DCAPS8, the driver should copy an initialized D3DCAPS8 structure into the lpvData field of the DD_GETDRIVERINFODATA structure. This structure is new for DirectX 8.0 and is used for both reporting capabilities from the driver to runtime and from the runtime to the application.

D3DCAPS8 has fields that describe both capabilities new to DirectX 8.0 and capabilities carried forward from DirectX 7.0. D3DCAPS8 is not a complete replacement for existing capabilities. Although this structure (along with information of supported surface formats) is a complete description of the device’s capabilities from an API perspective it is not sufficient for the DDI. The runtime makes use of the DirectDraw capabilities reported by the driver for such information as supported surface capabilities (DDSCAPS) even though these are not exposed directly through the DirectX 8.0 API. Furthermore, the driver is required to continue to report legacy capability structures (such as D3DHAL_D3DEXTENDEDCAPS) as applications using legacy interfaces (DirectX 7.0 and earlier) will continue to request these capabilities. Therefore, reporting DirectX 8.0 style caps through D3DCAPS8 is an additional requirement, rather than a replacement for the existing capability reporting mechanisms. When DirectX 8.0 interfaces are used by the application the runtime will not query for extended D3D capabilities such as D3DHAL_D3DEXTENDEDCAPS if the driver reports DirectX 8.0 capabilities with D3DCAPS8.

D3DCAPS8 is described in the DirectX 8.0 SDK documentation. The driver should not initialize the DeviceType or AdapterOrdinal fields. These will be initialized to appropriate values by the runtime. The driver should simply set these fields to zero.


Minimum Capability Requirements for DirectX 8.0 Drivers

In addition to returning the D3DCAPS8 data structure in response to a GetDriverInfo2 query, the DirectX 8.0 runtime has other requirements that a driver must meet to be considered a DirectX 8.0 level driver.

A DirectX 8.0 driver must explicitly:

  • Report support for one or more vertex streams in the MaxStreams field of D3DCAPS8.
  • Report a maximum point sprite size of at least one in the MaxPointSize field of D3DCAPS8.
  • Modify its list of supported texture formats to support new style pixel format specifications.
  • Handle the new D3dDrawPrimitives2 (DP2) drawing tokens.
  • Handle D3dCreateSurfaceEx for vertex and index buffers even if your driver does not support video memory vertex buffer creation. Handles for system memory vertex and index buffers will be passed to the driver.
  • Set the new post-transformed clipping flag D3DPMISCCAPS_CLIPTLVERT if the hardware supports clipping of post-transformed vertex data.

It should be noted that a driver is not required to support any of the new features of DirectX 8.0 such as pixel or vertex shaders, volume textures, point sprites (beyond the non-zero maximum point size), multi-sampling or even multiple vertex streams (as the driver can set the maximum number of simultaneous vertex streams to one) in order to be considered a DirectX 8.0 driver.


Reporting Support for Video Memory Vertex and Index Buffers

DirectX 8.0 has added two new Direct3D capability flags that flag to the runtime whether the driver does or does not support video memory vertex and index buffers. Before these flags were created, the runtime could not determine whether the driver provided real support for video memory vertex buffers or not. Therefore, if a DirectX 8.0 exports the execute buffer (d3d buffer) creation and destruction driver entry points it should add one or both of the capability bits D3DDEVCAPS_HWVERTEXBUFFER and D3DDEVCAPS_HWINDEXBUFFER to the DevCaps field of the D3DCAPS8 structure reported via GetDriverInfo2 to the runtime. Set the flag D3DDEVCAPS_HWVERTEXBUFFER if your driver supports video or non-local video memory vertex buffers and D3DDEVCAPS_HWINDEXBUFFER if your driver supports video or non-local video memory index buffers.

The runtime masks these capability bits off before reporting capabilities to the application (they are not useful to applications only to the runtime itself). Therefore, these capabilities will not be visible to the DirectX Caps Viewer application even if your driver exports them.

Correct support for these capabilities will be part of WHQL certification testing.


The Texture Format List

Direct 8.0 introduces a new mechanism for describing pixel formats. In previous versions of DirectDraw and Direct3D pixel formats were described by a data structure (DDPIXELFORMAT) which contained information about the number of bits per color channel and bit masks for each color channel (along with flags and size field). Pixel formats in DirectX 8.0 are simple DWORDs that identify a particular pixel format and are compatible with FOURCC codes (Direct3D pixel formats are simply FOURCC codes with all but the least significant bytes being zero).

The DDPIXELFORMAT data structure is no longer exposed through API level interfaces. However, it is still used at the DDI level. Specifically, the driver still reports its supported texture formats through a texture format array that consists of surface descriptions with their embedded DDPIXELFORMAT data structures. However, the embedded pixel format structures can now be used to report new style pixel formats. To specify a new style pixel format using the DDPIXELFORMAT data structure, set the dwFlags field of the structure to the value DDPF_D3DFORMAT and store the new pixel format identifier in the dwFourCC field. In addition, certain other new fields have been added to DDPIXELFORMAT (the new fields have been added as members of unions with existing fields so the size of the data structure is the same). These fields include: dwOperations, dwPrivateFormatBitCount, and wFlipMSTypes and wBltMSTypes.

A DirectX 8.0 DDI compliant driver should continue to report DX7 style surface formats through the standard mechanisms, that is, the texture format list reported in the global driver data structure (D3DHAL_GLOBALDRIVERDATA) and the Z/Stencil list reported in response to a GUID_ZPixelFormats from DdGetDriverInfo. However, the driver should also report all of its supported surface formats through the new DirectX 8.0 DDI mechanism described below.

DirectX 8.0 DDI style surface formats are reported using GetDriverInfo2. Two GetDriverInfo2 query types are used by the runtime to query for surface formats from the driver. D3DGDI2_TYPE_GETFORMATCOUNT is used to request the number of DirectX 8.0 style surface formats supported by the driver. D3DGDI2_TYPE_GETFORMAT is used to query for a particular surface format from the driver.

To handle the D3DGDI2_TYPE_GETFORMATCOUNT, the driver must store the number of DirectX 8.0 DDI style surface formats that it supports in the dwFormatCount field of the DD_GETFORMATCOUNTDATA.

When the runtime has received the number of supported formats from the driver, it will then query for each surface format in turn with GetDriverInfo2 queries of type D3DGDI2_TYPE_GETFORMAT. The data structure pointed to by the lpvData field of the DD_GETDRIVERINFODATA data structure is, in this case, DD_GETFORMATDATA.

The DirectX 8.0 runtime scans the texture format list reported by the driver examining the dwFlags fields of each pixel format. If any of the texture formats have dwFlags set to DDPF_D3DFORMAT, then the runtime identifies this texture format list as DX8 style and will filter all texture formats whose pixel format is not flagged as DDPF_D3DFORMAT. Furthermore, a DX7 runtime will filter any texture format which does have DDPF_D3DFORMAT set. Therefore, a driver supporting the DX8 DDI can return a texture format list that contains two entries for each supported format, one specified in the old style and one in the new. DX8 runtimes will use the formats specified in the new style and DX7 runtimes will use the formats specified in the old style.

All supported surface formats, such as textures, depth or stencil buffers, or render targets, should be reported through the GetDriverInfo2 mechanism. The runtime will ignore the texture and Z/Stencil formats returned through legacy mechanisms (D3DHAL_GLOBALDRIVERDATA and GUID_ZPixelFormats). No attempt will be made to map these formats to DX8 style formats for DirectX 8.0 drivers. However, legacy formats will be mapped to the new style for legacy, DirectX 7.0 or earlier drivers. Therefore, a driver must report all supported surface formats through the DirectX 8.0 DDI. Furthermore, as legacy runtimes will not map new style surface formats to old style formats it is essential that the driver continue to report DirectX 7.0 style surface and Z/Stencil formats through the legacy mechanism.


Format Operations

When reporting supported surface formats a DirectX 8.0 driver must also indicate which operations can be performed on surfaces of that format. The supported operations for a pixel format are reported through the dwOperations field of the DDPIXELFORMAT structure. The driver should set this field to the logical combination of all supported operations for surfaces of that format.


Surface Formats as FOURCC Codes

Three of the new surface formats defined by DirectX 8.0, D3DFMT_Q8W8V8U8, D3DFMT_V16U16 and D3DFMT_W11V11U10, are passed to the driver as FOURCC codes. This means the various bit depth and mask fields of the DDPIXELFORMAT data structure are not initialized and their values are undefined. Hence, a driver processing these three formats must not rely on the bit count or masks in the pixel format but must compute these as necessary. For example, when computing the pitch of a surface of one of these types the dwRGBBitCount field of the pixel format must not be used. All other formats other than YUV, DXT and IHV specific extension formats are mapped to the legacy DDPIXELFORMAT representation when passed to the driver and, hence, will have valid pixel formats and masks in the pixel format data structure.


Multiple Vertex Streams

DirectX 8.0 adds support for multiple vertex streams. Even if the driver and hardware combination does not support more than one stream of vertex data, the driver must still handle the stream binding DP2 tokens (D3DDP2OP_SETSTREAMSOURCE and D3DDP2OP_SETSTREAMSOURCEUM) and the new vertex stream based DP2 drawing tokens (see New DP2 Stream Drawing Tokens). These are the mechanisms for passing vertex data to the driver in drawing for DirectX 8.0 level drivers.


Reporting Multiple Vertex Stream Capability

A driver reports the ability to support multiple vertex streams by setting the value of the MaxStreams field of the D3DCAPS8 structure. A driver that supports multiple vertex streams should specify a value greater than one. A DX8 level driver that does not support multiple vertex streams should set MaxStreams to one. No DX8 level driver should specify a value of zero for this field. The driver should also set the MaxStreamStride field to the maximum supported stride (in bytes) between vertex elements in a vertex stream.


Stream Zero

Vertex stream zero is treated differently from the other streams (by virtue of the fact that it was the only stream supported by prior versions of Direct3D). Vertex buffers that have a flexible vertex format (FVF), where the FVF field is non-zero, can only be bound to stream zero. However, this does not imply that the vertex buffer bound to stream zero will always have a flexible vertex format.

Stream zero is also the implied vertex source when one of the special, fixed-function vertex shaders is the current vertex shader handle.


Notification of Stream / Vertex Buffer Binding

DirectX DDK

Notification of Stream and Vertex Buffer Binding

[This is preliminary documentation and subject to change.]

A driver is notified of the binding of a vertex buffer to a particular stream through a new DP2 token, D3DDP2OP_SETSTREAMSOURCE, and its associated HAL data structure, D3DHAL_DP2SETSTREAMSOURCE.


Index Buffers

DirectX 8.0 introduces the concept of index buffers. These buffers are very similar to vertex buffers but store simple 16 or 32-bit indices into vertex data rather than the vertex data itself. Index buffers extend all the benefits of vertex buffers, for example optimal download and caching, to index data.

Index buffers are created, locked, unlocked and destroyed with the same driver entry points as those used for vertex buffers. A driver can distinguish between these buffer types using the new surface capability bit DDSCAPS2_INDEXBUFFER. For index buffers, this flag will be set in the ddsCapsEx.dwCaps2 field of the surface’s DD_SURFACE_MORE structure. It will be clear for vertex buffers.

Unlike many other surface types, a driver does not need to set the capability DDSCAPS2_INDEXBUFFER when reporting its capabilities to the runtime in order to receive driver calls for index buffer creation, destruction, and locking. A DirectX 8.0 driver that supports vertex buffers is assumed to support index buffers also. If the underlying hardware has no direct support for index buffers then the driver should handle index buffer creation by allocating system memory for the surface.


Reporting Support for 32-bit Indices

Prior to DirectX 8.0 vertex indices were restricted to 16-bit quantities. DirectX 8.0 adds support for 32-bit indices. A driver reports support for 32-bit indices by setting the value of the MaxVertexIndex field of D3DCAPS8 (currently also in D3DHAL_D3DEXTENDEDCAPS) to a value greater than 0xFFFF. This field also allows the driver to report that although it supports indices requiring 32-bits of storage it does not support the full range of 32-bit values.


Setting the Current Index Buffer

As with vertex data, the index buffer to be used by drawing primitives is no longer part of the data passed to the driver with the primitive, but rather is driver state. The current index buffer is set by a new DP2 token, D3DDP2OP_SETINDICES. This token established the index buffer with the given handle as the current index buffer to use when drawing indexed primitives until a new index buffer is set or the current index buffer is cleared (an index buffer handle of zero is specified in the DP2 token data).


New DP2 Stream Drawing Tokens

DirectX 8.0’s support for multiple streams of vertex data requires that new DP2 drawing tokens be introduced. These new tokens are necessary because existing drawing tokens assumed that there was a single pointer to vertex data for a particular drawing instruction. With multiple streams, this is no longer the case. A drawing command may well access multiple vertex data buffers simultaneously through streams.

It is important to note that these drawing tokens replace the existing primitive type specific tokens (for example, D3DDP2OP_POINTS, D3DDP2OP_TRIANGLELIST, D3DDP2OP_TRIANGLESTRIP) for calls through the new DirectX 8.0 interfaces only. Calls made through DX7 our earlier interfaces will still be passed through the DDI as the old style drawing tokens. Therefore, a DX8 driver is required to support both old and new style drawing tokens.

The indexed and non-indexed drawing tokens have two variants. For example, non-indexed drawing is accomplished by the tokens D3DDP2OP_DRAWPRIMITIVE and D3DDP2OP_DRAWPRIMITIVE2. Similarly, indexed drawing is accomplished by the tokens D3DDP2OP_DRAWINDEXEDPRIMITIVE and D3DDP2OP_DRAWINDEXEDPRIMITIVE2.

The main distinction between the two variants is that D3DDP2OP_DRAWPRIMITIVE2 and D3DDP2OP_DRAWINDEXEDPRIMITIVE2 are used when the vertex data has been transformed by the runtime. This can be the case either because the driver/hardware combination does not support hardware vertex processing or the software vertex processing has been explicitly selected. For these tokens, only stream zero is used and it contains transformed and lit vertices.

D3DDP2OP_DRAWPRIMITIVE and D3DDP2OP_DRAWINDEXEDPRIMITIVE are used then the runtime has not processed the vertex data. Thus, these tokens can supply untransformed vertex data when the hardware supports hardware vertex processing or transformed vertex data when the application supplies transformed data direct to the runtime. In this case any number of streams (up to MaxStreams) can be active. These variants (along with the other new drawing token, D3DDP2OP_CLIPPEDTRIANGLEFAN) enable optimal code paths in the runtime and the distinctions beyond those described here are not significant to the driver.


Copying Vertex and Index Buffers in the DP2 Stream

A new DP2 token, D3DDP2OP_BUFFERBLT, has been added to support optimal copying and updating of index and vertex buffers. This token is very similar to the existing D3DDP2OP_TEXBLT which copies and updates textures but has been modified to support sub-buffer copying rather than simple rectangles.


Point Sprites

DirectX 8.0 introduces support for point sprites. A point sprite is an extension to basic point rendering which allows the size of the point to be specified, either by a render state or by a vertex component. When accelerated, the point sprites will be rendered in hardware as a screen space quadrilateral formed of two triangles, and render states such as textures and blending will be used.


Reporting Support for Point Sprites

A driver notifies the runtime of its support for point sprites by setting the MaxPointSize field of the D3DCAPS8 structure to a floating point number greater than one (reporting a value of one is part of the requirement to indicate a DX8 level HAL). This value specifies the maximum point width and height in render target pixels. Devices that do not support point sprites can set this value to 1.0.

The size of a point sprite can be specified either by a new per-vertex element or by a new render state. If the driver and hardware combination supports the interleaving of point size information with other vertex data (rather than simply through the point size render state D3DRS_POINTSIZE), it should set the D3DFVFCAPS_PSIZE flag in the FVFCaps field of the D3DCAPS8 structure.

The absence of D3DFVFCAPS_PSIZE indicates that the device does not support D3DFVF_PSIZE (per-vertex point size) for pre-transformed vertices (and thus the base point size will always come from D3DRS_POINTSIZE). D3DFVF_PSIZE is always supported for post-transformed vertices.

The implication of this is that DX8 drivers for which the D3DFVFCAPS_PSIZE bit is not set are still required to accept D3DFVF_PSIZE for post-transformed vertices. This ability will not be emulated in the runtime, and the driver must gracefully ignore any point size data passed through the FVF. Note that the D3DUSAGE_POINTS bit is required to be set for vertex buffers which are to be used for rendering point sprites, so the driver can avoid allocating these vertex buffers in memory types which are slow for reads into the CPU.

Point sprites present a challenge when user clip planes are being used. It is possible that a particular hardware implementation of point sprites will clip only the actual vertex position of the point sprite against the user clip plane, rather than the expanded quad actually rendered. If the driver and hardware combination can support clipping of point sprites by their actual computed size rather than simple vertex position then the D3DPMISCCAPS_CLIPPLANESCALEDPOINTS capability bit should be set in the PrimitiveMiscCaps field of D3DCAPS8.

Drivers that perform transform and lighting (i.e. offer hardware vertex processing) are entirely responsible for a correct point sprite implementation. No emulation will be performed by the DirectX runtime. This means that even if the hardware is used with software vertex processing point sprites are the drivers responsibility.


Computing the Size of Point Sprites

Point sprites are rendered using the existing D3DPT_POINT primitive type. The size of point sprites can be controlled either through the new render state D3DRS_POINTSIZE or by the new FVF component D3DFVF_PSIZE.

For vertices without the D3DFVF_PSIZE vertex component the current value of the D3DRS_POINTSIZE render state should be used. Otherwise, the value specified in the vertex data should be used. In either case, the value is a floating-point number that is the size (width and height) of the rendered quad in rendering target pixels. The default value of the point size render state (1.0) is sent to the driver during initialization.

Two render states control clamping of the computed point sprite size, D3DRS_POINTSIZE_MIN and D3DRS_POINTSIZE_MAX. The computed size of the point should be clamped to be no smaller than the size given by D3DRS_POINTSIZE_MIN and no larger than the size given by D3DRS_POINTSIZE_MAX. It is the driver’s responsibility to ensure that the point sprite size is clamped to the minimum and maximum sizes specified by the render states.

For drivers that support hardware vertex processing the size of point sprites may also be scaled based on the distance from the point to the eye (in eye space). Scaling of the point sprites is enabled by the new render state D3DRS_POINTSCALEENABLE. If the value of this render state is TRUE then the points are scaled according to the following formula. Note that in this case the application-specified point size is expressed in camera space units. This scaling is performed by drivers that support transform and lighting only.

Si
Iinput point size (either per-vertex or D3DRS_POINTSIZE)
A,B,C
Point scale factors D3DRS_POINTSCALEA/B/C
Vh
Height of viewport (dwHeight field in D3D_VIEWPORT)
Pe = (Xe, Ye, Ze)
Eye space position of point
De = sqrt (Xe2 + Ye2 + Ze2)
Distance from eye to position (eye at origin)
Ss = Vh * Si * sqrt(1/(A + B*De + C*(De2))
Screen space point size
Smax
MaxPointSize device capability
Smin
D3DRS_POINTSIZE_MIN
Final screen-space point size S =
Smax if Ss > Smax

Smin if Ss < Smin

Ss otherwise

Note that for the application to be drawing single pixel vertices, rather than point sprites, it must have the following render states set:

SetRenderState (D3DRS_POINTSCALEENABLE, FALSE)
// All textures must be turned off.
SetTexture (0, NULL);
SetTextureStageState(1, D3DTSS_COLOROP,  D3DTOP_DISABLE);
// The point size render state must be set to any value between 0.0-1.0
SetRenderState(D3DRS_POINTSIZE, 1.0);
// D3DRS_POINTSIZE_MIN and D3DRS_POINTSIZE_MAX
// must be set appropriately to allow
// D3DRS_POINTSIZE to be set to a value between 0.0-1.0


Rendering Point Sprites

A screen space point P = (X, Y, Z, W) of screen-space size S is rasterized as a quadrilateral with the following 4 vertices:

(X–S/2, Y–S/2, Z, W)
(X+S/2, Y–S/2, Z, W)
(X–S/2, Y+S/2, Z, W)
(X+S/2, Y+S/2, Z, W)

The vertex color attributes are duplicated at each of the 4 vertices, therefore each point is always rendered with constant colors.

The assignment of texture indices is controlled by the D3DRS_POINTSPRITEENABLE setting. If D3DRS_POINTSPRITEENABLE is set to FALSE, then the texture coordinates of the vertex are duplicated at each of the 4 vertices. If no texture coordinates are present in the vertex the default values of (0.0f, 0.0f, 0.0f, 1.0f) are used for the corners of the point sprite. If the D3DRS_POINTSPRITEENABLE is set to TRUE, then the texture coordinates at the 4 vertices, starting from the top left corner and winding clockwise, are set to:

(0.0f, 0.0f)
(1.0f, 0.0f)
(0.0f, 1.0f)
(1.0f, 1.0f)

When clipping is enabled, points are clipped as follows. If the vertex is outside the view frustum in Z (either near or far), then the point is not rendered. If the point, taking into account the point size, is totally outside the viewport in x or y, then the point is not rendered. Remaining points are rendered. Note that it is possible for the point position to be outside the viewport (in x or y) and still be partially visible.

Points may or may not be correctly clipped to user-defined clip planes. If D3DDEVCAPS_CLIPPLANESCALEDPOINTS is not set, then points are clipped to user-defined clip planes based only on the vertex position, ignoring the point size. In this case, scaled points will be fully rendered when the vertex position is inside the clip planes, and discarded when the vertex position is outside a clip plane. Applications may prevent potential ‘popping’ artifacts by adding a border geometry to clip planes that is as large as the maximum point size.

If the D3DDEVCAPS_CLIPPLANESCALEDPOINTS bit is set, then the scaled points are correctly clipped to user-defined clip planes.

It is important to remember that point sprites should have no dependencies on the culling or fill modes. Point sprites should always be rendered regardless of the cull or fill mode.

Also it is important that in point fill mode with flat shading that the rules for flat shading a primitive are complied with. This means that the first vertex of a primitive dictates the color of that primitive and hence the color for each vertex of the primitive. This is not what occurs with the current version of the reference rasterizer or the sample driver (version 8.0) and will be fixed in later versions.


Volume Textures

DirectX 8.0 adds support for volume or 3D textures. Such textures have depth in addition to width and height.


Reporting Support for Volume Textures

DirectX 8.0 introduces two new primitive texture capabilities flags that the driver sets to indicate support for volume textures. These flags are D3DPTEXTURECAPS_VOLUMEMAP and D3DPTEXTURECAPS_MIPVOLUMEMAP. D3DPTEXTURECAPS_VOLUMEMAP should be set in the dwTextureCaps field of the D3DPRIMCAPS8 structure (part of D3DCAPS8) if the hardware has support for volume textures. D3DPTEXTURECAPS_MIPVOLUMEMAP indicates that the driver supports MIP mapped volume textures.

It is a requirement that hardware that supports volume textures supports the use of volume textures in multi-texturing scenarios (in combination with other volume textures or 2D textures). If this scenario is not supported by the hardware, the driver cannot set D3DPTEXTURECAPS_VOLUMEMAP.

The driver can indicate that it requires the dimensions of the volume texture to be a power of 2 by setting the primitive texture capability D3DPTEXTURECAPS_VOLUMEMAP_POW2.

A driver that supports volume textures is also required to specify the minimum and maximum volume texture dimensions it supports. The field MaxVolumeExtent should be set to the maximum supported dimensions of the volume texture. It is a requirement that the same constraint applies to all three dimensions of the volume texture (width, height and depth).

A driver notifies the runtime of the volume texture filtering and texture addressing modes supported by the hardware by setting the VolumeTextureFilterCaps and VolumeTextureAddressCaps to the appropriate combinations of flags.

Finally, the driver notifies the runtime about what surface formats can be used with volume textures by setting the D3DFORMAT_OP_VOLUMETEXTURE in the dwOperations field of the surface format’s DDPIXELFORMAT.


Handling the Creation of Volume Textures

DirectX 8.0 introduces a new surface capability bit DDSCAPS2_VOLUME. This flag will be set in the ddsCapsEx.dwCaps2 field of the surface’s DD_SURFACE_MORE structure. In the DdCreateSurface and D3dCreateSurfaceEx callbacks the depth of the volume texture can be found in the low word of the dwCaps4 field of the extended surface capabilities (ddsCapsEx) of the surface’s DD_SURFACE_MORE structure. The driver should return the “slice pitch” (that is, the number of bytes to add to move from one 2D slice of the volume to the next) of the volume texture in the dwBlockSizeY field of the surface global structure.


Copying Volume Textures in the DP2 Stream

A new DP2 token, D3DDP2OP_VOLUMEBLT, has been added to support optimal copying and updating of volume textures. This token is very similar to the existing D3DDP2OP_TEXBLT which copies and updates textures but has been extended to support sub-volume (box) copying rather than simple rectangles.


Presentation

DirectX 8.0 formalizes the concept of “presentation” (or making the results of rendering visible to the user) in the API. Previously, this was accomplished either by page flipping in full screen mode or by blitting in windowed mode. The new Present API abstracts the differences of fullscreen and windowed mode away. However, this abstraction is not yet exposed at the DDI level. The runtime simply maps the present API to either the DdFlip or DdBlt DDI entry points depending on the application mode.

DirectX 8.0 has added two new DirectDraw blt flags which are passed to the driver as notification of when a blt operation is actually part of a Present and hence marks a frame boundary. These new flags are DDBLT_PRESENTATION and DDBLT_LAST_PRESENTATION. Two flags are necessary because clipping may result in a single Present call invoking multiple blt operations in the driver. In this case all of the blts that are invoked as a result of the Present operation have the DDBLT_PRESENTATION flag set. However, only the final blt of the sequence used to perform the Present will have the DDBLT_LAST_PRESENTATION bit set. Therefore, if blt is used to implement a Present call, the driver will see zero or more blts with the DDBLT_PRESENTATION bit set followed by exactly one blt with both the DDLT_PRESENTATION and DDBLT_LAST_PRESENTATION bits set. These flags are never set by the application. Only the runtime is allowed to pass these flags to a blt. In addition, these flags will only be passed to drivers supporting the DirectX 8.0 DDI.

The driver is only permitted to queue a maximum of three frames. If the driver sees a blt call with DDBLT_PRESENTATION set and it already has three DDBLT_LAST_PRESENTATION blts queued it must fail the call with DDERR_WASSTILLDRAWING. The runtime will retry until the queue has drained sufficiently.

If the driver can’t effectively determine when a DDBLT_LAST_PRESENTATION blt in the queue has been retired, then the must not queue frames at all. DDBLT_LAST_PRESENTATION should cause such drivers to return DDERR_WASSTILLDRAWING until the accelerator is completely finished, exactly as if the application had called Lock on the source surface before calling Blt.

Finally, in the case of multiple windowed applications running simultaneously, the driver should count presentation blts based on the source of each blt, rather than the primary, that is, the driver is allowed to queue three frames per window/render target. This will result in better performance in this case.


New DDSCAPS2 Flags

A new flag, DDSCAPS2_DISCARDBACKBUFFER, has been introduced to indicate that preservation of the back buffer is not required. It will be set on the primary surface and the back buffers if the application has set D3DSWAPEFFECT_DISCARD on the Present API.

DX8 runtimes now set another new flag, DDSCAPS2_NOTUSERLOCKABLE, on the primary and the back buffers if the flipping chain is not lockable, or on any render target that is not lockable. This allows drivers to do behind the scenes optimization. Note that it is still possible to lock the surfaces so the driver will need to handle these cases, but such locks will be very infrequent and are not expected to be fast.


Present and GetBltStatus

For DX8 the runtime no longer calls DdGetBltStatus on blts involving system memory surfaces. This was always the behavior on Windows® 2000 and is now the behavior on Windows 98/Me also. The result is that asynchronous DMA to or from system memory surfaces is no longer possible (see Asynchronous DMA Support in DirectDraw for details). DX8 drivers should not page lock system memory surfaces by themselves, and system memory to video memory transfers should be synchronous.


Palettized Textures

Although API support for palettized textures has been completely overhauled for DirectX 8.0, this is not reflected in the DDI. The existing palette oriented DP2 tokens continue to be used to notify the driver of the binding between a palette and a texture and of updates to palettes.

It cannot be assumed that, because an association between a surface and a palette has been established with D3DDP2OP_SETPALETTE, the lpPalette field of the surface structure points to a valid palette. The association between a palette and a surface established by the DP2 stream will not be reflected in the actual surface and palette data structures.

Furthermore, DirectDraw’s palette DDI entry points will not be called for these palettes. All DDI notifications of texture palette operations are done through the DP2 stream.


Cursors

DirectX 8.0 has added an API to support high update frequency cursors without requiring API level direct access to the primary surface. For DirectX 8.0, the cursor is the standard GDI cursor if capabilities permit, or else it is emulated with DirectDraw blts. To support the DirectX cursor API, the driver has to return capability information in D3DCAPS8.

The CursorCaps field should be set to D3DCURSORCAPS_MONO, D3DCURSORCAPS_COLOR, or both to indicate support for monochrome and color hardware cursors. The MaxCursorEdgeSize field should be set to the minimum of the maximum width and maximum height of the hardware cursor (or zero if no hardware cursor is supported). It is not possible to express different maximum sizes for the width and height of the cursor.


Vertex Shaders

All drivers that support the DirectX 8.0 DDI must support the new DP2 token D3DDP2OP_SETVERTEXSHADER even if programmable vertex shaders are not supported in hardware. This is because D3DDP2OP_SETVERTEXSHADER is the mechanism by which the FVF of incoming vertex data is communicated to the driver when using fixed function as well as programmable vertex processing.

D3DDP2OP_SETVERTEXSHADER can be used to notify the driver of either the handle of the current programmable vertex shader to use or the FVF of the vertex data for fixed function vertex processing due to the nature of the handle name space for vertex shaders. The vertex shader handle name space includes all vertex FVF codes. Thus, a vertex shader handle can refer either to a programmable vertex shader handle previously created by means of the D3DDP2OP_CREATEVERTEXSHADER DP2 token, or to the FVF code of a vertex format to be processed by fixed function vertex processing.

Therefore the driver for hardware that does not support programmable vertex processing should process D3DDP2OP_SETVERTEXSHADER to determine the FVF (and hence the processing to be performed) on the vertex data bound to stream zero. This is particularly important when processing user memory (UM) primitives. In this case, the only way of determining the FVF of the supplied vertex data is through the D3DDP2OP_SETVERTEXSHADER token. The test to determine whether a handle is a vertex shader handle or a legacy FVF code is simple. If the least significant bit of the handle is set (1) then the handle is vertex shader handler. If the least significant bit is clear (0) the handle is a legacy FVF code.

If the FVF code of a vertex buffer conflicts with that specified by D3DDP2OP_SETVERTEXSHADER the driver should ignore the FVF code of the vertex buffer and continue.

The DirectX runtime guarantees that only FVF codes will be passed as vertex shader handles to a driver that does not support programmable vertex processing. However, such a driver should have debug code to verify that the FVF code that is passed is supported.


Reporting Support for Programmable Vertex Processing Hardware

For a DirectX 8.0 level driver to report support for programmable vertex shader hardware it must set the VertexShaderVersion field of the D3DCAPS8 structure to a valid, non-zero vertex shader version number. The VertexShaderVersion is a DWORD where the most significant word must have the value 0xFFFE and the least significant word holds the actual version number. The least significant byte of this word holds the minor version number and the most significant byte holds the major version number. As the format of this DWORD is complex the driver must set the value of VertexShaderVersion using the macro D3DVS_VERSION defined in d3d8types.h. For example, the following code fragment sets the VertexShaderVersion to indicate support for 1.0 level functionality.

myD3DCaps8.VertexShaderVersion = D3DVS_VERSION(1, 0);

To report no support for programmable vertex shaders the following code fragment would be used:

myD3DCaps8.VertexShaderVersion = D3DVS_VERSION(0, 0);

Drivers that do not support programmable vertex processing should set VertexShaderVersion to zero.

In addition to setting the vertex shader version, the driver should report the number of constant registers it has for vertex shading. In order to support the 1.0 vertex shading specification the device must have at least 96 constant registers. The driver reports the number of constant registers in the MaxVertexShaderConst field of the D3DCAPS8 structure. For example, the following code fragment reports the minimum number of constant registers required for version 1.0 vertex shaders.

myD3DCaps8.MaxVertexShaderConst = 96;

d3d8types.h defines a symbol for the minimum number of constant registers required by version 1.0 of the vertex shader specification. This symbol is D3DVS_CONSTREG_MAX_V1_0 and it is recommended that the driver use this symbol unless it supports more than 96 constant registers.


Pixel Shaders

All drivers that support the DirectX 8.0 DDI may support the new DP2 token D3DDP2OP_SETPIXELSHADER if programmable pixel shaders are supported in hardware.

D3DDP2OP_SETPIXELSHADER can be used to notify the driver of the handle of the current programmable pixel shader to use. A pixel shader handle refers to a programmable pixel shader handle previously created by means of the D3DDP2OP_CREATEPIXELSHADER DP2 token.


Reporting Support for Programmable Pixel Processing Hardware

For a DirectX 8.0 level driver to report support for programmable pixel shader hardware it must set the PixelShaderVersion field of the D3DCAPS8 structure to a valid, non-zero pixel shader version number. The PixelShaderVersion is a DWORD where the most significant word must have the value 0xFFFF and the least significant word holds the actual version number. This least significant byte of this word holds the minor version number and the most significant byte holds the major version number. As the format of this DWORD is complex the driver must set the value of PixelShaderVersion using the macro D3DPS_VERSION defined in d3d8types.h. For example, the following code fragment sets the PixelShaderVersion to indicate support for 1.0 level functionality.

myD3DCaps8.PixelShaderVersion = D3DPS_VERSION(1, 0);

To report support for 0.5 level pixel shaders the code would be as follows:

myD3DCaps8.PixelShaderVersion = D3DPS_VERSION(0, 5);

Drivers that do not support programmable pixel processing should set PixelShaderVersion to zero.

Unlike vertex shaders, a device cannot expose more constant registers than the 1.0 specification defines. A device which implements the 1.0 pixel shader specification must expose only eight constant pixel shader registers. However, there is an additional pixel shader related capability that a driver should set, MaxPixelShaderValue. This field gives the internal range of values supported for pixel color blending operations. Implementations must allow data within the range they report to pass through pixel processing unmodified (for example unclamped). This value normally defines the limits of a signed range, that is, an absolute value. Therefore, for example, 1 indicates that the range is [-1.0 to 1.0], and 8 indicates that the range is [-8.0 to 8.0].

However, the special value 0.0 indicates that no signed range is supported, and therefore the range is [0 .. 1.0] as in DirectX 6/7.


High Order Surfaces

DirectX 8 introduces support for a class for high order surfaces. This section describes the mechanics of the DDI for these patch surfaces but it does not describe the algorithms used. Please refer to the reference rasterizer source code included with the DDK for the details of the algorithms employed.


Reporting Support for High Order Surfaces

A driver reports its support for high order surfaces using four new capability bits in the DevCaps field of the D3DCAPS8 structure. These flags are as follows:

D3DDEVCAPS_QUINTICRTPATCHES

Device supports quintic béziers and B-splines.

D3DDEVCAPS_RTPATCHES

Device supports rectangular and triangular patches.

D3DDEVCAPS_RTPATCHHANDLEZERO

When this device capability is set, the hardware architecture does not require caching of any information and that un-cached patches (handle zero) will be drawn as efficiently as cached ones. Note that D3DDEVCAPS_RPATCHHANDLERZERO does not mean that a patch with handle zero can be drawn. A handle zero patch can always be drawn whether this cap is set or not.

D3DDEVCAPS_NPATCHES

Device supports n-patches.


High Order Surface DP2 Stream Drawing Tokens

The D3DDP2OP_DRAWRECTPATCH token is sent to the driver to draw a rectangular patch. The D3DDP2OP_DRAWTRIPATCH token is sent to the driver to draw a triangular patch.


High Order Surface Render States

There are three render states that are used with high order surfaces. These render states are described below.

D3DRS_PATCHEDGESTYLE

This render state is used to control whether patch edges use discrete or continues tessellation. See the DirectX 8.0 SDK documentation for more details.

D3DRS_PATCHSEGMENTS

This render state gives the number of segments to be used for each edge of the patch. If an explicit number of segments is specified in the DP2 token those segments should override the value of this render state. See the DirectX 8.0 SDK documentation for more details.

D3DRS_DELETERTPATCH

This render state notifies the driver that a patch is to be deleted.


Multisample Rendering

DirectX 8.0 introduces support for multi-sample rendering with the number of samples per pixel under application control. The API support multi-sampling in both fullscreen and windowed modes of operation. Furthermore, there is sufficient flexibility to support hardware that performs the processing of samples into pixels at the back end (directly out of the frame buffer) or at the front end (via a special flip or blt call).


Reporting Multi-sample Support

A driver reports the multi-sample capabilities of the hardware by specifying the number of samples per pixel for each surface format it reports. DDPIXELFORMAT has been extended to include a structure called MultiSampleCaps. This structure has fields that let the driver express the number of samples per pixel for both flip (fullscreen) and blt (windowed) multi-sampling. Each of these fields is a WORD in which each bit indicates support for a given number of samples per pixel. Hence, the driver can express support for several different sample counts with a single surface format entry.


Multi-sample Support via StretchBlt

Although not the recommended mechanism for supporting multi-sampling it is possible to implement multi-sampling support in the driver by rendering to a large back buffer and performing a stretch blt to resample the large back buffer to the lower resolution primary. However, if this is the mechanism by which the driver supports multi-sampling it must set the new capability bit D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE in the RasterCaps field of the D3D8CAPS structure.

It is important to note if the driver uses a stretch blt to perform a page flip in fullscreen mode the driver should specify the supported sample counts in wFlipMSTypes and not wBltMSTypes as, conceptually at least, a flip is being performed.


Handling the Creation of Multi-Sampled Surfaces

When a multi-sampled surface is being created the number of samples can be found in the ddsCapsEx.dwCaps3 of the DD_SURFACE_MORE structure. This field simply holds one of the values of the enumerated type D3DMULTISAMPLE_TYPE. It is not a bit field like wFlipMSTypes or wBltMSTypes. If a surface is not multi-sampled dwCaps3 will have the value D3DMULTISAMPLE_NONE (0).

When determining whether a creation request for a multi-sample surface can be satisfied or not the driver should not take into account the current value of the D3DRS_MULTISAMPLEANTIALIAS render state. It is not permissible for a driver to fail a request to set D3DRS_MULTISAMPLEANTIALIAS false. Therefore, any restriction which would affect the ability to perform multi-sample rendering should be enforced at context create time even if D3DRS_MULTISAMPLEANTIALIAS is FALSE at that time.

Although DirectX 8.0 reduces the applications ability to access the primary surface it does not eliminate them. This has important implications when the primary buffer itself is multi-sampled. In those cases where Direct3D does lock the primary it does not expect the surface data to be multi-sampled. Therefore, if the underlying hardware does have a multi-sampled primary it must take appropriate action when the primary is locked and unlocked. On DdLock the driver must return a buffer of data that contains the contents of the primary in a single sample-per-pixel format. On DdUnlock the driver must convert the single sample-per-pixel format back to primary’s multi-sampled format. The new cursor API can also result in DdBlt calls targeting the primary. Again, if the primary is multi-sampled, the DdBlt call must handle the conversion from the single sample-per-pixel cursor data to the mutli-sampled primary.


Controlling Multi-sampling

Two render states control multi-sample rendering.

D3DRS_MULTISAMPLEANTIALIAS

A BOOL value that determines how individual samples are computed when using a multi-sample render target buffer. When set to TRUE, the multiple samples are computed so that full-scene antialiasing is performed by sampling at different sample positions for each multiple sample. When set to FALSE, the multiple samples are all written with the same sample value (sampled at the pixel center), which allows non-antialiased rendering to a multi-sample buffer. This render state has no effect when rendering to a single sample buffer. The default value is TRUE.

See the DirectX 8.0 SDK documentation for more details.

D3DRS_MULTISAMPLEMASK

Each bit in this mask, starting at the LSB, controls modification of one of the samples in a multi-sample render target. Thus, for an 8-sample render target, the low byte contains the 8 write enables for each of the 8 samples. This render state has no effect when rendering to a single sample buffer. The default value is 0xFFFFFFFF.

This render state enables use of a multi-sample buffer as an accumulation buffer, doing multi-pass rendering of geometry where each pass updates a subset of samples. See the DirectX 8.0 SDK documentation for more details.


Pure Device Support

DirectX 8.0 introduces the concept of a “pure” device. When using a pure device the runtime is somewhat more lightweight; it will not track state or state blocks or perform any software vertex processing on behalf of the hardware. Furthermore, the application cannot query back state from the runtime. The lack of state tracking, particularly when state blocks are being used, can result in a significant performance boost for the application.

Only vertex processing directly supported by the hardware is available to the application when using a pure device. For example, for cards that don’t support hardware transform and lighting, only pre-transformed vertices can be passed to Direct3D. Furthermore, the API functions SetClipStatus, GetClipStatus and ProcessVertices cannot be used with the pure device.

In order to use a pure device the application must request it with the device creation flag D3DCREATE_PUREDEVICE and the driver must report its ability to act as a pure device.


Reporting Pure Device Capability

A driver reports the ability to support pure devices by setting the new device capability D3DDEVCAPS_PUREDEVICE in the DevCaps field of the D3DCAPS8 structure.


State Block Recording and Pure Devices

State block handling is different for a device operating in pure device mode. In this mode, the state block control DP2 token (D3DDP2OP_STATESET) will be sent to the driver with a new operation type (in the dwOperations field). This new operation type is D3DHAL_STATESETCREATE.


Processing the D3DDP2OP_CLEAR DP2 Token

DirectX 8.0 introduces some changes to the required processing of the D3DDP2OP_CLEAR token. Specifically a new flag D3DCLEAR_COMPUTERECTS has been added to the dwFlags field of the D3DHAL_DP2CLEAR data structure. This new flag will only be passed to the driver when a pure device type is being used (that is, D3DCREATE_PUREDEVICE was specified when creating the device and the driver exports the D3DDEVCAPS_PUREDEVICE device cap). Furthermore, this flag will never be passed to non-DirectX 8.0 drivers and it will not be specified using the legacy Clear or Clear2 driver callbacks.


Vertex Buffer Issues

The following section contains update information for vertex buffer creation and use.


Vertex Buffer Callbacks and Windows 2000

DirectX 7.0 on the initial retail release of Windows® 2000 and on Windows 2000 Service Pack 1 (SP1) suffers from a defect that prevents a driver’s execute buffer (D3D buffer) callbacks from being invoked by the runtime. This prevents the driver from being notified of vertex buffer creation requests and, hence, no video memory or non-local video memory buffers can be created or used in this scenario. This defect is not present in DirectX 8.0 or in the version of DirectX 7.0 that is shipped with DirectX 8.0. Furthermore, it will be corrected in an upcoming service pack for Windows 2000 and in all future versions of Windows 2000. However, there is no workaround to enable video memory vertex buffers on Windows 2000 or Windows 2000 SP1 other than to install DirectX 8.0.


Vertex Buffer Creation Handling on Windows 2000

In DirectX 8.0 vertex (and index) buffers can be managed as textures were in DirectX 7.0. That is, a system memory copy of a vertex copy is maintained at all times and a video memory copy is only allocated when that vertex buffers is actually required. In order to make vertex management work correctly, however, it is essential that the driver fail vertex buffer creation in the correct way. If the driver does not want to allocate a vertex buffer in video memory but, instead, wishes the runtime to allocate the buffer in system memory, it should not return DDHAL_DRIVER_NOTHANDLED but rather should return DDHAL_DRIVER_HANDLED and indicate failure by setting a ddRVal of E_FAIL. If the driver returns DDHAL_DRIVER_NOTHANDLED the runtime will attempt to allocate the surface from the video memory heaps returned by the driver. This may either fail and return an error to the application or result in the surface being allocated in local or non-local video memory (which is not the intention).

Therefore, if you wish the runtime to allocate a vertex buffer in system memory on your behalf please set ddRVal to E_FAIL and return DDHAL_DRIVER_HANDLED.


Vertex Buffer Renaming

To improve parallelism between the driver and the runtime Direct3D supports the concept of vertex buffer “renaming”. Essentially this is a double buffering scheme for vertex buffers. In certain circumstances a driver can, when passed a vertex buffer through a DDI call, modify the video memory pointer of the vertex buffer. In this way, the driver can continue to process the contents of the vertex buffer, while, at the same time, the application can lock and fill the vertex buffer. As far as the application is concerned it is using the same vertex buffer. The fact that the memory pointed to by that vertex buffer has been modified is hidden by the runtime and driver.

Although previous versions of DirectX supported vertex buffer renaming there have been certain changes with DirectX 8.0. In previous versions of Direct3D, renaming was primarily accomplished via the D3dDrawPrimitives2 DDI entry point. Flags specified in D3DHAL_DRAWPRIMITIVES2DATA would specify whether the driver could swap the vertex or command buffer and if so, what the required sizes of the buffers would be. However, in DirectX 8.0 vertex buffer swapping is not accomplished through D3dDrawPrimitives2 (although calls through legacy interfaces will still exploit this mechanism) but rather through the LockExecuteBuffer (LockD3DBuffer) DDI entry point.

DirectX 8.0 defines a new lock flag, D3DLOCK_DISCARD, that when passed to the driver indicates that the caller does not require the existing contents of the driver and hence they can be discarded prior to returning the pointer to the vertex buffer data. Hence, when the driver receives a vertex buffer lock call with the D3DLOCK_DISCARD flag set it can choose to rename the vertex buffer by setting the fpVidMem to a new value.

It is important to note that the D3DLOCK_DISCARD flag will not be passed to the driver by the initial retail release of Windows® 2000. The flag will be passed on Windows 2000 Service Pack 1 (SP1) and all subsequent versions of Windows 2000 and all versions of Windows 98/Me.

In DirectX 7.0 vertex buffer renaming could also be accomplished via LockExecuteBuffer using the flag DDLOCK_DISCARDCONTENTS. However, there were defects in the synchronization between runtime and driver on the original release of DirectX 7.0 that prevent this mechanism working correctly. However, the version of DirectX 7.0 released with DirectX 8.0 corrects this problem and vertex buffer renaming at lock time will be functional through DirectX 7.0 interfaces.


Handling Renaming on Windows 2000

In order to correctly perform vertex buffer renaming it is important to understand the nature of the fpVidMem pointer stored in the surface global object on Windows® 2000 and later. The interpretation of fpVidMem depends on the type of memory in which the surface is stored. For both system and non-local video memory (AGP) surfaces the fpVidMem is a pointer directly into the user mode address space of the process owning that surface.

For local video memory surfaces, fpVidMem is an offset from the start of video memory. In order to convert this to a user mode pointer it is necessary to add the base address of video memory as mapped into a user mode process. This base address can be found in the fpProcess field of the DirectDraw local object for a given process.

Although fpVidMem for a non-local video memory surface is simply a user mode pointer the means by which this user mode pointer are generated are somewhat complex. It is necessary to understand how the Windows 2000 kernel maintains AGP heaps and manages surface allocations from them. The first important point is that, for non-local heaps, the start address of the heap maintained by the kernel may not be a heap into any real address space. It is in fact, normally, a numerical offset designed to ensure that valid allocations from that heap cannot have a NULL (zero) address.

It may be helpful to think of AGP heaps as residing in a conceptual address space that does not correspond to any real address space. The fpStart field of an AGP heap is the base address of the heap in this conceptual address space. Furthermore, any surfaces allocated from an AGP heap have an fpHeapOffset that also lies in this conceptual address space. Thus, fpHeapOffset is an offset from the base of this conceptual heap and it is not an offset from the start of the heap itself. Furthermore, it is not a pointer into any real address space. In order for a user mode process to access the memory of a surface fpHeapOffset must be mapped (via pointer arithmetic) into the address space of that user mode process. When a surface is created the kernel performs this mapping according to the formula outlined below.

Given a surface (pSurface), a kernel mode AGP heap (pvmHeap) and a mapping of the heap into a particular user mode process (pMap), the following formula is used to compute the actual, user mode, fpVidMem, for a surface:

fpVidMem = pMap->pvVirtAddr +
    (pSurface->fpHeapOffset – pvmHeap->fpStart)

pvVirtAddr is the base address of the user mode mapping of the AGP heap into a given process. fpStart is the offset of the base of the AGP heap into the conceptual address space described above and fpHeapOffset is the offset of the start of the surface from the base of the same conceptual address space.

Your driver is notified of the conceptual base address of AGP heaps through the DdGetDriverInfo callback. When DdGetDriverInfo is called with GUID_UpdateNonLocalHeap the fpGARTLin field of the data structure passed is the same value as fpStart, i.e., the base address of the start of the AGP heap in the conceptual address space. Unfortunately, your driver is not notified of the value of pvVirtAddr and it is not visible to the driver through any of the data structures passed to the driver. Therefore, its value has to be computed from the fpVidMem computed by the kernel for the vertex buffer on initial creating. Given the fpVidMem computed by the kernel simply subtract the current fpHeapOffset less the heap’s fpStart. Given the fpHeapOffset of the new memory to be swapped into the vertex buffer on renaming the new value of fpVidMem can be easily computed.

The following code fragment demonstrates computing a new fpVidMem for an AGP surface in a lock call.

// Get the vertex buffer’s surface local and global from the
// lock data
LPDDRAWI_DDRAWSURFACE_LCL*pLcl = pLockData->lpDDSurface;
LPDDRAWI_DDRAWSURFACE_GBL*pGbl = pLcl->lpGbl;

// Get heap this vertex buffer was allocated from
LPVVIDEOMEMORY pHeap = pGbl->lpVidMemHeap;

// Get the current fpVidMem for the vertex buffer
FLATPTR fpCurrentVidMem = pGbl->fpVidMem;

// Compute the virtual base address of the mapping of this AGP
// into the process owning this vertex buffer.
FLATPTR pvVirtAddr = fpCurrentVidMem –
                     (pGbl->fpHeapOffset – pHeap->fpStart);

// Given the fpHeapOffset of the non-local video memory to be
// swapped into the new vertex buffer compute the new fpVidMem
// as follow
FLATPTR fpNewVidMem = pvVirtAddr + (fpNewHeapOffset – pHeap->fpStart);

// Now store the new fpVidMem in the surface global object and
// also in the lock data.
pGbl->fpHeapOffset = fpNewHeapOffset;
pGbl->fpVidMem = fpNewVidMem;
pLockData->lpSurfData = fpNewVidMem;

// Return success and driver handled
pLockData->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;

In order to make non-local video memory accessible to a user mode process it is necessary for the memory to be both committed and mapped to the user mode process. To ensure that this is done when vertex buffer renaming is being performed it is essential that the new memory for the vertex buffer be allocated using the Eng Xxx function HeapVidMemAllocAligned. This will guarantee that the memory is committed and mapped prior to use. HeapVidMemAllocAligned returns an offset into the conceptual address space of the AGP heap and, hence, this pointer can be used as an fpHeapOffset directly.

If the driver returns DDHAL_DRIVER_HANDLED for a lock of an AGP surface the kernel code will return to the runtime and application the value of lpSurfData in the DD_LOCKDATA data structure. If the driver returns DDHAL_DRIVER_NOTHANDLED the kernel simply returns the value of fpVidMem to user mode. Therefore, it is not necessary to return DDHAL_DRIVER_HANDLED as long as fpVidMem is updated to point to the new user mode pointer. However, we recommend that the driver both set fpVidMem and lpSurfData and return DDHAL_DRIVER_HANDLED.


Clipping Transformed Vertices

The Direct3D 8.0 runtime fully supports the clipping of pre-transformed vertices through both the DrawPrimitive and ProcessVertices API calls. This clipping includes user defined clipping planes as well as Z and the X and Y viewport extents. However, the runtime does not guarantee the clipping of post-transformed vertices. Post-transformed vertex data is passed directly from the application to the driver by the runtime. This does not imply that a driver is required to full clip post-transformed vertex data. A new capability flag D3DPMISCCAPS_CLIPTLVERTS has been added for DirectX 8.0. If the driver sets this flag in the PrimitiveMiscCaps field of the D3DCAPS8 structure the application can assume that the driver will fully clip post-transformed vertex data to Z and the X and Y viewport extents. Clipping to user-defined clip planes is never supported for post-transformed data. If the driver does not set this flag the application is required to performing clipping of the post-transformed data to the Z extents and to (at least) the guard band extents in X and Y.

It is important to note that the runtime does not validate that the application has correctly clipped post-transformed data. It is the driver’s responsibility to ensure that a crash or hang does not occur if unclipped or incorrectly clipped data is passed when this flag is set.


DirectX Video Acceleration Overview

This document describes an Application Programming Interface (API) and a corresponding Device Driver Interface (DDI) for acceleration of digital video decoding processing, with support of alpha blending for such purposes as DVD subpicture support. It provides an interface definition focused on support of MPEG-2 “main profile” video (formally ITU-T H.262 | ISO/IEC 13818-2), but is also intended to support other key video codecs (e.g., ITU-T Recommendations H.263 and H.261, and MPEG-1 and MPEG-4). This design is limited to decoding support, but encoding features may be defined as the interface is further extended in the future. The interface is designed to extract the most basic computationally-intensive building-blocks of these various codec designs and support their acceleration in hardware.

Graphics hardware drivers should implement support for this interface to provide a generic form of access to the acceleration capabilities of their hardware implementations. Somewhat similar vendor-specific capabilities have been defined in the past by several companies for use with their graphics hardware. However, the intent of this specification is to establish a common interface to provide cross-vendor compatibility between software application programs and advanced graphics acceleration capabilities. The establishment of a common interface is expected to increase the capability of computing systems to support video, increase the demand for software applications that provide this capability, and increase the demand for high-performance graphics capabilities.


Summary

The interface defined in this specification is capable of supporting today’s dominant standard motion-compensated video codecs, including the H.26x series from the ITU-T and the MPEG-x series from ISO/IEC JTC1. It is primarily designed to support the current most commercially-dominant video codec known as MPEG-2, more formally known as ITU-T Recommendation H.262 or ISO/IEC 13838-2.

The syntax specified herein is designed to provide very direct support of that standard with very low “translation” requirements for converting its syntax to the format defined herein. Additional features have been added as necessary to support the other standards in a maximally-consistent manner, and encryption is supported for applications which may require it. By extracting the core common basic operations of these various standards and confining some standard-specific processing to the host CPU, this interface enables support of video codec hardware acceleration with a high degree of cross-standard flexibility while requiring minimal standard-specific customization in the acceleration hardware.


Purpose and Standards Addressed

This specification defines a language of video decoder acceleration which permits one or more stages to be divided among one or more devices. Currently, this document describes a division between a Host CPU and hardware Accelerator which executes the motion-compensated prediction (MCP) and/or inverse discrete-cosine transform (IDCT) stages of ITU-T H.261, MPEG-1 (ISO/IEC 11172-2), MPEG-2 (ISO/IEC 13818-2 | ITU-T Rec. H.262), ITU-T H.263, and a subset of MPEG-4 (ISO/IEC 14496-2). The overall goal is to offload simple (yet frequently-executed) operations wasteful of CPU resources onto a low-cost accelerator designed for this specific purpose, while allowing implementations to leave the complex, less frequently-executed operations such as bitstream parsing and variable-length decoding (VLD) on the host CPU.

The specification as described herein is for the decoding of a single video stream. No support is provided within the Microsoft® DirectX® VA API to explicitly support multiple video streams. Support of multiple video streams would therefore require a separate DirectX® VA session operation for each such video stream (e.g., a separate pair of output and input pins for the video decoder and acceleration driver for use in filter graph operation).


Requirements, Performance Verification and Schedule

A verification of compliance with the contents of this specification will be required of any accelerator driver exposing the interface described herein. This will include:

  • Verification that the operations carried out by hardware using this API will yield the intended mathematical results, and
  • Verification that the performance obtained by a software decoder using this API will be of adequate speed and reliability to justify use of this API rather than host-software implementation of its functionality.

Until such verification is conducted, Microsoft considers the implementation to be strictly for testing purposes and not suitable for deployment with a driver that exposes the interface specified herein.

Support of this interface and performance verification for that support is expected to be required for certification of implementations for decoders and graphics accelerators in the intermediate-term future. The precise test suites and performance metrics are yet to be defined. The intermediate-term future requirements as specified herein are expected to be defined as requirements applicable in mid 2001 on all Microsoft Windows® operating systems, e.g. Windows Millenium and later and Windows 2000 and later, for any graphics acceleration hardware claiming support for hardware video decoding acceleration and for any software decoders claiming to use such graphics acceleration hardware support. Any longer-term future requirements as specified herein are expected to be defined as requirements applicable approximately one year after the intermediate-term requirements. The deadline dates of these expected requirements may be adjusted as events progress.

Anticipated encryption, configuration, and restricted mode support requirements are discussed in later sections that describe the encryption support, configurations and restricted modes. Pixel format support requirements are discussed in the following section .


Uncompressed Picture Formats

For applications to use the uncompressed decoded pictures produced through DirectX VA, these pictures must be produced in some known format. The list of uncompressed pixel formats supported by any DirectX VA accelerator shall contain at least one member of the following list of pixel formats [Reference: YUV Formats]:

  • For decoding compressed 4:2:2 video:
    • a. “YUY2”, in which the data can be treated as an array of unsigned char in which the first byte contains the first sample of Y, the second byte contains the first sample of Cb, the third byte contains the second sample of Y, the fourth byte contains the first sample of Cr; etc. (such that if addressed as an array of two little-endian WORD type variables, the first WORD contains Y0 in the LSBs and Cb in the MSBs and the second WORD contains Y1 in the LSBs and Cr in the MSBs). This is the preferred DirectX VA 4:2:2 pixel format, and is expected to be an intermediate-term requirement for DirectX VA accelerators supporting 4:2:2 video.
    • b. “UYVY”, which is the same as “YUY2”, except for swapping of the byte order in each word (such that if addressed as an array of two little-endian WORD type variables, the first WORD contains Cb in the LSBs and Y0 in the MSBs and the second WORD contains Cr in the LSBs and Y1 in the MSBs).
  • For decoding compressed 4:2:0 video:
    • a. “YUY2” as above, except that two lines of output Cb and Cr samples are produced for each actual line of 4:2:0 Cb and Cr samples, the second of each pair of such two lines being either a duplicate of the first or an average of the first and third. The ability to “front-end” convert from whichever format is in use to this format is expected to be an intermediate-term requirement.
    • b. “UYVY” as above, except that two lines of output Cb and Cr samples are produced for each actual line of 4:2:0 Cb and Cr samples, the second of each pair of such two lines being a either a duplicate of the first or an average of the first and third.
    • c. “YV12”, in which all Y samples are found first in memory as an array of unsigned char (possibly with a larger stride for memory alignment), followed immediately by all Cr samples (with half the stride of the Y lines, and half the number of lines), then followed immediately by all Cb samples in a similar fashion.
    • d. “IYUV”, which is the same as YV12, except for swapping the order of the Cb and Cr planes.
    • e. “NV12” (not found in the referenced web page), in which all Y samples are found first in memory as an array of unsigned char with an even number of lines (possibly with a larger stride for memory alignment), followed immediately by an array of unsigned char containing interleaved Cb and Cr samples (such that if addressed as a little-endian WORD type, Cb would be in the LSBs and Cr would be in the MSBs) with the same total stride as the Y samples. This is the preferred 4:2:0 pixel format, and is expected to be an intermediate term requirement for DirectX VA accelerators supporting 4:2:0 video.
    • f. “NV21” (a neologism not found on the referenced web page), as in NV12 except that Cb and Cr samples are swapped so that the chroma array of unsigned char would have Cr followed by Cb for each sample (such that if addressed as a little-endian WORD type, Cr would be in the LSBs and Cb would be in the MSBs).
    • g. “IMC1” (a neologism not found on the referenced web page), as in YV12, except that the stride of the Cb and Cr planes is the same as the stride in the Y plane. The Cb and Cr planes are also restricted to fall on memory boundaries which are a multiple of 16 lines (a restriction which has no effect on usage for the standard formats, since the standards all use 16×16 macroblocks).
    • h. “IMC2” “ (a neologism not found on the referenced web page), as in IMC1, except that Cb and Cr lines are interleaved at half-stride boundaries. In other words, each full-stride line in the chrominance area starts with a line of Cr, followed by a line of Cb that starts at the next half-stride boundary. (This is a more address-space efficient format than IMC1, cutting the chrominance address space in half, and thus cutting the total address space by 25%.) This runs a close second in preference relative to NV12, but NV12 appears to be more popular.
    • i. “IMC3” (a neologism not found on the referenced web page), as in IMC1, except for swapping Cb and Cr.
    • j. “IMC4” (a neologism not found on the referenced web page), as in IMC2, except for swapping Cb and Cr.

Our primary goal in specifying these formats is to document the formats in use, to enable use of the decompressed video for subsequent processing which would manipulate the video as DirectDraw surface textures. Our secondary goal is to simplify software operation by cutting down the proliferation of different formats over time – eliminating the use of different formats that unnecessarily duplicate the same functionality.


Accelerator Sequentiality Requirements

The primary burden for ensuring that race conditions do not cause undesirable behavior in the operation of the interface is placed on the host software decoder rather than the hardware accelerator. The only requirement imposed herein on the accelerator in this regard is to be able to properly report when queried whether the display of an uncompressed surface is pending or in progress and to be able to properly report when queried whether requested operations have been completed.


Software Decoder Sequentiality Requirements

Certain requirements are imposed herein to provide an assurance of proper operation of sequential operations in the decoding process. These concern the handling of uncompressed surfaces for decoding and display. The examples provided herein concern the handling of picture decoding for conventional I-, B-, and P-structured video frames (without using a deblocking filter). The same principles apply in an obvious way to other scenarios.

The guiding principles are simple: Don’t write over what you need for referencing or display, and avoid race conditions. This principle can be decomposed into two rules:

  1. No picture can be overwritten that has been submitted for display unless it has already been shown on the display and also removed from the display (to avoid tearing artifacts on the display), and
  2. No picture can be overwritten that is needed as a reference for the creation of other pictures that have not yet been created.

This results a requirement that the software decoder must query the status of the accelerator to avoid race conditions, and also results in a requirement that the decoder must use a sufficient number of uncompressed picture surfaces to ensure that space is available for all necessary operations.

This results in a need for at least four uncompressed picture surfaces for I, B, P picture processing (more are generally encouraged, and more are necessary for some operations such as the use of front-end alpha blending).

The following two subsections describe the use of four or more uncompressed surfaces for video decoding with B pictures, concluding that at least four uncompressed surfaces are generally needed and five or more are recommended for applications without critical delay-minimization requirements. Using extra surfaces can greatly reduce the need to wait for operational dependencies to be resolved.

Note that for compressed buffers as well as uncompressed surfaces, it is generally better to cycle through using all of the available buffers that have been allocated rather than to keep re-using the same one or the same subset of the allocated buffers, possibly causing bottlenecks which require delays to be added to wait on unnecessary dependencies. In some cases the allocation of multiple buffers by a driver may be meant to indicate that cycling through use of these buffers for double or triple buffering is the proper way to operate without artifacts. (This applies to alpha blend data loading in particular.)


Using Four Uncompressed Surfaces for Decoding

The following table shows a hypothetical case of a video decoder that requires one frame time to decode each picture and is decoding a bitstream which contains a steadily-increasing number of B pictures (starting from zero B pictures after an initial I picture) between pairs of P pictures. In this example, a letter is used to show the type of each picture (I, B, or P), a subscript is used to show the temporal display order of each picture, and a superscript is used to show which buffer is used for holding the picture. Each B picture requires two prior pictures in bitstream order in order to be decoded. As a consequence, the decoder cannot begin displaying pictures with their proper timing until after the second picture has been decoded – i.e., until during the third time slice of decoding. Somewhere during this time slice, the display of pictures with their proper timing can begin.

The initiation of the display of a picture does not in general perfectly coincide with that picture appearing on the display. Instead, the display may continue to show a picture that is prior to the one that has been commanded for display (until the proper time arrives to switch to the new picture). Thus, for optimal performance, surface 0 (which holds the first I picture) should not be overwritten for use by the B picture which arrives three frame times later, even though the I picture is not needed by that B picture for referencing. Instead, a fourth surface (surface 3) should ideally be used to hold that B picture. This avoids the need to check whether the display period of the first I picture has been completed before decoding the B picture.

Application of the two rules given above imply that the first three decoded pictures must be placed in different surfaces, because none of them has been displayed until some time during the third period (period 2). Then the fourth decoded picture should ideally be placed in a fourth surface because the display of the first displayed picture may not yet be over until some time during the fourth period (period 3).

A significant bottleneck in the process illustrated in the following figure occurs upon encountering the 10th decoded picture (B19) as a result of having more than two B pictures in a row. When the third or subsequent B picture in a contiguous series is encountered, the time lag tolerance between the display of one B picture and the use of a surface to hold the next decoded B picture is eliminated. In this situation, the host decoder must check the display status of the B picture displayed in the previous period (in this case, B17) to ensure that it has been removed from the display (waiting for this to happen if necessary), and then must immediately use the same surface for the next B picture to be decoded (in this case, surface 1 used for B19). It cannot decode the new B picture into either of the surfaces being used to hold its reference I or P pictures (in this case, surfaces 0 and 2 used for P06 and P210), and cannot decode the new B picture into the surface being displayed during the same interval of time (in this case, surface 3 used for B38). So it must use the surface that was displayed in the immediately preceding period (in this case, surface 1).

Decoding Process: |  |  |  |  |  |
Display Process: |  |  |  |  |  |
Frames Decoded: (at start of interval) | 0 | 1 | 2 | 3 | 4 | 5
Decoding Process: |  |  |  |  |  |
Display Process: |  |  |  |  |  |
Frames Decoded: (at start of interval) | 6 | 7 | 8 | 9 | 10 | 11
Decoding Process: |  |  |  |  |  |
Display Process: |  |  |  |  |  |
Frames Decoded: (at start of interval) | 12 | 13 | 14 | 15 | 16 | 17
Decoding Process: |  |  |  |  |  | …
Display Process: |  |  |  |  |  | …
Frames Decoded: (at start of interval) | 18 | 19 | 20 | 21 | 22 | …

Four-Frame Decoder Buffering (superscript is buffer number, subscript is frame display index)


Using Five or more Uncompressed Surfaces for Decoding

More than four buffers can be used – allowing the time lag between the start of the display of a buffer and new writes to that buffer to increase from a minimum of one display period to two or more. This can provide more of an allowance for jitter in the timing of the decoding process. This can also enable output processing on the decoded pictures to perform a three-field deinterlace operation as part of the display process (since not only the current picture would be available for display, but the prior picture would also be available and could be used to provide context and/or allow a one-field delay in the actual display process). It can also provide some immunity against badly-designed hardware drivers that may not be written with a proper awareness of whether a picture is actually still being displayed or not (although one should properly be able to depend on hardware drivers not to exhibit such behavior). Although four buffers is the minimum for effective use of DirectX VA with B pictures, using five or more buffers is encouraged – particularly in scenarios in which very low delay is not a requirement. DirectX VA decoders for I, B, P-structured video decoding are therefore expected to set their minimum and maximum requested uncompressed surface allocation counts to at least 4 and 5, respectively, when allocating uncompressed surfaces. Using one or more extra uncompressed surfaces may often be a good way to achieve smooth, reliable, tear-free operation.


Terminology

The following sections cover the Abbreviations and Symbols, Bit Numbering Convention and Definitions used in these documents.


Abbreviations and Symbols

' ' | Binary value (left bit is MSB)
" " | Decimal value
0x | Hexadecimal value
LSB | Least Significant Bit
MSB | Most Significant Bit
// | Division with rounding away from zero
/ | Division with truncation toward zero


Bit Numbering Convention

Bit numbering in this specification is done per Microsoft prevailing convention, which is to number the LSB as bit 0 and the MSB as bit N-1 for an N bit quantity.

Note This numbering convention differs from the one used in some of the video coding standards, in which the lowest-numbered bit would be the MSB.

However, when a sequence of fields of less than 8 bits is shown in a structure in this document, the sequencing follows the convention used in the video coding standards, which is to say that elements listed first are considered to lie closer to the MSB. For example, if we have an array of five single-bit elements to place in sequence into a structure description, they will be listed in decreasing index order in the structure description.

The schizophrenia inherent in this approach means that the ultimate authority for exactly where each bit goes in this interface specification should be considered to be the “.h” file associated with this interface, not this document.


Definitions

reference block
Block area extracted from reference frame buffer.
prediction block
Block filtered from reference block.
prediction plane
Array of samples formed prior to combining of macroblock prediction. Each plane represents a set of prediction blocks, usually collected from one frame location. Planes are combined to form a single macroblock prediction.
Prediction macroblock
Macroblock prediction including all color channels
component
One of three color channels {Y, Cb, Cr }.
Host CPU
Programmable processor which controls overall function of video decode (high level operations).
Accelerator
Functional unit which executes simple but high rate operations such as IDCT, MCP, display format conversion.
motion vector arithmetic
Operations which convert motion vectors to prediction block addresses.
prediction address
Location of the prediction block within an implementation-specific design.
composite prediction block
Prediction block whose attributes apply to both luminance and chrominance.
component prediction block
Prediction block whose attributes apply to either luminance or chrominance.
intra
Representation of picture content without prediction using any previously-decoded picture as a reference.
inter
Representation of picture content by first encoding a prediction of an area of the picture using some previously-decoded picture and then optionally adding a signal representing the deviation from that prediction.
residual difference decoding
Decoding of the waveform which represents the error signal which has been encoded to represent whatever signal remains after motion-compensated prediction as appropriate. This may entail simply an “intra” representation of a non-predicted waveform or an “inter” difference after prediction.
ReservedBits
Any field in this specification having the name ReservedBits as its name or part of its name is not presently used in this specification and shall have the value zero.
should
Used to describe encouraged (but not required) behavior.
shall
Used to describe required behavior.


Stages

The stages depicted in the following figure comprise the MCP and IDCT Accelerator.

Decoder Stages


Frame Buffer Organization

All picture buffers are assumed to have frame-organized buffers as per MPEG-2 specification. Address Units shall be given in frame coordinates unless otherwise specified. It is possible to losslessly convert prediction blocks described in frame coordinates to field coordinates via an implementation-specific translation layer. For example, a single frame motion prediction can be broken into two separate, top and bottom macroblock-portion predictions.

The three video component channels {Y, Cb, Cr} are accessed by interfaces defined in this specification. Motion vectors for the two chrominance components are derived from those sent for luminance components. Conversion of these motion vectors to different coordinate systems is a responsibility of the Accelerator.


Operation for Current Standards

Host and Accelerator System

The basic operations of H.261, MPEG-1, MPEG-2 (H.262), H.263, and MPEG-4 are listed in chronological order in the following sections with a brief description of how they can be realized using this specification.


ITU-T H.261

Formally titled “Video Codec for Audiovisual Services at px64 kbit/s,” ITU-T Recommendation H.261 was the first digital video coding standard to deliver a practical design with relatively high compression (the first digital video coding standard, H.120, is largely forgotten today), and it contains the same basic design to be later used in the other video codec standards, using 8-bit samples with Y, Cb, and Cr components, 4:2:0 sampling, 16x16 “macroblock”-based motion compensation, 8x8 IDCT, zig-zag inverse scanning of coefficients, scalar quantization, and variable-length coding of coefficients based on a combination of zero-valued run-lengths and quantization index values. All H.261 prediction blocks use forward-only prediction from the previous picture. H.261 does not have half-sample accurate prediction filters, but instead uses a type of low-pass filter called the “loop filter” (Section 3.2.3 of the H.261 specification) which can be turned off or on during motion compensation prediction for each macroblock.

Annex D Graphics: H.261 later included an interesting trick mode called “Annex D Graphic Transfer.” No special support is provided for this feature in this accelerator interface. This feature can be supported using this specification by reading four decoded pictures from the accelerator back onto the host and interleaving them there for display as a higher-resolution graphic picture.


MPEG-1

MPEG-1 video, formally ISO/IEC 11172-2, was developed not long after H.261 and borrowed significantly from it. It has no loop filter, and instead has a simple half-sample filter which attempts to resolve sub-pixel movement between frames. Two additional prediction modes, bi-directional and backward prediction were added which require one additional reference frame to be buffered. The bi-directional prediction averages forward- and backward-predicted prediction blocks. The arithmetic for averaging forward and backward prediction blocks is similar to that for creating a half-sampled “interpolated” prediction block. The basic structure is otherwise the same as H.261.


MPEG-2 (a.k.a. H.262)

MPEG-2, formally titled "Information Technology – Generic Coding of Moving Pictures and Associated Audio Information: Video,” ITU-T Recommendation H.262 | ISO/IEC 13818-2, added only a basic 16x8 shape to the existing tools of MPEG-1 (from a very low layer perspective). From a slightly higher layer perspective, MPEG-2 added many additional ways to combine predictions referenced from multiple fields in an attempt to deal with interlaced video characteristics.

MPEG-2 frame structured pictures:

Frame MC: has a 16x16 prediction block shape, much the same as MPEG-1 predictions. This is the only progressive-style motion within MPEG-2 (as specified by the motion_type parameter in MPEG-2). There are either one prediction plane (forward-only or backward-only) or two (bi-directional) as determined by the macroblock_type MPEG-2 parameter. Reference blocks are formed from contiguous frame lines from the frame buffer. The frame buffer is selected by the semantics of the decoding process. Half-sample interpolation (MPEG-2 Section 7.6.4) and bi-directional interpolation (MPEG-2 Section 7.6.7.1) have identical averaging operations as in the MPEG-1 case.

Field (16x8) MC: Each plane (forward and backward directions) consists of a top 16x8 prediction block, and a bottom 16x8 prediction block. The reference block corresponding to each prediction block may be extracted from the top field or bottom field of a reference frame, as determined by the MPEG-2 parameter motion_vertical_field_select[r][s]. There are either one set of two prediction blocks for one prediction plane (forward-only or backward-only, for which there would be a total of two prediction blocks per macroblock), or sets for two prediction planes (bi-directional, for which there would then be a total of four prediction blocks in a macroblock).

Dual Prime: like the Field MC case above, each plane (parity) consists of a top and bottom 16x8 shape. The same and opposite parity planes are combined together via the averaging operation identical to bi-directional interpolation in (1, 2, 4, 5). Unlike the other motion types (1, 2, 4, 5), a Dual Prime macroblock always consists of two sets of prediction blocks (same and opposite parity), for a total of four prediction blocks per macroblock.

MPEG-2 field structured pictures:

Field (16x16) MC: Resembles Frame MC in that each prediction has a 16x16 shape, however the reference block data is formed from sequential top or bottom lines only, not a mixture of alternating top and bottom lines (as in progressive motion). As with all motion types in field-structured pictures, the reconstructed macroblock is likewise stored in the current frame buffer as only sequential top or bottom lines. Top or bottom field destination is determined by the MPEG-2 variable picture_structure.

16x8 MC: Although the basic prediction block shapes of this type of motion are the same as for the other 16x8 shapes (2,3), it is not partitioned into the macroblock in the same manner. The two partitions correspond to upper and lower halves of a macroblock prediction plane, rather than top and bottom fields within a macroblock. (See Figure X). Particular attention should be paid to the fact that the anchor point for the lower 16x8 half is the upper left hand corner of the 16x8 lower portion, not the upper left hand corner of the whole macroblock as is the case with all other types of motion.

Dual Prime: At the lowest layer there is virtually no distinction between Dual Prime and the field structured field motion compensation with bi-directional prediction. The differences are manifested in the frame buffer selections from which reference blocks are formed. Dual Prime motion type in field structured pictures always consists of two 16x16 prediction blocks (same and opposite parity predictions).


ITU-T H.263

Formally titled "Video Coding for Low Bit Rate Communication," ITU-T Recommendation H.263 is a more recent video coder with improved compression performance relative to H.261, MPEG-1, and MPEG-2. It contains a “baseline” mode of operation supporting only the most basic form of H.263. It also contains a large number of optional enhanced modes of operation for various purposes. (It originally had five optional modes in the first version approved in late 1995, but more were added in a second version technically completed in 1997, and a few more are being finalized in 2000.) Baseline H.263 prediction operates in this interface using a subset of the MPEG-1 features. The baseline mode contains no bi-directional prediction – only forward prediction.

Rounding Control: Several H.263 optional modes require rounding control. This is supported by the bRcontrol flag in this specification.

Motion vectors over picture boundaries: Several H.263 optional modes allow motion vectors that address locations outside the boundaries of a picture as defined in H.263 Annex D. This is supported in this specification by a bPicExtrapolation flag indicating whether the accelerator needs to support such motion. There are two basic ways of supporting such motion: 1) clipping the value of the address on each sample fetch to ensure that it stays within picture boundaries, and 2) padding the picture by duplicated samples to widen the actual memory area used by one macroblock width and height across each border of the picture. The accelerator can use either method, as the result is the same.

Bi-directional motion prediction: The bi-directional motion prediction used in some optional H.263 prediction operations uses a different rounding operator than MPEG-1 – using division with truncation rather than rounding. This is supported by the bBidirectionalAveragingMode flag in this specification.

Four-MV motion compensation (4MV): Although each macroblock in H.263 is 16x16 in size, some optional modes (e.g., Annexes F and J) of H.263 allow four motion vectors to be sent for a single macroblock, with one macroblock for each 8x8 luminance block within the macroblock. The corresponding 8x8 chrominance area uses a single derived motion vector.

Overlapped Block Motion Compensation (OBMC): H.263 Annex F contains Overlapped Block Motion Compensation (OBMC) for luminance samples in addition to 4MV support. OBMC prediction is supported in this specification by allowing sending twelve motion vectors for forward prediction of a macroblock.

OBMC prediction blocks can be realized in hardware with the tools given in this specification as a combination of predictions organized into three planes: a current plane ("0"), an upper/lower plane ("1"), and a left/right plane ("2"). The three planes can serve as temporary storage for the blocks q(x,y), r(x,y), and s(x,y) defined in H.263 Section F.3. After each of the three planes have been filled out for all four blocks, they would then be combined according to the formula in H.263 Section F.3 and weighted by their respective H matrices given in H.263 Figures F.2, F.3, and F.4.

As an example, an OBMC luminance macroblock prediction may be comprised of eight top/bottom prediction blocks of 8x4 shape, eight left/right blocks of 4x8 shape, and four current blocks of 8x8 shape. If all four of the plane 0 motion vectors have the same motion vector (i.e., when not in a 4MV macroblock), a single 16x16 macroblock prediction can be used to fill the entire 16x16 plane 0.

In terms of the representation of the OBMC process in this specification, ten motion vectors are sent for the macroblock. The first four are for the Y0, Y1, Y2, and Y3 blocks in the current macroblock, remote vectors for the left and right halves of the top of the macroblock are then sent, then remote vectors for the top and bottom halves of the left side of the macroblock, and finally the remote vectors for the top and bottom halves of the right side of the macroblock. (H.263 does not use distinct remote vectors for the left and right halves of the bottom of the macroblock – it instead reuses the vectors for the current macroblock.)

H.263 Registration of One 8x8 Block in the OBMC Prediction Planes

P-B frames (Annex G & M): In this mode, macroblocks for a P frame and a pseudo B-frame are multiplexed together into the unique "PB-frame" picture coding type. The B-frame portion of each macroblock borrows from information encoded for the P-frame portion of the macroblock: the B-portion forward and backward motion vectors are scaled from the P-portion vector, and the reconstructed P-portion macroblock serves as backward reference for the B-portion. The PB includes only a pseudo B-frame since the backward macroblock can only refer to the reconstructed P macroblock contained within the same PB macroblock. However, as with traditional B-frame semantics, the B macroblock within a PB-frame can refer to any location within the forward reference frame.

This limitation of the backward reference creates smaller size backward prediction block shapes as depicted in H.263 Figure G.2. This specification supports PB frames by labeling them as a distinct macroblock type with two motion vectors.

Deblocking Filter (Annex J): Special commands are defined in this specification to accelerate deblocking filters, whether used in the loop as with Annex J or used outside of the loop as would be the case for deblocking H.261 pictures or H.263 baseline pictures. The Host CPU shall create deblocking commands which observe GOB or slice segments if necessary.

Reference Picture Selection (Annexes N and U): Multiple reference frames are supported by the Accelerator using the picture index selection field of each prediction block.

Scalability (Annex O): Temporal, SNR, and Spatial scalability are supported by the tools of this specification. H.263 Spatial scalability B frames are very similar in this interface to MPEG-1 B-frames. Spatial scalability requires upsampling the lower-layer reference picture and then using the upsampled picture as the reference (in all other aspects it is essentially the same as SNR and Temporal scalability). The appropriate bi-directional averaging rounding control should be set to truncation for H.263 (MPEG-1 and MPEG-2 use upward-biased averaging, and H.263 uses downward truncation averaging).

Reference Picture Resampling (Annex P): The simple form of this annex is supported by reference buffer resampling. For fancier forms of Annex P resampling, the reconstructed frames which serve as reference frames must be resampled by external means and stored as reference frame buffers addressable by the Accelerator.

Reduced-Resolution Update mode (Annex Q): The H.263 Reduced-Resolution Update mode is not currently supported by this specification, as it has unusual residual upsampling requirements, a different form of deblocking filter, and a different form of Advanced Prediction OBMC. However, its operation with the Deblocking Filter mode active and the Advanced Prediction mode inactive could perhaps be supported in this interface with host-based IDCT processing.

Independent Segment Decoding (Annex R): There is no low-level or accelerator awareness of independent segment borders. Some forms of Annex R can be supported without any special handling (e.g., baseline plus Annex R is trivial). Forms of Annex R which require picture segment extrapolation can be supported by decoding each segment as a picture and then constructing the complete output picture from these smaller pictures.

Other H.263 Optional Features: Other H.263 optional features can be supported without any impact on the accelerator interface. For example, Annexes I, K, S, and T can be handled easily by altering the host side of the processing without any impact on the accelerator.

Specific IDCT: This interface allows specification of support of a specific IDCT which is expected to be added as a new H.263 optional feature in the near future.


MPEG-4

MPEG-4 was based heavily on H.263 for progressive-scan coding and MPEG-2 for support of interlace and color sampling formats other than 4:2:0. The features in this specification which support H.263 and MPEG-2 can be used to support MPEG-4. A parameter BPP is provided to support more than eight bits per pixel. The features most unique to MPEG-4 such as shape coding, object orientation, face modeling, mesh objects, sprites, etc. are not supported in the current interface, although they may be added in some future variation on the theme.


Prediction Principles

Block motion-compensated prediction (MCP) is the basic tool which gives MPEG and the H.26x family of codecs a gain over pure still-frame coding methods such as JPEG. Generic instances of prediction exist at many stages of the codec, but MCP is the most processing intensive. Motion vectors, DCT coefficients, and other elements not directly part of the MCP process also employ prediction to make the transmitted form of those elements more compact. These instances of prediction are not covered by this specification, and are considered to be executed on the Host CPU processor or bitstream parser/variable-length-decoding unit.

In a generic prediction coding scheme, previously transmitted and decoded elements serve as the prediction for current elements, and differences between the prediction and the actual current element values are sent as prediction error. The transmitted difference information updates the prediction to the correct value, or in the case of MCP, to a value which is a close enough approximation to a desired value. Previously decoded frames are used to predict or "guess" what future frames should look like. The difference data (known prediction error) then corrects the guess, attempting to bring the combined prediction + prediction error (reconstructed) image as close to the original (prior to compression) future frame as possible.

The reconstructed current elements are in turn stored to serve as prediction for future elements. This recursive loop is occasionally broken by various types of resets specific to the element being predicted. The resets are described by the semantics of the decoding process. For example, motion vectors and DC coefficient predictions are reset at slices, while the whole temporal frame prediction chain is reset by an intra refresh frame. The temporal basic prediction loop fits this description, but works with modified data taken from whole frames which serve as prediction. Data from the reference frames which serve as prediction are modified in order to account for movement or other types of change which occur over time.

Generic MCP Signal Flow


Stages of Prediction

For purposes of this specification, the formation of a macroblock prediction (via MCP) shall be described as a series of discrete phases. This realization will help explain why this specification models the MCP process in the way that it does.

Signal Flow of MoComp3 Prediction Blocks

Stage 1. Form reference frame.

Note This may include resampling the input picture as necessary.

Evolution of Prediction Data within MCP

Stage 2. Reference block

A reference block is not necessarily the same as a prediction block. It most likely consists of extra samples which are needed in the prediction filtering stages. The reference block is not defined in this specification since it is likely to have properties which reflect implementation-specific means of maintaining picture buffers. Unless half-sample filtering is executed in the memory unit, the reference block for a 16x16 half-sample filtered macroblock will have a 17x17 shape. The size of the reference block is both a function of the prediction block dimensions and filter attributes of the prediction block. In this specification, a reference block shall refer to a block of data extracted from a reference frame buffer for use in motion compensated prediction (MCP).

Stage 3. Prediction block

The outcome of a filtered reference block.

Stage 4. Combined macroblock prediction

The outcome of an averaging process between one or more prediction blocks.


Macroblock Portions

Macroblocks are broken into regular segments in an attempt compartmentalize areas with different characteristics.

Basic Macroblock Portioning Schemes

In the MPEG-2 case, the top and bottom portion of a macroblock represent lines from two different fields captured at different instances in time, as much as 1/50-th of a second apart. Thus the top and bottom portion could have totally non-correlated content if significant movement has taken place between the two fields for the frame area covered by the macroblock. An additional 16x8 scheme is added in field-structured pictures to provide finer vertical granularity of prediction.

The Two MPEG-2 Macroblock 16x8 Portions

Partitioning of macroblocks also provides finer granularity of prediction, to better accommodate edges and smaller objects with divergent motion velocities. The prediction block itself is a crude approximation of shape, and represents a kind of average motion vector for all samples which belong to the portion of the macroblock which the prediction block represents. Ideally, each sample (or subsample) would have its own motion vector, but this would consume considerable bits and extra overhead in processing. The prediction block remains a reasonable approximation.

Prediction blocks contribute to only one portion of a macroblock. A whole prediction block covers the 16x16 area of a macroblock. This is the case with all H.261 and MPEG-1 predictions. MPEG-2 introduced the 16x8 prediction shape to address the dual field/frame nature of macroblocks. The 16x8 shape was also borrowed for use in MPEG-2 field-structured pictures to create a finer-granularity of prediction. The 8x8 shape is deployed in H.263 (Advanced Prediction), H.264, and MPEG-4. The finest granularity to date is the draft of the future “H.26L”'s 4x4 prediction block shape.

Chrominance prediction blocks usually have half the size in both horizontal and vertical directions as their corresponding luminance prediction blocks, and share the same vector used for luminance since the standards addressed by this specification always model motion as component planar co-located. Chrominance vectors are therefore scaled from luminance vectors by some means, to account for the difference in the respective luminance and chrominance sample dimensions. MPEG-2's 16x8 luminance prediction blocks have corresponding 8x4 chrominance shapes. Exceptions are often made when the luminance prediction block becomes too small. For example, in the H.263 Advanced Prediction mode, the chrominance prediction block remains 8x8 in shape, and the chrominance motion vector is derived from a scaled average of the four 8x8 luminance motion vectors. In most contexts of this document, we shall only refer to the luminance dimensions of a prediction block, plane, or macroblock – the chrominance dimensions shall be inferred unless explicitly stated.


Prediction Planes

MPEG-2 Macroblock Prediction Planes

The above figure illustrates the conceptual macroblock prediction planes which exist prior to forming the final macroblock prediction. MPEG-2 has two planes: forward & backward (bi-directional prediction), or same-parity & opposite-parity (Dual Prime). In the MPEG-1 and MPEG-2 case, planes are combined together via the simple averaging operation. More sophisticated prediction schemes such as H.263's Overlapped Block Motion Compensated Prediction have three planes. Future coding methods may employ up to eight or more prediction planes which can be combined with more sophisticated filters.


DXVA Data Structures and Program Constructs

The following sections cover Encryption Support, Global Restricted Mode Information, Probing and Locking of Configurations, Buffer Description List and Compressed Picture Decoding.


Encryption Support

The security needs of some applications may require encryption of some of the data used in video decoding. To support such applications, this specification allows for encryption of DirectX VA data to be applied to three of the data structures defined for its operation:

  • The macroblock control command data structures,
  • The residual difference block data structures, and
  • Bitstream buffer contents

However, encryption is an optional aspect of DirectX VA operation for the intermediate-term future. All accelerators shall be capable of operation without encryption in use. Some encryption protocol is expected to be made a requirement in the longer-term future.

Good obfuscation of host-based software and data for processing clear-text data and performing the encryption process is essential to protecting the content. Such protection is equally important for the accelerator-side decryption process (although the decryption may be a hardware-based operation).

In order for the host decoder software to be able to use encryption, it must determine what types of encryption are supported by the accelerator. The basic information regarding what types of encryption are supported by the accelerator is contained in a list of encryption-type GUIDs supplied to the host as video accelerator type GUIDs. (The “no encryption” GUID DXVA_NoEncrypt shall not be sent in this list, as support for it is required and therefore implicit.)

The host chooses the type of encryption protocol to apply and indicates this choice to the accelerator via GUIDs as described in Section 3.2. In a typical encryption scenario, two more steps need to take place before encrypted data can be successfully transferred:

  • The host decoder may require verification that the accelerator is authorized to receive the data. This may be done by having the accelerator pass a signed data structure to the host to prove that it holds an authorized public key, private key pair.
  • The host decoder would then send an encrypted “content key” to the accelerator.

The precise number of steps for initializing the encryption protocol may depend on the particular type of encryption to be used. Each data set exchanged between the host and accelerator for the initialization of the encryption process shall be prefixed by the encryption protocol type GUID, to distinguish data for one type of encryption from data for another (in the event of the use of one type of encryption for one type of DirectX VA buffer, and some other type of encryption for another type of DirectX VA buffer).


Global Restricted Mode Information

In order for a decoder to operate using this API, an understanding must be reached between the decoder and the video accelerator for two distinct aspects of operation:

  1. What type of video data format is to be decoded. This is codified herein using the DXVA_ConnectMode data structure.
  2. How the API will be configured to operate, as to what intermediate data formats are used and which aspects of the processing are to reside on the host and which on the accelerator. This established by the negotiation of a connection configuration for each DXVA function to be used.


Probing and Locking of Configurations

The process of establishing the configuration for each DirectX VA function (a specific value of bDXVA_Func) that needs configuration is performed by:

  1. Optionally probing to determine whether a configuration is accepted by the accelerator, and
  2. Locking in a specific configuration if it is supported.

Probing for support of a specific configuration is performed by sending a probing command to the accelerator for the particular bDXVA_Func to be probed with a configuration. Along with the probing command is sent a configuration data structure (specific to the DXVA_Func value) which describes the configuration being probed to determine support. The accelerator then returns a S_OK or S_FALSE indication for whether the specified configuration is supported by the accelerator or not. The accelerator may also return a suggested alternative configuration.

Locking in a specific configuration is performed by sending a locking command to the accelerator for the particular bDXVA_Func to be locked into a specific configuration. Along with the locking command is sent a configuration data structure (specific to the bDXVA_Func value) which describes the configuration to be locked in if supported. The accelerator then returns a S_OK or S_FALSE indication for whether the specified configuration is supported by the accelerator. If the indication is S_OK, the specified configuration is locked in for use. If the indication is S_FALSE, a suggested alternative configuration is returned.

The decoder may send a locking command without first sending a probing command for the specified configuration. If the accelerator has returned a S_OK in a probing command for a specific configuration, it shall return a S_OK to a locking command for that same configuration, unless otherwise noted herein.

Once a locking command has been sent and acknowledged for use with a returned Yes indication, the specified configuration is locked in, and no further probing or locking commands shall be sent by the decoder for the same value of bDXVA_Func.

In order to ensure that all DirectX VA software decoders shall be capable of operation with all DirectX VA accelerators, a minimal interoperability configuration set, is defined as a set of configurations that must all be supported by any software decoder that wishes to use a particular bDXVA_Func. At least one member of that minimal interoperability configuration set shall be supported by every accelerator that indicates support for the bDXVA_Func by exposing an associated video accelerator GUID. In some cases an additional encouraged configuration set may also be defined.

Probing and locking are controlled by DXVA_ConfigQueryOrReplyFunc, which is passed as the first member of the data structure sent in a probing or locking command.


Buffer Description List

DirectX VA primarily operates by passing buffers of data from the host to the accelerator. The DXVA function parameter (bDXVA_Func) determines what types of buffers may be passed and what specific DXVA task is to be performed. A variety of enumerated buffer types are defined herein, specifically the types are:

  1. Picture decoding parameter buffers
  2. Macroblock control command buffers (closely associated with and having a 1:1 correspondence with residual difference block data buffers)
  3. Residual difference block data buffers
  4. Deblocking Filter control command buffers (with or without a restriction on the effect of the filter)
  5. Inverse quantization matrix buffers (only used with off-host VLD processing)
  6. Slice control buffers (closely associated with and having a 1:1 correspondence with bitstream data buffers)
  7. Bitstream data buffers
  8. AYUV alpha blending sample buffers
  9. IA44/AI44 alpha blending surface buffers
  10. DPXD alpha blending surface buffers
  11. Highlight data buffers
  12. DCCMD data buffers
  13. Alpha blend combination buffers
  14. Picture resampling control buffers
  15. Read-back command buffers containing commands to read macroblocks of the resulting picture back to the host.

When a set of buffers is passed from the host to the accelerator, some additional data about these buffers is also passed. This additional data is termed buffer description list. A buffer description list consists of an ordered list, starting from the first buffer of the first type as enumerated above, proceeding to the next buffer of the same type, and so on, then proceeding to the first buffer of the next type, etc.


Compressed Picture Decoding

bDXVA_Func = 1

The first function type defined for DirectX VA operation is the decoding of some or all of a compressed picture.


Minimal Interoperability Configuration Set

It is a design requirement for all DirectX VA decoders to interoperate with all DirectX VA accelerators. This requires that every DirectX VA decoder be capable of operation with any member of a set of connection configurations, and that every DirectX VA accelerator be capable of operation with at least one connection configuration member of that set. That minimal interoperability set is defined as follows:

  1. All members of this most basic set have the following aspects in common:
    • guidConfigBitstreamEncryption = DXVA_NoEncrypt
    • guidConfigMBcontrolEncryption = DXVA_NoEncrypt
    • guidConfigResidDiffEncryption = DXVA_NoEncrypt
    • bConfigBitstreamRaw = 0
    • bConfigHostInverseScan = 0
    • bConfigSpecificIDCT = 0
  2. The first two members of this set (among which accelerators are encouraged to support the variation with bConfigSpatialHost8or9Clipping = 0) are defined by:
    • bConfigMBcontrolRasterOrder = 1
    • bConfigResidDiffHost = 1
    • bConfigSpatialResid8 = 0
    • bConfigResid8Subtraction = 0
    • bConfigSpatialHost8or9Clipping = 0 or 1
    • bConfigSpatialResidInterleaved = 0
    • bConfigIntraResidUnsigned = 0
    • bConfigResidDiffAccelerator = 0
  3. The third member of the set (not particularly encouraged for accelerator implementation) is defined by:
    • bConfigMBcontrolRasterOrder = 1
    • bConfigResidDiffHost = 1
    • bConfigSpatialResid8 = 1
    • bConfigResid8Subtraction = 0
    • bConfigSpatialHost8or9Clipping = 0
    • bConfigSpatialResidInterleaved = 1
    • bConfigIntraResidUnsigned = 0
    • bConfigResidDiffAccelerator = 0
  4. The fourth member of this set (not particularly encouraged for accelerator implementation) is defined by:
    • bConfigMBcontrolRasterOrder = 1
    • bConfigResidDiffHost = 1
    • bConfigSpatialResid8 = 0
    • bConfigResid8Subtraction = 0
    • bConfigSpatialHost8or9Clipping = 1
    • bConfigSpatialResidInterleaved = 0
    • bConfigIntraResidUnsigned = 1
    • bConfigResidDiffAccelerator = 0
  5. Two additional members of this set (among which accelerators are encouraged to support the variation with bConfigResid8Subtraction = 1) are defined by:
    • bConfigMBcontrolRasterOrder = 1
    • bConfigResidDiffHost = 1
    • bConfigSpatialResid8 = 1
    • bConfigResid8Subtraction = 0 or 1
    • bConfigSpatialHost8or9Clipping = 0
    • bConfigSpatialResidInterleaved = 0
    • bConfigIntraResidUnsigned = 0
    • bConfigResidDiffAccelerator = 0
  6. One additional member of this set is defined only for the MPEG2_C and MPEG2_D restricted mode profiles as defined in Section 4 and indicated in DXVA_ConnectMode. No other profiles include this configuration in their minimal interoperability set. This additional member is defined by:
    • bConfigMBcontrolRasterOrder = 1
    • bConfigResidDiffHost = 0
    • bConfigResidDiffAccelerator = 1
    • bConfigHostInverseScan = 0
    • bConfig4GroupedCoefs = 1


Additional Encouraged Configuration Set

Some additional configurations are encouraged to be supported in software decoders, as we believe these configurations will exist in hardware shipping in large quantities and as we believe that these configurations can provide a significant performance benefit relative to those in the minimal configuration set. These include:

  1. All members of this set have the following aspects in common:
    • guidConfigBitstreamEncryption = DXVA_NoEncrypt
    • guidConfigMBcontrolEncryption = DXVA_NoEncrypt
    • guidConfigResidDiffEncryption = DXVA_NoEncrypt
    • bConfigMBcontrolRasterOrder = 0
    • bConfigResidDiffHost = 0
    • bConfigSpatialResid8 = 0
    • bConfigResid8Subtraction = 0
    • bConfigSpatialHost8or9Clipping = 0
    • bConfigSpatialResidInterleaved = 0
    • bConfigSpecificIDCT = 0
  2. For good support of off-host bitstream processing acceleration, the first member of this set is defined by:
    • bConfigBitstreamRaw = 1
    • bConfigResidDiffAccelerator = 0
    • bConfigHostInverseScan = 0
    • bConfig4GroupedCoefs = 0
  3. For good support of off-host IDCT acceleration, the second member of this set is defined by:
    • bConfigBitstreamRaw = 0
    • bConfigResidDiffAccelerator = 1
    • bConfigHostInverseScan = 1
    • bConfig4GroupedCoefs = 0
  4. For support of off-host IDCT as expected to be found in some implementations, the third member of this set (not particularly encouraged for accelerators relative to the second set member) is defined by:
    • bConfigBitstreamRaw = 0
    • bConfigResidDiffAccelerator = 1
    • bConfigHostInverseScan = 0
    • bConfig4GroupedCoefs = 1

Accelerators supporting the first of these encouraged configurations are strongly encouraged to also support the second of them, in order to provide flexibility in the manner in which their acceleration capabilities can be used.


Buffer Structure for Macroblocks of a Picture

A decoded picture shall contain one or more macroblock control command buffers if it does not contain bitstream data buffers. The decoding process for every macroblock shall be addressed (only once) in some buffer of each type that is used. For every macroblock control command buffer, there shall be a corresponding IDCT residual coding buffer containing the same set of macroblocks. If one or more deblocking filter control buffers are sent, the set of macroblocks in each deblocking filter control buffer shall be the same as the set of macroblocks in corresponding macroblock control and IDCT residual coding buffers.

The processing of the picture requires that the motion prediction for each macroblock must precede the addition of the IDCT residual data. This can be accomplished either by processing the motion prediction commands first and then reading this data back in from the destination picture buffer while processing the IDCT residual coding commands, or by processing these two buffers in a coordinated fashion – adding the residual data to the prediction before writing the result to the destination picture buffer. The motion prediction command and IDCT residual coding command for each macroblock affect only the rectangular region within that macroblock.

A deblocking filter command for a macroblock may require access to read the reconstructed values of two rows and two columns of samples neighboring the current macroblock at the top and left as well as reconstructed values within the current macroblock. It can result in modification of one row and one column of samples neighboring the current macroblock at the top and left as well as up to three rows and three columns within the current macroblock. The filtering process for a given macroblock may therefore require the prior reconstruction of other macroblocks. Two different types of deblocking filter buffers are defined herein: 1) a buffer type which requires access and modification of the value of reconstructed samples for macroblocks outside the current buffer (when bPicDeblockConfined is “0”), and 2) a buffer type which does not (when bPicDeblockConfined is “1”). To process the first of these two types of deblocking command buffer, the accelerator must ensure that the reconstruction has been completed for all buffers which affect macroblocks to the left and top of the macroblocks in the current buffer before processing the deblocking commands in the current buffer. Processing the second of these two types requires only prior reconstruction values within the current buffer. The deblocking post-processing can be conducted either by processing the motion prediction and IDCT residual coding commands for the entire buffer or frame first, followed by reading back in the values of some of the samples and modifying them as a result of the deblocking filter operations, or by processing the deblocking command buffer in a coordinated fashion with the IDCT residual coding bufer – performing the deblocking before writing the final output values to the destination picture buffer. Note also that the destination picture buffer for the deblocked picture may differ from that of the reconstructed picture prior to deblocking, in order to support “outside the loop” deblocking as a post-processing operation which does not affect the sample values used for prediction of the next picture.


Macroblock Control Commands

if(bPicIntra)
{
    NumMV = 0;
}
else if(PicOBMC)
{
    NumMV = 10;
    if(bPicBinPB)
    {
        NumMV++;
    }
}
else
{
    NumMV = 4;
    if(bPicBinPB && bPic4MVallowed)
    {
        NumMV++;
    }
}

DXVA_MB_Control // Alignment to 16 Bytes
{
    // General Macroblock Info
    wMBaddress // 16b Which macroblock
    wMBtype // 16b Control bits
    MBskipsFollowing // 8b

    // Residual Difference Info
    MBdataLocation // 24b Where in buffer
    wPatternCode // 16b Which blks coded

    if(bPicOverflowBlocks==1 && IntraMacroblock==0)
    {
        wPC_Overflow // 16b Which blks oflow
        dwReservedBits1 // 32b
    }
    else if(HostResidDiff)
    {
        ReservedBits2 // 48b
    }
    else if(bChromaFormat == '01')
    {
        for(i=0; i<6; i++)
        {
            bNumCoef[i] // 8b * 6 blocks = 48b
        }
    }
    else
    {
        wTotalNumCoef // 16 b
        ReservedBits3 // 32 b
    }

    if(bPicIntra != 0)
    {
        // Motion Prediction Info
        for(i=0; i<NumMV; i++)
        {
            MVector[i].horz // 16b * NumMV vectors
            MVector[i].vert // 16b * NumMV vectors
        }
        if(bMV_RPS)
        {
            for(i=0; i<NumMV; i++)
            {
                bRefPicSelect[i] // 8b * NumMV vectors
            }
        }

        ReservedBits4 // 16 Byte Align
    }
}

wMBaddress: Specifies the macroblock address of the current macroblock in raster scan order (0 being the address of the top left macroblock, PicWidthInMBminus1 being the address of the top right macroblock, and PicHeightInMBminus1 * PicWidthInMB being the address of the bottom left macroblock, and PicHeightInMBminus1 * PicWidthInMB + PicWidthInMBminus1 being the address of the bottom right macroblock).

wMBtype: Specifies the type of macroblock being processed as described as follows:

  • bit 15: MvertFieldSel[3] (The MSB),
  • bit 14: MvertFieldSel[2],
  • bit 13: MvertFieldSel[1],
  • bit 12: MvertFieldSel[0]: Specifies vertical field selection for corresponding motion vectors sent later in the macroblock control command, as specified in further detail below. For frame-based motion with a frame picture structure (e.g., for H.261 and H.263), these bits shall all be zero. The use of these bits is the same as that specified for the corresponding bits in Section 6.3.17.2 of MPEG-2.
  • bit 11: ReservedBits.
  • bit 10: HostResidDiff: Specifies whether spatial-domain residual difference decoded blocks are sent or whether transform coefficients are sent for off-host IDCT for the current macroblock. Shall be “0” if bConfigResidDiffHost is “0”. Shall be “1” if bConfigResidDiffAccelerator is “0”.
  • bits 9 and 8: MotionType: Specifies the motion type in the picture, as specified in further detail below. For frame-based motion with a frame picture structure (e.g., for H.261), these bits shall be ‘10’ (frame motion). The use of these bits is defined in the following table and corresponds directly to the use of frame_motion_type or field_motion_type bits in Section 6.3.17.1 and Tables 6-17 and 6-18 of MPEG-2 when these bits are present in MPEG-2.
  • bits 7 and 6: MBscanMethod: Shall equal bPicScanMethod if bPicScanFixed is “1”. If bConfigHostInverseScan is “0”, MBscanMethod shall be as follows:
    • ‘00’ = Zig-zag scan (MPEG-2 Figure 7-2),
    • ‘01’ = Alternate-vertical (MPEG-2 Figure 7-3),
    • ‘10’ = Alternate-horizontal (H.263 Figure I.2 Part a),
  • If bConfigHostInverseScan is “1”, MBscanMethod shall be equal to:
    • ‘11’ = Arbitrary scan with absolute coefficient address.
  • bit 5: FieldResidual: A flag indicating whether the IDCT blocks use a field IDCT structure as specified in MPEG-2.
  • bit 4: H261LoopFilter: A flag specifying whether the H.261 loop filter (Section 3.2.3 of H.261) is active for the current macroblock prediction. The H.261 loop filter is a separable ¼, ½, ¼ filter applied both horizontally and vertically to all six blocks in an H.261 macroblock except at block edges where one of the taps would fall outside the block. In such cases the filter is changed to have coefficients 0, 1, 0. Full arithmetic precision is retained with rounding to 8-bit integers at the output of the 2-D filter process (half-integer or higher values being rounded up).
  • bit 3: Motion4MV: A flag indicating that forward motion uses a distinct motion vector for each of the four luminance blocks in the macroblock, as used in H.263 Annexes F and J. Motion4MV shall be “0” if MotionForward is “0” or bPic4MVallowed is “0”.
  • bit 2: MotionBackward: A flag used as specified for the corresponding macroblock_motion_backward parameter in MPEG-2. If bPicBackwardPrediction is “0”, MotionBackward shall be “0”. Further information on the use of this flag is given below.
  • bit 1: MotionForward: A flag used as specified for the corresponding macroblock_motion_forward in MPEG-2. Further information on the use of this flag is given below.
  • bit 0: IntraMacroblock: (The LSB) A flag indicating that the macroblock is coded as “intra”, and no motion vectors are used for the current macroblock. Corresponds to macroblock_intra in MPEG-2. Further information on the use of this flag is given below.

MBskipsFollowing: Specifies the number of “skipped macroblocks” to be generated following the current macroblock. Each skipped macroblock shall be generated in a manner mathematically equivalent to incrementing the value of wMBaddress and then repeating the same macroblock control command.

Any macroblock control command with a non-zero value for MBskipsFollowing contains the explicit specification of how motion-compensated prediction is to be performed for each macroblock to be skipped, and is equivalent (except for the value of MBskipsFollowing) to an explicit “non-skip” specification of the generation of the first of the series of skipped macroblocks. Thus, whenever MBskipsFollowing is not “0”, the following parameters shall all be equal to “0”:

  • Motion4MV,
  • IntraMacroblock,
  • wPatternCode,
  • wPCOverflow (if present)
  • bNumCoef[i] (if present)

Furthermore, the generation of following skipped macroblocks shall be restricted by the decoder to not include a “wrap” to a new row of macroblocks in the picture. In other words, a separate macroblock control command must be sent to generate the first (but not necessarily the last) macroblock of each row of macroblocks.

  1. The generation of a skipped macroblock in this context differs somewhat from that in MPEG-2 Section 7.6.6. In this specification, the manner in which the skipped macroblocks are generated is specified in a separate macroblock control command, rather than being inferred from the type of the preceding non-skipped macroblock and the type of picture (e.g., in MPEG-2 the method of generating skipped macroblocks depends on whether the picture is a P picture or B picture). To illustrate this point, we provide the following example. Suppose that in an MPEG-2 bitstream, macroblock 0 is coded with a residual difference, macroblock 1 is skipped, macroblock 2 is coded with a residual difference, macroblocks 3, 4, and 5 are skipped, and then macroblock 6 is coded with a residual difference. These seven macroblocks would require the generation of (at least) five DirectX VA macroblock control commands. The minimal five control commands would be characterized by the folllowing:
    • the first would have wMBaddress = “0” and MBskipsFollowing = “0”,
    • the second would have wMBaddress = “1” and MBskipsFollowing = “0”,
    • the third would have wMBaddress = “2” and MBskipsFollowing = “0”,
    • the fourth would have wMBaddress = “3” and MBskipsFollowing = “2”, and
    • the fifth would have wMBaddress = “6” and MBskipsFollowing = “0”.
  2. The following conditions are required as specified above:
    • skipped macroblocks have no residual differences,
    • skipped macroblocks can be generated by repeating the operation of a macroblock control command with an incremented wMBaddress, and
    • macroblock skipping is restricted to not wrap to a new row of macroblocks,
  3. Because of the three conditions listed in note 2, an accelerator may actually implement motion compensation (when Motion4MV is “0”) as the application of the specified motion vectors to a rectangle of width equal to MacroblockWidth·(MBskipsFollowing+1) in the luminance component (and to a similarly-specified rectangle in the chrominance components), rather than as MBskipsFollowing+1 repetitions of the same macroblock control operation.
  4. The generation of macroblocks indicated as skipped in H.263 with Advanced Prediction mode (Annex F) active requires coding some “skipped” macroblocks as non-skipped macroblocks using this specification – in order to specify the OBMC effect within these macroblocks.

MBdataLocation: An index into the IDCT residual coding block data buffer, indicating the location of the residual difference data for the blocks of the current macroblock, expressed as a multiple of 32 bits. Shall be “0” for the first macroblock in the macroblock control command buffer.

wPatternCode: When using host-based residual difference decoding, bit 11-i of wPatternCode (where bit 0 is the LSB) indicates whether a residual difference block is sent for block i, where i is the index of the block within the macroblock as specified in MPEG-2 Figures 6-10, 6-11, and 6-12 (raster-scan order for Y, followed by 4:2:0 blocks of Cb in raster-scan order, followed by 4:2:0 blocks of Cr, followed by 4:2:2 blocks of Cb, followed by 4:2:2 blocks of Cr, followed by 4:4:4 blocks of Cb, followed by 4:4:4 blocks of Cr). The data for the coded blocks (those blocks having bit 11-i equal to 1) is found in the residual coding buffer in the same indexing order (increasing i). For 4:2:0 MPEG-2 data, the value of wPatternCode corresponds to shifting the decoded value of CBP left by six bit positions (those lower bit positions being for the use of 4:2:2 and 4:4:4 chroma formats).

If bConfigSpatialResidInterleaved is “1”, host-based residual differences are sent in a chroma-interleaved form matching that of the YUV pixel format in use. In this case each Cb and spatially-corresponding Cr pair of blocks is treated as a single residual difference data structure unit. This does not alter the value or meaning of wPatternCode, but it implies that both members of each pair of Cb and Cr data blocks are sent whenever either of these data blocks has the corresponding bit set in wPatternCode. If the bit in wPatternCode for a particular data block is zero, the corresponding residual difference data values shall be sent as zero whenever this pairing necessitates sending a residual difference data block for a block with a wPatternCode bit equal to zero.

wPC_Overflow: When using host-based residual difference decoding with bPicOverflowBlocks equal to “1” and IntraMacroblock equal to “0” (the 8-8 overflow method), wPC_Overflow contains the pattern code of the overflow blocks as specified in the same manner as for wPatternCode. The data for the coded overflow blocks (those blocks having bit 11-i equal to 1) is found in the residual coding buffer in the same indexing order (increasing i).

bNumCoef[i]: Indicates the number of coefficients in the residual difference data buffer for each block i of the macroblock, where i is the index of the block within the macroblock as specified in MPEG-2 Figures 6-10, 6-11, and 6-12 (raster-scan order for Y, followed by Cb, followed by Cr). Used only when HostResidDiff is “0” and bChromaFormat is ‘01’ (4:2:0). (If used in 4:2:2 or 4:4:4 formats, it would increase the size of typical macroblock control commands past a critical memory alignment boundary, so only EOB is used for determining the number of coefficients in each block in non-4:2:0 cases.) The data for these coefficients is found in the residual difference buffer in the same order.

wTotalNumCoef: Indicates the total number of coefficients in the residual difference data buffer for the entire macroblock. Used only when HostResidDiff is “0” and bChromaFormat is not ‘01’ (4:2:0).

MVector[i].horz, MVector[i].vert: Specifies the value of a motion vector in horizontal and vertical dimensions. The two-dimensional union of these two values is referred to as MVvalue[i]. Each dimension of each motion vector contains a signed integer motion offset in half-sample units. Both elements shall be even if bMVprecisionAndChromaRelation is ‘10’ (H.261-style motion supporting only integer-sample offsets).

bRefPicSelect[i]: Specifies the reference picture buffer used in prediction for MVvalue[i] when motion vector reference picture selection is in use.

Valid combinations of IntraMacroblock, MotionForward, MotionBackward, PicMotionType, MvertFieldSel, and MVector[i] are shown in the following table. The values specified in the table are for when H261LoopFilter, Motion4MV and bPicOBMC are all zero.

IntraMacroblock, MotionForward, MotionBackward | MotionType (meaning dep on picture type) | MVector[0] MvertFieldSel[0] (1st, dir1) | MVector[1] MvertFieldSel[1] (1st, dir2) | MVector[2] MvertFieldSel[2] (2nd, dir1) | MVector[3] MvertFieldSel[3] (2nd, dir2)
Frame Structured Pictures (bPicStructure = ‘11’)
1,0,0 (intra) | ‘00’ (intra) | - - | - - | - - | - -
0,0,0 (no motion) | ‘10’ (no motion) | 0 - | - - | - - | - -
0,1,0 | ‘10’ (frame MC) | PMV[0][0] - | - - | - - | - -
0,0,1 | ‘10’ (frame MC) | - - | PMV[0][1] - | - - | - -
0,1,1 | ‘10’ (frame MC) | PMV[0][0] - | PMV[0][1] - | - - | - -
0,1,0 | ‘01’ (field MC) | PMV[0][0] sel[0][0] | - - | PMV[1][0] sel[1][0] | - -
0,0,1 | ‘01’ (field MC) | - - | PMV[0][1] sel[0][1] | - - | PMV[1][1] sel[1][1]
0,1,1 | ‘01’ (field MC) | PMV[0][0] sel[0][0] | PMV[0][1] sel[0][1] | PMV[1][0] sel[1][0] | PMV[1][1] sel[1][1]
0,1,0 | ‘11’ (dual-prime) | PMV[0][0] 0 (top) | vector'[2][0][0], vector'[2][0][1]<<1 1 (bot) | PMV[0][0] 1 | vector'[3][0][0], vector’[3][0][1]<<1 0
Field Structured Pictures (bPicStructure == ‘01’ or ‘10’)
1,0,0 (intra) | ‘00’ (intra) | - - | - - | - - | - -
0,0,0 (no motion) | ‘01’ (no motion) | 0 PicCurrentField | - - | - - | - -
0,1,0 | ‘01’ (field MC) | PMV[0][0] sel[0][0] | - - | - - | - -
0,0,1 | ‘01’ (field MC) | - - | PMV[0][1] sel[0][1] | - - | - -
0,1,1 | ‘01’ (field MC) | PMV[0][0] sel[0][0] | PMV[0][1] sel[0][1] | - - | - -
0,1,0 | ‘10’ (16x8 MC) | PMV[0][0] sel[0][0] | - - | PMV[1][0] sel[1][0] | - -
0,0,1 | ‘10’ (16x8 MC) | - - | PMV[0][1] sel[0][1] | - - | PMV[1][1] sel[1][1]
0,1,1 | ‘10’ (16x8 MC) | PMV[0][0] sel[0][0] | PMV[0][1] sel[0][1] | PMV[1][0] sel[1][0] | PMV[1][1] sel[1][1]
0,1,0 | ‘11’ (dual-prime) | PMV[0][0] PicCurrentField | vector'[2][0] !PicCurrentField | - - | - -

Use of Macroblock Parameters for Various Motion Types

  14. 1. This is an extremely important table. It must be inspected very closely and fully understood. Experience has shown that there will be bugs in any implementation that fails to properly account for every utilized macroblock type in the table (especially for field-structured pictures or dual-prime motion).
  15. In a number of places in the above table the variable PMV is used rather than the raw motion vector value. This is to distinguish between PMV, which is in frame coordinates, from a motion vector which may be in field coordinates (i.e., at half-vertical resolution). In all such cases above, PMV refers to the value of PMV after updating by the current motion vector.
  16. The definitions of vector'[2][0] and vector'[3][0] are found in MPEG-2 Section 7.6.3.6. The shift operation shown indicates that the vertical component is modified to frame coordinates.
  17. In both “no motion” cases (0,0,0) above, the macroblock parameters emulate a forward prediction macroblock (0,1,0) with a zero-valued motion vector. (See also MPEG-2 Section 7.6.3.5.)

The remaining allowed cases are as follows:

  • H261LoopFilter == 1 && bPicOBMC == 0 && Motion4MV == 0: This indicates that one forward motion vector is sent in MVector[0] and the H.261 loop filter as specified in Section 3.2.3 of H.261 is active for the forward prediction in the macroblock. MotionForward shall be “1” in this case and IntraMacroblock and MotionBackward shall both be “0”.
  • bPicOBMC == 0 && Motion4MV == 1: This indicates that four forward motion vectors are sent in MVector[0, 1, 2, 3]. MotionForward shall be “1” in this case and IntraMacroblock shall be “0”. If MotionBackward is “1”, a fifth motion vector is sent for backward prediction in MVector[4].
  • bPicOBMC == 1 && Motion4MV == 0: This indicates that ten forward motion vectors are sent in MVector[0, 1, 2, …, 9] for specification of OBMC motion, and that the values of the first four such motion vectors are all equal. If MotionBackward is “1”, an eleventh motion vector is sent for backward prediction in MVvalue[10].
  • bPicOBMC == 1 && Motion4MV == 1: This indicates that ten forward motion vectors are sent in MVvalue[0, 1, 2, …, 9] for specification of OBMC motion, and that the values of the first four such motion vectors may differ from each other. If MotionBackward is “1”, an eleventh motion vector is sent for backward prediction in MVvalue[10].

Note No current configuration of the H.263 standard would exercise the case in which bPicOBMC == 1, Motion4MV == 1, and MotionBackward == 1.

Note The average operator is mathematically identical ((s1+s2)//2) for MPEG-1, MPEG-2 half-sample prediction filtering, bi-directional averaging, and Dual Prime same-opposite parity combining. This operator is the same as the C-language expression: (s1+s2+1)>>1. The H.263 bi-directional averaging operator does not seed with an offset of “+1” prior to downshifting. The bBidirectionalAveragingMode parameter determines which of these methods is used.


Inverse Quantization, Pre-IDCT Saturation, Mismatch Control, Intra DC Offset, IDCT, Picture Reconstruction and Reconstruction Clipping

The interface supports three low-level methods of handling IDCT. In all cases the basic inverse quantization process, pre-IDCT range saturation, MPEG-2 mismatch control (if necessary), and intra DC offset (if necessary) are performed on the host, and the final picture reconstruction and reconstruction clipping is done on the accelerator. The first method is to pass macroblocks of transform coefficients to the accelerator for external IDCT, picture reconstruction, and reconstruction clipping. The second and third involve performing an IDCT on the host and passing blocks of spatial-domain results for external picture reconstruction and reconstruction clipping.

The inverse quantization, pre-IDCT saturation, mismatch control, intra DC offset, IDCT, picture reconstruction, and reconstruction clipping processes are defined as the following:

Performing inverse quantization as necessary (including application of any inverse quantization weighting matrices) to create a set of IDCT coefficient values F"(u,v) from entropy-coded quantization indices (performed by the host).

Saturating each reconstructed coefficient value F"(u,v) of the transform coefficient block to obtain a value F'(u,v) within the restricted allowable range (performed by the host):

Mismatch control (described as needed for MPEG-2 only, and performed by the host) is performed by adding up the saturated values of all coefficients in the macroblock (equivalent to XORing their LSBs). If the sum is even, then the saturated value of the last coefficient F'(WT-1,HT-1) shall be modified by subtracting one if F'(WT-1,HT-1) is odd and adding one if F'(WT-1,HT-1) is even (equivalent to toggling its LSB). (If the sum is odd, the saturated value of F'(WT-1,HT-1) is used without alteration.) The coefficient values subsequent to the saturation and mismatch control are then denoted herein as F(u,v).

Note

MPEG-1 has a different form of mismatch control that consists of altering the value by plus or minus 1 for each coefficient that would otherwise be even after inverse quantization. H.263 does not require mismatch control in the sense described herein. In any case, where applicable, mismatch control is the host’s responsibility.

Adding an intra DC offset if necessary (performed by the host) so that all intra blocks correspond to adding a difference to a spatial reference prediction value of 2(BPP-1). Such an offset is necessary for all of the referenced video coding standards (H.261&3 and MPEG-1&2&4) except when HostResidDiff is “1” and bConfigIntraResidUnsigned is “1”, and has the value (2(BPP-1))WTHT in all of these cases (this value being 1024 in all such cases except MPEG-4, which allows BPP>8).

Performing the unitary separable transformation (either on the host or the accelerator):

where:

C(u) = 1 for u = 0, otherwise 2,

C(v) = 1 for v = 0, otherwise 2,

x and y are the horizontal and vertical spatial coordinates in the pixel domain,

u and v are the transform-domain horizontal and vertical frequency coordinates, and

WT and HT are the width and height of the transform block (normally both are eight).

Note

The accuracy of this IDCT process shall conform to that required in the H.261&3 and MPEG-1&2&4 video coding standards (all have very similar requirements).

Adding the spatial-domain residual information to the motion-compensated prediction value for non-intra blocks or to the constant reference value for intra blocks (this constant being 2(BPP-1) except when HostResidDiff is “1” and bConfigIntraResidUnsigned is “1”, in which case it is “0”) to perform picture reconstruction (on the accelerator), and finally

Clipping the picture reconstruction to a range of [0, (2BPP)-1] to store as the final resulting picture sample values (on the accelerator).


Off-Host IDCT

The transfer of macroblock IDCT coefficient data for off-host IDCT processing consists of a buffer of index and value information. Index information is sent as 16 bit words (although only 6 bit quantities are really needed for 8×8 transform blocks), and transform coefficient value information is sent as signed 16 bit words (although only 12 bits are needed for the usual case of 8×8 transform blocks and BPP=8).

Transform coefficients are sent in either DXVA_TCoefSingle or DXVA_TCoef4Group data structures. If bConfig4GroupedCoefs is “0”, coefficients are sent singly using DXVA_TCoefSingle structures. If bConfig4GroupedCoefs is “1”, coefficients are sent in groups of four using DXVA_TCoef4Group structures. These two alternative data structures contain two similar basic elements which are defined below.

TCoefIDX: specifies the index of the coefficient in the block, as determined from bConfigHostInverseScan. There are two basic ways that TCoefIDX can be used:

  1. Run-length ordering: When bConfigHostInverseScan is “0”, MBscanMethod indicates a zig-zag, alternate-vertical, or alternate-horizontal inverse scan. In this case, TCoefIDX contains the number of zero-valued coefficients which precede the current coefficient in the specified scan order, subsequent to the last transmitted coefficient for the block (or relative to the start of the block if none preceding).
  2. Arbitrary ordering: When bConfigHostInverseScan is “1”, MBscanMethod indicates arbitrary ordering. In this case, TCoefIDX simply contains the raster index of the coefficient within the block (i.e., TCoefIDX = u + v·WT)

TCoefIDX shall never be greater than or equal to WT·HT.

TCoefValue: The value of the coefficient in the block. TCoefValue shall be clipped to the appropriate range as specified in Section 3.4.2 above by the host prior to passing the coefficient value to the accelerator for inverse DCT operation. MPEG-2 mismatch control, if necessary, is also the responsibility of the host, not the accelerator (this may require the creation of extra “phantom” nonzero coefficients).

Host Based IDCT

[This is preliminary documentation and subject to change.]

IDCT may be performed on the host, with the result passed through the API. There are two supported schemes for sending the results – the 16-bit method and the 8-8 overflow method. An indication of which is used is sent in bConfigSpatialResid8.

The 16 bit Method

When sending data using the 16-bit method, blocks of 16-bit data are sent sequentially. Each block of spatial-domain data consists of WT·HT values of DXVA_Sample16.

A DXVA_Sample16 is a 16-bit signed integer. If BPP is greater than 8, only the 16-bit method is allowed. If bPicIntra is “1” and BPP is “8”, the 16-bit method is not allowed. If IntraMacroblock is “0”, the 16-bit samples are sent as signed quantities relative to the motion-compensated prediction values. If IntraMacroblock is “1”, the 16-bit samples are sent as follows:

  • If bConfigIntraResidUnsigned is “1”, the samples are sent as unsigned quantities relative to the constant reference value of “0”,
  • If bConfigIntraResidUnsigned is “0”, the samples are sent as signed quantities relative to the constant reference value of 2(BPP-1).

Blocks of data are sent sequentially, in the order specified by scanning wPatternCode for 1-valued bits from MSB to LSB.

NOTES:

  1. No clipping of these values can be assumed to have been performed on the host, unless bConfigSpatialHost8or9Clipping is “1”. Although only a BPP+1 bit range is needed to adequately represent the spatial-domain difference data, the output of some IDCTs will produce numbers beyond this range unless they are clipped. The accelerator shall work properly with at least a 15-bit range of values.
  2. Although video coding standards typically specify clipping of a difference value prior to adding it to a prediction value (e.g., 9 bit clipping in 8 bit-per-sample video), this clipping stage is actually unnecessary since it has no effect on the resulting decoded output picture. We therefore do not assume that this clipping occurs herein unless necessary for the accelerator hardware as indicated by bConfigSpatialHost8or9Clipping being set to “1”.

The 8-8 Overflow Method

If BPP is “8”, the 8-bit difference method may be used. Its use is required if bPicIntra is “1” and BPP is “8”. In this case, each spatial-domain difference value is represented using only eight bits. When sending data using the 8-bit method, blocks of 8-bit data are sent sequentially. Each block of 8-bit spatial-domain residual difference data consists of WT·HT values of DXVA_Sample8.

If IntraMacroblock is “0” the 8-bit samples are signed differences to be added or subtracted (as determined from bConfigResid8Subtraction and whether the sample is in a first pass block or overflow block) relative to a motion compensation prediction. If IntraMacroblock is “0” and the difference to be represented for some pixel in a block is too large to represent using only eight bits, a second “overflow” block of samples can be sent.

If IntraMacroblock is “1”, the 8-bit samples are set as follows:

  • If bConfigIntraResidUnsigned is “1”, the 8-bit samples are sent as unsigned quantities relative to the constant reference value of “0”,
  • If bConfigIntraResidUnsigned is “0”, the 8-bit samples are sent as signed quantities relative to the constant reference value of 2(BPP-1).

Overflow blocks shall not be sent if IntraMacroblock is “1”.

Blocks of data are sent sequentially, in the order specified by scanning wPatternCode for 1-valued bits from MSB to LSB, and then all necessary 8-bit overflow blocks are sent as specified by wPC_Overflow. Such overflow blocks are subtracted rather than added if bConfigResid8Subtraction is “1”.

The first pass of 8-bit differences for each non-intra macroblock is added. If bPicOverflowBlocks is “0” or IntraMacroblock is “1”, there is no second pass. If bPicOverflowBlocks is “1”, IntraMacroblock is “0”, and bConfigResid8Subtraction is “1”, the second pass of 8-bit differences for each non-intra macroblock is subtracted. If bPicOverflowBlocks is “1”, IntraMacroblock is “0”, and bConfigResid8Subtraction is “0”, the second pass of 8-bit differences for each non-intra macroblock is added.

If any sample is non-zero in both an original 8-bit block and in a corresponding 8-bit overflow block, then:

  • If bConfigResid8Subtraction is “0”, the sign of the sample shall be the same in both blocks.
  • If bConfigResid8Subtraction is “1”, the sign of the sample in the original 8-bit block shall be the same as the sign of minus one times the value of the sample in the corresponding overflow block.

This allows the sample to be added to the prediction picture with 8-bit clipping of the result after each of the two passes.

Note The 8+8 method (using 8-bit differences with overflow blocks with bConfigResid8Subtraction equal to “0”) cannot represent a residual difference value of +255 if IntraMacroblock is “0”, which makes it not strictly compliant with video coding standards. However, this format is supported herein as it is 1) used in some existing implementations, 2) more efficient than 16-bit sample use in terms of the amount of data needed to represent a picture, and 3) not considered to normally result in any meaningful degradation of video quality.


Glossary for Graphics Drivers

DirectX DDK

Graphics Drivers Glossary

This glossary contains terms and acronyms of interest to Windows NT®/Windows® 2000 graphics driver writers.


A

accelerated graphics port (AGP)
A technology that provides a dedicated, high speed port through which large blocks of 3D texture data can be moved between the computer's graphics controller and system memory.
Active Server Page (ASP)
A server-side scripting environment used to create Web pages and build Web applications. Active Server Pages (ASPs) are files that contain HTML tags, text, and script commands. ASPs can call ActiveX components to perform such tasks as: connecting to a database, performing a business calculation, or creating a printer Web page.

See COM Interfaces for Printer Web Pages for more information.

Adobe font metrics (AFM)
Files that contain font metrics and pair kerning information for Type 1 fonts. Also called PostScript fonts.


alpha blending

DirectX DDK
alpha blending
A technique by which the color in a source bitmap is combined with that in a destination bitmap to produce a new destination bitmap.

GDI performs per-pixel alpha blending, according to the formula: Blend = Alpha * Source + (1 - Alpha) * Destination. This formula is used to compute the alpha blend at each pixel, for each of the red, green, and blue color channels. In this computation, the first product (Alpha * Source) is premultiplied, using a constant alpha value.

animation
The display of a series of graphic images, simulating motion. Animation can be frame-based or cast-based.
applet
A small (usually single-purpose) application that is launched by some other application. For example, the different options of the Control Panel are referred to as applets.


asynchronous rendering

DirectX DDK
asynchronous rendering
A display driver supports asynchronous rendering if it can hand off a batch of one or more DDI drawing operations to the graphics coprocessor, returning immediately to GDI. If GDI needs to perform graphics operations of its own, it must synchronize itself with the bitmap or surface. To do this, GDI calls a display driver-implemented synchronization routine called either DrvSynchronize (for device-managed surfaces) or DrvSynchronizeSurface (for arbitrary surfaces). See synchronization routine.


B

Built on Sunday, March 11, 2001


bank

DirectX DDK
bank
See banked memory.


bank manager

DirectX DDK
bank manager
Code responsible for mapping a bank of memory into the range of addresses that the CPU can address.


banked callback

DirectX DDK
banked callback
A callback routine provided by the display drive to enable GDI to access banked memory. GDI cannot directly access banked memory associated with a banked frame buffer. Consequently, the display driver of a device with such a frame buffer must divide the frame buffer into a series of contiguous banks and provide a means for GDI to perform its draw operations to the appropriate frame buffer banks. That is, GDI is made to write data to one bank of the frame buffer before being moved to subsequent banks, as necessary, to complete the draw operation through a mechanism referred to as "banked callbacks."


banked memory

DirectX DDK
banked memory
Memory that is partitioned into distinct blocks. Prior to the advent of PCI devices, most video cards could expose only 64 KB of video memory to the system at a time. This memory was present at physical address 0xa0000. The video card typically had considerably more than 64 KB of memory, and would map views of this larger frame buffer into the 64 KB window. This process was referred to as banking. A bank is one 64 KB block of the frame buffer. The current bank is the bank that is visible to the CPU.
BIOS
Basic input/output system. A collection of low-level routines for input and output.


bit-block transfer

DirectX DDK
bit-block transfer
A programming technique that manipulates blocks of bits in memory that represent the color and other attributes of a rectangular block of pixels forming a screen image. The bit block is moved through a computer's video RAM as a unit so that its pixels can be rapidly displayed in a desired location on the screen. The bits can also be altered: light and dark portions of an image can be reversed, for example. Successive displays can thus be used to change the appearance of an image or to move it around on the screen. Some computers contain special graphics hardware for manipulating bit blocks on the screen independently of the contents of the rest of the screen. This speeds the animation of small shapes, because a program need not constantly compare and redraw the background around the moving shape. Also called bitblt or blt.

A stretched bit-block transfer copies a rectangular block of pixels to a rectangle of different size at a different location.

A non-stretched bit-block transfer copies a rectangular block of pixels to a rectangle of the same size at a different location.

bitmap
See standard format bitmap.


BRUSHOBJ

DirectX DDK
BRUSHOBJ
A GDI user object that contains information that describes a brush object. Brush objects are used to define fill patterns.
brush origin
The coordinate of a pixel on a device's surface that is aligned with the upper left pixel of the brush's pattern.


C

character translation table (CTT)
Used in Windows NT print minidrivers and translated in Windows NT to RLE files.


CLIPOBJ

DirectX DDK
CLIPOBJ
A GDI user object that describes the clip region used when drawing. This region can be enumerated as a series of rectangles.


clip region

DirectX DDK
clip region
A rectangle or set of rectangles used to control which portions of an image are displayed.


clip region locking

DirectX DDK
clip region locking
A mechanism by which GDI ensures that a clip region will not change during a drawing operation. To prevent a clip region from being changed during such operation, GDI acquires a lock for the region, thereby controlling access to the data structures that could affect clipping.


clip window

DirectX DDK
clip window
A rectangular region that is used to mask an area in a document or image. Only the portion of the document or image that lies inside the clipping region appears when the document is printed or the image is displayed.
CMYK
The color space that is often implemented on printers. The acronym represents the four colors: Cyan, Magenta, Yellow, and Black.
color index
An index into an array of RGB values.
Common Property Sheet User Interface (CPSUI)
A user-mode dynamic link library that enables developers to create property sheet pages that have a standard appearance.


D

design space
See notional space.
despooling
The conversion of spooled device-independent records into device-specific records.


DC

DirectX DDK
device context (DC)
A structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations.

Conceptually, a device context is a link between a Windows-based application, a device driver, and an output device such as a display, printer, or plotter.


DDB

DirectX DDK
device-dependent bitmap (DDB)
A data structure that describes a bit image by specifying: the width and height of a rectangular region in pixels; the width of the array that maps entries from the device palette to pixels; and the device's color format in terms of color planes and bits per pixel. A DDB is device-managed, as opposed to being engine-managed. See device-independent bitmap.
device driver interface (DDI)
A set of functions that are implemented by graphics drivers and used by GDI to communicate with the drivers.
device extension
A video miniport driver's only global storage area for adapter-specific state information. Each video miniport driver defines the size, internal structure, and contents of its device extension.


DIB

DirectX DDK
device-independent bitmap (DIB)
Information on the bitmap is stored in a data structure containing information such as color format, resolution and color palette for the device on which the image appears, an array of bits that maps RGB triplets to pixels, and a data-compression identifier which indicates which if any data compression scheme was used to reduce the size of the array of bits. A GDI bitmap that can be rendered accurately on different devices because it contains a color table that can be read by the rendering device driver. These are standard format bitmaps created and supported by GDI through EngCreateBitmap. A DIB is engine-managed, as opposed to being device-managed. See device-dependent bitmap.


device-managed surface

DirectX DDK
device-managed surface
A surface managed by a particular output device, rather than by the Graphics Engine (kernel-mode GDI). There are two types of device-managed surfaces: standard-format bitmaps, and nonstandard-format surfaces.

A standard-format bitmap can be either opaque or non-opaque, terms that indicate whether GDI has information about the location and format of the bitmap. For a standard-format bitmap that is opaque, the display driver must handle all rendering tasks done on the surface. For a standard-format non-opaque bitmap, the display driver handles some rendering tasks, and can refer others back to GDI.

A display driver calls on GDI to create a nonstandard-format surface. After creating the surface, GDI returns a surface handle to the display driver, which must carry out all subsequent operations pertaining to the surface. One type of nonstandard-format surface is the device-dependent bitmap (DDB) , which is supported to allow drivers such as the VGA driver perform faster bitmap-to-screen block transfers. See Surface Types for more information.


device palette

DirectX DDK
device palette
See palette.
device space
The coordinate space that measures 227 units in height by 227 units in width, in which the x coordinate increases toward the right and the y coordinate increases downward. The only transformation allowed in device space is translation, which ensures that the origin in device space maps to the proper location on the physical device (that is, in physical device space).

See also design space.

display data channel (DDC)
A standard that allows the display to inform the host about its identity and capabilities. Two levels of communication channel are defined: a uni-directional channel from display to host (DDC1 and DDC2B), and bi-directional (DDC2B+ and DDC2AB).
display power management signaling (DPMS)
A standard that defines display power management states and provides a standard method for the display controller to signal to the display to enter into those states.
dithering
A technique used to create the illusion of varying shades of gray on a monochrome display or printer, or additional colors on a color display or printer. Dithering relies on treating areas of an image as groups of dots that are colored in different patterns. Similar to halftones in photography.


document-sticky

DirectX DDK
document-sticky
A printer property page setting that applies only to a single document. For example, the left and right margins of a particular document are document-sticky settings. Contrast with printer-sticky.


drawing functions

DirectX DDK
drawing functions
A set of functions that the display driver can implement to perform rendering operations. The DDI drawing functions are shown in the following list. These functions cover many kinds of rendering operations, including alpha blends, bit block transfers, rendering lines, color fills, and displaying text.

DrvAlphaBlend
DrvBitBlt
DrvCopyBits
DrvDitherColor
DrvFillPath
DrvGradientFill
DrvLineTo
DrvPlgBlt
DrvRealizeBrush
DrvStretchBlt
DrvStretchBltROP
DrvStrokeAndFillPath
DrvStrokePath
DrvTextOut
DrvTransparentBlt


E

Built on Sunday, March 11, 2001


engine-managed surface

DirectX DDK
engine-managed surface
A device-independent bitmap (DIB) that is created and managed by GDI. GDI can handle any or all drawing operations for the surface. For a surface to be engine-managed, it must be a DIB. See Surface Types for more information.
enhanced metafile (EMF)
A type of spool file used by the Windows NT print spooler that reduces the time between the application's print request and when control is returned back to it. The GDI function calls that produce the application's graphics object are stored directly in the EMF. The time-consuming execution of these stored GDI functions is carried out later, in the background, when the spool file is played back.

Using EMF spool files also promotes printer device independence. For example, a picture measuring 2 inches by 4 inches on a VGA display and stored in an EMF maintains these original dimensions, regardless of the printer's resolution.

extended display identification data (EDID)
A format that lets the display inform the host about its identity and capabilities, independent of the communications protocol used between the monitor and host.


F

Built on Sunday, March 11, 2001


filter device object

DirectX DDK
filter device object
An object that represents a filter to a filter driver.


flush mechanism

DirectX DDK
flush mechanism
A mechanism that enables GDI to synchronize itself to the current state of a surface. In addition to providing a synchronization routine, a display driver can also activate either a time-based flush mechanism or programmatic flush mechanism. It does this by setting the flGraphicsCaps2 field of the DEVINFO structure to one of the following flag values:
  • GCAPS2_SYNCTIMER—Causes the driver's synchronization routine to be called periodically (GDI calls the driver's synchronization routine every 50 ms.). Drivers that batch DDI calls must specify this flag. By doing so, these drivers avoid problems such as lag in a software cursor's movement or in drawing that is performed in bursts.

    GDI passes the DSS_TIMER_EVENT flag to DrvSynchronizeSurface when this synchronization routine is called due to a periodic event.

  • GCAPS2_SYNCFLUSH—Causes the driver's synchronization routine to be called whenever the Win32 GdiFlush function (described in the Platform SDK documentation) is called. Drivers that perform asynchronous rendering must specify this flag and provide a synchronization routine.

    GDI passes the DSS_FLUSH_EVENT flag to DrvSynchronizeSurface when this synchronization routine is called due to a flush-based event.

    See also asynchronous renderingDDK_asynchronous_rendering_GG_gly.


FONTOBJ

DirectX DDK
FONTOBJ
A GDI user object that is used to give a driver access to information about a particular instance of a font. As an accelerator, the driver is allowed to access the public members of the FONTOBJ structure.
FOURCC
In the original Microsoft® Windows® multimedia APIs, media types were tagged with 32-bit values created from four 8-bit character codes, known as FOURCCs.


frame buffer

DirectX DDK
frame buffer
Dedicated memory on a video adapter, that can hold the contents of a single screen image. One type of frame buffer is the linear frame buffer, in which memory is mapped linearly into CPU address space. The other type of frame buffer is the banked frame buffer, so-called because its memory is partitioned into contiguous segments, or "banks." Most currently-manufactured video accelerators have linear frame buffers.
functional device object (FDO)
A device object that represents a device to a function driver.

See also physical device object and filter device object.


G

Built on Sunday, March 11, 2001


gamma ramp

DirectX DDK
gamma ramp
A lookup table (LUT) of numeric values used to compensate for a particular monitor's color response. The table is divided into three parts (one each for red, green, and blue), with each part containing 256 lookup values.

A gamma ramp is used to map the range of possible intensities for each color to a limited number (256) of values. An IHV chooses these values so that the transition from one color intensity to the next is as smooth as possible, given that the eye perceives changes in light intensity nonlinearly.

DirectDraw takes a pixel from the frame buffer, and examines it in terms of its individual red, green, and blue color components. Each component is represented by a value from 0 to 65535. DirectDraw takes the original value, and uses it as an index into a 256-element array (the ramp), where each element contains a value that replaces the original one. DirectDraw performs this "look-up and replace" process for each color component of each pixel within the frame buffer, thereby changing the final colors for all of the on-screen pixels. For more information, see the Platform SDK documentation.

generic printer description (GPD)
A text-based file used to describe a printer that is printing from Microsoft® Windows® 2000 using the Universal Printer Driver (Unidrv). It contains information about the printer features that Unidrv will present in the user interface to allow the user to configure the printer.

A GPD also contains the printer commands and attributes that enable Unidrv to generate the correct printer-ready output data when the user prints from a Windows-based application. Creating a Windows 2000 printer driver can be as simple as creating a GPD file if there is no custom functionality beyond what Unidrv provides.

glyph
The actual shape (bit pattern, outline, and so forth) of a character image. For example, an italic 'a' and a roman 'a' are two different glyphs that represent the same underlying character. Synonymous with "character image" or simply "image."


gradient fill

DirectX DDK
gradient fill
A technique used to fill a rectangular or triangular region with color that changes smoothly across the region. For rectangular regions, the gradient fill can be specified as top to bottom, or left to right. See DrvGradientFill.
graphics capabilities bits (GCAPS)
A driver specifies its graphics capabilities by setting GCAPS_Xxx and GCAPS2_Xxx flags in the flGraphicsCaps and flGraphicsCaps2 members of the DEVINFO structure. GDI obtains the GCAPS when it calls the driver's DrvEnablePDEV routine.
graphics device interface (GDI)
Consists of Win32® GDI and Kernel-mode GDI.

Win32 GDI is a user-mode API used by Win32 applications that require graphics support. Kernel-mode GDI interfaces directly with kernel-mode graphics drivers, as well as the window manager. Kernel-mode GDI exports several services and functions that can be called by device drivers to perform a host of drawing and graphics-related operations. This eliminates the need for graphics drivers to implement much of the required graphics functionality.

The Win32 GDI library that is directly assessable to Win32 applications can be found in gdi32.dll. It fields calls to the functions listed in wingdi.h and passes the application-supplied information to kernel-mode GDI by way of Windows NT's Executive system services. The kernel-mode GDI library is found in win32k.sys. Kernel-mode GDI communicates with a graphics driver by calling the driver's implementations of the DDI functions listed in winddi.h.

graphics engine
Another name for GDI. See the kernel-mode GDI definition under GDI.
glyph translation table (GTT)
A table that maps characters with the bitmaps used to display those characters.


H

hardware abstraction layer (HAL)
A Windows NT executive component that provides platform-specific support for the Windows NT Kernel, I/O Manager, kernel-mode debuggers, and lowest-level device drivers. The HAL exports routines that abstract platform-specific hardware details about caches, I/O buses, interrupts, and so forth, and provides an interface between the platform's hardware and the system software. For example, the HAL implements a routine to map each device driver's bus-relative device interrupt vector to a system-assigned vector with a corresponding platform-specific hardware priority (DIRQL), as well as several routines that provide DMA-transfer support.


HDEV

DirectX DDK
HDEV
A handle to a device object. Every Windows NT/Windows 2000 display driver needs a handle to its device object; this handle is of type HDEV. An object of this type is created by GDI at driver initialization and is stored by the driver for use when calling GDI engine services.

The term hdev, in lower-case, is typically used as the name of a function parameter or structure member of type HDEV.


heap manager

DirectX DDK
heap manager
The portion of the display driver responsible for managing the frame buffer memory.
hook
A callback function that handles I/O port and board memory accesses. Synonymous with handler.


I

IEEE 1284 Bi-Directional Parallel Peripheral Interface
An interface standard that adds bidirectional communication capabilities to a peripheral device connected to a computer's parallel port.
image color management (ICM)
A technology developed by Microsoft that ensures that a color image, graphic or text object is rendered as close as possible to its original intent on any device, despite differences in imaging technologies and color capabilities between devices.
independent hardware vendor (IHV)
A third-party hardware vendor.


ISV

DirectX DDK
independent software vendor (ISV)
A third-party software vendor.
installable client driver (ICD)
A complete OpenGL driver.
inter-integrated circuit (I2C)
The I2C bus is a standard protocol two wire (clock and data) serial data bus.
inter-integrated circuit (IIC)
See I2C.
IOCTL
Input/output control. Functions that handle control of I/O within a device driver module.
IRP
I/O request packet. The basic I/O Manager structure used to communicate with drivers and to allow drivers to communicate with each other. A packet consists of two different parts:

1. Header, or fixed part of the packet — Used by the I/O Manager to store information about the original request, such as the caller's parameters and the address of the device object upon which the file is open. It is also used by drivers for storing information such as the final status of the request. See also I/O status block and device object.

2. I/O stack locations — Following the header is a set of I/O stack locations, one per driver in the chain of layered drivers for which the request is bound. Each stack location contains the parameters, function codes, and context used by the corresponding driver to determine what it is supposed to be doing.


K

kernel mode
The privileged processor mode in which Windows NT executive code runs. A driver or thread running in kernel mode has access to system memory and hardware. See also user mode.
kernel space
See system space.


L

language monitor
A type of print monitor that provides a full duplex communications path between the print spooler and bi-directional printers. It can also add printer control information to the data stream.


linear frame buffer

DirectX DDK
linear frame buffer
Dedicated memory on a video adapter, that can hold the contents of a single screen image. A linear frame buffer is one in which the memory is linearly addressable, or "flat". This is in contrast to banked frame buffers, in which memory is partitioned into segments, or "banks".


M

memory descriptor list (MDL)
An opaque structure, defined by the Memory Manager, that uses an array of physical page frame numbers (PFNs) to describe the pages that back a virtual memory range.


MCD

DirectX DDK
miniclient driver (MCD)
A graphics interface whose primary goal is to allow straightforward, low-overhead hardware acceleration for OpenGL. The MCD is designed for all but very high-end 3D hardware accelerators. As such, it allows vendors to fully accelerate OpenGL at the rasterization level.
minidriver development tool (MDT)
An application that simplifies development of Unidrv minidrivers. See Microsoft Minidriver Development Tool for more details.


mirror driver

DirectX DDK
mirror driver
A display driver for a virtual device that mirrors the drawing operations of one or more additional physical display devices.

When video mirroring is active, each time the system draws to the primary video device at a location inside the mirrored area, a copy of the draw operation is executed on the mirrored video device in real time. With this mirroring scheme, you can simultaneously draw the same output to several video devices. Since the driver allocates memory dynamically for targets, the number of displays that your system can support depends on how much free memory you have at mirror-time.


monitor profile

DirectX DDK
monitor profile
A type of device profile used for color management. This profile contains information about how to convert colors in a monitor's color space and color gamut into colors in a device-independent color space. Any user-mode application, such as a setup program or a word processor with graphics capabilities, can use a monitor profile, provided that Image Color Management (ICM) has been enabled, and that the application has knowledge of the profile's format.


N

notional space
Also called design space. A coordinate system font designers use when they design fonts. For example, PostScript fonts are designed in 1000x1000 unit character cells. Before a glyph in a particular font can be rendered on an output device, its notional space coordinates must be first be transformed into device space coordinates. These coordinates must then be transformed into coordinates suitable for the physical device.

Most of the metrics returned in the IFIMETRICS structure are given in terms of notional space coordinates.

NTF files
Binary files used for describing the device fonts of Postscript-compatible printers. In Windows 2000, Adobe Font Metrics (AFM) files must be converted to NTF files.


NTVDM

DirectX DDK
NTVDM
The Windows NT virtual DOS machine. Also called VDM.


O

Built on Sunday, March 11, 2001


off-screen memory

DirectX DDK
off-screen memory
Video memory whose contents do not appear on the video display. Off-screen memory can be used for double buffering, a technique in which a complex graphics image that requires numerous graphics operations can be completely rendered before it is displayed. After each image has been displayed, another image can be constructed in the same way, providing an effective way to achieve animation.


P

palette
A mapping between color indexes and 24-bit RGB color values. The color indexes can be any bit depth, but are typically 1-, 4-, or 8-bits per pixel. GDI typically uses the palette mapping in reverse. That is, an application specifies an RGB color value for drawing and GDI must locate the color index that causes the device to display that color.

A driver specifies its palette so that GDI can determine how different color indexes are to appear on the device. If the palette for a device can be changed to hold a different set of colors, it is called a settable palette.

A device palette is the palette for a physical device. When the device sends image data to the monitor, the device palette is used. A device can have only one device palette.


palette realization

DirectX DDK
palette realization
A palette is realized when a display driver sets its internal hardware palette to match changes in a device palette.

For video hardware that supports palettes that can be set, GDI calls the DrvSetPalette DDI in the display driver when it has finished mapping colors into the device palette requested by the application. GDI passes the new palette to the display driver, and the driver queries the PALOBJ to set its internal hardware palette to match the palette changes for the video hardware.


PALOBJ

DirectX DDK
PALOBJ
A GDI user object that represents an indexed color palette.
partial print provider
A print provider that supplies limited functionality and works in conjunction with Windows NT's local print provider. See Writing a Network Print Provider.


PATHOBJ

DirectX DDK
PATHOBJ
A GDI user object used to describe a set of lines and Bezier curves that are to be stroked or filled. Associated functions allow the lines and curves to be enumerated for the driver.


PDEV

DirectX DDK
PDEV
A logical representation of a physical device. A PDEV is a private, driver-defined data structure containing all the information and data that represents the associated physical device. As part of enabling a PDEV, a driver provides information to GDI that describes the requested device and its capabilities. Important information that the driver gives GDI is a set of flags that allow GDI to determine what kinds of operations the PDEV (and the requested device) supports. For example, GDI can test the flags returned as part of the PDEV to determine whether or not the requested device can handle Bezier curves and geometric wide lines.

The term pdev, in lower-case, is typically used as the name of a function parameter or structure member of type PDEV.

A related type, DHPDEV, is a device handle of a PDEV structure. The term dhpdev, in lower-case, is typically used as the name of a function parameter or structure member of type DHPDEV.


PDO

DirectX DDK
physical device object (PDO)
A device object created by a bus driver using IoCreateDevice. A PDO represents the underlying bus driver in the stack of PnP drivers for a device. The PDO is at the bottom of the device stack of drivers for a device.
plotter characterization data (PCD)
A DLL that provides device-specific information to a graphics plotter driver.


pointer exclusion

DirectX DDK
pointer exclusion
A bit block transfer in which the pointer's image is not copied to the destination. This means that if you are copying a portion of the screen, and the pointer is currently in that portion of the screen, the pointer should not be included in the copy. In the past, pointer exclusion was implemented by turning the pointer off before the copy, and turning it back on after the copy. This is no longer required with windows layering.
port monitor
A type of print monitor, responsible for providing a communications path between the user-mode print spooler and the kernel-mode port drivers that access I/O port hardware
PostScript printer description (PPD)
A file read by the generic PostScript driver as part of device initialization. PPD files conform to specifications published by Adobe Corporation and are supplied by PostScript printer manufacturers.
preimaging
The process of building a movie frame in a memory buffer before it is displayed.
primary display
Also referred to as primary monitor and primary display device. The primary display in a multiple monitor system is the one that contains the origin (0,0). Other than this, the primary display in Windows 2000 can be any display.
primary monitor
See primary display.
Print Monitor
User-mode DLL responsible for directing a print data stream from the print spooler to an appropriate port driver. For more information, see Writing a Print Monitor.
Print Processor
User-mode DLL responsible for converting a print job's spooled data into a format that can be sent to a print monitor. For more information, see Writing a Print Processor.
printer control language (PCL)
A page description language developed by Hewlett Packard (HP) and used by many HP laser and inkjet printers.
printer font metrics (PFM)
Files that describe fonts for a printer.
printer job language (PJL)
Language that implements communication between a bidirectional printer device and a computer. PJL was defined and implemented by Hewlett-Packard.


printer-sticky

DirectX DDK
printer-sticky
A printer property page setting that applies to a single printer. For example, the amount of memory installed on a particular printer is a printer-sticky setting. Contrast with document-sticky.
Pscript
Abbreviated name for the Microsoft Postscript Printer Driver.


R

raster operation (ROP)
A bitwise operation applied to the bits of color data for the replicated brush and the bits of color data for the target rectangle on the display. There are 256 ROPs in Windows.
realized brush
A data structure containing information and accelerators that the display driver needs in order to fill an area with a pattern.
resource interchange file format (RIFF)
A tagged-file specification used to define standard formats for multimedia files. The tagged-file structure helps prevent compatibility problems that often occur when file-format definitions change over time. Because each piece of data in the file is identified by a standard header, an application that does not recognize a given data element can skip over the unknown information.
RIFF chunk
A chunk whose ID is RIFF, and that includes an identifying code and zero or more sub-chunks, the contents of which depend on the form type.
RIFF file
A file whose format complies with one of the published RIFF forms. Examples of RIFF files include WAVE files for waveform audio data, RMID files for MIDI sequences, and RDIB files for bitmaps.
RIFF form
A file-format specification based on the RIFF standard.
RLE bitmap
A run-length encoded (RLE) bitmap is compressed to reduce disk and memory storage required for the bitmap. Encoding format is specified in the biCompression member of the BITMAPINFO structure (described in the Platform SDK documentation).


S

standard format bitmap
Single plane, packed-pixel (where the data for each pixel is stored in a contiguous manner) format bitmaps created and supported by GDI through EngCreateBitmap. Each scan line of the bitmap is aligned on a four-byte boundary. Standard format bitmaps code information at a rate of 1, 4, 8, 16, or 32 bits per pixel.
streaming
The process of transferring information from a storage device, such as a hard disk or CD-ROM, to a device driver. Rather than transferring all the information in a single data copy, the information is transferred in smaller parts over a period of time, typically while the application is performing other tasks.


STROBJ

DirectX DDK
STROBJ
A GDI text string user object that contains an enumeration of glyph handles and positions for the device driver.
surface
Drawing and text output require a surface, associated with the requested device, on which to draw. Such a device surface is a subset of an array of 2 ( ( ( (28) ) ) ) by 2 ( ( ( (28) ) ) ) pixels. These pixels are addressed by pairs of 28-bit signed numbers; the upper leftmost pixel of the device surface is given the coordinates (0,0). The device surface lies in the lower right quadrant of this coordinate space, where both coordinates are nonnegative. A surface is associated with a particular PDEV.


SURFOBJ

DirectX DDK
SURFOBJ
A GDI user object that describes a surface. A device driver usually calls methods on a surface object only when the surface object represents a GDI bitmap or a device-managed surface.


synchronization routine

DirectX DDK
synchronization routine
A routine that synchronizes GDI with a particular surface. A display driver that supports asynchronous rendering can batch together one or more drawing operations to be performed by its graphic coprocessor. Such a display driver must implement a synchronization routine that GDI can call, a routine that notifies GDI that it is safe for it to carry out its own graphics operations. The synchronization routine to be implemented is named DrvSynchronize (for device-managed surfaces) or DrvSynchronizeSurface (for arbitrary surfaces) .
system space
A block of virtual memory dedicated to the use of kernel-mode code. Generally, the NT system space is a range of high-order virtual addresses around one to two gigabytes in size. Also known as kernel space.


T

tagged file format
A file format in which data is tagged by using standard headers that identify information type and length.
tile
Repetition of a brush pattern, to cover an entire device surface.


triangle texture fill

DirectX DDK
triangle texture fill
A texture fill in which the surface of a three-dimensional image is partitioned into a mesh of triangles, each of which is filled with the same texture.
True Type font substitute (TTFS)
For printers that provide hardware-resident or cartridge fonts, a font substitution table can be specified. By providing a font substitution table, you specify hardware-resident or cartridge fonts that can be substituted for TrueType fonts that must be downloaded. When Unidrv receives text in such a TrueType font, it first checks to see if the font substitution table contains a hardware-resident substitution for the font. If Unidrv finds a substituted resident font, and if the font metrics (such as character set, weight, italic, orientation, and so on) are compatible, the resident font is used.


U

Unidrv
Abbreviated name for the Microsoft Universal Printer Driver.
Unidrv font metrics (UFM)
A set of metrics that describe a particular Unidrv font.
upper memory block (UMB)
An upper memory block is a contiguous block of memory starting at an address above 640 KB. MS-DOS® distinguishes between conventional memory (addresses between 0 and 640 KB) and upper memory (addresses above 640 KB).
user mode
The nonprivileged processor mode in which application code, including protected subsystem code, runs. User-mode applications cannot gain access to system data except by calling subsystem-supplied functions, which, in turn, call system resources. See also kernel mode.


V

vertical blanking interval (VBI)
The length of time required to move a graphics display's electron beam from the bottom scan line back up to the top scan line.
Video Electronics Standards Association (VESA)
An organization that sets standards for video devices.
video port extensions (VPE)
The video port extensions to DirectX®. Driver developers for devices with a hardware video port should implement these extensions. The hardware video port is a dedicated connection between video devices, typically between an MPEG device or NTSC decoder and the video card. This dedicated connection carries horizontal sync (Hsync) and vertical sync (Vsync) information with the video data. The hardware video port and overlay can use this sync information to flip automatically between multiple buffers, writing to one surface while the overlay displays another. This allows tear-free video without burdening the application.
video request packet (VRP)
A mechanism used to communicate device I/O control requests from a display driver to its corresponding adapter-specific miniport driver. For example, when a display driver calls EngDeviceIoControl, this function calls a system service causing the Windows NT I/O Manager to set up an IRP and call the NT-supplied video port driver with that IRP. The video port driver uses the IRP to set up a VRP in a VIDEO_REQUEST_PACKET structure. The video port driver then calls the corresponding video miniport driver's StartIo entry point with the VRP.
virtual device driver (VDD)
A device driver that operates in user mode and communicates with a corresponding device driver in kernel mode. A VDD supports only special-purpose hardware devices from an MS–DOS application. The VDD acts as a layer between MS-DOS applications and the hardware attached to the Windows NT machine.
virtual DOS machine (VDM)
See Windows NT virtual DOS machine and NTVDM.


W

Windows Driver Model (WDM)
A common set of services designed to allow driver writers for certain classes of devices to construct drivers with binary compatibility between the Microsoft® Windows® 98 and Windows 2000 operating systems. (This binary compatibility is only possible on Intel Architecture-compatible processors.)
Windows File Protection (WFP)
A new feature of Windows 2000, prevents setup programs that are not part of the operating system from overwriting shared system files.

WFP protects system files (typically DLLs and EXEs) by running in the background and detecting attempts to replace protected system files.

Windows Hardware Quality Lab (WHQL)
A Microsoft group whose purpose is to ensure hardware functionality across the Windows Family of Operating Systems.
Windows NT virtual DOS machine
A protected environment subsystem that emulates MS-DOS and 16-bit Windows within Windows NT. A VDM is created whenever a user starts an MS-DOS application on Windows NT.
Windows on Win32 (WOW)
A protected subsystem that runs within a VDM process. It provides a 16-bit Windows environment capable of running any number of 16-bit Windows applications on Windows NT.


X

Built on Sunday, March 11, 2001


XFORMOBJ

DirectX DDK
XFORMOBJ
A GDI user object that describes an arbitrary linear two-dimensional transform, such as for geometric wide lines. The transform can be downloaded to the driver.


XLATEOBJ

DirectX DDK
XLATEOBJ
A GDI user object that is used to translate color indexes from one palette to another.


DirectDraw Driver Functions

This section provides reference pages for Microsoft® DirectDraw® driver functions, callbacks, and function-specific structures. Except for the Drv Xxx functions, all other function names are pseudonames to be decided upon by the display driver writer.

DirectDraw Driver Header Files, Sample Code, and References lists the include files containing most of the DirectDraw function prototypes and structure and constant definitions.


DdAddAttachedSurface

DdAddAttachedSurface attaches a surface to another surface.

DWORD
  (APIENTRY *PDD_SURFCB_ADDATTACHEDSURFACE)(
    PDD_ADDATTACHEDSURFACEDATA  lpAddAttachedSurface
    );

Parameters

lpAddAttachedSurface
Points to a DD_ADDATTACHEDSURFACEDATA structure that contains information required for the driver to perform the attachment.

Return Value

DdAddAttachedSurface returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Headers

Declared in ddraw.h or ddrawint.h. Include ddraw.h or ddrawint.h.

Comments

DdAddAttachedSurface can be optionally implemented in DirectDraw drivers.

The driver should update any internal surface state it keeps to reflect the attachment.

DD_ADDATTACHEDSURFACEDATA

The DD_ADDATTACHEDSURFACEDATA structure contains information necessary to attach a surface to another surface.

typedef struct _DD_ADDATTACHEDSURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  PDD_SURFACE_LOCAL  lpSurfAttached;
  HRESULT  ddRVal;
  VOID  *AddAttachedSurface;
} DD_ADDATTACHEDSURFACEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that represents the driver.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that represents the surface to which another surface is being attached.
lpSurfAttached
Points to a DD_SURFACE_LOCAL structure that represents the surface to be attached.
ddRVal
Specifies the location in which the driver writes the return value of the DdAddAttachedSurface callback. A return code of DD_OK indicates success.
AddAttachedSurface
Is unused on Windows® 2000 and later.


DdBlt

DdBlt performs a bit-block transfer.

DWORD
  (APIENTRY *PDD_SURFCB_BLT)(
    PDD_BLTDATA  lpBlt
    );

Parameters

lpBlt
Points to the DD_BLTDATA structure that contains the information required for the driver to perform the blit.

Return Value

DdBlt returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Headers

Declared in ddraw.h or ddrawint.h. Include ddraw.h or ddrawint.h.

Comments

DdBlt can be optionally implemented in DirectDraw drivers.

Before performing the bit block transfer, the driver should ensure that a flip involving the destination surface is not in progress. If the destination surface is involved in a flip, the driver should set ddRVal to DDERR_WASSTILLDRAWING and return DDHAL_DRIVER_HANDLED.

The driver should check dwFlags to determine the type of blit operation to perform. The driver should not check for flags that are undocumented.

When performing transparent (color keyed) blts, drivers should ignore any unused pixel bits in their comparisons. (For instance in 32bpp modes, the high byte is typically unused. This byte should not be used in the color key comparison.)

DD_BLTDATA

The DD_BLTDATA structure contains the information relevant to the driver for doing bit block transfers.

typedef struct _DD_BLTDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDDestSurface;
  RECTL  rDest;
  PDD_SURFACE_LOCAL  lpDDSrcSurface;
  RECTL  rSrc;
  DWORD  dwFlags;
  DWORD  dwROPFlags;
  DDBLTFX  bltFX;
  HRESULT  ddRVal;
  VOID  *Blt;
  BOOL  IsClipped;
  RECTL  rOrigDest;
  RECTL  rOrigSrc;
  DWORD  dwRectCnt;
  LPRECT  prDestRects;
  DWORD  dwAFlags;            // Windows 2000 and later
  DDRGBA  ddrgbaScaleFactors; // Windows 2000 and later
 } DD_BLTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw object.
lpDDDestSurface
Points to the DD_SURFACE_LOCAL structure that describes the surface on which to blit.
rDest
Points to a RECTL structure that specifies the upper left and lower right points of a rectangle on the destination surface. These points define the area in which the blit should occur and its position on the destination surface.
lpDDSrcSurface
Points to a DD_SURFACE_LOCAL structure that describes the source surface.
rSrc
Points to a RECTL structure that specifies the upper left and lower right points of a rectangle on the source surface. These points define the area of the source blit data and its position on the source surface.
dwFlags
Is a set of flags that specify the type of blit operation to perform and what associated structure members have valid data that the driver should use. This member is a bit-wise OR of any of the following flags:
Flag | Meaning
DDBLT_AFLAGS | This flag is not yet used as of DirectX® 7.0. Indicates to the driver that the dwAFlags and ddrgbaScaleFactors members in this structure are valid. This flag is always set if the DD_BLTDATA structure is passed to the driver from the DdAlphaBlt callback. Otherwise this flag is zero. If this flag is set, the DDBLT_ROTATIONANGLE and DDBLT_ROP flags will be zero.
DDBLT_ASYNC | Perform this blit asynchronously through the FIFO in the order received. If no room exists in the hardware FIFO, the driver should fail the call and return immediately.
DDBLT_COLORFILL | Use the dwFillColor member in the DDBLTFX structure (defined in the DirectDraw SDK documentation) as the RGB color with which to fill the destination rectangle on the destination surface.
DDBLT_DDFX | Use the dwDDFX member in the DDBLTFX structure (defined in the DirectDraw SDK documentation) to determine the effects to use for the blit.
DDBLT_DDROPS | This flag is reserved for system use and should be ignored by the driver. The driver should also ignore the dwDDROPS member of the DDBLTFX structure.
DDBLT_KEYDESTOVERRIDE | Use the dckDestColorkey member in the DDBLTFX structure (defined in the DirectDraw SDK documentation) as the color key for the destination surface. If an override is not being set, then dckDestColorkey does not contain the color key. The driver should test the surface itself.
DDBLT_KEYSRCOVERRIDE | Use the dckSrcColorkey member in the DDBLTFX structure (defined in the DirectDraw SDK documentation) as the color key for the source surface. If an override is not being set, then dckDestColorkey does not contain the color key. The driver should test the surface itself.
DDBLT_ROP | Use the dwROP member in the DDBLTFX structure (defined in the DirectDraw SDK documentation) for the raster operation for this blit. Currently, the only ROP passed to the driver is SRCCOPY. This ROP is the same as that defined in the Win32® API. See the Platform SDK documentation for details.
DDBLT_ROTATIONANGLE | This flag is not supported on Windows 2000 and later and should be ignored by the driver.
DDBLT_WAIT | Do not return immediately with the DDERR_WASSTILLDRAWING message if the blitter is busy—wait until the blit can be set up or another error occurs.

dwROPFlags
Is unused on Windows 2000 and later and should be ignored by the driver.
bltFX
Specifies a DDBLTFX structure (defined in the DirectDraw SDK documentation) that contains override information for more complex blit operations. For example, the dwFillColor member is used for solid color fills, and the ddckSrcColorKey and ddckDestColorKey members are used for color key blits. The driver can determine which members of bltFX contain valid data by looking at the dwFlags member of the DD_BLTDATA structure. Note that the DDBLTFX_NOTEARING, DDBLTFX_MIRRORLEFTRIGHT, and DDBLTFX_MIRRORUPDOWN flags are unsupported on Windows 2000 and later and will never be passed to the driver.See the Platform SDK documentation for information about the DDBLTFX structure.
ddRVal
Specifies the location in which the driver writes the return value of the DdBlt callback. A return code of DD_OK indicates success.
Blt
Is used by the DirectDraw API and should not be filled in by the driver.
IsClipped
Indicates whether this is a clipped blit. On Windows 2000 and later, this member is always FALSE, indicating that the blit is unclipped.
rOrigDest
Is unused for Windows 2000 and later. Specifies a RECTL structure that defines the unclipped destination rectangle. This member is valid only if IsClipped is TRUE.
rOrigSrc
Is unused for Windows 2000 and later. Specifies a RECTL structure that defines the unclipped source rectangle. This member is valid only if IsClipped is TRUE.
dwRectCnt
Is unused for Windows 2000 and later. Specifies the number of destination rectangles to which prDestRects points. This member is valid only if IsClipped is TRUE.
prDestRects
Is unused for Windows 2000 and later. Points to an array of RECTL structures that describe of destination rectangles. This member is valid only if IsClipped is TRUE.
dwAFlags (Windows 2000 and later only)
Is valid only if the DDBLT_AFLAGS flag is set in the dwFlags member of this structure. This member specifies operation flags used only by the DdAlphaBlt callback (which is not yet implemented as of DirectX 7.0). This member is a bit-wise OR of any of the following flags:
Flag | Meaning
DDABLT_BILINEARFLITER | Enable bilinear filtering of the source pixels during a stretch blit. By default, no filtering is performed. Instead, a nearest-neighbor source pixel is copied to a destination pixel.
DDABLT_NOBLEND | Write the source pixel values to the destination surface without blending. The pixels are converted from the source pixel format to the destination format, but no color keying, alpha blending, or RGBA scaling are performed. In the case of a fill operation (where the lpDDSrcSurface member is NULL), the lpDDRGBAScaleFactors member of this structure points to the source alpha and color components that are to be converted to the destination pixel format and are used to fill the destination. A blit operation is performed if a valid source surface is specified, but in this case, lpDDRGBAScaleFactors must be NULL or the call will fail. This flag cannot be used in conjunction with the DDBLT_KEYSRC and DDBLT_KEYDEST flags.
DDABLT_SRCOVERDEST | If set, this flag indicates that the operation originated from the application's AlphaBlt routine. If the call was originated by the application's Blt method, this flag is not set. Drivers that have a unified DdBlt and DdAlphaBlt callback can use this flag to distinguish between the two application function calls.

ddrgbaScaleFactors (Windows 2000 and later only)
Is valid only if the DDBLT_AFLAGS flag is set in the dwFlags member of this structure. This member is a DDARGB structure (defined in ddraw.h) that contains RGBA-scaling factors. These scaling factors are used to scale the color and alpha components of each source pixel before it is composited to the destination surface.


DdCanCreateSurface

DdCanCreateSurface indicates whether the driver can create a surface of the specified surface description.

DWORD
  (APIENTRY *PDD_CANCREATESURFACE)(
    PDD_CANCREATESURFACEDATA  lpCanCreateSurface
    );

Parameters

lpCanCreateSurface
Points to the DD_CANCREATESURFACEDATA structure containing the information required for the driver to determine whether a surface can be created.

Return Value

DdCanCreateSurface returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Headers

Declared in ddraw.h or ddrawint.h. Include ddraw.h or ddrawint.h.

Comments

DdCanCreateSurface should check the surface description to which lpDDSurfaceDesc points to determine if the driver can support the format and capabilities of the requested surface for the mode that the driver is currently in. The driver should return DD_OK in ddRVal if it supports the surface; otherwise, it should return the DDERR_Xxx error code that best describes why it does not support the surface.

The bIsDifferentPixelFormat member of the following structure is unreliable for z-buffers. Drivers should use bIsDifferentPixelFormat only when they have first checked that the specified surface is not a z-buffer. Drivers can perform this check by determining whether the DDSCAPS_ZBUFFER flag is set in lpDDSurfaceDesc—>ddsCaps.dwCaps.

This function must be implemented in a DirectDraw driver.

DD_CANCREATESURFACEDATA

The DD_CANCREATESURFACEDATA structure contains information necessary to indicate whether a surface can be created.

typedef struct _DD_CANCREATESURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACEDESC  lpDDSurfaceDesc;
  DWORD  bIsDifferentPixelFormat;
  HRESULT  ddRVal;
  VOID  *CanCreateSurface;
} DDHAL_CANCREATESURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure representing the DirectDraw object.
lpDDSurfaceDesc
Points to a DDSURFACEDESC structure that contains a description of the surface to be created. See the Comments section for additional information about this member.
bIsDifferentPixelFormat
Indicates whether the pixel format of the surface to be created differs from that of the primary surface.
ddRVal
Specifies the location in which the driver writes the return value of the DdCanCreateSurface callback. A return code of DD_OK indicates success.
CanCreateSurface
Is used by the DirectDraw API and should not be filled in by the driver.

Comments

The DirectDraw surface description pointed to by the lpDDSurfaceDesc member is actually a DDSURFACEDESC2 structure (rather than a DDSURFACEDESC structure) for DirectDraw 6.0 and later runtimes. Therefore, if you need information at CanCreateSurface time from those members that are in the DDSURFACEDESC2 structure but not in the DDSURFACEDESC structure, you can simply cast the pointer to a DDSURFACEDESC structure to a pointer to a DDSURFACEDESC2 structure prior to use. The following example shows how the value of dwTextureStage (a member of the DDSURFACEDESC2 structure, but not also of the DDSURFACEDESC structure) can be obtained from a pointer to a DDSURFACEDESC structure.

DDSURFACEDESC2* pddsd = (DDSURFACEDESC2*)pccsd->lpDDSurfaceDesc;
DWORD dwStage = pddsd->dwTextureStage;

See Also

DdCreateSurface


DdControlColor

DdControlColor controls the luminance and brightness controls of an overlay surface.

DWORD
  (APIENTRY *PDD_COLORCB_COLORCONTROL)(
    PDD_COLORCONTROLDATA  lpColorControl
    );

Parameters

lpColorControl
Points to a DD_COLORCONTROLDATA structure that contains the color control information for a specified overlay surface.

Return Value

DdControlColor returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdControlColor can be optionally implemented in a DirectDraw driver.

DD_COLORCONTROLDATA

The DD_COLORCONTROLDATA structure contains the color control information for the specified overlay.

typedef struct _DD_COLORCONTROLDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  LPDDCOLORCONTROL  lpColorData;
  DWORD  dwFlags;
  HRESULT  ddRVal;
  VOID  *ColorControl;
} DD_COLORCONTROLDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to the DD_SURFACE_LOCAL structure representing the overlay surface.
lpColorData
Points to a DDCOLORCONTROL structure. See the dwFlags member to determine how to use this member.
dwFlags
Is a set of flags that specify the color control flags. This member can be one of the following values:
Flag | Meaning
DDRAWI_GETCOLOR | The driver should return the color controls it supports for the specified overlay in the lpColorData member. The driver should set the appropriate flags in the dwFlags member of the DDCOLORCONTROL structure to indicate in which other members the driver has returned valid data.
DDRAWI_SETCOLOR | The driver should set the current color controls for the specified overlay using the values specified in the lpColorData member.

ddRVal
Specifies the location in which the driver writes the return value of the DdControlColor callback. A return code of DD_OK indicates success.
ColorControl
Is used by the DirectDraw API and should not be filled in by the driver.


DdCreatePalette

DdCreatePalette creates a DirectDrawPalette object for the specified DirectDraw object.

DWORD
  (APIENTRY *PDD_CREATEPALETTE)(
    PDD_CREATEPALETTEDATA  lpCreatePalette
    );

Parameters

lpCreatePalette
Points to a DD_CREATEPALETTEDATA structure that contains the information necessary to create the DirectDrawPalette object.

Return Value

DdCreatePalette returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DD_CREATEPALETTEDATA

The DD_CREATEPALETTEDATA structure contains information necessary to create a DirectDrawPalette object for this DirectDraw object.

typedef struct _DD_CREATEPALETTEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_PALETTE_GLOBAL  lpDDPalette;
  LPPALETTEENTRY  lpColorTable;
  HRESULT  ddRVal;
  VOID  *CreatePalette;
  BOOL  is_excl;
} DD_CREATEPALETTEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that represents the DirectDraw object.
lpDDPalette
Points to a DD_PALETTE_GLOBAL structure representing the DirectDrawPalette object.
lpColorTable
Points to an array of 2, 4, 16, or 256 PALETTEENTRY structures used to initialize the colors for this DirectDrawPalette object.
ddRVal
Specifies the location in which the driver writes the return value of the DdCreatePalette callback. A return code of DD_OK indicates success.
CreatePalette
Is used by the DirectDraw API and should not be filled in by the driver.
is_excl
Indicates whether this process has exclusive mode.


DdCreateSurface

DdCreateSurface creates a DirectDraw surface.

DWORD
  (APIENTRY *PDD_CREATESURFACE)(
    PDD_CREATESURFACEDATA  lpCreateSurface
    );

Parameters

lpCreateSurface
Points to a DD_CREATESURFACEDATA structure that contains the information required to create a surface.

Return Value

DdCreateSurface returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

The driver can allocate the surface memory itself or can request that DirectDraw perform the memory management. If the driver performs the allocation, it must do the following:

  • Perform the allocation and write a valid pointer to the memory in the fpVidMem member of the DD_SURFACE_GLOBAL structure.
  • If the surface has a FourCC format, write the pitch in the lPitch member of the DD_SURFACE_GLOBAL and DDSURFACEDESC structures, and update the flags accordingly.

Otherwise, the driver can have DirectDraw allocate the surface by returning one of the following values in fpVidMem:

  • DDHAL_PLEASEALLOC_BLOCKSIZE, requesting that DirectDraw allocate the surface memory from offscreen memory.
  • DDHAL_PLEASEALLOC_USERMEM, requesting that DirectDraw allocate the surface memory from user memory. The driver must also return the size in bytes of the memory region in the dwUserMemSize member of DD_SURFACE_GLOBAL.

For DirectDraw to perform the allocation of a surface with a FourCC format, the driver must also return the pitch and x- and y-block sizes in the lPitch, dwBlockSizeX, and dwBlockSizeY members, respectively, of the DD_SURFACE_GLOBAL structure. The pitch must also be returned in the lPitch member of the DDSURFACEDESC structure. For linear memory, the driver should set dwBlockSizeX to the size in bytes of the memory region and set dwBlockSizeY to 1.

By default, the driver is not notified when a primary surface is created on Windows 2000 and later. However, if the driver supports GUID_NTPrivateDriverCaps and the DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION flag is set, then the driver will be notified.

DD_CREATESURFACEDATA

The DD_CREATESURFACEDATA structure contains information necessary to create a surface.

typedef struct _DD_CREATESURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACEDESC  lpDDSurfaceDesc;
  PDD_SURFACE_LOCAL  *lplpSList;
  DWORD  dwSCnt;
  HRESULT  ddRVal;
  VOID  *CreateSurface;
} DD_CREATESURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure representing the driver.
lpDDSurfaceDesc
Points to the DDSURFACEDESC structure describing the surface that the driver should create.
lplpSList
Points to a list of DD_SURFACE_LOCAL structures describing the surface objects created by the driver. On Windows 2000 and later, there is usually only one entry in this array. However, if the driver supports the Windows 98/Me-style surface creation techniques using DdGetDriverInfo with GUID_NTPrivateDriverCaps, and the driver sets the DDHAL_PRIVATECAP_ATOMICSURFACECREATION flag, the member will contain a list of surfaces (usually more than one).
dwSCnt
Specifies the number of surfaces in the list to which lplpSList points. This value is usually 1 on Windows 2000 and later. However, if the driver support the Windows 98/Me-style surface creation techniques using DdGetDriverInfo with GUID_NTPrivateDriverCaps, the member will contain the actual number of surfaces in the list (usually more than one).
ddRVal
Specifies the location in which the driver writes the return value of the DdCreateSurface callback. A return code of DD_OK indicates success.
CreateSurface
Is used by the DirectDraw API and should not be filled in by the driver.


DdDestroyPalette

DdDestroyPalette destroys the specified palette.

DWORD
  (APIENTRY *PDD_PALCB_DESTROYPALETTE)(
    PDD_DESTROYPALETTEDATA  lpDestroyPalette
    );

Parameters

lpDestroyPalette
Points to a DD_DESTROYPALETTEDATA structure that contains the information needed to destroy a palette.

Return Value

DdDestroyPalette returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DD_DESTROYPALETTEDATA

The DD_DESTROYPALETTEDATA structure contains information necessary to destroy the specified palette.

typedef struct _DD_DESTROYPALETTEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_PALETTE_GLOBAL  lpDDPalette;
  HRESULT  ddRVal;
  VOID  *DestroyPalette;
} DD_DESTROYPALETTEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure representing the DirectDraw object.
lpDDPalette
Points to the DD_PALETTE_GLOBAL structure representing the palette object to be destroyed.
ddRVal
Specifies the location in which the driver writes the return value of the DdDestroyPalette callback. A return code of DD_OK indicates success.
DestroyPalette
Is used by the DirectDraw API and should not be filled in by the driver.


DdDestroySurface

DdDestroySurface destroys a DirectDraw surface.

DWORD
  (APIENTRY *PDD_SURFCB_DESTROYSURFACE)(
    PDD_DESTROYSURFACEDATA  lpDestroySurface
    );

Parameters

lpDestroySurface
Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.

Return Value

DdDestroySurface returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

If DirectDraw did the memory allocation at surface creation time, DdDestroySurface should return DDHAL_DRIVER_NOTHANDLED.

If the driver is performing the surface memory management itself, DdDestroySurface should free the surface memory and perform any other cleanup, such as freeing private data stored in the dwReserved1 members of the DD_SURFACE_GLOBAL and DD_SURFACE_LOCAL structures.

DD_DESTROYSURFACEDATA

The DD_DESTROYSURFACEDATA structure contains information necessary to destroy the specified surface.

typedef struct _DD_DESTROYSURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  HRESULT  ddRVal;
  VOID  *DestroySurface;
} DD_DESTROYSURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to the DD_SURFACE_LOCAL structure representing the surface object to be destroyed.
ddRVal
Specifies the location in which the driver writes the return value of the DdDestroySurface callback. A return code of DD_OK indicates success.
DestroySurface
Is used by the DirectDraw API and should not be filled in by the driver.


DdFlip

DdFlip causes the surface memory associated with the target surface to become the primary surface, and the current surface to become the nonprimary surface.

DWORD
  (*PDD_SURFCB_FLIP)(
    PDD_FLIPDATA  lpFlip
    );

Parameters

lpFlip
Points to a DD_FLIPDATA structure that contains the information required to perform the flip.

Return Value

DdFlip returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdFlip allows a display driver to perform multibuffering. DirectDraw drivers must implement this function.

The driver should update its surface pointers so that the next frame will be written to the surface to which the lpSurfTarg member of the following structure points. If a previous flip request is still pending, the driver should fail the call and return DDERR_WASSTILLDRAWING. The driver should ensure that the scan line is not in the vertical blank before performing the flip. DdFlip does not affect the actual display of the video data.

If the driver's hardware supports overlays or textures, DdFlip should make any necessary checks based on the surface type before performing the flip.

DD_FLIPDATA

The DD_FLIPDATA structure contains information needed to do a flip.

typedef struct _DD_FLIPDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpSurfCurr;
  PDD_SURFACE_LOCAL  lpSurfTarg;
  DWORD  dwFlags;
  HRESULT  ddRVal;
  VOID  *Flip;
  PDD_SURFACE_LOCAL  lpSurfCurrLeft;
  PDD_SURFACE_LOCAL  lpSurfTargLeft;
} DD_FLIPDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpSurfCurr
Points to the DD_SURFACE_LOCAL structure describing the current surface.
lpSurfTarg
Points to the DD_SURFACE_LOCAL structure describing the target surface; that is, the surface to which the driver should flip.
dwFlags
Is a set of flags that provide the driver with details for the flip. This member can be a bit-wise OR of the following flags:
Flag | Meaning
DDFLIP_EVEN | The surface to which the lpSurfTarg member points contains only the even field of video data. This flag is valid only when the surface is an overlay, and is mutually exclusive of DDFLIP_ODD.
DDFLIP_ODD | The surface to which the lpSurfTarg member points contains only the odd field of video data. This flag is valid only when the surface is an overlay, and is mutually exclusive of DDFLIP_EVEN.
DDFLIP_NOVSYNC | The driver should perform the flip and return immediately. Typically, the current back buffer (which used to be the front buffer) is still visible until the next vertical retrace. Subsequent operations involving the surfaces to which the lpSurfCurr and lpSurfTarg members point will not check to see if the physical flip has finished. This allows an application to perform flips at a higher frequency than the monitor refresh rate, although it might introduce visible artifacts.
DDFLIP_INTERVAL2 | The driver should perform the flip on every other vertical sync. It should return DDERR_WASSTILLDRAWING until the second vertical retrace has occurred. This flag is mutually exclusive of DDFLIP_INTERVAL3 and DDFLIP_INTERVAL4.
DDFLIP_INTERVAL3 | The driver should perform the flip on every third vertical sync. It should return DDERR_WASSTILLDRAWING until the third vertical retrace has occurred. This flag is mutually exclusive of DDFLIP_INTERVAL2 and DDFLIP_INTERVAL4.
DDFLIP_INTERVAL4 | The driver should perform the flip on every fourth vertical sync. It should return DDERR_WASSTILLDRAWING until the fourth vertical retrace has occurred. This flag is mutually exclusive of DDFLIP_INTERVAL2 and DDFLIP_INTERVAL3.

ddRVal
Specifies the location in which the driver writes the return value of the DdFlip callback. A return code of DD_OK indicates success.
Flip
Is used by the DirectDraw API and should not be filled in by the driver.
lpSurfCurrLeft
Points to the DD_SURFACE_LOCAL structure describing the current left surface.
lpSurfTargLeft
Points to the DD_SURFACE_LOCAL structure describing the left target surface to flip to.


DdFlipToGDISurface

DdFlipToGDISurface notifies the driver when DirectDraw is flipping to or from a GDI surface.

DWORD
  (*PDD_FLIPTOGDISURFACE)(
    PDD_FLIPTOGDISURFACEDATA  lpFlipToGDISurface
    );

Parameters

lpFlipToGDISurface
Points to a DD_FLIPTOGDISURFACEDATA structure that contains the notification information.

Return Value

DdFlipToGDISurface returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdFlipToGDISurface can be implemented in drivers with hardware that needs to be enabled or disabled, depending on whether a GDI surface is being flipped to.

DD_FLIPTOGDISURFACEDATA

The DD_FLIPTOGDISURFACEDATA structure contains the GDI surface notification information.

typedef struct _DD_FLIPTOGDISURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  DWORD  dwToGDI;
  DWORD  dwReserved;
  HRESULT  ddRVal;
  VOID  *FlipToGDISurface;
} DD_FLIPTOGDISURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
dwToGDI
Indicates that DirectDraw is flipping to a GDI surface when TRUE; indicates that DirectDraw is flipping from a GDI surface when FALSE.
dwReserved
Is reserved for system use and should be ignored by the driver.
ddRVal
Specifies the location in which the driver writes the return value of the DdFlipToGDISurface callback. A return code of DD_OK indicates success.
FlipToGDISurface
Is used by the DirectDraw API and should not be filled in by the driver.


DdFreeDriverMemory

DdFreeDriverMemory frees offscreen or nonlocal display memory to satisfy a new allocation request.

DWORD
  (APIENTRY *PDD_FREEDRIVERMEMORY)(
    PDD_FREEDRIVERMEMORYDATA  lpfdm
    );

Parameters

lpfdm
Points to a DD_FREEDRIVERMEMORYDATA structure that contains the details of the free request.

Return Value

DdFreeDriverMemory returns one of the following callback codes:

DDHAL_DRIVER_HANDLED when the driver hooks the call.

DDHAL_DRIVER_NOTHANDLED

Comments

The driver should implement DdFreeDriverMemory when it has DirectDraw manage all offscreen display memory management, including allocations for DrvCreateDeviceBitmap. DirectDraw requests for allocations in offscreen memory should always take precedence over GDI device bitmap allocations.

DirectDraw calls DdFreeDriverMemory when it does not have enough offscreen or nonlocal display memory to allocate a surface requested by an application. The driver should move a GDI device bitmap from offscreen memory into system memory and then immediately return. Bitmap moves can be accomplished by calling EngModifySurface.

DirectDraw will continually call DdFreeDriverMemory until there is enough offscreen memory from which to allocate the requested surface or until the driver returns DDERR_OUTOFMEMORY.

DD_FREEDRIVERMEMORYDATA

The DD_FREEDRIVERMEMORYDATA structure contains the details of the free request.

typedef struct _DD_FREEDRIVERMEMORYDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  HRESULT  ddRVal;
  VOID  *FreeDriverMemory;
} DD_FREEDRIVERMEMORYDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to the DD_SURFACE_LOCAL structure representing the surface that DirectDraw is attempting to allocate.
ddRVal
Specifies the location in which the driver writes the return value of the DdFreeDriverMemory callback. A return code of DD_OK indicates that the driver succeeded in freeing some space; otherwise, the driver should set this to be DDERR_OUTOFMEMORY.
FreeDriverMemory
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DrvCreateDeviceBitmap, EngModifySurface, HeapVidMemAllocAligned


DdGetAvailDriverMemory

DdGetAvailDriverMemory queries the amount of free memory in the driver-managed memory heap.

DWORD
  (APIENTRY *PDD_GETAVAILDRIVERMEMORY)(
    PDD_GETAVAILDRIVERMEMORYDATA  lpGetAvailDriverMemory
    );

Parameters

lpGetAvailDriverMemory
Points to a DD_GETAVAILDRIVERMEMORYDATA structure that contains the information required to perform the query.

Return Value

DdGetAvailDriverMemory returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This function does not need to be implemented if the memory will be managed by DirectDraw.

DdGetAvailDriverMemory determines how much free memory is in the driver's private heaps for the specified surface type. The driver should check the surface capabilities specified in the DDSCaps member of the following structure against the heaps it is maintaining internally, to determine what heap size to query. For example, if DDSCAPS_NONLOCALVIDMEM is set, the driver should return only contributions from the AGP heaps.

The driver indicates its support of DdGetAvailDriverMemory by implementing a response to GUID_MiscellaneousCallbacks in DdGetDriverInfo.

DD_GETAVAILDRIVERMEMORYDATA

The DD_GETAVAILDRIVERMEMORYDATA structure contains the information needed by the driver to query and return the amount of free memory.

typedef struct _DD_GETAVAILDRIVERMEMORYDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  DDSCAPS  DDSCaps;
  DWORD  dwTotal;
  DWORD  dwFree;
  HRESULT  ddRVal;
  VOID  *GetAvailDriverMemory;
} DD_GETAVAILDRIVERMEMORYDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
DDSCaps
Points to a DDSCAPS structure that describes the type of surface for which memory availability is being queried.
dwTotal
Specifies the location in which the driver returns the number of bytes of driver-managed memory that can be used for surfaces of the type described by DDSCaps.
dwFree
Specifies the location in which the driver returns the amount of free memory, in bytes, for the surface type described by DDSCaps.
ddRVal
Specifies the location in which the driver writes the return value of the DdGetAvailDriverMemory callback. A return code of DD_OK indicates success.
GetAvailDriverMemory
Is used by the DirectDraw API and should not be filled in by the driver.


DdGetBltStatus

DdGetBltStatus queries the blit status of the specified surface.

DWORD
  (APIENTRY *PDD_SURFCB_GETBLTSTATUS)(
    PDD_GETBLTSTATUSDATA  lpGetBltStatus
    );

Parameters

lpGetBltStatus
Points to a DD_GETBLTSTATUSDATA structure that contains the information required to perform the blit status query.

Return Value

DdGetBltStatus returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

The blit status that the driver returns is based on the dwFlags member of the structure that lpGetBltStatus points to, as follows:

  • If the flag is DDGBS_CANBLT, the driver should determine whether the surface is currently involved in a flip. If a flip is not in progress and if the hardware is otherwise capable of currently accepting a blit request, the driver should return DD_OK in the ddRVal member of the following structure. If a flip is in progress or if the hardware cannot currently accept another blit request, the driver should set the ddRVal member to DDERR_WASSTILLDRAWING.
  • If the flag is DDGBS_ISBLTDONE, the driver should set ddRVal to DDERR_WASSTILLDRAWING if a blit is currently in progress; otherwise it should return DD_OK.

DD_GETBLTSTATUSDATA

The DD_GETBLTSTATUSDATA structure returns the blit status information.

typedef struct _DD_GETBLTSTATUSDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  DWORD  dwFlags;
  HRESULT  ddRVal;
  VOID  *GetBltStatus;
} DD_GETBLTSTATUSDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure representing the surface whose blit status is being queried. For GetSysmemBltStatus calls, the driver is assured that this member points to a system memory surface.
dwFlags
Specifies the blit status being requested. This member can be one of the following values:
Flag | Meaning
DDGBS_CANBLT | Queries whether the driver can currently perform a blit.
DDGBS_ISBLTDONE | Queries whether the driver has completed the last blit.

ddRVal
Specifies the location in which the driver writes the return value of the DdGetBltStatus callback. A return code of DD_OK indicates success.
GetBltStatus
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DdBlt


DdGetDriverInfo

DdGetDriverInfo queries the driver for additional information about itself.

DWORD
  (APIENTRY *PDD_GETDRIVERINFO)(
    PDD_GETDRIVERINFODATA  lpGetDriverInfo
    );

Parameters

lpGetDriverInfo
Points to a DD_GETDRIVERINFODATA structure that contains the information required to perform the query.

Return Value

DdGetDriverInfo must return DDHAL_DRIVER_HANDLED.

Comments

Drivers must implement DdGetDriverInfo to expose driver-supported DirectDraw functionality that is not returnable through DrvEnableDirectDraw.

The driver's DrvGetDirectDrawInfo function returns a pointer to DdGetDriverInfo in the GetDriverInfo member of the DD_HALINFO structure.

To inform DirectDraw that the DdGetDriverInfo member has been set correctly, the driver must also set the DDHALINFO_GETDRIVERINFOSET bit of the dwFlags member in the DD_HALINFO structure.

DdGetDriverInfo should determine whether the driver and its hardware support the callbacks or capabilities requested by the specified GUID. For all GUIDs except GUID_D3DParseUnknownCommandCallback, if the driver does provide the requested support, it should set the following members of the DD_GETDRIVERINFODATA structure:

  • Set dwActualSize to the size in bytes of the callback or capability structure being returned by the driver.
  • In the memory that lpvData points to, initialize the members of the callback or capability structure that corresponds with the requested feature as follows:
    • Set the dwSize member to the size in bytes of the structure.
    • For callbacks, set the function pointers to point to those callbacks implemented by the driver, and set the bits in the dwFlags member to indicate what functions the driver supports.
    • For capabilities, set the appropriate members of the capability structure with values supported by the driver/device.
  • Return DD_OK in ddRVal.

If the driver does not support the feature, it should set ddRVal to DDERR_CURRENTLYNOTAVAIL and return.

DirectDraw informs the driver of the expected amount of data in the dwExpectedSize member of the DD_GETDRIVERINFODATA structure. The driver must not fill in more data than dwExpectedSize bytes.

To avoid problems using DdGetDriverInfo:

  • Do not implement dependencies based on the order in which DdGetDriverInfo is called. For example, avoid hooking driver initialization steps into DdGetDriverInfo.
  • Do not try to ascertain the DirectDraw version based on the calls to DdGetDriverInfo.
  • Do not assume anything about the number of times DirectDraw will call the driver, or the number of times DirectDraw will query a given GUID. It is possible that DirectDraw will probe the driver repeatedly with the same GUID. Implementing assumptions about this in the driver hampers its compatibility with future runtimes.

DD_GETDRIVERINFODATA

The DD_GETDRIVERINFODATA structure is used to pass data to and from the DdGetDriverInfo callback routine.

typedef struct _DD_GETDRIVERINFODATA {
  VOID  *dhpdev;        // Windows 2000 and later
  DWORD  dwSize;
  DWORD  dwFlags;
  GUID  guidInfo;
  DWORD  dwExpectedSize;
  PVOID  lpvData;
  DWORD  dwActualSize;
  HRESULT  ddRVal;
  ULONG_PTR  dwContext; // Windows 98/Me only
} DD_GETDRIVERINFODATA, *PDD_GETDRIVERINFODATA;

Members

dhpdev (Windows 2000 and later only)
Specifies a handle to the driver's PDEV.
dwSize
Specifies the size in bytes of this DD_GETDRIVERINFODATA structure.
dwFlags
Is currently unused and is set to zero.
guidInfo
Specifies the GUID of the DirectX support for which the driver is being queried. In a Windows 2000 and later DirectDraw driver, this member can be one of the following values (in alphabetic order):
GUID | Description
GUID_ColorControlCallbacks | Queries whether the driver supports DdControlColor. If the driver does support it, the driver should initialize and return a DD_COLORCONTROLCALLBACKS structure in the buffer to which lpvData points.
GUID_D3DCallbacks | Queries whether the driver supports any of the functionality specified through the D3DHAL_CALLBACKS structure. If the driver does not provide any of this support, it should initialize and return a D3DHAL_CALLBACKS structure in the buffer to which lpvData points.
GUID_D3DCallbacks2 | Obsolete.
GUID_D3DCallbacks3 | Queries whether the driver supports any of the functionality specified through the D3DHAL_CALLBACKS3 structure. If the driver does provide any of this support, it should initialize and return a D3DHAL_CALLBACKS3 structure in the buffer to which lpvData points.
GUID_D3DCaps | Obsolete.
GUID_D3DExtendedCaps | Queries whether the driver supports any of the Microsoft® Direct3D® functionality specified through the D3DHAL_D3DEXTENDEDCAPS structure. If the driver does provide any of this support, it should initialize and return a D3DHAL_D3DEXTENDEDCAPS structure in the buffer to which lpvData points.
GUID_D3DParseUnknownCommandCallback | Provides the Direct3D portion of the driver with the Direct3D runtime's D3dParseUnknownCommandCallback. The driver's D3dDrawPrimitives2 callback calls D3dParseUnknownCommandCallback to parse commands from the command buffer that the driver doesn't understand.DirectDraw passes a pointer to this function in the buffer to which lpvData points. If the driver supports this aspect of Direct3D, it should store the pointer.
GUID_GetHeapAlignment | Queries whether the driver supports surface alignment requirements on a per-heap basis. If the driver does provide this support, it should initialize and return a DD_GETHEAPALIGNMENTDATA structure in the buffer to which lpvData points.
GUID_KernelCallbacks | Queries whether the driver supports any of the functionality specified through the DD_KERNELCALLBACKS structure. If the driver does provide any of this support, it should initialize and return a DD_KERNELCALLBACKS structure in the buffer to which lpvData points.
GUID_KernelCaps | Queries whether the driver supports any of the kernel-mode capabilities specified through the DDKERNELCAPS structure. If the driver does provide any of this support, it should initialize and return a DDKERNELCAPS structure in the buffer to which lpvData points.
GUID_MiscellaneousCallbacks | Queries whether the driver supports DdGetAvailDriverMemory. If the driver does support it, the driver should initialize and return a DD_MISCELLANEOUSCALLBACKS structure in the buffer to which lpvData points.
GUID_Miscellaneous2Callbacks | Queries whether the driver supports the additional miscellaneous functionality specified in the DD_MISCELLANEOUS2CALLBACKS structure. If the driver does support any of this support, the driver should initialize and return a DD_MISCELLANEOUS2CALLBACKS structure in the buffer to which lpvData points.
GUID_MotionCompCallbacks | Queries whether the driver supports the motion compensation functionality specified through the DD_MOTIONCOMPCALLBACKS structure. If the driver does provide any of this support, is should initialize and return a DD_MOTIONCOMPCALLBACKS structure in the buffer to which lpvData points.
GUID_NonLocalVidMemCaps | Queries whether the driver supports any of the nonlocal display memory capabilities specified through the DD_NONLOCALVIDMEMCAPS structure. If the driver does provide any of this support, it should initialize and return a DD_NONLOCALVIDMEMCAPS structure in the buffer to which lpvData points.
GUID_NTCallbacks | Queries whether the driver supports any of the functionality specified through the DD_NTCALLBACKS structure. If the driver does provide any of this support, it should initialize and return a DD_NTCALLBACKS structure in the buffer to which lpvData points.
GUID_NTPrivateDriverCaps | Queries whether the driver supports the Windows 98/Me-style surface creation techniques specified through the DD_NTPRIVATEDRIVERCAPS structure. If the driver does provide any of this support, it should initialize and return a DD_NTPRIVATEDRIVERCAPS structure in the buffer to which lpvData points.
GUID_UpdateNonLocalHeap | Queries whether the driver supports retrieval of the base addresses of each nonlocal heap in turn. If the driver does provide this support, it should initialize and return a DD_UPDATENONLOCALHEAPDATA structure in the buffer to which lpvData points.
GUID_VideoPortCallbacks | Queries whether the driver supports the video port extensions (VPE). If the driver does support VPE, it should initialize and return a DD_VIDEOPORTCALLBACKS structure in the buffer to which lpvData points.
GUID_VideoPortCaps | Queries whether the driver supports any of the VPE object capabilities specified through the DDVIDEOPORTCAPS structure. If the driver does provide any of this support, it should initialize and return a DDVIDEOPORTCAPS structure in the buffer to which lpvData points.
GUID_ZPixelFormats | Queries the pixel formats supported by the depth buffer. If the driver supports Direct3D, it should allocate and initialize the appropriate members of a DDPIXELFORMAT structure for every z-buffer format that it supports and return these in the buffer to which lpvData points.

dwExpectedSize
Specifies the number of bytes of data that DirectDraw expects the driver to pass back in the buffer to which lpvData points.
lpvData
Points to a DirectDraw-allocated buffer into which the driver copies the requested data. This buffer is typically dwExpectedSize bytes in size. The driver must not write more than dwExpectedSize bytes of data in it.
dwActualSize
Specifies the location in which the driver returns the number of bytes of data it writes in lpvData.
ddRVal
Specifies the driver's return value.
dwContext (Windows 98/Me only)
Specifies context information for the driver. This member is filled in by DirectDraw. On Windows 98/Me, this is the dwReserved3 member of the DDRAWI_DIRECTDRAW_GBL structure.

Comments

The data structure passed to the driver for a DdGetDriverInfo call has minor differences between Windows 98/Me and Windows 2000 and later. On Windows 2000 and later the data structure is called DD_GETDRIVERINFODATA and on Windows 98/Me the data structure is called DDHAL_GETDRIVERINFODATA. Both data structrures include a field for driver specific context information. On Windows 2000 and later, DD_GETDRIVERINFODATA includes a field dhpdev that stores the DHPDEV of the driver being called. On Windows 98/Me, DDHAL_GETDRIVERINFODATA includes a field dwContext that is copied for the driver reserved dwReserved3 field of the DirectDraw global object.


DdGetFlipStatus

DdGetFlipStatus determines whether the most recently requested flip on a surface has occurred.

DWORD
  (APIENTRY *PDD_SURFCB_GETFLIPSTATUS)(
    PDD_GETFLIPSTATUSDATA  lpGetFlipStatus
    );

Parameters

lpGetFlipStatus
Points to a DD_GETFLIPSTATUSDATA structure that contains the information required to perform the flip status query.

Return Value

DdGetFlipStatus returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

The driver should report its flip status based on the flag set in the dwFlags member of the structure that lpGetFlipStatus points to as follows:

  • If the flag is DDGFS_CANFLIP, the driver should determine whether the surface is currently involved in a flip. If a flip or a blit is not in progress and if the hardware is otherwise capable of currently accepting a flip request, the driver should return DD_OK in ddRVal. If a flip is in progress or if the hardware cannot currently accept a flip request, the driver should set ddRVal to DDERR_WASSTILLDRAWING.
  • If the flag is DDGFS_ISFLIPDONE, the driver should set ddRVal to DDERR_WASSTILLDRAWING if a flip is currently in progress; otherwise it should return DD_OK.

DD_GETFLIPSTATUSDATA

The DD_GETFLIPSTATUSDATA structure returns the flip status information.

typedef struct _DD_GETFLIPSTATUSDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  DWORD  dwFlags;
  HRESULT  ddRVal;
  VOID  *GetFlipStatus;
} DD_GETFLIPSTATUSDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure representing the driver.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that describes the surface whose flip status is being queried.
dwFlags
Specifies the flip status being requested. This member can be one of the following values:
Flag | Meaning
DDGFS_CANFLIP | Queries whether the driver can currently perform a flip.
DDGFS_ISFLIPDONE | Queries whether the driver has finished the last flip.

ddRVal
Specifies the location in which the driver writes the return value of the DdGetFlipStatus callback. A return code of DD_OK indicates success.
GetFlipStatus
Is used by the DirectDraw API and should not be filled in by the driver.


DdGetScanLine

DdGetScanLine returns the number of the current physical scan line.

DWORD
  (APIENTRY *PDD_GETSCANLINE)(
    PDD_GETSCANLINEDATA  pGetScanLine
    );

Parameters

pGetScanLine
Points to a DD_GETSCANLINEDATA structure in which the driver returns the number of the current scan line.

Return Value

DdGetScanLine returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

If the monitor is not in vertical blank, the driver should write the scan line value in the dwScanLine member of the following structure. The number must be in the range [0, n], where scan line 0 is the first visible scan line and scan line n is the last visible scan line on the screen. The driver should then set DD_OK in ddRVal and return DDHAL_DRIVER_HANDLED.

The scan line is indeterminate if a vertical blank is in progress. In this situation, the driver should set ddRVal to DDERR_VERTICALBLANKINPROGRESS and return DDHAL_DRIVER_HANDLED.

DD_GETSCANLINEDATA

The DD_GETSCANLINEDATA structure contains the members required to query and return the number of the current scan line.

typedef struct _DD_GETSCANLINEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  DWORD  dwScanLine;
  HRESULT  ddRVal;
  VOID  *GetScanLine;
} DD_GETSCANLINEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that represents the driver.
dwScanLine
Specifies the location in which the driver returns the number of the current scan line. See the Comments section for more information.
ddRVal
Specifies the location in which the driver writes the return value of the DdGetScanLine callback. A return code of DD_OK indicates success.
GetScanLine
Is used by the DirectDraw API and should not be filled in by the driver.

Comments

The returned scan line value in dwScanLine must be greater than or equal to 0 and less than N, where N is the sum of the number of visible scan lines and the number of scan lines that occur during vblank. For example, with a display operating at a resolution of 640x480, that has 12 scan lines during vblank, the value returned to GetScanLine could range from 0 to 491.


DdLock

DdLock locks a specified area of surface memory and provides a valid pointer to a block of memory associated with a surface.

DWORD
  (APIENTRY *PDD_SURFCB_LOCK)(
    PDD_LOCKDATA  lpLock
    );

Parameters

lpLock
Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.

Return Value

DdLock returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdLock should set the ddRVal member of the following structure to DDERR_WASSTILLDRAWING and return DDHAL_DRIVER_HANDLED if a blit or flip is in progress.

Unless otherwise specified by the dwFlags member of the following structure, the driver can return a memory pointer to the top of the surface in lpSurfData, also a member of the following structure. If the driver needs to calculate its own address for the surface, it can rely on the pointer passed in the fpProcess member of the following structure as being a per-process pointer to the user-mode mapping of its DirectDraw-accessible frame buffer.

A lock does not provide exclusive access to the requested memory block; that is, multiple threads can lock the same surface at the same time. It is the application’s responsibility to synchronize access to the memory block whose pointer is being obtained.

DD_LOCKDATA

The DD_LOCKDATA structure contains information necessary to do a lock as defined by DirectDraw's parameter structures.

typedef struct _DD_LOCKDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  DWORD  bHasRect;
  RECTL  rArea;
  LPVOID  lpSurfData;
  HRESULT  ddRVal;
  VOID  *Lock;
  DWORD  dwFlags;
  FLATPTR  fpProcess; // Windows 2000 and later
} DD_LOCKDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that describes the surface associated with the memory region to be locked down.
bHasRect
Specifies whether the area in rArea is valid.
rArea
Specifies a RECTL structure that defines the area on the surface to lock down.
lpSurfData
Specifies the location in which the driver can return a pointer to the memory region that it locked down.
ddRVal
Specifies the location in which the driver writes the return value of the DdLock callback. A return code of DD_OK indicates success.
Lock
Is used by the DirectDraw API and should not be filled in by the driver.
dwFlags
Specifies a bitmask that tells the driver how to perform the memory lockdown. This member is a bitwise-OR of any of the following values:
Flag | Meaning
DDLOCK_DISCARDCONTENTS No assumptions will be made about the contents of the surface or vertex buffer during this lock. This enables two things:
1. Direct3D or the driver may provide an alternative memory area as the vertex buffer. This is useful when one plans to clear the contents of the vertex buffer and fill in new data.
2. Drivers sometimes store surface data in a reordered format. When the application locks the surface, the driver is forced to undo this surface data reordering before allowing the application to see the surface contents.

This flag is a hint to the driver that it can skip the un-reordering process since the application plans to overwrite every single pixel in the surface or locked rectangle (and so erase any un-re-ordered pixels anyway). Applications should always set this flag when they intend to overwrite the entire surface or locked rectangle.
DDLOCK_DONOTWAIT | On IDirectDrawSurface7 and higher interfaces, the default is DDLOCK_WAIT. If you wish to override the default and use time when the accelerator is busy (as denoted by the DDERR_WASSTILLDRAWING return code) then use this flag.
DDLOCK_EVENT | Set if an event handle is being passed to Lock, which triggers the event when it can return the surface memory pointer requested.
DDLOCK_NOOVERWRITE | Used only with Direct3D vertex buffer locks. Indicates that no vertices that were referred to in IDirect3DDevice7::DrawPrimitiveVB and IDirect3DDevice7::DrawIndexedPrimitiveVB calls (described in the Direct3D SDK documentation) since the start of the frame (or the last lock without this flag) will be modified during the lock. This can be useful when one is only appending data to the vertex buffer.
DDLOCK_NOSYSLOCK Indicates that a system-wide lock should not be taken when this surface is locked. This has several advantages when locking video memory surfaces, such as cursor responsiveness, ability to call more Windows functions, and easier debugging. However, an application specifying this flag must comply with a number of conditions documented in the help file.
This flag cannot be specified when locking the primary.
DDLOCK_OKTOSWAP | Same as DDLOCK_DISCARDCONTENTS.
DDLOCK_READONLY | The surface being locked will only be read from. On Windows 2000 and later, this flag is never set.
DDLOCK_SURFACEMEMORYPTR | The driver should return a valid memory pointer to the top of the rectangle specified in rArea. If no rectangle is specified, the driver should return a pointer to the top of the surface.
DDLOCK_WAIT | Set to indicate that Lock should wait until it can obtain a valid memory pointer before returning. If this bit is set, Lock will never return DDERR_WASSTILLDRAWING.
DDLOCK_WRITEONLY | The surface being locked will only be written to. On Windows 2000 and later, this flag is never set.

fpProcess (Windows 2000 and later only)
Specifies a pointer to a user-mode mapping of the driver's memory. The driver performs this mapping in DdMapMemory.

See Also

DdMapMemory, DdUnlock


DdMapMemory

DdMapMemory maps application-modifiable portions of the frame buffer into the user-mode address space of the specified process, or unmaps memory.

DWORD
  (APIENTRY *PDD_MAPMEMORY)(
    PDD_MAPMEMORYDATA  lpMapMemory
    );

Parameters

lpMapMemory
Points to a DD_MAPMEMORYDATA structure that contains details for the memory mapping or unmapping operation.

Return Value

DdMapMemory returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdMapMemory is called to perform memory mapping before the first call to DdLock. The handle returned by the driver in fpProcess will be passed to every DdLock call made on the driver.

DdMapMemory is also called to unmap memory after the last DdUnLock call is made.

To prevent driver crashes, the driver must not map any portion of the frame buffer that must not be modified by an application.

DD_MAPMEMORYDATA

The DD_MAPMEMORYDATA structure contains the information necessary to perform the mapping or unmapping.

typedef struct _DD_MAPMEMORYDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  BOOL  bMap;
  HANDLE  hProcess;
  FLATPTR  fpProcess;
  HRESULT  ddRVal;
} DD_MAPMEMORYDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that represents the driver.
bMap
Specifies the memory operation that the driver should perform. A value of TRUE indicates that the driver should map memory; FALSE means that the driver should unmap memory.
hProcess
Specifies a handle to the process whose address space is affected.
fpProcess
Specifies the location in which the driver should return the base address of the process's memory-mapped space when bMap is TRUE. When bMap is FALSE, fpProcess contains the base address of the memory to be unmapped by the driver.
ddRVal
Specifies the location in which the driver writes the return value of the DdMapMemory callback. A return code of DD_OK indicates success.


DdMoCompBeginFrame

DdMoCompBeginFrame starts decoding a new frame.

DWORD
  (APIENTRY *PDD_MOCOMPCB_BEGINFRAME)(
    PDD_BEGINMOCOMPFRAMEDATA  lpFrameData
    );

Parameters

lpFrameData
Points to a DD_BEGINMOCOMPFRAMEDATA structure that contains the information needed to start decoding a new frame.

Return Value

DdMoCompBeginFrame returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompBeginFrame.

DirectDraw ensures that begin and end frames will be properly paired.

DD_BEGINMOCOMPFRAMEDATA

The DDHAL_BEGINMOCOMPFRAMEDATA structure contains the frame information required to start decoding.

typedef struct _DD_BEGINMOCOMPFRAMEDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_MOTIONCOMP_LOCAL  lpMoComp;
  PDD_SURFACE_LOCAL  lpDestSurface;
  DWORD  dwInputDataSize;
  LPVOID  lpInputData;
  DWORD  dwOutputDataSize;
  LPVOID  lpOutputData;
  HRESULT  ddRVal;
} DD_BEGINMOCOMPFRAMEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpMoComp
Points to a DD_MOTIONCOMP_LOCAL structure that contains a description of the motion compensation being requested.
lpDestSurface
Points to a DD_SURFACE_LOCAL structure representing the destination surface in which to decode this frame.
dwInputDataSize
Indicates the amount of other optional input data in lpInputData required to begin this frame.
lpInputData
Points to an optional input buffer, the contents of which are defined by the GUID. This buffer cannot contain any embedded pointers.
dwOutputDataSize
Indicates the amount of other optional output data in lpOutputData required to begin this frame.
lpOutputData
Points to an optional output buffer, the contents of which are defined by the GUID. This buffer cannot contain any embedded pointers.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompBeginFrame callback. A return code of DD_OK indicates success.


DdMoCompCreate

DdMoCompCreate notifies the driver that a software decoder will start using motion compensation with the specified GUID.

DWORD
  (APIENTRY *PDD_MOCOMPCB_CREATE)(
    PDD_CREATEMOCOMPDATA  lpCreateData
    );

Parameters

lpCreateData
Points to a DD_CREATEMOCOMPDATA structure that contains the information required to begin using motion compensation.

Return Value

DdMoCompCreate returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdMoCompCreate can be optionally implemented in DirectDraw drivers. It is not required for motion compensation support.

DdMoCompCreate also reports the width, height, and format of the output frame. The driver can fail this call if it cannot support motion compensation with these dimensions.

DD_CREATEMOCOMPDATA

The DD_CREATEMOCOMPDATA structure contains the data required to begin using motion compensation.

typedef struct _DD_CREATEMOCOMPDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_MOTIONCOMP_LOCAL  lpMoComp;
  GUID  *lpGuid;
  DWORD  dwUncompWidth;
  DWORD  dwUncompHeight;
  DDPIXELFORMAT  ddUncompPixelFormat;
  LPVOID  lpData;
  DWORD  dwDataSize;
  HRESULT  ddRVal;
} DD_CREATEMOCOMPDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpMoComp
Points to a DD_MOTIONCOMP_LOCAL structure that contains a description of the motion compensation object.
lpGuid
Points to a GUID that describes the motion compensation process being used.
dwUncompWidth
Specifies the width of the uncompressed output frame.
dwUncompHeight
Specifies the height of the uncompressed output frame.
ddUncompPixelFormat
Points to a DDPIXELFORMAT structure that contains the format of the uncompressed output frame.
lpData
Points to an optional data buffer that contains any optional information required by the GUID given in lpGuid. This buffer cannot contain any embedded pointers.
dwDataSize
Indicates the size of the data buffer contained in lpData.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompCreate callback. A return code of DD_OK indicates success.


DdMoCompDestroy

DdMoCompDestroy notifies the driver that this motion compensation object will no longer be used. The driver now needs to perform any necessary cleanup.

DWORD
  (APIENTRY *PDD_MOCOMPCB_DESTROY)(
    PDD_DESTROYMOCOMPDATA  lpDestroyData
    );

Parameters

lpDestroyData
Points to a DD_DESTROYMOCOMPDATA structure that contains the information needed to finish motion compensation.

Return Value

DdMoCompDestroy returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdMoCompDestroy can be optionally implemented in DirectDraw drivers. It is not required for motion compensation support.

DD_DESTROYMOCOMPDATA

The DD_DESTROYMOCOMPDATA structure contains the information required to finish performing motion compensation.

typedef struct _DD_DESTROYMOCOMPDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_MOTIONCOMP_LOCAL  lpMoComp;
  HRESULT  ddRVal;
} DD_DESTROYMOCOMPDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpMoComp
Points to a DD_MOTIONCOMP_LOCAL structure that contains a description of the motion compensation being requested.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompDestroy callback. A return code of DD_OK indicates success.


DdMoCompEndFrame

DdMoCompEndFrame completes a decoded frame.

DWORD
  (APIENTRY *PDD_MOCOMPCB_ENDFRAME)(
    PDD_ENDMOCOMPFRAMEDATA  lpFrameData
    );

Parameters

lpFrameData
Points to a DD_ENDMOCOMPFRAMEDATA structure that contains the information needed to complete the decoded frame.

Return Value

DdMoCompEndFrame returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompEndFrame.

DirectDraw ensures that begin and end frames will be properly paired.

DD_ENDMOCOMPFRAMEDATA

The DD_ENDMOCOMPFRAMEDATA structure contains information required to complete a decoded frame.

typedef struct _DD_ENDMOCOMPFRAMEDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_MOTIONCOMP_LOCAL  lpMoComp;
  LPVOID  lpInputData;
  DWORD  dwInputDataSize;
  HRESULT  ddRVal;
} DD_ENDMOCOMPFRAMEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpMoComp
Points to a DD_MOTIONCOMP_LOCAL structure that contains a description of the motion compensation being requested.
lpInputData
Points to an optional buffer, the contents of which are defined by the GUID. This buffer cannot contain any embedded pointers.
dwInputDataSize
Indicates the amount of data in lpInputData.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompEndFrame callback. A return code of DD_OK indicates success.


DdMoCompGetBuffInfo

DDMoCompGetBufferInfo allows the driver to specify how many interim surfaces are required to support the specified GUID, and the size, location, and format of each of these surfaces.

DWORD
  (APIENTRY *PDD_MOCOMPCB_GETCOMPBUFFINFO)(
    PDD_GETMOCOMPCOMPBUFFDATA  lpBufferData
    );

Parameters

lpBufferData
Points to a DD_GETMOCOMPCOMPBUFFDATA structure that contains the compressed buffer information.

Return Value

DdMoCompGetBufferInfo returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdMoCompGetBufferInfo can be optionally implemented in DirectDraw drivers. This function is required for motion compensation support.

DD_GETMOCOMPCOMPBUFFDATA

The DD_GETMOCOMPCOMPBUFFDATA structure contains the compressed buffer information.

typedef struct _DD_GETMOCOMPCOMPBUFFDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  GUID  *lpGuid;
  DWORD  dwWidth;
  DWORD  dwHeight;
  DDPIXELFORMAT  ddPixelFormat;
  DWORD  dwNumTypesCompBuffs;
  LPDDCOMPBUFFERINFO  lpCompBuffInfo;
  HRESULT  ddRVal;
} DD_GETMOCOMPCOMPBUFFDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpGuid
Points to a GUID for which the compressed buffer information is requested.
dwWidth
Indicates the width of the uncompressed output frame.
dwHeight
Indicates the height of the uncompressed output frame.
ddPixelFormat
Points to a DDPIXELFORMAT structure that contains the pixel format of the uncompressed output frame.
dwNumTypesCompBuffs
Indicates how many different types of surfaces the driver requires to perform motion compensation using the requested GUID.
lpCompBuffInfo
Points to a DDCOMPBUFFERINFO structure that contains the driver-supplied information for each type of required surface.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompGetBufferInfo callback. A return code of DD_OK indicates success.


DdMoCompGetFormats

DdMoCompGetFormats indicates the uncompressed formats to which the hardware can decode the data.

DWORD
  (APIENTRY *PDD_MOCOMPCB_GETFORMATS)(
    PDD_GETMOCOMPFORMATSDATA  lpGetFormatData
    );

Parameters

lpGetFormatData
Points to a DD_GETMOCOMPFORMATSDATA structure that contains the uncompressed format information for the hardware.

Return Value

DdMoCompGetFormats returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompGetFormats.

DD_GETMOCOMPFORMATSDATA

The DD_GETMOCOMPFORMATSDATA structure contains the uncompressed format information.

typedef struct _DD_GETMOCOMPFORMATSDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  GUID  *lpGuid;
  DWORD  dwNumFormats;
  LPDDPIXELFORMAT  lpFormats;
  HRESULT  ddRVal;
} DD_GETMOCOMPFORMATSDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpGuid
Points to a GUID that describes the uncompressed formats being requested.
dwNumFormats
Indicates the number of uncompressed formats supported for the specified GUID.
lpFormats
Points to a DDPIXELFORMAT structure that contains the motion compensation pixel format. If this member is not NULL, the uncompressed formats are copied into the buffer pointed to by this member.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompGetFormats callback. A return code of DD_OK indicates success.


DdMoCompGetGuids

DdMoCompGetGuids retrieves the number of GUIDs the driver supports.

DWORD
  (APIENTRY *PDD_MOCOMPCB_GETGUIDS)(
    PDD_GETMOCOMPGUIDSDATA  lpGetGuidData
    );

Parameters

lpGetGuidData
Points to a DD_GETMOCOMPGUIDSDATA structure that contains the GUID information.

Return Value

DdMoCompGetGuids returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompGetGuids.

DD_GETMOCOMPGUIDSDATA

The DD_GETMOCOMPGUIDSDATA structure contains the motion compensation GUID information.

typedef struct _DD_GETMOCOMPGUIDSDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  DWORD  dwNumGuids;
  GUID  *lpGuids;
  HRESULT  ddRVal;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
dwNumGuids
Indicates the number of motion compensation GUIDs in lpGuids.
lpGuids
Points to a list of GUIDs that describe the motion compensation processes being used. If lpGuids is NULL, the driver should set dwNumGuids to the number of GUIDs that it supports. Otherwise, it should fill lpGuids with the GUIDs that it supports and set the number in dwNumGuids.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompGetGuids callback. A return code of DD_OK indicates success.


DdMoCompGetInternalInfo

DdMoCompGetInternalInfo allows the driver to report that it internally allocates display memory to perform motion compensation.

DWORD
  (APIENTRY *PDD_MOCOMPCB_GETINTERNALINFO)(
    PDD_GETINTERNALMOCOMPDATA  lpInternalData
    );

Parameters

lpInternalData

Points to a DD_GETINTERNALMOCOMPDATA structure that contains the internal memory requirements.

Return Value

DdMoCompGetInternalInfo returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompGetInternalInfo.

This function allows the decoder and DirectShow® to make better-informed decisions regarding what GUID to choose.

DD_GETINTERNALMOCOMPDATA

The DD_GETINTERNALMOCOMPDATA structure contains the internal memory requirements.

typedef struct _DD_GETINTERNALMOCOMPDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  GUID  *lpGuid;
  DWORD  dwWidth;
  DWORD  dwHeight;
  DDPIXELFORMAT  ddPixelFormat;
  DWORD  dwScratchMemAlloc;//..out
  HRESULT  ddRVal;
} DD_GETINTERNALMOCOMPDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpGuid
Points to a GUID for which the internal memory requirement is requested.
dwWidth
Indicates the width of uncompressed output frame.
dwHeight
Indicates the height of uncompressed output frame.
ddPixelFormat
Points to a DDPIXELFORMAT structure that contains the pixel format of the uncompressed output frame.
dwScratchMemAlloc
Indicates the amount of internal memory the display driver will privately reserve to perform motion compensation
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompGetInternalInfo callback. A return code of DD_OK indicates success.


DdMoCompQueryStatus

DdMoCompQuerytatus queries the status of the most recent rendering operation to the specified surface.

DWORD
  (APIENTRY *PDD_MOCOMPCB_QUERYSTATUS)(
    PDD_QUERYMOCOMPSTATUSDATA  lpStatusData
    );

Parameters

lpStatusData
Points to a DD_QUERYMOCOMPSTATUSDATA structure that contains the information needed to query the status.

Return Value

DdMoCompQueryStatus returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompQueryStatus.

DD_QUERYMOCOMPSTATUSDATA

The DD_QUERYMOCOMPSTATUSDATA structure contains information required to query the status of the previous frame.

typedef struct _DD_QUERYMOCOMPSTATUSDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_MOTIONCOMP_LOCAL  lpMoComp;
  PDD_SURFACE_LOCAL  lpSurface;
  DWORD  dwFlags;
  HRESULT  ddRVal;
} DD_QUERYMOCOMPSTATUSDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpMoComp
Points to a DD_MOTIONCOMP_LOCAL structure that contains a description of the motion compensation being requested.
lpSurface
Points to a DD_SURFACE_LOCAL structure that contains the surface being queried.
dwFlags
Indicates the type of surface access.
DDMCQUERY_READ
Indicates that the surface can only be tested for read or display access. If this flag is not set, the surface can be tested for write access.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompQueryStatus callback. A return code of DD_OK indicates the hardware has finished processing the DdMoCompRender request. Otherwise the return value must be DDERR_WASSTILLDRAWING.


DdMoCompRender

DdMoCompRender tells the driver what macroblocks to render by specifying the surfaces containing the macroblocks, the offsets in each surface where the macroblocks exist, and the size of the macroblock data to be rendered.

DWORD
  (APIENTRY *PDD_MOCOMPCB_RENDER)(
    PDD_RENDERMOCOMPDATA  lpRenderData
    );

Parameters

lpRenderData
Points to a DD_RENDERMOCOMPDATA structure that contains the information needed to render a frame.

Return Value

DdMoCompRender returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support motion compensation must implement DdMoCompRender.

DdMoCompRender can be called multiple times between the DdMoCompBeginFrame and DdMoCompEndFrame sequence.

If a previous render operation is not yet finished, the driver should set the DirectDraw return code to DDERR_WASSTILLDRAWING.

DD_RENDERMOCOMPDATA

The DD_RENDERMOCOMPDATA structure contains the information required to render a frame.

typedef struct _DD_RENDERMOCOMPDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_MOTIONCOMP_LOCAL  lpMoComp;
  DWORD  dwNumBuffers;
  LPDDMOCOMPBUFFERINFO  lpBufferInfo;
  DWORD  dwFunction;
  LPVOID  lpInputData;
  DWORD  dwInputDataSize;
  LPVOID  lpOutputData;
  DWORD  dwOutputDataSize;
  HRESULT  ddRVal;
} DD_RENDERMOCOMPDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpMoComp
Points to a DD_MOTIONCOMP_LOCAL structure that contains a description of the motion compensation being requested.
dwNumBuffers
Indicates the number of entries in the lpBufferInfo member.
lpBufferInfo
Points to a DDMOCOMPBUFFERINFO structure that contains the surfaces and the locations within the surfaces from which to get the macroblock data to render.
dwFunction
Indicates a specific operation the decoder would like the driver to perform. The possible values for this member are defined by the GUID used.
lpInputData
Points to an optional input buffer, the contents of which are defined by the GUID. This buffer cannot contain any embedded pointers.
dwInputDataSize
Specifies the size of the data pointed to by lpInputData.
lpOutputData
Points to an optional output buffer, the contents of which are defined by the GUID. This buffer cannot contain any embedded pointers.
dwOutputDataSize
Specifies the size of the data pointed to by lpOutputData.
ddRVal
Specifies the location in which the driver writes the return value of the DdMoCompRender callback. A return code of DD_OK indicates success.


DdSetClipList

DdSetClipList is obsolete.

DWORD
  (APIENTRY *PDD_SURFCB_SETCLIPLIST)(
    PDD_SETCLIPLISTDATA  lpSetClipList
    );


DdSetColorKey

DdSetColorKey sets the color key value for the specified surface.

DWORD
  (APIENTRY *PDD_SURFCB_SETCOLORKEY)(
    PDD_SETCOLORKEYDATA  lpSetColorKey
    );

Parameters

lpSetColorKey
Points to a DD_SETCOLORKEYDATA structure that contains the information required to set the color key for the specified surface.

Return Value

DdSetColorKey returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DDHAL_DRIVER_NOCKEYHW

Comments

DdSetColorKey sets the source or destination color key for the specified surface. Typically, this callback is implemented only for drivers that support overlays with color key capabilities.

DD_SETCOLORKEYDATA

The DD_SETCOLORKEYDATA structure contains information necessary to set the color key value for the specified surface.

typedef struct _DD_SETCOLORKEYDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  DWORD  dwFlags;
  DDCOLORKEY  ckNew;
  HRESULT  ddRVal;
  VOID  *SetColorKey;
} DD_SETCOLORKEYDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to the DD_SURFACE_LOCAL structure that describes the surface with which the color key is to be associated.
dwFlags
Specifies which color key is being requested. This member is a bit-wise OR of any of the following values:
Value | Meaning
DDCKEY_COLORSPACE | The DDCOLORKEY structure contains a color space. If this bit is not set, the structure contains a single color key.
DDCKEY_DESTBLT | The DDCOLORKEY structure specifies a color key or color space to be used as a destination color key for blt operations.
DDCKEY_DESTOVERLAY | The DDCOLORKEY structure specifies a color key or color space to be used as a destination color key for overlay operations.
DDCKEY_SRCBLT | The DDCOLORKEY structure specifies a color key or color space to be used as a source color key for blit operations.
DDCKEY_SRCOVERLAY | The DDCOLORKEY structure specifies a color key or color space to be used as a source color key for overlay operations

ckNew
Specifies a DDCOLORKEY structure that specifies the new color key values for the DirectDrawSurface object.
ddRVal
Specifies the location in which the driver writes the return value of the DdSetColorKey callback. A return code of DD_OK indicates success.
SetColorKey
This is not used on Windows 2000 and later.


DdSetEntries

DdSetEntries updates the palette entries in the specified palette.

DWORD
  (APIENTRY *PDD_PALCB_SETENTRIES)(
    PDD_SETENTRIESDATA  lpSetEntries
    );

Parameters

lpSetEntries
Points to a DD_SETENTRIESDATA structure that contains the information required to set the palette's entries.

Return Value

DdSetEntries returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DD_SETENTRIESDATA

The DD_SETENTRIESDATA structure contains information necessary to set palette entries.

typedef struct _DD_SETENTRIESDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_PALETTE_GLOBAL  lpDDPalette;
  DWORD  dwBase;
  DWORD  dwNumEntries;
  LPPALETTEENTRY  lpEntries;
  HRESULT  ddRVal;
  VOID  *SetEntries;
} DD_SETENTRIESDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDPalette
Points to a DD_PALETTE_GLOBAL structure that represents the DirectDrawPalette object.
dwBase
Specifies an index into the color table of the first entry to be modified.
dwNumEntries

Specifies the number of palette entries that the driver should update.

lpEntries
Points to a PALETTEENTRY structure that specifies the color table.
ddRVal
Passes the DirectDraw return values.
SetEntries
Is used by the DirectDraw API and should not be filled in by the driver.


DdSetExclusiveMode

DdSetExclusiveMode notifies the driver when a DirectDraw application is switching to or from exclusive mode.

DWORD
  (APIENTRY *PDD_SETEXCLUSIVEMODE)(
    PDD_SETEXCLUSIVEMODEDATA  lpSetExclusiveMode
    );

Parameters

lpSetExclusiveMode
Points to a DD_SETEXCLUSIVEMODEDATA structure that contains the notification information.

Return Value

DdSetExclusiveMode returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdSetExclusiveMode can be optionally implemented in display drivers. Drivers for hardware that needs to be partially enabled and/or disabled to support exclusive mode should implement this function.

DirectDraw applications can go fullscreen and take total control of the primary surface. Specifically, the application is responsible for operations such as DirectDraw mode changes and primary surface flipping when in exclusive mode.

DD_SETEXCLUSIVEMODEDATA

The DD_SETEXCLUSIVEMODEDATA structure contains the exclusive mode notification information.

typedef struct _DD_SETEXCLUSIVEMODEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  DWORD  dwEnterExcl;
  DWORD  dwReserved;
  HRESULT  ddRVal;
  VOID  *SetExclusiveMode;
} DD_SETEXCLUSIVEMODEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
dwEnterExcl
Indicates that a DirectDraw application is switching into exclusive mode when TRUE; indicates that a DirectDraw application is leaving exclusive mode when FALSE.
dwReserved
This is reserved for system use and should be ignored by the driver.
ddRVal
Specifies the location in which the driver writes the return value of the DdSetExclusiveMode callback. A return code of DD_OK indicates success.
SetExclusiveMode
Is used by the DirectDraw API and should not be filled in by the driver.


DdSetOverlayPosition

DdSetOverlayPosition sets the position for an overlay.

DWORD
  (APIENTRY *PDD_SURFCB_SETOVERLAYPOSITION)(
    PDD_SETOVERLAYPOSITIONDATA  lpSetOverlayPosition
    );

Parameters

lpSetOverlayPosition
Points to a DD_SETOVERLAYPOSITIONDATA structure that contains the information required to set the overlay position.

Return Value

DdSetOverlayPosition returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

When the overlay is visible, the driver should cause the overlay to be displayed on the primary surface. The upper left corner of the overlay should be anchored at (lXPos,lYPos). For example, values of (0,0) indicates that the upper left corner of the overlay should appear in the upper left corner of the surface identified by lpDDDestSurface.

When the overlay is invisible, the driver should set DDHAL_DRIVER_HANDLED in ddRVal and return.

DD_SETOVERLAYPOSITIONDATA

The DD_SETOVERLAYPOSITIONDATA structure contains information necessary to change the display coordinates of an overlay surface.

typedef struct _DD_SETOVERLAYPOSITIONDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSrcSurface;
  PDD_SURFACE_LOCAL  lpDDDestSurface;
  LONG  lXPos;
  LONG  lYPos;
  HRESULT  ddRVal;
  VOID  *SetOverlayPosition;
} DD_SETOVERLAYPOSITIONDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSrcSurface
Points to a DD_SURFACE_LOCAL structure that represents the DirectDraw overlay surface.
lpDDDestSurface
Points to a DD_SURFACE_LOCAL structure representing the surface that is being overlaid.
lXPos
Specifies the x coordinate of the upper left corner of the overlay, in pixels.
lYPos
Specifies the y coordinate of the upper left corner of the overlay, in pixels.
ddRVal
Specifies the location in which the driver writes the return value of the DdSetOverlayPosition callback. A return code of DD_OK indicates success.
SetOverlayPosition
Is used by the DirectDraw API and should not be filled in by the driver.


DdSetPalette

DdSetPalette attaches a palette to the specified surface.

DWORD
  (APIENTRY *PDD_SURFCB_SETPALETTE)(
    PDD_SETPALETTEDATA  lpSetPalette
    );

Parameters

lpSetPalette
Points to a DD_SETPALETTEDATA structure that contains the information required to set a palette to the specified surface.

Return Value

DdSetPalette returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DD_SETPALETTEDATA

The DD_SETPALETTEDATA structure contains information necessary to set a palette for a specific surface.

typedef struct _DD_SETPALETTEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  PDD_PALETTE_GLOBAL  lpDDPalette;
  HRESULT  ddRVal;
  VOID  *SetPalette;
  BOOL  Attach;
} DD_SETPALETTEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that represents the DirectDraw object.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that represents the DirectDrawSurface object.
lpDDPalette
Points to a DD_PALETTE_GLOBAL structure that specifies the palette to set to the surface.
ddRVal
Specifies the location in which the driver writes the return value of the DdSetPalette callback. A return code of DD_OK indicates success.
SetPalette
Is used by the DirectDraw API and should not be filled in by the driver.
Attach
Indicates whether to attach this palette to the surface.


DdSyncSurfaceData

DdSyncSurfaceData sets and modifies surface data before it is passed to the miniport.

DWORD
  (APIENTRY *PDD_KERNELCB_SYNCSURFACE)(
    PDD_SYNCSURFACEDATA  lpSyncSurface
    );

Parameters

lpSyncSurface
Points to a DD_SYNCSURFACEDATA structure that contains the surface data.

Return Value

DdSyncSurfaceData returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DD_SYNCSURFACEDATA

The DD_SYNCSURFACEDATA structure contains the surface information.

typedef struct _DD_SYNCSURFACEDATA {
  DWORD  dwSize;              // Windows 98/Me only
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  DWORD  dwSurfaceOffset;
  ULONG_PTR  fpLockPtr;
  LONG  lPitch;
  DWORD  dwOverlayOffset;
  DWORD  dwOverlaySrcWidth;   // Windows 98/Me only
  DWORD  dwOverlaySrcHeight;  // Windows 98/Me only
  DWORD  dwOverlayDestWidth;  // Windows 98/Me only
  DWORD  dwOverlayDestHeight; // Windows 98/Me only
  ULONG  dwDriverReserved1;
  ULONG  dwDriverReserved2;
  ULONG  dwDriverReserved3;
  ULONG  dwDriverReserved4;   // Windows 2000 and later
  HRESULT  ddRVal;
} DD_SYNCSURFACEDATA;

Members

dwSize (Windows 98/Me only)
Specifies the size of this structure. This member must be initialized before the structure is used.
lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpDDSurface
Points to the DD_SURFACE_LOCAL structure that describes the surface with which to sync.
dwSurfaceOffset
Contains the byte offset from the start of the frame buffer to the start of the surface. This value is used only by the miniport. This member must contain data that is filled in by the driver.
fpLockPtr
Contains the pointer value to be returned by the DdLock call for accessing the surface. This value is used by a kernel-mode client. This member can be modified by the driver, but does not need to be.
lPitch
Contains the pitch passed to the client during a DdLock call. This member can be modified by the driver, but does not need to be.
dwOverlayOffset
Contains the byte offset from the start of the frame buffer to the start of the overlay. This value is used only by the miniport and may be different than the dwSurfaceOffset member if cropping is involved or if the overlay origin is not the top left of the surface. This member must contain data that is filled in by the driver.
dwOverlaySrcWidth (Windows 98/Me only)
Specifies the source width of the overlay. This value is used only by the miniport. This member can be modified by the driver, but does not need to be.
dwOverlaySrcHeight (Windows 98/Me only)
Specifies the source height of the overlay. This value is used only by the miniport. This member can be modified by the driver, but does not need to be.
dwOverlayDestWidth (Windows 98/Me only)
Specifies the destination width of the overlay. This value is used only by the miniport. This member can be modified by the driver, but does not need to be.
dwOverlayDestHeight (Windows 98/Me only)
Specifies the destination height of the overlay. This value is used only by the miniport. This member can be modified by the driver, but does not need to be.
dwDriverReserved1
Is reserved for use by the display driver.
dwDriverReserved2
Is reserved for use by the display driver.
dwDriverReserved3
Is reserved for use by the display driver.
dwDriverReserved4 (Windows 2000 and later only)
Is reserved for use by the display driver.
ddRVal
Specifies the location in which the driver writes the return value of the DdSyncSurfaceData callback. A return code of DD_OK indicates success.


DdSyncVideoPortData

DdSyncVideoPortData sets and modifies VPE object data before it is passed to the miniport.

DWORD
  (APIENTRY *PDD_KERNELCB_SYNCVIDEOPORT)(
    PDD_SYNCVIDEOPORTDATA  lpSyncVideoPort
    );

Parameters

lpSyncVideoPort
Points to a DD_SYNCVIDEOPORTDATA structure that contains the VPE object data.

Return Value

DdSyncVideoPortData returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

DD_SYNCVIDEOPORTDATA

The DD_SYNCVIDEOPORTDATA structure contains the VPE object information.

typedef struct _DD_SYNCVIDEOPORTDATA {
  DWORD  dwSize; // Windows 98/Me only
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwOriginOffset;
  DWORD  dwHeight;
  DWORD  dwVBIHeight;
  ULONG  dwDriverReserved1;
  ULONG  dwDriverReserved2;
  ULONG  dwDriverReserved3;
  HRESULT  ddRVal;
} DD_SYNCVIDEOPORTDATA;

Members

dwSize (Windows 98/Me only)
Specifies the size of this structure. This member must be initialized before the structure is used.
lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that that describes the hardware video port with which to sync.
dwOriginOffset
Contains the byte offset from the top left corner of the surface to the top left corner of where the VPE object writes its data. This value is only used by the miniport. This member must contain data that is filled in by the driver.
dwHeight
Contains the height of the VPE object data. By default, this is twice the field height when interleaved, but the driver can change this if it needs to. This value is used only by the miniport. This member can be modified by the driver, but does not need to be.
dwVBIHeight
Contains the number of lines in the VBI region. This value is used only by the miniport. This member can be modified by the driver, but does not need to be.
dwDriverReserved1, dwDriverReserved2, dwDriverReserved3
Are reserved for use by the display driver.
ddRVal
Specifies the location in which the driver writes the return value of the DdSyncVideoPortData callback. A return code of DD_OK indicates success.


DdUnlock

DdUnLock releases the lock held on the specified surface.

DWORD
  (APIENTRY *PDD_SURFCB_UNLOCK)(
    PDD_UNLOCKDATA  lpUnlock
    );

Parameters

lpUnlock
Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release.

Return Value

DdUnlock returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

The driver does not need to verify that the memory was previously locked down by DdLock, because DirectDraw does parameter validation before calling this routine.

DD_UNLOCKDATA

The DD_UNLOCKDATA structure contains information necessary to do an unlock as defined by DirectDraw parameter structures.

typedef struct _DD_UNLOCKDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  HRESULT  ddRVal;
  VOID  *Unlock;
} DD_UNLOCKDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the DirectDraw API.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that describes the surface to be unlocked.
ddRVal
Specifies the location in which the driver writes the return value of the DdUnlock callback. A return code of DD_OK indicates success.
Unlock
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DdLock


DdUpdateOverlay

DdUpdateOverlay repositions or modifies the visual attributes of an overlay surface.

DWORD
  (APIENTRY *PDD_SURFCB_UPDATEOVERLAY)(
    PDD_UPDATEOVERLAYDATA  lpUpdateOverlay
    );

Parameters

lpUpdateOverlay
Points to a DD_UPDATEOVERLAYDATA structure that contains the information required to update the overlay.

Return Value

DdUpdateOverlay returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdUpdateOverlay shows, hides, or repositions an overlay surface on the screen. It also sets attributes of the overlay surface, such as the stretch factor or type of color key to be used.

The driver should determine whether it has the bandwidth to support the overlay update request. The driver should use dwFlags to determine the type of request and how to process it.

The driver/hardware must stretch or shrink the overlay accordingly when the rectangles specified by rDest and rSrc are different sizes.

Note that DdFlip is used for flipping between overlay surfaces, so performance for DdUpdateOverlay is not critical.

DD_UPDATEOVERLAYDATA

The DD_UPDATEOVERLAYDATA structure contains information necessary for updating an overlay surface.

typedef struct _DD_UPDATEOVERLAYDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDDestSurface;
  RECTL  rDest;
  PDD_SURFACE_LOCAL  lpDDSrcSurface;
  RECTL  rSrc;
  DWORD  dwFlags;
  DDOVERLAYFX  overlayFX;
  HRESULT  ddRVal;
  VOID  *UpdateOverlay;
} DD_UPDATEOVERLAYDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that represents the DirectDraw object.
lpDDDestSurface
Points to a DD_SURFACE_LOCAL structure that represents the DirectDraw surface to be overlaid. This value can be NULL if DDOVER_HIDE is specified in dwFlags.
rDest
Specifies a RECTL structure that contains the x, y, width, and height of the region on the destination surface to be overlaid.
lpDDSrcSurface
Points to a DD_SURFACE_LOCAL structure that describes the overlay surface.
rSrc
Specifies a RECTL structure that contains the x, y, width, and height of the region on the source surface to be used for the overlay.
dwFlags
Specifies how the driver should handle the overlay. This member can be a combination of any of the following flags:
Flag | Meaning
DDOVER_ADDDIRTYRECT | Should be ignored by the driver.
DDOVER_AUTOFLIP | The driver should autoflip the overlay whenever the hardware video port autoflips. Drivers that support VPE need only check this flag.
DDOVER_BOB | The driver should display each field of VPE object data individually without causing any jittery artifacts. This flag pertains to both VPE and decoders that want to do their own flipping in kernel mode using the kernel-mode video transport functionality.
DDOVER_BOBHARDWARE | Indicates that bob will be performed by hardware rather than by software or emulation. Drivers that support VPE need only check this flag.
DDOVER_DDFX | The driver should show the overlay surface using the attributes specified by the overlayFX member.
DDOVER_HIDE | The driver should hide the overlay; that is, the driver should turn this overlay off.
DDOVER_INTERLEAVED | The overlay surface is composed of interleaved fields. Drivers that support VPE need only check this flag.
DDOVER_KEYDEST | The driver should use the color key associated with the destination surface.
DDOVER_KEYDESTOVERRIDE | The driver should use the dckDestColorKey member of the DDOVERLAYFX structure (described in the DirectDraw SDK documentation) as the destination color key instead of the color key associated with the destination surface.
DDOVER_KEYSRC | The driver should use the color key associated with the destination surface.
DDOVER_KEYSRCOVERRIDE | The driver should use the dckSrcColorKey member of the DDOVERLAYFX structure (described in the DirectDraw SDK documentation) as the source color key instead of the color key associated with the destination surface.
DDOVER_OVERRIDEBOBWEAVE | Bob/weave decisions should not be overridden by other interfaces. If the overlay mixer sets this flag, DirectDraw will not allow a kernel-mode driver to use the kernel-mode video transport functionality to switch the hardware between bob and weave mode.
DDOVER_REFRESHALL | Should be ignored by the driver.
DDOVER_REFRESHDIRTYRECTS | Should be ignored by the driver.
DDOVER_SHOW | The driver should show the overlay; that is, the driver should turn this overlay on.

overlayFX
Specifies a DDOVERLAYFX structure (described in the DirectDraw SDK documentation) that describes additional effects that the driver should use to update the overlay. The driver should use this structure only if one of DDOVER_DDFX, DDOVER_KEYDESTOVERRIDE, or DDOVER_KEYSRCOVERRIDE are set in the dwFlags member.
ddRVal
Specifies the location in which the driver writes the return value of the DdUpdateOverlay callback. A return code of DD_OK indicates success.
UpdateOverlay
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DdSetColorKey, DdSetOverlayPosition


DdVideoPortCanCreate

The DdVideoPortCanCreate callback determines whether the driver can support a DirectDraw VPE object of the specified description.

DWORD
  (APIENTRY *PDD_VPORTCB_CANCREATEVIDEOPORT)(
    PDD_CANCREATEVPORTDATA  lpCanCreateVideoPort
    );

Parameters

lpCanCreateVideoPort
Points to a DD_CANCREATEVPORTDATA structure that contains the information necessary for the driver to determine whether the specified DirectDraw VPE object can be supported.

Return Value

DdVideoPortCanCreate returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortCanCreate must be implemented in drivers that support VPE.

The driver should check the members of the DDVIDEOPORTDESC structure to which lpDDVideoPortDesc points to determine whether the hardware supports the specified type of VPE object.

DD_CANCREATEVPORTDATA

The DD_CANCREATEVPORTDATA structure contains the information required for the driver to determine whether a VPE object can be created.

typedef struct _DD_CANCREATEVPORTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  LPDDVIDEOPORTDESC  lpDDVideoPortDesc;
  HRESULT  ddRVal;
  VOID  *CanCreateVideoPort;
} DD_CANCREATEVPORTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpDDVideoPortDesc
Points to a DDVIDEOPORTDESC structure that contains a description of the VPE object being requested.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortCanCreate callback. A return code of DD_OK indicates success.
CanCreateVideoPort
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DdVideoPortCreate


DdVideoPortCreate

DdVideoPortCreate notifies the driver that DirectDraw has created a VPE object.

DWORD
  (APIENTRY *PDD_VPORTCB_CREATEVIDEOPORT)(
    PDD_CREATEVPORTDATA  lpCreateVideoPort
    );

Parameters

lpCreateVideoPort
Points to a DD_CREATEVPORTDATA structure that describes the created VPE object.

Return Value

DdVideoPortCreate returns one of the following values:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortCreate can be optionally implemented in DirectDraw drivers that support VPE.

DdVideoPortCreate can allocate memory for and initialize any private, VPE object-specific data. The driver can use the dwReserved1 and dwReserved2 members of the DD_VIDEOPORT_LOCAL structure to store this data. The driver cannot use or change any other members of the DD_VIDEOPORT_LOCAL structure.

If the hardware video port is implemented to use the feature connector, the driver might need to initialize the feature connector for hardware video port use.

DdVideoPortCreate should not turn the hardware video port on. This is accomplished in DdVideoPortUpdate.

DD_CREATEVPORTDATA

The DD_CREATEVPORTDATA structure contains the information necessary to describe the VPE object being created.

typedef struct _DD_CREATEVPORTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  LPDDVIDEOPORTDESC  lpDDVideoPortDesc;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  HRESULT  ddRVal;
  VOID  *CreateVideoPort;
} DD_CREATEVPORTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpDDVideoPortDesc
Points to a DDVIDEOPORTDESC structure that describes the created VPE object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents the created VPE object.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortCreate callback. A return code of DD_OK indicates success.
CreateVideoPort
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortDestroy

DdVideoPortDestroy notifies the driver that DirectDraw has destroyed the specified VPE object.

DWORD
  (APIENTRY *PDD_VPORTCB_DESTROYVPORT)(
    PDD_DESTROYVPORTDATA  lpDestroyVideoPort
    );

Parameters

lpDestroyVideoPort
Points to a DD_DESTROYVPORTDATA structure that contains the information required for the driver to clean up.

Return Value

DdVideoPortDestroy returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortDestroy can be optionally implemented in DirectDraw drivers that support VPE.

The driver should free any memory that it allocated and associated with the specified VPE object. This includes freeing any driver-allocated memory accessed through the dwReserved1 and dwReserved2 members of the DD_VIDEOPORT_LOCAL structure.

DD_DESTROYVPORTDATA

The DD_DESTROYVPORTDATA structure contains the information necessary for the driver to clean up.

typedef struct _DD_DESTROYVPORTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  HRESULT  ddRVal;
  VOID  *DestroyVideoPort;
} DD_DESTROYVPORTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortDestroy callback. A return code of DD_OK indicates success.
DestroyVideoPort
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DdVideoPortCreate


DdVideoPortFlip

DdVideoPortFlip performs a physical flip, causing the VPE object to start writing data to the new surface.

DWORD
  (APIENTRY *PDD_VPORTCB_FLIP)(
    PDD_FLIPVPORTDATA  lpFlipVideoPort
    );

Parameters

lpFlipVideoPort
Points to a DD_FLIPVPORTDATA structure that contains the information required for the driver to perform the flip.

Return Value

DdVideoPortFlip returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortFlip must be implemented in DirectDraw drivers that support VPE.

The driver should update its surface pointers so that the next frame of video will be written to the surface to which lpSurfTarg points. If a previous flip request is still pending, the driver should fail the call and return DDERR_WASSTILLDRAWING. DdVideoPortFlip does not affect the actual display of the video data.

A call to DdVideoPortFlip typically accompanies a call to DdFlip when an application is performing video streaming.

DD_FLIPVPORTDATA

The DD_FLIPVPORTDATA structure contains the information necessary for the VPE object to perform a flip.

typedef struct _DD_FLIPVPORTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  PDD_SURFACE_LOCAL  lpSurfCurr;
  PDD_SURFACE_LOCAL  lpSurfTarg;
  HRESULT  ddRVal;
  VOID  *FlipVideoPort;
} DD_FLIPVPORTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
lpSurfCurr
Points to the current surface; that is, the surface on which data is currently being written.
lpSurfTarg
Points to the target surface; that is, the surface to which the driver should flip.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortFlip callback. A return code of DD_OK indicates success.
FlipVideoPort
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetBandwidth

DdVideoPortGetBandwidth reports the bandwidth limitations of the device's frame buffer memory based the specified VPE object output format.

DWORD
  (APIENTRY *PDD_VPORTCB_GETBANDWIDTH)(
    PDD_GETVPORTBANDWIDTHDATA  lpGetVideoPortBandwidth
    );

Parameters

lpGetVideoPortBandwidth
Points to a DD_GETVPORTBANDWIDTHDATA structure that contains the information required for the driver to return the bandwidth data.

Return Value

DdVideoPortGetBandwidth returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortGetBandwidth must be implemented in DirectDraw drivers that support VPE.

DdVideoPortGetBandwidth informs clients of bandwidth requirements for any specified format, helping them to choose a format and better understand its limitations. The driver can supply accurate bandwidth information only after the VPE object has been created because the driver needs the information in the DDVIDEOPORTDESC structure.

DdVideoPortGetBandwidth is typically called twice to obtain the bandwidth parameters of the specified hardware video port. Depending on the dwFlags member of the DD_GETVPORTBANDWIDTHDATA structure, the driver should do the following:

  • When the flag is DDVPB_TYPE, the driver should indicate the type of device it is by setting one of the following flags in the dwCaps member of the DDVIDEOPORTBANDWIDTH structure to which lpBandwidth points:
    • DDVPBCAPS_DESTINATION indicates that the device will describe its bandwidth capabilities in terms of the overlay stretch factor; that is, that the bandwidth information returned by the driver in the next call to DdVideoPortGetBandwidth will refer to the size of the destination overlay. This flag best describes hardware that refreshes from both the primary and overlay surfaces simultaneously. As the destination video is stretched, the hardware has more time to read the pixels from the overlay surface, decreasing the required memory bandwidth.
    • DDVPBCAPS_SOURCE indicates that the device will describe its bandwidth capabilities in terms of the required source overlay size; that is, that the bandwidth information returned by the next call to DdVideoPortGetBandwidth refers to the size of the source overlay. This flag best describes hardware that pre-fetches the overlay data into a line buffer or large FIFO. Such hardware does not require extra bandwidth, but does require that the source overlay data fit entirely within the buffer/FIFO size supported by the hardware.

    The driver should also set the dwSize member of the DDVIDEOPORTBANDWIDTH structure before returning.

  • When the flag is DDVPB_VIDEOPORT, the dwWidth and dwHeight members in the DD_GETVPORTBANDWIDTHDATA structure refer to the pre-scale size of the video data that the hardware video port will write to the frame buffer as the source overlay. The driver should return an overlay stretch factor at which the device can display the overlay, multiplied by 1000, in each of the dwOverlay, dwColorkey, dwYInterpolate, and dwYInterpAndColorkey members of the DDVIDEOPORTBANDWIDTH structure. For example, a value of 2000 indicates that the device has the bandwidth to stretch the overlay to two times the source's specified size when displaying it. A value of 1000 indicates that no stretching need be done for the specified data size. A value of 500 indicates that the device has sufficient bandwidth to shrink the overlay destination in half. The driver must set a valid value in dwOverlay, but can return -1 in any of the other three members that it does not support.

    The DDVPB_VIDEOPORT flag assumes that the device is best described by the DDVPBCAPS_DESTINATION flag. If this is not the case, the driver should fail the call.

  • When the DDVPB_OVERLAY flag is set, the dwWidth and dwHeight members in the DD_GETVPORTBANDWIDTHDATA structure refer to the source overlay size. The driver should return a percentage of this overlay's size, multiplied by 1000, at which it can support displaying the overlay in each of the dwOverlay, dwColorkey, dwYInterpolate, and dwYInterpAndColorkey members of the DDVIDEOPORTBANDWIDTH structure. For example, a value of 750 indicates that the device requires the specified source overlay to be shrunk to 75% of its original size in order for the device to successfully display it. A value of 1000 indicates that no shrinking is required. Drivers for this type of device do not typically return a value greater than 1000. The driver must set a valid value in dwOverlay, but can return 0 in any of the other three members if it does not support color keying and/or Y-axis interpolation.

    The DDVPB_OVERLAY flag assumes that the device is best described using the DDVPBCAPS_SOURCE flag. If this is not the case, the driver should fail the call.

DD_GETVPORTBANDWIDTHDATA

The DD_GETVPORTBANDWIDTHDATA structure contains the bandwidth information for any specified format.

typedef struct _DD_GETVPORTBANDWIDTHDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  LPDDPIXELFORMAT  lpddpfFormat;
  DWORD  dwWidth;
  DWORD  dwHeight;
  DWORD  dwFlags;
  LPDDVIDEOPORTBANDWIDTH  lpBandwidth;
  HRESULT  ddRVal;
  VOID  *GetVideoPortBandwidth;
} DD_GETVPORTBANDWIDTHDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
lpddpfFormat
Points to a DDPIXELFORMAT structure that describes the output pixel format for which the driver should return bandwidth information.
dwWidth, dwHeight
Specify the dimensions of the source overlay or of the video data, in pixels, depending on the value of dwFlags. These values are calculated by the client based on the VPE object's capabilities returned in a prior call to DdVideoPortGetBandwidth.
dwFlags
Are the flags indicating how the driver should interpret the dwWidth and dwHeight members. This member can be one of the following values:
Flag | Meaning
DDVPB_OVERLAY | The dwWidth and dwHeight members specify the size in pixels of the source overlay surface. This flag indicates that the VPE object is dependent on the overlay source size.
DDVPB_TYPE | The dwWidth and dwHeight members are not set.
DDVPB_VIDEOPORT | The dwWidth and dwHeight members specify the pre-scale size of the video data that the VPE object writes to the frame buffer. This flag indicates that the VPE object is dependent on the overlay stretch factor.

lpBandwidth
Points to the DDVIDEOPORTBANDWIDTH structure in which the driver should write the bandwidth parameters.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetBandwidth callback. A return code of DD_OK indicates success.
GetVideoPortBandwidth
Is used by the DirectDraw API and should not be filled in by the driver.

See Also

DdVideoPortCreate


DdVideoPortColorControl

DdVideoPortColorControl gets or sets the VPE object color controls.

DWORD
  (APIENTRY *PDD_VPORTCB_COLORCONTROL)(
    PDD_VPORTCOLORDATA  lpColorControl
    );

Parameters

lpColorControl
Points to a DD_VPORTCOLORDATA structure that contains the information required for the driver to get the current VPE object color controls or to set new values.

Return Value

DdVideoPortColorControl returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that set the DDVPCAPS_COLORCONTROL flag in the DDVIDEOPORTCAPS structure must implement DdVideoPortColorControl.

Depending on the value of the dwFlags member of the DD_VPORTCOLORDATA structure, the driver should do the following:

  • When dwFlags is DDRAWI_VPORTGETCOLOR, the driver should fill in each member of the DDCOLORCONTROL structure that it supports with the VPE object's current color control setting. The driver must set the corresponding bit in the dwFlags member of DDCOLORCONTROL for every color control member in which it writes data.

    DdVideoPortColorControl can be called to determine the color control capabilities of the VPE object. The driver should therefore fail the call if it does not support a requested color control capability.

  • When dwFlags is DDRAWI_VPORTSETCOLOR, the driver should set the VPE object's color control settings to the values specified in the DDCOLORCONTROL structure. The driver should check the dwFlags member of DDCOLORCONTROL to determine which structure members contain valid data.

DD_VPORTCOLORDATA

The DD_VPORTCOLORDATA structure contains the VPE object color control information.

typedef struct _DD_VPORTCOLORDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwFlags;
  LPDDCOLORCONTROL  lpColorData;
  HRESULT  ddRVal;
  VOID  *ColorControl;
} DD_VPORTCOLORDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure representing the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
dwFlags
Specifies the color control operation to be performed by the driver. This member can be one of the following values:
Flag | Meaning
DDRAWI_VPORTGETCOLOR | The driver should write the current VPE object color controls into the DDCOLORCONTROL structure to which lpColorData points.
DDRAWI_VPORTSETCOLOR | The driver should set new values for the VPE object color controls based on the contents of the DDCOLORCONTROL structure to which lpColorData points.

lpColorData
Points to a DDCOLORCONTROL structure that defines the color control associated with the VPE object to which lpVideoPort points. The value of dwFlags determines whether the driver reads from or writes to this structure.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortColorControl callback. A return code of DD_OK indicates success.
ColorControl
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetConnectInfo

DdVideoPortGetConnectInfo returns the connections supported by the specified VPE object.

DWORD
  (APIENTRY *PDD_VPORTCB_GETVPORTCONNECT)(
    PDD_GETVPORTCONNECTDATA  lpGetConnect
    );

Parameters

lpGetConnect
Points to a DD_GETVPORTCONNECTDATA structure that contains the information required for the driver to return the VPE object connection data.

Return Value

DdVideoPortGetConnectInfo returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortGetConnectInfo must be implemented in DirectDraw drivers that support VPE.

DirectDraw calls DdVideoPortGetConnectInfo to obtain the number of connections supported by the specified VPE object and the characteristics of each connection. DdVideoPortGetConnectInfo is called twice for the specified VPE object:

  • In the first call, lpConnect is NULL. The driver should write the number of connections that the VPE object supports in dwNumEntries. Upon return, DirectDraw will allocate this number of DDVIDEOPORTCONNECT structures to pass in the second call to DdVideoPortGetConnectInfo.
  • In the second call, lpConnect points to the array of allocated DDVIDEOPORTCONNECT structures. The driver should fill in each structure to describe each connection that the VPE object supports. The driver should also return the number of supported connections in dwNumEntries. Note that the driver is guaranteed that the buffer to which lpConnect points is large enough to hold the connection information being requested.

DD_GETVPORTCONNECTDATA

The DD_GETVPORTCONNECTDATA structure contains the connection combinations supported by the specified VPE object.

typedef struct _DD_GETVPORTCONNECTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  DWORD  dwPortId;
  LPDDVIDEOPORTCONNECT  lpConnect;
  DWORD  dwNumEntries;
  HRESULT  ddRVal;
  VOID  *GetVideoPortConnectInfo;
} DD_GETVPORTCONNECTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure representing the DirectDraw object.
dwPortId
Specifies the ID of the VPE object for which the driver is to retrieve connection information. DirectDraw obtains this ID from the dwVideoPortID member of the DDVIDEOPORTCAPS structure.
lpConnect
Points to an array of DDVIDEOPORTCONNECT structures in which the driver should return the characteristics of each connection that the VPE object supports. This member can be NULL.
dwNumEntries
Specifies the location in which the driver returns the number of connection combinations supported by the specified VPE object.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetConnectInfo callback. A return code of DD_OK indicates success.
GetVideoPortConnectInfo
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetField

DdVideoPortGetField determines whether the current field of an interlaced signal is even or odd.

DWORD
  (APIENTRY *PDD_VPORTCB_GETFIELD)(
    PDD_GETVPORTFIELDDATA  lpGetField
    );

Parameters

lpGetField
Points to a DD_GETVPORTFIELDDATA structure that contains the information required for the driver to determine whether the current field is even or odd.

Return Value

DdVideoPortGetField returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that set the DDVPCAPS_READBACKFIELD flag in the DDVIDEOPORTCAPS structure must implement DdVideoPortGetField.

The driver should determine whether the current field is even or odd and write TRUE or FALSE in bField, accordingly. If the query cannot be performed because the hardware video port is disabled, the driver should set DDERR_VIDEONOTACTIVE in ddRVal and return DDHAL_DRIVER_HANDLED.

DD_GETVPORTFIELDDATA

The DD_GETVPORTFIELDDATA structure contains the information required for the driver to determine whether the current field of an interlaced signal is even or odd.

typedef struct _DD_GETVPORTFIELDDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  BOOL  bField;
  HRESULT  ddRVal;
  VOID  *GetVideoPortField;
} DD_GETVPORTFIELDDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw API.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
bField
Specifies the location in which the driver should indicate the polarity of the field. This member should be set to TRUE if the current field is the even field of an interlaced signal and to FALSE if the current field is the odd field.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetField callback. A return code of DD_OK indicates success.
GetVideoPortField
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetFlipStatus

DdVideoPortGetFlipStatus determines whether the most recently requested flip on a surface has occurred.

DWORD
  (APIENTRY *PDD_VPORTCB_GETFLIPSTATUS)(
    PDD_GETVPORTFLIPSTATUSDATA  lpGetFlipStatus
    );

Parameters

lpGetFlipStatus
Points to a DD_GETVPORTFLIPSTATUSDATA structure that contains the information required for the driver to determine a surface's flip status.

Return Value

DdVideoPortGetFlipStatus returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support VPE must implement DdVideoPortGetFlipStatus.

The driver should set ddRVal to DDERR_WASSTILLDRAWING if a flip is currently in progress; otherwise it should return DD_OK.

If the driver returns DDERR_WASSTILLDRAWING, DirectDraw will fail locks and blits on that surface.

DD_GETVPORTFLIPSTATUSDATA

The DD_GETVPORTFLIPSTATUSDATA structure contains the flip status information for the specified surface.

typedef struct _DD_GETVPORTFLIPSTATUSDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  FLATPTR  fpSurface;
  HRESULT  ddRVal;
  VOID  *GetVideoPortFlipStatus;
} DD_GETVPORTFLIPSTATUSDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
fpSurface
Points to the surface for which the flip status information is required.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetFlipStatus callback. A return code of DD_OK indicates success.
GetVideoPortFlipStatus
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetInputFormats

DdVideoPortGetInputFormats determines the input formats that the DirectDraw VPE object can accept.

DWORD
  (APIENTRY *PDD_VPORTCB_GETINPUTFORMATS)(
    PDD_GETVPORTINPUTFORMATDATA  lpGetInputFormats
    );

Parameters

lpGetInputFormats
Points to a DD_GETVPORTINPUTFORMATDATA structure that contains the information required for the driver to return the input formats the VPE object can accept.

Return Value

DdVideoPortGetInputFormats returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DdVideoPortGetInputFormats must be implemented in DirectDraw drivers that support VPE.

DirectDraw calls DdVideoPortGetInputFormats to obtain the number of input formats supported by the specified VPE object and a description of each format. DdVideoPortGetInputFormats is called twice for the specified VPE object:

  • In the first call, lpddpfFormat is NULL. The driver should write the number of input formats that the VPE object supports in dwNumFormats. Upon return, DirectDraw will allocate this number of DDPIXELFORMAT structures to pass in the second call to DdVideoPortGetInputFormats.
  • In the second call, lpddpfFormat points to the array of allocated DDPIXELFORMAT structures. The driver should fill in each structure to describe each input format that the VPE object supports. The driver should also return the number of supported input formats in dwNumFormats. Note that the driver is guaranteed that the buffer to which lpddpfFormat points is large enough to hold the format information being requested.

If the dwFlags member of the DD_GETVPORTINPUTFORMATDATA structure is set only to DDVPFORMAT_VIDEO, the driver should return only those formats that are supported for the normal video data. If dwFlags is set only to DDVPFORMAT_VBI, the driver should return only those formats supported for the VBI data. If dwFlags is set to both flags, the driver should return all formats supported by the VPE object.

DD_GETVPORTINPUTFORMATDATA

The DD_GETVPORTINPUTFORMATDATA structure contains the information required for the driver to return the input formats that the VPE object can accept.

typedef struct _DD_GETVPORTINPUTFORMATDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwFlags;
  LPDDPIXELFORMAT  lpddpfFormat;
  DWORD  dwNumFormats;
  HRESULT  ddRVal;
  VOID  *GetVideoPortInputFormats;
} DD_GETVPORTINPUTFORMATDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
dwFlags
Indicates the type of formats for which support is being queried. This member can be one or more of the following values:
Flag | Meaning
DDVPFORMAT_VBI | The driver should return formats for the VBI data.
DDVPFORMAT_VIDEO | The driver should return formats for the video data.

lpddpfFormat
Points to an array of DDPIXELFORMAT structures in which the driver should write the pixel formats supported by the VPE object. This member can be NULL.
dwNumFormats
Specifies the location in which the driver should write the number of formats that the VPE object supports.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetInputFormats callback. A return code of DD_OK indicates success.
GetVideoPortInputFormats
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetOutputFormats

DdVideoPortGetOutputFormats determines the output formats that the VPE object supports.

DWORD
  (APIENTRY *PDD_VPORTCB_GETOUTPUTFORMATS)(
    PDD_GETVPORTOUTPUTFORMATDATA  lpGetOutputFormats
    );

Parameters

lpGetOutputFormats
Points to a DD_GETVPORTOUTPUTFORMATDATA structure that contains the information required for the driver to return the output formats the VPE object supports.

Return Value

DdVideoPortGetOutputFormats returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support VPE must implement DdVideoPortGetOutputFormats.

DirectDraw calls DdVideoPortGetOutputFormats to obtain the number of output formats supported by the specified VPE object and a description of each format. DdVideoPortGetOutputFormats is called twice for the specified VPE object:

  • In the first call, lpddpfOutputFormats is NULL. The driver should write the number of output formats that the VPE object supports in dwNumFormats. Upon return, DirectDraw will allocate this number of DDPIXELFORMAT structures to pass in the second call to DdVideoPortGetOutputFormats.
  • In the second call, lpddpfOutputFormats points to the array of allocated DDPIXELFORMAT structures. The driver should fill in each structure with a description of each output format that the VPE object can write to the frame buffer. The driver should return only those output formats that it supports based on the input format of the video data. The driver should also return the number of supported output formats in dwNumFormats. Note that the driver is guaranteed that the buffer to which lpddpfOutputFormats points is large enough to hold the format information being requested.

If dwFlags is set only to DDVPFORMAT_VIDEO, the driver should return only those output formats that are supported for normal video data. If dwFlags is set only to DDVPFORMAT_VBI, the driver should return only those formats supported for VBI data. If dwFlags is set to both flags, the driver should return all formats supported by the VPE object.

DD_GETVPORTOUTPUTFORMATDATA

The DD_GETVPORTOUTPUTFORMATDATA structure contains the information required for the driver to return all of the output formats that the VPE object supports for a given input format.

typedef struct _DD_GETVPORTOUTPUTFORMATDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwFlags;
  LPDDPIXELFORMAT  lpddpfInputFormat;
  LPDDPIXELFORMAT  lpddpfOutputFormats;
  DWORD  dwNumFormats;
  HRESULT  ddRVal;
  VOID  *GetVideoPortOutputFormats;
} DD_GETVPORTOUTPUTFORMATDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to the DD_VIDEOPORT_LOCAL structure that represents this VPE object.
dwFlags
Indicates the type of output formats for which support is being queried. This member can be one or more of the following values:
Flag | Meaning
DDVPFORMAT_VBI | The driver should return formats for the VBI data.
DDVPFORMAT_VIDEO | The driver should return formats for the video data.

lpddpfInputFormat
Points to a DDPIXELFORMAT structure that contains an input format supported by the VPE object. This format was returned by DdVideoPortGetInputFormats.
lpddpfOutputFormats
Points to an array of DDPIXELFORMAT structures in which the driver should return the output formats that the VPE object supports for the input format specified by lpddpfInputFormat. This member can be NULL.
dwNumFormats
Specifies the location in which the driver should return the number of output formats that the VPE object supports for the specified input format.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetOutputFormats callback. A return code of DD_OK indicates success.
GetVideoPortOutputFormats
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetLine

DdVideoPortGetLine returns the current line number of the hardware video port.

DWORD
  (APIENTRY *PDD_VPORTCB_GETLINE)(
    PDD_GETVPORTLINEDATA  lpGetLine
    );

Parameters

lpGetLine
Points to a DD_GETVPORTLINEDATA structure that contains the information required for the driver to determine and return the current line number for the specified hardware video port.

Return Value

DdVideoPortGetLine returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

Drivers that set the DDVPCAPS_READBACKLINE flag in the DDVIDEOPORTCAPS structure must implement DdVideoPortGetLine.

The driver should write the number of the current video line in dwLine. The returned line number must be zero-based; that is, the first line of video is line 0, the second line of video is line 1, etc.

If the device is in a vertical blank, the driver should set DDERR_VERTICALBLANKINPROGRESS in ddRVal. If the query cannot be performed because the hardware video port is disabled, the driver should set DDERR_VIDEONOTACTIVE in ddRVal. In both of these failed cases, the driver should return DDHAL_DRIVER_HANDLED.

DD_GETVPORTLINEDATA

The DD_GETVPORTLINEDATA structure contains the current line number of the hardware video port.

typedef struct _DD_GETVPORTLINEDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwLine;
  HRESULT  ddRVal;
  VOID  *GetVideoPortLine;
} DD_GETVPORTLINEDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
dwLine
Specifies the location in which the driver should write the current line number on the hardware video port.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetLine callback. A return code of DD_OK indicates success.
GetVideoPortLine
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortGetSignalStatus

DdVideoPortGetSignalStatus retrieves the status of the video signal currently being presented to the hardware video port.

DWORD
  (APIENTRY *PDD_VPORTCB_GETSIGNALSTATUS)(
    PDD_GETVPORTSIGNALDATA  lpGetSignalStatus
    );

Parameters

lpGetSignalStatus
Points to a DD_GETVPORTSIGNALDATA structure that contains the information required for the driver to retrieve the status of the video signal.

Return Value

DdVideoPortGetSignalStatus returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support VPE must implement DdVideoPortGetSignalStatus.

The driver should determine whether a valid signal is coming in to the hardware video port and report the result in dwStatus.

DD_GETVPORTSIGNALDATA

The DD_GETVPORTSIGNALDATA structure contains the signal status of the hardware video port.

typedef struct _DD_GETVPORTSIGNALDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwStatus;
  HRESULT  ddRVal;
  VOID  *GetVideoSignalStatus;
} DD_GETVPORTSIGNALDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
dwStatus
Specifies the location in which the driver should write the status of the signal at the hardware video port. This member can be one of the following values:
Flag | Meaning
DDVPSQ_NOSIGNAL | No video signal is present at the hardware video port.
DDVPSQ_SIGNALOK | A valid video signal is present at the hardware video port.

ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortGetSignalStatus callback. A return code of DD_OK indicates success.
GetVideoSignalStatus
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortUpdate

DdVideoPortUpdate starts and stops the VPE object, and modifies the VPE object data stream.

DWORD
  (APIENTRY *PDD_VPORTCB_UPDATE)(
    PDD_UPDATEVPORTDATA  lpUpdate
    );

Parameters

lpUpdate
Points to a DD_UPDATEVPORTDATA structure that contains the information required for the driver to update the VPE object.

Return Value

DdVideoPortUpdate returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

DirectDraw drivers that support VPE must implement DdVideoPortUpdate.

When dwFlags is DDRAWI_VPORTSTART or DDRAWI_VPORTUPDATE, the driver should do the following:

  • Check all flags in the dwVPFlags member of the DDVIDEOPORTINFO structure to which lpVideoInfo points. These flags describe how the driver should transfer video data to a surface (or surfaces); for example, they indicate whether the driver should perform autoflipping, crop the video or VBI data, etc.
  • Set up loops in the hardware to write video and/or VBI data to the surfaces in the order in which the surfaces are stored in the array(s). The driver should return as quickly as possible after setting up these loops.
  • If autoflipping has been requested, store the frame buffer offset for each surface in the driver's internal data structure. The surface offsets should be stored in the order in which the surfaces occur in the DD_SURFACE_INT arrays. In this way, when DdUpdateOverlay is called, the driver has a record of the flipping order of the surface chain.

If the dwVBIHeight member of the DDVIDEOPORTINFO structure is greater than zero and lplpDDVBISurface is not NULL, the driver should write dwVBIHeight lines of VBI data into each surface in the array to which lplpDDVBISurface points.

If the driver's hardware cannot support the number of surfaces specified when autoflipping is requested, DdVideoPortUpdate should fail the call by setting DDERR_UNSUPPORTED in ddRVal.

The number of surfaces in the video and VBI surface chains can be different; that is, dwNumAutoflip and dwNumVBIAutoflip can be different values.

When dwFlags is DDRAWI_VPORTSTOP, the driver should return immediately. The driver should not poll until the data stream stops.

DD_UPDATEVPORTDATA

The DD_UPDATEVPORTDATA structure contains the information required to start, stop, and change the VPE object.

typedef struct _DD_UPDATEVPORTDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  PDD_SURFACE_INT  *lplpDDSurface;
  PDD_SURFACE_INT  *lplpDDVBISurface;
  PDD_VIDEOPORTINFO  lpVideoInfo;
  DWORD  dwFlags;
  DWORD  dwNumAutoflip;
  DWORD  dwNumVBIAutoflip;
  HRESULT  ddRVal;
  VOID  *UpdateVideoPort;
} DD_UPDATEVPORTDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
lplpDDSurface
Points to an array of surface structure(s) that represent regular video surface(s). This member can be NULL.
lplpDDVBISurface
Points to an array of surface structure(s) that represent VBI surface(s). This member can be NULL.
lpVideoInfo
Points to a DDVIDEOPORTINFO structure that describes how the VPE object should transfer video data to a surface. This member can be NULL when dwFlags is DDRAWI_VPORTSTOP.
dwFlags
Indicates the action to be performed by the VPE object. This member must be one of the following values:
Flag | Meaning
DDRAWI_VPORTSTART | The driver should start the flow of data through the VPE object.
DDRAWI_VPORTSTOP | The driver should stop the flow of data through the VPE object.
DDRAWI_VPORTUPDATE | DdVideoPortUpdate has been called with a new set of flags in the dwVPFlags member of the DDVIDEOPORTINFO structure to which lpVideoInfo points. The driver should change the flow of data through the VPE object according to the new flags.

dwNumAutoflip
Specifies the number of surfaces in the list to which lplpDDSurface points. If this member is greater than 1, lplpDDSurface is an array of surface structures to accommodate autoflipping.
dwNumVBIAutoflip
Specifies the number of surfaces in the list to which lplpDDVBISurface points. If this member is greater than 1, lplpDDVIBSurface is an array of surface structures to accommodate autoflipping of VBI data.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortUpdate callback. A return code of DD_OK indicates success.
UpdateVideoPort
Is used by the DirectDraw API and should not be filled in by the driver.


DdVideoPortWaitForSync

DdVideoPortWaitForSync waits until the next vertical synch occurs.

DWORD
  (APIENTRY *PDD_VPORTCB_WAITFORSYNC)(
    PDD_WAITFORVPORTSYNCDATA  lpWaitForSync
    );

Parameters

lpWaitForSync
Points to a DD_WAITFORVPORTSYNCDATA structure that contains the information required for the driver to synchronize the VPE object.

Return Value

DdVideoPortWaitForSyncData returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

If the condition on which the driver is waiting does not occur before the number of milliseconds specified in dwTimeOut has elapsed, the driver should set ddRVal to DDERR_VIDEONOTACTIVE and return.

The driver must specify its own timeout criteria when dwTimeOut is zero.

DD_WAITFORVPORTSYNCDATA

The DD_WAITFORVPORTSYNCDATA structure contains the information required for the driver to synchronize the VPE object.

typedef struct _DD_WAITFORVPORTSYNCDATA {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwFlags;
  DWORD  dwLine;
  DWORD  dwTimeOut;
  HRESULT  ddRVal;
  VOID  *UpdateVideoPort;
  } DD_WAITFORVPORTSYNCDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that represents the DirectDraw object.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure that represents this VPE object.
dwFlags
Indicates the condition for which the driver should wait. This member can be one of the following values:
Flag | Meaning
DDVPWAIT_BEGIN | The driver should return at the beginning of the next V-sync.
DDVPWAIT_END | The driver should return at the end of the next/current V-sync.
DDVPWAIT_LINE | The driver should return at the beginning of the line specified in dwLine.

dwLine
Specifies the line number on which the driver should synchronize when dwFlags is DDVPWAIT_LINE. The driver should ignore this member when dwFlags is set to DDVPWAIT_BEGIN or DDVPWAIT_END.
dwTimeOut
Specifies the maximum amount of time the driver should wait, in milliseconds, before timing out.
ddRVal
Specifies the location in which the driver writes the return value of the DdVideoPortWaitForSync callback. A return code of DD_OK indicates success.
UpdateVideoPort
Is used by the DirectDraw API and should not be filled in by the driver.


DdWaitForVerticalBlank

DdWaitForVerticalBlank returns the vertical blank status of the device.

DWORD
  (APIENTRY *PDD_WAITFORVERTICALBLANK)(
    PDD_WAITFORVERTICALBLANKDATA  lpWaitForVerticalBlank
    );

Parameters

lpWaitForVerticalBlank
Points to a DD_WAITFORVERTICALBLANKDATA structure that contains the information required to obtain the vertical blank status.

Return Value

DdWaitForVerticalBlank returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

Depending on the value of dwFlags, the driver should do the following:

  • If dwFlags is DDWAITVB_I_TESTVB, the driver should query the current vertical blanking status. The driver should set bIsInVB to TRUE if the monitor is currently in a vertical blank; otherwise it should set it to FALSE.
  • If dwFlags is DDWAITVB_BLOCKBEGIN, the driver should block and wait until a vertical blank begins. If a vertical blank is in progress when the driver begins the block, the driver should wait until the next vertical blank begins before returning.
  • If dwFlags is DDWAITVB_BLOCKEND, the driver should block and wait until a vertical blank ends.

When the driver successfully handles the action specified in dwFlags, it should set DD_OK in ddRVal and return DDHAL_DRIVER_HANDLED. The driver should return DDHAL_DRIVER_NOTHANDLED for those flags that it is incapable of handling.

DdWaitForVerticalBlank allows an application to synchronize itself with the vertical blanking interval (VBI).

Note DdWaitForVerticalBlank should never enter a polling loop if the monitor power state will cause the driver to hang. For example, during a monitor power-down, an app might call WaitForVerticalBlank. The DirectDraw run-time calls the display driver's DdWaitForVerticalBlank entry point, which waits for the status to change. If the monitor is powered down, this value will never change - unless the driver writer prepares for this scenario. One solution is to include a timeout in the polling loop while waiting for a vertical blank. The sample Permedia2 driver is simply set to not poll at all if the monitor is powered down.

There is also an issue with the WHQL Display Compatibility Tests (DCTs). One of the DCTs for power management powers down the monitor and then polls the vertical blank status, waiting for it to change. If the driver always reports the same vertical blank status when the monitor is powered down, then the test app will hang waiting for the result to change. This was fixed in the Permedia2 sample driver by returning alternating results while the monitor is powered down. That is, the first time the driver's DdWaitForVerticalBlank entry point is called with the DDWAIT_I_TESTVB flag (when the monitor is powered down), it returns FALSE, the next time it returns TRUE, next time FALSE, etc.

DD_WAITFORVERTICALBLANKDATA

The DD_WAITFORVERTICALBLANKDATA structure contains information necessary to obtain the monitor's vertical blank information.

typedef struct _DDHAL_WAITFORVERTICALBLANKDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  DWORD  dwFlags;
  DWORD  bIsInVB;
  DWORD  hEvent;
  HRESULT  ddRVal;
  VOID  *WaitForVerticalBlank;
} DDHAL_WAITFORVERTICALBLANKDATA;

Members

lpDD
Points to the DirectDraw structure representing the DirectDraw object.
dwFlags
Specifies how the driver should wait for the vertical blank. This member can be one of the following values:
Flag | Meaning
DDWAITVB_BLOCKBEGIN | The driver should return when it detects the beginning of the vertical blank interval.
DDWAITVB_BLOCKBEGINEVENT | Set up an event to trigger when the vertical blank begins. This flag is not currently supported.
DDWAITVB_BLOCKEND | The driver should return when it detects the end of the vertical blank interval and display begins.
DDWAITVB_I_TESTVB | The driver should determine whether a vertical blank is currently occurring and return the status in bIsInVB.

bIsInVB
Indicates the status of the vertical blank. A value of TRUE indicates that the device is in a vertical blank; FALSE means that it is not. The driver should return the current vertical blanking status in this member when dwFlags is DDWAITVB_I_TESTVB.
hEvent
Is a handle for the event that should be triggered when the vertical blank begins. The event is triggered on an interrupt, so if your hardware is able to generate an interrupt on the vertical blank, you should pass this event handle to your ring 0 interrupt handler so that it is triggered when the interrupt fires. Is currently unsupported and should be ignored by the driver.
ddRVal
Specifies the location in which the driver writes the return value of the DdWaitForVerticalBlank callback. A return code of DD_OK indicates success.
WaitForVerticalBlank
Is used by the DirectDraw API and should not be filled in by the driver.


DrvDisableDirectDraw

DrvDisableDirectDraw disables hardware for DirectDraw use.

VOID
  DrvDisableDirectDraw(
    IN DHPDEV  dhpdev
    );

Parameters

dhpdev
Handle to the PDEV that was returned by the driver’s DrvEnablePDEV routine.

Comments

GDI calls DrvDisableDirectDraw when the last DirectDraw application has finished running. A driver’s DrvDisableDirectDraw implementation should clean up any software resources and reclaim any hardware resources that the driver dedicated to DirectDraw in DrvEnableDirectDraw.


DrvEnableDirectDraw

DrvEnableDirectDraw enables hardware for DirectDraw use.

BOOL
  DrvEnableDirectDraw(
    IN DHPDEV  dhpdev,
    OUT DD_CALLBACKS  *pCallBacks,
    OUT DD_SURFACECALLBACKS  *pSurfaceCallBacks,
    OUT DD_PALETTECALLBACKS  *pPaletteCallBacks
    );

Parameters

dhpdev
Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
pCallBacks
Points to the DD_CALLBACKS structure to be initialized by the driver.
pSurfaceCallBacks
Points to the DD_SURFACECALLBACKS structure to be initialized by the driver.
pPaletteCallBacks
Points to the DD_PALETTECALLBACKS structure to be initialized by the driver.

Return Value

DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE.

Comments

GDI calls DrvEnableDirectDraw to obtain pointers to the DirectDraw callbacks that the driver supports. The driver should set the function pointer members of DD_CALLBACKS, DD_SURFACECALLBACKS, and DD_PALETTECALLBACKS to point to those functions that it implements. A driver should also set the corresponding bit fields in the dwFlags members of these structures for all supported callbacks.

A driver’s DrvEnableDirectDraw implementation can also dedicate hardware resources such as display memory for use by DirectDraw only.

See Also

DrvGetDirectDrawInfo


DrvGetDirectDrawInfo

DrvGetDirectDrawInfo returns the capabilities of the graphics hardware.

BOOL
  DrvGetDirectDrawInfo(
    IN DHPDEV  dhpdev,
    OUT DD_HALINFO  *pHalInfo,
    OUT DWORD  *pdwNumHeaps,
    OUT VIDEOMEMORY  *pvmList,
    OUT DWORD  pdwNumFourCC,
    OUT DWORD  *pdwFourCC
    );

Parameters

dhpdev
Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
pHalInfo
Points to a DD_HALINFO structure in which the driver should return the hardware capabilities that it supports.
pdwNumHeaps
Points to the location in which the driver should return the number of VIDEOMEMORY structures pointed to by pvmList.
pvmList
Points to an array of VIDEOMEMORY structures in which the driver should return information about each display memory chunk that it controls. The driver should ignore this parameter when it is NULL.
pdwNumFourCC
Points to the location in which the driver should return the number of DWORDs pointed to by pdwFourCC.
pdwFourCC
Points to an array of DWORDs in which the driver should return information about each FOURCC that it supports. The driver should ignore this parameter when it is NULL.

Return Value

DrvGetDirectDrawInfo returns TRUE if it succeeds; otherwise, it returns FALSE.

Comments

The driver's DrvGetDirectDrawInfo routine should do the following:

  • When pvmList and pdwFourCC are NULL:
    1. Reserve offscreen display memory for DirectDraw use.
    2. Write the number of driver display memory heaps and supported FOURCCs in pdwNumHeaps and pdwNumFourCC, respectively.
  • When pvmList and pdwFourCC are not NULL:
    1. Write the number of driver display memory heaps and supported FOURCCs in pdwNumHeaps and pdwNumFourCC, respectively.
    2. For each VIDEOMEMORY structure in the list to which pvmList points, fill in the appropriate members to describe a particular chunk of display memory. The list of structures provides DirectDraw with a complete description of the driver's offscreen memory.
  • Initialize the members of the DD_HALINFO structure with driver-specific information as follows:
    1. Initialize the appropriate members of the VIDEOMEMORYINFO structure to describe the general characteristics of the display's memory.
    2. Initialize the appropriate members of the DDCORECAPS structure to describe the capabilities of the hardware.
    3. If the driver implements a DdGetDriverInfo function, set GetDriverInfo to point to it and set dwFlags to DDHALINFO_GETDRIVERINFOSET.

See Also

DD_HALINFO, DdGetDriverInfo, DrvEnableDirectDraw, VIDEOMEMORY, VIDEOMEMORYINFO


DxApi

DxApi is a single entry point in DirectDraw that accepts commands from the hardware decoder to access the DxApi miniport functions.

DWORD
  FAR PASCAL DxApi(
    IN DWORD  dwFunctionNum,
    IN LPVOID  lpvInBuffer,
    IN DWORD  cbInBuffer,
    OUT LPVOID  lpvOutBuffer,
    OUT DWORD  cbOutBuffer
    );

Parameters

dwFunctionNum
Indicates the behavior of the DxApi function (function identifier).
lpvInBuffer
Points to the input buffer.
cbInBuffer
Indicates the size in bytes of the input buffer.
lpvOutBuffer
Points to the output buffer.
cbOutBuffer
Indicates the size in bytes of the output buffer.

Return Value

DxApi returns the number of bytes actually written to the output buffer.

Comments

DxApi accepts a function identifier (dwFunctionNum), an input buffer (lpvInBuffer) and its size (cbInBuffer), and an output buffer (lpvOutBuffer) and its size (cbOutBuffer). The behavior of the function and the size and format of the input and output buffers depend on the specified function identifier. The return value is the number of actual bytes written into the output buffer.

The following function identifiers are defined for the DxApi function in the ddkmapi.h header file:

DD_DXAPI_ADDVPCAPTUREBUFFER

DD_DXAPI_CLOSEHANDLE

DD_DXAPI_FLIP_OVERLAY

DD_DXAPI_FLIP_VP

DD_DXAPI_FLUSHVPCAPTUREBUFFERS

DD_DXAPI_GET_CURRENT_VP_AUTOFLIP_SURFACE

DD_DXAPI_GET_LAST_VP_AUTOFLIP_SURFACE

DD_DXAPI_GET_POLARITY

DD_DXAPI_GET_SURFACE_STATE

DD_DXAPI_GET_VP_FIELD_NUMBER

DD_DXAPI_GETKERNELCAPS

DD_DXAPI_GETVERSIONNUMBER

DD_DXAPI_LOCK

DD_DXAPI_OPENDIRECTDRAW

DD_DXAPI_OPENSURFACE

DD_DXAPI_OPENVIDEOPORT

DD_DXAPI_OPENVPCAPTUREDEVICE

DD_DXAPI_REGISTER_CALLBACK

DD_DXAPI_SET_SURFACE_STATE

DD_DXAPI_SET_VP_FIELD_NUMBER

DD_DXAPI_SET_VP_SKIP_FIELD

DD_DXAPI_UNREGISTER_CALLBACK


DD_DXAPI_ADDVPCAPTUREBUFFER

DD_DXAPI_ADDVPCAPTUREBUFFER adds a new buffer to the internal capture queue. Each time a hardware video port V-sync occurs, the kernel-mode video transport determines whether the previous field needs to be captured and if so, initiates a bus master to the next buffer in the queue.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDADDVPCAPTUREBUFF structure that contains the information required to add a new buffer.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

This function identifier can be called at raised IRQL.

DDADDVPCAPTUREBUFF

The DDADDVPCAPTUREBUFF structure contains the information required to add a new buffer to the internal capture queue.

typedef struct _DDADDVPCAPTUREBUFF {
  HANDLE  hCapture;
  DWORD  dwFlags;
  PMDL  pMDL;
  PKEVENT  pKEvent;
  LPDDCAPBUFFINFO  lpBuffInfo;
} DDADDVPCAPTUREBUFF, FAR * LPDDADDVPCAPTUREBUFF;

Members

hCapture
Contains the VPE capture handle.
dwFlags
Indicates whether the destination buffer exists in regular system memory or nonlocal display memory (AGP). One of the following:
Flag | Meaning
DDADDBUFF_INVERT | The buffer is to be inverted during capture.
DDADDBUFF_NONLOCALVIDMEM | The destination buffer exists in nonlocal display memory.
DDADDBUFF_SYSTEMMEMORY | The destination buffer exists in system memory.

pMDL
Points to an MDL (defined in wdm.h) that describes the physical pages of the destination buffer.
pKEvent
Points to a KEVENT that the kernel-mode video transport sets when the destination has been filled.
lpBuffInfo
Points to a DDCAPBUFFINFO structure that the kernel-mode video transport fills in before setting the KEVENT.

DDCAPBUFFINFO

The DDCAPBUFFINFO structure contains the capture information.

typedef struct _DDCAPBUFFINFO {
  DWORD  dwFieldNumber;
  DWORD  bPolarity;
  LARGE_INTEGER  liTimeStamp;
  DWORD  ddRVal;
} DDCAPBUFFINFO, FAR * LPDDCAPBUFFINFO;

Members

dwFieldNumber
Indicates the internal field number of the field captured.
bPolarity
Specifies whether the captured field is an even or odd field.
liTimeStamp
Is used by DirectDraw and should be ignored by the driver.
ddRVal
Specifies the location in which the driver writes the return value. Contains DD_OK if the capture buffer contains valid data.


DD_DXAPI_CLOSEHANDLE

DD_DXAPI_CLOSEHANDLE closes the kernel-mode handle.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to the DDCLOSEHANDLE structure that contains the appropriate handle.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

The input buffer specifies the DirectDraw object, surface, VPE object, or VPE capture handle that needs to be closed. Calling this function identifier does not cause the corresponding close routines to be called. The output from this function identifier is a DirectDraw return code. This function identifier can only be called at passive level.

DDCLOSEHANDLE

The DDCLOSEHANDLE structure contains the DirectDraw object, surface, VPE object, or VPE capture handle.

typedef struct _DDCLOSEHANDLE {
  HANDLE  hHandle;
} DDCLOSEHANDLE, FAR *LPDDCLOSEHANDLE;

Members

hHandle
Specifies the handle to be closed.


DD_DXAPI_FLIP_OVERLAY

DD_DXAPI_FLIP_OVERLAY flips the overlay to display the other surface.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDFLIPOVERLAY structure that contains the surface information required for the flip.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

This call does not rotate the memory pointers as does the user-mode DdFlip function, so it is up to the client to keep track of which surface is visible and which is not. The dwFlags member of the DDFLIPOVERLAY structure can contain DDFLIP_EVEN or DDFLIP_ODD to accommodate bob mode when not using a hardware video port. If the overlay is associated with a hardware video port, the hardware video port is not automatically flipped. This function identifier cannot be called while autoflipping.

This function identifier can be called at raised IRQL.

DDFLIPOVERLAY

The DDFLIPOVERLAY structure contains the surface information required for the flip.

typedef struct _DDFLIPOVERLAY {
  HANDLE  hDirectDraw;
  HANDLE  hCurrentSurface;
  HANDLE  hTargetSurface;
  DWORD   dwFlags;
} DDFLIPOVERLAY, FAR *LPDDFLIPOVERLAY;

Members

hDirectDraw
Specifies the DirectDraw handle.
hCurrentSurface
Specifies the current DirectDrawSurface handle.
hTargetSurface
Specifies the handle of the DirectDrawSurface to which the flip occurs.
dwFlags
Flags specifying flip options.
Flag | Meaning
DDFLIP_EVEN | For use only when displaying video in an overlay surface. The new surface contains data from the even field of a video signal. This flag cannot be used with the DDFLIP_ODD flag.
DDFLIP_ODD | For use only when displaying video in an overlay surface. The new surface contains data from the odd field of a video signal. This flag cannot be used with the DDFLIP_EVEN flag.


DD_DXAPI_FLIP_VP

DD_DXAPI_FLIP_VP causes the hardware video port to write data to a different surface.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDFLIPVIDEOPORT structure that contains the handle information required to flip the hardware video port.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

The dwFlags member of the DDFLIPVIDEOPORT structure should contain DDVPFLIP_VIDEO or DDVPFLIP_VBI to indicate whether the video or the VBI region of the video signal should be flipped. To flip both regions, this function identifier should be called twice. This function identifier cannot be called while autoflipping.

This function identifier can be called from raised IRQL.

DDFLIPVIDEOPORT

The DDFLIPVIDEOPORT structure contains the information required to flip the hardware video port.

typedef struct _DDFLIPVIDEOPORT {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
  HANDLE  hCurrentSurface;
  HANDLE  hTargetSurface;
  DWORD  dwFlags;
} DDFLIPVIDEOPORT, FAR *LPDDFLIPVIDEOPORT;

Members

hDirectDraw
Specifies the DirectDraw handle.
hVideoPort
Specifies the VPE object handle.
hCurrentSurface
Specifies the current DirectDrawSurface handle.
hTargetSurface
Specifies the handle of the DirectDrawSurface to which the flip occurs.
dwFlags
Indicates whether the surfaces represent VBI surfaces or regular surfaces. One of the following:
Flag | Meaning
DDVPFLIP_VBI | Flips the VBI surface.
DDVPFLIP_VIDEO | Flips the normal video surface.


DD_DXAPI_FLUSHVPCAPTUREBUFFERS

DD_DXAPI_FLUSHVPCAPTUREBUFFERS removes all buffers from the capture queue and stops video capture for that device.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Contains the VPE capture handle (HANDLE hCapture;).
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

All KEVENTs that have been registered using the DD_DXAPI_ADDVPCAPTUREBUFFER function identifier will be set. This function identifier can be called at raised IRQL.


DD_DXAPI_GET_CURRENT_VP_AUTOFLIP_SURFACE

DD_DXAPI_GET_CURRENT_VP_AUTOFLIP_SURFACE returns the surface(s) handles that are receiving the current video and VBI data from the hardware video port.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDGETAUTOFLIPIN structure that contains the required handle information.
lpvOutBuffer
Points to a DDGETAUTOFLIPOUT structure that contains the surface information and the VBI data from the hardware video port.

Comments

An error is returned if the hardware video port is not in autoflip mode. It also returns the polarity of the current field, where the bPolarity member of the DDGETAUTOFLIPOUT structure is set to TRUE if the current field is the even field of an interlaced video signal.

This function identifier can be called at raised IRQL.

DDGETAUTOFLIPIN

The DDGETAUTOFLIPIN structure contains the handle information.

typedef struct _DDGETAUTOFLIPIN {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
} DDGETAUTOFLIPIN, FAR *LPDDGETAUTOFLIPIN;

Members

hDirectDraw
Specifies the DirectDraw handle.
hVideoPort
Specifies the VPE object handle.

DDGETAUTOFLIPOUT

The DDGETAUTOFLIPOUT structure contains the handle and polarity information returned from the DD_DXAPI_GET_CURRENT_VP_AUTOFLIP_SURFACE and DD_DXAPI_GET_LAST_VP_AUTOFLIP_SURFACE function identifiers of the DxApi function.

typedef struct _DDGETAUTOFLIPOUT {
  DWORD   ddRVal;
  HANDLE  hVideoSurface;
  HANDLE  hVBISurface;
  BOOL  bPolarity;
} DDGETAUTOFLIPOUT, FAR *LPDDGETAUTOFLIPOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
hVideoSurface
Specifies the handle for the current video surface.
hVBISurface
Specifies the handle for the current VBI data.
bPolarity
Specifies whether the field is an even or odd field of an interlaced video signal.


DD_DXAPI_GET_LAST_VP_AUTOFLIP_SURFACE

DD_DXAPI_GET_LAST_VP_AUTOFLIP_SURFACE returns the surface(s) handles that received the most recent field of data written to the frame buffer (taking field skipping into account).

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDGETAUTOFLIPIN structure that contains the required handle information.
lpvOutBuffer
Points to a DDGETAUTOFLIPOUT structure that contains the surface information and the VBI data from the hardware video port.

Comments

The surfaces returned by this function identifier may be the same surfaces that are receiving the current field if the hardware video port is interleaving the data. This function identifier also returns the polarity of the field most recently written to the frame buffer, where the bPolarity member of the DDGETAUTOFLIPOUT structure is set to TRUE if the field was the even field of an interlaced video signal. An error is returned if the hardware video port is not in autoflip mode.

This function identifier can be called at raised IRQL.


DD_DXAPI_GET_POLARITY

DD_DXAPI_GET_POLARITY returns the polarity of the current hardware video port field.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDGETPOLARITYIN structure that contains the handle information.
lpvOutBuffer
Points to a DDGETPOLARITYOUT structure that contains the polarity information.

Comments

The bPolarity member of the DDGETPOLARITYOUT structure is set to TRUE if the current field is the even field of an interlaced video signal. This function identifier can be called at raised IRQL.

DDGETPOLARITYIN

The DDGETPOLARITYIN structure contains the DirectDraw and VPE object handles.

typedef struct _DDGETPOLARITYIN {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
} DDGETPOLARITYIN, FAR *LPDDGETPOLARITYIN;

Members

hDirectDraw
Specifies the DirectDraw handle.
hVideoPort
Specifies the VPE object handle.

DDGETPOLARITYOUT

The DDGETPOLARITYOUT structure contains the requested polarity information.

typedef struct _DDGETPOLARITYOUT {
  DWORD  ddRVal;
  BOOL  bPolarity;
} DDGETPOLARITYOUT, FAR *LPDDGETPOLARITYOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
bPolarity
Specifies whether the field is an even or odd field of an interlaced video signal.


DD_DXAPI_GET_SURFACE_STATE

DD_DXAPI_GET_SURFACE_STATE indicates whether the overlay surface is in bob or weave mode and whether it can be put into bob or weave mode.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDGETSURFACESTATEIN structure that contains the surface handle.
lpvOutBuffer
Points to a DDGETSURFACESTATEOUT structure that contains the surface capabilities.

Comments

The dwStateCaps member of the DDGETSURFACESTATEOUT structure returns its capabilities, including DDSTATE_BOB and DDSTATE_WEAVE. The dwStateStatus member can return DDSTATE_BOB, DDSTATE_WEAVE, DDSTATE_SOFTWARE_AUTOFLIP (so the caller can know whether the hardware is using software or hardware autoflipping) and DDSTATE_EXPLICITLY_SET (indicating the caller is in this state due to a previous DD_DXAPI_SET_SURFACE_STATE call).

This function identifier can be called at raised IRQL.

DDGETSURFACESTATEIN

The DDGETSURFACESTATEIN structure contains the DirectDraw and DirectDraw surface handle information.

typedef struct _DDGETSURFACESTATEIN {
  HANDLE  hDirectDraw;
  HANDLE  hSurface;
} DDGETSURFACESTATEIN, FAR *LPDDGETSURFACESTATEIN;

Members

hDirectDraw
Specifies the DirectDraw handle.
hSurface
Specifies the DirectDrawSurface handle.

DDGETSURFACESTATEOUT

The DDGETSURFACESTATEOUT structure contains the capabilities and status of the specified surface.

typedef struct _DDGETSURFACESTATEOUT {
  DWORD  ddRVal;
  DWORD  dwStateCaps;
  DWORD  dwStateStatus;
} DDGETSURFACESTATEOUT, FAR *LPDDGETSURFACESTATEOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
dwStateCaps
Contains the DirectDrawSurface's capabilities of the device. One or more of the following:
Flag | Meaning
DDSTATE_BOB | The device is capable of performing bob mode.
DDSTATE_WEAVE | The device is capable of performing weave mode.

dwStateStatus
Contains the status of the selected DirectDrawSurface. One or more of the following:
Flag | Meaning
DDSTATE_BOB | Bob mode is being used on this surface.
DDSTATE_EXPLICITLY_SET | This state is due to a previous DD_DXAPI_SET_SURFACE_STATE call.
DDSTATE_SKIPEVENFIELDS | Stop bob or weave mode and skip every other field instead.
DDSTATE_SOFTWARE_AUTOFLIP | Software (as opposed to hardware) autoflipping is being used.
DDSTATE_WEAVE | Weave mode is being used on this surface.


DD_DXAPI_GET_VP_FIELD_NUMBER

DD_DXAPI_GET_VP_FIELD_NUMBER returns the field number of the current hardware video port field.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDGETFIELDNUMIN structure that contains the required DirectDraw and VPE object handles.
lpvOutBuffer
Points to a DDGETFIELDNUMOUT structure that contains the field number.

Comments

This function identifier can be used when using the VPE capture functions, because they also return the field number being captured. This function identifier can be called at raised IRQL.

DDGETFIELDNUMIN

The DDGETFIELDNUMIN structure contains the DirectDraw and VPE object handle information.

typedef struct _DDGETFIELDNUMIN {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
} DDGETFIELDNUMIN, FAR *LPDDGETFIELDNUMIN;

Members

hDirectDraw
Specifies the DirectDraw handle.
hVideoPort
Specifies the VPE object handle.

DDGETFIELDNUMOUT

The DDGETFIELDNUMOUT structure contains the hardware video port's field number.

typedef struct _DDGETFIELDNUMOUT {
  DWORD  ddRVal;
  DWORD  dwFieldNum;
} DDGETFIELDNUMOUT, FAR *LPDDGETFIELDNUMOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
dwFieldNum
Specifies the hardware video port's field number.


DD_DXAPI_GETKERNELCAPS

DD_DXAPI_GETKERNELCAPS returns the capabilities of this kernel-mode device.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Contains the DirectDraw handle (HANDLE hDirectDraw;).
lpvOutBuffer
Points to a DDGETKERNELCAPSOUT structure that contains the capabilities of the specified DirectDraw object.

Comments

The hDirectDraw handle specifies the DirectDraw object for which to return the kernel-mode capabilities. The dwCaps member of the DDGETKERNELCAPSOUT structure contains the DDKERNELCAPS_XXX flags defined in ddkernel.h and the dwIRQCaps member contains the DDIRQ_XXX flags defined in ddkernel.h. This function identifier can only be called at passive level.

DDGETKERNELCAPSOUT

The DDGETKERNELCAPSOUT structure contains the capabilities of the DirectDraw object.

typedef struct _DDGETKERNELCAPSOUT {
  DWORD  ddRVal;
  DWORD  dwCaps;
  DWORD  dwIRQCaps;
} DDGETKERNELCAPSOUT, FAR *LPDDGETKERNELCAPSOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
dwCaps
Can be any combination of the capabilities in the dwCaps field of DDKERNELCAPS.
dwIRQCaps
Can be a combination of the flags in the dwIRQCaps field of DDKERNELCAPS.


DD_DXAPI_GETVERSIONNUMBER

DD_DXAPI_GETVERSIONNUMBER returns the version of the kernel-mode video transport supported by this interface.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
NULL.
lpvOutBuffer
Points to a DDGETVERSIONNUMBER structure that contains the DirectDraw version number.

Comments

This function identifier can only be called at passive level.

DDGETVERSIONNUMBER

The DDGETVERSIONNUMBER structure contains the version number information.

typedef struct _DDGETVERSIONNUMBER {
  DWORD  ddRVal;
  DWORD  dwMajorVersion;
  DWORD  dwMinorVersion;
} DDGETVERSIONNUMBER, FAR *LPDDGETVERSIONNUMBER;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
dwMajorVersion
Specifies the DirectDraw major version number.
dwMinorVersion
Specifies the DirectDraw minor version number.


DD_DXAPI_LOCK

DD_DXAPI_LOCK allows the client to access the surface for an indefinite amount of time.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDLOCKIN structure that contains the handle information required for the lock.
lpvOutBuffer
Points to a DDLOCKOUT structure that contains the surface information from the surface that is locked.

Comments

If the surface ever becomes unusable due to a fullscreen command prompt, a resolution change, and so on, the pfnSurfaceClose callback specified in the DD_DXAPI_OPENSURFACE function identifier is called to notify the client that it should no longer access this surface.

The lpSurface member of the DDLOCKOUT structure contains the pointer that can be used to access the surface. The other members of the DDLOCKOUT structure relate closely to their counterparts in the DDSURFACEDESC structure (dwSurfWidth correlates to dwWidth, SurfaceCaps correlates to ddsCaps, dwFormatFlags correlates to ddpfPixelFormat.dwFlags, and so on).

There is no corresponding Unlock function identifier.

This function identifier can only be called from passive level.

DDLOCKIN

The DDLOCKIN structure contains the DirectDraw object and DirectDraw surface handle information.

typedef struct _DDLOCKIN {
  HANDLE  hDirectDraw;
  HANDLE  hSurface;
} DDLOCKIN, FAR *LPDDLOCKIN;

Members

hDirectDraw
Specifies the DirectDraw handle.
hSurface
Specifies the DirectDrawSurface handle.

DDLOCKOUT

The DDLOCKOUT structure contains a description of the surface.

typedef struct _DDLOCKOUT {
  DWORD  ddRVal;
  DWORD  dwSurfHeight;
  DWORD  dwSurfWidth;
  LONG   lSurfPitch;
  PVOID  lpSurface;
  DWORD  SurfaceCaps;
  DWORD  dwFormatFlags;
  DWORD  dwFormatFourCC;
  DWORD  dwFormatBitCount;
  union
  {
      DWORD  dwRBitMask;
      DWORD  dwYBitMask;
  };
  union
  {
      DWORD  dwGBitMask;
      DWORD  dwUBitMask;
  };
  union
  {
      DWORD  dwBBitMask;
      DWORD  dwVBitMask;
  };
} DDLOCKOUT, FAR *LPDDLOCKOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
dwSurfHeight, dwSurfWidth
Specify the dimensions of the surface, in pixels.
lSurfPitch
Specifies the distance, in bytes, to the start of the next line.
lpSurface
Points to the surface memory.
SurfaceCaps
Is a set of flags that specify the capabilities of the surface. This member can be set to one or more of the following flags:
Flag | Meaning
DDSCAPS_3DDEVICE | This surface can be used for 3D rendering. Applications can use this flag to ensure that a device that can only render to a certain heap has offscreen surfaces allocated from the correct heap. If this flag is set for a heap, the surface is not allocated from that heap.
DDSCAPS_ALLOCONLOAD | Memory for the surface is not allocated until the surface is loaded by the application using the IDirect3DDevice7::Load method.
DDSCAPS_ALPHA | This surface contains alpha information. The pixel format must be queried to determine whether this surface contains only alpha information or alpha information interlaced with pixel color data (such as RGBA or YUVA).
DDSCAPS_BACKBUFFER | This surface is the back buffer of a surface flipping structure. Typically, this capability is set by the application's CreateSurface method when the DDSCAPS_FLIP flag is used. Only the surface that immediately precedes the DDSCAPS_FRONTBUFFER surface has this capability set. The other surfaces are identified as back buffers by the presence of the DDSCAPS_FLIP flag, their attachment order, and the absence of the DDSCAPS_FRONTBUFFER and DDSCAPS_BACKBUFFER capabilities. If this capability is sent to the application's CreateSurface method, a stand-alone back buffer is being created. After this method is called, this surface could be attached to a front buffer, another back buffer, or both to form a flipping surface structure. For more information, see the AddAttachedSurface method in the DirectX SDK documentation. DirectDraw supports an arbitrary number of surfaces in a flipping structure.
DDSCAPS_COMPLEX | A complex surface is being described. A complex surface results in the creation of more than one surface. The additional surfaces are attached to the root surface. The complex structure can be destroyed only by destroying the root.
DDSCAPS_FLIP | This surface is a part of a surface flipping structure. When this capability is passed to the application's CreateSurface method, a front buffer and one or more back buffers are created. DirectDraw sets the DDSCAPS_FRONTBUFFER bit on the front-buffer surface and the DDSCAPS_BACKBUFFER bit on the surface adjacent to the front-buffer surface. The dwBackBufferCount member of the DDSURFACEDESC structure must be set to at least 1 in order for the method call to succeed. The DDSCAPS_COMPLEX capability must always be set when creating multiple surfaces by using the CreateSurface method.
DDSCAPS_FRONTBUFFER | This surface is the front buffer of a surface flipping structure. This flag is typically set by the application's CreateSurface method when the DDSCAPS_FLIP capability is set. If this capability is sent to the CreateSurface method, a stand-alone front buffer is created. This surface will not have the DDSCAPS_FLIP capability. It can be attached to other back buffers to form a flipping structure by using the application's AddAttachedSurface method.
DDSCAPS_HWCODEC | This surface should be able to have a stream decompressed to it by the hardware.
DDSCAPS_LIVEVIDEO | This surface should be able to receive live video.
DDSCAPS_LOCALVIDMEM | This surface exists in true, local display memory rather than nonlocal display memory. If this flag is specified then DDSCAPS_VIDEOMEMORY must be specified as well. This flag cannot be used with the DDSCAPS_NONLOCALVIDMEM flag.
DDSCAPS_MIPMAP | This surface is one level of a mipmap. This surface will be attached to other DDSCAPS_MIPMAP surfaces to form the mipmap. This can be done explicitly by creating a number of surfaces and attaching them by using the application's AddAttachedSurface method, or implicitly by the application's CreateSurface method. If this capability is set, DDSCAPS_TEXTURE must also be set.
DDSCAPS_MODEX | This surface is a 320×200 or 320×240 Mode X surface.
DDSCAPS_NONLOCALVIDMEM | This surface exists in nonlocal display memory rather than true, local display memory. If this flag is specified, then DDSCAPS_VIDEOMEMORY flag must be specified as well. This cannot be used with the DDSCAPS_LOCALVIDMEM flag.
DDSCAPS_OFFSCREENPLAIN | This surface is any offscreen surface that is not an overlay, texture, z-buffer, front-buffer, back-buffer, or alpha surface. It is used to identify plain surfaces.
DDSCAPS_OPTIMIZED | Not currently implemented.
DDSCAPS_OVERLAY | This surface is an overlay. It may or may not be directly visible depending on whether it is currently being overlaid onto the primary surface. DDSCAPS_VISIBLE can be used to determine if it is being overlaid at the moment.
DDSCAPS_OWNDC | This surface will have a device context (DC) association for a long period.
DDSCAPS_PALETTE | This device driver allows unique DirectDrawPalette objects to be created and attached to this surface.
DDSCAPS_PRIMARYSURFACE | The surface is the primary surface. It represents what is visible to the user at the moment.
DDSCAPS_PRIMARYSURFACELEFT | This surface is the primary surface for the left eye. It represents what is visible to the user's left eye at the moment. When this surface is created, the surface with the DDSCAPS_PRIMARYSURFACE capability represents what is seen by the user's right eye.
DDSCAPS_STANDARDVGAMODE | This surface is a standard VGA mode surface, and not a ModeX surface. This flag cannot be used in combination with the DDSCAPS_MODEX flag.
DDSCAPS_SYSTEMMEMORY | This surface memory was allocated in system memory.
DDSCAPS_TEXTURE | This surface can be used as a 3D texture. It does not indicate whether the surface is being used for that purpose.
DDSCAPS_VIDEOMEMORY | This surface exists in display memory.
DDSCAPS_VIDEOPORT | This surface can receive data from a hardware video port.
DDSCAPS_VISIBLE | Changes made to this surface are immediately visible. It is always set for the primary surface, as well as for overlays while they are being overlaid and texture maps while they are being textured.
DDSCAPS_WRITEONLY | Only write access is permitted to the surface. Read access from the surface may generate a general protection fault (GPF), but the read results from this surface are not meaningful.
DDSCAPS_ZBUFFER | This surface is the z-buffer. The z-buffer contains information that cannot be displayed. Instead, it contains bit-depth information that is used to determine which pixels are visible and which are obscured.

dwFormatFlags
Is a set of optional control flags. This member can be set to a combination of the following flags:
Flag | Meaning
DDPF_ALPHA | The pixel format describes an alpha-only surface.
DDPF_ALPHAPIXELS | The surface has alpha channel information in the pixel format.
DDPF_ALPHAPREMULT | Reserved for system use.
DDPF_BUMPDUDV | Bump map dUdV data in the pixel format is valid.
DDPF_BUMPLUMINANCE | Luminance data in pixel format is valid. This flag is used when hanging luminance off bumpmap surfaces; the bit mask for the luminance portion of the pixel is then indicated by the dwBumpLuminanceBitCount member of the DDPIXELFORMAT structure.
DDPF_COMPRESSED | The surface accepts pixel data in the specified format and compresses it during the write operation.
DDPF_FOURCC | The FourCC code is valid.
DDPF_LUMINANCE | Luminance data in the pixel format is valid. This flag is used for luminance only or luminance plus alpha surfaces; the bit depth is then indicated by the dwLuminanceBitCount member of the DDPIXELFORMAT structure.
DDPF_PALETTEINDEXED1 | The surface is 1-bit color indexed.
DDPF_PALETTEINDEXED2 | The surface is 2-bit color indexed.
DDPF_PALETTEINDEXED4 | The surface is 4-bit color indexed.
DDPF_PALETTEINDEXED8 | The surface is 8-bit color indexed.
DDPF_PALETTEINDEXEDTO8 | The surface is 1-, 2-, or 4-bit color indexed to an 8-bit palette.
DDPF_RGB | The RGB data in the pixel format structure is valid.
DDPF_RGBTOYUV | The surface accepts RGB data and translates it during the write operation to YUV data. The format of the data to be written is contained in the pixel format structure. The DDPF_RGB flag is set.
DDPF_STENCILBUFFER | The surface contains stencil information along with the Z information.
DDPF_YUV | The YUV data in the pixel format structure is valid.
DDPF_ZBUFFER | The pixel format describes a z-buffer-only surface.
DDPF_ZPIXELS | The surface is in RGBZ format.

dwFormatFourCC
Specifies the FourCC code. For more information on FourCC codes, see the DirectX SDK documentation.
dwFormatBitCount
Specifies the number of bits per pixel (4, 8, 16, 24, or 32) of the RGB or YUV data.
dwRBitMask
Specifies the mask for red bits.
dwYBitMask
Specifies the mask for Y bits.
dwGBitMask
Specifies the mask for green bits.
dwUBitMask
Specifies the mask for U bits.
dwBBitMask
Specifies the mask for blue bits.
dwVBitMask
Specifies the mask for V bits.


DD_DXAPI_OPENDIRECTDRAW

DD_DXAPI_OPENDIRECTDRAW notifies the kernel-mode video transport that the driver wants to use a DirectDraw object.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDOPENDIRECTDRAWIN structure that contains the DirectDraw handle information.
lpvOutBuffer
Points to a DDOPENDIRECTDRAWOUT structure that contains the new DirectDraw handle information.

Comments

The object is specified by the dwDirectDrawHandle member of the DDOPENDIRECTDRAWIN structure, which is the handle passed down from user mode. The driver must also specify a callback that is called if the DirectDraw object goes away. The pContext member of the DDOPENDIRECTDRAWIN structure contains a value that is passed if the pfnDirectDrawClose callback is ever called.

If ddRVal is set to DD_OK, the output from this function identifier is a DirectDraw return code and a new DirectDraw handle. This new handle must be used on all subsequent calls that require a DirectDraw handle.

This function identifier can only be called at passive level.

DDOPENDIRECTDRAWIN

The DDOPENDIRECTDRAWIN structure contains the DirectDraw object information.

typedef struct _DDOPENDIRECTDRAWIN {
  ULONG_PTR  dwDirectDrawHandle;
  LPDD_NOTIFYCALLBACK  pfnDirectDrawClose;
  PVOID  pContext;
} DDOPENDIRECTDRAWIN, FAR *LPDDOPENDIRECTDRAWIN;

Members

dwDirectDrawHandle
Contains the DirectDraw handle that was passed down from user mode.
pfnDirectDrawClose
Points to a pfnDirectDrawClose callback function that is called if the DirectDraw object goes away.
pContext
Contains a value that is passed if the pfnDirectDrawClose callback is ever called.

DDOPENDIRECTDRAWOUT

The DDOPENDIRECTDRAWOUT structure contains a DirectDraw return code and a new DirectDraw handle for the DD_DXAPI_OPENDIRECTDRAW function identifier of the DxApi function if ddRVal is set to DD_OK. This new handle must be used on all subsequent calls that require a DirectDraw handle.

typedef struct _DDOPENDIRECTDRAWOUT {
  DWORD  ddRVal;
  HANDLE  hDirectDraw;
} DDOPENDIRECTDRAWOUT, FAR *LPDDOPENDIRECTDRAWOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
hDirectDraw
Contains the new DirectDraw handle.


DD_DXAPI_OPENSURFACE

DD_DXAPI_OPENSURFACE notifies the kernel-mode video transport that the driver wants to use a surface object.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDOPENSURFACEIN structure that contains the DirectDrawSurface object information.
lpvOutBuffer
Points to a DDOPENSURFACEOUT structure that contains the new DirectDrawSurface handle information.

Comments

The object is specified by the dwSurfaceHandle member of the DDOPENSURFACEIN structure, which is the handle passed down from user mode. The hDirectDraw member specifies the DirectDraw object with which it is associated. The driver must also specify a callback that is called when the surface becomes unusable due to it being released at user mode, a fullscreen command prompt, or a mode change. The pContext member contains a value that is passed if the pfnSurfaceClose callback function is ever called.

If ddRVal is set to DD_OK, the output from this function identifier is a DirectDraw return code and a new surface handle. This new handle must be used on all subsequent calls that reference this surface.

This function identifier can only be called at passive level.

DDOPENSURFACEIN

The DDOPENSURFACEIN structure contains the DirectDrawSurface object information.

typedef struct _DDOPENSURFACEIN {
  HANDLE  hDirectDraw;
  ULONG_PTR  dwSurfaceHandle;
  LPDD_NOTIFYCALLBACK  pfnSurfaceClose;
  PVOID  pContext;
} DDOPENSURFACEIN, FAR *LPDDOPENSURFACEIN;

Members

hDirectDraw
Specifies the DirectDraw object to which the surface handle will be associated.
dwSurfaceHandle
Specifies the DirectDrawSurface handle passed down from user mode.
pfnSurfaceClose
Points to a pfnSurfaceClose callback function that is called if the DirectDraw object goes away.
pContext
Contains a value that is passed if the pfnSurfaceClose callback function is ever called.

DDOPENSURFACEOUT

The DDOPENSURFACEOUT structure contains a DirectDraw return code and a new DirectDrawSurface handle, if ddRVal is set to DD_OK. This new handle must be used on all subsequent calls that require a DirectDrawSurface handle.

typedef struct _DDOPENSURFACEOUT {
  DWORD  ddRVal;
  HANDLE  hSurface;
} DDOPENSURFACEOUT, FAR *LPDDOPENSURFACEOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
hSurface
Contains the new DirectDrawSurface handle.


DD_DXAPI_OPENVIDEOPORT

DD_DXAPI_OPENVIDEOPORT notifies the kernel-mode video transport that the driver wants to use a hardware video port.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDOPENVIDEOPORTIN structure that contains the DirectDraw VPE object information.
lpvOutBuffer
Points to a DDOPENVIDEOPORTOUT structure that contains the new VPE object handle information.

Comments

The object is specified by the dwVideoPortHandle member of the DDOPENVIDEOPORTIN structure, which is the hardware video port ID specified when the VPE object was created in user mode. The hDirectDraw member specifies the DirectDraw object with which it is associated. The driver must also specify a callback that is called when the VPE object becomes unusable due to it being released at user mode. The pContext member contains a value that is passed if the pfnVideoPortClose callback function is ever called.

If ddRVal is set to DD_OK, the output from this function identifier is a DirectDraw return code and a new surface handle. This new handle must be used on all subsequent calls that reference this VPE object.

This function identifier can only be called at passive level.

DDOPENVIDEOPORTIN

The DDOPENVIDEOPORTIN structure contains the VPE object information.

typedef struct _DDOPENVIDEOPORTIN {
  HANDLE  hDirectDraw;
  ULONG  dwVideoPortHandle;
  LPDD_NOTIFYCALLBACK  pfnVideoPortClose;
  PVOID  pContext;
} DDOPENVIDEOPORTIN, FAR *LPDDOPENVIDEOPORTIN;

Members

hDirectDraw
Specifies the DirectDraw object to which the surface handle will be associated.
dwVideoPortHandle
Specifies the hardware video port ID that was passed down when the VPE object was created in user mode.
pfnVideoPortClose
Points to a pfnVideoPortClose callback function that is called if the DirectDraw object goes away.
pContext
Contains a value that is passed if the pfnVideoPortClose callback function is ever called.

DDOPENVIDEOPORTOUT

The DDOPENVIDEOPORTOUT structure contains a DirectDraw return code and a new surface handle if ddRVal is set to DD_OK. This new handle must be used on all subsequent calls that require a VPE object handle.

typedef struct _DDOPENVIDEOPORTOUT {
  DWORD  ddRVal;
  HANDLE  hVideoPort;
} DDOPENVIDEOPORTOUT, FAR *LPDDOPENVIDEOPORTOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
hVideoPort
Contains the new VPE object handle.


DD_DXAPI_OPENVPCAPTUREDEVICE

DD_DXAPI_OPENVPCAPTUREDEVICE opens the device for capture.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDOPENVPCAPTUREDEVICEIN structure that contains the relevant VPE object information required for the capture.
lpvOutBuffer
Points to a DDOPENVPCAPTUREDEVICEOUT structure that contains the new capture handle.

Comments

A VPE capture device allows hardware video port data to be automatically bus mastered from the surface to a specified buffer. Opening the capture device determines which lines are to be captured. For example, for VBI the capture driver may only be interested in the first 21 lines. If the capture driver wants to capture different regions to different buffers (for example, VBI and video to separate buffers), multiple capture devices can be created.

When a capture device is created, the kernel-mode video transport creates a queue for each device. The driver can later add buffers to this queue. Each time the hardware video port V-sync occurs, the kernel-mode video transport automatically initiates the correct bus masters from the frame buffer surface most recently filled by the hardware video port to the buffer in the queue. If you don't want to capture on every field, you can indicate this by setting the dwCaptureEveryNFields member of the DDOPENVPCAPTUREDEVICEIN structure to something other than 1.

The hDirectDraw and hVideoPort members of the DDOPENVPCAPTUREDEVICEIN structure specify the DirectDraw object and VPE object from which you want to capture. The dwStartLine and dwEndLine members indicate which lines are to be captured. The dwStartLine member is relative to the start of the surface (0 is the first line) and dwEndLine is inclusive (setting dwStartLine and dwEndLine to 0 causes the first line to be captured).

The driver must also specify a callback that is called when the capture device becomes unusable due to the VPE object being released at user mode. The pContext member of the DDOPENVPCAPTUREDEVICEIN structure contains a value that is passed if the pfnCaptureClose callback function is ever called.

If ddRVal is set to DD_OK, the output from this function identifier is a DirectDraw return code and a new capture handle. This new handle must be used on all subsequent calls that reference this capture device.

This function identifier can only be called at passive level.

DDOPENVPCAPTUREDEVICEIN

The DDOPENVPCAPTUREDEVICEIN structure contains the VPE capture information.

typedef struct _DDOPENVPCAPTUREDEVICEIN {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
  DWORD  dwStartLine;
  DWORD  dwEndLine;
  DWORD  dwCaptureEveryNFields;
  LPDD_NOTIFYCALLBACK  pfnCaptureClose;
  PVOID  pContext;
  DWORD  dwFlags;
} DDOPENVPCAPTUREDEVICEIN, FAR * LPDDOPENVPCAPTUREDEVICEIN;

Members

hDirectDraw
Specifies the DirectDraw handle from which the capture takes place.
hVideoPort
Specifies the VPE object handle from which the capture takes place.
dwStartLine
Indicates the starting line of the capture. This member is relative to the start of the surface (0 is the first line).
dwEndLine
Indicates the last line of the capture (inclusive).
dwCaptureEveryNFields
Contains a value that is the divisor for the number of fields that are to be captured per second. A field is a region that typically contains 240 lines, in which two fields make up a frame. Fields come at a rate of approximately 60 per second. To capture all 60 fields per second, set this value to 1, to capture 30 fields per second, set this value to 2, to capture 15 fields per second, set this field to 4, and so on.
pfnCaptureClose
Points to a pfnCaptureClose callback that is called when the capture device becomes unusable due to the VPE object being released at user mode.
pContext
Contains the value that is passed if the pfnCaptureClose callback is ever called.
dwFlags
One of the following:
Flag | Meaning
DDOPENCAPTURE_VBI | Capture from the VBI stream.
DDOPENCAPTURE_VIDEO | Capture from the video stream.

DDOPENVPCAPTUREDEVICEOUT

The DDOPENVPCAPTUREDEVICEOUT structure contains the VPE capture handle.

typedef struct _DDOPENVPCAPTUREDEVICEOUT {
  DWORD  ddRVal;
  HANDLE  hCapture;
} DDOPENVPCAPTUREDEVICEOUT,
FAR * LPDDOPENVPCAPTUREDEVICEOUT;

Members

ddRVal
Specifies the location in which the driver writes the return value. A return code of DD_OK indicates success.
hCapture
Contains the new VPE capture handle.


DD_DXAPI_REGISTER_CALLBACK

DD_DXAPI_REGISTER_CALLBACK allows the client to register a callback that is called when an event occurs.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDREGISTERCALLBACK structure that contains the information required to register a callback.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

This function identifier can only register a single event at a time. If the client wants to be called for multiple events, it must call DD_DXAPI_REGISTER_CALLBACK multiple times.

The IRQ events are actually called at IRQ time, so the callback function must return quickly and only perform calls that are safe.

The pContext member of the DDREGISTERCALLBACK structure contains client data that is passed back to the client when the pfnDirectDrawClose callback is called.

This function identifier can only be called at passive level.

DDREGISTERCALLBACK

The DDREGISTERCALLBACK structure contains the register callback information. This structure is used by both the DD_DXAPI_REGISTER_CALLBACK and DD_DXAPI_UNREGISTER_CALLBACK function identifiers of the DxApi function.

typedef struct _DDREGISTERCALLBACK {
  HANDLE  hDirectDraw;
  ULONG  dwEvents;
  LPDD_NOTIFYCALLBACK  pfnCallback;
  ULONG_PTR  dwParam1;
  ULONG_PTR  dwParam2;
  PVOID  pContext;
} DDREGISTERCALLBACK, FAR *LPDDREGISTERCALLBACK;

Members

hDirectDraw
Specifies the DirectDraw handle.
dwEvents
Defines the event that should trigger the callback. The values in dwParam1 and dwParam2 depend on the event. The following events are defined:
Event Description dwParam1,
dwParam2
DDEVENT_DISPLAY_VSYNC Called every time a display V-sync occurs. unused,
unused
DDEVENT_POSTDOSBOX Called after returning from a full-screen MS-DOS® box. unused,
unused
DDEVENT_POSTRESCHANGE Called after a mode change occurs. unused,
unused
DDEVENT_PREDOSBOX Called before entering a full-screen MS-DOS box. unused,
unused
DDEVENT_PRERESCHANGE Called before a mode change occurs. unused,
unused
DDEVENT_VP_LINE Sets an IRQ to occur each time the hardware video port writes the specified line and then calls the callback each time the IRQ is triggered. hVideoPort,
line
DDEVENT_VP_VSYNC Called each time a hardware video port V-sync occurs. hVideoPort,
unused

pfnCallback
Points to a pfnCallback callback function that is called if the DirectDraw object goes away.
dwParam1
Is defined by the dwEvent member.
dwParam2
Is defined by the dwEvent member.
pContext
Contains client data that is passed back to the client if the pfnCallback callback function is called.


DD_DXAPI_SET_SURFACE_STATE

DD_DXAPI_SET_SURFACE_STATE allows the client to switch the overlay surface between bob and weave mode.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDSETSURFACESTATE structure that contains the requested surface state information.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

The dwState member of the DDSETSURFACESTATE structure contains the new state, which can be either DDSTATE_BOB or DDSTATE_WEAVE.

If the surface is associated with a hardware video port, it is possible to indicate that you would like the state change to occur at a future time. In this instance, dwStartField indicates the field on which the state change should occur. A value of 0 indicates it should occur at the start of the next field, a value of one indicates the start of the following field, and so on.

This function identifier can be called at raised IRQL.

DDSETSURFACESTATE

The DDSETSURFACESTATE structure contains the surface state information.

typedef struct _DDSETSURFACETATE {
  HANDLE  hDirectDraw;
  HANDLE  hSurface;
  DWORD  dwState;
  DWORD  dwStartField;
} DDSETSURFACESTATE, FAR *LPDDSETSURFACESTATE;

Members

hDirectDraw
Specifies the DirectDraw handle.
hSurface
Specifies the DirectDrawSurface handle.
dwState
Indicates the surface state. One of the following:
Flag | Meaning
DDSTATE_BOB | Bob mode is to be used on this surface.
DDSTATE_WEAVE | Weave mode is to be used on this surface.

dwStartField
Indicates the field on which the state change should occur. A value of 0 indicates it should occur at the start of the next field, a value of 1 indicates the start of the following field, and so on.


DD_DXAPI_SET_VP_FIELD_NUMBER

DD_DXAPI_SET_VP_FIELD_NUMBER sets the internal field number for the specified VPE object to the specified value.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Pointsto a DDSETFIELDNUM structure that specifies the appropriate handles and the field number to be set.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

The internal field number is returned using the DD_DXAPI_GET_VP_FIELD_NUMBER function identifier and the DD_DXAPI_ADDVPCAPTUREBUFFER function identifier.

This function identifier can be called at raised IRQL.

DDSETFIELDNUM

The DDSETFIELDNUM structure contains the handles and the field number.

typedef struct _DDSETFIELDNUM {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
  DWORD  dwFieldNum;
} DDSETFIELDNUM, FAR *LPDDSETFIELDNUM;

Members

hDirectDraw
Specifies the DirectDraw handle.
hVideoPort
Specifies the VPE object handle.
dwFieldNum
Specifies the hardware video port's field number to be set.


DD_DXAPI_SET_VP_SKIP_FIELD

DD_DXAPI_SET_VP_SKIP_FIELD indicates that the hardware video port should not write a future field into the frame buffer. This is useful primarily for undoing the 3:2 pattern often introduced in some video content.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDSETSKIPFIELD structure that contains the VPE object information and the number of the start field.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

This function identifier only skips a single field and must be called explicitly for each field that needs to be skipped. If VBI data is present in the field, the VBI portion if the data is not skipped.

This function identifier can be called at raised IRQL.

DDSETSKIPFIELD

The DDSETSKIPFIELD structure contains the start field information.

typedef struct _DDSETSKIPFIELD {
  HANDLE  hDirectDraw;
  HANDLE  hVideoPort;
  DWORD  dwStartField;
} DDSETSKIPFIELD, FAR *LPDDSETSKIPFIELD;

Members

hDirectDraw
Specifies the DirectDraw handle.
hVideoPort
Specifies the VPE object handle.
dwStartField
Indicates the field that needs to be skipped and is relative to the current field. A value of 0 indicates it should skip the next field, a value of 1 indicates the field after that, and so on.


DD_DXAPI_UNREGISTER_CALLBACK

DD_DXAPI_UNREGISTER_CALLBACK allows the client to unregister a previously-registered callback. This function identifier can only unregister one event at a time.

When this function identifier is used as the dwFunctionNum parameter of the DxApi function, the input and output buffer parameters of DxApi are defined as:

lpvInBuffer
Points to a DDREGISTERCALLBACK structure that contains the information required to unregister a callback.
lpvOutBuffer
Points to a DWORD (ddRVal) that contains the DirectDraw return value.

Comments

The parameters are identical to those of the DD_DXAPI_REGISTER_CALLBACK function identifier.

This function identifier can only be called at passive level.


DxBobNextField

DxBobNextField bobs the next field of interleaved data.

DWORD
  (*PDX_BOBNEXTFIELD)(
    PVOID  HwDeviceExtension,
    PDDBOBNEXTFIELDINFO  BobNextFieldInfo,
    PVOID  lpOutput
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
BobNextFieldInfo
Points to a DDBOBNEXTFIELDINFO structure that contains the bob information for the surface.
lpOutput
Is reserved for system use.

Return Value

DxBobNextField returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

When data is interleaved, DdFlip is called every other frame. This is insufficient for bob because it must be notified after every V-sync. This function is called when a V-sync does not cause a flip.

DDBOBNEXTFIELDINFO

The DDBOBNEXTFIELDINFO structure contains the bob information for the surface.

typedef struct _DDBOBNEXTFIELDINFO {
  LPDDSURFACEDATA  lpSurface;
} DDBOBNEXTFIELDINFO, *PDDBOBNEXTFIELDINFO;

Members

lpSurface
Points to a DDSURFACEDATA structure that represents the surface.


DxEnableIRQ

DxEnableIRQ indicates to the miniport which IRQs should be enabled or disabled.

DWORD
  (*PDX_ENABLEIRQ)(
    PVOID  HwDeviceExtension,
    PDDENABLEIRQINFO  EnableIrqInfo,
    PVOID  lpOutput
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
EnableIrqInfo
Points to the DDENABLEIRQINFO structure that contains the information required to enable interrupts.
lpOutput
Is reserved for system use.

Return Value

DxEnableIRQ returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

The dwIRQSources member of the DDENABLEIRQINFO structure contains the DDIRQ_xxx flags that are set for every IRQ that should be enabled. If an IRQ is not specified in this call, it should be disabled. If the requested combination cannot be supported, this function fails.

Because the miniport must always manage its own IRQ, it needs to call the specified IRQCallback when an IRQ occurs. When calling IRQCallback, the dwIRQFlags member of the DX_IRQDATA structure passed to IRQCallback contains the DDIRQ_xxxx flags that indicate what caused the IRQ.

DDENABLEIRQINFO

The DDENABLEIRQINFO structure contains the information required to enable interrupts.

typedef struct _DDENABLEIRQINFO {
  DWORD  dwIRQSources;
  DWORD  dwLine;
  PDX_IRQCALLBACK  IRQCallback;
  PDX_IRQDATA  lpIRQData;
} DDENABLEIRQINFO, *PDDENABLEIRQINFO;

Members

dwIRQSources
Indicates the interrupts that should be enabled. One or more of the following:
Flag | Meaning
DDIRQ_DISPLAY_VSYNC | The device can generate IRQs based on the display V-sync.
DDIRQ_VPORT0_LINE | The device can generate IRQs based on a programmable line for hardware video port number 0.
DDIRQ_VPORT0_VSYNC | The device can generate V-sync IRQs for hardware video port number 0.
DDIRQ_VPORT1_LINE | The device can generate IRQs based on a programmable line for hardware video port number 1.
DDIRQ_VPORT1_VSYNC | The device can generate V-sync IRQs for hardware video port number 1.
DDIRQ_VPORT2_LINE | The device can generate IRQs based on a programmable line for hardware video port number 2.
DDIRQ_VPORT2_VSYNC | The device can generate V-sync IRQs for hardware video port number 2.
DDIRQ_VPORT3_LINE | The device can generate IRQs based on a programmable line for hardware video port number 3.
DDIRQ_VPORT3_VSYNC | The device can generate V-sync IRQs for hardware video port number 3.
DDIRQ_VPORT4_LINE | The device can generate IRQs based on a programmable line for hardware video port number 4.
DDIRQ_VPORT4_VSYNC | The device can generate V-sync IRQs for hardware video port number 4.
DDIRQ_VPORT5_LINE | The device can generate IRQs based on a programmable line for hardware video port number 5.
DDIRQ_VPORT5_VSYNC | The device can generate V-sync IRQs for hardware video port number 5.
DDIRQ_VPORT6_LINE | The device can generate IRQs based on a programmable line for hardware video port number 6.
DDIRQ_VPORT6_VSYNC | The device can generate V-sync IRQs for hardware video port number 6.
DDIRQ_VPORT7_LINE | The device can generate IRQs based on a programmable line for hardware video port number 7.
DDIRQ_VPORT7_VSYNC | The device can generate V-sync IRQs for hardware video port number 7.
DDIRQ_VPORT8_LINE | The device can generate IRQs based on a programmable line for hardware video port number 8.
DDIRQ_VPORT8_VSYNC | The device can generate V-sync IRQs for hardware video port number 8.
DDIRQ_VPORT9_LINE | The device can generate IRQs based on a programmable line for hardware video port number 9.
DDIRQ_VPORT9_VSYNC | The device can generate V-sync IRQs for hardware video port number 9.

dwLine
Indicates which line should generate the IRQ. If the hardware does not have the ability to generate an IRQ based on a programmable line, the value in this member is meaningless.
IRQCallback
Points to an IRQCallback that the miniport calls when the miniport is managing IRQs, and an IRQ occurs.
lpIRQData
Points to the data to be sent to IRQCallback when IRQCallback is called.

Comments

The dwIRQSources member of this structure does not use the DDIRQ_BUSMASTER flag. However, the DDIRQ_BUSMASTER flag can be set in the dwIrqFlags member of the DX_IRQDATA structure accessed by the IRQCallback function the driver calls when an IRQ occurs.


DxFlipOverlay

DxFlipOverlay is called when a miniport client wants to flip the overlay or when autoflipping is enabled.

DWORD
  (*PDX_FLIPOVERLAY)(
    PVOID  HwDeviceExtension,
    PDDFLIPOVERLAYINFO  FlipOverlayInfo,
    PVOID  lpOutput
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
FlipOverlayInfo
Points to the DDFLIPOVERLAYINFO structure that contains the flip information for the surface.
lpOutput
Is reserved for system use.

Return Value

DxFlipOverlay returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

If a hardware video port is not used and the client still wants the overlay to bob the data, the dwFlags member of the DDFLIPOVERLAYINFO structure specifies the polarity of the data in the field being flipped (using the DDFLIP_EVEN or DDFLIP_ODD flags). These flags are not used when flipping a surface that is fed by a hardware video port.

DDFLIPOVERLAYINFO

The DDFLIPOVERLAYINFO structure contains the flip information for the surface.

typedef struct _DDFLIPOVERLAYINFO {
  LPDDSURFACEDATA  lpCurrentSurface;
  LPDDSURFACEDATA  lpTargetSurface;
  DWORD  dwFlags;
} DDFLIPOVERLAYINFO, *PDDFLIPOVERLAYINFO;

Members

lpCurrentSurface
Points to a DDSURFACEDATA structure that contains information about the current surface.
lpTargetSurface
Points to a DDSURFACEDATA structure that contains information about the target surface.
dwFlags
Specifies the polarity of the data in the field being flipped. One of the following:
Flag | Meaning
DDFLIP_EVEN | The target surface contains the even field of video data.
DDFLIP_ODD | The target surface contains the odd field of video data.


DxFlipVideoPort

DxFlipVideoPort is called when a miniport client wants to flip the VPE object or when autoflipping is enabled.

DWORD
  (*PDX_FLIPVIDEOPORT)(
    PVOID  HwDeviceExtension,
    PDDFLIPVIDEOPORTINFO  FlipVideoPortInfo,
    PVOID  lpOutput
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
FlipVideoPortInfo
Points to the DDFLIPVIDEOPORTINFO structure that contains the flip information for the surface and VPE object.
lpOutput
Is reserved for system use.

Return Value

DxFlipVideoPort returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

The dwFlipVPFlags member of the DDFLIPVIDEOPORTINFO structure uses the DDVPFLIP_VIDEO or DDVPFLIP_VBI flags to indicate whether the surfaces represent VBI surfaces or regular surfaces.

DDFLIPVIDEOPORTINFO

The DDFLIPVIDEOPORTINFO structure contains the VPE object and surface information.

typedef struct _DDFLIPVIDEOPORTINFO {
  LPDDVIDEOPORTDATA  lpVideoPortData;
  LPDDSURFACEDATA  lpCurrentSurface;
  LPDDSURFACEDATA  lpTargetSurface;
  DWORD  dwFlipVPFlags;
} DDFLIPVIDEOPORTINFO *PDDFLIPVIDEOPORTINFO;

Members

lpVideoPortData
Points to a DDVIDEOPORTDATA structure that contains the VPE object information.
lpCurrentSurface
Points to a DDSURFACEDATA structure that contains information about the current surface.
lpTargetSurface
Points to a DDSURFACEDATA structure that contains information about the target surface.
dwFlipVPFlags
Indicates whether the surfaces represent VBI surfaces or regular surfaces. One of the following:
Flag | Meaning
DDVPFLIP_VBI | Flip the VBI surface.
DDVPFLIP_VIDEO | Flip the normal video surface.


DxGetCurrentAutoflip

DxGetCurrentAutoflip is called when the device is hardware autoflipping and a miniport client wants to know which surface is receiving the current field of video data for capture purposes.

DWORD
  (*PDX_GETCURRENTAUTOFLIP)(
    PVOID HwDeviceExtension,
    PDDGETCURRENTAUTOFLIPININFO  GetCurrentAutoflipInInfo,
    PDDGETCURRENTAUTOFLIPOUTINFO  GetCurrentAutoflipOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
GetCurrentAutoflipInInfo
Points to the DDGETCURRENTAUTOFLIPININFO structure that contains the VPE object information.
GetCurrentAutoflipOutInfo
Points to the DDGETCURRENTAUTOFLIPOUTINFO structure that contains the surface information.

Return Value

DxGetCurrentAutoflip returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

The DxGetCurrentAutoflip function returns the current index in the autoflip chain of the current surface in the dwSurfaceIndex member of the DDGETCURRENTAUTOFLIPOUTINFO structure.

DDGETCURRENTAUTOFLIPININFO

The DDGETCURRENTAUTOFLIPININFO structure contains the VPE object information.

typedef struct _DDGETCURRENTAUTOFLIPININFO {
  LPDDVIDEOPORTDATA  lpVideoPortData;
} DDGETCURRENTAUTOFLIPININFO, *PDDGETCURRENTAUTOFLIPININFO;

Members

lpVideoPortData
Points to a DDVIDEOPORTDATA structure that contains the VPE object information.

DDGETCURRENTAUTOFLIPOUTINFO

The DDGETCURRENTAUTOFLIPOUTINFO structure provides the surface information.

typedef struct _DDGETCURRENTAUTOFLIPOUTINFO {
  DWORD  dwSurfaceIndex;
  DWORD  dwVBISurfaceIndex;
} DDGETCURRENTAUTOFLIPOUTINFO, *PDDGETCURRENTAUTOFLIPOUTINFO;

Members

dwSurfaceIndex
Specifies the current index in the autoflip chain of the current surface.
dwVBISurfaceIndex
Specifies the current index in the autoflip chain of the current VBI surface.


DxGetIRQInfo

DxGetIRQInfo indicates which interrupts the driver supports.

DWORD
  (*PDX_GETIRQINFO)(
    PVOID  HwDeviceExtension,
    PVOID  lpInput,
    PDDGETIRQINFO  GetIrqInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
lpInput
Is reserved for system use.
GetIrqInfo
Points to a DDGETIRQINFO structure that contains the interrupt information.

Return Value

DxGetIrqInfo returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

Because the miniport must always manage the IRQ, this function must always set the dwFlags member of the DDGETIRQINFO structure to IRQINFO_HANDLED. If any other flag is set, this function will fail.

DDGETIRQINFO

The DDGETIRQINFO structure contains interrupt information for the miniport.

typedef struct _DDGETIRQINFO {
  DWORD  dwFlags;
} DDGETIRQINFO, *PDDGETIRQINFO;

Members

dwFlags
Specifies the interrupt management status.
IRQINFO_HANDLED
The miniport is managing the interrupt.


DxGetPolarity

DxGetPolarity returns the polarity (even or odd) of the current field being written by the VPE object.

DWORD
  (*PDX_GETPOLARITY)(
    PVOID  HwDeviceExtension,
    PDDGETPOLARITYININFO  GetPolarityInInfo,
    PDDGETPOLARITYOUTINFO  GetPolarityOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
GetPolarityInInfo
Points to a DDGETPOLARITYININFO structure that contains the VPE object from which to get the polarity information.
GetPolarityOutInfo
Points to a DDGETPOLARITYOUTINFO structure that contains the polarity information for the specified VPE object.

Return Value

DxGetPolarity returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

DDGETPOLARITYININFO

The DDGETPOLARITYININFO structure contains the VPE object information.

typedef struct _DDGETPOLARITYININFO {
  LPDDVIDEOPORTDATA  lpVideoPortData;
} DDGETPOLARITYININFO, *PDDGETPOLARITYININFO;

Members

lpVideoPortData
Points to a DDVIDEOPORTDATA structure that contains the VPE object information.

DDGETPOLARITYOUTINFO

The DDGETPOLARITYOUTINFO structure contains the polarity information of the VPE object.

typedef struct _DDGETPOLARITYOUTINFO {
  DWORD  bPolarity;
} DDGETPOLARITYOUTINFO, *PDDGETPOLARITYOUTINFO;

Members

bPolarity
Indicates the polarity (even or odd) of the current field being written by the VPE object.


DxGetPreviousAutoflip

DxGetPreviousAutoflip is called when the device is hardware autoflipping and a miniport client wants to know which surface received the previous field of video data for capture purposes.

DWORD
  (*PDX_GETPREVIOUSAUTOFLIP)(
    PVOID  HwDeviceExtension,
    PDDGETPREVIOUSAUTOFLIPININFO  GetPreviousAutoflipInInfo,
    PDDGETPREVIOUSAUTOFLIPOUTINFO  GetPreviousAutoflipOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
GetPreviousAutoflipInInfo
Points to a DDGETPREVIOUSAUTOFLIPININFO structure that contains the VPE object information.
GetPreviousAutoflipOutInfo
Points to a DDGETPREVIOUSAUTOFLIPOUTINFO structure that contains the index of the autoflip chain.

Return Value

DxGetPreviousAutoflip returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

If interleaving, the surface that received the previous field may be the same surface that is receiving the current field.

DxGetPreviousAutoflip returns the index in the autoflip chain of the correct surface in the dwSurfaceIndex member of the DDGETPREVIOUSAUTOFLIPOUTINFO structure.

DDGETPREVIOUSAUTOFLIPININFO

The DDGETPREVIOUSAUTOFLIPININFO structure provides the VPE object information.

typedef struct _DDGETPREVIOUSAUTOFLIPININFO {
  LPDDVIDEOPORTDATA  lpVideoPortData;
} DDGETPREVIOUSAUTOFLIPININFO, *PDDGETPREVIOUSAUTOFLIPININFO;

Members

lpVideoPortData
Points to a DDVIDEOPORTDATA structure that contains the VPE object information.

DDGETPREVIOUSAUTOFLIPOUTINFO

The DDGETPREVIOUSAUTOFLIPOUTINFO structure provides the surface data.

typedef struct _DDGETPREVIOUSAUTOFLIPOUTINFO {
  DWORD  dwSurfaceIndex;
  DWORD  dwVBISurfaceIndex;
} DDGETPREVIOUSAUTOFLIPOUTINFO, *PDDGETPREVIOUSAUTOFLIPOUTINFO;

Members

dwSurfaceIndex
Specifies the current index in the autoflip chain of the current surface.
dwVBISurfaceIndex
Specifies the current index in the autoflip chain of the current VBI surface.


DxGetTransferStatus

DxGetTransferStatus is used by DirectDraw to determine which hardware bus master has completed.

DWORD
  (*PDX_GETTRANSFERSTATUS)(
    PVOID  HwDeviceExtension,
    PVOID  lpInput,
    PDDGETTRANSFEROUTINFO  GetTransferOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
lpInput
Is reserved for system use.
GetTransferOutInfo
Points to a DDGETTRANSFERSTATUSOUTINFO structure contains the transfer status information.

Return Value

DxGetTransferStatus returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

The driver identifies the bus master by supplying the transfer ID in the DDGETTRANSFERSTATUSOUTINFO structure. The transfer ID for each bus master is originally supplied by DirectDraw in the dwTransferID member of the DDTRANSFERININFO structure.)

DDGETTRANSFERSTATUSOUTINFO

The DDGETTRANSFERSTATUSOUTINFO structure contains the transfer status information.

typedef struct _DDGETTRANSFERSTATUSOUTINFO {
  DWORD  dwTransferID;
} DDGETTRANSFERSTATUSOUTINFO, *PDDGETTRANSFEROUTINFO;

Members

dwTransferID
Contains the transfer ID of the bus master that completed. The transfer ID was originally supplied to the driver in the dwTransferID member of the DDTRANSFERININFO structure.


DxLock

DxLock is called when a miniport client wants access to the frame buffer.

DWORD
  (*PDX_GETTRANSFERSTATUS)(
    PVOID  HwDeviceExtension,
    PDDLOCKININFO  LockInInfo,
    PDDLOCKOUTINFO  LockOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
LockInInfo
Points to a DDLOCKININFO structure that contains the surface information for the lock.
LockOutInfo
Points to a DDLOCKOUTINFO structure that contains the surface in the frame buffer.

Return Value

DxLock returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

DDLOCKININFO

The DDLOCKININFO structure contains the surface information.

typedef struct _DDLOCKININFO {
  LPDDSURFACEDATA  lpSurfaceData;
} DDLOCKININFO, *PDDLOCKININFO;

Members

lpSurfaceData
Points to a DDSURFACEDATA structure that contains the surface information.

DDLOCKOUTINFO

The DDLOCKOUTINFO structure contains the surface information output from the DxLock function.

typedef struct _DDLOCKOUTINFO {
  ULONG_PTR  dwSurfacePtr;
} DDLOCKOUTINFO, *PDDLOCKOUTINFO;

Members

dwSurfacePtr
Points to the surface in the frame buffer.


DxSetState

DxSetState is called when a miniport client decides it wants to switch from bob mode to weave mode, and vice versa.

DWORD
  (*PDX_SETSTATE)(
    PVOID  HwDeviceExtension,
    PDDSETSTATEININFO  SetStateInInfo,
    PDDSETSTATEOUTINFO  SetStateOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
SetStateInInfo
Points to a DDSETSTATEININFO structure that contains the surface and VPE object information.
SetStateOutInfo
Points to a DDSETSTATEOUTINFO structure that contains the state information for the hardware video port.

Return Value

DxSetState returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

The surface data passed contains the new state. If the new state is not supported, the miniport should fail the call.

If the new state requires the device to revert from hardware autoflipping to software autoflipping, the miniport should set the dwSoftwareAutoflip member of the DDSTATEOUTINFO structure equal to 1 and set dwSurfaceIndex equal to the current position in the autoflip list of the surface receiving hardware video port data.

DDSETSTATEININFO

The DDSETSTATEININFO structure contains the surface and VPE object information.

typedef struct _DDSETSTATEININFO {
  LPDDSURFACEDATA  lpSurfaceData;
  LPDDVIDEOPORTDATA  lpVideoPortData;
} DDSETSTATEININFO, *PDDSETSTATEININFO;

Members

lpSurfaceData
Points to a DDSURFACEDATA structure that contains the surface information.
lpVideoPortData
Points to a DDVIDEOPORTDATA structure that contains the VPE object information.

DDSETSTATEOUTINFO

The DDSETSTATEOUTINFO structure contains the state information for the VPE object.

typedef struct _DDSETSTATEOUTINFO {
  BOOL   bSoftwareAutoflip;
  DWORD  dwSurfaceIndex;
  DWORD  dwVBISurfaceIndex;
} DDSETSTATEOUTINFO, *PDDSETSTATEOUTINFO;

Members

bSoftwareAutoflip
When set to a non-zero value, causes DirectDraw to revert to software autoflipping. Note that once software autoflipping has been initiated, you cannot revert back to hardware autoflipping until the VPE object and surface are destroyed and restarted.
dwSurfaceIndex
Indicates the index in the autoflip chain of the surface currently receiving the data from the VPE object. This field is ignored unless the miniport driver is switching from hardware autoflipping to software autoflipping.
dwVBISurfaceIndex
Indicates the index in the autoflip chain of the VBI surface currently receiving the data from the VPE object. This field is ignored unless the miniport is switching from hardware autoflipping to software autoflipping.

Comments

When asked to switch from bob to weave, the miniport may need to switch from hardware autoflipping to software autoflipping (no current hardware supports automatic field skipping, and so on). All the driver has to do is set the dwSoftwareAutoflip member to a non-zero value and DirectDraw will revert to software autoflipping.

If the miniport driver switches from hardware to software autoflipping, DirectDraw must know which surface is currently receiving data from the VPE object so it can continue without causing a glitch. Therefore, the miniport driver must set the dwSurfaceIndex member to the index in the autoflip chain of the surface currently receiving the data from the VPE object. When DdVideoPortUpdate is called, it gives an array of surfaces that you can autoflip between. You can then program these addresses into your hardware when you software autoflip.


DxSkipNextField

DxSkipNextField is called when the next field needs to be skipped or re-enabled.

DWORD
  (*PDX_SKIPNEXTFIELD)(
    PVOID  HwDeviceExtension,
    PDDSKIPNEXTFIELDINFO  SkipNextFieldInfo,
    PVOID  lpOutput
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
SkipNextFieldInfo
Points to a DDSKIPNEXTFIELDINFO structure that contains the skip information for the VPE object.
lpOutput
Is reserved for system use.

Return Value

DxSkipNextField returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

If the dwSkipFlags member of the DDSKIPNEXTFIELDINFO structure is DDSKIP_SKIPNEXT, the following field should be skipped. If the vertical blanking interval (VBI) height is greater than zero, only the video data should be skipped (not the VBI data). If dwSkipFlags is set to DDSKIP_ENABLENEXT, the next field should be restored.

DDSKIPNEXTFIELDINFO

The DDSKIPNEXTFIELDINFO structure contains the skip information for the VPE object.

typedef struct _DDSKIPNEXTFIELDINFO {
  LPDDVIDEOPORTDATA  lpVideoPortData;
  DWORD  dwSkipFlags;
} DDSKIPNEXTFIELDINFO, *PDDSKIPNEXTFIELDINFO;

Members

lpVideoPortData
Points to a DDVIDEOPORTDATA structure that represents the VPE object.
dwSkipFlags
Indicates whether to skip the next field. One of the following:
Flag | Meaning
DDSKIP_ENABLENEXT | The next field should be restored.
DDSKIP_SKIPNEXT | The next field should be skipped.


DxTransfer

DxTransfer tells the driver to bus master data from a surface to the buffer specified in the memory descriptor list (MDL).

DWORD
  (*PDX_TRANSFER)(
    PVOID  HwDeviceExtension,
    PDDTRANSFERININFO  TransferInInfo,
    PDDTRANSFEROUTINFO  TransferOutInfo
    );

Parameters

HwDeviceExtension
Points to the miniport driver's device extension.
TransferInInfo
Points to a DDTRANSFERININFO structure that contains the transfer information for the surface.
TransferOutInfo
Points to a DDTRANSFEROUTINFO structure that contains the polarity of the field being captured.

Return Value

DxTransfer returns DX_OK if it succeeds; otherwise, it returns one of the following error values:

DXERR_GENERIC

DXERR_OUTOFCAPS

DXERR_UNSUPPORTED

Comments

The MDL is defined in the WDM documentation.

DxTransfer is called at hardware interrupt time. This means the driver cannot wait for a previous bus master to complete and it cannot call any functions that are not safe to call at interrupt time (that is, most of them).

In addition, the driver should not fail the call just because the hardware is currently busy. Instead, the driver should maintain an internal queue.

DDTRANSFERININFO

The DDTRANSFERININFO structure contains the transfer information for the surface

typedef struct _DDTRANSFERININFO {
  LPDDSURFACEDATA  lpSurfaceData;
  DWORD  dwStartLine;
  DWORD  dwEndLine;
  ULONG_PTR  dwTransferID;
  DWORD  dwTransferFlags;
  PMDL  lpDestMDL;
} DDTRANSFERININFO, *PDDTRANSFERININFO;

Members

lpSurfaceData
Points to a DDSURFACEDATA structure that represents the surface that contains the information to be transferred. The information in this structure is supplied by DirectDraw.
dwStartLine
Indicates the first line in the surface from which data will be transferred.
dwEndLine
Indicates the last line in the surface from which data will be transferred, inclusive.
dwTransferID
Specifies an identification for the transfer supplied by DirectDraw. This transfer ID is used by the driver in the DDGETTRANSFERSTATUSOUTINFO structure.
dwTransferFlags
Indicates the type of transfer. One of the following:
Flag | Meaning
DDTRANSFER_CANCEL | DirectDraw previously requested a transfer, but is now canceling that request.
DDTRANSFER_HALFLINES | Due to half line issues, the odd field contains an extra line of useless data at the top that the driver must account for.
DDTRANSFER_INVERT | During bus mastering, the capture driver is requesting an inversion.
DDTRANSFER_NONLOCALVIDMEM | The transfer is from display memory to AGP memory.
DDTRANSFER_SYSTEMMEMORY | The transfer is from display memory to system memory.

lpDestMDL
Points to a destination MDL structure.

DDTRANSFEROUTINFO

The DDTRANSFEROUTINFO structure returns the polarity of the field being captured.

typedef struct _DDTRANSFEROUTINFO {
  DWORD  dwBufferPolarity;
} DDTRANSFEROUTINFO, *PDDTRANSFEROUTINFO;

Members

dwBufferPolarity
Specifies the polarity of the field being captured. This value is set to true if the current video field is the even field of an interlaced video signal and false otherwise.


IRQCallback

IRQCallback points to a DirectDraw structure that is filled in by the driver with the information about the IRQ that has occurred.

VOID
  (*PDX_IRQCALLBACK) (
    PDX_IRQDATA  pIrqData
    );

Parameters

pIrqData
Points to the DX_IRQDATA structure that will be filled in with the driver's IRQ information.

DX_IRQDATA

The DX_IRQDATA structure contains the IRQ information supplied by the driver.

typedef struct _DX_IRQDATA {
  DWORD  dwIrqFlags;
} DX_IRQDATA, *PDX_IRQDATA;

Members

dwIrqFlags
Specifies the type of IRQ that has occurred. One or more of the following:
Flag | Meaning
DDIRQ_BUSMASTER | The IRQ was generated because a transfer request was completed.
DDIRQ_DISPLAY_VSYNC | The device can generate IRQs based on the display V-sync.
DDIRQ_VPORT0_LINE | The device can generate IRQs based on a programmable line for hardware video port number 0.
DDIRQ_VPORT0_VSYNC | The device can generate V-sync IRQs for hardware video port number 0.
DDIRQ_VPORT1_LINE | The device can generate IRQs based on a programmable line for hardware video port number 1.
DDIRQ_VPORT1_VSYNC | The device can generate V-sync IRQs for hardware video port number 1.
DDIRQ_VPORT2_LINE | The device can generate IRQs based on a programmable line for hardware video port number 2.
DDIRQ_VPORT2_VSYNC | The device can generate V-sync IRQs for hardware video port number 2.
DDIRQ_VPORT3_LINE | The device can generate IRQs based on a programmable line for hardware video port number 3.
DDIRQ_VPORT3_VSYNC | The device can generate V-sync IRQs for hardware video port number 3.
DDIRQ_VPORT4_LINE | The device can generate IRQs based on a programmable line for hardware video port number 4.
DDIRQ_VPORT4_VSYNC | The device can generate V-sync IRQs for hardware video port number 4.
DDIRQ_VPORT5_LINE | The device can generate IRQs based on a programmable line for hardware video port number 5.
DDIRQ_VPORT5_VSYNC | The device can generate V-sync IRQs for hardware video port number 5.
DDIRQ_VPORT6_LINE | The device can generate IRQs based on a programmable line for hardware video port number 6.
DDIRQ_VPORT6_VSYNC | The device can generate V-sync IRQs for hardware video port number 6.
DDIRQ_VPORT7_LINE | The device can generate IRQs based on a programmable line for hardware video port number 7.
DDIRQ_VPORT7_VSYNC | The device can generate V-sync IRQs for hardware video port number 7.
DDIRQ_VPORT8_LINE | The device can generate IRQs based on a programmable line for hardware video port number 8.
DDIRQ_VPORT8_VSYNC | The device can generate V-sync IRQs for hardware video port number 8.
DDIRQ_VPORT9_LINE | The device can generate IRQs based on a programmable line for hardware video port number 9.
DDIRQ_VPORT9_VSYNC | The device can generate V-sync IRQs for hardware video port number 9.


NotifyCallback

NotifyCallback points to a DirectDraw structure that is filled in by the runtime with information about an event that has occurred.

ULONG
  (FAR PASCAL *LPDD_NOTIFYCALLBACK)(
    DWORD  dwFlags,
    PVOID  pContext,
    DWORD  dwParam1,
    DWORD  dwParam2
    );

Parameters

dwFlags
Indicates the event that caused the callback to be called. The values in dwParam1 and dwParam2 depend on the value of dwFlags. The following values are possible:
Flag | dwParam1 | dwParam2
DDNOTIFY_CLOSECAPTURE | hCapture | unused
DDNOTIFY_CLOSEDIRECTDRAW | hDirectDraw | unused
DDNOTIFY_CLOSESURFACE | hSurface | unused
DDNOTIFY_CLOSEVIDEOPORT | hVideoPort | unused
DDNOTIFY_DISPLAY_VSYNC | hDirectDraw | unused
DDNOTIFY_POSTDOSBOX | hDirectDraw | unused
DDNOTIFY_POSTRESCHANGE | hDirectDraw | unused
DDNOTIFY_PREDOSBOX | hDirectDraw | unused
DDNOTIFY_PRERESCHANGE | hDirectDraw | unused
DDNOTIFY_VP_LINE | hVideoPort | unused
DDNOTIFY_VP_VSYNC | hVideoPort | unused

pContext
Contains a value that was passed from the calling function identifier.
dwParam1, dwParam2
Contain the parameters required by the event that caused the callback.


IDirectDrawKernel

This section describes the methods defined for the IDirectDrawKernel interface. Method prototypes are defined in ddkernel.h.


IDirectDrawKernel::GetCaps

The IDirectDrawKernel::GetCaps method returns the capabilities of this kernel-mode device.

STDMETHOD
  (GetCaps) (
    THIS_
    LPDDKERNELCAPS lpCaps,
    ) PURE;

Parameters

lpCaps
Caller-supplied pointer to a DDKERNELCAPS structure into which the kernel-mode capabilities of the DirectDraw device are returned.

Return Value

The method must return one of the following values:

Return Value | Definition
S_OK | The operation succeeded.
E_FAIL | The operation failed.
E_NOTIMPL | The method is not implemented.


IDirectDrawKernel::GetKernelHandle

The IDirectDrawKernel::GetKernelHandle method returns a kernel-mode handle to the DirectDraw object.

STDMETHOD
  (GetKernelHandle) (
    THIS_
    PULONG_PTR pulDirectDrawHandle,
    ) PURE;

Parameters

pulDirectDrawHandle
Caller-supplied pointer into which the kernel-mode handle of the DirectDraw object is returned.

Return Value

The method must return one of the following values:

Return Value | Definition
S_OK | The operation succeeded.
E_FAIL | The operation failed.
E_NOTIMPL | The method is not implemented.


IDirectDrawKernel::ReleaseKernelHandle

The IDirectDrawKernel::ReleaseKernelHandle method releases a kernel-mode handle to the DirectDraw object.

STDMETHOD
  (ReleaseKernelHandle) (
    THIS
    ) PURE;

Return Value

The method must return one of the following values:

Return Value | Definition
S_OK | The operation succeeded.
E_FAIL | The operation failed.
E_NOTIMPL | The method is not implemented.


IDirectDrawSurfaceKernel

This section describes the methods defined for the IDirectDrawSurfaceKernel interface. Method prototypes are defined in ddkernel.h.


IDirectDrawSurfaceKernel::GetKernelHandle

The IDirectDrawSurfaceKernel::GetKernelHandle method returns a kernel-mode handle to the DirectDraw surface.

STDMETHOD
  (GetKernelHandle) (
    THIS_
    PULONG_PTR pulSurfaceHandle,
    ) PURE;

Parameters

pulSurfaceHandle
Caller-supplied pointer into which the kernel-mode handle of the DirectDraw surface is returned.

Return Value

The method must return one of the following values:

Return Value | Definition
S_OK | The operation succeeded.
E_FAIL | The operation failed.
E_NOTIMPL | The method is not implemented.


IDirectDrawSurfaceKernel::ReleaseKernelHandle

The IDirectDrawSurfaceKernel::ReleaseKernelHandle method releases a kernel-mode handle to the DirectDraw surface.

STDMETHOD
  (ReleaseKernelHandle) (
    THIS
    ) PURE;

Return Value

The method must return one of the following values:

Return Value | Definition
S_OK | The operation succeeded.
E_FAIL | The operation failed.
E_NOTIMPL | The method is not implemented.


DirectDraw Driver Structures

This section describes the Microsoft® DirectDraw® driver structures supported on Windows®. These structures are used by display drivers that offer DirectDraw support. DirectDraw Driver Header Files, Sample Code, and References lists the include files that define the DirectDraw structures described in this section.

Although the DD_Xxx types described in this reference refer to the actual structures in the ddrawint.h header file, it is recommended that driver writers use the DDHAL_Xxx types from ddrawi.h. In cases where the structure names are different in the headers ddrawi.h and ddrawint.h, use types from the ddrawi.h file for cross-platform compatibility. The minor naming differences are aliased with typedefs in the dx95type.h header file, which is provided to help port drivers from Windows 98/Me to Windows 2000 and later.

See DirectDraw Driver Functions for function and callback reference information.

Note The memory for all DirectX® structures should be initialized to zero before the structures are used. In addition, all structures that contain a dwSize member should set this member to the size of the structure, in bytes, before use. The following example performs these tasks on a common structure, DDCORECAPS:

DDCORECAPS ddcorecaps; // Cannot use this yet.

ZeroMemory(&ddcorecaps, sizeof(ddcorecaps));
ddcorecaps.dwSize = sizeof(ddcorecaps);

// Now the structure can be used.


DD_ATTACHLIST

The DD_ATTACHLIST structure maintains a list of attached surfaces for DirectDraw.

typedef struct _DD_ATTACHLIST {
  PDD_ATTACHLIST  lpLink;
  PDD_SURFACE_LOCAL  lpAttached;
} DD_ATTACHLIST;

Members

lpLink
Points to the next attached surface.
lpAttached
Points to a DD_SURFACE_LOCAL structure that contains the attached surface local object.


DD_CALLBACKS

DD_CALLBACKS contains entry pointers to the object callbacks that a device driver supports.

typedef struct DD_CALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_DESTROYDRIVER  DestroyDriver;
  PDD_CREATESURFACE  CreateSurface;
  PDD_SETCOLORKEY  SetColorKey;
  PDD_SETMODE  SetMode;
  PDD_WAITFORVERTICALBLANK  WaitForVerticalBlank;
  PDD_CANCREATESURFACE  CanCreateSurface;
  PDD_CREATEPALETTE  CreatePalette;
  PDD_GETSCANLINE  GetScanLine;
  PDD_MAPMEMORY  MapMemory;
} DD_CALLBACKS;
typedef DD_CALLBACKS *PDD_CALLBACKS;

Members

dwSize
Specifies the size in bytes of this structure.
dwFlags
Indicates what DirectDraw object callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_CB32_CANCREATESURFACE
DDHAL_CB32_CREATEPALETTE
DDHAL_CB32_CREATESURFACE
DDHAL_CB32_GETSCANLINE
DDHAL_CB32_MAPMEMORY
DDHAL_CB32_SETCOLORKEY
DDHAL_CB32_SETMODE
DDHAL_CB32_WAITFORVERTICALBLANK

DestroyDriver
Is not used on Windows 2000 and later and should be ignored by the driver.
CreateSurface
Points to the driver-supplied DdCreateSurface object callback.
SetColorKey
Points to the driver-supplied DdSetColorKey object callback.
SetMode
Is not used on Windows 2000 and later and should be ignored by the driver.
WaitForVerticalBlank
Points to the driver-supplied DdWaitForVerticalBlank object callback.
CanCreateSurface
Points to the driver-supplied DdCanCreateSurface object callback.
CreatePalette
Points to the driver-supplied DdCreatePalette object callback.
GetScanLine
Points to the driver-supplied DdGetScanLine object callback.
MapMemory
Points to the driver-supplied DdMapMemory object callback.

Comments

Entries that the display driver does not use should be set to NULL.GDI allocates the memory for this structure and calls the driver's DrvEnableDirectDraw function to initialize it.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DrvEnableDirectDraw


DD_CLIPPER_GLOBAL

DD_CLIPPER_GLOBAL contains the global DirectDrawClipper data that can be shared between object instances.

typedef struct _DD_CLIPPER_GLOBAL {
  ULONG_PTR  dwReserved1;
} DD_CLIPPER_GLOBAL;

Members

dwReserved1
Is reserved for use by the display driver.


DD_CLIPPER_LOCAL

DD_CLIPPER_LOCAL structure contains local data for each individual DirectDrawClipper object.

typedef struct _DD_CLIPPER_LOCAL {
  ULONG_PTR  dwReserved1;
} DD_CLIPPER_LOCAL;

Members

dwReserved1
Is reserved for use by the display driver.


DD_COLORCONTROLCALLBACKS

DD_COLORCONTROLCALLBACKS structure contains an entry pointer to the DirectDraw color control callback that a device driver supports.

typedef struct _DD_COLORCONTROLCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_COLORCB_COLORCONTROL  ColorControl;
} DD_COLORCONTROLCALLBACKS, *PDD_COLORCONTROLCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_COLORCONTROLCALLBACKS structure.
dwFlags
Indicates whether the device supports the color control callback identified by ColorControl. The driver should set this member to be DDHAL_COLOR_COLORCONTROL when it implements the color control callback.
ColorControl
Points to the driver-supplied DdControlColor callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver should initialize this structure when its DdGetDriverInfo function is called with the GUID_ColorControlCallbacks GUID.

See Also

DD_CALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DdGetDriverInfo


DD_D3DBUFCALLBACKS

DD_D3DBUFCALLBACKS structure is used only by drivers that implement driver level allocation of command and vertex buffers.

typedef struct _DD_D3DBUFCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_CANCREATESURFACE  CanCreateD3DBuffer;
  PDD_CREATESURFACE  CreateD3DBuffer;
  PDD_SURFCB_DESTROYSURFACE  DestroyD3DBuffer;
  PDD_SURFCB_LOCK  LockD3DBuffer;
  PDD_SURFCB_UNLOCK  UnlockD3DBuffer;
} DD_D3DBUFCALLBACKS, *PDD_D3DBUFCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_D3DBUFCALLBACKS structure.
dwFlags
CanCreateD3DBuffer
Points to the driver's CanCreateD3DBuffer callback.
CreateD3DBuffer
Points to the driver's CreateD3DBuffer callback.
DestroyD3DBuffer
Points to the driver's DestroyD3DBuffer callback.
LockD3DBuffer
Points to the driver's LockD3DBuffer callback.
UnlockD3DBuffer
Points to the driver's UnlockD3DBuffer callback.

Comments

Drivers that manage their own command and vertex buffers will need to fill out a DD_D3DBUFCALLBACKS structure and point the lpD3DBufCallbacks member of DD_HALINFO to it.

The driver must also support the callback functions reported in the DD_D3DBUFCALLBACKS structure. These Xxx D3DBuffer callbacks are each analogous to the Dd Xxx Surface callback of similar name; they have the same prototypes and are called with the same input parameters. These new callbacks are called only when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the surface caps. The buffer creation flags are DDSCAPS_WRITEONLY, DDSCAPS2_VERTEXBUFFER and DDSCAPS2_COMMANDBUFFER.

The driver determines the type of buffer being requested by checking the ddsCaps member of the DD_SURFACE_LOCAL structure that is passed to CanCreateD3DBuffer and CreateD3DBuffer for the following flags:

  • DDSCAPS_VERTEXBUFFER

    Indicates that the driver should allocate an Explicit Vertex Buffer.

  • DDSCAPS_COMMANDBUFFER

    Indicates that the driver should allocate a Command Buffer.

  • The absence of both these flags

    Indicates that the driver should allocate an Implicit Vertex Buffer.

Implicit Vertex Buffers should not be placed in video memory since they are expected to be read/write. Only Explicit Vertex Buffers with the DDSCAPS_WRITEONLY flag set can be safely placed in video memory.


DD_DIRECTDRAW_GLOBAL

DD_DIRECTDRAW_GLOBAL contains driver information that describes the driver's device.

typedef struct _DD_DIRECTDRAW_GLOBAL {
  VOID  *dhpdev;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  dwReserved2;
  LPDDVIDEOPORTCAPS  lpDDVideoPortCaps;
} DD_DIRECTDRAW_GLOBAL;

Members

dhpdev
Is a handle to the driver's private PDEV.
dwReserved1
Is reserved for use by the display driver.
dwReserved2
Is reserved for use by the display driver.
lpDDVideoPortCaps
Points to an array of one or more DDVIDEOPORTCAPS structures in which the driver should describe the DirectDraw VPE object(s) that it supports. The structure(s) are allocated by DirectDraw; the number of structure(s) is based on the value returned in the dwMaxVideoPort member of DDCORECAPS.

This member is NULL when the driver does not implement the VPE.

Comments

DirectDraw allocates memory for this structure. Only one DD_DIRECTDRAW_GLOBAL definition exists per device. In a multi-monitor system, each device will have its own unique DD_DIRECTDRAW_GLOBAL structure.

The dwReserved1 and dwReserved2 members can be used as required by the driver. For example, a driver might store pointers to internal data structures in these members.

See Also

DD_DIRECTDRAW_LOCAL


DD_DIRECTDRAW_LOCAL

DD_DIRECTDRAW_LOCAL contains driver information that is relevant to the current DirectDraw process only.

typedef struct _DD_DIRECTDRAW_LOCAL {
  PDD_DIRECTDRAW_GLOBAL  lpGbl;
} DD_DIRECTDRAW_LOCAL;

Members

lpGbl
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the driver.


DD_DXVERSION

DirectX 8.0 and later versions only.

DD_GETDRIVERINFO2DATA is used by the runtime with type D3DGDI2_TYPE_DXVERSION to notify the driver of the current DX runtime version being used by the application.

//
// This data structure is used to notify drivers about the
// DirectX version number. This is the value that is denoted
// as DD_RUNTIME_VERSION in the DDK headers.
//
typedef struct _DD_DXVERSION
{
    DD_GETDRIVERINFO2DATA gdi2;        // [in/out]
                                       // GetDriverInfo2
                                       // data
    DWORD                 dwDXVersion; // [in]
                                       // The Version of DX
    DWORD                 dwReserved;  // Reserved
} DD_DXVERSION;

Members

gdi2
The GetDriverInfo2 data.
dwDXVersion
Specifies the version of DirectX. This field will be set to DD_RUNTIME_VERSION, which is 0x00000700 for DirectX 7.0 and 0x00000800 for DirectX 8.0.
dwReserved
Reserved field. Driver should not read or write.

Comments

This information is provided to a new driver (one that exposes GetDriverInfo2) for DX7 and DX8 applications.

The runtime provides a pointer to a DD_DXVERSION structure in the lpvData field of the DD_GETDRIVERINFODATA data structure.


DD_GETDRIVERINFO2DATA

DirectX 8.0 and later versions only.

DD_GETDRIVERINFO2DATA is passed in the lpvData field of the DD_GETDRIVERINFODATA structure when GUID_GetDriverInfo2 is specified.

typedef struct _DD_GETDRIVERINFO2DATA
{
  DWORD dwReserved;   // Reserved Field.
                      // Driver should not read or write.

  DWORD dwMagic;      // Magic Number. Has D3DGDI2_MAGIC
                      // if this is a GetDriverInfo2 call.
                      // Otherwise this structure is, in
                      // fact, a DD_STEREOMODE call.
                      // Driver should only read this field.

  DWORD dwType;       // Type of information requested. This
                      // field contains one of the
                      // DDGDI2_TYPE_ values listed below.
                      // Driver should only read (not write)
                      // this field.

  DWORD dwExpectedSize;   // Expected size of the
                          // information requested.
                          // Driver should only read
                          // (not write) this field.

  // The remainder of the data buffer (beyond the first
  // four DWORDs) follows here.
} DD_GETDRIVERINFO2DATA;

Members

dwReserved
Reserved field. Driver should not read or write.
dwMagic
Specifies the magic number. Has the value D3DGDI2_MAGIC if this is a GetDriverInfo2 call. Otherwise this structure is, in fact, a DD_STEREOMODE call.
dwType
Specifies the type of information requested. This field contains one of the DDGDI2_TYPE_ values listed below. Driver should only read (not write) this field.
Value | Meaning
D3DGDI2_TYPE_GETD3DCAPS8 | This type indicates that the runtime requests to receive a D3DCAPS8 structure giving the DirectX 8.0 style capabilities of the device. The driver should copy an initialized D3DCAPS8 structure into the lpvData field of the DD_GETDRIVERINFODATA structure.
D3DGDI2_TYPE_GETFORMATCOUNT | Is used to request the number of DirectX 8.0 style surface formats supported by the driver. The data structure pointed to by the lpvData field of the DD_GETDRIVERINFODATA is DD_GETFORMATCOUNTDATA.
D3DGDI2_TYPE_GETFORMAT | Is used to query for a particular surface format from the driver. The data structure pointed to by the lpvData field of the DD_GETDRIVERINFODATA data structure is DD_GETFORMATDATA.
D3DGDI2_TYPE_DXVERSION | Is used to notify the driver of the current DX runtime version being used by the application. The runtime provides a pointer to a DD_DXVERSION structure in the lpvData field of the DD_GETDRIVERINFODATA data structure.

dwExpectedSize
Specifies the expected size of the information requested. Driver should only read (not write) this field.

Comments

The dwExpectedSize field of the DD_GETDRIVERINFODATA structure is not used when a GetDriverInfo2 request is being made. Its value is undefined in this case and should be ignored. The actual expected size of the data is found in the dwExpectedSize field of the DD_GETDRIVERINFO2DATA structure.

The following code fragment demonstrates how to handle GetDriverInfo2:

D3DCAPS8 myD3DCaps8 = { … };

DWORD CALLBACK
DdGetDriverInfo(LPDDHAL_GETDRIVERINFODATA lpData)
{
  if (MATCH_GUID((lpData->guidInfo), GUID_GetDriverInfo2))
  {
    ASSERT(NULL != lpData);
    ASSERT(NULL != lpData->lpvData);

    // Is this a call to GetDriverInfo2 or DDStereoMode?
    if (((DD_GETDRIVERINFO2DATA*)(lpData->lpvData))->dwMagic
      == D3DGDI2_MAGIC)
    {
      // Yes, its a call to GetDriverInfo2, fetch the
      // DD_GETDRIVERINFO2DATA data structure.
      DD_GETDRIVERINFO2DATA* pgdi2 = lpData->lpvData;
      ASSERT(NULL != pgdi2);
      // What type of request is this?
      switch (pgdi2->dwType)
      {
        case D3DGDI2_TYPE_GETD3DCAPS8:
        {
          // The runtime is requesting the DX8 D3D caps
          // so copy them over now. It should be noted
          // that the dwExpectedSize field of
          // DD_GETDRIVERINFODATA is not used for
          // GetDriverInfo2 calls and should be ignored.
          size_t copySize = min(
            sizeof(myD3DCaps8), pgdi2->dwExpectedSize);
          memcpy(lpData->lpvData, &myD3DCaps8, copySize);
          lpData->dwActualSize = copySize;
          lpData->ddRVal       = DD_OK;
          return DDHAL_DRIVER_HANDLED;
        }
        default:
          // For any other GetDriverInfo2 types not handled
          // or understood by the driver set an ddRVal of
          // DDERR_CURRENTLYNOTAVAIL and return
          // DDHAL_DRIVER_HANDLED.
          return DDHAL_DRIVER_HANDLED;
      }
    }
    else
    {
      // It must be a call a request for stereo mode support.
      // Fetch the stereo mode data
      DD_STEREOMODE* pStereoMode = lpData->lpvData;
      ASSERT(NULL != pStereoMode);

      // Process the stereo mode request...
      lpData->dwActualSize = sizeof(DD_STEREOMODE);
      lpData->ddRVal       = DD_OK;
      return DDHAL_DRIVER_HANDLED;
    }
  }

  // Handle any other device GUIDs...

} // DdGetDriverInfo


DD_GETFORMATDATA

DirectX 8.0 and later versions only.

DD_GETFORMATDATA is the data structure pointed to by the lpvData field of DD_GETDRIVERINFODATA for DD_GETDRIVERINFO2DATA queries with the type D3DGDI2_TYPE_GETFORMAT.

typedef struct _DD_GETFORMATDATA
{
    DD_GETDRIVERINFO2DATA gdi2;          // [in/out]
                                         // GetDriverInfo2
                                         // data
    DWORD                 dwFormatIndex; // [in]
                                         // The format to
                                         // return
    DDPIXELFORMAT         format;        // [out]
                                         // The actual
                                         // format
} DD_GETFORMATDATA;

Members

gdi2
The GetDriverInfo2 data.
dwFormatIndex
Specifies the index of the pixel format to return.
format
Receives the actual pixel format.

Comments

The runtime identifies the format to be returned with an integer index whose value varies between zero and one less than the number of supported formats reported earlier by the driver. How these indices are mapped to actual formats is left to the driver. However, each index must map uniquely to one supported format. The order in which the formats are reported is not significant. When processing this GetDriverInfo2 request the driver should read the dwFormatIndex and map that to one of the supported formats (probably by using dwFormatIndex as an index into an array of DDPIXELFORMAT structures) and then copy that format into the format field of the DD_GETFORMATDATA field. The runtime guarantees that it will only pass an index to the driver that is in the range zero to one less than the number of surface formats reported by the driver. The range of the index should be validated in the debug driver build.


DD_GETFORMATCOUNTDATA

DirectX 8.0 and later versions only.

DD_GETFORMATCOUNTDATA is the data structure pointed to by the lpvData field of DD_GETDRIVERINFODATA for DD_GETDRIVERINFO2DATA queries with the type D3DGDI2_TYPE_GETFORMAT.

typedef struct _DD_GETFORMATCOUNTDATA
{
    DD_GETDRIVERINFO2DATA gdi2;          // [in/out]
                                         // GetDriverInfo2
                                         // data
    DWORD                 dwFormatCount; // [out]
                                         // Number of
                                         // supported
                                         // surface formats
    DWORD                 dwReserved;    // Reserved
} DD_GETFORMATCOUNTDATA;

Members

gdi2
The GetDriverInfo2 data.
dwFormatCount
Receives the number of supported surface formats.
dwReserved
Reserved field. Driver should not read or write.

Comments

To handle the D3DGDI2_TYPE_GETFORMATCOUNT, the driver must store the number of DirectX 8.0 DDI style surface formats that it supports in the dwFormatCount field of the DD_GETFORMATCOUNTDATA.


DD_GETHEAPALIGNMENTDATA

DD_GETHEAPALIGNMENTDATA contains data on required alignments from a particular heap.

typedef struct _DD_GETHEAPALIGNMENTDATA {
  ULONG_PTR  dwInstance;
  DWORD  dwHeap;
  HRESULT  ddRVal;
  VOID  *GetHeapAlignment;
  HEAPALIGNMENT  Alignment;
} DD_GETHEAPALIGNMENTDATA, *PDD_GETHEAPALIGNMENTDATA;

Members

dwInstance
Indicates the driver context as returned from the driver initialization routine and stored in the dhpDev member of the DD_DIRECTDRAW_GLOBAL structure.
dwHeap
Specifies the heap index passed by DirectDraw.
ddRVal
Is the location where the driver writes the return value. A return code of DD_OK indicates success.
GetHeapAlignment
Is unused on Windows 2000 and later versions of the operating system.
Alignment
Points to a HEAPALIGNMENT structure filled in by the driver.

Comments

The dwHeap member is the ordinal number of the heap for which alignment data is being requested. In other words, it is the index into the array of VIDEOMEMORY structures pointed to by the pvmList parameter of the DrvGetDirectDrawInfo driver function.


DD_HALINFO

DD_HALINFO describes the capabilities of the hardware and driver.

typedef struct _DD_HALINFO {
  DWORD  dwSize;
  VIDEOMEMORYINFO  vmiData;
  DDCORECAPS  ddCaps;
  PDD_GETDRIVERINFO  GetDriverInfo;
  DWORD  dwFlags;
  LPVOID  lpD3DGlobalDriverData;
  LPVOID  lpD3DHALCallbacks;
  PDD_D3DBUFCALLBACKS  lpD3DBufCallbacks;
} DD_HALINFO, *PDD_HALINFO;

Members

dwSize
Specifies the size in bytes of this DD_HALINFO structure.
vmiData
Is a VIDEOMEMORYINFO structure that describes the display's memory.
ddCaps
Is a DDCORECAPS structure that contains driver-specific capabilities.
GetDriverInfo
Points to the driver's DdGetDriverInfo function. This function will be called to get further DirectDraw driver information. This member can be NULL.
dwFlags
Specifies the display driver's creation flags. The driver should set this member to DDHALINFO_GETDRIVERINFOSET when it provides a function pointer in the GetDriverInfo member.
Flag | Meaning
DDHALINFO_ISPRIMARYDISPLAY | The driver is the primary display driver.
DDHALINFO_MODEXILLEGAL | This hardware does not support ModeX modes.
DDHALINFO_GETDRIVERINFOSET | The GetDriverInfo member is set.
DDHALINFO_GETDRIVERINFO2 | Driver supports GetDriverInfo2 variant of GetDriverInfo.

lpD3DGlobalDriverData
Points to a D3DHAL_GLOBALDRIVERDATA structure that describes the 3D capabilities of the driver and its device.
lpD3DHALCallbacks
Points to the driver's initialized D3DHAL_CALLBACKS structure.
lpD3DBufCallbacks
Should normally be ignored by the driver. Used only by drivers that wish to implement driver level vertex and command buffer allocation. This is usually done for performance reasons. The lpD3DBufCallbacks member is a pointer to a DD_D3DBUFCALLBACKS structure that the driver fills out with the callbacks used to support driver managed vertex and command buffers.

Comments

GDI allocates and zero-initializes the DD_HALINFO structure and passes it to the driver's DrvGetDirectDrawInfo routine to be initialized with driver-specific data.


DD_KERNELCALLBACKS

DD_KERNELCALLBACKS contains entry pointers to the DirectDraw kernel-mode callbacks that the driver supports.

typedef struct _DD_KERNELCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_KERNELCB_SYNCSURFACE  SyncSurfaceData;
  PDD_KERNELCB_SYNCVIDEOPORT  SyncVideoPortData;
} DD_KERNELCALLBACKS, *PDD_KERNELCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_KERNELCALLBACKS structure.
dwFlags
Indicates what DirectDraw kernel callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_KERNEL_SYNCSURFACEDATA
DDHAL_KERNEL_SYNCVIDEOPORTDATA

SyncSurfaceData
Points to the driver-supplied DdSyncSurfaceData object callback.
SyncVideoPortData
Points to the driver-supplied DdSyncVideoPortData object callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver should initialize this structure when its DdGetDriverInfo function is called with the GUID_KernelCallbacks GUID.

See Also

DD_COLORCONTROLCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DdGetDriverInfo


DD_MISCELLANEOUSCALLBACKS

DD_MISCELLANEOUSCALLBACKS contains an entry pointer to the memory query callback that a device driver supports.

typedef struct _DD_MISCELLANEOUSCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_GETAVAILDRIVERMEMORY  GetAvailDriverMemory;
} DD_MISCELLANEOUSCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_MISCELLANEOUSCALLBACKS structure.
dwFlags
Indicates whether the device supports the DdGetAvailDriverMemory callback. The driver should set this member to DDHAL_MISCCB32_GETAVAILDRIVERMEMORY when it implements the callback.
GetAvailDriverMemory
Points to the driver-supplied DdGetAvailDriverMemory callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver should initialize this structure when its DdGetDriverInfo function is called with the GUID_MiscellaneousCallbacks GUID.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DdGetDriverInfo


DD_MISCELLANEOUS2CALLBACKS

DD_MISCELLANEOUS2CALLBACKS is used to return the addresses of the four new callback routines for DirectX® 7.0 that are exposed through DdGetDriverInfo by responding to the GUID_Miscellaneous2Callbacks GUID.

typedef struct _DD_MISCELLANEOUS2CALLBACKS {
    DWORD                dwSize;
    DWORD                dwFlags;
    PDD_ALPHABLT         AlphaBlt;
    PDD_CREATESURFACEEX  CreateSurfaceEx;
    PDD_GETDRIVERSTATE   GetDriverState;
    PDD_DESTROYDDLOCAL   DestroyDDLocal;
} DD_MISCELLANEOUS2CALLBACKS, *PDD_MISCELLANEOUS2CALLBACKS;

Members

dwSize
The size, in bytes of this structure.
dwFlags
Specifies the callbacks supported and flag concerning their usage.
Value | Meaning
DDHAL_MISC2CB32_ALPHABLT | The AlphaBlt callback is supported.
DDHAL_MISC2CB32_CREATESURFACEEX | The CreateSurfaceEx callback is supported.
DDHAL_MISC2CB32_GETDRIVERSTATE | The GetDriverState callback is supported.
DDHAL_MISC2CB32_DESTROYDDLOCAL | The DestroyDDLocal callback is supported.

AlphaBlt
Points to the driver's AlphaBlt implementation. See the DirectDraw DDK documentation for coverage of this function.
CreateSurfaceEx
Points to the driver's D3dCreateSurfaceEx implementation. This callback creates an association between a DirectDraw® surface and a small integer handle.
GetDriverState
Points to the driver's D3dGetDriverState implementation.
DestroyDDLocal
Points to the driver's D3dDestroyDDLocal implementation. Used to destroy the local copy of the device context.


DD_MORESURFACECAPS

DD_MORESURFACECAPS defines more driver surface capabilities in addition to those described in DDCORECAPS.

typedef struct _DD_MORESURFACECAPS
{
    DWORD  dwSize;
    DDSCAPSEX  ddsCapsMore;
    struct
    {
    DDSCAPSEX  ddsCapsEx;
    DDSCAPSEX  ddsCapsExAlt;
    } ddsExtendedHeapRestrictions[1];
} DD_MORESURFACECAPS;

Members

dwSize
Specifies the size of this DD_MORESURFACECAPS structure. The DD_MORESURFACECAPS structure is of variable size. There should be exactly DD_HALINFO.vmiData.dwNumHeaps copies of the ddsExtendedHeapRestrictions structure within the array member of this structure. The total size of a DD_MORESURFACECAPS structure is thus:
dwSize =
   sizeof(DD_MORESURFACECAPS) +
   (DD_HALINFO.vmiData.dwNumHeaps - 1) * sizeof(DDSCAPSEX) * 2

This calculation accounts for the minimum size of the DD_MORESURFACECAPS structure, which includes only one ddsExtendedHeapRestrictions array element. Any additional ddsExtendedHeapRestrictions array elements must be accounted for by adding the sizes of the remaining array elements. That is, by adding the product of the number of remaining ddsExtendedHeapRestrictions structures times the size of each one.

ddsCapsMore
Specifies the extensions to ddcaps.ddsCaps that describe the types of extended surfaces the driver can create. When a DDCAPS structure is returned to the application, it will be a DDSCAPS2 structure manufactured from DDCAPS.ddsCaps and DD_MORESURFACECAPS.ddsCapsMore.
ddsExtendedHeapRestrictions
Is a structure containing two members. These members are filled in by DirectX 6.0-aware drivers (and drivers compliant with later versions of DirectX), to restrict the video memory heaps that are exposed to DirectDraw to certain sets of DDSCAPS_Xxx bits. The DirectDraw version is determined by looking at DDVERSIONINFO, which is defined in ddrawi.h. The ddsCapsEx and ddsCapsExAlt members of the DD_MORESURFACECAPS structure are exactly analogous to the ddsCaps and ddsCapsAlt members of the VIDEOMEMORY structures listed in the VIDMEMINFO.pvmList member of DD_HALINFO.vmiData.
ddsCapsEx
Specifies a DDSCAPS structure in which the driver returns the capabilities for which this chunk of memory cannot be used.
ddsCapsExAlt
Specifies a DDSCAPS structure in which the driver returns the capabilities for which this chunk of memory cannot be used for when no other memory is found on the first pass.

Comments

This structure contains the caps bits added to the DDCAPS.ddsCaps structure in DirectX 6.0. See the DirectDraw SDK documentation for a description of the DDCAPS structure.

Note for Windows 98/Me: DD_MORESURFACECAPS is the definition for Windows 2000 and later versions. Drivers that run on Windows 98/Me will use the name DDMORESURFACECAPS, which is aliased in dx95type.h.


DD_MOTIONCOMP_LOCAL

DD_MOTIONCOMP_LOCAL contains local data for each individual DirectDraw motion compensation object.

typedef struct _DD_MOTIONCOMP_LOCAL {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  GUID  guid;
  DWORD dwUncompWidth;
  DWORD  dwUncompHeight;
  DDPIXELFORMAT  ddUncompPixelFormat;
  DWORD  dwDriverReserved1;
  DWORD  dwDriverReserved2;
  DWORD  dwDriverReserved3;
  LPVOID  lpDriverReserved1;
  LPVOID  lpDriverReserved2;
  LPVOID  lpDriverReserved3;
} DD_MOTIONCOMP_LOCAL;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that describes the DirectDraw object.
guid
Is a GUID that describes the motion compensation process being used.
dwUncompWidth
Indicates the width of the uncompressed output frame.
dwUncompHeight
Indicates the height of the uncompressed output frame.
ddUncompPixelFormat
Is a DDPIXELFORMAT structure that contains the pixel format of the uncompressed output frame.
dwDriverReserved1, dwDriverReserved2, dwDriverReserved3
Are reserved for use by the display driver.
lpDriverReserved1, lpDriverReserved2, lpDriverReserved3
Are reserved for use by the display driver.


DD_MOTIONCOMPCALLBACKS

DD_MOTIONCOMPCALLBACKS contains entry pointers to the motion compensation callbacks that a device driver supports.

typedef struct _DD_MOTIONCOMPCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_MOCOMPCB_GETGUIDS  GetMoCompGuids;
  PDD_MOCOMPCB_GETFORMATS  GetMoCompFormats;
  PDD_MOCOMPCB_CREATE  CreateMoComp;
  PDD_MOCOMPCB_GETCOMPBUFFINFO  GetMoCompBuffInfo;
  PDD_MOCOMPCB_GETINTERNALINFO  GetInternalMoCompInfo;
  PDD_MOCOMPCB_BEGINFRAME  BeginMoCompFrame;
  PDD_MOCOMPCB_ENDFRAME  EndMoCompFrame;
  PDD_MOCOMPCB_RENDER  RenderMoComp;
  PDD_MOCOMPCB_QUERYSTATUS  QueryMoCompStatus;
  PDD_MOCOMPCB_DESTROY  DestroyMoComp;
} DD_MOTIONCOMPCALLBACKS, *PDD_MOTIONCOMPCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_MOTIONCOMPCALLBACKS structure.
dwFlags
Indicates what additional DirectDraw motion compensation callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_MOCOMP32_BEGINFRAME
DDHAL_MOCOMP32_CREATE
DDHAL_MOCOMP32_DESTROY
DDHAL_MOCOMP32_GETCOMPBUFFINFO
DDHAL_MOCOMP32_GETINTERNALINFO
DDHAL_MOCOMP32_ENDFRAME
DDHAL_MOCOMP32_GETFORMATS
DDHAL_MOCOMP32_GETGUIDS
DDHAL_MOCOMP32_QUERYSTATUS
DDHAL_MOCOMP32_RENDER

GetMoCompGuids
Points to the driver-supplied DdMoCompGetGuids object callback.
GetMoCompFormats
Points to the driver-supplied DdMoCompGetFormats object callback.
CreateMoComp
Points to the driver-supplied DdMoCompCreate object callback.
GetMoCompBuffInfo
Points to the driver-supplied DdMoCompGetBuffInfo object callback.
GetInternalMoCompInfo
Points to the driver-supplied DdMoCompGetInternalInfo object callback.
BeginMoCompFrame
Points to the driver-supplied DdMoCompBeginFrame object callback.
EndMoCompFrame
Points to the driver-supplied DdMoCompEndFrame object callback.
RenderMoComp
Points to the driver-supplied DdMoCompRender object callback.
QueryMoCompStatus
Points to the driver-supplied DdMoCompQueryStatus object callback.
DestroyMoComp
Points to the driver-supplied DdMoCompDestroy object callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver should initialize this structure when its DdGetDriverInfo function is called with the GUID_MotionCompCallbacks GUID.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DdGetDriverInfo


DD_NONLOCALVIDMEMCAPS

DD_NONLOCALVIDMEMCAPS contains the capabilities for nonlocal display memory.

typedef struct _DD_NONLOCALVIDMEMCAPS {
  DWORD  dwSize;
  DWORD  dwNLVBCaps;
  DWORD  dwNLVBCaps2;
  DWORD  dwNLVBCKeyCaps;
  DWORD  dwNLVBFXCaps;
  DWORD  dwNLVBRops[DD_ROP_SPACE];
} DD_NONLOCALVIDMEMCAPS, *PDD_NONLOCALVIDMEMCAPS;

Members

dwSize
Specifies the size in bytes of this DD_NONLOCALVIDMEMCAPS structure.
dwNLVBCaps
Contains the driver-specific capabilities for nonlocal-to-local display memory blits.
dwNLVBCaps2
Contains more of the driver-specific capabilities for nonlocal-to-local display memory blits.
dwNLVBCKeyCaps
Contains driver color key capabilities for nonlocal-to-local display memory blits.
dwNLVBFXCaps
Contains driver FX capabilities for nonlocal-to-local display memory blits.
dwNLVBRops
Is an array of DD_ROP_SPACE DWORDs containing the raster operations supported for nonlocal-to-local blits. The constant DD_ROP_SPACE is defined in ddraw.h.

Comments

On Windows 2000 and later versions, the data structure is called DD_NONLOCALVIDMEMCAPS and on Windows 98/Me the data structure is called DDNONLOCALVIDMEMCAPS.

Normally, the dwNLVBCaps, dwNLVBCaps2, dwNFLBCKeyCaps, dwNLVBFXCaps, and dwNLVBRops members contain a subset of the flags used in the DDCORECAPS structure that is relevant to nonlocal-to-local blitting. However, to allow flexibility for device driver writers, any of the flags in DDCORECAPS can be used.


DD_NTCALLBACKS

DD_NTCALLBACKS contains entry pointers to Windows 2000 and later DirectDraw callbacks that a device driver supports.

typedef struct _DD_NTCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_FREEDRIVERMEMORY  FreeDriverMemory;
  PDD_SETEXCLUSIVEMODE  SetExclusiveMode;
  PDD_FLIPTOGDISURFACE  FlipToGDISurface;
} DD_NTCALLBACKS, *PDD_NTCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_NTCALLBACKS structure.
dwFlags
Indicates what Windows 2000 and later callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_NTCB32_FREEDRIVERMEMORY
DDHAL_NTCB32_SETEXCLUSIVEMODE
DDHAL_NTCB32_FLIPTOGDISURFACE

FreeDriverMemory
Points to the driver-supplied DdFreeDriverMemory callback.
SetExclusiveMode
Points to the driver-supplied DdSetExclusiveMode callback.
FlipToGDISurface
Points to the driver-supplied DdFlipToGDISurface callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver should initialize this structure when its DdGetDriverInfo function is called with the GUID_NTCallbacks GUID.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DdGetDriverInfo


DD_NTPRIVATEDRIVERCAPS

DD_NTPRIVATEDRIVERCAPS enables the driver to change the behavior of DirectDraw when DirectDraw is creating surfaces.

typedef struct DD_NTPRIVATEDRIVERCAPS {
  DWORD  dwSize;
  DWORD  dwPrivateCaps;
} DD_NTPRIVATEDRIVERCAPS;

Members

dwSize
Specifies the size in bytes of this DD_NTPRIVATEDRIVERCAPS structure.
dwPrivateCaps
Indicates how DirectDraw should create the surface.
DDHAL_PRIVATECAP_AUTOMICSURFACECREATION
When this flag is set, it indicates that the driver requests DdCreateSurface to be called only once when the application creates a complex flipping chain using a single CreateSurface call. In this case, the lplpSList member of the DD_CREATESURFACEDATA structure points to a list of surfaces to create (rather than a single surface) and dwSCnt contains the number of surfaces in the list.
DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION
When this flag is set, the driver's DdCreateSurface function will be called when creating a primary surface. If this flag is not set, the driver's DdCreateSurface function will not be called.

Comments

The behavior of DirectDraw emulates the surface creation techniques employed by DirectDraw when creating surfaces for Windows 98/Me.

When the DDHAL_PRIVATECAP_AUTOMICSURFACECREATION flag is not set, DirectDraw will perform surface creation using the original method, that is, it will call the driver's DdCreateSurface function once for each surface being created.

When the DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION flag is not set, DirectDraw will perform primary surface creation using the original method, that is, it will not call the driver when creating a primary surface.


DD_PALETTE_GLOBAL

DD_PALETTE_GLOBAL contains the global DirectDrawPalette data that can be shared between object instances.

typedef struct _DD_PALETTE_GLOBAL {
  ULONG_PTR  dwReserved1;
} DD_PALETTE_GLOBAL;

Members

dwReserved1
Is reserved for use by the display driver.


DD_PALETTE_LOCAL

DD_PALETTE_LOCAL contains palette-related data that is unique to an individual palette object.

typedef struct _DD_PALETTE_LOCAL {
  ULONG  dwReserved0;
  ULONG_PTR  dwReserved1;
} DD_PALETTE_LOCAL;

Members

dwReserved0
Is reserved for system use.
dwReserved1
Is reserved for use by the display driver


DD_PALETTECALLBACKS

DD_PALETTECALLBACKS contains entry pointers to the DirectDraw palette callbacks that a device driver supports.

typedef struct DD_PALETTECALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_PALCB_DESTROYPALETTE  DestroyPalette;
  PDD_PALCB_SETENTRIES  SetEntries;
} DD_PALETTECALLBACKS, *PDD_PALETTECALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_PALETTECALLBACKS structure.
dwFlags
Indicates what DirectDrawPalette callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_PALCB32_DESTROYPALETTE
DDHAL_PALCB32_SETENTRIES

DestroyPalette
Points to the driver-supplied DdDestroyPalette palette callback.
SetEntries
Points to the driver-supplied DdSetEntries palette callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver initializes this structure in DrvEnableDirectDraw.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_SURFACECALLBACKS, DD_VIDEOPORTCALLBACKS, DrvEnableDirectDraw


DD_STEREOMODE

DD_STEREOMODE is used by the runtime with GUID_DDStereoMode to query whether the driver supports stereo for a given video display mode.

// The runtime checks each mode in the driver to see
// if it supports stereo. The driver returns DD_OK
// if GUID_DDStereoMode is supported.
typedef struct _DD_STEREOMODE
{
    DWORD       dwSize;         // size of DD_STEREOMODE
    DWORD       dwHeight;
    DWORD       dwWidth;
    DWORD       dwBpp;
    DWORD       dwRefreshRate;
    BOOL        bSupported;     // driver supports this mode
} DD_STEREOMODE, FAR * LPDDSTEREOMODE;} DD_DXVERSION;

Members

dwSize
Specifies the size in bytes of the DD_STEREOMODE structure.
dwHeight
Specifies the height in scanlines of the display mode. Has the value D3DGDI2_MAGIC if this structure is, in fact, a DD_GETDRIVERINFO2DATA call.
dwWidth
Specifies the width in pixels of the display mode.
dwBpp
Specifies the bits per pixel of the display mode.
dwRefreshRate
Specifies the refresh rate in hertz of the display mode.
bSupported
Driver sets to TRUE is stereo is supported with the specified display mode, or FALSE otherwise.

Comments

GUID_DDStereoMode is a way to turn OFF stereo per-mode, since it is expected that a driver that can do stereo can do stereo in any mode.

The runtime provides a pointer to a DD_STEREOMODE structure in the lpvData field of the DD_GETDRIVERINFODATA data structure.


DD_SURFACE_GLOBAL

DD_SURFACE_GLOBAL contains global surface-related data that can be shared between multiple surfaces.

typedef struct _DD_SURFACE_GLOBAL {
  DWORD  dwBlockSizeY;
  union {
  LPVIDEOMEMORY  lpVidMemHeap;
  DWORD  dwBlockSizeX;
  DWORD  dwUserMemSize;
  };
  FLATPTR  fpVidMem;
  union {
  LONG  lPitch;
  DWORD  dwLinearSize;
  };
  LONG  yHint;
  LONG  xHint;
  DWORD  wHeight;
  DWORD  wWidth;
  ULONG_PTR  dwReserved1;
  DDPIXELFORMAT  ddpfSurface;
  FLATPTR  fpHeapOffset;
  HANDLE  hCreatorProcess;
} DD_SURFACE_GLOBAL;

Members

dwBlockSizeY
Specifies the location in which the driver returns the height, in scanlines, of the offscreen memory block that DirectDraw should allocate. The driver should set this value when it returns DDHAL_PLEASEALLOC_BLOCKSIZE in the fpVidMem member.
lpVidMemHeap
Points to a VIDEOMEMORY structure from which the heap display memory was allocated.
dwBlockSizeX
Specifies the location in which the driver returns the size in bytes of the width of the offscreen memory block that DirectDraw should allocate. The driver should set this value when it returns DDHAL_PLEASEALLOC_BLOCKSIZE in the fpVidMem member.
dwUserMemSize
Specifies the location in which the driver returns the size in bytes of the memory block that DirectDraw should allocate in user-mode system memory. driver should set this value when it returns DDHAL_PLEASEALLOC_USERMEM in the fpVidMem member.
fpVidMem
If the driver allocates the memory block, it should return the offset into display memory in this member. If the driver requests DirectDraw to do the memory allocation, it can instead return one of the following values in this member from its DdCreateSurface routine:
Value | Meaning
DDHAL_PLEASEALLOC_BLOCKSIZE | DirectDraw should allocate a memory block of size dwBlockSizeX in offscreen memory.
DDHAL_PLEASEALLOC_USERMEM | DirectDraw should allocate a memory block of size dwBlockSizeX in user-mode memory.

dwLinearSize
Specifies the linear size of a non-rectangular surface.
lPitch
Specifies the pitch of the surface; that is, the distance in bytes to the start of the next line. This is also known as the stride of the surface.
yHint
Specifies the y-coordinate of the surface. This member is a 2D Cartesian coordinate specified in device space.
xHint
Specifies the x-coordinate of the surface. This member is a 2D Cartesian coordinate specified in device space.
wHeight
Specifies the height of the surface.
wWidth
Specifies the width of the surface.
dwReserved1
Is reserved for use by the display driver.
ddpfSurface
Points to the DDPIXELFORMAT structure that describes the pixel format of the surface.
fpHeapOffset
Points to the raw offset in the source heap.
hCreatorProcess
Is reserved for system use and should be ignored by the driver.

Comments

A vertex buffer, which is created by CreateD3DBuffer, holds a list of vertices used by the D3dDrawPrimitives2 callback for rendering primitives. Windows represents vertex buffers as a DirectDraw surfaces, thereby establishing a connection between vertex buffers and the DD_SURFACE_GLOBAL structure.

When a DirectX driver is working with a vertex buffer, it is important for it to be able to correctly determine the size of this buffer. DirectDraw passes the linear buffer size to the driver in the lPitch member of this structure. On Windows 2000 and later versions, but not on Windows 98/Me, the wWidth member of this structure is set to the same value. Note that both structure members should be considered to be read-only. The value that DirectDraw places in these members represents the minimum vertex buffer size. Should the need for a larger buffer arise (such as for optimization), a driver writer is free to create a buffer larger than that size. Under no circumstances, however, should the driver report the larger buffer size to DirectDraw.


DD_SURFACE_INT

DD_SURFACE_INT contains the DirectDrawSurface object's interface information.

typedef struct _DD_SURFACE_INT {
  PDD_SURFACE_LOCAL  lpLcl;
} DD_SURFACE_INT;

Members

lpLcl
Points to a DD_SURFACE_LOCAL structure that describes a unique surface object.


DD_SURFACE_LOCAL

DD_SURFACE_LOCAL contains surface-related data that is unique to an individual surface object.

typedef struct _DD_SURFACE_LOCAL {
  PDD_SURFACE_GLOBAL  lpGbl;
  DWORD  dwFlags;
  DDSCAPS  ddsCaps;
  ULONG_PTR  dwReserved1;
  union {
  DDCOLORKEY  ddckCKSrcOverlay;
  DDCOLORKEY  ddckCKSrcBlt;
  }
  union {
  DDCOLORKEY  ddckCKDestOverlay;
  DDCOLORKEY  ddckCKDestBlt;
  }
  PDD_SURFACE_MORE  lpSurfMore;
  PDD_ATTACHLIST  lpAttachList;
  PDD_ATTACHLIST  lpAttachListFrom;
  RECT  rcOverlaySrc;
} DD_SURFACE_LOCAL;

Members

lpGbl
Points to the DD_SURFACE_GLOBAL structure containing surface data that is shared globally with multiple surfaces.
dwFlags
Is a set of surface flags.
Flag | Meaning
DDRAWISURF_BACKBUFFER | The surface was originally a back buffer.
DDRAWISURF_DRIVERMANAGED | The surface is a driver managed texture used with Direct3D.
DDRAWISURF_FRONTBUFFER | The surface was originally a front buffer.
DDRAWISURF_HASCKEYSRCBLT | The surface has source color key overlay data in the ddckCKSrcBlt member.
DDRAWISURF_HASOVERLAYDATA | The surface has overlay data.
DDRAWISURF_HASPIXELFORMAT | The surface has pixel format data.
DDRAWISURF_INVALID | The surface has been invalidated by a mode setting operation.

ddsCaps
Is a DDSCAPS structure that describes the capabilities of the surface.
dwReserved1
Is reserved for use by the display driver.
ddckCKSrcOverlay
Is a DDCOLORKEY structure (defined in the DirectDraw SDK documentation) that contains the color key information for source overlay use.
ddckCKSrcBlt
Is a DDCOLORKEY structure that describes the color key for source color key overlays.
ddckCKDestOverlay
Is a DDCOLORKEY structure (defined in the DirectDraw SDK documentation) that contains the color key information for destination overlay use.
ddckCKDestBlt
Is a DDCOLORKEY structure (defined in the DirectDraw SDK documentation) that describes the color key for destination color key overlays.
lpSurfMore
Points to a DD_SURFACE_MORE structure that contains additional local surface data.
lpAttachList
Points to a DD_ATTACHLIST structure that contains the list of surfaces to which this surface attached.
lpAttachListFrom
Points to a DD_ATTACHLIST structure that contains the list of surfaces attached to this surface.
rcOverlaySrc
Is reserved for system use and should be ignored by the driver.


DD_SURFACE_MORE

DD_SURFACE_MORE contains additional local data for each individual DirectDrawSurface object.

typedef struct _DD_SURFACE_MORE {
  DWORD  dwMipMapCount;
  PDD_VIDEOPORT_LOCAL  lpVideoPort;
  DWORD  dwOverlayFlags;
  DDSCAPSEX  ddsCapsEx;
  DWORD  dwSurfaceHandle;
} DD_SURFACE_MORE, *PDD_SURFACE_MORE;

Members

dwMipMapCount
Contains the number of mipmap levels in the chain.
lpVideoPort
Points to a DD_VIDEOPORT_LOCAL structure of the VPE object currently writing data to this surface.
dwOverlayFlags
Is a set of flags that indicate the overlay flags most recently passed to DdUpdateOverlay.
Flag | Meaning
DDOVER_ADDDIRTYRECT | Add a dirty rectangle to an emulated overlaid surface.
DDOVER_ALPHADEST | Use the alpha information in the pixel format or the alpha channel surface attached to the destination surface as the alpha channel for the destination overlay.
DDOVER_ALPHADESTCONSTOVERRIDE | Use the dwConstAlphaDest member in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the destination alpha channel for this overlay.
DDOVER_ALPHADESTNEG | The NEG suffix indicates that the destination surface becomes more transparent as the alpha value increases.
DDOVER_ALPHADESTSURFACEOVERRIDE | Use the lpDDSAlphaDest member in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the alpha channel destination for this overlay.
DDOVER_ALPHAEDGEBLEND | Use the dwAlphaEdgeBlend member in the DDOVERLAYFX structure as the alpha channel for the edges of the image that border the color key colors.
DDOVER_ALPHASRC | Use the alpha information in the pixel format or the alpha channel surface attached to the source surface as the source alpha channel for this overlay.
DDOVER_ALPHASRCCONSTOVERRIDE | Use the dwConstAlphaSrc member in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the source alpha channel for this overlay.
DDOVER_ALPHASRCNEG | The NEG suffix indicates that the source surface becomes more transparent as the alpha value increases.
DDOVER_ALPHASRCSURFACEOVERRIDE | Use the lpDDSAlphaSrc member in the DDOVERLAYFX structure as the alpha channel source for this overlay.
DDOVER_AUTOFLIP | Autoflip the overlay whenever the VPE object autoflips.
DDOVER_BOB | Display each field of VPE object data individually without causing any jittery artifacts.
DDOVER_BOBHARDWARE | Bob is performed using hardware rather than software or emulated.
DDOVER_DDFX | Use the overlay FX flags to define special overlay FX.
DDOVER_HIDE | Turn this overlay off.
DDOVER_INTERLEAVED | Indicates that the surface memory is composed of interleaved fields.
DDOVER_KEYDEST | Use the color key associated with the destination surface.
DDOVER_KEYDESTOVERRIDE | Use the dckDestColorkey member in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the color key for the destination surface.
DDOVER_KEYSRC | Use the color key associated with the source surface.
DDOVER_KEYSRCOVERRIDE | Use the dckSrcColorkey member in the DDOVERLAYFX structure as the color key for the source surface.
DDOVER_OVERRIDEBOBWEAVE | Bob and weave decisions should not be overridden by other interfaces. If this flag is set, DirectDraw will not allow a kernel-mode driver to use the kernel-mode video transport functionality to switch the hardware between bob and weave mode.
DDOVER_REFRESHALL | Redraw the entire surface on an emulated overlayed surface.
DDOVER_REFRESHDIRTYRECTS | Redraw all dirty rectangles on an emulated overlayed surface.
DDOVER_SHOW | Turn this overlay on.

ddsCapsEx
Is used to expose extended surface capabilities. For more information, see Extended Surface Capabilities in the design guide.
dwSurfaceHandle
Is a cookie for D3dCreateSurfaceEx so that it can associated a texture handle with the surface.


DD_SURFACECALLBACKS

DD_SURFACECALLBACKS contains entry pointers to the DirectDraw surface callbacks that a device driver supports.

typedef struct DD_SURFACECALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_SURFCB_DESTROYSURFACE  DestroySurface;
  PDD_SURFCB_FLIP  Flip;
  PDD_SURFCB_SETCLIPLIST  SetClipList;
  PDD_SURFCB_LOCK  Lock;
  PDD_SURFCB_UNLOCK  Unlock;
  PDD_SURFCB_BLT  Blt;
  PDD_SURFCB_SETCOLORKEY  SetColorKey;
  PDD_SURFCB_ADDATTACHEDSURFACE  AddAttachedSurface;
  PDD_SURFCB_GETBLTSTATUS  GetBltStatus;
  PDD_SURFCB_GETFLIPSTATUS  GetFlipStatus;
  PDD_SURFCB_UPDATEOVERLAY  UpdateOverlay;
  PDD_SURFCB_SETOVERLAYPOSITION  SetOverlayPosition;
  LPVOID  reserved4;
  PDD_SURFCB_SETPALETTE  SetPalette;
} DD_SURFACECALLBACKS, *PDD_SURFACECALLBACKS;

Members

dwSize
Specifies the size in bytes of the DD_SURFACECALLBACKS structure. This member is unused by Windows 2000 and later versions.
dwFlags
Indicates which DirectDrawSurface callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_SURFCB32_DESTROYSURFACE
DDHAL_SURFCB32_FLIP
DDHAL_SURFCB32_SETCLIPLIST
DDHAL_SURFCB32_LOCK
DDHAL_SURFCB32_UNLOCK
DDHAL_SURFCB32_BLT
DDHAL_SURFCB32_SETCOLORKEY
DDHAL_SURFCB32_ADDATTACHEDSURFACE
DDHAL_SURFCB32_GETBLTSTATUS
DDHAL_SURFCB32_GETFLIPSTATUS
DDHAL_SURFCB32_UPDATEOVERLAY
DDHAL_SURFCB32_SETOVERLAYPOSITION
DDHAL_SURFCB32_SETPALETTE

DestroySurface
Points to the driver-supplied DdDestroySurface surface callback.
Flip
Points to the driver-supplied DdFlip surface callback.
SetClipList
Points to the driver-supplied DdSetClipList surface callback.
Lock
Points to the driver-supplied DdLock surface callback.
Unlock
Points to the driver-supplied DdUnlock surface callback.
Blt
Points to the driver-supplied DdBlt surface callback.
SetColorKey
Points to the driver-supplied DdSetColorKey surface callback.
AddAttachedSurface
Points to the driver-supplied DdAddAttachedSurface surface callback.
GetBltStatus
Points to the driver-supplied DdGetBltStatus surface callback.
GetFlipStatus
Points to the driver-supplied DdGetFlipStatus surface callback.
UpdateOverlay
Points to the driver-supplied DdUpdateOverlay surface callback.
SetOverlayPosition
Points to the driver-supplied DdSetOverlayPosition surface callback.
reserved4
Is reserved for system use and should be ignored by the driver.
SetPalette
Points to the driver-supplied DdSetPalette surface callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver initializes this structure in DrvEnableDirectDraw.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_VIDEOPORTCALLBACKS, DrvEnableDirectDraw


DD_UPDATENONLOCALHEAPDATA

DD_UPDATENONLOCALHEAPDATA contains the required heap information.

typedef struct _DD_UPDATENONLOCALHEAPDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  DWORD  dwHeap;
  FLATPTR  fpGARTLin;
  FLATPTR  fpGARTDev;
  ULONG_PTR  ulPolicyMaxBytes;
  HRESULT  ddRVal;
  VOID  *UpdateNonLocalHeap;
} DD_UPDATENONLOCALHEAPDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that represents the DirectDraw object.
dwHeap
Indicates the heap index.
fpGARTLin
Points to the linear graphic address remapping table (GART) address of the start of the heap.
fpGARTDev
Points to the physical GART address of the start of the heap.
ulPolicyMaxBytes
Indicates the maximum amount of AGP memory to use.
ddRVal
Is the location in which the driver writes the return value. A return code of DD_OK indicates success.
UpdateNonLocalHeap
Is unused on Windows 2000 and later versions of the operating system.


DD_VIDEOPORT_LOCAL

DD_VIDEOPORT_LOCAL contains VPE-related data that is unique to an individual DirectDraw VPE object.

typedef struct _DD_VIDEOPORT_LOCAL {
  PDD_DIRECTDRAW_LOCAL  lpDD;
  DDVIDEOPORTDESC  ddvpDesc;
  DDVIDEOPORTINFO  ddvpInfo;
  PDD_SURFACE_INT  lpSurface;
  PDD_SURFACE_INT  lpVBISurface;
  DWORD  dwNumAutoflip;
  DWORD  dwNumVBIAutoflip;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  dwReserved2;
  ULONG_PTR  dwReserved3;
} DD_VIDEOPORT_LOCAL;

Members

lpDD
Points to a DD_DIRECTDRAW_LOCAL structure that contains the DirectDraw object's data.
ddvpDesc
Is a DDVIDEOPORTDESC structure that describes the VPE object.
ddvpInfo
Is a DDVIDEOPORTINFO structure that describes the transfer of video data to a surface.
lpSurface
Points to a DD_SURFACE_INT structure for the surface receiving the video data.
lpVBISurface
Points to a DD_SURFACE_INT structure for the surface receiving the VBI data.
dwNumAutoflip
Specifies the number of current autoflip surfaces.
dwNumVBIAutoflip
Specifies the number of VBI surfaces currently being autoflipped.
dwReserved1, dwReserved2, dwReserved3
Are reserved for use by the display driver.

Comments

This structure is initialized and filled in by DirectDraw. Except for the dwReserved1, dwReserved2, and dwReserved3 members, the driver must not modify any other members of the DD_VIDEOPORT_LOCAL structure.


DD_VIDEOPORTCALLBACKS

DD_VIDEOPORTCALLBACKS contains entry pointers to DirectDraw VPE callbacks that a device driver supports.

typedef struct DD_VIDEOPORTCALLBACKS {
  DWORD  dwSize;
  DWORD  dwFlags;
  PDD_VPORTCB_CANCREATEVIDEOPORT  CanCreateVideoPort;
  PDD_VPORTCB_CREATEVIDEOPORT  CreateVideoPort;
  PDD_VPORTCB_FLIP  FlipVideoPort;
  PDD_VPORTCB_GETBANDWIDTH  GetVideoPortBandwidth;
  PDD_VPORTCB_GETINPUTFORMATS  GetVideoPortInputFormats;
  PDD_VPORTCB_GETOUTPUTFORMATS  GetVideoPortOutputFormats;
  LPVOID  lpReserved1;
  PDD_VPORTCB_GETFIELD  GetVideoPortField;
  PDD_VPORTCB_GETLINE  GetVideoPortLine;
  PDD_VPORTCB_GETVPORTCONNECT  GetVideoPortConnectInfo;
  PDD_VPORTCB_DESTROYVPORT  DestroyVideoPort;
  PDD_VPORTCB_GETFLIPSTATUS  GetVideoPortFlipStatus;
  PDD_VPORTCB_UPDATE  UpdateVideoPort;
  PDD_VPORTCB_WAITFORSYNC  WaitForVideoPortSync;
  PDD_VPORTCB_GETSIGNALSTATUS  GetVideoSignalStatus;
  PDD_VPORTCB_COLORCONTROL  ColorControl;
} DD_VIDEOPORTCALLBACKS, *PDD_VIDEOPORTCALLBACKS;

Members

dwSize
Specifies the size in bytes of this DD_VIDEOPORTCALLBACKS structure.
dwFlags
Indicates what VPE callbacks the driver has implemented. For every bit set in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be one or more of the following flags:

DDHAL_VPORT32_CANCREATEVIDEOPORT
DDHAL_VPORT32_CREATEVIDEOPORT
DDHAL_VPORT32_FLIP
DDHAL_VPORT32_GETBANDWIDTH
DDHAL_VPORT32_GETINPUTFORMATS
DDHAL_VPORT32_GETOUTPUTFORMATS
DDHAL_VPORT32_GETAUTOFLIPSURF
DDHAL_VPORT32_GETFIELD
DDHAL_VPORT32_GETLINE
DDHAL_VPORT32_GETCONNECT
DDHAL_VPORT32_DESTROY
DDHAL_VPORT32_GETFLIPSTATUS
DDHAL_VPORT32_UPDATE
DDHAL_VPORT32_WAITFORSYNC
DDHAL_VPORT32_GETSIGNALSTATUS
DDHAL_VPORT32_COLORCONTROL

CanCreateVideoPort
Points to the driver-supplied DdVideoPortCanCreate callback.
CreateVideoPort
Points to the driver-supplied DdVideoPortCreate callback.
FlipVideoPort
Points to the driver-supplied DdVideoPortFlip callback.
GetVideoPortBandwidth
Points to the driver-supplied DdVideoPortGetBandwidth callback.
GetVideoPortInputFormats
Points to the driver-supplied DdVideoPortGetInputFormats callback.
GetVideoPortOutputFormats
Points to the driver-supplied DdVideoPortGetOutputFormats callback.
lpReserved1
Is reserved for system use and should be ignored by the driver.
GetVideoPortField
Points to the driver-supplied DdVideoPortGetField callback.
GetVideoPortLine
Points to the driver-supplied DdVideoPortGetLine callback.
GetVideoPortConnectInfo
Points to the driver-supplied DdVideoPortGetConnectInfo callback.
DestroyVideoPort
Points to the driver-supplied DdVideoPortDestroy callback.
GetVideoPortFlipStatus
Points to the driver-supplied DdVideoPortGetFlipStatus callback.
UpdateVideoPort
Points to the driver-supplied DdVideoPortUpdate callback.
WaitForVideoPortSync
Points to the driver-supplied DdVideoPortWaitForSync callback.
GetVideoSignalStatus
Points to the driver-supplied DdVideoPortGetSignalStatus callback.
ColorControl
Points to the driver-supplied DdVideoPortColorControl callback.

Comments

Entries that the display driver does not use should be set to NULL. The driver should initialize this structure when its DdGetDriverInfo function is called with the GUID_VideoPortCallbacks GUID.

See Also

DD_COLORCONTROLCALLBACKS, DD_KERNELCALLBACKS, DD_MISCELLANEOUSCALLBACKS, DD_MOTIONCOMPCALLBACKS, DD_NTCALLBACKS, DD_PALETTECALLBACKS, DD_SURFACECALLBACKS, DdGetDriverInfo


DDCOLORCONTROL

DDCOLORCONTROL defines the color controls associated with a DirectDraw VPE object.

typedef struct _DDCOLORCONTROL {
  DWORD  dwSize;
  DWORD  dwFlags;
  LONG  lBrightness;
  LONG  lContrast;
  LONG  lHue;
  LONG  lSaturation;
  LONG  lSharpness;
  LONG  lGamma;
  LONG  lColorEnable;
  DWORD  dwReserved1;
} DDCOLORCONTROL;

Members

dwSize
Specifies the size in bytes of this DDCOLORCONTROL structure.
dwFlags
Is a set of flags that specify what structure members contain valid data. When the structure is returned by DdVideoPortColorControl, it also indicates what options are supported by the VPE object. This member can be a bitwise OR of the following values:
Flag | Meaning
DDCOLOR_BRIGHTNESS | The lBrightness member contains valid data.
DDCOLOR_CONTRAST | The lContrast member contains valid data.
DDCOLOR_COLORENABLE | The lColorEnable member contains valid data.
DDCOLOR_GAMMA | The lGamma member contains valid data.
DDCOLOR_HUE | The lHue member contains valid data.
DDCOLOR_SATURATION | The lSaturation member contains valid data.
DDCOLOR_SHARPNESS | The lSharpness member contains valid data.

lBrightness
Specifies the luminance intensity (Black Level), in IRE units*100. This member can range from 0 to 10,000, with a default value of 750 (7.5 IRE).
lContrast
Specifies the relative difference between higher and lower intensity luminance values, in IRE units*100. This member can range from 0 to 20,000, with a default value of 10,000 (100 IRE). Higher values of contrast cause darker luminance values to tend towards black, and cause lighter luminance values to tend towards white. Lower values of contrast cause all luminance values to move towards the middle luminance values.
lHue
Specifies the phase relationship of the chrominance components. Hue is specified in degrees, with a valid range of -180 to 180. The default is 0 degrees.
lSaturation
Specifies the color intensity, in IRE units*100. This member can range from 0 to 20,000, with a default value of 10,000 (100 IRE).
lSharpness
Specifies the sharpness in arbitrary units. The valid range is 0 to 10, with a default value of 5.
lGamma
Controls the amount of gamma correction applied to the luminance values. The valid range is 1 to 500 gamma units, with a default of 1.
lColorEnable
Is a flag indicating whether color is used. If this member is zero, color is not used; if it is 1, then color is used. The default value is 1.
dwReserved1
Is reserved for system use and should be ignored.


DDCOMPBUFFERINFO

DDCOMPBUFFERINFO contains driver-supplied information regarding compression buffers.

typedef struct _DDCOMPBUFFERINFO {
  DWORD  dwSize;
  DWORD  dwNumCompBuffers;
  DWORD  dwWidthToCreate;
  DWORD  dwHeightToCreate;
  DWORD  dwBytesToAllocate;
  DDSCAPS2  ddCompCaps;
  DDPIXELFORMAT  ddPixelFormat;
} DDCOMPBUFFERINFO, *LPDDCOMPBUFFERINFO;

Members

dwSize
Specifies the size in bytes of this DDCOMPBUFFERINFO structure.
dwNumCompBuffers
Indicates the number of surfaces of this type required for decompression.
dwWidthToCreate
Indicates the width of the surface of this type to create.
dwHeightToCreate
Indicates the height of the surface of this type to create.
dwBytesToAllocate
Indicates the total number of bytes used by each surface.
ddCompCaps
Points to a DDSCAPS2 structure that contains the capabilities to use when creating surfaces of this type. This allows the driver to specify the type of memory to use when creating these surfaces.
ddPixelFormat
Points to a DDPIXELFORMAT structure that contains the pixel formats to use when creating surfaces of this type.

Comments

This structure passes this information to the DD_GETMOCOMPCOMPBUFFDATA structure.


DDCORECAPS

DDCORECAPS specifies the core capabilities of the DirectDraw driver and its device, which are exposed to an application through the DirectDraw object.

typedef typedef struct _DDCORECAPS {
  DWORD  dwSize;
  DWORD  dwCaps;
  DWORD  dwCaps2;
  DWORD  dwCKeyCaps;
  DWORD  dwFXCaps;
  DWORD  dwFXAlphaCaps;
  DWORD  dwPalCaps;
  DWORD  dwSVCaps;
  DWORD  dwAlphaBltConstBitDepths;
  DWORD  dwAlphaBltPixelBitDepths;
  DWORD  dwAlphaBltSurfaceBitDepths;
  DWORD  dwAlphaOverlayConstBitDepths;
  DWORD  dwAlphaOverlayPixelBitDepths;
  DWORD  dwAlphaOverlaySurfaceBitDepths;
  DWORD  dwZBufferBitDepths;
  DWORD  dwVidMemTotal;
  DWORD  dwVidMemFree;
  DWORD  dwMaxVisibleOverlays;
  DWORD  dwCurrVisibleOverlays;
  DWORD  dwNumFourCCCodes;
  DWORD  dwAlignBoundarySrc;
  DWORD  dwAlignSizeSrc;
  DWORD  dwAlignBoundaryDest;
  DWORD  dwAlignSizeDest;
  DWORD  dwAlignStrideAlign;
  DWORD  dwRops[DD_ROP_SPACE];
  DDSCAPS  ddsCaps;
  DWORD  dwMinOverlayStretch;
  DWORD  dwMaxOverlayStretch;
  DWORD  dwMinLiveVideoStretch;
  DWORD  dwMaxLiveVideoStretch;
  DWORD  dwMinHwCodecStretch;
  DWORD  dwMaxHwCodecStretch;
  DWORD  dwReserved1;
  DWORD  dwReserved2;
  DWORD  dwReserved3;
  DWORD  dwSVBCaps;
  DWORD  dwSVBCKeyCaps;
  DWORD  dwSVBFXCaps;
  DWORD  dwSVBRops[DD_ROP_SPACE];
  DWORD  dwVSBCaps;
  DWORD  dwVSBCKeyCaps;
  DWORD  dwVSBFXCaps;
  DWORD  dwVSBRops[DD_ROP_SPACE];
  DWORD  dwSSBCaps;
  DWORD  dwSSBCKeyCaps;
  DWORD  dwSSBFXCaps;
  DWORD  dwSSBRops[DD_ROP_SPACE];
  DWORD  dwMaxVideoPorts;
  DWORD  dwCurrVideoPorts;
  DWORD  dwSVBCaps2;
} DDCORECAPS, *PDDCORECAPS;

Members

dwSize
Specifies the size in bytes of this DDCORECAPS structure.
dwCaps
Is a flag that specifies the driver's capabilities. The driver should set the appropriate DDCAPS_Xxx bit for every capability that it supports.
Flag | Meaning
DDCAPS_3D | The display hardware has 3D acceleration.
DDCAPS_ALIGNBOUNDARYDEST | DirectDraw supports only those source rectangles with the x-axis aligned to the dwAlignBoundaryDest boundaries of the surface.
DDCAPS_ALIGNBOUNDARYSRC | DirectDraw supports only those source rectangles with the x-axis aligned to the dwAlignBoundarySrc boundaries of the surface.
DDCAPS_ALIGNSIZEDEST | DirectDraw supports only those source rectangles whose x-axis sizes, in bytes, are dwAlignSizeDest multiples.
DDCAPS_ALIGNSIZESRC | DirectDraw supports only those source rectangles whose x-axis sizes, in bytes, are dwAlignSizeSrc multiples.
DDCAPS_ALIGNSTRIDE | DirectDraw creates display memory surfaces that have a stride alignment equal to the dwAlignStrideAlign value.
DDCAPS_ALPHA | The display hardware supports an alpha channel during blit operations.
DDCAPS_BANKSWITCHED | The display hardware is bank-switched and is potentially very slow at random access to display memory. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDCAPS_BLT | The display hardware is capable of blit operations.
DDCAPS_BLTCOLORFILL | The display hardware is capable of color filling with a blitter.
DDCAPS_BLTDEPTHFILL | The display hardware is capable of depth filling z-buffers with a blitter.
DDCAPS_BLTFOURCC | The display hardware is capable of color-space conversions during blit operations.
DDCAPS_BLTQUEUE | The display hardware is capable of asynchronous blit operations.
DDCAPS_BLTSTRETCH | The display hardware is capable of stretching during blit operations.
DDCAPS_CANBLTSYSMEM | The display hardware is capable of blitting to or from system memory.
DDCAPS_CANCLIP | The display hardware is capable of clipping with blitting.
DDCAPS_CANCLIPSTRETCHED | The display hardware is capable of clipping while stretch-blitting.
DDCAPS_COLORKEY | Some form of color key in either overlay or blit operations is supported. More specific color key capability information can be found in the dwCKeyCaps member.
DDCAPS_COLORKEYHWASSIST | The color key is hardware assisted.
DDCAPS_GDI | The display hardware is shared with GDI. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDCAPS_NOHARDWARE | No hardware support exists.
DDCAPS_OVERLAY | The display hardware supports overlays.
DDCAPS_OVERLAYCANTCLIP | The display hardware supports overlays but cannot clip them.
DDCAPS_OVERLAYFOURCC | The overlay hardware is capable of color-space conversions during overlay operations.
DDCAPS_OVERLAYSTRETCH | The overlay hardware is capable of stretching.
DDCAPS_PALETTE | DirectDraw is capable of creating and supporting DirectDrawPalette objects for more than just the primary surface. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDCAPS_PALETTEVSYNC | DirectDraw is capable of updating a palette synchronized with the vertical refresh.
DDCAPS_READSCANLINE | The display hardware is capable of returning the current scan line.
DDCAPS_STEREOVIEW | The display hardware has stereo vision capabilities.
DDCAPS_VBI | The display hardware is capable of generating a vertical-blank interrupt.
DDCAPS_ZBLTS | Supports the use of z-buffers with blit operations.
DDCAPS_ZOVERLAYS | Supports the use of the application's UpdateOverlayZOrder method as a z-value for overlays to control their layering. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.

dwCaps2
Specify more of the driver's capabilities. The driver should set the appropriate DDCAPS2_Xxx bit for every capability that it supports.
Flag | Meaning
DDCAPS2_AUTOFLIPOVERLAY | The overlay can be automatically flipped to the next surface in the flip chain each time a hardware video port V-sync occurs, allowing the VPE object and the overlay to double buffer the video without CPU overhead. This option is only valid when the surface is receiving data from hardware video port. If the hardware video port data is noninterlaced or noninterleaved, it flips on every V-sync. If the data is being interleaved in memory, it flips on every other V-sync.
DDCAPS2_CANBOBHARDWARE | The overlay hardware can display each field of an interlaced video stream individually.
DDCAPS2_CANBOBINTERLEAVED | The overlay hardware can display each field of an interlaced video stream individually while it is interleaved in memory without causing any artifacts that might normally occur without special hardware support. This option is only valid when the surface is receiving data from a VPE object and is only valid when the video is zoomed at least 200 percent in the vertical direction.
DDCAPS2_CANBOBNONINTERLEAVED | The overlay hardware can display each field of an interlaced video stream individually while it is not interleaved in memory without causing any artifacts that might normally occur without special hardware support. This option is only valid when the surface is receiving data from a VPE object and is only valid when the video is zoomed at least 200 percent in the vertical direction.
DDCAPS2_CANCALIBRATEGAMMA | A calibrator is available to adjust the gamma ramp according to the physical display properties so that the result will be identical on all calibrated systems.
DDCAPS2_CANDROPZ16BIT | Sixteen-bit RGBZ values can be converted into 16-bit RGB values. (The system does not support eight-bit conversions.)
DDCAPS2_CANFLIPODDEVEN | The driver supports bob using software without using a VPE object.
DDCAPS2_CANRENDERWINDOWED | The driver can render in windowed mode.
DDCAPS2_CERTIFIED | The display hardware is certified.
DDCAPS2_COLORCONTROLOVERLAY | The overlay surface contains color controls (brightness, sharpness, and so on).
DDCAPS2_COLORCONTROLPRIMARY | The primary surface contains color controls (gamma, and so on).
DDCAPS2_COPYFOURCC | The driver supports blitting any FOURCC surface to another surface of the same FOURCC.
DDCAPS2_FLIPINTERVAL | The driver will respond to the DDFLIP_INTERVAL2, DDFLIP_INTERVAL3, and DDFLIP_INTERVAL4 flags.
DDCAPS2_FLIPNOVSYNC | The driver will respond to DDFLIP_FLIPNOVSYNC.
DDCAPS2_NO2DDURING3DSCENE | The driver cannot interleave 2D operations such as DdBlt or DdLock on any surfaces that Direct3D is using between calls to the IDirect3DDevice::BeginScene and IDirect3DDevice::EndScene methods.
DDCAPS2_NONLOCALVIDMEM | The driver supports nonlocal display memory.
DDCAPS2_NONLOCALVIDMEMCAPS | Blit capabilities for nonlocal display memory surfaces differ from local display memory surfaces. If this flag is present, the DDCAPS2_NONLOCALVIDMEM flag will also be present.
DDCAPS2_NOPAGELOCKREQUIRED | The driver should be called for blits involving system memory surfaces even if the system memory surfaces are not pagelocked.
DDCAPS2_PRIMARYGAMMA | The driver supports loadable gamma ramps for the primary surface.
DDCAPS2_VIDEOPORT | The display hardware contains a hardware video port.
DDCAPS2_WIDESURFACES | The display driver can create surfaces wider than the primary surface. Drivers that set this bit should expect to receive CreateSurface requests from applications for surfaces wider than the primary surface.

dwCKeyCaps
Specify the color key capabilities of surfaces. The driver should set the appropriate DDCKEYCAPS_Xxx bit for every capability that it supports.
Flag | Meaning
DDCKEYCAPS_DESTBLT | Supports transparent blitting with a color key that identifies the replaceable bits of the destination surface for RGB colors.
DDCKEYCAPS_DESTBLTCLRSPACE | Supports transparent blitting with a color space that identifies the replaceable bits of the destination surface for RGB colors.
DDCKEYCAPS_DESTBLTCLRSPACEYUV | Supports transparent blitting with a color space that identifies the replaceable bits of the destination surface for YUV colors.
DDCKEYCAPS_DESTBLTYUV | Supports transparent blitting with a color key that identifies the replaceable bits of the destination surface for YUV colors.
DDCKEYCAPS_DESTOVERLAY | Supports overlaying with color keying of the replaceable bits of the destination surface being overlaid for RGB colors.
DDCKEYCAPS_DESTOVERLAYCLRSPACE | Supports a color space as the color key for the destination of RGB colors.
DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV | Supports a color space as the color key for the destination of YUV colors.
DDCKEYCAPS_DESTOVERLAYONEACTIVE | Supports only one active destination color key value for visible overlay surfaces.
DDCKEYCAPS_DESTOVERLAYYUV | Supports overlaying using color keying of the replaceable bits of the destination surface being overlaid for YUV colors.
DDCKEYCAPS_NOCOSTOVERLAY | Indicates that there are no bandwidth tradeoffs for using the color key with an overlay.
DDCKEYCAPS_SRCBLT | Supports transparent blitting using the color key for the source with this surface for RGB colors.
DDCKEYCAPS_SRCBLTCLRSPACE | Supports transparent blitting using a color space for the source with this surface for RGB colors.
DDCKEYCAPS_SRCBLTCLRSPACEYUV | Supports transparent blitting using a color space for the source with this surface for YUV colors.
DDCKEYCAPS_SRCBLTYUV | Supports transparent blitting using the color key for the source with this surface for YUV colors.
DDCKEYCAPS_SRCOVERLAY | Supports overlaying using the color key for the source with this overlay surface for RGB colors.
DDCKEYCAPS_SRCOVERLAYCLRSPACE | Supports overlaying using a color space as the source color key for the overlay surface for RGB colors.
DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV | Supports overlaying using a color space as the source color key for the overlay surface for YUV colors.
DDCKEYCAPS_SRCOVERLAYONEACTIVE | Supports only one active source color key value for visible overlay surfaces.
DDCKEYCAPS_SRCOVERLAYYUV | Supports overlaying using the color key for the source with this overlay surface for YUV colors.

dwFXCaps
Specify the driver's stretching and effects capabilities. The driver should set the appropriate DDFXCAPS_Xxx bit for every capability that it supports.
Flag | Meaning
DDFXCAPS_BLTARITHSTRETCHY | Uses arithmetic operations, rather than pixel-doubling techniques, to stretch and shrink surfaces during a blit operation. Occurs along the y-axis (vertically).
DDFXCAPS_BLTARITHSTRETCHYN | Uses arithmetic operations, rather than pixel-doubling techniques, to stretch and shrink surfaces during a blit operation. Occurs along the y-axis (vertically), and works only for integer stretching (×1, ×2, and so on).
DDFXCAPS_BLTMIRRORLEFTRIGHT | Supports mirroring left to right in a blit operation.
DDFXCAPS_BLTMIRRORUPDOWN | Supports mirroring top to bottom in a blit operation.
DDFXCAPS_BLTROTATION | Supports arbitrary rotation in a blit operation. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDFXCAPS_BLTROTATION90 | Supports 90-degree rotations in a blit operation. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDFXCAPS_BLTSHRINKX | Supports arbitrary shrinking of a surface along the x-axis (horizontally). This flag is valid only for blit operations.
DDFXCAPS_BLTSHRINKXN | Supports integer shrinking (×1, ×2, and so on) of a surface along the x-axis (horizontally). This flag is valid only for blit operations.
DDFXCAPS_BLTSHRINKY | Supports arbitrary shrinking of a surface along the y-axis (vertically). This flag is valid only for blit operations.
DDFXCAPS_BLTSHRINKYN | Supports integer shrinking (×1, ×2, and so on) of a surface along the y-axis (vertically). This flag is valid only for blit operations.
DDFXCAPS_BLTSTRETCHX | Supports arbitrary stretching of a surface along the x-axis (horizontally). This flag is valid only for blit operations.
DDFXCAPS_BLTSTRETCHXN | Supports integer stretching (×1, ×2, and so on) of a surface along the x-axis (horizontally). This flag is valid only for blit operations.
DDFXCAPS_BLTSTRETCHY | Supports arbitrary stretching of a surface along the y-axis (vertically). This flag is valid only for blit operations.
DDFXCAPS_BLTSTRETCHYN | Supports integer stretching (×1, ×2, and so on) of a surface along the y-axis (vertically). This flag is valid only for blit operations.
DDFXCAPS_OVERLAYARITHSTRETCHY | Uses arithmetic operations, rather than pixel-doubling techniques, to stretch and shrink surfaces during an overlay operation. Occurs along the y-axis (vertically).
DDFXCAPS_OVERLAYARITHSTRETCHYN | Uses arithmetic operations, rather than pixel-doubling techniques, to stretch and shrink surfaces during an overlay operation. Occurs along the y-axis (vertically), and works only for integer stretching (×1, ×2, and so on).
DDFXCAPS_OVERLAYMIRRORLEFTRIGHT | Supports mirroring of overlays around the vertical axis.
DDFXCAPS_OVERLAYMIRRORUPDOWN | Supports mirroring of overlays across the horizontal axis.
DDFXCAPS_OVERLAYSHRINKX | Supports arbitrary shrinking of a surface along the x-axis (horizontally). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that shrinking is available.
DDFXCAPS_OVERLAYSHRINKXN | Supports integer shrinking (×1, ×2, and so on) of a surface along the x-axis (horizontally). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that shrinking is available.
DDFXCAPS_OVERLAYSHRINKY | Supports arbitrary shrinking of a surface along the y-axis (vertically). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that shrinking is available.
DDFXCAPS_OVERLAYSHRINKYN | Supports integer shrinking (×1, ×2, and so on) of a surface along the y-axis (vertically). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that shrinking is available.
DDFXCAPS_OVERLAYSTRETCHX | Supports arbitrary stretching of a surface along the x-axis (horizontally). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that stretching is available.
DDFXCAPS_OVERLAYSTRETCHXN | Supports integer stretching (×1, ×2, and so on) of a surface along the x-axis (horizontally). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that stretching is available.
DDFXCAPS_OVERLAYSTRETCHY | Supports arbitrary stretching of a surface along the y-axis (vertically). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that stretching is available.
DDFXCAPS_OVERLAYSTRETCHYN | Supports integer stretching (×1, ×2, and so on) of a surface along the y-axis (vertically). This flag is valid only for DDSCAPS_OVERLAY surfaces. This flag indicates only the capabilities of a surface; it does not indicate that stretching is available.

dwFXAlphaCaps
This member and its flags are obsolete and should not be used by the driver.
dwPalCaps
Specify the driver's palette capabilities. The driver should set the appropriate DDPCAPS_Xxx bit for every capability that it supports. The DDPCAPS_Xxx flags are defined in ddraw.h. The DirectDraw runtime currently ignores these capabilities.
dwSVCaps
Specify the driver's stereo vision capabilities. The driver should set the appropriate DDSVCAPS_Xxx bit for every capability that it supports.
Flag | Meaning
DDSVCAPS_ENIGMA | The stereo view is accomplished using Enigma encoding.
DDSVCAPS_FLICKER | The stereo view is accomplished using high-frequency flickering.
DDSVCAPS_REDBLUE | The stereo view is accomplished when the viewer looks at the image through red and blue filters placed over the left and right eyes. All images must adapt their color spaces for this process.
DDSVCAPS_SPLIT | The stereo view is accomplished with split-screen technology.

dwAlphaBltConstBitDepths,
dwAlphaBltPixelBitDepths,
dwAlphaBltSurfaceBitDepths,
dwAlphaOverlayConstBitDepths,
dwAlphaOverlayPixelBitDepths,
dwAlphaOverlaySurfaceBitDepths,
Are reserved for system use and can be ignored by the driver.
dwZBufferBitDepths
Is a flag that specifies the Z buffer depths supported by the driver. This can be one or more of the following values:
Flag | Meaning
DDBD_8 | The driver supports an 8bpp depth buffer.
DDBD_16 | The driver supports a 16bpp depth buffer.
DDBD_24 | The driver supports a 24bpp depth buffer.
DDBD_32 | The driver supports a 32bpp depth buffer.

dwVidMemTotal
Specifies the total amount of display memory, in bytes.
dwVidMemFree
Specifies the number of bytes of free display memory. The driver sets this member once during initialization to the same value it returns in the dwVidMemTotal member. DirectDraw will update it every time the application does a memory allocation.
dwMaxVisibleOverlays
Specifies the maximum number of visible overlays.
dwCurrVisibleOverlays
Specifies the current number of visible overlays.
dwNumFourCCCodes
Specifies the number of FourCC codes that the driver supports.
dwAlignBoundarySrc
Specifies the source rectangle alignment. This member can be optionally set by the driver. If the driver sets this member, then the overlay source rectangle's top left coordinate value must be a multiple of dwAlignBoundarySrc.
dwAlignSizeSrc
Specifies the size of the source rectangle, in bytes. This member can be optionally set by the driver. If the driver sets this member, then the overlay source rectangle's width must be a multiple of dwAlignSizeSrc.
dwAlignBoundaryDest
Specifies the destination rectangle alignment. This member can be optionally set by the driver. If the driver sets this member, then the overlay destination rectangle's top left coordinate value must be a multiple of dwAlignBoundaryDest.
dwAlignSizeDest
Specifies the destination rectangle byte size. This member can be optionally set by the driver. If the driver sets this member, then the overlay destination rectangle's width must be a multiple of dwAlignSizeDest.
dwAlignStrideAlign
Is reserved for system use and should be ignored by the driver.
dwRops
Specifies an array of DD_ROP_SPACE DWORDs that together can hold flags to indicate the ROPs that the driver supports. The driver should set the bit field for every corresponding ROP that it supports. See the Platform SDK documentation for information about ROPs.
ddsCaps
Specifies a DDSCAPS structure that describes the types of surfaces the driver supports.
dwMinOverlayStretch, dwMaxOverlayStretch
Are the minimum and maximum overlay stretch factors multiplied by 1000. For example, a factor of 1.3 should be stored as 1300.
dwMinLiveVideoStretch, dwMaxLiveVideoStretch
Are the minimum and maximum live video stretch factors multiplied by 1000. For example, a factor of 1.3 should be stored as 1300.
dwMinHwCodecStretch, dwMaxHwCodecStretch
Are the minimum and maximum hardware codec stretch factors multiplied by 1000. For example, a factor of 1.3 should be stored as 1300.
dwReserved1, dwReserved2, dwReserved3
Are reserved for system use. The driver should ignore these members.
dwSVBCaps
Is a set of flags that specify the driver-specific capabilities for system-memory-to-display-memory blits. The driver should bitwise OR the appropriate DDCAPS_Xxx flags to indicate the types of blit operations it supports when blitting from system memory to display memory.
dwSVBCKeyCaps
Is a set of flags that specify driver color-key capabilities for system-memory-to-display-memory blits. The driver should bitwise OR the appropriate DDCKEYCAPS_Xxx flags to indicate the types of color key operations it supports when blitting from system memory to display memory.
dwSVBFXCaps
Is a set of flags that specify driver FX capabilities for system-memory-to-display-memory blits. The driver should bitwise OR the appropriate DDFXCAPS_Xxx flags to indicate the types of effects it supports when blitting from system memory to display memory.
dwSVBRops
Specifies an array of DD_ROP_SPACE DWORDs that together can hold flags to indicate the ROPs that the driver supports when performing system-memory-to-display-memory blits. The driver should set the bit field for every corresponding ROP that it supports. See the Platform SDK documentation for information about ROPs.
dwVSBCaps
Is a set of flags that specify driver-specific capabilities for display-memory-to-system-memory blits. The driver should bitwise OR the appropriate DDCAPS_Xxx flags to indicate the types of blit operations it supports when blitting from display memory to system memory.
dwVSBCKeyCaps
Is a set of flags that specify driver color-key capabilities for display-memory-to-system-memory blits. The driver should bitwise OR the appropriate DDCKEYCAPS_Xxx flags to indicate the types of color key operations it supports when blitting from display memory to system memory.
dwVSBFXCaps
Is a set of flags that specify driver FX capabilities for display-memory-to-system-memory blits. The driver should bitwise OR the appropriate DDFXCAPS_Xxx flags to indicate the types of effects it supports when blitting from display memory to system memory.
dwVSBRops
Specifies an array of DD_ROP_SPACE DWORDs that together can hold flags to indicate the ROPs that the driver supports when performing display-memory-to-system-memory blits. The driver should set the bit field for every corresponding ROP that it supports. See the Platform SDK documentation for information about ROPs.
dwSSBCaps
Is a set of flags that specify driver-specific capabilities for system-memory-to-system-memory blits. The driver should bitwise OR the appropriate DDCAPS_Xxx flags to indicate the types of blit operations it supports when blitting from system memory to system memory.
dwSSBCKeyCaps
Is a set of flags that specify driver color-key capabilities for system-memory-to-system-memory blits. The driver should bitwise OR the appropriate DDCKEYCAPS_Xxx flags to indicate the types of color key operations it supports when blitting from system memory to system memory.
dwSSBFXCaps
Is a set of flags that specify driver FX capabilities for system-memory-to-system-memory blits. The driver should bitwise OR the appropriate DDFXCAPS_Xxx flags to indicate the types of effects it supports when blitting from system memory to system memory.
dwSSBRops
Specifies an array of DD_ROP_SPACE DWORDs that together can hold flags to indicate the ROPs that the driver supports when performing system-memory-to-system-memory blits. The driver should set the bit field for every corresponding ROP that it supports. See the Platform SDK documention for information about ROPs.
dwMaxVideoPorts
Specifies the maximum number of useable VPE objects.
dwCurrVideoPorts
Specifies the current number of VPE objects used. The driver does not need to fill in this member because it is set by DirectDraw.
dwSVBCaps2
Specify additional driver-specific capabilities for system-memory-to-display-memory blits. Valid flags are identical to the blit-related flags used with the dwCaps2 member.

Comments

This section contains the DirectDraw driver structure whose name has the form DDCORECAPS, which is the form used on Windows 98/Me. This structure is identical to that whose name has the form DDNTCORECAPS which is the form used on Windows 2000 and later versions. The include file dx95type.h contains a type define from DDNTCORECAPS to DDCORECAPS.

This structure mirrors the first entries of the DDCAPS structure, but is of a fixed size and does not grow as DDCAPS does.

The driver initializes DDCORECAPS when it is initializing the other members of the DD_HALINFO structure in its DrvGetDirectDrawInfo structure. The DirectDraw runtime might update some members.

DirectDraw requests additional driver capabilities by calling the DdGetDriverInfo function that is also returned in the DD_HALINFO structure.


DDKERNELCAPS

DDKERNELCAPS notifies the client what support, if any, exists in the miniport driver for the kernel-mode video transport.

typedef struct _DDKERNELCAPS {
  DWORD  dwSize;
  DWORD  dwCaps;
  DWORD  dwIRQCaps;
} DDKERNELCAPS, FAR *LPDDKERNELCAPS;

Members

dwSize
Specifies the size, in bytes, of this structure. This member must be initialized before the structure is used.
dwCaps
Is a set of flags indicating the device's capabilities. This member can be any combination of the following capabilities:
Flag | Meaning
DDKERNELCAPS_AUTOFLIP | The driver supports the DxFlipVideoPort and the DxFlipOverlay callbacks, and that these callbacks can be used for autoflipping.
DDKERNELCAPS_CAPTURE_INVERTED | The device supports inverting the DIBs while capturing the data.
DDKERNELCAPS_CAPTURE_NONLOCALVIDMEM | The device supports a VPE capture interface capable of transferring data to nonlocal display memory.
DDKERNELCAPS_CAPTURE_SYSMEM | The device supports a VPE capture interface capable of transferring data to system memory.
DDKERNELCAPS_FIELDPOLARITY | The device can report the polarity (even/odd) of the current VPE object field.
DDKERNELCAPS_FLIPOVERLAY | The driver supports the DxFlipOverlay callback.
DDKERNELCAPS_FLIPVIDEOPORT | The driver supports the DxFlipVideoPort callback.
DDKERNELCAPS_LOCK | The device supports accessing the frame buffer without causing contention with blitters, and so on, and that the driver supports the DxLock callback.
DDKERNELCAPS_SETSTATE | The driver supports the DxSetState callback, allowing a client to switch between bob and weave display modes.
DDKERNELCAPS_SKIPFIELDS | The device supports field skipping, either using hardware or by supporting the DxSkipNextField callback.

dwIRQCaps
Can be a combination of the following flags:
Flag | Meaning
DDIRQ_DISPLAY_VSYNC | The device can generate IRQs based on the display VSYNC.
DDIRQ_VPORT0_LINE | The device can generate IRQs based on a programmable line for hardware video port number 0.
DDIRQ_VPORT0_VSYNC | The device can generate VSYNC IRQs for hardware video port number 0.
DDIRQ_VPORT1_LINE | The device can generate IRQs based on a programmable line for hardware video port number 1.
DDIRQ_VPORT1_VSYNC | The device can generate V-sync IRQs for hardware video port number 1
DDIRQ_VPORT2_LINE | The device can generate IRQs based on a programmable line for hardware video port number 2.
DDIRQ_VPORT2_VSYNC | The device can generate V-sync IRQs for hardware video port number 2.
DDIRQ_VPORT3_LINE | The device can generate IRQs based on a programmable line for hardware video port number 3.
DDIRQ_VPORT3_VSYNC | The device can generate V-sync IRQs for hardware video port number 3.
DDIRQ_VPORT4_LINE | The device can generate IRQs based on a programmable line for hardware video port number 4.
DDIRQ_VPORT4_VSYNC | The device can generate V-sync IRQs for hardware video port number 4.
DDIRQ_VPORT5_LINE | The device can generate IRQs based on a programmable line for hardware video port number 5.
DDIRQ_VPORT5_VSYNC | The device can generate V-sync IRQs for hardware video port number 5.
DDIRQ_VPORT6_LINE | The device can generate IRQs based on a programmable line for hardware video port number 6.
DDIRQ_VPORT6_VSYNC | The device can generate V-sync IRQs for hardware video port number 6.
DDIRQ_VPORT7_LINE | The device can generate IRQs based on a programmable line for hardware video port number 7.
DDIRQ_VPORT7_VSYNC | The device can generate V-sync IRQs for hardware video port number 7.
DDIRQ_VPORT8_LINE | The device can generate IRQs based on a programmable line for hardware video port number 8.
DDIRQ_VPORT8_VSYNC | The device can generate V-sync IRQs for hardware video port number 8.
DDIRQ_VPORT9_LINE | he device can generate IRQs based on a programmable line for hardware video port number 9.
DDIRQ_VPORT9_VSYNC | he device can generate V-sync IRQs for hardware video port number 9.


DDMOCOMPBUFFERINFO

DDMOCOMPBUFFERINFO contains the macro block information required to render a frame and passes this information to the DD_RENDERMOCOMPDATA structure.

typedef struct _DDMOCOMPBUFFERINFO {
  DWORD  dwSize;
  PDD_SURFACE_LOCAL  lpCompSurface;
  DWORD  dwDataOffset;
  DWORD  dwDataSize;
  LPVOID  lpPrivate;
} DDMOCOMPBUFFERINFO, *LPDDMOCOMPBUFFERINFO;

Members

dwSize
Specifies the size in bytes of this DDMOCOMPBUFFERINFO structure.
lpCompSurface
Points to a DD_SURFACE_LOCAL structure that contains the compressed data.
dwDataOffset
Indicates the offset to the relevant data, in bytes, from the beginning of the buffer. This value does not allow for pitch.
dwDataSize
Indicates the size of the relevant data in bytes. This value does not allow for pitch.
lpPrivate
Is used by DirectDraw and should be ignored by the driver.


DDPIXELFORMAT

DDPIXELFORMAT describes the pixel format of a DirectDrawSurface object.

typedef struct _DDPIXELFORMAT {
  DWORD  dwSize;
  DWORD  dwFlags;
  DWORD  dwFourCC;
union
{
  DWORD  dwRGBBitCount;
  DWORD  dwYUVBitCount;
  DWORD  dwZBufferBitDepth;
  DWORD  dwAlphaBitDepth;
  DWORD  dwLuminanceBitCount;
  DWORD  dwBumpBitCount;
  DWORD  dwPrivateFormatBitCount;
} ;
union
{
  DWORD  dwRBitMask;
  DWORD  dwYBitMask;
  DWORD  dwStencilBitDepth;
  DWORD  dwLuminanceBitMask;
  DWORD  dwBumpDuBitMask;
  DWORD  dwOperations;
} ;
union
{
  DWORD  dwGBitMask;
  DWORD  dwUBitMask;
  DWORD  dwZBitMask;
  DWORD  dwBumpDvBitMask;
  struct
  {
    WORD wFlipMSTypes;
    WORD wBltMSTypes;
  } MultiSampleCaps;
} ;
union
{
  DWORD  dwBBitMask;
  DWORD  dwVBitMask;
  DWORD  dwStencilBitMask;
  DWORD  dwBumpLuminanceBitMask;
} ;
union
{
  DWORD  dwRGBAlphaBitMask;
  DWORD  dwYUVAlphaBitMask;
  DWORD  dwLuminanceAlphaBitMask;
  DWORD  dwRGBZBitMask;
  DWORD  dwYUVZBitMask;
} ;
} DDPIXELFORMAT, FAR* LPDDPIXELFORMAT;

Members

dwSize
Specifies the size in bytes of the DDPIXELFORMAT structure. This member must be initialized before the structure is used.
dwFlags
Is a set of flags that specify optional control flags. This member is a bitwise-OR of any of the following values:
Flag | Meaning
DDPF_ALPHA | The pixel format describes an alpha-only surface.
DDPF_ALPHAPIXELS | The surface has alpha channel information in the pixel format.
DDPF_ALPHAPREMULT | The color components in the pixel are premultiplied by the alpha value in the pixel. If this flag is set, the DDPF_ALPHAPIXELS flag must also be set. If this flag is not set but the DDPF_ALPHAPIXELS flag is set, the color components in the pixel format are not premultiplied by alpha. In this case, the color components must be multiplied by the alpha value at the time that an alpha-blending operation is performed.
DDPF_BUMPDUDV | Bump map dUdV data in the pixel format is valid.
DDPF_BUMPHEIGHT | Bump map height data in the pixel format is valid.
DDPF_COMPRESSED | The surface accepts pixel data in the specified format and compresses it during the write operation.
DDPF_FOURCC | The FourCC code is valid.
DDPF_LUMINANCE | Luminance data in the pixel format is valid. Use this flag for luminance-only or luminance-plus-alpha surfaces; the bit depth is then specified in the dwLuminanceBitCount member.
DDPF_LUMINANCEPIXELS | Luminance data in the pixel format is valid. Use this flag when hanging luminance off, for example, bumpmap surfaces. The bit mask for the luminance portion of the pixel is then specified in the dwBumpLuminanceBitMask member.
DDPF_PALETTEINDEXED1 | The surface is 1-bit color indexed.
DDPF_PALETTEINDEXED2 | The surface is 2-bit color indexed.
DDPF_PALETTEINDEXED4 | The surface is 4-bit color indexed.
DDPF_PALETTEINDEXED8 | The surface is 8-bit color indexed.
DDPF_PALETTEINDEXEDTO8 | The surface is 1-, 2-, or 4-bit color indexed to an 8-bit palette.
DDPF_RGB | The RGB data in the pixel format structure is valid.
DDPF_RGBTOYUV | The surface accepts RGB data and translates it during the write operation to YUV data. The format of the data to be written is contained in the pixel format structure. The DDPF_RGB flag is set.
DDPF_STENCILPIXELS | The surface encodes stencil and depth information in each pixel of the z-buffer.
DDPF_YUV | The YUV data in the pixel format structure is valid.
DDPF_ZBUFFER | The pixel format describes a z-buffer-only surface.
DDPF_ZPIXELS | The surface is in RGBZ format.

dwFourCC
Specifies the FourCC code.
dwRGBBitCount
Specifies the number of RGB bits per pixel (4, 8, 16, 24, or 32).
dwYUVBitCount
Specifies the number of YUV bits per pixel.
dwZBufferBitDepth
Specifies the Z-buffer bit depth (8, 16, 24, or 32 bits).
dwAlphaBitDepth
Specifies the Alpha channel bit depth.
dwLuminanceBitCount
Specifies the number of bits per pixel.
dwBumpBitCount
Specifies the total number of bits per "bumpel" (bump-map texel).
dwPrivateFormatBitCount
Specifies the bits per pixel of a pixel format private to the driver (that is, not one of the standard ones defined by Direct3D).
dwRBitMask
Specifies the mask for red bits.
dwYBitMask
Specifies the mask for Y bits.
dwStencilBitDepth
Specifies the bit depth of the stencil buffer. This member specifies how many bits are reserved within each pixel of the z-buffer for stencil information.
dwLuminanceBitMask
Specifies the mask for luminance bits.
dwBumpDuBitMask
Specifies the mask for bump map U delta bits.
dwOperations
Specifies the intended operations that can be performed on surfaces with this pixel format, for example, whether they can be used as textures, cube maps, volume textures, or render targets. The operations that can be reported are as follows:
Operation | Meaning
D3DFORMAT_OP_TEXTURE | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as MIP mapped textures.
D3DFORMAT_OP_VOLUMETEXTURE | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as volume textures. Please note, that this flag is independent of D3DFORMAT_OP_TEXTURE. Thus, it is possible to specify a pixel format that can only be used for volume textures and not for conventional, MIP mapped textures.
D3DFORMAT_OP_CUBETEXTURE | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as cubic environment map textures. Please note, that this flag is independent of D3DFORMAT_OP_TEXTURE. Thus, it is possible to specify a pixel format that can only be used for cubic environment map textures and not for conventional, MIP mapped textures.
D3DFORMAT_OP_OFFSCREEN_RENDERTARGET | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as an offscreen render target regardless of the pixel format of the display mode (providing the pixel format of the current display mode was reported with the D3DFORMAT_OP_DISPLAYMODE and D3DFORMAT_OP_3DACCELERATION). If the pixel format of the current display mode did not have these flags set it indicates no 3D acceleration is available in this mode even if the render target is offscreen. This flag can be combined with D3DFORMAT_OP_TEXTURE to indicate that the device can render to textures of the specified pixel format.
D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as render targets but only when the pixel format of the surface matches the pixel format of the current display mode. This flag does not only apply to offscreen render target but can be specified on the pixel formats of display modes to indicate rendering target capability. This flag can be combined with D3DFORMAT_OP_TEXTURE to indicate that the device can render to textures of the specified pixel format.
D3DFORMAT_OP_ZSTENCIL | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as Z/Stencil buffers but only if the depth of the Z/Stencil surface matches the color depth of the rendering target to which the depth buffer is attached. When deciding on a match between Z/Stencil and color buffer depth, the pixel stride is used.
D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as Z/Stencil buffers regardless of the color depth of the render target to which the surface is attached. When specifying this flag you also should specify D3DFORMAT_OP_ZSTENCIL.
D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET | When this flag is specified in a pixel format it indicates that surfaces of this format can be used as a render target if the current display mode is the same depth, if the alpha channel is ignored. For example, if the device can render to A8R8G8B8 when the display mode is X8R8G8B8, then the format operation list entry for A8R8G8B8 should have this flag set.
D3DFORMAT_OP_DISPLAYMODE | When this flag is specified it indicates that there is a display mode with this pixel format that has DirectDraw support (including Flip). This flag should not to be set on alpha formats.
D3DFORMAT_OP_3DACCELERATION | When this flag is specified the graphics accelerator can support some level of Direct3D acceleration when in a display mode with this pixel format and also implies that the driver can create a context in this mode (for some render target format). This flag must only be used when reporting display mode formats (by specifying the D3DFORMAT_OP_DISPLAYMODE). It is not required and indeed should not be set when reporting offscreen render targets formats.

dwGBitMask
Specifies the mask for green bits.
dwUBitMask
Specifies the mask for U bits.
dwZBitMask
Specifies the mask for Z bits.
dwBumpDvBitMask
Specifies the mask for bump map V delta bits.
wFlipMSTypes, wBltMSTypes
Used when specifying surfaces that can be used when performing multi-sample rendering (see Comments).
dwBBitMask
Specifies the mask for blue bits.
dwVBitMask
Specifies the mask for V bits.
dwStencilBitMask
Specifies the mask for stencil bits within each z-buffer pixel.
dwBumpLuminanceBitMask
Specifies the mask for luminance in a bump map.
dwRGBAlphaBitMask, dwYUVAlphaBitMask
Specify the masks for alpha channel.
dwLuminanceAlphaBitMask
Specifies the mask for luminance in the alpha channel.
dwRGBZBitMask, dwYUVZBitMask
Specify the masks for the z channel.

Comments

The runtime now imposes some rules on the op list. The current rules are:

  • Only one Endian-ness (big or little) for any DS format is allowed, for example D15S1 or S1D15, not both independent of other bits.
  • A list should only include D3DFORMAT_OP_DISPLAYMODE for exactly one 16bpp format (for example it should not enumerate 5:5:5 and 5:6:5).
  • A list should not contain any alpha formats with D3DFORMAT_OP_DISPLAYMODE or D3DFORMAT_OP_3DACCELLERATION set.
  • Make sure no mode has D3DFORMAT_OP_3DACCELLERATION set that does not also have D3DFORMAT_OP_DISPLAYMODE set.

If the driver supports a lockable D16, it should report D3DFMT_D16_LOCKABLE in the op list; otherwise, it should report D3DFMT_D16.

Drivers supporting multisampling must fill in the MultiSampleCaps in the Depth/Stencil formats for which multisampling can be supported. This allows the runtime to detect if a driver supports multisampling for combinations of render target and Z buffer formats. For additional information about the restrictions related to stretch blt multi-sampling, see the description of D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE cap in the rastercaps contained in the D3DCAPS8 structure in the SDK documentation.

The enumerated type D3DMULTISAMPLE_TYPE defined in d3d8types.h is used when setting the bits in wFlipMSTypes and wBltMSTypes. To specify support for a specific number of samples per pixel, simply logically shift 1 by the appropriate value from the D3DMULTISAMPLE_TYPE enumerated type less 1 and OR this into the appropriate field (wFlipMSTypes and wBltMSTypes).

For example, if the driver supports both two and four samples for pixel when flipping (fullscreen mode) and four samples per pixel when blitting (windowed mode) on X8R8G8B8 surface the following entry would be reported in the surface format list.

DDPIXELFORMAT ddpf;
ZeroMemory(&ddpf, sizeof(ddpf));
ddpf.dwSize       = sizeof(DDPIXELFORMAT);
ddpf.dwFlags      = DDPF_D3DFORMAT;
ddpf.dwFourCC     = D3DFMT_X8R8G8B8;
ddpf.dwOperations = D3DFORMAT_OP_DISPLAYMODE |
                    D3DFORMAT_OP_3DACCELERATION;
ddpf.MultiSampleCaps.wFlipMSTypes = (1 << (D3DMULTISAMPLE_4_SAMPLES – 1))
                                  | (1 << (D3DMULTISAMPLE_2_SAMPLES – 1));
ddpf.MultiSampleCaps.wBltMSTypes = (1 << (D3DMULTISAMPLE_4_SAMPLES – 1));

It is not necessary to specify 1 << (D3DMULTISAMPLE_NONE - 1) when reporting formats. It is assumed that any format reported can also be used without multi-sampling. If the hardware supports multi-sample rendering with a z-buffer the z-buffer formats reported should also include the supported samples-per-pixels.


DDSCAPS

DDSCAPS defines the capabilities of a DirectDraw surface object.

typedef struct _DDSCAPS {
  DWORD  dwCaps;
} DDSCAPS, FAR* LPDDSCAPS;

Members

dwCaps
Is a set of flags that specify the capabilities of the surface. This member is a bitwise OR of any of the following flags:
Flag | Meaning
DDSCAPS_3DDEVICE | This surface can be used for 3D rendering. Applications can use this flag to ensure that a device that can only render to a certain heap has offscreen surfaces allocated from the correct heap. If this flag is set for a heap, the surface is not allocated from that heap.
DDSCAPS_ALLOCONLOAD | Memory for the surface is not allocated until the surface is loaded by the application using the IDirect3DTexture::Load method.
DDSCAPS_ALPHA | This surface contains alpha information only.
DDSCAPS_BACKBUFFER | This surface is the back buffer of a surface flipping structure. Typically, this capability is set by the application's CreateSurface method when the DDSCAPS_FLIP flag is used. Only the surface that immediately precedes the DDSCAPS_FRONTBUFFER surface has this capability set. The other surfaces are identified as back buffers by the presence of the DDSCAPS_FLIP flag, their attachment order, and the absence of the DDSCAPS_FRONTBUFFER and DDSCAPS_BACKBUFFER capabilities. If this capability is sent to the application's CreateSurface method, a stand-alone back buffer is being created. After this method is called, this surface could be attached to a front buffer, another back buffer, or both to form a flipping surface structure. For more information, see the AddAttachedSurface method in the DirectX SDK. DirectDraw supports an arbitrary number of surfaces in a flipping structure.
DDSCAPS_COMPLEX | A complex surface is being described. A complex surface results in the creation of more than one surface. The additional surfaces are attached to the root surface. The complex structure can be destroyed only by destroying the root.
DDSCAPS_FLIP | This surface is a part of a surface flipping structure. When this capability is passed to the application's CreateSurface method, a front buffer and one or more back buffers are created. DirectDraw sets the DDSCAPS_FRONTBUFFER bit on the front-buffer surface and the DDSCAPS_BACKBUFFER bit on the surface adjacent to the front-buffer surface. The dwBackBufferCount member of the DDSURFACEDESC structure must be set to at least 1 in order for the method call to succeed. The DDSCAPS_COMPLEX capability must always be set when creating multiple surfaces by using the CreateSurface method.
DDSCAPS_FRONTBUFFER | This surface is the front buffer of a surface flipping structure. This flag is typically set by the application's CreateSurface method when the DDSCAPS_FLIP capability is set. If this capability is sent to the CreateSurface method, a stand-alone front buffer is created. This surface will not have the DDSCAPS_FLIP capability. It can be attached to other back buffers to form a flipping structure by using the application's AddAttachedSurface method.
DDSCAPS_HWCODEC | This surface should be able to have a stream decompressed to it by the hardware.
DDSCAPS_LIVEVIDEO | This surface should be able to receive live video.
DDSCAPS_LOCALVIDMEM | This surface exists in true, local display memory rather than nonlocal display memory. If this flag is specified, then DDSCAPS_VIDEOMEMORY must be specified as well. This flag cannot be used with the DDSCAPS_NONLOCALVIDMEM flag.
DDSCAPS_MIPMAP | This surface is one level of a mipmap. This surface is attached to other DDSCAPS_MIPMAP surfaces to form the mipmap. This can be done explicitly by creating a number of surfaces and attaching them by using the application's AddAttachedSurface method, or implicitly by the application's CreateSurface method. If this capability is set, DDSCAPS_TEXTURE must also be set.
DDSCAPS_MODEX | This surface is a 320×200 or 320×240 Mode X surface. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDSCAPS_NONLOCALVIDMEM | This surface exists in nonlocal display memory rather than true, local display memory. If this flag is specified, then DDSCAPS_VIDEOMEMORY flag must be specified as well. This cannot be used with the DDSCAPS_LOCALVIDMEM flag.
DDSCAPS_OFFSCREENPLAIN | This surface is any offscreen surface that is not an overlay, texture, z-buffer, front-buffer, back-buffer, or alpha surface. It is used to identify plain surfaces.
DDSCAPS_OVERLAY | This surface is an overlay. The visibility of this overlay depends on whether it is currently being overlaid onto the primary surface. DDSCAPS_VISIBLE can be used to determine whether it is being overlaid at the moment.
DDSCAPS_OPTIMIZED | This flag is not currently implemented.
DDSCAPS_OWNDC | This surface will have a device context (DC) association for a long period. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDSCAPS_PALETTE | This device driver allows unique DirectDrawPalette objects to be created and attached to this surface.
DDSCAPS_PRIMARYSURFACE | This surface is the primary surface. It represents what is visible to the user at the moment.
DDSCAPS_PRIMARYSURFACELEFT | This surface is the primary surface for the left eye. It represents what is visible to the user's left eye at the moment. When this surface is created, the surface with the DDSCAPS_PRIMARYSURFACE capability represents what is seen by the user's right eye.
DDSCAPS_STANDARDVGAMODE | This surface is a standard VGA mode surface, and not a ModeX surface. This flag cannot be used in combination with the DDSCAPS_MODEX flag.
DDSCAPS_SYSTEMMEMORY | This surface memory was allocated from system memory. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDSCAPS_TEXTURE | This surface can be used as a 3D texture. It does not indicate whether the surface is being used for that purpose.
DDSCAPS_VIDEOMEMORY | This surface exists in display memory.
DDSCAPS_VIDEOPORT | This surface can receive data from a VPE object.
DDSCAPS_VISIBLE | Changes made to this surface are immediately visible. It is always set for the primary surface, as well as for overlays while they are being overlaid and texture maps while they are being textured.
DDSCAPS_WRITEONLY | Only write access is permitted to the surface. Read access from the surface may generate a general protection fault (GPF), but the read results from this surface are not meaningful. If this capability bit is set by the Windows 2000 or later driver, DirectDraw will be disabled.
DDSCAPS_ZBUFFER | This surface is the z-buffer. It contains bit-depth information that is used to determine which pixels are visible and which are obscured. The z-buffer contains information that cannot be displayed.

Comments

This structure is used by the driver to report the types of surfaces the driver supports. It is also filled in by an application to specify the type of surface to be created.


DDSCAPS2

DDSCAPS2 defines additional capabilities of a DirectDraw surface object.

typedef struct _DDSCAPS2 {
  DWORD  dwCaps;
  DWORD  dwCaps2;
  DWORD  dwCaps3;
  DWORD  dwCaps4;
} DDSCAPS2, FAR* LPDDSCAPS2;

Members

dwCaps
Is a set of flags representing the capabilities of the surface. The flags in this member are identical to those in the corresponding member of the DDSCAPS structure.
dwCaps2
Is a set of flags that indicate additional surface capabilities. This member can contain one or more of the following capability flags. Each of these flags, except DDSCAPS2_TEXTUREMANAGE, are set by the application when the application calls its CreateSurface method.
Flag | Meaning
DDSCAPS2_COMMANDBUFFER | Marks a command buffer, used by Direct3D to batch commands.
DDSCAPS2_CUBEMAP | This surface is a cubic environment map. When using this flag, also specify the face or faces of the cubic environment map to create.
DDSCAPS2_CUBEMAP_POSITIVEX | This flag is used with the DDSCAPS2_CUBEMAP flag to create the positive X face of a cubic environment map.
DDSCAPS2_CUBEMAP_NEGATIVEX | This flag is used with the DDSCAPS2_CUBEMAP flag to create the negative X face of a cubic environment map.
DDSCAPS2_CUBEMAP_POSITIVEY | This flag is used with the DDSCAPS2_CUBEMAP flag to create the positive Y face of a cubic environment map.
DDSCAPS2_CUBEMAP_NEGATIVEY | This flag is used with the DDSCAPS2_CUBEMAP flag to create the negative Y face of a cubic environment map.
DDSCAPS2_CUBEMAP_POSITIVEZ | This flag is used with the DDSCAPS2_CUBEMAP flag to create the positive Z face of a cubic environment map.
DDSCAPS2_CUBEMAP_NEGATIVEZ | This flag is used with the DDSCAPS2_CUBEMAP flag to create the negative Z face of a cubic environment map.
DDSCAPS2_CUBEMAP_ALLFACES | This flag is used with the DDSCAPS2_CUBEMAP flag to create all six faces of a cubic environment map.
DDSCAPS2_D3DTEXTUREMANAGE | The texture is always managed by Direct3D.
DDSCAPS2_DISCARDBACKBUFFER DirectX 8.0 and later versions only.

Indicates that preservation of the back buffer is not required. It will be set on the primary surface and the back buffers if the application has set D3DSWAPEFFECT_DISCARD on the Present API.
DDSCAPS2_DONOTPERSIST | The managed surface can be safely lost.
DDSCAPS2_HARDWAREDEINTERLACE | The driver must convert the interlaced signal to progressive frames. The DDSCAPS_VIDEOPORT and DDSCAPS_OVERLAY flags in this structure must also be set.
DDSCAPS2_HINTANTIALIASING | The application will use antialiasing. This flag is valid only if the DDSCAPS_3DDEVICE flag is also set.
DDSCAPS2_HINTDYNAMIC | The application will be updating the surface frequently. Surfaces with this flag set must also have the DDSCAPS_TEXTURE flag in this structure set. This flag cannot be used with the DDSCAPS2_HINTSTATIC or DDSCAPS2_OPAQUE flags.
DDSCAPS2_HINTSTATIC | The application will be updating the surface infrequently, but still requires access. Surfaces with this flag set must also have the DDSCAPS_TEXTURE flag in this structure set. This flag cannot be used with the DDSCAPS2_HINTDYNAMIC or DDSCAPS2_OPAQUE flags.
DDSCAPS2_INDEXBUFFER DirectX 8.0 and later versions only.

Marks an index buffer, created and controlled by the application.
DDSCAPS2_MIPMAPSUBLEVEL | It enables easier use of GetAttachedSurface, rather than EnumAttachedSurfaces, for surface constructs such as cube maps, in which there is more than one mipmap surface attached to the root surface. This should be set on all non-top-level surfaces in a mipmapped cube map so that a call to GetAttachedSurface can distinguish between top-level faces and attached mipmap levels. This capability bit is ignored by CreateSurface.
DDSCAPS2_NOTUSERLOCKABLE DirectX 8.0 and later versions only.

Set on the primary and the back buffers if the flipping chain is not lockable, or on any render target that is not lockable. This allows drivers to do behind the scenes optimization. Note that it is still possible to lock the surfaces so the driver will need to handle these cases, but such locks will be very infrequent and are not expected to be fast.
DDSCAPS2_NPATCHES DirectX 8.0 and later versions only.

Indicates that the vertex buffer data can be used to render n-patches.
DDSCAPS2_OPAQUE | The application will never lock, blit, or update the surface for the rest of that surface's lifetime. The driver can compress or reorder the surface without ever having to decompress it. Surfaces with this flag set must also have the DDSCAPS_TEXTURE flag in this structure set. This flag cannot be used with the DDSCAPS2_HINTDYNAMIC or DDSCAPS2_HINTSTATIC flags.
DDSCAPS2_POINTS DirectX 8.0 and later versions only.

Indicates that the vertex buffer data can be used to render points and point sprites.
DDSCAPS2_RTPATCHES DirectX 8.0 and later versions only.

Indicates that the vertex buffer data can be used to render rt-patches.
DDSCAPS2_STEREOSURFACELEFT This surface is part of a stereo flipping chain. When this flag is set during a CreateSurface call, a pair of stereo surfaces are created for each buffer in the primary flipping chain. You must create a complex flipping chain (with back buffers). You cannot create a single set of stereo surfaces. The Flip method requires back buffers, so at least 4 surfaces must be created.

In addition, when this flag is set in a DDSURFACEDESC structure as the result of an EnumDisplayModes or GetDisplayMode call, it indicates support for stereo in that mode.
DDSCAPS2_TEXTUREMANAGE | The client indicates that this texture surface should be managed by the driver if possible; otherwise it is managed by Direct3D Immediate Mode. This flag can be used only for texture surfaces (DDSCAPS_TEXTURE flag set in the dwCaps member). For more information, see Automatic Texture Management in the Direct3D Immediate Mode documentation.
DDSCAPS2_VERTEXBUFFER | Marks an explicit vertex buffer, created and controlled by the application.
DDSCAPS2_VOLUME DirectX 8.0 and later versions only.

This flag will be set if the texture has depth in addition to width and height.

dwCaps3
Is the number of samples for a multi-sampled surface. This field holds one of the values of the enumerated type D3DMULTISAMPLE_TYPE. If a surface is not multi-sampled, dwCaps3 will have the value D3DMULTISAMPLE_NONE (0).
dwCaps4
The low word is the depth for a volume texture.

Comments

This structure is used by the driver to report the types of surfaces the driver supports. It is also filled in by an application to specify the type of surface to be created.


DDSURFACEDATA

DDSURFACEDATA is used by DirectDraw to represent a surface to the kernel-mode miniport driver.

typedef struct _DDSURFACEDATA {
  DWORD  ddsCaps;
  DWORD  dwSurfaceOffset;
  ULONG_PTR  fpLockPtr;
  DWORD  dwWidth;
  DWORD  dwHeight;
  LONG   lPitch;
  DWORD  dwOverlayFlags;
  DWORD  dwOverlayOffset;
  DWORD  dwOverlaySrcWidth;
  DWORD  dwOverlaySrcHeight;
  DWORD  dwOverlayDestWidth;
  DWORD  dwOverlayDestHeight;
  DWORD  dwVideoPortId;
  DWORD  dwFormatFlags;
  DWORD  dwFormatFourCC;
  DWORD  dwFormatBitCount;
  DWORD  dwRBitMask;
  DWORD  dwGBitMask;
  DWORD  dwBBitMask;
  ULONG  dwDriverReserved1;
  ULONG  dwDriverReserved2;
  ULONG  dwDriverReserved3;
  ULONG  dwDriverReserved4;
} DDSURFACEDATA, *LPDDSURFACEDATA;

Members

ddsCaps
Points to a DDSCAPS structure that contains the creation capabilities used to describe the surface.
dwSurfaceOffset
Specifies the byte offset from the beginning of the frame buffer to the start of the surface. This field is used only by the miniport driver.
fpLockPtr
Points to the start of the surface.
dwWidth
Specifies the surface width, in pixels.
dwHeight
Specifies the surface height, in pixels.
lPitch
Specifies the surface pitch.
dwOverlayFlags
Is a set of flags that specify the current user-mode DDOVER_Xxx flags set by DdUpdateOverlay.
Flag | Meaning
DDOVER_ADDDIRTYRECT | Add a dirty rectangle to an emulated overlaid surface.
DDOVER_ALPHADEST | Use either the alpha information in pixel format or the alpha channel surface attached to the destination surface as the alpha channel for this overlay.
DDOVER_ALPHADESTCONSTOVERRIDE | Use the dwAlphaDestConst member of the DDOVERLAYFX structure as the destination alpha channel for this overlay. The DDOVERLAYFX structure is defined in ddraw.h.
DDOVER_ALPHADESTNEG | The destination surface becomes more transparent as the alpha value increases (0 is opaque).
DDOVER_ALPHADESTSURFACEOVERRIDE | Use the lpDDSAlphaDest member of the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the alpha channel destination for this overlay.
DDOVER_ALPHAEDGEBLEND | Use the dwAlphaEdgeBlend member of the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the alpha channel for the edges of the image that border the color key colors.
DDOVER_ALPHASRC | Use either the alpha information in pixel format or the alpha channel surface attached to the source surface as the source alpha channel for this overlay.
DDOVER_ALPHASRCCONSTOVERRIDE | Use the dwAlphaSrcConst member of the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the source alpha channel for this overlay.
DDOVER_ALPHASRCNEG | The source surface becomes more transparent as the alpha value increases (0 is opaque).
DDOVER_ALPHASRCSURFACEOVERRIDE | Use the lpDDSAlphaSrc member of the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the alpha channel source for this overlay.
DDOVER_AUTOFLIP | Automatically flip to the next surface in the flip chain each time a hardware video port VSYNC occurs.
DDOVER_BOB | Display each field of the interlaced video stream individually without causing any artifacts.
DDOVER_BOBHARDWARE | Bob is performed using hardware rather than software or being emulated.
DDOVER_DDFX | Use the overlay FX flags to define special overlay effects.
DDOVER_HIDE | Turn this overlay off.
DDOVER_INTERLEAVED | The surface memory is composed of interleaved fields.
DDOVER_KEYDEST | Use the color key associated with the destination surface.
DDOVER_KEYDESTOVERRIDE | Use the dckDestColorkey member of the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the color key for the destination surface.
DDOVER_KEYSRC | Use the color key associated with the source surface.
DDOVER_KEYSRCOVERRIDE | Use the dckSrcColorkey member of the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the color key for the source surface.
DDOVER_OVERRIDEBOBWEAVE | Bob and weave decisions should not be overridden by other interfaces. If this flag is set, DirectDraw will not allow a kernel-mode driver to use the kernel-mode video transport functionality to switch the hardware between bob and weave mode.
DDOVER_REFRESHALL | Redraw the entire surface on an emulated overlaid surface.
DDOVER_REFRESHDIRTYRECTS | Redraw all dirty rectangles on an emulated overlaid surface.
DDOVER_SHOW | Turn this overlay on.

dwOverlayOffset
Specifies the byte offset from the beginning of the frame buffer to the start of the overlay. This field is used only by the miniport driver.
dwOverlaySrcWidth
Specifies the overlay source width. This field is used only by the miniport driver.
dwOverlaySrcHeight
Specifies the overlay source height. This field is used only by the miniport driver.
dwOverlayDestWidth
Specifies the overlay destination width. This field is used only by the miniport driver.
dwOverlayDestHeight
Specifies the overlay destination height. This field is used only by the miniport driver.
dwVideoPortId
If this surface is being fed by a VPE object, this field indicates the ID of the VPE object, an integer in the range (0 - (maximum number of hardware video ports -1 )); otherwise, this field is -1.
dwFormatFlags
Is a set of pixel-format control flags.
Flag | Meaning
DDPF_ALPHA | The pixel format describes an alpha-only surface.
DDPF_ALPHAPIXELS | The surface has alpha channel information in the pixel format.
DDPF_ALPHAPREMULT | The color components in the pixel are premultiplied by the alpha value in the pixel. If this flag is set, the DDPF_ALPHAPIXELS flag must also be set. If this flag is not set but the DDPF_ALPHAPIXELS flag is set, the color components in the pixel format are not premultiplied by alpha. In this case, the color components must be multiplied by the alpha value at the time that an alpha-blending operation is performed.
DDPF_BUMPDUDV | The bump map dUdV data in the pixel format is valid.
DDPF_BUMPLUMINANCE | The luminance data in pixel format is valid. This flag is used when hanging luminance off bumpmap surfaces. The bit mask for the luminance portion of the pixel is then indicated by the dwBumpLuminanceBitCount member of the DDPIXELFORMAT structure.
DDPF_COMPRESSED | The surface will accept pixel data in the specified format and compress it during the write operation.
DDPF_FOURCC | The FourCC code is valid.
DDPF_LUMINANCE | The luminance data in the pixel format is valid. This flag is used for luminance only or luminance plus alpha surfaces; the bit depth is then indicated by the dwLuminanceBitCount member of the DDPIXELFORMAT structure.
DDPF_PALETTEINDEXED1 | The surface is 1--bit color indexed.
DDPF_PALETTEINDEXED2 | The surface is 2--bit color indexed.
DDPF_PALETTEINDEXED4 | The surface is 4--bit color indexed.
DDPF_PALETTEINDEXED8 | The surface is 8-bit color indexed.
DDPF_PALETTEINDEXEDTO8 | The surface is 1-, 2-, or 4-bit color indexed to an 8-bit palette.
DDPF_RGB | The RGB data in the pixel format structure is valid.
DDPF_RGBTOYUV | The surface will accept RGB data and translate it during the write operation to YUV data. The format of the data to be written will be contained in the pixel format structure. The DDPF_RGB flag will be set.
DDPF_STENCILBUFFER | The surface contains stencil information along with Z information.
DDPF_YUV | The YUV data in the pixel format structure is valid.
DDPF_ZBUFFER | The pixel format describes a z-buffer-only surface.
DDPF_ZPIXELS | The surface is in RGBZ format.

dwFormatFourCC
Specifies the FourCC code.
dwFormatBitCount
Specifies the number of bits per pixel (4, 8, 16, 24, or 32).
dwRBitMask
Specifies the red bit mask.
dwGBitMask
Specifies the green bit mask.
dwBBitMask
Specifies the blue bit mask.
dwDriverReserved1, dwDriverReserved2, dwDriverReserved3, dwDriverReserved4
Are reserved for use by the miniport driver.


DDSURFACEDESC

DDSURFACEDESC contains a description of a surface to be created by the driver.

typedef struct _DDSURFACEDESC {
  DWORD  dwSize;
  DWORD  dwFlags;
  DWORD  dwHeight;
  DWORD  dwWidth;
  union
  {
  LONG  lPitch;
  DWORD  dwLinearSize;
  };
  DWORD  dwBackBufferCount;
  union
  {
  DWORD  dwMipMapCount;
  DWORD  dwZBufferBitDepth;
  DWORD  dwRefreshRate;
  };
  DWORD  dwAlphaBitDepth;
  DWORD  dwReserved;
  LPVOID  lpSurface;
  DDCOLORKEY  ddckCKDestOverlay;
  DDCOLORKEY  ddckCKDestBlt;
  DDCOLORKEY  ddckCKSrcOverlay;
  DDCOLORKEY  ddckCKSrcBlt;
  DDPIXELFORMAT  ddpfPixelFormat;
  DDSCAPS  ddsCaps;
} DDSURFACEDESC;

Members

dwSize
Specifies the size in bytes of this DDSURFACEDESC structure. This member must be initialized before the structure is used.
dwFlags
Is a set of flags that determine what members of the DDSURFACEDESC structure contain valid data. This member can be one or more of the following flags:
Flag | Meaning
DDSD_ALL | All input members contain valid data.
DDSD_ALPHABITDEPTH | The dwAlphaBitDepth member is valid.
DDSD_BACKBUFFERCOUNT | The dwBackBufferCount member is valid.
DDSD_CAPS | The ddsCaps member is valid.
DDSD_CKDESTBLT | The ddckCKDestBlt member is valid.
DDSD_CKDESTOVERLAY | The ddckCKDestOverlay member is valid.
DDSD_CKSRCBLT | The ddckCKSrcBlt member is valid.
DDSD_CKSRCOVERLAY | The ddckCKSrcOverlay member is valid.
DDSD_HEIGHT | The dwHeight member is valid.
DDSD_LINEARSIZE | The dwLinearSize member is valid.
DDSD_MIPMAPCOUNT | The dwMipMapCount member is valid.
DDSD_PITCH | The lPitch member is valid.
DDSD_PIXELFORMAT | The ddpfPixelFormat member is valid.
DDSD_REFRESHRATE | The dwRefreshRate member is valid.
DDSD_WIDTH | The dwWidth member is valid.
DDSD_ZBUFFERBITDEPTH | The dwZBufferBitDepth member is valid.

dwHeight
Specifies the height of surface in pixels.
dwWidth
Specifies the width of the surface in pixels.
lPitch
Specifies the number of bytes between the beginnings of two adjacent scan lines; that is, the number of bytes to add to the beginning address of one scan line to reach the beginning address of the next scan line below it. The driver's DdCreateSurface callback must return this value.
dwLinearSize
Specifies the size of a formless, late-allocated, optimized surface.
dwBackBufferCount
Specifies the number of back buffers associated with the surface.
dwMipMapCount
Specifies the number of mipmap levels.
dwZBufferBitDepth
Specifies the depth of z-buffer in bits per pixel.
dwRefreshRate
Specifies the refresh rate of the monitor (used when the display mode is described).
dwAlphaBitDepth
Specifies the depth of the alpha buffer in bits per pixel.
dwReserved
Is reserved and should be set to zero.
lpSurface
Specifies the address of the associated surface memory.
ddckCKDestOverlay
Specifies the color key for destination overlay use.
ddckCKDestBlt
Specifies the color key for destination blt use.
ddckCKSrcOverlay
Specifies the color key for source overlay use.
ddckCKSrcBlt
Specifies the color key for source blt use.
ddpfPixelFormat
Specifies a DDPIXELFORMAT structure that describes the pixel format of the surface.
ddsCaps
Specifies a DDSCAPS structure that contains the DirectDraw surface capabilities.

Comments

The relevant members differ for each potential type of surface. This structure is typically created and initialized by an application.


DDSURFACEDESC2

DDSURFACEDESC2 contains a description of a surface to be created by the driver.

typedef struct _DDSURFACEDESC2 {
  DWORD  dwSize;
  DWORD  dwFlags;
  DWORD  dwHeight;
  DWORD  dwWidth;
  union
  {
  LONG  lPitch;
  DWORD  dwLinearSize;
  } ;
  DWORD  dwBackBufferCount;
  union
  {
  DWORD  dwMipMapCount;
  DWORD  dwRefreshRate;
  DWORD  dwSrcVBHandle;
  } ;
  DWORD  dwAlphaBitDepth;
  DWORD  dwReserved;
  LPVOID  lpSurface;
  union
  {
  DDCOLORKEY  ddckCKDestOverlay;
  DWORD  dwEmptyFaceColor;
  } ;
  DDCOLORKEY  ddckCKDestBlt;
  DDCOLORKEY  ddckCKSrcOverlay;
  DDCOLORKEY  ddckCKSrcBlt;
  union
  {
  DDPIXELFORMAT  ddpfPixelFormat;
  DWORD  dwFVF;
  } ;
  DDSCAPS2  ddsCaps;
  DWORD  dwTextureStage;
} DDSURFACEDESC2;

Members

dwSize
Specifies the size in bytes of this DDSURFACEDESC2 structure. This member must be initialized before the structure is used.
dwFlags
Is a set of flags that determine what members of the DDSURFACEDESC2 structure contain valid data. This member can be one or more of the following flags:
Flag | Meaning
DDSD_ALL | All input members contain valid data.
DDSD_ALPHABITDEPTH | The dwAlphaBitDepth member is valid.
DDSD_BACKBUFFERCOUNT | The dwBackBufferCount member is valid.
DDSD_CAPS | The ddsCaps member is valid.
DDSD_CKDESTBLT | The ddckCKDestBlt member is valid.
DDSD_CKDESTOVERLAY | The ddckCKDestOverlay member is valid.
DDSD_CKSRCBLT | The ddckCKSrcBlt member is valid.
DDSD_CKSRCOVERLAY | The ddckCKSrcOverlay member is valid.
DDSD_FVF | The dwFVF member is valid.
DDSD_HEIGHT | The dwHeight member is valid.
DDSD_LINEARSIZE | The dwLinearSize member is valid.
DDSD_LPSURFACE | The lpSurface member is valid.
DDSD_MIPMAPCOUNT | The dwMipMapCount member is valid.
DDSD_PITCH | The lPitch member is valid.
DDSD_PIXELFORMAT | The ddpfPixelFormat member is valid.
DDSD_REFRESHRATE | The dwRefreshRate member is valid.
DDSD_SRCVBHANDLE | The dwSrcVBHandle member is valid.
DDSD_TEXTURESTAGE | The dwTextureStage member is valid.
DDSD_WIDTH | The dwWidth member is valid.
DDSD_ZBUFFERBITDEPTH | This flag is not used in DDSURFACEDESC2. It is only used in DDSURFACEDESC.

dwHeight
Specifies the height of surface in pixels.
dwWidth
Specifies the width of the surface in pixels.
lPitch
Specifies the number of bytes between the beginnings of two adjacent scan lines; that is, the number of bytes to add to the beginning address of one scan line to reach the beginning address of the next scan line below it. The driver's DdCreateSurface callback must return this value.
dwLinearSize
Specifies the size of a formless, late-allocated, optimized surface.
dwBackBufferCount
Specifies the number of back buffers associated with the surface.
dwMipMapCount
Specifies the number of mipmap levels.
dwZBufferBitDepth
Removed in DDSURFACEDESC2. Use the ddpfPixelFormat member of this structure instead.
dwRefreshRate
Specifies the refresh rate of the monitor (used when the display mode is described).
dwSrcVBHandle
Specifies the source used in IDirect3DVertexBuffer7::Optimize (described in the Direct3D SDK documentation).
dwAlphaBitDepth
Specifies the depth of the alpha buffer in bits per pixel.
dwReserved
Is reserved and should be set to zero.
lpSurface
Specifies the address of the associated surface memory.
ddckCKDestOverlay
Specifies the color key for destination overlay use.
dwEmptyFaceColor
Specifies the physical color for empty cube map faces.
ddckCKDestBlt
Specifies the color key for destination blit use.
ddckCKSrcOverlay
Specifies the color key for source overlay use.
ddckCKSrcBlt
Specifies the color key for source blit use.
ddpfPixelFormat
Specifies a DDPIXELFORMAT structure that describes the pixel format of the surface.
dwFVF
Specifies the Flexible Vertex Format (FVF) for the vertex buffers.
ddsCaps
Specifies a DDSCAPS structure that contains the DirectDraw surface capabilities.
dwTextureStage
Specifies the stage in the multitexture cascade.

Comments

The relevant members differ for each potential type of surface. This structure is typically created and initialized by an application.


DDVIDEOPORTBANDWIDTH

DDVIDEOPORTBANDWIDTH describes the bandwidth characteristics of an overlay when used with a particular VPE object/pixel format configuration.

typedef struct _DDVIDEOPORTBANDWIDTH {
  DWORD  dwSize;
  DWORD  dwCaps;
  DWORD  dwOverlay;
  DWORD  dwColorkey;
  DWORD  dwYInterpolate;
  DWORD  dwYInterpAndColorkey;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  dwReserved2;
} DDVIDEOPORTBANDWIDTH;

Members

dwSize
Specifies the size in bytes of this DDVIDEOPORTBANDWIDTH structure.
dwCaps
Specifies the dependencies of the bandwidth. The driver's DdVideoPortGetBandwidth function sets this member to one of the following values:
Flag | Meaning
DDVPBCAPS_DESTINATION | The device’s capabilities are described in terms of the destination overlay’s minimum stretch factor. The bandwidth information set by the driver in the dwOverlay, dwColorkey, dwYInterpolate, and dwYInterpAndColorkey members refers to the destination overlay size.
DDVPBCAPS_SOURCE | The device’s capabilities are described in terms of the required source overlay's rectangle size (in pixels). The bandwidth information set by the driver in the dwOverlay, dwColorkey, dwYInterpolate, and dwYInterpAndColorkey members refers to the source overlay size.

dwOverlay
Specifies the stretch factor or overlay source size at which the device can support an overlay, multiplied by 1000. The driver sets this value based on its device's type and capabilities, and on the dimensions specified in the dwWidth and dwHeight members of the DD_GETVPORTBANDWIDTHDATA structure passed to DdVideoPortGetBandwidth. For example, a stretch factor of 2 is specified as 2000, and an overlay source size of 750 indicates that the specified source overlay be shrunk to 75 percent of its original size. The driver must return a valid number in this member.
dwColorkey
Specifies the stretch factor or overlay source size at which an overlay with color keying is supported, multiplied by 1000. The driver sets this value based on its device's type and capabilities, and on the dimensions specified in the dwWidth and dwHeight members of the DD_GETVPORTBANDWIDTHDATA structure passed to DdVideoPortGetBandwidth. For example, a stretch factor of 2 is specified as 2000.
dwYInterpolate
Specifies the stretch factor or overlay source size at which an overlay with y-axis interpolation is supported, multiplied by 1000. The driver sets this value based on its device's type and capabilities, and on the dimensions specified in the dwWidth and dwHeight members of the DD_GETVPORTBANDWIDTHDATA structure passed to DdVideoPortGetBandwidth. For example, a stretch factor of 2 is specified as 2000.
dwYInterpAndColorkey
Specifies the stretch factor or overlay source size at which an overlay with y-axis interpolation and color keying is supported, multiplied by 1000. The driver sets this value based on its device's type and capabilities, and on the dimensions specified in the dwWidth and dwHeight members of the DD_GETVPORTBANDWIDTHDATA structure passed to DdVideoPortGetBandwidth. For example, a stretch factor of 2 is specified as 2000.
dwReserved1, dwReserved2
Are reserved for system use and should be ignored by the driver.


DDVIDEOPORTCAPS

DDVIDEOPORTCAPS describes the capabilities and alignment restrictions of a hardware video port.

typedef struct _DDVIDEOPORTCAPS {
  DWORD  dwSize;
  DWORD  dwFlags;
  DWORD  dwMaxWidth;
  DWORD  dwMaxVBIWidth;
  DWORD  dwMaxHeight;
  DWORD  dwVideoPortID;
  DWORD  dwCaps;
  DWORD  dwFX;
  DWORD  dwNumAutoFlipSurfaces;
  DWORD  dwAlignVideoPortBoundary;
  DWORD  dwAlignVideoPortPrescaleWidth;
  DWORD  dwAlignVideoPortCropBoundary;
  DWORD  dwAlignVideoPortCropWidth;
  DWORD  dwPreshrinkXStep;
  DWORD  dwPreshrinkYStep;
  DWORD  dwNumVBIAutoFlipSurfaces;
  DWORD  dwNumPreferredAutoflip;
  WORD  wNumFilterTapsX;
  WORD  wNumFilterTapsY;
} DDVIDEOPORTCAPS;

Members

dwSize
Specifies the size in bytes of the structure.
dwFlags
Specify what members in this structure contain valid data. This member can be a bitwise-OR of any of the following values:
Flag | Meaning
DDVPD_ALIGN All of the alignment members are valid. These include:
dwAlignVideoPortBoundary,
dwAlignVideoPortPrescaleWidth,
dwAlignVideoPortCropBoundary, and
dwAlignVideoPortCropWidth.
DDVPD_AUTOFLIP | The dwNumAutoFlipSurfaces is valid.
DDVPD_CAPS | The dwCaps member is valid.
DDVPD_FX | The dwFX member is valid.
DDVPD_HEIGHT | The dwMaxHeight member is valid.
DDVPD_ID | The dwVideoPortID member is valid.
DDVPD_WIDTH | The dwMaxWidth and dwMaxVBIWidth members are valid.

dwMaxWidth
Specifies the maximum field width supported by the hardware video port. This value is typically dictated by the number of bits in the width register.
dwMaxVBIWidth
Specifies the maximum width of VBI data supported by the hardware video port. This value can be larger than the normal field width if the hardware video port supports oversampled VBI data.
dwMaxHeight
Specifies the maximum field height supported by the hardware video port. This value is typically dictated by the number of bits in the height register.
dwVideoPortID
Specifies the hardware video port ID for this entry. This member should be the index number of this DDVIDEOPORTCAPS structure within the array to which the lpDDVideoPortCaps member of the DD_DIRECTDRAW_GLOBAL structure points. This value ranges from 0 to (dwMaxVideoPorts - 1). (dwMaxVideoPorts is a member of the DDCORECAPS structure.) If the device supports only one hardware video port, this member should be zero.
dwCaps
Is a set of flags that specify the capabilities supported by this hardware video port. This member can be a bitwise-OR of any of the following values:
Flag | Meaning
DDVPCAPS_AUTOFLIP | A flip can be performed automatically to avoid tearing.
DDVPCAPS_COLORCONTROL | The hardware video port can perform color operations on the incoming data before it is written to the frame buffer.
DDVPCAPS_INTERLACED | The hardware video port supports interlaced video.
DDVPCAPS_NONINTERLACED | The hardware video port supports noninterlaced video.
DDVPCAPS_OVERSAMPLEDVBI | The hardware video port can accept VBI data in a different width or format than the regular video data.
DDVPCAPS_READBACKFIELD | The device can return a value signifying whether the current field of an interlaced signal is even or odd.
DDVPCAPS_READBACKLINE | The device can return the number of the current line of video being written into the frame buffer.
DDVPCAPS_SHAREABLE | Is ignored by DirectDraw.
DDVPCAPS_SKIPEVENFIELDS | The hardware video port can automatically discard even fields of video.
DDVPCAPS_SKIPODDFIELDS | The hardware video port can automatically discard odd fields of video.
DDVPCAPS_SYNCMASTER | The device is capable of driving the graphics V-sync with the hardware video port driver V-sync.
DDVPCAPS_SYSTEMMEMORY | The hardware video port can write data directly to system memory.
DDVPCAPS_VBISURFACE | The data within the vertical blanking interval can be written to a different surface.

dwFX
Is a set of flags that specify the effects supported by this hardware video port. This member is a bitwise-OR of any of the following values:
Flag | Meaning
DDVPFX_CROPTOPDATA | The hardware video port supports limited cropping to crop out the vertical interval data.
DDVPFX_CROPX | The hardware video port can crop incoming data in the x direction before writing it to the surface.
DDVPFX_CROPY | The hardware video port can crop incoming data in the y direction before writing it to the surface.
DDVPFX_IGNOREVBIXCROP | The hardware video port can ignore the left and right cropping coordinates for video data when cropping oversampled VBI data.
DDVPFX_INTERLEAVE | The hardware video port supports interleaving interlaced fields in memory.
DDVPFX_MIRRORLEFTRIGHT | The hardware video port supports mirroring left to right as the video data is written into the frame buffer.
DDVPFX_MIRRORUPDOWN | The hardware video port supports mirroring top to bottom as the video data is written into the frame buffer.
DDVPFX_PRESHRINKX | Data can be arbitrarily shrunk in the x direction before it is written to the surface.
DDVPFX_PRESHRINKXB | Data can be shrunk by negative powers of 2 (1/2, 1/4, 1/8, and so on) in the x direction before it is written to the surface.
DDVPFX_PRESHRINKXS | Data can be shrunk in increments of 1/dwPreshrinkXStep in the x direction before it is written to the surface.
DDVPFX_PRESHRINKY | Data can be arbitrarily shrunk in the y direction before it is written to the surface.
DDVPFX_PRESHRINKYB | Data can be shrunk by negative powers of 2 (1/2, 1/4, 1/8, and so on) in the y direction before it is written to the surface.
DDVPFX_PRESHRINKYS | Data can be shrunk in increments of 1/dwPreshrinkYStep in the y direction before it is written to the surface.
DDVPFX_PRESTRETCHX | Data can be arbitrarily stretched in the x direction before it is written to the surface.
DDVPFX_PRESTRETCHXN | Data can be stretched by integer factors in the x direction before it is written to the surface.
DDVPFX_PRESTRETCHY | Data can be arbitrarily stretched in the y direction before it is written to the surface.
DDVPFX_PRESTRETCHYN | Data can be stretched by integer factors in the y direction before it is written to the surface.
DDVPFX_VBICONVERT | Data within the vertical blanking interval can be converted independent of the remaining video data.
DDVPFX_VBINOSCALE | Scaling can be disabled for data within the vertical blanking interval.

dwNumAutoFlipSurfaces
Specifies the maximum number of surfaces supported in the autoflip chain, if the hardware video port supports autoflipping. If the hardware video port does not support autoflipping, the driver should set this member to zero.
dwAlignVideoPortBoundary
Specifies the byte alignment restriction of where the hardware video port can be oriented relative to the origin of the surface in the x direction.
dwAlignVideoPortPrescaleWidth
Specifies the byte alignment restriction of how wide the hardware video port data can be when prescaling is performed.
dwAlignVideoPortCropBoundary
Specifies the byte alignment restriction for the left cropping coordinate.
dwAlignVideoPortCropWidth
Specifies the byte alignment restriction for the width of the cropping rectangle.
dwPreshrinkXStep
Indicates that the hardware video port can shrink the video data width in steps of 1/dwPreshrinkXStep. This member is valid only when the DDVPFX_PRESHRINKXS capability is specified.
dwPreshrinkYStep
Indicates that the hardware video port can shrink the video data height in steps of 1/dwPreshrinkYStep. This member is valid only when the DDVPFX_PRESHRINKYS capability is specified.
dwNumVBIAutoFlipSurfaces
Specifies the maximum number of surfaces supported in the autoflip chain, if the hardware video port supports autoflipping. If the hardware video port does not support autoflipping, the driver should set this member to zero. This member works the same way as dwNumAutoFlipSurfaces except that it pertains only to devices that can send the VBI data to a different surface than that to which the normal video is being written.
dwNumPreferredAutoflip
Specifies the optimal number of autoflippable surfaces supported by the hardware.
wNumFilterTapsX
Indicates the number of taps the prescaler uses in the x direction. A value of 0 indicates no prescale, a value of 1 indicates replication, and so on.
wNumFilterTapsY
Indicates the number of taps the prescaler uses in the y direction. A value of 0 indicates no prescale, a value of 1 indicates replication, and so on.

Comments

The driver reports the capabilities described by the DDVIDEOPORTCAPS structure when its DdGetDriverInfo function is called with the GUID_VideoPortCaps GUID.


DDVIDEOPORTCONNECT

DDVIDEOPORTCONNECT describes a hardware video port connection.

typedef struct _DDVIDEOPORTCONNECT {
  DWORD  dwSize;
  DWORD  dwPortWidth;
  GUID  guidTypeID;
  DWORD  dwFlags;
  ULONG_PTR  dwReserved1;
} DDVIDEOPORTCONNECT;

Members

dwSize
Specifies the size in bytes of the DDVIDEOPORTCONNECT structure.
dwPortWidth
Specifies the width of the hardware video port. This value represents the number of physical pins on the hardware video port. This member must always be filled in, even when the guidTypeID assumes a certain size.
guidTypeID
Specifies a GUID that describes the synchronization characteristics of the hardware video port. The following port types are predefined:
Port Type | Description
DDVPTYPE_E_HREFH_VREFH | External syncs where HREF is active high and VREF is active high.
DDVPTYPE_E_HREFH_VREFL | External syncs where HREF is active high and VREF is active low.
DDVPTYPE_E_HREFL_VREFH | External syncs where HREF is active low and VREF is active high.
DDVPTYPE_E_HREFL_VREFL | External syncs where HREF is active low and VREF is active low.
DDVPTYPE_BROOKTREE | Sync information is embedded in the data stream using the Brooktree definition.
DDVPTYPE_CCIR656 | Sync information is embedded in the data stream according to the CCIR656 specification.
DDVPTYPE_PHILIPS | Sync information is embedded in the data stream using the Philips definition.

dwFlags
Is a set of flags that identify the capabilities of the hardware video port connection. This member can be a bitwise OR of any of the following flags:
Flag | Meaning
DDVPCONNECT_DISCARDSVREFDATA | The device discards any data written during the VREF period, causing this data to not be written to the frame buffer. This flag should be set only by the driver.
DDVPCONNECT_DOUBLECLOCK | When set by the driver, this flag indicates that the hardware video port is capable of double clocking the data. When set by the client, it indicates that the hardware video port should double clock the data. This flag is valid only in a hardware video port with a guidTypeID that supports an external sync.
DDVPCONNECT_HALFLINE | When set by the driver, this flag indicates that the hardware video port supports writing half lines into the frame buffer, sometimes causing the data to not be displayed correctly. When set by the client, it indicates that the driver may write half lines.
DDVPCONNECT_INTERLACED | When set by the driver, this flag indicates that the hardware video port supports interlaced signals. When set by the client, it indicates that the signal is interlaced.
DDVPCONNECT_INVERTPOLARITY | When set by the driver, this flag indicates that the hardware video port is capable of inverting the field polarities; that is, treating even fields as odd and vice versa. When set by the client, it indicates that the hardware video port should invert the field polarities.
DDVPCONNECT_SHAREEVEN | This is currently an unimplemented feature and should be ignored by the driver.
DDVPCONNECT_SHAREODD | This is currently an unimplemented feature and should be ignored by the driver.
DDVPCONNECT_VACT | When set by the driver, this flag indicates that the hardware video port is capable of using an external VACT signal. When set by the client, it indicates that the hardware video port should use the external VACT signal.

dwReserved1
Is reserved for system use and should be set to zero.

Comments

The driver's DdVideoPortGetConnectInfo callback routine initializes a DDVIDEOPORTCONNECT structure for every connection that the hardware video port supports. The client can change the dwFlags member of one of the driver's DDVIDEOPORTCONNECT structures before calling the driver's DdVideoPortCanCreate callback.


DDVIDEOPORTDATA

DDVIDEOPORTDATA is used by DirectDraw to represent a VPE object to the kernel-mode miniport.

typedef struct DDVIDEOPORTDATA {
  DWORD  dwVideoPortId;
  DWORD  dwVPFlags;
  DWORD  dwOriginOffset;
  DWORD  dwHeight;
  DWORD  dwVBIHeight;
  ULONG  dwDriverReserved1;
  ULONG  dwDriverReserved2;
  ULONG  dwDriverReserved3;
} DDVIDEOPORTDATA, *LPDDVIDEOPORTDATA;

Members

dwVideoPortId
Specifies the ID of this hardware video port, an integer in the range (0 - (maximum number of hardware video ports - 1)).
dwVPFlags
Is a set of flags that specify the current user mode DDVP_Xxx flags set by DdVideoPortUpdate.
Flag | Meaning
DDVP_AUTOFLIP | Perform automatic flipping. Autoflipping is performed between the overlay surface that was attached to the hardware video port using the application's AttachSurface method, and the overlay surfaces that are attached to the surface using the application's AttachSurface method. The flip order is the order in which the overlay surfaces were attached.
DDVP_CONVERT | Perform the conversion using the target surface format.
DDVP_CROP | Perform cropping using the specified rectangle.
DDVP_HARDWAREDEINTERLACE | The hardware video port should use the deinterlacing hardware.
DDVP_IGNOREVBIXCROP | The video data should ignore the left and right cropping coordinates when cropping the VBI data.
DDVP_INTERLEAVE | Interlaced fields should be interleaved in memory.
DDVP_MIRRORLEFTRIGHT | The data should be mirrored left to right as it is written into the frame buffer.
DDVP_MIRRORUPDOWN | The data should be mirrored top to bottom as it is written into the frame buffer.
DDVP_OVERRIDEBOBWEAVE | These bob and weave decisions should not be overridden by other interfaces. If this flag is set, DirectDraw will not allow a kernel-mode driver to use the kernel-mode video transport functionality to switch the hardware between bob and weave modes.
DDVP_PRESCALE | Perform pre-scaling/zooming based on the prescale parameters.
DDVP_SKIPEVENFIELDS | Ignore input of even fields.
DDVP_SKIPODDFIELDS | Ignore input of odd fields.
DDVP_SYNCMASTER | Drive the graphics V-syncs using the hardware video port V-syncs.
DDVP_VBICONVERT | The lpddpfVBIOutputFormat member contains data that should be used to convert the data within the vertical blanking interval.
DDVP_VBINOINTERLEAVE | Interleaving can be disabled for data within the vertical blanking interval.
DDVP_VBINOSCALE | Data within the vertical blanking interval should not be scaled.

dwOriginOffset
Specifies the byte offset of the VPE object relative to the start of the surface. This value is used only by the miniport driver.
dwHeight
Specifies the height of the VPE object data. This value is used only by the miniport driver.
dwVBIHeight
Specifies the height of the VBI data. This value is used only by the miniport driver.
dwDriverReserved1, dwDriverReserved2, dwDriverReserved3
Are reserved for use by the miniport driver.


DDVIDEOPORTDESC

DDVIDEOPORTDESC describes the VPE object being created.

typedef struct _DDVIDEOPORTDESC {
  DWORD  dwSize;
  DWORD  dwFieldWidth;
  DWORD  dwVBIWidth;
  DWORD  dwFieldHeight;
  DWORD  dwMicrosecondsPerField;
  DWORD  dwMaxPixelsPerSecond;
  DWORD  dwVideoPortID;
  DWORD  dwReserved1;
  DDVIDEOPORTCONNECT  VideoPortType;
  ULONG_PTR  dwReserved2;
  ULONG_PTR  dwReserved3;
} DDVIDEOPORTDESC;

Members

dwSize
Specifies the size in bytes of the DDVIDEOPORTDESC structure.
dwFieldWidth
Specifies the width in pixels of the incoming video stream.
dwVBIWidth
Specifies the width in pixels of the VBI data in the incoming video stream.
dwFieldHeight
Specifies the field height in scan lines of the incoming video stream.
dwMicrosecondsPerField
Specifies the time interval in microseconds between live video VSYNCs. This number should be rounded up to the nearest whole microsecond.
dwMaxPixelsPerSecond
Specifies the maximum pixel rate per second.
dwVideoPortID
Specifies the ID of the hardware video port to be used. This ID should range from 0 to (dwMaxVideoPorts -1), where dwMaxVideoPorts is a member of the DDCORECAPS structure.
dwReserved1
Is reserved for system use and should be ignored by the driver.
VideoPortType
Specifies a DDVIDEOPORTCONNECT structure describing the connection characteristics of the hardware video port.
dwReserved2, dwReserved3
Are reserved for future use and should be ignored by the driver.


DDVIDEOPORTINFO

DDVIDEOPORTINFO describes how the driver should transfer video data to a surface (or to surfaces) and it is a member of the DD_VIDEOPORT_LOCAL structure.

typedef struct _DDVIDEOPORTINFO {
  DWORD  dwSize;
  DWORD  dwOriginX;
  DWORD  dwOriginY;
  DWORD  dwVPFlags;
  RECT  rCrop;
  DWORD  dwPrescaleWidth;
  DWORD  dwPrescaleHeight;
  LPDDPIXELFORMAT  lpddpfInputFormat;
  LPDDPIXELFORMAT  lpddpfVBIInputFormat;
  LPDDPIXELFORMAT  lpddpfVBIOutputFormat;
  DWORD  dwVBIHeight;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  dwReserved2;
} DDVIDEOPORTINFO;

Members

dwSize
Specifies the size in bytes of the structure. This member must be initialized before the structure is used.
dwOriginX
Indicates the x placement of the video data within the surface, in pixels. This offset applies to all surfaces when autoflipping is requested.
dwOriginY
Indicates the y placement of the video data within the surface, in pixels. This offset applies to all surfaces when autoflipping is requested.
dwVPFlags
Is a set of flags that specify how the driver should transfer the video data. This member can be a bitwise OR of the following values:
Flag | Meaning
DDVP_AUTOFLIP | Perform automatic flipping. Auto-flipping is performed between the overlay surface that was attached to the hardware video port and the overlay surfaces that are attached to the surface. The flip order is the order in which the overlay surfaces were attached.
DDVP_CONVERT | The video data and target surface have different formats. The driver should convert the video data to the format of the target surface format.
DDVP_CROP | The driver should crop both the video and VBI data using the rectangle in the rCrop member.
DDVP_IGNOREVBIXCROP | The driver should ignore the left and right cropping coordinates when cropping the VBI data.
DDVP_INTERLEAVE | Interlaced fields of both video and VBI data should be interleaved in memory.
DDVP_MIRRORLEFTRIGHT | Video data should be mirrored left to right as it is written into the frame buffer.
DDVP_MIRRORUPDOWN | Video data should be mirrored top to bottom as it is written into the frame buffer.
DDVP_NOINTERLEAVE | If the DDVP_INTERLEAVE flag is set, the driver should interleave the video data only; that is, the driver should not interleave the VBI data.
DDVP_OVERRIDEBOBWEAVE | The bob and weave decisions should not be overridden by other interfaces. If this flag is set, DirectDraw will not allow a kernel-mode driver to use the kernel-mode video transport functionality to switch the hardware between bob and weave modes.
DDVP_PRESCALE | Perform prescaling/zooming based on the dwPrescaleWidth and dwPrescaleHeight members. The driver should prescale only the video data if DDVP_VBINOSCALE is set; otherwise, it should prescale both the video and VBI data.
DDVP_SKIPEVENFIELDS | Ignore input of even fields for both video and VBI data.
DDVP_SKIPODDFIELDS | Ignore input of odd fields for both video and VBI data.
DDVP_SYNCMASTER | Drive the graphics VSYNCs using the hardware video port VSYNCs.
DDVP_VBICONVERT | The DDPIXELFORMAT structure to which the lpddpfVBIOutputFormat member points contains data that should be used to convert the data within the vertical blanking interval.
DDVP_VBINOSCALE | Data within the vertical blanking interval should not be scaled.

rCrop
Specifies a RECT structure that specifies a cropping rectangle in pixels. This member contains a valid rectangle when the DDVP_CROP flag is set in the dwVPFlags member.
dwPrescaleWidth
Specifies the width in pixels to which the video and VBI data should be prescaled or zoomed. For example, if the video data is 720 pixels wide and the client requests the width cut in half, the client will specify 360 in dwPrescaleWidth. This member contains a valid width when the DDVP_PRESCALE flag is set in the dwVPFlags member.
dwPrescaleHeight
Specifies the height in pixels to which the video and VBI data should be prescaled or zoomed. For example, if the video data is 240 pixels wide and the client requests the width cut in half, the client will specify 120 in dwPrescaleHeight. This member contains a valid width when the DDVP_PRESCALE flag is set in the dwVPFlags member.
lpddpfInputFormat
Points to a DDPIXELFORMAT structure that specifies the format of the video data to be written to the VPE object. This format can be different from the target surface format if the VPE object performs a conversion.
lpddpfVBIInputFormat
Points to a DDPIXELFORMAT structure that specifies the input format of the data within the vertical blanking interval.
lpddpfVBIOutputFormat
Points to a DDPIXELFORMAT structure that specifies the output format of the data within the vertical blanking interval.
dwVBIHeight
Specifies the number of lines of data within the vertical blanking interval.
dwReserved1, dwReserved2
Are reserved for system use and should be ignored by the driver.

Comments

All members of this structure are set by the client and the driver should never change them. The client is typically the overlay mixer.


DXAPI_INTERFACE

DXAPI_INTERFACE contains the interfaces for the DxApi miniport driver functions.

typedef struct _DXAPI_INTERFACE {
  USHORT  Size;
  USHORT  Version;
  PVOID  Context;
  PVOID  InterfaceReference;
  PVOID  InterfaceDereference;
  PDX_GETIRQINFO  DxGetIrqInfo;
  PDX_ENABLEIRQ  DxEnableIrq;
  PDX_SKIPNEXTFIELD  DxSkipNextField;
  PDX_BOBNEXTFIELD  DxBobNextField;
  PDX_SETSTATE  DxSetState;
  PDX_LOCK  DxLock;
  PDX_FLIPOVERLAY  DxFlipOverlay;
  PDX_FLIPVIDEOPORT  DxFlipVideoPort;
  PDX_GETPOLARITY  DxGetPolarity;
  PDX_GETCURRENTAUTOFLIP  DxGetCurrentAutoflip;
  PDX_GETPREVIOUSAUTOFLIP  DxGetPreviousAutoflip;
  PDX_TRANSFER  DxTransfer;
  PDX_GETTRANSFERSTATUS  DxGetTransferStatus;
} DXAPI_INTERFACE, *PDXAPI_INTERFACE;

Members

Size
Specifies the size in bytes of this DXAPI_INTERFACE structure.
Version
Specifies the version of the DxApi miniport functions. This value will be passed back to the driver on subsequent DxApi miniport function calls.
Context
Points to the device extension of the device.
InterfaceReference
Is not used by the driver.
InterfaceDereference
Is not used by the driver.
DxGetIrqInfo
Points to the driver-supplied DxGetIrqInfo miniport driver callback routine.
DxEnableIrq
Points to the driver-supplied DxEnableIrq miniport driver callback routine.
DxSkipNextField
Points to the driver-supplied DxSkipNextField miniport driver callback routine.
DxBobNextField
Points to the driver-supplied DxBobNextField miniport driver callback routine.
DxSetState
Points to the driver-supplied DxSetState miniport driver callback routine.
DxLock
Points to the driver-supplied DxLock miniport driver callback routine.
DxFlipOverlay
Points to the driver-supplied DxFlipOverlay miniport driver callback routine.
DxFlipVideoPort
Points to the driver-supplied DxFlipVideoPort miniport driver callback routine.
DxGetPolarity
Points to the driver-supplied DxGetPolarity miniport driver callback routine.
DxGetCurrentAutoflip
Points to the driver-supplied DxGetCurrentAutoflip miniport driver callback routine.
DxGetPreviousAutoflip
Points to the driver-supplied DxGetPreviousAutoflip miniport driver callback routine.
DxTransfer
Points to the driver-supplied DxTransfer miniport driver callback routine.
DxGetTransferStatus
Points to the driver-supplied DxGetTransferStatus miniport driver callback routine.


HEAPALIGNMENT

HEAPALIGNMENT contains data specifying the alignment requirements for a given display memory heap.

typedef struct _HEAPALIGNMENT {
  DWORD  dwSize;
  DDSCAPS  ddsCaps;
  DWORD  dwReserved;
  SURFACEALIGNMENT  ExecuteBuffer;
  SURFACEALIGNMENT  Overlay;
  SURFACEALIGNMENT  Texture;
  SURFACEALIGNMENT  ZBuffer;
  SURFACEALIGNMENT  AlphaBuffer;
  SURFACEALIGNMENT  Offscreen;
  SURFACEALIGNMENT  FlipTarget;
} HEAPALIGNMENT, FAR *LPHEAPALIGNMENT;

Members

dwSize
Specifies the size in bytes of this HEAPALIGNMENT structure.
ddsCaps
Specifies a DDSCAPS structure that indicates what alignment fields are valid.
dwReserved
Is reserved for system use.
ExecuteBuffer
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_EXECUTEBUFFER.
Overlay
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_OVERLAY.
Texture
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_TEXTURE.
ZBuffer
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_ZBUFFER.
AlphaBuffer
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_ALPHA.
Offscreen
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_OFFSCREENPLAIN.
FlipTarget
Specifies a SURFACEALIGNMENT structure that contains heap alignment requirements for surfaces tagged with DDSCAPS_FLIP.

Comments

The driver should verify that the dwSize member is at least as large as sizeof(HEAPALIGNMENT). In the future, this structure may grow as additional surface types are added, but the order of the existing members will not change.


SURFACEALIGNMENT

The SURFACEALIGNMENT structure contains the extended heap alignment requirements.

typedef struct _SURFACEALIGNMENT
{
  union
  {
  struct
  {
      DWORD  dwStartAlignment;
      DWORD  dwPitchAlignment;
      DWORD  dwReserved1;
      DWORD  dwReserved2;
  } Linear;
  struct
  {
      DWORD  dwXAlignment;
      DWORD  dwYAlignment;
      DWORD  dwReserved1
      DWORD  dwReserved2
  } Rectangular;
  };
} SURFACEALIGNMENT;
typedef struct SURFACEALIGNMENT FAR *LPSURFACEALIGNMENT;

Members

dwStartAlignment
Value of the start-offset alignment for linear heaps.
dwPitchAlignment
Value of the pitch alignment for linear heaps.
dwReserved1 and dwReserved2
Reserved for future use.
dwXAlignment
Value of the X alignment for rectangular heaps.
dwYAlignment
Value of the Y alignment for rectangular heaps.
dwReserved1 and dwReserved2
Reserved for future use.

Comments

A value of zero in any of these members means "don't care", allowing the driver to express alignment restrictions for either or both members. Note that for rectangular heaps, DirectDraw rounds any X alignment up to the nearest multiple of 4 bytes: the driver cannot specify an X alignment that is more fine-grained than one DWORD.


VIDEOMEMORY

VIDEOMEMORY allows the driver to manage its display memory into heaps.

typedef struct _VIDEOMEMORY {
  DWORD  dwFlags;
  FLATPTR  fpStart;
  union{
  FLATPTR  fpEnd;
  DWORD  dwWidth;
  };
  DDSCAPS  ddsCaps;
  DDSCAPS  ddsCapsAlt;
  union{
    struct _VMEMHEAP  *lpHeap;
    DWORD  dwHeight;
  };
} VIDEOMEMORY, *LPVIDEOMEMORY;

Members

dwFlags
Is a set of flags that describe this particular section of display memory. This member can be a bitwise OR of any of the following values:
Flag | Meaning
VIDMEM_ISLINEAR | The display memory is a contiguous block of memory.
VIDMEM_ISRECTANGULAR | The display memory is rectangular.
VIDMEM_ISHEAP | This flagais reserved for system use and should be ignored by the driver.
VIDMEM_ISNONLOCAL | The heap resides in nonlocal (AGP) memory.
VIDMEM_ISWC | The driver has enabled write-combining on the display memory in this heap. Write-combining is a special caching mode in Pentium™ Pro-class processors that batches writes to the same cache line so they can be transferred in a single bus clock. Write-combining does not preserve ordering of the writes, a tradeoff that is usually acceptable for frame buffers. Refer to Intel® documentation for more information on write-combining. This flag cannot be used unless the VIDMEM_ISNONLOCAL flag is also set.
VIDMEM_HEAPDISABLED | The DirectDraw run-time uses this flag to turn off a heap when the heap's initialization has failed. This will most likely occur with an AGP heap. The driver should not set this bit.

fpStart
Points to the starting address of a memory range in the heap.
fpEnd
Points to the ending address of a memory range if the heap is linear. This address is inclusive, that is, it specifies the last valid address in the range. Thus, the number of bytes specified by fpStart and fpEnd is (fpEnd - fpStart + 1).
dwWidth
Specifies the width in bytes of the section of memory pointed to by fpStart. This member should only be used to describe rectangular memory regions.
ddsCaps
Specifies a DDSCAPS structure in which the driver returns the capabilities for which this section of memory cannot be used.
ddsCapsAlt
Specifies a DDSCAPS structure in which the driver returns the capabilities for which this chunk of memory cannot be used when no other memory is found on the first pass.
lpHeap
Is reserved for system use and should be ignored by the driver.
dwHeight
Specifies the height of the chunk of memory to which fpStart points. This member should only be used to describe rectangular memory regions.

Comments

On Windows 2000 and later the data structure is called VIDEOMEMORY and on Windows 98/Me the data structure is called VIDMEM.

GDI allocates and passes an array of VIDEOMEMORY structures to the second call of the driver's DrvGetDirectDrawInfo function. The driver should fill in the appropriate members of each structure to describe each particular section of memory. The list provides a complete description of the driver's offscreen memory.

DirectDraw scans through to allocate its surfaces in the order the display memory heaps are listed. Heaps are managed in an array of VIDEOMEMORY structures. The memory allocated first will be the memory that is accessed first. The VIDEOMEMORY structure sets up certain starting points, and determines the amount of memory on the surface and what cannot be done with the surface. DirectDraw manages it by sub-allocating and deallocating memory, that is, creating and destroying surfaces under each heap's jurisdiction. Physical limits determine how to set up these attributes.

DirectDraw's heap manager makes two passes through the VIDEOMEMORY structures. The ddsCaps member indicates to DirectDraw what the memory in the heap cannot be used for on the first pass. For example, if the heap was just big enough for a back buffer, sprites could be excluded from being allocated on the first pass by setting the DSCAPS_OFFSCREENPLAIN flag in the DDSCAPS structure. That way, other surfaces would fill up with sprites, while preserving the back buffer for page flipping. The ddsCapsAlt member could be set to allow sprites on the second pass (by removing the DSCAPS_OFFSCREENPLAIN flag). This allows heaps to be used preferentially for their highest and best use, without ruling out alternative uses. By choosing the order of allocation carefully (for example, by listing the back buffer last), the need to sort by ddsCaps and ddsCapsAlt can sometimes be eliminated.


VIDEOMEMORYINFO

VIDEOMEMORYINFO describes the general format of the display's memory.

typedef struct _VIDEOMEMORYINFO {
  FLATPTR  fpPrimary;
  DWORD  dwFlags;
  DWORD  dwDisplayWidth;
  DWORD  dwDisplayHeight;
  LONG   lDisplayPitch;
  DDPIXELFORMAT  ddpfDisplay;
  DWORD  dwOffscreenAlign;
  DWORD  dwOverlayAlign;
  DWORD  dwTextureAlign;
  DWORD  dwZBufferAlign;
  DWORD  dwAlphaAlign;
  PVOID  pvPrimary;  // Windows 2000 and later
  DWORD  dwNumHeaps; // Windows 98/Me only
  LPVIDMEM  pvmList; // Windows 98/Me only
} VIDEOMEMORYINFO, *LPVIDEOMEMORYINFO;

Members

fpPrimary
Specifies the offset, in bytes, in display memory to the primary surface.
dwFlags
Is currently unused and should be set to zero.
dwDisplayWidth
Specifies the current width of the display, in pixels.
dwDisplayHeight
Specifies the current height of the display, in pixels.
lDisplayPitch
Specifies the current pitch of the display, in bytes.
ddpfDisplay
Specifies a DDPIXELFORMAT structure in which the pixel format of the display is described.
dwOffscreenAlign
Specifies the byte alignment required when allocating this memory for offscreen surfaces.
dwOverlayAlign
Specifies the byte alignment required when allocating this memory for overlay planes.
dwTextureAlign
Specifies the byte alignment required when allocating this memory for textures.
dwZBufferAlign
Specifies the byte alignment required when allocating this memory for the depth buffer.
dwAlphaAlign
Specifies the byte alignment required when allocating this memory for an alpha buffer.
pvPrimary (Windows 2000 and later only)
Specifies a kernel-mode pointer to the beginning of the primary surface.
dwNumHeaps (Windows 98/Me only)
Specifies the number of memory heaps in pvmList.
pvmList (Windows 98/Me only)
Points to the first heap in an array of heaps.

Comments

The VIDEOMEMORYINFO structure has minor differences between Windows 98/Me and Windows 2000 and later. On Windows 2000 and later the data structure is called VIDEOMEMORYINFO and on Windows 98/Me the data structure is called VIDMEMINFO. On Windows 2000 and later, VIDEOMEMORYINFO includes a field pvPrimary that stores a kernel-mode pointer to the primary surface. On Windows 98/Me, VIDMEMINFO includes the fields dwNumHeaps and pvmList that specify an array of memory heaps.

GDI allocates memory for and passes a VIDEOMEMORYINFO structure to the driver's DrvGetDirectDrawInfo function as a member of the DD_HALINFO parameter. The driver should fill in the appropriate members to describe the general characteristics of the device's memory.


VMEMHEAP

VMEMHEAP contains information about the heap.

typedef struct _VMEMHEAP {
  DWORD  dwFlags;
  DWORD  stride;
  LPVOID  freeList;
  LPVOID  allocList;
  DWORD  dwTotalSize;
  FLATPTR  fpGARTLin;
  FLATPTR  fpGARTDev;
  DWORD  dwCommitedSize;
  DWORD  dwCoalesceCount;
  HEAPALIGNMENT  Alignment;
  DDSCAPSEX  ddsCapsEx;
  DDSCAPSEX  ddsCapsExAlt;
  LARGE_INTEGER  liPhysAGPBase;
  HANDLE  hdevAGP;
  LPVOID  pvPhysRsrv;
} VMEMHEAP, FAR *LPVMEMHEAP;

Members

dwFlags
Is reserved for system use and should be ignored by the driver.
stride
Is reserved for system use and should be ignored by the driver.
freeList
Is reserved for system use and should be ignored by the driver.
allocList
Is reserved for system use and should be ignored by the driver.
dwTotalSize
Is reserved for system use and should be ignored by the driver.
fpGARTLin
Points to the linear graphic address remapping table (GART) address of the start of the heap for nonlocal display memory.
fpGARTDev
Points to the physical GART address of the start of the heap for nonlocal display memory.
dwCommitedSize
Is reserved for system use and should be ignored by the driver.
dwCoalesceCount
Is reserved for system use and should be ignored by the driver.
Alignment
Is reserved for system use and should be ignored by the driver.
ddsCapsEx
Is reserved for system use and should be ignored by the driver.
ddsCapsExAlt
Is reserved for system use and should be ignored by the driver.
liPhysAGPBase
Is reserved for system use and should be ignored by the driver.
hdevAGP
Is reserved for system use and should be ignored by the driver.
pvPhysRsrv
Is reserved for system use and should be ignored by the driver.


Windows 98/Me Structures

This section lists structures that are used by Windows® 98/Me drivers. These structures are defined in ddrawi.h.


DBLNODE

DBLNODE holds a node in a doubly-linked list of surface interfaces.

typedef struct _DBLNODE {
  struct  _DBLNODE  FAR  *next;
  struct  _DBLNODE  FAR  *prev;
  LPDDRAWI_DDRAWSURFACE_LCL  object;
  LPDDRAWI_DDRAWSURFACE_INT  object_int;
} DBLNODE, FAR *LPDBLNODE;

Members

next
Points to the next node.
prev
Points to the previous node.
object
Points to a DDRAWI_DDRAWSURFACE_LCL structure that is the link to the object.
object_int
Points to a DDRAWI_DDRAWSURFACE_INT structure containing the object interface.


DDHAL_Xxx Structures

This table contains all the DirectDraw driver structures whose names have the form DDHAL_Xxx, which is the form used on Windows 98/Me. These structures are identical to those whose names have the form DD_Xxx, which is the form used on Windows 2000 and later. The include file dx95type.h contains type defines from DD_Xxx to DDHAL_Xxx.

DDHAL_Xxx Structure | DD_Xxx Structure
DDHAL_BLTDATA | DD_BLTDATA
DDHAL_DDKERNELCALLBACKS | DD_KERNELCALLBACKS
DDHAL_GETBLTSTATUSDATA | DD_GETBLTSTATUSDATA
DDHAL_GETDRIVERINFODATA | DD_GETDRIVERINFODATA
DDHAL_GETSCANLINEDATA | DD_GETSCANLINEDATA
DDHAL_LOCKDATA | DD_LOCKDATA
DDHAL_SYNCSURFACEDATA | DD_SYNCSURFACEDATA
DDHAL_SYNCVIDEOPORTDATA | DD_SYNCVIDEOPORTDATA
DDHAL_WAITFORVERTICALBLANKDATA | DD_WAITFORVERTICALBLANKDATA


DDHALDDRAWFNS

DDHALDDRAWFNS contains pointers to ddraw16.dll entry points.

typedef struct {
  DWORD  dwSize;
  LPDDHAL_SETINFO  lpSetInfo;
  LPDDHAL_VIDMEMALLOC  lpVidMemAlloc;
  LPDDHAL_VIDMEMFREE  lpVidMemFree;
} DDHALDDRAWFNS, FAR *LPDDHALDDRAWFNS;

Members

dwSize
Specifies the size of this structure.
lpSetInfo
Points to the DDHAL_SetInfo function.
lpVidMemAlloc
Points to the DDHAL_VidMemAlloc function.
lpVidMemFree
Points to the DDHAL_VidMemFree function.

DDHAL_SetInfo

DDHAL_SetInfo provides GDI with current information about the driver.

extern BOOL DDAPI DDHAL_SetInfo(
  LPDDHALINFO  lpDDHALInfo,
  BOOL  reset
  );

Parameters

lpDDHALInfo
Points to the DDHALINFO structure.
reset
Specifies whether there has been a mode change. If set TRUE, there has been a mode change.

DDHAL_VidMemAlloc

DDHAL_VidMemAlloc allocates a block of video memory.

extern
  FLATPTR DDAPI DDHAL_VidMemAlloc(
    LPDDRAWI_DIRECTDRAW_GBL  lpDD,
    int  heap,
    DWORD  dwWidth,
    DWORD  dwHeight
    );

Parameters

lpDD
Points to a DDRAWI_DIRECTDRAW_GBL structure.
heap
Specifies the index of the DirectDraw heap from which to allocate the surface.
dwWidth
Specifies the width in bytes of the requested surface.
dwHeight
Specifies the height in scanlines of the requested surface.

DDHAL_VidMemFree

DDHAL_VidMemFree frees a block of video memory previously allocated by DDHAL_VidMemAlloc.

extern void
  DDAPI DDHAL_VidMemFree(
    LPDDRAWI_DIRECTDRAW_GBL  lpDD,
    int heap,
    FLATPTR  fpMem
    );

Parameters

lpDD
Points to a DDRAWI_DIRECTDRAW_GBL structure.
heap
Specifies the index of the DirectDraw heap from which the surface was allocated.
fpMem
Is the FLATPTR offset of the allocated surface.


DDHALINFO

DDHALINFO collects all the information needed to create an instance of a DirectDraw driver.

typedef struct _DDHALINFO {
  DWORD   dwSize;
  LPDDHAL_DDCALLBACKS  lpDDCallbacks;
  LPDDHAL_DDSURFACECALLBACKS  lpDDSurfaceCallbacks;
  LPDDHAL_DDPALETTECALLBACKS  lpDDPaletteCallbacks;
  VIDMEMINFO  vmiData;
  DDCORECAPS  ddCaps;
  DWORD  dwMonitorFrequency;
  LPDDHAL_GETDRIVERINFO  GetDriverInfo;
  DWORD  dwModeIndex;
  LPDWORD  lpdwFourCC;
  DWORD  dwNumModes;
  LPDDHALMODEINFO  lpModeInfo;
  DWORD  dwFlags;
  LPVOID  lpPDevice;
  DWORD  hInstance;
  DWORD  lpD3DGlobalDriverData;
  DWORD  lpD3DHALCallbacks;
  LPDDHAL_DDEXEBUFCALLBACKS  lpDDExeBufCallbacks;
} DDHALINFO, FAR *LPDDHALINFO;

Members

dwSize
Specifies the size of the structure. This member must be initialized before the structure is used.
lpDDCallbacks
Specifies the address of the DDHAL_DDCALLBACKS structure containing the DirectDraw object callbacks.
lpDDSurfaceCallbacks
Specifies the address of the DDHAL_DDSURFACECALLBACKS structure containing the DirectDrawSurface object callbacks.
lpDDPaletteCallbacks
Specifies the address of the DDHAL_DDPALETTECALLBACKS structure containing the DirectDrawPalette object callbacks.
vmiData
Specifies the address of a VIDEOMEMORYINFO structure that contains the display memory information.
ddCaps
Specifies the DDCORECAPS structure (defined in the DirectDraw SDK documentation) that specifies the capabilities the hardware can set.
dwMonitorFrequency
Indicates the monitor frequency in the current mode. (You can also poll for the monitor frequency using getDisplayDuration.)
GetDriverInfo
Is a callback to get an arbitrary vtable from the driver.
dwModeIndex
Specifies an ndex into a mode array that indicates the current mode.
lpdwFourCC
Indicates the FourCC codes supported in this mode only, and are listed in the order of preference of use (speed and quality).
dwNumModes
Indicates the number of modes supported.
lpModeInfo
Specifies the address of a DDHALMODEINFO structure that contains the mode information.
dwFlags
Is a set of display driver creation flags.
Flag | Meaning
DDHALINFO_GETDRIVERINFOSET | The GetDriverInfo member is set.
DDHALINFO_ISPRIMARYDISPLAY | The driver is the primary display driver.
DDHALINFO_MODEXILLEGAL | This hardware does not support ModeX modes.

lpPDevice
Indicates that the physical device pointer is the physical device in the display miniport driver.
hInstance
Is an instance handle to the 16-bit driver.
lpD3DGlobalDriverData
Points to the Direct3D global data.
lpD3DHALCallbacks
Points to the Direct3D callbacks.
lpDDExeBufCallbacks
Points to the execute buffer pseudo-object callbacks.

Comments

Windows 2000 and later use a similarly named structure, DD_HALINFO, to accomplish the same purpose.

DDHALINFO is filled out in the buildDDHALInfo16 and buildDDHALInfo32 functions of the DirectDraw HAL and contains all the unchanging function names and capabilities of the hardware and driver. The only entries of concern to the Direct3D HAL are the lpD3DGlobalDriverData, lpD3DHAL_Callbacks, and GetDriverInfo members. The other structure members relate only to the DirectDraw portion of the driver.

See Also

DD_HALINFO


DDRAWI_DDRAWCLIPPER_GBL

DDRAWI_DDRAWCLIPPER_GBL contains the global DirectDrawClipper data that can be shared between object instances.

typedef struct _DDRAWI_DDRAWCLIPPER_GBL {
  DWORD  dwRefCnt;
  DWORD  dwFlags;
  LPDDRAWI_DIRECTDRAW_GBL lpDD;
  DWORD  dwProcessId;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  hWnd;
  LPRGNDATA  lpStaticClipList;
} DDRAWI_DDRAWCLIPPER_GBL;

Members

dwRefCnt
Is used by DirectDraw and should not be filled in by the driver.
dwFlags
Is a set of clip list control flags.
Flag | Meaning
DDRAWICLIP_ISINITIALIZED | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWICLIP_INMASTERSPRITELIST | The clipper is referenced in the master sprite list.
DDRAWICLIP_WATCHWINDOW | This flag is used by DirectDraw and should not be filled in by the driver.

lpDD
Is used by DirectDraw and should not be filled in by the driver.
dwProcessId
Is used by DirectDraw and should not be filled in by the driver.
dwReserved1
Is reserved for use by the display driver.
hWnd
Is the handle to the window being tracked by the clipper.
lpStaticClipList
Points to a RGNDATA structure (defined in dciddi.h) that contains the clip list set by the application.


DDRAWI_DDRAWCLIPPER_INT

DDRAWI_DDRAWCLIPPER_INT contains the DirectDrawClipper object's interface information.

typedef struct _DDRAWI_DDRAWCLIPPER_INT {
  LPVOID  lpVtbl;
  LPDDRAWI_DDRAWCLIPPER_LCL  lpLcl;
  LPDDRAWI_DDRAWCLIPPER_INT  lpLink;
  DWORD  dwIntRefCnt;
} DDRAWI_DDRAWCLIPPER_INT;

Members

lpVtbl
Is used by DirectDraw and should not be filled in by the driver.
lpLcl
Points to a DDRAWI_DDRAWCLIPPER_LCL structure that contains the local object.
lpLink
Is used by DirectDraw and should not be filled in by the driver.
dwIntRefCnt
Is used by DirectDraw and should not be filled in by the driver.


DDRAWI_DDRAWCLIPPER_LCL

DDRAWI_DDRAWCLIPPER_LCL contains local data for each individual DirectDrawClipper object.

typedef struct _DDRAWI_DDRAWCLIPPER_LCL {
  DWORD  lpClipMore;
  LPDDRAWI_DDRAWCLIPPER_GBL  lpGbl;
  LPDDRAWI_DIRECTDRAW_LCL  lpDD_lcl;
  DWORD  dwLocalRefCnt;
  IUnknown  FAR  *pUnkOuter;
  LPDDRAWI_DIRECTDRAW_INT  lpDD_int;
  ULONG_PTR  dwReserved1;
  IUnknown  *pAddrefedThisOwner;
} DDRAWI_DDRAWCLIPPER_LCL;

Members

lpClipMore
Points to additional local data. This member is for future use.
lpGbl
Points to a DDRAWI_DDRAWCLIPPER_GBL structure that contains the clip list data.
lpDD_lcl
Is used by DirectDraw and should not be filled in by the driver.
dwLocalRefCnt
Is used by DirectDraw and should not be filled in by the driver.
pUnkOuter
Is used by DirectDraw and should not be filled in by the driver.
lpDD_int
Is used by DirectDraw and should not be filled in by the driver.
dwReserved1
Is reserved for use by the display driver.
pAddrefedThisOwner
Is used by DirectDraw and should not be filled in by the driver.


DDRAWI_DDRAWPALETTE_GBL

DDRAWI_DDRAWPALETTE_GBL contains the global DirectDrawPalette data that can be shared between object instances.

typedef struct _DDRAWI_DDRAWPALETTE_GBL {
  DWORD  dwRefCnt;
  DWORD  dwFlags;
  LPDDRAWI_DIRECTDRAW_LCL  lpDD_lcl;
  DWORD  dwProcessId;
  LPPALETTEENTRY  lpColorTable;
  union
  {
     ULONG_PTR  dwReserved1;
     HPALETTE  hHELGDIPalette;
  };
  DWORD  dwDriverReserved;
  DWORD  dwContentsStamp;
  DWORD  dwSaveStamp;
  DWORD  dwHandle;
} DDRAWI_DDRAWPALETTE_GBL;

Members

dwRefCnt
Is used by DirectDraw and should not be filled in by the driver.
dwFlags
Is a set of palette control flags.
Flag | Meaning
DDRAWIPAL_2 | The palette has 2 entries.
DDRAWIPAL_4 | The palette has 4 entries.
DDRAWIPAL_16 | The palette has 16 entries.
DDRAWIPAL_256 | The palette has 256 entries.
DDRAWIPAL_ALLOW256 | The palette can be fully updated.
DDRAWIPAL_ALPHA | The entries in the palette contain alpha information.
DDRAWIPAL_DIRTY | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWIPAL_EXCLUSIVE | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWIPAL_GDI | The palette is allocated through GDI.
DDRAWIPAL_INHEL | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWIPAL_STORED_8 | The palette is stored as 8 bpp per entry.
DDRAWIPAL_STORED_8INDEX | The palette is stored as an 8-bit index into the destination palette.
DDRAWIPAL_STORED_16 | The palette is stored as 16 bpp per entry.
DDRAWIPAL_STORED_24 | The palette is stored as 24 bpp per entry.

lpDD_lcl
Is used by DirectDraw and should not be filled in by the driver.
dwProcessId
Is used by DirectDraw and should not be filled in by the driver.
lpColorTable
Specifies the address of an array of PALETTEENTRY structures that contain the RGB values that are the colors in the palette.
dwReserved1
Is reserved for use by the display driver.
hHELGDIPalette
Is used by DirectDraw and should not be filled in by the driver.
dwDriverReserved
Is reserved for use by the HAL, regardless of who created the object.
dwContentsStamp
Is incremented when the palette changes.
dwSaveStamp
Is set to dwContentsStamp when the palette is saved to a surface file.
dwHandle
Is a handle used in D3dDrawPrimitives2 palette notification.


DDRAWI_DDRAWPALETTE_INT

DDRAWI_DDRAWPALETTE_INT contains the DirectDrawPalette object's interface information.

typedef struct _DDRAWI_DDRAWPALETTE_INT {
  LPVOID  lpVtbl;
  LPDDRAWI_DDRAWPALETTE_LCL  lpLcl;
  LPDDRAWI_DDRAWPALETTE_INT  lpLink;
  DWORD  dwIntRefCnt;
} DDRAWI_DDRAWPALETTE_INT;

Members

lpVtbl
Is used by DirectDraw and should not be filled in by the driver.
lpLcl
Points to a DDRAWI_DDRAWPALETTE_LCL structure that contains the local object.
lpLink
Is used by DirectDraw and should not be filled in by the driver.
dwIntRefCnt
Is used by DirectDraw and should not be filled in by the driver.


DDRAWI_DDRAWPALETTE_LCL

DDRAWI_DDRAWPALETTE_LCL contains local data for each individual DirectDrawPalette object.

typedef struct _DDRAWI_DDRAWPALETTE_LCL {
  DWORD  lpPalMore;
  LPDDRAWI_DDRAWPALETTE_GBL  lpGbl;
  ULONG_PTR  dwUnused0;
  DWORD  dwLocalRefCnt;
  IUnknown FAR  *pUnkOuter;
  LPDDRAWI_DIRECTDRAW_LCL  lpDD_lcl;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  dwDDRAWReserved1;
  ULONG_PTR  dwDDRAWReserved2;
  ULONG_PTR  dwDDRAWReserved3;
} DDRAWI_DDRAWPALETTE_LCL;

Members

lpPalMore
Specifies the address of additional local data. Reserved for system use.
lpGbl
Specifies the address of a DDRAWI_DDRAWPALETTE_GBL structure that contains the palette data.
dwUnused0
Is not currently used.
dwLocalRefCnt
Is used by DirectDraw and should not be filled in by the driver.
pUnkOuter
Is used by DirectDraw and should not be filled in by the driver.
lpDD_lcl
Is the address of the owning local driver object.
dwReserved1
Is reserved for use by the display driver.
dwDDRAWReserved1
dwDDRAWReserved2
dwDDRAWReserved3


DDRAWI_DDRAWSURFACE_GBL

DDRAWI_DDRAWSURFACE_GBL contains the global DirectDrawSurface data that can be shared between object instances.

typedef struct _DDRAWI_DDRAWSURFACE_GBL {
  DWORD  dwRefCnt;
  DWORD  dwGlobalFlags;
  union
  {
     LPACCESSRECTLIST  lpRectList;
     DWORD  dwBlockSizeY;
  };
  union
  {
     LPVMEMHEAP  lpVidMemHeap;
     DWORD  dwBlockSizeX;
  };
  union
  {
     LPDDRAWI_DIRECTDRAW_GBL lpDD;
     LPVOID   lpDDHandle;
  };
  FLATPTR   fpVidMem;
  union
  {
     LONG   lPitch;
     DWORD  dwLinearSize;
  };
  WORD    wHeight;
  WORD    wWidth;
  DWORD   dwUsageCount;
  ULONG_PTR   dwReserved1;
  DDPIXELFORMAT   ddpfSurface;
} DDRAWI_DDRAWSURFACE_GBL;

Members

dwRefCnt
Is used by DirectDraw and should not be filled in by the driver.
dwGlobalFlags
Is a set of global surface flags.
Flag | Meaning
DDRAWISURFGBL_FASTLOCKHELD | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURFGBL_HARDWAREOPDEST | This surface was the destination for an asynchronous hardware operation.
DDRAWISURFGBL_HARDWAREOPSOURCE | This surface was the source for an asynchronous hardware operation.
DDRAWISURFGBL_IMPLICITHANDLE | This hKernelHandle was created implicitly.
DDRAWISURFGBL_ISCLIENTMEM | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURFGBL_ISGDISURFACE | The surface represents what to GDI is a front buffer.
DDRAWISURFGBL_LATEALLOCATELINEAR | An optimized surface was allocate as a formless chunk. The lPitch member is invalid, but the dwLinearSize member is valid.
DDRAWISURFGBL_LOCKBROKEN | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURFGBL_LOCKNOTHOLDINGWIN16LOCK | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURFGBL_LOCKVRAMSTYLE | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURFGBL_MEMFREE | Video memory has been freed.
DDRAWISURFGBL_READONLYLOCKHELD | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURFGBL_SOFTWAREAUTOFLIP | This surface is autoflipped using software.
DDRAWISURFGBL_SYSMEMEXECUTEBUFFER | The driver sets this flag to inform DirectDraw that the surface was allocated in system memory.
DDRAWISURFGBL_SYSMEMREQUESTED | The surface is in system memory at the request of the user.
DDRAWISURFGBL_VPORTDATA | This surface received data from the video port.
DDRAWISURFGBL_VPORTINTERLEAVED | This surface contains interleaved video port data.

lpRectList
Is used by DirectDraw and should not be filled in by the driver.
dwBlockSizeY
Contains the block size of the y axis of display memory that the display driver requested.
lpVidMemHeap
Points to a VMEMHEAP structure from which the heap display memory was allocated.
dwBlockSizeX
Contains the block size of the x axis of display memory that the display driver requested.
lpDD
Points to a DDRAWI_DIRECTDRAW_GBL structure that contains information about the DirectDraw object.
lpDDHandle
Points to a handle to the DirectDraw object. This member is used by the display driver when calling functions in ddraw16.dll.
fpVidMem
Is the address of display memory.
lPitch
Specifies the distance in bytes to the start of the next line on the surface.
dwLinearSize
Specifies tthe linear size of a nonrectangular surface.
wHeight
Specifies the height of the surface in scanlines.
wWidth
Specifies the width of the surface in pixels.
dwUsageCount
Is used by DirectDraw and should not be filled in by the driver.
dwReserved1
Is reserved for use by the display driver for display memory surfaces only.
ddpfSurface
Is the address of a DDPIXELFORMAT structure that contains the pixel format information for this surface. This member is allocated only if the pixel format differs from that of the primary display; that is, it is not allocated unless the DDRAWISURF_HASPIXELFORMAT flag in the DDRAWI_DDRAWSURFACE_LCL structure is set.

Comments

Driver writers should use the GET_LPDDRAWSURFACE_GBL_MORE macro to traverse from a DDRAWI_DDRAWSURFACE_GBL address to the DDRAWI_DDRAWSURFACE_GBL_MORE structure.

The DDRAWI_DDRAWSURFACE_GBL structure is similar in purpose to the Windows 2000 and later structure, DD_SURFACE_GLOBAL.


DDRAWI_DDRAWSURFACE_GBL_MORE

DDRAWI_DDRAWSURFACE_GBL_MORE contains additional global DirectDrawSurface data that can be shared between object instances.

typedef struct _DDRAWI_DDRAWSURFACE_GBL_MORE {
  DWORD    dwSize;
  union
  {
     DWORD     dwPhysicalPageTable;
     FLATPTR   fpPhysicalVidMem;
  };
  LPDWORD  pPageTable;
  DWORD    cPages;
  ULONG_PTR    dwSavedDCContext;
  FLATPTR  fpAliasedVidMem;
  ULONG_PTR    dwDriverReserved;
  ULONG_PTR    dwHELReserved;
  DWORD    cPageUnlocks;
  ULONG_PTR    hKernelSurface;
  DWORD    dwKernelRefCnt;
  LPDDCOLORCONTROL lpColorInfo;
  FLATPTR  fpNTAlias;
  DWORD    dwContentsStamp;
  LPVOID   lpvUnswappedDriverReserved;
  LPVOID   lpDDRAWReserved2;
  DWORD    dwDDRAWReserved1;
  DWORD    dwDDRAWReserved2;
  FLATPTR  fpAliasOfVidMem;
} DDRAWI_DDRAWSURFACE_GBL_MORE;

Members

dwSize
Specifies the size of the structure. This member must be initialized before the structure is used.
dwPhysicalPageTable
Specifies the physical address of the page table (an array of physical addresses with one per 4KB page). This is the physical address of the table of physical addresses of the pages that hold the page-locked system memory surface. This table will be valid whenever the dwPageLockCount member of the DDRAWI_DDRAWSURFACE_MORE structure is non-zero.
fpPhysicalVidMem
Is the physical address of the surface (non-local display memory only).
pPageTable
Is the linear address of the page table whose physical address is given in dwPhysicalPageTable.
cPages
Specifies the count of elements in the array pointed to by dwPhysicalPageTable and pPageTable. This will be equal to the number of physical pages representing the surface.
dwSavedDCContext
Is used by the DirectDraw API and should not be filled in by the driver.
fpAliasedVidMem
Is used by DirectDraw and should not be filled in by the driver.
dwDriverReserved
Is reserved for driver use (both system and display memory surfaces).
dwHELReserved
Is used by DirectDraw and should not be filled in by the driver.
cPageUnlocks
Specifies the number of times a surface is page-unlocked. This member is incremented whenever the surface is page-unlocked. Drivers can cache the physical page table of a surface, then check this value whenever a new DMA request is received. If the value has changed, then the driver's cache of the physical page table needs to be updated. If not, the surface has remained page-locked since the last time it was passed to the driver.
hKernelSurface
Is the kernel handle for this surface.
dwKernelRefCnt
Is used by DirectDraw and should not be filled in by the driver.
lpColorInfo
Is used by DirectDraw and should not be filled in by the driver.
fpNTAlias
Is used by internally by DirectDraw and should not be filled in by the driver.
dwContentsStamp
Is a value that changes when the surface data changes. A value of 0 means no information.
lpvUnswappedDriverReserved
Is reserved for use by the display driver. It is not swapped when a Flip is called on this surface.
lpDDRAWReserved2
dwDDRAWReserved1
dwDDRAWReserved2
fpAliasOfVidMem
Is used by DirectDraw and should not be filled in by the driver.

Comments

Driver writers should use the GET_LPDDRAWSURFACE_GBL_MORE macro to traverse from a DDRAWI_DDRAWSURFACE_GBL address to the DDRAWI_DDRAWSURFACE_GBL_MORE structure.


DDRAWI_DDRAWSURFACE_INT

DDRAWI_DDRAWSURFACE_INT contains the DirectDrawSurface object's interface information.

typedef struct _DDRAWI_DDRAWSURFACE_INT {
  LPVOID  lpVtbl;
  LPDDRAWI_DDRAWSURFACE_LCL  lpLcl;
  LPDDRAWI_DDRAWSURFACE_INT  lpLink;
  DWORD   dwIntRefCnt;
} DDRAWI_DDRAWSURFACE_INT;

Members

lpVtbl
Is used by DirectDraw and should not be filled in by the driver.
lpLcl
Points to a DDRAWI_DDRAWSURFACE_LCL structure that contains the local object.
lpLink
Is used by DirectDraw and should not be filled in by the driver.
dwIntRefCnt
Is used by DirectDraw and should not be filled in by the driver.


DDRAWI_DDRAWSURFACE_LCL

DDRAWI_DDRAWSURFACE_LCL contains local data for each individual DirectDrawSurface object.

struct _DDRAWI_DDRAWSURFACE_LCL {
  LPDDRAWI_DDRAWSURFACE_MORE lpSurfMore;
  LPDDRAWI_DDRAWSURFACE_GBL  lpGbl;
  ULONG_PTR   hDDSurface;
  LPATTACHLIST  lpAttachList;
  LPATTACHLIST  lpAttachListFrom;
  DWORD  dwLocalRefCnt;
  DWORD  dwProcessId;
  DWORD  dwFlags;
  DDSCAPS  ddsCaps;
  union
  {
     LPDDRAWI_DDRAWPALETTE_INT  lpDDPalette;
     LPDDRAWI_DDRAWPALETTE_INT  lp16DDPalette;
  };
  union
  {
     LPDDRAWI_DDRAWCLIPPER_LCL  lpDDClipper;
     LPDDRAWI_DDRAWCLIPPER_INT  lp16DDClipper;
  };
  DWORD  dwModeCreatedIn;
  DWORD  dwBackBufferCount;
  DDCOLORKEY  ddckCKDestBlt;
  DDCOLORKEY  ddckCKSrcBlt;
  ULONG_PTR  hDC;
  ULONG_PTR  dwReserved1;
  DDCOLORKEY  ddckCKSrcOverlay;
  DDCOLORKEY  ddckCKDestOverlay;
  LPDDRAWI_DDRAWSURFACE_INT lpSurfaceOverlaying;
  DBLNODE  dbnOverlayNode;
  RECT  rcOverlaySrc;
  RECT  rcOverlayDest;
  DWORD  dwClrXparent;
  DWORD  dwAlpha;
  LONG  lOverlayX;
  LONG  lOverlayY;
} DDRAWI_DDRAWSURFACE_LCL;

Members

lpSurfMore
Is the address of a DDRAWI_DDRAWSURFACE_MORE structure that contains additional local data.
lpGbl
Is the address of a DDRAWI_DDRAWSURFACE_GBL structure that contains the display memory information for this surface.
hDDSurface
Is the Windows 2000 and later kernel-mode handle.
lpAttachList
Is the address of an ATTACHLIST structure that contains the list of surfaces to which this surface attached.
lpAttachListFrom
Address of an ATTACHLIST structure that contains the list of surfaces that are attached to this surface.
dwLocalRefCnt
Is used by DirectDraw and should not be filled in by the driver.
dwProcessId
Is used by DirectDraw and should not be filled in by the driver.
dwFlags
Is a set of surface control flags.
Flag | Meaning
DDRAWISURF_ATTACHED | The surface is attached to another surface.
DDRAWISURF_ATTACHED_FROM | This surface has other surfaces attached to it.
DDRAWISURF_BACKBUFFER | The surface was originally a back buffer.
DDRAWISURF_DATAISALIASED | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_DCIBUSY | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_DRIVERMANAGED | The surface is a driver-managed surface.
DDRAWISURF_FRONTBUFFER | The surface was originally a front buffer.
DDRAWISURF_GETDCNULL | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_HASCKEYDESTBLT | The surface has CKDestBlt
DDRAWISURF_HASCKEYDESTOVERLAY | The surface has CKDestOverlay.
DDRAWISURF_HASCKEYSRCBLT | The surface has CKSrcBlt.
DDRAWISURF_HASCKEYSRCOVERLAY | The surface has CKSrcOverlay.
DDRAWISURF_HASDC | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_HASOVERLAYDATA | The surface has overlay data.
DDRAWISURF_HASPIXELFORMAT | The surface has pixel format data.
DDRAWISURF_HELCB | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_HW_CKEYDESTBLT | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_HW_CKEYDESTOVERLAY | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_HW_CKEYSRCBLT | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_HW_CKEYSRCOVERLAY | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_IMPLICITCREATE | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_IMPLICITROOT | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_INMASTERSPRITELIST | The surface is referenced in the master sprite list.
DDRAWISURF_INVALID | The surface has been invalidated by a mode set.
DDRAWISURF_ISFREE | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_LOCKEXCLUDEDCURSOR | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_PARTOFPRIMARYCHAIN | The surface is part of a primary chain.
DDRAWISURF_SETGAMMA | Gamma ramp for this surface is active.
DDRAWISURF_STEREOSURFACELEFT | The surface is the left of a stereo pair.
DDRAWISURF_SW_CKEYDESTBLT | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_SW_CKEYDESTOVERLAY | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_SW_CKEYSRCBLT | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWISURF_SW_CKEYSRCOVERLAY | This flag is used by DirectDraw and should not be filled in by the driver.

ddsCaps
Specifies the address of a DDSCAPS structure that contains the capabilities of the surface.
lpDDPalette
Points to a DDRAWI_DDRAWPALETTE_INT structure that contains the palette information associated with this surface.
lp16DDPalette
Is a 16-bit pointer to a DDRAWI_DDRAWPALETTE_INT structure that contains the palette information associated with this surface.
lpDDClipper
Points to a DDRAWI_DDRAWCLIPPER_LCL structure that contains the clip list information associated with this surface.
lp16DDClipper
Is a 16-bit pointer to a DDRAWI_DDRAWCLIPPER_INT structure that contains the clip list information associated with this surface.
dwModeCreatedIn
Is used by DirectDraw and should not be filled in by the driver.
dwBackBufferCount
Indicates the number of back buffers that were created for this surface.
ddckCKDestBlt
Is a DDCOLORKEY structure (defined in the DirectDraw SDK documentation) that contains the color key information for destination blt use.
ddckCKSrcBlt
Is a DDCOLORKEY structure that contains the color key information for source blt use.
hDC
Is used by DirectDraw and should not be filled in by the driver.
dwReserved1
Is reserved for use by the display driver.
ddckCKSrcOverlay
Is a DDCOLORKEY structure (defined in the DirectDraw SDK documentation) that contains the color key information for source overlay use.
ddckCKDestOverlay
Is a DDCOLORKEY structure that contains the color key information for destination overlay use.
lpSurfaceOverlaying
Points to a DDRAWI_DDRAWSURFACE_INT structure that contains the information about the surface that is being overlaid.
dbnOverlayNode
Is a DBLNODE structure that contains the pointers to the previous and next overlays.
rcOverlaySrc
Is used by DirectDraw and should not be filled in by the driver.
rcOverlayDest
Is used by DirectDraw and should not be filled in by the driver.
dwClrXparent
Is used by DirectDraw and should not be filled in by the driver.
dwAlpha
Is used by DirectDraw and should not be filled in by the driver.
lOverlayX
Specifies the current x overlay position.
lOverlayY
Specifies the current y overlay position.

Comments

Every member of this structure following the dwReserved1 member is allocated only if the surface can be used for overlays. When this part of the structure is allocated, ddckCDSrcOverlay must not be moved from the beginning of this area.

The DDRAWI_DDRAWSURFACE_LCL structure is similar in purpose to the Windows 2000 and later structure, DD_SURFACE_LOCAL.


DDRAWI_DDRAWSURFACE_MORE

DDRAWI_DDRAWSURFACE_MORE contains additional local data for each individual DirectDrawSurface object.

typedef struct _DDRAWI_DDRAWSURFACE_MORE {
  DWORD  dwSize;
  IUNKNOWN_LIST  FAR  *lpIUnknowns;
  LPDDRAWI_DIRECTDRAW_LCL  lpDD_lcl;
  DWORD  dwPageLockCount;
  DWORD  dwBytesAllocated;
  LPDDRAWI_DIRECTDRAW_INT  lpDD_int;
  DWORD  dwMipMapCount;
  LPDDRAWI_DDRAWCLIPPER_INT  lpDDIClipper;
  //------- Fields added in Version 5.0 -------
  LPHEAPALIASINFO  lpHeapAliasInfo;
  DWORD  dwOverlayFlags;
  VOID  *rgjunc;
  LPDDRAWI_DDVIDEOPORT_LCL  lpVideoPort;
  LPDDOVERLAYFX  lpddOverlayFX;
  DDSCAPSEX  ddsCapsEx;
  DWORD  dwTextureStage;
  LPVOID  lpDDRAWReserved;
  LPVOID  lpDDRAWReserved2;
  LPVOID  lpDDrawReserved3;
  DWORD  dwDDrawReserved4;
  LPVOID  lpDDrawReserved5;
  LPDWORD  lpGammaRamp;
  LPDWORD  lpOriginalGammaRamp;
  LPVOID  lpDDrawReserved6;
#ifndef WIN95
  DISPLAYMODEINFO  dmiDDrawReserved7;
#endif
  DWORD  dwSurfaceHandle;
  DWORD  qwDDrawReserved8[2];
  LPVOID  lpDDrawReserved9;
  DWORD  cSurfaces;
  LPDDSURFACEDESC2  pCreatedDDSurfaceDesc2;
  LPDDRAWI_DDRAWSURFACE_LCL *slist;
  DWORD  dwFVF;
  PVOID  lpVB;
} DDRAWI_DDRAWSURFACE_MORE;

Members

dwSize
Specifies the size of this structure. This member must be initialized before the structure is used.
lpIUnknowns
Is used by DirectDraw and should not be filled in by the driver.
lpDD_lcl
Is used by DirectDraw and should not be filled in by the driver.
dwPageLockCount
Is used by DirectDraw and should not be filled in by the driver.
dwBytesAllocated
Is used by DirectDraw and should not be filled in by the driver.
lpDD_int
Is used by DirectDraw and should not be filled in by the driver.
dwMipMapCount
Contains the number of MIP map levels in the chain.
lpDDIClipper
Is used by DirectDraw and should not be filled in by the driver.
lpHeapAliasInfo
Is used by DirectDraw and should not be filled in by the driver.
dwOverlayFlags
Contains the overlay flags most recently passed to UpdateOverlay.
Flag | Meaning
DDOVER_ADDDIRTYRECT | Add a dirty rectangle to an emulated overlaid surface.
DDOVER_ALPHADEST | Use the alpha information in the pixel format or the alpha channel surface attached to the destination surface as the alpha channel for the destination overlay.
DDOVER_ALPHADESTCONSTOVERRIDE | Use the dwConstAlphaDest field in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the destination alpha channel for this overlay.
DDOVER_ALPHADESTNEG | The NEG suffix indicates that the destination surface becomes more transparent as the alpha value increases.
DDOVER_ALPHADESTSURFACEOVERRIDE | Use the lpDDSAlphaDest field in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the alpha channel destination for this overlay.
DDOVER_ALPHAEDGEBLEND | Use the dwAlphaEdgeBlend field in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the alpha channel for the edges of the image that border the color key colors.
DDOVER_ALPHASRC | Use the alpha information in the pixel format or the alpha channel surface attached to the source surface as the source alpha channel for this overlay.
DDOVER_ALPHASRCCONSTOVERRIDE | Use the dwConstAlphaSrc field in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the source alpha channel for this overlay.
DDOVER_ALPHASRCNEG | The NEG suffix indicates that the source surface becomes more transparent as the alpha value increases.
DDOVER_ALPHASRCSURFACEOVERRIDE | Use the lpDDSAlphaSrc field in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentaion) as the alpha channel source for this overlay.
DDOVER_ARGBSCALEFACTORS | The DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) contains valid ARGB scaling factors.
DDOVER_AUTOFLIP | Autoflip the overlay whenever the video port autoflips.
DDOVER_BOB | Display each field of video port data individually without causing any jittery artifacts.
DDOVER_BOBHARDWARE | Bob will be performed using hardware rather than software or emulation.
DDOVER_DDFX | Use the overlay FX flags to define special overlay FX.
DDOVER_DEGRADEARGBSCALING | ARGB scaling factors can be degraded to conform with driver capabilities.
DDOVER_HIDE | Turn this overlay off.
DDOVER_INTERLEAVED | The surface memory is composed of interleaved fields.
DDOVER_KEYDEST | Use the color key associated with the destination surface.
DDOVER_KEYDESTOVERRIDE | Use the dckDestColorkey field in the DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) as the color key for the destination surface.
DDOVER_KEYSRC | Use the color key associated with the source surface.
DDOVER_KEYSRCOVERRIDE | Use the dckSrcColorkey field in the DDOVERLAYFX structure as the color key for the source surface.
DDOVER_OVERRIDEBOBWEAVE | Bob/weave decisions should not be overridden by other interfaces.
DDOVER_REFRESHALL | Redraw the entire surface on an emulated overlaid surface.
DDOVER_REFRESHDIRTYRECTS | Redraw all dirty rectangles on an emulated overlaid surface.
DDOVER_SHOW | Turn this overlay on.

rgjunc
Is used by DirectDraw and should not be filled in by the driver.
lpVideoPort
Points to a DDRAWI_DDVIDEOPORT_LCL structure of the video port currently writing data to this surface.
lpddOverlayFX
Points to a DDOVERLAYFX structure (defined in the DirectDraw SDK documentation) that contains the current overlay FX.
ddsCapsEx
dwTextureStage
Specifies the stage in a multitexture cascade.
lpDDRAWReserved
lpDDRAWReserved2
lpDDrawReserved3
dwDDrawReserved4
lpDDrawReserved5
lpGammaRamp
lpOriginalGammaRamp
lpDDrawReserved6
dmiDDrawReserved7
dwSurfaceHandle
Specifies a cookie for use with the CreateSurfaceEx DDI.
qwDDrawReserved8
lpDDrawReserved9
cSurfaces
Is used by DirectDraw and should not be filled in by the driver.
pCreatedDDSurfaceDesc2
Is used by DirectDraw and should not be filled in by the driver.
slist
Is used by DirectDraw and should not be filled in by the driver.
dwFVF
Specifies the saved FVF flags for execute buffers.
lpVB
Is used by DirectDraw and should not be filled in by the driver.

Comments

The DDRAWI_DDRAWSURFACE_MORE structure is similar in purpose to the Windows 2000 and later structure, DD_SURFACE_MORE.


DDRAWI_DDVIDEOPORT_INT

DDRAWI_DDVIDEOPORT_INT contains the DirectDraw video port object's interface information.

typedef struct _DDRAWI_DDVIDEOPORT_INT {
  LPVOID  lpVtbl;
  LPDDRAWI_DDVIDEOPORT_LCL  lpLcl;
  LPDDRAWI_DDVIDEOPORT_INT  lpLink;
  DWORD  dwIntRefCnt;
  DWORD  dwFlags;
} DDRAWI_DDVIDEOPORT_INT;

Members

lpVtbl
Is used by DirectDraw and should not be filled in by the driver.
lpLcl
Points to a DDRAWI_DDVIDEOPORT_LCL structure that contains the local object.
lpLink
Is used by DirectDraw and should not be filled in by the driver.
dwIntRefCnt
Is used by DirectDraw and should not be filled in by the driver.
dwFlags
Is used by DirectDraw and should not be filled in by the driver.


DDRAWI_DDVIDEOPORT_LCL

DDRAWI_DDVIDEOPORT_LCL contains local data for each individual DirectDraw video port object.

typedef struct _DDRAWI_DDVIDEOPORT_LCL {
  LPDDRAWI_DIRECTDRAW_LCL  lpDD;
  DDVIDEOPORTDESC  ddvpDesc;
  DDVIDEOPORTINFO  ddvpInfo;
  LPDDRAWI_DDRAWSURFACE_INT  lpSurface;
  LPDDRAWI_DDRAWSURFACE_INT  lpVBISurface;
  LPDDRAWI_DDRAWSURFACE_INT *lpFlipInts;
  DWORD  dwNumAutoflip;
  DWORD  dwProcessID;
  DWORD  dwStateFlags;
  DWORD  dwFlags;
  DWORD  dwRefCnt;
  FLATPTR  fpLastFlip;
  ULONG_PTR  dwReserved1;
  ULONG_PTR  dwReserved2;
  HANDLE  hDDVideoPort;
  DWORD  dwNumVBIAutoflip;
  LPDDVIDEOPORTDESC  lpVBIDesc;
  LPDDVIDEOPORTDESC  lpVideoDesc;
  LPDDVIDEOPORTINFO  lpVBIInfo;
  LPDDVIDEOPORTINFO  lpVideoInfo;
  DWORD  dwVBIProcessID;
} DDRAWI_DDVIDEOPORT_LCL;

Members

lpDD
Points to a DDRAWI_DIRECTDRAW_LCL structure that contains the local DirectDraw object's data.
ddvpDesc
Points to a DDVIDEOPORTDESC structure that describes the video port object.
ddvpInfo
Points to a DDVIDEOPORTINFO structure that describes the transfer of video data to a surface.
lpSurface
Points to a DDRAWI_DDRAWSURFACE_INT structure for the surface receiving the data.
lpVBISurface
Points to a DDRAWI_DDRAWSURFACE_INT structure for the surface receiving the VBI data.
lpFlipInts
Is used by DirectDraw and should not be filled in by the driver.
dwNumAutoflip
Specifies the number of current autoflip surfaces. The driver should use this member for information purposes only.
dwProcessID
Is used by DirectDraw and should not be filled in by the driver.
dwStateFlags
Is used by DirectDraw and should not be filled in by the driver.
dwFlags
Is used by DirectDraw and should not be filled in by the driver.

dwRefCnt
Is used by DirectDraw and should not be filled in by the driver.
fpLastFlip
Is used by DirectDraw and should not be filled in by the driver.
dwReserved1
Is reserved for use by the display driver.
dwReserved2
Is reserved for use by the display driver.
hDDVideoPort
Is used by DirectDraw and should not be filled in by the driver.
dwNumVBIAutoflip
Specifies the number of VBI surfaces currently being autoflipped. The driver should use this member for information purposes only.
lpVBIDesc
lpVideoDesc
lpVBIInfo
lpVideoInfo
dwVBIProcessID
Specifies the ID of the process owning this video port.

Comments

The DDRAWI_DDVIDEOPORT_LCL structure is similar in purpose to the Windows 2000 and later structure, DD_VIDEOPORT_LOCAL.


DDRAWI_DIRECTDRAW_GBL

DDRAWI_DIRECTDRAW_GBL contains the global DirectDraw data that can be shared between object instances.

typedef struct _DDRAWI_DIRECTDRAW_GBL {
  DWORD  dwRefCnt;
  DWORD  dwFlags;
  FLATPTR  fpPrimaryOrig;
  DDCORECAPS  ddCaps;
  DWORD  dwInternal1;
  DWORD  dwUnused1[9];
  LPDDHAL_CALLBACKS  lpDDCBtmp;
  LPDDRAWI_DDRAWSURFACE_INT  dsList;
  LPDDRAWI_DDRAWPALETTE_INT  palList;
  LPDDRAWI_DDRAWCLIPPER_INT  clipperList;
  LPDDRAWI_DIRECTDRAW_GBL  lp16DD;
  DWORD  dwMaxOverlays;
  DWORD  dwCurrOverlays;
  DWORD  dwMonitorFrequency;
  DDCORECAPS  ddHELCaps;
  DWORD  dwUnused2[50];
  DDCOLORKEY  ddckCKDestOverlay;
  DDCOLORKEY  ddckCKSrcOverlay;
  VIDMEMINFO  vmiData;
  LPVOID  lpDriverHandle;
  LPDDRAWI_DIRECTDRAW_LCL  lpExclusiveOwner;
  DWORD  dwModeIndex;
  DWORD  dwModeIndexOrig;
  DWORD  dwNumFourCC;
  DWORD FAR  *lpdwFourCC;
  DWORD  dwNumModes;
  LPDDHALMODEINFO  lpModeInfo;
  PROCESS_LIST  plProcessList;
  DWORD  dwSurfaceLockCount;
  DWORD  dwAliasedLockCnt;
  ULONG_PTR  dwReserved3;
  ULONG_PTR  hDD;
  char  cObsolete[12];
  DWORD  dwReserved1;
  DWORD  dwReserved2;
  DBLNODE  dbnOverlayRoot;
  volatile LPWORD  lpwPDeviceFlags;
  DWORD  dwPDevice;
  DWORD  dwWin16LockCnt;
  DWORD  dwUnused3;
  DWORD  hInstance;
  DWORD  dwEvent16;
  DWORD  dwSaveNumModes;
 //------- Fields added in Version 2.0 -------
  ULONG_PTR  lpD3DGlobalDriverData;
  ULONG_PTR  lpD3DHALCallbacks;
  DDCORECAPS  ddBothCaps;
//------- Fields added in Version 5.0 -------
  LPDDVIDEOPORTCAPS  lpDDVideoPortCaps;
  LPDDRAWI_DDVIDEOPORT_INT  dvpList;
  ULONG_PTR  lpD3DHALCallbacks2;
  RECT  rectDevice;
  DWORD  cMonitors;
  LPVOID  gpbmiSrc;
  LPVOID  gpbmiDest;
  LPHEAPALIASINFO  phaiHeapAliases;
  ULONG_PTR  hKernelHandle;
  ULONG_PTR  pfnNotifyProc;
  LPDDKERNELCAPS  lpDDKernelCaps;
  LPDDNONLOCALVIDMEMCAPS  lpddNLVCaps;
  LPDDNONLOCALVIDMEMCAPS  lpddNLVHELCaps;
  LPDDNONLOCALVIDMEMCAPS  lpddNLVBothCaps;
  ULONG_PTR  lpD3DExtendedCaps;
//--------Fields added in Version 5.0A
  DWORD  dwDOSBoxEvent;
  RECT  rectDesktop;
  char  cDriverName[MAX_DRIVER_NAME];
//------ Fields added in Version 6.0 -------
  ULONG_PTR   lpD3DHALCallbacks3;
  DWORD  dwNumZPixelFormats;
  LPDDPIXELFORMAT  lpZPixelFormats;
  LPDDRAWI_DDMOTIONCOMP_INT mcList;
  DWORD  hDDVxd;
  DDSCAPSEX  ddsCapsMore;
} DDRAWI_DIRECTDRAW_GBL;

Members

dwRefCnt
Is used by DirectDraw and should not be filled in by the driver.
dwFlags
Contains the DirectDraw object's control flags.
Flag | Meaning
DDRAWI_ATTACHEDTODESKTOP | The device is attached to the desktop.
DDRAWI_CHANGINGMODE | The display is currently in a mode change.
DDRAWI_DDRAWDATANOTFETCHED | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWI_DISPLAYDRV | The driver is the display driver.
DDRAWI_EMULATIONINITIALIZED | Emulation has been initialized.
DDRAWI_EXPLICITMONITOR | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWI_EXTENDEDALIGNMENT | At least one heap has extended alignment. Ignore the alignment specified in VIDEOMEMORYINFO.
DDRAWI_FLIPPEDTOGDI | The driver has been flipped to show the GDI surface.
DDRAWI_FULLSCREEN | The driver is in full-screen mode.
DDRAWI_GDIDRV | The driver is a GDI driver.
DDRAWI_HASCKEYDESTOVERLAY | The driver has CKDestOverlay.
DDRAWI_HASCKEYSRCOVERLAY | The driver has CKSrcOverlay.
DDRAWI_HASGDIPALETTE | A GDI palette exists on the primary surface.
DDRAWI_HASGDIPALETTE_EXCLUSIVE | The palette is in exclusive mode.
DDRAWI_MODECHANGED | The display mode has been changed.
DDRAWI_MODEX | The driver is using Mode X.
DDRAWI_MODEXILLEGAL | ModeX is not supported by this hardware.
DDRAWI_NEEDSWIN16FORVRAMLOCK | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWI_NOEMULATION | There is no emulation.
DDRAWI_NOHARDWARE | There is no hardware associated with this driver.
DDRAWI_PALETTEINIT | The GDI palette has been initialized.
DDRAWI_PDEVICEVRAMBITCLEARED | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWI_SECONDARYDRIVERLOADED | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWI_STANDARDVGA | The device is using standard VGA mode (DDRAWI_MODEX will be set).
DDRAWI_TESTINGMODES | This flag is used by DirectDraw and should not be filled in by the driver.
DDRAWI_UMODELOADED | A user-mode driver DLL is loaded.
DDRAWI_VIRTUALDESKTOP | The driver is really a multimonitor virtual desktop.

fpPrimaryOrig
Points to the memory location of the primary surface display memory.
ddCaps
Specifies a DDCORECAPS structure (defined in the DirectDraw SDK documentation) that contains the driver capabilities.
dwInternal1
Is used by DirectDraw and should not be filled in by the driver.
dwUnused1
Is not currently used.
lpDDCBtmp
Points to a DDHAL_CALLBACKS structure that contains pointers to HAL callbacks.
dsList
Is used by DirectDraw and should not be filled in by the driver.
palList
Is used by DirectDraw and should not be filled in by the driver.
clipperList
Is used by DirectDraw and should not be filled in by the driver.
lp16DD
Is used by DirectDraw and should not be filled in by the driver.
dwMaxOverlays
Specifies the maximum number of overlays.
dwCurrOverlays
Specifies the current number of overlays.
dwMonitorFrequency
Specifies the monitor frequency in the current mode.
ddHELCaps
Specifies a DDCORECAPS structure (defined in the DirectDraw SDK documentation) that contains the HEL capabilities.
dwUnused2
Is not currently used.
ddckCKDestOverlay
Is a DDCORECAPS structure used to hold the color key for destination overlay use.
ddckCKSrcOverlay
Is a DDCORECAPS structure (defined in the DirectDraw SDK documentation) used to hold the color key for source overlay use.
vmiData
Specifies a VIDEOMEMORYINFO structure that contains information about display memory.
lpDriverHandle
Is a handle for use by the display driver to call functions in ddraw16.dll.
lpExclusiveOwner
Is used by DirectDraw and should not be filled in by the driver.
dwModeIndex
Contains the current mode index.
dwModeIndexOrig
Contains the original mode index.
dwNumFourCC
Specifies the number of FourCC codes supported.
lpdwFourCC
Is used by DirectDraw and should not be filled in by the driver.
dwNumModes
Specifies the number of modes supported.
lpModeInfo
Is used by DirectDraw and should not be filled in by the driver.
plProcessList
Is used by DirectDraw and should not be filled in by the driver.
dwSurfaceLockCount
Specifies the total number of outstanding locks.
dwAliasedLockCnt
Is used by DirectDraw and should not be filled in by the driver.
dwReserved3
Is reserved for use by the display driver.
hDD
Is used by DirectDraw and should not be filled in by the driver.
cObsolete
Is an obsolete member and should not be used.
dwReserved1
Is reserved for use by the display driver.
dwReserved2
Is reserved for use by the display driver.
dbnOverlayRoot
Specifies the root node of the doubly-linked list of overlay z orders.
lpwPDeviceFlags
Points to a memory location containing a set of driver physical device flags.
dwPDevice
Points to the driver's physical device. This member is a 16:16 pointer.
dwWin16LockCnt
Specifies the count of Win16Lock holds.
dwUnused3
Is currently unused.
hInstance
Is the handle to the driver instance.
dwEvent16
Specifies an event used by the 16-bit side of the driver to tell the 32-bit side that a mode change has occurred.
dwSaveNumModes
Specifies the number of modes supported.
lpD3DGlobalDriverData
Points to global Direct3D data.
lpD3DHALCallbacks
Points to the start of a block of memory containing a list of Direct3D HAL callbacks.
ddBothCaps
Specifies a DDCORECAPS structure (defined in the DirectDraw SDK documentation) containing the logical AND of the driver and the HEL capabilities.
lpDDVideoPortCaps
Points to a DDVIDEOPORTCAPS structure containing the information returned by the HAL. This will be an array of these structures if more than one video port is in existence.
dvpList
Is used by DirectDraw and should not be filled in by the driver.
lpD3DHALCallbacks2
Points to a block of memory containing post-DirectX 3.0 HAL callbacks.
rectDevice
Specifies a rectangle, in desktop coordinates, for the device.
cMonitors
Specifies the number of monitors in the system.
gpbmiSrc
Is used by DirectDraw and should not be filled in by the driver.
gpbmiDest
Is used by DirectDraw and should not be filled in by the driver.
phaiHeapAliases
Is used by DirectDraw and should not be filled in by the driver.
hKernelHandle
This member is used by DirectDraw and should not be filled in by the driver.
pfnNotifyProc
Points to a notification process registered with the VDD. This member is used by DirectDraw and should not be filled in by the driver.
lpDDKernelCaps
Points to a DDKERNELCAPS structure that contains the capabilities of the kernel mode interface.
lpddNLVCaps
Points to a DD_NONLOCALVIDMEMCAPS structure that contains the hardware non-local to local display memory capabilities.
lpddNLVHELCaps
Points to a DD_NONLOCALVIDMEMCAPS structure that contains the emulation layer non-local to local display memory capabilities.
lpddNLVBothCaps
Points to a DD_NONLOCALVIDMEMCAPS structure that contains the logical AND of hardware and emulation non-local to local display memory capabilities.
lpD3DExtendedCaps
Points to the start of a block of memory containing a set of extended capabilities for Direct3D.
dwDOSBoxEvent
Is an event set when return from a DOS box.
rectDesktop
Specifies the rectangle in which the desktop lies.
cDriverName
Specifies the display name.
lpD3DHALCallbacks3
Points to the start of a block of memory containing DirectX 6.0 callbacks.
dwNumZPixelFormats
Specifies the number of z-buffer and stencil pixel formats.
lpZPixelFormats
Points to an array of z-buffer pixel formats.
mcList
Is used by DirectDraw and should not be filled in by the driver.
hDDVxd
Is a handle to ddraw.vxd.
ddsCapsMore
Is a DDSCAPSEX structure as queried by the GUID_DDMoreSurfaceCaps GUID.

Comments

The DDRAWI_DIRECTDRAW_GBL structure is similar in purpose to the Windows 2000 and later structure, DD_DIRECTDRAW_GLOBAL.


DDRAWI_DIRECTDRAW_LCL

DDRAWI_DIRECTDRAW_LCL contains local data for each individual DirectDraw object.

typedef struct _DDRAWI_DIRECTDRAW_LCL {
  DWORD  lpDDMore;
  LPDDRAWI_DIRECTDRAW_GBL  lpGbl;
  DWORD  dwUnused0;
  DWORD  dwLocalFlags;
  DWORD  dwLocalRefCnt;
  DWORD  dwProcessId;
  IUnknown FAR  *pUnkOuter;
  DWORD  dwObsolete1;
  ULONG_PTR  hWnd;
  ULONG_PTR  hDC;
  DWORD  dwErrorMode;
  LPDDRAWI_DDRAWSURFACE_INT  lpPrimary;
  LPDDRAWI_DDRAWSURFACE_INT  lpCB;
  DWORD   dwPreferredMode;
  //------- Fields added in Version 2.0 -------
  HINSTANCE  hD3DInstance;
  IUnknown FAR  *pD3DIUnknown;
  LPDDHAL_CALLBACKS  lpDDCB;
  ULONG_PTR  hDDVxd;
  //------- Fields added in Version 5.0 -------
  DWORD   dwAppHackFlags;
  //------- Fields added in Version 5.A -------
  ULONG_PTR    hFocusWnd;
  DWORD   dwHotTracking;
  DWORD   dwIMEState;
  //------- Fields added in Version 6.0 -------
  ULONG_PTR  hWndPopup;
  ULONG_PTR  hDD;
  ULONG_PTR  hGammaCalibrator;
  LPDDGAMMACALIBRATORPROC  lpGammaCalibrator;
} DDRAWI_DIRECTDRAW_LCL;

Members

lpDDMore
Points to additional local data.
lpGbl
Points to a DDRAWI_DIRECTDRAW_GBL structure that contains the DirectDraw global data.
dwUnused0
Is not currently used.
dwLocalFlags
Is a set of local flags.
Flag | Meaning
DDRAWILCL_ACTIVENO
DDRAWILCL_ACTIVEYES
DDRAWILCL_ALLOWMODEX | Mode X is supported.
DDRAWILCL_ATTEMPTEDD3DCONTEXT | This flag is for the use of DirectDraw only, and should not be set by the driver.
DDRAWILCL_CREATEDWINDOW
DDRAWILCL_CURSORCLIPPED
DDRAWILCL_DIRECTDRAW7
DDRAWILCL_DIRTYDC | Set on ChangeDisplaySettings, cleared when device DC is reinitialized.
DDRAWILCL_DISABLEINACTIVATE
DDRAWILCL_EXPLICITMONITOR | The device was chosen explicitly; that is,. not by a call to DirectDrawCreate(NULL).
DDRAWILCL_FPUPRESERVE | Direct3D needs to switch to single precision/exceptions disabled each time.
DDRAWILCL_FPUSETUP | Direct3D does not need to switch to single precision/exceptions disabled each time.
DDRAWILCL_HASEXCLUSIVEMODE
DDRAWILCL_HOOKEDHWND
DDRAWILCL_ISFULLSCREEN
DDRAWILCL_MODEHASBEENCHANGED
DDRAWILCL_MULTITHREADED | The application indicates that it must be multithreaded.
DDRAWILCL_POWEREDDOWN | This flag is for the use of DirectDraw only, and should not be set by the driver.
DDRAWILCL_SETCOOPCALLED
DDRAWILCL_V1SCLBEHAVIOUR

dwLocalRefCnt
Specifies the local reference count.
dwProcessId
Specifies the ID of the owning process.
pUnkOuter
Points to the outer IUnknown.
dwObsolete1
Is obsolete and should not be used.
hWnd
hDC
Is a handle to the device context.
dwErrorMode
lpPrimary
lpCB
dwPreferredMode
hD3DInstance
Is a handle to Direct3D's DLL.
pD3DIUnknown
Points to Direct3D's aggregated IUnknown.
lpDDCB
Points to a DDHAL_CALLBACKS structure containing pointers to HAL callbacks.
hDDVxd
Is a handle to ddraw.vxd.
dwAppHackFlags
Is a set of application compatibilty flags.
hFocusWnd
Is a handle to the focus window set by SetCoopLevel.
dwHotTracking
Specifies the reactive menu (and other user interface elements) setting cached while the application was fullscreen.
dwIMEState
Specifies the IME toolbar setting.
hWndPopup
Is a handle to a popup window.
hDD
Is used by DirectDraw and should not be filled in by the driver.
hGammaCalibrator
Is used by DirectDraw and should not be filled in by the driver.
lpGammaCalibrator
Is used by DirectDraw and should not be filled in by the driver.

Comments

The DDRAWI_DIRECTDRAW_LCL structure is similar in purpose to the Windows 2000 and later structure, DD_DIRECTDRAW_LOCAL.


Direct3D Driver Functions

This section provides reference pages for the callback functions and their associated structures in the Windows® Direct3D® driver interface. All callback names are pseudonames to be decided upon by the display driver writer.

Direct3D DDI Header Files, Sample Code, and References lists the include file that contains Direct3D function prototypes.

For general Direct3D data structure definitions, see Direct3D Driver Structures. Additional information for writing a Direct3D driver can be found in Direct3D DDI.

The end of this reference contains the D3DBuffer Callbacks that are used only in drivers that manage their own command and vertex buffers.


D3dContextCreate

D3dContextCreate creates a context.

DWORD
  (*APIENTRY *LPD3DHAL_CONTEXTCREATECB)(
    LPD3DHAL_CONTEXTCREATEDATA  pccd
    );

Parameters

pccd
Points to a D3DHAL_CONTEXTCREATEDATA structure that contains the information required to create a context and the data that the driver should store in the new context.

Return Value

D3dContextCreate returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

D3dContextCreate must be implemented in drivers that support Direct3D. It should perform the following steps:

  • Initialize the driver's context with all information required by the driver to perform rendering. This includes associating the rendering target and depth buffer that lpDDS and lpDDSZ point to, respectively, with the context.
  • Generate a unique context ID for this new context and return it in dwhContext. Direct3D will use this context ID in every subsequent callback it makes to this Direct3D device. The driver must never create a context handle of zero.
  • Set ddrval to DD_OK upon success, and to D3DHAL_OUTOFCONTEXTS if it cannot create the context.
  • Return DDHAL_DRIVER_HANDLED upon return.

State is not shared between contexts; therefore, the driver must maintain full state information for each context. This state will be changed by any subsequent calls to D3dDrawPrimitives2.

The driver must be able to reference all texture handles that are created within the created context. This is so that the driver can clean up all driver-specific data related to textures created within this context when a D3dContextDestroy call is made.

D3DHAL_CONTEXTCREATEDATA

The D3DHAL_CONTEXTCREATEDATA structure contains all of the information that D3dContextCreate needs to create a new context.

typedef struct _D3DHAL_CONTEXTCREATEDATA {
  PDD_DIRECTDRAW_LOCAL  lpDDLcl;
  PDD_SURFACE_LOCAL  lpDDSLcl;
  PDD_SURFACE_LOCAL  lpDDSZLcl;
  DWORD  dwPID;
  ULONG_PTR  dwhContext;
  HRESULT  ddrval;
} D3DHAL_CONTEXTCREATEDATA, *LPD3DHAL_CONTEXTCREATEDATA;

Members

lpDDLcl
Points to the DirectDraw object that an application must create in order to retrieve the COM Interface to Direct3D. This allows context information to be shared between a DirectDraw application and the driver. lpDDLcl is the common and binding factor between the application's context and the driver's context. It points to a DD_DIRECTDRAW_LOCAL structure that is used to identify the surfaces that belong to a given Direct3D context and is relevant to the current DirectDraw process only. lpDDLcl is necessary because surfaces (for example, depth buffers, rendering buffers, and textures) can be created before a Direct3D context is ever created in the driver.
lpDDSLcl
Points to a DD_SURFACE_LOCAL structure that describes the DirectDraw surface to be used as the rendering target.
lpDDSZLcl
Points to a DD_SURFACE_LOCAL structure that describes the DirectDraw surface to be used as a depth buffer. If this member is NULL, no depth buffering is to be performed.
dwPID
Specifies the current process ID. This is the process ID of the Direct3D application that initiated the creation of the Direct3D device.
dwhContext
Specifies the location where the driver returns the context handle upon successfully creating the context. The driver should return a unique context ID for Direct3D to use when communicating with the driver.
ddrval
Specifies the location where the driver writes the return value of D3dContextCreate. A return code of DD_OK indicates success.

See Also

D3dContextDestroy, D3dDrawPrimitives2.


D3dContextDestroy

D3dContextDestroy deletes the specified context.

DWORD
  (APIENTRY *LPD3DHAL_CONTEXTDESTROYCB)(
    LPD3DHAL_CONTEXTDESTROYDATA  pcdd
    );

Parameters

pcdd
Points to a D3DHAL_CONTEXTDESTROYDATA structure that contains the information required for the driver to destroy the context.

Return Value

D3dContextDestroy returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

The driver should free all resources it allocated to the context being deleted. For example, the driver should free any texture resources it associated with the context. The driver should not free the DirectDraw surface(s) associated with the context because these will be freed by DirectDraw in response to an application or Direct3D runtime request.

D3DHAL_CONTEXTDESTROYDATA

The D3DHAL_CONTEXTDESTROYDATA structure contains the information that D3dContextDestroy needs to delete a context.

typedef struct _D3DHAL_CONTEXTDESTROYDATA {
  ULONG_PTR  dwhContext;
  HRESULT  ddrval;
} D3DHAL_CONTEXTDESTROYDATA, *LPD3DHAL_CONTEXTDESTROYDATA;

Members

dwhContext
Specifies the handle to the context to be destroyed.
ddrval
Specifies the location where the driver writes the return value of D3dContextDestroy. DD_OK indicates success.

See Also

D3dContextCreate


D3dCreateSurfaceEx

D3dCreateSurfaceEx creates a Direct3D surface from a DirectDraw surface and associates a requested handle value to it.

DWORD
  (APIENTRY *PDD_CREATESURFACEEX)(
    PDD_CREATESURFACEEXDATA  pcsxd
    );

Parameters

pcsxd
Points to a DD_CREATESURFACEEXDATA structure that contains the information required for the driver to create the surface (described below).

Return Value

D3dCreateSurfaceEx returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

All Direct3D drivers must support D3dCreateSurfaceEx.

D3dCreateSurfaceEx creates an association between a DirectDraw surface and a small integer surface handle. By creating these associations between a handle and a DirectDraw surface, D3dCreateSurfaceEx allows a surface handle to be embedded in the Direct3D command stream. For example, when the D3DDP2OP_TEXBLT command token is sent to D3dDrawPrimitives2 to load a texture map, it uses a source handle and destination handle that were associated with a DirectDraw surface through D3dCreateSurfaceEx.

For every DirectDraw surface created under the local DirectDraw object, the runtime generates a valid handle that uniquely identifies the surface and places it in pcsxd->lpDDSLcl->lpSurfMore->dwSurfaceHandle. (See the DD_SURFACE_MORE structure for more information about its dwSurfaceHandle member.) This handle value is also used with the D3DRENDERSTATE_TEXTUREHANDLE render state to enable texturing, and with the D3DDP2OP_SETRENDERTARGET and D3DDP2OP_CLEAR commands to set and clear new rendering and depth buffers. The driver should fail the call and return DDHAL_DRIVER_HANDLED if it cannot create the Direct3D surface.

Upon the destruction of a system memory surface with a dwSurfaceHandle, the driver will be notified by a D3dCreateSurfaceEx callback. The fpVidMem pointer (a member of the DD_SURFACE_GLOBAL structure) for the system memory surface is cleared to zero. The driver should then invalidate and free any driver-private data associated to this system memory surface. It is common for a video memory surface to have fpVidMem set to zero, so drivers must check memory type before applying this special destruction notification. Upon destruction of video memory surface, however, there is no additional D3dCreateSurfaceEx callback notification because drivers always get a DdDestroySurface callback for video memory surface.

The driver should also store any surface-related information that it subsequently will need when using the surface. The driver must create a new surface table for each new lpDDLcl and implicitly enlarge the table when necessary to accommodate more surfaces. Typically this is done with an exponential growth algorithm so that you do not have to enlarge the table too often. See the perm3 sample driver that ships with the DDK for implementation details.

Direct3D calls D3dCreateSurfaceEx after the surface is created by DirectDraw by request of the Direct3D runtime or the application.

DD_CREATESURFACEEXDATA

The DD_CREATESURFACEEXDATA contains information required for the driver to create a surface and associate with it a supplied texture handle.

typedef struct _DD_CREATESURFACEEXDATA {
  DWORD  dwFlags;
  PDD_DIRECTDRAW_LOCAL  lpDDLcl;
  PDD_SURFACE_LOCAL  lpDDSLcl;
  HRESULT  ddRVal;
} DD_CREATESURFACEEXDATA;

Members

dwFlags
Is a set of flags for D3dCreateSurfaceEx that are currently not used and always zero.
lpDDLcl
Is a handle to the DirectDraw object created by the application. This is the scope within which the lpDDSLcl handles exist. A DD_DIRECTDRAW_LOCAL structure describes the driver.
lpDDSLcl
Is a handle to the DirectDraw surface to be created for Direct3D. These handles are unique within each different DD_DIRECTDRAW_LOCAL structure. A DD_SURFACE_LOCAL structure represents the created surface object.
ddRVal
Specifies the location where the driver writes the return value of the D3dCreateSurfaceEx callback. A return code of DD_OK indicates success.

See Also

D3dDestroyDDLocal

Sample implementation of D3dCreateSurfaceEx

LPDDRAWI_DDRAWSURFACE_LCL GetAttachedSurface(
    LPDDRAWI_DDRAWSURFACE_LCL pLcl,
    DDSCAPS2 * pddsCaps2)
{
    LPATTACHLIST pAl;

    pAl = pLcl->lpAttachList;

    while (pAl)
    {
        LPDDRAWI_DDRAWSURFACE_LCL pLclAttached = pAl->lpAttached;
        LPATTACHLIST pAlAttached = pLclAttached->lpAttachList;

        if ((pLclAttached->lpSurfMore->ddsCapsEx.dwCaps2 & pddsCaps2->dwCaps2) ||
            (pLclAttached->lpSurfMore->ddsCapsEx.dwCaps3 & pddsCaps2->dwCaps3) ||
            (pLclAttached->lpSurfMore->ddsCapsEx.dwCaps4 & pddsCaps2->dwCaps4) ||
            (pLclAttached->ddsCaps.dwCaps & pddsCaps2->dwCaps)
            )
        {
            return pLclAttached;
        }
        pAl = pAl->lpLink;
    }
    return NULL;
}

void CSExProcessPossibleMipmap(LPDDRAWI_DDRAWSURFACE_LCL pLcl)
{
    //
    // A more likely scenario would be to build a list of surfaces
    // so that the driver can create one structure that represents the
    // entire mipmap, rather than creating an object to represent each
    // level as depicted here.
    //
    DDSCAPS2 ddsCaps2 = {0,DDSCAPS2_MIPMAPSUBLEVEL,0,0};
    while (pLcl)
    {
        //Call the private driver routine that creates a driver-side surface structure
        CreateMyRepresentation(pLcl);

        pLcl = GetAttachedSurface(pLcl,&ddsCaps2);
    }
}

//
// The actual return type should reflect the fact that the only
// way this routine should fail is with DDERR_OUTOFMEMORY
//
void MyCreateSurfaceExHelper(LPDDRAWI_DDRAWSURFACE_LCL pLcl)
{
    LPATTACHLIST pAl;
    DDSCAPS2 ddsCaps2 = {0,0,0,0};
    LPDDRAWI_DDRAWSURFACE_LCL pLclAttached;
    LPDDRAWI_DDRAWSURFACE_LCL pLclStart;

    if (pLcl->lpGbl->fpVidMem == 0)
    {
        //A required check against bad surfaces
        if (pLcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
            return;

        //Else, this is a system memory surface, so we are being informed of
        // its destruction
        DestroyMyRepresentation(pLcl->lpSurfMore->dwSurfaceHandle);
        return;
    }

    CSExProcessPossibleMipmap(pLcl);

    if (pLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_CUBEMAP)
    {
        int i;
        //
        // The root surface is always positive X, so we check for the
        // other five face types.
        //
        DWORD dw[5] = {
            DDSCAPS2_CUBEMAP_NEGATIVEX,
            DDSCAPS2_CUBEMAP_POSITIVEY,
            DDSCAPS2_CUBEMAP_NEGATIVEY,
            DDSCAPS2_CUBEMAP_POSITIVEZ,
            DDSCAPS2_CUBEMAP_NEGATIVEZ};

        for(i=0;i< sizeof(dw)/sizeof(dw[0]);i++)
        {
            ddsCaps2.dwCaps2 = dw[i];
            pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
            if (pLclAttached)
                CSExProcessPossibleMipmap(pLclAttached);
        }

        //
        // Once we know it's a cube map, we know there can't be any other
        // attachments.
        //
        return;
    }

    //
    // At this point:
    //      If it's a cubemap, we returned above.
    //      If it's a mipmap, we handled all cases above.
    // The only other complex surface possibility is a primary flipping chain.
    // Since a primary flipping chain cannot be mipmapped, we will simply return
    // here if this surface is a mipmap.
    //

    if (pLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
        return;

    //
    // The only system memory surfaces we'll ever be interested in are textures (mipmaps)
    // and cube maps. Any other kind of system memory surface is not interesting to
    // us, and we return here. WE DO NOT PROPAGATE AN ERROR CODE FOR SYSTEM MEMORY
    // SURFACES WHOSE FORMAT WE DO NOT UNDERSTAND. This could cause an error code to
    // be propagated to the application when it was trying to use system memory surfaces
    // of a format we don't understand, but is valid for the reference rasterizer, for example.
    //

    if (pLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
        return;

    //
    // Now walk around a flipping chain. A flipping chain is a ring of
    // surface attached to each other (each surface is attached to the next
    // and to the previous surface in the ring, but not to any other surface
    // in the ring).
    // We need to watch out for this circular ring and make sure we exit appropriately.
    // There is also the possibility of a z buffer attached to one of the surfaces
    // in the ring, which may or may not have been CreateSurfaceEx'ed already.
    //

    pLclStart = pLcl;

    while (pLcl && pLcl != pLclStart)
    {
        //Check for Z buffer attached to this surface in the ring.
        ddsCaps2.dwCaps = DDSCAPS_ZBUFFER;
        ddsCaps2.dwCaps2 = 0;
        pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
        if (pLclAttached)
            CreateMyRepresentation(pLclAttached);

        //Check for stereo left surface attached to this surface in the ring
        ddsCaps2.dwCaps = 0;
        ddsCaps2.dwCaps2 = DDSCAPS2_STEREOSURFACELEFT;
        pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
        if (pLclAttached)
            CreateMyRepresentation(pLclAttached);

        // Move to next surface in the primary flipping ring. The next surface is
        // definitely in video memory (all surfaces in an attachment structure have
        // to be in the same memory type, and we excluded system memory above).
        // The next surface in the ring is thus the attached video memory surface
        // that is NOT a z buffer NOR a stereo left surface.

        ddsCaps2.dwCaps = DDSCAPS_VIDEOMEMORY;
        ddsCaps2.dwCaps2 = 0;
        do
        {
            pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
        }
        while (
            pLclAttached->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
            pLclAttached->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT
            );

        pLcl = pLclAttached;

        if (pLcl != pLclStart)
            CreateMyRepresentation(pLcl);
    }
}


D3dDestroyDDLocal

D3dDestroyDDLocal destroys all the Direct3D surfaces previously created by D3DCreateSurfaceEx that belong to the same given local DirectDraw object.

DWORD
  (APIENTRY *PDD_DESTROYDDLOCAL)(
    PDD_DESTROYDDLOCALDATA  pcdddd
    );

Parameters

pcdddd
Points to a DDHAL_DESTROYDDLOCALDATA structure that contains the information required for the driver to destroy the surfaces.

Return Value

D3dDestroyDDLocal returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

All Direct3D drivers must support D3dDestroyDDLocal.

Direct3D calls D3dDestroyDDLocal when the application indicates that the Direct3D context is no longer required and it will be destroyed along with all surfaces associated to it. The association comes through the pointer to the local DirectDraw object. The driver must free any memory that the driver's D3dCreateSurfaceEx callback allocated for each surface, if necessary.

The driver should not destroy the DirectDraw surfaces associated with these Direct3D surfaces. This is the application's responsibility.

DDHAL_DESTROYDDLOCALDATA

DDHAL_DESTROYDDLOCALDATA contains the information required for the driver to destroy a set of surfaces associated to a given local DirectDraw object.

typedef struct _DDHAL_DESTROYDDLOCALDATA {
  DWORD  dwFlags;
  PDD_DIRECTDRAW_LOCAL  pDDLcl;
  HRESULT  ddrval;
} DDHAL_DESTROYDDLOCALDATA, *LPDDHAL_DESTROYDDLOCALDATA;

Members

dwFlags
Currently unused.
pDDLcl
Points to the local Direct Draw object that serves as a reference for all Direct3D surfaces that have to be destroyed.
ddrval
Specifies the location where the driver writes the return value of D3dDestroyDDLocal. A return code of DD_OK indicates success.

See Also

D3dCreateSurfaceEx


D3dDrawPrimitives2

D3dDrawPrimitives2 renders primitives and returns the updated render state.

DWORD
  (APIENTRY *LPD3DHAL_DRAWPRIMITIVES2CB)(
    LPD3DHAL_DRAWPRIMITIVES2DATA  pdp
    );

Parameters

pdp
Points to a D3DHAL_DRAWPRIMITIVES2DATA structure that contains the information required for the driver to render one or more primitives.

Return Value

D3dDrawPrimitives2 returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

D3dDrawPrimitives2 must be implemented in Direct3D drivers.

The driver must do the following:

  • Ensure that the context handle specified by the dwhContext member of the D3DHAL_DRAWPRIMITIVES2DATA structure is valid.
  • Check that a flip to the drawing surface associated with the context is not in progress. If the drawing surface is involved in a flip, the driver should set the ddrval member of the following structure to DDERR_WASSTILLDRAWING and return DDHAL_DRIVER_HANDLED.
  • Determine the location where the first D3DHAL_DP2COMMAND structure is found by adding dwCommandOffset bytes to the command buffer that lpDDCommands points to. dwCommandOffset and lpDDCommands are members of the D3DHAL_DRAWPRIMITIVES2DATA structure.
  • Determine the location in the vertex buffer where the first vertex is found. This should only be done if there is data in the vertex buffer; that is, when a D3DDP2OP_Xxx command token is received (except when the token is D3DDP2OP_LINELIST_IMM or D3DDP2OP_TRIANGLEFAN_IMM). These two opcodes indicate that the vertex data is passed immediately in the command stream, rather than in a vertex buffer. So, assuming there is data in the vertex buffer, if the vertex buffer is in user memory, the first vertex is dwVertexOffset bytes into the buffer that lpVertices points to. Otherwise, the driver should apply dwVertexOffset to the memory associated with the DD_SURFACE_LOCAL structure to which lpDDVertex points. dwVertexOffset, lpVertices, and lpDDVertex are members of the following structure.
  • Check the dwVertexType member of the D3DHAL_DRAWPRIMITIVES2DATA structure to ensure that the driver supports the requested FVF. The driver should fail the call if any of the following conditions exist:
    • Vertex coordinates are not specified; that is, if D3DFVF_XYZRHW is not set.
    • Normals are specified; that is, if D3DFVF_NORMAL is set.
    • Any of the reserved D3DFVF_RESERVEDx bits are set.
  • Process all of the commands in the command buffer sequentially. For each D3DHAL_DP2COMMAND structure, the driver should do the following:
    • If the command is D3DDP2OP_RENDERSTATE, process the wStateCount D3DHAL_DP2RENDERSTATE structures that follow in the command buffer, updating the driver state for each render state structure. When the D3DHALDP2_EXECUTEBUFFER flag is set, the driver should also reflect the state change in the array that lpdwRStates points to. wStateCount and lpdwRStates are members of the D3DHAL_DRAWPRIMITIVES2DATA structure.
    • If the command is D3DDP2OP_TEXTURESTAGESTATE, process the wStateCount D3DHAL_DP2TEXTURESTAGESTATE structures that follow in the command buffer, updating the driver's texture state associated with the specified texture stage for each texture state structure.
    • If the command is D3DDP2OP_VIEWPORTINFO, process the D3DHAL_DP2VIEWPORTINFO structure that follows in the command buffer, updating the viewport information stored in the driver's internal rendering context.
    • If the command is D3DDP2OP_WINFO, process the D3DHAL_DP2WINFO structure that follows in the command buffer, updating the w-buffering information stored in the driver's internal rendering context.
    • Otherwise, process the D3DHAL_DP2Xxx primitive structures that follow the D3DDP2OP_Xxx primitive rendering command in the command buffer.
    • If the command is unknown, call the runtime's D3dParseUnknownCommand callback. The runtime provides this callback to the driver's DdGetDriverInfo callback with the GUID_D3DParseUnknownCommandCallback GUID.

The driver does not need to probe for readability the memory where the command and vertex buffers are stored. However, the driver must stay within the bounds specified by the dwCommandLength and dwVertexLength members of the D3DHAL_DRAWPRIMITIVES2DATA structure.

If the driver must fail D3dDrawPrimitives2, it should fill in the dwErrorOffset member of the D3DHAL_DRAWPRIMITIVES2DATA structure with the offset into the command buffer where the first unhandled D3DHAL_DP2COMMAND can be found.

If a DirectX 8.0 or later interface on the runtime is being used, there is no concept of current vertex buffer. Never stall upon D3dDrawPrimitives2. Otherwise, if the current vertex buffer (passed in via lpDDVertex) has only DDSCAPS_EXECUTEBUFFER set, never stall at the end of D3dDrawPrimitives2.

Note Although this is how it is supposed to work, due to a bug, it doesn't. The end-result is that if the driver doesn't always stall on vertex buffers with only DDSCAPS_EXECUTEBUFFER set (known as implicit vertex buffers), there might be some synchronization issues and resulting corruption. The workaround is to stall when transitioning between rendering user-memory primitives (identified by D3DHALDP2_USERMEMVERTICES) and rendering from an implicit vertex buffer only when D3DHALDP2_SWAPVERTEXBUFFER is not set. Here is an example of when D3dDrawPrimitives2 should stall on an implicit vertex buffer:

DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Don't stall
DrawPrimitives2(Implicit VB, 0); // STALL due to D3D bug

And here is an example of when D3dDrawPrimitives2 should not stall on an implicit vertex buffer:

DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Don't stall
DrawPrimitives2(Explicit VB, 0); // Don't stall if not locked
DrawPrimitives2(Explicit VB, D3DHALDP2_SWAPVERTEXBUFFER); // Don't stall whether or not locked
DrawPrimitives2(Implicit VB, 0); // Don't stall whether or not locked
DrawPrimitives2(Implicit VB, 0); // Don't stall whether or not locked
DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Don't stall
DrawPrimitives2(Implicit VB, D3DHALDP2_SWAPVERTEXBUFFER); // Don't stall because D3DHALDP2_SWAPVERTEXBUFFER is set

Please turn off these workarounds when the driver detects a DirectX 8b or later runtime.

If the current vertex buffer (passed in via lpDDVertex) has DDSCAPS_EXECUTEBUFFER and DDSCAPS2_VERTEXBUFFER set and there is an outstanding lock on the vertex buffer, stall at the end of D3dDrawPrimitives2 if you are not renaming (via D3DHALDP2_SWAPVERTEXBUFFER). If you rename, then there is no need to stall.

Note Although this is how it is supposed to work, due to a bug, it doesn't. The end-result is that the driver is called to render from a locked explicit vertex buffer more often then really necessary. Since the explicit vertex buffer is locked, the D3dDrawPrimitives2 call would stall and would hurt performance. However, there is a workaround that can reduce this problem in the most common slowdown case. It turns out that if D3DHALDP2_REQCOMMANDBUFSIZE is also set, then there is no need to stall. Note that D3DHALDP2_REQCOMMANDBUFSIZE has itself nothing to do with this issue or the D3D bug. But it so happens that the bug inducing code path in D3D also sets D3DHALDP2_REQCOMMANDBUFSIZE and hence it becomes a way for the driver to detect (and workaround) this case. Here is an example of when D3dDrawPrimitives2 should stall on an explicit vertex buffer:

DrawPrimitives2(Explicit VB, 0); // STALL when locked (will happen rarely)

And here is an example of when D3dDrawPrimitives2 should not stall on an explicit vertex buffer:

DrawPrimitives2(Explicit VB, D3DHALDP2_REQCOMMANDBUFSIZE); // Don't stall whether or not locked
DrawPrimitives2(Explicit VB, D3DHALDP2_SWAPVERTEXBUFFER); // Don't stall whether or not locked
DrawPrimitives2(Explicit VB, D3DHALDP2_SWAPVERTEXBUFFER | D3DHALDP2_REQCOMMANDBUFSIZE); // Don't stall

Please turn off these workarounds when the driver detects a DirectX 8b or later runtime.

D3DHAL_DRAWPRIMITIVES2DATA

The D3DHAL_DRAWPRIMITIVES2DATA structure contains the information required by D3dDrawPrimitives2 to render primitives.

typedef struct _D3DHAL_DRAWPRIMITIVES2DATA {
    ULONG_PTR         dwhContext;
    DWORD             dwFlags;
    DWORD             dwVertexType;
    PDD_SURFACE_LOCAL lpDDCommands;
    DWORD             dwCommandOffset;
    DWORD             dwCommandLength;
    union
    {
        PDD_SURFACE_LOCAL lpDDVertex;
        LPVOID            lpVertices;
    };
    DWORD             dwVertexOffset;
    DWORD             dwVertexLength;
    DWORD             dwReqVertexBufSize;
    DWORD             dwReqCommandBufSize;
    LPDWORD           lpdwRStates;
    union
    {
        DWORD         dwVertexSize;
        HRESULT       ddrval;
    };
    DWORD             dwErrorOffset;
} D3DHAL_DRAWPRIMITIVES2DATA;

Members

dwhContext
Specifies the context handle of the Direct3D device.
dwFlags
Specifies flags that provide additional instructions to the driver or provide information from the driver. This member can be a bitwise OR of the following values:
Value | Meaning
D3DHALDP2_EXECUTEBUFFER | The command and vertex buffers were created in system memory. The driver should update the state array that lpdwRStates points to. This flag is set by Direct3D only.
D3DHALDP2_REQCOMMANDBUFSIZE | The driver must be able to increase the current command buffer by at least the size specified in dwReqCommandBufSize. Drivers that do not support multi-buffering of command buffers can ignore this flag. This flag is set by Direct3D only.
D3DHALDP2_REQVERTEXBUFSIZE | The driver must be able to allocate a vertex buffer of at least the size specified in dwReqVertexBufSize. Drivers that do not support multi-buffering of vertex buffers can ignore this flag. This flag is set by Direct3D only.
D3DHALDP2_SWAPCOMMANDBUFFER | The driver can swap the buffer that lpDDCommands points to with a new command buffer and return immediately, asynchronously processing the original buffer while Direct3D fills the new command buffer. Drivers that do not support multi-buffering of command buffers can ignore this flag. This flag is set by Direct3D only.
D3DHALDP2_SWAPVERTEXBUFFER | The driver can swap the buffer that lpDDVertex or lpVertices points to with a new vertex buffer and return immediately, asynchronously processing the original buffer while Direct3D fills the new vertex buffer. Drivers that do not support multi-buffering of vertex buffers can ignore this flag. This flag is set by Direct3D only.
D3DHALDP2_USERMEMVERTICES | The lpVertices member is valid so the driver should obtain the vertex data from the user-allocated memory that lpVertices points to. This flag is set by Direct3D only.
D3DHALDP2_VIDMEMCOMMANDBUF | The command buffer allocated by the driver as a swap buffer is not in system memory. This flag can be set by drivers that support multi-buffering of command buffers.
D3DHALDP2_VIDMEMVERTEXBUF | The vertex buffer allocated by the driver as a swap buffer is not in system memory. This flag can be set by drivers that support multi-buffering of vertex buffers.

dwVertexType
Identifies the FVF of the data in the vertex buffer; that is, dwVertexType specifies which per-vertex data fields are present in the vertex buffer that lpDDVertex or lpVertices points to. This member can be a bitwise OR of the values in the following table. Only one of the D3DFVF_TEXx flags will be set.
Value | Meaning
D3DFVF_DIFFUSE | Each vertex has a diffuse color.
D3DFVF_SPECULAR | Each vertex has a specular color.
D3DFVF_TEX0 | No texture coordinates are provided with the vertex data.
D3DFVF_TEX1 | Each vertex has one set of texture coordinates.
D3DFVF_TEX2 | Each vertex has two sets of texture coordinates.
D3DFVF_TEX3 | Each vertex has three sets of texture coordinates.
D3DFVF_TEX4 | Each vertex has four sets of texture coordinates.
D3DFVF_TEX5 | Each vertex has five sets of texture coordinates.
D3DFVF_TEX6 | Each vertex has six sets of texture coordinates.
D3DFVF_TEX7 | Each vertex has seven sets of texture coordinates.
D3DFVF_TEX8 | Each vertex has eight sets of texture coordinates.
D3DFVF_XYZRHW | Each vertex has x, y, z, and w coordinates. This flag is always set.

lpDDCommands
Points to the DD_SURFACE_LOCAL structure that identifies the DirectDraw surface containing the command data. The fpVidMem member of the embedded DD_SURFACE_GLOBAL structure points to the buffer that contains state change and primitive drawing commands for the driver to process. Specifically, this buffer contains one or more D3DHAL_DP2COMMAND structures, each followed by a D3DHAL_DP2Xxx structure whose exact type is identified by D3DHAL_DP2COMMAND's bCommand member.
dwCommandOffset
Specifies the number of bytes into the surface that lpDDCommands points to and where the command data starts.
dwCommandLength
Specifies the number of bytes of valid command data in the surface that lpDDCommands points to starting at dwCommandOffset.
lpDDVertex
Points to the DD_SURFACE_LOCAL structure that identifies the DirectDraw surface containing the vertex data when the D3DHALDP2_USERMEMVERTICES flag is not set in dwFlags. Forms a union with lpVertices.
lpVertices
Points to a user-mode memory block containing vertex data when the D3DHALDP2_USERMEMVERTICES flag is set in dwFlags.
dwVertexOffset
Specifies the number of bytes into the surface pointed to by lpDDVertex or lpVertices where the vertex data starts.
dwVertexLength
The number of vertices for which valid data exists in the surface pointed to by lpDDVertex (starting at dwVertexOffset). Note that dwVertexOffset is specified in bytes.
dwReqVertexBufSize
Specifies the minimum number of bytes that the driver must allocate for the swap vertex buffer. This member is valid only when the D3DHALDP2_REQVERTEXBUFSIZE flag is set. Drivers that do not support multi-buffering of vertex buffers should ignore this member.
dwReqCommandBufSize
Specifies the minimum number of bytes that the driver must increase the swap command buffer by. This member is valid only when the D3DHALDP2_REQCOMMANDBUFSIZE flag is set. Drivers that do not support multi-buffering of command buffers should ignore this member.
lpdwRStates
Points to a render state array that the driver should update when it parses render state commands from the command buffer. The driver should update this array only when the D3DHALDP2_EXECUTEBUFFER flag is set in dwFlags. The driver should use the D3DRENDERSTATETYPE enumerated types to update the appropriate element of the render state array.
dwVertexSize
Specifies the size of each vertex, in bytes. Forms a union with ddrval.
ddrval
Specifies the location where the driver writes the return value of D3dDrawPrimitives2. D3D_OK indicates success. Otherwise, the driver should return the appropriate D3DERR_Xxx error code.
Value | Meaning
D3D_OK | The operation completed successfully.
D3DERR_COMMAND_UNPARSED | The driver requires that the Direct3D run-time to parse the execute buffer.

dwErrorOffset
Specifies the location where the driver should write the offset into the surface that lpDDCommands points to where the first unhandled D3DHAL_DP2COMMAND can be found. The driver must set this value when it returns an error condition in ddrval.

See Also

D3DHAL_DP2INDEXEDLINELIST, D3DHAL_DP2INDEXEDLINESTRIP, D3DHAL_DP2INDEXEDTRIANGLEFAN, D3DHAL_DP2INDEXEDTRIANGLELIST, D3DHAL_DP2INDEXEDTRIANGLESTRIP, D3DHAL_DP2LINELIST, D3DHAL_DP2LINESTRIP, D3DHAL_DP2POINTS, D3DHAL_DP2TRIANGLEFAN, D3DHAL_DP2TRIANGLELIST, D3DHAL_DP2TRIANGLESTRIP, FVF


D3dGetDriverState

D3dGetDriverState is used by both the DirectDraw and Direct3D runtimes to obtain information from the driver about its current state.

DWORD
  (APIENTRY *PDD_GETDRIVERSTATE)(
    PDD_GETDRIVERSTATEDATA  pgdsd
    );

Parameter

pgdsd
Points to a DD_GETDRIVERSTATEDATA structure.

Return Value

D3dGetDriverState returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This callback routine is used by both the DirectDraw and Direct3D runtimes to obtain information from the driver about its current state.

DD_GETDRIVERSTATEDATA

typedef struct _DD_GETDRIVERSTATEDATA {
    DWORD    dwFlags;
    union
    {
        PDD_DIRECTDRAW_GLOBAL  lpDD;
        DWORD_PTR              dwhContext;
    };
    LPDWORD  lpdwStates;
    DWORD    dwLength;
    HRESULT  ddRVal;
} DD_GETDRIVERSTATEDATA;

Members

dwFlags
Is a set of flags to indicate the data requested.
lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure describing the device.
dwhContext
Specifies the ID of the context that information is being requested for.
lpdwStates
Points to the Direct3D driver state data to be filled in by the driver.
dwLength
Specifies the length of the state data to be filled in by the driver.
ddRVal
Specifies the return value.


D3dValidateTextureStageState

D3dValidateTextureStageState returns the number of passes where the hardware can perform the blending operations specified in the current state.

DWORD
  (APIENTRY *LPD3DHAL_VALIDATETEXTURESTAGESTATECB)(
    LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA  pvtssd
    );

Parameters

pvtssd
Points to a D3DHAL_VALIDATETEXTURESTAGESTATEDATA structure that contains the information required for the driver to determine and return the number of passes required to perform the blending operations.

Return Value

D3dValidateTextureStageState returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

Direct3D drivers that support texturing must implement D3dValidateTextureStageState.

The driver's implementation of this function must evaluate the current texture state for all texture stages associated with the context. If the driver's hardware can perform the specified blending operations, then the driver should return the number of passes on the state data that its hardware requires. If the hardware cannot perform the specified blending operations, then the driver should return one of the following error codes in the ddrval member of the following structure:

Error Code | Meaning
D3DERR_CONFLICTINGTEXTUREFILTER | The hardware cannot do both trilinear filtering and multitexturing at the same time.
D3DERR_TOOMANYOPERATIONS | The hardware cannot handle the specified number of operations.
D3DERR_UNSUPPORTEDALPHAARG | The hardware does not support a specified alpha argument.
D3DERR_UNSUPPORTEDALPHAOPERATION | The hardware does not support a specified alpha operation.
D3DERR_UNSUPPORTEDCOLORARG | The hardware does not support a specified color argument.
D3DERR_UNSUPPORTEDCOLOROPERATION | The hardware does not support a specified color operation.
D3DERR_UNSUPPORTEDFACTORVALUE | The hardware does not support a D3DTA_TFACTOR greater than 1.0.
D3DERR_WRONGTEXTUREFORMAT | The hardware does not support the current state in the selected texture format.

Direct3D calls D3dValidateTextureStageState in response to an application request through a call to IDirect3DDevice7::ValidateDevice. The number of passes returned by the driver is propagated back to the application, which can then decide whether it will proceed with rendering using the current state or if it must change the blending operations to render faster or to render at all. There are no limits to the number of passes that a driver can return.

A driver that returns more than one pass is responsible for properly executing the passes on all state and primitive data when rendering.

D3DHAL_VALIDATETEXTURESTAGESTATEDATA

The D3DHAL_VALIDATETEXTURESTAGESTATEDATA structure contains the information required for the driver to determine and return its ability to support multi-texturing using the current state.

typedef struct _D3DHAL_VALIDATETEXTURESTAGESTATEDATA {
  ULONG_PTR  dwhContext;
  DWORD  dwFlags;
  ULONG_PTR  dwReserved;
  DWORD  dwNumPasses;
  HRESULT  ddrval;
} D3DHAL_VALIDATETEXTURESTAGESTATEDATA, FAR *LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA;

Members

dwhContext
Specifies the context ID of the Direct3D device.
dwFlags
Is currently set to zero and should be ignored by the driver.
dwReserved
Is reserved for system use and should be ignored by the driver.
dwNumPasses
Specifies the location where the driver should write the number of passes required by the hardware to perform the blending operations.
ddrval
Specifies the location where the driver writes the return value of D3dValidateTextureStageState. A return code of DD_OK indicates success.

See Also

D3dDrawPrimitives2

Requests that are likely to fail D3dValidateTextureStageState:

  • Using diffuse iterated values as ARGs, or the BLENDDIFFUSE operation is sparsely supported on current hardware. Many parts can introduce only iterated color data at the last texture operation stage.
  • Trying to specify the texture for each stage as its arg1 in preference to arg2.
  • Attempting to use diffuse or scalar values at arbitrary multitexture blending stages. For many cards, these values can be used only at the final texture blending state; for others, only at the first stage.
  • Attempting to do more in the first texture than merely replicate alpha to color channels or invert the input. For many cards, the blending units associated with the first texture are incapable of handling operations more complex than these. The samples below try to use only the second texture’s blending unit, if it is possible to do so. The first unit is presumed to be in its default state in the samples.dev.SetTextureStageState( n, D3DTSS_COLORARG1, D3DTA_TEXTURE ); *
    dev.SetTextureStageState( n, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); *
  • Performing operations for the output alpha that are more intricate than, or substantially different from, the operations specified for the color channels is less likely to be supported.
  • Attempting to use D3DTA_TFACTOR and D3DTA_DIFFUSE simultaneously. Some hardware does not support this.
  • Attempting the simultaneous use of multiple textures and MIP mapped trilinear filtering. Many cards do not support these operations at the same time. If trilinear filtering has been requested for a texture involved in multitexture operations and it fails validation, turn off trilinear and try again. In this case it may be best to do multipass rendering instead.

    Syntax used in the equations describing these operations:

Expression | Meaning
TexN (N = 0, 1, 2) | Texture bound to texture stage N
Ctex | This texture's RGB
Atex | This texture's Alpha
Cin | Current color value RGB (output of previous operation)
Ain | Current color value Alpha (output of previous operation)
Cdif | DIFFUSE color value RGB
Adif | DIFFUSE color value Alpha
Cfact | FACTOR, a scalar value specified at API level RGB
Afact | FACTOR, a scalar value specified at API level Alpha


D3DBuffer Callbacks

The D3DBuffer callbacks are used only if the driver manages driver-level command and vertex buffers.

To support driver-allocated command and vertex buffers, the driver must support the callback functions reported in the DD_D3DBUFCALLBACKS structure, which is exposed through the lpD3DBufCallbacks pointer member of the DD_HALINFO structure.

Each Xxx D3DBuffer callback is analogous to the similarly named Dd Xxx Surface callback; both callbacks have the same prototypes and are called with the same input parameters. The Xxx D3DBuffer callbacks are called only when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the surface caps. The buffer creation flags are DDSCAPS_WRITEONLY, DDSCAPS2_VERTEXBUFFER and DDSCAPS2_COMMANDBUFFER.

To determine the type of buffer being requested, the driver checks the ddsCaps member of the DD_SURFACE_LOCAL structure, which is passed to CanCreateD3DBuffer and CreateD3DBuffer. This value may be one (or neither) of the following flags:

Flag | Meaning
DDSCAPS2_COMMANDBUFFER | The driver should allocate a command buffer.
DDSCAPS2_VERTEXBUFFER | The driver should allocate an Explicit Vertex Buffer.

Note If neither flag is set, the driver should allocate an Implicit Vertex Buffer. Implicit Vertex Buffers should not be placed in video memory since they are expected to be read/write. Only Explicit Vertex Buffers with the DDSCAPS_WRITEONLY flag set can be safely placed in video memory.

The Xxx D3DBuffer callbacks are shown in the following list:

CanCreateD3DBuffer

CreateD3DBuffer

DestroyD3DBuffer

LockD3DBuffer

UnlockD3DBuffer


CanCreateD3DBuffer

CanCreateD3DBuffer determines whether the driver can create a driver-level command or vertex buffer of the specified description.

DWORD
  (APIENTRY *PDD_CANCREATED3DBUFFER)(
    PDD_CANCREATESURFACEDATA  lpCanCreateD3DBuffer
    );

Parameters

lpCanCreateD3DBuffer
Points to a DD_CANCREATESURFACEDATA structure. This structure contains the information required for the driver to determine whether a command or vertex buffer can be created.

Return Value

CanCreateD3DBuffer returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This callback is used only if the driver manages driver-level command and vertex buffers.

CanCreateD3DBuffer should check the surface description that the lpDDSurfaceDesc member of the DD_CANCREATESURFACEDATA structure points to in order to determine whether the driver can support the format and capabilities of the requested buffer for the mode that the driver is currently in. The driver should return DD_OK in the ddRVal member of the same structure if it supports that type of buffer. Otherwise, it should return the DDERR_Xxx error code that best describes why it does not support the buffer.

This call has the same prototype as DdCanCreateSurface. The CanCreateD3DBuffer callback is used, however, when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the ddsCaps member of the DD_SURFACE_LOCAL structure.

The driver determines the type of buffer being requested by checking the ddsCaps member of the DD_SURFACE_LOCAL structure for the following flags:

Flag | Meaning
DDSCAPS2_COMMANDBUFFER | The driver should allocate a command buffer.
DDSCAPS2_VERTEXBUFFER | The driver should allocate an Explicit Vertex Buffer.

Note If neither flag is set, the driver should allocate an Implicit Vertex Buffer. Implicit Vertex Buffers should not be placed in video memory since they are expected to be read/write. Only Explicit Vertex Buffers with the DDSCAPS_WRITEONLY flag set can be safely placed in video memory.

DD_CANCREATESURFACEDATA

The DD_CANCREATESURFACEDATA structure contains information necessary to indicate if a buffer can be created.

typedef struct _DD_CANCREATESURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACEDESC  lpDDSurfaceDesc;
  DWORD  bIsDifferentPixelFormat;
  HRESULT  ddRVal;
  VOID*  CanCreateSurface;
} DDHAL_CANCREATESURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure representing the DirectDraw object.
lpDDSurfaceDesc
Points to a DDSURFACEDESC structure that contains a description of the buffer to be created.
bIsDifferentPixelFormat
Indicates if the pixel format of the buffer to be created differs from that of the primary surface. Since the driver is attempting to create a buffer that contains vertex data or commands, rather than pixel data, this member will always be set to FALSE.
ddRVal
Specifies the location where the driver writes the return value of the CanCreateD3DBuffer callback. A return code of DD_OK indicates success.
CanCreateSurface
Is unused on Windows 2000 and later versions.

Comments

The DirectDraw surface description pointed to by the lpDDSurfaceDesc member is actually a DDSURFACEDESC2 structure (rather than a DDSURFACEDESC structure) for DirectDraw 6.0 and later runtimes. Therefore, if you need information at CanCreateD3DBuffer time from those members that are in the DDSURFACEDESC2 structure but not in the DDSURFACEDESC structure, you can simply cast the pointer to a DDSURFACEDESC structure to a pointer to a DDSURFACEDESC2 structure prior to use. The following example shows how the value of ddsCaps (a DDSCAPS2 in the DDSURFACEDESC2 structure, but a DDSCAPS in the DDSURFACEDESC structure) can be obtained from a pointer to a DDSURFACEDESC structure.

DDSURFACEDESC2* pddsd = (DDSURFACEDESC2*)pccsd->lpDDSurfaceDesc;
DDSCAPS2 ddsCaps = pddsd->ddsCaps;

See Also

CreateD3DBuffer


CreateD3DBuffer

CreateD3DBuffer is used to create a driver-level command or vertex buffer of the specified description.

DWORD
  (APIENTRY *PDD_CREATED3DBUFFER)(
    PDD_CREATESURFACEDATA  lpCreateD3DBuffer
    );

Parameters

lpCreateD3DBuffer
Points to a DD_CREATESURFACEDATA structure that contains the information required to create the buffer.

Return Value

CreateD3DBuffer returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This callback is used only if the driver manages driver-level command and vertex buffers.

If the buffer is created out of system memory instead of video memory, the runtime must be notified by updating lpSurf->lpGbl->dwGlobalFlags with DDRAWISURFGBL_SYSMEMEXECUTEBUFFER.

By default, the driver is not notified when a primary surface is created on Windows 2000 and later versions. However, if the driver supports the GUID_NTPrivateDriverCaps GUID and the DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION flag is set, then the driver will be notified.

The pitch must be returned in the lPitch member of both the DD_SURFACE_GLOBAL and DDSURFACEDESC structures. For linear memory, the driver should set dwBlockSizeX to the size, in bytes, of the memory region and set dwBlockSizeY to 1. Both are members of the DD_SURFACE_GLOBAL structure.

This call has the same prototype as DdCreateSurface. The CreateD3DBuffer callback is used instead when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the surface caps (DD_SURFACE_LOCAL.ddsCaps). The buffer creation flags are DDSCAPS_WRITEONLY, DDSCAPS2_VERTEXBUFFER and DDSCAPS2_COMMANDBUFFER.

The driver determines the type of buffer being requested by checking the ddsCaps member of the DD_SURFACE_LOCAL structure for the following flags:

Flag | Meaning
DDSCAPS2_COMMANDBUFFER | The driver should allocate a command buffer.
DDSCAPS2_VERTEXBUFFER | The driver should allocate an Explicit Vertex Buffer.

Note If neither flag is set, the driver should allocate an Implicit Vertex Buffer. Implicit Vertex Buffers should not be placed in video memory since they are expected to be read/write. Only Explicit Vertex Buffers with the DDSCAPS_WRITEONLY flag set can be safely placed in video memory.

The driver can allocate the buffer memory itself or it can request that DirectDraw perform the memory management. If the driver performs the allocation, it must:

  • Perform the allocation and write a valid pointer to the memory in the fpVidMem member of the DD_SURFACE_GLOBAL structure.

Alternatively, the driver can request that DirectDraw allocate the buffer by returning one of the following values in fpVidMem:

Value | Meaning
DDHAL_PLEASEALLOC_BLOCKSIZE | DirectDraw should allocate the buffer memory from offscreen memory.
DDHAL_PLEASEALLOC_USERMEM | DirectDraw should allocate the buffer memory from user memory. The driver must also return the size, in bytes, of the memory region in dwUserMemSize.

DD_CREATESURFACEDATA

The DD_CREATESURFACEDATA structure contains information necessary to create a command or vertex buffer.

typedef struct _DD_CREATESURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACEDESC  lpDDSurfaceDesc;
  PDD_SURFACE_LOCAL  *lplpSList;
  DWORD  dwSCnt;
  HRESULT  ddRVal;
  VOID*  CreateSurface;
} DD_CREATESURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure representing the driver.
lpDDSurfaceDesc
Points to the DDSURFACEDESC structure describing the buffer that the driver should create.
lplpSList
Points to a list of DD_SURFACE_LOCAL structures describing the surface objects created by the driver. On Windows 2000 and later versions, there is usually only one entry in this array. However, if the driver supports the Windows 98/Me-style surface creation techniques using DdGetDriverInfo with GUID_NTPrivateDriverCaps GUID, and the driver sets the DDHAL_PRIVATECAP_ATOMICSURFACECREATION flag, this member will contain a list of surfaces (usually more than one).
dwSCnt
Specifies the number of surfaces in the list that lplpSList points to. This value is usually 1 on Windows 2000 and later versions. However, if the driver support the Windows 98/Me-style surface creation techniques using DdGetDriverInfo with GUID_NTPrivateDriverCaps, this member will contain the actual number of surfaces in the list (usually more than one).
ddRVal
Specifies the location where the driver writes the return value of the CreateD3DBuffer callback. A return code of DD_OK indicates success.
CreateSurface
Is unused on Windows 2000 and later versions.


DestroyD3DBuffer

DestroyD3DBuffer is used to destroy a driver-level command or vertex buffer.

DWORD
  (APIENTRY *PDD_SURFCB_DESTROYD3DBUFFER)(
    PDD_DESTROYSURFACEDATA  lpDestroyD3DBuffer
    );

Parameters

lpDestroyD3DBuffer
Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a Direct3D command or vertex buffer.

Return Value

DdDestroySurface returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This callback is used only if the driver manages driver-level command and vertex buffers.

If DirectDraw performed the memory allocation at buffer creation time, DestroyD3DBuffer should return DDHAL_DRIVER_NOTHANDLED.

If the driver is performing the buffer memory management itself, DestroyD3DBuffer should free the buffer memory and perform any other cleanup, such as freeing private data stored in the dwReserved1 members of the DD_SURFACE_GLOBAL and DD_SURFACE_LOCAL structures.

This call has the same prototype as DdDestroySurface. The DestroyD3DBuffer callback is used instead when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the surface caps (DD_SURFACE_LOCAL.ddsCaps).

DD_DESTROYSURFACEDATA

The DD_DESTROYSURFACEDATA structure contains information necessary to destroy the specified buffer.

typedef struct _DD_DESTROYSURFACEDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  HRESULT  ddRVal;
  VOID*  DestroySurface;
} DD_DESTROYSURFACEDATA;

Members

lpDD
Points to the DD_DIRECTDRAW_GLOBAL structure that describes the driver.
lpDDSurface
Points to the DD_SURFACE_LOCAL structure representing the buffer object to be destroyed.
ddRVal
Specifies the location where the driver writes the return value of the DestroyD3DBuffer callback. A return code of DD_OK indicates success.
DestroySurface
Is unused on Windows 2000 and later versions.


LockD3DBuffer

LockD3DBuffer is used to lock a specified area of buffer memory and to provide a valid pointer to a block of memory associated with the buffer.

DWORD
  (APIENTRY *PDD_SURFCB_LOCKD3DBUFFER)(
    PDD_LOCKDATA  lpLockD3DBuffer
    );

Parameters

lpLockD3DBuffer
Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.

Return Value

LockD3DBuffer returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This callback is used only if the driver manages driver-level command and vertex buffers.

LockD3DBuffer should set the ddRVal member of DD_LOCKDATA to DDERR_WASSTILLDRAWING and return DDHAL_DRIVER_HANDLED if a blt or flip is in progress.

Unless otherwise specified by the dwFlags member of DD_LOCKDATA, the driver can return a memory pointer to the top of the buffer in the lpSurfData member of DD_LOCKDATA. If the driver must calculate its own address for the buffer, it can rely on the pointer passed in the fpProcess member of DD_LOCKDATA to be a per-process pointer to the user-mode mapping of its DirectDraw-accessible frame buffer.

A lock does not provide exclusive access to the requested memory block. That is, multiple threads can lock the same buffer at the same time. It is the application’s responsibility to synchronize access to the memory block that the pointer is being obtained for.

This call has the same prototype as DdLock. The LockD3DBuffer callback is used instead when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the surface caps (DD_SURFACE_LOCAL.ddsCaps).

If a vertex buffer is being locked and is also being rendered from by the hardware, stall the LockD3DBuffer if you are not renaming (via D3DHALDP2_SWAPVERTEXBUFFER). If you rename, then there is no need to stall.

DD_LOCKDATA

The DD_LOCKDATA structure contains information to do a lock as defined by DirectDraw's parameter structures.

typedef struct _DD_LOCKDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  DWORD  bHasRect;
  RECTL  rArea;
  LPVOID  lpSurfData;
  HRESULT  ddRVal;
  VOID*  Lock;
  DWORD  dwFlags;
  FLATPTR  fpProcess;
} DD_LOCKDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the driver.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that describes the surface associated with the memory region to be locked down.
bHasRect
Specifies whether the area in rArea is valid.
rArea
Specifies a RECTL structure that defines the area in the buffer to lock down.
lpSurfData
Specifies the location where the driver can return a pointer to the memory region that it locked down.
ddRVal
Specifies the location where the driver writes the return value of the LockD3DBuffer callback. A return code of DD_OK indicates success.
Lock
Is unused on Windows 2000 and later versions.
dwFlags
Specifies a bitmask that tells the driver how to perform the memory lockdown. This member is a bitwise OR of any of the following values:
Value | Meaning
DDLOCK_EVENT | This flag is reserved for system use and should be ignored by the driver.
DDLOCK_READONLY | The buffer being locked will only be read from. On Windows 2000 and later versions, this flag is never set.
DDLOCK_SURFACEMEMORYPTR | The driver should return a valid memory pointer to the top of the rectangle specified in rArea. If no rectangle is specified, the driver should return a pointer to the top of the buffer.
DDLOCK_WAIT | This flag is reserved for system use and should be ignored by the driver.
DDLOCK_WRITEONLY | The buffer being locked will only be written to. On Windows 2000 and later versions, this flag is never set.

fpProcess
Points to a user-mode mapping of the driver's memory. The driver performs this mapping in DdMapMemory.

See Also

UnlockD3DBuffer


UnlockD3DBuffer

UnLockD3DBuffer is used to release a lock held on a specified area of driver-managed buffer memory.

DWORD
  (APIENTRY *PDD_SURFCB_UNLOCKD3DBUFFER)(
    PDD_UNLOCKDATA  lpUnlockD3DBuffer
    );

Parameters

lpUnlockD3DBuffer
Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release.

Return Value

DdUnlock returns one of the following callback codes:

DDHAL_DRIVER_HANDLED

DDHAL_DRIVER_NOTHANDLED

Comments

This callback is used only if the driver manages driver-level command and vertex buffers.

The driver does not need to verify that the memory was previously locked down by LockD3DBuffer, because DirectDraw does parameter validation before calling this routine.

This call has the same prototype as DdUnLock. The UnLockD3DBuffer callback is used instead when the surface in question has the DDSCAPS_EXECUTEBUFFER flag set in the surface caps (DD_SURFACE_LOCAL.ddsCaps).

DD_UNLOCKDATA

The DD_UNLOCKDATA structure contains information to do an unlock as defined by DirectDraw parameter structures.

typedef struct _DD_UNLOCKDATA {
  PDD_DIRECTDRAW_GLOBAL  lpDD;
  PDD_SURFACE_LOCAL  lpDDSurface;
  HRESULT  ddRVal;
  VOID*  Unlock;
} DD_UNLOCKDATA;

Members

lpDD
Points to a DD_DIRECTDRAW_GLOBAL structure that describes the driver.
lpDDSurface
Points to a DD_SURFACE_LOCAL structure that describes the buffer to be unlocked.
ddRVal
Specifies the location where the driver writes the return value of the DdUnlock callback. A return code of DD_OK indicates success.
Unlock
Is unused on Windows 2000 and later versions.

See Also

LockD3DBuffer


Direct3D Driver Structures

This section describes the Direct3D® driver structures. It is divided into two main groupings: the first consists of the D3DHAL_Xxx structures defined in d3dnthal.h on Windows® 2000 and later and d3dhal.h on Windows 98/Me; the second grouping consists of the remaining structures, including device description structures, and other Direct3D structures defined in d3dcaps.h and d3dtypes.h. Direct3D DDI Header Files, Sample Code, and References lists the include files that contain Direct3D structure definitions.

Direct3D callbacks and their parameter structures are described in Direct3D Driver Functions. Additional information for writing a Direct3D driver can be found in Direct3D DDI.


D3DNTHAL_Xxx Structures

This table contains all the Direct3D driver structures whose names have the form D3DNTHAL_Xxx. These structures are identical to those whose names have the form D3DHAL_Xxx, which is the form used on Windows 98/Me for DirectX 7.0 and on both Windows 98/Me and Windows 2000 and later for DirectX 8.0 and later versions. The include file dx95type.h contains type defines from D3DNTHAL_Xxx to D3DHAL_Xxx.

D3DNTHAL_Xxx Structure | D3DHAL_Xxx Structure
D3DNTHAL_CALLBACKS | D3DHAL_CALLBACKS
D3DNTHAL_CALLBACKS3 | D3DHAL_CALLBACKS3
D3DNTHAL_CONTEXTCREATEDATA | D3DHAL_CONTEXTCREATEDATA
D3DNTHAL_CONTEXTDESTROYDATA | D3DHAL_CONTEXTDESTROYDATA
D3DNTHAL_D3DEXTENDEDCAPS | D3DHAL_D3DEXTENDEDCAPS
D3DNTHAL_DP2CLEAR | D3DHAL_DP2CLEAR
D3DNTHAL_DP2COMMAND | D3DHAL_DP2COMMAND
D3DNTHAL_DP2CREATELIGHT | D3DHAL_DP2CREATELIGHT
D3DNTHAL_DP2EXT | D3DHAL_DP2EXT
D3DNTHAL_DP2INDEXEDLINELIST | D3DHAL_DP2INDEXEDLINELIST
D3DNTHAL_DP2INDEXEDLINESTRIP | D3DHAL_DP2INDEXEDLINESTRIP
D3DNTHAL_DP2INDEXEDTRIANGLEFAN | D3DHAL_DP2INDEXEDTRIANGLEFAN
D3DNTHAL_DP2INDEXEDTRIANGLELIST | D3DHAL_DP2INDEXEDTRIANGLELIST
D3DNTHAL_DP2INDEXEDTRIANGLELIST2 | D3DHAL_DP2INDEXEDTRIANGLELIST2
D3DNTHAL_DP2INDEXEDTRIANGLESTRIP | D3DHAL_DP2INDEXEDTRIANGLESTRIP
D3DNTHAL_DP2LINELIST | D3DHAL_DP2LINELIST
D3DNTHAL_DP2LINESTRIP | D3DHAL_DP2LINESTRIP
D3DNTHAL_DP2POINTS | D3DHAL_DP2POINTS
D3DNTHAL_DP2RENDERSTATE | D3DHAL_DP2RENDERSTATE
D3DNTHAL_DP2SETCLIPPLANE | D3DHAL_DP2SETCLIPPLANE
D3DNTHAL_DP2SETLIGHT | D3DHAL_DP2SETLIGHT
D3DNTHAL_DP2SETPALETTE | D3DHAL_DP2SETPALETTE
D3DNTHAL_DP2SETPRIORITY | D3DHAL_DP2SETPRIORITY
D3DNTHAL_DP2SETRENDERTARGET | D3DHAL_DP2SETRENDERTARGET
D3DNTHAL_DP2SETTEXLOD | D3DHAL_DP2SETTEXLOD
D3DNTHAL_DP2SETTRANSFORM | D3DHAL_DP2SETTRANSFORM
D3DNTHAL_DP2STARTVERTEX | D3DHAL_DP2STARTVERTEX
D3DNTHAL_DP2STATESET | D3DHAL_DP2STATESET
D3DNTHAL_DP2TEXBLT | D3DHAL_DP2TEXBLT
D3DNTHAL_DP2TEXTURESTAGESTATE | D3DHAL_DP2TEXTURESTAGESTATE
D3DNTHAL_DP2TRIANGLEFAN | D3DHAL_DP2TRIANGLEFAN
D3DNTHAL_DP2TRIANGLEFAN_IMM | D3DHAL_DP2TRIANGLEFAN_IMM
D3DNTHAL_DP2TRIANGLELIST | D3DHAL_DP2TRIANGLELIST
D3DNTHAL_DP2TRIANGLESTRIP | D3DHAL_DP2TRIANGLESTRIP
D3DNTHAL_DP2UPDATEPALETTE | D3DHAL_DP2UPDATEPALETTE
D3DNTHAL_DP2VIEWPORTINFO | D3DHAL_DP2VIEWPORTINFO
D3DNTHAL_DP2WINFO | D3DHAL_DP2WINFO
D3DNTHAL_DP2ZRANGE | D3DHAL_DP2ZRANGE
D3DNTHAL_DRAWPRIMITIVES2DATA | D3DHAL_DRAWPRIMITIVES2DATA
D3DNTHAL_GLOBALDRIVERDATA | D3DHAL_GLOBALDRIVERDATA
D3DNTHAL_VALIDATETEXTURESTAGESTATEDATA | D3DHAL_VALIDATETEXTURESTAGESTATEDATA
D3DNTHALDEVICEDESC_V1 | D3DDEVICEDESC_V1


D3DHAL_Xxx Structures

This section contains all the Direct3D driver structures whose names have the form D3DHAL_Xxx.


D3DHAL_CALLBACKS

D3DHAL_CALLBACKS is one of several callback structures that describe the Direct3D support provided by the driver.

typedef struct _D3DHAL_CALLBACKS {
    DWORD                           dwSize;
    // Device context
    LPD3DHAL_CONTEXTCREATECB        ContextCreate;
    LPD3DHAL_CONTEXTDESTROYCB       ContextDestroy;
    LPD3DHAL_CONTEXTDESTROYALLCB    ContextDestroyAll;
    // Scene Capture
    LPD3DHAL_SCENECAPTURECB         SceneCapture;
    // Execution
    LPVOID                          dwReserved10;
    LPVOID                          dwReserved11;
    LPVOID                          dwReserved22;
    LPVOID                          dwReserved23;
    ULONG_PTR                       dwReserved;
    // Textures
    LPD3DHAL_TEXTURECREATECB        TextureCreate;
    LPD3DHAL_TEXTUREDESTROYCB       TextureDestroy;
    LPD3DHAL_TEXTURESWAPCB          TextureSwap;
    LPD3DHAL_TEXTUREGETSURFCB       TextureGetSurf;
    LPVOID                          dwReserved12;
    LPVOID                          dwReserved13;
    LPVOID                          dwReserved14;
    LPVOID                          dwReserved15;
    LPVOID                          dwReserved16;
    LPVOID                          dwReserved17;
    LPVOID                          dwReserved18;
    LPVOID                          dwReserved19;
    LPVOID                          dwReserved20;
    LPVOID                          dwReserved21;
    // Pipeline state
    LPVOID                          dwReserved24;
    ULONG_PTR                       dwReserved0;
    ULONG_PTR                       dwReserved1;
    ULONG_PTR                       dwReserved2;
    ULONG_PTR                       dwReserved3;
    ULONG_PTR                       dwReserved4;
    ULONG_PTR                       dwReserved5;
    ULONG_PTR                       dwReserved6;
    ULONG_PTR                       dwReserved7;
    ULONG_PTR                       dwReserved8;
    ULONG_PTR                       dwReserved9;
} D3DHAL_CALLBACKS, *LPD3DHAL_CALLBACKS;

Members

dwSize
Specifies the size in bytes of this D3DHAL_CALLBACKS structure.
ContextCreate
Points to the driver-supplied D3dContextCreate callback. A driver must implement the callback that this member points to.
ContextDestroy
Points to the driver-supplied D3dContextDestroy callback. A driver must implement the callback that this member points to.
ContextDestroyAll
Must be set to NULL in a Windows 2000 and later driver.
SceneCapture
Must be set to NULL in a Windows 2000 and later driver. This was a pointer to the driver-supplied D3dSceneCapture callback that was replaced by the D3DRENDERSTATE_SCENECAPTURE render state. This render state is handled in D3dDrawPrimitives2.
dwReserved10, dwReserved11, dwReserved22, dwReserved23, dwReserved
Are reserved and must be set to zero.
TextureCreate
Must be set to NULL in a Windows 2000 and later driver. This was a pointer to the driver-supplied D3dTextureCreate callback, or NULL.
TextureDestroy
Must be set to NULL in a Windows 2000 and later driver. This was a pointer to the driver-supplied D3dTextureDestroy callback, or NULL.
TextureSwap
Must be set to NULL in a Windows 2000 and later driver. This was a pointer to the driver-supplied D3dTextureSwap callback, or NULL.
TextureGetSurf
Must be set to NULL in a Windows 2000 and later driver. This was a pointer to the driver-supplied D3dTextureGetSurf callback, or NULL.
dwReserved12-dwReserved21, dwReserved24, dwReserved0-dwReserved9
Are reserved and must be set to zero.

Comments

The driver allocates this structure and sets appropriate values in all members. The driver's DrvGetDirectDrawInfo function returns a pointer to this structure in the lpD3DHALCallbacks member of the DD_HALINFO structure.

Texture management is now handled though opcodes that are managed in the driver's implementation of D3dDrawPrimitives2.

See Also

D3DHAL_CALLBACKS3, DdGetDriverInfo, DrvGetDirectDrawInfo


D3DHAL_CALLBACKS3

D3DHAL_CALLBACKS3 is one of several callback structures that describe the Direct3D support provided by the driver.

typedef struct _D3DHAL_CALLBACKS3 {
    DWORD                                   dwSize;
    DWORD                                   dwFlags;
    LPD3DHAL_CLEAR2CB                       Clear2;
    LPVOID                                  lpvReserved;
    LPD3DHAL_VALIDATETEXTURESTAGESTATECB    ValidateTextureStageState;
    LPD3DHAL_DRAWPRIMITIVES2CB              DrawPrimitives2;
} D3DHAL_CALLBACKS3, *LPD3DHAL_CALLBACKS3;

Members

dwSize
Specifies the size in bytes of this structure.
dwFlags
Indicates the callbacks associated with this structure that the driver has implemented. For every bit the driver sets in dwFlags, the driver must initialize the corresponding function pointer member of this structure. This member can be the bitwise-OR of one or more of the following flags:
Flag | Meaning
D3DHAL3_CB32_CLEAR2 | Not used in DirectX® 7.0 and later versions.
D3DHAL3_CB32_DRAWPRIMITIVES2 | The DrawPrimitives2 member points to a driver-implemented D3dDrawPrimitives2 callback.
D3DHAL3_CB32_RESERVED | Not used in DirectX® 7.0 and later versions.
D3DHAL3_CB32_VALIDATETEXTURESTAGESTATE | The ValidateTextureStageState member points to a driver-implemented D3dValidateTextureStageState callback.

Clear2
Must be set to NULL. This was a pointer to the driver-supplied D3dClear2 callback that is no longer used for DirectX® 7.0 and beyond. Instead the driver should respond to the D3DDP2OP_CLEAR command stream token in its implementation of D3dDrawPrimitives2.
lpvReserved
Must be set to NULL in a Windows 2000 and later driver.
ValidateTextureStageState
Points to the driver-supplied D3dValidateTextureStageState callback, or NULL. Drivers that support multi-texturing must implement the callback that this member points to.
DrawPrimitives2
Points to the driver-supplied D3dDrawPrimitives2 callback. A driver must implement the callback that this member points to.

Comments

The driver allocates this structure and sets appropriate values in all members. The driver's DdGetDriverInfo function returns a pointer to this structure when that function is called with the GUID_D3DCallbacks3 GUID.

See Also

D3DHAL_CALLBACKS, DdGetDriverInfo


D3DHAL_CLIPPEDTRIANGLEFAN

DirectX 8.0 and later versions only.

One or more D3DHAL_CLIPPEDTRIANGLEFAN structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_CLIPPEDTRIANGLEFAN, and are used to render clipped triangle fans.

typedef struct _D3DHAL_CLIPPEDTRIANGLEFAN
{
    DWORD FirstVertexOffset;       // Offset in bytes in the
                                   // current stream 0
    DWORD dwEdgeFlags;
    DWORD PrimitiveCount;
} D3DHAL_CLIPPEDTRIANGLEFAN, *LPD3DHAL_CLIPPEDTRIANGLEFAN;

Members

FirstVertexOffset
Specifies the byte offset into stream 0 of the start of the vertex data (not the index of the vertex).
dwEdgeFlags
Specifies what edges are to be drawn when rendering wire frame (to prevent the drawing of edges introduced by clipping).
PrimitiveCount
Specifies the number of triangles in the given triangle fan.


D3DHAL_D3DEXTENDEDCAPS

D3DHAL_D3DEXTENDEDCAPS describes additional 3D capabilities of the driver.

typedef struct _D3DHAL_D3DEXTENDEDCAPS {
    DWORD     dwSize;
    DWORD     dwMinTextureWidth;
    DWORD     dwMaxTextureWidth;
    DWORD     dwMinTextureHeight;
    DWORD     dwMaxTextureHeight;
    DWORD     dwMinStippleWidth;
    DWORD     dwMaxStippleWidth;
    DWORD     dwMinStippleHeight;
    DWORD     dwMaxStippleHeight;
    DWORD     dwMaxTextureRepeat;
    DWORD     dwMaxTextureAspectRatio;
    DWORD     dwMaxAnisotropy;
    D3DVALUE  dvGuardBandLeft;
    D3DVALUE  dvGuardBandTop;
    D3DVALUE  dvGuardBandRight;
    D3DVALUE  dvGuardBandBottom;
    D3DVALUE  dvExtentsAdjust;
    DWORD     dwStencilCaps;
    DWORD     dwFVFCaps;
    DWORD     dwTextureOpCaps;
    WORD      wMaxTextureBlendStages;
    WORD      wMaxSimultaneousTextures;
    DWORD     dwMaxActiveLights;
    D3DVALUE  dvMaxVertexW;
    WORD      wMaxUserClipPlanes;
    WORD      wMaxVertexBlendMatrices;
    DWORD     dwVertexProcessingCaps;
    DWORD     dwReserved1;
    DWORD     dwReserved2;
    DWORD     dwReserved3;
    DWORD     dwReserved4;
    DWORD     dwReserved5;
} D3DHAL_D3DEXTENDEDCAPS;

Members

dwSize
Specifies the size in bytes of this D3DHAL_D3DEXTENDEDCAPS structure.
dwMinTextureWidth, dwMaxTextureWidth
Specify the minimum and maximum texture widths supported by the driver or device. These fields are provided as hints to the application, and it is the application's responsibility to adjust texture sizes when necessary.
dwMinTextureHeight, dwMaxTextureHeight
Specify the minimum and maximum texture heights supported by the driver.
dwMinStippleWidth, dwMaxStippleWidth
Specify the minimum and maximum stipple widths supported by the driver.
dwMinStippleHeight, dwMaxStippleHeight
Specify the minimum and maximum stipple heights supported by the driver.
dwMaxTextureRepeat
Specifies the full range of integer (non-fractional) bits of the post-normalized texture indexes. If the D3DDEVCAPS_TEXREPEATNOTSCALEDBYSIZE bit is set, then the number of times a texture can be wrapped is specified by this member. If the D3DDEVCAPS_TEXREPEATNOTSCALEDBYSIZE bit is not set, then the number of time a texture can be wrapped is given by the expression: dwMaxTextureRepeat * (texture size).
dwMaxTextureAspectRatio
Specifies the maximum texture aspect ratio supported by the hardware. This member is typically a power of 2.
dwMaxAnisotropy
Specifies the maximum valid value for the D3DRENDERSTATE_ANISOTROPY render state.
dvGuardBandLeft, dvGuardBandTop, dvGuardBandRight, dvGuardBandBottom
Specify the screen-space coordinates of the guard-band clipping region. The upper-left corner of this rectangle has coordinates (dvGuardBandLeft, dvGuardBandTop). The lower-left corner has coordinates (dvGuardBandRight, dvGuardBandBottom). Coordinates inside this rectangle but outside the viewport rectangle will automatically be clipped.
dvExtentsAdjust
Specifies the number of pixels required to adjust the extents rectangle outward to accommodate antialiasing kernels.
dwStencilCaps
Are flags that specify the stencil buffer operations supported by the driver or device. For further descriptions of the stencil buffer operations shown in the following table, see D3DSTENCILOP in the DirectX SDK documentation. Stencil operations are assumed to be valid for all three stencil buffer operation render states (D3DRENDERSTATE_STENCILFAIL, D3DRENDERSTATE_STENCILPASS, and D3DRENDERSTATE_STENCILZFAIL). This member can be a bitwise OR of any of the following values:
Value | Stencil Buffer Operation
D3DSTENCILCAPS_DECR | The D3DSTENCILOP_DECR operation is supported.
D3DSTENCILCAPS_DECRSAT | The D3DSTENCILOP_DECRSAT operation is supported.
D3DSTENCILCAPS_INCR | The D3DSTENCILOP_INCR operation is supported.
D3DSTENCILCAPS_INCRSAT | The D3DSTENCILOP_INCRSAT operation is supported.
D3DSTENCILCAPS_INVERT | The D3DSTENCILOP_INVERT operation is supported.
D3DSTENCILCAPS_KEEP | The D3DSTENCILOP_KEEP operation is supported.
D3DSTENCILCAPS_REPLACE | The D3DSTENCILOP_REPLACE operation is supported.
D3DSTENCILCAPS_ZERO | The D3DSTENCILOP_ZERO operation is supported.

dwFVFCaps
Specifies the number of texture coordinates that the driver can process. This value can be an integer in the range 0 through 8, where 0 indicates that the driver does not support texturing, 1 indicates that the driver can process only one set of texture coordinates, 2 indicates that the driver can process two sets of texture coordinates, and so on.

A driver must be able to parse all texture coordinates present in the vertex data regardless of the number of texture coordinates that the driver actually uses. The driver should use the index provided with the D3DTSS_TEXCOORDINDEX value of the D3DTEXTURESTAGESTATETYPE enumeration, described in the DirectX SDK documentation, to determine what texture coordinate set to use when rendering.

dwTextureOpCaps
Specify the texture operations supported by the device. See D3DTEXTUREOP in the DirectX SDK documentation for descriptions of the texture operations listed in the following table. This member can be a bitwise OR of the following values:
Value | Texture Operation Supported
D3DTEXOPCAPS_ADD | The D3DTOP_ADD texture blending operation is supported by this device.
D3DTEXOPCAPS_ADDSIGNED | The D3DTOP_ADDSIGNED texture blending operation is supported by this device.
D3DTEXOPCAPS_ADDSIGNED2X | The D3DTOP_ADDSIGNED2X texture blending operation is supported by this device.
D3DTEXOPCAPS_ADDSMOOTH | The D3DTOP_ADDSMOOTH texture blending operation is supported by this device.
D3DTEXOPCAPS_BLENDCURRENTALPHA | The D3DTOP_BLENDCURRENTALPHA texture blending operation is supported by this device.
D3DTEXOPCAPS_BLENDDIFFUSEALPHA | The D3DTOP_BLENDDIFFUSEALPHA texture blending operation is supported by this device.
D3DTEXOPCAPS_BLENDFACTORALPHA | The D3DTOP_BLENDFACTORALPHA texture blending operation is supported by this device.
D3DTEXOPCAPS_BLENDTEXTUREALPHA | The D3DTOP_BLENDTEXTUREALPHA texture blending operation is supported by this device.
D3DTEXOPCAPS_BLENDTEXTUREALPHAPM | The D3DTOP_BLENDTEXTUREALPHAPM texture blending operation is supported by this device.
D3DTEXOPCAPS_BUMPENVMAP. | The D3DTOP_BUMPENVMAP texture blending operation is supported by this device.
D3DTEXOPCAPS_BUMPENVMAPLUMINANCE | The D3DTOP_BUMPENVMAPLUMINANCE texture blending operation is supported by this device.
D3DTEXOPCAPS_DISABLE | The D3DTOP_DISABLE texture blending operation is supported by this device.
D3DTEXOPCAPS_DOTPRODUCT3 | The D3DTOP_DOTPRODUCT3 texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATE | The D3DTOP_MODULATE texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATE2X | The D3DTOP_MODULATE2X texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATE4X | The D3DTOP_MODULATE4X texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | The D3DTOP_MODULATEALPHA_ADDCOLOR texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | The D3DTOP_MODULATEALPHA_ADDCOLOR texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR | The D3DTOP_MODULATEINVALPHA_ADDCOLOR texture blending operation is supported by this device.
D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA | The D3DTOP_MODULATEINVCOLOR_ADDALPHA texture blending operation is supported by this device.
D3DTEXOPCAPS_PREMODULATE | The D3DTOP_PREMODULATE texture blending operation is supported by this device.
D3DTEXOPCAPS_SELECTARG1 | The D3DTOP_SELECTARG1 texture blending operation is supported by this device.
D3DTEXOPCAPS_SELECTARG2 | The D3DTOP_SELECTARG2 texture blending operation is supported by this device.
D3DTEXOPCAPS_SUBTRACT | The D3DTOP_SUBTRACT texture blending operation is supported by this device.

wMaxTextureBlendStages
Specifies the maximum number of texture blending stages supported by this device.
wMaxSimultaneousTextures
Specifies the maximum number of textures that can be simultaneously bound to the texture blending stages for this device. That is, wMaxSimultaneousTextures specifies how many of the texture stages can have textures bound to them through the lDirect3DDevice7::SetTexture method. See the Platform SDK documentation for more information about this method.
dwMaxActiveLights
Specifies the maximum number of active lights supported by this device. This only needs to be specified in drivers that support hardware transform and lighting (and therefore specify D3DDEVCAPS_HWTRANSFORMANDLIGHT in their device caps).
dvMaxVertexW
Specifies the maximum W range supported by this device. This only needs to be specified in drivers that support W buffering (and therefore specify D3DPRASTERCAPS_WBUFFER in their rasterization caps).
wMaxUserClipPlanes;
Specifies the maximum number of user-defined clip planes supported.
wMaxVertexBlendMatrices
Specifies the number of world matrices supported for vertex blending.
dwVertexProcessingCaps
Specifies the vertex processing caps supported.
dwReserved1, dwReserved2, dwReserved3, dwReserved4, dwReserved5
Reserved for system use.

Comments

The driver allocates and zero-initializes this structure and sets appropriate values in the members it supports. The driver's DdGetDriverInfo function returns a pointer to this structure when that function is called with the GUID_D3DExtendedCaps GUID.

When the driver fills in this structure, it can set values for execute buffer capabilities even when the interface being used to retrieve the capabilities (such as lDirect3DDevice3) doesn't support execute buffers.


D3DHAL_DP2BUFFERBLT

DirectX 8.0 and later versions only.

D3DHAL_DP2BUFFERBLT is used for vertex or index buffer blts when D3dDrawPrimitives2 responds to the D3DDP2OP_BUFFERBLT command token.

typedef struct _D3DHAL_DP2BUFFERBLT
{
  DWORD   dwDDDestSurface; // dest surface
  DWORD   dwDDSrcSurface;  // src surface
  DWORD   dwOffset;        // offset in the dest surface (in BYTES)
  D3DRANGE rSrc;           // src surface range (contains UINT Offset
                           // and UINT Size)
  DWORD   dwFlags;         // blt flags
} D3DHAL_DP2BUFFERBLT, *LPD3DHAL_DP2BUFFERBLT;

Members

dwDDDestSurface
Specifies the handle to the destination vertex or index buffer.
dwDDSrcSurface
Specifies the handle to the source vertex or index buffer.
dwOffset
Specifies the part of the destination buffer the copy should be directed into.
rSrc
Specifies what range of the source buffer should be copied.
dwFlags
Is currently unused.

Comments

The CreateD3DBuffer callback creates the small integer handles to the vertex or index buffers that can be used as source and destination buffers for buffer blts.

See Comments for D3DHAL_DP2TEXBLT.

See Also

D3dDrawPrimitives2, D3DHAL_DP2COMMAND


D3DHAL_DP2CLEAR

D3DHAL_DP2CLEAR contains all of the information that the driver needs to perform hardware-assisted clearing on the rendering target, depth buffer or stencil buffer.

typedef struct _D3DHAL_DP2CLEAR {
    DWORD     dwFlags;
    DWORD     dwFillColor;
    D3DVALUE  dvFillDepth;
    DWORD     dwFillStencil;
    RECT      Rects[1];
} D3DHAL_DP2CLEAR, *LPD3DHAL_DP2CLEAR;

Members

dwFlags
Specifies what buffer(s) the driver should clear. This member can be a bitwise OR of the following values:
Value | Meaning
D3DCLEAR_TARGET | The driver should clear the context's render target to the color specified by the dwFillColor member.
D3DCLEAR_STENCIL | The driver should clear the context's stencil buffer to the value specified by the dwFillStencil member.
D3DCLEAR_ZBUFFER | The driver should clear the context's depth buffer to the depth specified by the dwFillDepth member.
D3DCLEAR_COMPUTERECTS DirectX 8.0 and later versions only.

If this flag is set, the specified rectangles should be clipped against the current viewport. Furthermore, it is possible that when D3DCLEAR_COMPUTERECTS is specified the number of rectangles to clear can be zero (the number of rectangles to clear can be found in the wStateCount/wPrimtiveCount union of the D3DHAL_DP2COMMAND structure for the clear). In this case the entire viewport should be cleared.

dwFillColor
Specifies the color that the driver should clear the context's render target to.
dvFillDepth
Specifies the value that the driver should use to set the depth in the context's depth buffer. This member can be a value in the interval 0.0 to 1.0. The driver should convert this value to an integer using the dwZBitMask member of the depth buffer's DDPIXELFORMAT structure.
dwFillStencil
Specifies the value that the driver should clear the context's stencil buffer to. This member can be an integer in the interval 0 to 2n-1, where n is the number of bits in the stencil buffer.
Rects
Specifies the rectangular areas of the buffer that the driver should clear. The rectangles are specified in screen coordinates. This member of the structure contains the first rectangle area to be blitted. The wStateCount member of the D3DHAL_DP2COMMAND contains the total number of rectangle areas to be blitted. The other (wStateCount-1) RECT structures required will follow the D3DHAL_DP2CLEAR structure without any padding.

Comments

This structure is used with the D3DDP2OP_CLEAR command token to replace the legacy D3dClear and D3dClear2 callbacks.

It is important to note that when the number of rectangles is zero, the D3DHAL_DP2CLEAR data structure still includes space for a single RECT. Thus, the size of this single RECT should be included when advancing to the next DP2 instruction. However, the contents of the RECT in this case are undefined and the driver should not attempt to read them.


D3DHAL_DP2COMMAND

One or more D3DHAL_DP2COMMAND structures are parsed from the command buffer by the D3dDrawPrimitives2 callback, which uses the information it receives to draw one or more primitives. Each structure specifies either a primitive to draw or a state change to process.

typedef struct _D3DHAL_DP2COMMAND {
    BYTE  bCommand;
    BYTE  bReserved;
    union
    {
        WORD  wPrimitiveCount;
        WORD  wStateCount;
    };
} D3DHAL_DP2COMMAND, *LPD3DHAL_DP2COMMAND;

Members

bCommand
Specifies a primitive to draw or a state change to process. This member can be one of the D3DHAL_DP2OPERATION enumerated values.
bReserved
Is reserved for system use and should be ignored by the driver.
wPrimitiveCount
Specifies the number of primitives to process. This member is valid when bCommand is not either of D3DDP2OP_RENDERSTATE or D3DDP2OP_TEXTURESTAGESTATE.
wStateCount
Specifies the number of state changes to process. This member is valid when bCommand is one of D3DDP2OP_RENDERSTATE or D3DDP2OP_TEXTURESTAGESTATE.


D3DHAL_DP2CREATELIGHT

The D3DHAL_DP2CREATELIGHT structure is used to create a light for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2CREATELIGHT {
    DWORD  dwIndex;
} D3DHAL_DP2CREATELIGHT, *LPD3DHAL_DP2CREATELIGHT;

Member

dwIndex
Specifies the index of the light being created.

Comments

The D3DHAL_DP2CREATELIGHT structure is used to hold the index into the light array. The driver should enlarge its light array as necessary to accommodate at least as many lights as specified by the index.


D3DHAL_DP2CREATEPIXELSHADER

DirectX 8.0 and later versions only.

The D3DHAL_DP2CREATEPIXELSHADER structure is used to create a pixel shader when a D3DDP2OP_CREATEPIXELSHADER opcode is received by D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2CREATEPIXELSHADER
{
    DWORD dwHandle;     // Shader handle
    DWORD dwCodeSize;   // Shader code size in bytes
    // Shader code follows
} D3DHAL_DP2CREATEPIXELSHADER, *LPD3DHAL_DP2CREATEPIXELSHADER;

Member

dwHandle
Specifies the handle assigned by the runtime. This value is guaranteed to be non-zero.
dwCodeSize
Specifies the size, in bytes, of the shader code following this data structure in the DP2 stream.

Comments

The runtime generates a handle for this shader before calling the driver. The shader code itself follows the D3DHAL_DP2CREATEPIXELSHADER in the DP2 stream.

Before calling the driver, the runtime validates the pixel shader code to ensure that it is legal for the specified shader language version.

It is important to note that the creation of a pixel shader does not imply the setting of the current shader.

See Also

D3DHAL_DP2PIXELSHADER


D3DHAL_DP2CREATEVERTEXSHADER

DirectX 8.0 and later versions only.

The D3DHAL_DP2CREATEVERTEXSHADER structure is used to create a vertex shader when a D3DDP2OP_CREATEVERTEXSHADER opcode is received by D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2CREATEVERTEXSHADER
{
    DWORD dwHandle;     // Shader handle
    DWORD dwDeclSize;   // Shader declaration size in bytes
    DWORD dwCodeSize;   // Shader code size in bytes
    // Declaration follows
    // Shader code follows
} D3DHAL_DP2CREATEVERTEXSHADER, *LPD3DHAL_DP2CREATEVERTEXSHADER;

Member

dwHandle
Specifies the handle assigned by the runtime. This value is guaranteed to be non-zero. Furthermore, although vertex FVF codes are part of the shader handle name space it is guaranteed that the handle passed will not be an FVF code.
dwDeclSize
Specifies the shader declaration size in bytes.
dwCodeSize
Specifies the shader code size in bytes.

Comments

Before invoking the driver, the runtime performs validation to ensure that the specified shader is legal for the specified shader language version. The runtime flushes all pending state and rendering when this token is to be sent to the driver. Thus, processing of this token is assumed to be synchronous with the runtime and the driver reports failure of the creation request by failing the D3dDrawPrimitives2 DDI call. Thus, the driver should validate the given shader declaration and code on receipt of this token and report success of failure accordingly.

See Also

D3DHAL_DP2VERTEXSHADER


D3DHAL_DP2DRAWINDEXEDPRIMITIVE

DirectX 8.0 and later versions only.

D3DHAL_DRAWINDEXEDPRIMITIVE is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_DRAWINDEXEDPRIMITIVE, and is used to render a primitive using vertex indices.

typedef struct _D3DHAL_DP2DRAWINDEXEDPRIMITIVE
{
    D3DPRIMITIVETYPE primType;
    DWORD BaseVertexIndex;   // Vertex that corresponds to index 0
    DWORD MinIndex;          // Min vertex index in the vertex buffer
    DWORD NumVertices;       // Number of vertices starting from
                             // MinIndex
    DWORD StartIndex;        // Start index in the index buffer
    DWORD PrimitiveCount;
} D3DHAL_DP2DRAWINDEXEDPRIMITIVE, *LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE;

Members

primType
Specifies the type of primitive to draw (one of D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP or D3DPT_TRIANGLEFAN).
BaseVertexIndex
Specifies the amount that should be added to each index referenced by the various primitives to determine the actual index of the vertex elements in each vertex stream.
MinIndex
Specifies the minimum index of a range of vertices that are potentially accessed by the primitives to be drawn and, therefore, which vertices should be processed.
NumVertices
Specifies the number of vertices in a range that are potentially accessed by the primitives to be drawn and, therefore, which vertices should be processed.
StartIndex
Specifies the first index in the index buffer from which indices are read to draw the primitives.
PrimitiveCount
Specifies the number of triangles, lines or points to draw for the given primitive.

Comments

The vertex data can be untransformed (if the hardware supports hardware vertex processing) or transformed if the application supplied data in that form to the runtime.

As with vertices, the actual indices to use are not passed with the token data, but rather should be read from the currently selected index buffer. See Index Buffers for more details.

See Also

D3DHAL_DP2DRAWINDEXEDPRIMITIVE2


D3DHAL_DP2DRAWINDEXEDPRIMITIVE2

DirectX 8.0 and later versions only.

D3DHAL_DRAWINDEXEDPRIMITIVE2 is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_DRAWINDEXEDPRIMITIVE2, and is used to render a primitive using vertex indices.

typedef struct _D3DHAL_DP2DRAWINDEXEDPRIMITIVE2
{
    D3DPRIMITIVETYPE primType;
    INT   BaseVertexOffset;  // Stream 0 offset of the vertex that
                             // corresponds to index 0. This
                             // offset could be negative, but when
                             // an index is added to the offset
                             // the result is positive
    DWORD MinIndex;          // Min vertex index in the vertex buffer
    DWORD NumVertices;       // Number of vertices starting from
                             // MinIndex
    DWORD StartIndexOffset;  // Offset of the start index in the
                             // index buffer
    DWORD PrimitiveCount;    // Number of triangles (points, lines)
} D3DHAL_DP2DRAWINDEXEDPRIMITIVE2, *LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE2;

Members

primType
Specifies the type of primitive to draw (one of D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP or D3DPT_TRIANGLEFAN).
BaseVertexOffset
Specifies the offset that should be added to each vertex in vertex stream 0 by the various primitives to determine the actual vertex in vertex stream 0.
MinIndex
Specifies the minimum index of a range of vertices that are potentially accessed by the primitives to be drawn and, therefore, which vertices should be processed.
NumVertices
Specifies the number of vertices in a range that are potentially accessed by the primitives to be drawn and, therefore, which vertices should be processed.
StartIndexOffset
Specifies the offset of the first index in the index buffer from which indices are read to draw the primitives.
PrimitiveCount
Specifies the number of triangles, lines or points to draw for the given primitive.

Comments

The vertex data has been transformed by the runtime.

As with vertices, the actual indices to use are not passed with the token data, but rather should be read from the currently selected index buffer. See Index Buffers for more details.

See Also

D3DHAL_DP2DRAWINDEXEDPRIMITIVE


D3DHAL_DP2DRAWPRIMITIVE

DirectX 8.0 and later versions only.

D3DHAL_DRAWPRIMITIVE is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_DRAWPRIMITIVE, and is used to render a primitive.

typedef struct _D3DHAL_DP2DRAWPRIMITIVE
{
    D3DPRIMITIVETYPE    primType;
    DWORD               VStart;
    DWORD               PrimitiveCount;
} D3DHAL_DP2DRAWPRIMITIVE, *LPD3DHAL_DP2DRAWPRIMITIVE;

Members

primType
Specifies the type of primitive to draw (one of D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP or D3DPT_TRIANGLEFAN).
VStart
Specifies the index (into each active vertex stream) of the vertex elements with which to start drawing. Actual vertex data should be read from the current vertex streams (those referenced by the current vertex shader) rather than from the vertex data pointer in D3DHAL_DRAWPRIMITIVES2DATA.
PrimitiveCount
Specifies the number of triangles, lines or points to draw for the given primitive.

Comments

The vertex data can be untransformed (if the hardware supports hardware vertex processing) or transformed if the application supplied data in that form to the runtime.


D3DHAL_DP2DRAWPRIMITIVE2

DirectX 8.0 and later versions only.

D3DHAL_DRAWPRIMITIVE2 is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_DRAWPRIMITIVE2, and is used to render a primitive.

typedef struct _D3DHAL_DP2DRAWPRIMITIVE2
{
    D3DPRIMITIVETYPE primType;
    DWORD FirstVertexOffset;       // Offset in bytes in the stream 0
    DWORD PrimitiveCount;
} D3DHAL_DP2DRAWPRIMITIVE2, *LPD3DHAL_DP2DRAWPRIMITIVE2;

Members

primType
Specifies the type of primitive to draw (one of D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP or D3DPT_TRIANGLEFAN).
FirstVertexOffset
Specifies the offset, in bytes, in stream zero of the vertex data. This is in contrast to D3DDP2OP_DRAWPRIMITIVE where the start of the vertex data in the vertex stream is specified by a vertex index rather than an actual byte offset.
PrimitiveCount
Specifies the number of triangles, lines or points to draw for the given primitive.

Comments

The vertex data has been transformed by the runtime.

See Also

D3DHAL_DP2DRAWPRIMITIVE


D3DHAL_DP2DRAWRECTPATCH

DirectX 8.0 and later versions only.

D3DHAL_DRAWRECTPATCH is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_DRAWRECTPATCH, and is used to render a rectangular patch.

typedef struct _D3DHAL_DP2DRAWRECTPATCH
{
    DWORD Handle;
    DWORD Flags;
    // Optionally followed by D3DFLOAT[4] NumSegments
    // and/or D3DRECTPATCH_INFO
} D3DHAL_DP2DRAWRECTPATCH, *LPD3DHAL_DP2DRAWRECTPATCH;

Members

Handle
Specifies the handle associated with the surface.
Flags
Specifies what, if any, additional information follows the D3DHAL_DP2DRAWRECTPATCH data structure in the DP2 stream.

Comments

Handle is used to associate the surface with a handle, so that the next time this surface is drawn, there is no need to re-specify the D3DRECTPATCH_INFO for this patch. This makes it possible for the driver to pre-compute and cache forward difference coefficients and/or any other information, which in turn allows subsequent D3DDP2OP_DRAWRECTPATCH tokens using the same handle to execute more efficiently.

The actual value of Handle is determined by the application and is not under runtime control. Therefore, the driver should be prepared to cope with any value specifiable by a DWORD. The special handle value of zero means that the patch is dynamic and there is no point pre-computing or caching information for this patch. A non-zero value for Handle means the patch is static (or updated with low frequency) and pre-computation and caching are possible.

The Flags is used to communicate what, if any, additional information follows the D3DHAL_DP2DRAWRECTPATCH data structure in the DP2 stream. If RTPATCHFLAG_HASSEGS is specified then four floating point values follow D3DHAL_DP2DRAWRECTPATCH in the DP2 stream. These floats give the segment counts for each of the four edges of the rectangular patch and override the value of the render state D3DRS_PATCHSEGMENTS. If RTPATCHFLAG_HASINFO is specified then a D3DRECTPATCH_INFO data structure follows in the DP2 stream. Information on this structure can be found in the DirectX 8.0 SDK documentation. If both flags are specified the four floats specifying segment counts follow D3DHAL_DP2DRAWRECTPATCH and the D3DRECTPATCH_INFO structure follows the floating point values.

There are four scenarios a driver must handle when processing D3DDP2OP_DRAWRECTPATCH.

If Handle is zero then the patch is dynamic and no pre-computation or caching should be performed. In this case a D3DRECTPATCH_INFO will follow D3DHAL_DP2DRAWRECTPATCH in the DP2 stream (and the flag RTPATCHFLAG_HASINFO will be set to indicate the presence of the D3DHAL_DP2DRAWRECTPATCH data structure). Optionally, RTPATCHFLAG_HASSEGS may also be set to indicate the presence of the segment information. However, if this is omitted the value of the render state D3DRS_PATCHSEGMENTS should be used instead.

If Handle is non-zero and the handle value has not been specified by an earlier D3DDP2OP_DRAWRECTPATCH this indicates that a new cacheable patch is being drawn. The driver should allocate memory to store cached data and add this data to its patch handle table. As this patch has not been seen before the RTPATCHFLAG_HASINFO flags should be set and a D3DRECTPATCH_INFO flag should follow in the DP2 stream. The runtime does not guarantee this, however, and the driver should verify the presence of the patch information by testing the flag. If no information is specified this token should be ignored and no handle should be allocated in the driver’s patch handle table. Optionally, RTPATCHFLAG_HASSEGS may also be set to indicate the presence of the segment information. However, if this is omitted the value of the render state D3DRS_PATCHSEGMENTS should be used instead.

If Handle is non-zero, the handle value has been specified by an earlier D3DDP2OP_DRAWRECTPATCH token and the Flags field contains RTPATCHFLAG_HASINFO then the definition for the patch is being updated. A D3DRECTPATCH_INFO data structure will follow in the DP2 stream and the driver should use that to re-compute and re-cache patch information. Optionally, RTPATCHFLAG_HASSEGS may also be set to indicate the presence of the segment information. However, if this is omitted the value of the render state D3DRS_PATCHSEGMENTS should be used instead.

If Handle is non-zero, the handle value has been specified by an earlier D3DDP2OP_DRAWRECTPATCH token and the Flags field does not contain RTPATCHFLAG_HASINFO then the cached information should be used for drawing the patch. In this case the current vertex streams are ignored, the cached information should be used instead. However, it is still possible in this case for a new segment information to be specified. Therefore, the driver should check for the flag RTPATCHFLAG_HASSEGS and handle specified segment information even if using a cached patch.

The driver receives notification that cached patch information is be released via the render state D3DRS_DELETERTPATCH. The value of this render state is the patch to be deleted.

See Also

D3DHAL_DP2DRAWTRIPATCH


D3DHAL_DP2DRAWTRIPATCH

DirectX 8.0 and later versions only.

D3DHAL_DRAWTRIPATCH is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_DRAWTRIPATCH, and is used to render a triangular patch.

typedef struct _D3DHAL_DP2DRAWTRIPATCH
{
    DWORD Handle;
    DWORD Flags;
    // Optionally followed by D3DFLOAT[3] NumSegments
    // and/or D3DTRIPATCH_INFO
} D3DHAL_DP2DRAWTRIPATCH, *LPD3DHAL_DP2DRAWTRIPATCH;

Members

Handle
Specifies the handle associated with the surface.
Flags
Specifies what, if any, additional information follows the D3DHAL_DP2DRAWTRIPATCH data structure in the DP2 stream.

Comments

Handle is used to associate the surface with a handle, so that the next time this surface is drawn there is no need to re-specify the D3DTRIPATCH_INFO for this patch. This makes it possible for the driver to pre-compute and cache forward difference coefficients and/or any other information, which in turn allows subsequent D3DDP2OP_DRAWTRIPATCH tokens using the same handle to execute more efficiently.

The actual value of Handle is determined by the application and is not under runtime control. Therefore, the driver should be prepared to cope with any value specifiable by a DWORD. The special handle value of zero means that the patch is dynamic and there is no point pre-computing or caching information for this patch. A non-zero value for Handle means the patch is static (or updated with low frequency) and pre-computation and caching are possible.

The Flags is used to communicate what, if any, additional information follows the D3DHAL_DP2DRAWTRIPATCH data structure in the DP2 stream. If RTPATCHFLAG_HASSEGS is specified then three floating point values follow D3DHAL_DP2DRAWTRIPATCH in the DP2 stream. These floats give the segment counts for each of the three edges of the triangular patch and override the value of the render state D3DRS_PATCHSEGMENTS. If RTPATCHFLAG_HASINFO is specified then a D3DTRIPATCH_INFO data structure follows in the DP2 stream. Information on this structure can be found in the DirectX 8.0 SDK documentation. If both flags are specified the three floats specifying segment counts follow D3DHAL_DP2DRAWTRIPATCH and the D3DTRIPATCH_INFO structure follows the floating point values.

There are four scenarios a driver must handle when processing D3DDP2OP_DRAWTRIPATCH.

If Handle is zero then the patch is dynamic and no pre-computation or caching should be performed. In this case a D3DTRIPATCH_INFO will follow D3DHAL_DP2DRAWTRIPATCH in the DP2 stream (and the flag RTPATCHFLAG_HASINFO will be set to indicate the presence of the D3DHAL_DP2DRAWTRIPATCH data structure). Optionally, RTPATCHFLAG_HASSEGS may also be set to indicate the presence of the segment information. However, if this is omitted the value of the render state D3DRS_PATCHSEGMENTS should be used instead.

If Handle is non-zero and the handle value has not been specified by an earlier D3DDP2OP_DRAWTRIPATCH this indicates that a new cacheable patch is being drawn. The driver should allocate memory to store cached data and add this data to its patch handle table. As this patch has not been seen before the RTPATCHFLAG_HASINFO flags should be set and a D3DTRIPATCH_INFO flag should follow in the DP2 stream. The runtime does not guarantee this, however, and the driver should verify the presence of the patch information by testing the flag. If no information is specified this token should be ignored and no handle should be allocated in the driver’s patch handle table. Optionally, RTPATCHFLAG_HASSEGS may also be set to indicate the presence of the segment information. However, if this is omitted the value of the render state D3DRS_PATCHSEGMENTS should be used instead.

If Handle is non-zero, the handle value has been specified by an earlier D3DDP2OP_DRAWTRIPATCH token and the Flags field contains RTPATCHFLAG_HASINFO then the definition for the patch is being updated. A D3DTRIPATCH_INFO data structure will follow in the DP2 stream and the driver should use that to re-compute and re-cache patch information. Optionally, RTPATCHFLAG_HASSEGS may also be set to indicate the presence of the segment information. However, if this is omitted the value of the render state D3DRS_PATCHSEGMENTS should be used instead.

If Handle is non-zero, the handle value has been specified by an earlier D3DDP2OP_DRAWTRIPATCH token and the Flags field does not contain RTPATCHFLAG_HASINFO then the cached information should be used for drawing the patch. In this case the current vertex streams are ignored, the cached information should be used instead. However, it is still possible in this case for a new segment information to be specified. Therefore, the driver should check for the flag RTPATCHFLAG_HASSEGS and handle specified segment information even if using a cached patch.

The driver receives notification that cached patch information is be released via the render state D3DRS_DELETERTPATCH. The value of this render state is the patch to be deleted.

See Also

D3DHAL_DP2DRAWRECTPATCH


D3DHAL_DP2EXT

The D3DHAL_DP2EXT structure's use has yet to be defined.

typedef struct _D3DHAL_DP2EXT {
    DWORD  dwExtToken;
    DWORD  dwSize;
} D3DHAL_DP2EXT, *LPD3DHAL_DP2EXT;
‹ ›

Members

dwExtToken
Is the extension token.
dwSize
Specifies the size, in bytes of this structure.

Comments

This structure is used with hardware transform and lighting and will be explained further in future documentation releases. Contact the DirectX team at Microsoft if you need further implementation details now.


D3DHAL_DP2INDEXEDLINELIST

D3DHAL_DP2INDEXEDLINELIST is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_INDEXEDLINELIST, and is used to render the lines using vertex indices.

typedef struct _D3DHAL_DP2INDEXEDLINELIST {
    WORD  wV1;
    WORD  wV2;
} D3DHAL_DP2INDEXEDLINELIST;

Members

wV1
Specifies the index into the vertex buffer, identifying the first endpoint of the line.
wV2
Specifies the index into the vertex buffer, identifying the second endpoint of the line.

Comments

D3dDrawPrimitives2 should process (wPrimitiveCount * 2) indexes from the command buffer, in effect processing wPrimitiveCount D3DHAL_DP2INDEXEDLINELIST structures. The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The driver should process a total of (wPrimitiveCount * 2) vertices from the vertex buffer, two vertices per line. The sequence of lines rendered is (wV10, wV20), (wV11, wV21), …, (wV1n, wV2n), where n equals (wPrimitiveCount - 1). The driver should interpret the vertex buffer indexes based on the current command as follows:

  • When the command is D3DDP2OP_INDEXEDLINELIST, the vertex buffer indexes are relative to the vertex buffer offset specified by the dwVertexOffset member of the D3DHAL_DRAWPRIMITIVES2DATA structure.
  • When the command is D3DDP2OP_INDEXEDLINELIST2, a D3DHAL_DP2STARTVERTEX structure immediately follows it and precedes the D3DHAL_DP2INDEXEDLINELIST structure(s) in the command buffer. The vertex buffer indexes are relative to the vertex buffer offset specified by dwVertexOffset plus the base offset obtained from the wVStart member of the D3DHAL_DP2STARTVERTEX structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDLINELIST command and two D3DHAL_DP2INDEXEDLINELIST structures. The driver should draw two lines using the following four vertices from the vertex buffer: (v[0], v[4]), (v[5], v[6]).

Similarly, the following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDLINELIST2 command, a D3DHAL_DP2STARTVERTEX offset, and two D3DHAL_DP2INDEXEDLINELIST structures. The driver should process four vertices from the vertex buffer, rendering two lines defined by (v[3], v[7]), (v[8], v[9]).


D3DHAL_DP2INDEXEDLINESTRIP

D3DHAL_DP2INDEXEDLINESTRIP is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_INDEXEDLINESTRIP, and is used to render a sequence of connected line segments using vertex indices.

typedef struct _D3DHAL_DP2INDEXEDLINESTRIP {
    WORD  wV[2];
} D3DHAL_DP2INDEXEDLINESTRIP;

Members

wV
Specifies the indexes into the vertex buffer from which the driver obtains coordinate data for the vertices making up the line strip.

Although this member has only enough space to hold two indexes, this array of indexes should be treated as a variable-sized array with (wPrimitiveCount + 1) elements. (wPrimitiveCount is a member of the D3DHAL_DP2COMMAND structure.)

Comments

Indexed line strips rendered with vertex buffers are specified using D3DHAL_DP2INDEXEDLINESTRIP. The number of line segments to process is specified by the wPrimitiveCount member of D3DHAL_DP2COMMAND. The sequence of line segments rendered will be: (wV[0], wV[1]), (wV[1], wV[2]), (wV[2], wV[3]), ..., (wVStart[wPrimitiveCount-1], wVStart[wPrimitiveCount]).

D3dDrawPrimitives2 should process (wPrimitiveCount+1) indexes from the command buffer, in effect processing wPrimitiveCount D3DHAL_DP2INDEXEDLINESTRIP structures. The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

A D3DHAL_DP2STARTVERTEX structure immediately follows the command in the command buffer. The vertex buffer indexes are relative to the vertex buffer offset specified by the dwVertexOffset member of the D3DHAL_DRAWPRIMITIVES2DATA structure plus the base offset obtained from the wVStart member of the D3DHAL_DP2STARTVERTEX structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDLINESTRIP command, a D3DHAL_DP2STARTVERTEX offset, and a list of D3DHAL_DP2INDEXEDLINESTRIP structures. The driver should process four vertices from the vertex buffer, rendering three connected line segments defined by (v[8], v[4]), (v[4], v[7]), (v[7], v[6]).


D3DHAL_DP2INDEXEDTRIANGLEFAN

D3DHAL_DP2INDEXEDTRIANGLEFAN is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_INDEXEDTRIANGLEFAN, and is used to render a sequence of connected triangles using vertex indices. All of the triangles share a common vertex.

typedef struct _D3DHAL_DP2INDEXEDTRIANGLEFAN {
    WORD wV[3];
} D3DHAL_DP2INDEXEDTRIANGLEFAN;

Members

wV
Specifies the indexes into the vertex buffer from which the driver obtains coordinate data for the vertices making up the triangle fan.

Although this member has only enough space to contain three indexes, this array of indexes should be treated as a variable-sized array with (wPrimitiveCount + 2) elements. (wPrimitiveCount is a member of the D3DHAL_DP2COMMAND structure.)

Comments

D3dDrawPrimitives2 should process (wPrimitiveCount+2) indexes from the command buffer, in effect, processing wPrimitiveCount D3DHAL_DP2INDEXEDTRIANGLEFAN structures. The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The driver should process a total of (wPrimitiveCount+2) vertices from the vertex buffer, three vertices per triangle. The sequence of triangles rendered is: (wV[1], wV[2], wV[0]), (wV[2], wV[3], wV[0]), (wV[3], wV[4], wV[0]), …, (wV[wPrimitiveCount], wV[wPrimitiveCount+1], wV[0]). Notice that all of the triangles have the vertex specified in wV[0] in common.

A D3DHAL_DP2STARTVERTEX structure immediately follows the command in the command buffer. The vertex buffer indexes are relative to the vertex buffer offset specified by the dwVertexOffset member of the D3DHAL_DRAWPRIMITIVES2DATA structure plus the base offset obtained from the wVStart member of the D3DHAL_DP2STARTVERTEX structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDTRIANGLEFAN command, a D3DHAL_DP2STARTVERTEX offset, and a logical list of D3DHAL_DP2INDEXEDTRIANGLEFAN structures. The driver should process five vertices from the vertex buffer, rendering a fan with three triangles defined by (v[4], v[5], v[7]), (v[5], v[6], v[7]), (v[6], v[9], v[7]).


D3DHAL_DP2INDEXEDTRIANGLELIST

One or more D3DHAL_DP2INDEXEDTRIANGLELIST structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_INDEXEDTRIANGLELIST, and are used to render a sequence of unconnected triangles using vertex indices.

typedef struct _D3DHAL_DP2INDEXEDTRIANGLELIST {
    WORD  wV1;
    WORD  wV2;
    WORD  wV3;
    WORD  wFlags;
} D3DHAL_DP2INDEXEDTRIANGLELIST;

Members

wV1
Specifies the index into the vertex buffer location containing coordinate data for the first vertex of the triangle.
wV2
Specifies the index to the vertex buffer location containing coordinate data for the second vertex of the triangle.
wV3
Specifies the index to the vertex buffer location containing coordinate data for the third vertex of the triangle.
wFlags
Are the flags that describe how the driver should render the triangle. This member can be a bitwise OR of the following values:
Flag | Meaning
D3DTRIFLAG_EDGEENABLE1 | The driver should render the triangle edge between wV1 and wV2 when the fill mode is D3DFILL_WIREFRAME.
D3DTRIFLAG_EDGEENABLE2 | The driver should render the triangle edge between wV2 and wV3 when the fill mode is D3DFILL_WIREFRAME.
D3DTRIFLAG_EDGEENABLE3 | The driver should render the triangle edge between wV3 and wV1 when the fill mode is D3DFILL_WIREFRAME.
D3DTRIFLAG_EDGEENABLETRIANGLE | The driver should render all triangle edges when the fill mode is D3DFILL_WIREFRAME.

Comments

D3dDrawPrimitives2 should process wPrimitiveCount*3 indexes from the command buffer, processing wPrimitiveCount D3DHAL_DP2INDEXEDTRIANGLELIST structures. The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The driver should process a total of wPrimitiveCount*3 vertices from the vertex buffer, three vertices per triangle, for the current command. The sequence of triangles rendered is (wV10, wV20, wV30), (wV11, wV21, wV31), …, (wV1n, wV2n, wV3n), where n equals (wPrimitiveCount - 1). The driver should calculate the vertex locations based on the current command as follows:

  • When the command is D3DDP2OP_INDEXEDTRIANGLELIST, the indexes into the vertex buffer are relative to the vertex buffer offset specified by the dwVertexOffset member of the D3DHAL_DRAWPRIMITIVES2DATA structure.
  • When the command is D3DDP2OP_INDEXEDTRIANGLELIST2, there is a D3DHAL_DP2STARTVERTEX structure that immediately follows the command in the command buffer. The indexes into the vertex buffer are relative to the vertex buffer offset specified by dwVertexOffset plus the base offset obtained from the wVStart member of the D3DHAL_DP2STARTVERTEX structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDTRIANGLELIST command and two D3DHAL_DP2INDEXEDTRIANGLELIST structures. The driver should draw two triangles – with all edges enabled – using the following six vertices from the vertex buffer: (v[3], v[4], v[5]), (v[0], v[1], v[2]).

Similarly, the following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDTRIANGLELIST2 command, a D3DHAL_DP2STARTVERTEX offset, and two D3DHAL_DP2INDEXEDTRIANGLELIST structures. The driver should process six vertices from the vertex buffer, rendering two triangles defined by (v[5], v[6], v[7]), (v[2], v[3], v[4]).


D3DHAL_DP2INDEXEDTRIANGLELIST2

One or more D3DHAL_DP2INDEXEDTRIANGLELIST2 structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_INDEXEDTRIANGLELIST2, and are used to render a sequence of unconnected triangles using vertex indices.

typedef struct _D3DHAL_DP2INDEXEDTRIANGLELIST2 {
    WORD  wV1;
    WORD  wV2;
    WORD  wV3;
} D3DHAL_DP2INDEXEDTRIANGLELIST2, *LPD3DHAL_DP2INDEXEDTRIANGLELIST2;

Members

wV1
Specifies the index to the vertex buffer location containing coordinate data for the first vertex of the triangle.
wV2
Specifies the index to the vertex buffer location containing coordinate data for the second vertex of the triangle.
wV3
Specifies the index to the vertex buffer location containing coordinate data for the third vertex of the triangle.

Comments

The D3DHAL_DP2INDEXEDTRIANGLELIST2 structure specifies unconnected triangles to render with a vertex buffer. The vertex indexes are specified by wV1, wV2, and wV3. All edges are visible. The number of triangles to render (that is, the number of D3DHAL_DP2INDEXEDTRIANGLELIST2 structures to process) is specified by the wPrimitiveCount field of D3DHAL_DP2COMMAND. All indexes are relative to a vertex whose index is wVStart from D3DHAL_DP2STARTVERTEX. The sequence in the command stream is D3DHAL_DP2COMMAND followed by D3DHAL_DP2STARTVERTEX followed by wPrimitiveCount D3DHAL_DP2INDEXEDTRIANGLELIST2 structures.

The D3dDrawPrimitives2 callback parses D3DHAL_DP2INDEXEDTRIANGLELIST2 structure(s) from the command buffer and renders the triangles using vertex indexes when D3DHAL_DP2COMMAND is D3DDP2OP_INDEXEDTRIANGLELIST2. A D3DHAL_DP2STARTVERTEX structure immediately follows the D3DHAL_DP2COMMAND in the command stream. This allows a base index to be specified for all the indexes that follow it. Thus triangles can be easily relocated and no flags are necessary to specify the triangle edges as is the case with D3DDP2OP_INDEXEDTRIANGLELIST.


D3DHAL_DP2INDEXEDTRIANGLESTRIP

One or more D3DHAL_DP2INDEXEDTRIANGLESTRIP structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_INDEXEDTRIANGLESTRIP, and are used to render strips of connected triangles using vertex indices.

typedef struct _D3DHAL_DP2INDEXEDTRIANGLESTRIP {
    WORD  wV[3];
} D3DHAL_DP2INDEXEDTRIANGLESTRIP;

Members

wV
Specifies the index into the vertex buffer containing coordinate data for the first vertex of the triangle strip.

Although this member has only enough space to contain three indexes, this array of indexes should be treated as a variable-sized array with (wPrimitiveCount + 2) elements. (wPrimitiveCount is a member of the D3DHAL_DP2COMMAND structure.)

Comments

D3dDrawPrimitives2 should process (wPrimitiveCount+2) indexes from the command buffer, in effect, processing wPrimitiveCount D3DHAL_DP2INDEXEDTRIANGLESTRIP structures.

The triangle edges in a triangle strip are rendered in this order: (wV[0], wV[1], wV[2]), (wV[1], wV[3], wV[2]), (wV[2], wV[3], wV[4]), (wV[3], wV[5], wV[4]),...

For the last triangle in the triangle strip, however, the edges will be rendered in different orders when wPrimitiveCount is odd and when it is even.

  • When wPrimitiveCount is an odd number, the last triangle's edges are rendered in this order: (wV[wPrimitiveCount - 1], wV[wPrimitiveCount], wV[wPrimitiveCount + 1]).
  • When wPrimitiveCount is an even number, the last triangle's edges are rendered in this order: (wV[wPrimitiveCount - 1], wV[wPrimitiveCount+1], wV[wPrimitiveCount]).

A D3DHAL_DP2STARTVERTEX structure immediately follows the command in the command buffer. The vertex buffer indexes are relative to the vertex buffer offset specified by the dwVertexOffset member of the D3DHAL_DRAWPRIMITIVES2DATA structure plus the base offset obtained from the wVStart member of the D3DHAL_DP2STARTVERTEX structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_INDEXEDTRIANGLESTRIP command, a D3DHAL_DP2STARTVERTEX offset of zero, and a logical list of D3DHAL_DP2INDEXEDTRIANGLESTRIP structures. The driver should process five vertices from the vertex buffer, rendering a strip of three triangles defined by (v[1], v[3], v[6]), (v[3], v[4], v[6]), (v[6], v[4], v[5]).


D3DHAL_DP2LINELIST

One D3DHAL_DP2LINELIST structure is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_LINELIST, and is used to render unconnected line segments.

typedef struct _D3DHAL_DP2LINELIST {
    WORD  wVStart;
} D3DHAL_DP2LINELIST;

Members

wVStart
Specifies the index into the vertex buffer containing coordinate data for the initial vertex of the line list.

Comments

One D3DHAL_DP2LINELIST structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

D3dDrawPrimitives2 should sequentially process a total of wPrimitiveCount*2 vertices from the vertex buffer, two vertices per line, rendering a total of wPrimitiveCount lines. Starting from the vertex buffer offset, the sequence of lines rendered is (wVStart, wVStart+1), (wVStart+2, wVStart+3),…, (wVStart+(wPrimitiveCount-1)*2, wVStart+(wPrimitiveCount*2-1)). The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_LINELIST command and one D3DHAL_DP2LINELIST structure. The driver should draw three lines using the following six vertices from the vertex buffer: (v[0], v[1]), (v[2], v[3]), (v[4], v[5]).


D3DHAL_DP2LINESTRIP

One D3DHAL_DP2LINESTRIP structure is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_LINESTRIP, and is used to render the specified connected line segments.

typedef struct _D3DHAL_DP2LINESTRIP {
    WORD  wVStart;
} D3DHAL_DP2LINESTRIP;

Members

wVStart
Specifies the index into the vertex buffer containing coordinate data for the initial vertex of the line strip.

Comments

One D3DHAL_DP2LINESTRIP structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

D3dDrawPrimitives2 should sequentially process a total of (wPrimitiveCount+1) vertices from the vertex buffer. Starting from the vertex buffer offset, the sequence of lines rendered is (wVStart, wVStart+1), (wVStart+1, wVStart+2), (wVStart+2, wVStart+3), …, (wVStart+(wPrimitiveCount-1), wVStart+wPrimitiveCount). The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_LINESTRIP command and one D3DHAL_DP2LINESTRIP structure. The driver should draw three connected lines using the following four vertices from the vertex buffer: (v[4], v[5]), (v[5], v[6]), (v[6], v[7]).


D3DHAL_DP2MULTIPLYTRANSFORM

DirectX 8.0 and later versions only.

The D3DHAL_DP2MULTIPLYTRANSFORM structure is used to modify the transform matrix for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2MULTIPLYTRANSFORM
{
    D3DTRANSFORMSTATETYPE xfrmType;  // which transform to multiply
    D3DMATRIX matrix;                // the matrix to multiply by
} D3DHAL_DP2MULTIPLYTRANSFORM, *LPD3DHAL_DP2MULTIPLYTRANSFORM;

Members

xfrmType
Specifies the current transform being modified.
Value | Meaning
D3DTRANSFORMSTATE_PROJECTION | Specifies the current projection transformation.
D3DTRANSFORMSTATE_VIEW | Specifies the current view transformation.
D3DTRANSFORMSTATE_WORLD | Specifies the current world transformation.

matrix
Specifies the matrix used to modify the current transform.

Comments

This structure is used with hardware transform and lighting and is used by the Direct3D run-time to inform the driver about modifications to the various transformation matrices.

See Also

D3DHAL_DP2SETTRANSFORM


D3DHAL_DP2PIXELSHADER

DirectX 8.0 and later versions only.

The D3DHAL_DP2PIXELSHADER structure is used to set the current pixel shader, or delete a pixel shader, depending on the opcode received (D3DDP2OP_SETPIXELSHADER or D3DDP2OP_DELETEPIXELSHADER) by D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2PIXELSHADER
{
    // Pixel shader handle.
    // The handle could be 0, meaning that the current pixel
    // shader is invalid (not set).
    DWORD dwHandle;
} D3DHAL_DP2PIXELSHADER, *LPD3DHAL_DP2PIXELSHADER;

Member

dwHandle
Specifies the handle assigned by the runtime to the pixel shader to set or delete. For delete, the handle is guaranteed to be non-zero. For set, It is legal for this handle to be zero in which case the driver should unset any programmable pixel state and revert to fixed function pixel processing behavior (for example by using render states).

Comments

When switching from fixed function pixel processing to programmable vertex processing the values of, for example, legacy render states and texture stage states should be preserved. If and when a switch from programmable to fixed function pixel processing occurs (the driver receives a D3DDP2OP_SETPIXELSHADER with a shader handle of zero) that preserved state should be restored.

When switching between programmable shaders, any constant register that has a value specified in the definition of that shader should be set to that value. The values of all other constant registers should remain unchanged.

See Also

D3DHAL_DP2SETPIXELSHADERCONST, D3DHAL_DP2CREATEPIXELSHADER


D3DHAL_DP2POINTS

One or more D3DHAL_DP2POINTS structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_POINTS, and are used to render the specified points.

typedef struct _D3DHAL_DP2POINTS {
    WORD  wCount;
    WORD  wVStart;
} D3DHAL_DP2POINTS;

Members

wCount
Specifies the number of points to render.
wVStart
Specifies the index into the vertex buffer containing coordinate data for the initial point.

Comments

D3dDrawPrimitives2 should process wPrimitiveCount D3DHAL_DP2POINTS structures from the command buffer. The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

For each D3DHAL_DP2POINTS structure, D3dDrawPrimitives2 should sequentially process wCount vertices from the vertex buffer. Starting from the vertex buffer offset, the sequence of points rendered is wVStart, (wVStart+1), …, (wvStart+(wCount-1)).

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_POINTS command and two D3DHAL_DP2POINTS structures. The driver should draw a total of seven points using the following vertices from the vertex buffer: v[2], v[3], v[4], v[7], v[8], v[9], v[10].


D3DHAL_DP2RENDERSTATE

One or more D3DHAL_DP2RENDERSTATE structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_RENDERSTATE, and are used to set the appropriate render state.

typedef struct _D3DHAL_DP2RENDERSTATE {
    D3DRENDERSTATETYPE  RenderState;
    union
    {
        D3DVALUE  fState;
        DWORD  dwState;
    };
} D3DHAL_DP2RENDERSTATE;
‹ ›

Members

RenderState
Specifies a D3DRENDERSTATETYPE enumerated value that specifies the render state to be updated. The render states are described in the DirectX SDK documentation.
fState
Specifies the value that the driver should update the render state identified by the RenderState member with. This member is valid when RenderState requires a D3DVALUE.
dwState
Specifies the value that the driver should update the render state identified by RenderState to. This member is valid when RenderState requires a DWORD.

Comments

D3dDrawPrimitives2 should process wStateCount D3DHAL_DP2RENDERSTATE structures from the command buffer. The value of wStateCount is specified in the D3DHAL_DP2COMMAND structure.

For each D3DHAL_DP2RENDERSTATE structure, D3dDrawPrimitives2 should update the driver's private render state and the render state array that the lpdwRStates member of D3DHAL_DRAWPRIMITIVES2DATA points to. The element to be updated in the public render state array is lpdwRStates[RenderState].

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_RENDERSTATE command and two D3DHAL_DP2RENDERSTATE structures. The driver should update lpdwRStates[D3DRENDERSTATE_FILLMODE] to be D3DFILL_SOLID and lpdwRStates[D3DRENDERSTATE_SHADEMODE] to be D3DSHADE_GOURAUD. The driver should also update its private state accordingly.

Although render states whose values are boolean in type are documented as only accepting TRUE(1) and FALSE(0) the runtime does not validate this and accepts any non-zero value as true. The sample driver interprets this strictly and does interpret values other than 1 as being TRUE. However, as the runtime does not offer validation your driver should interpret 0 as FALSE and any other non-zero value as TRUE. In this respect your driver should not mimic the behavior of the supplied sample driver.


D3DHAL_DP2SETCLIPPLANE

The D3DHAL_SETCLIPPLANE structure allows user defined clip planes to be used in world space.

typedef struct _D3DHAL_DP2SETCLIPPLANE {
    DWORD     dwIndex;
    D3DVALUE  plane[4];
} D3DHAL_DP2SETCLIPPLANE, *LPD3DHAL_DP2SETCLIPPLANE;
‹ ›

Members

dwIndex
Is the index of the clipping plane for which the plane equation coefficients will be set.
plane
Is a four-element array of the coefficients A, B, C, and D, in that order, in the general plane equation for the clipping plane.

Comments

The general plane equation in standard form is Ax + By + Cz + Dw = 0. A point with homogeneous coordinates (x, y, z, w) is visible in the half-space of this plane if Ax + By + Cz + Dw >= 0. Points that exist on or behind the clipping plane are clipped from the scene. That is, points for which Ax + By + Cz + Dw <= 0 are clipped.


D3DHAL_DP2SETINDICES

DirectX 8.0 and later versions only.

The D3DHAL_DP2SETINDICES structure is used to set the current index buffer for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETINDICES
{
    DWORD dwVBHandle;   // Index buffer handle
    DWORD dwStride;     // Index size in bytes (2 or 4)
} D3DHAL_DP2SETINDICES, *LPD3DHAL_DP2SETINDICES;

Member

dwVBHandle
Specifies the surface handle associated with this surface through a call to D3dCreateSurfaceEx.
dwStride
Specifies the size of the indices contained in the index buffer and will have the value 2 if the indices are 16-bit, or 4 if the indices are 32-bit quantities.

Comments

A handle value of zero is valid and indicates that the current index buffer is cleared. Subsequent attempts to draw indexed primitives (before a new current index buffer is established via another D3DDP2OP_SETINDICES token) should be handled by the driver such that a crash does not occur. The debug version of your driver should display informative messages to the debug output stream when this error condition is detected.


D3DHAL_DP2SETLIGHT

The D3DHAL_DP2SETLIGHT structure allows lights to be set for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETLIGHT {
    DWORD  dwIndex;
    DWORD  dwDataType;
} D3DHAL_DP2SETLIGHT, *LPD3DHAL_DP2SETLIGHT;
‹ ›

Members

dwIndex
Specifies an index into an array of lights.
dwDataType
Specifies the type of data being passed.
Value | Meaning
D3DHAL_SETLIGHT_DATA | Specifies that a D3DLIGHT7 (described in the Platform SDK documentation) structure defining the light will follow immediately in the command stream.
D3DHAL_SETLIGHT_ENABLE | Enables the light whose index is specified in dwIndex.
D3DHAL_SETLIGHT_DISABLE | Disables the light whose index is specified in dwIndex.


D3DHAL_DP2SETPALETTE

The D3DHAL_DP2SETPALETTE structure is used to associate a palette with a texture when a driver responds to D3DDP2OP_SETPALETTE in D3dDrawPrimitives2. This opcode is used to map an association between a palette handle and a surface handle, and specify the characteristics of the palette.

typedef struct _D3DHAL_DP2SETPALETTE {
    DWORD  dwPaletteHandle;
    DWORD  dwPaletteFlags;
    DWORD  dwSurfaceHandle;
} D3DHAL_DP2SETPALETTE, *LPD3DHAL_DP2SETPALETTE;
‹ ›

Members

dwPaletteHandle
Specifies a handle to the palette to be set up. If the value is zero, the surface specified by dwSurfaceHandle should be uncoupled from any palette it might have been associated with previously.
dwPaletteFlags
Is a set of flags that specify the attributes of the palette.
Flag | Meaning
DDRAWIPAL_2 | The palette has 2 entries. Currently unused.
DDRAWIPAL_4 | The palette has 4 entries. Currently unused.
DDRAWIPAL_16 | The palette has 16 entries. Currently unused.
DDRAWIPAL_256 | The palette has 256 entries. Currently unused.
DDRAWIPAL_ALLOW256 | The palette can be fully updated. Currently unused.
DDRAWIPAL_ALPHA | The palette's alpha data channel is valid and should be used.
DDRAWIPAL_DIRTY | The palette has been changed so the GDI palette is out of sync. Currently unused.
DDRAWIPAL_EXCLUSIVE | The palette is being used in exclusive mode. Currently unused.
DDRAWIPAL_GDI | The palette is allocated through GDI. Currently unused.
DDRAWIPAL_INHEL | The palette is done in the HEL (hardware emulation layer). Currently unused.
DDRAWIPAL_STORED_8 | The palette is stored using 8 bpp per entry. Currently unused.
DDRAWIPAL_STORED_16 | The palette is stored using 16 bpp per entry. Currently unused.
DDRAWIPAL_STORED_24 | The palette is stored using 24 bpp per entry. Currently unused.
DDRAWIPAL_STORED_8INDEX | The palette is stored as an 8-bit index into a destination palette. Currently unused.

dwSurfaceHandle
Specifies a handle to the Direct3D surface (texture) that this palette (identified by dwPaletteHandle) is associated to.

Comments

The number of D3DHAL_DP2SETPALETTE structures to follow is specified by the wStateCount member of the D3DHAL_DP2COMMAND structure that precedes them in the command stream.


D3DHAL_DP2SETPIXELSHADERCONST

DirectX 8.0 and later versions only.

The D3DHAL_DP2SETPIXELSHADERCONST structure is used to set one or more of the pixel shader constant registers when the D3DDP2OP_SETPIXELSHADERCONST opcode is received by D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETPIXELSHADERCONST
{
    DWORD dwRegister;   // Const register to start copying
    DWORD dwCount;      // Number of 4-float vectors to copy
    // Data follows
} D3DHAL_DP2SETPIXELSHADERCONST, *LPD3DHAL_DP2SETPIXELSHADERCONST;

Member

dwRegister
Specifies the index of the first register to set.
dwCount
Specifies gives the number of registers to set. Immediately following this data structure in the DP2 stream are dwCount vectors of four single precision floating point numbers. This is the data to copy to the target registers.

Comments

The runtime passes the first register to set and the number of registers to set. The actual data to copy to those registers consists of vectors of four, single precision floating point numbers. These vectors (the same number as there are registers to set) follow this token and its associated data structure in the DP2 stream.

The runtime validates that the specified register range lies within the legal range for the version of the current pixel shader.

See Also

D3DHAL_DP2PIXELSHADER, D3DHAL_DP2CREATEPIXELSHADER


D3DHAL_DP2SETPRIORITY

The D3DHAL_DP2SETPRIORITY structure is used to inform the driver of the priority of the texture specified by the handle dwDDDestSurface.

typedef struct _D3DHAL_DP2SETPRIORITY {
    DWORD  dwDDDestSurface;
    DWORD  dwPriority;
} D3DHAL_DP2SETPRIORITY, *LPD3DHAL_DP2SETPRIORITY;
‹ ›

Members

dwDDDestSurface
Specifies the handle of the texture.
dwPriority
Specifies the priority of the dwDDDestSurface texture.

Comments

Drivers are notified of handles at texture creation time. The driver can expect to receive priority notifications only for driver-managed textures.

Priorities are used to determine when managed textures are to be evicted from memory. A texture assigned a low priority will be evicted before a texture with a high priority. If two textures have the same priority, the texture that was used more recently is kept in memory; the other texture is evicted.


D3DHAL_DP2SETRENDERTARGET

The D3DHAL_DP2SETRENDERTARGET structure is used with the D3DDP2OP_SETRENDERTARGET opcode to map a new rendering target surface and depth buffer in the current context.

typedef struct _D3DHAL_DP2SETRENDERTARGET {
    DWORD  hRenderTarget;
    DWORD  hZBuffer;
} D3DHAL_DP2SETRENDERTARGET, *LPD3DHAL_DP2SETRENDERTARGET;
‹ ›

Members

hRenderTarget
Is a handle to the rendering target.
hZBuffer
Is a handle to the depth buffer.

Comments

The driver should carry out the following tasks in response to a D3DDP2OP_SETRENDERTARGET opcode in the D3dDrawPrimitives2 command stream:

  1. Store the rendering target identified by hRenderTarget in the driver's context.
  2. Store the depth buffer identified by hZBuffer in the driver's context.

See the p3samp sample driver that ships with this DDK for more implementation details.


D3DHAL_DP2SETSTREAMSOURCE

DirectX 8.0 and later versions only.

The D3DHAL_DP2SETSTREAMSOURCE structure is used to bind a vertex stream source to a vertex buffer for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETSTREAMSOURCE
{
    DWORD dwStream;     // Stream index, starting from zero
    DWORD dwVBHandle;   // Vertex buffer handle
    DWORD dwStride;     // Vertex stride
} D3DHAL_DP2SETSTREAMSOURCE, *LPD3DHAL_DP2SETSTREAMSOURCE;

Member

dwStream
Specifies stream being bound. It will have a value between zero and the maximum number of streams specified by the driver.
dwVBHandle
Specifies the vertex buffer handle. It is legal for the vertex buffer handle to be zero, in which case the stream is no longer bound to a vertex buffer.
dwStride
Specifies the vertex size in bytes.

Comments

A driver is notified of the binding of a vertex buffer to a particular stream through a new DP2 token, D3DDP2OP_SETSTREAMSOURCE.

The debug runtime validates that dwStream is within the legal range but the retail version does not, so validation must be present in the driver. DirectX 8.0 does not define the behavior of the driver or hardware in the error case where the stream index given is larger than the maximum stream supported by the hardware (as reported through MaxStreams in D3DCAPS8) beyond requiring that the driver and hardware combination not fault or hang in this case and that, on restoration of correct state the driver and hardware combination should continue to operate normally. Debug versions of your display driver should display messages in the debug output stream indicating when this problem has been detected.

The runtime does not validate that the streams accessed by the current vertex shader are non-NULL. It is the responsibility of the driver writer to ensure the driver/hardware does not crash when this error case arises. Debug versions of your display driver should display messages in the debug output stream to indicate when this problem has been detected.

It is guaranteed that only a single stream source will be set by a D3DHAL_DP2COMMAND. That is, the wStateCount field of the D3DHAL_DP2COMMAND will always be one when bCommand is D3DDP2OP_SETSTREAMSOURCE.

See Also

D3DHAL_DP2SETSTREAMSOURCEUM


D3DHAL_DP2SETSTREAMSOURCEUM

DirectX 8.0 and later versions only.

The D3DHAL_DP2SETSTREAMSOURCEUM structure is used to bind a vertex stream source to a user memory buffer for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETSTREAMSOURCEUM
{
    DWORD dwStream;     // Stream index, starting from zero
    DWORD dwStride;     // Vertex stride
} D3DHAL_DP2SETSTREAMSOURCEUM, *LPD3DHAL_DP2SETSTREAMSOURCEUM;

Member

dwStream
Specifies stream being bound. For DirectX 8.0 it will always be zero.
dwStride
Specifies the vertex size in bytes.

Comments

In addition to binding a stream to a vertex buffer, it is possible for the vertex data of stream zero to be supplied in a user memory (UM) buffer. In this case, another DP2 token is used to notify the driver of stream binding. That token is D3DDP2OP_SETSTREAMSOURCEUM.

DirectX 8.0 does not support multiple vertex streams with user supplied buffers rather than vertex buffers. Additionally, it is not possible to mix user memory buffers with vertex buffers. When a user memory buffer is supplied, it is guaranteed to be stream zero and to be the only stream that should be accessed by subsequent drawing primitives. It is possible that other streams will have non-NULL vertex buffers bound to them at the time when a user memory buffer is bound to stream. However, those other streams must be ignored by the driver and hardware.

The actual user memory pointer to the vertex data should be extracted from the D3DHAL_DRAWPRIMITIVES2DATA passed when actually drawing primitives.

See Also

D3DHAL_DP2SETSTREAMSOURCE


D3DHAL_DP2SETTEXLOD

The D3DHAL_DP2SETTEXLOD structure is used to set the level of detail (LOD) for MIP maps when the D3DDP2OP_SETTEXLOD command is sent to D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETTEXLOD {
    DWORD  dwDDSurface;
    DWORD  dwLOD;
} D3DHAL_DP2SETTEXLOD, *LPD3DHAL_DP2SETTEXLOD;

Members

dwDDSurface
Specifies a handle to a surface chain.
dwLOD
Controls the maximum MIP level loaded into video memory. Hence, if the most detailed MIP map in the chain has dimensions 256x256, setting the maximum level to 2 means that the largest MIP map ever present in video memory has dimensions 64x64.

Comments

Used only for driver-managed textures. This structure contains a surface handle to the MIP map and the maximum level of detail to set.


D3DHAL_DP2SETTRANSFORM

D3DHAL_DP2SETTRANSFORM structure is used to specify the transform state and matrix for D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETTRANSFORM {
    D3DTRANSFORMSTATETYPE  xfrmType;
    D3DMATRIX  matrix;
} D3DHAL_DP2SETTRANSFORM, *LPD3DHAL_DP2SETTRANSFORM;
‹ ›

Members

xfrmType
Specifies the type of transform being done.
Value | Meaning
D3DTRANSFORMSTATE_PROJECTION | Specifies a projection transformation.
D3DTRANSFORMSTATE_VIEW | Specifies a view transformation.
D3DTRANSFORMSTATE_WORLD | Specifies a world transformation.

matrix
Specifies the matrix used to perform the transform.

Comments

This structure is used with hardware transform and lighting and is used by the Direct3D run-time to inform the driver about the various transformation matrices.

See Also

D3DHAL_DP2MULTIPLYTRANSFORM


D3DHAL_DP2SETVERTEXSHADERCONST

DirectX 8.0 and later versions only.

The D3DHAL_DP2SETVERTEXSHADERCONST structure is used to set one or more of the vertex shader constant registers when the D3DDP2OP_SETVERTEXSHADERCONST opcode is received by D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2SETVERTEXSHADERCONST
{
    DWORD dwRegister;     // Const register to start copying
    DWORD dwCount;         // Number of 4-float vectors to copy
    // Data follows
} D3DHAL_DP2SETVERTEXSHADERCONST, *LPD3DHAL_DP2SETVERTEXSHADERCONST;

Member

dwRegister
Specifies the index of the first vertex shader constant to have its value sent.
dwCount
Specifies the number of constant registers to set and, hence, the number of four element, single precision float vectors to read from the DP2 stream.

Comments

A start register and register count are given. One or more vectors of four single precision floating point values immediately follow the D3DHAL_DP2SETVERTEXSHADERCONST data structure in the DP2 stream.

The runtime validates that the range of registers specified is legal given the level of vertex shader support reported to the driver. Furthermore, if the driver does not support any form of programmable vertex processing the runtime will not send this token to the driver.

See Also

D3DHAL_DP2VERTEXSHADER, D3DHAL_DP2CREATEVERTEXSHADER


D3DHAL_DP2STARTVERTEX

A D3DHAL_DP2STARTVERTEX structure follows certain D3DHAL_DP2COMMAND structures in the command buffer, and indicates the offset in the vertex buffer for the first vertex to use in D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2STARTVERTEX {
    WORD  wVStart;
} D3DHAL_DP2STARTVERTEX, *LPD3DHAL_DP2STARTVERTEX;

Members

wVStart
Specifies an additional offset to be added to any index used for determining the location of vertices in the vertex buffer (in the case of indexed primitives).

Comments

A D3DHAL_DP2STARTVERTEX structure follows a D3DHAL_DP2COMMAND structure in the command buffer when the bCommand member of D3DHAL_DP2COMMAND is one of the following values:

  • D3DDP2OP_INDEXEDLINELIST2
  • D3DDP2OP_INDEXEDLINESTRIP
  • D3DDP2OP_INDEXEDTRIANGLELIST2
  • D3DDP2OP_INDEXEDTRIANGLESTRIP
  • D3DDP2OP_INDEXEDTRIANGLEFAN

The first vertex of such primitives is located (wVStart + dwVertexOffset) bytes from the beginning of the vertex buffer, where dwVertexOffset is a member of D3DHAL_DRAWPRIMITIVES2DATA.


D3DHAL_DP2STATESET

The D3DHAL_DP2STATESET structure is used to inform the driver about stateset operations to perform.

typedef struct _D3DHAL_DP2STATESET {
    DWORD              dwOperation;
    DWORD              dwParam;
    D3DSTATEBLOCKTYPE  sbType;
} D3DHAL_DP2STATESET, *LPD3DHAL_DP2STATESET;
‹ ›

Members

dwOperation
Specifies the operation to perform. The value of this member can be one of the following:
Value | Meaning
D3DHAL_STATESETBEGIN | Specifies the beginning of the stateset referenced by dwParam.
D3DHAL_STATESETCAPTURE | Specifies that capture is to be done. When this flag is specified, the driver must capture a snapshot of the current state that matches the state block referenced by the handle passed in dwParam. That is, only the state that is specified in the state block is captured. See Accelerated State Management for important details about state capture.
D3DHAL_STATESETCREATE DirectX 8.0 and later versions only.

On receipt of this request the driver should create a state block of the type given in the field sbType. The information to record for each state block type is described below.
D3DHAL_STATESETDELETE | Specifies that the stateset referenced by dwParam should be deleted.
D3DHAL_STATESETEND | Specifies the end of the stateset referenced by dwParam.
D3DHAL_STATESETEXECUTE | Specifies that the stateset referenced by dwParam should be executed.

dwParam
Specifies the stateset handle that references the state block being manipulated with the current dwOperation.
sbType
The driver should ignore this member unless it implements render state extensions, or implements Pure Device Support (DirectX 8.0 and later versions only).

If the driver implements extended render states, that is, render states beyond those the Direct3D run-time supplies, it can use sbType to determine what types of predefined render states are being used. From this information the driver can determine how to append the state block appropriately, to support its extensions.

The sbType member, which is valid only for D3DHAL_STATESETBEGIN, D3DHAL_STATESETEND, and D3DHAL_STATECREATE, specifies the state block type with one of the following D3DSTATEBLOCKTYPE enumerated types. For more details see the DirectX SDK documentation.
Value | Meaning
D3DSBT_ALL Signals the driver to capture all state.

When requested to capture all state in pure device mode the driver should capture all state with the exception of the current vertex stream state, the current index stream state and the currently realized textures.

The state that should be captured is as follows; the render states listed below, the texture stage states listed below, the viewport, all the world transforms, the view transform, the projection transform, the texture transform for all texture stages, all user clip planes, the current material, all lights that have been used prior to the state block creation, the current vertex shader handle, the current pixel shader handle, the current vertex shader constants and the current pixel shader constants.

The render states to record are as follows:

D3DRENDERSTATE_SPECULARENABLE
D3DRENDERSTATE_ZENABLE
D3DRENDERSTATE_FILLMODE
D3DRENDERSTATE_SHADEMODE
D3DRENDERSTATE_LINEPATTERN
D3DRENDERSTATE_ZWRITEENABLE
D3DRENDERSTATE_ALPHATESTENABLE
D3DRENDERSTATE_LASTPIXEL
D3DRENDERSTATE_SRCBLEND
D3DRENDERSTATE_DESTBLEND
D3DRENDERSTATE_CULLMODE
D3DRENDERSTATE_ZFUNC
D3DRENDERSTATE_ALPHAREF
D3DRENDERSTATE_ALPHAFUNC
D3DRENDERSTATE_DITHERENABLE
D3DRENDERSTATE_FOGENABLE
D3DRENDERSTATE_STIPPLEDALPHA
D3DRENDERSTATE_FOGCOLOR
D3DRENDERSTATE_FOGTABLEMODE
D3DRENDERSTATE_FOGSTART
D3DRENDERSTATE_FOGEND
D3DRENDERSTATE_FOGDENSITY
D3DRENDERSTATE_EDGEANTIALIAS
D3DRENDERSTATE_ALPHABLENDENABLE
D3DRENDERSTATE_ZBIAS
D3DRENDERSTATE_RANGEFOGENABLE
D3DRENDERSTATE_STENCILENABLE
D3DRENDERSTATE_STENCILFAIL
D3DRENDERSTATE_STENCILZFAIL
D3DRENDERSTATE_STENCILPASS
D3DRENDERSTATE_STENCILFUNC
D3DRENDERSTATE_STENCILREF
D3DRENDERSTATE_STENCILMASK
D3DRENDERSTATE_STENCILWRITEMASK
D3DRENDERSTATE_TEXTUREFACTOR
D3DRENDERSTATE_WRAP0
D3DRENDERSTATE_WRAP1
D3DRENDERSTATE_WRAP2
D3DRENDERSTATE_WRAP3
D3DRENDERSTATE_WRAP4
D3DRENDERSTATE_WRAP5
D3DRENDERSTATE_WRAP6
D3DRENDERSTATE_WRAP7
D3DRENDERSTATE_AMBIENT
D3DRENDERSTATE_COLORVERTEX
D3DRENDERSTATE_FOGVERTEXMODE
D3DRENDERSTATE_CLIPPING
D3DRENDERSTATE_LIGHTING
D3DRENDERSTATE_NORMALIZENORMALS
D3DRENDERSTATE_LOCALVIEWER
D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
D3DRENDERSTATE_AMBIENTMATERIALSOURCE
D3DRENDERSTATE_DIFFUSEMATERIALSOURCE
D3DRENDERSTATE_SPECULARMATERIALSOURCE
D3DRENDERSTATE_VERTEXBLEND
D3DRENDERSTATE_CLIPPLANEENABLE
D3DRS_SOFTWAREVERTEXPROCESSING
D3DRS_POINTSIZE
D3DRS_POINTSIZE_MIN
D3DRS_POINTSPRITEENABLE
D3DRS_POINTSCALEENABLE
D3DRS_POINTSCALE_A
D3DRS_POINTSCALE_B
D3DRS_POINTSCALE_C
D3DRS_MULTISAMPLEANTIALIAS
D3DRS_MULTISAMPLEMASK
D3DRS_PATCHEDGESTYLE
D3DRS_PATCHSEGMENTS
D3DRS_POINTSIZE_MAX
D3DRS_INDEXEDVERTEXBLENDENABLE
D3DRS_COLORWRITEENABLE
D3DRS_TWEENFACTOR
D3DRS_BLENDOP

The texture stage states to record are as follows:

D3DTSS_COLOROP
D3DTSS_COLORARG1
D3DTSS_COLORARG2
D3DTSS_ALPHAOP
D3DTSS_ALPHAARG1
D3DTSS_ALPHAARG2
D3DTSS_BUMPENVMAT00
D3DTSS_BUMPENVMAT01
D3DTSS_BUMPENVMAT10
D3DTSS_BUMPENVMAT11
D3DTSS_TEXCOORDINDEX
D3DTSS_ADDRESSU
D3DTSS_ADDRESSV
D3DTSS_BORDERCOLOR
D3DTSS_MAGFILTER
D3DTSS_MINFILTER
D3DTSS_MIPFILTER
D3DTSS_MIPMAPLODBIAS
D3DTSS_MAXMIPLEVEL
D3DTSS_MAXANISOTROPY
D3DTSS_BUMPENVLSCALE
D3DTSS_BUMPENVLOFFSET
D3DTSS_TEXTURETRANSFORMFLAGS
D3DTSS_ADDRESSW
D3DTSS_COLORARG0
D3DTSS_ALPHAARG0
D3DTSS_RESULTARG
D3DSBT_PIXELSTATE Signals the driver to capture pixel state only.

When capturing pixel state in pure device mode the following state should be captured; the pixel processing related render states listed below, the pixel processing texture stage states listed below, the current pixel shader handle and the current pixel shader constants.

The render states to record are as follows:

D3DRENDERSTATE_ZENABLE
D3DRENDERSTATE_FILLMODE
D3DRENDERSTATE_SHADEMODE
D3DRENDERSTATE_LINEPATTERN
D3DRENDERSTATE_ZWRITEENABLE
D3DRENDERSTATE_ALPHATESTENABLE
D3DRENDERSTATE_LASTPIXEL
D3DRENDERSTATE_SRCBLEND
D3DRENDERSTATE_DESTBLEND
D3DRENDERSTATE_ZFUNC
D3DRENDERSTATE_ALPHAREF
D3DRENDERSTATE_ALPHAFUNC
D3DRENDERSTATE_DITHERENABLE
D3DRENDERSTATE_STIPPLEDALPHA
D3DRENDERSTATE_FOGSTART
D3DRENDERSTATE_FOGEND
D3DRENDERSTATE_FOGDENSITY
D3DRENDERSTATE_EDGEANTIALIAS
D3DRENDERSTATE_ALPHABLENDENABLE
D3DRENDERSTATE_ZBIAS
D3DRENDERSTATE_STENCILENABLE
D3DRENDERSTATE_STENCILFAIL
D3DRENDERSTATE_STENCILZFAIL
D3DRENDERSTATE_STENCILPASS
D3DRENDERSTATE_STENCILFUNC
D3DRENDERSTATE_STENCILREF
D3DRENDERSTATE_STENCILMASK
D3DRENDERSTATE_STENCILWRITEMASK
D3DRENDERSTATE_TEXTUREFACTOR
D3DRENDERSTATE_WRAP0
D3DRENDERSTATE_WRAP1
D3DRENDERSTATE_WRAP2
D3DRENDERSTATE_WRAP3
D3DRENDERSTATE_WRAP4
D3DRENDERSTATE_WRAP5
D3DRENDERSTATE_WRAP6
D3DRENDERSTATE_WRAP7
D3DRS_COLORWRITEENABLE
D3DRS_BLENDOP

The texture stage states to record are as follows:

D3DTSS_COLOROP
D3DTSS_COLORARG1
D3DTSS_COLORARG2
D3DTSS_ALPHAOP
D3DTSS_ALPHAARG1
D3DTSS_ALPHAARG2
D3DTSS_BUMPENVMAT00
D3DTSS_BUMPENVMAT01
D3DTSS_BUMPENVMAT10
D3DTSS_BUMPENVMAT11
D3DTSS_TEXCOORDINDEX
D3DTSS_ADDRESSU
D3DTSS_ADDRESSV
D3DTSS_BORDERCOLOR
D3DTSS_MAGFILTER
D3DTSS_MINFILTER
D3DTSS_MIPFILTER
D3DTSS_MIPMAPLODBIAS
D3DTSS_MAXMIPLEVEL
D3DTSS_MAXANISOTROPY
D3DTSS_BUMPENVLSCALE
D3DTSS_BUMPENVLOFFSET
D3DTSS_TEXTURETRANSFORMFLAGS
D3DTSS_ADDRESSW
D3DTSS_COLORARG0
D3DTSS_ALPHAARG0
D3DTSS_RESULTARG
D3DSBT_VERTEXSTATE Signals the driver to capture vertex state only.

When capturing vertex state in pure device mode the following state should be captured; the vertex processing related render states listed below, the vertex processing texture stage states listed below, all lights that have been used prior to the state block creation, the current vertex shader handle and the current vertex shader constants.

The render states to record are as follows:

D3DRENDERSTATE_SHADEMODE
D3DRENDERSTATE_SPECULARENABLE
D3DRENDERSTATE_CULLMODE
D3DRENDERSTATE_FOGENABLE
D3DRENDERSTATE_FOGCOLOR
D3DRENDERSTATE_FOGTABLEMODE
D3DRENDERSTATE_FOGSTART
D3DRENDERSTATE_FOGEND
D3DRENDERSTATE_FOGDENSITY
D3DRENDERSTATE_RANGEFOGENABLE
D3DRENDERSTATE_AMBIENT
D3DRENDERSTATE_COLORVERTEX
D3DRENDERSTATE_FOGVERTEXMODE
D3DRENDERSTATE_CLIPPING
D3DRENDERSTATE_LIGHTING
D3DRENDERSTATE_NORMALIZENORMALS
D3DRENDERSTATE_LOCALVIEWER
D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
D3DRENDERSTATE_AMBIENTMATERIALSOURCE
D3DRENDERSTATE_DIFFUSEMATERIALSOURCE
D3DRENDERSTATE_SPECULARMATERIALSOURCE
D3DRENDERSTATE_VERTEXBLEND
D3DRENDERSTATE_CLIPPLANEENABLE
D3DRS_SOFTWAREVERTEXPROCESSING
D3DRS_POINTSIZE
D3DRS_POINTSIZE_MIN
D3DRS_POINTSPRITEENABLE
D3DRS_POINTSCALEENABLE
D3DRS_POINTSCALE_A
D3DRS_POINTSCALE_B
D3DRS_POINTSCALE_C
D3DRS_MULTISAMPLEANTIALIAS
D3DRS_MULTISAMPLEMASK
D3DRS_PATCHEDGESTYLE
D3DRS_PATCHSEGMENTS
D3DRS_POINTSIZE_MAX
D3DRS_INDEXEDVERTEXBLENDENABLE
D3DRS_TWEENFACTOR

The texture stage states to record are as follows:

D3DTSS_TEXCOORDINDEX
D3DTSS_TEXTURETRANSFORMFLAGS
NULL | No predefined state group is specified.

Comments

See Accelerated State Management in the Graphics Design Guide for more information about the use of this structure in state block management.


D3DHAL_DP2TEXBLT

The D3DHAL_DP2TEXBLT structure is used for texture blts when D3dDrawPrimitives2 responds to the D3DDP2OP_TEXBLT command token.

typedef struct _D3DHAL_DP2TEXBLT {
    DWORD  dwDDDestSurface;
    DWORD  dwDDSrcSurface;
    POINT  pDest;
    RECTL  rSrc;
    DWORD  dwFlags;
} D3DHAL_DP2TEXBLT, *LPD3DHAL_DP2TEXBLT;
‹ ›

Members

dwDDDestSurface
Specifies the handle to the destination texture.
dwDDSrcSurface
Specifies the handle to the source texture.
pDest
Specifies the destination point where the blt should be performed; that is, the point in the destination surface (dwDDDestSurface) to begin the blt.
rSrc
Specifies the rectangle to be blitted in the source texture; that is, the source rectangle in the source surface (dwDDSrcSurface) to blt from.
dwFlags
Is reserved for system use.

Comments

The D3dCreateSurfaceEx callback creates the small integer handles to the textures that can be used as source and destination textures for texture blts.

The D3DHAL_DP2TEXBLT structure is used with a D3DDP2OP_TEXBLT command stream token to inform the drivers to perform a blt operation from a source texture to a destination texture. A texture can also be cubic environment map. The driver should copy a rectangle specified by rSrc in the source texture to the location specified by pDest in the destination texture. The destination and source textures are identified by handles that the driver was notified with during texture creation time. If the driver is capable of managing textures, then it is possible that the destination handle is 0. This indicates to the driver that it should preload the texture into video memory (or wherever the hardware efficiently textures from). In this case, the driver can ignore rSrc and pDest.

Note that for MIP mapped textures, only one D3DDP2OP_TEXBLT instruction is inserted into the D3dDrawPrimitives2 command stream. In this case, the driver is expected to blt all the MIP map levels present in the texture. The regions to be copied in MIP map sub-levels can be obtained by dividing rSrc and pDest by 2 at each level.

It is possible that the source and destination textures may contain different number of MIP map levels. In this case, the driver is expected to blt the common levels. For example, if a 256x256 source texture has 8 MIP map levels, and if the destination is a 64x64 texture with 6 levels, then the driver should blt the 6 corresponding levels from the source. The driver can expect the dimensions of the top MIP level of the destination texture to always be less than or equal to the dimensions of the top MIP level of the source texture.

Note that the source and destination handles always refer to the top level surfaces and never to any MIP map sub-level. Due to an error in the application, it is possible that the destination texture contains extra MIP map levels. For instance, a source 256x256 texture may contain five levels, but the destination 256x256 texture may contain eight. The driver is expected to safely handle this case, but it is not expected to produce correct results. Due to legacy application compatibility issues, Direct3D does not prevent such source/destination texture pairs from being passed on to the driver.

The driver can expect the pixel formats of the source and destination textures to be identical and, in general, the specified blt will be safe to perform. Other than the single case mentioned above, the driver should not expect to be presented with any situation that makes it impossible to perform a blt. The hope of this is to ensure that the driver's TexBlt implementation is as efficient as possible.

If the driver wishes to perform asynchronous blts from system memory to video memory, then it should implement the DirectDraw® HAL call GetSysmemBltStatus, otherwise inconsistencies may arise.

With TexBlt it is not necessary for the driver to perform any synchronization because TexBlts are always issued in the proper order along with rendering commands. Before this, it was necessary for the driver to correctly handle the case when a DirectDraw blt modified any texture that was referenced by rendering commands in any Direct3D context. When multiple contexts are present, Direct3D will not issue TexBlts. This means that the driver writer can omit synchronization code in the TexBlt code path (but will still need syncing for blts).

Sample

The following pseudo code in shows how a subrectangle should be computed for consecutive MIP levels, to go to MIP level i + 1 from MIP level i:

rect.left >>= 1;
rect.top >>= 1;
DWORD right = (rect.right + 1) >> 1;
DWORD bottom = (rect.bottom + 1) >> 1;
rect.right = ((right - rect.left) < 1) ? (rect.left + 1) : (right);
rect.bottom = ((bottom - rect.top ) < 1) ? (rect.top + 1) : (bottom);


D3DHAL_DP2TEXTURESTAGESTATE

One or more D3DHAL_DP2TEXTURESTAGESTATE structures are parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_TEXTURESTAGESTATE, and are used to set the appropriate texture stage state.

typedef struct _D3DHAL_DP2TEXTURESTAGESTATE {
    DWORD                     dwStage;
    D3DTEXTURESTAGESTATETYPE  TSState;
    DWORD                     dwValue;
} D3DHAL_DP2TEXTURESTAGESTATE;

Members

dwStage
Identifies the texture stage where to update the texture state. This member can be an integer in the range 0 through 7, with the highest numbered texture being closest to the frame buffer.
TSState
Specifies a D3DTEXTURESTAGESTATETYPE enumerated value, described in the DirectX SDK documentation, that specifies the texture state to be updated.
dwValue
Specifies the value that the driver should update the texture state identified by TSState to.

Comments

D3dDrawPrimitives2 should process wStateCount D3DHAL_DP2TEXTURESTAGESTATE structures from the command buffer. The value of wStateCount is specified in the D3DHAL_DP2COMMAND structure.

For each D3DHAL_DP2TEXTURESTAGESTATE structure, D3dDrawPrimitives2 should update the driver's internal texture state associated with the texture at dwStage to reflect the new value based on TSState.

Drivers that do not support multi-texturing should implement support for texture stage 0 only.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_TEXTURESTAGESTATE command and three D3DHAL_DP2TEXTURESTAGESTATE structures. The driver should update stages zero and three of its private texture stage state accordingly.


D3DHAL_DP2TRIANGLEFAN

One D3DHAL_DP2TRIANGLEFAN structure is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_TRIANGLEFAN, and is used to render a triangle fan.

typedef struct _D3DHAL_DP2TRIANGLEFAN {
    WORD  vVStart;
} D3DHAL_DP2TRIANGLEFAN;

Members

vVStart
Specifies the index into the vertex buffer containing coordinate data for the initial vertex of the triangle fan.

Comments

One D3DHAL_DP2TRIANGLEFAN structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

D3dDrawPrimitives2 should process a total of wPrimitiveCount+2 vertices from the vertex buffer, three vertices per triangle, rendering wPrimitiveCount triangles. Starting from the vertex buffer offset, the sequence of triangles rendered is (wVStart+1, wVStart+2, wVStart), (wVStart+2, wVStart+3, wVStart),…, (wVStart+wPrimitiveCount, wVStart+wPrimitiveCount+1, wVStart). The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_TRIANGLEFAN command and a D3DHAL_DP2TRIANGLEFAN structure. The driver should process six vertices from the vertex buffer, rendering a fan with four triangles defined by (v[3], v[4], v[2]), (v[4], v[5], v[2]), (v[5], v[6], v[2]), (v[6], v[7], v[2]).


D3DHAL_DP2TRIANGLEFAN_IMM

One D3DHAL_DP2TRIANGLEFAN_IMM structure is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_TRIANGLEFAN_IMM, and is used to render a triangle fan.

typedef struct _D3DHAL_DP2TRIANGLEFAN_IMM {
    DWORD  dwEdgeFlags;
} D3DHAL_DP2TRIANGLEFAN_IMM, *LPD3DHAL_DP2TRIANGLEFAN_IMM;

Members

dwEdgeFlags
Specifies a bitmask that identifies which of the fan's outside edges should be rendered when the fill mode is D3DFILL_WIREFRAME. A set bit indicates that its corresponding edge should be rendered.

Comments

One D3DHAL_DP2TRIANGLEFAN_IMM structure immediately follows the D3DHAL_DP2COMMAND structure in the command buffer. The triangle fan's vertex data is DWORD-aligned immediately following the D3DHAL_DP2TRIANGLEFAN_IMM structure in the command buffer.

D3dDrawPrimitives2 should process a total of wPrimitiveCount+2 vertices from the command buffer, three vertices per triangle, rendering wPrimitiveCount triangles. The sequence of triangles rendered is (V[1], V[2], V[0]), (V[2], V[3], V[0]), (V[3], V[4], V[0]), …, (V[wPrimitiveCount], V[wPrimitiveCount+1], V[0]). The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The driver must check the edge flag for each of the fan's outside edges when the fill mode is D3DFILL_WIREFRAME. Starting from the least significant bit of dwEdgeFlags, bit 0 applies to the V[0]-V[1] edge, bit 1 applies to the V[1]-V[2] edge, …, bit wPrimitiveCount applies to the V[wPrimitiveCount]-V[wPrimitiveCount+1] edge, and bit (wPrimitiveCount+1) applies to the V[wPrimitiveCount+1]-V[0] edge.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_TRIANGLEFAN_IMM command, a D3DHAL_DP2TRIANGLEFAN_IMM structure, and the vertex data. The driver should process the five vertices from the command buffer, rendering a fan with three triangles defined by (v[1], v[2], v[0]), (v[2], v[3], v[0]), (v[3], v[4], v[0]).


D3DHAL_DP2TRIANGLELIST

One D3DHAL_DP2TRIANGLELIST structure is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_TRIANGLELIST, and is used to render the specified unconnected triangles.

typedef struct _D3DHAL_DP2TRIANGLELIST {
    WORD  wVStart;
} D3DHAL_DP2TRIANGLELIST;

Members

wVStart
Specifies the offset into the vertex buffer containing coordinate data for the initial vertex of the triangle list

Comments

One D3DHAL_DP2TRIANGLELIST structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

D3dDrawPrimitives2 should sequentially process a total of wPrimitiveCount*3 vertices from the vertex buffer, three vertices per triangle, rendering wPrimitiveCount triangles. Starting from the vertex buffer offset, the sequence of triangles rendered is (wVStart, wVStart+1, wVStart+2), (wVStart+3, wVStart+4, wVStart+5),…, (wVStart+(wPrimitiveCount-1)*3, wVStart+wPrimitiveCount*3-2, wVStart+wPrimitiveCount*3-1). The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_TRIANGLELIST command and one D3DHAL_DP2TRIANGLELIST structure. The driver should draw two triangles using the following six vertices from the vertex buffer: (v[2], v[3], v[4]), (v[5], v[6], v[7]).


D3DHAL_DP2TRIANGLESTRIP

One D3DHAL_DP2TRIANGLESTRIP structure is parsed from the command buffer by the D3dDrawPrimitives2 callback when the D3DHAL_DP2COMMAND structure's bCommand member is set to D3DDP2OP_TRIANGLESTRIP, and is used to render the specified connected triangle strip.

typedef struct _D3DHAL_DP2TRIANGLESTRIP {
    WORD  wVStart;
} D3DHAL_DP2TRIANGLESTRIP;

Members

wVStart
Specifies the index to the vertex buffer containing coordinate data for the initial vertex of the triangle strip.

Comments

One D3DHAL_DP2TRIANGLESTRIP structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

D3dDrawPrimitives2 should process a total of (wPrimitiveCount+2) vertices from the vertex buffer. The value of wPrimitiveCount is specified in the D3DHAL_DP2COMMAND structure.

The triangle edges in a triangle strip are rendered in this order: (wV[0], wV[1], wV[2]), (wV[1], wV[3], wV[2]), (wV[2], wV[3], wV[4]), (wV[3], wV[5], wV[4]),...

For the last triangle in the triangle strip, however, the edges will be rendered in different orders when wPrimitiveCount is odd and when it is even.

  • When wPrimitiveCount is an odd number, the last triangle's edges are rendered in this order: (wV[wPrimitiveCount - 1], wV[wPrimitiveCount], wV[wPrimitiveCount + 1]).
  • When wPrimitiveCount is an even number, the last triangle's edges are rendered in this order: (wV[wPrimitiveCount - 1], wV[wPrimitiveCount+1], wV[wPrimitiveCount]).

The following figure shows a portion of a sample command buffer containing a D3DDP2OP_TRIANGLESTRIP command and one D3DHAL_DP2TRIANGLESTRIP structure. The driver should process five vertices from the vertex buffer, rendering a strip of three triangles defined by (v[0], v[1], v[2]), (v[1], v[3], v[2]), (v[2], v[3], v[4]).


D3DHAL_DP2UPDATEPALETTE

The D3DHAL_DP2UPDATEPALETTE structure is used when responding to the D3DDP2OP_UPDATEPALETTE opcode in D3dDrawPrimitives2. It is used to make alterations to the palette that is used for palletized textures.

typedef struct _D3DHAL_DP2UPDATEPALETTE {
    DWORD  dwPaletteHandle;
    WORD   wStartIndex;
    WORD   wNumEntries;
} D3DHAL_DP2UPDATEPALETTE, *LPD3DHAL_DP2UPDATEPALETTE;
‹ ›

Members

dwPaletteHandle
Is a handle to the palette to be altered.
wStartIndex
Specifies the index in the palette beyond which data will be updated.
wNumEntries
Specifies the number of PALETTEENTRYs being updated.

Comments

The palette handle attached to a surface is updated with wNumEntries PALETTEENTRYs starting at a specific wStartIndex member of the palette. A PALETTEENTRY (defined in wingdi.h and wtypes.h) is actually a DWORD with an ARGB color for each byte.

After the D3DHAL_DP2UPDATEPALETTE structure in the command stream, the actual palette data will follow (without any padding), consisting of one DWORD per palette entry (in ARGB format, with 8 bits for each of the four channels). There will only be one D3DHAL_DP2UPDATEPALETTE structure (plus palette data) following the D3DHAL_DP2COMMAND structure regardless of the value of wStateCount (a member of the D3DHAL_DP2COMMAND structure).


D3DHAL_DP2VERTEXSHADER

DirectX 8.0 and later versions only.

The D3DHAL_DP2VERTEXSHADER structure is used to set the current vertex shader, or delete a vertex shader, depending on the opcode received (D3DDP2OP_SETVERTEXSHADER or D3DDP2OP_DELETEVERTEXSHADER) by D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2VERTEXSHADER
{
    // Vertex shader handle.
    // The handle could be 0, meaning that the current vertex
    // shader is invalid (not set). When driver receives
    // handle 0, it should invalidate all streams pointers
    DWORD dwHandle;
} D3DHAL_DP2VERTEXSHADER, *LPD3DHAL_DP2VERTEXSHADER;

Member

dwHandle
Specifies the handle assigned by the runtime to the vertex shader to set or delete. For delete, the handle is guaranteed to be non-zero. For set, the supplied handle can be zero indicating that no vertex shader is currently realized. In this case the driver should invalidate all previously set streams and free any data associated with them. The runtime guarantees that streams will be re-initialized with D3DDP2OP_SETSTREAMSOURCE or D3DDP2OP_SETSTREAMSOURCEUM and a new vertex shader will be selected using D3DHAL_DP2VERTEXSHADER before any subsequent rendering operations.

Comments

All DirectX 8.0 level drivers must support the D3DDP2OP_SETVERTEXSHADER token because it will be sent even if the driver does not support programmable vertex processing. In that case, however, the shader handle will always be an FVF code indicating fixed function processing of the vertex data. The driver should use the FVF code stored in the dwHandle field as the format of the vertex data in stream zero. A driver that does support programmable vertex processing must examine the handle to determine whether it refers to a shader previously created with D3DDP2OP_CREATEVERTEXSHADER or an FVF code and take the appropriate action.

Pixel and vertex shaders are orthogonal. Thus, if a legacy FVF code is selected as the current vertex shader this does not imply legacy pixel processing. In order to reset pixel processing to a non-programmable mode the current pixel shader must also be set to zero. Care should be taken in the driver to only reset vertex processing state to a fixed function mode and not pixel processing state when the vertex shader is set to an FVF code.

When switching from fixed function vertex processing to programmable vertex processing, the values of legacy render state and matrices should be preserved. If and when a switch from programmable to fixed function vertex processing occurs (the driver receives a D3DDP2OP_SETVERTEXSHADER with an FVF as the shader handle), that preserved state should be restored.

When switching between programmable shaders, any constant register that has a value specified in the definition of that shader should be set to that value. The values of all other constant registers should remain unchanged.

See Also

D3DHAL_DP2SETVERTEXSHADERCONST, D3DHAL_DP2CREATEVERTEXSHADER


D3DHAL_DP2VIEWPORTINFO

The D3DHAL_DP2VIEWPORTINFO structure is used to inform guard-band aware drivers of the view clipping rectangle. The clipping rectangle is specified by the members dwX, dwY, dwWidth and dwHeight.

typedef struct _D3DHAL_DP2VIEWPORTINFO {
    DWORD  dwX;
    DWORD  dwY;
    DWORD  dwWidth;
    DWORD  dwHeight;
} D3DHAL_DP2VIEWPORTINFO, *LPD3DHAL_DP2VIEWPORTINFO;
‹ ›

Members

dwX, dwY
Specify the location, in screen coordinates, of the upper-left corner of the sub-rectangle.
dwWidth, dwHeight
Specify the width and height, respectively, of the sub-rectangle where the application is rendering. These members are specified in screen coordinates.

Comments

The D3dDrawPrimitives2 callback parses a D3DHAL_DP2VIEWPORTINFO structure from the command buffer and updates the driver's viewport description when D3DHAL_DP2COMMAND is set to D3DDP2OP_VIEWPORTINFO.

One D3DHAL_DP2VIEWPORTINFO structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

The driver should update the viewport portion of its internal rendering context with the location and size values specified in this structure. The driver can use this information to perform guard band clipping.

Non-guard-band drivers should ignore and skip over these instructions and continue processing the rest of the command buffer.


D3DHAL_DP2VOLUMEBLT

DirectX 8.0 and later versions only.

The D3DHAL_DP2VOLUMEBLT structure is used for volume texture blts when D3dDrawPrimitives2 responds to the D3DDP2OP_VOLUMEBLT command token.

typedef struct _D3DHAL_DP2VOLUMEBLT
{
    DWORD   dwDDDestSurface;// dest surface
    DWORD   dwDDSrcSurface; // src surface
    DWORD   dwDestX;        // dest X (width)
    DWORD   dwDestY;        // dest Y (height)
    DWORD   dwDestZ;        // dest Z (depth)
    D3DBOX  srcBox;         // src box
    DWORD   dwFlags;        // blt flags
} D3DHAL_DP2VOLUMEBLT, *LPD3DHAL_DP2VOLUMEBLT;

Members

dwDDDestSurface
Specifies the handle to the destination volume texture.
dwDDSrcSurface
Specifies the handle to the source volume texture.
dwDestX, dwDestY, dwDestZ
Specify the location in the destination volume texture to copy the defined source sub-volume.
srcBox
Specifies a sub-volume of the source volume texture to copy to the destination.
dwFlags
Is reserved for system use.

Comments

The D3dCreateSurfaceEx callback creates the small integer handles to the volume textures that can be used as source and destination volume textures for volume texture blts.

See Comments for D3DHAL_DP2TEXBLT.


D3DHAL_DP2WINFO

The D3DHAL_DP2WINFO structure is used to inform the driver of the w-range to be used for w-buffering.

typedef struct _D3DHAL_DP2WINFO {
    D3DVALUE  dvWNear;
    D3DVALUE  dvWFar;
} D3DHAL_DP2WINFO, *LPD3DHAL_DP2WINFO;
‹ ›

Members

dvWNear, dvWFar
Specify the near and far limit of the w-buffer, respectively. These members can be any valid floating point values.

Comments

The D3dDrawPrimitives2 callback parses a D3DHAL_DP2WINFO structure from the command buffer and updates the driver's scaling parameters for w-buffering when D3DHAL_DP2COMMAND is set to D3DDP2OP_WINFO.

One D3DHAL_DP2WINFO structure follows the D3DHAL_DP2COMMAND structure in the command buffer.

The driver should update the w-buffer portion of its internal rendering context with the w-ranges specified in this structure. The driver can use this information to scale the w-buffer.

Video adapters that do not support this feature should ignore and skip over these instructions and continue processing the rest of the command buffer.


D3DHAL_DP2ZRANGE

The D3DHAL_DP2ZRANGE structure is used to specify z-range minimum and maximum in D3dDrawPrimitives2.

typedef struct _D3DHAL_DP2ZRANGE {
    D3DVALUE  dvMinZ;
    D3DVALUE  dvMaxZ;
} D3DHAL_DP2ZRANGE, *LPD3DHAL_DP2ZRANGE;
‹ ›

Members

dvMinZ
Specifies the minimum z value for the Mvs matrix described in the Hardware Transform and Lighting section of the design guide.
dvMaxZ
Specifies the maximum z value for the Mvs matrix described in the Hardware Transform and Lighting section of the design guide.


D3DHAL_GLOBALDRIVERDATA

The D3DHAL_GLOBALDRIVERDATA structure specifies the 3D capabilities of the driver and its device.

typedef struct _D3DHAL_GLOBALDRIVERDATA {
    DWORD                  dwSize;
    D3DHALDEVICEDESC_V1    hwCaps;
    DWORD                  dwNumVertices;
    DWORD                  dwNumClipVertices
    DWORD                  dwNumTextureFormats;
    LPDDSURFACEDESC        lpTextureFormats;
} D3DHAL_GLOBALDRIVERDATA, *LPD3DHAL_GLOBALDRIVERDATA;
‹ ›

Members

dwSize
Specifies the size in bytes of this D3DHAL_GLOBALDRIVERDATA structure.
hwCaps
Specifies a D3DDEVICEDESC_V1 structure where the driver should return its hardware capabilities.
dwNumVertices
Is reserved for system use and should be set to zero by the driver.
dwNumClipVertices
Is reserved for system use and should be set to zero by the driver.
dwNumTextureFormats
Specifies the number of DDSURFACEDESC structures that lpTextureFormats points to.
lpTextureFormats
Points to an array of DDSURFACEDESC structures where the driver should return the texture formats supported by the device.

Comments

The driver is responsible for allocating space for and setting all members of this structure. The driver returns a pointer to this structure in the lpD3DGlobalDriverData member of the DD_HALINFO structure, which is passed to the driver's DrvGetDirectDrawInfo function during driver initialization.


Other Direct3D Driver Structures

This section contains all the Direct3D® driver structures that do not begin with D3DHAL_.


D3DDEVICEDESC_V1

Obsolete in DirectX 8.0 and later versions; see Comments.

The D3DDEVICEDESC_V1 structure describes the 3D capabilities of a device.

typedef struct _D3DDeviceDesc_V1 {
    DWORD             dwSize;
    DWORD             dwFlags;
    D3DCOLORMODEL     dcmColorModel;
    DWORD             dwDevCaps;
    D3DTRANSFORMCAPS  dtcTransformCaps;
    BOOL              bClipping;
    D3DLIGHTINGCAPS   dlcLightingCaps;
    D3DPRIMCAPS       dpcLineCaps;
    D3DPRIMCAPS       dpcTriCaps;
    DWORD             dwDeviceRenderBitDepth;
    DWORD             dwDeviceZBufferBitDepth;
    DWORD             dwMaxBufferSize;
    DWORD             dwMaxVertexCount;
} D3DDEVICEDESC_V1, *LPD3DDEVICEDESC_V1;
‹ ›

Members

dwSize
Specifies the size in bytes of this D3DDEVICEDESC_V1 structure.
dwFlags
Identifies the members of this structure that contain valid data. This member can be a bitwise OR of any of the following values:
Value | Meaning
D3DDD_BCLIPPING | The bClipping member contains valid data.
D3DDD_COLORMODEL | The dcmColorModel member contains valid data.
D3DDD_DEVCAPS | The dwDevCaps member contains valid data.
D3DDD_DEVICERENDERBITDEPTH | The dwDeviceRenderBitDepth member contains valid data.
D3DDD_DEVICEZBUFFERBITDEPTH | The dwDeviceZBufferBitDepth member contains valid data.
D3DDD_LIGHTINGCAPS | The dlcLightingCaps member contains valid data.
D3DDD_LINECAPS | The dpcLineCaps member contains valid data.
D3DDD_MAXBUFFERSIZE | The dwMaxBufferSize member contains valid data.
D3DDD_MAXVERTEXCOUNT | The dwMaxVertexCount member contains valid data.
D3DDD_TRANSFORMCAPS | The dtcTransformCaps member contains valid data.
D3DDD_TRICAPS | The dpcTriCaps member contains valid data.

dcmColorModel
Specifies the device's color model.
dwDevCaps
Identifies the capabilities of the device. This member can be a bitwise OR of any of the following values:
Value | Meaning
D3DDEVCAPS_CANBLTSYSTONONLOCAL | The device supports a TexBlt from system memory to non-local video memory.
D3DDEVCAPS_CANRENDERAFTERFLIP | The device can queue rendering commands after a page flip. Devices must support this capability on Windows 2000 and later, meaning that the driver would always set this flag.
D3DDEVCAPS_DRAWPRIMITIVES2 | The device can support D3dDrawPrimitives2.
D3DDEVCAPS_DRAWPRIMITIVES2EX | The device can support Extended D3dDrawPrimitives2; i.e. a DX7-compliant driver.
D3DDEVCAPS_DRAWPRIMTLVERTEX | The device can draw TLVERTEX primitives. This flag is obsolete but must be set by the driver.
D3DDEVCAPS_EXECUTESYSTEMMEMORY | The device can use execute buffers from system memory. The driver must always set this bit.
D3DDEVCAPS_EXECUTEVIDEOMEMORY | The device can use execute buffers from display memory. The driver must never set this bit.
D3DDEVCAPS_FLOATTLVERTEX | The device accepts floating point for post-transform vertex data. This flag is obsolete but must be set by the driver.
D3DDEVCAPS_HWRASTERIZATION | The device has hardware acceleration for rasterization.
D3DDEVCAPS_HWTRANSFORMANDLIGHT | The device can support transformation and lighting in hardware. D3DDEVCAPS_DRAWPRIMITIVES2EX must also be set.
D3DDEVCAPS_SEPARATETEXTUREMEMORIES | The device is texturing from separate memory pools.
D3DDEVCAPS_SORTDECREASINGZ | The device needs data sorted for decreasing depth.
D3DDEVCAPS_SORTEXACT | The device needs data sorted exactly.
D3DDEVCAPS_SORTINCREASINGZ | The device needs data sorted for increasing depth.
D3DDEVCAPS_TEXTURENONLOCALVIDEOMEMORY | The device can texture from nonlocal video memory.
D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | The device can use buffers from system memory for transformed and lit vertices. This flag is obsolete but must be set by the driver.
D3DDEVCAPS_TLVERTEXVIDEOMEMORY | The device can use buffers from display memory for transformed and lit vertices. This flag is obsolete and must not be set by the driver.
D3DDEVCAPS_TEXTURESYSTEMMEMORY | The device can retrieve textures from system memory.
D3DDEVCAPS_TEXTUREVIDEOMEMORY | The device can retrieve textures from device memory.

dtcTransformCaps
Specifies a D3DTRANSFORMCAPS structure that specifies the transformation capabilities of the device. The driver must set the dwCaps member of that structure to zero.
bClipping
Is set TRUE by the driver if the device can perform 3D clipping.
dlcLightingCaps
Is a D3DLIGHTINGCAPS structure that specifies the lighting capabilities of the device. The driver must set the dwCaps, dwLightingModel, and dwNumLights members of that structure to zero.
dpcLineCaps
Specifies a D3DPRIMCAPS structure that defines the drawing capabilities of the device for line primitives.
dpcTriCaps
Specifies a D3DPRIMCAPS structure that defines the drawing capabilities of the device for triangle primitives.
dwDeviceRenderBitDepth
Specifies the device's rendering bit-depth. This member can be a bitwise OR of the following DirectDraw® bit-depth constants: DDBD_8, DDBD_16, DDBD_24, or DDBD_32.
dwDeviceZBufferBitDepth
Specifies the device's z-buffer bit-depth. This member can be a bitwise OR of the following DirectDraw bit-depth constants: DDBD_8, DDBD_16, DDBD_24, or DDBD_32.
dwMaxBufferSize
Must be set to zero.
dwMaxVertexCount
Specifies the maximum number of vertices that the device can handle in a single call to D3dDrawPrimitives2.

Comments

This structure has been replaced by D3DCAPS8 (see the DirectX 8.0 SDK documentation) for DirectX 8.0 and later runtimes, but is required for legacy runtime (DirectX 7.0 and earlier) compatibility. See Reporting DirectX 8.0 Style Direct3D Capabilities for details.

The driver's DrvGetDirectDrawInfo function returns this information in the D3DHAL_GLOBALDRIVERDATA structure that the lpD3DGlobalDriverData member of the DD_HALINFO structure points to.

The Direct3D runtime constructs the application-level D3DDEVICEDESC7 structure (documented in the Platform SDK documentation) from the information returned in the D3DDEVICEDESC_V1 structure and the extended capabilities queried through the driver's DdGetDriverInfo function. While some of the dwDevCaps flags are obsolete at the driver level, the driver must set them appropriately in order for applications to work correctly.


D3DDEVICEDESC_V2

The D3DDEVICEDESC_V2 structure is obsolete; only D3DDEVICEDESC_V1 should be used.

The D3DDEVICEDESC_V2 structure contains fields that are already reported in the D3DHAL_D3DEXTENDEDCAPS structure when responding to the GUID_D3DExtendedCaps GUID in DdGetDriverInfo.

typedef struct _D3DDeviceDesc_V2 {
    DWORD             dwSize;
    DWORD             dwFlags;
    D3DCOLORMODEL     dcmColorModel;
    DWORD             dwDevCaps;
    D3DTRANSFORMCAPS  dtcTransformCaps;
    BOOL              bClipping;
    D3DLIGHTINGCAPS   dlcLightingCaps;
    D3DPRIMCAPS       dpcLineCaps;
    D3DPRIMCAPS       dpcTriCaps;
    DWORD             dwDeviceRenderBitDepth;
    DWORD             dwDeviceZBufferBitDepth;
    DWORD             dwMaxBufferSize;
    DWORD             dwMaxVertexCount;
    DWORD             dwMinTextureWidth;
    DWORD             dwMinTextureHeight;
    DWORD             dwMaxTextureWidth;
    DWORD             dwMaxTextureHeight;
    DWORD             dwMinStippleWidth;
    DWORD             dwMaxStippleWidth;
    DWORD             dwMinStippleHeight;
    DWORD             dwMaxStippleHeight;
} D3DDEVICEDESC_V2, *LPD3DDEVICEDESC_V2;
‹ ›


D3DDEVICEDESC_V3

The D3DDEVICEDESC_V3 structure is obsolete; only D3DDEVICEDESC_V1 should be used.

The D3DDEVICEDESC_V3 structure contains fields that are already reported in the D3DHAL_D3DEXTENDEDCAPS structure when responding to the GUID_D3DExtendedCaps GUID in DdGetDriverInfo.

typedef struct _D3DDeviceDesc_V3 {
    DWORD             dwSize;
    DWORD             dwFlags;
    D3DCOLORMODEL     dcmColorModel;
    DWORD             dwDevCaps;
    D3DTRANSFORMCAPS  dtcTransformCaps;
    BOOL              bClipping;
    D3DLIGHTINGCAPS   dlcLightingCaps;
    D3DPRIMCAPS       dpcLineCaps;
    D3DPRIMCAPS       dpcTriCaps;
    DWORD             dwDeviceRenderBitDepth;
    DWORD             dwDeviceZBufferBitDepth;
    DWORD             dwMaxBufferSize;
    DWORD             dwMaxVertexCount;
    DWORD             dwMinTextureWidth;
    DWORD             dwMinTextureHeight;
    DWORD             dwMaxTextureWidth;
    DWORD             dwMaxTextureHeight;
    DWORD             dwMinStippleWidth;
    DWORD             dwMaxStippleWidth;
    DWORD             dwMinStippleHeight;
    DWORD             dwMaxStippleHeight;
    DWORD             dwMaxTextureRepeat;
    DWORD             dwMaxTextureAspectRatio;
    DWORD             dwMaxAnisotropy;
    D3DVALUE          dvGuardBandLeft;
    D3DVALUE          dvGuardBandTop;
    D3DVALUE          dvGuardBandRight;
    D3DVALUE          dvGuardBandBottom;
    D3DVALUE          dvExtentsAdjust;
    DWORD             dwStencilCaps;
    DWORD             dwFVFCaps;
    DWORD             dwTextureOpCaps;
    WORD              wMaxTextureBlendStages;
    WORD              wMaxSimultaneousTextures;
} D3DDEVICEDESC_V3, *LPD3DDEVICEDESC_V3;
‹ ›


D3DLIGHTINGCAPS

Obsolete in DirectX 8.0 and later versions; see Comments.

The D3DLIGHTINGCAPS structure describes the lighting capabilities of a device.

typedef struct _D3DLIGHTINGCAPS {
    DWORD  dwSize;
    DWORD  dwCaps;
    DWORD  dwLightingModel;
    DWORD  dwNumLights;
} D3DLIGHTINGCAPS, *LPD3DLIGHTINGCAPS;
‹ ›

Members

dwSize
Specifies the size, in bytes, of the D3DLIGHTINGCAPS structure.
dwCaps
Specifies flags describing the capabilities of the lighting module. The following flags are defined:
Value | Meaning
D3DLIGHTCAPS_DIRECTIONAL | Directional lights are supported.
D3DLIGHTCAPS_GLSPOT | OpenGL-style spotlights are supported.
D3DLIGHTCAPS_PARALLELPOINT | Parallel-point lights are supported.
D3DLIGHTCAPS_POINT | Point lights are supported.
D3DLIGHTCAPS_SPOT | Spotlights are supported.

dwLightingModel
Specifies flags indicating whether the lighting model is RGB or monochrome. The following flags are defined:
Value | Meaning
D3DLIGHTINGMODEL_MONO | The lighting model is monochromatic.
D3DLIGHTINGMODEL_RGB | The lighting model is RGB.

dwNumLights
Specifies the number of lights that can be handled.

Comments

This structure has been replaced by D3DCAPS8 (see the DirectX 8.0 SDK documentation) for DirectX 8.0 and later runtimes, but is required for legacy runtime (DirectX 7.0 and earlier) compatibility. See Reporting DirectX 8.0 Style Direct3D Capabilities for details.

This structure is a member of the D3DDEVICEDESC_V1 structure.


D3DPRIMCAPS

Obsolete in DirectX 8.0 and later versions; see Comments.

The D3DPRIMCAPS structure defines the capabilities for each primitive type.

typedef struct _D3DPrimCaps {
    DWORD  dwSize;
    DWORD  dwMiscCaps;
    DWORD  dwRasterCaps;
    DWORD  dwZCmpCaps;
    DWORD  dwSrcBlendCaps;
    DWORD  dwDestBlendCaps;
    DWORD  dwAlphaCmpCaps;
    DWORD  dwShadeCaps;
    DWORD  dwTextureCaps;
    DWORD  dwTextureFilterCaps;
    DWORD  dwTextureBlendCaps;
    DWORD  dwTextureAddressCaps;
    DWORD  dwStippleWidth;
    DWORD  dwStippleHeight;
} D3DPRIMCAPS, *LPD3DPRIMCAPS;
‹ ›

Members

dwSize
Specifies the size, in bytes, of the D3DPRIMCAPS structure.
dwMiscCaps
Specifies the general capabilities for this primitive. This member can be one or more of the following:
Value | Meaning
D3DPMISCCAPS_CONFORMANT | The device conforms to the OpenGL® standard.
D3DPMISCCAPS_CULLCCW | The driver supports counterclockwise culling through the D3DRENDERSTATE_CULLMODE render state. (This applies only to triangle primitives.) This corresponds to the D3DCULL_CCW enumerator of the D3DCULL enumerated type.
D3DPMISCCAPS_CULLCW | The driver supports clockwise triangle culling through the D3DRENDERSTATE_CULLMODE render state. (This applies only to triangle primitives.) This corresponds to the D3DCULL_CW enumerator of the D3DCULL enumerated type.
D3DPMISCCAPS_CULLNONE | The driver does not perform triangle culling. This corresponds to the D3DCULL_NONE enumerator of the D3DCULL enumerated type.
D3DPMISCCAPS_LINEPATTERNREP The driver can handle values other than 1 in the wRepeatFactor member of the D3DLINEPATTERN structure. (This applies only to line-drawing primitives.)

D3DPMISCCAPS_LINEPATTERNREP and D3DPRASTERCAPS_PAT must be set consistently (both on or both off).
D3DPMISCCAPS_MASKPLANES | The device can perform a bitmask of color planes.
D3DPMISCCAPS_MASKZ | The device can enable and disable modification of the z-buffer on pixel operations.

dwRasterCaps
Contains information on raster-drawing capabilities. This member can be one or more of the following:
Value | Meaning
D3DPRASTERCAPS_ANISOTROPY | The device supports anisotropic filtering. For more information, see D3DTSS_MAXANISOTROPY in the DirectX SDK documentation.
D3DPRASTERCAPS_ANTIALIASEDGES | The device can antialias lines forming the convex outline of objects. For more information, see D3DRENDERSTATE_EDGEANTIALIAS in the DirectX SDK documentation.
D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT | The device supports antialiasing that is dependent on the sort order of the polygons (back-to-front or front-to-back). The application must draw polygons in the right order for antialiasing to occur. For more information, see the D3DANTIALIASMODE enumerated type in the DirectX SDK documentation.
D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT | The device supports antialiasing that is not dependent on the sort order of the polygons. For more information, see the D3DANTIALIASMODE enumerated type in the DirectX SDK documentation.
D3DPRASTERCAPS_DITHER | The device can dither to improve color resolution through the D3DRENDERSTATE_DITHERENABLE render state.
D3DPRASTERCAPS_FOGRANGE | The device supports range-based fog, in which the distance of an object from the viewer, rather than the depth of the object (its z-coordinate), is used to compute fog effects in the scene. For more information, see D3DRENDERSTATE_RANGEFOGENABLE in the DirectX SDK documentation.
D3DPRASTERCAPS_FOGTABLE | The device calculates the fog value by referring to a look-up table containing fog values that are indexed to the depth of a given pixel. For more information, see D3DRENDERSTATE_FOGCOLOR, D3DRENDERSTATE_FOGDENSITY, D3DRENDERSTATE_FOGENABLE, D3DRENDERSTATE_FOGEND, D3DRENDERSTATE_FOGSTART, and D3DRENDERSTATE_FOGTABLEMODE in the DirectX SDK documentation.
D3DPRASTERCAPS_FOGVERTEX | The device calculates the fog value during the lighting operation, places the value into the alpha component of the D3DCOLOR value given for the specular member of the D3DTLVERTEX structure (defined in the Direct3D SDK documentation), and interpolates the fog value during rasterization. For more information, see D3DRENDERSTATE_FOGCOLOR, D3DRENDERSTATE_FOGDENSITY, D3DRENDERSTATE_FOGENABLE, D3DRENDERSTATE_FOGEND, D3DRENDERSTATE_FOGSTART, and D3DRENDERSTATE_FOGVERTEXMODE in the DirectX SDK documentation.
D3DPRASTERCAPS_PAT The driver can perform patterned drawing (lines or fills with D3DRENDERSTATE_LINEPATTERN or one of the D3DRENDERSTATE_STIPPLEPATTERN render states) for the primitive being queried.

D3DPRASTERCAPS_PAT and D3DPMISCCAPS_LINEPATTERNREP must be set consistently (both on or both off).
D3DPRASTERCAPS_ROP2 | The device can support raster operations other than R2_COPYPEN.
D3DPRASTERCAPS_STIPPLE | The device can stipple polygons to simulate translucency.
D3DPRASTERCAPS_SUBPIXEL | The device performs subpixel placement of z, color, and texture data, rather than working with the nearest-integer pixel coordinate. This helps avoid bleedthrough due to z imprecision, and jitter of color and texture values for pixels. Note that there is no corresponding state that can be enabled and disabled; the device either performs subpixel placement or it does not, and this bit is present only so that the Direct3D client can better determine what the rendering quality will be.
D3DPRASTERCAPS_SUBPIXELX | The device is subpixel-accurate along the x-axis only, and is clamped to an integer y-axis scan line. For information about subpixel accuracy, see the previously mentioned definition of D3DPRASTERCAPS_SUBPIXEL.
D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT | The hardware can perform translucency without sorting. This is an offshoot of the A buffer technique for antialiasing.
D3DPRASTERCAPS_WBUFFER | The device supports w-buffering.
D3DPRASTERCAPS_WFOG | The device supports w-based fog.
D3DPRASTERCAPS_XOR | The device can support XOR operations. If this flag is not set but D3DPRASTER_ROP2 is set, then XOR operations must still be supported.
D3DPRASTERCAPS_ZBIAS | The device supports z-bias values, integer values assigned to polygons to allow physically coplanar polygons to appear separate. For more information, see D3DRENDERSTATE_ZBIAS in the DirectX SDK documentation.
D3DPRASTERCAPS_ZBUFFERLESSHSR | The device can perform hidden-surface removal (HSR) without requiring the application to sort polygons, and without requiring the allocation of a z-buffer. This leaves more video memory for textures. The method used to perform HSR is hardware-dependent and is transparent to the application. Z-buffer-less HSR is performed if no z-buffer surface is attached to the rendering target surface and the z-buffer comparison test is enabled (that is, when the state value associated with the D3DRENDERSTATE_ZENABLE render state value is set to TRUE).
D3DPRASTERCAPS_ZFOG | The device supports z based fog.
D3DPRASTERCAPS_ZTEST | The device can perform z-test operations. This effectively renders a primitive and indicates whether any z pixels would have been rendered.

dwZCmpCaps
Specifies Z-buffer comparison functions that the driver can perform through the D3DRENDERSTATE_ZFUNC render state. This member can be one or more of the following:
Comparison Function | Description
D3DPCMPCAPS_ALWAYS | Always pass the z test.
D3DPCMPCAPS_EQUAL | Pass the z test if the new z equals the current z.
D3DPCMPCAPS_GREATER | Pass the z test if the new z is greater than the current z.
D3DPCMPCAPS_GREATEREQUAL | Pass the z test if the new z is greater than or equal to the current z.
D3DPCMPCAPS_LESS | Pass the z test if the new z is less than the current z.
D3DPCMPCAPS_LESSEQUAL | Pass the z test if the new z is less than or equal to the current z.
D3DPCMPCAPS_NEVER | Always fail the z test.
D3DPCMPCAPS_NOTEQUAL | Pass the z test if the new z does not equal the current z.

dwSrcBlendCaps
Specifies source blending capabilities supported by the driver through the D3DRENDERSTATE_SRCBLEND render state. This member can be one or more of the following values. (The RGBA values of the source and destination are indicated with the subscripts s and d.)
Value | Meaning
D3DPBLENDCAPS_BOTHINVSRCALPHA | Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As) and destination blend factor is (As, As, As, As); the destination blend selection is overridden.
D3DPBLENDCAPS_BOTHSRCALPHA | Source blend factor is (As, As, As, As) and destination blend factor is (1 - As, 1 - As, 1 - As, 1 - As); the destination blend selection is overridden.
D3DPBLENDCAPS_DESTALPHA | Blend factor is (Ad, Ad, Ad, Ad).
D3DPBLENDCAPS_DESTCOLOR | Blend factor is (Rd, Gd, Bd, Ad).
D3DPBLENDCAPS_INVDESTALPHA | Blend factor is (1 - Ad, 1 - Ad, 1 - Ad, 1 - Ad).
D3DPBLENDCAPS_INVDESTCOLOR | Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad).
D3DPBLENDCAPS_INVSRCALPHA | Blend factor is (1 - As, 1 - As, 1 - As, 1 - As).
D3DPBLENDCAPS_INVSRCCOLOR | Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As).
D3DPBLENDCAPS_ONE | Blend factor is (1, 1, 1, 1).
D3DPBLENDCAPS_SRCALPHA | Blend factor is (As, As, As, As).
D3DPBLENDCAPS_SRCALPHASAT | Blend factor is (f, f, f, 1); f = min(As, 1 - Ad).
D3DPBLENDCAPS_SRCCOLOR | Blend factor is (Rs, Gs, Bs, As).
D3DPBLENDCAPS_ZERO | Blend factor is (0, 0, 0, 0).

dwDestBlendCaps
Specifies destination blending capabilities supported by the driver through the D3DRENDERSTATE_DESTBLEND render state. This member can be the same capabilities that are defined for the dwSrcBlendCaps member.
dwAlphaCmpCaps
Specifies alpha-test comparison functions that the driver can perform. This member uses the same comparison functions as are defined for the dwZCmpCaps member. If the dwAlphaCmpCaps member of the D3DPRIMCAPS structure is 0, the driver does not support alpha test render states D3DRENDERSTATE_ALPHAFUNC, D3DRENDERSTATE_ALPHAREF, and D3DRENDERSTATE_ALPHATESTENABLE.
dwShadeCaps
Specifies shading operations that the device can perform. It is assumed, in general, that if a device supports a given command (such as D3DOP_TRIANGLE) at all, it supports the D3DSHADE_FLAT mode (as specified in the D3DSHADEMODE enumerated type in the DirectX SDK documentation). This flag specifies whether the driver can also support Gouraud and Phong shading and whether alpha color components are supported for each of the three color-generation modes. When alpha components are not supported in a given mode, the alpha value of colors generated in that mode is implicitly 255. This is the maximum possible alpha (that is, the alpha component is at full intensity).

The color, specular highlights, fog, and alpha interpolants of a triangle each have capability flags that an application can use to find out how they are implemented by the device driver. These are modified by the shade mode and color model, and by whether the alpha component of a color is blended or stippled.

This member can be one or more of values listed in the following table. Related flags are grouped together in this table.
Value Meaning
D3DPSHADECAPS_ALPHAFLATBLEND
D3DPSHADECAPS_ALPHAFLATSTIPPLED 		The device can support an alpha component for flat-blended and stippled (D3DRENDERSTATE_STIPPLEDALPHA) transparency, respectively (the D3DSHADE_FLAT state for the D3DSHADEMODE enumerated type). In these modes, the alpha color component for a primitive is provided as part of the color for the first vertex of the primitive.
D3DPSHADECAPS_ALPHAGOURAUDBLEND
D3DPSHADECAPS_ALPHAGOURAUDSTIPPLED 		The device can support an alpha component for Gouraud blended and stippled (D3DRENDERSTATE_STIPPLEDALPHA) transparency, respectively (the D3DSHADE_GOURAUD state for the D3DSHADEMODE enumerated type). In these modes, the alpha color component for a primitive is provided at vertices and interpolated across a face along with the other color components.
D3DPSHADECAPS_ALPHAPHONGBLEND
D3DPSHADECAPS_ALPHAPHONGSTIPPLED 		The device can support an alpha component for Phong-blended and stippled (D3DRENDERSTATE_STIPPLEDALPHA) transparency, respectively (the D3DSHADE_PHONG state for the D3DSHADEMODE enumerated type). In these modes, vertex parameters are reevaluated on a per-pixel basis, applying lighting effects for the red, green, and blue color components.
D3DPSHADECAPS_COLORFLATMONO
D3DPSHADECAPS_COLORFLATRGB 		The device can support colored flat shading in the D3DCOLOR_MONO and D3DCOLOR_RGB color models, respectively. In these modes, the color component for a primitive is provided as part of the color for the first vertex of the primitive. In monochromatic lighting modes, only the blue component of the color is interpolated; in RGB lighting modes, of course, the red, green, and blue components are interpolated.
D3DPSHADECAPS_COLORGOURAUDMONO
D3DPSHADECAPS_COLORGOURAUDRGB 		The device can support colored Gouraud shading in the D3DCOLOR_MONO and D3DCOLOR_RGB color models, respectively. In these modes, the color component for a primitive is provided at vertices and interpolated across a face along with the other color components. In monochromatic lighting modes, only the blue component of the color is interpolated; in RGB lighting modes, of course, the red, green, and blue components are interpolated.
D3DPSHADECAPS_COLORPHONGMONO
D3DPSHADECAPS_COLORPHONGRGB 		The device can support colored Phong shading in the D3DCOLOR_MONO and D3DCOLOR_RGB color models, respectively. In these modes, vertex parameters are reevaluated on a per-pixel basis. Lighting effects are applied for the red, green, and blue color components in RGB mode, and for the blue component only for monochromatic mode.
D3DPSHADECAPS_FOGFLAT
D3DPSHADECAPS_FOGGOURAUD,
D3DPSHADECAPS_FOGPHONG 		The device can support fog in the flat, Gouraud, and Phong shading models, respectively.
D3DPSHADECAPS_SPECULARFLATMONO
D3DPSHADECAPS_SPECULARFLATRGB 		The device can support specular highlights through the D3DRENDERSTATE_SPECULARENABLE render state in flat shading in the D3DCOLOR_MONO and D3DCOLOR_RGB color models, respectively.
D3DPSHADECAPS_SPECULARGOURAUDMONO
D3DPSHADECAPS_SPECULARGOURAUDRGB 		The device can support specular highlights through the D3DRENDERSTATE_SPECULARENABLE render state in Gouraud shading in the D3DCOLOR_MONO and D3DCOLOR_RGB color models, respectively.
D3DPSHADECAPS_SPECULARPHONGMONO
D3DPSHADECAPS_SPECULARPHONGRGB 		The device can support specular highlights through the D3DRENDERSTATE_SPECULARENABLE render state in Phong shading in the D3DCOLOR_MONO and D3DCOLOR_RGB color models, respectively. Phong shading is not supported for DirectX 2.0.

Most hardware drivers should expose the D3DPSHADECAPS_COLORFLATRGB and D3DPSHADECAPS_COLORGOURAUDRGB capabilities. Hardware that supports intensity (grayscale) lighting (see D3DRENDERSTATE_MONOENABLE for more details) should also expose the D3DPSHADECAPS_COLORFLATMONO and D3DSHADECAPS_COLORGOURAUDMONO capabilities.

dwTextureCaps
Specifies miscellaneous texture-mapping capabilities. This member can be one or more of the following:
Value | Meaning
D3DPTEXTURECAPS_ALPHA | RGBA textures are supported in the D3DTEX_DECAL and D3DTEX_MODULATE texture filtering modes. If this capability is not set, then only RGB textures are supported in those modes. Regardless of whether this flag is set, alpha must always be supported in the D3DTEX_DECAL_MASK, D3DTEX_DECAL_ALPHA, and D3DTEX_MODULATE_ALPHA filtering modes whenever those filtering modes are available.
D3DPTEXTURECAPS_ALPHAPALETTE | Palletized texture surfaces whose palettes contain alpha information are supported (see the DDPCAPS_ALPHA flag in the DDCAPS structure in the DirectDraw SDK documentation).
D3DPTEXTURECAPS_BORDER | Texture mapping along borders is supported.
D3DPTEXTURECAPS_COLORKEYBLEND | The device is capable of performing color key blending.
D3DPTEXTURECAPS_CUBEMAP | The device is capable of supporting cube environment mapping.
D3DPTEXTURECAPS_PERSPECTIVE | Perspective correction is supported. See D3DRENDERSTATE_TEXTUREPERSPECTIVE in the DirectX SDK documentation.
D3DPTEXTURECAPS_POW2 | All non-MIP mapped textures have widths and heights specified as powers of two. (Note that all MIP mapped textures must always have dimensions that are powers of two.)
D3DPTEXTURECAPS_PROJECTED | The device can divide transformed texture coordinates by the COUNTth texture coordinate. In other words, the device can do D3DTTFF_PROJECTED. See D3DTEXTURETRANSFORMFLAGS in the DirectX SDK documentation.
D3DPTEXTURECAPS_NONPOW2CONDITIONAL | The device can use non-POW2 textures if the D3DTADDRESS_CLAMP enumerator of the D3DTEXTUREADDRESS enumerated type is set for this texture's stage, D3DRENDERSTATE_WRAPN is zero for this texture's coordinates, or MIP mapping and anisotroptic filtering are disabled.
D3DPTEXTURECAPS_SQUAREONLY | All textures must be square.
D3DPTEXTURECAPS_TEXREPEATNOTSCALESBYSIZE | Texture indexes are not scaled by the texture size before interpolation.
D3DPTEXTURECAPS_TEXTURETRANSFORM | The device is capable of doing texture transforms.
D3DPTEXTURECAPS_TRANSPARENCY | Texture transparency is supported. (Only those texels that are not the current transparent color are drawn.)

dwTextureFilterCaps
Specifies texture-mapping capabilities. This member can be one or more of the following:
Value | Meaning
D3DPTFILTERCAPS_LINEAR | Bilinear filtering is supported. A weighted average of a 2-by-2 area of texels surrounding the desired pixel is used. This applies to both zooming in and zooming out. If either zooming in or zooming out is supported, then both must be supported.
D3DPTFILTERCAPS_LINEARMIPLINEAR | Trilinear interpolation between MIP maps is supported. Performs bilinear filtering on the two nearest MIP maps, then interpolates linearly between the two colors to determine the final color.
D3DPTFILTERCAPS_LINEARMIPNEAREST | Linear interpolation between two point sampled MIP maps is supported. Chooses the nearest texel from the two closest MIP map levels, then performs linear interpolation between them.
D3DPTFILTERCAPS_MAGFAFLATCUBIC | Per-stage flat-cubic filtering for magnifying textures is supported. The flat-cubic magnification filter is represented by the D3DTFG_FLATCUBIC member of the D3DTEXTUREMAGFILTER enumeration.
D3DPTFILTERCAPS_MAGFANISOTROPIC | Per-stage anisotropic filtering for magnifying textures is supported. The anisotropic magnification filter is represented by the D3DTFG_ANISOTROPIC member of the D3DTEXTUREMAGFILTER enumeration.
D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC | Per-stage Gaussian-cubic filtering for magnifying textures is supported. The Gaussian-cubic magnification filter is represented by the D3DTFG_GAUSSIANCUBIC member of the D3DTEXTUREMAGFILTER enumeration.
D3DPTFILTERCAPS_MAGFLINEAR Per-stage bilinear-interpolation filtering for magnifying textures is supported. The bilinear-interpolation magnification filter is represented by the D3DTFG_LINEAR member of the D3DTEXTUREMAGFILTER enumeration.
Specifies that bilinear filtering on the magnify filter is supported.
D3DPTFILTERCAPS_MAGFPOINT | Per-stage point-sampled filtering for magnifying textures is supported. The point-sample magnification filter is represented by the D3DTFG_POINT member of the D3DTEXTUREMAGFILTER enumeration.
D3DPTFILTERCAPS_MINFANISOTROPIC | Per-stage anisotropic filtering for minifying textures is supported. The anisotropic minification filter is represented by the D3DTFN_ANISOTROPIC member of the D3DTEXTUREMINFILTER enumeration.
D3DPTFILTERCAPS_MINFLINEAR | Per-stage bilinear-interpolation filtering for minifying textures is supported. The bilinear minification filter is represented by the D3DTFN_LINEAR member of the D3DTEXTUREMINFILTER enumeration.
D3DPTFILTERCAPS_MINFPOINT | Per-stage point-sampled filtering for minifying textures is supported. The point-sample minification filter is represented by the D3DTFN_POINT member of the D3DTEXTUREMINFILTER enumeration.
D3DPTFILTERCAPS_MIPFLINEAR | Per-stage trilinear-interpolation filtering for MIP maps (that is, bi-linear filtering between MIP levels) is supported. The trilinear-interpolation MIP mapping filter is represented by the D3DTFP_LINEAR member of the D3DTEXTUREMIPFILTER enumeration.
D3DPTFILTERCAPS_MIPFPOINT | Per-stage point-sampled filtering for MIP maps is supported. The point-sample MIP mapping filter is represented by the D3DTFP_POINT member of the D3DTEXTUREMIPFILTER enumeration.
D3DPTFILTERCAPS_MIPLINEAR | Nearest MIP mapping, with bilinear filtering applied to the result is supported. Chooses the texel from the appropriate MIP map that has the nearest coordinates, then performs a weighted average with the four surrounding texels to determine the final color.
D3DPTFILTERCAPS_MIPNEAREST | Nearest MIP mapping is supported. Chooses the texel from the appropriate MIP map with coordinates nearest to the desired pixel value.
D3DPTFILTERCAPS_NEAREST | Point sampling is supported. The texel with coordinates nearest to the desired pixel value is used. This applies to both zooming in and zooming out. If either zooming in or zooming out is supported, then both must be supported.

dwTextureBlendCaps
Specifies texture-blending capabilities. See the D3DRENDERSTATE_TEXTUREMAPBLEND enumerated type for discussions of the various texture-blending modes. This member can be one or more of the following:
Value | Meaning
D3DPTBLENDCAPS_ADD | Add mode texture-blending is supported (D3DTBLEND_COPY from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_COPY | Copy mode texture-blending is supported (D3DTBLEND_COPY from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_DECAL | Decal texture-blending mode is supported (D3DTBLEND_DECAL from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_DECALALPHA | Decal-alpha texture-blending mode is supported (D3DTBLEND_DECALALPHA from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_DECALMASK | Decal-mask texture-blending mode is supported (D3DTBLEND_DECALMASK from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_MODULATE | Modulate-texture-blending mode is supported (D3DTBLEND_MODULATE from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_MODULATEALPHA | Modulate-alpha texture-blending mode is supported (D3DTBLEND_MODULATEALPHA from the D3DTEXTUREBLEND enumerated type).
D3DPTBLENDCAPS_MODULATEMASK | Modulate-mask texture-blending mode is supported (D3DTBLEND_MODULATEMASK from the D3DTEXTUREBLEND enumerated type).

dwTextureAddressCaps
Specifies the texture-addressing capabilities. This member can be one or more of the following, corresponding to D3DTEXTUREADDRESS texture-addressing modes:
Value | Meaning
D3DPTADDRESSCAPS_BORDER | The device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DTSS_BORDERCOLOR texture stage state. This ability corresponds to the D3DTADDRESS_BORDER texture-addressing mode.
D3DPTADDRESSCAPS_CLAMP | The device can clamp textures to addresses. This ability corresponds to the D3DTADDRESS_CLAMP texture-addressing mode.
D3DPTADDRESSCAPS_INDEPENDENTUV | The device can separate the texture-addressing modes of the U and V coordinates of the texture. This ability corresponds to the D3DTSS_ADDRESSU and D3DTSS_ADDRESSV texture stage states.
D3DPTADDRESSCAPS_MIRROR | The device can mirror textures to addresses. This ability corresponds to the D3DTADDRESS_MIRROR texture-addressing mode.
D3DPTADDRESSCAPS_WRAP | The device can wrap textures to addresses. This ability corresponds to the D3DTADDRESS_WRAP texture-addressing mode.

dwStippleWidth, dwStippleHeight
Specify the maximum width and height of the supported stipple (up to 32-by-32).

Comments

This structure has been replaced by D3DCAPS8 (see the DirectX 8.0 SDK documentation) for DirectX 8.0 and later runtimes, but is required for legacy runtime (DirectX 7.0 and earlier) compatibility. See Reporting DirectX 8.0 Style Direct3D Capabilities for details.

This structure is used when a device is created and when the capabilities of a device are queried. It defines several members in the D3DDEVICEDESC_V1 structure.


D3DTRANSFORMCAPS

Obsolete in DirectX 8.0 and later versions.

D3DTRANSFORMCAPS structure describes the transform capabilities of a device.

typedef struct _D3DTRANSFORMCAPS {
    DWORD  dwSize;
    DWORD  dwCaps;
} D3DTRANSFORMCAPS, *LPD3DTRANSFORMCAPS;

Members

dwSize
Specifies the size, in bytes, of the D3DTRANSFORMCAPS structure.
dwCaps
Specifies flags describing the capabilities of the lighting module. The following flag is defined:
D3DTRANSFORMCAPS_CLIP
The device can do clipping operations while transforming.

Comments

This structure has been replaced by D3DCAPS8 (see the DirectX 8.0 SDK documentation) for DirectX 8.0 and later runtimes, but is required for legacy runtime (DirectX 7.0 and earlier) compatibility. See Reporting DirectX 8.0 Style Direct3D Capabilities for details.

This structure is a member of the D3DDEVICEDESC_V1 structure.


Direct3D Driver Enumerations

This section describes the enumerated types that are used by Direct3D® drivers. Enumerated types that are used by both Direct3D drivers and applications, such as D3DRENDERSTATETYPE, are described in the DirectX SDK documentation.

Direct3D DDI Header Files, Sample Code, and References lists the include files that define Direct3D enumerated types.


D3DNTHAL_DP2OPERATION

D3DNTHAL_DP2OPERATION is type defined as D3DHAL_DP2OPERATION in dx95type.h, the shorter form is used here for clarity. Either form is equally valid on Windows 2000 and later implementations, but only the shorter form can be used on Windows 98/Me.


D3DHAL_DP2OPERATION

The D3DHAL_DP2OPERATION enumerated type specifies the D3dDrawPrimitives2 operation in the bCommand member of the D3DHAL_DP2COMMAND structure. The operations are enumerated below.

Note that since the D3DNTDP2OP_XXX format is type defined as D3DDP2OP_XXX internally in the Windows® DDK, the shorter form is used here for clarity. Either form is valid on Windows 2000 and later implementations, but only the shorter form can be used on Windows 98/Me.

Primitive-Rendering Enumerators

Operation | Meaning
D3DDP2OP_CLIPPEDTRIANGLEFAN | DirectX 8.0 and later versions only. This token is sent to the driver to draw transformed, clipped triangle fans. This token is a replacement for the DirectX 7.0 tokens that used inline vertices in the command stream. The triangle fans are specified by one or more D3DHAL_CLIPPEDTRIANGLEFAN structures.
D3DDP2OP_DRAWINDEXEDPRIMITIVE | DirectX 8.0 and later versions only. This token is sent to the driver to draw indexed primitives. D3DDP2OP_DRAWINDEXEDPRIMITIVE2 is used if the vertex data has been transformed by the runtime. The indexed primitives are specified by one or more D3DHAL_DP2DRAWINDEXEDPRIMITIVE structures.
D3DDP2OP_DRAWINDEXEDPRIMITIVE2 | DirectX 8.0 and later versions only. This token is sent to the driver to draw indexed primitives if the vertex data has been transformed by the runtime. Stream zero contains transform and lit vertices and is the only stream that should be accessed. The indexed primitives are specified by one or more D3DHAL_DP2DRAWINDEXEDPRIMITIVE2 structures.
D3DDP2OP_DRAWPRIMITIVE | DirectX 8.0 and later versions only. This token is sent to the driver to draw non-indexed primitives. D3DDP2OP_DRAWPRIMITIVE2 is used if the vertex data has been transformed by the runtime. The primitives are specified by one or more D3DHAL_DP2DRAWPRIMITIVE structures.
D3DDP2OP_DRAWPRIMITIVE2 | DirectX 8.0 and later versions only. This token is sent to the driver to draw non-indexed primitives where the vertex data has been transformed by the runtime. Stream zero contains transform and lit vertices and is the only stream that should be accessed. The primitives are specified by one or more D3DHAL_DP2DRAWPRIMITIVE2 structures.
D3DDP2OP_DRAWRECTPATCH | DirectX 8.0 and later versions only. This token is sent to the driver to draw a rectangular patch. This token is sent to the driver when drawing a new patch, drawing a cached patch or to update the specification of a previously defined patch. The patches are specified by one or more D3DHAL_DP2DRAWRECTPATCH structures.
D3DDP2OP_DRAWTRIPATCH | DirectX 8.0 and later versions only. This token is sent to the driver to draw a triangular patch. This token is sent to the driver when drawing a new patch, drawing a cached patch or to update the specification of a previously defined patch. The patches are specified by one or more D3DHAL_DP2DRAWTRIPATCH structures.
D3DDP2OP_INDEXEDLINELIST | Draws a list of lines, with each line specified by a pair of vertex indexes. The indexed line list is specified by one or more D3DHAL_DP2INDEXEDLINELIST structures.
D3DDP2OP_INDEXEDLINELIST2 | Draws a list of lines. Each line is specified by a pair of vertex indexes, with each offset from the beginning of the vertex buffer by a fixed amount. The indexed line list is specified by one or more D3DHAL_DP2INDEXEDLINELIST structures.
D3DDP2OP_INDEXEDLINESTRIP | Draws a connected strip of lines defined by a sequence of vertex indexes. The indexed line strip is specified by a D3DHAL_DP2INDEXEDLINESTRIP structure.
D3DDP2OP_INDEXEDTRIANGLEFAN | Draws a triangle fan. The triangle fan is specified by a sequence of vertex indexes. The indexed triangle fan is specified by a D3DHAL_DP2INDEXEDTRIANGLEFAN structure.
D3DDP2OP_INDEXEDTRIANGLELIST | Draws a list of triangles. Each triangle is specified by three indexes into the vertex buffer, one index per triangle vertex. The triangle list is specified by one or more D3DHAL_DP2INDEXEDTRIANGLELIST structures.
D3DDP2OP_INDEXEDTRIANGLELIST2 | Draws a list of triangles. Each triangle is specified by three indexes into the vertex buffer, one index per triangle vertex. The triangle list is specified by one or more D3DHAL_DP2INDEXEDTRIANGLELIST2 structures.
D3DDP2OP_INDEXEDTRIANGLESTRIP | Draws a connected strip of triangles that are specified by a sequence of vertex indexes. The three most current vertex indexes are used to draw each triangle. The indexed triangle list is specified by a D3DHAL_DP2INDEXEDTRIANGLELIST structure.
D3DDP2OP_LINELIST | Draws a list of lines. Each line is specified by a pair of vertices. The vertices are processed in sequential order starting at an initial specified vertex index. The line list is specified by a D3DHAL_DP2LINELIST structure.
D3DDP2OP_LINELIST_IMM | Draws a set of lines. Each line is specified by a pair of vertices stored in the command stream (immediate data). The wPrimitiveCount member of the D3DHAL_DP2COMMAND structure specifies how many pairs of vertices follow. The type and size of the vertices are determined by the dwVertexType member of the D3DHAL_DRAWPRIMITIVES2DATA structure.
D3DDP2OP_LINESTRIP | Draws a connected strip of lines defined by a sequence of vertices starting at an initial specified vertex index. The line strip is specified by a D3DHAL_DP2LINESTRIP structure.
D3DDP2OP_POINTS | Draws a list of indexed or non-indexed points. Each list is specified by one or more D3DHAL_DP2POINTS structures.
D3DDP2OP_TRIANGLEFAN | Draws a triangle fan. The fan is specified by a sequence of vertices that start at an initial specified vertex index. The triangle fan is specified by a D3DHAL_DP2TRIANGLEFAN structure.
D3DDP2OP_TRIANGLEFAN_IMM | Draws a triangle fan. The fan is specified by a sequence of vertices stored in the command stream (immediate data). The wPrimitiveCount member of the D3DHAL_DP2COMMAND structure specifies the number of triangles to render. The type and size of the vertices are specified by the dwVertexType member of the D3DHAL_DRAWPRIMITIVES2DATA structure.
D3DDP2OP_TRIANGLELIST | Draws a list of triangles. Each triangle is specified by three vertices that are processed starting at an initial specified vertex index. The triangles are processed in sequential order. The triangle list is specified by a D3DHAL_DP2TRIANGLELIST structure.
D3DDP2OP_TRIANGLESTRIP | Draws a connected strip of triangles. Each triangle is specified by a sequence of vertices starting at an initial specified vertex index. The three most current vertices are used to draw each triangle. The triangle list is specified by a D3DHAL_DP2TRIANGLESTRIP structure.

Non-Primitive-Rendering Enumerators

Operation | Meaning
D3DDP2OP_BUFFERBLT | DirectX 8.0 and later versions only. Specifies a blt operation from a source vertex or index buffer to a destination vertex or index buffer. It is specified by one or more D3DHAL_DP2BUFFERBLT structures.
D3DDP2OP_CLEAR | Specifies a clear operation. Replaces the Clear and Clear2 callbacks. See D3DHAL_DP2CLEAR.
D3DDP2OP_CREATELIGHT | Creates a light. See D3DHAL_DP2CREATELIGHT.
D3DDP2OP_CREATEPIXELSHADER | DirectX 8.0 and later versions only. This token is sent to the driver when a pixel shader is created. This token gives the driver the opportunity to convert the pixel shader code into a hardware specific format and associate this information with the given shader handle. See D3DHAL_DP2CREATEPIXELSHADER.
D3DDP2OP_CREATEVERTEXSHADER | DirectX 8.0 and later versions only. This token is sent to the driver when a vertex shader is created. This token gives the driver the opportunity to convert the vertex shader declaration and code into a hardware specific format and associate this information with the given shader handle. See D3DHAL_DP2CREATEVERTEXSHADER.
D3DDP2OP_DELETEPIXELSHADER | DirectX 8.0 and later versions only. This token is sent to the driver to notify the driver of the deletion of a pixel shader and to give the driver an opportunity to clean up any driver side resources associated with the given pixel shader. Note that this uses the same structure (D3DHAL_DP2PIXELSHADER) as D3DDP2OP_SETVPIXELSHADER.
D3DDP2OP_DELETEVERTEXSHADER | DirectX 8.0 and later versions only. This token is sent to the driver to notify the driver of the deletion of a vertex shader and to give the driver an opportunity to clean up any driver side resources associated with the given vertex shader. Note that this uses the same structure (D3DHAL_DP2VERTEXSHADER) as D3DDP2OP_SETVERTEXSHADER.
D3DDP2OP_EXT | Behavior not yet defined. See D3DHAL_DP2EXT.
D3DDP2OP_MULTIPLYTRANSFORM | Multiplies a current transform. See D3DHAL_DP2MULTIPLYTRANSFORM.
D3DDP2OP_RENDERSTATE | Specifies a render state change that requires processing. The rendering state to change is specified by one or more D3DHAL_DP2RENDERSTATE structures.
D3DDP2OP_SETCLIPPLANE | Specifies that a user-defined clip plane is being used. See D3DHAL_DP2SETCLIPPLANE.
D3DDP2OP_SETINDICES | DirectX 8.0 and later versions only. Sets the current index buffer. See D3DHAL_DP2SETINDICES.
D3DDP2OP_SETLIGHT | Specifies that a light is being set. See D3DHAL_DP2SETLIGHT.
D3DDP2OP_SETMATERIAL | Sets the properties for a material. D3DHAL_DP2SETMATERIAL is a D3DMATERIAL7 structure (described in the DirectX® SDK documentation) that is used to set the material properties.
D3DDP2OP_SETPALETTE | Specifies that the palette is being set for a texture. See D3DHAL_DP2SETPALETTE.
D3DDP2OP_SETPIXELSHADER | DirectX 8.0 and later versions only. This token is passed to the driver to set the current pixel shader. All subsequent drawing operations should use the given shader until another is selected. Note that this uses the same structure (D3DHAL_DP2PIXELSHADER) as D3DDP2OP_DELETEPIXELSHADER.
D3DDP2OP_SETPIXELSHADERCONST | DirectX 8.0 and later versions only. This token is passed to the driver to set one or more pixel shader constant registers. See D3DHAL_DP2SETPIXELSHADERCONST.
D3DDP2OP_SETPRIORITY | Sets the priority of a managed texture. See D3DHAL_DP2SETPRIORITY.
D3DDP2OP_SETRENDERTARGET | Sets the render target. Direct3D drivers must respond to this opcode exactly the same as with the older SetRenderTarget callback. See D3DHAL_DP2SETRENDERTARGET.
D3DDP2OP_SETSTREAMSOURCE | DirectX 8.0 and later versions only. Binds a vertex stream source to a vertex buffer. See D3DHAL_DP2SETSTREAMSOURCE.
D3DDP2OP_SETSTREAMSOURCEUM | DirectX 8.0 and later versions only. Binds a vertex stream source to a user memory buffer. See D3DHAL_DP2SETSTREAMSOURCEUM.
D3DDP2OP_SETTEXLOD | Indicates that the level of detail (LOD) for MIP maps is being set. See D3DHAL_DP2SETTEXLOD.
D3DDP2OP_SETTRANSFORM | Sets up a transform. See D3DHAL_DP2SETTRANSFORM.
D3DDP2OP_SETVERTEXSHADER | DirectX 8.0 and later versions only. This token is passed to the driver to set the current vertex shader. All subsequent drawing operations should use the given shader until another is selected. Note that this uses the same structure (D3DHAL_DP2VERTEXSHADER) as D3DDP2OP_DELETEVERTEXSHADER.
D3DDP2OP_SETVERTEXSHADERCONST | DirectX 8.0 and later versions only. This token is passed to the driver to set one or more vertex shader constant registers. See D3DHAL_DP2SETVERTEXSHADERCONST.
D3DDP2OP_STATESET | Specifies a stateset operation to perform. See D3DHAL_DP2STATESET.
D3DDP2OP_TEXBLT | Specifies a blt operation from a source texture to a destination texture. It is used as a more efficient alternative to the DirectDraw® Blt DDI. It is specified by one or more D3DHAL_DP2TEXBLT structures. Since Direct3D drivers maintain all the state necessary to do a blt (for example, texture handles and blending modes), a blt can be accomplished with just the information in the D3DDP2OP_TEXBLT opcode. This new token signals the driver that a texture has to be transferred from system memory into local or nonlocal video memory.
D3DDP2OP_TEXTURESTAGESTATE | Specifies a texture render state change that requires processing. The render state to change is specified by one or more D3DTEXTURESTAGESTATETYPE values following a D3DHAL_DP2COMMAND.
D3DDP2OP_UPDATEPALETTE | Specifies that a texture palette is to be updated. See D3DHAL_DP2UPDATEPALETTE.
D3DDP2OP_VIEWPORTINFO | Specifies the clipping rectangle that is used for guard-band clipping by guard-band aware drivers. The clipping rectangle (that is, the viewing rectangle) is specified by the D3DHAL_DP2VIEWPORTINFO structure.
D3DDP2OP_VOLUMEBLT | DirectX 8.0 and later versions only. Specifies a blt operation from a source volume texture to a destination volume texture. It is specified by one or more D3DHAL_DP2VOLUMEBLT structures.
D3DDP2OP_WINFO | Specifies the w range for w buffering. This range is specified by one or more D3DHAL_DP2WINFO structures.
D3DDP2OP_ZRANGE | Specifies the range of z values. See D3DHAL_DP2ZRANGE.


D3DOPCODE

The D3DOPCODE enumerated type is obsolete.

See D3DHAL_DP2OPERATION for current opcodes.


D3DRENDERSTATETYPE

The D3DRENDERSTATETYPE enumerated type lists a variety of attributes, or render states, that the driver uses when it performs graphics rendering. These attributes include such characteristics as whether alpha blending is enabled, whether dithering is enabled, whether Direct3D lighting is used, and the type of shading to be used.

Only render states that are specific to the DDK are included here. The render states accessible to DirectX applications are included in the DirectX SDK documentation.

Enumerator | Description
Miscellaneous Rendering
D3DRENDERSTATE_SCENECAPTURE | Specifies either begin scene information or end scene information for geometric data captured within a frame.
D3DRS_DELETERTPATCH | DirectX 8.0 and later versions only. Deletes a patch (rectangular or triangular).
Textures
D3DRENDERSTATE_EVICTMANAGEDTEXTURES | Determines whether textures are evicted from memory.

Comments

To update a particular render state, Direct3D stores information about the render state, and then calls the driver's D3dDrawPrimitives2 callback routine. The information provided to the driver enables it to:

  • Determine that it should update one or more render states.
  • Identify which render states to update, and what the new render state values should be.

Note that for certain render states to be honored, the driver must have previously set capability flags in the relevant member of the D3DPRIMCAPS structure.

In order to indicate a specific render state update, Direct3D inserts a D3DHAL_DP2COMMAND structure into the command buffer, setting the bCommand member of this structure to D3DDP2OP_RENDERSTATE, and setting the wStateCount member of the same structure to the number of render states to be updated.

Immediately following the D3DHAL_DP2COMMAND structure, Direct3D inserts one D3DHAL_DP2RENDERSTATE structure into the command buffer for each render state to be updated. The RenderState member of this structure identifies the render state to be changed; the new value of this render state is specified in either the dwState member (for DWORD values) or the fState member (for D3DVALUE values).

The following figure shows a portion of the command buffer containing a D3DDP2OP_RENDERSTATE command and two D3DHAL_DP2RENDERSTATE structures. The first of the three structures indicates that two render states are to be updated. The second structure indicates that the D3DRENDERSTATE_FILLMODE render state is to be changed to D3DFILL_SOLID. The third structure indicates that the D3DRENDERSTATE_SHADEMODE render state should be updated to D3DSHADE_GOURAUD.

Additional Notes

See the D3DTEXTURESTAGESTATETYPE, D3DTEXTUREOP, and D3DTEXTUREFILTER enumerated types in the DirectX SDK documentation for complete listings of all of the enabled render state types.

Some changes have been made to the D3DRENDERSTATETYPE enumerated type for DirectX 5.0 and beyond. D3DRENDERSTATE_BLENDENABLE has been removed completely although it is defined as D3DRENDERSTATE_ALPHABLENDENABLE in the d3dtypes.h header file. See D3DRENDERSTATE_COLORKEYENABLE for an explanation. The 128 integer values in the interval [128, 255] are reserved for texture coordinate wrap flags. These are constructed with the D3DWRAP_U and D3DWRAP_V macros. Using a flags word preserves forward compatibility with texture coordinates of higher dimension than 2D.

Multitexture macro ops and D3DRENDERSTATE_TEXTUREFACTOR override all of the per-texture stage blending controls (COLOR{OP,ARG1,ARG2} & ALPHA{OP,ARG1,ARG2}).


D3DRENDERSTATE_EVICTMANAGEDTEXTURES

The D3DRENDERSTATE_EVICTMANAGEDTEXTURES DDI render state is one value of the D3DRENDERSTATETYPE enumerated type. It is used to evict textures from memory.

Render State Value Type | Default Value
BOOL | None

Comments

This render state determines whether the driver evicts textures that it manages (as opposed to textures managed by the Direct3D runtime) from video memory. If the render state value is TRUE, the driver evicts the textures. Otherwise, the driver does not evict those textures.


D3DRENDERSTATE_SCENECAPTURE

The D3DRENDERSTATE_SCENECAPTURE render state is one value of the D3DRENDERSTATETYPE enumerated type. It replaces the legacy D3DHALCallbacks->D3dSceneCapture callback routine. This render state is handled along with the other render states in D3dDrawPrimitives2.

The driver responds to D3DRENDERSTATE_SCENECAPTURE by passing TRUE for begin scene information and FALSE for end scene information to capture geometric data within a frame.

See the permedia2 sample driver that ships with this DDK for an example implementation.

Render State Value Type | Default Value
BOOL | TRUE

Comments

Care must be taken in updating a driver that implements the legacy D3DHALCallbacks->D3dSceneCapture callback routine to one using the D3DRENDERSTATE_SCENECAPTURE render state. The D3DSceneCapture callback routine uses the constants D3DHAL_SCENE_CAPTURE_START and D3DHAL_SCENE_CAPTURE_END to indicate, respectively, the beginning and end of a scene. The values of these constants are, respectively, 0 and 1. If you use these constants in place of TRUE and FALSE in this render state, the meaning will be the exact opposite of what you intend.


D3DRS_DELETERTPATCH

The D3DRS_DELETERTPATCH DDI render state is one value of the D3DRENDERSTATETYPE enumerated type. It is used to delete rectangular or triangular patches from memory.

Render State Value Type | Default Value
DWORD | None

DirectX 8.0 and later versions only.

Comments

This render state notifies the driver that a patch is to be deleted. The value of this render state is the handle to the patch affected. All cached information should be freed and the handle should be removed from the driver’s patch handle table. This render state is not API visible, but is generated internally by the API call DeletePatch. This render state is sent to the driver only when patches are deleted by the API explicitly. All other patches should be cleaned up when the device is destroyed.


DirectX Video Acceleration Structures

The following sections describe the DirectX Video Acceleration structures:

DXVA_AYUVsample

DXVA_BlendCombination

DXVA_BufferDescription

DXVA_ConfigAlphaCombine

DXVA_ConfigAlphaLoad

DXVA_ConfigPictureDecode

DXVA_ConnectMode

DXVA_EncryptProtocolHeader

DXVA_Highlight

DXVA_MBctrl_I_HostResidDiff_1

DXVA_MBctrl_I_OffHostIDCT_1

DXVA_MBctrl_P_HostResidDiff_1

DXVA_MBctrl_P_OffHostIDCT_1

DXVA_MVvalue

DXVA_PictureParameters

DXVA_PicResample

DXVA_QmatrixData

DXVA_SliceInfo

DXVA_TCoef4Group

DXVA_TCoefSingle


DXVA_AYUVsample

The DirectX VA data structure used to specify the value of a color in Y, Cb, Cr color space and an associated opacity value. DXVA_AYUVsample is used for each sample in a DXVA AYUV blending surface and for OutsideYUVcolor in a DXVA_BlendCombination structure. The same data structure is also used for 16-entry AYUV alpha blending palettes

typedef struct _DXVA_AYUVsample {
  BYTE bSampleAlpha8;
  BYTE bY_Value;
  BYTE bCbValue;
  BYTE bCrValue;
} DXVA_AYUVsample, *LPDXVA_AYUVsample;

Members

bSampleAlpha8
The opacity of the sample. The value “0” indicates that the sample is transparent (so that the other entries have no effect on the resulting blended picture) and the value “255” indicates that the sample is opaque (so that the other entries completely determine the value of the resulting blended picture sample). For non-zero values of SampleAlpha8, the blend specified is to add (SampleAlpha8+1) times the graphic value to (255–SampleAlpha8) times the picture value and to the constant 128, and right-shift the result by eight places. For a zero value of SampleAlpha8, the blend specified is to use the picture value without alteration.
bY_Value
A color in Y color space (per ITU-T Rec. 601) as an unsigned quantity. Thus with BPP=8, the color Black is nominally specified by Y=16, Cb=Cr=128, and the color White is nominally specified by Y=235, Cb=Cr=128.
bCbValue
A color in Cb color space (per ITU-T Rec. 601) as an unsigned quantity. Thus with BPP=8, the color Black is nominally specified by Y=16, Cb=Cr=128, and the color White is nominally specified by Y=235, Cb=Cr=128.
bCrValue
A color in Cr color space (per ITU-T Rec. 601) as an unsigned quantity. Thus with BPP=8, the color Black is nominally specified by Y=16, Cb=Cr=128, and the color White is nominally specified by Y=235, Cb=Cr=128.

Note The width and height of the AYUV alpha blending surface are specified in the associated buffer description list..


DXVA_BlendCombination

The DirectX VA data structure that governs the generation of a blended picture from a source picture and a graphic image with accompanying alpha blending information. In the event that the source and destination pictures are not in 4:4:4 format, every second sample of the graphic blending information (i.e., the first, third, fifth, etc.) shall be applied to the subsampled source chrominance information in the vertical or horizontal direction as applicable to produce the blended result.

typedef struct _DXVA_BlendCombination {
  WORD  wPictureSourceIndex;
  WORD  wBlendedDestinationIndex;
  RECT  PictureSourceRect16thPel;
  RECT  PictureDestinationRect;
  RECT  GraphicSourceRect;
  RECT  GraphicDestinationRect;
  WORD  wBlendDelay;
  BYTE  bBlendOn;
  BYTE  bWholePlaneAlpha;
  DXVA_AYUVsample  OutsideYUVcolor;
} DXVA_BlendCombination, *LPDXVA_BlendCombination;

Members

wPictureSourceIndex
The index of the picture to be combined with the graphic. Shall be 0xFFFF if back-end hardware alpha blending is in use.
wBlendedDestinationIndex
The index of the combined picture to be created. Shall be 0xFFFF if back-end hardware alpha blending is in use. Shall not be equal to wPictureSourceIndex.
PictureSourceRect16thPel
The area of the source picture to be combined with the graphic, specified as a RECT data structure in units of 1/16th sample in the luminance component. In other words, the parameters in the RECT data structure are fixed-point representations which each have 28 bits before and 4 bits after the binary point. (This 1/16th sample accuracy allows PictureSourceRect16thPel to contain the same accuracy as the frame_centre_horizontal_offset and frame_centre_vertical_offset pan-scan parameters in MPEG-2.) If bConfigPictureResizing is “0”, all parameters in PictureSourceRect16thPel shall therefore be integer multiples of 16.

The following restrictions apply to the RECT parameters of PictureSourceRect16thPel:

  • “left” and “top” shall be greater than or equal to zero,
  • “right” and “bottom” shall be greater than or equal to “left” and “top”, respectively,
  • if “right” is equal to “left” or “top” is equal to “bottom”, a case only allowed if bConfigOnlyUsePicDestRectArea is “0”, all of the RECT parameters shall have the value “0”, indicating no use of the source picture, and
  • “right” and “bottom” shall not exceed 16 times the allocated width and height, respectively, of the uncompressed source picture surface.

For example, if PictureSourceRect16thPel is used to select an entire MPEG-2 decoded picture, the PictureSourceRect16thPel parameters can be computed as follows:

left = 0

top = 0

right = 16·horizontal_size

bottom = 16·vertical_size

PictureDestinationRect
The area of the destination picture to hold the area from the source picture, specified as a RECT data structure. If bConfigPictureResizing is “0”, shall have the same width and height as the area specified by PictureSourceRect16thPel. If PictureDestinationRect differs in size from PictureSourceRect16thPel, the resampling method to be applied is not specified, but should have a quality at least equivalent to that of bilinear resampling.

The following restrictions apply to the RECT parameters:

  • “left” and “top” shall be greater than or equal to zero,
  • “right” and “bottom” shall be greater than or equal to “left” and “top”, respectively,
  • if “right” is equal to “left” or “top” is equal to “bottom”, a case only allowed if bConfigOnlyUsePicDestRectArea is “0”, all of the RECT parameters shall have the value “0” and PictureSourceRect16thPel shall also specify all parameters having the value “0”,
  • if bConfigBlendType = 0, “right” and “bottom” shall not exceed the allocated width and height, respectively, of the uncompressed destination picture surface, and

if bConfigBlendType = 1, “right” and “bottom” shall not exceed the allocated width and height, respectively, of the source graphic surface.

GraphicSourceRect
The area of the graphic picture to be combined with the source picture, specified as a RECT data structure. If alpha blend data loading uses bConfigDataType equal to “2”, the following restrictions on GraphicSourceRect apply:
  1. The “top” and “left” parameters of GraphicSourceRect shall be zero.
  2. The “right” parameter of GraphicSourceRect shall be equal to the “End X-coordinate” minus the “Start X-coordinate” of the last preceding DVD SET_DAREA DCCMD, plus 1 to adjust for the differing rectangle interpretations as described in the note below.
  3. The “bottom” parameter of GraphicSourceRect shall be equal to the “End Y-coordinate” minus the “Start Y-coordinate” of the last preceding DVD SET_DAREA DCCMD, plus 1 to adjust for the differing rectangle interpretations as described in the note below.

The following restrictions apply to the RECT parameters:

  • “left” and “top” shall be greater than or equal to zero,
  • “right” and “bottom” shall be greater than or equal to “left” and “top”, respectively,
  • if “right” is equal to “left” or “top” is equal to “bottom”, all of the RECT parameters shall have the value “0”, indicating no use of the graphic picture, and

“right” and “bottom” shall not exceed the allocated width and height, respectively, of the graphic source surface. The allocated width and height are defined as 720 and 576, respectively, when bConfigDataType = “2”.

GraphicDestinationRect
The area of the destination picture to hold the area from the graphic picture, specified as a RECT data structure. If bConfigGraphicResizing is “0”, shall have the same width and height as the area specified by GraphicSourceRect. If GraphicDestinationRect differs in size from GraphicSourceRect, the resampling method to be applied to the graphic is not specified, but should have a quality at least equivalent to that of bilinear resampling of an AYUV surface representing the blending information.

The following restrictions apply to the RECT parameters of GraphicDestinationRect:

  • “left” and “top” shall be greater than or equal to zero, unless this requirement conflicts with the need to offset the graphic by 8 samples as described in the next paragraph and in DVD 704-Wide Non-Pan-Scan Picture Operation and DVD 352-Wide Picture Operation ,
  • “right” and “bottom” shall be greater than or equal to “left” and “top”, respectively,
  • if “right” is equal to “left” or “top” is equal to “bottom”, then all of the RECT parameters shall have the value “0” and GraphicSourceRect shall also specify all parameters having the value “0”,
  • if bConfigBlendType = 0, “right” and “bottom” shall not exceed the allocated width and height, respectively, of the uncompressed destination picture surface, and
  • if bConfigBlendType = 1, “right” and “bottom” shall not exceed the allocated width and height, respectively, of the source graphic surface, and

If alpha blend data loading uses bConfigDataType equal to “2” and if bConfigGraphicResizing is “0”, the following additional restrictions on GraphicDestinationRect apply:

  1. “top” shall be equal to the “Start Y-coordinate” of the last preceding DVD SET_DAREA DCCMD.
  2. “left” shall be equal to either the “Start X-coordinate” of the last preceding DVD SET_DAREA DCCMD or to that value minus 8 (see in DVD 704-Wide Non-Pan-Scan Picture Operation and DVD 352-Wide Picture Operation ).
  3. The “right” parameter of GraphicDestinationRect shall be equal to the value of “left” plus the “End X-coordinate” minus the “Start X-coordinate” of the last preceding DVD SET_DAREA DCCMD, plus 1 to adjust for the differing rectangle interpretations as described in the note below.
  4. The “bottom” parameter of GraphicDestinationRect shall be equal to the value of “top” plus the “End Y-coordinate” minus the “Start Y-coordinate” of the last preceding DVD SET_DAREA DCCMD, plus 1 to adjust for the differing rectangle interpretations as described in the note below.

Note There appears to be a difference between the way the DVD specification defines a subpicture rectangular area and the convention typically used in Microsoft applications. We follow the Microsoft convention for this specification, which is to say that a rectangle of width 10 and height 10 in the upper left corner of the picture is defined by “top” = 0, “left” = 0, “right” = 10, “bottom” = 10. The convention in the DVD specification appears to instead use an equivalent of “right” = 9 and “bottom” = 9.

wBlendDelay
If back-end hardware blending is in use, wBlendDelay contains a number of milliseconds of delay prior to the combination operation going into effect. Has no meaning and shall be “0” if front-end blending is in use.
bBlendOn
If back-end hardware blending is in use, the specified blending shall be applied from the time specified in a blending combination function with bBlendOn being “1” until the specified execution time of a new blending combination with bBlendOn being “1” or until the blending is disabled by a blending combination function with bBlendOn being “0”. Has no meaning and shall be “0” if front-end blending is in use.

If back-end hardware blending is in use and bBlendOn is “0”, the only other parameter in the alpha blend combination buffer that has meaning is wBlendDelay.

bWholePlaneAlpha
Contains an opacity multiplier for the alpha channel of the graphic. The value “0” indicates that the graphic is transparent (so that the graphic content has no effect on the resulting blended picture) and the value “255” indicates that the graphic content uses its full sample opacity. For non-zero values of bWholePlaneAlpha, the blend specified is to multiply the opacity of each location in the graphic content by (bWholePlaneAlpha+1)/256. For a zero value of bWholePlaneAlpha, the blend specified is to use the opacity specified in the graphic content without alteration. Shall be equal to “255” if bConfigWholePlaneAlpha is “0”.
OutsideYUVcolor
Contains an indication of whether the areas outside of the PictureDestinationRect are to be generated as having a constant color for blending, and contains that constant color if so indicated. OutsideYUVcolor is formatted as a DXVA_AYUVsample and shall follow the following convention:
  • The value of bSampleAlpha8 in OutsideYUVcolor shall be “255” if the areas outside of the PictureDestinationRect are to be generated as a constant color for blending.
  • The value of bSampleAlpha8 in OutsideYUVcolor shall be “0” if either of the following two cases applies:
  1. if the areas outside of the PictureDestinationRect are to be unaffected by the blend or
  2. if the areas outside of the PictureDestinationRect cannot be used (as indicated by bConfigStayInPicDestRectArea having the value “1”).
  • All other values for bSampleAlpha8 in OutsideYUVcolor are reserved for future use.

The value of bSampleAlpha8 in OutsideYUVcolor shall be “0” if bConfigStayInPicDestRectArea is “1”.

If bSampleAlpha8 in OutsideYUVcolor is “0”, the only area of the destination surface that will be affected by the blend is the part within the PictureDestinationRect. If bSampleAlpha8 in OutsideYUVcolor is “255”, any area of the destination surface that is outside of the PictureDestinationRect but within the GraphicDestinationRect shall be generated by blending the graphic with the color specified in the non-alpha parameters of OutsideYUVcolor and the entire allocated area of the destination surface that falls outside of both PictureDestinationRect and GraphicDestinationRect shall be set to the color specified in the non-alpha parameters of OutsideYUVcolor. If bConfigBlendType is “1”, the OutsideYUVcolor parameters shall be set to indicate blending with black by specifying bSampleAlpha8 = 255, bY_Value = 16, bCbValue = bCrValue = 128.

Note When bConfigBlendType is “1” (back-end hardware blend), the actual blending operations may differ somewhat in method from what is described herein. However, the visual result shall be equivalent. For example, some resizing specified to map a video picture from a source to a destination size may instead be applied in an inverse manner map the graphic content to its proper location relative to the source video picture, with the blended result then displayed in a manner compensating for this difference in operation – but the ultimate visual effect of the result shall be as specified by the blend combination command.


DXVA_BufferDescription

The DirectX VA data structure that contains data about a buffer that is passed from the host to the accelerator. When a set of buffers is passed from the host to the accelerator, some additional data about these buffers is also passed. This additional data is termed buffer description list. A buffer description list consists of an ordered list, starting from the first buffer of the first type as enumerated above, proceeding to the next buffer of the same type, and so on, then proceeding to the first buffer of the next type, etc. Each member of the list consists of a DXVA_BufferDescription data structure.

typedef struct _DXVA_BufferDescription {
  DWORD  dwTypeIndex;
  DWORD  dwBufferIndex;
  DWORD  dwDataOffset;
  DWORD  dwDataSize;
  DWORD  dwFirstMBaddress;
  DWORD  dwNumMBsInBuffer;
  DWORD  dwWidth;
  DWORD  dwHeight;
  DWORD  dwStride;
  DWORD  dwReservedBits;
} DXVA_BufferDescription, *LPDXVA_BufferDescription;

Members

dwTypeIndex
The type number of the relevant buffer from the following list:

Picture decoding parameter buffers

Macroblock control command buffers (closely associated with and having a 1:1 correspondence with residual difference block data buffers)

Residual difference block data buffers

Deblocking Filter control command buffers (with or without a restriction on the effect of the filter)

Inverse quantization matrix buffers (only used with off-host VLD processing)

Slice control buffers (closely associated with and having a 1:1 correspondence with bitstream data buffers)

Bitstream data buffers

AYUV alpha blending sample buffers

IA44/AI44 alpha blending surface buffers

DPXD alpha blending surface buffers

Highlight data buffers

DCCMD data buffers

Alpha blend combination buffers

Picture resampling control buffers

Read-back command buffers containing commands to read macroblocks of the resulting picture back to the host.

dwBufferIndex
The sequence number of the buffer within the buffers of the same type passed in the same buffer description list.
dwDataOffset
The offset of the relevant data from the beginning of the buffer (in bytes). Shall be zero.
dwDataSize
The amount of relevant data in the buffer (in bytes). Thus the location of the last byte of content in the buffer is given by dwDataOffset + dwDataSize – 1.
dwFirstMBaddress
The macroblock address of the first macroblock in the buffer in raster scan order (0 being the address of the top left macroblock, PicWidthInMBminus1 being the address of the top right macroblock, and PicHeightInMBminus1 * PicWidthInMB being the address of the bottom left macroblock, and PicHeightInMBminus1 * PicWidthInMB + PicWidthInMBminus1 being the address of the bottom right macroblock). Shall be zero if the data buffer is among the following types: picture decoding parameters, inverse quantization matrix, slice control, bitstream data, AYUV, IA44/AI44, DPXD, Highlight, or DCCMD. If the data buffer is a residual difference block data buffer, dwFirstMBaddress shall have the same value as for the corresponding macroblock control command buffer.
dwNumMBsInBuffer
The number of macroblocks of data in the buffer. This count includes skipped macroblocks. Shall be zero if the data buffer is among the following types: picture decoding parameters, inverse quantization matrix, AYUV, IA44/AI44, DPXD, Highlight, or DCCMD. If the data buffer is a macroblock control command buffer, dwNumMBsInBuffer shall be equal to the total of the values of MBskipsFollowing plus the total number of macroblock control commands in the macroblock control command buffer. If the data buffer is a residual difference block data buffer, dwNumMBsInBuffer shall have the same value as for the corresponding macroblock control command buffer. If the data buffer is a slice control command buffer, dwNumMBsInBuffer shall be equal to the total of the values of wNumberMBsInSlice in the slice control buffer. If the data buffer is a bitstream data buffer, dwNumMBsInBuffer shall have the same value as for the corresponding slice control command buffer.
dwWidth
The width of the data in the buffer. Shall be zero unless the data buffer is among the following types: IA44/AI44, or DPXD. For the applicable buffer types, dwStride is determined from the buffer allocation setup performed by the accelerator.
dwHeight
The height of the data in the buffer. Shall be zero unless the data buffer is among the following types: IA44/AI44, or DPXD. For the applicable buffer types, dwStride is determined from the buffer allocation setup performed by the accelerator.
dwStride
The stride of the data in the buffer. Shall be zero unless the data buffer is among the following types: IA44/AI44, or DPXD. For the applicable buffer types, dwStride is determined from the buffer allocation setup performed by the accelerator. Note, the decoder must take care to honor the stride specified for IA44/AI44 or DPXD.
dwReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.


DXVA_ConfigAlphaCombine

The DirectX VA data structure used for establishing the configuration of the manner in which DXVA alpha blending combination operations are to be performed.

typedef struct _DXVA_ConfigAlphaCombine {

  DXVA_ConfigQueryOrReplyFunc dwFunction;

  DWORD dwReservedBits[3];

  BYTE  bConfigBlendType;
  BYTE  bConfigPictureResizing;
  BYTE  bConfigOnlyUsePicDestRectArea;
  BYTE  bConfigGraphicResizing;
  BYTE  bConfigWholePlaneAlpha;

} DXVA_ConfigAlphaCombine, *LPDXVA_ConfigAlphaCombine;

Members

dwFunction
Contains a DXVA_ConfigQueryOrReplyFunc describing the configuration data structure.
dwReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.
bConfigBlendType
Specifies the type of alpha blend combinations to be performed, as defined by:

“0”: Front-end buffer-to-buffer blend,

“1”: Back-end hardware blend.

Support for bConfigBlendType equal to “1” is allowed for near-term accelerator implementations, but support of bConfigBlendType being “0” is expected to be required in the intermediate term.

bConfigPictureResizing
Specifies whether the PictureSourceRect16thPel for subpicture blending may differ in width and height from the PictureDestinationRect (adjusted for the 1/16th-sample scaling of PictureSourceRect16thPel) and whether the parameters in PictureSourceRect16thPel may not be multiples of 16, thus requiring the source picture to be resampled by the accelerator. “1” indicates that resampling (whether for resizing and/or for sub-pixel accuracy) is supported and “0” indicates that it is not.
bConfigOnlyUsePicDestRectArea
Specifies whether the decoder can command operations which specify values for areas of an output generated destination picture that fall outside of the PictureDestinationRect. “0” indicates that areas outside of the PictureDestinationRect can be specified by the blend combination commands. “1” indicates that the host decoder cannot rely on the values of and cannot display any region of the blended surface outside of the area specified by PictureDestinationRect.
bConfigGraphicResizing
Specifies whether the GraphicSourceRect for subpicture blending may differ in size from the GraphicDestinationRect, thus requiring the alpha blending graphic to be resampled by the accelerator. “1” indicates that resizing is supported and “0” indicates that it is not.
bConfigWholePlaneAlpha
Specifies whether a whole-plane alpha parameter can be applied to the graphic data. “1” indicates that a whole-plane alpha can be applied, and “0” indicates that it cannot.


DXVA_ConfigAlphaLoad

The DirectX VA data structure used for establishing the configuration of the manner in which DXVA alpha blending texture loading operations are to be performed.

typedef struct _DXVA_ConfigAlphaLoad {

  DXVA_ConfigQueryOrReplyFunc dwFunction;

  DWORD dwReservedBits[3];

  BYTE  bConfigDataType;
} DXVA_ConfigAlphaLoad, *LPDXVA_ConfigAlphaLoad;

Members

dwFunction
Contains a DXVA_ConfigQueryOrReplyFunc describing the configuration data structure.
dwReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.
bConfigDataType
Specifies the type of alpha blend data to be used, as defined by:

“0”: 16-entry AYUV palette with IA44 alpha blending surface,

“1”: 16-entry AYUV palette with AI44 alpha blending surface,

“2”: 16-entry AYUV palette with DPXD, Highlight, and DCCMD data,

“3”: AYUV graphic surface.

Support for bConfigDataType being “0” or “2” are allowed for near-term accelerator implementations, but other formats are preferred and both formats “1” and “3” are expected to be required in the intermediate term.


DXVA_ConfigPictureDecode

The DirectX VA connection configuration data structure for compressed picture decoding.

typedef struct _DXVA_ConfigPictureDecode {

  DXVA_ConfigQueryOrReplyFunc dwFunction;

  DWORD dwReservedBits[3];

  GUID guidConfigBitstreamEncryption;
  GUID guidConfigMBcontrolEncryption;
  GUID guidConfigResidDiffEncryption;

  BYTE bConfigBitstreamRaw;

  BYTE bConfigMBcontrolRasterOrder;

  BYTE bConfigResidDiffHost;
  BYTE bConfigSpatialResid8;
  BYTE bConfigResid8Subtraction;
  BYTE bConfigSpatialHost8or9Clipping;
  BYTE bConfigSpatialResidInterleaved;
  BYTE bConfigIntraResidUnsigned;

  BYTE bConfigResidDiffAccelerator;
  BYTE bConfigHostInverseScan;
  BYTE bConfigSpecificIDCT;
  BYTE bConfig4GroupedCoefs;
} DXVA_ConfigPictureDecode, *LPDXVA_ConfigPictureDecode;

Members

dwFunction
Contains a DXVA_ConfigQueryOrReplyFunc describing the configuration data structure.
ReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.
guidConfigBitstreamEncryption
Indicates a GUID associated with the encryption protocol type for bitstream data buffers. The value DXVA_NoEncrypt (a GUID name defined in the DXVA header file) indicates that encryption is not applied. Shall be DXVA_NoEncrypt if bConfigBitstreamRaw is “0”.
guidConfigMBcontrolEncryption
Indicates a GUID associated with the encryption protocol type for macroblock control data buffers. The value DXVA_NoEncrypt (a GUID name defined in the DXVA header file) indicates that encryption is not applied. Shall be DXVA_NoEncrypt if bConfigBitstreamRaw is “1”.
guidConfigResidDiffEncryption
Indicates a GUID associated with the encryption protocol type for residual difference decoding data buffers (buffers containing spatial-domain data or sets of transform-domain coefficients for accelerator-based IDCT). The value DXVA_NoEncrypt (a GUID name defined in the DXVA header file) indicates that encryption is not applied. Shall be DXVA_NoEncrypt if bConfigBitstreamRaw is “1”.
bConfigBitstreamRaw
A value of “1” specifies that the data for the pictures will be sent in bitstream buffers as raw bitstream content, and a value of “0” specifies that picture data will be sent using macroblock control command buffers. Shall be “0” if bConfigResidDiffHost is “1” or if bConfigResidDiffAccelerator is “1”. An intermediate-term requirement is to support “0”. Additional support of “1” is desired.
bConfigMBcontrolRasterOrder
A value of “1” specifies that the macroblock control commands within each macroblock control command buffer shall be in raster-scan order, and a value of “0” indicates arbitrary order. For some types of bitstreams, forcing raster order will either greatly increase the number of required macroblock control buffers that must be processed or will require host reordering of the control information. Support of arbitrary order can thus be advantageous for the decoding process. For example, H.261 CIF-resolution decoding can require 36 macroblock control buffers per picture if raster-scan order is necessary within each buffer (H.263 Annex K’s arbitrary slice ordering and rectangular slice modes have similar repercussions.) An intermediate-term requirement is to support “0”. Support of “1” is allowed in the near term, but is considered a less preferred lower level of capability.
bConfigResidDiffHost
A value of “1” specifies that some residual difference decoding data may be sent as blocks in the spatial domain from the host, and a value of “0” specifies that spatial domain data will not be sent. Shall be “0” if bConfigBitstreamRaw is “1”. An intermediate-term requirement is to support “1”, which is the preferred value.
bConfigSpatialResid8
Indicates the word size used for representing residual difference spatial-domain blocks for predicted (i.e., non-intra) pictures when using host-based residual difference decoding (i.e. when bConfigResidDiffHost is equal to “1”).

If bConfigSpatialResid8 is “1” and bConfigResidDiffHost is “1”, this indicates that the host will send residual difference spatial-domain blocks for non-intra macroblocks using 8 bit signed samples and for intra macroblocks in predicted (i.e. non-intra) pictures in a format depending on bConfigIntraResidUnsigned as follows:

  • If bConfigIntraResidUnsigned is “0”, spatial-domain blocks for intra macroblocks are sent as 8 bit signed integer values relative to a constant reference value of 2(BPP-1), and
  • If bConfigIntraResidUnsigned is “1”, spatial-domain blocks for intra macroblocks are sent as 8 bit unsigned integer values relative to a constant reference value of 0.

If bConfigSpatialResid8 is “0” and bConfigResidDiffHost is “1”, this indicates that the host will send residual difference spatial-domain blocks of data for non-intra macroblocks using 16 bit signed samples and for intra macroblocks in predicted (i.e. non-intra) pictures in a format depending on bConfigIntraResidUnsigned as follows:

  • If bConfigIntraResidUnsigned is “0”, spatial domain blocks for intra macroblocks are sent as 16 bit signed integer values relative to a constant reference value of 2(BPP-1), and
  • If bConfigIntraResidUnsigned is “1”, spatial domain blocks for intra macroblocks are sent as 16 bit unsigned integer values relative to a constant reference value of 0.

bConfigSpatialResid8 shall be “0” if bConfigResidDiffHost is “0”. This specification does not contain a preference for one particular value of bConfigSpatialResid8 when bConfigResidDiffHost is “1”.

Note For intra pictures, spatial-domain blocks shall always be sent using 8-bit samples if BPP is “8” and using 16-bit samples if BPP > 8. If bConfigIntraResidUnsigned is “0”, these samples are sent as signed integer values relative to a constant reference value of 2(BPP-1), and if bConfigIntraResidUnsigned is “1”, these samples are sent as unsigned integer values relative to a constant reference value of 0.

bConfigResid8Subtraction
A value of “1” when bConfigSpatialResid8 is “1” indicates that 8-bit difference overflow blocks are subtracted rather than added. Shall be “0” unless bConfigSpatialResid8 is “1”. If “1”, this indicates that any overflow blocks will be subtracted rather than added. An intermediate-term requirement is to support “1” if bConfigSpatialResid8 is “1”. This ability to subtract differences rather than add them allows 8-bit difference decoding to be fully compliant with the full ±255 range of values required in video decoder specifications, since +255 cannot be represented as the addition of two signed 8-bit numbers but any number in the range ±255 can be represented as the difference between two signed 8-bit numbers (+255 = +127 minus –128).
bConfigSpatialHost8or9Clipping
A value of “1” with bConfigSpatialResid8 equal to “0” and bConfigResidDiffHost equal to “1” indicates that spatial-domain blocks for intra macroblocks shall be clipped to an 8-bit range on the host and that spatial-domain blocks for non-intra macroblocks shall be clipped to a 9-bit range on the host, and a value of “0” indicates that no such clipping is necessary by the host. Shall be “0” unless bConfigSpatialResid8 is equal to “0” and bConfigResidDiffHost is equal to “1”. An intermediate-term requirement is to support “0”. Nearer-term support of “1” is allowed but less preferred, and is considered a lower level of accelerator capability.
bConfigSpatialResidInterleaved
A value of “1” when bConfigResidDiffHost is “1” and the YUV format is “NV12” or “NV21” indicates that any spatial-domain residual difference data shall be sent in a chrominance-interleaved form matching the YUV format chrominance interleaving pattern. Shall be “0” unless bConfigResidDiffHost is “1” and the YUV format is “NV12” or “NV21”. An intermediate-term requirement is to support “0”. Nearer-term support of “1” is allowed but less preferred, and is considered a lower level of accelerator capability.
bConfigIntraResidUnsigned
Indicates the method of representation of spatial-domain blocks of residual difference data for intra blocks when using host-based difference decoding (i.e. when bConfigResidDiffHost is equal to “1”).

If bConfigIntraResidUnsigned is equal to “0” with bConfigResidDiffHost equal to “1”, this indicates that spatial-domain residual difference data blocks for intra macroblocks shall be sent as follows:

  • In a non-intra picture if bConfigSpatialResid8 is “0”, the spatial-domain residual difference data blocks for intra macroblocks shall be sent as 16-bit signed integer values relative to a constant reference value of 2(BPP-1).
  • In a non-intra picture if bConfigSpatialResid8 is “1” and in an intra picture if BPP is equal to “8” (regardless of the value of bConfigSpatialResid8), the spatial-domain residual difference data blocks for intra macroblocks shall be sent as 8-bit signed integer values relative to a constant reference value of 2(BPP-1).

If bConfigIntraResidUnsigned is equal to “1” with bConfigResidDiffHost equal to “1”, this indicates that spatial-domain residual difference data blocks for intra macroblocks shall be sent as follows:

  • In a non-intra picture if bConfigSpatialResid8 is “0”, the spatial-domain residual difference data blocks for intra macroblocks shall be sent as 16-bit unsigned integer values relative to a constant reference value of 0.
  • In a non-intra picture if bConfigSpatialResid8 is “1” and in an intra picture if BPP is equal to “8” (regardless of the value of bConfigSpatialResid8), the spatial-domain residual difference data blocks for intra macroblocks shall be sent as 8-bit unsigned integer values relative to a constant reference value of 0.

bConfigIntraResidUnsigned shall be “0” unless bConfigResidDiffHost is “1”. Nearer-term support of bConfigIntraResidUnsigned equal to “1” is allowed but less preferred than bConfigIntraResidUnsigned equal to “0”, and is considered a lower level of accelerator capability.

bConfigResidDiffAccelerator
A value of “1” indicates that transform-domain blocks of coefficient data may be sent from the host for accelerator-based IDCT, and a value of “0” specifies that accelerator-based IDCT will not be used. If both bConfigResidDiffHost and bConfigResidDiffAccelerator are “1”, this indicates that some residual difference decoding will be done on the host and some on the accelerator, as indicated by macroblock-level control commands. Shall be “0” if bConfigBitstreamRaw is “1”. Support for bConfigResidDiffAccelerator equal to “1” is desired, but there is not expected to be an intermediate-term requirement for this support. Support for bConfigResidDiffAccelerator equal to “1” with bConfigResidDiffHost also equal to “1” indicates that the residual difference decoding can be shared between the host and accelerator on a macroblock basis, and is considered an even higher level of accelerator capability than bConfigResidDiffAccelerator equal to “1” with bConfigResidDiffHost equal to “0”.
bConfigHostInverseScan
A value of “1” indicates that the inverse scan for transform-domain block processing will be performed on the host, and absolute indices will be sent instead for any transform coefficients, and a value of “0” indicates that inverse scan will be performed on the accelerator. Shall be “0” if bConfigResidDiffAccelerator is “0”. Shall be “1” if bConfig4GroupedCoefs is “0”. An intermediate-term expected requirement is to support “1” if bConfigResidDiffAccelerator is “1”. Nearer-term support of “0” with bConfig4GroupedCoefs equal to “1” is allowed but less preferred (due to its lack of flexibility to support arbitrary scan patterns and our perception that host inverse scan adds little burden to the host software decoder processing), and is considered a lower level of accelerator capability.
bConfigSpecificIDCT
A value of “1” indicates use of the IDCT specified in Annex W of ITU-T Recommendation H.263, and a value of “0” indicates that any compliant IDCT can be used for off-host IDCT. (NOTE: The referenced H.263 annex does not comply with the IDCT requirements of MPEG-2 corrigendum 2 and thus bConfigSpecificIDCT shall not be “1” for use with MPEG-2 video.) Shall be zero if bConfigResidDiffAccelerator is “0” (indicating purely host-based residual difference decoding). An intermediate-term expected requirement is to support “0” if bConfigResidDiffAccelerator is “1”. Additional support of “1” is desired. Additional values may be defined in the future.
bConfig4GroupedCoefs
A value of “1” indicates that transform coefficients for off-host IDCT will be sent using the DXVA_TCoef4Group data structure rather than the DXVA_TCoefSingle data structure. Shall be “0” if bConfigResidDiffAccelerator is “0” or if bConfigHostInverseScan is “1”. An intermediate-term expected requirement is to support “0” if bConfigResidDiffAccelerator is “1”. Nearer-term support of “1” with bConfigHostInverseScan equal to “0” is allowed but less preferred, and is considered a lower level of accelerator capability.


DXVA_ConnectMode

The DirectX VA data structure for establishing the defined restricted mode for operational use within a DirectX VA connection.

typedef struct _DXVA_ConnectMode {
  GUID guidMode;
  WORD wRestrictedMode;
} DXVA_ConnectMode, *LPDXVA_ConnectMode;

Members

guidMode
A GUID associated with the restricted mode profile to be used.
wRestrictedMode
The numeric identifier of the connection restricted mode.


DXVA_EncryptProtocolHeader

The DirectX VA structure that is passed between the host and accelerator to specify the use of an encryption protocol.

typedef struct _DXVA_EncryptProtocolHeader {
  DXVA_EncryptProtocolFunc dwFunction;
  DWORD ReservedBits[3];
  GUID  guidEncryptProtocol;
} DXVA_EncryptProtocolHeader, *LPDXVA_EncryptProtocolHeader;

Members

dwFunction
Contains a DXVA_EncryptProtocolFunction indicating that the contents pertain to the encryption protocol.
ReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.
guidEncryptProtocol
Contains the GUID associated with the encryption protocol.


DXVA_Highlight

The DirectX VA data structure for specifying a highlighted rectangular area of a subpicture as used in the DVD ROM Video specification.

typedef struct _DXVA_Highlight {
  WORD wHighlightActive;
  WORD wHighlightIndices;
  WORD wHighlightAlphas;
  RECT HighlightRect;
} DXVA_Highlight, *LPDXVA_Highlight;

Members

wHighlightActive
Indicates whether or not a rectangular highlight area is currently activated (“0” indicates inactive, and “1” indicates active). If inactive, the highlight data shall have no effect on the content of the blended picture.
wHighlightIndices
Contains the four-bit palette index of the highlighted rectangular area on the subpicture for each of the two-bit indices in the DPXD. The four MSBs shall be for index 3, the next four bits shall be for index 2, the next four bits shall be for index 1, and the four LSBs shall be for index 0.
wHighlightAlphas
Contains the four-bit opacity of the highlighted rectangular area on the subpicture for each of the two-bit indices used by the DPXD. The four MSBs shall be for index 3, the next four bits shall be for index 2, the next four bits shall be for index 1, and the four LSBs shall be for index 0. The interpretation of the four-bit opacity values shall be as described above for SampleAlpha4.
HighlightRect
Contains the definition of the area of the highlight rectangle as a RECT data type.

The following restrictions apply to the RECT parameters:

  • “left” and “top” shall be greater than or equal to zero,
  • “right” and “bottom” shall be greater than “left” and “top”, respectively, and
  • “right” shall not exceed 720, and “bottom” shall not exceed 576.

Note There appears to be a difference between the way the DVD specification defines a subpicture rectangular area and the convention typically used in Microsoft applications. We follow the Microsoft convention for this specification, which is to say that a rectangle of width 10 and height 10 in the upper left corner of the picture is defined by Top = 0, Left = 0, Right = 10, Bottom = 10. The convention in the DVD specification appears to instead use Right = 9 and Bottom = 9.


DXVA_MBctrl_I_HostResidDiff_1

The DirectX VA data structure used for sending macroblock control commands when bPicIntra is “1” (i.e., for Intra pictures) and HostResidDiff is “1” (host-based IDCT).

typedef struct _DXVA_MBctrl_I_HostResidDiff_1 {
  WORD  wMBaddress;
  WORD  wMBtype;
  DWORD dwMB_SNL;
  WORD  wPatternCode;
  WORD  wPC_Overflow;
  DWORD dwReservedBits2;
} DXVA_MBctrl_I_HostResidDiff_1;

Members

wMBaddress
Specifies the macroblock address of the current macroblock in raster scan order (0 being the address of the top left macroblock, PicWidthInMBminus1 being the address of the top right macroblock, and PicHeightInMBminus1 * PicWidthInMB being the address of the bottom left macroblock, and PicHeightInMBminus1 * PicWidthInMB + PicWidthInMBminus1 being the address of the bottom right macroblock).
wMBtype
Specifies the type of macroblock being processed dwMB_SNL

Contains the two fields MBskipsFollowing (in the upper 8 bits) and MBdataLocation (in the lower 24 bits). wPatternCode

Specifies which blocks of the macroblock use residual difference data wPC_Overflow

Specifies which blocks of the macroblock use overflow residual difference data dwReservedBits2

Reserved bits used for packing and/or alignment. Shall be zero.


DXVA_MBctrl_I_OffHostIDCT_1

The DirectX VA data structure used for sending macroblock control commands when bPicIntra is “1” (i.e., for Intra pictures) and bChromaFormat is ‘01’ (4:2:0) and HostResidDiff is “0” (off-host IDCT).

typedef struct _DXVA_MBctrl_I_OffHostIDCT_1 {
  WORD  wMBaddress;
  WORD  wMBtype;
  DWORD dwMB_SNL;
  WORD  wPatternCode;
  BYTE  bNumCoef[DXVA_NumBlocksPerMB_420];
} DXVA_MBctrl_I_OffHostIDCT_1;

Members

wMBaddress
Specifies the macroblock address of the current macroblock in raster scan order (0 being the address of the top left macroblock, PicWidthInMBminus1 being the address of the top right macroblock, and PicHeightInMBminus1 * PicWidthInMB being the address of the bottom left macroblock, and PicHeightInMBminus1 * PicWidthInMB + PicWidthInMBminus1 being the address of the bottom right macroblock).
wMBtype
Specifies the type of macroblock being processed dwMB_SNL

Contains the two fields MBskipsFollowing (in the upper 8 bits) and MBdataLocation (in the lower 24 bits). wPatternCode

Specifies which blocks of the macroblock use residual difference data bNumCoef

The value of bNumCoef[i] indicates the number of coefficients in the residual difference data buffer for each block i of the macroblock, where i is the index of the block within the macroblock as specified in MPEG-2 Figures 6-10, 6-11, and 6-12 (raster-scan order for Y, followed by Cb, followed by Cr). Used only when HostResidDiff is “0” and bChromaFormat is ‘01’ (4:2:0). (If used in 4:2:2 or 4:4:4 formats, it would increase the size of typical macroblock control commands past a critical memory alignment boundary, so only EOB is used for determining the number of coefficients in each block in non-4:2:0 cases.) The data for these coefficients is found in the residual difference buffer in the same order.


DXVA_MBctrl_P_HostResidDiff_1

The DirectX VA data structure used for sending macroblock control commands when bPicIntra is not “1” (i.e., for P and B pictures – and also used for concealment motion vectors in I pictures) and HostResidDiff is “1” (host-based IDCT) and bPicOBMC and bMV_RPS are zero and at least one of bPicBinPB and bPic4MVallowed is zero.

typedef struct _DXVA_MBctrl_P_HostResidDiff_1 {
  WORD         wMBaddress;
  WORD         wMBtype;
  DWORD        dwMB_SNL;
  WORD         wPatternCode;
  WORD         wPC_Overflow;
  DWORD        dwReservedBits2;
  DXVA_MVvalue MVector[DXVA_NumMV_OBMC_off_BinPBwith4MV_off];
} DXVA_MBctrl_P_HostResidDiff_1;

Members

wMBaddress
Specifies the macroblock address of the current macroblock in raster scan order (0 being the address of the top left macroblock, PicWidthInMBminus1 being the address of the top right macroblock, and PicHeightInMBminus1 * PicWidthInMB being the address of the bottom left macroblock, and PicHeightInMBminus1 * PicWidthInMB + PicWidthInMBminus1 being the address of the bottom right macroblock).
wMBtype
Specifies the type of macroblock being processed dwMB_SNL

Contains the two fields MBskipsFollowing (in the upper 8 bits) and MBdataLocation (in the lower 24 bits). wPatternCode

Specifies which blocks of the macroblock use residual difference data wPC_Overflow

Specifies which blocks of the macroblock use overflow residual difference data dwReservedBits2

Reserved bits used for packing and/or alignment. Shall be zero.

MVector
An array containing the value of the motion vector(s) for the macroblock, each represented using a DXVA_MVvalue structure.


DXVA_MBctrl_P_OffHostIDCT_1

The DirectX VA data structure used for sending macroblock control commands when bPicIntra is not “1” (i.e., for P and B pictures – and also used for concealment motion vectors in I pictures) and HostResidDiff is “0” (off-host IDCT) and bPicOBMC and bMV_RPS are zero and at least one of bPicBinPB and bPic4MVallowed is zero and bChromaFormat is ‘01’ (4:2:0).

typedef struct _DXVA_MBctrl_P_OffHostIDCT_1 {
  WORD         wMBaddress;
  WORD         wMBtype;
  DWORD        dwMB_SNL;
  WORD         wPatternCode;
  BYTE         bNumCoef[DXVA_NumBlocksPerMB_420];
  DXVA_MVvalue MVector[DXVA_NumMV_OBMC_off_BinPBwith4MV_off];
} DXVA_MBctrl_P_OffHostIDCT_1;

Members

wMBaddress
Specifies the macroblock address of the current macroblock in raster scan order (0 being the address of the top left macroblock, PicWidthInMBminus1 being the address of the top right macroblock, and PicHeightInMBminus1 * PicWidthInMB being the address of the bottom left macroblock, and PicHeightInMBminus1 * PicWidthInMB + PicWidthInMBminus1 being the address of the bottom right macroblock).
wMBtype
Specifies the type of macroblock being processed dwMB_SNL

Contains the two fields MBskipsFollowing (in the upper 8 bits) and MBdataLocation (in the lower 24 bits). wPatternCode

Specifies which blocks of the macroblock use residual difference data bNumCoef

The value of bNumCoef[i] indicates the number of coefficients in the residual difference data buffer for each block i of the macroblock, where i is the index of the block within the macroblock as specified in MPEG-2 Figures 6-10, 6-11, and 6-12 (raster-scan order for Y, followed by Cb, followed by Cr). Used only when HostResidDiff is “0” and bChromaFormat is ‘01’ (4:2:0). (If used in 4:2:2 or 4:4:4 formats, it would increase the size of typical macroblock control commands past a critical memory alignment boundary, so only EOB is used for determining the number of coefficients in each block in non-4:2:0 cases.) The data for these coefficients is found in the residual difference buffer in the same order.

MVector
An array containing the value of the motion vector(s) for the macroblock, each represented using a DXVA_MVvalue structure.


DXVA_MVvalue

The DirectX VA data structure used for the specification of a two-dimensional motion vector value.

typedef struct _DXVA_MVvalue {
  SHORT horz, vert;
} DXVA_MVvalue, *LPDXVA_MVvalue;

Members

horz
Specifies the horizontal component of the value of a motion vector. Contains a signed integer motion offset in half-sample units. Shall be even if bMVprecisionAndChromaRelation is ‘10’ (H.261-style motion supporting only integer-sample offsets).
vert
Specifies the vertical component of the value of a motion vector. Contains a signed integer motion offset in half-sample units. Shall be even if bMVprecisionAndChromaRelation is ‘10’ (H.261-style motion supporting only integer-sample offsets).


DXVA_PictureParameters

The DirectX VA data structure used to convey the picture-level parameters of a compressed picture for decoding.

typedef struct _DXVA_PictureParameters {

  WORD wDecodedPictureIndex;
  WORD wDeblockedPictureIndex;

  WORD wForwardRefPictureIndex;
  WORD wBackwardRefPictureIndex;

  WORD wPicWidthInMBminus1;
  WORD wPicHeightInMBminus1;

  BYTE bMacroblockWidthMinus1;
  BYTE bMacroblockHeightMinus1;

  BYTE bBlockWidthMinus1;
  BYTE bBlockHeightMinus1;

  BYTE bBPPminus1;

  BYTE bPicStructure;
  BYTE bSecondField;
  BYTE bPicIntra;
  BYTE bPicBackwardPrediction;

  BYTE bBidirectionalAveragingMode;
  BYTE bMVprecisionAndChromaRelation;
  BYTE bChromaFormat;

  BYTE bPicScanFixed;
  BYTE bPicScanMethod;
  BYTE bPicReadbackRequests;

  BYTE bRcontrol;
  BYTE bPicSpatialResid8;
  BYTE bPicOverflowBlocks;
  BYTE bPicExtrapolation;

  BYTE bPicDeblocked;
  BYTE bPicDeblockConfined;
  BYTE bPic4MVallowed;
  BYTE bPicOBMC;
  BYTE bPicBinPB;
  BYTE bMV_RPS;

  BYTE bReservedBits;

  WORD wBitstreamFcodes;
  WORD wBitstreamPCEelements;
  BYTE bBitstreamConcealmentNeed;
  BYTE bBitstreamConcealmentMethod;

} DXVA_PictureParameters, *LPDXVA_PictureParameters;

Members

wDecodedPictureIndex
Specifies destination frame buffer for the decoded macroblocks.
wDeblockedPictureIndex
Specifies destination frame buffer for the deblocked output picture when bPicDeblocked is “1”. Has no meaning and shall be “0” if bPicDeblocked is “0”. May be the same as wDecodedPictureIndex.
wForwardRefPictureIndex
Specifies the frame buffer index of the picture to be used as a reference picture for “forward prediction” of the current picture. Shall not be the same as wDecodedPictureIndex. Shall be 0xFFFF if bPicIntra is “1”.
wBackwardRefPictureIndex
Specifies the frame buffer index of the picture to be used as a reference picture for “backward prediction” of the current picture. Shall not be the same as wDecodedPictureIndex if backward reference motion prediction is used. Shall be 0xFFFF if bPicBackwardPrediction is “0”.
wPicWidthInMBminus1
Specifies the width of the current picture in units of macroblocks, minus 1. A derived term called PicWidthInMB is formed by adding one to PicWidthInMBminus1.
wPicHeightInMBminus1
Specifies the height of the current picture in units of macroblocks, minus 1. A derived term called PicHeightInMB is formed by adding one to PicHeightInMBminus1.
bMacroblockWidthMinus1
Specifies the destination luminance sample width of a macroblock. This is equal to “15” for MPEG-1, MPEG-2, H.263, and MPEG-4. A derived term called MacroblockWidth is formed by adding one to bMacroblockWidthMinus1.
bMacroblockHeightMinus1
Specifies the destination luminance sample height of a macroblock. This is equal to “15” for MPEG-1, MPEG-2, H.261, H.263, and MPEG-4. A derived term called MacroblockHeight is formed by adding one to bMacroblockHeightMinus1.
bBlockWidthMinus1
Specifies the block width of an residual difference block. This is equal to “7” for MPEG-1, MPEG-2, H.261, H.263, and MPEG-4. Shall be “7” if bConfig4GroupedCoefs is “1”. Residual difference blocks within a macroblock are sent in the order specified as in MPEG-2 Figures 6-10, 6-11, and 6-12 (raster-scan order for Y, followed by all 4:2:0 blocks of Cb in raster-scan order, followed by 4:2:0 blocks of Cr, followed by 4:2:2 blocks of Cb, followed by 4:2:2 blocks of Cr, followed by 4:4:4 blocks of Cb, followed by 4:4:4 blocks of Cr). A derived term called WT is formed by adding one to BlockWidthMinus1.
bBlockHeightMinus1
Specifies the block height of an IDCT block. This is equal to “7” for MPEG-1, MPEG-2, H.261, H.263, and MPEG-4. Shall be “7” if bConfig4GroupedCoefs is “1”. A derived term called HT is formed by adding one to BlockHeightMinus1.
bBPPminus1
Specifies the number of bits per pixel for the video sample values. This shall be at least “7” (indicating 8-bit pixels). It is equal to “7” for MPEG-1, MPEG-2, H.261, and H.263. A larger number of bits per pixel is supported in some operational modes of MPEG-4. A derived term called BPP is formed by adding one to bBPPminus1.
bPicStructure
This parameter has the same meaning as the picture_structure parameter defined in Section 6.3.10 and Table 6-14 of MPEG-2, and indicates whether the current picture is a top-field picture (value ‘01’), a bottom-field picture (value ‘10’), or a frame picture (value ‘11’). In progressive-scan frame-structured coding such as in H.261, bPicStructure shall be ‘11’. A derived parameter PicCurrentField is defined as “0” unless bPicStructure is ‘10’ (bottom field), in which case it is “1”.
bSecondField
Indicates whether, in the case of field-structured coding (when bPicStructure is ‘01’ or ‘10’), the current field is the second field of a picture. This is used to determine whether the opposite-parity field used as a reference for the opposite-parity lines for motion compensation prediction is the opposite-parity field of the reference picture or the opposite-parity field of the current picture. If bSecondField is “1”, the current field is the second field of a picture and the field used as a reference for the opposite-parity lines for motion compensation are the opposite-parity lines of the current picture. (In both cases the field used as a reference for the same-parity lines for motion compensation are the same-parity lines of the reference picture.) Otherwise, bSecondField shall be “0”.
bPicIntra
Indicates whether motion compensated prediction is needed for this picture. If bPicIntra is “1”, all macroblocks are sent with IntraMacroblock equal to “1” (i.e. no motion compensated prediction is performed for the picture). Otherwise, some macroblocks of the picture may have IntraMacroblock equal to “0”.
bPicBackwardPrediction
Indicates whether any macroblocks of the current picture include backward prediction. If bPicIntra is “1”, bPicBackwardPrediction shall be “0”. If bPicBackwardPrediction is “0”, MotionBackward shall be “0” in all macroblocks of the picture. If bPicBackwardPrediction is “1”, some macroblocks of the picture may have MotionBackward equal to “1”.
bBidirectionalAveragingMode
This flag indicates the rounding method for combining prediction planes in bi-directional motion compensation (used for B pictures and Dual-Prime motion). The value “0” indicates MPEG-1 and MPEG-2 rounded averaging (//2), and the value “1” indicates H.263 truncated averaging (/2). bBidirectionalAveragingMode shall be “0” if no bidirectional averaging is needed.
bMVprecisionAndChromaRelation
This two-bit field indicates the precision of luminance motion vectors and how chrominance motion vectors shall be derived from luminance motion vectors:

‘00’ indicates that luminance motion vectors have half-sample precision and that chrominance motion vectors are derived from luminance motion vectors according to the rules in MPEG-2,

‘01’ indicates that luminance motion vectors have half-sample precision and that chrominance motion vectors are derived from luminance motion vectors according to the rules in H.263,

‘10’ indicates that luminance motion vectors have full-sample precision and that chrominance motion vectors are derived from luminance motion vectors according to the rules in H.261 Section 3.2.2 (dividing by two and truncating toward zero to full-sample values), and

‘11’ is reserved.

bChromaFormat
Affects number of prediction error blocks expected by the Accelerator. This variable is defined in Section 6.3.5 and Table 6-5 of MPEG-2. For MPEG-1, MPEG-2 “Main Profile,” H.261 and H.263 bitstreams, this value shall always be set to ‘01’, indicating "4:2:0" format. If ‘10’ this indicates “4:2:2”, and “11” indicates “4:4:4” sampling. Shall be equal ‘01’ if bConfig4GroupedCoefs is “1” (since bConfig4GroupedCoefs does not include the EOB indication needed within coefficient data in 4:2:2 and 4:4:4 formats).

Note Horizontal chroma siting differs slightly between H.261, H.263, MPEG-1 versus MPEG-2 and MPEG-4. This difference is assumed to be small enough to ignore.

bPicScanFixed
When using accelerator-based IDCT processing of residual difference blocks, a value of “1” for this flag indicates that the inverse-scan method is the same for all macroblocks in the picture, and a value of “0” indicates that it is not. Shall be “1” if bConfigHostInverseScan is “1” or if bConfigResidDiffAccelerator is “0”.
bPicScanMethod
When bPicScanFixed is “1”, this field indicates the fixed inverse scan method for the picture. When bPicScanFixed is “0”, this field has no meaning and shall be ‘00’. If bPicScanFixed is “1” this field shall have one of the following values:

If bConfigHostInverseScan is “0”, bPicScanMethod shall be as follows:

‘00’ = Zig-zag scan ‘01’ = Alternate-vertical ‘10’ = Alternate-horizontal If bConfigHostInverseScan is “1”, bPicScanMethod shall be as follows:

‘11’ = Arbitrary scan with absolute coefficient address.

bPicReadbackRequests
Indicates whether read-back control requests are issued for the current picture to read back the values of macroblocks in the final decoded (ad deblocked, if deblocking is applied with wDeblockedPictureIndex equal to wDecodedPictureIndex) picture. A value of “1” indicates that read-back requests are present, and “0” indicates that they are not.
bRcontrol
This flag is defined in H.263 Section 6.1.2. It defines the rounding method to be used for half-sample motion compensation. A value of “0” indicates the half-sample rounding method found in MPEG-1, MPEG-2, and the first version of H.263. A value of “1” indicates the rounding method which includes a downward averaging bias which can be selected in some optional modes of H.263 and MPEG-4. It is meaningless for H.261, since H.261 has no half-sample motion compensation. It shall be set to “0” for all MPEG-1, and MPEG-2 bitstreams in order to conform with the rounding operator defined by those standards.
bPicSpatialResid8
A value of “1” indicates that spatial-domain difference blocks for host-based residual difference decoding can be sent using 8-bit samples, and a value of “0” indicates that they cannot. Shall be “0” if bConfigResidDiffHost is “0” or if BPP > 8. Shall be “1” if BPP is “8” and bPicIntra is “1” and bConfigResidDiffHost is “1”. Shall be “1” if bConfigSpatialResid8 is “1”. If equal to “1”, bPicSpatialResid8 indicates that spatial-domain intra macroblocks are sent as 8-bit values (which are either signed or unsigned as determined by bConfigIntraResidUnsigned) and that spatial-domain non-intra macroblock differences are sent as signed 8-bit difference values relative to some motion compensated prediction. bPicSpatialResid8 differs from bConfigSpatialResid8 in that it is an indication for a particular picture, not a global indication for the entire video sequence. In some cases such as in an intra picture with BPP equal to “8”, bPicSpatialResid8 will be “1” even though bConfigSpatialResid8 may be “0”.
bPicOverflowBlocks
A value of “1” indicates that spatial-domain difference blocks for host-based residual difference decoding of a picture may be sent using “overflow” blocks, and a value of “0” indicates that they are not. Shall be “0” if bConfigResidDiffHost is “0” or if bConfigSpatialResid8 is “0” or if BPP > 8. bPicOverflowBlocks is an indication of whether any overflow blocks may be present for the particular picture. In an intra picture with BPP equal to “8”, bPicOverflowBlocks shall be “0” as no overflow blocks are needed in this case.
bPicExtrapolation
This flag indicates whether motion vectors over picture boundaries are allowed as specified by H.263 Annex D and MPEG-4. This requires either allocation of picture planes which are two macroblocks wider (one extra macroblock at the left and another at the right) and two macroblocks taller (one extra macroblock at the top and another at the bottom) than the decoded picture size, or clipping of the address of each individual pixel access to within the picture boundaries. Macroblock addresses in this specification are for macroblocks in the interior of the picture, not including padding.
bPicDeblocked
Indicates whether deblocking commands are sent for this picture for creating a deblocked output picture in the picture buffer indicated in wDeblockedPictureIndex. If bPicDeblocked is “1”, deblocking commands are sent and the deblocked frame shall be generated, and if bPicDeblocked is “0”, no deblocking commands are sent and no deblocked picture shall be generated.
bPicDeblockConfined
Indicates whether deblocking filter command buffers contain commands which confine the effect of the deblocking filter operations to within the same set of macroblocks as are contained in the buffer.
bPic4MVallowed
Specifies whether four forward-reference motion vectors per macroblock are allowed as used in H.263 Annexes F and J.
bPicOBMC
Specifies whether motion compensation for the current picture operates using overlapped block motion compensation (OBMC) as specified in H.263 Annex F. Shall be zero if bPic4MVallowed is “0”.
bPicBinPB
Specifies whether bi-directionally-predicted macroblocks in the picture use “B in PB” motion compensation, which restricts the bi-directionally predicted area for each macroblock to the region of the corresponding macroblock in the backward reference picture, as specified in Annexes G and M of H.263.
bMV_RPS
Specifies use of motion vector reference picture selection. If “1”, this indicates that a reference picture index is sent for each motion vector rather than just forward and possibly backward motion picture indexes for the picture as a whole. If bMV_RPS is “1”, the parameters wForwardRefPictureIndex and wBackwardRefPictureIndex have no meaning and shall be zero.
bReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.
wBitstreamFcodes
When bConfigBitstreamRaw is “1”, this parameter contains four motion vector f_code values as defined in MPEG-2. Each f_code value takes four bits. These values are packed into a sixteen bit word as in MPEG-2 as follows:

Bits 12-15 (the MSBs): f_code[0][0]: The forward horizontal f_code

Bits 8-11: f_code[0][1]: The forward vertical f_code

Bits 7-4: f_code[1][0]: The backward horizontal f_code

Bits 0-3 (the LSBs): f_code[1][1]: The backward vertical f_code

If any f_code value is unnecessary or irrelevant due to the structure of the bitstream data, due to bConfigBitstreamRaw being “0”, or due to the f_code parameter not being needed in the relevant video coding bitstream syntax (such as in H.261 or H.263), then the f_code value shall be 0xF.

Note MPEG-1 bitstreams provide this information in a different form. Therefore for MPEG-1 bitstreams, f_code[0][0] and f_code[0][1] shall be equal to MPEG-1’s forward_f_code and f_code[1][0] and f_code[1][1] shall be equal to MPEG-1’s backward_f_code.

wBitstreamPCEelements
When bConfigBitstreamRaw is “1”, this parameter contains a set of flags necessary for the bitstream decoding process of MPEG-2 video. It is not used and shall be “0” when bConfigBitstreamRaw is “0” and for non-MPEG-2 video. The bits in this parameter are defined by their correspondence with bitstream elements of the MPEG-2 picture coding extension as follows:

Bits 14 and 15: IntraDCprecision = intra_dc_precision

Bits 12 and 13: AnotherPicStructure = picture_structure.
Shall be equal to bPicStructure.

Bit 11: TopFieldFirst = top_field_first

Bit 10: FrameDCTprediction = frame_pred_frame_dct

Bit 9: ConcealmentMVs = concealment_motion_vectors

Bit 8: QuantScaleType = q_scale_type

Bit 7: IntraVLCformat = intra_vlc_format

Bit 6: AlternateScan = alternate_scan

Bit 5: RepeatFirstField = repeat_first_field
(not needed by the accelerator)

Bit 4: Chroma420type = chroma_420_type

(not needed by the accelerator and restricted by
MPEG-2 to be equal to progressive_frame)

Bit 3: ProgressiveFrame = progressive_frame

Bits 0, 1, and 2 (the LSBs): ReservedBits

bBitstreamConcealmentNeed
Specifies, when bConfigBitstreamRaw is “1”, whether there is a significant likelihood of the bitstream data containing errors. Shall be “0” if bConfigBitstreamRaw is “0”. Video accelerators must be designed not to crash or lock up, regardless of the content of the data given to them. However, it may be helpful for a video accelerator to have information about the host’s assessment of the likelihood of syntactical errors in order to determine whether there is a need to be able to invoke some more complex error concealment algorithms which might slow down the bitstream decoding process. Allowed values for this parameter are as follows (all other values are reserved):

“0”: indicates that the bitstream is unlikely to contain any significant amount of errors in its syntactical format.

“1”: indicates that the bitstream may contain some errors, but these errors are likely to be infrequent (e.g., some error once or twice per hour).

“2”: indicates that the bitstream is likely to contain some errors, and that these errors are likely to occur with a frequency that could have some impact on the user experience (e.g., some error every five to ten minutes), but that these errors are not likely to be a constant presence.

“3”: indicates that the bitstream is likely to contain relatively significant, serious, and frequent syntactical format errors (e.g., one per minute or more frequent errors).

bBitstreamConcealmentMethod
Specifies, when bConfigBitstreamRaw is “1”, a preferred default method for error concealment processing. Shall be “0” if bConfigBitstreamRaw is “0”. Allowed values for this parameter are as follows (all other values are reserved):

0: Preferred concealment method unknown or unspecified.

1: Preferred concealment method is to use spatial intra-picture concealment within the picture.

2: Preferred concealment method is to use the forward-motion reference picture for inter-picture concealment (to be used most typically in a P picture or in a B picture that is temporally closer to its forward-motion reference picture than to its backward-motion reference picture).

3: Preferred concealment method is to use the backward-motion reference picture for inter-picture concealment (to be used most typically in a B picture that is temporally closer to its backward-motion reference picture than to its forward-motion reference picture).


DXVA_PicResample

The DirectX VA data structure used for controlling the resampling process invoked by bDXVA_Func=4.

typedef struct _DXVA_PicResample {

  WORD  wPicResampleSourcePicIndex;
  WORD  wPicResampleDestPicIndex;

  WORD  wPicResampleRcontrol;
  BYTE  bPicResampleExtrapWidth;
  BYTE  bPicResampleExtrapHeight;

  DWORD dwPicResampleSourceWidth;
  DWORD dwPicResampleSourceHeight;

  DWORD dwPicResampleDestWidth;
  DWORD dwPicResampleDestHeight;

  DWORD dwPicResampleFullDestWidth;
  DWORD dwPicResampleFullDestHeight;

} DXVA_PicResample, *LPDXVA_PicResample;

Members

wPicResampleSourcePicIndex
Specifies the reference buffer to be resampled.
wPicResampleDestPicIndex
Specifies the buffer to be used for the output of the reference picture resampling operation.
wPicResampleRcontrol
Specifies the averaging rounding mode of the resampling operation. In the case of H.263 Annex O Spatial Scalability, this parameter shall be “1”. (This corresponds to the value of RCRPR in H.263 Annex P which is equivalent to the upsampling needed for H.263 Annex O spatial scalability.) In the case of H.263 Annex P Reference Picture Resampling, this parameter shall be equal to the H.263 parameter RCRPR.
bPicResampleExtrapWidth
If nonzero and the padding method of using motion vectors over picture boundaries is used on the accelerator, any resampling shall include padding of the resampled picture as well – and this padding shall cover at least the specified width around each edge of the resampled picture regardless of the resampling operation which is performed.
bPicResampleExtrapHeight
If nonzero and the padding method of using motion vectors over picture boundaries is used on the accelerator, any resampling shall include padding of the resampled picture as well – and this padding shall cover at least the specified height around each edge of the resampled picture regardless of the resampling operation which is performed.
dwPicResampleSourceWidth
The width of the area of the source picture to be resampled to the destination picture.
dwPicResampleSourceHeight
The height of the area of the source picture to be resampled to the destination picture.
dwPicResampleDestWidth
The width of the area of the destination picture to contain the resampled data from the source picture.
dwPicResampleDestHeight
The height of the area of the destination picture to contain the resampled data from the source picture.
dwPicResampleFullDestWidth
The full width of the area of the destination picture to contain the resampled data from the source picture. Clipping shall be used to generate any samples outside the source resampling area. (This parameter is necessary for H.263 Annex P support of custom source formats in which the luminance width or height is not divisible by 16.)
dwPicResampleFullDestHeight
The full height of the area of the destination picture to contain the resampled data from the source picture. Clipping shall be used to generate any samples outside the source resampling area. (This parameter is necessary for H.263 Annex P support of custom source formats in which the luminance width or height is not divisible by 16.)


DXVA_QmatrixData

The DirectX VA data structure used to load quantization matrix data for compressed video picture decoding.

typedef struct _DXVA_QmatrixData {
  BYTE bNewQmatrix[4];
  WORD Qmatrix[4][DXVA_USUAL_BLOCK_WIDTH * DXVA_USUAL_BLOCK_HEIGHT];
} DXVA_QmatrixData, *LPDXVA_QmatrixData;

Members

bNewQmatrix
Indicates whether a new inverse quantization matrix of type i is present in the buffer. If bNewQmatrix[i] is “1”, a new inverse quantization matrix of type i follows in the inverse quantization matrix buffer. Type i=0 is for intra luminance quantization, i=1 is for inter luminance quantization, i=2 is for intra chrominance quantization, and i=3 is for inter chrominance quantization. No default values of inverse quantization matrices may be assumed by the accelerator in the absence of any prior value sent by the host. The value of bNewQmatrix[i] shall not be zero for both i=0 and i=1.

If the value of bNewQmatrix[i] is “0” for i=2 or i=3, then:

  1. If bNewQmatrix[i-2] is “0”, the previous inverse quantization matrix for i shall continue to be used by the accelerator, and
  2. If bNewQmatrix[i-2] is “1”, the inverse quantization matrix for i shall be set equal to the new inverse quantization matrix for i-2.

If the relevant video coding specification does not need inverse quantization matrices (e.g., H.261 and H.263), no inverse quantization matrix buffer shall be sent. If the relevant video coding specification does need inverse quantization matrices, some value must be provided for these inverse quantization matrices by the host prior to, or in conjunction with, the transferal of any bitstream data buffers at the start of the video decoding process.

Note No default value is assumed for quantization matrices in the absence of any prior value sent from the host. The quantization matrix values must be sent explicitly, even if they contain values that are available by default in the relevant video coding specification.

Qmatrix
An inverse quantization matrix. Present only when bNewQmatrix[i] is equal to “1”. The matrix consists of WT·HT unsigned words (in which only the lower eight bits of each word are used for the dominant video coding standards). The order of the data values within the inverse quantization matrix shall be as specified in the relevant video coding specification.

Note For MPEG-2 bitstreams, the data values within Qmatrix[i] are in zig-zag inverse scan order, as specified in subclause 7.3.1 and Figure 7-2 of MPEG-2.


DXVA_SliceInfo

The DirectX VA data structure used to specify the slice-level parameters of a slice of bitstream data for off-host bitstream compressed picture decoding.

typedef struct _DXVA_SliceInfo {
  WORD  wHorizontalPosition;
  WORD  wVerticalPosition;
  DWORD dwSliceBitsInBuffer;
  DWORD dwSliceDataLocation;
  BYTE  bStartCodeBitOffset;
  BYTE  bReservedBits;
  WORD  wMBbitOffset;
  WORD  wNumberMBsInSlice;
  WORD  wQuantizerScaleCode;
  WORD  wBadSliceChopping;
} DXVA_SliceInfo, *LPDXVA_SliceInfo;

Members

wHorizontalPosition
The horizontal position of the first macroblock of the slice expressed in units of macroblocks with zero indicating the left-most or top-most macroblock of the picture.
wVerticalPosition
The vertical position of the first macroblock of the slice expressed in units of macroblocks with zero indicating the left-most or top-most macroblock of the picture.
dwSliceBitsInBuffer
The total number of bits in the corresponding bitstream data buffer which contain data for the current slice. This shall be a multiple of eight for MPEG-1, MPEG-2, MPEG-4, and in the slice structured mode of H.263, since slice start codes in these cases are byte aligned.
dwSliceDataLocation
The location of the first byte containing data for the slice (e.g., the location of a slice start code) in the bitstream data buffer. Shall be zero if the start of the slice is not within the corresponding bitstream data buffer.
bStartCodeBitOffset
The number of MSBs of the byte at dwSliceDataLocation which do not contain data for the slice (zero for MPEG-1, MPEG-2, and MPEG-4 since slice start codes in these specifications are byte aligned, but possibly nonzero for H.261 and H.263 which do not force byte alignment of GOB start codes). Shall be in the range of 0…7. Shall be zero if the start of the slice is not within the corresponding bitstream data buffer. MSBs marked irrelevant for the current slice by bStartCodeBitOffset may contain data for a previous slice in the case of start codes which are not byte aligned, as may occur for example in H.263 baseline mode.
bReservedBits
Reserved bits used for packing and/or alignment. Shall be zero.
wMBbitOffset
The number of bits of slice header data prior to the first bit of macroblock layer data in the bitstream buffer. For example, if wMBbitOffset is 83, the macroblock layer data for the slice starts after 83 bits slice header data. Shall be zero if the start of the slice is not within the corresponding bitstream data buffer.
wNumberMBsInSlice
The number of macroblocks of data in the slice, including skipped macroblocks. May be zero if this number cannot be readily determined from the header of the picture and the headers and initial macroblock data of the current and next slice in the bitstream, such as in the rectangular slice and arbitrary slice ordering submodes of the slice mode of H.263. Shall not be zero for H.261, MPEG-1, MPEG-2, MPEG-4, or when not using the rectangular slice or arbitrary slice submodes of the slice structured mode in H.263.
wQuantizerScaleCode
The quantizer scaling code from the slice level of the bitstream, as specified in the particular video coding specification (ranging from “1” to “31” for H.261, H.262/MPEG-2, H.263, MPEG-1, and MPEG-4).
wBadSliceChopping
A parameter containing a value defined as follows:

“0” : All bits for the slice are located within the corresponding bitstream data buffer.

“1” : The bits for the start of the slice are within the corresponding bitstream data buffer, and the bits for the end of the slice are not (because the bitstream data buffer is full).

“2” : The bits for the start of the slice are not within the corresponding bitstream data buffer (because the previous bitstream data buffer was full), but the bits for the end of the slice are within the corresponding bitstream data buffer.

“3” : The bits for the start of the slice are not within the corresponding bitstream data buffer (because the previous bitstream data buffer was full), and the bits for the end of the slice are also not within the corresponding bitstream data buffer (because the corresponding bitstream data buffer is also full).

Nonzero values of wBadSliceChopping should generally be avoided by the host software decoder.


DXVA_TCoef4Group

The DirectX VA data structure used to specify DCT coefficient values when HostResidDiff is “0” and bConfig4GroupedCoefs is “1”.

typedef struct _DXVA_TCoef4Group {
  BYTE  TCoefIDX[4];
  SHORT TCoefValue[4];
} DXVA_TCoef4Group, *LPDXVA_TCoef4Group;

Members

TCoefIDX
In the DXVA_TCoef4Group data structure, groups of four transform coefficients are sent together at a time along with run-length values. The ith element of each array in DXVA_TCoef4Group contains element 3-i of the actual coefficient or run-length list (so the first coefficient or index goes into element 3, the next in element 2, etc.). If only NC<4 nonzero coefficients need to be sent, then TCoefIDX[i] shall be 63 (hexadecimal 0x3F) and TCoefValue[i] shall be equal to TCoefValue[4–NC] for i=0 to 3–NC.
TCoefValue
In the DXVA_TCoef4Group data structure, groups of four transform coefficients are sent together at a time along with run-length values. The ith element of each array in DXVA_TCoef4Group contains element 3-i of the actual coefficient or run-length list (so the first coefficient or index goes into element 3, the next in element 2, etc.). If only NC<4 nonzero coefficients need to be sent, then TCoefIDX[i] shall be 63 (hexadecimal 0x3F) and TCoefValue[i] shall be equal to TCoefValue[4–NC] for i=0 to 3–NC.


DXVA_TCoefSingle

The DirectX VA data structure used to specify DCT coefficient values when HostResidDiff is “0” and bConfig4GroupedCoefs is “0”.

typedef struct _DXVA_TCoefSingle {
  WORD  wIndexWithEOB;
  SHORT TCoefValue;
} DXVA_TCoefSingle, *LPDXVA_TCoefSingle;

Members

wIndexWithEOB
A word containing two fields: TCoefIDX (the 15 MSBs) and TCoefEOB (the LSB).

TCoefIDX specifies the index of the coefficient in the block, as determined from bConfigHostInverseScan. There are two basic ways that TCoefIDX can be used:

1) Run-length ordering: When bConfigHostInverseScan is “0”, MBscanMethod indicates a zig-zag, alternate-vertical, or alternate-horizontal inverse scan. In this case, TCoefIDX contains the number of zero-valued coefficients which precede the current coefficient in the specified scan order, subsequent to the last transmitted coefficient for the block (or relative to the start of the block if none preceding).

2) Arbitrary ordering: When bConfigHostInverseScan is “1”, MBscanMethod indicates arbitrary ordering. In this case, TCoefIDX simply contains the raster index of the coefficient within the block (i.e., TCoefIDX = u + v·WT)

TCoefIDX shall never be greater than or equal to WT·HT.

TCoefEOB Indicates whether the current coefficient is the last one associated with the current block of transform coefficients. TCoefEOB is the LSB of the first word of the DXVA_TCoefSingle data structure. A value of “1” is indicates that the current coefficient is the last one for the block, and a value of “0” indicates that it is not.

TCoefValue
The value of the coefficient in the block. TCoefValue shall be clipped to the appropriate range as specified in by the host prior to passing the coefficient value to the accelerator for inverse DCT operation. MPEG-2 mismatch control, if necessary, is also the responsibility of the host, not the accelerator (this may require the creation of extra “phantom” nonzero coefficients).


Kernel Streaming Overview

Kernel Streaming (KS) is a broad term for the services that support kernel-mode processing of streamed data. KS enables efficient real-time streaming for multimedia devices such as sound cards and TV tuner cards.

This chapter introduces Kernel Streaming topics that are relevant to minidriver development under the following Microsoft-supplied class driver models: Port Class, Stream Class, and AVStream. For information specific to developing minidrivers under AVStream, please see AVStream Overview.

The following diagram shows the kernel streaming model in Windows 2000, Me, and Whistler operating systems. Note that AVStream is valid only in DirectX 8.0 and Whistler.

Microsoft provides three class drivers, all of which broker interactions between the KS layer at the top of the diagram, and the minidriver below. These class drivers are clients of the upper KS layer, which provides a set of services in compliance with the Microsoft-defined WDM-CSA (Windows Driver Model Connection Streaming Architecture) kernel streaming specification.

  • AVStream is a new class driver that provides support for both audio and video minidrivers, and some additional features not found in its predecessors. Use the AVStream services if you are implementing a new driver, or if your existing stream or port class-based minidriver could benefit from being ported to use AVStream.

    AVStream is an acronym for "Audio/Video Streaming." More information on this class driver can be found in the AVStream Overview.

  • Kernel Streaming 1.0 (KS1.0) refers to the Microsoft-supplied Port Class and Stream Class class drivers. These class drivers provide services to facilitate development of audio and video minidrivers. For more information on the Stream Class, please see the Stream Minidriver Design Guide. Port Class is covered in the WDM Audio Driver Design Guide, and video capture and DVD minidrivers are covered in the Video Capture Minidriver Design Guide and DVD Driver Model Design Notes, respectively .

KS provides mechanisms for drivers to report capabilities to the operating system. Clients written to run on top of the kernel streaming model can determine the multimedia capabilities of the current platform. Kernel streaming is part of the Windows Driver Model (WDM).

KS drivers can be both filter and functional drivers. The operating system can load filter drivers to transparently extend the multimedia capabilities of a platform.

The WDM Streaming architecture divides processing of data into basic “building-blocks” called filters. These filters serve as the atomic components in the system. Each filter’s capability is partly described by a number of connection points called pin factories, from which pin instances can normally be created. Each pin instance can consume, produce, or both consume and produce a data stream, such as digital audio. More specialized tasks can be solved by connecting these filters together, via their pin instances, into a meta-topology (not the same as an internal filter topology discussed later). An example is connecting filters to play filtered and mixed audio.

The WDM Streaming architecture also provides mechanisms for querying filters and controlling filters (for example, getting the volume level, or starting playback). Specific implementation of these mechanisms, such as an interface to pass coefficients to a low-pass audio filter, are also provided.


Kernel Streaming Implementation

Kernel streaming is based on the DirectShow model of filters and filter pins. The distinction between Kernel Streaming and DirectShow is that KS runs in kernel-mode, and DirectShow runs in user-mode. KS filters, accessed using file handles, share an underlying device object per physical instance of hardware.

The following diagram illustrates the general concept of a filter.

The type of filter is defined by the functional categories to which it belongs. For example, an audio mixer could have a pin that consumes audio data, of which infinite instances can be made to connect to other audio producing filters. The mixer could also have a single pin which produces audio, of which only a single instance can be made.

Communication with this kernel mode filter by its user mode component takes place through file I/O; the communication path is established by calling the Win32 API CreateFile with the name of the device. For example, “\\.\filters\audio\default renderer” could be a link to the audio device which the user configured for default output. PnP will also expose enumeration APIs which can be used to locate both hardware and software based filters by supported filter functional categories. For more information on functional categories, see KSPROPERTY_TOPOLOGY_CATEGORIES.

Once a handle has been obtained, communication with this filter from user mode is performed by calling the Win32 API DeviceIoControl. This interface allows parameters which have been serialized into data-blocks to be passed to and from the filter. For instance, one method of communicating with filters via this API is by using a property set exposed by the filter. Property sets are a way of uniquely identifying a set of characteristics, and defining how which parameters are required in order to modify and retrieve these characteristics. For instance, a property could facilitate getting or setting a value such as volume.

Communication from user mode to a pin instance also normally takes place through file I/O. However, when establishing a connection to a pin factory, a client may instead choose some other supported method of communication. .

Pin factories represent locations where a filter can consume or produce data. Each pin factory may support a number of different data formats, such as 16bit 44K audio and 16bit 22k audio. The pin factories that are available on a filter, and their formats, can be enumerated from the filter. Thus, the pin factories are not seen as separate objects from the filter, but rather as a convenient grouping of capabilities. For example, if pin factory 2’s available formats are desired, they can be enumerated by calling DeviceIoControl on the filter requesting the property “PinFormats” for pin factory number “2”.

Configuration of a PCM sample sent to an FX processor and then to an audio renderer

A pin factory just represents the possible connection point, and before a client or another filter can stream data to or from a filter it must first create a pin instance connection and obtain a handle to that connection. This is done by specifying the pin factory number and the handle of the filter on which the connection is going to be made. Once the connection is made, a handle is passed back that can be used to stream data to or from. Note that this is similar to how classes and instances work in C++. The pin factory is the class of which instances (connections) must be made.

The connection path may have in or out data flow, such as demonstrated in the illustration above, in which audio data moves in a particular direction. It is important to note that although IRP flow through an IRP stack is top-down, the state transition path must be performed bottom-up to provide the proper stack order and depth. As a result, each pin factory must specify a communications property of sink, source or both that determines the connection type for each pin. For an IRP-based medium, this represents whether the pin is an IRP sink, source, or may act as either a sink or a source of IRP’s. This is not to be confused with data flow, as this describes how communication occurs once a connection is established.

Dispatching a state change request.

This illustration displays the communication and dataflow pin properties for the FX processor example.

An upper layer component submits a connection request to the kernel-mode filters using the connection API KsCreatePin, which in turn forwards this request to the filter. The data format property defines the raw data format of the medium.

Device objects and connections.

The above illustration displays the file handles created as the result of connection requests. The client requests a connection between the source and the sink pins. The sink connection point is always created first, and the handle is passed in when creating the source end of the connection. In this example, these filters create file handles to the connection in response to the request. As a result, the device object underlying the source will base its stack size on the stack size of the sink device object, plus one. The source device object will maintain a pointer to the sink device object, process incoming requests modifying data as necessary, and forward the requests to the lower level driver using the IoCallDriver function of the NT kernel. A file object is kept for each step of the path, which is handed to the next filter in the path. A handle to this file object is returned by the connection request, and is what is passed to the source connection point. The file object is referenced so that the handle may be closed by the client if no longer necessary. If instead the data flow was reversed, and the above rendering filter was a capturing filter, the order of connection would remain the same if the communication types on the various pins remained the same.

Creating a connection does not imply creating new device objects to represent the connection. A single underlying device object is used to support an instance of a filter, and all the instances of pins on that filter. The context information would normally be kept in the FILE_OBJECT.FsContext or FILE_OBJECT.FsContext2 of the file object structure. So context information is preserved while non-paged memory use is kept at a minimum.

As illustration below, a software digital audio mixer may provide an indeterminate number of connections to the source pin and provide a single destination pin. The pin properties define the medium; for this example the medium is DeviceIoControl. However, each pin may specify multiple mediums allowing the upper layers to determine the best possible data medium for the connection path.

Configuration of pins to mix multiple audio sources.

A device contains a stack depth indicator which the kernel uses when creating Irp’s for that device, no matter which, if any file object is associated with the Irp (It is possible for a kernel mode client of a device to not have a file object associated with an Irp, but this is a special case, such as PnP Irp’s). When various connections are made to a filter, this stack depth must be maintained such that any of the resulting I/O paths will have enough stack locations for any Irp passed through the filter. This depth is recalculated each time a pin transitions out of a Stop state. It is important for a filter to keep this depth as small as possible in order to minimize system resource usage.


Connection

The connection interface consists of IRP_MJ_CREATE, which is sent to the device object underlying the filter which owns the target pin on which the connection is being created. A connection request is either just a request to create a connection on a pin, or a request sent to one filter to connect a specified pin handle on another filter. In the former case, one would send a request to a filter to create a connection on its pin. In the latter case, the resultant handle from the aforementioned connection would be passed in a connection request to a filter to create a connection on its pin. That is, the second case must have a pin to connect to (sink), whereas the first case can be thought of as a connection from (source). Again, this terminology is only in reference to how the filters are connected together, and has no bearing on the direction in which data flows.

The second connection would increment the reference count on the underlying file object of the pin handed to it, and return a new file handle to the caller. A close would cause the connection to be terminated, however the handle on the first pin might still be open, so that must also be closed before the underlying file object is destroyed. This also implies that if the first pin is relying on resources provided by the second pin, it must be notified by the second pin when the connection is being terminated.

A connection is always represented by a file handle in user mode, which can be closed in order to terminate the connection. Within the filter, reference counts on the underlying FILE_OBJECT are incremented and decremented as other connections are created and destroyed. This means that after connecting a filter’s pins, none of the handles need to remain open excepting that which describes the connection points in the graph of filters (the second handle created when establishing a connection between pins). This includes the handle to the filter itself, which will be reference counted by pin instances as they are created. This also means that abnormal termination is handled robustly through the O/S process cleanup of handles. So the connection interface can be thought of as an IRP_MJ_CREATE which opens a pin instance with an extended set of parameters.

The extra parameters on the connection request specify the medium, interface, and data format to use on the connection. The medium is the basic method of communication that the connection will use. The IRP-based medium is what would normally be used, but this may be something different for filter’s whose functional piece resides on some DSP, and whose communication path could be contained on that DSP. The interface is the group of methods and properties to use, implemented on the specified medium. This could be a streaming music interface which would indicate a specific set of properties and methods available. The data format is the chosen format to use with that interface. This could be dynamically changed in some instances.

The KsCreatePin interface generates a call to NtCreateFile, using the filter file handle as the root, and the connection structure as the file name information. When a device routes this to its pin create dispatch function, the IRP is validated using KsValidateConnectRequest, which retrieves the connection structure.

For example:

The kernel mode client locates and opens the wave device filter and software mixer filter using PnP interfaces. This results in handles WaveDeviceHandle and SWMixHandle.

The client finds the appropriate pin factory for the connection on each device, enumerating properties on each pin factory if necessary.

The client calls the connection helper API to establish the connection on each filter, which is just a cover for sending an NtCreateFile request, passing the medium, interface and data format in a connection structure:

Error = KsCreatePin(
  IN SWMixHandle,
  IN Connect,
  IN DesiredAccess,
  OUT &PinHandle);

The connection API generates an NtCreateFile, which sends an IRP_MJ_CREATE to the filter, specifying the source pin factor identifier, and in the case of an IRP-source, the handle to the IRP sink pin previously created.

There are two properties within the pin property set which can be used to assist in determining if connections can be made, and using what data format. Depending on the use of these, a client need not know the structure of a specific data format type, or data range type. These are data ranges, and data range intersection. Querying data ranges allows a client to determine the full set of available data ranges for a specified pin. Querying data range intersection allows a client to specify a list of data ranges to choose from, and retrieve the best data format to use in connecting the specified pin. Given the internal topology, a graph builder can map the path from one data format on a pin, to another data format on some other pin, and determine if this path generates the correct result.

Data range intersection is meant to be used in conjunction with topology, and data ranges in order to choose a data format to connect filters, without having to know the specifics of a data format or data range. That is, the client could treat data formats as opaque structures, and still use these properties to choose viable data formats with which to make connections. Obviously the data range intersection is just that, an intersection, which may contain multiple choices. However, only the “best” choice would be returned by the filter in the form of a data format structure. This data format could then be passed on to use in determining how to make the pin connection. In some cases the entire graph of connections could be determined before actually making a single connection. Clients which have intimate knowledge of data formats and ranges may elect to perform their own intersection and choose a more appropriate data format rather than using what the filter proposes as the “best” format.

For instances wherein the affected pins and their data ranges are not known until the connection is actually made, such as a splitter filter which consumes the Active Streaming Format, and produces individual streams for each stream in the original stream, data range intersection may fail with an error specific to this case.


Connection Clients

Connections are instantiated through requests by a client. In some instances this client may be a filter which is abstracting underlying connections, but for the most part, the client is some set of tools such as DirectShow’s automated graph creation. This client may not actually know that there are kernel mode filters involved, but instead may be communicating with some generic DirectShow user mode filter which has enumerated properties and methods on the kernel mode component in order to present them as interfaces in user mode. Other clients may live on top of DirectShow, or instantiate the kernel mode filters directly. Such clients could include DirectX, VB, or Active Animation. These would provide solution graphs to specific problems, but may not use DirectShow to build the graphs. The advantage would be mostly one of efficiency, and creating an exact solution, but would be at a cost of being able to drop other filters into that same graph in order to perform additional synchronization. So at the very least it would be appropriate to use DirectShow filter graph objects, even if automated graph building is not used.

The above picture depicts using DirectShow as the connection client, with the standard Filter Graph Editor sample application showing the visual representation of the graph. From the point of view of DirectShow, these filters are just standard user mode components.

A client is responsible for:

  • Attempting to determine initial compatibility between two pins before requesting that they be connected, thereby making it more likely that a connection is possible.
  • Instantiating any intermediate filters needed in order to complete the connection in a compatible manner.
  • Assigning any quality management, and master clock.

If the user mode DirectShow filters are to be bypassed, the client is also responsible for negotiating medium, interfaces, and data formats to be used between the kernel mode filters. Normally this is something which the user mode DirectShow filters perform. The end result is that these connections become data and control paths, and are used by applications in synchronizing and transforming media streams.


Streaming Interface

The standard streaming interface consists of IOCTL_KS_READ_STREAM and IOCTL_KS_WRITE_STREAM, which are sent to pin connections to send or receive data in a non-buffered manner. These requests contain a stream header list, each optionally pointing to the actual stream data. The headers also may contain the presentation time and duration (depending on the data format negotiated, e.g., MPEG II may not always send buffers with time stamps). These presentation times are then used to synchronize to the master clock’s presentation time (when a master clock is being used). Altering this presentation time changes the synchronization between filter pins. This also enables easily relocating the synchronization points without modifying the data itself, and without maintaining an entire history of transforms to apply to an underlying physical clock in order to report that presentation time. The filter graph can then easily maintain timings with sample accuracy. For example, sending data through a filter that time-shifts audio samples and requires an external stream to synchronize to this shifted data is merely a matter of translating presentation timestamps.

The presentation time on a stream need not start at zero, but always progresses. For instance, playback from some file source may begin at some point within the file, so that the initial presentation time in the first stream buffer would most likely not be zero. Any change in this presentation time must be performed by a filter which alters such times, such as through some script. So presentation time can generally be thought of as “file” position, though the source may not at all be from a file. Some data formats allow buffers to be sent without time stamps and/or duration specified. They must use the appropriate flags specified below in that case.

DeviceIoControl(
  IN DeviceHandle,
  IN IOCTL_KS_WRITE_STREAM,  /* or IOCTL_KS_READ_STREAM */
  IN NULL,
  IN 0,
  OUT &StreamHdrList,
  IN StreamHdrCount,
  OUT &BytesReturned,
  OUT &Overlapped);

If the buffers passed to the streaming interface need to be modified in-place by the filter, the requirement must have been negotiated when determining an allocator. This enables efficient in-place transforms to be done on a stream of data without having to copy data as it passes through a series of filters. Additional media-specific streaming interfaces may be defined. For example a Music streaming interface may define additional music-specific properties in addition to the standard set, not to imply that media-specific streaming interfaces are always a superset of a basic streaming interface.

The stream header may also indicate that this is the end of a media stream or sequence. This is used to stop any QM problems from being generated, or to show the end of a segment within a stream containing discontiguous segments. If these flags are used on a write, there may be no actual data buffer attached to the request.


Kernel Streaming Client Interface

The interface a kernel streaming driver presents to a client consists of a set of file objects. Each file object represents a different capability of the driver. Clients issue I/O requests to file objects to control different aspects of the driver.

The file objects of a kernel streaming driver fall in several distinct families:

  • Filters

    A KS filter encapsulates a functional unit on a device. A driver can support multiple instances of the same filter. A driver for a multifunction device can support several different types of KS filters. Do not confuse KS filters with filter drivers — every type of KS driver, either functional or filter, has one or more KS filter file objects that it creates.

  • Pins

    A pin represents an I/O channel on the device. Clients can connect to pins, and connect pins to each other. Clients can also query a pin for the types of data formats it supports.

  • Clocks

    Drivers that support on-board clocks expose the clock as a file object. Clients can query the clock time, as well as request to be notified when the clock reaches a certain time.

  • Allocators

    Drivers that support custom memory management interfaces, for example management of device on-board memory, expose the interface as a file object. Clients can use the file object to allocate and deallocate memory.

KS file objects are organized hierarchically — clients use IRP_MJ_CREATE to instantiate KS filters on the driver, and in turn use IRP_MJ_CREATE to instantiate pins on the filter, and clocks and allocators on a pin.

The kernel streaming architecture provides an extensible mechanism for drivers and clients to interact. KS objects support several different semantic concepts:

  • Properties

    KS objects support properties. Clients can query the object to determine what types of properties it supports, and it can get or set such properties. For example, audio driver pins can support properties to allow clients to get or set the device volume.

  • Events

    A KS object can define the types of asynchronous events it supports. Clients can query the object to determine what events it supports, and they can request to be notified when an event occurs. For example, a client can request a clock object to notify it when the clock reaches a certain timestamp.

  • Methods

    Like COM objects, KS objects can support methods. For example, allocator objects support methods to allocate or deallocate memory.

Microsoft defines standard sets of properties, events, and methods. Clients and drivers can support these sets to cooperate to support standard forms of multimedia. Drivers can also support custom sets of properties, events, and methods that device-specific clients can use to interact with a particular device.

Clients interact with KS objects through a set of IRP_MJ_DEVICE_CONTROL IOCTLs. Clients specify the driver and kernel streaming object in the DeviceObject and FileObject members of the IO_STACK_LOCATION for the IRP.

  • IOCTL_KS_READ_STREAM

    Clients use this to read data from a pin.

  • IOCTL_KS_WRITE_STREAM

    Clients use this to write data from a pin.

  • IOCTL_KS_PROPERTY

    Clients use this IOCTL to get or set properties, or to determine the properties supported by a KS object.

  • IOCTL_KS_ENABLE_EVENT

    Clients use this IOCTL to request notification of an event type, or to determine the events supported by a KS object.

  • IOCTL_KS_DISABLE_EVENT

    Clients use this IOCTL to rescind a previous request notification.

  • IOCTL_KS_METHOD

    Clients use this IOCTL to execute a method on a KS object.

Drivers do not need to support these I/O requests directly. Microsoft provides class drivers to handle the intricacies of supporting these request. See Kernel Streaming Driver Implementation for details.


Kernel Streaming Driver Implementation

To ease the development of kernel streaming drivers, Microsoft provides class drivers which handle most of the work of supporting kernel streaming semantics:

  • The audio port class driver supports internal sound cards on a system bus such as ISA or PCI.
  • The stream class driver supports kernel streaming drivers which process video signals, including DVD devices, video capture devices. This class driver also supports external sound devices.
  • The AVStream class driver supports both audio and video minidrivers. Use AVStream for development of new classes of minidrivers, such as Broadcast Driver Architecture.

Each class driver provides an interface to support kernel streaming objects and their I/O requests. Drivers provide a description of the KS objects they support, and the class drivers transparently handle the creation of file objects, and receiving the IOCTL_KS_XXX requests.

The audio port class driver is documented in Audio Miniport Drivers. The stream class driver is documented in the Stream Minidriver Design Guide. For more on AVStream, please see the AVStream Overview.

For each individual multimedia technology area, Microsoft has defined standard kernel streaming semantics that drivers support. Audio, video capture and DVD devices are documented in the following chapters:

WDM Audio Driver Design Guide

Video Capture Minidriver Design Guide

DVD Driver Model Design Notes


Efficient Streaming

Kernel streaming is more efficient when the number of ring transitions is minimized. he following diagrams indicate different possible scenarios involving various numbers of ring transitions. Each ring transition is time- consuming due to parameter validation, security validation, and possibly data copying. Accordingly, your kernel streaming package will be more efficient with fewer such transitions.

The following diagram represents one possible flow of data. Code modules executing in user mode are shown above the double-line; code executing in kernel mode is shown below the double-line. The first transition of the data stream between user mode and kernel mode might be, for example, to achieve decompression. The second transition might be to perform rendering. In this case, KsProxy handles the transition to kernel-mode, effectively making a kernel-mode component appear as a DirectShow module to user-mode modules.

Data Streaming Involving Multiple User Mode to Kernel Mode Transitions

. In the next example, almost all the data streaming takes place in kernel mode. The filter modules executing in user mode apply controls to the kernel-mode device drivers and hardware. For example, in the case of a video data stream, a user-mode filter might apply a color correction control to the kernel-mode driver/hardware renderer.

WDM Data Streaming Involving One Mode Transition

The following diagram shows a stream entirely produced and consumed in kernel mode, with only controls exposed to the user mode client. In this case, , a source filter reads a file, passes it through a hardware based codec, and then passes it on through the remaining filters. If the filters in-between reside on the same physical hardware, they may negotiate a faster transfer mechanism or interface, which avoids memory copies, and possibly avoids use of the host CPU in their communication.

WDM Data Streaming Involving No Mode Transitions


KS Properties, Events, and Methods

Each KS object supports intrinsic operations that allow clients to get and set object state, execute object methods, and register notification callbacks for events. (For more on KS objects, please see the Kernel Streaming Glossary.) Drivers support each of these categories of operations — properties, methods, and events — in a standardized manner.

  • Set

    Functionally similar operations are grouped together in a set. Each property, event, or method set is identified by a GUID. Microsoft defines GUIDs for standard technology-specific operations. Drivers can define their own GUIDs for custom operations.

  • Identifier

    Each operation is specified by an ID number within the set.

  • Operation-specific identification data

    Specific operations may require additional data to be completely specified. For example, pins on an audio device support the KSPROPSETID_Audio property set. An audio pin may support several different audio channels. Clients getting or setting certain KSPROPSETID_Audio properties must specify the audio channel to which the request applies. Currently, the only Microsoft-defined KS operations that require additional data are property sets.

Standard GUIDs and identifiers for general-purpose operations are found in the header ks.h. Standard GUIDs and identifiers for particular classes of multimedia technology are found in ksmedia.h.

Clients issue I/O requests to get and set properties, execute methods, and register or unregister event notifications. For each of these I/O requests, the client passes two buffers:

  • Instance Specification. The client specified the operation instance to be the target of the I/O request. Every instance specification begins with a header that describes the operation set, operation ID, and operation flags, followed by any operation-specific identification data. The following table describes the header structures.
    Operation type | Instance specification header
    Property | KSPROPERTY
    Event | KSEVENT
    Method | KSMETHOD

    To handle operations that require extended data structures, drivers use extended data structures that contain the instance header as the first member. For example, properties in the KSPROPSETID_Pin property set use the KSP_PIN structure to specify the property instance. The appropriate extended data structure is documented with each individual property set.

  • Operation data. The client specifies a data buffer for the operation. Property requests use this buffer to either get or set the property. Method requests use this buffer for method input or output. Event notification requests use this property to determine the event notification type requested.


KS Properties

Filters and pins can support property sets that represent things like the number of pins available and the types of connections they can make. Property sets are also used to configure filters and pins. Property sets are a method for accessing a group of related data on an object, and each property request may be fulfilled either synchronously or asynchronously.

Each property set has a unique identifier, which is used to access a requested property set. The method of using unique identifiers for property sets allows custom driver extensions that will not conflict with any other custom extensions or future development.

Filters and pins support property sets using the IOCTL_KS_PROPERTY device I/O control. If a filter or pin must support multiple distinct copies of the same property set, it must use instance identifiers.

The flags of an identifier are used to distinguish between Getting a property and Setting a property.

To get or set individual properties, clients call the Win32 function DeviceIoControl with an IOCTL_KS_PROPERTY request. The class driver in use receives an IRP, in turn, and then the class driver calls KsPropertyHandler.

KsInitializeDriver initializes the driver object of an AVStream driver. Clients make this call from DriverEntry. Note that clients wishing to handle device initialization on their own do not need to call this function. KsInitializeDriver takes as one of its parameters a pointer pointing to an array of structures containing filter descriptors for the individual filter types supported by the device in question. Moving down the chain to properties, KSFILTER_DESCRIPTOR has a pointer to a KSAUTOMATION_TABLE, a new AVStream feature that consolidates properties, methods, and events. Defining Automation Tables in the BDA Design Guide contains more information on automation tables. As such, a KSAUTOMATION_TABLE contains a pointer to an array of KSPROPERTY_SET objects. KSPROPERTY_SET is a KS 1.0 structure that contains a pointer to an array of KSPROPERTY_ITEM objects. Another KS 1.0 object, KSPROPERTY_ITEM contains pointers to handlers for property events, such as Get and Set.

The Flags member of KSPROPERTY specifies the type of operation: KSPROPERTY_TYPE_GET for a get property request, and KSPROPERTY_TYPE_SET for a set property request.

When the client makes a get property request, the driver returns the property in the data buffer the client passes. When the client makes a set property request, the driver uses the data in the passed data buffer to specify the new property value.

Additional values for the Flags member allow the client to request information about a property. For example:

  • KSPROPERTY_TYPE_SETSUPPORT

    If the client specifies this flag, the driver returns no data in the data buffer, but it returns STATUS_SUCCESS if it supports the property set, and an error code if it does not.

  • KSPROPERTY_TYPE_BASICSUPPORT

    If the client specifies this flag, the driver returns STATUS_SUCCESS if it supports the property, and an error code if it does not. In the data buffer, the driver passes information about the property, such as if the property is read-only, write-only, or read-write.

All property sets must support the KSPROPERTY_TYPE_BASICSUPPORT and KSPROPERTY_TYPE_RELATIONS flags. These allow queries for the support of a specific property within a property set, optionally valid values, and related properties, if supported by that property. Do this by specifying a support handler in the SupportHandler field of KSPROPERTY_ITEM.

For basic support (KSPROPERTY_TYPE_BASICSUPPORT), the flags returned from a query determine whether one has read, write, or read/write access to the property. The queried identifier is appended to the structure as property-specific data. For multiple instance property sets, this refers to all the sets as a whole, rather than any particular instance. When querying for related properties, a list of related properties is returned.

Furthermore, the return from a KSPROPERTY_TYPE_BASICSUPPORT request depends on the size of the output buffer passed to the call. If the output buffer is the size of a ULONG, only the access flags are returned. If the output buffer is the size of the KSPROPERTY_DESCRIPTION structure described below, the structure is filled with the access flags (KSPROPERTY_TYPE_GET and KSPROPERTY_TYPE_SET that are the same flags used when Setting and Getting the property), the inclusive size of the entire values information, the property value type information, and the number of members lists that would normally follow the structure. Otherwise the size of the output buffer must be large enough to contain both the description header, and all values information (excluding the default value that can be queried separately). This allows a client to query the size of values information before attempting to acquire it. Please see KSPROPERTY_DESCRIPTION for more information.

Also see KSPROPERTY_MEMBERSHEADER for more information.

The property values within a filter are stored in a slightly different manner, with the aim towards easy static definitions, and enumeration by a helper function that converts to a serialized format for return. Its property item description (KSPROPERTY_ITEM is described later) may optionally point to a KSPROPERTY_VALUES structure, which contains a list of value lists.

Each outer list element is a wrapper for a KSPROPERTY_MEMBERSHEADER structure, and the list of associated values. The values list depends on the description in the header, containing a range, stepped range, or straight values.

  • KSPROPERTY_TYPE_DEFAULTVALUES

    If the client specifies this flag, the driver uses the data buffer to return a description of its value type, including possibly its allowed range and default value. This flag is similar in result to KSPROPERTY_TYPE_BASICSUPPORT, except that any values returned are those that have been marked with KSPROPERTY_MEMBER_FLAG_DEFAULT in KSPROPERTY_MEMBERSHEADER.Flags.

  • Relations

    For relations support (KSPROPERTY_TYPE_RELATIONS) the return also depends on the size of the output buffer passed to the call. If the output buffer size is zero, the size that would be used to return the related properties is returned in BytesReturned with a warning status of STATUS_BUFFER_OVERFLOW. Else if the buffer is the size of a KSMULTIPLE_ITEM structure, both the byte size and count of relations is returned. Else the buffer is expected to be long enough to return the KSMULTIPLE_ITEM structure and all related property identifiers, which is returned as just a list of KSIDENTIFIER structures. This is how a client determines the effects of changing this property, which may affect properties in completely different property sets. The assumption is that if a related property is returned in the list, that is all the information necessary to find that property. I.e., it belongs to a property set on the same pin, filter, or clock, and there is only one such property set, not multiple instances, or refers to the same set instance.

  • Serialization

    Support for serialization of a property set is done through KSPROPERTY_TYPE_SERIALIZESET and KSPROPERTY_TYPE_UNSERIALIZESET. These allow a built-in method of acquiring, or setting the state of multiple properties with a single call from the client. These are broken up into multiple calls by KsPropertyHandler if the KS handler is being used to process property requests. When using this handler, the property set definition controls which properties are to be serialized. The KSPROPERTY_ITEM.SerializedSize is checked for a non-zero value indicating the size in bytes of the property, where –1 is unknown and must be queried (all unknown properties begin with a KSMULTIPLE_ITEM structure that can be queried separately). A value of zero indicates that the property should not be serialized. To query for the total size a serialization would take, pass a zero length buffer. The in BytesReturned is filled with the size in bytes the buffer must be to serialize the set and a warning status of STATUS_BUFFER_OVERFLOW is returned. A buffer allocated that size can then be filled with the serialized data.

    The format of the serialization buffer is a KSPROPERTY_SERIALHDR, followed by serialized properties. Each property that follows contains a header (KSPROPERTY_SERIAL), followed by the property data, with the start of each property on FILE_LONG_ALIGNMENT. Note that the serial header structure is defined to be on FILE_LONG_ALIGNMENT.

  • Raw Serialization

    Support for raw serialization of a property set is done through KSPROPERTY_TYPE_SERIALIZERAW and KSPROPERTY_TYPE_UNSERIALIZERAW. This can only be supported if a property item handler exists, as the data format is private to the property set. The standard KsPropertyHandler function just passes this on to the handler, if one exists. Size of such serialization can also be queried by passing a zero length buffer to a serialize raw request. Since handlers are attached to property items, and not the property set, then a specific item within the property set must be specified in the Property parameter. This handler may deal with multiple properties within the set.

  • Parameter Access Macros

    The following macros are defined to allow access to Irp->Tail.Overlay.DriverContext parameters in the Irp passed to a handler function. These are initialized by KsPropertyHandler and KsPropertyHandlerWithAllocator.

  • KSPROPERTY_SET_IRP_STORAGE

    This macro accesses a pointer to the KSPROPERTY_SET in which the property was located.

  • KSPROPERTY_ITEM_IRP_STORAGE

    This macro accesses a pointer to the specific KSPROPERTY_ITEM located. Note that this value is only set when using KsPropertyHandlerWithAllocator.


KS Events

See KS Properties, Events, and Methods for an overview of KS operations.

See Event Handling in AVStream for details on how minidrivers running under AVStream should handle events.

Clients of a driver can request to be notified when a certain condition holds. For example, a client can schedule to take a specific action when the time stamp on a data stream reaches a certain point.

To request event notification, the client submits an IOCTL_KS_ENABLE_EVENT request. In the data buffer of the request, the client passes a KSEVENTDATA structure that describes how the driver should notify the client when the event occurs.

Clients can unregister an event through the IOCTL_KS_DISABLE_EVENT request. To identify the event, clients passes the address of the original data buffer. This address does not have to point to the original data buffer — the driver simply uses it to identify which event notification to disable.

An event type may require additional parameters of the event notification to be specified. For example, the KSEVENT_CLOCK_POSITION_MARK event on a clock is triggered when the clock reaches a certain time stamp. Clients that register to be notified of this event must also specify the timestamp that triggers the event. Any additional data parameters are passed in the data buffer after the KSEVENTDATA structure. Drivers that support such an event type use an extended data structure, whose first member is KSEVENTDATA, to hold the notification data. The structure types are discussed with the respective event set.

The client can specify different options for the event notification within the Flags member of KSEVENT:

  • KSEVENT_TYPE_ENABLE

    The driver notifies the client each time the event occurs, until the client explicitly unregisters the notification.

  • KSEVENT_TYPE_ONESHOT

    The driver notifies the client the first time the event occurs. The client is not notified on any subsequent occurrences of that event, and does not need to unregister the notification.

  • KSEVENT_TYPE_ENABLEBUFFERED

    Instead of notifying the client, the driver queues event notifications. The client then issues a second IOCTL_KS_ENABLE_EVENT request with the KSEVENT_TYPE_QUERYBUFFER to receive the queued event notifications.

Clients can also use the KSEVENT_TYPE_SETSUPPORT and KSEVENT_TYPE_BASICSUPPORT flags to probe a KS object for its support of an event set, or a specific event.


KS Methods

See KS Properties, Events, and Methods for an overview of KS operations.

Clients use the IOCTL_KS_METHOD request to execute a method on a KS object. The Flags member of KSMETHOD specifies the validity of the data buffer for the operation: KS_METHOD_TYPE_NONE if the data buffer cannot be read or written to, KS_METHOD_TYPE_READ or KS_METHOD_TYPE_WRITE if the data is read- or write-only, and KS_METHOD_TYPE_MODIFY if the data buffer can be both read or written.

Clients can also use IOCTL_KS_METHOD to query if a driver supports a method set by specifying KS_METHOD_TYPE_SETSUPPORT, or a specific method within a method set by specifying KS_METHOD_TYPE_BASICSUPPORT.


Method Sets

Method sets are used to perform an action, rather than merely setting or retrieving an attribute as in properties. As a general rule, if an aspect of a device is manipulated by “getting” and “setting” it, then it is most likely a property. However, if it is something that performs an action, such as allocating memory, then it is most likely a method.

Method sets provide a way to access related actions. Each method request may be fulfilled either synchronously or asynchronously. The method sets themselves have unique identifiers, which are used to retrieve the correct method set requested. The method of using unique identifiers for method sets allows custom driver extensions that will not conflict with any other custom extensions, or future development.

Filters or pins support method sets using the IOCTL_KS_METHOD device I/O control. If a filter or pin must support multiple distinct copies of the same method set, it must use instance identifiers.

Although similar to a property set, the parameters for a method differ in that a method may pass no information, or pass it in, out, or bi-directionally. The expected parameter passing type is determined by the definition within the filter, and must be known to the client. The filter uses the first group of flags to define the type of method. The client uses the second set of flags when initiating a method request. These flags indicate what action, if any, will take place on the second buffer of the device I/O control.

The request is passed using the KSMETHOD structure, which may contain instance information appended to the structure. A method-specific buffer may be passed.

All method sets must support the KSMETHOD_TYPE_BASICSUPPORT flag, and allows one to query for the support of a specific method within a method set. The buffer is returned with the flags specifying the type of support for the method (KSMETHOD_TYPE_WRITE, etc.), or an error is returned. In order to query for support of a method set in general, use the KSMETHOD_TYPE_SETSUPPORT flag. In this case the identifier is ignored.

The IOCTL_KS_METHOD is defined using the METHOD_NEITHER flag. However, the buffers are copied as needed when processed using the KsMethodHandler service. The first buffer is copied, and the second buffer is copied if needed according to the above flags. Therefore access exceptions on this data is not a problem within method handlers called by this service, except for the case of KSMETHOD_TYPE_SOURCE in combination with KSMETHOD_TYPE_NONE. Refer to the API section for details on this service.

Parameter Access Macros

The following macros are defined to allow access to Irp->Tail.Overlay.DriverContext parameters in the Irp passed to a handler function. These are initialized by KsMethodHandler and KsMethodHandlerWithAllocator.

KSMETHOD_SET_IRP_STORAGE

This macro accesses a pointer to the KSMETHOD_SET in which the method was located.

KSMETHOD_ITEM_IRP_STORAGE

This macro accesses a pointer to the specific KSMETHOD_ITEM located. Note that this value is only set when using KsMethodHandlerWithAllocator.

KSMETHOD_TYPE_IRP_STORAGE

This macro accesses the type of method as described in the KSMETHOD_ITEM. If the method will be processed asynchronously using KsDispatchSpecificMethod, this storage must be maintained intact.


KS Filters, Pins and Node Topology

This section introduces the basics of pins and their interactions.


Pin Connections

To interact with a KS driver, a client instantiates a KS filter on that driver. Clients normally instantiate a KS filter through Microsoft® DirectShow®. A driver can support multiple types of filters, and multiple instances of the same type of filter. Typically, a driver might support multiple types of filters if it supported multiple types of multimedia functionality. When the client instantiates a KS filter, the driver creates a file object. The client sends all subsequent kernel streaming I/O requests to filter, or any child file objects it creates.

Each KS filter can support several different streams of data simultaneously. To set up a data stream, the client instantiates a pin on the filter. The filter represents each pin as a file object subordinate to the file object for the filter. The client instantiates a pin by sending an IRP_MJ_CREATE request to the filter.

Pins come in different flavors that determine how they can be used:

  • IRP source versus IRP sink

    An IRP sink pin responds to IOCTL_KS_READ_STREAM and IOCTL_KS_WRITE_STREAM requests; an IRP source pin issues them. A client can send I/O requests directly to an IRP sink pin. When a client instantiates an IRP source pin, on the other hand, it specifies an IRP sink pin the IRP source connects to. Once connected, the IRP source pin transparently reads or writes data to the IRP sink, with no further intervention by the client required.

  • Data source versus data sink

    A data source pin provides data, while a data sink pin consumes data. Data source pins can only be connected to data sink pins. Note that the property of being a data source or sink is independent of being an IRP source or sink. For example, the client can connect a data source, IRP sink pin to a data sink, IRP source pin. The IRP source pin sends IOCTL_KS_READ_STREAM requests to fetch data from the IRP sink.

By forming connections between KS filters, a client can dynamically assemble a filter graph through which data can flow transparently. For example, a client could dynamically load a filter that translates between audio data formats, and attach it to serve as a bridge between two devices that speak different formats.

Note that the DDK provides the grapher utility (grapher.exe) in the tools\wdmaudio directory of the DDK. The grapher utility can be used to build, examine, and test WDM KS filter graphs on Windows 98/Millennium and Windows 2000. Although the grapher utility is designed primarily for audio filter graphs, it can be used to build and explore graphs for any WDM KS filters.

When a client performs I/O, it usually has specific requirements for the type of data it wishes to send or receive from the device. For example, a client can choose whether it receives audio or video data from a DVD player. To this end, KS filters expose several different pin factories. In its create request, the client specifies a pin factory, and the filter creates a pin of that type for the connection. The filter can create one or many pins from the same pin factory.

To provide for run-time discovery of pin factories and their capabilities, KS filters support the KSPROPSETID_Pin property set. Clients use the KSPROPERTY_PIN_CTYPES property of this property set to determine the number of pin factories supported by the filter. (See KS Properties for a general description of properties and property sets.)

The other members of the KSPROPSETID_Pin property set allow clients to discover individual properties of each pin factory. Clients can query for the following pin factory properties:

  • Communication direction

    (KSPROPERTY_PIN_COMMUNICATION) This property specifies the direction of IRP flow on pins instantiated by the pin factory. Pins can be IRP sources, IRP sinks, both, or neither.

  • Dataflow direction

    (KSPROPERTY_PIN_DATAFLOW) This property specifies the direction of data flow on pins instantiated by the pin factory. Pins can be data sources, data sinks, or both.

  • Data formats

    (KSPROPERTY_PIN_DATARANGES, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, and KSPROPERTY_PIN_DATAINTERSECTION) Pins typically can support only certain data formats. These properties specify the data formats supported by pins instantiated by the pin factory. See KS Data Formats and Data Ranges for details.

  • Medium

    (KSPROPERTY_PIN_MEDIUMS) Devices can support custom communication mediums that bypass IRP processing. For example, a DVD device might be able to write directly to the video card, bypassing the CPU. The KS filter represents such mediums by a GUID that represents the medium set, and an ID number that identifies the medium within the medium set. Clients use this property to request a list of all mediums supported by pins instantiated by the pin factory. Clients specify the actual medium to use when they connect to the pin.

  • Interface

    (KSPROPERTY_PIN_INTERFACES). Pins instantiated by the pin factory can require a certain set of properties, events, and methods. The KS filter uses the interface property to indicate the pin factory requirements. Each interface is identified by a GUID that represents the interface set, and an ID number that identifies the interface within the interface set.

  • Category

    (KSPROPERTY_PIN_CATEGORY). The KS filter uses this property to indicate the standard functional category of pins instantiated by the pin factory.

  • Name

    (KSPROPERTY_PIN_NAME). The KS filter can provide names for each of its pin factories in the Registry.


Pin Internal Topology

KS filters may also support internal connections. For example, consider a simple filter that has one data sink pin and one data source pin. The filter receives incoming data on the data sink pin, processes it internally, and writes it to the data source pin. In the following figure, the pins are shown as heavy line segments. Internally, the filter connects the data sink pin to an internal processing unit, a node, which in turn is connected to the data source pin.

Diagram of a Simple KS Filter

More complicated devices may combine or split data flows between pins. For example, consider an audio mixer that supports several pin instances that accept data streams. The mixer combines them into a single stream, and writes that stream to a data source pin. Graphically, we could represent the data flow as follows:

Diagram of a Mixer

Each input pin can be thought of as connected to output pins on the mixer node in the center. The mixer node, in turn, can be thought of as having an input pin connected to the output pin on the KS filter. The graph describes the internal relationship between the filter's pins. An even more complicated device could support several different nodes, which perform different transformations on data flowing through the filter.

KS filters can report internal connections between pins, and internal nodes through the KSPROPSETID_Topology property set.

  • The KSPROPERTY_TOPOLOGY_NODES property provides a sequence of GUIDs that represent the type of the node. Microsoft defines a standard set of node types of the form KSNODETYPE_XXX in the ksmedia.h header. In other requests of the property set, clients refer to a node by its zero-based index in this sequence.
  • The KSPROPERTY_TOPOLOGY_CONNECTIONS property provides a sequence of KSTOPOLOGY_CONNECTION structures that represent the connections between pins and nodes.
  • In the mixer example above, the sequence of KSTOPOLOGY_CONNECTION structures could be as follows:
    //    FromNode,       FromNodePin,     ToNode,        ToNodePin,
{
 {  KSFILTER_NODE,        0,            0,               0     },
 {       0,               1,       KSFILTER_NODE,        1     }
}
  • The KS filter represents internal connections as pins on the internal nodes. Actual pins are represented as connections on the KSFILTER_NODE node.


Reading and Writing on Pins

Clients perform reads and writes on pins by scatter/gather. When a client submits an IOCTL_KS_READ_STREAM or IOCTL_KS_WRITE_STREAM requests, it passes an array of KSSTREAM_HEADER structures that describe the data buffer for the operation.

Each entry in the KSSTREAM_HEADER array describes one entry in the scatter/gather list. The Data member holds the virtual address of the data buffer, while the FrameExtent member specifies the size. Typically, each entry specifies a single frame in a stream of time-dependent data. Drivers can include a current time stamp in the PresentationTime member and a duration in the Duration member.

KS drivers and clients can dynamically negotiate data formats. When the data format of a stream changes, the driver specifies the KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY flag in the OptionsFlag member of a KSSTREAM_HEADER. The driver passes the new data format itself, described in a KSDATAFORMAT structure, in the corresponding data buffer. For more details, see KS Data Format Negotiation.

Drivers or clients can also specify stream state information in the OptionsFlag member of KSSTREAM_HEADER. For example, KSSTREAM_HEADER_OPTIONS_ENDOFSTREAM specifies that the current frame is the last. See KSSTREAM_HEADER for a description of the possible flags.

Drivers may require extended stream header structures to describe each frame. Such a structure must contain KSSTREAM_HEADER as its first member. For example, video streams require the KS_FRAME_INFO structure to describe each frame of streaming video data.


KS Data Formats and Data Ranges

The following sections introduce the basics of data formats and data ranges: specifying data formats and ranges, and negotiating data formats.

Specifying a KS Data Format or Data Range

KS Data Format Negotiation


Specifying a KS Data Format or Data Range

To support the many forms of multimedia data, each pin possesses a current data format. Data formats are specified by one, two, or three GUIDs, plus optionally some additional parameters particular to each data format.

Each data format has a major format GUID. Within major formats, the data format can require a subformat GUID and a specifier GUID. A particular data format can also require additional information to completely determine the data format. For example, the major format KSDATAFORMAT_TYPE_VIDEO requires the length and width of the viewing area of the source video stream to be completely specified.

Both clients and drivers use the KSDATAFORMAT structure to describe data formats. The structure specifies the three GUIDs that specify the basic format type, followed in memory by a variable-sized format-specific data block.

Pins typically frequently support ranges of data formats. For example, a pin can support the KSDATAFORMAT_TYPE_VIDEO major format, but for a restricted range of values for the length and width of the source viewing area. Drivers use the KSDATARANGE structure to specify a range of data formats (drivers can support several different ranges). The format-independent part of KSDATARANGE is a copy of KSDATAFORMAT – the driver can specify a specific GUID for the major format, subformat, or specifier, or the driver can specify a wildcard to match all formats, all subformats, or all specifiers.

The standard members of KSDATARANGE are also followed in memory by a variable-sized format-specific data block. The layout of this block is independent of the format-specific data block used by KSDATAFORMAT, even for the same major format, subformat, and specifier. For example, to specify a range of values for the length and width of a video viewing area requires more information than specifying a single value for the length and width, so the data range structure used by KSDATAFORMAT_TYPE_VIDEO is laid out differently than the data format structure used by the same format type.

Thus, each data format has two data structures associated with it – one to specify the data format, and one to specify a range of the data format. The documentation for each data format includes both the data format structure, and the data range structure.

Note that while KSDATAFORMAT and KSDATARANGE have the same standard headers, the variable-sized data block that follows need not be the same. For example, video capture drivers use the KS_DATAFORMAT_VIDEOINFOHEADER structure to describe video data formats, and the KS_DATARANGE_VIDEO structure to describe ranges of data formats.


KS Data Format Negotiation

Clients and KS filters can negotiate the data format to use for a data stream. Clients can use four different properties to query data format support of pins instantiated by a given pin factory on the filter:

  • KSPROPERTY_PIN_DATARANGES. The KS filter reports all data ranges supported by pins instantiated by the pin factory. This includes every data format the pin can ever support.
  • KSPROPERTY_PIN_CONSTRAINEDDATARANGES. The KS filter reports all data ranges supported by pins instantiated by the pin factory, given the current internal driver state.
  • KSPROPERTY_PIN_PROPOSEDATAFORMAT. Clients can use this property to query if pins instantiated by the pin factory support a specific data format. The KS filter returns STATUS_SUCCESS if the pins supports the data format, or an error code otherwise.
  • KSPROPERTY_PIN_DATAINTERSECTION. Clients can use this property to offer a range of data formats. The KS filter returns a single format in that range that pins instantiated by the pin factory support, if any exist.

Once a pin is instantiated, the client can determine the current data format or request a change of data format through KSPROPSETID_Connection property requests. For example, the client can use the KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT request to determine if a pin supports a given data format. The client can then use the KSPROPERTY_CONNECTION_DATAFORMAT request to actually change the data format.


KS Clocks

KS drivers use clock objects to represent a time-dependent counter. Clock objects can represent actual on-board hardware clocks, or they can represent the current timestamp of a data stream.

Clocks support the KSPROPSETID_Clock property set. A clock provides two, possibly different, timestamps at any given instance. The physical time of a clock is tied to a physical clock — either the system clock, or an on-board hardware clock The physical time of a clock only moves forward. The presentation time of a clock represents the timestamps on a data stream. For example, a clock can represent the current time on an audio stream that supports rewinding. The presentation time may reverse, or be reset to arbitrary values.

Clients can use the KSPROPERTY_CLOCK_PHYSICALTIME property to determine the current physical time on the clock, and KSPROPERTY_CLOCK_TIME to determine the current presentation time. For either request, the driver returns the current time in 100 nanosecond units in a LONGLONG in its data buffer. Clocks are not required to support a 100 nanosecond resolution. Clients can determine the actual clock resolution through the KSPROPERTY_CLOCK_RESOLUTION property.

A client can request to be notified when a clock reaches a certain timestamp, or to receive periodic notification that a fixed amount of time on the clock has elapsed. To do so, clients register the KSEVENT_CLOCK_POSITION_MARK to request notification that a certain timestamp has been reached, and KSEVENT_CLOCK_INTERVAL_MARK to request periodic notification.

A data stream may synchronize input and output to a clock, known as the master clock for the stream. Drivers can synchronize their streams to clocks created by other drivers, and multiple streams can be synchronized to one clock. A client can determine the master clock on a pin through the KSPROPERTY_STREAM_MASTERCLOCK property. Clients can also use this property to set the master clock for the pin.


Master Clocks

A master clock controls the rate of presentation time within a graph, and is used by filters within that graph to synchronize presentation time stamps in streams. It provides a standard mechanism to query the current presentation time, query the physical clock time, compare presentation, physical, and local host times, and to establish event notifications based on position changes in the master clock’s presentation time. A client of a master clock may also look at the parent file object of the clock, which is contained in FILE_OBJECT.RelatedFileObject. This allows a filter to determine if the clock is actually owned by that particular filter, even in the case where the device object supports multiple filters, or different clocks on multiple pins. Master clocks are assigned to pins by the filter graph, and are acquired from filter pin instances that provide clocks.

A master clock’s current presentation time is normally derived from the presentation time of a particular stream within a graph, though it could also be derived from some external pulse, such as the local host clock. If it is being derived from a stream, and the stream experiences a famine state, the reference clock will also stall until data flow has resumed, unless the time discontinuity flag is set. When a graph is stopped, the clock presentation time is stopped, thus, a clock is a graph-specific entity, and sharing a clock between graphs would likely be handled by some proxy inbetween, which interprets the changes in the first graph’s clock so that the graphs are independent.

In some cases the data stream may have time discontinuities. When these discontinuities are marked in the data stream, the presentation time should continue to progress at the underlying physical clock rate, until the next data frame is sent. At that point, if the presentation time has not reached the timestamp present in the new frame, then rendering of the frame is delayed until that point. If the presentation time has already proceeded past the frame’s presentation time, then the physical time is set back to the frame’s timestamp, and the frame is rendered. If the frame has no timestamp, it is assumed to be stamped with whatever the current presentation time is, and immediately rendered. If the time discontinuity is not marked, then the presentation clock will stall until the next frame is received. It will then be set to the timestamp on that frame. If the frame has no timestamp, it is assumed to be stamped sequencially with the current time.

This treatment of time discontinuities holds true for both data streams of regular sample frequency, such as video and audio, and those with irregular sample frequency, such as MIDI. In the case of a MIDI data stream, each packet should have a time discontinuity flag set, so that the presentation time, which is based on some underlying physical clock, can continue to progress. When the next packet is received, the presentation time will progress until the new timestamp is reached, and the samples will then be rendered. If the flag is not set, then the presentation time will not progress, and the next packet will determine what the new presentation time will be. If the next packet does not have a timestamp, the presentation time will just progress from the same point, and the packet will be immediately rendered.

The interface to a master clock is a file object and supports methods, properties and events just as filters and pins. All queries against the file object are available only at PASSIVE_LEVEL. However, the clock position query is also supported through a direct function call pointer available at DISPATCH_LEVEL, which is valid as long as the file object is valid. This direct call must be passed the clock’s file object as a context parameter. It is assumed that the filter that acquired the clock file handle will ensure that there are no outstanding calls to the clock entry points when the file object is released.

The file handle is acquired through a create request on a filter pin instance, much as the pin creation is done by IRP_MJ_CREATE. The request causes a file handle to be created, just as a file handle to a pin is created, with its own context information. This is then passed back to the caller. This handle can then be used to set the master clock for kernel mode filters. The pin instance that owns the master clock can tell that it indeed owns the master clock when the filter is being assigned the graph’s master clock by querying for the parent file object.

Not all filter pins have to support a master clock or synchronize to a master clock, and most likely only rendering and capturing pins need do so.

When a filter is given the file handle to this master clock, it can then be used to query properties and such. From a DirectShow point of view, if a master clock is based on a kernel mode filter, it must support an interface to query the file handle to the kernel mode portion of the master clock. If the interface is not supported, then it is assumed that the clock is user mode-based, and kernel mode filters cannot synchronize to it. The DirectShow proxy filter requesting the master clock handle would then pass it to its underlying kernel mode filter file handle. The kernel mode filter would reference the underlying file object. If the filter already had a master clock, it would dereference the file object and use the new handle, which may be NULL for no master clock, instead. This can only be done when the filter is in a Stop state.

The DirectShow proxy filter is responsible for closing the handle it retrieved from the master clock interface. Also, a kernel mode filter must release its reference on any master clock on being closed in case of abnormal termination. Any DirectShow proxy filter will support a property that indicates that the filter must have a kernel mode-based clock. This will allow any graph building process to build viable graphs more efficiently. Additionally, a kernel mode proxy for a user mode clock exists. This accepts correction times from a client, and interpolates using the PC clock.

Any user mode component, including the user mode proxy of the master clock, becomes just another client of the master clock, except that it cannot acquire the direct function call pointer used at DISPATCH_LEVEL by kernel mode filters. So the DirectShow proxy filters could retain the handle acquired from the master clock for direct access to the kernel mode clock, or duplicate the handle for cross-process access. However, the same interfaces should be available on the proxy clock itself.

The clock presentation time is used by other filters or applications to synchronize actions or stream presentation times to. There is no method to set the presentation time on a master clock directly. One would indirectly affect clock presentation time by pausing, flushing, and seeking a graph to some presentation time. This will cause new data to be retrieved with a new presentation time. Normally source filters would pay attention to a seek presentation time request, and produce data with the new presentation time. The first timestamp on the stream underlying the master clock would set the new clock time.

If a filter is composing a stream from multiple sources, each of which is composed of data within different parts of a file, the composing filter must obviously be communicating with an interface that specifies byte positions, and translate presentation timestamps to use in the streams. Such filters feeding the composition filter would be passed modified presentation time positions in seek requests, or they may ignore the seek position if the composition filter interface request specific data. In other words, either a filter is receptive to seek requests, and may additionally use the master clock to synchronize its pins presentation times with clock presentation time, or it receives specific requests from a connection.

A graph does not necessarily have a master clock. Data could be presented a nominal rates based on individual physical clocks with no specific relationship to each other. For instance, an audio stream mixer with independent pins that are merely mixed, but not necessarily with any specific relationship to each other, would not need a clock.

The physical time on the master clock object is one that is normally hardware-based, and although related to the clock presentation time by virtue of being presented by the same filter pin, is independent of it. It would normally be connected to the rate at which data is actually being presented, but may not be running when the graph is in a Pause state. That is, if some pre-roll is done when in a Pause state, it may not affect the physical clock. If a filter that presents the master clock has no physical clock at all, and merely presents data as it is received, then presumably the “physical clock” would actually just progress on a basis of the data presented, and probably stop progressing when data is not being presented, as when the device is in a famine state.

The physical time behind the master clock may be remote, in which case it is the responsibility of the local proxy to provide accurate readings. For instance, compensating for the delay across a 1394 connection, or averaging the delay across a network. Additionally, if some other kernel filter is just a proxy for a second device on the same 1394 bus, the two devices may negotiate a private method of interfacing with the master clock. They would have to use private interfaces to determine the type of clock in order to verify compatibility.


Default Clock

A default implementation of a clock source is supported, which may be used by filters that would normally use the system clock to regulate their data flow. This clock supports the normal KSPROPSETID_Clock interface, and may be accessed just as any other clock presented by a filter pin. The underlying data structure however is created by the filter pin, and shared among that pin, and any instances of the clock that are created. The clock relies on the pin to update the current state and other elements in the shared structure. The default clock handles notification requests and clock queries. The property set and API’s used to create and support default clocks are described in later sections.

When a pin on the filter that provides this clock is assigned a master clock, it should treat this clock just as if the pin owned the clock (which in fact it does). The pin should reference the clock file object, just as if it was assigned some other clock implementation. The default clock does not reference the pin’s file object when an instance is created, so there is no circular reference counting problems. Instead, it keeps an internal reference count based on the initial allocation of the common clock structure, and on each file object opened on the clock. Even if the clock’s owner frees the clock structure, it will remain in place until all file objects are closed. The pin may of course directly access the default clock object, rather than go through the standard clock interface.


Rate Matching

Rate matching involves compensating for actual frequency variations in physical clocks. Two crystals will never resonate at the exact same frequency, and thus two time sources based on those crystals will never run at the exact same frequency. So a mechanism to allow one clock to compensate for the relative drift against another clock, and thus modify the contents of the stream produced is a means of rate matching.

For example, a hardware based audio source set to produce samples at a frequency of 44.1 kHz, and a separate hardware based audio sink also set to consume samples at a frequency of 44.1 kHz. The physical clocks on which the production or consumption of samples is actually based are separate, and cannot be guaranteed to be exactly the same relative to each other. The source may actually be running at 44.100005 kHz relative to the sink, which would mean that more samples are being produced than consumed, and over time, drift would occur between the two, causing eventual flood. Likewise, not enough samples may be produced, which would generate a famine condition for the consumer.

The master clock allows any filter to query an accurate representation of “wall clock” time, which is an ever-progressing 100-nanosecond resolution counter. If the audio consumer owns the master clock, presumably the physical hardware that is rendering the audio would be used to present the physical time on the master clock. The audio producer would be able to query this physical time at intervals to determine relative drift. The producer would then compensate the number of samples to match the frequency difference. In the case of audio, this rate matching is a built in function that can be used by a filter to modify the samples in a stream buffer.

In some cases the physical time may be based on the same hardware. The producer in that case would not need to compare for drift, but that is based on the type of clock, which is a stream property for which the producer can query the master clock owner. For example, if the producer and consumer are both on the same full duplex audio card, then producer and consumer could use the same hardware timing. In this instance if the producer queried the stream property for the type of master clock, it would find that the clock was based on the very same hardware instance used by the producer. It would not need to perform any rate matching in this case.

Any of these clocks are just approximations of “wall clock” time, and the same presentation rendered on a different machine will play for a slightly different amount of time. But in most cases, the important factor is the relative drift between physical clocks, rather than the drift against some perfect “wall clock” time.

Using the physical clock for rate matching allows instantaneous feedback as to rate differences, rather than using something like the clock presentation time, which stalls based on data famine, and therefore only allows an infinitely long sequence of approximations to match the rate. For example, if too much data is produced, then correct feedback is given to slow the rate (except if famine occurs at any point), although a data flood would not automatically be relieved. However, if not enough data was produced, or the stream was live, so data was delayed, the rate of flow would always approach its nominal rate, and would force the production rate up (how fast would depend on how often the rate was checked, versus how many buffers produced), but would take an infinite amount of time to reach the correct rate. Using the physical clock would produce the same result with a data flood, which would have to be corrected by Quality Management complaints, but the data famine would be self-correcting. That is, the reference clock would stall while data was being produced, and thus close the gap, and adjust for the frequency discrepancy at the same time.


KS Allocators

An allocator is a KS object that handles allocating data buffers for I/O requests. A KS driver can provide an allocator for a pin optimized for I/O throughput.

Drivers can in principle support allocators for multiple buffer types, for example on-board RAM in a video card. However, most drivers use the default allocator. The default allocator allocates system memory. Drivers can specify frame size, maximum number of frames, and alignment requirements. The default allocator takes care of meeting the requirements, and can optimize by reusing discarded frames.

Drivers that support an allocator respond to the KSPROPERTY_CONNECTION_ALLOCATORFRAMING property. The data buffer for this property is a KSALLOCATOR_FRAMING structure. Drivers use this structure to specify the requirements they impose on their data buffers. Such restrictions can include: fixed frame size, a strict upper bound on allowable outstanding frames, alignment, or pool type. Drivers that support the default allocator set the KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY flag of the RequirementsFlag member.

Minidrivers running under AVStream should use the KSALLOCATOR_FRAMING_EX structure to specify allocator requirements. Please see additional information in the documentation for this structure.


Frame Allocators

Minidrivers running under AVStream may include pins that implement their own allocators. Do this by setting the KSALLOCATOR_DISPATCH member of the KSPIN_DISPATCH structure. Specify NULL for this member if you do not want to specify an allocator for this pin.

Simple Allocator Configuration

Figure 1 is a diagram of the configuration of a simple allocator where a single allocator is assigned for use by three filters. No allocation is required in the transform or sink filters because the system has not assigned an allocator handle to these filters.

The source filter allocates a frame, fills it with data and submits it to the next filter. The transform filter performs an in-place data transformation and submits the frame to the next filter. When the sink filter completes the I/O operation, the source filter either frees or reuses the frame. Flow control is maintained in this filter graph by the number of total outstanding frames that can be allocated from the sink allocator and by the rate of completion of the I/O operation.

Allocator Configuration with Multiple Sinks

Figure 2 is a diagram of an allocator configuration where a source frame is routed to multiple destination sinks. For instance, the file writer could represent wave out to a file, and the device a sound card to which audio is being sent.

This filter graph contains two allocators: the transform’s allocator and the device’s allocator. The source filter allocates a frame from the transform allocator, fills it with data and submits it to the transform filter and then to the file writer. On receipt of a frame, the transform filter allocates a frame from the device allocator, performs a transformation of the data into the new frame and submits this frame to the device.

Flow control is maintained in this filter graph by the number of total outstanding frames that can be allocated from the allocators and by the rate of completion of the I/O operations. Note that there must be a separate allocator for each separate list of source/sink segments created through connecting pins. If separate allocators are not present, a given segment may consume all frames available, leaving none for the next segment, which may require one or more frames to process the data created by the previous segment.


Allocator Negotiation

When an DirectShow client connects a filter graph and initiates negotiation of the IMemInputPin interface, that client, through a proxy, negotiates the respective properties of the kernel-mode allocators by querying each kernel-mode filter at the data output handle of each filter connection for its requirements using the KSPROPERTY_CONNECTION_ALLOCATORFRAMING property. This property can only be set when the pin state is KSSTATE_STOP.

When the filter graph requirements have been determined and if there are any requirements for kernel-mode allocators, the client creates the allocators using the associated pin handles of the filter connections and sets the allocator property for each source handle of each filter connection using KSPROPERTY_STREAM_ALLOCATOR. The receiving pin references a non-NULL handle to the allocator using ObRefrenceObjectByHandle. For optimization, setting a NULL handle to signify that no allocator is required is an optional operation for a client and therefore all filters must default to a NULL allocator. If no allocator is specified by the client, the filter can assume that the stream segments submitted via stream I/O controls meet the filter’s requirements and it may freely modify the data in-place if necessary.


Default Allocator

The default allocator provides a system memory allocator for device drivers that are able to transfer data from system memory but requiring specific memory allocation properties. The default allocator simplifies a filter by only requiring a filter to handle the allocator requirements request.

To interface to the default allocator, the filter responds to the KSPROPERTY_CONTROL_ALLOCATORFRAMING property and returns the requirements including the KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY flag for the filter. When an IRP_MJ_CREATE is submitted and the create type is KSCREATE_REQUEST_ALLOCATOR, the filter forwards the Irp to the default allocator handler by calling the KsCreateDefaultAllocator function. All remaining processing is handled by the default allocator.


Filter Specific Allocator

Filters requiring allocators for on-board memory or other device dependent storage methods can provide an specific allocator by supporting the allocator properties and methods.

An allocator is represented by a file object of the device. A create request of the KSCREATE_REQUEST_ALLOCATOR type is submitted to the filter specifying the framing options for the allocator. The allocator creation function validates the create request using the KsValidateAllocatorCreateRequest function that returns a pointer to the KSALLOCATOR_FRAMING structure and a pointer to the parent file object.

If the allocator can not satisfy the framing requirements, it returns immediately with a failure code. Otherwise the filter attaches a pointer to a structure to the FsContext member of the file object and services the resulting allocator requests. Note that the allocator does not call ObReferenceObjectByPointer for the related (or parent) file object as such a reference would cause a circular reference and would not allow the parent pin object to be closed.

The allocator must support the standard stream allocator properties and methods detailed in the property set and method set references in later sections.

There are two interfaces available to the allocator. All allocators must provide the IRP-based KSMETHODSET_Stream_Allocator interface. Optionally, if the allocation pool type can be serviced at DISPATCH_LEVEL, a function table interface may be supported.

Allocators control the flow of data by maintaining a maximum number of allocated frames.

The IRP-based interface operates as follows:

When an allocate request is submitted to the allocator, the allocator completes the request with a pointer to a frame or if all frames have been allocated, the allocator marks the IRP pending, adds the IRP to the allocator’s queue and returns STATUS_PENDING.

When a free request is submitted to the allocator, the allocator attempts to complete the first request in the queue for the Irp based interface, if any, otherwise the frame is returned to the free list. If the DISPATCH_LEVEL interface is also supported, the allocator signals the stream allocator “free frame” event. Note that it is possible for both the DISPATCH_LEVEL interface and the IRP-based interface to contend for the free frames. Synchronization to the queue is maintained by the cancel spinlock.

The DISPATCH_LEVEL interface operates as follows:

When an allocate request is submitted to the allocator, the allocator returns a pointer to a frame is one is available or it returns NULL immediately.

When a free request is submitted to the allocator, the allocator signals the stream allocator “free frame” event notifying the client that a free frame is available. Additionally, if there are allocation request IRPs waiting to be completed, the allocator must schedule a worker item (if the current IRQL is not PASSIVE_LEVEL) and complete the request with the free frame.


KS Mediums and Interfaces

A medium defines a communication bus, and an interface defines how and what can actually be communicated. An interface has a medium-specific implementation, but the same interface may be implemented over several mediums. The KSINTERFACESETID_Standard interface is implemented as specific read and write Ioctl’s over the KSMEDIUMSETID_Standard medium, but may have a completely different implementation over some alternate bus.

A medium may also represent communication over some external bus, such as between components on a DSP. The Guid for the medium would be the unique identifier for this bus type, and the Id within that medium set would represent the unique instance of that type of bus. This unique instance is generated in a bus-specific manner. The Standard medium represents the system bus, with only the Id value of KSMEDIUM_TYPE_ANYINSTANCE being valid.


Interface Sets

Interfaces also are described as a set, and an element of that set. The KSINTERFACESETID_Standard contains the set of standard interfaces supported by various types of pins.

The KSPIN_INTERFACE structure identifies an interface, with a unique interface set, and element of that set.

typedef KSIDENTIFIER KSPIN_INTERFACE;
typedef enum {
  KSINTERFACE_STANDARD_STREAMING,
  KSINTERFACE_STANDARD_LOOPED_STREAMING,
  KSINTERFACE_STANDARD_CONTROL
} KSINTERFACE_STANDARD;
Standard Interfaces | Description
KSINTERFACE_STANDARD_STREAMING | Basic streaming interface.
KSINTERFACE_STANDARD_LOOPED_STREAMING | Basic streaming interface that also enables looping on buffers.
KSINTERFACE_STANDARD_CONTROL | Non-streaming control interface.

The interfaces within the standard set cover the base set of pin classes that have been implemented. Note that for MDL-based streaming, the originator of the request must create a stream header for each MDL in the list, and assign a completion routine if the MDL list must not be freed on completion of the IRP.


KS Supplemental Documentation

Built on Sunday, March 11, 2001


Quality Management

Quality Management (QM) notifications are one method of fine-tuning flow control based on resource constraints, and of determining degradation needs in a filter graph. The other flow control being buffer allocation interfaces, which block on allocation requests, limiting the number of outstanding buffers in order to constrain data flow. QM notifications are sent to a Quality Manager, should one exist, through a kernel mode proxy. If one does not exist, QM notifications are not supported. The Quality Manager is acquired much the same way as the file handle to a master clock.

When a Quality Manager is assigned to a graph, each pin instance in the graph is notified. The Quality Manager can be changed at any point. Old QM information may be discarded on assignment of a new Quality Manager.

When a connection is established in an DirectShow proxy of a kernel mode filter, the connection may query the user mode Quality Manager for an interface to use in retrieving a handle to the kernel mode Quality Manager proxy. The DirectShow filter then passes that handle, along with an DirectShow-specific context parameter, to the pin instance via a stream property. The kernel filter’s pin instance references the underlying file object, and can use that to send QM problem notifications to the kernel mode Quality Manager proxy. The DirectShow filter is responsible for closing the handle that it retrieved, but it may also be used for direct access to the kernel mode Quality Manager, should that be needed.

The kernel mode filter pin now has a file object and context parameter for the Quality Manager proxy that can be notified via the normal method and property calls. If a new Quality Manager is specified for the connection, or a NULL Quality Manager is specified, any previous Quality Manager reference should be dereferenced. If the connection is closed, then any outstanding Quality Manager file object should be dereferenced.

This Quality Manager is specific to the connection, and any QM problems reported to the manager include the context parameter specified in the original property call, which is then presumably passed to the user mode Quality Manager. In the case of DirectShow being the connection client, this context parameter may be a pointer to the DirectShow proxy filter pin interface, which it could use to determine topology.

This allows a DirectShow proxy to have both kernel mode connections and user mode connections, and allows kernel mode filters to be contained in multiple graphs. The former is of immediate use, but the later will not be of use until future versions. This also implies that the kernel mode portion is currently just a funnel for QM problems reported by kernel mode connections. In the DirectShow scenario these problems are then routed to the user mode Quality Manager, which determines what to do based on the strategy and QM information previously queried from the pins.

To do this the user mode portion of the Quality Manager keeps multiple asynchronous IRP’s outstanding on the kernel mode proxy in order to receive the QM problems. The context parameters returned could be translated into DirectShow pin interfaces so that all QM problems can be treated equally within the graph. In the case of user mode QM problems, the interface to the Quality Manager could been used directly. The Quality Manager then makes calls to various pin interfaces within the graph in an attempt to solve the QM problem. For proxy DirectShow pin connections, the kernel mode connection sends the QM problem to the kernel mode QM manager with the context parameter, which the kernel mode Quality Manager forwards to the user mode Quality Manager via the pending I/O previously mentioned. Please see related documentation on the KSQUALITY structure in Kernel Streaming reference material.

QM problem complaints are generated by filter pin instances when data is not being received fast enough, or too much data is being received, or not enough resources are available to deal with the data stream (which in some cases may look exactly like data is not being received fast enough). These conditions are determined from the KSQUALITY.DeltaTime and KSQUALITY.Proportion elements in the QM complaint. For instance, a delta time of zero, but a proportion of 500 would indicate that only 50% of the frames being sent to a filter pin instance are actually being used. This would indicate that the filter does processing of frames asynchronously to when they are sent, and does not have enough resources to process those frames.

Alternatively a negative delta with a 100% proportion would indicate a flood of data, and a famine would be specified by positive delta (frames are being delivered past the time at which they could be used). An ill-formed filter that performs too much processing of the data as it is sent, rather than queuing the frames, may complain that data is being sent too late if it does not have sufficient resources to process the frames fast enough. That is, by the time it is finished with one frame, and accepts the next frame, the optimal time may have passed to use that frame. Since the filter is constructed in this manner, it really is a resource complaint.

A resource complaint on one filter pin may be followed shortly by a famine complaint on some pin down the data stream. So the Quality Manager must act on complaints serially to determine if it has solved the problem. There is also the special condition of time discontinuity. No QM complaints related to data famine should be generated after a time discontinuity has been received (which indicates the end of a stream segment).

Note that the delta is specified in native units, which are determined by the Interface used by the connection. A Quality Manager may not understand the specific units, but it can still use the information to determine if frames are being delivered too late or too early. If any connection in the stream supports Rate Capability queries, and has a Topologically related connection of the correct Interface, then the Quality Manager would be able to translate between unknown time stamp formats.

A QM complaint is considered to be outstanding until told otherwise, although complaints of the same type may be generated by the same pin instance, and override previous complaints. Also, if the QM returns to a tolerable rate, the pin may generate a QM that indicates that the problem has been solved (Proportion = 1000, DeltaTime = 0). Even when the graph is in a Stop state, QM notifications may be sent, as in the case of pre-configuring the QM of a graph on a low-end machine.

The type of items that can be degraded are represented by KSDEGRADE structures. Also see the enumeration KSDEGRADE_STANDARD.

There is a standard set of identifiers KSDEGRADESETID_Standard, which contains the very basic broad categories of items that can be degraded.

The sample degradation implies manipulation of the frequency of samples in a stream processed by a pin. For example, by producing less samples less time may be spent processing samples that may not be used. Specific data formats may imply which samples are to be removed first. In loose terms, this sets the number of "frames" that are produced by the filter or filter pin compared to the number received.

The quality degradation implies manipulation of the quality of data samples in a stream processed by a pin. For example, by reducing the size of samples less work may be done in processing them, as in the case of a Px64 algorithm, or reducing from 16 bit to 8 bit PCM wave samples; as long as the destination filter can interpret the changed data format. In loose terms, this sets the quality of "data frames" that are produced by the filter or filter pin.

The computational degradation implies manipulation of the general computational effort expended on a stream processed by a pin. For example, a 100th order algorithm could be reduced to a 50th order algorithm. In loose terms, this sets the amount of effort expended by a filter or filter pin in processing a stream.

For the first three strategies, the KSDEGRADE.Flags member of the structure contains the current percentage in one-tenth percentage points of degradation in this category, where 1000 is no degradation. For the last strategy, the KSDEGRADE.Flags contains the amount of time in native units as specified by the Interface. Since this is a ULONG value, multiple Skip requests may be needed to remedy the QM complaint.


Object State

Resetting state essentially returns the object (e.g., a pin) to the state it was in upon being set to an Acquire state. That is, state information based on stream contents is discarded (for example RLE information). Any reset must be propagated through a data stream from pin connection to pin connection by the proxy. Any reset request received on any pin while resetting is ignored, and a reset on any pin may affect the filter as a whole, as it propagates the request through the effected pins in relation to what the filter routing for that pin instance is.

A reset is initiated on a pin by sending an IOCTL_KS_RESET_STATE IOCTL with a value of KSRESET_BEGIN contained in the input buffer. This begins the reset state, and indicates to a pin that any pending or new data received while in a reset state should be rejected withSTATUS_DEVICE_NOT_READY. The reset state is ended by either a disconnection, or by receiving an IOCTL_KS_RESET_STATE with a value of KSRESET_END contained in the input buffer (It is not canceled by changing pin state). This indicates to a pin that new data can be accepted. It also indicates that it can once again pass data to it connection, even if previously data had been rejected. Normally rejecting data indicates to a pin that it should halt sending more data.

An object’s state may be flushed using IRP_MJ_FLUSH. This is used to ensure the object state and stream data has been flushed to permanent storage, or otherwise completely processed by the underlying hardware. Any object may support this through a KSDISPATCH_TABLE entry.


Recalculating Stack Depth

When the state of a pin transitions from KSSTATE_STOP, each connection that forwards Irp’s must recalculate stack depth. In kernel-mode drivers this allows connections to be made and remade in any order.

What this implies is that although connections can be established in any order, changing state from Stop to any other state must be performed from bottom of stack up. Each request causes the pin to recalculate its stack requirements (DEVICE_OBJECT.StackSize) based on the lower pin in the stack (if it forwards Irp’s and therefore relies on the lower stack depth). A filter that forwards Irp’s must keep a list of all pin instance file objects associated with this device object so that the StackSize in the device object can be recalculated correctly. Any request out of order can be rejected because lower stack depth may not have been recalculated, however KsForwardIrp validates that there is remaining stack, and returns STATUS_INVALID_DEVICE_REQUEST otherwise. So this recalculation is only needed if Irp’s are passed on through connections, rather than associated Irp’s being created.

The second implication is that no Irp can be passed down a connection until an Acquire state has been reached, since the stack depth is not yet known.

If a driver attaches itself to a filter using IoAttachDevice, it must recalculate stack depth also, adding an additional stack location for itself.


Canceling I/O

Canceling outstanding I/O for a thread must be performed through NtCancelIoFile. Closing an object or setting a streaming object to a Stop state also cancels outstanding I/O. This would possibly be done when responding to real-time input that directs a different path to be taken.


Asynchronous Assumptions

All file object are opened assuming asynchronous access. That is, each filter must perform its own serialization. Any synchronous access must be emulated by waiting on the request to complete, as KsSynchronousDeviceIoControl does. There is no extra overhead in doing this, as the file system would internally wait for the file object to be signaled in any case. However it does mean that the filter itself can control how much serialization is needed for the various types of requests, in that property queries should not need to overly inhibit streaming of data, etc.

.


Kernel Streaming Glossary

Built on Sunday, March 11, 2001


A

Audio class
The class of filters which deal with PCM or similar digitized data or analog signals.


C

Codec
Coder-decoder. A filter for data which manipulates it, usually by compressing or decompressing the data stream.


D

Data flow
An arbitrary method of defining a class of connection between devices. This allows one to locate pairs of pins which present compatible flow values, and therefore are more likely to be able to establish a connection. For instance, a particular pin may designate itself as an “output, “ and another as an “input.”
DirectX
User mode media interfaces for games.
Device
Mostly refers to a device object, but sometimes refers to hardware, or some software functionality such as a software codec.
Device object
A device instance (sometimes just referred to as a device) which is associated with a particular driver object (module).
Driver stack
Device objects which forward IRPs through to other device objects using IoCallDriver. They specifically do not use IoAttachDevice, but instead open an instance of the device through the filter connection.


E

Event set
A uniquely identified set which represents a group of items about which a client can be notified.


F

Filter
An entity which represents a collection of related connection points called pins, which have some internal routing. Under DirectShow this is a user mode entity (an instance of a COM object normally implemented by a DLL), and under WDM Streaming this is a kernel mode entity (a device object normally implemented by a kernel driver).


G

GUID
Globally Unique Identifier. A 16 byte quantity which is unique, having been generated from the unique identifier on a network card, the current date/time, and a sequence number. This is used to allow any party to create identifiers which will be guaranteed to not overlap with other identifiers similarly created.


I

In
In terms of data flow, indicates consumption of data. An in pin is compatible with an out pin.
Interface
A specific set of methods and properties implemented on a medium that a filter connection uses to communicate (such as a specific set of IOCTL’s).
IOCTL
I/O Control. A custom class of IRP available to user mode.
IRP
I/O Request Packet. The basic method of communication between NT kernel-mode devices.
IRP_MJ_Xxx
IRP Major. One of a predefined class of IRP’s which a device can accept, such as IRP_MJ_WRITE.


K

Kernel mode
The processor mode which allows full unprotected access to the system.
Kernel Streaming Object
An individual KS component represented to a client as a file object. Includes filters, pins, clocks, and allocators. Also see FILE_OBJECT.


M

Medium
The underlying method that a device connection uses to communicate (such as IRPs through IoCallDriver).
MID
Musical Instrument Digital Interface. A serial cable and data standard for communicating between hardware. Most references only involve the data standard, which is a byte stream used for controlling musical instruments, and storing the output of such instruments.
Multifunction device
A piece of hardware which supports multiple discrete functions, such as audio, mixer, and music on a single card. This sometimes is treated as a bus which can be enumerated to locate the devices on that bus.
Music class
The class of filters which deal with music data, such as MIDI.


O

Out
In terms of data flow, indicates production of data. An out pin is compatible with an in pin.


P

PCM
Pulse Code Modulation (PCM) is a subclass of the Microsoft waveform (.WAV) file format. In PCM, data for .WAV files is stored using linear samples. In contrast, ADPCM records deltas between samples.
Pin
May refer to either a Pin Factory, a Pin Instance, or the general notion of connection points on a filter, depending on the context.
Pin Instance
An instance created by a pin factory representing one end of a connection point between filters. It represents the embodiment of a connection using a particular data format and communications methodology. Used for control and data flow. Pin instances support at minimum a connection property set
Pin Factory
A set of properties which describe a potential connection point to a filter, and is used to generate Pin Instances of that category. Each pin factory has a filter-unique identifier which allows support of pin-specific properties or data formats. This is a zero-based count by which the pin factory can be identified. The count stays constant between creation of pin instances.
Power management
An interface PnP provides to manipulate the power state on a hardware device.
Property set
A uniquely identified set which represents types of related information.
Property Sets (WDM Streaming Property Sets)
WDM Streaming defined mechanism to set and get properties on a driver.


S

Sequencer
A hardware or software functionality which interprets a time stamped music data stream, and sends packets to music hardware as their time comes due.
Sound Blaster
A piece of hardware produced by Creative Labs, Inc., which for DOS-based games represents one of the major hardware interfaces for both audio and music (in specific, MIDI) data.
Sink
In terms of device stacking, indicates that a pin represents possible connections that are attached to, rather than those that attach.
Source
In terms of device stacking, indicates that a pin represents possible connections that attach, rather than those that are attached to.


W

WDM
See Windows Driver Model.
Windows Driver Model (WDM)

The 32-bit driver model used for Windows 2000 and Windows 98.


AVStream Overview

AVStream, like its predecessors, stream class and port class, is based on the class driver and minidriver design models. AVStream as a class driver provides much of the default behavior required to make your filter work as a WDM-CSA (kernel streaming) compliant filter. AVStream provides a unified kernel streaming class model for both audio and video minidrivers. AVStream also provides support for vendors to use COM objects to plug in new interfaces without altering existing minidriver binaries.

Each AVStream minidriver exposes its functionality to clients through a number of filter types. An AVStream minidriver can expose many different types of filters through a hierarchy that is illustrated in the following diagram:

This chapter contains the following information:

  • AVStream Descriptors
  • AVStream Dispatch Tables
  • Describing Your AVStream Filter
  • The Queue and Stream Pointers
  • Pin-Centric Processing
  • Filter-Centric Processing
  • Processing Commonality
  • Common AVStream Services
  • Special Concerns of Hardware Drivers
  • AVStream DMA Services
  • Stream Pointers


Writing an AVStream Minidriver

This chapter describes the most basic steps required to write a working AVStream minidriver. At points where the minidriver writer has a choice whether to use default behavior or provide implementation-specific behavior, this choice is highlighted but the default behavior described.

An AVStream minidriver that does not handle device initialization on its own calls KsInitializeDriver from the minidriver's DriverEntry routine. See more information in the section DriverEntry for AVStream. A driver that handles device initialization on its own will not call this function. KsInitializeDriver initializes the driver object of an AVStream driver. This function also initializes IRP dispatching, PNP add device messages, and unloading.

In calling KsInitializeDriver, the minidriver passes a pointer to the driver object to initialize, a pointer to the registry path, and, optionally, a device descriptor. Note that passing the KSDEVICE_DESCRIPTOR object is not required. If the minidriver does pass a device descriptor, AVStream will create a device with the specified characteristics at AddDevice time.

The device descriptor object contains a pointer to a KSDEVICE_DISPATCH object. Any of the callbacks in this structure may be set to NULL, indicating that the minidriver will not receive notification of the related events. Note that the Start callback should be non-NULL if the driver must evaluate assigned resources. AVStream extracts resource lists from the IRP for the convenience of the driver; see details in the reference page for KSDEVICE_DISPATCH.

The device descriptor object also contains a pointer to an array of filter descriptors. Provide a filter descriptor for each filter type your minidriver will support. When the minidriver calls KsInitializeDriver, AVStream creates a filter factory object for each type of filter exposed by the minidriver. Individual filters are then instantiated by the filter factory upon receipt of a create IRP for the associated create item. Each filter descriptor contains a pointer to an array of KSPIN_DESCRIPTOR_EX objects. AVStream creates a pin factory on the relevant filter for each type of pin the minidriver exposes through that filter. Pin factories are completely internal to AVStream, and are mentioned here for conceptual purposes. When a connection is made to a given pin type on a filter, it is the AVStream pin factory that instantiates a pin object. Note that each filter must expose at least one pin. Note that the minidriver can impose a maximum on the number of pins that a pin factory can instantiate by using the InstancesPossible member of KSPIN_DESCRIPTOR_EX.

When laying out the descriptors, a minidriver writer must decide what type of processing each filter type will perform. AVStream provides two distinct types of processing: Filter-Centric Processing, and Pin-Centric Processing. See the preceding links for information on how to select filter-centric or pin-centric processing.

If a filter is filter-centric, AVStream calls the minidriver to process data only when all pins have data at a given point in time. Filter-centric filters typically operate at the software level. For instance, filter-centric processing could be used for a software transform, or data flow routing at the software level.

Conversely, if a filter is pin-centric, AVStream calls the minidriver when any selected pin has data. Pin-centric filters, typically perform data routing, in particular data routing to and from hardware that performs a transform or renders data.

To install your AVStream minidriver with an .inf file, follow the guidelines in the section Creating an INF File. Here are sample registry entries for parent and child devices:

In the AddReg section for the parent device in the parent driver's inf:

[ParentName.AddReg]
HKR,"ENUM\[DeviceName]",pnpid,,"[string]"

In the .inf for the child device's driver:

[Manufacturer]
...=ChildName
[ChildName]
...=ChildName.Device,AVStream\[string]

Note that "AVStream" would be "Stream" for a stream class driver.


AVStream Descriptors

An AVStream minidriver describes itself and the filter types it supports through the use of descriptor structures. Each key component – the device, the filter factory, and the pin factory – has an associated descriptor – a device descriptor, a filter descriptor, and a pin descriptor. The descriptor contains the basic characteristics of the object it describes. This allows AVStream to provide default behavior on the part of the minidriver.

The device descriptor, for example, tells AVStream how many filter types your minidriver exposes and where to find descriptors for each of these filter types. Individual filter descriptors tell AVStream how many pins types your filter supports, where to find descriptors for them, the KS categories your filter is to be registered under, and the topology of your filter. Pin descriptors tell AVStream what interfaces, mediums, and data formats that your pin supports.

Common to each of the three main descriptor types (device descriptor, filter descriptor, and pin descriptor) is the dispatch table, detailed in AVStream Dispatch Tables.


AVStream Dispatch Tables

The dispatch table allows the client minidriver to refine the behavior provided by AVStream. A dispatch table is a set of function pointers to dispatch functions. These functions receive notifications of certain events and may extend or modify the default event handling provided by AVStream.

Dispatch functions can inform a client minidriver of a variety of events. For instance, a device can provide dispatch functions to get Plug and Play (PnP)-related information. In this way, a hardware driver can determine the resources that that PnP has assigned to a given device. Filters can be notified about creations, deletions, the need to process data, and resets. Pins can be notified of many events, for example, creation, closure, the need to process data, resets, setting of data formats, and state changes.

There are several other types of dispatch tables that are described in detail in the AVStream DDK reference.


Describing Your AVStream Filter

Typically, AVStream minidrivers will lay out static descriptor tables in their source and call KsInitializeDriver to perform all of the setup work.

The main descriptor for an AVStream minidriver is the device descriptor. This structure describes what dispatch messages your minidriver wishes to receive and how many filter factories you expose. The device descriptor structure looks as follows:

  struct _KSDEVICE_DESCRIPTOR {
    const KSDEVICE_DISPATCH* Dispatch;
    ULONG FilterDescriptorsCount;
    const KSFILTER_DESCRIPTOR*const* FilterDescriptors;
  };

The KSDEVICE_DISPATCH table indicates which dispatch messages the minidriver wishes to receive. Possible PnP dispatch messages include: add device, start device, poststart, query stop, cancel stop, stop, query remove, cancel remove, remove, query capabilities, surprise removal, query power, and set power. Minidrivers that do not wish to receive PnP notifications need not supply a dispatch table. Alternatively, minidrivers can register dispatch functions for only the notifications they wish to receive.

The FilterDescriptors entry in the device descriptor will point to a table of pointers to filter descriptors, one for each filter type the minidriver exposes. Filter descriptors look as follows:

  struct _KSFILTER_DESCRIPTOR {
    const KSFILTER_DISPATCH* Dispatch;
    const KSAUTOMATION_TABLE* AutomationTable;
    ULONG Version;
    ULONG Flags;
    const GUID* ReferenceGuid;
    ULONG PinDescriptorsCount;
    ULONG PinDescriptorSize;
    const KSPIN_DESCRIPTOR_EX* PinDescriptors;
    ULONG CategoriesCount;
    const GUID* Categories;
    ULONG NodeDescriptorsCount;
    ULONG NodDescriptorSize;
    const KSNODE_DESCRIPTOR* NodeDescriptors;
    ULONG ConnectionsCount;
    const KSTOPOLOGY_CONNECTION* Connections;
    const KSCOMPONENTID* ComponentId;
  };

For a detailed description of these fields, see KSFILTER_DESCRIPTOR.

Inside each filter descriptor, minidrivers must provide a table of pin descriptors that describes each pin type present on the filter. A pin descriptor looks as follows:

  Struct KSPIN_DESCRIPTOR_EX {
    const KSPIN_DISPATCH* Dispatch;
    const KSAUTOMATION_TABLE* AutomationTable;
    KSPIN_DESCRIPTOR PinDescriptor;
    ULONG Flags;
    ULONG InstancesPossible;
    ULONG InstancesNecessary;
    const KSALLOCATOR_FRAMING_EX* AllocatorFraming;
    PFNKSINTERSECTHANDLEREX IntersectHandler;
  };

For a detailed description of these fields, see KSPIN_DESCRIPTOR_EX.

If you examine the filter dispatch table and the pin dispatch table, you will notice that both of these structures provide a dispatch called Process. Use this dispatch to differentiate a filter-centric filter from a pin-centric one. A filter that provides a process dispatch function in the filter dispatch table is filter-centric. On the other hand, a filter that provides a process dispatch in each of the pin descriptor tables is pin-centric. As stated earlier, this is one of the most important design decisions that a minidriver writer must make. The two methods of accessing data are very different, although the support provided by AVStream for each is similar.


Event Handling in AVStream

In order to support events, an AVStream minidriver places a series of KSEVENT_ITEM structures in the automation table (see KSAUTOMATION_TABLE). When some other component wishes to be notified of that event, it sends an IOCTL_KS_ENABLE_EVENT down to the device. In the event item, the AddHandler and RemoveHandler pointers may be NULL or non-NULL. To decide which will work better for your driver, please consult the comments section in KSEVENT_ITEM.


The Queue and Stream Pointers

Regardless of whether you choose to employ filter-centric or pin-centric processing, AVStream provides a queue object for each pin or inplace transport on a filter. The AVStream queue is a very flexible mechanism for controlling data frame travel. Data in the queue is accessed through an abstraction known as the stream pointer. Each AVStream queue object contains, by default, one stream pointer known as the leading edge stream pointer. When frames (data frames or empty buffers) arrive into an empty queue, the leading edge is set to point to the first of these data frames. It does not move until specifically advanced by the client (the mechanisms of advancement differ between pin-centric and filter-centric processing) or until a streaming IRP is cancelled.

Depending on the flags on the pin(s) associated with a given queue, the queue may also have another stream pointer called the trailing edge stream pointer. As can be inferred from the name, the trailing edge trails behind the leading edge and is advanced only by the client minidriver or by cancellation. Minidrivers can also create their own new pointers into the data stream through a call to KsStreamPointerClone.

Each pointer into the data stream can be in one of two states: locked or unlocked. If a given stream pointer is unlocked, it is not guaranteed to point at data. It is invalid for a client minidriver to attempt to access the data referenced by the stream pointer while it is unlocked. The minidriver must first call KsStreamPointerLock. On the other hand, a locked stream pointer is guaranteed to point to valid data.

Data movement out of the queue is controlled by the position of the leading edge and by reference counts. Any data frame in the queue ahead of the leading edge has not yet been “seen” by the minidriver and thus will not leave the queue unless the IRP associated with the frame is canceled. Each stream pointer pointing to a data frame in the queue adds a reference to that data frame. Further, any data frame in the window between the leading edge and the trailing edge has an additional reference count. Data frames leave the queue when they are behind the leading edge and have a zero reference count.

The question of IRP cancellation arises frequently. A minidriver does not need to know that an IRP has been canceled if the minidriver has no stream pointers referencing canceled frames that are ahead of the queue's leading edge. Should a minidriver hold a locked stream pointer referencing a particular frame, the frame (and hence the IRP associated with that frame) cannot be canceled. Therefore, client minidrivers should avoid holding locked stream pointers for an extended period of time.

Sometimes, however, a client wants to hold a data pointer into the stream but still allow the frame to be canceled. In this case, the minidriver must hold an unlocked stream pointer on the data frame and supply a cancellation callback in the creation of the stream pointer via KsStreamPointerClone.

For more detailed information regarding stream pointers, their effect on frames in the queue, and cancellation, see The Queue and Stream Pointers.


Pin-Centric Processing

Should you decide that pin-centric processing is the right paradigm for a filter, you need to provide a processing dispatch in each KSPIN_DISPATCH table and omit the processing dispatch in the KSFILTER_DISPATCH table. Once you have supplied the descriptor structures and registered them with AVStream via KsInitializeDriver, your filter can be instantiated and used. As stated earlier, AVStream will provide much of the default behavior necessary to make your filter work as a WDM-CSA [kernel streaming] compliant filter.

In the pin-centric dispatch, AVStream will provide you with a pointer to the pin object that has available data. The minidriver’s processing dispatch can then acquire a pointer into the data stream via KsPinGetLeadingEdgeStreamPointer. This will acquire the leading edge stream pointer into the queue. All data manipulation will take place through the stream pointer and stream pointer API.

Perhaps just as important as understanding the context of the dispatch call is understanding when AVStream will call upon a pin to process data. There are three general paradigms for dispatching in a pin-centric sense:

  • By default, AVStream will attempt processing when new data (or a new buffer) arrives into a previously empty queue.
  • If the pin specifies KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL, AVStream will attempt processing every time a data frame or buffer arrives into the queue.
  • If the pin specifies KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING, AVStream will never directly call upon the pin to process. Instead, the client is responsible for calling KsPinAttemptProcessing when they wish to have a pin process dispatch attempted.

Note that processing attempts can fail for a variety of reasons. For instance, processing cannot occur if the minidriver is holding the processing mutex via KsPinAcquireProcessingMutex. Problems may also arise if the minidriver directly manipulates an object known as a gate via the KsGate* calls.


Filter-Centric Processing

Once you have decided that filter-centric processing is the right choice for the specific filter you are implementing, you need to provide a processing dispatch in the KSFILTER_DISPATCH table and leave off processing dispatches in each of the KSPIN_DISPATCH tables. Once you have supplied all of the descriptor structures and registered them with AVStream via KsInitializeDriver, your filter can be instantiated and used. Again, AVStream will provide much of the default behavior necessary to make your filter work as a WDM-CSA [kernel streaming] compliant filter.

In the filter-centric processing dispatch, AVStream provides a process pins table described by a table of index entries as shown below:

  struct _KSPROCESSPIN_INDEXENTRY {
    PKSPROCESSPIN *Pins,
    ULONG Count
  };

This table will be indexed in order of the pins described in the pin descriptor table for the corresponding filter. The first pin described in the descriptor table will have the first entry in the index table passed into your processing function. The count field will tell you how many pins of the corresponding type are currently instantiated. Pins will point to a table of KSPROCESSPIN structures, one for each instance of the pin type. Each process pin looks as follows:

  struct _KSPROCESSPIN {
    PKSPIN Pin;
    PKSSTREAM_POINTER StreamPointer;
    PKSPROCESSPIN InPlaceCounterpart;
    PKSPROCESSPIN DelegateBranch;
    PKSPROCESSPIN CopySource;
    PVOID Data;
    ULONG BytesAvailable;
    ULONG BytesUsed;
    ULONG Flags;
    BOOLEAN Terminate;
  };

Typically, most clients will be concerned with the fields Pin, Data, BytesAvailable, BytesUsed, Flags, and Terminate. Data can be read from the stream or written into the stream through the Data field; BytesAvailable tells the client how many bytes of data are available in the current data frame (buffer) that Data points to. As the client minidriver reads from or writes to the stream, BytesUsed should be updated to reflect how many bytes of data have been consumed. The terminate flag can be set if the minidriver is done with the current frame despite the fact that BytesUsed is not equal to BytesAvailable. Once the minidriver exits the processing dispatch, pointers will be advanced, frames will be completed as appropriate, etc.

Perhaps more important than the context in which the processing dispatch is called is when the processing dispatch gets called. The simplest answer is that your processing dispatch will be called when there are data frames available on each instantiated pin; however, this answer is not quite complete. The rules applied to pin-centric processing still apply here, but the overall result is more complex.

The events described in pin-centric processing as triggering a processing attempt still apply to filter-centric processing. Pins will still trigger processing attempts as described in pin-centric processing; however, the processing attempts are on the filter and the following new rules apply:

  • A processing attempt will not succeed unless frames are available on every pin that does not specify KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
  • A processing attempt will not succeed if a pin on the filter is in a state below the minimum processing level (normally this is KSSTATE_PAUSE, although it can be set to KSSTATE_RUN by specifying KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY)
  • A processing attempt will not succeed if the required number of pins as specified by InstancesNecessary (a member of KSPIN_DESCRIPTOR_EX) is not met.
  • A processing attempt will not succeed if the minidriver has previously closed the filter's process control gate using the KsGate* functions.


Processing Commonality

Both pin-centric and filter-centric processing attempts will cause processing to continue until one of the specified events occurs:

  • No data is currently available on the pin (pin-centric) or on a pin that does not specify KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING (filter-centric).
  • The processing routine returns STATUS_PENDING.

Once the processing attempt is complete, processing will occur again only when one of the aforementioned events (depending on pin flags) takes place. Sometimes, this means that the client must manually call KsPinAttemptProcessing or KsFilterAttemptProcessing. This circumstance can occur when the defaults are used, a situation in which pin flags are not used. In this case, the processing dispatch is called with frames available on the pin (or on every pin that requires frames in the filter-centric case), and the minidriver chooses not to process by returning STATUS_PENDING. Since by default, processing is only attempted when new data arrives into a previously empty queue and none of the associated queues are empty, the minidriver will never be called on to process. Thus, if you set STATUS_PENDING in this circumstance, you must inform AVStream when you are ready to resume processing via Ks*AttemptProcessing.

It is very important to note that a minidriver should NOT return STATUS_SUCCESS from the processing dispatch if the minidriver does not actually process data. This will cause AVStream to immediately call you back – often resulting in an infinite loop between AVStream and your processing dispatch.


Common AVStream Services

AVStream provides several services on behalf of the client that are useful for any driver. One of the main services provided is the object bag. Each AVStream object that is visible to the client minidriver (device, filter factory, filter, pin) provides a container known as the object bag. An object bag is a generic container for holding dynamically allocated memory associated with a given object. Whenever a client minidriver allocates dynamic memory with ExAllocatePool and associates it with a given object, the minidriver should call KsAddItemToObjectBag to add the allocated memory to the object bag.

The main advantage of the object bag to the client is simplification of cleanup. When an item is placed into an object bag, a cleanup function is associated with the object (typically this will be ExFreePool, however, the client minidriver can provide its own cleanup function). Whenever the object is destructed (the pin is closed, the filter is closed, and so on), the object bag will be terminated; AVStream will remove every item from the object bag and call the associated cleanup function.

The conceptual section in the AVStream DDK section talks about object bags in more detail; however, one important point to note is that a single item can be contained in more than one object bag. In this case, the given item will not be cleaned up until it is no longer contained in any object bag.


Special Concerns of Hardware Drivers

Minidrivers manipulating hardware will typically provide PnP dispatch functions in the device dispatch table. The routines most typically supported will be the PnP start device and query capabilities messages, as well as the power messages for hardware supporting any sort of power management.

The PnP start device dispatch is commonly used to allocate context information and associate it with the AVStream device. [In stream class terms, this context information would be the device extension]. This dispatch will also provide the minidriver with the resources assigned to the device by the PnP subsystem. Typically, this list will be parsed to find the interrupt assigned to the device as well as the physical address of any memory regions. Minidrivers are responsible for connecting the interrupt with IoConnectInterrupt.

In addition, hardware that supports DMA must obtain a DMA adapter object with IoGetDmaAdapter. Any buffers your minidriver requires for DMA transfers can be allocated with HalAllocateCommonBuffer at this stage also.

There is another key factor associated with hardware drivers. Because of the multiple filter types and multiple instance support inherent in AVStream, client minidrivers should NOT attempt to configure hardware to support a particular filter until pins on that filter transition to KSSTATE_ACQUIRE. Many older drivers, particularly stream class drivers, tended to configure the hardware (or acquire the hardware resources) when key pins were connected on a filter. This is an incorrect design for a minidriver.

Imagine for instance, a piece of hardware that can support both encoding and decoding of some type of data, but can only do one of these operations at a time. As such, it exposes two different types of filters: an encode filter, and a decode filter. Imagine now that an application builds a filter graph containing the encode filter and the minidriver loads microcode or configures the hardware for encoding at pin connection time. The filter graph starts and the hardware is encoding. Now, imagine that another application attempts to place a decode filter in a filter graph. When the decode pins are connected, the device will configure the hardware for decode and this will cause serious problems in the encode graph that is currently running. Thus, the rule is: do not acquire hardware resources (load microcode, configure hardware for a particular filter) until the appropriate pins on that filter transition into KSSTATE_ACQUIRE.


AVStream DMA Services

AVStream provides a set of DMA services for use by client minidrivers that do not necessarily need to double buffer data [double buffering should be avoided if at all possible – in some circumstances, however, it is the only option].

Once a minidriver sets up its interrupt with IoConnectInterrupt and sets up its DMA adapter object via IoGetDmaAdapter, the minidriver must register the DMA adapter object with AVStream via KsDeviceRegisterAdapterObject. This allows AVStream to perform some basic services on behalf of the client.

In order to make use of these services, a pin that is performing DMA to or from hardware must specify the flag KSPIN_FLAG_GENERATE_MAPPINGS. When the minidriver specifies this flag on a pin, AVStream will automatically generate scatter/gather mappings for each frame in the queue when a client locks a stream pointer referencing the frame. Now, instead of each KSSTREAM_POINTER_OFFSET structure pointing directly to the virtual addresses of the data, it points to a mappings table through the Mappings field. The count and remaining fields of the stream pointer offset will be mapping granular instead of byte granular. Each mapping in the mappings table will contain the physical address of a contiguous chunk of the frame, the number of bytes in the chunk, and the alignment of the chunk.

One very useful feature of the automatic mapping generation is that AVStream can be told by the minidriver that the device is only capable of using scatter/gather mappings of a certain size. When the minidriver calls KsDeviceRegisterAdapterObject, it informs AVStream of the maximum size of a single mapping. Should any scatter/gather mapping exceed this maximum size, AVStream will automatically break it into multiple scatter/gather mappings, each of which is no larger than the size specified by the client.


Stream Pointers

The stream pointer abstraction provides a flexible method of accessing data in a stream. The KS framework uses stream pointers for all stream data access, though clients Error! Bookmark not defined. needn't deal with stream pointers directly. For client performing processing at the pin level, the stream pointer abstraction provides many different ways to access stream data.

Stream pointers are the objects, implemented as a Error! Bookmark not defined. with associated functions, through which the client driver uses the KS framework's internal queue implementation. The framework does not expose the queue object to the client, but internal to the framework, queues are used to hold frames until they are processed and released by client code. Depending on the pipe configuration, a single queue may be associated with one or many pins. In cases in which data is not being processed in-place and there is no pipe splitting, there is a queue for each pin. For an input pin, the associated queue holds load-bearing frames until the client is done processing them:

For an output pin, the associated queue holds empty frames until the client has filled them:

When a stream is processed in-place, the queue holds load-bearing frames that have arrived on the input pin until the client has processed the frames, and they are ready to pass through the output pin:

A stream pointer is a reference to a frame that is residing in an associated queue. There may be any number of stream pointers associated with a queue, and stream pointers may be in a locked or unlocked state. The following rules apply to queues, stream pointers and frames:

  • A frame may only be in one queue at a time.
  • Any number of stream pointers may reference a frame.
  • A stream pointer is associated with a particular queue and may only reference frames in that queue.
  • A frame that is referenced by one or more stream pointers will not leave the queue in which it resides unless the frame is cancelled (that is, unless the IRP that contains the frame is cancelled).
  • A frame that is referenced by one or more locked stream pointers cannot be cancelled. A frame that is not referenced by any locked stream pointers may be cancelled.

A queue has one or two distinguished stream pointers that play special roles. All queues have a leading edge stream pointer through which the client first encounters new frames. Some queues have a trailing edge stream pointer, which often, but not always, indicates the oldest frame of interest to the client. Some additional rules apply to these distinguished stream pointers. These rules are best described in terms of a reference count pertaining to a frame in a queue.

  • The initial reference count for a frame arriving at a queue is zero.
  • All stream pointers except the trailing edge stream pointer increment a frame's reference count when they are set to reference that frame.
  • All stream pointers except the leading edge stream pointer in a queue that has a trailing edge stream pointer decrement a frame's reference count when they are set to no longer reference that frame.
  • When a frame's reference count changes from one to zero, the frame leaves the queue for its next destination.

The effect of these rules is that frames between the leading and trailing edge remain in the queue unless they are cancelled, even if they have no stream pointer referencing them. This is useful for clients that wish to maintain a 'window' on a stream consisting of multiple contiguous frames. Clients what wish to access the stream at only one point can use just the leading edge stream pointer. Clients what want to control the movement of each frame individually can create their own stream pointers by cloning an existing stream pointer. The use of the trailing edge and cloning may also be mixed, if desired.

The leading edge stream pointer and optional trailing edge stream pointer are created and managed by the queue. The functions KsPinGetLeadingEdgeStreamPointer and KsPinGetTrailingEdgeStreamPointer provide access to these stream pointers through a pin associated with the queue. All other stream pointers are created by the client by cloning using the function KsStreamPointerClone. Any stream pointer may be cloned. Cloning creates a new stream pointer just like the parent: it references the same frame and it has the same lock status. Once created, clones are independent of their parents and may be locked, unlocked, deleted or moved to a different frame (by advancing).

In addition to a reference to a frame, stream pointers contain a pair of offsets into the frame. For clients that are using virtual addresses to access stream data, the offsets allow the stream position to be specified to byte resolution. For clients that are using scatter/gather physical mappings, the offsets allow the stream position to be specified to the resolution of one mapping. Two offsets are provided so that in-place processing may use separate input and output offsets. The framework supplies functions that advance offsets and move to a new frame when offsets hit the end of the old frame. Clients may alter offsets as they wish or simply access the data at frame resolution.

Cancellation poses a problem in many circumstances in which IRPs must be kept in a queue (KS queues contain frames, which are in turn related to IRPs). The KS framework gives the client a number of options with regard to cancellation.

  • Many clients only need brief access to stream data at a single access point. This is accomplished by requesting a locked stream pointer (probably by calling KsPinGetLeadingEdgeStreamPointer with a state argument of KSSTREAM_POINTER_STATE_LOCKED) and unlocking the stream pointer immediately after processing is complete (with KsStreamPointerUnlock or KsStreamPointerAdvanceOffsetsAndUnlock). This is simple for the client and does not block cancellation for a significant amount of time assuming that the thread does not block between acquiring the pointer and unlocking it.
  • Some clients need access to stream data for an indefinite amount of time, but are able to relinquish their claim in the context of a cancellation callback. This is generally accomplished by creating a clone (by calling KsStreamPointerClone) of a locked stream pointer (usually the leading edge), unlocking it, and responding correctly to the cancellation callback supplied in the call to KsStreamPointerClone. Because the callback occurs with the queue's spinlock taken, very little can be done with the stream pointer in the callback except delete it. Fortunately, this is almost always exactly what the client wants to do, after making sure the associated data will not be accessed. This approach to cancellation can be more difficult for the client, but it often provides the best balance between efficient access and quick response to cancellation.
  • Some clients need period access to a frame and can tolerate the disappearance of the frame between accesses. This is accomplished by keeping an unlocked clone and locking it whenever access is to occur. If the frame is cancelled, the next attempt to lock the stream pointer will fail, and the client can delete the stream pointer. As with the first option, responsiveness to cancellation is a function of how long the stream pointer is locked.
  • Some clients need access to stream data for an indefinite period, but are unable to relinquish their claim in response to a callback. In such cases, a locked clone stream pointer may be maintained for any length of time to prevent cancellation. The downside of this approach is that responsiveness to cancellation may be poor depending on how long the stream pointer remains locked. Stream pointer timeouts, discussed below, may be useful in such cases.

There are a few miscellaneous features relating to stream pointers that may be useful for some clients:

  • A timer can be set on any stream pointer. A callback to the client indicates that the timer has expired. To set a timeout, call KsStreamPointerScheduleTimeout, and call KsStreamPointerCancelTimeout to cancel a timeout.
  • When a clone is created using KsStreamPointerClone, an optional context size can be supplied. If a non-zero context size is supplied, additional memory is allocated for the context and the stream pointer's Context field is set to point to the allocated context. Because the memory is allocated along with the stream pointer structure, no additional allocation calls are generated by using this feature.
  • Clone stream pointers associated with a queue can be enumerated (by way of an associated pin) using KsPinGetFirstCloneStreamPointer and KsStreamPointerGetNextClone.


AVStream Concepts

This chapter contains the following information:

  • Object Bags
  • Flow Control Gates in AVStream
  • Pipes, Pipe Sections, and Circuits
  • Frame Injection
  • AVStream Splitters
  • Format Negotiation and Data Intersections
  • Graph Builders
  • Kernel Mode Filters, DirectShow, and Proxying
  • Common AVStream Services
  • Mutexes in AVStream


Object Bags

Object bags are dynamic memory containers that an AVStream minidriver can use. Use object bags to associate dynamic memory with a given object; this may be context information or other information that the minidriver allocates off the pool. Object bags can be used with any AVStream object, from a device down to a pin. For instance, place device extensions in the device object bag and pin extensions in the pin object bag. Use the object bag as a way to track dynamically allocated memory associated with a given object.

Since AVStream automatically performs clean up tasks when objects are deleted, using object bags simplifies cleanup. Whenever an AVStream object (pin, filter, etc.) is deleted, AVStream empties the corresponding object bag. During this process, AVStream calls the Free method for each item in the bag in order to free the dynamic memory associated with the item. Note that only available memory limits the number of items that an object bag can contain.

With object bags, many AVStream objects can share a specific piece of dynamic data. To facilitate this, AVStream allows minidrivers to place a given item in multiple object bags. When a minidriver places an item into an object bag, this bag is also associated with the device to which the object belongs. The first time an item is placed into any object bag associated with a device, the item is also placed into the device bag and is given a reference count of one. When the item is placed into an additional object bag, the item’s reference count in the device bag is incremented.

Items can also be removed from an object bag, either automatically by AVStream when the object is terminated, or manually by the minidriver through a call to KsRemoveItemFromObjectBag or KsDiscard. When an item is removed from an object bag, its reference count will be decremented in the corresponding device bag entry. If the item’s reference count becomes zero, the item will be removed from the device bag. Depending on how the item was removed, the item's cleanup function may then be called. The default cleanup function is ExFreePool, but the minidriver can request that AVStream call a cleanup function of the minidriver's choosing upon removal of an item. To do this, the minidriver specifies the cleanup function when it adds the item to an object bag by calling KsAddItemToObjectBag.

AVStream also uses the object bag to track what structures are editable within descriptors. If a descriptor or a substructure of a descriptor is dynamically allocated, it will be in the bag for the object to which the descriptor is attached. This is the how KsEdit determines whether a given structure is editable or not.

The following diagram explains the object bag concept:

Figure 1.1 Structure of an Object Bag

Figure 1.1 presents a hypothetical situation where a filter and a pin both have an associated context structure. There is also a chunk of dynamic memory that is used by both the filter and the pin. Filter context and dynamic memory are in the filter object bag; pin context and dynamic memory are in the pin object bag. The arrows show the associations between items in object bags and their respective entries in the device bag.

For example, if the filter context is removed from the filter object bag, the filter's reference count becomes 0, which causes the device bag's cleanup function to be called. On the other hand, if the dynamic memory is removed from the filter object bag and not from the pin object bag, the device bag's cleanup function will not be called since its reference count would still be 1. For more information on object bags see KsAddItemToObjectBag, KsRemoveItemFromObjectBag, KsDiscard.


Flow Control Gates in AVStream

Gates are an AVStream control flow mechanism. Inside of AVStream, they are used as a processing control mechanism, deciding when it is appropriate to process data. Each gate is represented by a KSGATE structure.

Conceptually, AVStream gates are much like ordinary logic gates. As such, there are two different types of gates: AND gates and OR gates. Both gate types are implemented using the KSGATE structure, but the semantics of the fields in KSGATE are different. As an example, consider a pin that has an AND gate as a processing control. There can be any number of inputs to this AND gate and each input can be in one of two states: on and off. The diagram below illustrates three different AND gates each with three inputs:

Figure 1.2 Three AND Gates

The first AND gate in Figure 1.2 has one on input and two off inputs. The state of the gate is therefore off or closed since by definition all inputs to an AND gate must be on for the gate to pass the signal. You will notice a similar situation for the second gate in the diagram. The third gate, however, has all on inputs; the gate is therefore on or open.

In each of the gates, you will notice a bold number. This is the value that is stored in the Count field of the KSGATE structure. For an AND gate, the value will be one minus the number of off inputs:

Count = 1 - (number of off inputs)

If this value is less than or equal to zero, the gate is considered to be closed. If this value is greater than zero, the gate is open.

OR gates are also implemented using KSGATE, but the semantics of the Count field are different. Consider the following diagram:

Figure 1.3 Three OR Gates

The first gate in Figure 1.3 has three off inputs. The state of the gate is therefore off or closed. However, the second gate is in the on or open state because at least one of its inputs is on. The bold number in the OR gates is again the value stored in the Count field of KSGATE for the given gate. For an OR gate, this value will be the number of on inputs to the gate. If this value is equal to zero, the gate is considered to be closed. If this value is greater than zero, the gate is open.

Count = (number of on inputs)

Note that AVStream performs no checks internally as to whether the state a minidriver sets the gate to is valid. AND gates have a valid Count range of one or below whereas OR gates have a valid Count range of zero or above. Minidrivers should not use the gate API to set gates to invalid values.

In each of the three gates above, note the arrow at the right of each gate. This arrow could be used as an input to another gate. In this way, gates can be attached to other gates, forwarding transitions from one gate to the next. When a gate is attached to another gate and it transitions from closed to open, it will turn on an input to the gate it is attached to. Similarly, when a gate attached to another gate transitions from open to closed, it will turn off an input to the second gate.

AVStream uses this gating mechanism to determine when it is appropriate to process data and for what device. When a thread enters a state in which it is ready to process, it attempts to capture the on input of the AND gate that controls processing for the processing object. The thread attempts capture by making a call to KsGateCaptureThreshold. This call will check whether the gate is open and if it is, it will close it. In either case, the state of the gate (open or closed) will be returned. If the gate was originally open, processing will commence. While processing is proceeding, no other thread can capture the on input of the gate; therefore no other thread can process data.

This mechanism can also be used by minidrivers to suspend processing for an indefinite period of time. In order to do this, a minidriver should add or turn off an input to the processing AND gate and no processing will occur.

For more information regarding the gate API, see KsGateXxx and KsXxxGateXxx functions in AVStream Functions.


Pipes, Pipe Sections, and Circuits

Pipes, pipe sections, and circuits are concepts inside streaming and AVStream. Understanding the general mechanisms and internal layout of filter and connection within AVStream can be very useful in debugging, designing, and understanding AVStream drivers.

A pipe is a set of filters that all use a mutual allocator. The following illustration shows a simple pipe composed of three AVStream filters: a source filter, an inplace transform filter, and a renderer filter:

Figure 1.4 Simple Pipe Example

The filter on the left in Figure 1.4 is a source filter. Behavior of this filter is specified by the AVStream minidriver code attached to the filter's queue. In this particular pipe, the source filter has been chosen as the allocator, and thus has a requestor object associated with it. Data from the source filter will flow into a transform filter implemented by another AVStream driver. Finally, data will flow into the renderer filter implemented by a third AVStream filter.

When this graph is first built, the pins, shown in the diagram connecting the three large blocks, are interconnected. When the graph transitions to an ACQUIRE state, the pins query each other to see if they are finished with acquisition and whether they are AVStream pins. If they are, the pins are bypassed and AVStream transport interfaces are established that connect the first filter’s queue directly to the second filter’s queue and the second filter’s queue directly to the third filter's queue. The third filter’s queue is attached back to the requestor so that frames sent downstream will be returned and recycled once they are completed by the renderer. The circuit is where all the action occurs in a pipe containing AVStream filters. The queue contains the queue objects and the requestor and is the circular path across which frames flow.

The pipe in Figure 1.4 is not an object physically implemented by AVStream. It is a concept. AVStream implements the pipe in sections. Thus, a pipe section is that piece of a pipe that is associated with a given filter. In Figure 1.4 there are three pipe sections.However, it is not always the case that every filter in a graph is an AVStream filter. Figure 1.5 illustrates the case where the transform is not an AVStream filter, but is still a kernel-mode filter.

Figure 1.5 AVStream Filter Example

In this diagram, as in Figure 1.4, there are three filters: one AVStream source filter, one kernel streaming transform filter (this could be a driver that uses KS directly or a minidriver under stream class, and so on), and one AVStream renderer filter. As in the previous graph, the pins are first interconnected. When the graph transitions to ACQUIRE, however, the sequence of events changes. The Kernel Streaming 1.0 filter does not support the AVStream transport interface. Thus the pins are not bypassed. When an object leaves the source filter’s queue, it ends up in the pin where it gets passed down to the transform through the call to IoCallDriver. When the renderer’s input pin receives an IRP, the pin places the IRP in the queue. When the renderer driver completes frames, the frames are sent back to the pin where an IoCompleteRequest routine will in turn cause them to be sent back upstream. The source filter’s output pin receives a completion notification and then moves frames back to the requestor where they are recycled into the circuit.

It is also possible, however, that the source of frames or the final destination is in user mode. As an example, consider the case of a kernel-mode non-inplace transform filter receiving frames from a user-mode DirectShow® filter and sending the new transformed frame to a kernel-mode AVStream renderer. The structure of the pipe is as follows:

Figure 1.6

The connection progresses as previously discussed; however, notice that this graph is quite different from the previous two. There are two different pipes and three pipe sections involved in this example. Frames come down from user mode and are injected into the queue for the input pipe section by the AVStream pin object. The second pipe is a circuit for the transformed frames that are allocated in kernel mode by the non-inplace transform filter. Since the renderer is an AVStream filter, the pins can be bypassed and the frames can be sent through the AVStream transport interface directly into the renderer’s queue.

There is another case in which the requestor does not receive frames from a kernel-mode allocator. Instead, the minidriver specifically injects frames into the circuit by calling KsPinSubmitFrame or KsPinSubmitFrameMdl. See the section on Frame Injection for more information on this subject. For more information on pipes, see KsPinSubmitFrame, KsPinSubmitFrameMdl, and Frame Injection sections in the DDK.


Frame Injection

The default behavior for building the AVStream constructs required to stream data between filters is as follows: A requestor is created that in turn primes a queue by allocating a given number of frames. The minidriver then fills the frames either by pin-centric or filter-centric processing. The frames then move across a transport to the next object in the circuit. The frame proceeds around the circuit until it eventually returns to the requestor. At this point, the frame is reused.

Minidrivers, however, can override this default behavior by calling KsPinRegisterFrameReturnCallback while the filter is in the stop state (that is, the pin object is created and the pin creation dispatch is called). This will place the requestor in an injection mode where instead of acquiring empty frames from an allocator and placing them in the queue, it will wait until the minidriver specifically injects frames into the circuit via a call to KsPinSubmitFrame or KsPinSubmitFrameMdl.

When the frames make their way around the circuit and back to the requestor, the frame return callback registered by KsPinRegisterFrameReturnCallback will be called so that the minidriver can deallocate the frame, complete anything pending on the return of the frame, or refill and reinject the frame. The diagram below illustrates the construction for an AVStream filter set composed of a source, an inplace transform, and a renderer with the source injecting frames:

Figure 1.7


AVStream Splitters

One very convenient feature provided by AVStream is the splitter. Any pin that specifies KSPIN_FLAG_SPLITTER behaves as an automatic splitter. The entire functionality of the splitter is contained within AVStream. All a minidriver needs to do is specify this flag; AVStream will automatically handle all data copying necessary to perform the splitting. In releases post-DirectX 8.0, the KSPIN_FLAG_SPLITTER flag works for pins on both filter-centric and pin-centric filters. Older releases support this flag only for pins on filter-centric filters.

The following diagram shows the configuration of a filter that has specified that its output pin should be a splitter (when the downstream filters of the output pin are modifying data inplace):

Figure 1.8

Note that this diagram does not show where frames are coming from on the output pin; there may be a requestor and allocator associated with each queue and belonging to this pipe section, or the frames may come from some other downstream filter. Frames arrive on the input pin and are placed into the input queue. The minidriver interfaces only with the input queue and the output queue for the original pin. AVStream handles the automatic copying of data from the first pin’s queue to the second pin’s queue. The following diagram shows how the minidriver distinguishes these two pins in the process pins list:

Figure 1.9 Process Pins Table

There are two types of pins described in Figure 1.9: the input pin and the output pin. There is one instance of the input pin and two instances of the output pin.

In this diagram DB refers to the DelegateBranch field of the process pin and CS to the CopySource field. Both the DelegateBranch and CopySource fields of the input pin and the first output pin are NULL. This is an indication that the minidriver is responsible for handling frames on these pins.

The second output pin, however, has a CopySource that points back to the first output pin. This indicates that the second output pin is in a separate pipe from the first output pin and that AVStream is automatically copying any data that is placed into the first output pin’s queue into the second output pin’s queue.

More complicated splitter cases can arise when two output pins are built into the same pipe. This can occur, for example, if downstream filters are not modifying the data sent out via the aforementioned output pins. Because there is no modification, they can be considered read-only and both downstream filters can receive the same buffers. It is also possible that there is mixing of downstream filters: some downstream filters that automatically attach to the splitter pin modify the data and some do not. In this case, you may see a filter layout similar to the following diagram, which depicts a filter that has had three instances of the split output pin connected.:

Figure 1.10

Pins A and B in Figure 1.10 are assigned to the same pipe because the downstream filters do not modify the data; thus the filters downstream of A and B receive the same buffer pointers. Pin C could not be assigned to the pipe containing A and B and was therefore assigned a separate pipe. Note that the minidriver only has to interact with the input queue and a single output queue. AVStream performs automatic copying from the A/B queue and the C queue. It also creates a splitter object that will send the same data frames through pin A and pin B (note that the stream headers will differ).

The process pins table for the filter shown in figure 1.10 is slightly different from the process pins table (figure 1.9) for the filter shown in figure 1.8. It is arranged as follows:

Figure 1.11

This process pins table again only has two types of pins: the input pin and the output pin. However, this time there are three instances of the output pin. Pin A has a NULL DelegateBranch and CopySource. Pin B has a DelegateBranch pointing back to A, and pin C has a CopySource pointing back to A. The only pin that the minidriver must interact with under normal circumstances is pin A.

The DelegateBranch field indicates whether or not a specific pin receives frames from another process pin in the same pipe. If this field is non-NULL, then AVStream is performing an automatic split and the pin from which the split data comes is the process pin pointed to by DelegateBranch. The CopySource field indicates whether or not this pin receives copies of frames from a process pin in another pipe. An important distinction here is that DelegateBranch indicates that the same data buffers are being received downstream and CopySource indicates that AVStream is copying the data into different buffers.

Note that the splitter is completely automatic. All a minidriver has to do to make use of the splitter is mark a pin with KSPIN_FLAG_SPLITTER. AVStream will then automatically handle splitting as appropriate. In the majority of situations, the minidriver only has to deal with process pins that have NULL DelegateBranch and CopySource fields.

For simplification of the above diagrams, requestors and allocators were intentionally left out of the diagrams. The diagrams are intended only to demonstrate the frame splitting process.

For more information on the KSPIN_FLAG_SPLITTER flag, see KSPIN_DESCRIPTOR_EX.


Format Negotiation and Data Intersections

A data intersection is a mechanism in a KS-compliant driver that chooses a data format from two lists of data ranges. A data format is a single format that is set on the connection; it specifies exact parameters. For example, an audio data format might specify a certain format of audio at X samples per second and Y bits per sample. A data range on the other hand specifies a format with a range of valid parameters. An audio data range might specify a certain format of audio at A-B samples per second and C-D bits per sample.

When the minidriver lays out a pin descriptor, it provides a list of data ranges that it supports. Some mechanism must be provided to turn a data range into a specific and viable data format. This is the responsibility of the data intersection. When any KS compliant driver receives an intersection request, it is given two lists of data ranges and asked to intersect them. It is the responsibility of the intersection to determine a specific data format in the intersection of the two lists of data ranges that will be agreeable. The diagram below illustrates an example of an intersection within a generic KS compliant driver:

Figure 1.12 Data Intersection

The driver has received two lists of data ranges to intersect: list 1 and list 2. Note that the diagramshows only one range of parameters per data range. It is quite likely that a data range will specify ranges for more than one value (that is, audio specifying samples per second and bits per sample ranges). The intersection of these two data ranges is shown to the right in Figure 1.12. It is a range of “type B” with the parameter in the highlighted region. The data intersection handler is then responsible for choosing the optimal data format within that range.

To simplify dealing with lists of data ranges, AVStream, like many other class drivers, performs the data intersection through a call back function: the pin’s intersect handler. When the intersect handler is called, two data ranges will be passed to it, one from each list. The two data ranges are guaranteed to match with respect to major type, subformat, and specifier. Further, the required attributes of the data ranges are guaranteed to match. It is the responsibility of the intersection handler to find the intersection of the two data ranges and then to select and return a preferred data format from that range. If the two data ranges do not intersect, the handler returns STATUS_NO_MATCH. If they do intersect and sufficient buffer space is provided to copy a format back, the intersection routine chooses a format in the intersection and copies it back to the caller.

Once a data format has been selected for the connection, the pins will be created, and AVStream will call an internal routine to set the data format on the pin. This will validate that the selected data format is within the data range in the minidriver’s pin descriptor list of data ranges. Should the minidriver specify a SetDataFormat dispatch, this dispatch will now be called to inform the minidriver that a specific format is being set on the pin. The SetDataFormat dispatch is prototyped as follows:

NTSTATUS
  SetDataFormat (
    IN PKSPIN Pin,
    IN PKSDATAFORMAT OldFormat OPTIONAL,
    IN PKSMULTIPLE_ITEM OldAttributeList OPTIONAL,
    IN const KSDATARANGE* DataRange,
    IN const KSATTRIBUTE_LIST* AttributeRange OPTIONAL
);

The selected data format is PinConnectionFormat. AVStream has verified that the format is a partial match for DataRange (in at least as much as major type, subformat, specifier, and attributes). The minidriver’s dispatch function is responsible for determining whether it really is a match for DataRange; this is the last chance for the minidriver to turn down a specific data format for the connection. If it is determined that the format is to be turned down (that it is not a match), the dispatch function should return STATUS_NO_MATCH instead of STATUS_SUCCESS.


Graph Builders

How these mechanisms are used to connect two filters depends on the graph builder. Intersections, for example, may be performed in a cross-pin manner or in a single-pin manner. A graph builder, for example, upon attempting to connect two pins on two filters A and B, may take the list of data ranges on the appropriate pin on filter A and ask filter B to perform an intersection with the associated pin. This would be an example of the intersection type illustrated above in Figure 1.12. Filter B would attempt to find a data format in the intersection that is acceptable to both pins and then return this to the builder. The returned format would then be used for a connection.

Conversely, a builder, upon attempting to connect two pins, may use intersections in a single-pin manner. For example, upon attempting to connect two pins on two filters A and B, the builder may get a specific data range from the pin on filter B and ask filter B to perform an intersection between the acquired data range and the pin’s list of data ranges. This intersection may seem irrelevant as it often intersects a data range with itself. However, it serves an important purpose: it turns the data range into a data format which is both inside the range and optimalfor filter B. This data format could then be relayed to filter A.

To maximize versatility, the intersection routine should be prepared to deal with both eventualities.


Kernel Mode Filters, DirectShow, and Proxying

Many times, kernel mode filters will be connected in user mode through the proxy (which makes a kernel mode filter appear to user mode as a DirectShow filter). When this mode of connection is used, DirectShow will use its normal means to attempt to connect the filters: For example, pin A's media types will be enumerated and relayed to pin B until a connection is made or the available types on pin A are exhausted. If the available types are exhausted, the enumeration will happen in reverse: pin B’s media types are enumerated and relayed to pin A.

It is important to note that the relation is made between kernel mode data formats and DirectShow media types. When a media type is enumerated off a kernel mode pin, the Nth data range on the pin is intersected with the pin’s data range. This intersection yields a data format, as described previously. The proxy converts the resulting data format into a DirectShow media type.

When a media type is relayed to a proxied pin, the proxy will either ask a data handler to determine whether the media type is acceptable, or it will determine whether the media type is a partial match for a data range on the pin. A partial match indicates that, in the context of kernel mode semantics, the major type, subformat, specifier, and required attributes match, either exactly or by wildcard. If the media type is a partial match, the connection will proceed. Before the connection completes, AVStream will call the minidriver’s SetDataFormat dispatch to inform the minidriver of the data format being set. Note that this format corresponds to the user mode media type that was suggested to the proxied pin. AVStream will also provide the data range that was determined to be a partial match for the format. At this point, the minidriver’s SetDataFormat dispatch can still decline the format by returning STATUS_NO_MATCH. The dispatch might do this if, for instance, it determines that the format is not a match for the range.


Mutexes in AVStream

In AVStream, minidrivers perform synchronization tasks using three types of mutexes, and also using process control gates. For more information on process control gates, please refer to the section entitled Flow Control Gates in AVStream. All three mutexes are directly accessible to the minidriver. See details in the sections listed below.

Several AVStream API functions require that associated mutexes be held. Notes are included in the Comments sections of relevant function reference pages stating which mutex should be held before calling that particular function.

  • Device Mutex in AVStream
  • Filter Control Mutex in AVStream
  • Processing Mutex in AVStream


Device Mutex in AVStream

The first mutex is the device mutex. Each AVStream device has a single associated device mutex. This mutex is used to synchronize access to the object hierarchy from the device down to the filters. Creation and destruction of both filter factories and filters are synchronized with this mutex. Certain Plug and Play and power management operations are also synchronized with this mutex. The main concern of the minidriver in dealing with the device mutex is in manually creating filter factories with KsCreateFilterFactory or in traversing the object hierarchy via the Ks*GetFirstChild*, Ks*GetNextSibling* functions. The object hierarchy is only guaranteed to be stable from the device down to individual filters if the device mutex is held.

AVStream will hold the device mutex on behalf of the minidriver during the following operations:

  • PnP QueryStop (IRP_MN_QUERY_STOP) dispatch
  • PnP QueryRemove (IRP_MN_QUERY_REMOVE) dispatch
  • PostStart dispatch
  • PnP StartDevice (IRP_MN_START_DEVICE) dispatch
  • Power Management QueryPower (IRP_MN_QUERY_POWER) dispatch
  • Power Management SetPower (IRP_MN_SET_POWER) dispatch
  • Sleep and Wake notifications on filters and pins

It is important to note that the device mutex is not recursively reobtainable. This means that if AVStream executes a callback to a minidriver for a Sleep notification in the context of thread A, and then the minidriver subsequently attempts to obtain the mutex in that same thread (A), thread A will deadlock with itself.

Also note that AVStream often obtains control mutexes while the device mutex is already held. Consequently, as a general rule, a thread that has taken a control mutex should not subsequently take the device mutex.

To manipulate the device mutex, use the following functions:

KsAcquireDevice, KsReleaseDevice


Filter Control Mutex in AVStream

The second mutex used in AVStream is the filter control mutex. Each AVStream filter instance has an associated filter control mutex. This mutex is used to synchronize access to the object hierarchy from the filter downward to individual pins. Creation and destruction of filters and pins are synchronized with this mutex. The filter control mutex is also used to synchronize state transitions. The main concern of the minidriver in dealing with the filter control mutex is in traversing the object hierarchy via the Ks*GetFirstChild*, Ks*GetNextSibling* functions. The object hierarchy is only guaranteed to be stable from a specific filter instance downward if the filter control mutex is held.

AVStream will also obtain the filter control mutex when handling properties which require the hierarchy to remain stable, performing descriptor modification, etc.

Note that there is a single control mutex used for the object hierarchy from the filter level downward. This means that a pin object uses its parent’s control mutex (the filter control mutex) when a minidriver calls this function with a pin object.

AVStream holds the filter control mutex on behalf of the minidriver during the following operations:

  • Filter Create dispatch
  • Filter Close dispatch
  • Pin Create dispatch
  • Pin Close dispatch
  • Pin Connect dispatch
  • Pin Disconnect dispatch
  • Pin Reset dispatch
  • Pin SetDataFormat dispatch
  • Pin SetDeviceState dispatch

It is important to note that, like the device mutex, the filter control mutex is not recursively reobtainable. If, for instance, AVStream makes a callback to a minidriver for a Create dispatch in the context of thread A and the minidriver later attempts to obtain the mutex in that same thread (A), thread A will deadlock with itself.

As mentioned in Filter Control Mutex in AVStream, a thread that has taken a processing mutex should not subsequently take the filter control mutex. In addition, AVStream often obtains process mutexes while already holding control mutexes. So in general, a thread that already holds a processing mutex should not take the control mutex.

To manipulate the filter control mutex, use the following functions:

KsAcquireControl, KsFilterAcquireControl, KsPinAcquireControl, KsReleaseControl, KsFilterReleaseControl, KsPinReleaseControl


Processing Mutex in AVStream

The third mutex is the processing mutex. Individual filters and pins have their own processing mutexes. AVStream independently acquires the processing mutex before processing at the filter level, in order to synchronize access to processing-related structures. AVStream also acquires the processing mutex during several other operations, including binding pins to a pipe section, sleep or wake power operations, and making modifications to descriptors. Minidrivers can manually acquire the mutex to perform an synchronous operation, such as processing, descriptor modification. A minidriver should obtain the processing mutex before making any change that cannot happen concurrently with processing.

As with the other two types of mutexes, process mutexes are also not recursively reobtainable. This means that if a minidriver attempts to grab the process mutex while processing, a deadlock will occur.

Minidrivers should not use the processing mutex to suspend processing for a long period of time. Instead, manipulate the processing control gate directly using the KsGate* functions.

As mentioned in Filter Control Mutex in AVStream, a thread that has taken a process mutex should not subsequently take the filter control mutex.

To manipulate the processing mutex, use the following functions:

KsFilterAcquireProcessingMutex, KsPinAcquireProcessingMutex, KsFilterReleaseProcessingMutex, KsPinReleaseProcessingMutex


Broadcast Receiver Topology

A Broadcast Driver Architecture (BDA) receiver topology is an abstract representation of a filter graph. It is composed of a network of logical nodes, each of which performs an operation on a signal. Each node can be associated with an individual filter or combined with other nodes in a filter. The following sections discuss BDA receiver topology:

  • Functional Topology
  • Control Nodes, Filters and Hardware
  • Common Control Nodes and Filters


Functional Topology

To enable the building of broadcast receiver filter graphs in a way that works for all varieties of network types, and hardware and software implementations of, for example, tuners and decoders, Broadcast Architecture takes the familiar concept of a filter graph from DirectShow and abstracts it in the concept of a functional topology. A functional topology, like a filter graph, describes the series of transformations that occur on the incoming signal. However, unlike a filter graph, a functional topology does not describe any actual filters or software modules; or how an operation is implemented in software or hardware. Instead, it describes a configuration of abstract control nodes, each of which represents some common discrete operation.

Depending on the type of hardware and software components that are installed in a computer, the same functional topology can result in different filter graph configurations or actual topologies. For example, if a hardware vendor chooses to implement a tuner and a demodulator on the same circuit card, then KSProxy represents this hardware device in the filter graph as a single filter with two internal control nodes. A BDA device filter distinguishes itself from a more traditional DirectShow filter because a single BDA device filter can encapsulate as many hardware functions (control node implementations) as are built into a single functional module (for example, a circuit card or chip).

The function that a control node provides is uniquely identified by a GUID. For definitions of node description GUIDS, see the header file, bdamedia.h, in the DDK. During the graph-building process, the network provider filter uses these GUIDs to determine which nodes are useful in supporting a particular network type or tuning space. Filters in a broadcast receiver filter graph indicate, through a COM interface, the node types and the pin types they support. The Ring 0 drivers for filters indicate this same information through KS property sets. A filter contains data structures that describe its node types, pin types, and the ways in which pins and nodes can be connected. This information is called the filter's template topology. The following figure illustrates a template topology.

Template topology

The template topology in the preceding figure contains five different node types and four different pin types. The numbers of the pin and node types are arbitrary identifiers assigned by the filter. Each node type, however, is associated with a node description GUID that the network provider can examine. Each node type can occur only once in the topology, but since the filter arbitrarily assigns identifiers to node types, the same control node GUID could be associated with more than one node type. For example, node types that are identified with numbers 1 and 3 could represent the same control node GUID with two different output paths. A template topology must represent this scenario with two separate node types. The lines that connect these pin and node types in the template topology show the paths that the filter supports.

The network provider must examine this topology and determine the transformations that the filter performs on a signal in any particular graph. For more information on the data structures that describe the template topology, see Broadcast Driver Architecture Minidrivers.


Control Nodes, Filters and Hardware

BDA control nodes in BDA receiver topology can be separated into individual filters or combined in filters. In addition, BDA control nodes can be associated with hardware or be software-only components. The following sections describe:

  • Control Nodes
  • Combining Nodes in a Filter
  • Separating Nodes in Individual Filters
  • Control Nodes for Processing IP Data


Control Nodes

The following figure shows an example of one possible functional topology that receives digital broadcast content. It illustrates the operations necessary to:

  • tune and demodulate the signal.
  • capture and demultiplex the signal.
  • obtain electronic program guide (EPG) information.
  • obtain audio and video content.
  • obtain IP data.

Receiver topology

Note that some functions in receiver topology that acquire content, such as the tuner, are always associated with hardware. Other functions, such as content stream demultiplexing, can be performed with hardware or software components. Still others, such as the transport information filter (TIF) and network provider filter, are always software components.

The blocks in the preceding figure correspond to BDA control nodes. Each control node combines network and program-specific parameter data with the input signal, or signal component, using a standard algorithm. The result produces a new signal component that is useful to the control nodes connected immediately downstream.


Combining Nodes in a Filter

The following figure of a sample DirectShow filter graph shows one possible way in which the control nodes can be represented as filters in a filter graph. The network provider is always its own filter and precedes all other filters. In this sample, because the tuner and demodulator nodes are combined on the same circuit card, they appear as one filter. The capture filter follows the tuner/demodulator filter. For all of these filters so far, the actual internal and external connections in the filter match the control nodes. The next filter downstream is the MPEG-2 transport stream demultiplexer, which is represented by a single filter that exposes the packet identifier (PID) filters as shown in the figure in the Control Nodes section. The actual MPEG-2 transport stream demultiplexer filter reproduces the topology as many times as necessary to handle all the elementary streams.

Sample DirectShow Filter Graph with Tuner and Demodulator Combined in One Filter


Separating Nodes in Individual Filters

The following figure of a sample DirectShow filter graph shows another way in which the control nodes can be represented as filters in a filter graph. In this sample, the tuner and demodulator control nodes are separated into individual filters. All other control nodes are as described in the Combining Nodes in a Filter section.

Sample DirectShow Filter Graph with Separate Tuner and Demodulator Filters


Control Nodes for Processing IP Data

The following sequence and figure describe the data flow for IP data that is part of the received digital signal.

  1. The receiver device receives IP data and passes the IP data over the PC bus as part of the transport stream.
  2. The demultiplexer receives the transport stream and passes the private sections containing the IP data.
  3. The private sections are received by the multiprotocol encapsulation (MPE) parser, which removes the multiprotocol encapsulation and outputs the IP data. The MPE parser passes the IP data to the IPSink filter.
  4. The IPSink filter passes the IP data through a private interface to the broadcast NDISIP miniport driver.
  5. The NDISIP miniport driver is installed as a virtual NDIS miniport. The NDISIP miniport driver sends the IP data to NDIS.
  6. NDIS propagates the IP data through TCP/IP and Windows Sockets (WinSock) as it would for any other NDIS adapter.

IP data flow


Common Control Nodes and Filters

The types of control nodes and filters that are shown in the figures in the Control Nodes, Filters and Hardware section are common to the reception of digital satellite, terrestrial, and cable broadcasts. However, you can create other node types and filters for a wide variety of broadcast media and devices as well. It is important to remember that each control node need not correspond to a single BDA device filter. In some cases, a single BDA device filter can encapsulate more than one control node.

The following list describes control nodes and filters that are commonly found in Broadcast Architecture:

Network Provider
A network provider filter (or network provider) routes a digital television signal to and through BDA devices. A variety of broadcast providers currently transmit digital television signals over three basic network types—satellite, cable and antenna. These digital signals are transmitted in formats defined by multiple standards, including ATSC, DVB-S, DVB-C, and DVB-T. BDA devices receive and manage these digital signals.

A network provider:

• is the source filter in a filter graph, although no data actually passes through it.

• exists for each network type or can be created for a new network type.

• participates in the graph building process.

• communicates with other filters in the graph through property and method sets of BDA minidrivers that initialized such filters.

Each network provider can build a different graph configuration for its associated network type. Applications pass tune requests to a network provider, which in turn passes the information to a BDA minidriver. See the Broadcast Architecture section of the Platform SDK documentation for more information.

Tuner
This control node filters the particular frequency that carries the transport stream. It can appear inside a filter by itself or together with other control nodes.
Demodulator
A control node that translates the analog signal into a digital bit stream. It can appear inside a filter by itself or together with other control nodes.
Capture
A filter that moves the data into host memory.
PID Filter
A control node that selects one or more elementary data streams from the transport stream. This is the primary function of a demultiplexer. It can appear inside a filter by itself or together with other control nodes.
MPE Parser
A filter that parses IP data from a stream containing MPEG-2 private sections.
IPSink
A filter that accepts IP packets as data samples and forwards the data to the NDIS TCP/IP stack.
NDISIP
An NDIS miniport driver that acts as a receiver for a network adapter for the data that the IPSink filter passes.


Broadcast Driver Architecture Minidrivers

Broadcast Driver Architecture (BDA) minidrivers control hardware that performs the following operations:

  • tuning a digital broadcast signal
  • demodulating the digital signal
  • capturing frames of the digital signal
  • demultiplexing the signal into video, audio, and data streams

BDA minidrivers are AVStream minidrivers that run under the AVStream module in the kernel-streaming driver ks.sys. AVStream is a class driver that provides a unified kernel streaming class model for both audio and video minidrivers, and that supports use of COM objects without altering existing minidriver binaries. The AVStream class driver provides much of the default behavior required to make a minidriver's filter work as a WDM-CSA (kernel streaming) compliant filter. To simplify the task of writing BDA minidrivers, you can use the BDA support library (Bdasup.lib) of functions that is included in the DDK. This library provides extensive default handling for the BDA minidriver's property and method sets.

Typically, driver writers only have to code the appropriate static template structures, register them with the BDA support library, and then let the library provide default handling for all the properties and methods. In some instances, a BDA minidriver must intercept a property or method request and perform appropriate operations.

The following figure shows an architectural overview for BDA minidrivers:

BDA minidriver architecture

The following sections describe implementation details for a BDA minidriver, discuss details of some property and method sets, and contain sample code that shows how to intercept certain properties and methods:

  • Initializing a BDA Minidriver
  • Starting a BDA Minidriver
  • Creating Dispatch Tables
  • Defining Automation Tables
  • Initializing a BDA Filter
  • Determining BDA Device Topology
  • Mapping Connection Topology
  • Determining the Controlling Pin of a Node
  • Configuring a BDA Filter
  • Changing BDA Filter Properties
  • Accessing Frequency Properties of a BDA Node


Initializing a BDA Minidriver

A BDA minidriver is initialized similarly to other AVStream minidrivers. The BDA minidriver's DriverEntry function calls the AVStream KsInitializeDriver function to initialize the BDA minidriver's driver object. In this call, the BDA minidriver passes a pointer to a KSDEVICE_DESCRIPTOR structure that specifies characteristics of the device, which can include:

  • A pointer to a KSDEVICE_DISPATCH structure that contains the dispatch table for the BDA device. At a minimum, the BDA minidriver should supply routines that create and start the device and specify these routines in the Add and Start members respectively of the KSDEVICE_DISPATCH structure. The BDA minidriver's create routine should allocate memory for the device class and reference the pointer to the KSDEVICE structure for the BDA device to this device class. The BDA minidriver's start routine should get information about the device from the registry, set information on the device, and then register a group of static template structures with the BDA support library. See Starting a BDA Minidriver for more information.
  • An array of KSFILTER_DESCRIPTOR structures for the individual filter types supported by this device. This structure type describes the characteristics of a filter created by a given filter factory. You should specify members of structures of this type in this array if you create your BDA minidriver so that it does not use the BDA support library (Bdasup.lib) to handle your BDA minidriver's property and method sets. If you create your BDA minidriver so that it uses the BDA support library, then your BDA minidriver should instead call the BdaCreateFilterFactory support function to add filter factory descriptors (KSFILTER_DESCRIPTOR structures) for your device. See Starting a BDA Minidriver for more information.

The following code snippet shows examples of an array of filter descriptors, a dispatch table for the BDA device, and the descriptor for the BDA device:

//
//  Array containing descriptors for all filter factories
//  available on the device.
//
//  Note!  Only used when dynamic topology is not used (that is,
//         only when filters and pins are fixed). Typically, this
//         is when the network provider is not present.
//
DEFINE_KSFILTER_DESCRIPTOR_TABLE(FilterDescriptors)
{
    &TemplateTunerFilterDescriptor
};
//
//  Device Dispatch Table
//
//  Lists the dispatch routines for the major events related to
//  the underlying device.
//
extern
const
KSDEVICE_DISPATCH
DeviceDispatch =
{
    CDevice::Create,    // Add
    CDevice::Start,     // Start
    NULL,               // PostStart
    NULL,               // QueryStop
    NULL,               // CancelStop
    NULL,               // Stop
    NULL,               // QueryRemove
    NULL,               // CancelRemove
    NULL,               // Remove
    NULL,               // QueryCapabilities
    NULL,               // SurpriseRemoval
    NULL,               // QueryPower
    NULL                // SetPower
};
//
//  Device Descriptor
//
//  Brings together the data structures that define the device and
//  the initial filter factories that can be created on it.
//  Note that because template topology structures are specific
//  to BDA, the device descriptor does not include them.
//  Note also that if BDA dynamic topology is used, the device
//  descriptor does not specify a list of filter factory descriptors.
//  If BDA dynamic topology is used, the BDA minidriver calls
//  BdaCreateFilterFactory to add filter factory descriptors.
extern
const
KSDEVICE_DESCRIPTOR
DeviceDescriptor =
{
    &DeviceDispatch,    // Dispatch
#ifdef DYNAMIC_TOPOLOGY // network provider is present
    0,    // FilterDescriptorsCount
    NULL, // FilterDescriptors
#else     // network provider is not present
    SIZEOF_ARRAY( FilterDescriptors), // FilterDescriptorsCount
    FilterDescriptors                 // FilterDescriptors
#endif // DYNAMIC_TOPOLOGY


Starting a BDA Minidriver

When a BDA device starts operating, the Plug and Play (PnP) Manager dispatches a start IRP (IRP_MN_START_DEVICE). The AVStream class in turn calls the start routine of the BDA minidriver associated with the BDA device. This start routine retrieves information about the device from the registry, sets information on the device, and then calls the BdaCreateFilterFactory support function to:

  • Create the filter factory for the device from the initial filter descriptor (KSFILTER_DESCRIPTOR) for the device. The initial filter descriptor references dispatch and automation tables for the filter and input pins. See Creating Dispatch Tables and Defining Automation Tables for more information.
  • Associate the filter factory with a BDA_FILTER_TEMPLATE structure. This structure references the template filter descriptor for the device and the list of possible pairs of input and output pins. This descriptor and list in turn reference:
    • Static template structures that a network provider can use to determine the topology of a BDA filter.
    • Nodes and pins for a BDA filter along with possible ways to connect the filter.
    • Routines that a network provider can use to create and close a filter instance.
    • Static template structures that a network provider can use to manipulate a BDA filter.
  • Register the static template structures that are specified by BDA_FILTER_TEMPLATE with the BDA support library so that the library can provide default handling for a BDA minidriver's properties and methods.

The following code snippet shows an example of an initial filter descriptor for the device that BdaCreateFilterFactory sets as the filter factory:

const KSFILTER_DESCRIPTOR    InitialTunerFilterDescriptor;
//
//  Filter Factory Descriptor for the tuner filter
//
//  This structure brings together all of the structures that define
//  the tuner filter instance as it appears when it is first created.
//  Note that not all template pin and node types are exposed as
//  pin and node factories when the filter instance is created.
//
DEFINE_KSFILTER_DESCRIPTOR(InitialTunerFilterDescriptor)
{
    &FilterDispatch,             // Table of dispatch routines
    &FilterAutomation,           // Table of properties and methods
    KSFILTER_DESCRIPTOR_VERSION, // Version
    0,                           // Flags
    &KSNAME_Filter,              // Reference Guid
    DEFINE_KSFILTER_PIN_DESCRIPTORS(InitialPinDescriptors),
                                   // PinDescriptorsCount
                                   // PinDescriptorSize
                                   // PinDescriptors
    DEFINE_KSFILTER_CATEGORY(KSCATEGORY_BDA_RECEIVER_COMPONENT),
                            // CategoriesCount
                            // Categories
    DEFINE_KSFILTER_NODE_DESCRIPTORS_NULL(NodeDescriptors),
                                    // NodeDescriptorsCount
                                    // NodeDescriptorSize
                                    // NodeDescriptors
    DEFINE_KSFILTER_DEFAULT_CONNECTIONS, // ConnectionsCount
                                         // Connections
    NULL                // ComponentId
};

The following code snippet shows an example of an array of initial pin descriptors that are exposed by an initialized filter. The network provider initializes a filter using such an array before the network provider configures that filter. However, when configuring an initialized filter, the network provider selects pins that are referenced in the pointer to the filter descriptor member of the BDA_FILTER_TEMPLATE structure. See Configuring a BDA Filter for more information.

//
//  Initial Pin Descriptors
//
//  This data structure defines the pins that will appear on the
//  filter when it is first created.
//
const
KSPIN_DESCRIPTOR_EX
InitialPinDescriptors[] =
{
    //  Antenna Pin
    //
    {
        &AntennaPinDispatch,
        &AntennaAutomation,   // AntennaPinAutomation
        {
            0,  // Interfaces
            NULL,
            0,  // Mediums
            NULL,
            SIZEOF_ARRAY(AntennaPinRanges),
            AntennaPinRanges,
            KSPIN_DATAFLOW_IN,
            KSPIN_COMMUNICATION_BOTH,
            NULL,   // Name
            NULL,   // Category
            0
        },
        KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT |
        KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING |
        KSPIN_FLAG_FIXED_FORMAT,
        1,      // InstancesPossible
        0,      // InstancesNecessary
        NULL,   // Allocator Framing
        NULL    // PinIntersectHandler
    }
};

Note that an initialized filter must have one or more input pins exposed so that the Microsoft® DirectShow® IFilterMapper2 or IFilterMapper interface can locate that filter. See the Microsoft Windows Platform SDK documentation for information about these DirectShow interfaces.

The following code snippet shows examples of a BDA_FILTER_TEMPLATE structure and related structures and arrays:

const KSFILTER_DESCRIPTOR  TemplateTunerFilterDescriptor;
const BDA_PIN_PAIRING  *TemplateTunerPinPairings;
//
//  BDA Template Topology Descriptor for the filter factory.
//
//  This structure defines the pin and node types that the network
//  provider can create on the filter and how they are arranged.
//
const
BDA_FILTER_TEMPLATE
TunerBdaFilterTemplate =
{
    &TemplateTunerFilterDescriptor,
    SIZEOF_ARRAY(TemplateTunerPinPairings),
    TemplateTunerPinPairings
};
//
//  Filter Factory Descriptor for the tuner filter template topology
//
//  This structure brings together all of the structures that define
//  the topologies that the tuner filter can assume as a result of
//  pin factory and topology creation methods.
//
DEFINE_KSFILTER_DESCRIPTOR(TemplateTunerFilterDescriptor)
{
    &FilterDispatch,             // Table of dispatch routines
    &FilterAutomation,           // Table of properties and methods
    KSFILTER_DESCRIPTOR_VERSION, // Version
    0,                           // Flags
    &KSNAME_Filter,              // Reference Guid
    DEFINE_KSFILTER_PIN_DESCRIPTORS(TemplatePinDescriptors),
                                   // PinDescriptorsCount
                                   // PinDescriptorSize
                                   // PinDescriptors
    DEFINE_KSFILTER_CATEGORY(KSCATEGORY_BDA_RECEIVER_COMPONENT),
                            // CategoriesCount
                            // Categories
    DEFINE_KSFILTER_NODE_DESCRIPTORS(NodeDescriptors),
                                    // NodeDescriptorsCount
                                    // NodeDescriptorSize
                                    // NodeDescriptors
    DEFINE_KSFILTER_CONNECTIONS(TemplateTunerConnections),
                               // ConnectionsCount
                               // Connections
    NULL                // ComponentId
};
//
//  Lists how pairs of input and output pins are configured.
//
//  Values given to the BDA_PIN_PAIRING structures in the list inform
//  the network provider which nodes get duplicated when more than one
//  output pin type is connected to a single input pin type or when
//  more that one input pin type is connected to a single output pin
//  type. Also, informs of the joints array.
//
const
BDA_PIN_PAIRING TemplateTunerPinPairings[] =
{
    //  Antenna to Transport Topology Joints
    //
    {
        0,  // ulInputPin
        1,  // ulOutputPin
        1,  // ulcMaxInputsPerOutput
        1,  // ulcMinInputsPerOutput
        1,  // ulcMaxOutputsPerInput
        1,  // ulcMinOutputsPerInput
        SIZEOF_ARRAY(AntennaTransportJoints),   // ulcTopologyJoints
        AntennaTransportJoints                  // pTopologyJoints
    }
};


Creating Dispatch Tables

You must create a filter dispatch table for a filter descriptor (KSFILTER_DESCRIPTOR) of a BDA minidriver so that the network provider filter can open and initialize an instance of the filter and later release the filter instance. You must also create a pin dispatch table for each pin descriptor (KSPIN_DESCRIPTOR_EX) in the array of pin types that are available in the filter's template topology. The network provider filter uses a pin dispatch table to open and initialize a pin and later release the pin. The following code snippet shows examples of filter and pin dispatch tables:

//
//  Filter Dispatch Table
//
//  Lists the dispatch routines for major events at the filter
//  level.
//
const
KSFILTER_DISPATCH
FilterDispatch =
{
    CFilter::Create,        // Create
    CFilter::FilterClose,   // Close
    NULL,                   // Process
    NULL                    // Reset
};

//
//  Input Pin Dispatch Table
//  Lists the dispatch routines for major events at the pin level.
//
const
KSPIN_DISPATCH
AntennaPinDispatch =
{
    CAntennaPin::PinCreate,         // Create
    CAntennaPin::PinClose,          // Close
    NULL,                           // Process signal data
    NULL,                           // Reset
    NULL,                           // SetDataFormat
    CAntennaPin::PinSetDeviceState, // SetDeviceState
    NULL,                           // Connect
    NULL,                           // Disconnect
    NULL,                           // Clock
    NULL                            // Allocator
};


Defining Automation Tables

An automation table for a filter, pin, or node is what describes the properties and methods supported by the filter, pin, or node. If a BDA minidriver supplies a property or method handler that is already implemented by AVStream, the BDA minidriver's implementation supersedes AVStream's.

A BDA minidriver should define arrays of property and method sets and then define automation tables for those set arrays so that the minidriver can automatically process requests. See the Determining BDA Device Topology section for an example of how the minidriver also defines a property set to which this section refers.

The following code snippet shows examples of filter automation tables and arrays of property and method sets:

//
//  Filter Level Property Set supported
//
//  This array defines a property set supported by the
//  filter that is exposed by the minidriver.
//
DEFINE_KSPROPERTY_SET_TABLE(FilterPropertySets)
{
    DEFINE_KSPROPERTY_SET
    (
        &KSPROPSETID_BdaTopology,                   // Set
        SIZEOF_ARRAY(FilterTopologyProperties),     // PropertiesCount
        FilterTopologyProperties,                   // PropertyItems
        0,                                          // FastIoCount
        NULL                                        // FastIoTable
    )
};
//
//  Filter Level Method Sets supported
//
//  This array defines method sets supported by the
//  filter that is exposed by the minidriver.
//
DEFINE_KSMETHOD_SET_TABLE(FilterMethodSets)
{
    DEFINE_KSMETHOD_SET
    (
        &KSMETHODSETID_BdaChangeSync,               // Set
        SIZEOF_ARRAY(BdaChangeSyncMethods),         // PropertiesCount
        BdaChangeSyncMethods,                       // PropertyItems
        0,                                          // FastIoCount
        NULL                                        // FastIoTable
    ),
    DEFINE_KSMETHOD_SET
    (
        &KSMETHODSETID_BdaDeviceConfiguration,      // Set
        SIZEOF_ARRAY(BdaDeviceConfigurationMethods),// PropertiesCount
        BdaDeviceConfigurationMethods,              // PropertyItems
        0,                                          // FastIoCount
        NULL                                        // FastIoTable
    )
};
//
//  Filter Automation Table
//
//  Lists all arrays of property and method sets for the filter that
//  is exposed by the minidriver.
//
DEFINE_KSAUTOMATION_TABLE(FilterAutomation) {
    DEFINE_KSAUTOMATION_PROPERTIES(FilterPropertySets),
    DEFINE_KSAUTOMATION_METHODS(FilterMethodSets),
    DEFINE_KSAUTOMATION_EVENTS_NULL
};

The following code snippet shows an example of a node automation table and an array of property sets:

//
//  RF tuner node property set supported
//
//  This array defines a property set supported by the
//  RF Tuner Node associated with the antenna input pin.
//
DEFINE_KSPROPERTY_SET_TABLE(RFNodePropertySets)
{
    DEFINE_KSPROPERTY_SET
    (
        &KSPROPSETID_BdaFrequencyFilter,            // Set
        SIZEOF_ARRAY(RFNodeFrequencyProperties),    // PropertiesCount
        RFNodeFrequencyProperties,                  // PropertyItems
        0,                                          // FastIoCount
        NULL                                        // FastIoTable
    )
};
//
//  Radio frequency tuner node automation table
//
//
DEFINE_KSAUTOMATION_TABLE(RFTunerNodeAutomation) {
    DEFINE_KSAUTOMATION_PROPERTIES( RFNodePropertySets),
    DEFINE_KSAUTOMATION_METHODS_NULL,
    DEFINE_KSAUTOMATION_EVENTS_NULL
};


Initializing a BDA Filter

A network provider filter uses the create dispatch routine of the BDA device's initial filter descriptor to create an initial filter instance of the BDA device when the network provider creates a filter graph. This initial filter descriptor was set as a filter factory and associated with the BDA filter template for the BDA device when the BDA device started. The initial filter instance that is created should expose at least one input. Typically, the initial filter instance exposes an input pin for each possible input pin in the initial filter descriptor but exposes no output pins. See Starting a BDA Minidriver and Creating Dispatch Tables for more information.

The BDA filter's create routine should allocate memory for its filter object, should set member variables for the filter object, and then should call the BdaInitFilter support function to initialize the filter instance. In this call, the BDA filter's create routine passes a pointer to the KSFILTER structure for the initial filter to create and a pointer to the BDA_FILTER_TEMPLATE structure that describes possibilities for the filter's template topology for the initial filter instance.


Determining BDA Device Topology

A BDA device topology is composed of a connected network of nodes, each of which represent some transformation on a signal. Nodes can be grouped arbitrarily among different filters. This arbitrary grouping provides hardware vendors with a certain freedom in how they implement their hardware and drivers so that such hardware and drivers work in a generic way with the network providers for the different types of networks they wish to support.

For this arbitrary grouping architecture to work, the network provider must be able to query filters as to what kind of transformations those filters perform on a signal (that is, what types of node networks the filter can support). The underlying Ring 0 minidriver for a filter conveys a picture of its supported node networks to the network provider through the KSPROPSETID_BdaTopology property set.

When determining the template topology for a filter, the network provider iterates lists of node types and pin types and queries each node and pin for its capabilities. The network provider uses the following properties of KSPROPSETID_BdaTopology to determine the template topology for the filter:

  • KSPROPERTY_BDA_NODE_TYPES

    Node types represent possible functional nodes within the filter. The KSPROPERTY_BDA_NODE_TYPES property returns a list of all node types that are provided by a filter instance of the BDA minidriver. The minidriver assigns arbitrary values to identify node types. Typically, the minidriver uses the index of each element in the list of the minidriver's node types as the value for each node type. The BDA minidriver assigns each node type a node description GUID. Description GUIDs for node types that the network provider currently supports are defined in bdamedia.h. This node description indicates to the network provider what the node does. In a template topology, a node type can occur only once. However, more than one node of a specific type may have the same node description GUID. This allows a specific signal transformation to occur in more than one place in the filter’s topology while allowing the network provider to identify a single topology node unambiguously.

  • KSPROPERTY_BDA_PIN_TYPES

    Pin types represent possible connections to other filters in the graph. The KSPROPERTY_BDA_PIN_TYPES property returns a list of all pin types that can be created on the filter. In a template topology, a pin type can occur only once.

  • KSPROPERTY_BDA_TEMPLATE_CONNECTIONS

    The KSPROPERTY_BDA_TEMPLATE_CONNECTIONS property returns an array that represents all the possible connections between node types and pin types that can be configured on the filter. See Mapping Connection Topology for more information.

When a filter instance is first created and added to the graph, it typically has input pins but no output pins. To create output pins, the network provider first uses the KSPROPSETID_BdaTopology properties to determine what operations the filter can perform. From these properties, the network provider determines which operations it requires the filter to perform for a particular filter graph. The network provider then uses the KSMETHODSETID_BdaDeviceConfiguration method set to create output pins matching a particular pin type and create the internal topology, which is the actual hardware path, between those pins and the input pins. See Configuring a BDA Filter for more information.

The following code snippet shows how to define functions that are exported by the BDA support library as dispatch routines for the KSPROPSETID_BdaTopology property set:

//
//  KSPROPSETID_BdaTopology property set
//
//  Defines the dispatch routines for the filter level
//  topology properties
//
DEFINE_KSPROPERTY_TABLE(FilterTopologyProperties)
{
    DEFINE_KSPROPERTY_ITEM_BDA_NODE_TYPES(
        BdaPropertyNodeTypes,
        NULL
        ),
    DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPES(
        BdaPropertyPinTypes,
        NULL
        ),
    DEFINE_KSPROPERTY_ITEM_BDA_TEMPLATE_CONNECTIONS(
        BdaPropertyTemplateConnections,
        NULL
        ),
    DEFINE_KSPROPERTY_ITEM_BDA_CONTROLLING_PIN_ID(
        BdaPropertyGetControllingPinId,
        NULL
        )
};


Mapping Connection Topology

In order for the BDA support library to provide properties and methods to applications in Ring 3 on behalf of a BDA minidriver, the BDA minidriver must provide a mapping of its connection topology to the BDA support library. The BDA minidriver previously provided this mapping when it passed an array of BDA_TEMPLATE_CONNECTION structures to the support library in an array of KSTOPOLOGY_CONNECTION structures in its BdaCreateFilterFactory function call. See Starting a BDA Minidriver for more information. This array provides a representation of all the possible connections between node and pin types that can be made within a filter or between a filter and adjoining filters.

The network provider filter can subsequently make a KSPROPERTY_BDA_TEMPLATE_CONNECTIONS property request of the KSPROPSETID_BdaTopology property set on a filter instance of the BDA minidriver to retrieve the minidriver's connection topology. The BDA minidriver in turn calls the BdaPropertyTemplateConnections support function, which returns the list of the filter's template connections (BDA_TEMPLATE_CONNECTION structures) in an array of KSTOPOLOGY_CONNECTION structures. The members of a BDA_TEMPLATE_CONNECTION structure identify the following pairs of node and pin types of a connection:

  • node and pin types where the connection begins
  • node and pin types where the connection ends

Setting the node type to a value of –1 indicates that the connection begins or ends at a pin of either an upstream or downstream filter respectively. Otherwise, the value of the node type corresponds to the index of the element in the zero-based array of internal node types. This array is an array of KSNODE_DESCRIPTOR structures. The value of the pin type corresponds to the index of the element in the zero-based array of pin types that are available in the template filter descriptor for the BDA minidriver. This array is an array of KSPIN_DESCRIPTOR_EX structures.

The following code snippet shows example arrays of node types and pin types that are available in the template filter descriptor for the BDA minidriver:

//
//  Template Node Descriptors
//
//  This array describes all Node Types available in the template
//  topology of the filter.
//
const
KSNODE_DESCRIPTOR
NodeDescriptors[] =
{
    {   // 0 node type
        &RFTunerNodeAutomation,// PKSAUTOMATION_TABLE AutomationTable;
        &KSNODE_BDA_RF_TUNER,  // Type
        NULL                   // Name
    },
    {   // 1 node type
        &VSB8DemodulatorNodeAutomation, // PKSAUTOMATION_TABLE
                                        // AutomationTable;
        &KSNODE_BDA_8VSB_DEMODULATOR,   // Type
        NULL                            // Name
    }
};
//
//  Template Pin Descriptors
//
//  This data structure defines the pin types available in the filters
//  template topology. These structures will be used to create a
//  pin factory ID for a pin type when BdaMethodCreatePin is called.
//
const
KSPIN_DESCRIPTOR_EX
TemplatePinDescriptors[] =
{
    //  Antenna Pin
    //  0 pin type
    {
        &AntennaPinDispatch,
        &AntennaAutomation,   // AntennaPinAutomation
        {
            0,  // Interfaces
            NULL,
            0,  // Mediums
            NULL,
            SIZEOF_ARRAY(AntennaPinRanges),
            AntennaPinRanges,
            KSPIN_DATAFLOW_IN,
            KSPIN_COMMUNICATION_BOTH,
            NULL,   // Name
            NULL,   // Category
            0
        },
        KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT |
        KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING |
        KSPIN_FLAG_FIXED_FORMAT,
        1,      // InstancesPossible
        0,      // InstancesNecessary
        NULL,   // Allocator Framing
        NULL    // PinIntersectHandler
    },

    //  Tranport Pin
    //  1 pin type
    {
        &TransportPinDispatch,
        &TransportAutomation,   // TransportPinAutomation
        {
            0,  // Interfaces
            NULL,
            1,  // Mediums
            &TransportPinMedium,
            SIZEOF_ARRAY(TransportPinRanges),
            TransportPinRanges,
            KSPIN_DATAFLOW_OUT,
            KSPIN_COMMUNICATION_BOTH,
            (GUID *) &PINNAME_BDA_TRANSPORT,   // Name
            (GUID *) &PINNAME_BDA_TRANSPORT,   // Category
            0
        },
        KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT |
        KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING |
        KSPIN_FLAG_FIXED_FORMAT,
        1,
        1,      // InstancesNecessary
        NULL,   // Allocator Framing
        NULL    // PinIntersectHandler
    }
};

The following code snippet shows examples of arrays of template connections and joints:

//
//  BDA Template Topology Connections
//
//  Lists the possible connections between pin types and
//  node types. This structure along with the BDA_FILTER_TEMPLATE,
//  KSFILTER_DESCRIPTOR, and BDA_PIN_PAIRING structures
//  describe how topologies are created in the filter.
//
const
KSTOPOLOGY_CONNECTION TemplateTunerConnections[] =
{
    { -1,  0,  0,  0}, // from upstream filter to 0 pin of 0 node
    {  0,  1,  1,  0}, // from 1 pin of 0 node to 0 pin of 1 node
    {  1,  1,  -1, 1}, // from 1 pin of 1 node to downstream filter
};
//
//  Lists the template joints between antenna (input) and transport
//  (output) pin types. Values given to joints correspond to indexes
//  of elements in the preceding KSTOPOLOGY_CONNECTION array.
//
//  For this template topology, the RF node (0) belongs to the antenna
//  pin and the 8VSB demodulator node (1) belongs to the transport pin
//
const
ULONG   AntennaTransportJoints[] =
{
    1  // Second element in the preceding KSTOPOLOGY_CONNECTION array.
};


Determining the Controlling Pin of a Node

Unlike filters and pins, nodes do not have an associated file handle by which applications in Ring 3 can access them. Because nodes are internal components within a filter, they exist somewhere between the filter's input and output pins. The network provider must determine which filter pin to use, then use the pin to access a node. This filter pin is called the controlling pin for that node. To determine the controlling pin for each node in the BDA template connection list of a filter, the network provider queries the KSPROPERTY_BDA_CONTROLLING_PIN_ID property of the KSPROPSETID_BdaTopology property set. The BDA minidriver in turn calls the BdaPropertyGetControllingPinId support function for each node. In this call, the minidriver passes a pointer to a KSP_BDA_NODE_PIN structure. This structure identifies the property request to retrieve the controlling pin for a specific node type and a pair of the filter's input and output pins. The BDA support library returns the identifier of the controlling pin for the node type.

A BDA minidriver does not typically intercept the KSPROPERTY_BDA_CONTROLLING_PIN_ID property. The minidriver automatically dispatches the BdaPropertyGetControllingPinId support function from the KSPROPSETID_BdaTopology property set. See Determining BDA Device Topology for more information.

The support library is able to do all the work of determining the identifier of the controlling pin because the BDA minidriver provided the support library with a pointer to the BDA_FILTER_TEMPLATE structure when the BDA minidriver started operating. See Starting a BDA Minidriver for more information. A BDA minidriver informs the BDA support library how to determine controlling pins through information contained in BDA_FILTER_TEMPLATE. This information includes:

  • An array of connections. This array is a KSTOPOLOGY_CONNECTION array that provides a representation of all the possible connections between node and pin types that can be made within a filter or between a filter and adjoining filters. See Mapping Connection Topology for more information on the KSTOPOLOGY_CONNECTION array.
  • An array of joint values. A joint is a point in the topology where one input splits into one or more paths to different outputs, or one or more inputs join into a single output path. The value given to a joint corresponds to the index of an element in the KSTOPOLOGY_CONNECTION array. Most topologies will have only one joint.
  • An array of BDA_PIN_PAIRING structures. These structures identify input and output pin types, the maximum number of input-type instances that can be created on the filter, and the maximum number of output-type instances that can be created on the filter. These structures also contain a pointer to the array of joint values between the input and output pins. See Starting a BDA Minidriver for more information on the BDA_PIN_PAIRING array.

The following figure shows how the support library determines the filter pin that controls a specific node:

Determination of controlling pin


Configuring a BDA Filter

A BDA minidriver processes method requests of the KSMETHODSETID_BdaDeviceConfiguration method set to configure a filter instance for the minidriver in the current filter graph.

In the following code snippet, two of the methods of the KSMETHODSETID_BdaDeviceConfiguration method set are dispatched directly to the BDA support library and the remaining method is first intercepted by the BDA minidriver before dispatching to the BDA support library.

//
//  BDA Device Configuration Method Set
//
//  Defines the dispatch routines for the filter level
//  topology configuration methods
//
DEFINE_KSMETHOD_TABLE(BdaDeviceConfigurationMethods)
{
    DEFINE_KSMETHOD_ITEM_BDA_CREATE_PIN_FACTORY(
        BdaMethodCreatePin,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_DELETE_PIN_FACTORY(
        BdaMethodDeletePin,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_CREATE_TOPOLOGY(
        CFilter::CreateTopology,
        NULL
        )
};
/*
** CreateTopology()
**
** Keeps track of topology association between input and output pins
**
*/
NTSTATUS
CFilter::
CreateTopology(
    IN PIRP         pIrp,
    IN PKSMETHOD    pKSMethod,
    PVOID           pvIgnored
    )
{
    NTSTATUS            Status = STATUS_SUCCESS;
    CFilter *           pFilter;
    ULONG               ulPinType;
    PKSFILTER           pKSFilter;

    ASSERT( pIrp);
    ASSERT( pKSMethod);

    //  Obtain a "this" pointer for the method.
    //
    //  Because this function is called directly from the property
    //  dispatch table, get pointer to the underlying object.
    //
    pFilter = FilterFromIRP( pIrp);
    ASSERT( pFilter);
    if (!pFilter)
    {
        Status = STATUS_INVALID_PARAMETER;
        goto errExit;
    }

    //  Let the BDA support library create the standard topology.
    //  It will also validate the method, instance count, etc.
    //
    Status = BdaMethodCreateTopology( pIrp, pKSMethod, pvIgnored);
    if (Status != STATUS_SUCCESS)
    {
        goto errExit;
    }

    //  This is where the filter can keep track of associated pins.
    //
errExit:
    return Status;
}

The KSMETHOD_BDA_CREATE_TOPOLOGY method request calls the minidriver's CFilter::CreateTopology method. This method calls the BDA support library function BdaMethodCreateTopology to create a topology between filter pins. This function actually creates a topology structure in Ring 3, which reflects, for other property sets, the known connections of the filter. A BDA minidriver should intercept the KSMETHOD_BDA_CREATE_TOPOLOGY method request as shown in the preceding code snippet if that minidriver must send special instructions to the hardware when connecting particular pin types--for example, if the BDA device performs hardware demultiplexing and creates an arbitrary number of output pins fanned off from a single input pin.


Changing BDA Filter Properties

Because multiple instances of an application that views media broadcasts can run simultaneously on a system, you should write a BDA minidriver to accommodate multiple instances of a filter. Each filter instance can contain different information. For example, one instance of a tuner filter can contain a request to tune to channel 5, while another instance can contain a request to tune to channel 8. As control transitions from one instance to another, the BDA minidriver must instruct the underlying tuning device to change the way resources are configured. A BDA minidriver processes method requests of the KSMETHODSETID_BdaChangeSync method set to coordinate a list of property requests on one the minidriver's filter instances.

The primary purpose of the KSMETHODSETID_BdaChangeSync method set is to provide trigger points at which the underlying minidriver for a filter can acquire and release resources from the minidriver's device object. The minidriver must coordinate these trigger points with the filter's transition to and from a stopped state. For example, if the filter is in a stopped state, the minidriver should assign new resources to the filter but not acquire those resources whenever the network provider specifies to commit BDA topology changes. When the filter subsequently transitions out of its stopped state, the minidriver should then attempt to acquire those resources from the underlying device.

On the other hand, if the filter is already active, the minidriver should attempt to acquire new resources from the underlying device whenever the network provider specifies to commit BDA topology changes. Only one instance of the filter can be active—in the running state and holding the same resources—at any given time. When a filter transitions to the stopped state, it should therefore release all its resources, including those resources that were allocated for any of its pins, so that the resources are available to another filter graph that transitions to the running state.

Typically, a BDA minidriver's filter object intercepts and supplies methods for the methods of the KSMETHODSETID_BdaChangeSync method set. For example, the minidriver supplies methods for starting, checking, and committing filter changes and for getting the change state of a filter. In addition, the following minidriver-supplied methods should call the corresponding BDA support library functions to synchronize changes on the structures that the minidriver previously registered with the BDA support library:

  • Start-changes method calls the BdaStartChanges function.
  • Check-changes method calls the BdaCheckChanges function.
  • Commit-changes method calls the BdaCommitChanges function.
  • Get-changed-state method calls the BdaGetChangeState function.

The following code snippet shows how to intercept method requests of the KSMETHODSETID_BdaChangeSync method set using an internal method:

//
//  BDA Change Sync Method Set
//
//  Defines the dispatch routines for the filter level
//  Change Sync methods
//
DEFINE_KSMETHOD_TABLE(BdaChangeSyncMethods)
{
    DEFINE_KSMETHOD_ITEM_BDA_START_CHANGES(
        CFilter::StartChanges,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_CHECK_CHANGES(
        CFilter::CheckChanges,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_COMMIT_CHANGES(
        CFilter::CommitChanges,
        NULL
        ),
    DEFINE_KSMETHOD_ITEM_BDA_GET_CHANGE_STATE(
        CFilter::GetChangeState,
        NULL
        )
};

The following code snippet shows how the internal start-changes method in a BDA minidriver resets pending resource changes after the minidriver calls the BdaStartChanges support function to initiate the setting of new BDA topology changes:

//
// StartChanges ()
//
//    Puts the filter into change state.  All changes to BDA topology
//    and properties changed after this will be in effect only after
//    CommitChanges.
//
NTSTATUS
CFilter::
StartChanges(
    IN PIRP         pIrp,
    IN PKSMETHOD    pKSMethod,
    OPTIONAL PVOID  pvIgnored
    )
{
    NTSTATUS        Status = STATUS_SUCCESS;
    CFilter *       pFilter;

    ASSERT( pIrp);
    ASSERT( pKSMethod);

    // Obtain a "this" pointer for the method.
    //
    // Because this function is called directly from the property
    // dispatch table, must get pointer to the underlying object.
    //
    pFilter = FilterFromIRP( pIrp);
    ASSERT( pFilter);
    if (!pFilter)
    {
        Status = STATUS_INVALID_PARAMETER;
        goto errExit;
    }

    //  Reset any pending BDA topology changes.
    //
    Status = BdaStartChanges( pIrp);
    if (!NT_SUCCESS( Status))
    {
        goto errExit;
    }

    //  Reset any pending resource changes.
    //
    pFilter->m_NewTunerResource = pFilter->m_CurTunerResource;
    pFilter->m_BdaChangeState = BDA_CHANGES_COMPLETE;

errExit:
    return Status;
}


Accessing Frequency Properties of a BDA Node

A network provider uses the KSPROPSETID_BdaFrequencyFilter property set to control an RF tuner node in a BDA filter topology. For example, the network provider uses this property set to inform the tuner node how to tune the RF signal.

In the following code snippet, the controlling pin of the tuner node in the BDA minidriver intercepts and supplies methods for one property of the KSPROPSETID_BdaFrequencyFilter property set:

//
//  BDA RF Tune Frequency Filter
//
//  Defines the dispatch routines for the Frequency Filter Properties
//  on the RF Tuner Node
//
DEFINE_KSPROPERTY_TABLE(RFNodeFrequencyProperties)
{
    DEFINE_KSPROPERTY_ITEM_BDA_RF_TUNER_FREQUENCY(
        CAntennaPin::GetCenterFrequency,
        CAntennaPin::PutCenterFrequency
        ),
    DEFINE_KSPROPERTY_ITEM_BDA_RF_TUNER_POLARITY(
        NULL, NULL
        ),
    DEFINE_KSPROPERTY_ITEM_BDA_RF_TUNER_RANGE(
        NULL, NULL
        ),
    DEFINE_KSPROPERTY_ITEM_BDA_RF_TUNER_TRANSPONDER(
        NULL, NULL
        ),
};


BDA Tuner Driver

This sample is the source code for a Broadcast Driver Architecture (BDA) tuner driver. It is provided as an example of a BDA device minidriver for the AVStream class of kernel streaming. Use the BDA tuner driver with a Philips tuner card.


Building the BDA Tuner Driver Sample

To build the sample, open a DDK command window, change to the BDA directory, and use the build command. Before you can use the sample, you need to install the Philips tuner card.

To install the tuner card, shut down the computer, insert the tuner card, and boot. The operating system uses the Philtune.inf file to detect and install the tuner card.

After the tuner card is installed, the built sample, Philtune.sys, is in the %SystemRoot%\System32\Drivers directory of the operating system.

Building this sample produces one file: Philtune.sys. You can build both free and checked versions of this sample.


BDA Tuner Driver Tools

The BDA network provider filter uses the BDA tuner driver to configure a filter in a filter graph. This filter is used to tune and demodulate a digital signal. Other filters in the filter graph capture video frames and present the video on the display.


BDA Tuner Driver Resources

To get a logo for your device, consult the Windows Hardware Quality Labs Web site for information and test suites.

Your device should support Plug and Play (PnP). Download PnP specs from the Windows Driver and Hardware Development Web site.


BDA Tuner Driver Code Tour

The following table contains a file manifest for the sample:

File | Description
Antenna.cpp | Implements the class for the input Antenna pin
Ari.cpp | Implements the ARI-chip properties of the device class
Bdadebug.h | Contains macros that the driver uses for debugging
Bdaguid.c | Includes header files used for defining GUIDs
Bdatune.htm | The documentation for this sample (this file)
Common.h | Includes necessary header files, like Bdasup.h
DevCaps.cpp | Contains data specific to hardware
Device.cpp | Main code of BDA device, including driver-entry point
Filter.cpp | Implements methods of the filter class
FiltProp.cpp | Implements properties of the filter class
Gpio.cpp | Implements the GPIO class
Gpio.h | Defines GPIO class
I2Script.cpp | Implements the class for the Inter-IC (I2C) bus that is used to connect integrated circuits (ICs) on the card
I2Script.h | Defines structure for the I2C bus
Ksvsb.h | Defines constants and structures for VSB that are also used in user mode
Makefile | The makefile for the project; do not edit.
Medguid.h | Contains definitions of medium GUIDs
Mpoc.cpp | Implements the MPOC-chip properties of the device class
Mpoc.h | Defines constants and structures for MPOC chip
ObjDesc.cpp | Defines automation and dispatch tables and template structures
Philtune.h | Defines classes for filter, device, and filter I/O pins
Philtune.inf | Installation information for the sample
Philtune.rc | Version information resource
Sources | DDK build instructions
Trnsport.cpp | Implements the class for the output Transport pin
Tuneprop.cpp | Implements the tuner-chip properties of the device class
Tuner.cpp | Implements the tuner class -- Sets up the tuner node
Tuner.h | Defines tuner class
Tunerdef.h | Defines tuner constants and structures
Util.cpp | Implements supporting functions
Util.h | Defines supporting functions
Vsb.h | Defines constants and structures for VSB
Vsb1.cpp | Implements the VSBDemod1 class -- Sets the demodulator node
Vsb1.h | Defines the VSBDemod1 class
Vsb2.cpp | Implements the VSBDemod2 class -- Sets the demodulator node
Vsb2.h | Defines the VSBDemod2 class
Vsbbase.cpp | Implements the VSBDemod class -- Sets the demodulator node
Vsbbase.h | Defines the VSBDemod class
Vsbdef.h | Defines more constants and structures for VSB
Vsbprop.cpp | Implements the VSB properties of the device class
Wdmcommon.h | Defines constants and structures common to WDM
Wdmdebug.h | Contains macros for WDM debugging
Wdmdrv.h | Defines constants and structures for a WDM driver


BDA Tuner Driver Programming Tour

The ObjDesc.cpp file contains definitions and templates that the network provider filter uses to determine topology, to configure and change a filter instance, and to manipulate tuner and demodultor nodes. The BDA tuner driver registers these definitions and templates with the BDA support library so the library can handle most aspects of these operations. Other files of this sample define constants, structures, and classes and implement methods for those classes.


Kernel Streaming Enumeration and Structures


BUS_INTERFACE_REFERENCE

A software device enumerator (swenum) exports this interface to allow drivers to reference count PDOs such that the device will remain active while in use and be unloaded when not in use.

typedef struct {
    //
    // Standard interface header
    //

    INTERFACE                   Interface;

    //
    // Standard bus interfaces
    //

    PFNREFERENCEDEVICEOBJECT    ReferenceDeviceObject;
    PFNDEREFERENCEDEVICEOBJECT  DereferenceDeviceObject;
    PFNQUERYREFERENCESTRING     QueryReferenceString;

} BUS_INTERFACE_REFERENCE, *PBUS_INTERFACE_REFERENCE;

Members

Interface
ReferenceDeviceObject
Increments the reference count for the given PDO. This assures that the device object will remain active and enumerated until the reference count returns to 0.
DereferenceDeviceObject
Decrements the reference count of the PDO. When the PDO's reference count is 0, it becomes eligible for removal. Note that this condition does not guarantee removal.
QueryReferenceString
Creates a buffer from the paged pool and copies the reference string associated with the PDO into this buffer. The caller is expected to free the buffer using ExFreePool.


KS_COMPRESSION

Defines the compression of frames on an output pin.

typedef struct {
    ULONG RatioNumerator;
    ULONG RatioDenominator;
    ULONG RatioConstantMargin;
} KS_COMPRESSION, *PKS_COMPRESSION;

Members

RatioNumerator
Numerator of the compression/expansion ratio.
RatioDenominator
Denominator of the compression/expansion ratio.
RatioConstantMargin

Comments

For compression, specify a fraction less than 1. For instance, a compressor might specify 1:3. For decompression, specify a fraction greater than 1. A decompressor, for instance, might specify 3:1.


KS_FRAMING_ITEM

This structure is one of the new objects used to declare allocator requirements on a kernel mode pin. Each KSALLOCATOR_FRAMING_EX contains one or more framing items.

typedef struct {
    GUID MemoryType;
    GUID BusType;
    ULONG MemoryFlags;
    ULONG BusFlags;
    ULONG Flags;
    ULONG Frames;
    ULONG FileAlignment;
    ULONG MemoryTypeWeight;
    KS_FRAMING_RANGE PhysicalRange;
    KS_FRAMING_RANGE_WEIGHTED FramingRange;
} KS_FRAMING_ITEM, *PKS_FRAMING_ITEM;

Members

MemoryType
The type of memory used for buffers/data frames. There is a partial correspondance between this field and the field PoolType in KSALLOCATOR_FRAMING. The two fields differ in that PoolType allowed only paged/non-paged. MemoryType can be any of the following:
KSMEMORY_TYPE_WILDCARD / KSMEMORY_TYPE_DONT_CARE / KSTYPE_DONT_CARE -
Can handle any type of memory
KSMEMORY_TYPE_SYSTEM -
KSMEMORY_TYPE_USER -
KSMEMORY_TYPE_KERNEL_PAGED -
Buffers must be kernel paged memory. This corresponds to KSALLOCATOR_FRAMING.PoolType ==PagedPool and RequirementsFlags having SYSTEM_MEMORY set.
KSMEMORY_TYPE_KERNEL_NONPAGED -
Buffers must be kernel nonpaged memory. This would correspond to KSALLOCATOR_FRAMING.PoolType == NonPagedPool and RequirementsFlags having SYSTEM_MEMORY set.
KSMEMORY_TYPE_DEVICE_UNKNOWN
BusType
MemoryFlags
BusFlags
Flags
Similar to the options flags and requirements flags found in KSALLOCATOR_FRAMING..
Frames
Total number of allowable outstanding frames. Corresponds to KSALLOCATOR_FRAMING.Frames.
FileAlignment
Requirement for frame alignment. Corresponds to KSALLOCATOR_FRAMING.FileAlignment.
MemoryTypeWeight
This memory type weight pin-wide.
PhysicalRange
Specifies the physical limit of frame sizes.
FramingRange
Specifies the optimal range of frame sizes.

Comments

Each KSALLOCATOR_FRAMING_EX instance contains one or more framing items.

See Also

KSALLOCATOR_FRAMING_EX , KS_FRAMING_RANGE , KS_FRAMING_RANGE_WEIGHTED , KS_COMPRESSION


KS_FRAMING_RANGE

Specifies a range for frame sizes for a given framing item.

typedef struct {
    ULONG MinFrameSize;
    ULONG MaxFrameSize;
    ULONG Stepping;
} KS_FRAMING_RANGE, *PKS_FRAMING_RANGE;

Members

MinFrameSize
Minimum frame size.
MaxFrameSize
Maximum frame size.
Stepping

Comments

Frames can be size k where

k = MinFrameSize + Stepping * Z,. where MinFrameSize <= k <= MaxFrameSize


KS_FRAMING_RANGE_WEIGHTED

Specifies a weighted framing range.

typedef struct {
    KS_FRAMING_RANGE Range;
    ULONG InPlaceWeight;
    ULONG NotInPlaceWeight;
} KS_FRAMING_RANGE_WEIGHTED, *PKS_FRAMING_RANGE_WEIGHTED;

Members

Range
The framing range.
InPlaceWeight
Maximum frame size.
NotInPlaceWeight


KSALLOCATOR_FRAMING

The KSALLOCATOR_FRAMING structure is used to query framing requirements and submit requests of a filter. Use it to submit an allocator creation request to a handle of a sink via IRP_MJ_CREATE.

typedef struct {
    union {
        ULONG    OptionsFlags;
        ULONG    RequirementsFlags;
    };
    POOL_TYPE   PoolType;
    ULONG        Frames;
    ULONG        FrameSize;
    ULONG        FileAlignment;
    ULONG        Reserved;
} KSALLOCATOR_FRAMING, *PKSALLOCATOR_FRAMING;

Members

OptionsFlags
Specifies the allocator option flags specified during allocator creation for the connection point. For a description of the flags, see the Comments section.
RequirementsFlags
Specifies the allocator requirements specified during the query of the connection point. For a description of the flags, see the Comments section.
PoolType
Allocation pool type for kernel mode only. See POOL_TYPE for pool type identifier details.
Frames
Specifies the total number of allowable outstanding frames. Zero indicates that the filter has no requirement for this member.
FrameSize
Specifies the total size of the frame including prefix and postfix. Zero indicates that the filter has no requirement for this member.
FileAlignment
Specifies the alignment allocation specification. The minimum allocation alignment is FILE_QUAD_ALIGNMENT. Allocators must always align on at least quad boundaries.
Reserved
Reserved for system use. Set to zero.

Comments

The RequirementsFlags member can contain the following values.

Flag Value | Description
KSALLOCATOR_REQUIREMENTF_ INPLACE_MODIFIER | Indicates that the connection point can perform an in-place modification.
KSALLOCATOR_REQUIREMENTF_ SYSTEM_MEMORY | Indicates that the connection point requires system memory for allocations. If this option is not set, it is assumed that the sink provides a system address space mapping to on-board RAM or other forms of storage on the device.
KSALLOCATOR_REQUIREMENTF_ FRAME_INTEGRITY | Indicates that the connection point requires that downstream filters maintain the data integrity of specified frames.
KSALLOCATOR_REQUIREMENTF_ MUST_ALLOCATE | Indicates that the connection point requires that it allocate any frames sent.
KSALLOCATOR_REQUIREMENTF_ PREFERENCES_ONLY | Indicates that the Requirements flags are preferences only and the connection point is able to allocate frames that do not meet those specifications.

The OptionsFlags member can contain the following values.

OptionsFlags | Description
KSALLOCATOR_OPTIONF_ COMPATIBLE | Indicates that the framing options of the allocator being created are compatible with the downstream allocator. This option is typically specified when an in-place modifier is assigned an allocator for copy buffers. If the filter is not required to modify a given frame, it may submit the frame to the downstream filter without allocating an additional frame from the downstream allocator, when this option is specified.
KSALLOCATOR_OPTIONF_ SYSTEM_MEMORY | Indicates the use of system memory for allocations. When specified, the allocator must allocate memory from the pool as specified in the PoolType member. Otherwise, it is assumed that the sink provides a system address mapping to on-board RAM or other forms of storage on the device.

See Also

KsCreateAllocator


KSALLOCATOR_FRAMING_EX

The KSALLOCATOR_FRAMING_EX structure is used to query framing requirements and submit requests of a filter.

typedef struct {
    ULONG CountItems;
    ULONG PinFlags;
    KS_COMPRESSION OutputCompression;
    ULONG PinWeight;
    KS_FRAMING_ITEM     FramingItem[1];
} KSALLOCATOR_FRAMING_EX, *PKSALLOCATOR_FRAMING_EX;

Members

CountItems
The number of framing items that are present in the extended allocator framing structure. Count of items in KSALLOCATOR_FRAMING_EX.FramingItem.
PinFlags
Reserved, set to zero.
OutputCompression
Defines the frame ratio for transforms that change the size of a frame. For instance, a decompressor might specify 3 to 1 and a compressor might specify 1 to 3. May be used to allow in-place compression and expansion of frames through pins with different framing requirements.
PinWeight
This pin's framing weight graph-wide. Reserved, set to zero.
FramingItem
The actual framing item(s).

Comments

KSALLOCATOR_FRAMING_EX is a replacement for KSALLOCATOR_FRAMING. AVStream provides support for this extended allocator framing structure, but does not support KSALLOCATOR_FRAMING. When using AVStream, use KSALLOCATOR_FRAMING_EX to define allocator requirements on a pin in a kernel level filter.

A minidriver can also use DECLARE_SIMPLE_FRAMING_EX to declare an extended framing structure in line with the original structure. This macro is defined in ks.h:

#define DECLARE_SIMPLE_FRAMING_EX(FramingExName, MemoryType, Flags, Frames, Alignment, MinFrameSize, MaxFrameSize) const KSALLOCATOR_FRAMING_EX FramingExName

DECLARE_SIMPLE_FRAMING_EX declares a KSALLOCATOR_FRAMING_EX structure called FramingExName with the specified memory type (often either STATIC_KS_TYPE_DONT_CARE or one of the kernel paged or non paged GUIDs). The Frames and Alignment fields correspond to the KSALLOCATOR_FRAMING. MinFrameSize and MaxFrameSize ensure that frames are within a specific size range. Flags corresponds to the old OptionsFlags and RequirementsFlags in KSALLOCATOR_FRAMING.

See Also

KS_FRAMING_ITEM , KSALLOCATOR_FRAMING , KS_COMPRESSION , KS_FRAMING_RANGE , KS_FRAMING_RANGE_WEIGHTED


KSATTRIBUTE

KSATTRIBUTE defines an additional attribute of a data range or data format that is not covered by the KSDATARANGE/KSDATAFORMAT structures or the extended information based on the range/format specifier.

typedef struct {
    ULONG Size;
    ULONG Flags;
    GUID Attribute;
} KSATTRIBUTE, *PKSATTRIBUTE;

Members

Size
The size of the attribute. This will be at least the size of the KSATTRIBUTE structure and may be more if there exists extended information based on the identifying GUID in the Attribute field.
Flags
The flags of the attribute. The only used flag is KSATTRIBUTE_REQUIRED; this flag specifies that an attribute is required. If this flag is not set, the attribute is optional. Note that the topmost bit is reserved for internal use in KS.
Attribute
A unique identifier identifying the attribute.

Comments

Please note that KSATTRIBUTE is used in conjunction with data ranges and data formats; attributes on data ranges and formats are taken into consideration when determining if a data range intersects with another data range or whether a data format is acceptable to a given pin.

See Also

KSDATARANGE,

KSDATAFORMAT


KSBUFFER_ITEM

The KSBUFFER_ITEM is used to store a list of data buffers copied from the event source, which can be retrieved by the event sink through KSEVENT_TYPE_QUERYBUFFER. It extends the normal DPC structure, which may be needed for event generation, but does not use the structure itself.

typedef struct {
    KSDPC_ITEM          DpcItem;
    LIST_ENTRY          BufferList;
} KSBUFFER_ITEM, *PKSBUFFER_ITEM;

Members

DpcItem
Contains the DPC item structure, which may be used by internal DPC’s, but is not used for data buffering.
BufferList

The head of a list of pool allocated buffers that are created by calls to KsGenerateDataEvent for events that have buffering enabled.


KSCLOCK_CREATE

Used in clock create parameters for KsCreateClock function.

typedef struct {
    ULONG       CreateFlags;
} KSCLOCK_CREATE, *PKSCLOCK_CREATE;

Members

CreateFlags
Currently consists of a flags item, which must be set to zero.


KSCLOCK_FUNCTIONTABLE

The KSPROPERTY_CLOCK_FUNCTIONTABLE property fills in a KSCLOCK_FUNCTIONTABLE structure with function pointers that are valid until the file object for the clock is released.

typedef struct {
    PFNKSCLOCK_GETTIME GetTime;
    PFNKSCLOCK_GETTIME GetPhysicalTime;
    PFNKSCLOCK_CORRELATEDTIME GetCorrelatedTime;
    PFNKSCLOCK_CORRELATEDTIME GetCorrelatedPhysicalTime;
} KSCLOCK_FUNCTIONTABLE, *PKSCLOCK_FUNCTIONTABLE;

Members

GetTime
This entry point is used to retrieve the current clock time.
GetPhysicalTime
This entry point is used to retrieve the current underlying physical time.
GetCorrelatedTime
This entry point is used to retrieve the current clock time and a correlated system time as an atomic operation.
GetCorrelatedPhysicalTime
This entry point is used to retrieve the current physical time and a correlated system time as an atomic operation.


KSCOMPONENT_ID

A client may query the KSPROPERTY_GENERAL_COMPONENTID property to retrieve the component information within the provided KSCOMPONENT_ID structure.

typedef struct {
    GUID Manufacturer;
    GUID Product;
    GUID Component;
    GUID Name;
    ULONG Version;
    ULONG Revision;
} KSCOMPONENTID, *PKSCOMPONENTID;

Members

Manufacturer
Contains the unique identifier for the manufacturer of the component. This is generated by the manufacturer, and may be resolved to a localized string representation through a registry entry.
Product
Contains the unique identifier for the product to which the component belongs. This is generated by the manufacturer, and may be resolved to a localized string representation through a registry entry.
Component
Contains the unique identifier for the component. This is generated by the manufacturer, and may be resolved to a localized string representation through a registry entry.
Name

Optionally contains the unique identifier for the name, which may be different than the Component entry, or this may be GUID_NULL. This is generated by the manufacturer, and may be resolved to a localized string representation through a registry entry.

Version
Contains the version number for the component or product.
Revision
Contains the revision number for the component or product.


KSCORRELATED_TIME

The KSPROPERTY_CLOCK_CORRELATEDTIME property is passed a KSCORRELATED_TIME structure, which is filled in with the current time and system time.

typedef struct {
    LONGLONG    Time;
    LONGLONG    SystemTime;
} KSCORRELATED_TIME, *PKSCORRELATED_TIME;

Members

Time
Contains the current clock time in 100-nanosecond units.
SystemTime
Contains the correlated system time in 100-nanosecond units.

Comments

The system time is acquired from KeQueryPerformanceCounter. Note that the performance counter is not suspended when the machine is suspended, so that correlations will change when the machine goes through a suspend.


KSDATAFORMAT

The KSDATAFORMAT structure is a variable-length structure that describes a data format.

typedef struct {
    ULONG FormatSize;
    ULONG Flags;
    ULONG SampleSize;
    ULONG Reserved;
    GUID MajorFormat;
    GUID SubFormat
    GUID Specifier;
} KSDATAFORMAT;

Members

FormatSize
Size in bytes of this structure. This must be at least sizeof(KSDATAFORMAT), but may be larger for specific settings of MajorFormat, SubFormat, and Specifier.
Flags
Normally set to zero.
SampleSize
The sample size of the data, for fixed sample sizes, or zero if the format has a variable sample size.
Reserved
Reserved for system use. Drivers must set this to zero.
MajorFormat
Specifies general format type. The currently supported data formats may be found in as the KSDATAFORMAT_TYPE_XXX symbolic constants in the ksmedia.h header that comes with the DDK documentation. A data stream that has no particular format should use KSDATAFORMAT_TYPE_STREAM (defined in ks.h) as its MajorFormat.
SubFormat
Specifies the subformat of a general format type. The currently supported data formats may be found in the KSDATAFORMAT_SUBTYPE_XXX symbolic constants in the ksmedia.h header that comes with the DDK documentation. Major formats that do not support subformats should use KSDATAFORMAT_SUBTYPE_NONE for this member.
Specifier
Specifies additional data format type information for a specific setting of MajorFormat and Subformat. The significance of this field is determined by the major format (and subformat, if the major format supports subformats). For example, Specifier may represent a particular encoding of a subformat, or it may be used to specify what type of data structure follows KSDATAFORMAT in memory.

The following specifiers (defined in ks.h) are of general use:

KSDATAFORMAT_SPECIFIER_NONE
Stands for no specifier. Used for formats that do not support specifiers.
KSDATAFORMAT_SPECIFIER_FILENAME
Indicates that a zero-terminated Unicode string immediately follows the KSDATAFORMAT structure in memory.
KSDATAFORMAT_SPECIFIER_FILEHANDLE
Indicates that a file handle immediately follows KSDATAFORMAT in memory.

Comments

At the minimum, a data format is specified by the MajorFormat, SubFormat, and Specifier members. A family of similar data formats may share the same values for MajorFormat, SubFormat, and Specifier. In that case, the specific data format is distinguished by additional data that follows the Specifier member in memory.

Technology-specific data formats are detailed within that technology area's documentation.


KSDATARANGE

The KSDATARANGE structure is a variable-length structure that describes a range of data formats.

typedef struct {
    ULONG FormatSize;
    ULONG Flags;
    ULONG SampleSize;
    ULONG Reserved;
    GUID MajorFormat;
    GUID SubFormat
    GUID Specifier;
} KSDATARANGE;

Members

FormatSize
Size in bytes of this structure. This must be at least sizeof(KSDATARANGE), but may be larger for specific settings of MajorFormat, SubFormat, and Specifier.
Flags
This field is ignored.
SampleSize
This field is ignored.
Reserved
Reserved. Drivers must set this to zero.
MajorFormat
Either the specific major format of a data format that this data range matches, or KSDATAFORMAT_TYPE_WILDCARD if this data range matches all major formats. When MajorFormat has this value, both SubFormat and Specifier must also take on their wild card values.
SubFormat
Either the specific subformat of a data format that this data range matches, or KSDATAFORMAT_SUBTYPE_WILDCARD if this data range matches all subformats. (In this instance, the specifier is not required to be its wild card value, unless MajorFormat is KSDATAFORMAT_TYPE_WILDCARD.)
Specifier
Either the specifier of the data format that this data range matches, or KSDATAFORMAT_SPECIFIER_WILDCARD if this data range matches all specifier values.

Comments

Drivers use data ranges to describe the ranges of data formats they support.


KSDEGRADE

The KSDEGRADE identifier is defined in the ks.h header file:

typedef KSIDENTIFIER KSDEGRADE, *PKSDEGRADE;

See Also

KSDEGRADE_STANDARD , Quality Management


KSDEGRADE_STANDARD

The KSDEGRADE_STANDARD enumeration lists different types of degradation.

typedef enum {
    KSDEGRADE_STANDARD_SAMPLE,
    KSDEGRADE_STANDARD_QUALITY,
    KSDEGRADE_STANDARD_COMPUTATION,
    KSDEGRADE_STANDARD_SKIP
} KSDEGRADE_STANDARD;

Elements

KSDEGRADE_STANDARD_SAMPLE
Sample degradation.
KSDEGRADE_STANDARD_QUALITY
Quality degradation.
KSDEGRADE_STANDARD_COMPUTATION
Computation degradation.
KSDEGRADE_STANDARD_SKIP
Skip ahead a specified delta in the data stream.

See Also

KSDEGRADE , Quality Management


KSDISPATCH_TABLE

The KSDISPATCH_TABLE structure is used for dispatching IRP’s to various types of objects contained under a single DRIVER_OBJECT. A pointer to a dispatch table is contained in the opaque object header that is the first element of data pointed to by an FsContext within a file object.

typedef struct {
    PDRIVER_DISPATCH        DeviceIoControl;
    PDRIVER_DISPATCH        Read;
    PDRIVER_DISPATCH        Write;
    PDRIVER_DISPATCH        Flush;
    PDRIVER_DISPATCH        Close;
    PDRIVER_DISPATCH        QuerySecurity;
    PDRIVER_DISPATCH        SetSecurity;
    PFAST_IO_DEVICE_CONTROL FastDeviceIoControl;
    PFAST_IO_READ           FastRead;
    PFAST_IO_WRITE          FastWrite;
} KSDISPATCH_TABLE, *PKSDISPATCH_TABLE;

Members

DeviceIoControl
The Device I/O Control handler.
Read
The Read handler.
Write
The Write handler.
Flush
The Flush handler.
Close
The Close handler.
QuerySecurity
The Query Security handler.
SetSecurity
The Set Security handler.
FastDeviceIoControl
The fast Device I/O Control handler.
FastRead
The fast Read handler.
FastWrite
The fast Write handler.


KSDPC_ITEM

The KSDPC_ITEM is used to store information related to any internal DPC’s that might be used to generate event notification from a raised IRQL level. It uses a reference counting scheme to determine when to free the structure.

typedef struct {
    KDPC            Dpc;
    ULONG           ReferenceCount;
    KSPIN_LOCK      AccessLock;
} KSDPC_ITEM, *PKSDPC_ITEM;

Members

Dpc
Contains the DPC structure that is queued to perform notifications that cannot occur at raised IRQL.
ReferenceCount
Specifies whether or not pending DPC’s will be referencing this structure. This is initially set to 1 when the event structure is created, and decremented when destroyed. If the reference count is non-zero at that time, then the last DPC to run will free the structure rather than the event disable call.
AccessLock
This lock is used to synchronize deletion of an event item with any DPC that might be running.


KSE_NODE

Just as KSP_NODE is used for properties on a node, KSE_NODE is used for events on a node.

typedef struct {
    KSEVENT Event;
    ULONG NodeId;
    ULONG Reserved;
} KSE_NODE;

Members

Event
Specifies the event.
NodeId
Specifies the node ID.
Reserved
Reserved for system use. Should be set to zero.


KSERROR

The Error structure is used to report Streaming errors in both kernel and user mode to their respective Quality Managers.

typedef struct {
    PVOID       Context;
    ULONG       Status;
} KSERROR, *PKSERROR;

Members

Context
Contains a context parameter that was originally passed to the connection.
Status
Contains the NTSTATUS error.

Comments

Streaming error notifications can be generated against the Quality Management sink, if assigned. The same method of proxying Quality Management complaints is used for forwarding Error reports for DirectShow graphs.


KSEVENT

The KSEVENT structure describes the event and request type of a event request.

typedef struct {
    GUID Set;
    ULONG Id;
    ULONG Flags;
} KSEVENT;

typedef KSIDENTIFIER KSEVENT;

Members

Set
A GUID identifying this event set.
Id
Specifies the member of the event set.
Flags
Specifies the request type. Should be one of:
Value | Type of event request
KSEVENT_TYPE_ENABLE | Enable event notification for this event type. The driver continues event notification until the client explicitly disables it.
KSEVENT_TYPE_ONESHOT | Enable event notification for the next occurrence of this event, only. The client does not need to (and should not) disable the event once it has occurred.
KSEVENT_TYPE_SETSUPPORT | Queries for the list of event sets, or support of a particular event set.
KSEVENT_TYPE_BASICSUPPORT | Queries for support of a particular event type.
KSEVENT_TYPE_ENABLEBUFFERED | Enable buffered event notifications. The driver buffers each notification without signaling the client. The client then uses KSEVENT_TYPE_QUERYBUFFER to retrieve buffered events.
KSEVENT_TYPE_TOPOLOGY | Event passed is of type KSE_NODE, where NodeId indicates the numeric id of the topology node. Do not set this flag on its own; instead, OR it with other flags from this list.
KSEVENT_TYPE_QUERYBUFFER | Retrieve the next buffered event notification.

Comments

The KSEVENT, KSMETHOD, and KSPROPERTY structures are aliases for the KSIDENTIFIER structure. As such, their definitions are identical.


KSEVENTDATA

The KSEVENTDATA structure specifies the method by which a driver notifies a client when an event occurs.

Comments

Drivers should treat this as an opaque data structure.


KSEVENT_ENTRY

The kernel streaming subsystem uses the KSEVENT_ENTRY structure to describe how an event should be triggered.

Comments

Drivers should treat this as an opaque data structure.


KSEVENT_ITEM

Drivers can use the KSEVENT_ITEM structure to describe how they support an event within an event set.

typedef struct {
    ULONG               EventId;
    ULONG               DataInput;
    ULONG               ExtraEntryData;
    PFNKSADDEVENT       AddHandler;
    PFNKSREMOVEEVENT    RemoveHandler;
    PFNKSHANDLER        SupportHandler;
} KSEVENT_ITEM, *PKSEVENT_ITEM;

Members

EventId
The unique ID of the event within the event set.
DataInput
Specifies the size of event data. The event data begins with a KSEVENTDATA structure that describes how the client should be notified when the event occurs, optionally followed by any additional parameters that specify when the event occurs. Must be at least sizeof(KSEVENTDATA).
ExtraEntryData
Specifies the size of any additional memory that the system should allocate for each enable request for this event. The driver uses this memory to store any data it needs to keep track of the event request. The memory is allocated directly after the event enable request's KSEVENT_ENTRY structure.
AddHandler
Not used by the stream class driver. AVStream minidrivers may place a pointer to a handler here. Related details in Comments below.
RemoveHandler
Not used by the stream class driver. AVStream minidrivers may place a pointer to a handler here. Related details in Comments below.
SupportHandler
Not used by the stream class driver.

Comments

The following comments are for AVStream minidrivers only.

If an AVStream minidriver specifies AddHandler as non-NULL, note that the default behavior of adding the item to the object's event list is not performed by AVStream. Should the minidriver choose not to perform the default action, and instead specifies an AddHandler and does not add the event to the object's event list via KsDefaultAddEventHandler() or via a Ks*AddEvent() call, the minidriver is directly responsible for cleaning up the event.

A minidriver that specifies AddHandlers and RemoveHandlers and does not properly clean the events up can cause a resource (memory/handle) leak.

Alternatively, a minidriver can add to the default behavior by calling KsDefaultAddEventHandler or Ks*AddEvent in the AddHandler routine and then adding implementation-specific steps following this call. If this is the case, AVStream will still automatically perform cleanup duties upon receiving IOCTL_KS_DISABLE_EVENT or filter/pin closure as long as RemoveHandler is NULL. If RemoveHandler is non-NULL, the minidriver must clean up the event. If the event is on the object's event list (via a NULL AddHandler or via the AddHandler calling KsDefaultAddEventHandler()), then the RemoveHandler must do a RemoveEntryList:

&EventEntry -> ListEntry


KSEVENT_SET

The KSEVENT_SET structure describes the events that make up an event set.

typedef struct {
    const GUID *Set;
    ULONG EventsCount;
    const KSEVENT_ITEM *EventItem;
} KSEVENT_SET, *PKSEVENT_SET;

Members

Set
Pointer to the GUID that identifies the event set.
EventsCount
The number of events in the event set.
EventItem
Pointer to the beginning of the array of KSEVENT_ITEM structures that describe each event in the event set. The size of the array is in the EventsCount member.


KSFASTMETHOD_ITEM

Each method in a method set is described by a KSMETHOD_ITEM in an array of such items. This specifies the method, type of method, handler, and required size of parameters. The array elements may be placed in any arbitrary order. Arbitrary items may also have a associated KSFASTMETHOD_ITEM, which enables Fast I/O dispatching.

typedef struct {
    ULONG                   MethodId;
    union {
        PFNKSFASTHANDLER        MethodHandler;
        BOOLEAN                 MethodSupported;
    };
} KSFASTMETHOD_ITEM, *PKSFASTMETHOD_ITEM;

Members

MethodId
Contains the identifier of the method and the flags describing the type of method.
MethodHandler
Points to the fast handler for this method.
MethodSupported
Set to TRUE if the method is supported, otherwise set to FALSE.

See Also

KSMETHOD_ITEM


KSFRAMETIME

This property is supported by rendering pins, and is used to return the duration of the next “frame” of data, and flags associated with that frame.

typedef struct {
    LONGLONG    Duration;
    ULONG       FrameFlags;
    ULONG       Reserved;
} KSFRAMETIME, *PKSFRAMETIME;

Members

Duration
The duration in presentation time units.
FrameFlags
Flags specific to the next frame, or to all frames. These are described in the following table.
Reserved
Set to zero.

Comments

Note that this is an optional property, which need only be implemented if the pin instance understands the specifics of the media type it is transporting.

DeviceIoControl(
    DeviceHandle,
    IOCTL_KS_PROPERTY,
    &Property,
    sizeof(KSPROPERTY),
    &Extent,
    sizeof(KSFRAMETIME),
    &BytesReturned,
    &Overlapped);

define KSFRAMETIME_VARIABLESIZE    0x00000001


KSIDENTIFIER

The KSIDENTIFIER structure uses a GUID to uniquely identify a set, and a set-specific ID to refer to a member within that set.

typedef struct {
    GUID Set;
    ULONG Id;
    ULONG Flags;
} KSIDENTIFIER;

typedef KSIDENTIFIER KSEVENT;

Members

Set
Contains the globally unique set identifier.
Id
Contains the set-specific identifier for an item within the set.
Flags
Used for various set types, such as Properties and Methods. Zero when not used.

Comments

The KSEVENT, KSMETHOD, and KSPROPERTY structures are aliases for the KSIDENTIFIER structure. As such, their definitions are identical.

The use of an ID within the set allows one to perform a single large compare for a set identifier, then smaller quick compares (for example, by using a switch statement for identifiers within a set). For instance, a property set is referred to by a unique GUID identifier, and properties within that set are referred to by the short ID.

Method, event, interface, and medium sets can be thought of as “classes” of sets.


KSINTERVAL

Specifies a base time and time interval for recurring events.

typedef struct {
    LONGLONG TimeBase;
    LONGLONG Interval;

Members

} KSINTERVAL, *PKSINTERVAL;
TimeBase
64-bit time base.
Interval
Recurrence interval, also 64-bit.

See Also

KSEVENT_CLOCK_INTERVAL_MARK , KSEVENT_CLOCK_POSITION_MARK.


KSM_NODE

.Just as KSP_NODE is used for properties on a node, KSM_NODE is used for methods on a node

typedef struct {
    KSMETHOD Method;
    ULONG NodeId;
    ULONG Reserved;
} KSM_NODE;

Members

Method
Specifies the method.
NodeId
Specifies the node ID.
Reserved
Reserved for system use. Should be set to zero.


KSMETHOD

The KSMETHOD structure describes the method and request type of a method request.

typedef struct {
    GUID Set;
    ULONG Id;
    ULONG Flags;
} KSIDENTIFIER;

typedef KSIDENTIFIER KSMETHOD;

Members

Set
A GUID identifying this method set.
Id
Specifies the member of the method set.
Flags
Specifies the request type. This should be one of the following values:
Value | Type of method request
KSMETHOD_TYPE_NONE | Used by the filter in a method description to indicate that the second buffer is not expected to be used. For buffered methods although space is allocated, no data is copied to or from the system buffer. When in source mode (KSMETHOD_TYPE_SOURCE), no MDL is created.
KSMETHOD_TYPE_READ | Used by the filter in a method description to indicate that parameters are expected to be read from the second buffer. When buffered, data is copied to the system buffer. When in source mode, the data is probed and locked for IoReadAccess.
KSMETHOD_TYPE_WRITE | Used by the filter in a method description to indicate that parameters are expected to be written to the second buffer. When buffered, data is copied from the system buffer. When in source mode, the data is probed and locked for IoWriteAccess.
KSMETHOD_TYPE_MODIFY | Used by the filter in a method description to indicate that parameters are expected to be read and written to the second buffer. The data passed in is overwritten by the data returned. This might imply that a structure passed in could be merely updated. When buffered, the data is copied to the system buffer, and copied back when the IRP is completed. When in source mode, the data is probed and locked for IoModifyAccess.
KSMETHOD_TYPE_SOURCE | Used by the filter in a method description to Indicate the method is to be processed in source mode. An MDL is allocated and the data is probed and locked.
KSMETHOD_TYPE_SEND | Passed by the client in the KSMETHOD.Flags structure element to indicate that the specified method should be executed. The effect of the method on the given parameters must be known to the client. That is, whether the parameters are read from, written to, both, or neither.
KSMETHOD_TYPE_SETSUPPORT | Query the driver to determine if it supports this method set.
KSMETHOD_TYPE_TOPOLOGY | Method passed is of type KSM_NODE, where NodeId indicates the numeric id of the topology node. Do not set this flag on its own; instead, OR it with other flags from this list.
KSMETHOD_TYPE_BASICSUPPORT | Query the driver to determine if this member of the method set is supported.

Comments

The KSEVENT, KSMETHOD, and KSPROPERTY structures are aliases for the KSIDENTIFIER structure. As such, their definitions are identical.


KSMETHOD_ITEM

The KSMETHOD_ITEM structure describes a single method within a method set.

typedef struct {
    ULONG MethodId;
    PFNKSHANDER MethodHandler;
    ULONG MinMethod;
    ULONG MinData;
    PFNKSHANDLER SupportHandler;
    ULONG Flags;
} KSMETHOD_ITEM;

Members

MethodId
Specifies the identifier of this method within its method set.
MethodHandler
Reserved for system use. Do not use.
MinMethod
Specifies the minimum size of buffer need to specify the method completely. This is at least sizeof(KSMETHOD) bytes in size.
MinData
Specifies the minimum size of buffer needed to specify the method data buffer.
SupportHandler
Reserved for system use. Do not use.
Flags

See Also

KSFASTMETHOD_ITEM


KSMETHOD_SET

The KSMETHOD_SET structure is used by drivers to describe a method set.

typedef struct {
    const GUID* Set;
    ULONG MethodsCount;
    PKSMETHOD_ITEM MethodItem;
    ULONG FastIoCount;
    PKSFASTMETHOD_ITEM FastIoTable;
} KSMETHOD_SET;

Members

Set
Specifies the GUID
MethodsCount
Specifies the number of methods in this method set.
MethodItem
Pointer to an array of KSMETHOD_ITEM structures. Each structure describes one method of the method set.
FastIoCount
Reserved for system use. Do not use.
FastIoTable
Reserved for system use. Do not use.


KSMULTIPLE_ITEM

The KSMULTIPLE_ITEM structure is a generic header for property data that can contain multiple entries.

typedef struct {
    ULONG Size;
    ULONG Count;
} KSMULTIPLE_ITEM;

Members

Size
The size in bytes of this header and the items following.
Count
The number of items following.


KSNODE_CREATE

The KSNODE_CREATE structure describes the set of information used to create the node handle.

typedef struct {
    ULONG CreateFlags;
    ULONG Node;
} KSNODE_CREATE, *PKSNODE_CREATE;

Members

CreateFlags
Set to zero.
Node
Indicates what node a handle should be created for. This refers to the node identifiers returned when querying topology information. A node identifier of –1 may be used to refer to the collection of nodes as a whole, if the filter supports it.


KSOBJECT_CREATE_ITEM

The Object Create Item is used to look up the string passed to a create request. A pointer to the create item structure containing the matching string is placed in KSCREATE_ITEM_IRP_STORAGE(Irp) before calling the associated create function.

typedef struct {
    PDRIVER_DISPATCH        Create;
    PVOID                   Context;
    UNICODE_STRING          ObjectClass;
    PSECURITY_DESCRIPTOR    SecurityDescriptor;
    ULONG                   Flags;
} KSOBJECT_CREATE_ITEM, *PKSOBJECT_CREATE_ITEM;

Members

Create
Contains the create dispatch function for this particular base object class.
Context
This value can be used to store object type-specific context information. Since a pointer to the create item structure is contained in KSCREATE_ITEM_IRP_STORAGE(Irp) before calling the specific create routine, this can be retrieved during creation of a new object.
ObjectClass
Points to a Unicode string that identifies the object class. This is the string that was used to register with PnP for a particular class of object supported by this device.
SecurityDescriptor
Optionally contains a security descriptor for this type of object, else it is NULL. If security is used, this must be freed when the object type is no longer used. This must use pool memory, and cannot be shared, as it may be replaced. If this is modified, the Flags element is updated.
Flags

Specifies the request type. Flags as described below

Value | Type of method request
KSCREATE_ITEM_SECURITYCHANGED | Indicates that the security descriptor on this object type has been changed and should be persisted.
KSCREATE_ITEM_WILDCARD | Indicates that this create item represents a wildcard that will be used for any create requests that do not match any other create items. The ordering of the wildcard entry in the list of create items is irrelevant. Only a single wildcard entry is valid on any list of create items.
KSCREATE_ITEM_NOPARAMETERS | Indicates that this create item does not allow any parameters to be passed, and will fail if any are found. Normally, create parameters are passed on to the create handler. This cannot be used with a wildcard flag.


KSOBJECT_CREATE

This structure contains an array of create handlers for base object classes supported by this device object.

typedef struct {
    ULONG                    CreateItemsCount;
    PKSOBJECT_CREATE_ITEM    CreateItemsList;
} KSOBJECT_CREATE, *PKSOBJECT_CREATE;

Members

CreateItemsCount
Contains the number of items in the following table.
CreateItemsList
Points to an array of create handlers for base object classes supported by this device object.


KSP_NODE

Kernel streaming clients use the KSP_NODE structure to specify the property and node type within a KSPROPERTY_TOPOLOGY_NAME property request.

typedef struct {
    KSPROPERTY Property;
    ULONG NodeId;
    ULONG Reserved;
} KSP_NODE;

Members

Property
Specifies the property.
NodeId
Specifies the node ID.
Reserved
Reserved for system use. Should be set to zero.


KSP_PIN

Kernel streaming clients use the KSP_PIN structure to specify the property and pin type within a KSPROPSETID_Pin property request.

typedef struct {
    KSPROPERTY Property;
    ULONG PinId;
    ULONG Reserved;
} KSP_PIN;

Members

Property
Specifies the property.
PinId
Specifies the pin type ID.
Reserved
Reserved. Should be set to zero.


KSP_TIMEFORMAT

This structure corresponds to KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT. The fields of the structure correspond one to one with DirectShow's IMediaSeeking::ConvertTimeFormat.

typedef struct {
    KSPROPERTY Property;
    GUID SourceFormat;
    GUID TargetFormat;
    LONGLONG Time;
} KSP_TIMEFORMAT, *PKSP_TIMEFORMAT;

Members

Property
Specifies the property.
SourceFormat
TargetFormat
Time


KSPIN_CONNECT

Clients use the KSPIN_CONNECT structure to describe the connection they request from a driver in a KsCreatePin call.

typedef struct {
    KSPIN_INTERFACE Interface;
    KSPIN_MEDIUM Medium;
    ULONG PinId;
    HANDLE PinToHandle;
    KSPRIORITY Priority;
} KSPIN_CONNECT;

Members

Interface
Specifies the interface to use for this connection.
Medium
Specifies the medium to use for this connection.
PinId
Specifies the pin type ID number. If the PinToHandle field is not NULL, this field contains the identifier of the source pin to which the request is being sent. Otherwise this field refers to the sink pin that is being connected to. If a pin can support being both a source and sink in communications, then this is the implicit method of telling it how it should act in the connection.
PinToHandle
NULL when a client requests a connection to itself. Otherwise, the target of the connection request. This field is used to indicate both what type of destination pin the create is intended for, and in the case of a source destination, what pin to connect to. In the case of a source destination, this contains the handle of the pin instance to establish a connection to. In the case of a sink destination, this field contains NULL, and is not otherwise used.
Priority
Specifies the priority for the connection. Usually KSPRIORITY_NORMAL. See the KSPROPERTY_CONNECTION_PRIORITY property for details.

Comments

If the KSPIN_CONNECT.PinToHandle element is not NULL, IRP_MJ_CREATE instructs the device to connect the source KSPIN_CONNECT.PinId pin to the KSPIN_CONNECT.PinToHandle pin instance. Otherwise, this is a request from a client for connection to the KSPIN_CONNECT.PinId pin using the KSPIN_CONNECT.Medium method and a specific data format specified after the connection structure. In either case, the device driver may fail this request if this connection cannot be accepted.


KSPIN_DESCRIPTOR

The KSPIN_DESCRIPTOR structure describes the basic KSPROPSETID_Pin properties of a pin type.

typedef struct {
    ULONG InterfacesCount;
    const KSPIN_INTERFACE* Interfaces;
    ULONG MediumsCount;
    const KSPIN_MEDIUM *Mediums;
    ULONG DataRangesCount;
    const PKSDATARANGE* DataRanges;
    KSPIN_DATAFLOW DataFlow;
    KSPIN_COMMUNICATION Communication;
    const GUID* Category;
    const GUID* Name;
    ULONG ConstrainedDataRangesCount;
    PKSDATARANGE* ConstrainedDataRanges;
} KSPIN_DESCRIPTOR;

Members

InterfacesCount
The size of the array pointed to by Interfaces.
Interfaces
The interfaces supported by this pin type.
MediumsCount
The number of elements in the array pointed to by Mediums.
Mediums
The mediums supported by this pin type.
DataRangesCount
The size of the array pointed to by DataRanges.
DataRanges
The data ranges supported by this pin type.
DataFlow
One of KSPIN_DATAFLOW_IN or KSPIN_DATAFLOW_OUT. See KSPROPERTY_PIN_DATAFLOW for the meaning of each value.
Communication
One of KSPIN_COMMUNICATION_NONE, KSPIN_COMMUNICATION_SINK, KSPIN_COMMUNICATION_SOURCE, KSPIN_COMMUNICATION_BOTH or KSPIN_COMMUNICATION_BRIDGE. See KSPROPERTY_PIN_COMMUNICATION for the meaning of each value.
Category
The category GUID.
Name
The GUID of the localized Unicode string name for the pin type, stored in the Registry.
ConstrainedDataRangesCount
The number of entries in the array pointed to by ConstrainedDataRanges.
ConstrainedDataRanges
The set of data ranges the pin type currently supports, based on the driver's internal state.

Comments

Drivers typically define one KSPIN_DESCRIPTOR structure for each pin type they support.

See Also

KSPIN_MEDIUM


KSPIN_INTERFACE

The KSPIN_MEDIUM structure describes a specific medium within a medium set.

typedef struct {
    GUID Set;
    ULONG Id;
    ULONG Flags;
} KSIDENTIFIER;

typedef KSIDENTIFIER KSPIN_INTERFACE;

Members

Set
The GUID that specifies this interface set.
Id
The ID number of this particular interface within the interface set.
Flags
Reserved for system use.


KSPIN_MEDIUM

The KSPIN_MEDIUM structure identifies a specific connection on a communication bus.

typedef struct {
    GUID Set;
    ULONG Id;
    ULONG Flags;
} KSIDENTIFIER;

typedef KSIDENTIFIER KSPIN_MEDIUM;

Members

Set
A GUID that specifies this communication bus.
Id
Identifies a unique connection on the bus.
Flags
Reserved for system use.

Comments

The KSPIN_MEDIUM structure identifies a medium, with a unique medium GUID and instance identifier, which is generated in a bus-specific manner. There is a reserved identifier value KSMEDIUM_TYPE_ANYINSTANCE that is used when bus instances are not of concern. For instance, the KSMEDIUMSETID_Standard refers to the system bus, of which there should only be one. So this instance identifier is always used just as a convenience.

A pin may support multiple mediums and interfaces on those mediums. The way in which a pin is described implies that the list of interfaces is supported on all mediums enumerated for a pin. So if there is a case in which this is not true, another pin may be used to describe each subset of interfaces for the specific mediums. Also see KSPROPERTY_PIN_MEDIUMS.

The medium is also cached by KS to speed up the search for a possible connection.

An example of use of this structure can be found in a tuner sample, in which KSPIN_MEDIUM represents unique connections between tuners, crossbars, and other tuner components.


KSPIN_PHYSICALCONNECTION

Data type returned by KSPROPERTY_PIN_PHYSICALCONNECTION.

typedef struct {
    ULONG Size;
    ULONG Pin;
    WCHAR SymbolicLinkName[1];
} KSPIN_PHYSICALCONNECTION, *PKSPIN_PHYSICALCONNECTION;

Members

Size
Pin
SymbolicLinkName


KSPROPERTY

The KSPROPERTY structure describes the property and request type of a property request.

typedef struct {
    GUID Set;
    ULONG Id;
    ULONG Flags;
} KSIDENTIFIER;

typedef KSIDENTIFIER KSPROPERTY;

Members

Set
A GUID identifying this property set.
Id
Specifies the member of the property set.
Flags
Specifies the request type. Should be one of the following values:
Value | Type of property request
KSPROPERTY_TYPE_GET | Get the current property data setting.
KSPROPERTY_TYPE_SET | Set the current property data setting.
KSPROPERTY_TYPE_SETSUPPORT | Does the driver support this property set?
KSPROPERTY_TYPE_BASICSUPPORT | What request types does the driver handle for this property? What is the valid data type, and what are the valid ranges for the property data?
KSPROPERTY_TYPE_DEFAULTVALUES | What are the driver's default values for the property data for this property? If default values exist, they are returned in the Basic Support information, rather than the normal range values. Default values are tagged as such by the filter when defining property range values.
KSPROPERTY_TYPE_RELATIONS | Specify all properties whose property data depends on the current setting of this property. Specifies that the property relations list is to be returned, or the amount of buffer room required by such a list if the return buffer is the size of a ULONG. Each element is on FILE_QUAD_ALIGNMENT, preceded by a KSMULTIPLE_ITEM structure. This is not valid when querying support of the property set in general.
KSPROPERTY_TYPE_SERIALIZESET | Serialize the property set, using the standard KSPROPERTY_SERIALHDR and KSPROPERTY_SERIAL structures.
KSPROPERTY_TYPE_UNSERIALIZESET | Unserialize the property set, using the standard KSPROPERTY_SERIALHDR and KSPROPERTY_SERIAL structures.
KSPROPERTY_TYPE_SERIALIZESIZE | What is the size of the property data for this property, when serialized as part of a KSPROPERTY_TYPE_SERIALIZESET request? The size is returned in the output buffer as a ULONG. A size of zero indicates that a property does not need to be serialized.
KSPROPERTY_TYPE_SERIALIZERAW | Specifies that the properties in this set should be serialized by the property set support handler, if one exists. If not, the call will fail. The serialization format is private. This operation must be the inverse of KSPROPERTY_TYPE_UNSERIALIZERAW.
KSPROPERTY_TYPE_TOPOLOGY | Property passed is of type KSP_NODE, where NodeId indicates the numeric id of the topology node. Do not set this flag on its own; instead, OR it with the above.
KSPROPERTY_TYPE_UNSERIALIZERAW | Specifies that the buffer provided contains a group of properties belonging to this set that should be unserialized by the property set support handler, if one exists. If not, the call will fail. The serialization format is private. This operation must be the inverse of KSPROPERTY_TYPE_SERIALIZERAW.

Comments

The KSEVENT, KSMETHOD, and KSPROPERTY structures are aliases for the KSIDENTIFIER structure. As such, their definitions are identical.


KSPROPERTY_BOUNDS_LONG

This structure defines the bounds for a 32-bit property.

typedef union {
    struct {
        LONG SignedMinimum;
        LONG SignedMaximum;
    };
    struct {
        ULONG UnsignedMinimum;
        ULONG UnsignedMaximum;
    };
} KSPROPERTY_BOUNDS_LONG, *PKSPROPERTY_BOUNDS_LONG;

Members

Signed Minimum
Minimum specified as a signed 32-bit value.
Signed Maximum
Maximum specified as a signed 32-bit value.
Unsigned Minimum
Minimum specified as an unsigned 32-bit value.
Unsigned Maximum
Maximum specified as an unsigned 32-bit value.

Comments

See the Testcap sample in the DDK for examples of usage.

See Also

KSPROPERTY_VALUES, KSPROPERTY_MEMBERSLIST


KSPROPERTY_BOUNDS_LONGLONG

This structure defines the bounds for a 64-bit property.

typedef union {
    struct {
        LONGLONG SignedMinimum;
        LONGLONG SignedMaximum;
    };
    struct {
        ULONGLONG UnsignedMinimum;
        ULONGLONG UnsignedMaximum;
    };
} KSPROPERTY_BOUNDS_LONGLONG, *PKSPROPERTY_BOUNDS_LONGLONG;

Members

Signed Minimum
Minimum specified as a signed 64-bit value.
Signed Maximum
Maximum specified as a signed 64-bit value.
Unsigned Minimum
Minimum specified as an unsigned 64-bit value.
Unsigned Maximum
Maximum specified as an unsigned 64-bit value.

Comments

See the Testcap sample in the DDK for examples of usage.

See Also

KSPROPERTY_VALUES, KSPROPERTY_MEMBERSLIST


KSPROPERTY_DESCRIPTION

This structure specifies the size and type of values contained in a specific property.

typedef struct {
  ULONG AccessFlags;
  ULONG DescriptionSize;
  KSIDENTIFIER PropTypeSet;
  ULONG MembersListCount;
  ULONG Reserved;
} KSPROPERTY_DESCRIPTION;

Members

AccessFlags
Contains the access allowed to this property.
DescriptionSize
Contains the inclusive size of the entire values information. This is the size of KSPROPERTY_DESCRIPTION if no values information is supported.
PropTypeSet
If supported by the specific property, specifies the type of values contained in this property. This group is uniquely specified by a GUID, such that new types of values may be created without overlapping with extensions to this set. The value types indicate the type of the value (like VT_BOOL, VT_UI4 in the standard set). This is GUID_NULL, with an identifier of zero, if values information is not supported by this property.
MembersListCount
Contains the number of members list headers that would normally follow this header.
Reserved
Reserved for future use. Set to zero.

Comments

The property values type set is specified by a KSIDENTIFIER structure. The basic set supported is KSPROPTYPESETID_General. The identifiers within that set are the standard VARENUM types used for OLE.

The values information that may follow the KSPROPERTY_DESCRIPTION structure is described by a list of variable length structures, each with a common header describing the type of variable length data, and the members in that list element. If supported, these contain the valid values that the specific property may contain.


KSPROPERTY_ITEM

Drivers can use the KSPROPERTY_ITEM structure to describe how they support a property in a property set.

typedef struct {
    ULONG PropertyId;
    union {
        PFNKSHANDLER GetPropertyHandler;
        BOOLEAN GetSupported;
    };
    ULONG MinProperty;
    ULONG MinData;
    union {
        PFNKSHANDLER SetPropertyHandler;
        BOOLEAN SetSupported;
    };
    PKSPROPERTY_VALUES Values;
    ULONG RelationsCount;
    PKSPROPERTY Relations;
    PKFNKSHANDLER SupportHandler;
    ULONG SerializedSize;
} KSPROPERTY_ITEM;

Members

PropertyId
Specifies the ID of the property being described.
GetPropertyHandler
Used only by drivers running under AVStream or KS 1.0. Contains the handler for retrieving the property. If this is NULL, the property cannot be read.
GetSupported
Used only by minidrivers running under stream class. TRUE if this property supports get requests, FALSE if it does not. (The class driver fulfills the request through the SRB_GET_DEVICE_PROPERTY or SRB_GET_STREAM_PROPERTY requests.)
MinProperty
The minimum buffer length to hold the property identifier. Must be at least sizeof(KSPROPERTY).
MinData
The minimum buffer length to hold the data read from or written to this property.
SetPropertyHandler
Used only by drivers running under AVStream or KS 1.0. Contains the handler for setting the property. If this is NULL, the property cannot be set.
SetSupported
TRUE if this property supports set requests, FALSE if it does not. (The class driver fulfills the request through the SRB_SET_DEVICE_PROPERTY or SRB_SET_STREAM_PROPERTY requests.)
Values
If not NULL, this specifies the acceptable and/or default values for a property. These are the same as the values reported by a driver in response to an IOCTL_KS_PROPERTY request with the KSPROPERTY_TYPE_BASICSUPPORT and KSPROPERTY_TYPE_DEFAULTVALUES flags set.
RelationsCount
The number of entries in the array pointed to by Relations.
Relations
Points to an array of related properties. Two properties are considered related if changing one property may affect the value of the other property. The Flags member of each entry is unused.
SupportHandler
Provide only if implementing your own format for raw serialization or raw unserialization. Basic support queries, range queries, and relations queries are automatically handled by AVStream, which will return the relevant values from other members of this KSPROPERTY_ITEM structure.
SerializedSize
The size of the property when serialized in a KSPROPERTY_TYPE_SERIALIZESET request. Should be zero if the property cannot be serialized.

Comments

Stream class minidrivers use KSPROPERTY_ITEM to describe to the client how to fulfill property requests on each property within a set. Handling for the property set as a whole is specified in the KSPROPERTY_SET structure, which contains pointers to arrays of KSPROPERTY_ITEM structures.

The stream class driver handles property requests on behalf of the minidriver. When the stream class driver requires more information from the minidriver, it passes an SRB_XXX request to one of the minidriver's StrMiniReceiveXXXRequest routines. The stream class driver handles the different request types as follows:

Property request flags value | Response
KSPROPERTY_TYPE_GET | If GetSupported is TRUE, the stream class driver submits an SRB_GET_DEVICE_PROPERTY or SRB_GET_STREAM_PROPERTYrequest to the appropriate minidriver StrMiniReceiveXXXRequest routine.
KSPROPERTY_TYPE_SET | If SetSupported is TRUE, the stream class driver submits an SRB_SET_DEVICE_PROPERTY or SRB_SET_STREAM_PROPERTY request to the appropriate minidriver StrMiniReceiveXXXRequest routine.
KSPROPERTY_TYPE_BASICSUPPORT | The stream class driver uses KSPROPERTY_ITEM to obtain the information necessary to fulfill this request. For example, to specify the data type and permitted ranges of the property data, they each use the Values member of this structure.
KSPROPERTY_TYPE_SETSUPPORT | The stream class driver completes the property request IRP as STATUS_SUCCESS if and only if the driver supplies an entry for the property set within its KSPROPERTY_SET structure.
KSPROPERTY_TYPE_DEFAULTVALUES | The stream class driver uses the Values member of this structure to determine the default values for the property data.
KSPROPERTY_TYPE_RELATIONS | The stream class driver uses the Relations member to determine what properties are related to this property.

KSPROPERTY_MEDIAAVAILABLE

[This is preliminary documentation and subject to change.]

Corresponds with DirectShow's IMediaSeeking::GetAvailable.

typedef struct {
    LONGLONG Earliest;
    LONGLONG Latest;
} KSPROPERTY_MEDIAAVAILABLE, *PKSPROPERTY_MEDIAAVAILABLE;

Members

Earliest
Latest


KSPROPERTY_MEMBERSHEADER

The KSPROPERTY_MEMBERSHEADER structure is one member of the KSPROPERTY_MEMBERSLIST structure. Its purpose is to describe the size and type of each element in the members list pointed to by the Members member of the KSPROPERTY_MEMBERSLIST structure.

typedef struct {
    ULONG   MembersFlags;
    ULONG   MembersSize;
    ULONG   MembersCount;
    ULONG   Flags;
} KSPROPERTY_MEMBERSHEADER, *PKSPROPERTY_MEMBERSHEADER;

Members

MembersFlags
Specifies the type of entries in the members list. Should be one of the following values:
Value | Description
KSPROPERTY_MEMBER_RANGES | Indicates that the following value members are described as ranges, with a minimum and maximum range. The size of the range pair is determined by the type of values as specified in KSPROPERTY_DESCRIPTION.PropTypeSet. The number of range pairs is determined by KSPROPERTY_MEMBERSHEADER.MembersCount.
KSPROPERTY_MEMBER
_STEPPEDRANGES 		Indicates that the following members are described as ranges with a specified stepping between values within that range. The stepping is followed by the minimum and maximum range pair. The size of the stepping value is also determined by KSPROPERTY_DESCRIPTION.PropTypeSet. The number of range pairs is determined by KSPROPERTY_MEMBERSHEADER.MembersCount.
KSPROPERTY_MEMBER_VALUES | Each entry in the members array is a single value. The size of each valid value is determined by KSPROPERTY_DESCRIPTION.PropTypeSet. The number of values is determined by KSPROPERTY_MEMBERSHEADER.MembersCount.

MembersSize
The size, in bytes, of the members array.
MembersCount
The number of entries in the members array.
Flags
Either zero, if the entries in the members array specify acceptable values for a property, or KSPROPERTY_MEMBER_FLAG_DEFAULT. This flag indicates that the members in this list represent the default values for this property. These values are returned when the client uses the KSPROPERTY_TYPE_DEFAULTVALUES flag on a query.

Comments

KSPROPERTY_MEMBERSHEADER is an auxiliary structure used by KSPROPERTY_MEMBERSLIST.


KSPROPERTY_MEMBERSLIST

The KSPROPERTY_MEMBERSLIST structure specifies a list of acceptable values and/or default values for a property.

typedef struct {
    KSPROPERTY_MEMBERSHEADER    MembersHeader;
    const VOID*                 Members;
} KSPROPERTY_MEMBERSLIST, *PKSPROPERTY_MEMBERSLIST;

Members

MembersHeader
Specifies how each entry in the array pointed to by Members should be interpreted.
Members
Points to an array of entries. Each entry describes a value or a set of a values. The type of each entry is specified in MembersHeader.MembersFlags. The number of entries is specified in MembersHeader.MembersCount.

Comments

KSPROPERTY_MEMBERSLIST is an auxiliary structure used by KSPROPERTY_VALUES to specify a list of acceptable values for a property.

An entry in the Members array can represent either a value, or a range of values. Optionally the range may include a step value.

If MembersHeader.MembersFlags == KSPROPERTY_MEMBER_VALUES, then each entry is a single value. The type of the value is specified in the PropTypeSet member of KSPROPERTY_VALUES.

If MembersHeader.MembersFlags == KSPROPERTY_MEMBER_RANGES, then each entry is a range of values, specified by a minimum and a maximum value. The type of each value is specified in the PropTypeSet member of KSPROPERTY_VALUES.

If MembersHeader.MembersFlags == KSPROPERTY_MEMBER_STEPPEDRANGES, then each entry is a step size, followed by a range. The type of each value is specified in the PropTypeSet member of KSPROPERTY_VALUES.

If MembersHeader.Flags == KSPROPERTY_MEMBER_FLAG_DEFAULT, the value or set of values supplied represent default values for the property.

Otherwise, the entries represent a list of acceptable values for the property


KSPROPERTY_POSITIONS

Used with the KSPROPERTY_MEDIASEEKING_POSITIONS property. Corresponds to DirectShow's IMediaSeeking::GetPositions and IMediaSeeking::SetPositions.

typedef struct {
    LONGLONG Current;
    LONGLONG Stop;
    KS_SEEKING_FLAGS CurrentFlags;
    KS_SEEKING_FLAGS StopFlags;
} KSPROPERTY_POSITIONS, *PKSPROPERTY_POSITIONS;

Members

Current
Current position as a 64-bit value.
Stop
Stop position as a 64-bit value.
CurrentFlags
StopFlags


KSPROPERTY_SERIAL

Each property that follows the KSPROPERTY_SERIALHDR contains a header (KSPROPERTY_SERIAL), followed by the property data, with the start of each property on FILE_LONG_ALIGNMENT. Note that the serial header structure is defined to be on FILE_LONG_ALIGNMENT.

typedef struct {
    KSIDENTIFIER    PropTypeSet;
    ULONG           Id;
    ULONG           PropertyLength;
} KSPROPERTY_SERIAL, *PKSPROPERTY_SERIAL;

Members

PropTypeSet
Specifies the type of property data. This is the same information obtained from querying Basic Support.
Id
Contains the identifier for this property.
PropertyLength
The length in bytes of the following property data. This does not include any alignment buffering that may be appended to the property data before the next property in the serialization.

See Also

KSPROPERTY_SERIALHDR


KSPROPERTY_SERIALHDR

The format of the serialization buffer is a KSPROPERTY_SERIALHDR, followed by serialized properties.

typedef struct {
    GUID            PropertySet;
    ULONG           Count;
} KSPROPERTY_SERIALHDR, *PKSPROPERTY_SERIALHDR;

Members

PropertySet
Contains the GUID of the property set contained in the serialized buffer.
Count
Contains the count of serialized properties to follow.

See Also

KSPROPERTY_SERIAL


KSPROPERTY_SET

A kernel streaming driver or pin may use the KSPROPERTY_SET structure to describe how it supports a property set.

typedef struct {
    const GUID* Set;
    ULONG PropertiesCount;
    PKSPROPERTY_ITEM PropertyItem;
    ULONG FastIoCount
    PKSFAST_PROPERTY_ITEM FastIoTable;
} KSPROPERTY_SET;

Members

Set
The GUID that identifies the property set.
PropertiesCount
Size of the array pointed to by the PropertyItem member.
PropertyItem
Points to the beginning of an array of KSPROPERTY_ITEM structures that describe how the driver or pin supports each property in the set.
FastIoCount
Reserved for system use.
FastIoTable
Reserved for system use.


KSPROPERTY_STEPPING_LONG

This stepping structure defines the valid range of values for a 32-bit property.

typedef struct {
    ULONG SteppingDelta;
    ULONG Reserved;
    KSPROPERTY_BOUNDS_LONG Bounds;
} KSPROPERTY_STEPPING_LONG, *PKSPROPERTY_STEPPING_LONG;

Members

SteppingDelta
See comments below.
Reserved
Reserved for system use.
Bounds
See comments below.

Comments

Any value k that satisfies the following criteria is valid:

Bounds.*Minimum + Z * SteppingDelta, Bounds.*Minimum <= k <= Bounds.*Maximum

Also see the Testcap sample in the DDK for examples of usage.

See Also

KSPROPERTY_VALUES, KSPROPERTY_MEMBERSLIST


KSPROPERTY_STEPPING_LONGLONG

The stepping structures define the valid range of values for a 64-bit property.

typedef struct {
    ULONGLONG SteppingDelta;
    KSPROPERTY_BOUNDS_LONGLONG Bounds;
} KSPROPERTY_STEPPING_LONGLONG, *PKSPROPERTY_STEPPING_LONGLONG;

Members

SteppingDelta
See below.
Bounds
See below.

Comments

Any value k that satisfies the following criteria is valid:

Bounds.*Minimum + Z * SteppingDelta, Bounds.*Minimum <= k <= Bounds.*Maximum

Also see the Testcap sample in the DDK for examples of usage.

See Also

KSPROPERTY_VALUES, KSPROPERTY_MEMBERSLIST


KSPROPERTY_VALUES

The KSPROPERTY_VALUES structure describes the type and acceptable and/or default values of a property.

typedef struct {
    KSIDENTIFIER                    PropTypeSet;
    ULONG                           MembersListCount;
    const KSPROPERTY_MEMBERSLIST*   MembersList;
} KSPROPERTY_VALUES, *PKSPROPERTY_VALUES;

Members

PropTypeSet
A KSIDENTIFIER structure (see KSEVENT) that identifies the data type of the property. The Set member of a KSIDENTIFIER structure indicates the set of value types supported, and the Id member of the same structure identifies the type within the set.
MembersListCount
Number of entries in the array pointed to by MembersList.
MembersList
Pointer to an array of KSPROPERTY_MEMBERSLIST structures. Each entry specifies a list of possible values or sets of values that the property may assume.

Comments

PropTypeSet.Set almost always equals KSPROPTYPESETID_General. The individual value types in KSPROPTYPESETID_General correspond to the VARENUM types documented in the Platform SDK.

Possible values for PropTypeSet.Id include:

Value | Data type
VT_I4 | Signed 4-byte quantity
VT_UI4 | Unsigned 4-byte quantity


KSQUALITY

The Quality structure is used to report QM problems in both kernel and user mode to their respective Quality Managers.

typedef struct {
    PVOID       Context;
    ULONG       Proportion;
    LONGLONG    DeltaTime;
} KSQUALITY, *PKSQUALITY;

Members

Context
Contains a context parameter that was originally passed to the connection.
Proportion
Indicates the percentage of frames currently being received that are actually being used. This is expressed in units of one-tenth of a percent, where 1000 is optimal.
DeltaTime
Indicates the delta in native units (as indicated by the Interface) from optimal time at which the frames are being delivered, where a positive number means too late, and a negative number means too early. Zero indicates a correct delta.


KSQUERYBUFFER

The KSQUERYBUFFER is used when querying for outstanding buffers available on an event with KSEVENT_TYPE_QUERYBUFFER.

typedef struct {
    KSEVENT         Event;
    PKSEVENTDATA    EventData;
    PVOID           Reserved;
} KSQUERYBUFFER, *PKSQUERYBUFFER;

Members

Event
Contains the description of the original event, with the KSEVENT_TYPE_QUERYBUFFER flag set instead of the KSEVENT_TYPE_ENABLEBUFFERED flag.
EventData
Contains the original pointer to the event data passed when the event was enabled. This pointer is used as the unique identifier in locating the event, just as it is used when disabling the event.
Reserved
Not used, and set to zero.

Comments

If KSEVENT_TYPE_ENABLEBUFFERED was used to enable an event that also buffers data, then the data produced by the event can be queried using this method. The description of the event being queried is provided as the first parameter, and any buffer is provided as the second parameter to the query.

The query returns STATUS_NOT_FOUND if the event was not found; STATUS_INVALID_PARAMETER if it was not being buffered; STATUS_NO_MORE_ENTRIES if no buffers were available; STATUS_BUFFER_TOO_SMALL if the buffer size was insufficient; else STATUS_SUCCESS. The length of buffer needed can be queried by providing a zero length output buffer. The size of buffer is returned in the BytesReturned parameter, with a warning status of STATUS_BUFFER_OVERFLOW.

See Also

KSEVENT


KSRATE

The query is passed a KSRATE structure appended to the Property containing the rate request (known as a KSRATE_CAPABILITY structure), and is returned a KSRATE structure filled in with the capability given the rate request.

typedef struct {
    LONGLONG        PresentationStart;
    LONGLONG        Duration;
    KSPIN_INTERFACE Interface;
    LONG            Rate;
    ULONG           Flags;
} KSRATE, *PKSRATE;

Members

PresentationStart
Contains the start point for the rate in presentation time units.
Duration
Contains the duration of the rate in presentation time units.
Interface
Contains either the interface used in the connection this rate request is being sent to, or the interface of a related connection. This allows the time units to be interpreted by the pin.
Rate
Contains the rate in terms of 1/10th percentage points, where 1000 is the nominal 1.0 rate, 500 is 0.5 rate, etc. Negative numbers indicate reverse rates.
Flags
See the table below.
KSRATE_NOPRESENTATIONSTART | Specifies that there is no valid start time in this rate change request or query.
KSRATE_NOPRESENTATIONDURATION | Specifies that there is no valid duration in this rate change request or query.


KSRATE_CAPABILITY

The KSRATE_CAPABILITY structure is just a Property identifier followed by the Rate structure.

typedef struct {
    KSPROPERTY      Property;
    KSRATE          Rate;
} KSRATE_CAPABILITY, *PKSRATE_CAPABILITY;

Members

Property
Property identifier.
Rate
Rate structure.


KSRELATIVEEVENT

The KSPROPERTY_CONNECTION_STARTAT property is passed a KSRELATIVEEVENT structure:

typedef struct {
    ULONG Size;
    ULONG Flags;
    union {
        HANDLE ObjectHandle;
        PVOID ObjectPointer;
    };
    PVOID Reserved;
    KSEVENT Event;
    KSEVENTDATA EventData;
} KSRELATIVEEVENT;

Members

Size

The inclusive size of the structure, including any event specific data appended to the EventData element.

Flags

Flags indicating what type of object is being specified in the ObjectHandle and ObjectPointer union.

ObjectHandle

If the Flags element contains the KSRELATIVEEVENT_FLAG_HANDLE flag, this element contains the handle of the object supporting the event to be used.

ObjectPointer

If the Flags element contains the KSRELATIVEEVENT_FLAG_POINTER flag, this element contains a pointer to the object supporting the event to be used. This is valid only for kernel-mode clients.

Reserved
Reserved and set to zero.
Event
Contains the event to be used.
EventData
Contains the header for the event-specific data. The header itself is not actually used, except as a starting point to access the event-specific data, and must be initialized to zero.


KSRESOLUTION

The KSPROPERTY_CLOCK_RESOLUTION property is passed a KSRESOLUTION, which is returned with the granularity and error of the clock.

typedef struct {
    LONGLONG    Granularity;
    LONGLONG    Error;
} KSRESOLUTION, *PKSRESOLUTION;

Members

Granularity
Contains the increment granularity of the clock in 100-nanosecond units, where 1 is the best.
Error
Contains the ± notification error of the clock in 100-nanosecond units, where 0 is the best, meaning the event notification granularity is as good as the increment granularity.


KSSTREAMALLOCATOR_FUNCTIONTABLE

This property retrieves the function table of the given allocator.

typedef struct {
    PFNALLOCATOR_ALLOCATEFRAME  AllocateFrame;
    PFNALLOCATOR_FREEFRAME      FreeFrame;
} KSSTREAMALLOCATOR_FUNCTIONTABLE, *PKSSTREAMALLOCATOR_FUNCTIONTABLE;

Members

AllocateFrame
FreeFrame

Comments

This property is only supported by allocators supporting the DISPATCH_LEVEL function interface. Allocators supporting this property must be able to allocate and free frames at IRQL <= DISPATCH_LEVEL.

Because the DISPATCH_LEVEL interface is closely associated with the IRP-based interface, acquiring the function table is likely to result in the creation of an internal notification event to allow pending I/O to be completed when frames are returned to the free list. When the handle to the allocator is closed, the function table pointers are invalid and the associated events are automatically disabled.

This property is only accessible from kernel-mode.

DeviceIoControl(
    AllocatorHandle,
    IOCTL_KS_PROPERTY,
    &Allocator,
    sizeof(KSPROPERTY),
    &AllocatorFunctions,
    sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE),
    &BytesReturned,
    &Overlapped);


KSSTREAMALLOCATOR_STATUS

This property retrieves the current status of the given allocator.

typedef struct {
    KSALLOCATOR_FRAMING Framing;
    ULONG               AllocatedFrames;
    ULONG               Reserved;
} KSSTREAMALLOCATOR_STATUS, *PKSSTREAMALLOCATOR_STATUS;

Members

Framing
Contains the framing specified when the allocator was created.
AllocatedFrames
Contains the current number of allocated frames. Highly dynamic.
Reserved
Reserved and set to zero.

Comments

This status indicates the framing specifications and the currently allocated frames.

DeviceIoControl(
    AllocatorHandle,
    IOCTL_KS_PROPERTY,
    &Allocator,
    sizeof(KSPROPERTY),
    &AllocatorStatus,
    sizeof(KSSTREAMALLOCATOR_STATUS),
    &BytesReturned,
    &Overlapped);


KSSTREAMALLOCATOR_STATUS_EX

The status for allocators supporting the extended allocator framing.

typedef struct {
    KSALLOCATOR_FRAMING_EX Framing;
    ULONG                  AllocatedFrames;
    ULONG                  Reserved;
} KSSTREAMALLOCATOR_STATUS_EX, *PKSSTREAMALLOCATOR_STATUS_EX;

Members

Framing
Contains the framing specified when the allocator was created.
AllocatedFrames
Contains the current number of allocated frames.
Reserved
Reserved and set to zero.

Comments

Corresponds closely with KSSTREAMALLOCATOR_STATUS except that instead of passing back a KSALLOCATOR_FRAMING, it passes back the extended structure.


KSSTREAM_HEADER

The KSSTREAM_HEADER structure is a variable-length structure that describes a packet of data to be read from or written to a streaming driver pin.

typedef struct {
    ULONG       Size;
    ULONG       TypeSpecificFlags;
    KSTIME      PresentationTime;
    LONGLONG    Duration;
    ULONG       FrameExtent;
    ULONG       DataUsed;
    PVOID       Data;
    ULONG       OptionsFlags;
} KSSTREAM_HEADER, *PKSSTREAM_HEADER;

Members

Size
The size in bytes of the structure. Should be at least sizeof(KSSTREAM_HEADER).
TypeSpecificFlags
Flags specific to a data format.
PresentationTime
The presentation time for the related stream buffer, nominally in 100-nanoseconds units. This represents the presentation time of the initial sample in the stream data, and cannot be separately modified without knowledge of the data format. If the no-timestamp flag is set, this is ignored.
Duration
Optionally contains the duration of this stream segment in the same units as the presentation time. Set to zero when not used. This can be used to shorten the data presented from the amount of data actually passed. For instance, a set of MPEG frames may be passed all in a single block because of encryption constraints and the duration indicates the actual amount of data to be rendered.
FrameExtent
Specifies the size of the entire frame. The region within the frame extent is available to the filter and the resulting valid data size for the stream operation is reflected in the DataUsed member.
DataUsed
For a write operations, this field contains the number of bytes within the frame that are valid when submitting a frame to a lower-level driver. The headers are not modified on a write operation, however, IO_STATUS_BLOCK.Information contains the total number of bytes actually written. This is not the same as the return for a read operation. For a read operation, this field is not used when submitting a frame to a lower-level driver and must be set to 0. On return, this member contains the number of bytes actually filled in this frame and the IO_STATUS_BLOCK.Information field contains the size of the list of headers actually used.
OptionsFlags
Describes a variety of attributes of the data stream. The OptionsFlags member can have the following values:
#define    KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT        0x00000001
#define    KSSTREAM_HEADER_OPTIONSF_PREROLL            0x00000002
#define    KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY    0x00000004
#define    KSSTREAM_HEADER_OPTIONSF_TYPECHANGED        0x00000008
#define    KSSTREAM_HEADER_OPTIONSF_TIMEVALID        0x00000010
#define    KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY    0x00000040
#define    KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE        0x00000080
#define    KSSTREAM_HEADER_OPTIONSF_DURATIONVALID        0x00000100
#define    KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM        0x00000200
#define    KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA        0x80000000

Value | Description
KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY | Specifies that there has been a discontinuity in the data stream before the data contained in this packet. This implies that the filter may need to reset its internal state before processing the data. No actual data buffer need be attached.
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID | The Duration member of this structure is valid.
KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM | Indicates that this frame represents the end of the data stream. This can then be used to generate an end-of-stream event.
KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE | If the stream is paused, this buffer should be flushed. This parameter is used, for example, by live data sources, where a pause renders the current data stale.
KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA | This data buffer is the start of looped data. The driver should loop on this data until explicitly stopped.
KSSTREAM_HEADER_OPTIONSF_PREROLL | The data in this buffer is used to prime the device state. This is a stream-specific option.
KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT | The data stream is at a natural point for splicing. A client would use this, for example, when sending data that uses inter-frame compression, such as MPEG video, to indicate that it would be safe to splice at this point.
KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY | There is a discontinuity in the data stream after this packet. This flag may be used for positional oriented interfaces to indicate an end of stream data. No actual data buffer need be attached.
KSSTREAM_HEADER_OPTIONSF_TIMEVALID | The PresentationTime member of this structure is valid. Indicates that this buffer has a valid timestamp associated with it.
KSSTREAM_HEADER_OPTIONSF_TYPECHANGED | The data format for this stream has changed. The data buffer actually contains the KSDATAFORMAT structure that defined the new format. Valid only for streams that have previously negotiated dynamic type changing. On a Stream Write, the new data format must be contained in place of a media sample, and if the media-specific extension size is different, must be the last header in a list of headers for that stream request. The data allocator is not used to contain the new media format. On a Stream Read, any further I/O remains pending until the new format is retrieved through KSPROPERTY_CONNECTION_DATAFORMAT. On a Stream Write, the header must not be extended, and must be the only header in the Write.

Comments

This structure may be followed in memory by additional information specific to the type of data in the data packet.

The presentation time is normally in 100-nanosecond units, however the standard format of this time is based on the data format. For instance, this number might represent the current sample. This number can be normalized using the KSSTREAM_HEADER.PresentationTime.Numerator and KSSTREAM_HEADER.PresentationTime.Denominator as a scaling fractional. This allows time to be represented in a native format to reduce unnecessary conversions, but implies that the native value can be linearly scaled. A value of 1/1 indicates that no scaling is necessary. A conversion should use the Numerator first, then the Denominator, in order to reduce rounding errors. For example, an audio stream may present the current time as a byte offset in the data stream:

#define BITS_PER_BYTE    8
#define NANOSECONDS    10000000

StreamHdr->PresentationTime.Numerator = BITS_PER_BYTE * NANOSECONDS;
StreamHdr->PresentationTime.Denominator = BitsPerSample * Channels * Frequency;
StreamHdr->PresentationTime.Time = ByteOffset;
StreamHdr->Duration = ByteLength;

On an IOCTL_KS_READ_STREAM portions of the stream header are filled in by the call. Each KSSTREAM_HEADER.DataUsed element will contain the actual number of bytes read, which is less than or equal to each KSSTREAM_HEADER.FrameExtent. The pIrp->IoStatus.Information element will contain the total size of the header data to return, which is at least one sizeof(KSSTREAM_HEADER). The headers could be longer if this was defined by the data format.

On an IOCTL_KS_WRITE_STREAM, the member elements must be initialized, and each KSSTREAM_HEADER.DataUsed element contains the number of bytes to write. The actual number of total bytes written is returned in pIrp->IoStatus.Information. This is less than or equal to the total of all KSSTREAM_HEADER.DataUsed elements in the headers.


KSTIME

The KSTIME structure contains a time stamp.

typedef struct {
    LONGLONG    Time;
    ULONG       Numerator;
    ULONG       Denominator;
} KSTIME, *PKSTIME;

Members

Time
The time value, usually in 100-nanosecond units.
Numerator
If the time value is scaled, this is the numerator of the scaling factor. For a non-scaled value, this should be one. Numerator must not be zero.
Denominator
If the time value is scaled, this is the denominator of the scaling factor. For a non-scaled value, this should be one. Denominator must not be zero.

Comments

Unscaled time stamps are in 100-nanosecond units. A data stream may use different units by specifying the numerator and denominator of a scale factor.


KSTOPOLOGY

A driver may use the KSTOPOLOGY structure to describe the topology of its pins and nodes.

typedef struct {
    ULONG CategoriesCount;
    const GUID* Categories;
    ULONG TopologyNodesCount;
    const GUID* TopologyNodes;
    ULONG TopologyConnectionsCount;
    const KSTOPOLOGY_CONNECTION* TopologyConnections;
    const GUID* TopologyNodesNames;
    ULONG Reserved;
} KSTOPOLOGY;

Members

CategoriesCount
The number of functional categories the driver supports.
Categories
Pointer to the beginning of the array of functional categories the driver supports.
TopologyNodesCount
The number of nodes the driver supports.
TopologyNodes
Pointer to the beginning of the array of GUIDs that describe the type of each node. This should be one of the KSNODE_XXX GUIDs defined in the header ksmedia.h.
TopologyConnectionsCount
The number of entries in the array pointed to by TopologyConnections. The node numbers of each entry must correspond to the array offset of the node within TopologyNodes. When this structure is a part of a streaming minidriver's HW_STREAM_HEADER, the pin numbers must correspond to the offsets within the array of HW_STREAM_INFORMATION structures within the minidriver's HW_STREAM_DESCRIPTOR structure.
TopologyConnections
Pointer to the beginning of the array of topology connections for this structure.
TopologyNodesNames
The GUID of the localized Unicode string name for the node, stored in the Registry.
Reserved
Reserved for system use. Drivers should set this to zero.

Comments

A stream class minidriver creates and passes this structure as part of its HW_STREAM_HEADER structure. The class driver uses this structure to process topology property requests. The property data the class driver returns is determined from the KSTOPOLOGY structure as follows:

KSPROPERTY_TOPOLOGY_CATEGORIES
Returns the array that begins at the Categories member of KSTOPOLOGY.
KSPROPERTY_TOPOLOGY_CONNECTIONS
Returns the array that begins at the TopologyConnections member of KSTOPOLOGY.
KSPROPERTY_TOPOLOGY_NAME
KSPROPERTY_TOPOLOGY_NODES
Returns the array that begins at the Nodes member of KSTOPOLOGY.


KSTOPOLOGY_CONNECTION

A streaming driver returns an array of KSTOPOLOGY_CONNECTION structures in response to KSPROPERTY_TOPOLOGY_CONNECTIONS property get requests. The structure describes each connection between nodes.

typedef struct {
    ULONG FromNode;
    ULONG FromNodePin;
    ULONG ToNode;
    ULONG ToNodePin;
} KSTOPOLOGY_CONNECTION;

Members

FromNode
The node ID of the outgoing node of a connection, or KSFILTER_NODE to represent the driver.
FromNodePin
An ID number identifying the outgoing connection. If FromNode is KSFILTER_NODE, the outgoing connection represents an actual pin, and not just an internal logical connection. In that case, FromNodePin must be the pin type ID of the pin.
ToNode
The node ID of the incoming node of a connection, or KSFILTER_NODE to represent the driver.
ToNodePin
An ID number identifying the outgoing connection. If FromNode is KSFILTER_NODE, the outgoing connection represents an actual pin, and not just an internal logical connection. In that case, FromNodePin must be the pin type ID of the pin.

Comments

KSTOPOLOGY_CONNECTION represents a single connection, either between pins, or an internal connection between nodes.

When representing a connection between two pin types, both FromNode and ToNode should be set to KSFILTER_NODE, and the FromNodePin and ToNodePin should be the pin type ID of the pin. (See KSPROPSETID_Pin for a description of pin type IDs.)

Otherwise, FromNodePin or ToNodePin represent a logical incoming or outgoing pin for the connection. The logical pin numbers are used solely to describe a connection between nodes: they have no existence outside of the KSPROPERTY_TOPOLOGY_CONNECTIONS property.


Kernel Streaming Functions

This section describes the functions and macros available to kernel-mode drivers through the KS libraries. Some of these, such as pin-related items, are described in more detail elsewhere and references are made to the detailed explanations.

  • Allocator Functions

    Functions that assist with the management of allocators.

  • Clock Functions

    Functions that assist with the management of clocks.

  • Method Set Functions

    Functions that assist with the management of method sets. These functions can enable a filter or pin to present a method set to a client as well as perform some of the basic parameter validation and routing.

  • Property Set Functions

    Functions that assist with the management of property sets. These functions can enable a filter or pin to present a property set to a client as well as perform some of the basic parameter validation and routing.

  • Event Set Functions

    Functions that assist with the management of event sets.

  • Connection Functions

    Functions that assist in creating and destroying connections.

  • IRP Management Functions

    Functions that assist in general processing of IRPs.

  • Topology Management Functions

    Functions that assist in the management of a topology.

  • General Utility Functions

    Functions that are general helper functions.


Allocator Functions

This section specifies the helper functions for allocators. These functions allow a device object to create allocators, interface to the system default allocator, and validate creation requests. The following functions are provided:

KsCreateAllocator

KsCreateDefaultAllocator

KsValidateAllocatorCreateRequest

KsCreateDefaultAllocatorEx


KsCreateAllocator

The KsCreateAllocator function creates a handle to an allocator for the given sink connection handle. This function does not complete the IRP or set the status in the IRP.

KSDDKAPI NTSTATUS NTAPI
  KsCreateAllocator(
    IN HANDLE  ConnectionHandle,
    IN PKSALLOCATOR_FRAMING  AllocatorFraming,
    OUT PHANDLE  AllocatorHandle
    );

Parameters

ConnectionHandle
Specifies the handle to the sink connection on which to create the allocator.
AllocatorFraming
Specified framing for the allocator.
AllocatorHandle
Specifies the pointer to a handle to store the allocator handle.

Return Values

The KsCreateAllocator function returns STATUS_SUCCESS if successful, or it returns an error if unsuccessful.

Comments

There are two versions of thhe KsCreateAllocator function: one for user-mode clients and one for kernel-mode clients. This function can only be called at PASSIVE_LEVEL for kernel-mode clients.

See Also

KSALLOCATOR_FRAMING


KsCreateDefaultAllocator

Given a validated IRP_MJ_CREATE request, the KsCreateDefaultAllocator function creates a default allocator that uses the specified memory pool and associates the IoGetCurrentIrpStackLocation(Irp)->FileObject with the allocator using an internal dispatch table (KSDISPATCH_TABLE).

KSDDKAPI NTSTATUS NTAPI
  KsCreateDefaultAllocator(
    IN PIRP  Irp
    );

Parameters

Irp
Specifies the IRP with the IRP_MJ_CREATE request being handled.

Return Values

The KsCreateDefaultAllocator function returns STATUS_SUCCESS if successful, or it returns an error if unsuccessful.


KsCreateDefaultAllocatorEx

Creates a default allocator which uses the specified memory pool and associates the IoGetCurrentIrpStackLocation(pIrp)->FileObject with this allocator using an internal dispatch table (KSDISPATCH_TABLE).

KSDDKAPI NTSTATUS NTAPI
  KsCreateDefaultAllocatorEx(
    IN PIRP Irp,
    IN PVOID InitializeContext OPTIONAL,
    IN PFNKSDEFAULTALLOCATE DefaultAllocate OPTIONAL,
    IN PFNKSDEFAULTFREE DefaultFree OPTIONAL,
    IN PFNKSINITIALIZEALLOCATOR InitializeAllocator OPTIONAL,
    IN PFNKSDELETEALLOCATOR DeleteAllocator OPTIONAL    );

Parameters

Irp
Contains the IRP with the allocator create request being handled.
InitializeContext
Optionally contains a context to use with an external allocator. This is only used as the initialization context to the optional InitializeAllocator callback when creating an allocator context. The parameter is not otherwised used. If an external allocator is not provided, this parameter must be set to NULL.
DefaultAllocate
Optionally contains an external allocate function which is used in place of the default pool allocation. If this is NULL, default allocation is used.
DefaultFree
Optionally contains an external free function which is used in place of the default pool allocation. If an external allocator is not provided, this parameter must be set to NULL.
InitializeAllocator
Optionally contains an external allocator initialization function to which the InitializeContext parameter is passed. This function is expected to return an allocator context based on the allocator framing. If an external allocator is not provided, this parameter must be set to NULL.
DeleteAllocator
Optionally contains an external allocator delete function which is used for external allocators. If an external allocator is not provided, this parameter must be set to NULL.

Return Values

Returns STATUS_SUCCESS, else an error on default allocator creation failure. Does not complete the IRP or set the status in the IRP.

Comments

Assumes that the KSCREATE_ITEM_IRP_STORAGE (IRP) points to the create item for this allocator, and assigns a pointer to it in the FsContext. This is used for any security descriptor queries or changes.


KsValidateAllocatorCreateRequest

The KsValidateAllocatorCreateRequest function validates an IRP_MJ_CREATE request as an allocator request and returns the create structure associated with the request on success.

KSDDKAPI NTSTATUS NTAPI
  KsValidateAllocatorCreateRequest(
    IN PIRP  Irp,
    OUT PKSALLOCATOR_FRAMING*  AllocatorFraming
    );

Parameters

Irp
Specifies the IRP with the IRP_MJ_CREATE request being validated.
AllocatorFraming
Caller-defined pointer that on successful completion contains an address to the framing structure supplied with the request.

Return Values

The KsValidateAllocatorCreateRequest function returns STATUS_SUCCESS if successful, or an error if the allocator request is not valid.


Clock Functions

This section specifies the helper functions for clocks. These functions allow a device object to create clocks, interface to the system default clock, and validate creation requests. Internally the default clock implementation uses the shared structure KSIDEFAULTCLOCK. This allows a single structure to control many file object clients. There are specific functions for creating and manipulating one of these clock instances. This internal structure may change at any time and cannot be relied on externally. Externally, it is cast as a PVOID.

In order to allow convenient conversion from the performance counter time to 100-nanosecond units, a macro has been provided. KSCONVERT_PERFORMANCE_TIME performs an accurate 64-bit muldiv given the performance counter frequency and performance counter time, resulting in 100-nanosecond time units.

The following functions are provided:

KsCreateClock

KsCreateDefaultClock

KsAllocateDefaultClock

KsAllocateDefaultClockEx

KsFreeDefaultClock

KsValidateClockCreateRequest

KsGetDefaultClockState

KsSetDefaultClockState

KsGetDefaultClockTime

KsSetDefaultClockTime


KsAllocateDefaultClock

The KsAllocateDefaultClock function allocates and initializes the default clock structure.

The function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsAllocateDefaultClock(
    OUT PKSDEFAULTCLOCK*  DefaultClock
    );

Parameters

DefaultClock
Specifies the caller-allocated shared default clock structure. The current time is set to zero and the state is set to KSSTATE_STOP. Upon successful completion of this routine, the structure indicated by this pointer will contain a reference to the default clock. The data returned should be treated as opaque and reserved for system use.

Return Values

The KsAllocateDefaultClock function returns STATUS_SUCCESS if successful, or a memory error if unsuccessful.

Comments

The internal DefaultClock.ReferenceCount element is initialized to one by the KsAllocateDefaultClock function. The element is incremented and decremented as each notification DPC is queued and completed. When the structure is to be freed, the element is used to determine if the owner of the clock should free the structure or if a pending DPC should free it asynchronously.

When the clock is no longer needed, the driver must call KsFreeDefaultClock to release any resources allocated for use with the clock.

See Also

KsFreeDefaultClock , KsAllocateDefaultClockEx


KsAllocateDefaultClockEx

The KsAllocateDefaultClockEx function allocates and initializes the default clock structure.

KSDDKAPI NTSTATUS NTAPI
  KsAllocateDefaultClockEx(
    OUT PKSDEFAULTCLOCK* DefaultClock,
    IN PVOID Context OPTIONAL,
    IN PFNKSSETTIMER SetTimer OPTIONAL,
    IN PFNKSCANCELTIMER CancelTimer OPTIONAL,
    IN PFNKSCORRELATEDTIME CorrelatedTime OPTIONAL,
    IN const KSRESOLUTION* Resolution OPTIONAL,
    IN ULONG Flags    );

Parameters

DefaultClock
Specifies the caller-allocated shared default clock structure. The current time is set to zero and the state is set to KSSTATE_STOP. Upon successful completion of this routine, the structure indicated by this pointer will contain a reference to the default clock. The data returned should be treated as opaque and reserved for system use.
Context
Optionally contains the context of the alternate time facilities. This must be set if a timer or correlated time function is used.
SetTimer
Optionally contains an alternate function to use in generating DPC timer callbacks based on a Presentation Time. If this is set, this function will be used to set timers based on deltas to the current Presentation Time in order to generate event notifications. If an alternate function is passed in to set timers, a corresponding CancelTimer function must also be passed. This is set to NULL if the default KeSetTimerEx function is to be used to approximate the next notification time. This would normally be set only if a CorrelatedTime function was being used. The function must have the same characteristics as the default function.
CancelTimer
Optionally contains an alternate function to use in cancelling outstanding timer callbacks. If an alternate function is passed in to cancel timers, a corresponding SetTimer function must also be passed. This is set to NULL if the default KeCancelTimer function is to be used. The function must have the same characteristics as the default function.
CorrelatedTime
Optionally contains an alternate function to retrieve both the Presentation and Physical Time in a correlated manner. This allows the clock owner to completely determine the current time. This is set to NULL if the default KeQueryPerformanceCounter function is to be used to regulate time progression.
Resolution
Optionally contains an alternate Granularity and/or Error factor for the clock. This can only be used only if an alternate timer or correlated time function are being provided. An alternate Granularity may be specified if an alternate correlated time is being used, else the structure element must be zero. An alternate Error may be specified if an alternate timer is being used, else the structure element must be zero.
Flags
Reserved, set to zero.

Return Values

The KsAllocateDefaultClockEx function returns STATUS_SUCCESS if successful, or a memory error if unsuccessful.

Comments

The internal DefaultClock.ReferenceCount element is initialized to one by the KsAllocateDefaultClock function. The element is incremented and decremented as each notification DPC is queued and completed. When the structure is to be freed, the element is used to determine if the owner of the clock should free the structure or if a pending DPC should free it asynchronously.

The function can only be called at PASSIVE_LEVEL.

See Also

KsFreeDefaultClock , KsAllocateDefaultClock


KsCreateClock

The KsCreateClock function creates a handle to a clock instance. The function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsCreateClock(
    IN HANDLE  ConnectionHandle,
    IN PKSCLOCK_CREATE  ClockCreate,
    OUT PHANDLE  ClockHandle
    );

Parameters

ConnectionHandle
Specifies the handle to the connection on which to create the clock.
ClockCreate
Specifies clock create parameters. This currently consists of a flag, which must be set to zero.
ClockHandle
Specifies the new clock handle.

Return Values

The KsCreateClock function returns STATUS_SUCCESS if successful, or it returns an error on clock creation failure.


KsCreateDefaultClock

Given an IRP_MJ_CREATE request, the KsCreateDefaultClock function creates a default clock that uses the system clock as a time base and associates the IoGetCurrentIrpStackLocation(Irp)->FileObject with the clock using an internal dispatch table (KSDISPATCH_TABLE). Does not complete the IRP or set the status in the IRP.

The KsCreateDefaultClock function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsCreateDefaultClock(
    IN PIRP  Irp,
    IN PKSDEFAULTCLOCK  DefaultClock
    );

Parameters

Irp
Specifies the IRP with the clock-create request being handled.
DefaultClock
Specifies an initialize default clock structure that is shared among any instance of the default clock for the parent.

Return Values

The KsCreateDefaultClock function returns STATUS_SUCCESS if successful, or an error if unsuccessful.

Comments

The clock can be created after using KsAllocateDefaultClock to create and initialize the internal structures for a default clock instance. After initialization, many file objects can be created against the same underlying default clock instance.

See Also

KsAllocateDefaultClock


KsFreeDefaultClock

The KsFreeDefaultClock function frees a default clock structure previously allocated with KsAllocateDefaultClock, taking into account any currently running timer DPCs. This assumes that all instances of the clock have been closed. This may actually just decrement the internal reference counter and allow a pending DPC to free the structure asynchronously.

This may only be called at PASSIVE_LEVEL.

KSDDKAPI VOID NTAPI
  KsFreeDefaultClock(
    IN PKSDEFAULTCLOCK  DefaultClock
    );

Parameters

DefaultClock
Specifies the previously allocated structure to free.

Return Values

None


KsGetDefaultClockState

The KsGetDefaultClockState function gets the current state of the clock.

The function can be called at DISPATCH_LEVEL.

KSDDKAPI KSSTATE NTAPI
  KsGetDefaultClockState(
    IN PKSDEFAULTCLOCK  DefaultClock
    );

Parameters

DefaultClock
Specifies an initialized, default clock structure that is shared among any instance of the default clock for the parent.

Return Values

The KsGetDefaultClockState function returns the current clock state.

See Also

KsSetDefaultClockState


KsGetDefaultClockTime

The KsGetDefaultClockTime function gets the current time of the clock.

The function can be called at DISPATCH_LEVEL.

KSDDKAPI LONGLONG NTAPI
  KsGetDefaultClockTime(
    IN PKSDEFAULTCLOCK  DefaultClock
    );

Parameters

DefaultClock
Specifies an initialize default clock structure that is shared among any instance of the default clock for the parent.

Return Values

The KsGetDefaultClockTime function returns the current clock time.

See Also

KsSetDefaultClockTime


KsSetDefaultClockState

The KsSetDefaultClockState function sets the current state of the clock that is used to reflect the current state of the underlying filter pin. The owner of the default clock is expected to serialize access to this function and to call KsSetDefaultClockTime.

The function can be called at DISPATCH_LEVEL.

KSDDKAPI VOID NTAPI
  KsSetDefaultClockState(
    IN PKSDEFAULTCLOCK  DefaultClock,
    IN KSSTATE  State
    );

Parameters

DefaultClock
Specifies an initialize default clock structure that is shared among any instance of the default clock for the parent.
State
Specifies the new state to set the clock.

Return Values

None

See Also

KsGetDefaultClockState


KsSetDefaultClockTime

The KsSetDefaultClockTime function sets the current time of the clock. It modifies the current time returned by the clock. The owner of the default clock is expected to serialize access to this function and to the KsSetDefaultClockState function.

The function can be called at DISPATCH_LEVEL.

KSDDKAPI VOID NTAPI
  KsSetDefaultClockTime(
    IN PKSDEFAULTCLOCK  DefaultClock,
    IN LONGLONG  Time
    );

Parameters

DefaultClock
Specifies an initialize default clock structure that is shared among instances of the default clock for the parent.
Time
Specifies the new time to set the clock.

Return Values

None

See Also

KsGetDefaultClockTime


KsValidateClockCreateRequest

The KsValidateClockCreateRequest function validates the clock creation request and returns the create structure associated with the request.

This can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsValidateClockCreateRequest(
    IN PIRP  Irp,
    OUT PKSCLOCK_CREATE*  ClockCreate
    );

Parameters

lrp
Specifies the IRP with the clock create request being handled.
ClockCreate
Specifies the clock create structure pointer passed to the create request.

Return Values

The KsValidateClockCreateRequest function returns STATUS_SUCCESS if successful, or an error if unsuccessful.


Method Set Functions

This section specifies the helper functions for method sets and method set handlers. When a device object presents a method set to a client, these functions can perform some of the basic parameter validation and routing based on a method set table. Related helper functions are described in the KSMETHOD_KSTsection

The following functions are provided:

KsMethodHandler

KsMethodHandlerWithAllocator

KsFastMethodHandler

The handler function is called through the KsMethodHandler function and receives a prepared IRP, with parameters extracted. A pointer to the KSMETHOD_SET to which the method belongs is placed in the KSMETHOD_SET_IRP_STORAGE (Irp) field and the type of method is placed in KSMETHOD_TYPE_IRP_STORAGE (Irp). This information is used when doing asynchronous processing on the method with KsDispatchSpecificMethod.

A method set item can additionally have a support handler that can be used to determine support for the particular method item. A pointer to the KSMETHOD_SET to which the method belongs is placed in the KSMETHOD_SET_IRP_STORAGE(Irp) field before calling the support handler. This handler definition is also used for property and event sets, with the same parameters and return values.

typedef NTSTATUS (*PFNKSHANDLER)(
  IN PIRP  Irp,
  IN PKSIDENTIFIER  Request,
  OUT PVOID  Data
  );

Parameters

Irp
Specifies the IRP that contains the method request.
Request
Specifies an aligned copy of the method parameter.
Data
Specifies an aligned copy of the method data parameter or the system address of the original data parameter, depending on the flags specified in the method.

Return Values

PFNKSHANDLER returns STATUS_SUCCESS if the method in the set is handled and the data buffer has been filled in with the correct support flags. Alternatively, it returns the STATUS_SOME_NOT_MAPPED informational error if the item is handled but the particular query request was not completed by the function and must be completed by the method handling code. If it returns another error message, either the method is not supported or a parameter error occurred.


KsFastMethodHandler

The KsFastMethodHandler function handles fast methods requested through IOCTL_KS_METHOD. It responds to all method identifiers defined by the sets that are also contained in the fast I/O list. This function can only be called at PASSIVE_LEVEL.

KSDDKAPI BOOLEAN NTAPI
  KsFastMethodHandler(
    IN PFILE_OBJECT  FileObject,
    IN PKSMETHOD UNALIGNED  Method,
    IN ULONG  MethodLength,
    IN OUT PVOID UNALIGNED  Data,
    IN ULONG  DataLength,
    OUT PIO_STATUS_BLOCK  IoStatus,
    IN ULONG  MethodSetsCount,
    IN  const KSMETHOD_SET  *MethodSet
    );

Parameters

FileObject
Specifies the file object on which the request was made.
Method
Specifies the original method parameter. This will always be on FILE_LONG_ALIGNMENT, but may not be on FILE_QUAD_ALIGNMENT.
MethodLength
Specifies the length indicated by the caller of the method parameter.
Data
Specifies the original unaligned data parameter.
DataLength
Specifies the length indicated by the caller of the data parameter.
IoStatus
Specifies an aligned structure that is used to return error status and information.
MethodSetsCount
Indicates the number of method set structures being passed.
MethodSet
Specifies the pointer to the list of method set information.

Return Values

The KsFastMethodHandler function returns TRUE if the request is handled, or FALSE if the request is not handled. If the request is not handled, an IRP is generated. If the request was handled, the function sets the IoStatus->Information element to zero because of an internal error or the element is set by a method handler. The method handler also sets the IoStatus->Status field when the method is handled.

Comments

The owner of a method set can perform prefiltering or postfiltering of the method handling using the KsFastMethodHandler and KsMethodHandler functions. The KsFastMethodHandler function is used to process requests made through the fast I/O dispatch interface for Device Control. It is only used to process requests that can be fulfilled quickly. The Wait parameter of the fast I/O function is not passed and assumed to be TRUE.

See Also

Method Set Functions, KsMethodHandler


KsMethodHandler

The KsMethodHandler function handles methods requested through IOCTL_KS_METHOD. It works with all method identifiers defined by the sets. The function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsMethodHandler(
    IN PIRP  Irp,
    IN ULONG  MethodSetsCount,
    IN KSMETHOD_SET  MethodSet
    );

Parameters

Irp
Specifies the IRP with the method request being handled.
MethodSetsCount
Indicates the number of method set structures being passed.
MethodSet
Specifies the pointer to the list of method set information.

Return Values

The KsMethodHandler function returns STATUS_SUCCESS if successful, or an error specific to the method being handled if unsuccessful. The function always sets the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP to zero because of an internal error, or the element is set by a method handler. The function does not set the IO_STATUS_BLOCK.Status field nor complete the IRP.

Comments

The owner of a method set can perform pre-filtering or post-filtering of the method handling using the KsMethodHandler and KsFastMethodHandler functions.

See Also

Method Set Functions, KsFastMethodHandler


KsMethodHandlerWithAllocator

The KsMethodHandlerWithAllocator functions performs the same handling as KsMethodHandler, with the same restrictions, but allows an optional allocator callback to be used to provide a buffer for the parameters. If used, the filter may need to free the buffer in some nonconventional manner. Note that the IRP_BUFFERED_IO and IRP_DEALLOCATE_BUFFER flags are not set when using a custom allocator.

KSDDKAPI NTSTATUS NTAPI
  KsMethodHandlerWithAllocator(
    IN PIRP  Irp,
    IN ULONG  MethodSetsCount,
    IN PKSMETHOD_SET  MethodSet,
    IN PFNKSALLOCATOR  Allocator  OPTIONAL,
    IN ULONG  MethodItemSize  OPTIONAL,
    );

Parameters

Irp
Specifies the IRP with the method request being handled.
MethodSetsCount
Indicates the number of method set structures being passed.
MethodSet
Specifies the pointer to the list of method set information.
Allocator
Optionally points to an allocation function that will be used to allocate memory to store the method parameters.
MethodItemSize
Optionally contains the size of each KSMETHOD_ITEM structure in each list of methods. The method item may be extended in order to store private information. If this parameter is zero, the structure size is assumed to be normal. If it is greater than or equal to a method item structure, the KSMETHOD_ITEM_IRP_STORAGE macro can be used to return a pointer to the method item so the custom data can be retrieved.

Return Values

The KsMethodHandler function returns STATUS_SUCCESS if successful, or an error specific to the method being handled if unsuccessful. The function always sets the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP to zero because of an internal error, or the element is set by a method handler. The function does not set the IO_STATUS_BLOCK.Status field nor complete the IRP.


Property Set Functions

This section specifies the helper functions for property sets and property set handlers. When a device object presents a property set to a client, these functions can perform some of the basic parameter validation and routing based on a property set table.

The following functions are provided:

KsFastPropertyHandler

KsPropertyHandler

KsPropertyHandlerWithAllocator

KsUnserializeObjectPropertiesFromRegistry

The property set handlers include PFNKSHANDLER and PFNKSFASTHANDLER, and are described in the following text.

PFNKSHANDLER

PFNKSHANDLER defines the entry point for a specific handler of a property within a property set and is the type of function that is called by a general property set handler for a specific property. A pointer to the KSPROPERTY_SET to which the property belongs is then placed in the KSPROPERTY_SET_IRP_STORAGE(Irp) field.

typedef NTSTATUS (*PFNKSHANDLER)(
  IN PIRP  Irp,
  IN PKSIDENTIFIER  Request,
  IN OUT PVOID  Data
  );

Parameters

Irp
Specifies the original IRP passed to the property handler function.
Request
Specifies an aligned copy of the property parameter.
Data
Specifies an aligned copy of the property data parameter or a place in which to return data.

Return Values

The callback PFNKSHANDLER returns STATUS_SUCCESS if successful, or an error specific to the property being handled if unsuccessful. If data is being returned, it sets the Irp->IoStatus.Information field, but does not set the Irp->IoStatus.Status field nor does it complete the IRP. It can mark the IRP pending if it is to be completed asynchronously.

PFNKSFASTHANDLER

PFNKSFASTHANDLER circumvents the creation of an IRP in order to process a request if a property set contains fast I/O implementations. If implemented, it is in addition to and not a replacement for, typical IRP handlers. These handlers must deal with unaligned data and possible access violations; they are only used when the property can be quickly processed.

typedef BOOLEAN (*PFNKSFASTHANDLER)(
  IN PFILE_OBJECT  FileObject,
  IN PKSIDENTIFIER UNALIGNED  Request,
  IN ULONG  RequestLength,
  IN OUT PVOID UNALIGNED  Data,
  IN ULONG  DataLength,
  OUT PIO_STATUS_BLOCK  IoStatus
  );

Parameters

FileObject
Specifies the file object on which the request was made.
Request
Specifies the original property parameter. This will always be on FILE_LONG_ALIGNMENT, but can not be on FILE_QUAD_ALIGNMENT.
RequestLength
Specifies the length indicated by the caller of the property parameter.
Data
Specifies the original unaligned data parameter.
DataLength
Specifies the length indicated by the caller of the data parameter.
IoStatus
Specifies an aligned structure that is used to return error status and information. This information is then copied to the original I/O status structure on completion.

Return Values

PFNKSFASTHANDLER returns TRUE if the call was handled. If the call was not handled, it returns FALSE and an IRP is generated to handle the request.


KsFastPropertyHandler

The KsFastPropertyHandler function handles fast property requests through IOCTL_KS_PROPERTY. It responds to all property identifiers defined by the sets that are also contained in the fast I/O list. This function can only be called at PASSIVE_LEVEL.

KSDDKAPI BOOLEAN NTAPI
  KsFastPropertyHandler(
    IN PFILE_OBJECT  FileObject,
    IN PKSPROPERTY UNALIGNED  Property,
    IN ULONG  PropertyLength,
    IN OUT PVOID UNALIGNED  Data,
    IN ULONG  DataLength,
    OUT PIO_STATUS_BLOCK  IoStatus,
    IN ULONG  PropertySetsCount,
    IN const KSPROPERTY_SET  *PropertySet
    );

Parameters

FileObject
Specifies the file object on which the request was made.
Property
Specifies the original method parameter. This is always on FILE_LONG_ALIGNMENT, but may not be on FILE_QUAD_ALIGNMENT.
PropertyLength
Specifies the length indicated by the caller of the property parameter.
Data
Specifies the original unaligned data parameter.
DataLength
Specifies the length indicated by the caller of the data parameter.
IoStatus
Specifies an aligned structure used to return error status and information.
PropertySetsCount
Indicates the number of property set structures being passed.
PropertySet
Specifies the pointer to the list of property set information.

Return Values

The KsFastPropertyHandler function returns TRUE if the request was handled, or FALSE if the request was not handled. If FALSE is returned, an IRP is generated. If the request was handled, the function sets the IoStatus->Information element, either through setting it to zero because of an internal error, or through a property handler setting it. The property handler also sets the IoStatus->Status field when the property is actually handled.

Comments

The owner of a property set can perform prefiltering or postfiltering of the property handling, as well as processing requests made through the fast I/O dispatch interface for device control. The KsFastPropertyHandler function is only used to process requests that can be fulfilled quickly. The Wait parameter of the fast I/O function is not passed and is assumed to be TRUE.

See Also

Property Set Functions, KsPropertyHandler


KsPropertyHandler

Drivers call KsPropertyHandler function for IRP handling.

KSDDKAPI NTSTATUS NTAPI
  KsPropertyHandler(
    IN PIRP  Irp,
    IN ULONG  PropertySetsCount,
    IN  const KSPROPERTY_SET  *PropertySet
    );

Parameters

Irp
Specifies the IRP with the property request being handled.
PropertySetsCount
Specifies the number of property sets being passed.
PropertySet
Points to an array of KSPROPERTY_SET structures. The driver should provide one structure for each property set it wants KsPropertyHandler to handle.

Return Values

The KsPropertyHandler function returns STATUS_SUCCESS if successful, or an error specific to the property being handled if unsuccessful. The function sets the IRP->IO_STATUS_BLOCK.Information member, either through setting it to zero because of an internal error, or through a property handler setting it. The function does not set the lrp->IoStatus.Status member nor does it complete the IRP.

Comments

KsPropertyHandler responds to all property identifiers defined by the sets, and can only be called at PASSIVE_LEVEL.

Each KSPROPERTY_SET entry contains a pointer to an array of KSPROPERTY_ITEM structures in its PropertyItem member. For driver-specific processing, KsPropertyHandler hands off each request to one of the driver-supplied callbacks within PropertyItem. KsPropertyHandler takes care of any IRP processing required.

KsPropertyHandler does not use the FastIoTable member of its KSPROPERTY_SET structure. If the driver needs to support Fast I/O handling of requests, the same KSPROPERTY_SET structure should be passed to the KsFastPropertyHandler routine.

The owner of the property sets can perform prefiltering or postfiltering of property handling. Basic property structure access exceptions are handled by the KsPropertyHandler function, though cleanup for specific exceptions must be covered by the property handler.

See Also

Property Set Functions, KsFastPropertyHandler


KsPropertyHandlerWithAllocator

The KsPropertyHandlerWithAllocator performs the same handling as KsPropertyHandler, with the same restrictions, but allows an optional allocator callback to be used to provide a buffer for the parameters. If used, the filter may need to free the buffer in some nonconventional manner. IRP_BUFFERED_IO and IRP_DEALLOCATE_BUFFER flags are not set when using a custom allocator.

KSDDKAPI NTSTATUS NTAPI
  KsPropertyHandlerWithAllocator(
    IN PIRP  Irp,
    IN ULONG  PropertySetsCount,
    IN PKSPROPERTY_SET  PropertySet,
    IN PFNKSALLOCATOR  Allocator  OPTIONAL,
    IN ULONG  PropertyItemSize  OPTIONAL,
    );

Parameters

Irp
Specifies the IRP with the property request being handled.
PropertySetsCount
Specifies the number of property sets being passed.
PropertySet
Specifies the pointer to an array of property set information.
Allocator
Optionally points to an allocation function used to allocate memory to store the property parameters. See Event Set Functions.
PropertyItemSize
Optionally contains the size of each KSPROPERTY_ITEM structure in the properties. The property item may be extended in order to store private information. If this parameter is zero, the structure size is assumed to be normal. If it is greater than or equal to a property item structure, the KSPROPERTY_ITEM_IRP_STORAGE macro can be used to return a pointer to the property item so the custom data can be retrieved.

Return Values

The KsPropertyHandler function returns STATUS_SUCCESS if successful, or an error specific to the property being handled if unsuccessful. The function sets the Irp->IoStatus.Information member, either through setting it to zero because of an internal error, or through a property handler setting it. The function does not set the lrp->IoStatus.Status member nor does it complete the IRP.


KsUnserializeObjectPropertiesFromRegistry

The KsUnserializeObjectPropertiesFromRegistry function, when given a destination object and a registry path, enumerates the named values and applies them as serialized data to the specified property sets listed in the serialized data. An IRP is generated when sending the serialized data, so no assumption is made on use of KS property structures to internally define the property sets. The function does not use the names of the values.

KSDDKAPI NTSTATUS NTAPI
  KsUnserializeObjectPropertiesFromRegistry(
    IN PFILE_OBJECT  FileObject,
    IN HANDLE  ParentKey  OPTIONAL,
    IN PUNICODE_STRING  RegistryPath  OPTIONAL
    );

Parameters

FileObject
Specifies the file object whose properties are being set.
ParentKey
Optionally contains a handle to the parent of the path, or NULL. The Parent Key and/or the RegistryPath must be passed.
RegistryPath
Optionally contains the path to the key whose subkeys will be enumerated as property sets, or otherwise NULL. The ParentKey and/or the Registry Path must be passed.

Return Values

The KsUnserializeObjectPropertiesFromRegistry function returns STATUS_SUCCESS if the property sets were unserialized. The function returns an error if the registry path was invalid, one of the subkeys was invalid, setting a property was unsuccessful, the serialized format was invalid, or a property set was not supported on the object.

See Also

Property Set Functions


Event Set Functions

This section contains the helper functions for event sets and event generating code. These functions allow a device object to present an event set to a client and to perform some of the basic parameter validations and routing based on an event set table.

The following functions are provided:

KsGenerateEvent

KsEnableEventWithAllocator

KsGenerateDataEvent

KsGenerateEventList

KsEnableEvent

KsDiscardEvent

KsDisableEvent

KsFreeEventList

The PFNKSADDEVENT function prototype defines the entry point for an event set list add handler:

typedef NTSTATUS (*PFNKSADDEVENT)(
  IN PIRP  Irp,
  IN PKSEVENTDATA  EventData,
  IN struct _KSEVENT_ENTRY*  EventEntry
  );

Parameters

Irp
Specifies the original enable IRP passed to the event handler function.
EventData
Specifies an aligned copy of the original data attached to the event request.
EventEntry
Specifies the initialized entry that was created for the event request.

Return Values

The callback should return STATUS_SUCCESS or an error specific to the event being enabled. The function does not set the Irp->IoStatus.Information and Irp->IoStatus.Status fields, nor does it complete the IRP. It may mark the IRP pending if it is to be completed asynchronously. However, if enabling the event subsequently fails, KsDiscardEvent must be used to free the event entry data allocated by KsEnableEvent.

The PFNKSREMOVEEVENT function prototype defines the entry point for an event set list-remove handler:

typedef VOID (*PFNKSREMOVEEVENT)(
  IN PFILE_OBJECT  FileObject,
  IN struct _KSEVENT_ENTRY*  EventEntry
  );

Parameters

FileObject
Contains the file object on which the request was made.
EventEntry
Specifies the entry that was originally created for the event request.

Return Values

The callback must succeed.

Comments

The function allows a filter pin or master clock to keep separate lists for different types of events. Event set list handlers are specified for each event set.

The PFNKSALLOCATOR callback function is optionally used as a parameter to KsEnableEventWithAllocator, KsPropertyHandlerWithAllocator, and KsMethodHandlerWithAllocator. It specifies a filter-provided function that is used to allocate memory for data buffers. Normally pool memory is used for buffer allocations. This enables filters that pass event, property, and method queries directly to hardware to avoid extra data copies by allowing them to provide the buffer into which such data is placed by the standard handling functions. Thus, a filter may have memory blocks that already have been mapped to an adapter from which buffer allocations can occur.

Since this memory presumably is not normal pool allocated memory, the filter must perform buffer cleanup on completion of the IRP. This means that for input operations from user mode that are not synchronous, the allocator must allocate an MDL for the destination buffer, probe and lock it, and retrieve a system address. This must be done in order to enable copying of the return data to the original buffer.

Typedef NTSTATUS (*PFNKSALLOCATOR)(
  IN PIRP  Irp,
    IN ULONG  BufferSize,
    IN BOOL  InputOperation
    );

Parameters

Irp
Specifies the IRP for which the buffer allocation request is being made.
BufferSize
Specifies the size of buffer needed. This size covers all parameters in the request.
InputOperation
Set to TRUE if this is an input operation, meaning that on successful return, the Irp->IoStatus.Information field will contain the number of bytes to copy back to the original input buffer.

Comments

Typically, pool memory is used for buffer allocations. This enables filters that pass event, property, and method queries directly to hardware to avoid extra data copies by allowing them to provide the buffer into which such data is placed by the standard handling functions. So, a filter may have memory blocks that have already been mapped to an adapter from which buffer allocations can occur.

Since this memory presumably is not typical pool-allocated memory, the filter must perform buffer cleanup on completion of the Irp. This means that for input operations from usermode which are not synchronous, the allocator must allocate an MDL for the destination buffer, probe and lock it, and retrieve a system address. This must be done in order to enable copying of the return data to the original buffer.


KsDisableEvent

The KsDisableEvent function disables events requested through IOCTL_KS_DISABLE_EVENT. It responds to all events previously enabled through KsEnableEvent. If the input buffer length is zero, it is assumed that all events on the list are to be disabled. This function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsDisableEvent(
    IN PIRP  Irp,
    IN OUT PLIST_ENTRY  EventsList,
    IN KSEVENTS_LOCKTYPE  EventsFlags,
    IN PVOID  EventsLock
    );

Parameters

Irp
Specifies the IRP passed to the removal function, which uses the IRP to obtain context information. The file object associated with the IRP is used to compare against the file object originally specified when enabling the event. This allows a single event list to be used for multiple clients differentiated by file objects.
EventsList
Points to the head of the list of KSEVENT_ENTRY items on which the event may be found. If a client uses multiple event lists and does not know which list this event is on, the client can call this function multiple times. An event not found will return STATUS_UNSUCCESSFUL.
EventsFlags
Specifies a KSEVENTS_LOCKTYPE flag specifying the type of exclusion lock to be used in accessing the event list. If no flag is set, then no lock is taken.
EventsLock
Used to synchronize access to an element on the list. After the element has been accessed, it is marked as being deleted so that subsequent removal requests fail. The lock is then released after calling the removal function, if any. The removal function must synchronize with event generation before actually removing the element from the list.

Return Values

The KsDisableEvent function returns STATUS_SUCCESS if successful, or an error specific to the event being enabled. The function always sets the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP to zero. It does not set the IO_STATUS_BLOCK.Status field, nor does it complete the IRP.

Comments

It is important that the remove handler synchronize with event generation to ensure that when the event is removed from the list, it is not currently being serviced. Access to this list is assumed to be controlled with the lock passed.

See Also

Event Set Functions, KsEnableEvent


KsDiscardEvent

The KsDiscardEvent function discards the memory used by an event entry after the objects have been dereferenced. The function can be called when manually disabling events that have not been disabled by the event owner (by calling the KsFreeEventList function to disable events). For example, the function can be called when asynchronously enabling an event fails and the event entry needs to be discarded.

KSDDKAPI VOID NTAPI
  KsDiscardEvent(
    IN PKSEVENT_ENTRY  EventEntry
    );

Parameters

EventEntry
Specifies the pointer to the entry to discard. This pointer is no longer valid after a successful call to this function.

Return Values

None

Comments

Typically, the KsDiscardEvent function is automatically called by the KsDisableEvent function when a request to disable an event occurs, or by the KsFreeEventList function when a request to free a list of events occurs. This function can only be called at PASSIVE_LEVEL.

See Also

Event Set Functions


KsEnableEvent

The KsEnableEvent function enables events requested through IOCTL_KS_ENABLE_EVENT. It responds to all event identifiers defined by the sets. This function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsEnableEvent(
    IN PIRP  Irp,
    IN ULONG  EventSetsCount,
    IN KSEVENT_SET*  EventSet,
    IN OUT PLIST_ENTRY  EventsList  OPTIONAL,
    IN KSEVENTS_LOCKTYPE  EventsFlags  OPTIONAL,
    IN PVOID  EventsLock  OPTIONAL
    );

Parameters

Irp
Specifies the IRP with the enable request being handled. The file object associated with the IRP is stored with the event for later comparison when disabling the event.
EventSetsCount
Indicates the number of event set structures being passed.
EventSet
Specifies a pointer to the list of event set information.
EventsList
If the enabling event's KSEVENT_SET.AddHandler for the event set is NULL, it must point to the head of the list of KSEVENT_ENTRY items on which the event is to be added. This function assumes a single list for at least a subset of events.
EventsFlags
Specifies KSEVENTS_LOCKTYPE flags specifying the type of exclusion lock to be used in accessing the event list, if any. If no flag is set, then no lock is taken. If a handler is specified already, this parameter is ignored.
EventsLock
If the KSEVENT_SET.AddHandler for the event set containing the event being enabled is NULL, then this is used to synchronize access to the list. This value can be NULL if no flag is set in EventsFlags.

Return Values

The KsEnableEvent function returns STATUS_SUCCESS if successful, or an error specific to the event being enabled if unsuccessful. The function always sets the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP to zero. It does not set the IO_STATUS_BLOCK.Status field, nor does it complete the IRP.

See Also

Event Set Functions


KsEnableEventWithAllocator

The KsEnableEventWithAllocator function enables events requested through IOCTL_KS_ENABLE_EVENT but also allows an optional allocator callback to be used to provide a buffer for the parameters. It responds to all event identifiers defined by the sets. This function can only be called at PASSIVE_LEVEL.

If used, the filter may need to free the buffer in some nonconventional manner. Note that the IRP_BUFFERED_IO and IRP_DEALLOCATE_BUFFER flags are not set when using a custom allocator.

KSDDKAPI NTSTATUS NTAPI
  KsEnableEventWithAllocator(
    IN PIRP  Irp,
    IN ULONG  EventSetsCount,
    IN PKSEVENT_SET  EventSet,
    IN OUT PLIST_ENTRY  EventsList  OPTIONAL,
    IN KSEVENTS_LOCKTYPE  EventsFlags  OPTIONAL,
    IN PVOID  EventsLock  OPTIONAL,
    IN PFNKSALLOCATOR  Allocator  OPTIONAL,
    IN ULONG  EventItemSize  OPTIONAL
    );

Parameters

Irp
Specifies the IRP with the enable request being handled. The file object associated with the IRP is stored with the event for later comparison when disabling the event.
EventSetsCount
Indicates the number of event set structures being passed.
EventSet
Specifies a pointer to the list of event set information.
EventsList
If the enabling event's KSEVENT_SET.AddHandler for the event set is NULL, it must point to the head of the list of KSEVENT_ENTRY items on which the event is to be added. This function assumes a single list for at least a subset of events.
EventsFlags
Specifies KSEVENTS_LOCKTYPE flags specifying the type of exclusion lock to be used in accessing the event list, if any. If no flag is set, then no lock is taken. If a handler is specified already, this parameter is ignored.
EventsLock
If the KSEVENT_SET.AddHandler for the event set containing the event being enabled is NULL, then this is used to synchronize access to the list. This value can be NULL if no flag is set in EventsFlags.
Allocator
Optionally points to an allocation function that will be used to allocate memory to store the event parameters.
EventItemSize
Optionally contains the size of each KSEVENT_ITEM structure in each list of events. The event item may be extended in order to store private information. If this parameter is zero, the structure size is assumed to be normal. If it is greater than or equal to an event item structure, the KSEVENT_ITEM_IRP_STORAGE macro can be used to return a pointer to the event item so the custom data can be retrieved.

Return Values

Same as KsEnableEvent, which returns STATUS_SUCCESS if successful, or an error specific to the event being enabled if unsuccessful. The function always sets the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP to zero. It does not set the IO_STATUS_BLOCK.Status field, nor does it complete the IRP.

Comments

If the optional allocator callback is used, the filter may need to free the buffer in some nonconventional manner. Note that the IRP_BUFFERED_IO and IRP_DEALLOCATE_BUFFER flags are not set when using a custom allocator.


KsFreeEventList

The KsFreeEventList function handles freeing all events from a specified list, with the assumption that these events are composed of KSEVENT_ENTRY structures. This function can only be called at PASSIVE_LEVEL.

KSDDKAPI VOID NTAPI
  KsFreeEventList (
    IN PFILE_OBJECT  FileObject,
    IN OUT PLIST_ENTRY  EventsList,
    IN KSEVENTS_LOCKTYPE  EventsFlags,
    IN PVOID  EventsLock
    );

Parameters

FileObject
Specifies the file object passed to the removal function for context information. The file object associated is used to compare against the file object originally specified when enabling the event. This allows a single event list to be used for multiple clients differentiated by file objects.
EventsList
Points to the head of the list of KSEVENT_ENTRY items to be freed. If any events on the list are currently being disabled, they are passed over. If any new elements are added to the list while it is being processed, they may not be freed.
EventsFlags
Specifies a KSEVENTS_LOCKTYPE flag specifying the type of exclusion lock to be used in accessing the event list. If no flag is set, then no lock is taken.
EventsLock
Used to synchronize access to an element on the list. After the element has been accessed, it is marked as being deleted so subsequent removal requests fail. The lock is then released after calling the removal function, if any. The removal function must synchronize with event generation before actually removing the element from the list.

Return Values

None

Comments

The KsFreeEventList function calls the remove handler, then it calls KsDiscardEvent for each event. It does not assume that the caller is the event owner.

See Also

Event Set Functions, KsDiscardEvent


KsGenerateDataEvent

The KsGenerateDataEvent function generates one of the standard event notifications when given an event entry structure and callback data. This allows a device to determine when event notifications should be generated, yet still use this helper function to perform the actual notification. This function may be called at IRQL level.

KSDDKAPI NTSTATUS NTAPI
  KsGenerateDataEvent(
    IN PKSEVENT_ENTRY  EventEntry,
    IN ULONG  DataSize,
    IN PVOID  Data
    );

Parameters

EventEntry
Specifies the event entry structure that references the event data. The information is used to determine what type of notification to perform. If the notification type is not one of the predefined standards, an error is returned. In the case of a single, nonrecurring event, this entry will be invalid when returned from the function. Therefore, any code that enumerates a list of events must pre-increment to acquire the next event in the list before passing this event to the function.
DataSize
Specifies the size in bytes of the Data parameter passed.
Data
Points to data to be passed to the client callback. This data is copied to one of the preallocated buffer slots set up when the event was enabled. The size of the data must be less than whatever was originally allocated or the event will fail.

Return Values

The KsGenerateDataEvent function returns STATUS_SUCCESS if successful, or if unsuccessful it returns an exception or memory error.

Comments

It is assumed that the event list lock has been acquired before this function is called. This function can result in a call to the RemoveHandler for the event entry. Therefore, the function must not be called at higher than the IRQ level of the lock, or the Remove function must be able to handle being called at such an IRQ level.

This function is specifically for events that pass data back through a callback to a client.

See Also

Event Set Functions


KsGenerateEvent

The KsGenerateEvent function generates a standard event notification given an event entry structure. A device determines when event notifications are generated using the KSEVENT_ENTRY structure, then uses this function to perform the actual notification. This function can be called at IRQL level.

KSDDKAPI NTSTATUS NTAPI
  KsGenerateEvent(
    IN PKSEVENT_ENTRY  EventEntry
    );

Parameters

EventEntry
Specifies the event entry structure that references the event data. The information is used to determine what type of notification to perform. If the notification type is not one of the predefined standards, an error is returned. In the case of a single, nonrecurring event, this entry will be invalid on returning from the function. Therefore, any code that enumerates a list of events must pre-increment to acquire the next event in the list before passing this event to the function.

Return Values

The KsGenerateEvent function returns STATUS_SUCCESS if successful, or if unsuccessful it returns an exception or memory error.

See Also

Event Set Functions


KsGenerateEventList

The KsGenerateEventList function enumerates the event list and searches for the specified event to generate. It can be called at IRQL level if the locking mechanism permits it.

KSDDKAPI VOID NTAPI
  KsGenerateEventList(
    IN GUID*  Set OPTIONAL,
    IN ULONG  EventId,
    IN PLIST_ENTRY  EventsList,
    IN KSEVENTS_LOCKTYPE  EventsFlags,
    IN PVOID  EventsLock
    );

Parameters

Set
Specifies an optional set that the event to be generated belongs to. If present, this value is compared against the set identifier for each event in the list. If not present, the set identifiers are ignored and just the specific event identifier is used in the comparison for matching events on the list. This comparison saves time when all events are known to be contained in a single set.
EventId
Specifies the specific event identifier to look for on the list.
EventsList
Points to the head of the list of KSEVENT_ENTRY items on which the event can be found.
EventsFlags
Specifies the KSEVENTS_LOCKTYPE flag specifying the exclusion lock type to be used in accessing the event list. See KSEVENTS_LOCKTYPE for more information. If no flag is set, then no lock is taken.
EventsLock
Used to synchronize access to an element on the list. The lock is taken before enumerating the list and released after enumeration.

Return Values

None

See Also

Event Set Functions


Connection Functions

Several WDM Streaming functions assist with creating and destroying connections. The following functions are provided:

KsCreatePin

KsValidateConnectRequest

KsPinPropertyHandler

KsPinDataIntersection

KsHandleSizedListQuery

For more information on functions that handle IRPs, see the IRP Management Functions.


KsCreatePin

The KsCreatePin function passes a connection request to a device, creating a pin instance. This function can only be called at PASSIVE_LEVEL for kernel-mode clients.

KSDDKAPI NTSTATUS NTAPI
  KsCreatePin(
    IN HANDLE  FilterHandle,
    IN PKSPIN_CONNECT  Connect,
    IN ACCESS_MASK  DesiredAccess,
    OUT PHANDLE  PinHandle
    );

Parameters

FilterHandle
Specifies the handle of the filter initiating the create request and where the connection will occur.
Connect
Specifies a system address that is the connection information. This should be followed in memory by a KSDATAFORMAT data structure, describing the data format requested for the connection.
DesiredAccess
Specifies the access desired to the pin. This is typically FILE_READ_ACCESS or FILE_WRITE_ACCESS. For data flowing into the pin this value should be set to FILE_WRITE_ACCESS, and for data flowing out of the pin this should be set to FILE_READ_ACCESS regardless of the communication method.
ConnectionHandle
Specifies the connection handle passed. The routine fills this in with a handle to the file object of the created connection. This value can then be used to disconnect with CloseHandle.

Return Values

The KsCreatePin function returns STATUS_SUCCESS if the connection was successful, or it returns an error if the connection failed.

Comments

The routine sends a IRP_MJ_CREATE request to the driver. The driver accepts the request only if the interface, medium, and data format are compatible

If Connect->PinToHandle is NULL, KsCreatePin creates a pin the caller can use to send requests to the streaming driver specified in Connect->FilterHandle.. Connect->PinId determines the pin type of the pin to be created.


KsHandleSizedListQuery

The KsHandleSizedListQuery function, depending on the length of the system buffer, returns either the size of the buffer needed, number of entries in the specified data list, or copies the entries themselves. This assumes the structure of KSMULTIPLE_ITEM to be a Size followed by a Count.

KSDDKAPI NTSTATUS NTAPI
  KsHandleSizedListQuery(
    IN PIRP  Irp,
    IN ULONG  DataItemsCount,
    IN ULONG  DataItemSize,
    IN const VOID*  DataItems
    );

Parameters

Irp
Specifies the IRP with the identifier list request.
DataItemsCount
Specifies the number of items in the identifier list.
DataItemSize
Specifies the size of a data item.
DataItems
Specifies the list of data items.

Return Values

The KsHandleSizedListQuery function returns STATUS_SUCCESS if the number of entries and the data can be copied. If the buffer is larger than the size to store just the size and the count of entries but too small to contain all the entries, the function returns status STATUS_BUFFER_TOO_SMALL.

Comments

Use the KsHandleSizedListQuery function when implementing properties that are to return information in the multiple item format.


KsPinDataIntersection

The KsPinDataIntersection function handles the KSPROPERTY_PIN_KSNproperty, through a callback, and performs much of the initial validation of the parameters passed. The function also calls the intersection handler function with each potential data range after matching it to the list of data ranges assigned to that pin factory.

KSDDKAPI NTSTATUS NTAPI
  KsPinDataIntersection(
    IN PIRP  Irp,
    IN PKSP_PIN  Pin,
    OUT PVOID  Data,
    IN ULONG  DescriptorsCount,
    IN const KSPIN_DESCRIPTOR*  Descriptor,
    IN PFNKSINTERSECTHANDLER  IntersectHandler
    );

Parameters

Irp
Specifies the IRP handling the property request.
Pin
Specifies the specific property being queried.
Data
Specifies the pin property specific data.
DescriptorsCount
Indicates the number of descriptor structures.
Descriptor
Specifies the pointer to the list of pin information structures.
IntersectHandler
Specifies the handler for comparison of a data range. For more information, see the Comments section.

Return Values

The KsPinDataIntersection function returns STATUS_SUCCESS if a matching range is found, STATUS_NO_MATCH if no matching range was found, or an error specific to the property being handled.The intersection handler provided to KsPinDataIntersection is called with each data range supplied by the caller until either a match is found, or an error occurs.

Note that the intersection handler function has its own set of return values, as described in the following text.

Comments

A match can occur under three conditions: if the major format of the range passed is a wildcard or matches a pin factory range, if the sub-format is a wildcard or matches, and if the specifier is a wildcard or matches. Since the data range size may be variable, it is not validated beyond checking that it is at least the size of a data range structure.

The intersection handler function is as follows:

typedef NTSTATUS (*PFNKSINTERSECTHANDLER)(
  IN PIRP Irp,
  IN PKSP_PIN Pin,
  IN PKSDATARANGE DataRange,
  OUT PVOID Data
  );

Parameters

Irp
Specifies the IRP handling the property request.
Pin
Specifies the specific property being queried and the pin factory identifier that has been validated.
DataRange
Specifies the current data range to compare. The data range has been validated as either matching a particular range on the pin or as a wildcard match.
Data
Specifies the data format returned, or the size of the data format.

Return Values

Returns STATUS_SUCCESS if the range matched and data was returned, or STATUS_NO_MATCH if the range did not match, or an error. On a STATUS_NO_MATCH, the calling function continues with the next data range, if any.


KsPinPropertyHandler

The KsPinPropertyHandler function performs standard handling of the static members of the KSPROPSETID_Pin property set. This handling does not include KSPROPERTY_PIN_CINSTANCES or KSPROPERTY_PIN_DATAINTERSECTION.

KSDDKAPI NTSTATUS NTAPI
  KsPinPropertyHandler(
    IN PIRP  Irp,
    IN PKSPROPERTY  Property,
    IN OUT PVOID  Data,
    IN ULONG  DescriptorsCount,
    IN const KSPIN_DESCRIPTOR*  Descriptor
    );

Parameters

Irp
Specifies the IRP handling the connection request.
Property
Specifies the specific property information.
Data
Specifies the data parameter mapped to a system address. This is the same parameter passed to a property handler through a KsPropertyHandler callback.
DescriptorsCount
Specifies the number of pin descriptors being passed.
Descriptor
Specifies the pointer to the list of pin descriptors.

Return Values

The KsPinPropertyHandler function returns STATUS_SUCCESS or an error specific to the property being handled. The function fills in the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP. It does not set the IO_STATUS_BLOCK.Status field nor complete the IRP.

Comments

Do not use the KsPinPropertyHandler function to define a pin property set; a pin property set can be more easily defined using the DEFINE_KSPROPERY_PINSET macro.


KsValidateConnectRequest

The KsValidateConnectRequest function validates the structures passed to IRP_MJ_CREATE and returns a pointer to the connection structure and the root file object.

This function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsValidateConnectRequest(
    IN PIRP  Irp,
    IN ULONG  DescriptorsCount,
    IN KSPIN_DESCRIPTOR*  Descriptor,
    OUT PKSPIN_CONNECT*  Connect
    );

Parameters

Irp
Specifies the IRP handling the create request.
DescriptorsCount
Specifies the number of pin descriptors passed.
Descriptor
Specifies a pointer to the list of pin descriptors.
Connect
Specifies the returned connection structure.

Return Values

The KsValidateConnectRequest function returns STATUS_SUCCESS if successful, or it returns an error.

Comments

The KsValidateConnectRequest function handles basic connection structure access exceptions and validates the communication requirements, medium, protocol, and basic data format. The validation performed on the data format passed is based on the data range list for the specified pin against which a pin instance is to be created. Validation is successful in three instances: if a range major format is a wildcard, the range major format matches and the range sub-format is a wildcard, or the range major format, range sub-format, and the range specifier all match.

The buffer is passed a copy of the original input buffer, if the originator was not in kernel mode, and is therefore safe to access.


Topology Management Functions

Various functions can be used to assist with topology management, including:

KsCreateTopologyNode

KsValidateTopologyNodeCreateRequest

KsTopologyPropertyHandler


KsCreateTopologyNode

The KsCreateTopologyNode function creates a handle to a topology node instance. The function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsCreateTopologyNode(
    IN HANDLE  ParentHandle,
    IN PKSNODE_CREATE  NodeCreate,
    IN ACCESS_MASK  DesiredAccess,
    OUT PHANDLE  NodeHandle
    );

Parameters

ParentHandle
Specifies the handle to the parent on which the node is created.
NodeCreate
Specifies topology node create parameters.
DesiredAccess
Specifies the desired access to the object. This is typically GENERIC_READ and/or GENERIC_WRITE.
NodeHandle
Location for the topology node handle.

Return Values

Returns STATUS_SUCCESS, or an error if unable to create a node.

Comments

The KSNODE_CREATE structure describes the set of information used to create the node handle.

typedef struct {
  ULONG  CreateFlags;
  ULONG  Node;
} KSNODE_CREATE;

Parameters

CreateFlags
Always set to zero.
Node
Specifies that node a handle should be created for. This refers to the node identifiers returned when querying topology information.


KsTopologyPropertyHandler

The KsTopologyPropertyHandler function performs standard handling of the static members of the KSPROPSETID_Topology Property Set. The function uses the KSTOPOLOGY structure, which describes the set of information that is returned by this property set.

KSDDKAPI NTSTATUS NTAPI
  KsTopologyPropertyHandler(
    IN PIRP  Irp,
    IN PKSPROPERTY  Property,
    IN OUT PVOID  Data,
    IN const KSTOPOLOGY*  Topology
    );

Parameters

Irp
Specifies the IRP handling the property request.
Property
Specifies the specific property being queried.
Data
Specifies the topology property-specific data.
Topology
Points to a KSTOPOLOGY structure containing the topology information.

Return Values

The KsTopologyPropertyHandler function returns STATUS_SUCCESS if successful, or it returns an error specific to the property being handled. The function always fills in the IO_STATUS_BLOCK.Information field of the PIRP.IoStatus element within the IRP. It does not set the IO_STATUS_BLOCK.Status field, nor does it complete the IRP.


KsValidateTopologyNodeCreateRequest

The KsValidateTopologyNodeCreateRequest function validates a topology node creation request and returns the create structure associated with the request. The function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsValidateTopologyNodeCreateRequest(
    IN PIRP  Irp,
    IN PKSTOPOLOGY  Topology,
    OUT PKSNODE_CREATE*  NodeCreate
    );

Parameters

Irp
Specifies the IRP with the node create request being handled.
Topology
Specifies the topology structure associated with the parent object. This is used to validate the create request.
NodeCreate
Location for the node create structure pointer passed to the create request.

Return Values

The KsValidateTopologyNodeCreateRequest function returns a STATUS_SUCCESS if successful, or else an error if unsuccessful.


IRP Management Functions

IRP management functions assist in the general handling of IRPs. They include, alphabetically:

KsAcquireResetValue

KsAddIrpToCancelableQueue

KsAddObjectCreateItemToDeviceHeader

KsAddObjectCreateItemToObjectHeader

KsAllocateDeviceHeader

KsAllocateExtraData

KsAllocateObjectCreateItem

KsAllocateObjectHeader

KsCancelIo

KsCancelRoutine

KsDefaultDeviceIoCompletion

KsDispatchFastIoDeviceControlFailure

KsDispatchFastReadFailure

KsDispatchFastWriteFailure

KsDispatchInvalidDeviceRequest

KsDispatchSpecificMethod

KsDispatchSpecificProperty

KsFreeDeviceHeader

KsFreeObjectHeader

KsGetChildCreateParameter

KsMoveIrpsOnCancelableQueue

KsProbeStreamIrp

KsQueryInformationFile

KsQueryObjectAccessMask

KsQueryObjectCreateItem

KsReadFile

KsReleaseIrpOnCancelableQueue

KsRemoveIrpFromCancelableQueue

KsRemoveSpecificIrpFromCancelableQueue

KsSetInformationFile

KsSetMajorFunctionHandler

KsStreamIo

KsWriteFile


KsAcquireResetValue

The KsAcquireResetValue function retrieves the current reset state from a IOCTL_KS_RESET IRP.

KSDDKAPI NTSTATUS NTAPI
  KsAcquireResetValue(
    IN PIRP  Irp,
    OUT KSRESET*  ResetValue
    );

Parameters

Irp
Points to the IRP from which to retrieve the reset state.
ResetValue
Points to a caller-allocated buffer, that on successful completion contains the reset value (KSRESET_BEGIN, KSRESET_END) associated with the Irp

Return Values

The KsAcquireResetValue function returns STATUS_SUCCESS if the reset value was obtained.


KsAddIrpToCancelableQueue

The KsAddIrpToCancelableQueue function adds an IRP to a queue of cancellable IRPs, thus allowing the IRP to be canceled. If the IRP had been previously set to a canceled state, the KsAddIrpToCancelableQueue function completes the canceling of that IRP.

KSDDKAPI VOID NTAPI
  KsAddIrpToCancelableQueue(
    IN OUT PLIST_ENTRY  QueueHead,
    IN PKSPIN_LOCK  SpinLock,
    IN PIRP  Irp,
    IN KSLIST_ENTRY_LOCATION  ListLocation,
    IN PDRIVER_CANCEL  DriverCancel  OPTIONAL
    );

Parameters

QueueHead
Specifies the driver-allocated storage for the head of the queue on which to add the IRP.
SpinLock
Points to driver’s spin lock for queue access to the queue specified at QueueHead. A copy of this pointer is kept in the IRP’s KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) for use by the cancel routine, if necessary.
Irp
Specifies the IRP to add to the queue specified at QueueHead.
ListLocation
Indicates whether this IRP should be placed at the beginning or end of the queue. This value must be KsListEntryTail or KsListEntryHead.
DriverCancel
Optional parameter that specifies a driver-supplied cancel routine to use. If this is NULL, the standard KsCancelRoutine is used.

Return Values

None

Comments

If the IRP has been put into a cancel state when this routine is called, KsAddIrpToCancelableQueue will immediately call the cancel routine specified at DriverCancel, or if no routine was specified at DriverCancel the default streaming cancel routine is called.

The KsAddIrpToCancelableQueue function allows IRPs to be canceled even before being placed on a cancel list, or when being moved from one list to another. This function can be called at IRQ level DISPATCH_LEVEL or lower unless the driver-allocated queue and all entries in the queue are system-resident or allocated from resident storage.

The function does not use the cancel spinlock to add items to the list. Access to the list is synchronized using the provided spinlock and relies on atomic operations on Irp->CancelRoutine.


KsAddObjectCreateItemToDeviceHeader

The KsAddObjectCreateItemToDeviceHeader function adds the specified create-item to an empty item in the previously allocated create item list for this device header. An empty item is signified by a NULL create dispatch function in the entry. This function assumes that the caller is serializing multiple changes to the create items list.

KSDDKAPI NTSTATUS NTAPI
  KsAddObjectCreateItemToDeviceHeader(
    IN KSDEVICE_HEADER  Header,
    IN PDRIVER_DISPATCH  Create,
    IN PVOID  Context,
    IN PWCHAR  ObjectClass,
    IN PSECURITY_DESCRIPTOR  SecurityDescriptor
    );

Parameters

Header
Points to the device header that contains the previously allocated child create table.
Create
Specifies the create dispatch function.
Context
Specifies the context parameter.
ObjectClass
Specifies a pointer to a NULL-terminated character string that will be used for comparison on create requests. This pointer must remain valid while the device object is active.
SecurityDescriptor
Specifies the security descriptor. This must remain valid while the device object is active.

Return Values

The KsAddObjectCreateItemToDeviceHeader function returns STATUS_SUCCESS if an empty create item slot was found and the item was added.If unsuccessful, it returns STATUS_ALLOTTED_SPACE_EXCEEDED.


KsAddObjectCreateItemToObjectHeader

The KsAddObjectCreateItemToObjectHeader function adds the specified create-item to an empty item in the previously allocated create item list for this object header. An empty item is signified by a NULL create dispatch function in the entry. This function assumes that the caller is serializing multiple changes to the create items list.

KSDDKAPI NTSTATUS NTAPI
  KsAddObjectCreateItemToObjectHeader(
    IN KSOBJECT_HEADER  Header,
    IN PDRIVER_DISPATCH  Create,
    IN PVOID  Context,
    IN PWCHAR  ObjectClass,
    IN PSECURITY_DESCRIPTOR  SecurityDescriptor
    );

Parameters

Header
Points to the object header that contains the previously allocated child- create table.
Create
Specifies the create dispatch function to use.
Context
Specifies the context parameter.
ObjectClass
Specifies a pointer to a NULL-terminated character string that is used for comparison on create requests. This pointer must remain valid while the object is active.
SecurityDescriptor
Specifies the security descriptor. This must remain valid while the object is active.

Return Values

The KsAddObjectCreateItemToObjectHeader function returns STATUS_SUCCESS if an empty create item slot was found and the item was added. If unsuccessful, it returns STATUS_ALLOTTED_SPACE_EXCEEDED.


KsAllocateDeviceHeader

The KsAllocateDeviceHeader function allocates and initializes the required device extension header.

KSDDKAPI NTSTATUS NTAPI
  KsAllocateDeviceHeader(
    OUT PVOID  Header,
    IN ULONG  ItemsCount,
    IN PKSOBJECT_CREATE_ITEM  ItemsList  OPTIONAL
    );

Parameters

Header
Points to the location in which to return a pointer to the initialized header.
ItemsCount
Specifies the number of sub-items in the ItemsList. This should be zero if an ItemsList is not passed.
ItemsList
Optional. Points to a KSOBJECT_CREATE_ITEM structure for each sub-item. If there are no sub-items, this value should be NULL and ItemsCount should be zero.

Return Values

The KsAllocateDeviceHeader function returns STATUS_SUCCESS if successful or STATUS_INSUFFICIENT_RESOURCES if unable to allocate the necessary resources.

Comments

The KsAllocateDeviceHeader function allocates memory for the KSDEVICE_HEADER structure for a device. When the header is no longer needed, the driver should call the KsFreeDeviceHeader function to free the memory allocated.

If sub-objects exist for a given device, the driver must, before calling KsAllocateDeviceHeader, allocate a buffer of either paged or nonpaged memory of sufficient size to hold a KSOBJECT_CREATE_ITEM structure for each sub-object. For example:

/* Allocate a buffer for 4 sub-objects for a given streaming device */
PKSOBJECT_CREATE_ITEM createBuffer ;
ULONG bufferSize  = (sizeof (KSOBJECT_CREATE_ITEM)) * 4 ;

createBuffer = (PKSOBJECT_CREATE_ITEM)
               ExAllocatePool (PagedPool, bufferSize) ;

Drivers must not free the memory allocated for the sub-object KSOBJECT_CREATE_ITEM list until after calling KsFreeDeviceHeader. Failure to do so can result in a bug check condition.

Callers of the routine must be running at IRQL < DISPATCH_LEVEL.

See Also

KsFreeDeviceHeader, KSOBJECT_CREATE_ITEM


KsAllocateExtraData

The KsAllocateExtraData function is used with streaming IRPs to allocate a buffer to contain additional header data. A pointer to the allocated buffer is returned, and the buffer must eventually be freed by the caller. The function must be called at IRQL < DISPATCH_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsAllocateExtraData(
    IN PIRP  Irp,
    IN ULONG  ExtraSize,
    OUT PVOID*  ExtraBuffer
    );

Parameters

Irp
Specifies the IRP containing the stream headers. The IRP must have been previously passed to KsProbeStreamIrp to buffer the headers.
ExtraSize
Specifies the size, in bytes, of additional memory to allocate between each stream header. This value must be alignable on an eight-byte boundary. A copy of the headers is placed in the returned buffer, with the extra data size inserted between each header. This must be freed by the caller.
ExtraBuffer
Points to a caller-allocated pointer that, on successful completion, points to a system-allocated buffer containing the stream headers and the requested padding between them. This must be freed by the caller.

Return Values

The KsAllocateExtraData function returns STATUS_SUCCESS if successful, or it returns a resource or access error.

Comments

When KsAllocateExtraData completes successfully, a pointer to a block of memory is returned that contains both the stream data headers from the IRP, specified at Irp, and padding between each header of size specified in ExtraSize. An example of such a resultant buffer is shown below:

When the extra buffer is no longer needed, the memory should be freed using ExFreePool.


KsAllocateObjectCreateItem

The KsAllocateObjectCreateItem function allocates a slot for the specified create item, optionally allocating space for and copying the create item data as well. This function assumes that the caller is serializing multiple changes to the create entry list.

KSDDKAPI NTSTATUS NTAPI
  KsAllocateObjectCreateItem(
    IN KSDEVICE_HEADER  Header,
    IN PKSOBJECT_CREATE_ITEM  CreateItem,
    IN BOOL AllocateEntry,
    IN PFNKSITEMFREECALLBACK  ItemFreeCallback  OPTIONAL
    );

Parameters

Header
Points to the device header on which to attach the create item.
CreateItem
Contains the create item to attach.
AllocateEntry
Indicates whether the create item pointer passed should be attached directly to the header, or if a copy of it should be made instead.
ItemFreeCallback
Optionally contains a pointer to a callback function that is called when the create entry is being destroyed upon freeing the device header. This is only valid when AllocateEntry is TRUE.

Return Values

Returns STATUS_SUCCESS if a new item was allocated and attached. Otherwise, it returns STATUS_INSUFFICIENT_RESOURCES.

Comments

The PFNKSITEMFREECALLBACK is a method that should be called when freeing an allocated create item. It allows the client to perform any cleanup, including flushing security descriptor changes, which would be indicated by the flags set in the create item structure.

typedef NTSTATUS (*PFNKSITEMFREECALLBACK)(
  IN PKSOBJECT_CREATE_ITEM  CreateItem
    );

Parameters

CreateItem
Contains the create item that was previously allocated during the KsAllocateObjectCreteItem call. The Context parameter of this item must contain sufficient information to perform cleanup for this create item.

Return Values

The PFNKSITEMFREECALLBACK function returns STATUS_SUCCESS if the item was successfully freed. Otherwise, an appropriate error code is returned.


KsAllocateObjectHeader

The KsAllocateObjectHeader function initializes the required file context header.

KSDDKAPI NTSTATUS NTAPI
  KsAllocateObjectHeader(
    OUT PVOID  Header,
    IN ULONG  ItemsCount,
    IN PKSOBJECT_CREATE_ITEM  ItemsList  OPTIONAL,
    IN PIRP Irp,
    IN KSDISPATCH_TABLE*  Table
    );

Parameters

Header
Points to the caller-allocated location in which to return a pointer to the initialized KSOBJECT_HEADER if successful.
ItemsCount
Specifies the number of object create items in the ItemsList to be added to the object header once the header is allocated. This value should be zero if ItemsList is NULL.
ItemsList
Optionally specifies a pointer to a caller-allocated buffer containing a series of KSOBJECT_CREATE_ITEM structures to be dded to the object header. Must be set to NULL if there are no object create items.
Irp
Points to the IRP, of major function IRP_MJ_CREATE, that contains the necessary information to complete the creation of the object header.
Table
Points to an initialized dispatch table for this file object.

Return Values

The KsAllocateObjectHeader function returns STATUS_SUCCESS if successful or STATUS_INSUFFICIENT_RESOURCES if not enough resources are available to fulfill the request.

Comments

Before calling this routine the driver must allocate system-resident storage for a KSDISPATCH_TABLE and initialize the dispatch table. The memory for this dispatch table cannot be released until KsFreeObjectHeader is called.

KsAllocateObjectHeader allocates the memory for the KSOBJECT_HEADER structure and returns a pointer to the header at Header. Drivers must not attempt to free the memory themselves, but rather call KsFreeObjectHeader when all operations requiring this object header have been completed.

If sub-objects exist for a given device, the driver must, before calling KsAllocateObjectHeader, allocate a buffer of either paged or nonpaged memory of sufficient size to hold a KSOBJECT_CREATE_ITEM structure for each sub-object. For example:

/* Allocate a buffer for 4 sub-objects for a given streaming device */
PKSOBJECT_CREATE_ITEM createBuffer ;
ULONG bufferSize  = (sizeof (KSOBJECT_CREATE_ITEM)) * 4 ;

createBuffer = (PKSOBJECT_CREATE_ITEM)
               ExAllocatePool (PagedPool, bufferSize) ;

Drivers must not free the memory allocated for the sub-object KSOBJECT_CREATE_ITEM list until after calling KsFreeDeviceHeader. Failure to do so can result in a bug check condition.

Callers of this routine must be running at IRQL < DISPATCH_LEVEL.

See Also

KsFreeObjectHeader, KSOBJECT_CREATE_ITEM

KsFreeDeviceHeader


KsCancelIo

The KsCancelIo function cancels all IRPs on the specified cancel list. If an IRP on the list does not have a cancel routine, only the cancel bit is set in the IRP. The function can be called at IRQ level DISPATCH_LEVEL or lower.

KSDDKAPI VOID NTAPI
  KsCancelIo(
    IN OUT PLIST_ENTRY  QueueHead,
    IN PKSPIN_LOCK  SpinLock
    );

Parameters

QueueHead
Specifies the head of a driver-maintained queue containing the IRP's to be cancelled.
SpinLock
Points to a caller-allocated spin lock for queue access. A copy of this pointer is kept in the IRP’s KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) for use by the cancel routine, if necessary.

Comments

KsCancelIo cancels all IRPs in a given driver-maintained queue. If the IRP has a cancel routine, the cancel routine is called. Otherwise, the cancel flag in the IRP is set to TRUE. The IRPs are not removed from the queue by this routine. It is the sole responsibility of the driver to ensure that the IRPs are removed either by the cancel routine specified in the IRP or by some other driver-supplied functionality.

If the IRP being cancelled has a driver-supplied cancel routine, the cancel spin lock can be obtained from the IRP by calling KSQUEUE_SPINLOCK_IRP_STORAGE.

See Also

KsAddIrpToCancelableQueue, KSQUEUE_SPINLOCK_IRP_STORAGE

Return Values

None


KsCancelRoutine

The KsCancelRoutine function performs standard IRP cancel functionality: it removes the entry and then cancels and completes the request. The function is defined as a PDRIVER_CANCEL routine. It is the default function used for KsAddIrpToCancelableQueue if none is provided.

KSDDKAPI VOID NTAPI
  KsCancelRoutine(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the device object that owns the IRP.
Irp
Specifies the IRP being canceled.

Return Values

None

Comments

This function would typically be called by the I/O subsystem on canceling an IRP but can be called directly in response to an KSMETHOD_STREAM_PRESENTATION Set request. As with any typical cancel routine, this function expects the I/O cancel spin lock to have been acquired upon entering the function.

Note that this routine expects the KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) to point to the list access spinlock as provided in KsAddIrpToCancelableQueue.

KsCancelRoutine can be used to do the preliminary list removal processing, without actually completing the IRP. If the Irp->IoStatus.Status is set to STATUS_CANCELLED on entering this function, then the IRP will not be completed. Otherwise, the status will be set to STATUS_CANCELLED and the IRP will be completed. This KsCancelRoutine can be used within a cancel routine to do the initial list and spinlock manipulation and return to the driver's completion routine to do specific processing and final IRP completion.

See Also

KsAddIrpToCancelableQueue


KsDefaultDeviceIoCompletion

The KsDefaultDeviceIoCompletion function is used to return a default response and to complete any device I/O control. It can be used in the KSDISPATCH_TABLE and as the default response to unknown Ioctl's. It is important to use this function so that queries such as property requests return the correct value rather than just STATUS_INVALID_DEVICE_REQUEST when properties are not support for instance.

KSDDKAPI NTSTATUS NTAPI
  KsDefaultDeviceIoCompletion(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the device object dispatched to.
Irp
Specifies the IRP to return a default response to.

Return Values

The KsDefaultDeviceIoCompletion function returns the default response to the possible IOCTLs.

Comments

Note that this routine will complete the IRP.


KsDefaultForwardIrp

This default handler allows dispatch routines to forward I/O requests to corresponding Physical Device Objects.

KSDDKAPI ULONG NTAPI
KsDecrementCountedWorker(
    IN PKSWORKER Worker
    );

Parameters

Worker
Contains the previously allocated worker.

Return Values

Returns the status of the underlying Physical Device Object IRP processing.

Comments

This default handler provides a way for dispatch routines to fulfill the requirement that a driver have an IRP_MJ_* function handler for specific major functions.


KsDispatchFastIoDeviceControlFailure

The KsDispatchFastIoDeviceControlFailure function is used in a KSDISPATCH_TABLE.FastDeviceIoControl entry that are not handled. The function should always return FALSE.

KSDDKAPI BOOLEAN NTAPI
  KsDispatchFastIoDeviceControlFailure(
    IN PFILE_OBJECT  FileObject,
    IN BOOLEAN  Wait,
    IN PVOID  InputBuffer  OPTIONAL,
    IN ULONG  InputBufferLength,
    OUT PVOID  OutputBuffer  OPTIONAL,
    IN ULONG  OutputBufferLength,
    IN ULONG  IoControlCode,
    OUT PIO_STATUS_BLOCK  IoStatus,
    IN PDEVICE_OBJECT  DeviceObject
    );

Parameters

FileObject
Not used.
Wait
Not used.
InputBuffer
Not used.
InputBufferLength
Not used.
OutputBuffer
Not used.
OutputBufferLength
Not used.
IoControlCode
Not used.
IoStatus
Not used.
DeviceObject
Not used.

Return Values

The KsDispatchFastIoDeviceControlFailure function returns FALSE.

Comment

The KsDispatchFastIoDeviceControlFailure function is needed since the dispatch table for a particular opened instance of a device may not handle a specific major function that another opened instance needs to handle. Therefore, the function pointer in the driver object must always point to a function, such as the KsDispatchFastIoDeviceControlFailure function, that calls a dispatch table entry.


KsDispatchFastReadFailure

The KsDispatchFastReadFailure function is used in a KSDISPATCH_TABLE.FastRead entry when fast I/O read is not handled. The function should always return FALSE.

KSDDKAPI BOOLEAN NTAPI
  KsDispatchFastReadFailure(
    IN PFILE_OBJECT  FileObject,
    IN PLARGE_INTEGER  FileOffset,
    IN ULONG  Length,
    IN BOOLEAN  Wait,
    IN ULONG  LockKey,
    OUT PVOID  Buffer,
    OUT PIO_STATUS_BLOCK  IoStatus,
    IN PDEVICE_OBJECT  DeviceObject
    );

Parameters

FileObject
Not used.
FileOffset
Not used.
Length
Not used.
Wait
Not used.
LockKey
Not used.
Buffer
Not used.
IoStatus
Not used.
DeviceObject
Not used.

Return Values

The KsDispatchFastReadFailure function returns FALSE.

Comment

The KsDispatchFastReadFailure function is needed since the dispatch table for a particular opened instance of a device may not handle a specific major function that another opened instance needs to handle. Therefore, the function pointer in the driver object must always point to a function, such as the KsDispatchFastReadFailure function, that calls a dispatch table entry.


KsDispatchFastWriteFailure

The KsDispatchFastWriteFailure function is used in a KSDISPATCH_TABLE.FastWrite entry when fast I/O is not handled for a write operation. The function should always return FALSE.

KSDDKAPI BOOLEAN NTAPI
  KsDispatchFastReadFailure(
    IN PFILE_OBJECT  FileObject,
    IN PLARGE_INTEGER  FileOffset,
    IN ULONG  Length,
    IN BOOLEAN  Wait,
    IN ULONG  LockKey,
    IN PVOID  Buffer,
    OUT PIO_STATUS_BLOCK  IoStatus,
    IN PDEVICE_OBJECT  DeviceObject
    );

Parameters

FileObject
Not used.
FileOffset
Not used.
Length
Not used.
Wait
Not used.
LockKey
Not used.
Buffer
Not used.
IoStatus
Not used.
DeviceObject
Not used.

Return Values

The KsDispatchFastWriteFailure function returns FALSE.

Comment

The KsDispatchFastWriteFailure function is needed since the dispatch table for a particular opened instance of a device may not handle a specific major function that another opened instance needs to handle. Therefore, the function pointer in the driver object must always point to a function, such as the KsDispatchFastWriteFailure function, that calls a dispatch table entry.


KsDispatchInvalidDeviceRequest

The KsDispatchInvalidDeviceRequest function is used in KSDISPATCH_TABLE entries that are not handled and that need to return STATUS_INVALID_DEVICE_REQUEST.

KSDDKAPI NTSTATUS NTAPI
  KsDispatchInvalidDeviceRequest(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the device object associated with the IRP.
Irp
Specifies the IRP that is not being handled.

Return Values

The KsDispatchInvalidDeviceRequest function returns STATUS_INVALID_DEVICE_REQUEST and completes the IRP.

Comments

The KsDispatchInvalidDeviceRequest function is needed because the dispatch table for an opened instance of a device may not handle a specific major function that another opened instance needs to handle. Therefore, the function pointer in the driver object must always point to a function that calls a dispatch table entry.

See Also

KsDispatchFastIoDeviceControlFailure, KsDispatchFastWriteFailure, KsDispatchFastReadFailure


KsDispatchSpecificMethod

The KsDispatchSpecificMethod function dispatches a method to a specific handler. The function assumes that the caller has previously dispatched the IRP to a handler through the KsMethodHandler function.

The function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsDispatchSpecificMethod(
    IN PIRP  Irp,
    IN PFNKSHANDLER  Handler
    );

Parameters

Irp
Specifies the IRP with the method request being dispatched.
Handler
Specifies the pointer to the specific method handler.

Return Values

The KsDispatchSpecificMethod function returns STATUS_SUCCESS if successful, or if unsuccessful it returns an error.

Comments

The KsDispatchSpecificMethod function is intended for additional processing of the method such as completing a pending operation.

See Also

KsMethodHandler


KsDispatchSpecificProperty

The KsDispatchSpecificProperty function dispatches the property to a specific handler. The function assumes that the caller has previously dispatched this IRP to a handler through the KsPropertyHandler function.

This function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsDispatchSpecificProperty(
    IN PIRP  Irp,
    IN PFNKSHANDLER  Handler
    );

Parameters

Irp
Specifies the IRP with the property request being dispatched.
Handler
Specifies the pointer to the specific property handler.

Return Values

The KsDispatchSpecificProperty function returns STATUS_SUCCESS if successful, or if unsuccessful it returns an error.

Comments

The KsDispatchSpecificProperty function is intended for additional processing of a property such as completing a pending operation.

See Also

KsPropertyHandler


KsForwardAndCatchIrp

The KsForwardAndCatchIrp function forwards an IRP to the specified driver after initializing the next stack location, and regains control of the IRP on completion from that driver. The function is used with devices that can be stacked and do not use file objects to communicate.

If a file object is being used, the caller must initialize the current stack location with that file object before calling the KsForwardAndCatchIrp function. The function verifies that there is a new stack location to copy into before attempting to do so. If there is not a new stack location, the function returns STATUS_INVALID_DEVICE_REQUEST. Regardless of whether a new stack location is present, the IRP is not completed.

KSDDKAPI NTSTATUS NTAPI
  KsForwardAndCatchIrp(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp,
    IN PFILE_OBJECT  FileObject,
    IN KSSTACK_USE  StackUse
    );

Parameters

DeviceObject
Specifies the device to forward the IRP to.
Irp
Specifies the IRP that is being forwarded to the specified driver.
FileObject
Specifies a file object value to copy to the next stack location. This can be NULL in order to set no file object, but the value is always copied to the next stack location. If the current file object is to be preserved, it must be passed in this parameter.
StackUse
Specifies a value ennumerated by KSSTACK_USE. If the value is KsStackCopyToNewLocation, the parameters are copied to the next stack location. If the value is KsStackReuseCurrentLocation, the current stack location is reused when the IRP is forwarded and the stack location is returned to the current location. If the value is KsStackUseNewLocation, the new stack location is used as is.

Return Values

The KsForwardAndCatchIrp function returns the result of the IoCallDriver, or it returns an invalid status if no more stack depth is available.

Comments

The type KSSTACK_USE enumeration specifies how the IRP stack is used when forwarding the IRP to the next driver.

Enumeration | Description
KsStackCopyToNewLocation | Indicates that the parameters are to be copied to the next stack location.
KsStackReuseCurrentLocation | Indicates that the current stack location is to be reused.
KsStackUseNewLocation | Indicates that the next stack location is to be used without modification.


KsForwardIrp

The KsForwardIrp function forwards an IRP to the specified driver after initializing the next stack location and setting the file object.

KSDDKAPI NTSTATUS NTAPI
  KsForwardIrp(
    IN PIRP  Irp,
    IN PFILE_OBJECT  FileObject,
    IN BOOLEAN  ReuseStackLocation
    );

Parameters

Irp
Specifies the IRP that is being forwarded to the specified driver.
FileObject
Specifies the file object to initialize the next stack with.
ReuseStackLocation
Specifies the new stack location.

Return Values

The KsForwardIrp function returns the result of the IoCallDriver, or it returns an invalid status if no more stack depth is available.

Comments

Use the KsForwardIrp function when only the FileObject parameter of the forwarded IRP changes when the current stack parameters are copied to the next stack location. The function verifies that there is a new stack location to copy into before attempting to copy. If there is no new stack location, the IRP is completed with STATUS_INVALID_DEVICE_REQUEST.


KsFreeDeviceHeader

The KsFreeDeviceHeader function cleans up and frees a previously allocated device header.

KSDDKAPI VOID NTAPI
  KsFreeDeviceHeader(
    IN PVOID  Header
    );

Parameters

Header
Indicates the device header to free that had been previously allocated by KsAllocateDeviceHeader.

Return Values

None

See Also

KsAllocateDeviceHeader


KsFreeObjectHeader

The KsFreeObjectHeader function cleans up and frees a previously allocated object header.

KSDDKAPI VOID NTAPI
  KsFreeObjectHeader(
    IN PVOID  Header
    );

Parameters

Header
Points to the object header to free.

Return Values

None

See Also

KsAllocateObjectHeader


KsGetChildCreateParameter

The KsGetChildCreateParameter function returns the standard parameter passed to a create request. It is used when passing a create parameter in the standard method used for creating pins, clocks, and allocators.

KSDDKAPI NTSTATUS NTAPI
  KsGetChildCreateParameter(
    IN PIRP Irp,
    OUT PVOID*  CreateParameter
    );

Parameters

Irp
Specifies the Create IRP whose parameter is being retrieved.
CreateParameter
Location in which to return the create information.

Return Values

The KsGetChildCreateParameter function returns STATUS_SUCCESS if successful or STATUS_INVALID_PARAMETER if the size was incorrect.

Comments

The KsGetChildCreateParameter function assumes that the create request has been processed by the standard create dispatching list, which places the create item in KSCREATE_ITEM_IRP_STORAGE(Irp).


KsMoveIrpsOnCancelableQueue

The KsMoveIrpsOnCancelableQueue function moves the specified IRPs from the SourceList to the DestinationList. An IRP is moved if the ListCallback function indicates that it should be moved, whether or not it is currently acquired. It then continues through the list until the callback indicates that the search should be terminated, or the end of the list is reached. This function minimizes the use of the Cancel Spinlock by using the provided spinlocks to synchronize access when possible. The function does not allow the cancel routine to be modified while moving IRPs. The function can be called at DISPATCH_LEVEL or lower.

KSDDKAPI NTSTATUS NTAPI
  KsMoveIrpsOnCancelableQueue(
    IN OUT PLIST_ENTRY  SourceList,
    IN PKSPIN_LOCK  SourceLock,
    IN OUT PLIST_ENTRY  DestinationList,
    IN PKSPIN_LOCK  DestinationLock  OPTIONAL,
    IN KSLIST_ENTRY_LOCATION  ListLocation,
    IN PFNKSIRPLISTCALLBACK  ListCallback,
    IN PVOID  Context
    );

Parameters

SourceList
Specifies the head of the queue from which to remove the IRPs.
SourceLock
Pointer to driver's spin lock for source queue access.
DestinationList
Specifies the head of the queue on which to add the IRPs.
DestinationLock
Optionally contains a pointer to driver's spin lock for destination queue access. If this is not provided, the SourceLock is assumed to control both queues. If provided, this lock is always acquired after the SourceLock. If the destination list has a separate spinlock, the Cancel Spinlock is first acquired in order to move IRPs and allow the KSQUEUE_SPINLOCK_IRP_STORAGE() spinlock to be updated.
ListLocation
Indicates whether the IRPs should be enumerated from the head or the tail of the source queue. Any IRPs that are moved are placed on the destination queue's opposite end so that ordering is maintained.
ListCallback
Callback used to indicate whether or not a specific IRP should be moved from SourceList to DestinationList, or if enumeration should be terminated. If the function returns STATUS_SUCCESS, the IRP is moved. If the function returns STATUS_NO_MATCH, the IRP is not moved. Any other return warning or error value will terminate enumeration and be returned by the function. The STATUS_NO_MATCH value will not be returned as an error by the function. This function is called at DISPATCH_LEVEL. It is always called at least once at the end with a NULL IRP value in order to complete list processing.
Context
Context passed to ListCallback.

Return Values

Returns STATUS_SUCCESS if the list was completely enumerated, else returns any warning or error returned by ListCallback that interrupted enumeration.


KsProbeStreamIrp

The KsProbeStreamIrp function makes the specified modifications to the input and output buffers of the given IRP based on the flags passed, and it then validates the stream header. This is useful when localizing exception handling or performing asynchronous work on an IRP. The resulting IRP is in essentially the METHOD_OUT_DIRECT or METHOD_IN_DIRECT format, with the exception that the access to the data buffer may be IoModifyAccess, depending on the flags passed to this function or the flags in the stream header.

KSDDKAPI NTSTATUS NTAPI
  KsProbeStreamIrp(
    IN PIRP  Irp,
    IN ULONG  ProbeFlags,
    IN ULONG  HeaderSize
    );

Parameters

Irp
Specifies the IRP whose input and output buffers are to be mapped. The requestor mode of the IRP is used when probing the buffers.
ProbeFlags
Specifies flags specifying how to probe the streaming IRP; the flags are listed in the following table.
HeaderSize
Specifies the size to validate each header header against passed to this client, or zero if no validation is to be done. If used, it is assumed that the entire buffer passed is a multiple of this header size, unless the buffer instead contains a single format change header.

Return Values

The KsProbeStreamIrp function returns STATUS_SUCCESS if successful, or it returns a memory or access error.

Comments

If the function is used only to allocate MDL’s and not to probe and lock the addresses, the caller must have a completion routine to clean up the MDL’s. For instance, a just-in-time locking mechanism can allocate the MDL list but only lock memory as needed. The client must provide cleanup code to remove the partially locked MDL list before the IRP is completed, presumably in a completion routine.

If the headers appear to have already been copied to a system buffer, it is not validated again. In general, calling the KsProbeStreamIrp function multiple times with an IRP is not harmful. After calling the function, the stream headers are available in PIRP.AssociatedIrp.SystemBuffer. If the stream buffer MDLs have been allocated, they are available through the PIRP.MdlAddress.

The following defines are used for the ProbeFlags variable:

ProbeFlags Value | Description
KSPROBE_READ | Indicates that the operation is a stream read on the device. This is the default.
KSPROBE_WRITE | Indicates that the operation is a stream write on the device.
KSPROBE_ALLOCATEMDL | Indicates that MDLs should be allocated for the stream buffers if they have not already been allocated. If no stream buffers are present, the flag is ignored. If KSPROBE_PROBEANDLOCK is not specified at the same time as this flag, the caller must have a completion routine in order to clean up any MDL's if not all the MDLs were successfully probed and locked.
KSPROBE_PROBEANDLOCK | If the KSPROBE_ALLOCATEMDL is set, indicates that the memory referenced by the MDLs for the stream buffers should be probed and locked. If the MDL allocation flag is not set, this flag is ignored even if the MDL allocation has previously taken place. The method of probing is determined by what type of IRP is being passed. For a write operation, IoReadAccess is used. For a read operation, IoWriteAccess is used. If the client that sent the data is using the nonpaged pooll, appropriate MDLs are initialized rather than probing and locking.
KSPROBE_SYSTEMADDRESS | Retrieves a system address for each MDL in the chain so the caller does not need to do this in a separate step. This is ignored if the probe and lock flag is not set, even if the MDLs have previously been probed.
KSPROBE_ALLOWFORMATCHANGE | For a Stream Write, allows the KSSTREAM_HEADER_OPTIONSF_TYPECHANGED flag to be set in the stream header. This implies that the stream header is not of extended length, even if an extended header size was indicated. Also, there may only be one stream header contained in the IRP in this case. The buffer associated with this header contains the new data format. For system memory data streams, the buffer should not have been acquired from the negotiated allocator, as it is not part of the data stream.


KsQueryInformationFile

The KsQueryInformationFile function performs an information query against the specified file object. The function attempts to use FastIoDispatch if possible, or it generates an information request against the device object.

KSDDKAPI NTSTATUS NTAPI
  KsQueryInformationFile(
    IN PFILE_OBJECT  FileObject,
    OUT PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass
    );

Parameters

FileObject
Specifies the file object from which to query the standard information.
FileInformation
Indicates the place in which to put the file information. This is assumed to be a valid or probed address.
Length
Specifies the correct length of the FileInformation buffer.
FileInformationClass
Specifies the class of information being requested.

Return Values

The KsQueryInformationFile function returns STATUS_SUCCESS if successful, or if unsuccessful it returns a query error.

Comments

The KsQueryInformationFile function should only be used in cases where the query would result in an actual request to the underlying driver. For example, FilePositionInformation would not generate such a request and should not be used. It assumes the caller is serializing access to the file for operations against a FO_SYNCHRONOUS_IO file object.


KsQueryObjectAccessMask

The KsQueryObjectAccessMask function returns the access originally granted to the first client that created a handle on the associated object. Access can not be changed by duplicating handles.

KSDDKAPI ACCESS_MASK NTAPI
  KsQueryObjectAccessMask(
    IN KSOBJECT_HEADER  Header
    );

Parameters

Header
Points to a header previously allocated by KsAllocateObjectHeader whose access-granted mask pointer is to be returned.

Return Values

The KsQueryObjectAccessMask function returns an access mask.

See Also

KsAllocateObjectHeader


KsQueryObjectCreateItem

The KsQueryObjectCreateItem function returns the create item assigned to the object when created.

KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI
  KsQueryObjectCreateItem(
    IN KSOBJECT_HEADER  Header
    );

Parameters

Header
Indicates the header previously allocated.

Return Values

The KsQueryObjectCreateItem function returns a pointer to a create item.


KsReadFile

The KsReadFile function performs a read against the specified file object. It is assumed the caller is serializing access to the file for operations against a FO_SYNCHRONOUS_IO file object. The function attempts to use FastIoDispatch if possible, or generates a read request against the device object. All relevant statistics are updated.

KSDDKAPI NTSTATUS NTAPI
  KsReadFile(
    IN PFILE_OBJECT  FileObject,
    IN PKEVENT  Event  OPTIONAL,
    IN PVOID  PortContext  OPTIONAL,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  Buffer,
    IN ULONG  Length,
    IN ULONG  Key  OPTIONAL,
    IN KPROCESSOR_MODE  RequestorMode
    );

Parameters

FileObject
Specifies the file object to perform the read against.
Event
Optionally contains the event to use in the read. If no event is passed, the call is assumed to be on a synchronous file object. If not, the caller is waiting on the file object’s event, or it may be asynchronously completed. If the file has been opened for synchronous I/O, this must be NULL. If the variable is used, it must be an event allocated by the object manager.
PortContext
Optionally contains context information for a completion port.
IoStatusBlock
Specifies the address where the status information is to be returned. This is always assumed to be a valid address, regardless of the requestor mode.
Buffer
Specifies the buffer in which to place the data read. If the buffer needs to be probed and locked, an exception handler is used, along with RequestorMode.
Length
Specifies the size of the buffer passed.
Key
Optionally contains a key, or zero if none
RequestorMode
Indicates the processor mode to place in the read IRP if one needs to be generated. Additionally, it is used if the buffer needs to be probed and locked. This variable also determines if a fast I/O call can be performed. If the requestor mode is not KernelMode, but the previous mode was, then fast I/O cannot be used.

Return Values

The KsReadFile function returns STATUS_SUCCESS if successful, STATUS_PENDING if action is pending, or it returns a read error if unsuccessful.


KsReleaseIrpOnCancelableQueue

The KsReleaseIrpOnCancelableQueue function releases an acquired IRP that is already on a queue that can be canceled. The function sets the cancel function and completes the canceling of the IRP, if necessary. The function can be called at IRQ level DISPATCH_LEVEL or lower.

KSDDKAPI VOID NTAPI
  KsReleaseIrpOnCancelableQueue(
    IN PIRP  Irp,
    IN PDRIVER_CANCEL  DriverCancel  OPTIONAL
    );

Parameters

Irp
Specifies the IRP to release.
DriverCancel
Optional parameter that specifies the cancel routine to use. If this is NULL, the standard KsCancelRoutine is used.

Return Values

None


KsRemoveIrpFromCancelableQueue

The KsRemoveIrpFromCancelableQueue function pops the next noncanceled IRP from the specified queue that can be canceled and removes its cancel status. The function searches the list until an IRP is found that has a cancel routine or until the end of the list is reached. The function minimizes the use of the cancel spinlock by using the provided spinlock to synchronize access in most cases. The function may be called at IRQ level DISPATCH_LEVEL or lower.

KSDDKAPI PIRP NTAPI
  KsRemoveIrpFromCancelableQueue(
    IN OUT PLIST_ENTRY  QueueHead,
    IN PKSPIN_LOCK  SpinLock,
    IN KSLIST_ENTRY_LOCATION  ListLocation,
    IN KSIRP_REMOVAL_OPERATION  RemovalOperation
    );

Parameters

QueueHead
Points to the head of the queue from which to remove the IRP.
SpinLock
Points to driver’s spin lock for queue access.
ListLocation
Indicates whether this IRP should come from the beginning or end of the queue.
RemovalOperation
Specifies whether or not the IRP is removed from the list or just acquired by setting the cancel function to NULL. If it is only acquired, the IRP must be later released with KsReleaseIrpOnCancelableQueue or completely removed with KsRemoveSpecificIrpFromCancelableQueue.

Return Values

The KsRemoveIrpFromCancelableQueue function returns the next noncanceled IRP on the list, or it returns NULL if none is found or if an IRP that has not already been acquired cannot be found.

Comments

These enumerations are used in the previous parameters to control where the IRP is removed from and how.

typedef enum {
    KsListEntryTail,
    KsListEntryHead
} KSLIST_ENTRY_LOCATION;

typedef enum {
    KsAcquireOnly,
    KsAcquireAndRemove
} KSIRP_REMOVAL_OPERATION;

See Also

KsReleaseIrpOnCancelableQueue, KsRemoveSpecificIrpFromCancelableQueue


KsRemoveSpecificIrpFromCancelableQueue

The KsRemoveSpecificIrpFromCancelableQueue function removes the specified IRP from the specified queue. This is performed on an IRP that was previously acquired using KsRemoveIrpFromCancelableQueue, but that was not actually removed from the queue.

KSDDKAPI VOID NTAPI
  KsRemoveSpecificIrpFromCancelableQueue(
    IN PIRP  Irp
    );

Parameters

Irp
Points to I/O request packet.

Return Values

None


KsSetInformationFile

The KsSetInformationFile function performs an information set against the specified file object. The function attempts to use FastIoDispatch if possible, or it generates an information set against the device object.

KSDDKAPI NTSTATUS NTAPI
  KsSetInformationFile(
    IN PFILE_OBJECT  FileObject,
    IN PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass
    );

Parameters

FileObject
Specifies the file object to set the standard information on.
FileInformation
Indicates the place in which to put the file information. The file information is assumed to be a valid or probed address.
Length
Specifies the correct length of the FileInformation buffer.
FileInformationClass
Specifies the class of information being set.

Return Values

The KsSetInformationFile function returns STATUS_SUCCESS if successful, or if unsuccessful it returns a set error.

Comments

The KsSetInformationFile function should be used only when the set would result in an actual request to the underlying driver, not including complex operations that require additional parameters to be sent to the driver such as rename, deletion, and completion. For example, FilePositionInformation would not generate such a request and should not be used. It assumes the caller is serializing access to the file for operations against a FO_SYNCHRONOUS_IO file object.


KsSetMajorFunctionHandler

The KsSetMajorFunctionHandler function sets the handler for a specified major function to use the internal dispatching. It routes through a KSDISPATCH_TABLE contained in the opaque object header to be the first element within a structure pointed to by an FsContext within a file object. The dispatching assumes the table and FsContext structure are initialized by the device using KsAllocateObjectHeader.

KSDDKAPI NTSTATUS NTAPI
  KsSetMajorFunctionHandler(
    IN PDRIVER_OBJECT  DriverObject,
    IN ULONG  MajorFunction
    );

Parameters

DriverObject
Specifies the driver object whose major function is to be handled.
MajorFunction
Specifies the major function identifier to be handled. This sets the major function pointer in the driver object to an internal function that then dispatches to the KSDISPATCH_TABLE function. The pointer to this table is assumed to be the first element in a structure pointed to by FsContext in the file object of the specific IRP being dispatched. The valid major function identifiers are as listed.
Identifier | Description
IRP_MJ_CREATE | Create IRP. In this instance, a create request could be used for either creating a new instance of a filter, or for creating some object such as a pin under a filter or a clock under a pin. This assumes that the first element in the driver object’s extent contains a KSDEVICE_HEADER structure that is used to find the type of object to create, based on the name passed. If a parent file object is specified, then that object’s KSDISPATCH_TABLE.ChildCreateHandlerTable in the FsContext is looked at to determine which handler to use for the create, or use the device object’s table.
IRP_MJ_CLOSE | Close IRP.
IRP_MJ_DEVICE_CONTROL | Device control IRP.
IRP_MJ_READ | Read IRP.
IRP_MJ_WRITE | Write IRP.
IRP_MJ_FLUSH_BUFFERS | Flush IRP.
IRP_MJ_QUERY_SECURITY | Query security information.
IRP_MJ_SET_SECURITY | Set security information.
KSDISPATCH_FASTIO | This flag may be added to the MajorFunction identifier in order to specify that the entry refers to the fast I/O dispatch table, rather than the typical major function entry. This is valid only with IRP_MJ_READ, IRP_MJ_WRITE or IRP_MJ_DEVICE_CONTROL. The driver is responsible for creating the DriverObject->FastIoDispatch table. As with normal dispatching, if a handler is set for the driver object, all file objects must handle that fast I/O, even if the entry just points to DispatchFastIoDeviceControlFailure or a similar function.

Return Values

Returns STATUS_SUCCESS if the MajorFunction identifier is valid.

Comments

If a major function handler is set for a driver object, all file objects must handle that major function, even if the entry just points to KsDispatchInvalidDeviceRequest.

KSDISPATCH_FASTIO

This flag may be used to specify that the fast I/O entry should be set rather than the IRP-based entry.


KsStreamIo

The KsStreamIo function performs a stream read or write against the specified file object. The function attempts to use FastIoDispatch if possible, or it generates a read or write request against the device object.

KSDDKAPI NTSTATUS NTAPI
  KsStreamIo(
    IN PFILE_OBJECT FileObject,
    IN PKEVENT Event OPTIONAL,
    IN PVOID PortContext OPTIONAL,
    IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
    IN PVOID CompletionContext OPTIONAL,
    IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN OUT PVOID StreamHeaders,
    IN ULONG Length,
    IN ULONG Flags,
    IN KPROCESSOR_MODE RequestorMode
    );

Parameters

FileObject
Specifies the file object to perform the I/O against.
Event
Optionally contains the event to use in the I/O. If none is passed, the call is assumed to be on a synchronous file object or the caller is waiting on the file object's event, or else it can be asynchronously completed. If used, and the KSSTREAM_SYNCHRONOUS flag is not set, this must be an event allocated by the object manager. If the caller is performing asynchronous I/O, it must either wait on the file object’s event or pass an event in this parameter and wait on it. If this is not done, then there is no way for the caller to know when the IoStatusBlock has been updated by the call.
PortContext
Optionally contains context information for a completion port.
CompletionRoutine
Optionally points to a completion routine for this IRP.
CompletionContext
If CompletionRoutine is specified, this provides a context pointer in the completion routine callback.
CompletionInvocationFlags
Specifies invocation flags specifying when the completion routine is invoked. See following table for the values used.
IoStatusBlock
Location to return the status information. This is always assumed to be a valid address, regardless of the requestor mode. The value must remain valid until the call has updated the status. The caller must either perform synchronous I/O or must wait on the file object’s event or an event passed in the Event parameter before allowing this address to become invalid.
StreamHeaders
Specifies the list of stream headers. This address, as well as the addresses of the data buffers, are assumed to have been probed for appropriate access. Kernel-mode clients submitting streaming headers must allocate the headers from NonPagedPool memory.
Length
Specifies the size of the StreamHeaders passed.
Flags
Specifies various flags for the I/O. See the following table for the values used.
RequestorMode
Indicates the processor mode to place in the IRP if one is needs to be generated. This variable also determines if a fast I/O call can be performed. If the requestor mode is not kernel mode, but the previous mode is, then fast I/O cannot be used.

Return Values

The KsStreamIo function returns STATUS_SUCCESS if successful, STATUS_PENDING if action is pending, or if unsuccessful it returns an I/O error.

Comments

The following enumerated values are used for the CompletionInvocationFlags variable and are of type KSCOMPLETION_INVOCATION:

CompletionInvocationFlags Value | Description
KsInvokeOnSuccess | Invokes the completion routine on success.
KsInvokeOnError | Invokes the completion routine on error.
KsInvokeOnCancel | Invokes the completion routine on cancellation.

The following defined values are used for the Flags variable:

Flags Values | Description
KSSTREAM_READ | Specifies that an IOCTL_KS_STREAMREAD IRP is to be built. This is the default.
KSSTREAM_WRITE | Specifies that an IOCTL_KS_STREAMWRITE IRP is to be built.
KSSTREAM_PAGED_DATA | Specifies that the data is pageable. This is the default and can be used at all times.
KSSTREAM_NONPAGED_DATA | Specifies that the data is nonpaged and can be used as a performance enhancement.
KSSTREAM_SYNCHRONOUS | Specifies that the IRP is synchronous. This means that if the Event parameter is passed, it is not treated as an Object Manager event and is not referenced or dereferenced.


KsWriteFile

The KsWriteFile function performs a write against the specified file object. It is assumed that the caller is serializing access to the file for operations against a FO_SYNCHRONOUS_IO file object. The function attempts to use FastIoDispatch if possible, or it generates a write request against the device object. All relevant statistics are updated.

KSDDKAPI NTSTATUS NTAPI
  KsWriteFile(
    IN PFILE_OBJECT  FileObject,
    IN PKEVENT  Event  OPTIONAL,
    IN PVOID  PortContext  OPTIONAL,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PVOID  Buffer,
    IN ULONG  Length,
    IN ULONG  Key  OPTIONAL,
    IN KPROCESSOR_MODE  RequestorMode
    );

Parameters

FileObject
Specifies the file object to perform the read against.
Event
Optionally contains the event to use in the write. If no event is passed, the call is assumed to be on a synchronous file object or the caller is waiting on the file object’s event. If the call is not on a synchronous file object, it can be asynchronously completed. If the file has been opened for synchronous I/O, this variable must be NULL. If this variable is used, it must be an event allocated by the object manager.
PortContext
Optionally contains context information for a completion port.
IoStatusBlock
Indicates the location in which to return the status information. This is always assumed to be a valid address, regardless of the requestor mode.
Buffer
Specifies the buffer from which to write the data. If the buffer needs to be probed and locked, an exception handler is used, along with RequestorMode.
Length
Specifies the size of the buffer passed.
Key
Optionally contains a key, or zero if none.
RequestorMode
Indicates the processor mode to place in the read IRP if one needs to be generated. Additionally, it is used if a buffer needs to be probed and locked. This variable also determines if a fast I/O call can be performed. If the requestor mode is not KernelMode, but the previous mode was, then fast I/O cannot be used.

Return Values

The KsWriteFile function returns STATUS_SUCCESS if successful, STATUS_PENDING if action is pending, or it returns a read error if unsuccessful.


Security Functions

This following section describes the general helper functions. These include:

KsDefaultDispatchPnp

KsDefaultDispatchPower

KsForwardAndCatchIrp


KsAcquireDeviceSecurityLock

The KsAcquireDeviceSecurityLock function acquires the security lock associated with a device object. An exclusive lock is acquired when changing a security descriptor. When manipulating the security of any object under a particular device object, this lock must be acquired.

KSDDKAPI VOID NTAPI
  KsAcquireDeviceSecurityLock(
    IN PVOID  Header,
    IN BOOLEAN  Exclusive
    );

Parameters

Header
Points to a driver-allocated device header, previously allocated by KsAllocateDeviceHeader, for the device object described by the KSDEVICE_HEADER structure.
Exclusive
Indicates, if set to TRUE, that the lock is to be acquired exclusively.

Return Values

None

Comments

A shared lock is acquired when validating access during a create. An exclusive lock is acquired when changing a security descriptor. Callers of this routine must be running at IRQL < DISPATCH_LEVEL.

See Also

KsAllocateDeviceHeader


KsCreateDefaultSecurity

The KsCreateDefaultSecurity function creates a security descriptor with default security, optionally inheriting parameters from a parent security descriptor.

KSDDKAPI NTSTATUS NTAPI
  KsCreateDefaultSecurity(
    IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL,
    OUT PSECURITY_DESCRIPTOR* DefaultSecurity
    );

Parameters

ParentSecurity
Points to the parent object's security descriptor, describing inherited security parameters. This argument is optional.
DefaultSecurity
Points to the place in which to put the returned default security descriptor.

Return Values

KsCreateDefaultSecurity returns STATUS_SUCCESS if the operation is successful, else a resource or assignment error.

Comments

KsCreateDefaultSecurity is used to initialize sub-objects that do not have any stored security.


KsDispatchQuerySecurity

The KsDispatchQuerySecurity function is used in the KSDISPATCH_TABLE.QuerySecurity entry to handle querying about the current security descriptor. The assumption is that the KSOBJECT_HEADER structure is being used in the FsContext data structure and that the CreateItem points to a valid item that optionally contains a security descriptor.

KSDDKAPI NTSTATUS NTAPI
  KsDispatchQuerySecurity(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the device object associated with the IRP.
Irp
Specifies the IRP that is being handled.

Return Values

The KsDispatchQuerySecurity function returns the security query status and completes the IRP if a security descriptor is present. If no security descriptor is present, it returns STATUS_NO_SECURITY_ON_OBJECT.


KsDispatchSetSecurity

The KsDispatchSetSecurity function is used in the KSDISPATCH_TABLE.SetSecurity entry to handle setting the current security descriptor. The assumption is that the KSOBJECT_HEADER structure is being used in the FsContext data structure and that the CreateItem points to a valid item that optionally contains a security descriptor.

KSDDKAPI NTSTATUS NTAPI
  KsDispatchSetSecurity(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the device object associated with the IRP.
Irp
Specifies the IRP that is being handled.

Return Values

The KsDispatchSetSecurity function returns the security set status and completes the IRP.

Comments

This security descriptor must be allocated in its own piece of pool memory, since KsDispatchSetSecurity will replace the existing descriptor with a new allocation. Therefore, it cannot be shared with CreateItem.


KsReleaseDeviceSecurityLock

The KsReleaseDeviceSecurityLock function releases a previously acquired security lock on the device object header.

KSDDKAPI VOID NTAPI
  KsReleaseDeviceSecurityLock(
    IN KSDEVICE_HEADER  Header
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader whose security lock is to be released.

Return Values

None

See Also

KsAllocateDeviceHeader


General Utility Functions

This following section describes the general helper functions. These include:

KsDefaultDispatchPnp

KsDefaultDispatchPower

KsForwardAndCatchIrp

KsForwardIrp

KsNullDriverUnload

KsQueryDevicePnpObject

KsQueueWorkItem

KsRecalculateStackDepth

KsRegisterWorker

KsSetDevicePnpAndBaseObject

KsSetPowerDispatch

KsSetTargetDeviceObject

KsSynchronousIoControlDevice

KsUnregisterWorker

KsCacheMedium

KsCreateDefaultSecurity


KsCacheMedium

The KsCacheMedium function improves graph building performance of pins which use Mediums to define connectivity.

KSDDKAPI NTSTATUS NTAPI
  KsCacheMedium(
    IN PUNICODE_STRING SymbolicLink,
    IN PKSPIN_MEDIUM Medium,
    IN DWORD PinDirection
    );

Parameters

Symbolic Link
The symbolic link used to open the device interface.
Medium
Points to the medium to cache.
PinDirection
Contains the direction of the Pin. 1 is output, 0 is input.

Return Values

KsCacheMedium returns STATUS_SUCCESS if the caching operation is successful, failure if it is not.

Comments

KsCacheMedium improves graph building performance by creating a registry key at:

\System\CurrentControlSet\Control\MediumCache\{GUID}\DWord\DWord

This enables fast lookup of connected filters in TvTuner and other complex graphs. Note that the GUID identifies the Medium of the connection, and that the DWords denote the device instance. The value name is the SymbolicLink for the driver, and ActualValue is the pin direction.turning.


KsDecrementCountedWorker

Decrements the current worker count of a worker previous created by KsRegisterCountedWorker. This should be called after each task within a worker has been completed.

KSDDKAPI ULONG NTAPI
KsDecrementCountedWorker(
    IN PKSWORKER Worker
    );

Parameters

Worker
Contains the previously allocated worker.

Return Values

Returns the current counter. A count of zero implies that the task list has been completed.

Comments

This should be called after each task within a worker has been completed. A corresponding KsIncrementCountedWorker would have been previously called in order to increment the count. This may be called at DISPATCH_LEVEL.


KsDefaultDispatchPnp

The KsDefaultDispatchPnp function is the default, main PnP dispatch handler; notifications regarding the functional device object can be directed to this handler. This function passes all notifications to the PnP device object previously set with KsSetDevicePnpAndBaseObject and assumes the use of a device header. When the function is passed an IRP_MN_REMOVE_DEVICE, the device object is deleted.

KSDDKAPI NTSTATUS NTAPI
  KsDefaultDispatchPnp(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the functional device object.
Irp
Specifies the PnP IRP.

Return Values

The KsDefaultDispatchPnp function returns the status of the underlying physical device object IRP processing.

Comments

The KsDefaultDispatchPnp function is useful when there is no extra cleanup needed when removing a device beyond freeing the device header and deleting the actual device object.


KsDefaultDispatchPower

The KsDefaultDispatchPower function is a default main Power dispatch handler. Notifications regarding the Functional Device Object can be directed here. This function passes all notifications to the PnP Device Object previously set with KsSetDevicePnpAndBaseObject, and assumes the use of a device header.

KSDDKAPI NTSTATUS NTAPI
KsDefaultDispatchPower(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    );

Parameters

DeviceObject
Specifies the Functional Device Object.
Irp
Specifies the Power IRP.

Return Values

Returns the status of the underlying Physical Device Object IRP processing.

Comments

The KsDefaultDispatchPower function is useful when there is no extra cleanup needed on power IRPs, or just as a way of completing any power IRP. It also allows specific file objects, such as the default clock imlementation, to attach themselves to the power IRPs using KsSetPowerDispatch, and act on them before they are completed by this routine. This function calls each power dispatch routine before completing the IRP.


KsDereferenceBusObject

Dereferences the bus Physical Device Object.

KSDDKAPI VOID NTAPI
  KsDereferenceBusObject(
    IN KSDEVICE_HEADER Header
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader, which also contains the PnP device stack object.

Return Values

None.

Comments

This is used by filters which use the device header to keep track of the corresponding PnP object stack. This is normally called when closing a filter, if required by the bus for the given device. As an example, a software device would require such a call. This call matches a previous call to KsReferenceBusObject when opening the filter instance. The caller must have previously also called KsSetDevicePnpAndBaseObject in order to set the PnP device stack object. This would have been done in the PnP AddDevice function. The function calls the DereferenceDeviceObject method on the previously retrieved interface. The interface itself is released and freed when the device header is freed.


KsDispatchIrp

This function is used to multiplex an Irp to a specific file context.

KSDDKAPI
NTSTATUS
NTAPI
KsDispatchIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

Parameters

DeviceObject
Irp

Return Values

Comments

KsDispatchIrp will either make a call into the file object's KSDISPATCH_TABLE to handle the IRP, or if the file object refers to an AVStream device, it will directly dispatch the IRP to the appropriate AVStream device. Very few AVStream minidrivers will use this function. Class drivers written under AVStream may use it.


KsFreeObjectCreateItem

Frees the slot for the specified create item.

KSDDKAPI NTSTATUS NTAPI
  KsFreeObjectCreateItem(
    IN KSDEVICE_HEADER Header,
    IN PUNICODE_STRING CreateItem
    );

Parameters

Header
Points to the device header on which the create item is attached.
CreateItem
Contains the name of the create item to free.

Return Values

Returns STATUS_SUCCESS if the item was freed, else STATUS_OBJECT_NAME_NOT_FOUND.

Comments

This function does not assume that the caller is serializing multiple changes to the create entry list.

See Also

KsFreeObjectCreateItemsByContext


KsFreeObjectCreateItemsByContext

Frees all create items with a specific context.

KSDDKAPI NTSTATUS NTAPI
  KsFreeObjectCreateItemsByContext(
    IN KSDEVICE_HEADER Header,
    IN PVOID Context
    );

Parameters

Header
Points to the device header on which the create items are attached.
CreateItem
Contains the context of the create items to free. All create items with this context value will be freed.

Return Values

Returns STATUS_SUCCESS if the item was freed, else STATUS_OBJECT_NAME_NOT_FOUND.

Comments

Instead of freeing create items by name as KsFreeObjectCreateItems does, this function will free all create items with a specific context. For example, all create items associated with a filter factory will have the factory as context and can be freed simultaneously with this call instead of one at a time. Note that this function does not assume that the caller is serializing multiple changes to the create entry list.

See Also

KsFreeObjectCreateItem


KsIncrementCountedWorker

Increments the current worker count, and optionally queues the counted work item with the worker previously created by KsRegisterCountedWorker.

KSDDKAPI ULONG NTAPI
  KsDecrementCountedWorker(
    IN PKSWORKER Worker
    );

Parameters

Worker
Contains the previously allocated worker.

Return Values

Returns the current counter. A count of one implies that a worker was actually scheduled.

Comments

This should be called after an addition has been made to the worker's list of tasks to perform. A corresponding KsDecrementCountedWorker should be called within the work item after each task has been completed. This may be called at DISPATCH_LEVEL.


KsLoadResource

Copies (loads) a resource from the given image.

KSDDKAPI NTSTATUS NTAPI
  KsLoadResource(
    IN PVOID ImageBase,
    IN POOL_TYPE PoolType,
    IN ULONG_PTR ResourceName,
    IN ULONG ResourceType,
    OUT PVOID *Resource,
    OUT PULONG ResourceSize
    );

Parameters

ImageBase
Pointer to the image base
PoolType
Pool type to use when copying resource
ResourceName
Resource name.
ResourceType
Resource type
Resource
Pointer to resultant resource memory.
ResourceSize
Pointer to ULONG value to receive the size of the resource.

Return Values

STATUS_SUCCESS if successful, STATUS_INSUFFICIENT_RESOURCES if memory cannot be allocated, otherwise an appropriate error code.


KsNullDriverUnload

The KsNullDriverUnload function is a default function a driver can use when it has no other tasks to do in its unload function, but must still allow the device to be unloaded by its presence.

VOID
  KsNullDriverUnload(
    IN PDRIVER_OBJECT  DriverObject
    );

Parameters

DriverObject
Specifies the driver object for this device.

Return Values

None


KsPinDataIntersectionEx

Performs handling of the KSPROPERTY_PIN_DATAINTERSECTION through a callback.

KSDDKAPI NTSTATUS NTAPI
  KsPinDataIntersectionEx(
    IN PIRP Irp,
    IN PKSP_PIN Pin,
    OUT PVOID Data,
    IN ULONG DescriptorsCount,
    IN const KSPIN_DESCRIPTOR* Descriptor,
    IN ULONG DescriptorSize,
    IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL,
    IN PVOID HandlerContext OPTIONAL
    );

Parameters

Irp
Contains the IRP with the property request being handled
Pin
Contains the specific property being queried.
Data
Contains the pin property specific data.
DescriptorsCount
Indicates the number of descriptor structures.
Descriptor
Contains the pointer to the list of pin information structures.
DescriptorSize
Size of the descriptor structures in bytes.
IntersectHandler
Contains the optional handler for comparison of a Data Range.
HandlerContext
Optional context supplied to the handler.

Return Values

Returns STATUS_SUCCESS, else an error specific to the property being handled.

Comments

This is very similar to KsPinDataIntersection, except for some slight differences that are noted here. In this version, the size of the descriptor is passed, a feature which allows extended descriptors. Also, note that the callback is prototyped differently [NTSTATUS Callback (Context, Irp, Pin, DataRange, MatchingDataRange, DataBufferSize, Data, DataSize) versus the old version's NTSTATUS Callback (Irp, Pin, DataRange, Data)]. In the new version, the output buffer (Data) length is passed as a parameter to the callback (DataBufferSize) instead of needing to be extracted from the current I/O stack location. Also, the callback function is passed a context parameter (the same Context passed to KsPinDataIntersectionEx). Furthermore, the size of the resultant format is passed back in DataSize instead of Irp->IoStatus.Information. These differences excepted, the routines work quite similarly.


KsQueryDevicePnpObject

The KsQueryDevicePnpObject function returns the PnP device object that can be stored in the device header. This is the next device object on the PnP stack and is the device object that PnP requests are forwarded to if KsDefaultDispatchPnp is used.

KSDDKAPI PDEVICE_OBJECT NTAPI
  KsQueryDevicePnpObject(
    IN KSDEVICE_HEADER  Header
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader whose PnP device object is to be returned.

Return Values

The KsQueryDevicePnpObject function returns the previously set PnP device object. If none was set, it returns NULL.

See Also

KsDefaultDispatchPnp


KsQueueWorkItem

The KsQueueWorkItem function queues the specified work item with a worker previous created by the KsRegisterWorker function. The worker can only be on a queue in one place, so subsequent queuing of the worker must wait until the work item has begun executing. The function can only be called at DISPATCH_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsQueueWorkItem(
    IN PKSWORKER  Worker,
    IN PWORK_QUEUE_ITEM  WorkItem
    );

Parameters

Worker
Specifies the previously allocated worker.
WorkItem
Specifies the initialized work item to queue. This work item is only associated with the worker as long as the worker is on a queue. The work item must have been initialized by ExInitializeWorkItem.

Return Values

The KsQueueWorkItem function returns STATUS_SUCCESS if the work item was queued, or if unsuccessful the function returns an error when attempting to create a new worker if no threads are currently available.


KsRecalculateStackDepth

The KsRecalculateStackDepth function recalculates the maximum stack depth required by the underlying device object based on all of the objects that have set a target device (they have added themselves to the object list on the underlying device object using the KsSetTargetDeviceObject function). If the PnP device object has been set on the underlying device header using KsSetDevicePnpAndBaseObject, that device is also taken into account when calculating the maximum stack depth.

KSDDKAPI VOID NTAPI
  KsRecalculateStackDepth(
    IN KSDEVICE_HEADER  Header,
    IN BOOLEAN  ReuseStackLocation
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader.
ReuseStackLocation
If this is set to TRUE, the current stack location is reused when any IRP is forwarded. This means that this object does not require its own stack location when forwarding IRPs and an extra location is not added to the maximum stack size. If set to FALSE, the calculated stack size is incremented by one. If the Pnp object stack is set, the reuse parameter also applies to that stack. Note that KsDefaultDispatchPnp always reuses the current stack location. The minimum stack depth is 1.

Return Values

None

Comments

The KsRecalculateStackDepth function assumes that KsSetDevicePnpAndBaseObject has been called on this device header and has assigned a base object whose stack depth is to be recalculated.

This function allows IRPs to be forwarded through an object by ensuring that any IRP allocated on this device will have sufficient stack locations to allow it to be forwarded. Stack depth must be recalculated on a streaming device when the device transitions out of a Stop state. It can also be recalculated when an object is freed in order to conserve resources.

See Also

KsSetTargetDeviceObject, KsAllocateDeviceHeader, KsSetDevicePnpAndBaseObject, KsDefaultDispatchPnp


KsReferenceBusObject

References the bus Physical device object.

KSDDKAPI NTSTATUS NTAPI
  KsReferenceBusObject(
    IN KSDEVICE_HEADER Header
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader, which also contains the PnP device stack object.

Return Values

Returns STATUS_SUCCESS if the reference was successful, else an error such as STATUS_INSUFFICIENT_RESOURCES.

Comments

This function is used by filters which use the device header to keep track of their PnP object stack. This is normally called on a successful Open of the filter when the bus for this device requires such a reference (such as software devices), and is matched by a call to KsDereferenceBusObject on a close of that filter instance. The caller must have previously also called KsSetDevicePnpAndBaseObject in order to set the PnP device stack object. This would have been done in the PnP AddDevice function. If the object has not been previously referenced, interface space is allocated and the function uses the PnP device object to acquire the bus referencing interface. It then calls the ReferenceDeviceObject method on that interface. The interface itself is released and freed when the device header is freed.


KsRegisterCountedWorker

Handles clients registering for use of a thread.

KSDDKAPI NTSTATUS NTAPI
  KsRegisterCountedWorker(
    IN WORK_QUEUE_TYPE WorkQueueType,
    IN PWORK_QUEUE_ITEM CountedWorkItem,
    OUT PKSWORKER* Worker
    );

Parameters

WorkQueueType
Contains the priority of the work thread. This is normally one of the following: CriticalWorkQueue, DelayedWorkQueue, or HyperCriticalWorkQueue.
CountedWorkItem
Contains a pointer to the work queue item which will be queued as needed based on the current count value.
Worker
Contains the opaque context which must be used when scheduling a work item. Also contains the queue type, and is used to synchronize completion of work items.

Return Values

Returns STATUS_SUCCESS if a worker was initialized.

Comments

This must be matched by a corresponding KsUnregisterWorker when thread use is completed. This function resembles KsRegisterWorker, with the addition of passing the work item that will always be queued. This is to be used with KsIncrementCountedWorker and KsDecrementCountedWorker in order to minimize the number of work items queued, and reduce mutual exclusion code necessary in a work item needed to serialize access against multiple work item threads. The worker queue can still be used to queue other work items. This may only be called at PASSIVE_LEVEL.


KsRegisterWorker

The KsRegisterWorker function handles clients registering for use of a thread. The function can create a new thread of the specified priority if there are currently no free threads available. This must be matched by a corresponding KsUnregisterWorker when thread use is completed. The function can only be called at PASSIVE_LEVEL.

typedef PVOID PKSWORKER;

The worker routines function on opaque PKSWORKER objects that are created for each work item queued at one time.

KSDDKAPI NTSTATUS NTAPI
  KsRegisterWorker(
    IN WORK_QUEUE_TYPE  WorkQueueType,
    OUT PKSWORKER*  Worker
    );

Parameters

WorkQueueType
Specifies the priority of the thread to create. This is usually either CriticalWorkQueue, DelayedWorkQueue, or HyperCriticalWorkQueue.
Worker
Location to put the opaque context that must be used when scheduling a work item. This contains the queue type and is used to synchronize completion of work items.

Return Values

The KsRegisterWorker function returns STATUS_SUCCESS if a worker was initialized, or if unsuccessful the function returns a thread or parameter error.


KsSetDevicePnpAndBaseObject

The KsSetDevicePnpAndBaseObject function sets the PnP device object in the device header, which is the next device object on the PnP stack and is the device object that PnP requests are forwarded to if KsDefaultDispatchPnp is used.

KSDDKAPI VOID NTAPI
  KsSetDevicePnpAndBaseObject(
    IN KSDEVICE_HEADER  Header,
    IN PDEVICE_OBJECT  PnpDeviceObject,
    IN PDEVICE_OBJECT  BaseDevice
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader in which to put the PnP device object.
PnpDeviceObject
Specifies the PnP device object to place in the device header, overwriting any previously set device object.
BaseDevice
Specifies the base device object to which this device header is attached. This must be set if KsRecalculateStackDepth is used.

Return Values

None

See Also

KsAllocateDeviceHeader, KsRecalculateStackDepth


KsSetPowerDispatch

Sets the power dispatch function to be called when the driver object receives an IRP_MJ_POWER IRP. This is only effective if KsDefaultDispatchPower is called to dispatch or complete power IRPs.

This has the effect of adding this object header to a list of object headers that have power dispatch routines to execute. The head of this list is kept by the device header. Assumes that the caller has previously allocated a device header on the underlying Device Object with KsAllocateDeviceHeader.

KSDDKAPI VOID NTAPI
KsSetPowerDispatch(
    IN KSOBJECT_HEADER  Header,
    IN PFNKSCONTEXT_DISPATCH  PowerDispatch  OPTIONAL,
    IN PVOID  PowerContext  OPTIONAL
    );

Parameters

Header
Points to a header previously allocated by KsAllocateObjectHeader.
PowerDispatch
Optionally contains the power dispatch function that will be called, or NULL if the function is to be removed from the list of functions being called. This function must not complete the power IRP sent. The return value of this function must be STATUS_SUCCESS. KsSetPowerDispatch can be called while executing this power dispatch routine if the purpose is to manipulate this list entry only. Manipulating other list entries may confuse the current enumeration.
PowerContext
Optionally contains the context parameter to pass to the power dispatch function.

Return Values

None

Comments

The PFNKSCONTEXT_DISPATCH function prototype describes the type of function expected to be called with IRP_MJ_POWER IRPs. The below Context parameter is the value passed in the above PowerContext parameter.

typedef NTSTATUS (*PFNKSCONTEXT_DISPATCH)(
  IN PVOID Context,
  IN PIRP Irp
  );


KsSetTargetDeviceObject

The KsSetTargetDeviceObject function sets the target device object of an object. The function adds the object header to a list of object headers that have target devices.

KSDDKAPI VOID NTAPI
  KsSetTargetDeviceObject(
    IN KSOBJECT_HEADER  Header,
    IN PDEVICE_OBJECT  TargetDevice  OPTIONAL
    );

Parameters

Header
Points to a header previously allocated by KsAllocateObjectHeader.
TargetDevice
Optionally contains the target device object that will be used when recalculating the stack depth for the underlying device object. If the value is NULL, any current setting is removed. If the value is any setting other than NULL, the current setting is replaced.

Return Values

None

Comments

The KsSetTargetDeviceObject function assumes that the caller has previously allocated a device header on the underlying device object with the KsAllocateDeviceHeader function. The presence of the device header allows future calls to the function KsRecalculateStackDepth, and the device header is used when the object will be forwarding IRPs through a connection to another device and needs to keep track of the stack depth.

If KsSetDevicePnpAndBaseObject is also used to assign the PnP object stack, that device object will also be taken into account when recalculating stack depth.

See Also

KsSetDevicePnpAndBaseObject, KsRecalculateStackDepth, KsAllocateDeviceHeader, KsAllocateObjectHeader


KsSetTargetState

Sets the enabled state of a target device associated with the specified object header.

KSDDKAPI VOID NTAPI
  KsSetTargetState(
    IN KSOBJECT_HEADER Header,
    IN KSTARGET_STATE TargetState
    );

Parameters

Header
Points to a header previously allocated by KsAllocateDeviceHeader.
TargetState
Contains the new state of the target associated with this object header. This may be either KSTARGET_STATE_DISABLED or KSTARGET_STATE_ENABLED.

Return Values

None.

Comments

Assumes that such a target has been set with KsSetTargetDeviceObject. The target is initially disabled, and is ignored when recalculating stack depth. For WDM Streaming devices, this is called on a transition back to a Stop state, after having enabled the target and used KsRecalculateStackDepth on a transition to Acquire state. This allows the stack depth to be minimized.


KsSynchronousIoControlDevice

The KsSynchronousIoControlDevice function performs a synchronous device I/O control on the target device object. It waits in a nonalertable state until the I/O completes. This function can only be called at PASSIVE_LEVEL.

KSDDKAPI NTSTATUS NTAPI
  KsSynchronousIoControlDevice(
    IN PFILE_OBJECT  FileObject,
    IN KPROCESSOR_MODE  RequestorMode,
    IN DWORD  IoControl,
    IN PVOID  InBuffer,
    IN ULONG  InSize,
    OUT PVOID  OutBuffer,
    IN ULONG  OutSize,
    OUT PULONG  BytesReturned
    );

Parameters

FileObject
Indicates the file object to fill in the first stack location with.
RequestorMode
Indicates the processor mode to place in the IRP if one needs to be generated.
IoControl
Specifies the I/O control to send.
InBuffer
Points to the device input buffer.
InSize
Specifies the size in bytes of the device input buffer.
OutBuffer
Points to the device output buffer.
OutSize
Specifies the size in bytes of the device output buffer.
BytesReturned
Points to the place in which to put the number of bytes returned.

Return Values

KsSynchronousIoControlDevice returns the result of the device I/O control.


KsUnregisterWorker

The KsUnregisterWorker function allows clients to unregister a worker. The function can destroy threads, depending on the number of threads in use. This must only be used after successful execution of KsRegisterWorker. The function can only be called at PASSIVE_LEVEL.

KSDDKAPI VOID NTAPI
  KsUnregisterWorker(
    IN PKSWORKER  Worker
    );

Parameters

Worker
Specifies the previously allocated worker to be unregistered. The function will wait until any outstanding work item is completed.

Return Values

None

Comments

The client must ensure that outstanding I/O initiated on any worker thread has been completed before unregistering the worker has been completed. This means canceling or completing outstanding I/O either before unregistering the worker, or before the worker item returns from its callback for the last time and is unregistered. Unregistering of a worker will wait for any currently queued work items to complete before returning.


KsValidateAllocatorFramingEx

Validates allocator framing submitted in a 'set' of the property KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX.

KSDDKAPI NTSTATUS NTAPI
  KsValidateAllocatorFramingEx(
    IN PKSALLOCATOR_FRAMING_EX Framing,
    IN ULONG BufferSize,
    IN const KSALLOCATOR_FRAMING_EX *PinFraming
    );

Parameters

Framing
Contains the framing structure to validate.
BufferSize
Contains the size of the buffer containing the framing structure.
PinFraming
Contains the framing structure exposed by the pin. This is the structure that is returned when a 'get' is performed on the same property.

Return Values

Returns STATUS_SUCCESS, else an error.


Kernel Streaming Property Sets

This chapter documents general kernel streaming property sets that may optionally apply across the broad spectrum of technology types. Property sets that are device-type specific are covered in the documentation on how to write that type of driver.


KSPROPSETID_Clock

Kernel streaming clock objects support the KSPROPSETID_Clock property set. Clients can use these properties to examine the clock state.


KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME

Read-only. Clients use KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME to compare the current physical time on a clock to the current system time.

Specifying This Property

KSPROPERTY

Property Data

KSCORRELATED_TIME, a data structure of the form:

typedef struct {
    LONGLONG Time;
    LONGLONG SystemTime;
} KSCORRELATED_TIME;

The Time member contains the current physical time (see KSPROPERTY_CLOCK_PHYSICALTIME), while SystemTime contains the current system time as reported by KeQueryPerformanceCounter.


KSPROPERTY_CLOCK_CORRELATEDTIME

Read-only. Clients use KSPROPERTY_CLOCK_CORRELATEDTIME to compare the current presentation time on a clock to the current system time.

Specifying This Property

KSPROPERTY

Property Data

KSCORRELATED_TIME, a data structure of the form:

typedef struct {
    LONGLONG Time;
    LONGLONG SystemTime;
} KSCORRELATED_TIME;

The Time member contains the current presentation time (see KSPROPERTY_CLOCK_TIME), while SystemTime contains the current system time as reported by KeQueryPerformanceCounter.


KSPROPERTY_CLOCK_PHYSICALTIME

Read-only. Clients use KSPROPERTY_CLOCK_PHYSICAL_TIME to determine the current physical time of a clock.

Specifying This Property

KSPROPERTY

Property Data

LONGLONG, representing the current physical time in 100-nanosecond units.

Comments

The physical time of a clock is an ever-progressing counter. Unlike the presentation time, it cannot reverse.

Clocks are not required to support a 100-nanosecond resolution. To determine the clock resolution, clients can use the KSPROPERTY_CLOCK_RESOLUTION request.


KSPROPERTY_CLOCK_RESOLUTION

Clients use KSPROPERTY_CLOCK_RESOLUTION to determine the precision of a clock.

Specifying This Property

KSPROPERTY

Property Data

KSRESOLUTION, a data structure of the form:

typedef struct {
    LONGLONG Granularity;
    LONGLONG Error;
} KSRESOLUTION;

The Granularity member specifies the accuracy of the clock, in 100-nanosecond units. The Error member specifies any additional delay the clock has in issuing a clock event notification, in 100-nanosecond units.

Comments

The delay introduced in the Error member is in addition to that in the Granularity member. For example, a clock with a Granularity of one and Error of two would be able to issue clock event notifications every 300 nanoseconds.


KSPROPERTY_CLOCK_TIME

Clients use KSPROPERTY_CLOCK_TIME to determine the current presentation time on a clock.

Specifying This Property

KSPROPERTY.

Property Data

LONGLONG, specifying the current presentation time in 100-nanosecond units.

Comments

The presentation time of a clock can be reversed, unlike the physical time. The presentation time of a clock typically represents a timestamp on an underlying data stream. For example, a clock for a DVD player can report the timestamp of the current position in the DVD as its presentation time.

Clocks are not required to support a 100-nanosecond resolution. To determine the clock resolution, clients can use the KSPROPERTY_CLOCK_RESOLUTION request.


KSPROPSETID_Connection

Clients use the properties in the KSPROPSETID_Connection property set to examine or set the state of a connection on a pin. Pin instances handle these properties.

Stream minidrivers do not have to handle the KSPROPERTY_CONNECTION_STATE, KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, and KSPROPERTY_CONNECTION_DATAFORMAT properties directly. The stream class driver handles them, using Stream Request Blocks (SRB) to query for more information where necessary.


KSPROPERTY_CONNECTION_ALLOCATORFRAMING

Read-only. Clients use this property to determine framing requirements for a pin.

Specifying This Property

KSPROPERTY

Property Data

KSALLOCATOR_FRAMING, which describes the framing requirements for the pin. For example, the FrameSize member specifies the frame size of data on the pin.


KSPROPERTY_CONNECTION_DATAFORMAT

Read/write. Clients use this to get or set the current data format.

Specifying This Property

KSPROPERTY

Property Data

KSDATAFORMAT, specifying the current data format.

Comments

KS filters only need to support this property if they allow clients to reset the current property, or if connections can be made with the data format incompletely specified.


KSPROPERTY_CONNECTION_PRIORITY

Read/write. Clients use KSPROPERTY_CONNECTION_PRIORITY to get or set the priority of a connection.

Specifying This Property

KSPROPERTY

Property Data

KSPRIORITY, a structure of the form:

typedef struct {
    ULONG PriorityClass;
    ULONG PrioritySubClass;
} KSPRIORITY;

One priority is greater than another if the PriorityClass member is greater, or if the PriorityClass members are identical and the PrioritySubClass member is greater.

The following predefined values of PriorityClass are available: KSPRIORITY_LOW, KSPRIORITY_NORMAL, KSPRIORITY_HIGH, and KSPRIORITY_EXCLUSIVE. Priority defaults to KSPRIORITY_NORMAL. KSPRIORITY_EXCLUSIVE indicates the connection has exclusive access to resources used by a pin.

Comments

The priority values have global significance: a client can use the reported values to set priorities between two different pins on two unrelated kernel streaming (KS) filters.

KSPROPERTY_CONNECTION_PRIORITY is an optional property. Clients treat pins that do not support it as having priority KSPRIORITY_NORMAL.


KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT

Write-only. Clients can use this to propose a new data format for the connection. The KS filter returns STATUS_SUCCESS if the pin can be reset to the proposed data format, or an error code otherwise.

Specifying This Property

KSPROPERTY

Property Data

KSDATAFORMAT, specifying the proposed data format.

Comments

Note that this property request does not change the data format. Clients use the KSPROPERTY_CONNECTION_DATAFORMAT to change the format.


KSPROPERTY_CONNECTION_STATE

KSPROPERTY_CONNECTION_STATE specifies the current run state of the pin. The pin only reads or writes data in the KSSTATE_RUN state.

Specifying this Property

KSPROPERTY

Property Data

One of the following values:

Value | Description
KSSTATE_STOP | The initial state of a pin. No data is actually being read or written. In this state, the pin uses the least amount of resources possible.
KSSTATE_ACQUIRE | The pin is acquiring the resources necessary to read or write data.
KSSTATE_PAUSE | The pin is ready to read or write data, but data transfer is temporarily paused.
KSSTATE_RUN | The state from which the pin can actually read or write data.

Comments

Both individual pins and the KS filter as a whole may support this property.

Members

Manufacturer
Specifies the GUID for the manufacturer of the component. The manufacturer generates this GUID, and may associate a localized string representation through a registry entry.
Product
Specifies the GUID for the product to which the component belongs. The manufacturer generates this GUID, and may associate a localized string representation through a registry entry.
Component
Specifies the GUID for the component. The manufacturer generates this GUID, and may associate a localized string representation through a registry entry.
Name
Specifies the GUID for a registry-stored localized name for the component. This may be distinct from the Component member, or it may be GUID_NULL. The manufacturer generates this GUID.
Version
Specifies the version number for the component or product.
Revision
Specifies the revision number for the component or product.

›


KSPROPSETID_Pin

Clients use the properties in the KSPROPSETID_Pin property set to query a KS filter for information on each pin factory it supports.

The KSPROPERTY_PIN_CTYPES property specifies how many pin factories the KS filter supports. All other properties in this property set specify information about an individual pin factory. The KS filter identifies each pin factory by an ID, which ranges from zero to the number of pin factories minus one. The client includes the pin factory ID within the KSP_PIN structure it uses when it issues the property request.

Stream minidrivers do not have to handle most of these properties directly. The stream class driver handles them, using Stream Request Blocks (SRBs) to query for more information where necessary. The exceptions are: KSPROPERTY_PIN_GLOBALCINSTANCES, KSPROPERTY_PIN_NECESSARYINSTANCES, and KSPROPERTY_PIN_PHYSICALCONNECTION.


KSPROPERTY_PIN_CATEGORY

Read-only. The category of the pin factory.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

GUID that represents the category.


KSPROPERTY_PIN_CINSTANCES

Read-only. The current number of pins this pin factory has instantiated, as well as the maximum number of pins this pin factory can instantiate, per filter.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

KSPIN_CINSTANCES, a data structure of the form:

typedef struct {
    ULONG PossibleCount;
    ULONG CurrentCount;
} KSPIN_CINSTANCES;

Members

PossibleCount
Specifies the maximum number of pins the pin factory can instantiate on the filter, or KSINTANCE_INDETERMINATE if there is no maximum.
CurrentCount
Specifies the current number of pins the pin factory has instantiated on the filter.

Comments

This property specifies the per-filter maximum for a given pin factory. Use the KSPROPERTY_PIN_GLOBALCINSTANCES property to specify the overall maximum for a given pin factory.


KSPROPERTY_PIN_COMMUNICATION

Read-only. The communication direction of pins instantiated on a pin factory.

Specifying this Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

The KS filter returns one of the following values, which specifies the communication direction of a pin instantiated by this pin factory:

KSPIN_COMMUNICATION_NONE
The pin factory does not instantiate any pins.
KSPIN_COMMUNICATION_SINK
The pin factory instantiates IRP sink pins. Such pins can only be connected to IRP source pins.
KSPIN_COMMUNICATION_SOURCE
The pin factory instantiates IRP source pins. Such pins can only be connected to IRP sink pins.
KSPIN_COMMUNICATION_BOTH
The pin factory instantiates pins that are both IRP sinks and IRP sources.
KSPIN_COMMUNICATION_BRIDGE
This pin cannot connect to other pins, but instances may be created on it to receive non-KS I/O requests.

Comments

Source pins send IRPs to sink pins. Do not confuse the communication direction with data flow direction. (See KSPROPERTY_PIN_DATAFLOW.) A source pin may read or write data, and a sink pin may have data read to it or written from it.


KSPROPERTY_PIN_CONSTRAINEDDATARANGES

Read-only. This property specifies the list of data ranges currently supported by pins instantiated on the pin factory.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of 64-bit aligned KSDATARANGE structures.

Comments

A KS filter uses this property to report the data ranges currently supported by pins instantiated on this pin factory, based on any constraints imposed by the current internal state of the KS filter. Use the KSPROPERTY_PIN_DATARANGES property to report the complete list of all data ranges supported by the KS filter, regardless of dynamic constraints.


KSPROPERTY_PIN_CTYPES

Read-only. Clients use this request to determine how many pin types a KS filter supports.

Specifying This Property

KSPROPERTY

Property Data

ULONG. The number of pin factories the KS filter supports.


KSPROPERTY_PIN_DATAFLOW

Read-only. Clients use this property to determine if data flows in or out of a pin type.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

The KS filter returns one or more of the following flags:

KSPIN_DATAFLOW_IN
The pin factory instantiates data sink pins. Such pins can only be connected to data source pins.
KSPIN_DATAFLOW_OUT
The pin factory instantiates data source pins. Such pins can only be connected to data sink pins.


KSPROPERTY_PIN_DATAINTERSECTION

Read-only. The client supplies a list of data formats. The KS filter returns the first data format on that list supported by pins instantiated by the pin factory.

Specifying This Property

A KSP_PIN structure, followed by a KSMULTIPLE_ITEM structure and a sequence of 64-bit aligned KSDATARANGE structures. The PinId member of KSP_PIN specifies the pin factory.

Property Data

KSDATAFORMAT, the first matching data format.


KSPROPERTY_PIN_DATARANGES

Read-only. Clients use this property to determine the data ranges supported by pins instantiated by the pin factory.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of 64-bit aligned KSDATARANGE structures.

Comments

KS filters return all data ranges supported by pins instantiated by the pin factory. A KS filter may not support a reported data range in its current internal state. To determine the data ranges supported by the current internal state, use KSPROPERTY_PIN_CONSTRAINEDDATARANGES.


KSPROPERTY_PIN_GLOBALCINSTANCES

Read-only. The current number of pins this pin factory has instantiated, as well as the maximum number of pins this pin factory can instantiate. This property is optional.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

KSPIN_CINSTANCES, a data structure of the form:

typedef struct {
    ULONG PossibleCount;
    ULONG CurrentCount;
} KSPIN_CINSTANCES;

Members

PossibleCount
Specifies the maximum number of pin the pin factory can instantiate on the driver, or KSINTANCE_INDETERMINATE if there is no maximum.
CurrentCount
Specifies the current number of pins the pin factory has instantiated on the driver.

Comments

KSPROPERTY_PIN_GLOBALCINSTANCES specifies the absolute current and maximum number of instances, over all instances of the filter. To determine per-filter values, use KSPROPERTY_PIN_CINSTANCES.


KSPROPERTY_PIN_INTERFACES

Read-only. The list of interfaces supported by pins instantiated by the pin factory.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of KSPIN_INTERFACE structures. The interfaces are ordered by preference.


KSPROPERTY_PIN_MEDIUMS

Read-only. The list of mediums supported by pins instantiated by the pin factory.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of KSPIN_MEDIUM structures. The mediums are ordered by preference. Comments

For more information on mediums, please see related information in the Pin Connections section. Also see the KSPIN_MEDIUM structure.


KSPROPERTY_PIN_NAME

Read-only. The localized Unicode string name for the pin factory.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

A buffer containing the localized Unicode string.


KSPROPERTY_PIN_NECESSARYINSTANCES

Read-only. The minimum number of pins that the pin factory must instantiate before the filter can perform I/O operations.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

ULONG, specifying the minimum number of pins that the pin factory must instantiate.


KSPROPERTY_PIN_PHYSICALCONNECTION

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

Built on Sunday, March 11, 2001


KSPROPERTY_PIN_PROPOSEDATAFORMAT

Write-only. Clients use this to determine pins instantiated by the pin factory support a specific data format. The KS filter returns STATUS_SUCCESS if pins can be reset to the proposed data format, or an error code otherwise.

Specifying This Property

KSP_PIN. The PinId member specifies the pin factory.

Property Data

A KSDATAFORMAT structure, specifying the proposed data format.

Comments

This property does not actually change the data format. Clients use KSPROPERTY_CONNECTION_DATAFORMAT to change the data format.


KSPROPSETID_Stream

Clients use properties in the KSPROPSETID_Stream property set to query a pin for its stream state properties.

Stream minidrivers do not need to handle the KSPROPERTY_STREAM_MASTERCLOCK property. The stream class driver handles it automatically.


KSPROPERTY_STREAM_MASTERCLOCK

Clients use KSPROPERTY_STREAM_MASTERCLOCK to determine the master clock for a pin.

Specifying This Property

KSPROPERTY

Property Data

HANDLE, which specifies the handle of the file object that represents the master clock.


KSPROPSETID_Topology

Clients use requests in the KSPROPSETID_Topology property set to examine a KS filter's internal topology.

Each node in the topology has a zero-based node ID: KS filters with n nodes number them from 0 to n-1. The whole KS filter itself may be treated as a node, and has the special node ID number KSFILTER_NODE.

Stream minidrivers do not need to handle the properties in this property set. The stream class driver handles them on behalf of the minidriver.


KSPROPERTY_TOPOLOGY_CATEGORIES

Read-only. Specifying This Property

KSPROPERTY.

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of GUIDs representing the possible functional categories the KS filter supports. Microsoft provides standard categories in ks.h and ksmedia.h. The following is a list of the functional categories that are not technology-specific:

Functional Category | Description
KSCATEGORY_BRIDGE | Bridge to outside the kernel streaming subsystem.
KSCATEGORY_CAPTURE | Captures.
KSCATEGORY_ COMMUNICATIONSTRANSFORM | Transforms the type of communications being used.
KSCATEGORY_DATACOMPRESSOR | Compresses a data stream.
KSCATEGORY_DATADECOMPRESSOR | Decompresses a data stream.
KSCATEGORY_DATATRANSFORM | Transforms a data stream.
KSCATEGORY_FILESYSTEM | Moves a data stream into or out of the file system.
KSCATEGORY_INTERFACETRANSFORM | Transforms the interface type being used.
KSCATEGORY_MEDIUMTRANSFORM | Transforms the medium type being used.
KSCATEGORY_MIXER | Mixes multiple data streams.
KSCATEGORY_RENDER | Renderer.
KSCATEGORY_SPLITTER | Splits a data stream.


KSPROPERTY_TOPOLOGY_CONNECTIONS

Read-only. KSPROPERTY_TOPOLOGY_CONNECTION describes the connections between each node of a KS filter.

Specifying This Property

KSPROPERTY

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of KSTOPOLOGY_CONNECTION structures.

Comments

KSPROPERTY_TOPOLOGY_CONNECTIONS represents connections between pins and nodes on a KS filter. The KS filter represents each connection as formed between an incoming and an outgoing logical pin. The KS filter itself is a node, with ID number KSFILTER_NODE. Logical pins on KSFILTER_NODE represent external pins created by the pin factory with matching ID, while logical pins on all other nodes simply represent the incoming or outgoing portion of an internal connection.

Logical pins on any nodes other than KSFILTER_NODE are not external pins that clients can connect, but are simply a notion used to describing the internal connections between nodes. They cannot be instantiated, and they cannot receive I/O requests. They have no existence outside of the KSPROPERTY_TOPOLOGY_CONNECTIONS property.


KSPROPERTY_TOPOLOGY_NAME

Read-only. The localized Unicode string name of the node.

Specifying This Property

KSP_NODE. The NodeId member specifies the node ID of the node.

Property Data

A buffer to hold the string name.


KSPROPERTY_TOPOLOGY_NODES

Read-only. KSPROPERTY_TOPOLOGY_NODES provides a list of the topology nodes and node types the KS filter supports.

Specifying This Property

KSPROPERTY

Property Data

A KSMULTIPLE_ITEM structure, followed by a sequence of GUIDs representing the node types. The index within the sequence must match the node ID number.


Kernel Streaming Event Sets

Built on Sunday, March 11, 2001


Event Sets

Event sets are groups of related events, much like property sets, that can generate a notification to some listener(s). For example, changes in device state, or reaching a specific sample position, might be cause for a filter pin instance to generate an event notification to any clients which have registered to receive such a notification.

Using unique ID’s for event sets allows custom driver extensions which will not conflict with any other custom extensions, or future development.

Device objects support event sets using the IOCTL_KS_ENABLE_EVENT and IOCTL_KS_DISABLE_EVENT device I/O controls. If a filter or pin must support multiple distinct copies of the same event set, it must use instance identifiers as described in the Error! Reference source not found. section. A particular event may be defined as a single shot, meaning that the event only fires once, and is then automatically disabled. This would be in the case of things such as positional marks, wherein an event is triggered when the device reaches a specified position. Other events are defined to trigger multiple times until disabled. This is all dependent on the definition of the particular event.


Enable Event

The IOCTL_KS_ENABLE_EVENT request enables the specified event. The format of the event request varies for each specific event itself. An event is defined by:

  • An event set identifier.
  • An event identifier.
  • Event-specific data.

The KSEVENT structure contains the event identification information, and is essentially a KSIDENTIFIER. The flags element contains the type of query to perform. This may be one of the following:

#define KSEVENT_TYPE_ENABLE         0x00000001
#define KSEVENT_TYPE_ONESHOT        0x00000002
#define KSEVENT_TYPE_ENABLEBUFFERED 0x00000004
#define KSEVENT_TYPE_SETSUPPORT     0x00000100
#define KSEVENT_TYPE_BASICSUPPORT   0x00000200
#define KSEVENT_TYPE_QUERYBUFFER    0x00000400
Flags | Description
KSEVENT_TYPE_ENABLE | Normal enabling of an event for continuous notification. The event is not discarded until the client requests that it be discarded, or the file object on which the event was created is closed.
KSEVENT_TYPE_ONESHOT | Enables the event for a single notification. The event is discarded after a single notification.
KSEVENT_TYPE_ENABLEBUFFERED | Enables the event with event data buffering activated. If event generation also produces data, it will be buffered until either the event is disabled, or the data is retreived by the client.
KSEVENT_TYPE_SETSUPPORT | Queries for the list of event sets, or support of a particular event set.
KSEVENT_TYPE_BASICSUPPORT | Queries for support of a particular event type.
KSEVENT_TYPE_QUERYBUFFER | Queries for previously buffered data for an enabled event. This is used when event data buffering is also enabled.

For some event sets, where multiple instances of a single event set exist, a request may also have to specify event instance information. Instance information is also event-specific, meaning that it is appended to the end of the structure.

typedef struct {
  ULONG NotificationType;
  union {
    struct {
      HANDLE Event;
      ULONG Reserved[2];
    } EventHandle;
    struct {
      HANDLE Semaphore;
      ULONG Reserved;
      LONG Adjustment;
    } SemaphoreHandle;
    struct {
      PVOID Event;
      KPRIORITY Increment;
      ULONG Reserved;
    } EventObject;
    struct {
      PVOID Event;
      KPRIORITY Increment;
      LONG Adjustment;
    } EventObject;
    struct {
      PKDPC Dpc;
      ULONG ReferenceCount;
      ULONG Reserved;
    } Dpc;
    struct {
      PWORK_QUEUE_ITEM WorkQueueItem;
      WORK_QUEUE_ITEM WorkQueueItem;
      ULONG Reserved;
    } WorkItem;
    struct {
      PWORK_QUEUE_ITEM WorkQueueItem;
      PKSWORKER KsWorkerObject;
      ULONG Reserved;
    } KsWorkItem;
  };
} KSEVENTDATA
KSEVENTDATA Member | Description
NotificationType | Contains flags indicating what type of notification should be performed.
EventHandle.Event | When the KSEVENT_EVENT_HANDLE flag is set, this contains a handle to a synchronization event.
EventHandle.Reserved[2] | Reserved and set to zero.
SemaphoreHandle.Semaphore | When the KSEVENT_SEMAPHORE_HANDLE flag is set, this contains a handle to a semaphore.
SemaphoreHandle.Reserved | Reserved and set to zero.
SemaphoreHandle.Adjustment | Contains the adjustment to the semaphore when it is released.
EventObject.Event | When the KSEVENT_EVENT_OBJECT flag is set, and the IRP requestor mode was kernel-mode, this contains a pointer to a synchronization event.
EventObject.Increment | Specifies the priority increment to pass on to the event signal.
EventObject.Reserved | Reserved and set to zero.
SemaphoreObject.Semaphore | When the KSEVENT_SEMAPHORE_OBJECT flag is set, and the IRP requestor mode was kernel-mode, this contains a handle to a semaphore.
SemaphoreObject.Increment | Specifies the priority increment to pass on to the semaphore release.
SemaphoreObject.Adjustment | Contains the adjustment to the semaphore when it is released.
Dpc.Dpc | When the KSEVENT_DPC flag is set, and the IRP requester mode was kernel-mode, this contains a pointer to an initialized KDPC structure. The first system parameter points to the original KSEVENT structure. The second system parameter is undefined.
Dpc.ReferenceCount | Indicates that the DPC has been queued. This should be initialized to zero, and interlocked decremented when the DPC has been processed. This is incremented when the DPC is actually queued. It allows a client to determine if the DPC has possibly been taken off the queue to run, but has not completed execution yet. This allows the client to determine when data pertaining to the DPC can be safely be freed. The queued count should decremented within the DPC to maintain accuracy.
Dpc.Reserved | Reserved and set to zero.
WorkItem.WorkQueueItem | Points to an initialized work queue item which is used to queue a work item when the event is to be signaled. The work item is scheduled if the List.Blink element of the work queue item is NULL. If this element is NULL, and the event is to be signaled, the work item is queued. If this element is not NULL, then the event is not signaled. Normally the work item function would set this element to NULL when it could successfully be re-entered.
WorkItem.WorkQueueType | Contains the queue on which the work item is to be placed.
WorkItem.Reserved | Reserved and set to zero.
KsWorkItem.WorkQueueItem | Optionally points to an initialized work queue item which is used to queue a work item when the event is to be signaled. The work item is scheduled if the List.Blink element of the work queue item is NULL. If this element is NULL, and the event is to be signaled, the work item is queued. If this element is not NULL, then the event is not signaled. Normally the work item function would set this element to NULL when it could successfully be re-entered. If the WorkQueueItem is NULL, it is assumed that the work item is a counted work item, and KsIncrementedCountedWorker will be used for notification.
KsWorkItem.KsWorkerObject | Contains the worker on which the work item is to be queued.
KsWorkItem.Reserved | Reserved and set to zero.

#define    KSEVENTF_EVENT_HANDLE    0x00000001
#define  KSEVENTF_SEMAPHORE_HANDLE  0x00000002
#define  KSEVENTF_EVENT_OBJECT    0x00000004
#define  KSEVENTF_SEMAPHORE_OBJECT  0x00000008
#define  KSEVENTF_DPC      0x00000010
#define  KSEVENTF_WORKITEM    0x00000020
#define  KSEVENTF_KSWORKITEM    0x00000080
NotificationType Flags | Description
KSEVENTF_EVENT_HANDLE | Indicates that a Win32 synchronization or notification object handle is being passed. The KSEVENTDATA.EventHandle.Event element contains the handle.
KSEVENTF_SEMAPHORE_HANDLE | Indicates that a Win32 semaphore handle is being passed. The KSEVENTDATA.SemaphoreHandle.Semaphore element contains the handle.
KSEVENTF_EVENT_OBJECT | Indicates that a pointer to a kernel synchronization or notification object is being passed. The KSEVENTDATA.EventObject.Event element contains a pointer to this object. This is available only to kernel mode clients.
KSEVENTF_SEMAPHORE_OBJECT | Indicates that a pointer to a kernel semaphore object is being passed. The KSEVENTDATA.SemaphoreObject.Semaphore element contains a pointer to this object. This is available only to kernel mode clients.
KSEVENTF_DPC | Indicates that a pointer to a kernel DPC structure is being passed. The KSEVENTDATA.Dpc.Dpc element contains a pointer to the DPC. This is available only to kernel mode clients.
KSEVENTF_WORKITEM | Indicates that a pointer to a kernel work item structure is being passed. The KSEVENTDATA.WorkItem.WorkQueueItem contains a pointer to the work item. This is available only to kernel mode clients.
KSEVENTF_KSWORKITEM | Indicates that a pointer to a kernel work item structure is being passed. The KSEVENTDATA.KsWorkItem.WorkQueueItem contains a pointer to the work item, and is queued to a previously registered KS Worker. This is available only to kernel mode clients.

All event sets must support the KSEVENT_TYPE_BASICSUPPORT flag, which allows one to query for the support of a specific event within an event set. For multiple instance event sets, this refers to all the event sets as a whole, rather than any particular event set instance.

The synchronization or notification event, DPC, or work item is normally used to signal the occurrence of the event, unless otherwise specified by the specific event type. Event object, DPC notification and work item queuing can only be accessed by kernel-mode components. The original address of the KSEVENTDATA structure can later be used to disable the event, although the actual address does not have to be valid throughout the lifetime of the event. In order to query for support of an event set in general, use the KSEVENT_TYPE_SETSUPPORT flag.

DeviceIoControl(
  DeviceHandle,
  IOCTL_KS_ENABLE_EVENT,
  &Event,
  sizeof(KSEVENT),
  &EventData,
  sizeof(KSEVENTDATA),
  &BytesReturned,
  &Overlapped);


Disable Event

The IOCTL_KS_DISABLE_EVENT request disables a specified event. The same pointer which was used to enable the event must be used to disable it. The pointer is the key used to uniquely identify the event. Optionally, a NULL pointer and length of zero may be specified as the first buffer to disable all active events for the client. The format is defined as above. Note that all pending DPC’s and work items should be disposed of before freeing any critical structures that they rely on.

DeviceIoControl(
  DeviceHandle,
  IOCTL_KS_DISABLE_EVENT,
  &EventData,
  sizeof(KSEVENTDATA),
  NULL,
  0,
  &BytesReturned,
  &Overlapped);

Parameter Access Macros

The following macros are defined to allow access to Irp->Tail.Overlay.DriverContext parameters in the Irp passed to a handler function. These are initialized by KsEnableEvent and KsEnableEventWithAllocator.

KSEVENT_SET_IRP_STORAGE

This macro accesses a pointer to the KSEVENT_SET in which the event was located. This is only initialized for a basic support callback, and not for an enable callback.

KSEVENT_ITEM_IRP_STORAGE

This macro accesses a pointer to the specific KSEVENT_ITEM located. Note that this value is only set when using KsEnableEventWithAllocator.

KSEVENT_ENTRY_IRP_STORAGE

This macro accesses a pointer to the KSEVENT_ENTRY being allocated. This is not initialized for a basic support callback, only for an enable callback. If the event enable is to be handled asynchronously, this storage location must be maintained intact.


KSEVENTSETID_Clock

Clients can request to be notified of clock state events on a clock by registering these events with the clock's file object:

KSEVENT_CLOCK_INTERVAL_MARK

KSEVENT_CLOCK_POSITION_MARK

When a client submits the IOCTL_KS_ENABLE_EVENT request to register for event notification, it submits as a data buffer the structure documented in the EventData section of each event reference page.


KSEVENT_CLOCK_INTERVAL_MARK

Clients enable the KSEVENT_CLOCK_INTERVAL_MARK event to be notified when at an initial time value, and then at fixed time increments after that.

Event Data

KSEVENT_TIME_INTERVAL, a structure of the form:

typedef struct {
    KSEVENTDATA EventData;
    LONGLONG TimeBase;
    LONGLONG Interval;
} KSEVENT_TIME_INTERVAL;

TimeBase specifies the initial time that triggers this event; an Interval specifies the interval between subsequent occurrences of the event.


KSEVENT_CLOCK_POSITION_MARK

A KSEVENT_CLOCK_POSITION_MARK event occurs when a certain time on a clock is reached.

Event Data

KSEVENT_TIME_MARK, a structure of the form:

typedef struct {
    KSEVENTDATA EventData;
    LONGLONG MarkTime;
} KSEVENT_TIME_MARK;

The MarkTime member specifies the time stamp that triggers the event.


AVStream Functions


DriverEntry for AVStream

DriverEntry is the initial entry point into an AVStream minidriver.

NTSTATUS
  DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPathName
    )

Parameters

DriverObject
This is the driver object to initialize for this instance.
RegistryPathName
Contains the registry path which was used to load this instance.

Return Value

Returns the value returned by KsInitializeDriver.

Headers

Defined in minidriver. Include ks.h.

Comments

Each AVStream minidriver must have a function explicitly named DriverEntry in order to be loaded. DriverEntry is called directly by the I/O system. Usually, DriverEntry calls KsInitializeDriver and then returns the value returned by KsInitializeDriver.

See Also

KsInitializeDriver


KsAcquireControl

KsAcquireControl acquires the filter control mutex for Object.

VOID
  KsAcquireControl(
    IN PVOID  Object
    );

Parameters

Object
The object for which to acquire the filter control mutex, should be either a filter or a pin (cast to PVOID).

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

Minidrivers will typically not call this function directly, but will instead call either KsFilterAcquireControl or KsPinAcquireControl. These functions provide the necessary type casting to PVOID automatically.

See more information on Mutexes in AVStream.

See Also

KsReleaseControl, KsFilterAcquireControl, KsPinAcquireControl, Mutexes in AVStream


KsAcquireDevice

KsAcquireDevice gains synchronous access for Device by acquiring the device mutex.

VOID
  KsAcquireDevice(
    IN PKSDEVICE  Device
    );

Parameters

Device
AVStream device for which synchronous control should be acquired.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

See Also

KsReleaseDevice , KSDEVICE, Mutexes in AVStream


KsAddDevice

KsAddDevice is the default AddDevice handler installed by KsInitializeDriver .

NTSTATUS
  KsAddDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject
    );

Parameters

DriverObject
Points to the WDM driver object for the minidriver.
PhysicalDeviceObject
Points to the WDM physical device object.

Headers

Defined in ks.h. Include ks.h.

Comments

Normally, an AVStream minidriver will not call this function directly.

In some cases, the minidriver may wish to install a different AddDevice handler and call this function from that handler.

For example:

DriverObject -> DriverExtension -> AddDevice = MyAddDevice();

For other IRPs:

DriverObject -> MajorFunction [IRP_MJ_FOO] = MyFoo();

The minidriver can then call KsAddDevice (for add device) or KsDispatchIrp (for other IRPs) to have AVStream perform the default behavior.

Also, note that KsAddDevice extracts the device descriptor stored in the device extension allocated from a call to KsInitializeDriver and creates the device described by it. If KsInitializeDriver is not used to initialize the driver, this function will create a device with the default characteristics and no filter factories. The minidriver always has the option of calling KsCreateDevice directly, in which case the driver extension is not used by AVStream.

See Also

KsCreateDevice , KsInitializeDevice, KsInitializeDriver, KSDEVICE, KsDispatchIrp


KsAddEvent

KsAddEvent adds an event to Object’s event list.

VOID
  KsAddEvent(
    IN PVOID  Object,
    IN PKSEVENT_ENTRY  EventEntry
    );

Parameters

Object
The object to which the event will be added.
EventEntry
Points to an event entry structure describing the event to add to Object.

Headers

Defined in ks.h. Include ks.h.

Comments

Minidrivers typically will not call this routine directly; they will instead use KsFilterAddEvent or KsPinAddEvent.

Once events have been added to the event list, these events can then be generated as data events via a Ks*GenerateEvents call. Typecasting of the object (filter or pin) to PVOID must be provided by the caller.

See Also

KsFilterAddEvent , KsPinAddEvent, KsDefaultAddEventHandler, KsGenerateEvents, KSEVENT_ENTRY


KsAddItemToObjectBag

KsAddItemToObjectBag adds an object or chunk of memory to the given object bag.

NTSTATUS
  KsAddItemToObjectBag(
    IN KSOBJECT_BAG  ObjectBag,
    IN PVOID  Item,
    IN PFNKSFREE  Free  /*  optional */
    );

Parameters

ObjectBag
The object bag to which the requested item will be added. Every AVStream object (KSFILTER, KSPIN, etc…) has a field called Bag. Pass that field in this parameter.
Item
A pointer to the item to add to the object bag.
Free
A function which will be called when the item is removed from the object bag or when the object bag is deleted. This function is typically used to free any dynamic memory associated with Item. The function should be prototyped as follows:
void Free (IN PVOID Data);

If NULL is passed in this parameter, Item will be freed with ExFreePool when removed from the object bag or when the object bag is deleted.

Return Value

Either STATUS_SUCCESS will be returned indicating that the addition went normally or STATUS_INSUFFICIENT_RESOURCES will be returned indicating that there are not sufficient system resources for the operation to proceed.

Headers

Defined in ks.h. Include ks.h.

Comments

Note that the mutex associated with the bag must be held. Please see related information in KsMergeAutomationTables and Mutexes in AVStream.

See Also

KsRemoveItemFromObjectBag, KsDiscard, KsAllocateObjectBag, KsFreeObjectBag, KsCopyObjectBagItems , _KsEdit, Object Bags


KsAllocateObjectBag

KsAllocateObjectBag creates an object bag and associates it with Device.

NTSTATUS
  KsAllocateObjectBag(
    IN PKSDEVICE  Device,
    OUT KSOBJECT_BAG  *ObjectBag
    );

Parameters

Device
The AVStream device structure representing the device object to which the newly created object bag will be associated.
ObjectBag
A pointer to a KSOBJECT_BAG structure into which the newly allocated object bag will be deposited.

Return Value

STATUS_SUCCESS will be returned if a new object bag could be created. If a new object bag could not be allocated, STATUS_INSUFFICIENT_RESOURCES will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

An allocated object bag will not be automatically deleted. The minidriver calling KsAllocateObjectBag is responsible for deletion of the object bag. The easiest way to do this is by calling KsFreeObjectBag. Alternatively, if the minidriver has the addresses of the items in the bag, the minidriver can delete them individually by calling KsRemoveItemFromObjectBag.

See Also

KsFreeObjectBag, KsAddItemToObjectBag, KsRemoveItemFromObjectBag, KsDiscard, KsCopyObjectBagItems


KsCompletePendingRequest

KsCompletePendingRequest is used to complete a dispatch function which has previously returned STATUS_PENDING.

VOID
  KsCompletePendingRequest(
    IN PIRP  Irp
    );

Parameters

Irp
The IRP which needs to be completed; this will have been passed in the dispatch function which returned a pending code.

Headers

Defined in ks.h. Include ks.h.

Comments

If the dispatch function in question does not pass an IRP, it cannot be pended. Minidrivers should set the status field of the IRP prior to calling this function.

KsCompletePendingRequest can be used for PnP dispatch functions in the device dispatch table or filter creation/closure requests. Dispatch functions which allow STATUS_PENDING to be returned and which then do pend must call this function when they complete the request.

Return Value

None

See Also

KSDEVICE_DISPATCH, KSFILTER_DISPATCH, IRP


KsCopyObjectBagItems

KsCopyObjectBagItems copies all items from one object bag into another.

NTSTATUS
  KsCopyObjectBagItems(
    IN KSOBJECT_BAG  ObjectBagDestination,
    IN KSOBJECT_BAG  ObjectBagSource
    );

Parameters

ObjectBagDestination
The object bag into which items will be copied.
ObjectBagSource
The object bag from which items will be copied into ObjectBagDestination.

Return Value

STATUS_SUCCESS will be returned if the copy is successful; otherwise, an error code will be returned. Most often, this will be STATUS_INSUFFICIENT_RESOURCES indicating insufficient system resources to complete the copy operation. If STATUS_INSUFFICIENT_RESOURCES is returned, it is quite possible that some, but not all, of the items have been copied from ObjectBagSource to ObjectBagDestination.

Headers

Defined in ks.h. Include ks.h.

Comments

Please note that mutexes for both bags should be held. If the object bag in question is associated with a filter or a pin, acquire the filter control mutex. If the object bag belongs to a filter factory or the device, acquire the device mutex. See Mutexes in AVStream for more information.

See Also

KsAllocateObjectBag, KsFreeObjectBag, KsAddItemToObjectBag, KsRemoveItemFromObjectBag, KsDiscard, _KsEdit, KsEdit, KsPinGetConnectedPinInterface, KsPinGetConnectedFilterInterface, KsPinGetReferenceClockInterface, KsPinSetPinClockTime, Object Bags, Mutexes in AVStream


KsCreateDevice

KsCreateDevice creates an AVStream device.

NTSTATUS
  KsCreateDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject,
    IN const KSDEVICE_DESCRIPTOR*  Descriptor, /* optional */
    IN ULONG  ExtensionSize, /* optional */
    OUT PKSDEVICE*  Device /* optional */
    );

Parameters

DriverObject
Points to the WDM driver object of the minidriver.
PhysicalDeviceObject
Points to the WDM physical device object for the device you wish create under AVStream.
Descriptor
Points to a device descriptor which describes the characteristics of the device being created. If this pointer is NULL, a device will be created with default characteristics and no associated filter factories.
ExtensionSize
Contains the size of the device extension. If this is zero, the default extension size is used. If not, it must be at least sizeof (KSDEVICE_HEADER).
Device
Points to a PKSDEVICE where the created AVStream device structure will be stored. This is an optional parameter.

Return Value

STATUS_SUCCESS will be returned if the device is created successfully; otherwise, an appropriate error code will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

Normally, the minidriver does not call this function directly. Instead, KsCreateDevice is called by the default AddDevice handler, KsAddDevice. Minidrivers which handle AddDevice callbacks themselves and do not use KsInitializeDriver and make an explicit call to KsAddDevice from their AddDevice callback can use KsCreateDevice to create a device described by Descriptor. If no KSDEVICE_DESCRIPTOR is provided, a device is created with the default characteristics and no associated filter factories. If a KSDEVICE_DESCRIPTOR is supplied and contains a KSDEVICE_DISPATCH table with a create dispatch, the create dispatch will be called.

See Also

KsAddDevice , KsInitializeDevice, KSDEVICE, KsInitializeDriver, KSDEVICE_DESCRIPTOR, KSDEVICE_DISPATCH


KsCreateFilterFactory

KsCreateFilterFactory adds a filter factory to a given device.

NTSTATUS
  KsCreateFilterFactory(
    IN PDEVICE_OBJECT  DeviceObject,
    IN const KSFILTER_DESCRIPTOR  *Descriptor,
    IN PWCHAR  RefString, /* optional */
    IN PSECURITY_DESCRIPTOR  SecurityDescriptor, /* optional */
    IN ULONG  CreateItemFlags,
    IN PFNKSFILTERFACTORYPOWER  SleepCallback, /* optional */
    IN PFNKSFILTERFACTORYPOWER  WakeCallback, /* optional */
    OUT PKSFILTERFACTORY  FilterFactory /* optional */
    );

Parameters

DeviceObject
The device object on which to add a filter factory.
Descriptor
Points to a filter descriptor which describe the characteristics of individual filters which this factory will be responsible for creating.
RefString
If this argument is provided, this string will be used as the reference string for filters created by this factory. Otherwise, the reference guid provided in the descriptor will be used.
SecurityDescriptor
The security descriptor to use in creation of filters by this filter factory.
CreateItemFlags
The flags to use in creation of filters by this filter factory.
Flag | Meaning
KSCREATE_ITEM_SECURITY_CHANGED | Indicates that the security descriptor on this object type has been changed and should be persisted.
KSCREATE_ITEM_WILDCARD | Indicates that this create item represents a wildcard which will be used for any create requests which do not match any other create items. The ordering of the wildcard entry in the list of create items is irrelevant. Only a single wildcard entry is valid on any list of create items.
KSCREATE_ITEM_NOPARAMETERS | Indicates that this create item does not allow any parameters to be passed, and will fail if any are found. (Normally, create parameters are passed on to the create handler.) This flag cannot be used with a wildcard flag.
KSCREATE_ITEM_FREEONSTOP | Indicates that the create item should be freed at PnP stop. Note that AVStream automatically frees such create items when the device receives PnP stop (after the client has received the PnP stop notification).

SleepCallback
Points to a function designed to handle notifications that the device associated with this filter is going to sleep. This function should be prototyped as follows:
void SleepCallback (IN PKSFILTERFACTORY FilterFactory,
    IN DEVICE_POWER_STATE State);

If this parameter is NULL, there will be no notification to this filter factory that the device is going to sleep.

WakeCallback
Points to a function designed to handle notifications that the device associated with this filter is waking up. This function should be prototyped as follows:
  void WakeCallback (IN PKSFILTERFACTORY FilterFactory,
    IN DEVICE_POWER_STATE State);

If this parameter is NULL, there will be no notification to this filter factory that the device is waking up.

FilterFactory
Points to a KSFILTERFACTORY object into which will be deposited a pointer to the newly created filter factory object. This is an optional parameter; the caller need not be informed of the resulting filter factory object.

Return Value

STATUS_SUCCESS will be returned if the filter factory can be created; otherwise, an appropriate error code will be returned.

Comments

Note that KsCreateFilterFactory requires that the device mutex be held. See more information in Mutexes in AVStream.

This function should normally only be used by minidrivers which either initialize themselves without a call to KsInitializeDriver or which need to dynamically add and remove new filter types.

Headers

Defined in ks.h. Include ks.h.

See Also

KsDeleteFilterFactory, KSFILTER_DESCRIPTOR, KSPIN_DESCRIPTOR_EX, KSNODE_DESCRIPTOR, Mutexes in AVStream


KsDefaultAddEventHandler

KsDefaultAddEventHandler is a default routine to handle event ‘add’ requests.

NTSTATUS
  KsDefaultAddEventHandler(
    IN PIRP  Irp,
    IN PKSEVENTDATA  EventData,
    IN OUT PKSEVENT_ENTRY  EventEntry
    );

Parameters

Irp
The event IRP. This contains the object into which the event will be inserted.
EventData
Data associated with the event.
EventEntry
The event entry which will be inserted into the object’s event list. The object will be determined by Irp.

Return Value

Success or failure of adding the event into the object’s event list will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

KsDefaultAddEventHandler determines the relevant object from Irp and adds the specified event to the object’s event list.

This is functionally equivalent to KsAddEvent (or Ks*AddEvent, see below) for the object that is associated with Irp. Use KsDefaultAddEventHandler from a minidriver-specified AddEvent handler to insert the event into the object’s event list.

See Also

KsAddEvent, , KsFilterAddEvent, KsPinAddEvent, KsGenerateEvents, KSEVENT_ENTRY


KsDeleteFilterFactory

KsDeleteFilterFactory is a macro that deletes a given filter factory.

NTSTATUS
  KsDeleteFilterFactory(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory which is to be deleted.

Return Value

STATUS_SUCCESS if the filter factory was able to be deleted; otherwise, an appropriate error code.

Headers

Defined in ks.h. Include ks.h.

See Also

KsCreateFilterFactory, KsFilterFactoryAddCreateItem, KsFilterFactorySetDeviceClassesState


KsDeviceGetBusData

KsDeviceGetBusData will read data from the bus on which the given AVStream device resides.

ULONG
  KsDeviceGetBusData(
    IN PKSDEVICE  Device,
    IN ULONG  DataType,
    IN PVOID  Buffer,
    IN ULONG  Offset,
    IN ULONG  Length
    );

Parameters

Device
Points to the structure representing the given AVStream device for which data from the bus should be read.
DataType
The space from which data will be read. 0 corresponds to configuration space.
Buffer
Points to a buffer which receives the data read from the bus. Must be at least as large as Length.
Offset
Contains the offset in the space specified by DataType from which data will be read.
Length
Specifies the amount of data which will be read into Buffer.

Return Value

KsDeviceGetBusData will return the number of bytes actually read from the bus. If an errors occurs, this value will usually be zero.

Headers

Defined in ks.h. Include ks.h.

Comments

Depending on the driver for the bus on which the specified device resides, there are two possible behaviors and restriction sets on this function. If the given bus driver supports the bus interface standard (usually PCI), call this function at either IRQL PASSIVE_LEVEL or DISPATCH_LEVEL. After such a call, KsDeviceGetBusData returns the actual number of bytes read from the requested space. If, however, the given bus driver does not support the bus interface standard, then perform all communication with the bus driver via IoCallDriver. Note that this restricts use of KsDeviceGetBusData to IRQL PASSIVE_LEVEL and also means that the return value will either be 0, in the case of failure, or equal to Length if data acquisition was successful.

To ensure compatibility, minidriver writers may wish to restrict use of KsDeviceGetBusData to IRQL PASSIVE_LEVEL.

See Also

KsDeviceSetBusData, IoCallDriver


KsDeviceGetFirstChildFilterFactory

KsDeviceGetFirstChildFilterFactory returns the first child filter factory belonging to a given AVStream device.

PKSFILTERFACTORY
  KsDeviceGetFirstChildFilterFactory(
    IN PKSDEVICE  Device
    );

Parameters

Device
The AVStream device for which to find the first child filter factory.

Return Value

The first child filter factory of Device will be returned. If there are no filter factories registered on Device, NULL will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetFirstChild. Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the device mutex.

See the diagram in AVStream Overview for a graphical representation of AVStream parent/child relationships.

See Also

KSDEVICE, KSFILTERFACTORY, KsGetFirstChild , KsFilterFactoryGetNextSiblingFilterFactory, Mutexes in AVStream, AVStream Overview


KsDeviceGetOuterUnknown

KsDeviceGetOuterUnknown returns the outer unknown interface of the AVStream device specified by Device.

PUNKNOWN
  KsDeviceGetOuterUnknown(
    IN PKSDEVICE  Device
    );

Parameters

Device
The AVStream device for which you wish to get the outer unknown interface.

Return Value

The outer unknown interface of Device will be returned. This returned interface can then be used to query for other interfaces.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetOuterUnknown.

See Also

KsGetOuterUnknown, KsRegisterAggregatedClientUnknown


KsDeviceRegisterAdapterObject

KsDeviceRegisterAdapterObject registers a DMA adapter object with AVStream for performing scatter/gather DMA on the specified device.

VOID
  KsDeviceRegisterAdapterObject(
    IN PKSDEVICE  Device,
    IN PADAPTER_OBJECT  AdapterObject,
    IN ULONG  MaxMappingByteCount,
    IN ULONG  MappingTableStride
    );

Parameters

Device
Points to the stucture representing the AVStream device for which you wish to register an adapter object.
AdapterObject
Points to the adapter object for the device. Must be acquired via IoGetDmaAdapter prior to calling KsDeviceRegisterAdapterObject.
MaxMappingByteCount
Specifies the maximum size that the device can handle for a single mapping. Allows AVStream to automatically break up large chunks of contiguous physical memory into multiple scatter/gather elements for devices which impose a size limit on individual mappings in DMA transfers.
MappingTableStride
Specifies how many bytes each entry in the mapping table requires. This must be at least sizeof (KSMAPPING) and can be as large as necessary.

Additional space can be used by the minidriver as context information.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

A minidriver that calls KsDeviceRegisterAdapterObject is responsible for previously acquiring the adapter object via IoGetDmaAdapter.

Also note that if the minidriver specifies the KSPIN_FLAG_GENERATE_MAPPINGS flag for any pin on any filter on the device,.the minidriver must call KsDeviceRegisterAdapterObject prior to processing any data More information on this flag can be found in the reference page for KSPIN_DESCRIPTOR_EX.

See Also

KSFILTER_DESCRIPTOR, KSPIN_DESCRIPTOR_EX, KSMAPPING, IoGetDmaAdapter


KsDeviceSetBusData

KsDeviceSetBusData writes data to the bus on which the specified AVStream device resides.

ULONG
  KsDeviceSetBusData(
    IN PKSDEVICE  Device,
    IN ULONG  DataType,
    IN PVOID  Buffer,
    IN ULONG  Offset,
    IN ULONG  Length
    );

Parameters

Device
Points to the structure representing the AVStream device for which you wish data to be written to the bus.
DataType
The space to which data will be written. 0 corresponds to configuration space.
Buffer
A pointer to a buffer which contains the data you wish to write out to the bus. This buffer must be at least as long as specified by Length.
Offset
Contains the offset into the space specified by DataType where data will be written.
Length
Specifies the amount of data to write out to the bus from Buffer.

Return Value

KsDeviceSetBusData will return the number of bytes actually written to the bus. In the case of an error, zero will be the usual return result.

Headers

Defined in ks.h. Include ks.h.

Comments

Depending on the driver for the bus on which the specified device resides, there are two possible behaviors and restriction sets on this function. If the given bus driver supports the bus interface standard (usually PCI), call this function at either IRQL PASSIVE_LEVEL or DISPATCH_LEVEL. After such a call, KsDeviceSetBusData returns the actual number of bytes written to the requested space. If, however, the given bus driver does not support the bus interface standard, then perform all communication with the bus driver via IoCallDriver. Note that this restricts use of KsDeviceSetBusData to IRQL PASSIVE_LEVEL and also means that the return value will either be 0, in the case of failure, or equal to Length if the data was written successfully.

To ensure compatibility, minidriver writers may wish to restrict use of KsDeviceSetBusData to IRQL PASSIVE_LEVEL.

See Also

KsDeviceGetBusData, IoCallDriver


KsDiscard

KsDiscard is a fast way to remove a given item from an object bag.

ULONG
  KsDiscard(
    IN KSxxx  Object,
    IN PVOID  Pointer
    );

Parameters

Object
The object out of whose bag Pointer is to be removed.
Pointer
The item to be removed from the requested object’s bag.

Return Value

Same as KsRemoveItemFromObjectBag (Object -> Bag, Pointer, TRUE).

Headers

Defined in ks.h. Include ks.h.

Comments

This is implemented as a C-style preprocessing macro in the ks.h header.

KsDiscard simply calls KsRemoveItemFromObjectBag, passing the object bag associated with Object (Object -> Bag), the item specified by Pointer, and TRUE for the Free parameter.

See Also

KsRemoveItemFromObjectBag


_KsEdit

This function guarantees that a given item is dynamically allocated and associated with an AVStream object via the object bag.

KSDDKAPI NTSTATUS NTAPI
  _KsEdit(
    IN KSOBJECT_BAG  ObjectBag,
    IN OUT PVOID*  PointerToPointerToItem,
    IN ULONG  NewSize,
    IN ULONG  OldSize,
    IN ULONG  Tag
    );

Parameters

ObjectBag
The object bag to use in the check. If the item is not contained within the object bag, _KsEdit will dynamically allocate sufficient memory for the item, copy the old contents, and place the newly allocated memory in this object bag.
PointerToPointerToItem
A pointer to a pointer to the item being edited.
NewSize
The amount of memory to allocate for the item.
OldSize
The amount of memory the item currently takes up.
Tag
Contains the pool tag to use for the allocations.

Return Value

Success or failure of the edit is returned. If this fails, the minidriver should not assume that it safe to go ahead with whatever operation necessitated the edit.

Headers

Defined in ks.h. Include ks.h.

Comments

Note that KsEdit and KsEditSized are macros to make use of _KsEdit easier. While _KsEdit allows you to resize an item. KsEdit does not. The macro KsEdit simply calls _KsEdit, specifying sizeof(**PointerToPointerToItem) as both sizes.

For instance, consider a pin that needs to modify its allocator framing on creation. Since the descriptor is statically layed out in code and new pins may use it, the solution is to modify the pin descriptor.

        KsEdit(Pin, &Pin->Descriptor, Tag);
        Pin->Descriptor->AllocatorFraming = NewAllocatorFraming;

The call to KsEdit guarantees that Pin->Descriptor is dynamic memory that is associated with Pin. Note that arbitrary modification of descriptors and other AVStream structures can cause undesirable results. Minidrivers should exercise caution when using KsEdit on AVStream structures.

KsEditSized calls _KsEdit almost identically to the parameters passed into KsEditSized, except that Object is replaced by Object->Bag and the pointer is typecast to PVOID.

Note that when calling _KsEdit, a caller must hold the mutex associated with the bag. Please see related information in the section Mutexes in AVStream.

See Also

Mutexes in AVStream


KsFilterAcquireControl

KsFilterAcquireControl acquires the filter control mutex for the AVStream filter specified by Filter.

VOID
  KsFilterAcquireControl(
    IN PKSFILTER  Filter
    );

Parameters

Filter
The AVStream filter for which to acquire the control mutex.

Return Value

None

Headers

Defined inline in ks.h. Include ks.h.

Comments

This function is simply an inline call to KsAcquireControl with the appropriate type casting. Minidrivers that manipulate the filter control mutex should call this function instead of calling KsAcquireControl directly as it provides greater readability.

See Also

KsFilterReleaseControl , KsAcquireControl, Mutexes in AVStream


KsFilterAcquireProcessingMutex

KsFilterAcquireProcessingMutex acquires the processing mutex for the AVStream filter specified by Filter.

VOID
  KsFilterAcquireProcessingMutex(
    IN PKSFILTER  Filter
    );

Parameters

Filter
Points to the AVStream filter for which to acquire the processing mutex.

Return Value

None; however, the processing control mutex will be acquired upon return.

Headers

Defined in ks.h. Include ks.h.

Comments

A minidriver that needs to suspend processing for a long period of time should not use this mechanism. Instead, manipulate the processing control gate directly using the KsGate* functions.

See Also

KsFilterReleaseProcessingMutex, KsFilterReleaseProcessingMutex, KsFilterAttemptProcessing, KsPinGetAndGate, KsPinAcquireProcessingMutex, KsPinReleaseProcessingMutex, Mutexes in AVStream


KsFilterAddEvent

KsFilterAddEvent adds an event to Filter’s event list.

VOID
  KsFilterAddEvent(
    PKSFILTER  Filter,
    PKSEVENT_ENTRY  EventEntry
    );

Parameters

Filter
The filter to which to add a specified event.
EventEntry
Points to an event entry structure describing the event to add to Filter.

Headers

Defined inline in ks.h. Include ks.h.

Comments

This function is simply an inlined function call to KsAddEvent.

See Also

KsAddEvent , KsGenerateEvents, KSEVENT_ENTRY


KsFilterAddTopologyConnections

KsFilterAddTopologyConnections adds new topology connections to a filter.

KSDDKAPI NTSTATUS NTAPI
  KsFilterAddTopologyConnections (
    IN PKSFILTER Filter,
    IN ULONG NewConnectionsCount,
    IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections
    );

Parameters

Filter
The filter to which to add the new connections.
NewConnectionsCount
The number of connections in NewTopologyConnections.
NewTopologyConnections
An array containing the new topology connections.

Return Value

Success or failure of the attempt to add topology connections. Failure can occur due to invalid connections having been specified in the list, low memory, or other reasons. If failure occurs, none of the topology connections are added.

Headers

Defined in ks.h. Include ks.h.

Comments

Note that the filter control mutex must be held before calling this function.

See Also

Mutexes in AVStream


KsFilterAttemptProcessing

KsFilterAttemptProcessing attempts to initiate processing on Filter.

VOID
  KsFilterAttemptProcessing(
    IN PKSFILTER  Filter,
    IN BOOLEAN  Asychronous
    );

Parameters

Filter
Points to the AVStream filter object on which to attempt processing.
Asynchronous
Contains an indication as to whether the processing dispatch should occur asynchronously or not (should it occur). An asynchronous dispatch is guaranteed if this is TRUE; however, synchronous processing dispatches are governed by conditions described below.

Return Value

None.

Headers

Defined in ks.h. Include ks.h.

Comments

If the minidriver calls KsFilterAttemptProcessing when all of the conditions required to process data are met, a processing dispatch will occur. See KSFILTER_DISPATCH for more information on the process callback. In order for the attempt to result in an actual dispatch, the filter’s process control gate must be in an open state. Unlike pin-centric processing where a relatively few conditions affect the process control gate, filter-centric processing has many conditions which affect the process control gate. For more information on these requirements, see Filter-Centric Processing.

Should the conditions for processing be met (i.e. the process control gate is open), a processing dispatch will occur. This can occur in one of two ways: synchronously, or asynchronously. If the caller specifies TRUE in the Asynchronous parameter, the processing dispatch will always occur asynchronously in a work item. However, if the caller requests a synchronous processing dispatch, the dispatch will only occur synchronously if the system is currently at an IRQL at which the minidriver can handle processing. If currently at PASSIVE_LEVEL, the dispatch is guaranteed to happen synchronously. Conversely, if currently at DISPATCH_LEVEL, the dispatch will only happen synchronously if KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING is specified on the filter. Otherwise, a work item will be queued to perform processing. Note that this is only an attempt at processing; calling this function does not guarantee that processing will commence. Processing will only occur should the process control gate be “open.”

See Also

KSGATE, Filter-Centric Processing, Pin-Centric Processing, Processing Commonality, Flow Control Gates in AVStream, KSFILTER_DISPATCH, KsGateCaptureThreshold and other KsGate* functions


KsFilterCreateNode

KsFilterCreateNode creates a new topology node on the specified filter.

KSDDKAPI NTSTATUS NTAPI
  KsFilterCreateNode (
    IN PKSFILTER Filter,
    IN const KSNODE_DESCRIPTOR *const NodeDescriptor,
    OUT PULONG NodeID
    );

Parameters

Filter
The filter on which to create a new topology node.
NodeDescriptor
The descriptor of the new node.
NodeID
The ID of the new node is returned here.

Return Value

Success or failure of creating the node. The call may fail due to invalid parameters, low memory, or other reasons. Failure means that the node is not added.

Headers

Defined in ks.h. Include ks.h.

Comments

Note that the filter control mutex must be held before calling this function.

See Also

KsFilterCreatePinFactory, Mutexes in AVStream


KsFilterCreatePinFactory

KsFilterCreatePinFactory creates a new pin factory on the specified filter.

KSDDKAPI NTSTATUS NTAPI
  KsFilterCreatePinFactory (
    IN PKSFILTER Filter,
    IN const KSPIN_DESCRIPTOR_EX *const PinDescriptor,
    OUT PULONG PinID
    );

Parameters

Filter
The filter on which to create a new pin factory.
PinDescriptor
The descriptor of the pin.
PinID
The ID of the factory is returned here.

Headers

Defined in ks.h. Include ks.h.

Return Value

Success or failure of the attempt to create the pin factory. Fail may occur due to invalid parameters, low memory, or other reasons. Failure means that the pin factory has not been created.

Comments

Note that the filter control mutex must be held before calling this function.

See Also

KsFilterCreateNode, Mutexes in AVStream


KsFilterFactoryGetDevice

KsFilterFactoryGetDevice returns the AVStream device to which FilterFactory belongs.

PKSDEVICE __inline
  KsFilterFactoryGetDevice(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory for which to find the owning AVStream device.

Return Value

A pointer to the AVStream device to which FilterFactory belongs will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetDevice.

See the section AVStream Overview for more information on the AVStream object hierarchy.

See Also

KSFILTERFACTORY, KSDEVICE, KsGetDevice, AVStream Overview


KsFilterGenerateEvents

KsFilterGenerateEvents generates events of an indicated type that are present in Filter’s event list.

VOID _inline
  KsFilterGenerateEvents(
    IN PKSFILTER  Filter,
    IN const GUID*  EventSet, /* optional */
    IN ULONG  EventId,
    IN ULONG  DataSize,
    IN PVOID  Data, /* optional */
    IN PFNKSGENERATEEVENTCALLBACK  CallBack, /* optional */
    IN PVOID  CallBackContext /* optional */
    );

Parameters

Filter
The filter on which to generate events.
EventSet
The event set GUID to match against for determination of which events to generate. If this parameter is NULL, set GUID will not be taken into account in determination of matching events.
EventId
The event Id to match against for determination of which events to generate.
DataSize
The size of the data with which to generate the data event.
Data
The data with which to generate the data event. See additional information below.
CallBack
Points to a caller-specified function which will be called to determine whether a given event should be generated. If this is NULL, no callback verification is performed to determine whether or not an event should be generated (only EventSet and EventId will be used). See additional information below.
CallBackContext
Points to a caller-specified context which will be passed to the callback function CallBack. See additional information below.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

When calling this function, a minidriver must place Data and CallBackContext in a locked, non-pageable data segment. In addition, note that the Callback will be made at DISPATCH_LEVEL. The callback function must be in a locked segment and must be prepared to run at IRQL DISPATCH_LEVEL. Note that there is an additional issue in DX8 only: EventSet must be in a locked data segment.

This is simply an inline function call to KsGenerateEvents that performs the necessary type casting. Minidrivers should usually call this version instead of directly calling KsGenerateEvents.

An event will be generated if it is present in Filter’s event list and EventId matches the event’s id, EventSet either matches the event’s set GUID or is NULL, and CallBack is either NULL or authorizes the match.

CallBack is a caller specified callback used for additional match determination. It is prototyped as follows:

BOOLEAN CallBack (IN PVOID Context, IN PKSEVENT_ENTRY EventEntry);

Place context for the callback function in CallBackContext. The callback function should return TRUE if EventEntry should be generated. Otherwise, FALSE should be returned.

See Also

KsAddEvent , KsGenerateEvents, KsPinGenerateEvents, KSEVENT_ENTRY, Event Handling in AVStream, KS Events


KsFilterFactoryAddCreateItem

KsFilterFactoryAddCreateItem adds a new create item for the specified filter factory.

KSDDKAPI NTSTATUS NTAPI
  KsFilterFactoryAddCreateItem(
    IN PKSFILTERFACTORY  FilterFactory,
    IN PWCHAR  RefString,
    IN PSECURITY_DESCRIPTOR  SecurityDescriptor OPTIONAL,
    IN ULONG  CreateItemFlags
    );

Parameters

FilterFactory
The filter factory to which to add a new create item.
RefString
A text string that identifies the create item.
SecurityDescriptor
Optionally contains a security descriptor for this type of object. See KSOBJECT_CREATE_ITEM for related information.
CreateItemFlags
See the table for the Flags member of KSOBJECT_CREATE_ITEM.

Return Values

Returns success or failure of the attempt to add a new create item.

Headers

Defined in ks.h. Include ks.h.

Comments

Normally, only a single create item using the reference GUID supplied in the filter descriptor will be added for the filter factory. This function allows the caller to add additional create items associated with the given filter factory.

See Also

KSOBJECT_CREATE_ITEM, KsAllocateObjectCreateItem, KsAddObjectCreateItemToDeviceHeader, KsAddObjectCreateItemToObjectHeader, KsFreeObjectCreateItem, KsQueryObjectCreateItem, Writing an AVStream Minidriver


KsFilterFactoryGetFirstChildFilter

KsFilterFactoryGetFirstChildFilter returns the first instantiated filter created by FilterFactory.

PKSFILTER __inline
  KsFilterFactoryGetFirstChildFilter(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory for which to find the first instantiated child filter.

Return Value

A pointer to the first instantiated filter created by FilterFactory will be returned. If there are no instantiated filters created by FilterFactory, NULL will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetFirstChild. Note that the object hierarchy is only guaranteed to be stable while the appropriate mutex is held, in this case the device mutex.

See Also

KSFILTER, KSFILTERFACTORY, KsGetFirstChild , KsFilterGetNextSiblingFilter, Mutexes in AVStream


KsFilterFactoryGetNextSiblingFilterFactory

KsFilterFactoryGetNextSiblingFilterFactory returns the next filter factory belonging to the parent device of FilterFactory.

PKSFILTERFACTORY __inline
  KsFilterFactoryGetNextSiblingFilterFactory(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory for which to return the next filter factory of its parent device.

Return Value

The next sibling filter factory of FilterFactory is returned. If no such filter factory exists, NULL is returned.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetNextSibling. Note that the object hierarchy is only guaranteed to be stable while the appropriate mutex is held, in this case the device mutex.

See Also

KSFILTERFACTORY, KsDeviceGetFirstChildFilterFactory, KsGetNextSibling, Mutexes in AVStream


KsFilterFactoryGetOuterUnknown

KsFilterFactoryGetOuterUnknown returns the outer unknown interface of the specified filter factory.

PUNKNOWN __inline
  KsFilterFactoryGetOuterUnknown(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory for which to return the outer unknown interface.

Return Value

The outer unknown interface of FilterFactory is returned. The minidriver can then use it to query for other interfaces.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetOuterUnknown.

See Also

KsGetOuterUnknown, KsRegisterAggregatedClientUnknown, AVStream Overview, IksControl, KsFilterRegisterAggregatedClientUnknown


KsFilterFactoryGetParentDevice

KsFilterFactoryGetParentDevice returns the parent device of the given filter factory.

PKSDEVICE __inline
  KsFilterFactoryGetParentDevice(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory for which to return the parent device.

Return Value

The parent device of the filter factory is returned. This is the AVStream device to which the filter factory belongs.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetParent. Note that the object hierarchy is only guaranteed to be stable while the appropriate mutex is held, in this case the device mutex.

See Also

KSDEVICE, KSFILTERFACTORY, KsGetParent, Mutexes in AVStream


KsFilterFactoryGetSymbolicLink

KsFilterFactoryGetSymbolicLink returns the symbolic link associated with a given filter factory.

PUNICODE_STRING
  KsFilterFactoryGetSymbolicLink(
    IN PKSFILTERFACTORY  FilterFactory
    );

Parameters

FilterFactory
The filter factory for which to acquire the symbolic link.

Return Value

A pointer to a Unicode string containing the symbolic link for the filter factory is returned if the call is successful, and NULL if unsuccessful. NULL indicates that no device interfaces have been registered for FilterFactory.

Headers

Defined in ks.h. Include ks.h.

Comments

If FilterFactory has no registered device interfaces, KsFilterFactoryGetSymbolicLink returns NULL.

See Also

Built on Sunday, March 11, 2001


KsFilterFactorySetDeviceClassesState

KsFilterFactorySetDeviceClassesState enables or disables the device classes that have been registered by a given filter factory.

KSDDKAPI
NTSTATUS
NTAPI
KsFilterFactorySetDeviceClassesState(
    IN PKSFILTERFACTORY  FilterFactory,
    IN BOOLEAN  NewState
    );

Parameters

FilterFactory
A pointer to the filter factory for which to change device class status.
NewState
If set to TRUE, the device classes are enabled; if FALSE, they are disabled.

Return Values

Returns STATUS_SUCCESS, else an error.

Headers

Defined in ks.h. Include ks.h.


KsFilterGetAndGate

KsFilterGetAndGate returns the AND gate which is currently attached to Filter.

PKSGATE
  KsFilterGetAndGate(
    IN PKSFILTER  Filter
    );

Parameters

Filter
Points to the AVStream filter for which to acquire the currently attached AND gate.

Return Value

The AND gate currently attached to Filter will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

A minidriver can use AND gates on a filter as a processing control mechanism for that filter.

See Also

KSGATE, KsGateCaptureThreshold, KsGateTurnInputOn, KsGateTurnInputOff, KsPinAttachAndGate, KsPinGetAndGate


KsFilterGetChildPinCount

KsFilterGetChildPinCount returns the number of pins of a given type which are currently instantiated on a given filter.

ULONG
  KsFilterGetChildPinCount(
    IN PKSFILTER  Filter,
    IN ULONG  PinId
    );

Parameters

Filter
The filter for which to find the number of instantiated pins of type PinId.
PinId
The pin type for which to find the number of instantiated pins. PinId is an index into the array of pin descriptors for the filter to which the pin belongs.

Return Value

Returns the number of pins of type PinId that are currently instantiated on Filter. If no such pins exist or if PinId is out of range, zero is returned.

Headers

Defined in ks.h. Include ks.h.

Comments

The count returned by this call is only guaranteed to be correct if the function is called while the filter control mutex is held and is only guaranteed to remain correct after the call as long as this mutex continues to be held. As soon as the mutex is released, other pins can be added or removed, thereby altering the actual pin count.

See Also

KSPIN, KSFILTER, KsFilterGetFirstChildPin , KsPinGetNextSiblingPin, Mutexes in AVStream


KsFilterGetDevice

KsFilterGetDevice returns the AVStream device to which Filter belongs.

PKSDEVICE __inline
  KsFilterGetDevice(
    IN PKSFILTER  Filter
    );

Parameters

Filter
The filter for which to find the owning AVStream device.

Return Value

The AVStream device to which Filter belongs will be returned.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetDevice.

See Also

KSFILTER, KSDEVICE, KsGetDevice


KsFilterGetFirstChildPin

KsFilterGetFirstChildPin returns the first instantiated pin of type PinId on the filter specified by Filter.

PKSPIN
  KsFilterGetFirstChildPin(
    IN PKSFILTER  Filter,
    IN ULONG  PinId
    );

Parameters

Filter
The filter to query for instantiated pins.
PinId
The numeric Id of the pin type you wish to find the first instantiated member of.

Return Value

Returns the first instantiated pin of type PinId on the specified filter.

Headers

Defined in ks.h. Include ks.h.

Comments

Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the filter control mutex.

See Also

KSPIN, KsFilterGetChildPinCount , KsPinGetNextSiblingPin, Mutexes in AVStream


KsFilterGetNextSiblingFilter

KsFilterGetNextSiblingFilter returns the next instantiated filter belonging to the parent filter factory of Filter.

PKSFILTER __inline
  KsFilterGetNextSiblingFilter(
    IN PKSFILTER  Filter
    );

Parameters

Filter
The filter for which to find the next sibling filter.

Return Value

Returns the next sibling filter of Filter. If no such instantiated filter exists, returns NULL.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetNextSibling. Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the device mutex.

See Also

KSFILTER, KsFilterFactoryGetFirstChildFilter, KsGetNextSibling, Mutexes in AVStream


KsFilterGetOuterUnknown

KsFilterGetOuterUnknown returns the outer unknown interface of the filter specified by Filter.

PUNKNOWN __inline
  KsFilterGetOuterUnknown(
    IN PKSFILTER  Filter
    );

Parameters

Filter
The filter for which to return the outer unknown interface.

Return Value

Returns the outer unknown interface of Filter. The interface can then be used to query for other interfaces, or it can be used in conjunction with a Ks*RegisterAggregatedClientUnknown call to cause Filter to aggregate a minidriver supplied COM object.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetOuterUnknown.

See Also

KsGetOuterUnknown, KsRegisterAggregatedClientUnknown, KsPinRegisterAggregatedClientUnknown


KsFilterGetParentFilterFactory

KsFilterGetParentFilterFactory will return the parent filter factory of the given filter.

PKSFILTERFACTORY __inline
  KsFilterGetParentFilterFactory(
    IN PKSFILTER  Filter
    );

Parameters

Filter
The filter for which to return the parent filter factory.

Return Value

Returns the parent filter factory of Filter. This is AVStream filter factory from which Filter was created.

Headers

Defined in ks.h. Include ks.h.

Comments

This call is simply an inlined function call to KsGetParent . Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the device mutex. For more information on mutexes, see Mutexes in AVStream.

See Also

KSFILTER, KSFILTERFACTORY, KsGetParent, Mutexes in AVStream


KsFilterRegisterPowerCallbacks

KsFilterRegisterPowerCallbacks registers power management callbacks for Filter.

VOID
  KsFilterRegisterPowerCallbacks(
    IN PKSFILTER  Filter,
    IN PFNKSFILTERPOWER  Sleep, /* optional */
    IN PFNKSFILTERPOWER  Wake /* optional */
    );

Parameters

Filter
The filter for which to register power callbacks. In order to receive power notification messages, the filter must be capable of processing. Hence Filter must be filter-centric. For related information see the links below.
Sleep
Points to a function that handles sleep requests for the device.
Wake
Points to a function that handles wake requests for the device.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

The two callbacks should be prototyped as follows:

void Sleep/Wake (IN PKSFILTER Filter, IN DEVICE_POWER_STATE State);

The Sleep callback will be made if Filter is a filter-centric filter and the device is going to sleep. The Wake callback will be made if Filter is a filter-centric filter and the device is waking up. See the links below for related information.

See Also

KsPinRegisterPowerCallbacks, Writing an AVStream Minidriver, Filter-Centric Processing


KsFilterReleaseControl

KsFilterReleaseControl releases the control mutex for the AVStream filter specified by Filter.

VOID __inline
  KsFilterReleaseControl(
    IN PKSFILTER  Filter
    );

Parameters

Filter
The AVStream filter for which to release the control mutex.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

This function is simply an inline call to KsReleaseControl with the appropriate type casting. When manipulating a filter, minidrivers should call this function instead of calling KsReleaseControl directly as it provides greater readability.

See Mutexes in AVStream for a description of the filter control mutex.

See Also

KsFilterAcquireControl , KsReleaseControl, Mutexes in AVStream


KsFilterReleaseProcessingMutex

KsFilterReleaseProcessingMutex releases the processing mutex for the AVStream filter specified by Filter.

VOID
  KsFilterReleaseProcessingMutex(
    IN PKSFILTER  Filter
    );

Parameters

Filter
Points to the AVStream filter for which to release the processing mutex.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

For more AVStream-specific information on mutexes, please see Mutexes in AVStream.

See Also

KsFilterAcquireProcessingMutex, Mutexes in AVStream, Processing Mutex in AVStream


KsFreeObjectBag

KsFreeObjectBag empties and frees an object bag.

VOID
  KsFreeObjectBag(
    IN KSOBJECT_BAG  ObjectBag
    );

Parameters

ObjectBag
The object bag to be emptied and then freed.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

KsFreeObjectBag removes any items present in ObjectBag. In addition, if the reference count for a given object is zero (i.e. that object is not present in any other object bag associated with the same device as ObjectBag), that item is freed.

See Also

KsAllocateObjectBag, KsAddItemToObjectBag, KsRemoveItemFromObjectBag, KsDiscard, KsCopyObjectBagItems, Object Bags


KsGateAddOffInputToAnd

KsGateAddOffInputToAnd adds a new input in the OFF state to a given AND gate.

VOID __inline
  KsGateAddOffInputToAnd(
    IN PKSGATE  AndGate
    );

Parameters

AndGate
The AND gate to which to add a new OFF input.

Return Value

None.

Headers

Defined in ks.h. Include ks.h.

Comments

Note that adding an OFF input to an open AND gate closes the gate and propagates the close down to any attached gates.

This function should only be used on gates that were specifically created as AND gates; AVStream does not verify that the given gate is an AND gate.

KsGateAddOffInputToAnd is an inline function call to KsGateTurnInputOff. If conceptually adding a new input to a gate, the minidriver should call KsGateAddOffInputToAnd rather than KsGateTurnInputOff. This results in more readable and understandable code.

See Also

KsGateRemoveOffInputFromAnd, KsGateAddOnInputToAnd, KsGateRemoveOnInputFromAnd, KsGateTurnInputOn, KsGateTurnInputOff


KsGateAddOffInputToOr

KsGateAddOffInputToOr adds a new input in the OFF state to a given OR gate.

VOID __inline
  KsGateAddOffInputToOr(
    IN PKSGATE  OrGate
    );

Parameters

OrGate
The OR gate to which to add a new OFF input.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

This function should only be used on gates that were specifically created as OR gates; AVStream does not verify that the given gate is an OR gate.

This call is an empty function. It should be used for code readability and clarity.

See Also

KsGateRemoveOffInputFromOr, KsGateAddOnInputToOr, KsGateRemoveOnInputFromOr, KsGateTurnInputOn, KsGateTurnInputOff


KsGateAddOnInputToAnd

KsGateAddOnInputToAnd adds a new input in the ON state to a given AND gate.

VOID __inline
  KsGateAddOnInputToAnd(
    IN PKSGATE  AndGate
    );

Parameters

AndGate
The AND gate to which to add a new ON input.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

This function should only be used on gates that were specifically created as AND gates; AVStream does not verify that the given gate is an AND gate.

This call is an empty function. It should be used for code readability and clarity.

See Also

KsGateRemoveOnInputFromAnd, KsGateAddOffInputToAnd, KsGateRemoveOffInputFromAnd, KsGateTurnInputOn, KsGateTurnInputOff


KsGateAddOnInputToOr

KsGateAddOnInputToOr adds a new input in the ON state to a given OR gate.

VOID __inline
  KsGateAddOnInputToOr(
    IN PKSGATE  OrGate
    );

Parameters

OrGate
The OR gate to which to add a new ON input.

Return Value

None

Headers

Defined in ks.h. Include ks.h.

Comments

Adding an ON input to an OR gate in the OFF or closed state results in the gate opening and the transition being propagated to any gates attached to OrGate.Use this function only in conjunction with gates that were specifically created as OR gates. AVStream does not verify that the given gate is an OR gate.

This call is an inline function call to KsGateTurnInputOn. Minidrivers should call KsGateAddOnInputToOr rather than KsGateTurnInputOn if conceptually adding a new input to the gate. This results in more readable code.

See Also

KsGateRemoveOnInputFromOr, KsGateAddOffInputToOr, KsGateRemoveOffInputFromOr, KsGateTurnInputOn, KsGateTurnInputOff


KsGateCaptureThreshold

KsGateCaptureThreshold is used to capture an ON input of an AND gate specified by Gate.

BOOLEAN __inline
  KsGateCaptureThreshold(
    IN PKSGATE  Gate
    );

Parameters

Gate
The AND gate for which to capture an ON input synchronously.

Return Value

Returns TRUE if the AND gate was originally open. Note that returning TRUE implies that the gate was closed so that no other thread could simultaneously capture the gate and commence processing.

A return value of FALSE indicates that the gate was originally closed and that this thread was unable to capture an ON input of the gate. Thus, the current thread cannot process.

Headers

Defined in ks.h. Include ks.h.

Comments

In essence, KsGateCaptureThreshold checks the state of the given AND gate and if it is open turns off an input to the gate, thereby transitioning the gate to a closed state. Should the gate be closed, the function does nothing. Note that unlike KsGateGetStateUnsafe, this call is done synchronously with respect to other gate state changes; thus, it is the primary synchronization mechanism for processing based on gate control.

The name of this function is perhaps a slight misnomer. It is only a valid call for AND gates, not gates in general. AVStream, however, does not verify whether Gate is an AND gate or an OR gate. It is the caller’s responsibility to ensure that the call is only made on AND gates.

The call is made using interlocked functions and is thus synchronous with respect to any of the other gate state change functions; it is also a very efficient method of process control.

See Also

KsGateInitializeAnd, KsGateInitializeOr, KsGateGetStateUnsafe, KsGateAddOnInputToAnd, KsGateAddOnInputToOr, KsGateAddOffInputToAnd, KsGateAddOffInputToOr, KsGateRemoveOnInputFromAnd, KsGateRemoveOnInputFromOr, KsGateRemoveOffInputFromAnd, KsGateRemoveOffInputFromOr, KsGateTurnInputOn, KsGateTurnInputOff


KsGateGetStateUnsafe

KsGateGetStateUnsafe returns the state of the given gate (open or closed) in an unsafe manner, that is without regard to synchronization.

BOOLEAN __inline
  KsGateGetStateUnsafe(
    IN PKSGATE  Gate
    );

Parameters

Gate
The gate for which to return the state.

Return Value

This call will return TRUE if the gate is open and FALSE if the gate is closed. Note that it does this without regard to synchronization with other gate accesses.

Headers

Defined in ks.h. Include ks.h.

Comments

Since KsGateGetStateUnsafe does not handle synchronization, it is possible to get a result that is not consistent with the state of the gate if the gate is in mid-transition from one state to another at the time of the call. Consider for example a situation in which there exist two gates A->B. A transitions to closed, causing B to transition from open to closed. If, at the same time, this call is made in another thread between A being closed and B being closed, this call would still return that B was open.

KsGateGetStateUnsafe simply returns whether Gate->Count is greater than zero. The function does not use any interlocked functions to do this. Thus, the call is performed without regard to synchronization.


KsGateInitialize

KsGateInitialize initializes a gate for use. Normally, this function will not be called directly by minidrivers, and they will instead use KsGateInitializeAnd or KsGateInitializeOr.

VOID
  KsGateInitialize(
    IN PKSGATE  Gate,
    IN LONG  InitialCount,
    IN PKSGATE  NextGate, /* optional */
    IN BOOLEAN  StateToPropogate
    );

Parameters

Gate
Points to the KSGATE structure you wish to initialize
InitialCount
Specifies the initial count to place on the gate. This will fill in Gate -> Count. For a new AND gate, this count should be 1 (1 – 0 off inputs), and for a new OR gate, this count should be 0 (0 on inputs). See Flow Control Gates in AVStream.
NextGate
Points to a gate that Gate should attach its output to for state transitions. This parameter is optional. A gate need not be attached to another gate.
StateToPropogate
Specifies whether to propogate ON transitions or OFF transitions. For an OR gate, this should be set to TRUE, and for an AND gate, it should be set to FALSE.

Return Value

None

Comments

Minidrivers will ordinarily not call this function, they will instead use either KsGateInitializeAnd or KsGateInitializeOr. Remember, however, that and and OR gates are merely conceptualizations of the gating mechanism. AVStream does not distinguish between them in the implementation of the common gate functions. The gate functions specific to and and OR gates are merely inline calls to the common gate functions.

See Also

KsGateInitializeAnd, KsGateInitializeOr, KsGateTerminateAnd, KsGateTerminateOr, Flow Control Gates in AVStream


KsGateInitializeAnd

KsGateInitializeAnd initializes a KSGATE structure as an AND gate and attaches it to the OR gate specified by NextOrGate.

VOID
  KsGateInitializeAnd(
    IN PKSGATE  AndGate,
    IN PKSGTE  NextOrGate /* optional */
    );

Parameters

AndGate
Points to the KSGATE structure you wish to initialize as a new AND gate NextOrGate. Optionally points to an existing KSGATE structure which AndGate will attach to.

This parameter should be an OR gate.

Return Value

None

Comments

Note that when you attach the AND gate, the attached gate should be an OR gate.

This function is simply an inline call to KsGateInitialize.

See Also

KsGateInitialize, KsGateInitializeOr, KsGateTerminateAnd, KsGateTerminateOr


KsGateInitializeOr

KsGateInitializeOr initializes a KSGATE structure as an OR gate and attaches it to the AND gate specified by NextAndGate.

VOID
  KsGateInitializeOr(
    IN PKSGATE  OrGate,
    IN PKSGATE  NextAndGate /* optional */
    );

Parameters

OrGate
Points to the KSGATE structure you wish to initialize as a new OR gate.
NextAndGate
Optionally points to an existing KSGATE structure which OrGate will attach to.

This parameter should be an AND gate.

Return Value

None

Comments

Note that when you attach the OR gate, the attached gate should be an AND gate.

This function is simply an inline call to KsGateInitialize.

See Also

KsGateInitialize, KsGateInitializeAnd, KsGateTerminateAnd, KsGateTerminateOr


KsGateRemoveOffInputFromAnd

KsGateRemoveOffInputFromAnd removes an existing input which is in the OFF state from an AND gate. Removing the last OFF input from the gate will result in the gate opening and the transition being propogated to any gates connected to AndGate.

VOID
  KsGateRemoveOffInputFromAnd(
    IN PKSGATE  AndGate
    );

Parameters

AndGate
The AND gate from which to remove an OFF input

Return Value

None

Comments

This function should only be used on gates specifically created as AND gates; AVStream will perform no checking that the given gate is truly an AND gate.

This call is an inline function call to KsGateTurnInputOn. Minidrivers should make this call in preference to a KsGateTurnInputOn if conceptually removing an existing input to the gate as opposed to simply turning it off. It will result in more readable and understandable code.

See Also

KsGateAddOffInputToAnd, KsGateAddOnInputToAnd, KsGateRemoveOnInputFromAnd, KsGateTurnInputOn, KsGateTurnInputOff


KsGateRemoveOffInputFromOr

KsGateRemoveOffInputFromOr removes an existing input which is in the OFF state from an OR gate.

VOID
  KsGateRemoveOffInputFromOr(
    IN PKSGATE  OrGate
    );

Parameters

OrGate
The OR gate from which to remove an OFF input.

Return Value

None

Comments

This function should only be used on gates specifically created as AND gates; AVStream will perform no checking that the given gate is truly an AND gate.

This call is an empty function. It should be used for code readability and clarity.

See Also

KsGateAddOffInputToOr, KsGateAddOnInputToOr, KsGateRemoveOnInputFromOr, KsGateTurnInputOn, KsGateTurnInputOff


KsGateRemoveOnInputFromAnd

KsGateRemoveOnInputFromAnd removes an existing input which is in the ON state from an AND gate.

VOID
  KsGateRemoveOnInputFromAnd(
    IN PKSGATE  AndGate
    );

Parameters

AndGate
The AND gate from which to remove an ON input.

Return Value

None

Comments

This function should only be used on gates specifically created as AND gates; AVStream will perform no checking that the given gate is truly an AND gate.

This call is an empty function. It should be used for code readability and clarity.

See Also

KsGateAddOnInputToAnd, KsGateAddOffInputToAnd, KsGateRemoveOffInputFromAnd, KsGateTurnInputOn, KsGateTurnInputOff


KsGateRemoveOnInputFromOr

KsGateRemoveOnInputFromOr removes an existing input which is in the ON state from an OR gate. Removing the last ON input from a given OR gate will result in the gate closing and the transition being propogated to any gates connected to OrGate.

VOID
  KsGateRemoveOnInputFromOr(
    IN PKSGATE  OrGate
    );

Parameters

OrGate
The OR gate from which to remove an ON input.

Return Value

None

Comments

This function should only be used on gates specifically created as AND gates; AVStream will perform no checking that the given gate is truly an AND gate.

This call is an inline function call to KsGateTurnInputOff. Minidrivers should make this call in preference to a KsGateTurnInputOff if conceptually removing an existing input to the gate. It will result in more readable and understandable code.

See Also

KsGateAddOnInputToOr, KsGateAddOffInputToOr, KsGateRemoveOffInputFromOr, KsGateTurnInputOn, KsGateTurnInputOff


KsGateTerminateAnd

KsGateTerminateAnd deletes an existing AND gate and removes an input from any attached OR gate. Note that gates should be deleted in a front to back manner. This call will not patch the gate chain for gates being deleted at the end or in the middle.

VOID
  KsGateTerminateAnd(
    IN PKSGATE  AndGate
    );

Parameters

AndGate
The AND gate which you wish to delete. Note that this should be at the beginning of a gate chain.

Return Value

None

See Also

KsGateInitializeAnd, KsGateInitializeOr, KsGateTerminateOr


KsGateTerminateOr

KsGateTerminateOr deletes an existing OR gate and removes an input from any attached AND gate. Note that gates should be deleted in a front to back manner. This call will not patch the gate chain for gates being deleted at the end or in the middle.

VOID
  KsGateTerminateOr(
    IN PKSGATE  OrGate
    );

Parameters

OrGate
The OR gate which you wish to delete. Note that this should be at the beginning of a gate chain.

Return Value

None

See Also

KsGateInitializeAnd, KsGateInitializeOr, KsGateTerminateAnd


KsGateTurnInputOff

KsGateTurnInputOff turns off an existing input to Gate. Calling this function implies that there is currently an ON input to the given gate. AVStream will perform no checks as to the validity of this call. If, for instance you have an OR gate with no inputs currently in the ON state, calling this function will set the OR gate into an invalid state.

Further, should turning an input off cause the gate to transition from the open state to the closed state, this call will turn off an input to whatever gate is attached to Gate.

VOID
  KsGateTurnInputOff(
    IN PKSGATE  Gate /* optional */
    );

Parameters

Gate
The gate (be it and or or) which currently has an input in the ON state which you wish to transition to the OFF state.

Return Value

None

Comments

Minidrivers should only make this call if they are sure that there is an input in the ON state currently existing on the gate. Explicitly calling this when there is not will put OR gates into an invalid state (for an AND gate, it will be equivalent to adding another input in the OFF state).

See Also

KsGateTurnInputOn, KsGateAddOnInputToAnd, KsGateAddOnInputToOr, KsGateAddOffInputToAnd, KsGateAddOffInputToOr, KsGateRemoveOnInputFromAnd, KsGateRemoveOnInputFromOr, KsGateRemoveOffInputFromAnd, KsGateRemoveOffInputFromOr


KsGateTurnInputOn

KsGateTurnInputOn turns on an existing input to Gate. Calling this function implies that there is an off input to the specified gate. AVStream will perform no checks as to whether this is a valid call for Gate. If, for instance, you have an AND gate which is open and you make this call, you will place the gate into an invalid state. The caller is responsible for all validity checking.

VOID
  KsGateTurnInputOn(
    IN PKSGATE  Gate /* optional */
    );

Parameters

Gate
The gate (be it and or or) which currently has an input in the OFF state which you wish to transition to the ON state.

Return Value

None

Comments

Minidrivers should only make this call if they are sure that there is an input in the OFF state currently existing on the gate. Explicitly calling this when there is not will put AND gates into an invalid state (for an OR gate, it will be equivalent to adding another input in the ON state).

Further, should turning an input off cause the gate to transition from the closed state to the open state, this call will turn on an input to whatever gate is attached to Gate.

See Also

KsGateTurnInputOff, KsGateAddOnInputToAnd, KsGateAddOnInputToOr, KsGateAddOffInputToAnd, KsGateAddOffInputToOr, KsGateRemoveOnInputFromAnd, KsGateRemoveOnInputFromOr, KsGateRemoveOffInputFromAnd, KsGateRemoveOffInputFromOr


KsGenerateEvents

KsGenerateEvents generates events of an indicated type that are present in Object’s event list. An event will be generated if it is present in Object’s event list and EventId matches the event’s id, EventSet either matches the event’s set GUID or is NULL, and CallBack is either NULL or ok’s the match.

CallBack is a caller specified callback used for additional match determination. It is prototyped as follows:

BOOLEAN CallBack (IN PVOID Context, IN PKSEVENT_ENTRY EventEntry);

Context in the callback function will be CallBackContext. The function should return TRUE if EventEntry should be generated. Otherwise, FALSE should be returned.

VOID
  KsGenerateEvents(
    IN PVOID  Object,
    IN const  GUID* EventSet, /* optional */
    IN ULONG  EventId,
    IN ULONG  DataSize,
    IN PVOID  Data, /* optional */
    IN PFNKSGENERATEEVENTCALLBACK  CallBack, /* optional */
    IN PVOID  CallBackContext /* optional */
    );

Parameters

Object
The object on which to generate events. This can be an AVStream filter or pin object.
EventSet
The event set GUID to match against for determination of which events to generate. If this parameter is NULL, set GUID will not be taken into account in determination of matching events.
EventId
The event Id to match against for determination of which events to generate.
DataSize
The size of the data with which to generate the data event.
Data
The data with which to generate the data event. See additional information below.
CallBack
Points to a caller specified function which will be called to determine whether a given event should be generated. If this is NULL, no callback verification is performed to determine whether or not an event should be generated (only EventSet and EventId will be used). See additional information below.
CallBackContext
Points to a caller specified context blob which will be passed to the callback function CallBack. See additional information below.

Return Value

None

Comments

When calling this function, a minidriver must place Data and CallBackContext in a locked, non-pageable data segment. In addition, note that the Callback will be made at DISPATCH_LEVEL. The callback function must be in a locked segment and must be prepared to run at IRQL DISPATCH_LEVEL. Note that there is an additional issue in DX8 only: EventSet must be in a locked data segment.

Minidrivers will typically not call this function directly and will instead use one of the versions which performs appropriate casting: KsFilterGenerateEvents or KsPinGenerateEvents.

See Also

KsAddEvent, KsFilterGenerateEvents, KsPinGenerateEvents, KSEVENT_ENTRY


KsGetDevice

KsGetDevice returns the AVStream device structure that Object belongs to. Object should be one of: PKSPIN, PKSFILTER, or PKSFILTERFACTORY. Callers must perform appropriate type casting to PVOID.

PKSDEVICE
  KsGetDevice(
    IN PVOID  Object
    );

Parameters

Object
The object you wish to query for the device it belongs to.

Return Value

The AVStream device to which Object belongs will be returned.

Comments

Minidrivers will typically not call this function directly. There are a number of functions which perform inline calls to this and do type casting automatically: KsFilterFactoryGetDevice, KsFilterGetDevice, and KsPinGetDevice.

See Also

KSPIN, KSFILTER, KSFILTERFACTORY, KSDEVICE, KsFilterFactoryGetDevice , KsFilterGetDevice, KsPinGetDevice


KsGetDeviceForDeviceObject

KsGetDeviceForDeviceObject returns the AVStream device structure for a given functional device object.

PKSDEVICE
  KsGetDeviceForDeviceObject(
    IN PDEVICE_OBJECT  FunctionalDeviceObject
    );

Parameters

FunctionalDeviceObject
A pointer to the functional device object for which you wish to have returned a pointer to the KSDEVICE structure for the given AVStream device.

Return Value

KsGetDeviceForDeviceObject will return a pointer to a KSDEVICE structure corresponding to the inpassed functional device object.

See Also

KSDEVICE


KsGetFilterFromFileObject

KsGetFilterFromFileObject returns the AVStream filter object associated with FileObject. The minidriver must be sure that FileObject really is a file object associated with an AVStream filter. This can be verified via a call to KsGetObjectTypeFromFileObject.

PKSFILTER
  KsGetFilterFromFileObject(
    IN PFILE_OBJECT  FileObject
    );

Parameters

FileObject
The file object for which to return to associated AVStream filter object. The caller must ensure that FileObject really does refer to a filter before calling this function.

Comments

This call is simply an inline call to KsGetObjectFromFileObject. It merely type casts the return to a PKSFILTER.

See Also

KsGetObjectFromFileObject, KsGetObjectTypeFromFileObject


KsGetFilterFromIrp

KsGetFilterFromIrp will return the AVStream filter object associated with a given Irp. If the Irp is i/o for a pin, the filter to which the pin belongs will be returned. If the Irp is i/o for a topology node, currently NULL will be returned.

PKSFILTER
  KsGetFilterFromIrp(
    PIRP  Irp
    );

Parameters

Irp
The Irp for which the associated filter will be returned

Return Value

The filter associated with the given Irp will be returned or NULL will be returned. NULL indicates that either the Irp wasn’t associated with an AVStream object or that it was associated with a topology node. Currently, Irps associated with topology nodes cannot be queried for their associated filter.

Comments

Irps associated with topology nodes cannot be queried for their associated filter. This should be fixed in a future revision of AVStream.

See Also

KsGetPinFromIrp


KsGetFirstChild

KsGetFirstChild will return the first AVStream child object of Object. See KsGetParent for a hierarchy description of AVStream objects. Callers must manually perform type casts to and from PVOID.

PVOID
  KsGetFirstChild(
    IN PVOID  Object
    );

Parameters

Object
The object for which you wish to find the first AVStream child object.

Return Value

The first AVStream child object of Object will be returned. If no such child object exists, NULL will be returned.

Comments

Minidrivers will rarely call this function directly. There are a number of functions which are inline calls to this and perform type casts for you: KsDeviceGetFirstChildFilterFactory and KsFilterFactoryGetFirstChildFilter. Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the device mutex. Hierarchy objects from device to filter are synchronized with the device mutex, while objects from filter to pin are synchronized with the control mutex.

See Also

KsGetParent, KsDeviceGetFirstChildFilterFactory, KsFilterFactoryGetFirstChildFilter, KsFilterGetFirstChildPin, Mutexes in AVStream


KsGetNextSibling

KsGetNextSibling is used to determine the next sibling of the given object. If object is a filter factory, it will return the next filter factory belonging to the parent device, and so on. Callers must perform appropriate type casting to and from PVOID.

PVOID
  KsGetNextSibling(
    IN PVOID  Object
    );

Parameters

Object
The object which you wish to find the next sibling of.

Return Value

The next sibling object of Object will be returned. If no such sibling object exists, NULL will be returned.

Comments

Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the device mutex. Hierarchy objects from device to filter are synchronized with the device mutex, while objects from filter to pin are synchronized with the control mutex.

This function will rarely be called directly by minidrivers. There are a number of functions which are inlined calls to this and perform the type casting for you: KsFilterFactoryGetNextSiblingFilterFactory, KsFilterGetNextSiblingFilter, and KsPinGetNextSiblingPin.

See Also

KSFILTERFACTORY, KSFILTER, KSPIN, KsFilterFactoryGetNextSiblingFilterFactory, KsFilterGetNextSiblingFilter, KsPinGetNextSiblingPin, Mutexes in AVStream


KsGetNodeIdFromIrp

KsGetNodeIdFromIrp returns the node Id of the node to which Irp was submitted. If Irp was submitted to the filter and not to a topology node, the returned value will be KSNODE_FILTER.

ULONG
  KsGetNodeIdFromIrp(
    IN PIRP  Irp
    );

Parameters

Irp
The Irp for which to determine the associated node Id. This Irp must have been sent to a file object corresponding to a filter, pin, or node.

Return Value

The Id of the node to which Irp was submitted will be returned. If Irp was instead submitted to directly to the filter, KSNODE_FILTER will be returned.


KsGetObjectFromFileObject

KsGetObjectFromFileObject returns the AVStream object cast to PVOID from FileObject.

PVOID
  KsGetObjectFromFileObject(
    IN PFILE_OBJECT  FileObject
    );

Parameters

FileObject
The file object for which to determine the associated AVStream object.

Return Value

The AVStream object associated with FileObject (cast to PVOID) will be returned. This may be a PKSFILTER, PKSPIN, etc…

See Also

KsGetObjectTypeFromFileObject


KsGetObjectTypeFromFileObject

KsGetObjectTypeFromFileObject allows the minidriver to determine what AVStream object type is associated with a given file object.

KSOBJECTTYPE
  KsGetObjectTypeFromFileObject(
    IN PFILE_OBJECT  FileObject
    );

Parameters

FileObject
The file object for which to determine the associated AVStream object type

Return Value

The object type of the AVStream object associated with FileObject will be returned as a KSOBJECTTYPE enumeration. This can be one of the following: KsObjectTypeDevice, KsObjectTypeFilterFactory, KsObjectTypeFilter, or KsObjectTypePin.

See Also

KsGetObjectFromFileObject


KsGetObjectTypeFromIrp

KsGetObjectTypeFromIrp allows the minidriver to determine what AVStream object is associated with a given Irp.

KSOBJECTTYPE
  KsGetObjectTypeFromIrp(
    IN PIRP  Irp
    );

Parameters

Irp
The Irp for which you wish to find the associated AVStream object type.

Return Value

The type of AVStream object associated with the given Irp will be returned as a KSOBJECTTYPE enumeration. This will be one of the following: KsObjectTypeDevice, KsObjectTypeFilterFactory, KsObjectTypeFilter, KsObjectTypePin.


KsGetOuterUnknown

KsGetOuterUnknown returns the outer unknown interface of the given AVStream object. This can be used to manipulate an AVStream object in a COM-like manner. Typically, minidrivers will not call this function directly; instead, they will use one of the inlined versions which perform automatic type casting: KsDeviceGetOuterUnknown, KsFilterFactoryGetOuterUnknown, KsFilterGetOuterUnknown, KsPinGetOuterUnknown.

PUNKNOWN
  KsGetOuterUnknown(
    IN PVOID  Object
    );

Parameters

Object
The AVStream object for which you wish to get the outer unknown interface.

Return Value

The outer unknown interface of Object will be returned. This can be used to query for interfaces.

Comments

Minidrivers using this function must include kcom.h and also must use a C++ compiler, as the kernel COM system for AVStream uses C++.

See Also

KsDeviceGetOuterUnknown, KsFilterFactoryGetOuterUnknown, KsFilterGetOuterUnknown, KsPinGetOuterUnknown, KsRegisterAggregatedClientUnknown, COM and AVStream, KsDeviceRegisterAggregatedClientUnknown


KsGetParent

KsGetParent acquires the parent of the given object. Callers of this must manually perform type casts to and from PVOID.

PVOID
  KsGetParent(
    IN PVOID  Object
    );

Parameters

Object
The AVStream object which you wish to find the parent of. This can be a KSDEVICE, KSFILTERFACTORY, KSFILTER, or KSPIN. Callers must manually type cast the object to a PVOID.

Return Value

The parent of Object will be returned as a PVOID. Callers must manually cast this return value to whatever the type of the parent of Object is.

Comments

See the diagram in AVStream Overview for a graphical representation of AVStream parent/child relationships.

Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the device mutex. Hierarchy objects from device to filter are synchronized with the device mutex, while objects from filter to pin are synchronized with the control mutex.

Minidrivers will rarely use this function directly. There are a number of inlined versions which will do the casting for you: KsFilterFactoryGetParentDevice, KsFilterGetParentFilterFactory, and KsPinGetParentFilter.

See Also

KSDEVICE, KSFILTERFACTORY, KSFILTER, KSPIN, KsFilterFactoryGetParentDevice , KsFilterGetParentFilterFactory, KsPinGetParentFilter, Mutexes in AVStream


KsGetPinFromFileObject

KsGetPinFromFileObject returns the AVStream pin object associated with FileObject. The minidriver must be sure that FileObject really is a file object associated with an AVStream pin. This can be verified via a call to KsGetObjectTypeFromFileObject.

PKSPIN
    KsGetPinFromFileObject(
    IN PFILE_OBJECT  FileObject
    );

Parameters

FileObject
The file object for which to return to associated AVStream pin object. The caller must ensure that FileObject really does refer to a pin before calling this function.

Comments

This call is simply an inline call to KsGetObjectFromFileObject. It merely type casts the return to a PKSPIN.

See Also

KsGetObjectFromFileObject, KsGetObjectTypeFromFileObject


KsGetPinFromIrp

KsGetPinFromIrp will return the AVStream pin object associated with the given Irp.

PKSPIN
  KsGetPinFromIrp(
    IN PIRP  Irp
    );

Parameters

Irp
The Irp for which the associated pin will be returned.

Return Value

The pin associated with the given Irp will be returned or NULL will be returned. NULL indicates that either the Irp wasn’t associated with an AVStream object or that it was associated with a filter or a topology node. Currently, Irps associated with topology nodes cannot be queried for their associated pin.

Comments

Irps associated with topology nodes cannot be queried for their associated filter. This should be fixed in a future revision of AVStream.

See Also

KsGetFilterFromIrp, KsGetNodeIdFromIrp, KsAcquireControl, KsReleaseControl, KsFilterAcquireControl, KsFilterReleaseControl,


KsInitializeDevice

KsInitializeDevice is the routine which AVStream calls to initialize the AVStream device class from within KsCreateDevice. Most minidrivers will not call this routine directly. Only minidrivers which do not use KsInitializeDriver to initialize themselves, which handle AddDevice themselves and do not use KsAddDevice or KsCreateDevice in their AddDevice handler will want to call this routine.

NTSTATUS
  KsInitializeDevice (
    IN PDEVICE_OBJECT  FunctionalDeviceObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject,
    IN PDEVICE_OBJECT  NextDeviceObject,
    IN const KSDEVICE_DESCRIPTOR*  Descriptor /* optional */
    );

Parameters

FunctionalDeviceObject
Points to the WDM functional device object for the device being initialized.

Normally, this will be returned from an IoCreateDevice call. Minidrivers calling this function directly are responsible for calling IoCreateDevice themselves and attaching themselves into the device stack.

PhysicalDeviceObject
Points to the WDM physical device object for the device being initialized.
NextDeviceObject
Points to the next device object in the device stack as determined by a call to IoAttachDeviceToDeviceStack.
Descriptor
Points to a device descriptor which describes the characteristics of the device being initialized. If this parameter is NULL, the device will be initialized with the default characteristics and will have no associated filter factories.

Return Value

STATUS_SUCCESS will be returned indicating that the device was successfully initialized; otherwise, an appropriate error code will be returned.

Comments

Most minidrivers will not use this function directly. Minidrivers will most frequently call either KsInitializeDriver, or supply their own AddDevice handler and call KsAddDevice or KsCreateDevice from it.

See Also

KsInitializeDriver , KsAddDevice, KsCreateDevice, KsTerminateDevice, KSDEVICE


KsInitializeDriver

KsInitializeDriver initializes the driver object of an AVStream minidriver.

NTSTATUS
  KsInitializeDriver(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING  RegistryPath,
    IN const KSDEVICE_DESCRIPTOR  *Descriptor/* optional */
    );

Parameters

DriverObject
Points to the driver object for the AVStream driver being initialized. Minidrivers that call KsInitializeDriver should pass the driver object passed to DriverEntry by the operating system.
RegistryPath
Points to the registry path string passed into the minidriver’s DriverEntry function by the operating system.
Descriptor
Points to a KSDEVICE_DESCRIPTOR structure which specifies the characteristics of the device being initialized.

Return Value

KsInitializeDriver will either return STATUS_SUCCESS or an appropriate error code as returned by IoCreateDevice or internal AVStream device initialization routines.

Comments

This function is typically called from DriverEntry. KsInitializeDriver initializes IRP dispatching, PNP add device messages, and unloading. If a device descriptor is passed, AVStream creates a device with the specified characteristics at AddDevice time. Minidrivers that perform device initialization themselves do not necessarily need to call this function. Also note that the minidriver can later replace any dispatch functions installed by KsInitializeDriver.

See Also

KSDEVICE_DISPATCH, KSFILTER_DESCRIPTOR, KsInitializeDevice, KSDEVICE_DESCRIPTOR, IoCreateDevice, DriverEntry for AVStream, AddDevice


KsMergeAutomationTables

KsMergeAutomationTables merges two automation tables. AutomationTableA is the dominant table in the merge meaning that if there is an entry duplicated in AutomationTableA and AutomationTableB that the entry in AutomationTableA will be the one that is placed into the merged table. The newly created automation table will be placed in the requested bag if one is provided. The old automation tables are not modified by this call; if the caller wishes to delete them or remove them from a bag, the caller must do this itself as appropriate.

NTSTATUS
  KsMergeAutomationTables(
    OUT PKSAUTOMATION_TABLE  *AutomationTableAB,
    IN PKSAUTOMATION_TABLE  AutomationTableA, /* optional */
    IN PKSAUTOMATION_TABLE  AutomationTableB, /* optional */
    IN KSOBJECT_BAG  Bag /* optional */
    );

Parameters

AutomationTableAB
Points to a PKSAUTOMATION_TABLE into which will be placed a pointer to the merged automation table.
AutomationTableA
The first of the two automation tables to merge. This table is the dominant table with respect to duplicate entries. Any item present in both table A and table B will be placed into the merged automation table exactly as in table A.
AutomationTableB
The second of the two automation tables to merge.
Bag
If present, the newly created automation table will be placed into the specified object bag for later cleanup.

Return Value

STATUS_SUCCESS will be returned if the merge was completed successfully. If not, an error code will be returned. Most often this will be STATUS_INSUFFICIENT_RESOURCES indicating that there are not sufficient system resources to complete the merge.

Comments

If the Bag parameter is not NULL, the mutex associated with the bag needs to be taken. If the bag is associated with a pin or a filter, then the control mutex must be held. If the bag is associated with a filter factory or a device, then the device mutex should be held.

See Also

Mutexes in AVStream


KsPinAcquireControl

KsPinAcquireControl acquires the control mutex for the AVStream pin specified by Pin. The pin control mutex is the same mutex as is used by Pin’s parent (in other words, it is the filter control mutex as well). See KsAcquireControl for a description of what the control mutex is used for.

VOID
  KsPinAcquireControl(
    IN PKSPIN  Pin
    );

Return Value

None

Comments

This function is simply an inline call to KsAcquireControl with the appropriate type casting. Minidrivers should call this function instead of calling KsAcquireControl directly (for a pin) as it provides greater readability.

See Also

KsAcquireControl, KsPinReleaseControl, KsReleaseControl


KsPinAcquireProcessingMutex

KsPinAcquireProcessingMutex acquires the processing mutex for the AVStream pin specified by Pin. This mutex is acquired internally by AVStream before processing at the pin level. It is also acquired during several other operations including sleep or wake power operations, etc… Minidrivers can manually acquire the mutex with this call to perform an operation synchronously with respect to processing.

VOID
  KsPinAcquireProcessingMutex(
    IN PKSPIN  Pin
    );

Parameters

Pin
Points to the AVStream pin object for which you wish to acquire the processing mutex.

Return Value

None

Comments

Minidrivers which need to suspend processing for a long period of time should not use this mechanism to do so. They can instead manipulate the processing control gate directly via the KsGate* functions.

See Also

KsPinReleaseProcessingMutex


KsPinAddEvent

KsPinAddEvent adds a specified event to Pin’s event list. See KsAddEvent for more information.

VOID
  KsPinAddEvent(
    IN PKSPIN  Pin,
    IN PKSEVENT_ENTRY  EventEntry
    );

Parameters

Pin
The pin to which you wish to add a specified event.
EventEntry
Points to an event entry structure describing the event which you wish to add to Pin.

Comments

This function is simply an inlined function call to KsAddEvent.

See Also

KsAddEvent, KsGenerateEvents, KSEVENT_ENTRY, KsDefaultAddEventHandler, KsGenerateEvents,KsFilterGenerateEvents, KsPinGenerateEvents


KsPinAttachAndGate

KsPinAttachAndGate connects a pin's queue to a previously inserted AND gate in a filter, which in effect allows the minidriver to request a callback if there is a frame on only one input or output pin.

VOID
  KsPinAttachAndGate(
    IN PKSPIN Pin,
    IN PKSGATE AndGate OPTIONAL
    );

Parameters

Pin
The pin whose queue you wish to connect the gate.
AndGate
The previously inserted gate that you wish to connect to the pin's queue.

Comments

To insert the gate, first call KsGateInitializeAnd. Then call KsPinAttachAndGate to connect the specified gate to the specified pin's queue.

See Also

KsPinAttachOrGate


KsPinAttachOrGate

KsPinAttachOrGate connects a pin's queue to a previously inserted OR gate in a filter, which in effect allows the minidriver to request a callback if there is a frame on only one input or output pin.

VOID
  KsPinAttachOrGate(
    IN PKSPIN Pin,
    IN PKSGATE OrGate OPTIONAL
    );

Parameters

Pin
The pin whose queue you wish to connect the gate.
OrGate
The previously inserted gate that you wish to connect to the pin's queue.

Comments

To insert the gate, first call KsGateInitializeOr. Then call KsPinAttachAndGate to connect the specified gate to the specified pin's queue.

Do not leave an unattached OR gate at filter creation time. Instead, create the OR gate later, for instance when the minidriver instantiates the pin.

See Also

KsPinAttachAndGate


KsPinAttemptProcessing

KsPinAttemptProcessing attempts to initiate processing on Pin – this will result in a processing dispatch call to the processing object of Pin. This call will typically be made after a minidriver halts processing by return STATUS_PENDING from a processing dispatch, not setting the Terminate flag of a process pin, shutting off the processing control gate with KsGateTurnInputOff, etc… Note that this will only cause a processing dispatch if the process control gate is in the open state.

Should the gate be “open,” the processing dispatch can occur either synchronously or asynchronously. The Asynchronous flag will specify the minidriver’s preference for this. Should the minidriver request an asynchronous process dispatch, the dispatch will always be asynchronous; however, a synchronous dispatch will only occur if the system is currently at IRQL less than the maximum processing IRQL (ie – if the minidriver does not specify dispatch level processing and the call is made at IRQL DISPTACH_LEVEL, the call will occur in an asynchronous work item at PASSIVE_LEVEL).

VOID
  KsPinAttemptProcessing(
    IN PKSPIN  Pin,
    IN BOOLEAN  Asynchronous
    );

Parameters

Pin
Points to the AVStream pin object which you wish to attempt processing on.
Asynchronous
Indicates the minidriver’s preference as to whether the processing should occur synchronously or asynchronously. Should this be TRUE, processing will always be asynchronous. However, synchronous processing will only happen under certain circumstances. See above for details.

Return Value

None

Comments

Note that this is only an attempt at processing; calling this function does not guarantee that processing will commence. It will only occur should the process control gate be “open.”

See Also

KSGATE, Flow Control Gates in AVStream


KsPinGenerateEvents

KsPinGenerateEvents generates events of an indicated type that are present in Pin’s event list. An event will be generated if it is present in Pin’s event list and EventId matches the event’s id, EventSet either matches the event’s set GUID or is NULL, and CallBack is either NULL or ok’s the match.

CallBack is a caller specified callback used for additional match determination. It is prototyped as follows:

BOOLEAN CallBack (IN PVOID Context, IN PKSEVENT_ENTRY EventEntry);

Context in the callback function will be CallBackContext. The function should return TRUE if EventEntry should be generated. Otherwise, FALSE should be returned.

VOID
  KsPinGenerateEvents(
    IN PKSPIN  Pin,
    IN const GUID*  EventSet, /* optional */
    IN ULONG  EventId,
    IN ULONG  DataSize,
    IN PVOID  Data, /* optional */
    IN PFNKSGENERATEEVENTCALLBACK  CallBack, /* optional */
    IN PVOID  CallBackContext /* optional */
    );

Parameters

Pin
The pin on which to generate events.
EventSet
The event set GUID to match against for determination of which events to generate. If this parameter is NULL, set GUID will not be taken into account in determination of matching events.
EventId
The event Id to match against for determination of which events to generate.
DataSize
The size of the data with which to generate the data event.
Data
The data with which to generate the data event. See additional information below.
CallBack
Points to a caller specified function which will be called to determine whether a given event should be generated. If this is NULL, no callback verification is performed to determine whether or not an event should be generated (only EventSet and EventId will be used). See additional information below.
CallBackContext
Points to a caller specified context blob which will be passed to the callback function CallBack. See additional information below.

Return Value

None

Comments

When calling this function, a minidriver must place Data and CallBackContext in a locked, non-pageable data segment. In addition, note that the Callback will be made at DISPATCH_LEVEL. The callback function must be in a locked segment and must be prepared to run at IRQL DISPATCH_LEVEL. Note that there is an additional issue in DX8 only: EventSet must be in a locked data segment.

This is simply an inline function call to KsGenerateEvents which performs necessary type casting. Minidrivers will typically call this version instead of KsGenerateEvents directly.

See Also

KsAddEvent, KsGenerateEvents, KsFilterGenerateEvents, KSEVENT_ENTRY


KsPinGetAndGate

KsPinGetAndGate returns the processing control gate for the given Pin.

PKSGATE
  KsPinGetAndGate(
    IN PKSPIN  Pin
    );

Parameters

Pin
The pin for which you wish to get the processing control gate

Return Value

The processing control gate for Pin.


KsPinGetConnectedFilterInterface

KsPinGetConnectedFilterInterface queries the filter to which Pin is connected in order to obtain a pointer to a COM style interface. By default, objects will support the IUnknown interface and the IKsControl interface. If the respective filter and connected pin are AVStream objects, the query and the returned interface pointer will be direct calls to the other driver. If, on the other hand, the connected pin and filter do not belong to an AVStream driver, a thunk will be created that will provide IKsControl support through synchronous calls to the driver containing the filter (via IoCallDriver).

The most common usage of this function is to acquire the control interface for the filter Pin attaches to. This control interface can be used for property, method, or event calls down to the connected pin or can query for interfaces which have been aggregated onto the connected filter (if the connected filter is an AVStream filter; AVStream only provides thunking for IKsControl and IUnknown for non AVStream filters).

NTSTATUS
  KsPinGetConnectedFilterInterface(
    IN PKSPIN  Pin,
    IN const GUID*  InterfaceId,
    OUT PVOID*  Interface
    );

Parameters

Pin
It will be the filter to which the connected pin of Pin is attached which will be queried for the requested interface.
InterfaceId
Points to a GUID representing the interface id for the interface you wish to obtain. A QueryInterface call will automatically be performed for this interface.
Interface
As is done in COM, the resulting interface pointer will be deposited into *Interface. This interface has a corresponding reference count and must be released by the caller as in COM.

Return Value

Should the interface exist on the connected filter or in the AVStream thunk, STATUS_SUCCESS will be returned and the interface pointer will be deposited into *Interface. Otherwise, STATUS_NOINTERFACE (corresponding to the COM HRESULT E_NOINTERFACE) will be returned.

See Also

KsPinGetConnectedPinInterface , KsPinGetReferenceClockInterface, AVStream and KCOM, The IKsControl interface.


KsPinGetConnectedPinFileObject

KsPinGetConnectedPinFileObject returns the file object for the pin to which Pin is connected.

PFILE_OBJECT
  KsPinGetConnectedPinFileObject(
    IN PKSPIN  Pin
    );

Parameters

Pin
Points to the AVStream pin object for which you wish to acquire the file object for the connected pin.

Return Value

The file object for the pin to which Pin is connected will be returned.

See Also

KsPinGetConnectedPinInterface, KsPinGetConnectedFilterInterface


KsPinGetConnectedPinInterface

KsPinGetConnectedPinInterface queries the pin to which Pin is connected for a COM style interface. By default, objects will support the IUnknown interface and the IKsControl interface. If the connected pin is an AVStream pin, the query and the returned interface pointer will be direct calls to the other driver. If, on the other hand, the connected pin does not belong to an AVStream driver, a thunk will be created that will provide IKsControl support through synchronous calls to the driver containing the connected pin (via IoCallDriver).

The most common usage of this function is to acquire the control interface for the connected pin. This control interface can be used for property, method, or event calls down to the connected pin or can query for interfaces which have been aggregated onto the connected pin (if the connected pin is an AVStream pin; AVStream only provides thunking for IKsControl and IUnknown for non AVStream pins).

NTSTATUS
  KsPinGetConnectedPinInterface(
    IN PKSPIN  Pin,
    IN const GUID*  InterfaceId,
    OUT PVOID*  Interface
  );

Parameters

Pin
It will be the pin connected to Pin which is queried for the requested interface.
InterfaceId
Points to a GUID representing the interface id for the interface you wish to obtain. A QueryInterface call will automatically be performed for this interface.
Interface
As is done in COM, the resulting interface pointer will be deposited into *Interface. This interface has a corresponding reference count and must be released by the caller as in COM.

Return Value

Should the interface exist on the connected pin or in the AVStream thunk, STATUS_SUCCESS will be returned and the interface pointer will be deposited into *Interface. Otherwise, STATUS_NOINTERFACE (corresponding to the COM HRESULT E_NOINTERFACE) will be returned.

See Also

KsPinGetConnectedFilterInterface , KsPinGetReferenceClockInterface, AVStream and KCOM, The IKsControl interface.


KsPinGetDevice

KsPinGetDevice returns the AVStream device to which Pin belongs.

PKSDEVICE
  KsPinGetDevice(
    IN PKSPIN  Pin
    );

Parameters

Pin
The pin for which we will return the owning AVStream device.

Comments

This call is simply an inlined function call to KsGetDevice.

See Also

KSPIN, KSDEVICE, KsGetDevice


KsPinGetFirstCloneStreamPointer

KsPinGetFirstCloneStreamPointer returns the first cloned stream pointer on the specified pin. This function, along with KsStreamPointerGetNextClone can be used to enumerate all clone stream pointers on a given pin in the order in which they were cloned.

PKSSTREAM_POINTER
  KsPinGetFirstCloneStreamPointer(
    IN PKSPIN  Pin
    );

Parameters

Pin
The pin on which the first clone stream pointer will be returned.

Return Value

Either the first cloned stream pointer on the specified pin will be returned or NULL will be returned indicating that no clone stream pointers exist for the pin.

See Also

KsStreamPointerGetNextClone, KsStreamPointerClone


KsPinGetLeadingEdgeStreamPointer

KsPinGetLeadingEdgeStreamPointer acquires the leading edge stream pointer for the queue associated with the given pin. The leading edge stream pointer is a pointer into the data stream which points to the most recent unread data in the queue. If the state requested for the pin specifies that the stream pointer should be locked, then attempt a lock on the leading edge as well.

PKSSTREAM_POINTER
  KsPinGetLeadingEdgeStreamPointer(
    IN PKSPIN  Pin,
    IN KSSTREAM_POINTER_STATE  State
    );

Parameters

Pin
Points to the pin for whose queue the leading edge stream pointer should be acquired.
State
Specifies the state the leading edge stream pointer should be acquired in. This can be one of the following:
KSSTREAM_POINTER_STATE_UNLOCKED
The leading edge stream pointer will be acquired regardless of whether it actually references a data frame or not.

No attempts can be made to access any data associated with the pointer until the pointer is locked. Further, frames associated with an unlocked stream pointer can be cancelled.

KSSTREAM_POINTER_STATE_LOCKED
The leading edge stream pointer will be acquired and locked. If there is no data frame associated with it, NULL will be returned. If a non-null pointer is returned, it will be a locked stream pointer and will have a data frame associated with it. Frames associated with a locked stream pointer can not be cancelled.

Return Value

The leading edge stream pointer will be returned or NULL will be returned. A return value of NULL can indicate that either there is no queue associated with the pin (i.e. – the pin does not use the standard transport mechanism) or that an attempt to lock the leading edge failed (i.e. – there is no data frame associated with the leading edge).

Comments

This routine is mainly of use in pin-centric filters.

See Also

KsStreamPointerLock, KsStreamPointerUnlock, KsStreamPointerAdvance, KsStreamPointerAdvanceOffsetsAndUnlock, KsStreamPointerClone, KsStreamPointerDelete, KsPinGetTrailingEdgeStreamPointer


KsPinGetNextSiblingPin

KsPinGetNextSiblingPin returns the next instantiated pin of the same type and on the same filter as Pin.

PKSPIN
  KsPinGetNextSiblingPin(
    IN PKSPIN  Pin
    );

Parameters

Pin
The pin for which you wish to find the next instantiated sibling pin.

Return Value

The next instantiated sibling pin of Pin will be returned. If no such pin exists, NULL will be returned.

Comments

This call is simply an inlined function call to KsGetNextSibling. Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the filter control mutex.

See Also

KSPIN, KsFilterGetFirstChildPin , KsGetNextSibling, Mutexes in AVStream


KsPinGetOuterUnknown

KsPinGetOuterUnknown returns the outer unknown interface of the pin specified by Pin.

PUNKNOWN
  KsPinGetOuterUnknown(
    IN PKSPIN  Pin
    );

Parameters

Pin
The pin for which you wish to get the outer unknown interface.

Return Value

The outer unknown interface of Pin will be returned. This can be used to query for other interfaces.

Comments

This is simply an inlined function call to KsGetOuterUnknown.

See Also

KsGetOuterUnknown, KsRegisterAggregatedClientUnknown


KsPinGetParentFilter

KsPinGetParentFilter returns the parent filter of Pin (the filter which Pin is a part of).

KSFILTER
  KsPinGetParentFilter(
    IN PKSPIN  Pin
    );

Parameters

Pin
The pin for which you wish to know the parent filter.

Return Value

The parent filter of Pin will be returned (the filter which Pin is a part of).

Comments

This call is simply an inlined function call to KsGetParent. Note that the object hierarchy is only guaranteed stable while the appropriate mutex is held, in this case the filter control mutex.

See Also

KSFILTER, KSPIN, KsGetParent, Mutexes in AVStream


KsPinGetReferenceClockInterface

KsPinGetReferenceClockInterface returns a COM style interface to the reference clock associated with Pin. This interface pointer will be an IKsReferenceClock.

NTSTATUS
  KsPinGetReferenceClockInterface(
    IN PKSPIN  Pin,
    OUT PIKSREFERENCECLOCK*  Interface
    );

Parameters

Pin
The AVStream pin object for which you wish to acquire the reference clock interface.
Interface
The IKsReferenceClock pointer will be deposited into *Interface. Note that this is a COM style interface with an associated reference count. Minidrivers must release the interface when they are done with it.

Return Value

If the pin implements the clock or has received notification of the master clock through the KSPROPERTY_STREAM_MASTERCLOCK property, STATUS_SUCCESS will be returned and the IKsReferenceClock interface will be deposited into *Interface. If the pin has not yet received notification of the master clock, STATUS_DEVICE_NOT_READY will be returned.

See Also

KsPinGetConnectedPinInterface , KsPinGetConnectedFilterInterface, AVStream and KCOM, The IKsReferenceClock interface.


KsPinGetTrailingEdgeStreamPointer

KsPinGetTrailingEdgeStreamPointer acquires the trailing edge stream pointer for the queue associated with the specified pin. The trailing edge stream pointer is a special pointer into the data stream which exists if and only if the pin descriptor for the pin specifies a distinct trailing edge. If this pointer does exist, it will point to the oldest data in the queue unless specifically advanced by a KsStreamPointerAdvance* or a KsStreamPointerUnlock call. Older data can exist in the queue also if cloned stream pointers exist for frames older than the one pointed to by the trailing edge.

Data frames which reside in the window between the leading edge stream pointer and the trailing edge stream pointer have at least one reference count on them and thus will not leave the queue and be completed until they exit the window via the advancement of the trailing edge. Note that frames between the leading edge and trailing edge are not by default locked and thus can be cancelled.

PKSSTREAM_POINTER
  KsPinGetTrailingEdgeStreamPointer(
    IN PKSPIN  Pin,
    IN KSSTREAM_POINTER_STATE  State
    );

Parameters

Pin
Points to the pin for whose queue the trailing edge stream pointer should be acquired.
State
Specifies the state in which the trailing edge stream pointer should be acquired.

See KsPinGetLeadingEdgeStreamPointer for details.

Return Value

The trailing edge stream pointer will be returned or NULL will be returned. A return value of NULL can indicate that either there is no trailing edge for the queue associated with the pin (i.e. – the pin descriptor does not specify that the pin should have a distinct trailing edge), there is no queue associated with the pin (i.e. – the pin does not use the standard transport mechanism) or that an attempt to lock the trailing edge failed (i.e. – there is no data frame associated with the leading edge)

Comments

This routine is mostly of use in pin-centric filters. Further, in order for this routine to work, the pin descriptor for the pin must specify that the queue is to have a distinct trailing edge via the KSPIN_FLAG_DISTINCT_TRAILING_EDGE flag.

See Also

KsPinGetLeadingEdgeStreamPointer, KsStreamPointerLock, KsStreamPointerUnlock, KsStreamPointerAdvance, KsStreamPointerAdvanceOffsetsAndUnlock, KsStreamPointerClone, KsStreamPointerDelete


KsPinHandshake

KsPinHandshake attempts to perform a protocol handshake with a connected pin. Protocol handshakes can be used to negotiate private interfaces between two pins which are both AVStream pins.

Connections between AVStream pins are performed via this type of handshake.

NTSTATUS
  KsPinHandshake(
    IN PKSPIN  Pin,
    IN PKSHANDSHAKE  In,
    OUT PKSHANDSHAKE  Out
    );

Parameters

Pin
Points to the pin object which is initiating the handshake. The handshake request will be passed on to the pin connected to this object.
In
Points to the structure containing the handshake information to be passed to the connected pin. Members of this structure include the following:
Member | Value
GUID ProtocolId | A guid representing the interface which is attempting to be negotiated between the two pins.
PVOID Argument1 | Interface dependent argument. Often this will be used to pass an interface pointer back and forth.
PVOID Argument2 | Interface dependent argument

Out
Points to a structure which will be filled in with handshake information by the connected pin.

Return Value

STATUS_SUCCESS will be returned if the connected pin is accepting the negotiated connection; otherwise an appropriate error code will be returned.

See Also

KsPinGetConnectedPinInterface , KsPinRequestHandshakeCallback, KSHANDSHAKE


KsPinRegisterFrameReturnCallback

KsPinRegisterFrameReturnCallback registers a frame return callback with AVStream for a given pin. If a pin has registered a frame return callback prior to the time the pin transitions from KSSTATE_STOP to KSSTATE_ACQUIRE, the pin will be placed into injection mode. This indicates that the pin does not want to receive buffers and fill them, but rather wishes to manually inject data frames into the circuit via KsPinSubmitFrame or KsPinSubmitFrameMdl. When the data frame completes its travel around the circuit and returns to the pin on which it was submitted, it is recycled by calling FrameReturn.

VOID
  KsPinRegisterFrameReturnCallback(
    IN PKSPIN  Pin,
    IN PFNKSPINFRAMERETURN  FrameReturn
    );

Parameters

Pin
Points to the AVStream pin object which you wish to place into injection mode by registering a frame return callback.
FrameReturn
Points to a function which will be called when an injected frame has completed its trip around the circuit and is ready to be recycled (or freed.). The frame return callback should be prototyped as follows:
void FrameReturn (
IN PKSPIN Pin,
IN PVOID Data,/* optional */
IN ULONG Size,/* optional */
IN PMDL Mdl,/* optional */
IN PVOID Context,/* optional */
IN NTSTATUS Status/* optional */
);

The Pin pointer will point to the pin on which this frame was injected. Data and Size will be the data pointer and buffer size as originally specified via KsPinSubmitFrame. Mdl points to a memory descriptor list describing the injected frame as originally done via KsPinSubmitFrameMdl. The Context pointer will be the minidriver supplied context attached to the frame when the frame was injected into the circuit. Status will contain a copy of Irp->IoStatus.Status for the Irp to which the requested frame was attached.

Return Value

None

Comments

Minidrivers who call this function are directly responsible for injecting frames into the circuit; they will not receive buffers to fill and will not directly interact with the queue in the manner in which most minidrivers will. It is also important to note that the frame return callback should be registered before the kernel pipe section is created (when the pin transitions to KSSTATE_ACQUIRE).

See Also

KsPinSubmitFrame, KsPinSubmitFrameMdl, Frame Injection


KsPinRegisterHandshakeCallback

KsPinRegisterHandshakeCallback allows a pin to request a callback when AVStream receives a handshake request for the pin and the handshake requests a protocol which AVStream does not handle by default. Pins which wish to support private protocol connections with other AVStream pins should register a handshake callback.

VOID
  KsPinRegisterHandshakeCallback(
    IN PKSPIN  Pin,
    IN PFNKSPINHANDSHAKE  Handshake

Parameters

Pin
The pin for which you wish to register a handshake callback.
Handshake
Points to the function to be called when AVStream receives a protocol handshake request on Pin which it does not understand. The function should be prototyped as follows:
NTSTATUS Handshake (IN PIRP Irp,
    IN PKSIDENTIFIER Request,
    IN OUT PVOID Data);

The function should check the GUID in Request to determine if the pin supports the requested protocol. If so, Data should be filled in as a PKSHANDSHAKE structure, and STATUS_SUCCESS should be returned; otherwise, STATUS_INVALID_DEVICE_REQUEST should be returned.

Return Value

None

Comments

Minidrivers which intent to support private protocols between a given pin and another AVStream pin should call this routine as soon as possible to register a callback so that should another pin request a handshake, the minidriver can return the request.

See Also

KsPinHandshake, KSHANDSHAKE, KsFilterRegisterPowerCallbacks, KsPinRegisterPowerCallbacks, KsRegisterAggregatedClientUnknown,


KsPinRegisterPowerCallbacks

KsPinRegisterPowerCallbacks allows the caller to register power management callbacks for Pin. The two callbacks provided need to be prototyped as follows:

void Sleep/Wake (IN PKSPIN Pin, IN DEVICE_POWER_STATE State);

The Sleep callback will be made if Pin is a pin-centric pin and the device is going to sleep. The Wake callback will be made if Pin is a pin-centric pin and the device is waking up.

VOID
  KsPinRegisterPowerCallbacks(
    IN PKSPIN  Pin,
    IN PFNKSPINPOWER  Sleep, /* optional */
    IN PFNKSPINPOWER  Wake
    );

Parameters

Pin
The pin for which to register power callbacks. Note that the pin must actually process (be pin-centric) in order to receive power notification messages.
Sleep
Points to a function which will handle sleep requests for the device.
Wake
Points to a function which will handle wake requests for the device.

Return Value

None

See Also

KsFilterRegisterPowerCallbacks


KsPinReleaseControl

KsPinReleaseControl releases the control mutex for the AVStream pin specified by Pin. The pin control mutex is the same mutex as is used by Pin’s parent (in other words, it is the filter control mutex as well). See KsAcquireControl for a description of what the control mutex is used for.

VOID
  KsPinReleaseControl(
    IN PKSPIN  Pin
    );

Return Value

None

Comments

This function is simply an inline call to KsReleaseControl. Minidrivers should call this function instead of calling KsReleaseControl directly (for a pin) as it provides greater readability.

See Also

KsReleaseControl, KsPinAcquireControl, KsAcquireControl, Synchronization and AVStream


KsPinReleaseProcessingMutex

KsPinReleaseProcessingMutex releases the processing mutex for the AVStream pin specified by Pin. This mutex is acquired internally by AVStream before processing at the pin level. It is also acquired during several other operations including sleep or wake power operations, etc…

VOID
  KsPinReleaseProcessingMutex(
    IN PKSPIN  Pin
    );

Parameters

Pin
Points to the AVStream pin object for which you wish to acquire the processing mutex.

Return Value

None

Comments

Minidrivers which need to suspend processing for a long period of time should not use this mutex to do so. They can instead manipulate the processing control gate directly via the KsGate* functions.

See Also

KsPinAcquireProcessingMutex


KsPinSetPinClockTime

KsPinSetPinClockTime sets the current time of the clock exposed by Pin. This modifies the current time returned by the clock. If an external clock is used, this function can still be used to force a resetting of the current timer when an external timer is not being used. In this case the time provided is ignored and must be set to zero.

VOID
  KsPinSetPinClockTime(
    IN PKSPIN  Pin,
    IN LONGLONG  Time
    );

Parameters

Pin
Points to the AVStream pin object whose exposed clock will be set to the time specified by Time.
Time
Specifies the time that will be set on the clock exposed by Pin.

Return Value

None

See Also

KsPinGetReferenceClockInterface


KsPinSubmitFrame

If a pin has been placed into injection mode via a call to KsPinRegisterFrameReturnCallback, this will submit a frame directly into the transport circuit.

NTSTATUS
  KsPinSubmitFrame(
    IN PKSPIN  Pin,
    IN PVOID  Data, /* optional */
    IN ULONG  Size, /* optional */
    IN PKSSTREAM_HEADER  StreamHeader, /* optional */
    IN PVOID  Context, /* optional */
    );

Parameters

Pin
The pin on which to submit a frame.
Data
An optional pointer to the frame buffer. This should be NULL if and only if Size is equal to 0.
Size
The size of the frame buffer to which the Data field points. If the Data field is NULL, then this field must be set to zero.
StreamHeader
Contains an optional pointer to a stream header. The stream header will be copied if it is supplied.
Context
Contains an optional pointer which will be passed to the frame return callback registered via KsPinRegisterFrameReturnCallback.

Return Value

STATUS_SUCCESS will be returned if frame submission is successful; otherwise an appropriate error code will be returned.

See Also

KsPinSubmitFrameMdl


KsPinSubmitFrameMdl

If a pin has been placed into injection mode via a call to KsPinRegisterFrameReturnCallback, this function will submit a frame directly into the transport circuit. .

KSDDKAPI NTSTATUS NTAPI
  KsPinSubmitFrameMdl(
    IN PKSPIN  Pin,
    IN PMDL  Mdl OPTIONAL,
    IN PKSSTREAM_HEADER  StreamHeader OPTIONAL,
    IN PVOID  Context OPTIONAL
    );

Parameters

Pin
The pin on which to submit a frame.
Mdl
A memory descriptor list describing the frame buffer.
StreamHeader
Contains an optional pointer to a stream header. The stream header will be copied if it is supplied.
Context
Contains an optional pointer which will be passed to the frame return callback registered via KsPinRegisterFrameReturnCallback.

Return Value

STATUS_SUCCESS will be returned if frame submission is successful; otherwise an appropriate error code will be returned.

Comments

The difference between this function and KsPinSubmitFrame is that this function will submit a frame via an Mdl instead of via a data and size argument.

See Also

KsPinSubmitFrame


KsRegisterAggregatedClientUnknown

In a manner very similar to COM, this function aggregates two objects: the specified AVStream object and a client unknown object.

KSDDKAPI PUNKNOWN NTAPI
  KsRegisterAggregatedClientUnknown(
    IN PVOID  Object,
    IN PUNKNOWN  ClientUnknown
    );

Parameters

Object
The specified AVStream object.
ClientUnknown
The client unknown object.

Return Values

Comments

The client unknown becomes the inner part of the aggregate object, and the AVStream object becomes the outer unknown. When an interface is queried that AVStream does not handle, the query is passed to the inner aggregate. If a client unknown is already aggregated on the AVStream object, the previously registered aggregate will be released and the unknown passed to KsRegisterAggregatedClientUnknown will become the new inner unknown. Note that there exist also four wrappers to KsRegisterAggregatedClientUnknown that do typecasts. These functions are not separately documented. They are: KsDeviceRegisterAggregatedClientUnknown, KsFilterFactoryRegisterAggregatedClientUnknown, KsFilterRegisterAggregatedClientUnknown, and-KsPinRegisterAggregatedClientUnknown.


KsReleaseDevice

KsReleaseDevice is used by a client which is done accessing the device in a synchronous manner via a previous call to KsAcquireDevice. This will release the device mutex and exit the critical region.

VOID
  KsReleaseDevice(
    IN PKSDEVICE  Device
    );

Parameters

Device
The AVStream device you wish to release synchronous control of.

Return Value

None

See Also

KsAcquireDevice, KSDEVICE


KsRegisterFilterWithNoKSPins

KsRegisterFilterWithNoKSPins is used to register filters with DirectShow which have no kernel streaming pins and, therefore, do not stream in kernel mode. This function is typically used to register TvTuners, Crossbars, and similar components. It creates a new registry key, FilterData, that contains the Mediums and optionally the Categories for each pin on the filter.

NTSTATUS
  KsRegisterFilterWithNoKSPins(
    IN PDEVICE_OBJECT  DeviceObject,
    IN const GUID*  InterfaceClassGUID,
    IN ULONG  PinCount,
    IN BOOL*  PinDirection,
    IN KSPIN_MEDIUM*  MediumList,
    IN GUID*  CategoryList /* optional */
    );

Parameters

DeviceObject
The device object for the device this is being registered to.
InterfaceClassGUID
Contains the GUID representing the class to register. (ie: this would point to KSCATEGORY_TVTUNER for a TvTuner filter)
PinCount
Contains the count of the number of pins on the filter.
PinDirection
Contains an array of Boolean values indicating pin direction for each pin on the filter. Output pins are TRUE; input pins are FALSE. This array must be PinCount in length.
MediumList
Contains an array of KSPIN_MEDIUM structures defining the mediums for each pin on the filter. This array must be PinCount in length.
CategoryList
Contains an array of GUIDs defining the categories for each pin on the filter. If present, this array must be PinCount in length.

Return Value

Success or failure or creating the FilterData blob in the registry.

Comments

This function is only used to register filters with no corresponding kernel pins. It merely creates a blob in the registry which is understood by DirectShow.


KsReleaseControl

KsReleaseControl releases the control mutex for Object. Object will be either a filter or a pin. The control mutex is used in AVStream to synchronize the object hierarchy from a specific filter instance downward. This means that AVStream will take the control mutex during creation of a filter, creation of pins, deletion of pins, handling properties which require the hierarchy to remain stable, descriptor modification, etc…

One important thing to note is that there is a single control mutex used for the object hierarchy from the filter down. This means that a pin object uses its parent’s control mutex (the filter control mutex) when you call this function with a pin object.

VOID
  KsFilterReleaseControl(
    IN PVOID  Object
    );

Parameters

Object
The object for which to release the control mutex. This can be either a filter or a pin (cast to PVOID).

Comments

Minidrivers will typically not call this function directly, but will instead call either KsFilterReleaseControl or KsPinReleaseControl. These versions provide the necessary type casting to PVOID automatically.

See Also

KsAcquireControl, KsFilterReleaseControl, KsPinReleaseControl, Synchronization in AVStream


KsRemoveItemFromObjectBag

KsRemoveItemFromObjectBag removes an item from an object bag and frees it if the number of references on this item is zero and a free was requested.

A single item can reside in multiple object bags and this accounts for the reference counting on each item. If you remove Item from an object bag and another object bag contains Item also, it will not be freed.

ULONG
  KsRemoveItemFromObjectBag(
    IN KSOBJECT_BAG  ObjectBag,
    IN PVOID  Item,
    IN BOOLEAN  Free
   );

Parameters

ObjectBag
The object bag from which Item will be removed.
Item
The item to remove from the requested object bag. Note that the item will be removed from the requested object bag only. It will not be removed from any other object bags that it may be in.
Free
Indicates whether or not Item should be freed if it is contained in no other object bag once it has been removed from the specified object bag.

Return Value

The number of references on Item will be returned. Should this be 0, it indicates that Item was not in ObjectBag to begin with. A return value of 1 indicates that Item was successfully removed from ObjectBag and that it was not in any other object bag; if a free was requested in this case, Item will be freed with either ExFreePool or the Free method specified when KsAddItemToObjectBag was called. A return value above 1 indicates that the item is present in another object bag and that there are still references on it; in this case, Item has been removed from ObjectBag but has not yet been freed regardless the value of Free.

Comments

Note that the mutex associated with the bag must be held. Please see related information in KsMergeAutomationTables.

Items should be removed from an object bag only when they no longer are associated with a given object.

See Also

KsAddItemToObjectBag, KsDiscard, KsAllocateObjectBag, KsFreeObjectBag, KsCopyObjectBagItems


KsStreamPointerAdvance

KsStreamPointerAdvance advances a stream pointer to the next data frame. If the given stream pointer is currently locked, it will be unlocked prior to advancement. Once advanced, the stream pointer will be placed back into its original state (locked or unlocked) on the new frame.

NTSTATUS
  KsStreamPointerAdvance(
    IN PKSSTREAM_POINTER  StreamPointer
    );

Parameters

StreamPointer
The stream pointer which will get advanced to reference the next available data frame.

Return Value

STATUS_SUCCESS will be returned on a successful advancement. An error code will be returned otherwise. STATUS_DEVICE_NOT_READY will be the most often returned error code and will often indicate that locking the stream pointer after advancement failed (i.e. – the stream pointer passed in referenced the last frame in the queue).

Comments

Advancing a stream pointer which is unlocked will always succeed with STATUS_SUCCESS. The reason behind this is that since the stream pointer is not locked, there is no way to determine if the stream pointer references actual data. You must attempt a lock to determine if the newly advanced stream pointer references a data frame or not.

See Also

KsStreamPointerLock , KsStreamPointerUnlock, KsStreamPointerAdvanceOffsets, KsStreamPointerAdvanceOffsetsAndUnlock


KsStreamPointerAdvanceOffsets

KsStreamPointerAdvanceOffsets advances the offsets of StreamPointer into the data stream. The data pointers (both in and out) will be updated by the requested amount as will other associated fields. If advancing the offsets results in zero bytes remaining in the current frame, the stream pointer will be advanced to the next data frame and will be relocked.

NTSTATUS
  KsStreamPointerAdvanceOffsets(
    IN PKSSTREAM_POINTER  StreamPointer,
    IN ULONG  InUsed,
    IN ULONG  OutUsed,
    IN BOOLEAN  Eject
    );

Parameters

StreamPointer
The stream pointer which you wish to advance the offsets of. This stream pointer should be in the locked state when this function is called.
InUsed
The number of bytes to advance the input pointer of this stream pointer.

(StreamPointer -> OffsetIn)

OutUsed
The number of bytes to advance the output pointer of this stream pointer

(StreamPointer -> OffsetOut)

Eject
Contains an indication of whether the stream pointer should be advanced to the next data frame regardless of whether advancing the offsets causes the stream pointer to point to the end of a frame.

Return Value

Should this function succeed, STATUS_SUCCESS will be returned. STATUS_DEVICE_NOT_READY indicates that either StreamPointer was not locked to begin with or that after advancement, the stream pointer could not be locked.

Comments

Minidrivers should ensure that StreamPointer is locked prior to making this call. Also, a single advancement cannot advance a stream pointer to more than the beginning of the next frame in the queue; thus, minidrivers should not attempt to advance offsets more than StreamPointer -> Offset*.Remaining.

See Also

KsStreamPointerLock, KsStreamPointerUnlock, KsStreamPointerAdvance, KsStreamPointerAdvanceOffsetsAndUnlock


KsStreamPointerAdvanceOffsetsAndUnlock

KsStreamPointerAdvanceOffsetsAndUnlock will advance the stream pointer the specified number of bytes into the stream (adjusting the OffsetIn and OffsetOut fields of StreamPointer as requested) and unlock it. If using the specified number of bytes in the stream pointer results in zero remaining bytes to process in the current frame, the stream pointer will be advanced to the next available frame. Minidrivers can force advancement to the next frame regardless the number of bytes used through the Eject parameter.

VOID
  KsStreamPointerAdvanceOffsetsAndUnlock(
    IN PKSSTREAM_POINTER  StreamPointer,
    IN ULONG  InUsed,
    IN ULONG  OutUsed,
    IN BOOLEAN  Eject
    );

Parameters

StreamPointer
The stream pointer to advance and unlock.
InUsed
The number of input bytes that have been used on StreamPointer. This number must be less than the total number of remaining unused bytes in the frame referenced by StreamPointer. The input pointer will be advanced this many bytes into the data stream. If this is equal to the remaining number of bytes in the frame referenced by StreamPointer, it will be advanced to the next available data frame.
OutUsed
The number of output bytes that have been used on StreamPointer. This number must be less than the total number of remaining unused bytes in the frame referenced by StreamPointer. The output pointer will be advanced this many bytes into the data stream. If this is equal to the remaining number of bytes in the frame referenced by StreamPointer, it will be advanced to the next available data frame.
Eject
Indicates whether or not StreamPointer should be advanced to the next available data frame regardless the contents of InUsed and OutUsed.

See Also

KsStreamPointerAdvance, KsStreamPointerUnlock, KsStreamPointerLock, KsStreamPointerClone, KsStreamPointerDelete


KsStreamPointerCancelTimeout

KsStreamPointerCancelTimeout cancels a previously scheduled timeout callback (from KsStreamPointerScheduleTimeout) on the specified stream pointer. This routine will have no effect for stream pointers which have no currently scheduled timeout callback.

VOID
  KsStreamPointerCancelTimeout(
    IN PKSSTREAM_POINTER  StreamPointer
    );

Parameters

StreamPointer
The stream pointer for which to cancel a registered timeout callback.

Return Value

None

See Also

KsStreamPointerScheduleTimeout, KsPinGetFirstCloneStreamPointer


KsStreamPointerClone

KsStreamPointerClone creates a clone of a given stream pointer. The clone will refer to the same data frame as the original stream pointer and will be in the same state (locked or unlocked). Having a clone stream pointer referencing a data frame places a reference count on that particular frame meaning that the frame, and hence the Irp to which the frame belongs, will not be completed until the reference count drops to zero.

NTSTATUS
  KsStreamPointerClone(
    IN PKSSTREAM_POINTER  StreamPointer,
    IN PFNKSSTREAMPOINTER  CancelCallback /* optional */,
    IN ULONG  ContextSize,
    OUT PKSSTREAM_POINTER  *CloneStreamPointer
    );

Parameters

StreamPointer
The stream pointer which is to be cloned.
CancelCallback
Specifies a function which will get called should the Irp to which the data frame pointed to by this stream pointer belongs is cancelled. This callback function is prototyped as:
void CancelCallback (IN PKSSTREAM_POINTER StreamPointer);

Note that this function is called while the filter control mutex is held; thus, the callback function cannot perform any queue manipulation or call any functions which acquire the filter control mutex. Normally, this callback function is used to remove context information or send information to hardware concerning the cancellation of data.

ContextSize
Indicates how many bytes of minidriver context information this clone stream pointer should have. If this is nonzero, the requested number of bytes will be allocated immediately after the returned stream pointer and the Context field of CloneStreamPointer will point to the allocated memory.
CloneStreamPointer
Points to a PKSSTREAM_POINTER into which the cloned stream pointer will be deposited once the cloning operation is complete.

Return Value

Either STATUS_SUCCESS will be returned indicating that the cloning operation proceeded normally or an appropriate error code will be returned.

See Also

KsStreamPointerDelete , KsStreamPointerLock, KsStreamPointerUnlock, KsStreamPointerAdvance, KsStreamPointerAdvanceOffsets, KsStreamPointerAdvanceOffsetsAndUnlock


KsStreamPointerDelete

KsStreamPointerDelete deletes a given clone stream pointer, releasing a reference on the frame to which this stream pointer referred. If this frame has no other references on it after deletion, it will be completed; when the last frame in a given Irp is completed, the Irp will be completed.

Note that the leading edge and trailing edge stream pointers for a given queue and pin are special stream pointers that cannot be deleted.

VOID
  KsStreamPointerDelete(
    IN PKSSTREAM_POINTER  StreamPointer
    );

Parameters

StreamPointer
The clone stream pointer to delete. This pointer must be a clone stream pointer; it cannot be the leading or trailing edge stream pointers.

Return Value

None

See Also

KsStreamPointerClone, KsPinGetLeadingEdgeStreamPointer, KsPinGetTrailingEdgeStreamPointer


KsStreamPointerGetIrp

KsStreamPointerGetIrp returns the Irp associated with frame referenced by the given stream pointer. It can also be used to determine if the stream pointer references the first and/or last frame contained in the returned Irp.

PIRP
  KsStreamPointerGetIrp(
    IN PKSSTREAM_POINTER  StreamPointer,
    IN PBOOLEAN  FirstFrameInIrp, /* optional */
    IN PBOOLEAN  LastFrameInIrp /* optional */
    );

Parameters

StreamPointer
The stream pointer for which the Irp associated with the data frame referenced by this stream pointer will be returned.
FirstFrameInIrp
Points to a BOOLEAN into which will be placed TRUE if the frame referenced by the stream pointer is the first frame in the returned Irp and FALSE if it is not.
LastFrameInIrp
Points to a BOOLEAN into which will be placed TRUE if the frame referenced by the stream pointer is the last frame in the returned Irp and FALSE if it is not.

Return Value

The Irp associated with the frame referenced by the given stream pointer will be returned or NULL will be returned. A return value of NULL indicates that the stream pointer is not locked. Further, if FirstFrameInIrp or LastFrameInIrp are non NULL, the values will be filled in appropriately.

Comments

StreamPointer must be locked in order for this function to proceed successfully. Any attempt to call this function with an unlocked stream pointer will return NULL.

See Also

KsStreamPointerLock


KsStreamPointerGetMdl

KsStreamPointerGetMdl returns the MDL associated with the frame referenced by the given stream pointer. The stream pointer must be locked in order for this operation to proceed.

PMDL
  KsStreamPointerGetMdl(
    IN PKSSTREAM_POINTER  StreamPointer
    );

Parameters

StreamPointer
The stream pointer referencing the frame for which the MDL is to be returned.

Return Value

Either a pointer to the MDL describing the frame referenced by the passed in stream pointer will be returned or NULL will be returned. A result of NULL usually indicates that the given stream pointer is currently not locked.

See Also

KsStreamPointerGetIrp


KsStreamPointerGetNextClone

KsStreamPointerGetNextClone returns the clone stream pointer which was cloned immediately after the specified clone. The returned pointer will always be referring to the same pin as the passed in clone stream pointer. This function, along with KsPinGetFirstCloneStreamPointer, can be used to enumerate through all clone stream pointers on a given pin in the order in which they were cloned.

PKSSTREAM_POINTER
  KsStreamPointerGetNextClone(
    IN PKSSTREAM_POINTER  StreamPointer
    );

Parameters

StreamPointer
The clone stream pointer for which the clone stream pointer cloned immediately after it on the same pin will be returned.

Return Value

The clone stream pointer cloned immediately after StreamPointer on the same pin as StreamPointer will be returned or NULL will be returned indicating that either the passed stream pointer is the last clone on the pin or that it is not a clone (it is either the leading or trailing edge stream pointer).

See Also

KsPinGetFirstCloneStreamPointer, KsStreamPointerClone


KsStreamPointerLock

KsStreamPointerLock will attempt to lock the specified stream pointer. A locked stream pointer guarantees that there is a data frame associated with the stream pointer and that this frame will not be cancelled so long as a lock is held on it. Some mechanism of locking a stream pointer should be used before ever accessing data that a stream pointer appears to point to.

NTSTATUS
  KsStreamPointerLock(
    IN PKSSTREAM_POINTER  StreamPointer
    );

Parameters

StreamPointer
The stream pointer which is to be locked.

Return Value

Either STATUS_SUCCESS will be returned indicating that the stream pointer has been locked or an appropriate error code will be returned (STATUS_DEVICE_NOT_READY will be the usual error code indicating that the frame could not be locked. This usually means that the frame to which the stream pointer was pointing was cancelled).

Comments

If the pin which the stream pointer references specifies that DMA scatter / gather mappings should be generated via KSPIN_FLAG_GENERATE_MAPPINGS, the mappings will actually be generated when the stream pointer is locked.

See Also

KsStreamPointerUnlock


KsStreamPointerScheduleTimeout

KsStreamPointerScheduleTimeout registers a timeout callback with AVStream for the given stream pointer. If the stream pointer has not been deleted or the timeout cancelled before the requested time interval expires, the specified callback function will be called.

VOID
  KsStreamPointerScheduleTimeout(
    IN PKSSTREAM_POINTER  StreamPointer,
    IN PFNKSSTREAMPOINTER  Callback,
    IN ULONGLONG  Interval
    );

Parameters

StreamPointer
The stream pointer for which a timeout will be registered.
Callback
Points to a function which will be called after the amount of time specified by Interval should the stream pointer not be deleted or the timeout cancelled. The callback function should be prototyped as follows:

void Callback (IN PKSSTREAM_POINTER StreamPointer);

Interval
Contains the interval from the current time to the time at which the timeout will occur in 100-nanosecond units.

Return Value

None

Comments

It is safe to call this function on a stream pointer which already has a timeout scheduled. Should this be the case, the previous timeout will be cancelled and the new timeout will replace it.

See Also

KsStreamPointerCancelTimeout, KsStreamPointerDelete


KsStreamPointerSetStatusCode

KsStreamPointerSetStatusCode allows specification of a successful or unsuccessful error code with which to complete the given IRP.

KSDDKAPI NTSTATUS NTAPI
  KsStreamPointerSetStatusCode(
    IN PKSSTREAM_POINTER StreamPointer,
    IN NTSTATUS Status
    );

Parameters

StreamPointer
The IRP contains the frame to which this pointer points.
Status
The error code with which to complete the IRP.

Comments

Note that the IRP contains the frame to which StreamPointer points.


KsStreamPointerUnlock

KsStreamPointerUnlock unlocks a stream pointer which has previously been locked by an acquisition function (KsGet*EdgeStreamPointer) or by KsStreamPointerLock. This function can also advance the stream pointer to the next data frame.

VOID
  KsStreamPointerUnlock(
    IN PKSSTREAM_POINTER  StreamPointer,
    IN BOOLEAN  Eject
    );

Parameters

StreamPointer
The stream pointer which should be unlocked
Eject
Indicates whether or not the specified stream pointer should be advanced to the next data frame or not.

Return Value

None

See Also

KsStreamPointerLock, KsStreamPointerAdvance, KsStreamPointerAdvanceOffsets, KsStreamPointerAdvanceOffsetsAndUnlock


KsTerminateDevice

KsTerminateDevice is used to remove an AVStream device. Normally, this function will be called upon receipt of a PnP remove device Irp (IRP_MN_REMOVE_DEVICE). Most minidrivers will not call this function directly; however, it can be used to remove AVStream support for the device given in DeviceObject.

VOID
  KsTerminateDevice(
    IN PDEVICE_OBJECT  DeviceObject
    );

Parameters

DeviceObject
Points to a device object for the device you wish to remove AVStream support of.

Return Value

None

See Also

KsInitializeDriver , KsInitializeDevice, KsAddDevice, KsCreateDevice, KSDEVICE


AVStream Structures


KSALLOCATOR_DISPATCH

KSALLOCATOR_DISPATCH contains the callbacks required for a pin to implement its own kernel level allocator.

Typedef struct {
  PFNKSPININITIALIZEALLOCATOR  InitializeAllocator;
  PFNKSDELETEALLOCATOR  DeleteAllocator;
  PFNKSDEFAULTALLOCATE  Allocate;
  PFNKSDEFAULTFREE  Free;
} KSALLOCATOR_DISPATCH, *PKSALLOCATOR_DISPATCH;

Members

InitializeAllocator
Points to a function which will be called to initialize the given allocator. The handler for this callback should do whatever is necessary to prepare to handle memory allocation and free requests; it will be passed the allocator framing requirements that it must use to allocate memory, and it can store a pointer to an allocator context structure in the context parameter.

The function should return success/failure in initializing the allocator. It should be prototyped as follows:

    NTSTATUS InitializeAllocator (IN PKSPIN Pin, IN PKSALLOCATOR_FRAMING AllocatorFraming,
        OUT PVOID *Context);
DeleteAllocator
Points to a function which will be called to delete the allocator. Once this function is called, the allocator will no longer be used to allocate and free memory. The handler should be used to cleanup the allocator; it will be passed whatever context structure was set in the initialization dispatch.

The function should be prototyped as follows:

  VOID DeleteAllocator (IN PVOID Context);
Allocate
Points to a function which will be called in order to allocate a frame. The handler should allocate a frame as described by the allocator framing context passed into the initialization dispatch. The context structure set in the initialization dispatch will be passed to the allocation dispatch handler.

The function should be prototyped as follows:

  PVOID Allocate (IN PVOID Context);
Free
Points to a function which will be called in order to free a frame. The context structure set in the initialization dispatch will be passed, as will a pointer to the frame being freed.

The function should be prototyped as follows:

  VOID Free (IN PVOID Context,
    IN PVOID Buffer);

Comments

If in the pin dispatch table, a pointer is provided to a KSALLOCATOR_DISPATCH, that pin will be known to be capable of performing kernel level allocation. The allocator may or may not be used by the graph manager. Remember that memory allocated at kernel level cannot be passed to a user mode filter.

See Also

KSPIN_DISPATCH


KSAUTOMATION_TABLE

KSAUTOMATION_TABLE defines a structure that combines tables for properties, methods, and events.

typedef struct KSAUTOMATION_TABLE_
KSAUTOMATION_TABLE, *PKSAUTOMATION_TABLE;
struct KSAUTOMATION_TABLE_ {
  ULONG  PropertySetsCount;
  ULONG  PropertyItemSize;
  const  KSPROPERTY_SET* PropertySets;
  ULONG  MethodSetsCount;
  ULONG  MethodItemSize;
  const  KSMETHOD_SET* MethodSets;
  ULONG  EventSetsCount;
  ULONG  EventItemSize;
  const KSEVENT_SET*  EventSets;
#if !defined(_WIN64)
  PVOID  Alignment;
#endif // !defined(_WIN64)
};

Members

PropertySetsCount
The number of property sets in this automation table.
PropertyItemSize
The size of property items in this table.
PropertySets
An array of KSPROPERTY_SET objects (PropertySetsCount in length) defining the property sets in this automation table. Each set has a specific number of items in it of size PropertyItemSize.
MethodSetsCount
The number of method sets in this automation table
MethodItemSize
The size of method items in this table.
MethodSets
An array of KSMETHOD_SET objects (MethodSetsCount in length) defining the method sets in this automation table. Each set has a specific number of items in it of size MethodItemSize.
EventSetsCount
The number of event sets in this automation table.
EventItemSize
The size of event items in this table.
EventSets
An array of KSEVENT_SET objects (EventSetsCount in length) defining the event sets in this automation table. Each set has a specific number of items in it of size EventItemSize.
Alignment

Comments

Note that each object (pin, filter, topology node) should define an automation table. Most minidrivers will use the following macros:

        DEFINE_KSAUTOMATION_* (table)
        DEFINE_KSAUTOMATION_*_NULL

[with * replaced by PROPERTIES, EVENTS, or METHODS] which automatically fill in the count,

size, and sets field. For example:

        DEFINE_KSAUTOMATION_TABLE (MyAutomationTable) {
            DEFINE_KSAUTOMATION_PROPERTIES (MyPropertyTable),
            DEFINE_KSAUTOMATION_METHODS (MyMethodTable),
            DEFINE_KSAUTOMATION_EVENTS (MyEventTable)
        };


KSCLOCK_DISPATCH

KSCLOCK_DISPATCH allows a pin to expose a clock which can be chosen by the graph manager as the master clock.

typedef struct {
  PFNKSPINSETTIMER  SetTimer;
  PFNKSPINCANCELTIMER  CancelTimer;
  PFNKSPINCORRELATEDTIME  CorrelatedTime;
  PFNKSPINRESOLUTION  Resolution;
} KSCLOCK_DISPATCH, *PKSCLOCK_DISPATCH;

Members

SetTimer
Optionally contains a pointer to an alternate function to use in generating DPC timer callbacks based on a Presentation Time. If this is set, this function will be used to set timers based on deltas to the current Presentation Time in order to generate event notifications. If an alternate function is specified to set timers, a corresponding CancelTimer function must also be provided. This is set to NULL if the default KeSetTimerEx function is to be used to approximate the next notification time. This would normally be set only if a CorrelatedTime function was being used. The function must have the same characteristics as the default function.

The function should be prototyped as follows:

  BOOLEAN SetTimer (IN PKSPIN Pin,
    IN PKTIMER Timer,
    IN LARGE_INTEGER DueTime,
    IN PKDPC Dpc);

See the documentation for KeSetTimerEx for details on implementation of this function. Any client implementation must behave in a similar manner.

CancelTimer
Optionally contains an alternate function to use in canceling outstanding timer callbacks. If an alternate function is provided to cancel timers, a corresponding SetTimer function must also be provided. This is set to NULL if the default KeCancelTimer function is to be used. The function must have the same characteristics as the default function.

The function should be prototyped as follows:

  BOOLEAN CancelTimer (IN PKSPIN Pin,
    IN PKTIMER Timer);

See the documentation for KeCancelTimer for details on the implementation of this function. Any client implementation must behave in a similar manner.

CorrelatedTime
Pointer to a function to retrieve the current clock time and a correlated system time as an atomic operation. The function should be prototyped as follows:
  LONGLONG CorrelatedTime (IN PKSPIN Pin,
    OUT PLONGLONG SystemTime);

The current clock time should be returned and the current system time should be placed in SystemTime.

Resolution
Pointer to a function to specify the resolution of the clock. This corresponds to the KS property KSPROPERTY_CLOCK_RESOLUTION. This function should report the granularity in terms of 100-ns units. For more information, see the KS documentation on KSPROPERTY_CLOCK_RESOLUTION.

The function should be prototyped as follows:

    void Resolution (IN PKSPIN Pin,
        OUT PKSRESOLUTION Resolution);

See Also

KSPIN_DISPATCH


KSDEVICE_DESCRIPTOR

KSDEVICE_DESCRIPTOR describes the characteristics of a particular device.

typedef struct {
  const KSDEVICE_DISPATCH*  Dispatch;
  ULONG  FilterDescriptorsCount;
  const  KSFILTER_DESCRIPTOR*const* FilterDescriptors;
} KSDEVICE_DESCRIPTOR, *PKSDEVICE_DESCRIPTOR;

Members

Dispatch
Points to the client dispatch table for this device. This dispatch table contains client dispatch functions for PNP messages such as AddDevice, Start, Stop, Remove, etc… Clients are not required to supply a dispatch table unless they wish to receive callbacks for the PNP messages described in the dispatch table. Any member of the dispatch table can be NULL to indicate that the client does not wish to receive notification for that particular message. See KSDEVICE_DISPATCH for more information.
FilterDescriptorsCount
Contains the number of filter descriptors for this device which will be provided in the FilterDescriptors member. Zero is a legal value for this field; clients can create filter factories dynamically with the KsCreateFilterFactory function instead of statically describing them in the device descriptor.
FilterDescriptors
Points to an array of filter descriptors which describe filters creatable by this device. This field may be NULL if FilterDescriptorsCount is zero. See KSFILTER_DESCRIPTOR for more information.

Comments

Most often, this structure will be used in conjunction with KsInitializeDriver in the client’s DriverEntry function to initialize the device. This structure is also used to manually initialize or create devices with the KsInitializeDevice and KsCreateDevice functions.

See Also

KSDEVICE_DISPATCH, KSFILTER_DESCRIPTOR, KsInitializeDriver, KsInitializeDevice, KsCreateDevice


KSDEVICE_DISPATCH

KSDEVICE_DISPATCH describes the callbacks that a client will receive regarding device creation, PnP messages, etc.

typedef struct {
  PFNKSDEVICECREATE  Add;
  PFNKSDEVICEPNPSTART  Start;
  PFNKSDEVICE  PostStart;
  PFNKSDEVICEIRP  QueryStop;
  PFNKSDEVICEIRPVOID  CancelStop;
  PFNKSDEVICEIRPVOID  Stop;
  PFNKSDEVICEIRP  QueryRemove;
  PFNKSDEVICEIRPVOID  CancelRemove;
  PFNKSDEVICEIRPVOID  Remove;
  PFNKSDEVICEQUERYCAPABILITIES  QueryCapabilities;
  PFNKSDEVICEIRPVOID  SurpriseRemoval;
  PFNKSDEVICEQUERYPOWER  QueryPower;
  PFNKSDEVICESETPOWER  SetPower;
} KSDEVICE_DISPATCH, *PKSDEVICE_DISPATCH;

Members

Add
The add callback is made during the initialization of AVStream’s device implementation during the AddDevice stage. At the point at which this callback is made, the WDM device object has been created, the AVStream device object has been instantiated and initialized, and the KS device header has been allocated, possibly by the client in the device pre-create. This callback is most often used as an opportunity for the client to associate context information with the AVStream device object or initialize a device extension.

If this callback returns an unsuccessful status code, the AddDevice will fail. Pending is not a legal return code because no IRP is involved. The callback will be made at IRQL PASSIVE_LEVEL only and is prototyped as follows:

NTSTATUS Add (IN PKSDEVICE Device);

Start
This callback is made when a PnP start IRP (IRP_MN_START_DEVICE) is dispatched by the device. The callback is typically used by clients that need to evaluate assigned resources. The start is guaranteed to succeed if the callback returns a successful status code. Resource lists are extracted from the IRP for the convenience of the client. This function should be prototyped as follows:
    NTSTATUS Start (IN PKSDEVICE Device,
        IN PIRP Irp,
        IN PCM_RESOURCE_LIST TranslatedResourceList
        IN PCM_RESOURCE_LIST UntranslatedResourceList);

The TranslatedResourceList and UntranslatedResourceList are optional parameters which will be NULL if the device has no assigned resources.

PostStart
QueryStop
This callback is made when a PnP query stop IRP (IRP_MN_QUERY_STOP_DEVICE) is dispatched by the device. The callback is typically used by clients which need to prevent the stopping of the device for some reason or by clients which need to disallow activity that would otherwise prevent them from committing to a stop operation. If this callback is not made, AVStream will assume that the client can commit to a stop operation.

This callback may not return STATUS_PENDING; a success code indicates that the device can commit to a stop and an error code indicates that it cannot. It should be prototyped as follows:

    NTSTATUS QueryStop (IN PKSDEVICE Device,
        IN PIRP Irp);
CancelStop
This callback is made when a PnP cancel stop IRP (IRP_MN_CANCEL_STOP_DEVICE) is dispatched by the device.

The callback should be prototyped as follows:

    void CancelStop (IN PKSDEVICE Device,
        IN PIRP Irp);
Stop
This callback is made when a PnP stop IRP (IRP_MN_STOP_DEVICE) is dispatched by the device. This is usually provided by clients which need to detach from previously assigned resources before completing a stop operation. It should be prototyped as follows:
    void Stop (IN PKSDEVICE Device,
        IN PIRP Irp);
QueryRemove
This callback is made when a PnP query remove IRP (IRP_MN_QUERY_REMOVE_DEVICE) is dispatched by the device. It will usually be provided by clients which wish to prevent removal of the device or by clients that need to disallow activity which would otherwise prevent them from committing to a device removal operation. If this callback is not provided, AVStream will assume that the device can commit to a removal.

The callback is made at IRQL PASSIVE_LEVEL and may not return STATUS_PENDING; a success code indicates that the device can commit to a removal and an error code indicates that it cannot. It should be prototyped as follows:

    NTSTATUS QueryStop (IN PKSDEVICE Device,
        IN PIRP Irp);
CancelRemove
This callback is made when a PnP cancel remove IRP (IRP_MN_CANCEL_REMOVE_DEVICE) is dispatched by the device.

The callback should be prototyped as follows:

    void CancelRemove (IN PKSDEVICE Device,
        IN PIRP Irp);
Remove
This callback is made when a PnP remove IRP (IRP_MN_REMOVE_DEVICE) is dispatched by the device. It will typically be provided by clients that need to free device-associated resources. This callback is made at IRQL PASSIVE_LEVEL. It should be prototyped as follows:
    void Remove (IN PKSDEVICE Device,
        IN PIRP Irp);
QueryCapabilities
This callback is made when a PnP query capabilities IRP (IRP_MN_QUERY_CAPABILITIES) is dispatched by the device. It will usually be provided by clients that need to supply information regarding power management capabilities. This callback is made at IRQL PASSIVE_LEVEL. It cannot return STATUS_PENDING and should be prototyped as follows:
    NTSTATUS QueryCapabilities (IN PKSDEVICE Device,
        IN PIRP Irp);
SurpriseRemoval
QueryPower
SetPower

Comments

In describing a device with the KSDEVICE_DESCRIPTOR structure, clients will include a pointer to a dispatch table defined by this structure. Any member of this structure may be NULL indicating that the minidriver will receive no notification for that particular message.

See Also

KSDEVICE_DESCRIPTOR


KSDEVICE

KSDEVICE describes a WDM functional device that is managed by AVStream.

typedef struct {
  const KSDEVICE_DESCRIPTOR*  Descriptor;
  KSOBJECT_BAG  Bag;
  PVOID  Context;
  PDEVICE_OBJECT  FunctionalDeviceObject;
  PDEVICE_OBJECT  PhysicalDeviceObject;
  PDEVICE_OBJECT  NextDeviceObject;
  BOOLEAN  Started;
  SYSTEM_POWER_STATE  SystemPowerState;
  DEVICE_POWER_STATE  DevicePowerState;
} KSDEVICE, *PKSDEVICE;

Members

Descriptor
The descriptor structure describing the characteristics of the device and the static filters supported by it. See KSDEVICE_DESCRIPTOR for more information.
Bag
The object bag associated with the device. Object bags are structures used to associate dynamic memory with a specific AVStream object. Anything in the device object bag will automatically be cleaned up when the device is deleted. See the conceptual section on object bags for more information.
Context
This field is used specifically by clients to associate context information with the device. Often, clients will provide a PnP Start device callback in the dispatch table for the device and will allocate a device extension in that function. This is where the device extension pointer will be kept. Note that memory allocated for context should be placed in the object bag with KsAddItemToObjectBag.
FunctionalDeviceObject
Points to the WDM functional device object for the device being described.
PhysicalDeviceObject
Points to the WDM physical device object for the device being described.
NextDeviceObject
Points to the next device in the driver stack as determined by IoAttachDeviceToDeviceStack.
Started
Contains an indication of whether this particular device has been started or not. This flag if set during the processing of the PnP start IRP and is reset during the processing of the PnP stop IRP. A device that is not started will return STATUS_DEVICE_NOT_READY in response to all requests to create a filter.
SystemPowerState
The current power state of the system.
DevicePowerState
The current power state of the device.

Comments

Clients typically use this structure if they must implement specific PnP or Power Management behavior that is not provided by AVStream. A pointer to the device object structure is the first parameter to all device dispatch functions, and the client is free to use the context information to attach its own context for these functions. In addition, clients may obtain a pointer to the AVStream device object structure from a WDM device object pointer using the function KsGetDeviceForDeviceObject.

See Also

KSDEVICE_DESCRIPTOR, Object Bags, KsAddItemToObjectBag, KsGetDeviceForDeviceObject


KSFILTERFACTORY

KSFILTERFACTORY represents a filter factory.

typedef struct {
  Const KSFILTER_DESCRIPTOR*  Descriptor;
  KSOBJECT_BAG  Bag;
  PVOID  Context;
} KSFILTERFACTORY, *PKSFILTERFACTORY;

Members

Descriptor
Points to the descriptor structure which describes the characteristics of filters created by this factory.
Bag
The object bag associated with this filter factory. Object bags are structures used to associate dynamic memory with a specific AVStream object. Anything in the filter factory object bag will automatically be cleaned up when the filter factory is deleted. See the conceptual section on object bags for more information.
Context
A pointer which the client may use to associate context information with the filter factory. AVStream does not use this field in any way. Note that any dynamic memory associated with the filter factory should be placed in the object bag with KsAddItemToObjectBag.

Comments

A filter factory explicitly represents a device’s ability to instantiate a given type of filter as described by a filter descriptor.

Drivers for hardware typically use this structure to manage a particular function of the hardware that is exposed as a type of filter. Software filters generally do not need to manage the device at this level.

Filter factory objects are created in two ways. They can be created during the AddDevice processing as indicated by the device descriptor’s list of filter descriptors. They can also be created explicitly by the client in a call to KsCreateFilterFactory. The client may create filter factories at any time, but this is typically done during the processing of the PnP start IRP when an evaluation of assigned resources indicates what types of filters must be exposed by the device.

For the purposes of synchronization, the lifetime of filter factories created implicitly is defined as the interval starting when the client’s device create dispatch function is (or would be) called and ending after the client’s device PnP remove dispatch function is (or would be) called. The lifetime of filter factories created explicitly by calling KsCreateFilterFactory starts immediately after that call returns.

See Also

KSFILTER_DESCRIPTOR, KsCreateFilterFactory , Object Bags, KsAddItemToObjectBag


KSFILTER_DESCRIPTOR

KSFILTER_DESCRIPTOR describes the characteristics of a filter created by a given filter factory.

typedef struct {
  const KSFILTER_DISPATCH*  Dispatch;
  const KSAUTOMATION_TABLE*  AutomationTable;
  ULONG  Version;
  ULONG  Flags;
  const GUID*  ReferenceGuid;
  ULONG  PinDescriptorsCount;
  ULONG  PinDescriptorSize;
  const KSPIN_DESCRIPTOR_EX*  PinDescriptors;
  ULONG  CategoriesCount;
  const GUID*  Categories;
  ULONG  NodeDescriptorsCount;
  ULONG  NodeDescriptorSize;
  const KSNODE_DESCRIPTOR  NodeDescriptors;
  ULONG  ConnectionsCount;
  const KSTOPOLOGY_CONNECTION*  Connections;
  const KSCOMPONENTID*  ComponentId;
} KSFILTER_DESCRIPTOR, *PKSFILTER_DESCRIPTOR;

Members

Dispatch
Points to the dispatch table for this type of filter. This pointer is optional and need only be provided by clients which wish to receive notifications on filter creations, deletions, etc… Drivers which are interested in the processing of data (transforms, etc…) will typically provide this dispatch table and provide a processing function. Providing a filter processing function instead of individual pin processing functions is what makes a driver filter-centric instead of pin-centric.
AutomationTable
Points to the automation table for this type of filter. The automation table is what describes the properties, methods, and events supported by this filter. This automation table will be merged with the automation table supplied by AVStream for all filters. Should the client supply a property, method, or event handler already implemented by AVStream, the client’s implementation supercedes AVStream’s.
Version
The version of the filter descriptor. This should be set to KSFILTER_DESCRIPTOR_VERSION.
Flags
Flags describing the behavior of the filter. Flags can be any of the below:
KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING
Indicates that the filter wishes to process at IRQL DISPATCH_LEVEL as opposed to PASSIVE_LEVEL. This applies to the filter process callback as described in KSFILTER_DISPATCH.
KSFILTER_FLAG_CRITICAL_PROCESSING
If asynchronous processing has been specified or if passive level processing is demanded and a process call comes in at dispatch level, processing will be done in a queued work item. This flag indicates that the work item should be placed on the critical work queue as opposed to the delayed work queue.
KSFILTER_FLAG_HYPERCRITICAL_PROCESSING
If asynchronous processing has been specified or if passive level processing is demanded and a process call comes in at dispatch level, processing will be done in a queued work item. This flag indicates that the work item should be placed on the hypercritical work queue as opposed to the delayed work queue or critical work queue.
ReferenceGuid
Points to a GUID which is the binary representation of the Unicode reference string identifying this filter type. Other methods of supplying a reference string require that the filter descriptor be registered using KsCreateFilterFactory.
PinDescriptorsCount
The number of pin descriptors which will be provided for this filter type in PinDescriptors. Since all filters must expose at least one pin, zero is an illegal value for this field.
PinDescriptorSize
The size of each individual descriptor in the descriptor table. This value must be a multiple of eight and must be at least sizeof (KSPIN_DESCRIPTOR_EX). Larger values allow client-specific descriptor information to be appended to pin descriptors.
PinDescriptors
Points to a table of pin descriptors which describe the pins supported by this filter type. Since all filters must expose at least one pin, zero is an illegal value for this field.
CategoriesCount
The number of category GUIDs which will be provided in Categories for this filter type. Zero is a legal value for this field.
Categories
The list of category GUIDs for this filter type. If required, a device interface is registered for each category. This field may be null if and only if CategoriesCount is zero.
NodeDescriptorsCount
The number of topology node descriptors provided in NodeDescriptors. Zero is a legal value for this field.
NodeDescriptorSize
The size of each individual descriptor in the descriptor table. This value must be a multiple of eight and at least sizeof (KSNODE_DESCRIPTOR). Larger values allow client-specific descriptor information to be appended to node descriptors.
NodeDescriptors
Points to a table of topology node descriptors describing the topology nodes for this filter type. This field may be NULL if and only if NodeDescriptorsCount is zero.
ConnectionsCount
The number of topology connections present in Connections. This field may be zero indicating that the default connection set will be used. Using default connections means that the topology of the filter will be described with a single topology node where each pin on the filter is connected to the corresponding ID on the topology node. The direction of each connection is determined by pin data flow.
Connections
Points to a table of topology connections present in this filter type. This field is optional; it may be NULL if and only if ConnectionsCount is zero (in which case, the default topology will be used).
ComponentId
The component Id for this filter type. This is used for the component ID property which provides identification information. This field is optional.

Comments

In laying out the filter descriptor, there are a number of macros which the caller may find useful. Instead of specifying count, size, and then table for the pin descriptor table, categories table, and node descriptors table, there are a number of useful macros:

Macro | Description
DEFINE_KSFILTER_PIN_DESCRIPTORS(table) | Automatically inserts the number of items in table, the size of each item in the table, and the table of pin descriptors itself into the filter descriptor.
DEFINE_KSFILTER_CATEGORIES(table) | Automatically inserts the number of categories in the table and the table itself into the filter descriptor.
DEFINE_KSFILTER_CATEGORIES_NULL | Automatically fills in the category fields for a filter which defines no categories.
DEFINE_KSFILTER_NODE_DESCRIPTORS(table) | Automatically inserts the number of items in the table, the size of each item in the table, and the table of node descriptors itself into the filter descriptor.
DEFINE_KSFILTER_NODE_DESCRIPTORS_NULL | Automatically fills in the node descriptor fields for a filter which defines no topology nodes.
DEFINE_KSFILTER_CONNECTIONS(table) | Automatically inserts the number of connections in the table and the table itself into the filter descriptor.
DEFINE_KSFILTER_DEFAULT_CONNECTIONS | Automatically fills in the connections table for a filter which defines no explicit connections.

See Also

KSFILTER_DISPATCH, KSPIN_DESCRIPTOR_EX, KSNODE_DESCRIPTOR, KSTOPOLOGY_CONNECTION, KSCOMPONENTID, KsCreateFilterFactory


KSFILTER_DISPATCH

KSFILTER_DISPATCH describes the client callbacks which will be made to notify the client of certain events on a given filter type.

typedef struct {
  PFNKSFILTERIRP  Create;
  PFNKSFILTERIRP  Close;
  PFNKSFILTERPROCESS  Process;
  PFNKSFILTERVOID  Reset;
} KSFILTER_DISPATCH, *PKSFILTER_DISPATCH;

Members

Create
This callback is made when a filter is created. At the point at which the callback is made, the file object has an associated context, and the KS file header has been allocated. This callback is typically used by clients that want to initialize context and resources associated with the filter.

If the callback succeeds, the create operation is guaranteed to succeed. Clients can return success/failure codes or may return STATUS_PENDING. If a client returns STATUS_PENDING, AVStream will not complete the create Irp immediately. Prior to returning STATUS_PENDING, however, the client must call IoMarkIrpPending. Once the processing of the create is complete, the client must set the Irp’s status code and then call KsCompletePendingRequest.

This callback is made at IRQL PASSIVE_LEVEL with the device mutex held. It should be prototyped as follows:

    NTSTATUS Create (IN PKSFILTER Filter,
        IN PIRP Irp);
Close
This callback is made when the filter is closed. At the point at which the callback is made, any registered events on the filter have been freed, but the object is otherwise intact. It is usually provided by clients that want to free context and resources associated with the filter.

Clients can return success/failure codes or may return STATUS_PENDING. If a client returns STATUS_PENDING, AVStream will not complete the close Irp immediately. Prior to returning STATUS_PENDING, however, the client must call IoMarkIrpPending. Once the processing of the close is complete, the client must set the Irp’s status code and then call KsCompletePendingRequest.

This callback is made at IRQL PASSIVE_LEVEL with the device mutex held. It should be prototyped as follows:

    NTSTATUS Close (IN PKSFILTER Filter,
        IN PIRP Irp);
Process
This callback is made when the filter is meant to process frames. It is used to perform filter-centric processing; this type of processing is done for filters which process data as opposed to filters which transport data to hardware.

The callback is made at either IRQL PASSIVE_LEVEL or DISPATCH_LEVEL depending on the preference expressed in the filter descriptor. Filter descriptors which specify KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING will have their process callback at DISPATCH_LEVEL; filter descriptors which do not specify this flag will have their process callback at PASSIVE_LEVEL.

The callback should be prototyped as follows:

    NTSTATUS Process (IN PKSFILTER Filter,
        IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex);

For a description of the filter process dispatch and how to transform data, see the section on Filter-Centric Processing. Also see Processing Commonality.

Reset

Comments

Any of the callback pointers may be NULL, indicating that the driver does not wish to receive notification of a given event.

See Also

KsCompletePendingRequest, Filter-Centric Processing, KSPROCESSPIN, KSPROCESSPIN_INDEXENTRY, Processing Commonality


KSFILTER

KSFILTER describes an instantiated filter.

typedef struct {
  const KSFILTER_DESCRIPTOR*  Descriptor;
  KSOBJECT_BAG  Bag;
  PVOID  Context;
} KSFILTER, *PKSFILTER;

Members

Descriptor
Points to the descriptor which describes the characteristics of this particular filter.
Bag
The object bag associated with this filter instance. Object bags are structures used to associate dynamic memory with a specific AVStream object. Anything in the filter object bag will automatically be cleaned up when the filter is deleted. See the conceptual section on object bags for more information.
Context
A pointer which is used by the client to associate context information with the specific filter instance. Typically, such context information will be associated in the filter’s Create dispatch as defined in the KSFILTER_DISPATCH table for this filter instance. Any dynamically allocated context information should be placed in the object bag with KsAddItemToObjectBag.

Comments

Drivers implementing software filters typically associate filter state with this structure. Processing for software filters is usually done in the filter’s Process dispatch function. Hardware filters typically do not use this structure because the focus of the hardware driver is the platform transition: the movement of data between the host and the external hardware. This transition is typically handled with code associated with an AVStream queue object.

For the purposes of synchronization, the lifetime of this object is the interval starting when the client’s PreCreate dispatch function is called (or would be called) and ending when the client’s Close dispatch function returns, assuming the function does not return STATUS_PENDING. If it does return STATUS_PENDING, the object’s lifetime ends when the client indicates completion of the close request by calling KsCompletePendingRequest.

See Also

KSFILTER_DESCRIPTOR, KSFILTER_DISPATCH, KsCompletePendingRequest, Object Bags, KsAddItemToObjectBag


KSHANDSHAKE

KSHANDSHAKE is used to pass information back and forth while pins are handshaking in an attempt to negotiate a private interface.

typedef struct {
  GUID  ProtocolId;
  PVOID  Argument1;
  PVOID  Argument2;
} KSHANDSHAKE, *PKSHANDSHAKE;

Members

ProtocolId
A guid representing the interface or protocol which is attempting to be negotiated between two AVStream pins.
Argument1
An interface dependent argument. Most often, this is used to pass back and forth COM style interface pointers once a specific private interface or protocol has been agreed upon.
Argument2
An interface dependent argument.

Comments

See KsPinHandshake for more information about negotiating private interfaces between AVStream pins.

Pin handshaking is a concept which is usable only between two pins which support IOCTL_KS_HANDSHAKE. Currently, only AVStream pins support this interface; thus this is only useful for negotiating private interfaces between two AVStream pins. Currently, connections between AVStream pins are negotiated via this mechanism.

See Also

KsPinHandshake


KSMAPPING

The KSMAPPING structure is used to describe a single contiguous chunk of physical memory for use in scatter / gather DMA operations. In order for clients to make use of this structure within the stream pointer offsets, the pin on which this is referring must specify scatter / gather DMA mapping generation via KSPIN_FLAG_GENERATE_MAPPINGS and the client must register its DMA adapter object with AVStream via KsDeviceRegisterAdapterObject.

Typedef struct {
  PHYSICAL_ADRESS  PhysicalAddress;
  ULONG  ByteCount;
  ULONG  Alignment;
} KSMAPPING, *PKSMAPPING;

Members

PhysicalAddress
Contains the physical address of this piece of the data frame.
ByteCount
Contains the number of bytes of contiguous physical memory in this individual mapping.
Alignment
Specifies the memory alignment of the beginning of the buffer.

See Also

KSSTREAM_POINTER_OFFSET, KsDeviceRegisterAdapterObject


KSGATE

The KSGATE structure describes an AVStream gate object. Conceptually, these objects are quite similar to logic “and” and “or” gates; however, in AVStream, they are used as a processing control mechanism. See the conceptual section on Processing Control and KSGATE for more information.

typedef struct {
  LONG  Count;
  PKSGATE  NextGate;
} KSGATE, *PKSGATE;

Members

Count
Indicates the count on the gate. When this field is above zero, the gate is considered to be in the “open” state and allows processing. When the field is zero or below, the gate is considered to be in the “closed” state and does not allow processing. Although the KSGATE structure is the universal gate implementation in AVStream, conceptually, there are both “and” and “or” gates. For “and” gates, Count will be one minus the number of off inputs to the gate. For “or” gates, Count will be the number of on inputs for the gate. Thus, in general, this field can contain any value; however, for “and” gates, it can only contain values of one of less, and for “or” gates, it can only contain values of zero or greater. Clients should be careful not to specifically set the Count field to an invalid value for the given conceptual gate this structure represents.
NextGate
Points to the next gate in the gate chain. The “output” of one gate may be fed into another gate as an input and the outputting gate will pass state transitions down the gate chain. There are restrictions on this propogation using the KsGate*And and KsGate*Or functions. NextGate for an “and” gate must point to an “or” gate, and for an “or” gate must point to an “and” gate. Clients can specify state transitions manually via KsGateInitialize instead of KsGateInitializeAnd or KsGateInitializeOr.

Comments

Internally, AVStream uses this gate structure as an efficient way to provide processing control. All of the manipulations of Count are done using interlocked functions to provide synchronous state changes. Because of this, however, there is no distinction as to whether a given KSGATE represents an “and” gate or an “or” gate; thus, clients should be careful not to transition a gate into an invalid state by using KsGate*And functions on an or gate or KsGate*Or functions on an and gate or by using KsGateTurnInput* functions invalidly.

See Also

KsGateInitialize , KsGateInitializeAnd, KsGateInitializeOr


KSNODE_DESCRIPTOR

The KSNODE_DESCRIPTOR structure describes a topology node within a filter.

typedef struct {
  const KSAUTOMATION_TABLE*  AutomationTable;
  const GUID*  Type;
  const GUID*  Name;
} KSNODE_DESCRIPTOR, *PKSNODE_DESCRIPTOR;

Members

AutomationTable
Points to an automation table for this topology node. The automation table contains the properties, methods, and events supported by this topology node.
Type
Points to a guid defining the topology node.
Name
Points to a guid which represents the name of this topology node. This is used to return information on a KSPROPERTY_TOPOLOGY_NAME query. See the KS documentation on topology nodes for more information.

See Also

KSFILTER_DESCRIPTOR


KSPIN_DESCRIPTOR_EX

The KSPIN_DESCRIPTOR_EX structure describes the characteristics of a pin type on a given filter type.

Typedef struct {
  Const KSPIN_DISPATCH*  Dispatch;
  Const KSAUTOMATION_TABLE*  AutomationTable;
  KSPIN_DESCRIPTOR  PinDescriptor;
  ULONG  Flags;
  ULONG  InstancesPossible;
  ULONG  InstancesNecessary;
  Const KSALLOCATOR_FRAMING_EX*  AllocatorFraming;
  PFNKSINTERSECTIONHANDLEREX  IntersectHandler;
} KSPIN_DESCRIPTOR_EX, *PKSPIN_DESCRIPTOR_EX;

Members

Dispatch
Points to the client dispatch table for this pin. This pointer is optional and only need be provided by clients which wish to receive notifications regarding pin creation, deletion, state changes, etc… Clients which need to perform pin-centric processing (filters concerned with the routing of data: i.e. – hardware drivers) must provide this dispatch table and a process dispatch. See KSPIN_DISPATCH for more information.
AutomationTable
Points to the automation table for this pin. The automation table contains the properties, methods, and events supported by the pin. This automation table will be merged with the automation table provided by AVStream for all pins. If the client supplies any property, event, or method handlers which are already provided by AVStream, the clients’ implementation will supercede that of AVStream.
PinDescriptor
The basic pin descriptor described in the kernel streaming documentation. See KSPIN_DESCRIPTOR for more information.
Flags
Flags specifying the behavior of the pin. This can be any combination of the below:
Flag | Description
KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING | Indicates that the client wishes the process dispatch to happen at IRQL DISPATCH_LEVEL instead of PASSIVE_LEVEL
KSPIN_FLAG_CRITICAL_PROCESSING | If asynchronous processing has been specified or if passive level processing is demanded and a process call comes in at dispatch level, processing will be done in a queued work item. This flag indicates that the work item should be placed on the critical work queue as opposed to the delayed work queue.
KSPIN_FLAG_HYPERCRITICAL_PROCESSING | If asynchronous processing has been specified or if passive level processing is demanded and a process call comes in at dispatch level, processing will be done in a queued work item. This flag indicates that the work item should be placed on the hypercritical work queue as opposed to the delayed work queue or critical work queue.
KSPIN_FLAG_ASYNCHRONOUS_PROCESSING | Indicates that the pin should process data asynchronously. We will not wait for one process dispatch to be called before proceeding with additional frames.
KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING | Indicates that the processing should never be initiated; the process dispatch provided in the dispatch table will never be called. This is useful for clients which intend to directly poll the queue at, for example, DPC time to transport data to hardware.
KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL | Indicates that processing should occur every time a data frame arrives into the queue. Without specifying this flag of KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING, the process dispatch will only be called when data arrives into a previously empty queue.
KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING | Indicates that frames are not required on this pin for processing to commence. This flag is useful only for filter-centric filters. Pins which do not specify this flag will delay processing on the filter if they do not have available frames. Pins which do specify this flag will not delay processing in this manner. If a pin specifies this flag, it becomes the responsibility of the process dispatch to check for available frames.
KSPIN_FLAG_ENFORCE_FIFO | Specifying this flag causes the queue to force IRPs to be handled in a first-in-first-out manner. If one IRP is completed by the minidriver prior to an IRP that was sent earlier, the later IRP will not be completed by AVStream until the earlier IRP has been completed by the minidriver.
KSPIN_FLAG_GENERATE_MAPPINGS | Indicates that scatter/gather mappings should be generated for devices which will use scatter/gather DMA to transport data from the pin to hardware. Clients which intend to use this feature need to register their DMA adapter object with AVStream via the KsDeviceRegisterAdapterObject function.
KSPIN_FLAG_DISTINCT_TRAILING_EDGE | Indicates that the queue associated with the pin should have a trailing edge stream pointer. The trailing edge pointer is a special stream pointer which points (usually) to the oldest data in the queue (unless clone pointers exist on older data). Any data frame sitting in the window between the leading and trailing edge stream pointers are considered to have at least one reference count on them and will not be completed until they move out of the window by advancing the trailing edge with KsPinGetTrailingEdgeStreamPointer and one of the KsStreamPointerAdvance* or KsStreamPointerUnlock functions. Pins which do not specify this flag do not have a trailing edge stream pointer.
KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | Indicates that this pin will only process data while in KSSTATE_RUN. Pins which specify this flag will never be called upon to process while in KSSTATE_RUN. Further, any pin which specifies this flag and is part of a filter-centric filter will cause the filter not to process if the given pin is not in KSSTATE_RUN.
KSPIN_FLAG_SPLITTER | Indicates that this pin (an output pin) is a splitter. Pins which specify this flag should indicate a number of possible instances greater than one. When a second instance of this pin is created, AVStream will automatically set up a splitter so that frames sent to the original pin are copied to the new pin. Note that this copying is done automatically by AVStream. Clients typically can ignore process pins which have non NULL DelegateBranch and CopySource pointers. These fields indicate that the pin is part of a splitter branch and is handled automatically by AVStream. In releases post-DirectX 8.0, this flag works for pins on both filter-centric and pin-centric filters. Older releases support this flag only for pins on filter-centric filters.
KSPIN_FLAG_USE_STANDARD_TRANSPORT | This flag forces the pin to use the standard transport mechanism. It overrides all other checks (communication type, medium type, interface type, etc.) on the pin. Specifying both this flag and KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT will result in the standard transport being used. This flag overrides all other checks.
KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT | Indicates that the pin does not use the standard transport mechanism. Pins that do not use the standard transport mechanism will not belong to a pipe section and will not have associated queues.
KSPIN_FLAG_FIXED_FORMAT | Indicates that this pin uses a fixed data format. Any attempt to set the data format will return STATUS_INVALID_DEVICE_REQUEST.
KSPIN_FLAG_GENERATE_EOS_EVENTS
KSPIN_FLAG_RENDERER
KSPIN_FLAG_IMPLEMENT_CLOCK | Indicates that this pin exposes a clock which can be selected by the graph manager as a master clock.

InstancesPossible
Contains a count of the maximum number of possible instances of this pin. Any attempt to instantiate more than this number of pins of the given type will fail. Set to KSINSTANCE_INDETERMINATE to have no limit on number of pins instantiated.
InstancesNecessary
Contains a count of the number of instances of this pin type that are necessary for proper functioning of this filter. Any attempt to change the state of a filter which does not have this number of instances of this type of pin will fail.
AllocatorFraming
Specifies the allocator framing requirements for this pin type. Allocator framing specifies items such as memory alignment requirements, maximum frame size, minimum frame size, etc… This field can be NULL which will indicate that this pin does not support the allocator framing property. See KSALLOCATOR_FRAMING_EX for more information.
IntersectHandler
Points to the data intersection handler function. If this field is NULL, the pin will handle data intersection queries for data ranges with the specifier KSDATAFORMAT_SPECIFIER_NONE. The intersect handler function receives a single data range from the query and a single data range from the pins list of data ranges. The type, subtype, and specifier GUIDs of these ranges are guaranteed to match, though some may be wildcards. The function either indicates the data ranges do not match, or it produces the best data format in the intersection of the two data ranges. See Data Intersections and AVStream for more information.

Comments

The remaining undocumented flags will be documented in time.

Note that under certain circumstances the allocator framing requirements of your pin may be ignored despite the fact that your allocator framing specifies that alignment or size is absolutely required to be a certain value. If your kernel mode driver is connected to an upstream user mode filter which allocates for it and the particular upstream filter’s allocator does not understand framing requirements, this can happen (current particular examples include the MPEG-2 splitter).

Further, note that if you specify KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING and the pin does use the standard transport mechanism, you must have a processing object. This means there must be some process dispatch provided (either at the filter level or at the pin level); even if this function will never be called, it must be provided in this circumstance. ** DOC NOTE: ??? **

See Also

KSPIN_DISPATCH, KSPIN_DESCRIPTOR, KSALLOCATOR_FRAMING_EX, Data Intersections and AVStream, KsDeviceRegisterAdapterObject, Avstream Splitters


KSPIN_DISPATCH

The KSPIN_DISPATCH structure describes the callbacks which will be made to inform the client of certain events on a pin. Any of these pointers can be NULL, indicating that the client does not wish to receive notification for this particular dispatch.

typedef struct {
  PFNKSPINIRP  Create;
  PFNKSPINIRP  Close;
  PFNKSPIN  Process;
  PFNKSPINVOID  Reset;
  PFNKSPINSETDATAFORMAT  SetDataFormat;
  PFNKSPINSETDEVICESTATE  SetDeviceState;
  PFNKSPIN  Connect;
  PFNKSPINVOID  Disconnect;
  const KSCLOCK_DISPATCH*  Clock;
  const KSALLOCATOR_DISPATCH*  Allocator;
} KSPIN_DISPATCH, *PKSPIN_DISPATCH;

Members

Create
This callback is made when a pin is created. At the point at which this callback is made, the file object has an associated context, and the KS file header has been allocated. This function will typically be provided by clients that want to initialize context and resources associated with the pin. If the function succeeds, the create operation is guaranteed to succeed.

The client can return success/failure codes as well as STATUS_PENDING. If STATUS_PENDING is returned, AVStream will not complete the create Irp immediately. Prior to returning a pending code, the client must mark the Irp pending via IoMarkIrpPending. Once processing is complete, the client should set the Irp’s status code and call KsCompletePendingRequest.

The filter control mutex is held while in this function. The function will be called at IRQL PASSIVE_LEVEL and should be prototyped as follows:

  NTSTATUS Create (IN PKSPIN Pin,
        IN PIRP Irp);
Close
This callback is made when a pin is closed. At the point at which the callback is made, any registered events on the pin have been freed, but the object is otherwise intact. This will typically be provided by clients that want to free context and resources associated with the pin.

The client can return success/failure codes as well as STATUS_PENDING. If STATUS_PENDING is returned, AVStream will not complete the close Irp immediately. Prior to returning a pending code, the client must mark the Irp pending via IoMarkIrpPending. Once processing is complete, the client should set the Irp’s status code and call KsCompletePendingRequest.

The filter control mutex is held while in this function. The function is called at IRQL PASSIVE_LEVEL and should be prototyped as follows:

  NTSTATUS Close (IN PKSPIN Pin,
    IN PIRP Irp);
Process
This callback is made when there is data available for the pin to process. Supplying this dispatch function indicates that you will be performing pin-centric processing. The process dispatch can happen in one of three ways depending on the pin flags set in the pin descriptor. It can be called when new data arrives into a previously empty queue (default); it can be called when a data frame arrives regardless of whether the queue was previously empty or not (KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL); or it can never be called (KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING).

The client can return success/failure codes. Clients can also return STATUS_PENDING; please see Processing Commonality for related details. If the client does not wish to complete the frame immediately, the leading edge can be made not to advance, the trailing edge can not advance if the pin specifies a distinct trailing edge through KSPIN_FLAG_DISTINCT_TRAILING_EDGE, or the leading edge stream pointer can be cloned via KsStreamPointerClone.

The process dispatch is made at either IRQL PASSIVE_LEVEL (default) or at DISPATCH_LEVEL if the client has so specified in the pin descriptor via KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING. It should be prototyped as follows:

  NTSTATUS Process (IN PKSPIN Pin);
Reset
This callback is made when the pin’s reset state is changed due to the arrival of an IOCTL_KS_RESET_STATE device control. This will typically be provided by clients that must flush hardware buffers. Because this function receives unfiltered reset state change requests, indicated state changes may be null (from and to states are the same).

The filter control mutex is held during this function. It should be prototyped as follows:

  void Reset (IN PKSPIN Pin,
    IN KSRESET ToState,
    IN KSRESET FromState);
SetDataFormat
This callback is made to inform the pin that a specific data format is being set.

Note that this callback can be made before the pin receives a create dispatch and clients should be prepared to deal with this situation.

The client can return success/failure codes; however, STATUS_PENDING should not be returned from this function.

The function should be prototyped as follows:

  NTSTATUS SetDataFormat (IN PKSPIN Pin,
    IN PKSDATAFORMAT OldFormat,
    IN PKSMULTIPLE_ITEM OldAttributeList,
    IN const KSDATARANGE *DataRange,
    IN const KSATTRIBUTE_LIST
    *AttributeRange);

OldFormat, OldAttributeList, and AttributeRange are all optional parameters and can be NULL. Clients can use the OldFormat parameter to determine the data format that the pin was using prior to this call; if this is NULL, it indicates that no data format has been set for the pin yet.

SetDeviceState
This callback is made when the pin’s state is changed due to the arrival of a connection state property ‘set’ IOCTL. This will typically be provided by clients that need to change the state of hardware. Note that clients will not receive a stop upon initial connection of the pin.

Success/failure codes can be returned from this function; however, STATUS_PENDING should not be returned. The filter control mutex is held during this function. It should be prototyped as follows:

  NTSTATUS SetDeviceState (IN PKSPIN Pin,
    IN KSSTATE ToState,
    IN KSSTATE FromState);
Connect
Disconnect
Clock
Points to a dispatch table for clock functions. Only clients which claim to expose a clock via the pin flag KSPIN_FLAG_IMPLEMENT_CLOCK need to provide this dispatch table. See KSCLOCK_DISPATCH for more information.
Allocator
Points to a dispatch table for allocator functions. Pins which provide this dispatch table claim that they can be used as an allocator. Note that kernel mode allocators are quite special. If the data used by this pin will ever reach user mode, a kernel mode allocator cannot ordinarily be used; thus providing this dispatch table does not guarantee that your allocator will be chosen.

Comments

The undocumented dispatch functions will be documented at a future time.

See Also

KSCLOCK_DISPATCH, KSALLOCATOR_DISPATCH, KsCompletePendingRequest


KSPIN

The KSPIN structure describes an instantiated pin. In many ways, pins are the focus of filter behavior. This is reflected in the fact that the pin structure has a large number of members. Many clients need to refine pin behavior and maintain additional pin-associated context. For filters with fairly conventional pin behavior, no additional refinement or context will be required. In many cases, default pin behavior is sufficient, but the pins are accessed as part of filter- or queue-associated processing.

For the purposes of synchronization, the lifetime of this object is the interval starting when the client’s PreCreate dispatch function is called (or would be called) and ending when the client’s Close dispatch function returns, assuming the function does not return STATUS_PENDING. If it does return STATUS_PENDING, the object’s lifetime ends when the client indicates completion of the close request by calling KsCompletePendingRequest.

typedef struct {
  const KSPIN_DESCRIPTOR_EX*  Descriptor;
  KSOBJECT_BAG  Bag;
  PVOID  Context;
  ULONG  Id;
  KSPIN_COMMUNICATION  Communication;
  BOOLEAN  ConnectionIsExternal;
  KSPIN_INTERFACE  ConnectionInterface;
  KSPIN_MEDIUM  ConnectionMedium;
  KSPRIORITY  ConnectionPriority;
  PKSDATAFORMAT  ConnectionFormat;
  PKSMULTIPLE_ITEM  AttributeList;
  ULONG  StreamHeaderSize;
  KSPIN_DATAFLOW  DataFlow;
  KSSTATE  DeviceState;
  KSRESET  ResetState;
} KSPIN, *PKSPIN;

Members

Descriptor
Points to the pin descriptor for this particular pin. See KSPIN_DESCRIPTOR_EX for more information.
Bag
The object bag for this particular pin instance. Object bags are structures used to associate dynamic memory with a specific AVStream object. Anything in the pin object bag will automatically be cleaned up when the pin is closed. See the conceptual section on object bags for more information.
Context
This is a pointer clients can use to associate context information with a specific pin instance. Typically, this will be used for pin/stream extensions and will be allocated in the create dispatch provided in the pin dispatch table. Note that any dynamic memory allocated for context information should be placed in the pin instance’s object bag via KsAddItemToObjectBag.
Id
This is the pin type identifier; it is the index into the array of pin descriptors provided for the given filter type.
Communication
Indicates the type of communication used for this pin. See KSPIN_DESCRIPTOR for more information regarding this field.
ConnectionIsExternal
If this is TRUE, it indicates that the connected pin does not support the AVStream connection handshake. This is an indication of whether or not the connection between this pin and the pin it is connected to is a connection between two AVStream pins.
ConnectionInterface
The identifier for the interface being used for the connection. This information is supplied by the graph builder when the pin is created.
ConnectionMedium
The identifier for the connection medium. This information is supplied by the graph builder when the pin is created.
ConnectionPriority
The priority of the connection. This information is supplied by the graph builder when the pin is created.
ConnectionFormat
The data format of the connection. This information is initially supplied by the graph builder when the pin is created and may be changed through property access or by format change messages inserted into the stream. Access to this member is synchronized by the filter control mutex. This field should not be changed by the client.
AttributeList
The list of attributes, supplied during pin creation, that describes the connection. Specifies the direction of data flow for this pin (KSPIN_DATAFLOW_IN or KSPIN_DATAFLOW_OUT). This information is a static attribute of the pin and appears in the pin descriptor. It is cached here for access at IRQL above PASSIVE_LEVEL.
DeviceState
The current device state of the pin. This member is initially KSSTATE_STOP and is changed through property access. Access to this member is synchronized by the filter control mutex. The client should not change this member.
ResetState
The current reset state of the pin. This member is initially KSRESET_END and is changed through property access. Access to this member is synchronized by the filter control mutex. The client should not change this member.
StreamHeaderSize
Indicates the size of each KSSTREAM_HEADER for the pin. Typically used for output pins, a client can set this to any value greater than sizeof (KSSTREAM_HEADER) and have extended stream headers allocated (each stream header will be StreamHeaderSize bytes long). If a client does not set this field, this indicates that no extended information will follow stream headers. In such a situation, each stream header will be precisely sizeof (KSSTREAM_HEADER)). Clients can set this in the pin creation dispatch.
DataFlow
Specifies the direction of data flow for the pin. Possible settings include KSPIN_DATAFLOW_IN and KSPIN_DATAFLOW_OUT. This information is a static attribute of the pin and appears in the pin descriptor. It is cached here for access at IRQL above PASSIVE_LEVEL.

See Also

KSPIN_DESCRIPTOR_EX, KsAddItemToObjectBag , KsCompletePendingRequest


KSPROCESSPIN

The KSPROCESSPIN structure is used in filter-centric processing as a means to easily access data available on a specific input pin or to write out data which has been processed to an output pin. The structure itself describes the process state of a specific pin.

typedef struct {
  PKSPIN  Pin;
  PKSSTREAM_POINTER  StreamPointer;
  PKSPROCESSPIN  InPlaceCounterpart;
  PKSPROCESSPIN  DelegateBranch;
  PKSPROCESSPIN  CopySource;
  PVOID  Data;
  ULONG  BytesAvailable;
  ULONG  BytesUsed;
  ULONG  Flags;
  BOOLEAN  Terminate;
} KSPROCESSPIN, *PKSPROCESSPIN;

Members

Pin
Points to the AVStream pin object which this process structure is describing. Everything in the structure will refer to this pin.
StreamPointer
A KSSTREAM_POINTER pointing into the input stream at the current input location or into the output stream at the current output location. This can be used, for example, by output pins to stamp a stream header onto a data frame (StreamPointer -> StreamHeader). See KSSTREAM_POINTER for more information.
InPlaceCounterpart
If the pipe section that this process pin belongs to corresponds to an inplace transform, InPlaceCounterPart will point to the counterpart pin of of this process pin (ie- if this is the input to the in place transform, InPlaceCounterPart will point to the output process pin for the transform and vice versa).
DelegateBranch
If frames coming out of this process pin are being split and sent to multiple sink pins, and the split does not cause a data copy (ie- the split is sending the frames in a read only manner and all of the split pin instances are in the same pipe), DelegateBranch will point to the first instance of the process pin (the one that clients must be concerned with the splitter will automatically handle any processs pin which has a non null DelegateBranch).
CopySource
If frames coming out of this process pin are being split and sent to multiple sink pins in a manner which does cause a data copy (ie- one of the downstream filters is modifying the data frame via an inplace transform), CopySource will point to the process pin from which the frame was copied. The splitter will automatically handle any process pin which has a non null CopySource.
Data
If the pin being described by this process entry is an input pin, this will point to the next available byte of data to be input. On the other hand, if it is an output pin, it will point to an output buffer where processed data will be put.
BytesAvailable
Indicates how many bytes of data are available in Data.
BytesUsed
How many bytes of this data frame have been used by the process function. Clients should set this field to update how much they’ve read or written.
Flags
Should this particular process pin correspond to an input pin, this will contain a copy of the flags out of the stream header for the current flag.
Terminate
Contains an indication of whether the current data frame should be sent downstream after the process dispatch finishes despite the fact that not all data has been consumed.

Comments

Only clients using filter centric processing need concern themselves with process pins. Further, process pins which have a non null DelegateBranch or a non null CopySource are typically not of concern to the client. The splitter will automatically handle process pins with these pointers.

See Also

PKSPROCESSPIN_INDEXENTRY


KSPROCESSPIN_INDEXENTRY

The KSPROCESSPIN_INDEXENTRY structure is used in filter-centric processing to bring together all of the input and output pins in one context where they can all be manipulated. This structure tells how many process pins there are and gives pointers to all the process pins in pin id order.

Typedef struct {
  PKSPROCESSPIN  *Pins;
  ULONG  Count;
} KSPROCESSPIN_INDEXENTRY, *PKSPROCESSPIN_INDEXENTRY;

Members

Pins
Points to an array of KSPROCESSPINs. Pins will be ordered in pin id order. The array will contain a listing of the instances of the given pin.
Count
The number of process pins in Pins.

See Also

KSPROCESSPIN, Filter-centric processing


KSSTREAM_POINTER

The KSSTREAM_POINTER structure is the basic AVStream pointer into a stream. A queue object for a stream has at least one hard defined stream pointer: the leading edge stream pointer; this pointer normally points to the newest unprocessed data frame in the queue. Some queues also have a trailing edge stream pointer depending on whether or not the pin they are queuing for defines KSPIN_FLAG_DISTINCT_TRAILING_EDGE.

The queue can have any number of stream pointers associated with it; these can be created with the KsStreamPointerClone function. Stream pointers place references on the frames they point to. Also, any data frame in the window between the leading edge stream pointer and the trailing edge stream pointer has a reference on it by being in that window. As long as a data frame has more than one reference on it, it will leave the queue and be completed.

Stream pointers can be in one of two states: unlocked and locked. An unlocked stream pointer is not guaranteed to actually reference an existing data frame within the queue. In order to access the data which you believe the pointer points at, it must be locked. Further, data frames pointed to by an unlocked stream pointer can be cancelled; the client can receive notification of cancellation through the mechanism described in KsStreamPointerClone. Locked stream pointers are guaranteed to reference data in the queue. Data frames pointed to by locked stream pointers cannot be cancelled.

When a client is done with a particular stream pointer, they simply call KsStreamPointerDelete to delete the pointer and release a reference on the pointed to frame. The leading edge and trailing edge stream pointers cannot be deleted. They should be unlocked when not in use.

For more general conceptual information on stream pointers, see the Stream Pointers section.

typedef struct {
  PVOID  Context;
  PKSPIN  Pin;
  PKSSTREAM_HEADER  StreamHeader;
  PKSSTREAM_POINTER_OFFSET  Offset;
  KSSTREAM_POINTER_OFFSET  OffsetIn;
  KSSTREAM_POINTER_OFFSET  OffsetOut;
} KSSTREAM_POINTER, *PKSSTREAM_POINTER;

Members

Context
A pointer to client requested context information. The leading edge and trailing edge stream pointers will have this field set to NULL. Cloned stream pointers can specify that they wish to have context information via the mechanism described in KsStreamPointerClone.
Pin
Points to the AVStream pin object to which this stream pointer belongs.
StreamHeader
Points to the stream header object for the data frame that this stream pointer currently points to. See KSSTREAM_HEADER for more information.
Offset
Points either to OffsetIn or OffsetOut depending on whether the pin to which this stream pointer belongs is an input pin or output pin.
OffsetIn
A structure describing the data that the stream pointer currently points at. See KSSTREAM_POINTER_OFFSET for more information.
OffsetOut
A structure used to output data on an output pin. See KSSTREAM_POINTER_OFFSET for more information.

See Also

KSSTREAM_HEADER, KSSTREAM_POINTER_OFFSET, KsStreamPointerClone , KsStreamPointerDelete, KsStreamPointerLock, KsStreamPointerUnlock, KsStreamPointerAdvance, KsStreamPointerAdvanceOffsets, KsStreamPointerAdvanceOffsetsAndUnlock


KSSTREAM_POINTER_OFFSET

The KSSTREAM_POINTER_OFFSET structure describes the offset of the stream pointer into the data stream. It describes the amount of data available for input / output or the mappings for scatter / gather DMA.

Typedef struct {
    Union {
        PUCHAR  Data;
        PKSMAPPING  Mappings;
    };
    ULONG  Count;
    ULONG  Remaining;
} KSSTREAM_POINTER_OFFSET, *PKSSTREAM_POINTER_OFFSET;

Members

Data
If the client has not specified that this pin is to perform automatic scatter / gather DMA mapping generation via KSPIN_FLAG_GENERATE_MAPPINGS, then this will point to a buffer containing input data or a buffer to which data is to be output.
Mappings
If the client has specified that this pin is to perform automatic scatter / gather DMA mapping generation via KSPIN_FLAG_GENERATE_MAPPINGS, then this will point to a table of KSMAPPINGs describing each individual contiguous chunk of physical memory which the client can use to set up a scatter / gather DMA operation with hardware.
Count
Contains either the number of bytes of data available in the Data buffer or it contains the number of mappings in the Mappings table depending on whether this pin has specified mapping generation or not.
Remaining
Used by the client to describe how many bytes of data have been read / written or how many scatter / gather mappings have been read from / written to depending on whether this pin has specified mapping generation or not.

See Also

KSSTREAM_POINTER , KSMAPPING


AVStream Interfaces


IKsControl

The IKsControl interface is a COM style interface implemented on AVStream filters and pins. It allows clients to access AVStream automation objects (properties, methods, and events).

DECLARE_INTERFACE_(IKsControl, IUnknown) {
  DEFINE_ABSTRACT_UNKNOWN()

    STDMETHOD_(NTSTATUS, KsProperty)(THIS_
      IN PKSPROPERTY Property,
    IN ULONG PropertyLength,
      IN OUT PVOID PropertyData,
      IN ULONG DataLength,
    OUT ULONG* BytesReturned
    ) PURE;
  STDMETHOD_(NTSTATUS, KsMethod)(THIS_
      IN PKSMETHOD Method,
      IN ULONG MethodLength,
    IN OUT PVOID MethodData,
      IN ULONG DataLength,
      OUT ULONG* BytesReturned
  ) PURE;
    STDMETHOD_(NTSTATUS, KsEvent)(THIS_
      IN PKSEVENT Event,        /* optional */
      IN ULONG EventLength,
      IN OUT PVOID EventData,
      IN ULONG DataLength,
      OUT ULONG* BytesReturned
  ) PURE;
};

Functions

KsProperty
Get or set a property as specified by Property on the object to which this IKsControl interface refers.
KsMethod
Call a method as specified by Method on the object to which this IKsControl interface refers.
KsEvent
Query support for, enable, or disable an event as specified by Event on the object to which this IKsControl interface refers.

Comments

The IKsControl interface will typically be acquired through a call to KsPinGetConnected*Interface. Remember that this is a COM style interface, and that the function call to get this interface will have called QueryInterface and thus invoked AddRef to increment the interface pointer. Once done with the IKsControl interface, the client must release it with a call to Release.

Clients written in C will see the IKsControl interface as a structure containing a pointer to a table of functions instead of a C++ abstract base class. Therefore, whereas a client written in C++ might do the following:

    IKsControl *Control;

    if (NT_SUCCESS (
      KsPinGetConnectedPinInterface (
        Pin,
        IID_IKsControl,
        (PVOID *)&Control)
) {
        Control -> KsProperty (…);
        Control -> Release ();
    }

a client written in C would instead do the following:

    IKsControl *Control;

    If (NT_SUCCESS (
      KsPinGetConnectedPinInterface (
        Pin,
        IID_IKsControl,
        (PVOID *)&Control)
    ) {
      Control -> lpVtbl -> KsProperty (…);
      Control -> lpVtbl -> Release ();
    }

See Also

KsPinGetConnectedPinInterface, KsPinGetConnectedFilterInterface, AVStream, KCOM


IKsReferenceClock

The IKsReferenceClock interface is a COM style interface provided by AVStream on all pins. The pin will pass the request onto the master clock.

DECLARE_INTERFACE_(IKsReferenceClock, IUnknown) {
    DEFINE_ABSTRACT_UNKNOWN()

  STDMETHOD_(LONGLONG, GetTime)(THIS
    ) PURE;
  STDMETHOD_(LONGLONG, GetPhysicalTime)(THIS
  ) PURE;
  STDMETHOD_(LONGLONG, GetCorrelatedTime)(THIS_
      OUT PLONGLONG SystemTime
  ) PURE;
  STDMETHOD_(LONGLONG, GetCorrelatedPhysicalTime)(THIS_
      OUT PLONGLONG SystemTime
  ) PURE;
  STDMETHOD_(NTSTATUS, GetResolution)(THIS_
      OUT PKSRESOLUTION Resolution
  ) PURE;
  STDMETHOD_(NTSTATUS, GetState)(THIS_
      OUT PKSSTATE State
  ) PURE;
};

Functions

GetTime
Queries the associated reference clock for the current time.
GetPhysicalTime
Queries the associated reference clock for the current physical time.
GetCorrelatedTime
Queries the associated reference clock for the current correlated time and system time.
GetCorrelatedPhysicalTime
Queries the associated reference clock for the current correlated physical time and system time.
GetResolution
Queries the associated reference clock for its resolution.
GetState
Queries the associated reference clock for its current state.

Comments

The IKsReferenceClock interface will typically be acquired through a call to KsPinGetReferenceClockInterface. Remember that this is a COM style interface, and that the function call to get this interface will have called QueryInterface and thus invoked AddRef to increment the interface pointer. Once done with the IKsReferenceClock interface, the client must release it with a call to Release.

Clients written in C will see the IKsReferenceClock interface as a structure containing a pointer to a table of functions instead of a C++ abstract base class. Therefore, whereas a client written in C++ might do the following:

    PIKSREFERENECLOCK RefClock;

    if (NT_SUCCESS (
      KsPinGetReferenceClockInterface (
        Pin,
        &RefClock)
) {
        … RefClock -> GetCorrelatedTime (…);
        RefClock -> Release ();
    }

a client written in C would instead do the following:

    PIKSREFERENCECLOCK RefClock;

    If (NT_SUCCESS (
      KsPinGetReferenceClockInterface (
        Pin,
        &RefClock)
    ) {
      … RefClock -> lpVtbl -> GetCorrelatedTime (…);
      RefClock -> lpVtbl -> Release ();
    }

See Also

KsPinGetConnectedPinInterface, KsPinGetConnectedFilterInterface, AVStream, KCOM


Broadcast Driver Architecture Reference

A minidriver for Broadcast Driver Architecture (BDA) uses the functions, property and method sets, constants, enumerations, and structures in this reference to configure itself and control its operation.

The BDA Reference includes:

Broadcast Driver Architecture Support Functions

Broadcast Driver Architecture Property, Event, and Method Sets

Broadcast Driver Architecture Enumerations and Structures

Broadcast Driver Architecture Constants


Broadcast Driver Architecture Support Functions

This section documents the support functions that a BDA minidriver uses. The system-supplied BDA support library (Bdasup.lib) provides these functions. In order for your BDA minidriver to use these functions, you must include the Bdasup.h header file in your code and link to Bdasup.lib when you build your driver.

The following sections provide more information about the BDA support functions:

BdaCheckChanges

BdaCommitChanges

BdaCreateFilterFactory

BdaCreatePin

BdaCreateTopology

BdaDeletePin

BdaGetChangeState

BdaInitFilter

BdaMethodCreatePin

BdaMethodCreateTopology

BdaMethodDeletePin

BdaPropertyGetControllingPinId

BdaPropertyGetPinControl

BdaPropertyNodeTypes

BdaPropertyPinTypes

BdaPropertyTemplateConnections

BdaStartChanges

BdaSyncTopology

BdaValidateNodeProperty


BdaCheckChanges

The BdaCheckChanges function verifies a new set of BDA topology changes before they are committed.

STDMETHODIMP_(NTSTATUS)
  BdaCheckChanges(
    IN PIRP  Irp
    );

Parameters

Irp
Points to the IRP for the request to verify changes.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Returns the result that the BdaCommitChanges function would have returned.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaCheckChanges function to verify a group of BDA topology changes after the minidriver receives a KSMETHOD_BDA_CHECK_CHANGES request of the KSMETHODSETID_BdaChangeSync method set from the network provider. BDA minidrivers define dispatch and filter-automation tables so that those minidrivers either dispatch the BdaCheckChanges function directly or intercept this request using an internal method, which then calls the BdaCheckChanges function. For example, BDA minidrivers that intercept this request can obtain a pointer to the BDA filter from the passed IRP so that they can validate the new list of resources for the filter. See Defining Automation Tables and Changing BDA Filter Properties for more information.

See Also

BdaCommitChanges, KSMETHODSETID_BdaChangeSync


BdaCommitChanges

The BdaCommitChanges function commits the changes to BDA topology that have occurred since the last call to the BdaStartChanges function.

STDMETHODIMP_(NTSTATUS)
  BdaCommitChanges(
    IN PIRP  Irp
    );

Parameters

Irp
Points to the IRP for the request to commit changes.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaCommitChanges function to commit a set of BDA topology changes after the minidriver receives a KSMETHOD_BDA_COMMIT_CHANGES request of the KSMETHODSETID_BdaChangeSync method set from the network provider. BDA minidrivers define dispatch and filter-automation tables so that those minidrivers either dispatch the BdaCommitChanges function directly or intercept this request using an internal method, which then calls the BdaCommitChanges function. For example, BDA minidrivers that intercept this request can obtain a pointer to the BDA filter from the passed IRP so that they can:

  1. Set the new list of resources for the filter to the pending list of resources.
  2. Set the change state of the filter to BDA_CHANGES_COMPLETE.
  3. Commit the resources on the underlying device.

See Defining Automation Tables and Changing BDA Filter Properties for more information.

See Also

BDA_CHANGE_STATE, BdaCheckChanges, BdaStartChanges, KSMETHODSETID_BdaChangeSync


BdaCreateFilterFactory

BdaCreateFilterFactory adds the specified filter descriptor as a filter factory to the specified device and associates the filter factory with the specified BDA template topology.

STDMETHODIMP_(NTSTATUS)
  BdaCreateFilterFactory(
    IN PKSDEVICE  pKSDevice,
    IN const KSFILTER_DESCRIPTOR  *pFilterDescriptor,
    IN const BDA_FILTER_TEMPLATE  *pBdaFilterTemplate
    );

Parameters

pKSDevice
Points to the BDA device to which to add the filter factory with associated BDA template topology.
pFilterDescriptor
Points to a KSFILTER_DESCRIPTOR structure that describes a filter for the BDA device. Note that not all of the template pin and node types may be exposed as pin and node factories when the filter is first initialized.
pBdaFilterTemplate
Points to a BDA_FILTER_TEMPLATE structure that describes a BDA template topology.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaCreateFilterFactory function to add a filter factory with an associated BDA template topology to a device and to register all of the topology's static template structures with the BDA support library (BdaSup.sys). The BDA support library can then handle the following method and property calls:

KSMETHODSETID_BdaChangeSync

KSMETHODSETID_BdaDeviceConfiguration

KSPROPSETID_BdaTopology

See Also

BDA_FILTER_TEMPLATE, KSDEVICE, KSFILTER_DESCRIPTOR, KSMETHODSETID_BdaChangeSync, KSMETHODSETID_BdaDeviceConfiguration, KSPROPSETID_BdaTopology


BdaCreatePin

BdaCreatePin creates a new pin in the specified filter.

STDMETHODIMP_(NTSTATUS)
  BdaCreatePin(
    IN PKSFILTER  pKSFilter,
    IN ULONG  ulPinType,
    OUT ULONG  *pulPinId
    );

Parameters

pKSFilter
Points to the filter in which to create a pin.
ulPinType
Type of pin to create.
pulPinId
Points to a variable that receives the identifier for the created pin.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

The network provider uses the BdaMethodCreatePin function when it dynamically creates a pin using the KSMETHOD_BDA_CREATE_PIN_FACTORY request of the KSMETHODSETID_BdaDeviceConfiguration method set. If a BDA minidriver must create a pin without relying on the network provider, the BDA minidriver should call the BdaCreatePin function directly.

See Also

BdaDeletePin, BdaMethodCreatePin, KSFILTER, KSMETHODSETID_BdaDeviceConfiguration


BdaCreateTopology

BdaCreateTopology creates the topology between two pins.

STDMETHODIMP_(NTSTATUS)
  BdaCreateTopology(
    IN PKSFILTER  pKSFilter,
    IN ULONG  InputPinId,
    IN ULONG  OutputPinId
    );

Parameters

pKSFilter
Points to the BDA filter on which to create topology.
InputPinId
Identifier of the filter's input pin.
OutputPinId
Identifier of the filter's output pin.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Returns NULL if no valid pin pairing exists with the specified input and output pins.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

The network provider uses the BdaMethodCreateTopology function when it dynamically creates a topology between filter pins using the KSMETHOD_BDA_CREATE_TOPOLOGY request of the KSMETHODSETID_BdaDeviceConfiguration method set. If a BDA minidriver must create a topology between filter pins without relying on the network provider, the BDA minidriver should call the BdaCreateTopology function directly.

See Also

BdaMethodCreateTopology, KSFILTER, KSMETHODSETID_BdaDeviceConfiguration


BdaDeletePin

The BdaDeletePin function deletes a pin from the specified filter.

STDMETHODIMP_(NTSTATUS)
  BdaDeletePin(
    IN PKSFILTER  pKSFilter,
    IN ULONG  *pulPinId
    );

Parameters

pKSFilter
Points to the filter in which to delete a pin.
pulPinId
Points to a variable that contains the identifier for the pin to delete.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

The network provider uses the BdaMethodDeletePin function when it dynamically deletes a pin using the KSMETHOD_BDA_DELETE_PIN_FACTORY request of the KSMETHODSETID_BdaDeviceConfiguration method set. If a BDA minidriver must delete a pin without relying on the network provider, the BDA minidriver should call the BdaDeletePin function directly.

See Also

BdaCreatePin, BdaMethodDeletePin, KSFILTER, KSMETHODSETID_BdaDeviceConfiguration


BdaGetChangeState

The BdaGetChangeState function returns the current change state of BDA topology.

STDMETHODIMP_(NTSTATUS)
  BdaGetChangeState(
    IN PIRP  Irp,
    OUT BDA_CHANGE_STATE  *pChangeState
    );

Parameters

Irp
Points to the IRP for the request to get the current change state.
pChangeState
Points to a variable that receives the current change state of BDA topology. The BDA change state can be one of the following values from the BDA_CHANGE_STATE enumeration:
Value | Description
BDA_CHANGES_COMPLETE | BDA topology changes are complete.
BDA_CHANGES_PENDING | BDA topology changes are pending.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaGetChangeState function to retrieve the current change state of BDA topology after the minidriver receives a KSMETHOD_BDA_GET_CHANGE_STATE request of the KSMETHODSETID_BdaChangeSync method set from the network provider. BDA minidrivers define dispatch and filter-automation tables so that those minidrivers either dispatch the BdaGetChangeState function directly or intercept this request using an internal method, which then calls the BdaGetChangeState function. For example, BDA minidrivers that intercept this request can obtain a pointer to the BDA filter from the passed IRP so that they can:

  1. Not only check for pending topology changes but also for pending changes on the filter.
  2. Return the current change state for both BDA topology and the BDA filter.

See Defining Automation Tables and Changing BDA Filter Properties for more information.

See Also

BDA_CHANGE_STATE, KSMETHODSETID_BdaChangeSync


BdaInitFilter

BdaInitFilter initializes a filter from a device's filter factory and the specified BDA template topology.

STDMETHODIMP_(NTSTATUS)
  BdaInitFilter(
    IN PKSFILTER  pKSFilter,
    IN const BDA_FILTER_TEMPLATE  *pBdaFilterTemplate
    );

Parameters

pKSFilter
Points to the BDA filter to initialize.
pBdaFilterTemplate
Points to a BDA_FILTER_TEMPLATE structure that describes the filter template for the BDA device. To determine topology for and configure the initialized filter, the network provider uses information referenced in this BDA_FILTER_TEMPLATE structure.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaInitFilter function to initialize an instance of a filter from the specified BDA template topology and a filter factory that was previously created through a call to the BdaCreateFilterFactory function. The BDA minidriver can subsequently use this filter instance in calls to other BDA support functions, such as, BdaCreatePin.

See Also

BdaCreateFilterFactory, BdaCreatePin, BDA_FILTER_TEMPLATE, KSFILTER


BdaMethodCreatePin

The BdaMethodCreatePin function creates a pin factory.

STDMETHODIMP_(NTSTATUS)
  BdaMethodCreatePin(
    IN PIRP  Irp,
    IN KSMETHOD  *pKSMethod,
    OUT ULONG  *pulPinFactoryID
    );

Parameters

Irp
Points to the IRP for the request to create a pin factory.
pKSMethod
Points to a KSMETHOD structure that describes the method and request type of a method request.
pulPinFactoryID
Points to a variable that receives the identifier of the pin factory.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaMethodCreatePin function to create a pin factory after the minidriver receives a KSMETHOD_BDA_CREATE_PIN_FACTORY request of the KSMETHODSETID_BdaDeviceConfiguration method set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaMethodCreatePin function directly. See Defining Automation Tables and Configuring a BDA Filter for more information.

If a BDA minidriver must create a pin without relying on the network provider, the BDA minidriver should call the BdaCreatePin function.

See Also

BdaCreatePin, BdaMethodDeletePin, KSMETHOD, KSMETHODSETID_BdaDeviceConfiguration


BdaMethodCreateTopology

The BdaMethodCreateTopology function creates a template topology between two pins of a filter.

STDMETHODIMP_(NTSTATUS)
  BdaMethodCreateTopology(
    IN PIRP  Irp,
    IN KSMETHOD  *pKSMethod,
    OPTIONAL PVOID  pvIgnored
    );

Parameters

Irp
Points to the IRP for the request to create topology.
pKSMethod
Points to a KSMETHOD structure that describes the method and request type of a method request.
pvIgnored
Points to a buffer that is ignored.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaMethodCreateTopology function to create the template topology between two filter pins after the minidriver receives a KSMETHOD_BDA_CREATE_TOPOLOGY request of the KSMETHODSETID_BdaDeviceConfiguration method set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaMethodCreateTopology function directly. Some BDA minidrivers must intercept this request rather than dispatch it directly. These mindrivers must obtain a pointer to the BDA filter from the passed IRP before calling BdaMethodCreateTopology so that they can use the filter to keep track of associated pins. These mindrivers can then send instructions to the hardware when connecting particular pin types. See Defining Automation Tables and Configuring a BDA Filter for more information.

If a BDA minidriver must create the template topology between two filter pins without relying on the network provider, the BDA minidriver should call the BdaCreateTopology function.

See Also

BdaCreateTopology, BdaSyncTopology, KSMETHOD, KSMETHODSETID_BdaDeviceConfiguration


BdaMethodDeletePin

The BdaMethodDeletePin function deletes a pin factory.

STDMETHODIMP_(NTSTATUS)
  BdaMethodDeletePin(
    IN PIRP  Irp,
    IN KSMETHOD  *pKSMethod,
    OPTIONAL PVOID  pvIgnored
    );

Parameters

Irp
Points to the IRP for the request to delete a pin factory.
pKSMethod
Points to a KSMETHOD structure that describes the method and request type of a method request.
pvIgnored
Points to a buffer that is ignored.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaMethodDeletePin function to delete a pin factory after the minidriver receives a KSMETHOD_BDA_DELETE_PIN_FACTORY request of the KSMETHODSETID_BdaDeviceConfiguration method set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaMethodDeletePin function directly. See Defining Automation Tables and Configuring a BDA Filter for more information.

If a BDA minidriver must delete a pin without relying on the network provider, the BDA minidriver should call the BdaDeletePin function.

See Also

BdaDeletePin, BdaMethodCreatePin, KSMETHOD, KSMETHODSETID_BdaDeviceConfiguration


BdaPropertyGetControllingPinId

The BdaPropertyGetControllingPinId function retrieves the identifier of a pin on which to control the properties, methods, and events of a specific node.

STDMETHODIMP_(NTSTATUS)
  BdaPropertyGetControllingPinId(
    IN PIRP  Irp,
    IN KSP_BDA_NODE_PIN  *pProperty,
    OUT ULONG  *pulControllingPinId
    );

Parameters

Irp
Points to the IRP for the request to retrieve the controlling pin for a node.
pProperty
Points to a KSP_BDA_NODE_PIN structure that describes the property and request type of the property request to retrieve the controlling pin for a node.
pulControllingPinId
Points to a variable that receives the identifier of the controlling pin for a node.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaPropertyGetControllingPinId function to retrieve the identifier of the controlling pin for a node after the minidriver receives a KSPROPERTY_BDA_CONTROLLING_PIN_ID request of the KSPROPSETID_BdaTopology property set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaPropertyGetControllingPinId function directly. See Defining Automation Tables and Determining BDA Device Topology for more information.

See Also

KSP_BDA_NODE_PIN, KSPROPSETID_BdaTopology


BdaPropertyGetPinControl

The BdaPropertyGetPinControl function retrieves either the identifier or type of a pin.

STDMETHODIMP_(NTSTATUS)
  BdaPropertyGetPinControl(
    IN PIRP  Irp,
    IN KSPROPERTY  *pKSProperty,
    OUT ULONG  *pulProperty
    );

Parameters

Irp
Points to the IRP for the request to retrieve pin information.
pKSProperty
Points to a KSPROPERTY structure that describes the property and request type of the property request.
pulProperty
Points to a variable that receives either the identifier or type of a pin.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaPropertyGetPinControl function to retrieve either the identifier or type of a pin after the minidriver receives either a KSPROPERTY_BDA_PIN_ID or KSPROPERTY_BDA_PIN_TYPE request of the KSPROPSETID_BdaPinControl property set. Most BDA minidrivers can define pin-automation tables so that those minidrivers dispatch the BdaPropertyGetPinControl function directly.

See Also

KSPROPERTY, KSPROPSETID_BdaPinControl


BdaPropertyNodeTypes

The BdaPropertyNodeTypes function retrieves a list of node types in a template topology.

STDMETHODIMP_(NTSTATUS)
  BdaPropertyNodeTypes(
    IN PIRP  Irp,
    IN KSPROPERTY  *pKSProperty,
    OUT ULONG  *pulProperty
    );

Parameters

Irp
Points to the IRP for the request to retrieve list of node types.
pKSProperty
Points to a KSPROPERTY structure that describes the property and request type of the property request.
pulProperty
Points to an array that receives the list of node types.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaPropertyNodeTypes function to retrieve the list of node types after the minidriver receives a KSPROPERTY_BDA_NODE_TYPES request of the KSPROPSETID_BdaTopology property set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaPropertyNodeTypes function directly. See Defining Automation Tables and Determining BDA Device Topology for more information.

See Also

KSPROPERTY, KSPROPSETID_BdaTopology


BdaPropertyPinTypes

The BdaPropertyPinTypes function retrieves a list of pin types in a template topology.

STDMETHODIMP_(NTSTATUS)
  BdaPropertyPinTypes(
    IN PIRP  Irp,
    IN KSPROPERTY  *pKSProperty,
    OUT ULONG  *pulProperty
    );

Parameters

Irp
Points to the IRP for the request to retrieve list of pin types.
pKSProperty
Points to a KSPROPERTY structure that describes the property and request type of the property request.
pulProperty
Points to an array that receives the list of pin types.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaPropertyPinTypes function to retrieve the list of pin types after the minidriver receives a KSPROPERTY_BDA_PIN_TYPES request of the KSPROPSETID_BdaTopology property set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaPropertyPinTypes function directly. See Defining Automation Tables and Determining BDA Device Topology for more information.

See Also

KSPROPERTY, KSPROPSETID_BdaTopology


BdaPropertyTemplateConnections

The BdaPropertyTemplateConnections function retrieves a list of connections that describe how pin types and node types are connected in a template topology.

STDMETHODIMP_(NTSTATUS)
  BdaPropertyTemplateConnections(
    IN PIRP  Irp,
    IN KSPROPERTY  *pKSProperty,
    OUT KSTOPOLOGY_CONNECTION  *pConnectionProperty
    );

Parameters

Irp
Points to the IRP for the request to retrieve list of connections.
pKSProperty
Points to a KSPROPERTY structure that describes the property and request type of the property request.
pConnectionProperty
Points to an array that receives the list of KSTOPOLOGY_CONNECTION structures that describe the connections in a template topology.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaPropertyTemplateConnections function to retrieve the list of pin types after the minidriver receives a KSPROPERTY_BDA_TEMPLATE_CONNECTIONS request of the KSPROPSETID_BdaTopology property set from the network provider. Most BDA minidrivers can define dispatch and filter-automation tables so that those minidrivers dispatch the BdaPropertyTemplateConnections function directly. See Defining Automation Tables and Determining BDA Device Topology for more information.

The BDA minidriver retrieves a list of connections in an array of KSTOPOLOGY_CONNECTION structures. The BDA minidriver in turn returns to the network provider a list of possible connections in an array of BDA_TEMPLATE_CONNECTION structures. This array is a representation of all the possible connections between node and pin types that can be made within the filter or between the filter and adjoining filters.

See Also

KSPROPERTY, KSPROPSETID_BdaTopology, KSTOPOLOGY_CONNECTION


BdaStartChanges

The BdaStartChanges function initiates the setting of new BDA topology changes.

STDMETHODIMP_(NTSTATUS)
  BdaStartChanges(
    IN PIRP  Irp
    );

Parameters

Irp
Points to the IRP for the request to initiate changes.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A BDA minidriver calls the BdaStartChanges function to initiate the setting of new BDA topology changes after the minidriver receives a KSMETHOD_BDA_START_CHANGES request of the KSMETHODSETID_BdaChangeSync method set from the network provider. BDA minidrivers define dispatch and filter-automation tables so that those minidrivers either dispatch the BdaStartChanges function directly or intercept this request using an internal method, which then calls the BdaStartChanges function. For example, BDA minidrivers that intercept this request can obtain a pointer to the BDA filter from the passed IRP so that they can subsequently reset pending filter resources to the new requirements and set the change state of the filter to BDA_CHANGES_COMPLETE. See Defining Automation Tables and Changing BDA Filter Properties for more information.

See Also

BDA_CHANGE_STATE, BdaCommitChanges, KSMETHODSETID_BdaChangeSync


BdaSyncTopology

BdaSyncTopology updates the existing topology to complete all pending topology changes.

STDMETHODIMP_(NTSTATUS)
  BdaSyncTopology(
    IN PKSFILTER  pKSFilter
    );

Parameters

pKSFilter
Points to the BDA filter on which to update existing topology.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

If a BDA minidriver must create a topology between filter pins without relying on the network provider, the BDA minidriver calls the BdaCreateTopology function. After the minidriver calls BdaCreateTopology, it should call the BdaSyncTopology function to synchronize the pending topology changes with the BDA filter.

See Also

BdaCreateTopology, KSFILTER


BdaValidateNodeProperty

The BdaValidateNodeProperty function validates that the pin that is associated with the current request controls a node.

STDMETHODIMP_(NTSTATUS)
  BdaValidateNodeProperty(
    IN PIRP  Irp,
    IN KSPROPERTY  *pKSProperty
    );

Parameters

Irp
Points to the IRP for the request to validate that the current pin controls the node property at pKSProperty.
pKSProperty
Points to a KSPROPERTY structure that describes the property and request type of the property request.

Return Value

Returns STATUS_SUCCESS or an appropriate error code.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

A pin method in a BDA minidriver calls the BdaValidateNodeProperty function to validate that the pin controls a particular node after the minidriver receives a KSPROPERTY_BDA_RF_TUNER_FREQUENCY request of the KSPROPSETID_BdaFrequencyFilter property set or a KSPROPERTY_BDA_AUTODEMODULATE_START request of the KSPROPSETID_BdaAutodemodulate property set from the network provider. These property sets manipulate tuner and demodulator nodes. After calling BdaValidateNodeProperty, the minidriver must obtain a pointer to the BDA filter from the passed IRP so that the minidriver can perform an operation on the particular node.

See Also

KSPROPERTY, KSPROPSETID_BdaAutodemodulate, KSPROPSETID_BdaFrequencyFilter


Broadcast Driver Architecture Property, Event, and Method Sets

This section documents the property, event, and method sets that a BDA minidriver implements. These sets are a subset of the sets that are defined in bdamedia.h. The BDA minidriver can dispatch some of the properties and methods in these sets to default implementations in the BDA support library. See Broadcast Driver Architecture Minidrivers for information on how the minidriver can use the BDA support library of functions to provide default handling of these sets.

The following sections provide more information about the BDA property, event, and method sets:

KSPROPSETID_BdaAutodemodulate
The BDA autodemodulate property set controls signal demodulator nodes that can automatically determine the characteristics of the modulated signal and demodulate.
KSPROPSETID_BdaCA
The BDA conditional access property set queries Entitlement Control Message (ECM) map nodes for either status or user interface (UI) to display.
KSEVENTSETID_BdaCAEvent
The BDA conditional access event set notifies conditional access (CA) plugins either of changes in status or about the existence of UI to retrieve and display.
KSMETHODSETID_BdaChangeSync
The BDA change sync method set commits multiple changes on a filter or its pins and nodes all at once.
KSMETHODSETID_BdaDeviceConfiguration
The BDA device configuration method set configures the actual topologies of connected filters.
KSPROPSETID_BdaDigitalDemodulator
The BDA digital demodulator property set controls signal demodulator nodes that cannot automatically determine the characteristics of the modulated signal.
KSPROPSETID_BdaFrequencyFilter
The BDA frequency filter property set controls the RF tuner node in a receiver topology.
KSPROPSETID_BdaNullTransform
The BDA null transform property set controls when a node starts and stops operating.
KSPROPSETID_BdaPIDFilter
The BDA packet identifier (PID) filter property set controls PID filter nodes. A PID filter node filters out particular media content from the received broadcast stream.
KSPROPSETID_BdaPinControl
The BDA pin control property set retrieves the properties of a pin from that pin.
KSPROPSETID_BdaPinEvent
The BDA pin event set notifies other filters or plugins of events related to a pin.
KSPROPSETID_BdaTopology
The BDA topology property set retrieves the node capabilities and connections within a filter.
KSPROPSETID_BdaVoidTransform
The BDA void transform property set controls when a node starts and stops operating.


KSPROPSETID_BdaAutodemodulate

KSPROPSETID_BdaAutodemodulate is the BDA autodemodulate property set. It is used to control signal demodulator nodes that can automatically determine the characteristics of the modulated signal and demodulate. It is also used for demodulator nodes, such as the 8VSB demodulator node which only support one configuration of modulation parameters. For these types of nodes, the demodulator is not informed to set specific values such as Inner and Outer forward error correction (FEC) method. The following properties are available:

KSPROPERTY_BDA_AUTODEMODULATE_START
Informs the demodulator node that, when it is in pause or run state, it should attempt to automatically determine the modulation parameters and demodulate the signal.
KSPROPERTY_BDA_AUTODEMODULATE_STOP
Informs the demodulator node that it should stop trying to automatically demodulate the signal.


KSPROPSETID_BdaCA

KSPROPSETID_BdaCA is the BDA conditional access (CA) property set. It is used to query Entitlement Control Message (ECM) map nodes for status of those nodes and for status of associated CA modules and smart card readers. This property set can also query for user interface (UI) that CA plugins can display. Each property in this property set corresponds to an event in the KSEVENTSETID_BdaCAEvent event set. BDA minidrivers signal events in this event set to notify CA plugins. Those CA plugins then query corresponding properties in KSPROPSETID_BdaCA. BDA minidrivers signal these events either whenever a significant status change occurs or to interact with a user. BDA minidrivers interact with a user, for example, to present a message to the user or to negotiate a transaction with a user. A significant status change is, for example, when a user removes a smart card from the smart card reader.

The following properties are available:

KSPROPERTY_BDA_ECM_MAP_STATUS
Returns status on an ECM map node.
KSPROPERTY_BDA_CA_MODULE_STATUS
Returns status on the CA module associated with an ECM map node.
KSPROPERTY_BDA_CA_SMART_CARD_STATUS
Returns status on the smart card reader associated with an ECM map node.
KSPROPERTY_BDA_CA_MODULE_UI
Returns UI that a CA plugin can display. This UI is returned in a BDA_CA_MODULE_UI structure.


KSEVENTSETID_BdaCAEvent

KSEVENTSETID_BdaCAEvent is the BDA conditional access (CA) event set. It is used to notify CA plugins of changes in status of Entitlement Control Message (ECM) map nodes and CA modules and smart card readers associated with those nodes. This event set can also notify CA plugins about the existence of user interface (UI) that those plugins should retrieve and display. Each event in this event set corresponds to a property in the KSPROPSETID_BdaCA property set. BDA minidrivers signal events in this event set to notify CA plugins. Those CA plugins then query corresponding properties in KSPROPSETID_BdaCA. BDA minidrivers signal these events either whenever a significant status change occurs or to interact with a user. BDA minidrivers interact with a user, for example, to present a message to the user or to negotiate a transaction with a user. A significant status change is, for example, when a user removes a smart card from the smart card reader.

The following events are available:

KSEVENT_BDA_ECM_MAP_STATUS_CHANGED
Notifies of a status change on an ECM map node.
KSEVENT_BDA_CA_MODULE_STATUS_CHANGED
Notifies of a status change on the CA module associated with an ECM map node.
KSEVENT_BDA_CA_SMART_CARD_STATUS_CHANGED
Notifies of a status change on the smart card reader associated with an ECM map node.
KSEVENT_BDA_CA_MODULE_UI_REQUESTED
Notifies of the existence of UI that a CA plugin can retrieve and display.


KSMETHODSETID_BdaChangeSync

KSMETHODSETID_BdaChangeSync is the BDA change sync method set. It is implemented on filters. It is used to coordinate a list of property requests on a filter and its pins and nodes. The network provider filter can use this method set to begin a list of changes, make the changes, then commit them all at once. The following methods are available:

KSMETHOD_BDA_START_CHANGES
Before the network provider begins to make changes, it calls this method, which causes any existing change list that has not been committed to be discarded and informs the filter's pins and nodes to start keeping track of a new set of changes. The network provider then calls the necessary interface methods on the filter or its pins, but the methods are not actually called yet. If at any point the network provider determines that the changes will not work, it can call this method to clear out the list.
KSMETHOD_BDA_CHECK_CHANGES
Before committing the changes, the network provider calls this method to determine whether the requested changes will work. The minidriver may reserve resources when this method is called, to guarantee that the resources are available.
KSMETHOD_BDA_COMMIT_CHANGES
When the network provider calls this method, the changes from the method calls are committed on the underlying filters, at which point the filter resets its state and a new cycle can begin.
KSMETHOD_BDA_GET_CHANGE_STATE
Returns a value from the BDA_CHANGE_STATE enumeration that identifies the current change state for the filter.


KSMETHODSETID_BdaDeviceConfiguration

KSMETHODSETID_BdaDeviceConfiguration is the BDA device configuration method set. It is implemented on filters. It is used to configure the filter for the current filter graph. Many BDA minidrivers can setup this method set so that it is supported automatically by the BDA support library. The following methods are available:

KSMETHOD_BDA_CREATE_PIN_FACTORY
Triggers a call that creates a pin factory for the filter. Returns the identifier of the pin factory in a KSM_PIN structure.
KSMETHOD_BDA_DELETE_PIN_FACTORY
Triggers a call that deletes a pin factory for the filter. Specifies the pin factory to delete using a KSM_PIN structure.
KSMETHOD_BDA_CREATE_TOPOLOGY
Creates a topology structure in Ring 3 that reflects the known connections in the filter. Returns topology information in a KSMULTIPLE_ITEM structure.


KSPROPSETID_BdaDigitalDemodulator

KSPROPSETID_BdaDigitalDemodulator is the BDA digital demodulator property set. It is used to control signal demodulator nodes that require specific values to be set. This property set describes the properties of a DVB demodulator node. Use this property set instead of KSPROPSETID_BdaAutodemodulate if the demodulator requires specific values to be set. The following properties are available:

KSPROPERTY_BDA_MODULATION_TYPE
Sets or retrieves the demodulator type such as QPSK or 8VSB. The ModulationType enumeration identifies demodulator types.
KSPROPERTY_BDA_INNER_FEC_TYPE
Sets or retrieves the inner forward error correction (FEC) type. The FECMethod enumeration contains values that specify FEC types.
KSPROPERTY_BDA_INNER_FEC_RATE
Sets or retrieves the binary convolution scheme used for the inner FEC. The BinaryConvolutionCodeRate enumeration contains values that specify binary convolution schemes.
KSPROPERTY_BDA_OUTER_FEC_TYPE
Sets or retrieves the outer FEC type. The FECMethod enumeration contains values that specify FEC types.
KSPROPERTY_BDA_OUTER_FEC_RATE
Sets or retrieves the binary convolution coding scheme used for the outer FEC. The BinaryConvolutionCodeRate enumeration contains values that specify binary convolution schemes.
KSPROPERTY_BDA_SYMBOL_RATE
Sets or retrieves the symbol rate.
KSPROPERTY_BDA_SPECTRAL_INVERSION
Sets or retrieves the setting for spectral inversion. The SpectralInversion enumeration contains values that specify settings for spectral inversion.


KSPROPSETID_BdaFrequencyFilter

KSPROPSETID_BdaFrequencyFilter is the BDA frequency filter property set. It is used to control the RF tuner node in a receiver topology. This property set is generic across almost all tuners. It is used to inform the tuner node how to tune the RF signal. The following properties are available:

KSPROPERTY_BDA_RF_TUNER_FREQUENCY
This property informs the tuner node about the actual frequency, in Hertz, of the signal carrier.
KSPROPERTY_BDA_RF_TUNER_POLARITY
For some transmissions, particularly satellite transmissions, the signal may be polarized. This property informs the tuner node what polarization is used on the transmitted signal. The Polarization enumeration contains values that specify the polarity of the signal.
KSPROPERTY_BDA_RF_TUNER_RANGE
Some tuners control an external device, such as an LNB, that defines the domain on which to find a particular carrier frequency. This property sets the tuner range either to –1, meaning that tuner range is not used for the particular tuning space, or to a value that is specific to the tuning space.
KSPROPERTY_BDA_RF_TUNER_TRANSPONDER
Some tuning spaces have all of the information about how to acquire a frequency imbedded in hardware. These tuning spaces specify a transponder number. This property informs the tuner node of this transponder number. The tuner hardware can then automatically determine the tuning characteristics needed to acquire the intermediate frequency. In this case, the other properties in this property set are set to –1.


KSPROPSETID_BdaNullTransform

KSPROPSETID_BdaNullTransform is the BDA null transform property set. It is used for controlling when nodes start and stop. The network provider filter uses this property set to control the operation of nodes.

The following properties are available:

KSPROPERTY_BDA_NULL_TRANSFORM_START
Starts operation of a node.
KSPROPERTY_BDA_NULL_TRANSFORM_STOP
Stops operation of a node.


KSPROPSETID_BdaPIDFilter

KSPROPSETID_BdaPIDFilter is the BDA packet identifier (PID) filter property set. It is used to filter out particular media content from the received broadcast stream. This property set controls the properties of a PID filter node.

Each received broadcast stream is made up of a number of separate streams, called elementary streams (ES). Each ES contains a particular media content. A received broadcast stream may contain an ES for the video of a television program, another for the audio of the program in English, another for the audio of the program in Spanish, and another for data accompanying the program. Each ES consists of groups of packets that are identified with identical PIDs. The Program Map Table (PMT) specifies which ESs make up a particular program. An application or other filters must decide which ESs to decrypt. The PMT contains a descriptor for each ES that specifies information such as whether the ES contains Entitlement Control Messages (ECM) specifying conditional access (CA) information about that ES. A CA plugin uses its IBDA_ECMMap COM interface to send PIDs of required ESs and ES descriptors from the PMT corresponding to the required ESs to the CA filter.

The following properties are available:

KSPROPERTY_BDA_PIDFILTER_MAP_PIDS
Informs the PID filter node about a type of data to filter out of the input stream and then pass to a downstream filter. This property is also used to retrieve the type of data that the node outputs. The BDA_PID_MAP structure describes a map of this output data.
KSPROPERTY_BDA_PIDFILTER_UNMAP_PIDS
Informs the PID filter node about packets identified with specific PIDs to stop filtering from the input stream. The BDA_PID_UNMAP structure describes the packets to stop filtering from the input to the output.
KSPROPERTY_BDA_PIDFILTER_LIST_PIDS
Returns an array of PIDs that identify groups of packets that the PID filter node filters out of the input stream.


KSPROPSETID_BdaPinControl

KSPROPSETID_BdaPinControl is the BDA pin control property set. It is used to retrieve some BDA-specific information about a particular pin. After the network provider creates a pin for a filter using a KSMETHOD_BDA_CREATE_PIN_FACTORY request of the KSMETHODSETID_BdaDeviceConfiguration method set, the network provider uses the properties of KSPROPSETID_BdaPinControl to update its internal representation of the actual receiver topology.

Each pin factory of a BDA filter should support this property set.

The properties in this property set define a pin. Typically, pins of a filter are not required to intercept any of these properties. The BDA support library provides the BdaPropertyGetPinControl default function to handle this property set. A driver writer should create static structures that enable handling of this property set. Once these structures are created and registered with the BDA support library, the driver writer is not required to do anything further to support this property set.

The following properties are available:

KSPROPERTY_BDA_PIN_ID
Returns the BDA identifier (ID) for a pin. When the network provider creates a pin for a filter using KSMETHOD_BDA_CREATE_PIN_FACTORY, the BDA minidriver for the filter gives that pin an ID. KSPROPERTY_BDA_PIN_ID returns this ID.
KSPROPERTY_BDA_PIN_TYPE
Returns the value that specifies the type of a pin. When the network provider creates a pin for a filter using KSMETHOD_BDA_CREATE_PIN_FACTORY, it specifies a pin type from the list of pin types included in the filter's BDA template topology. KSPROPERTY_BDA_PIN_TYPE returns this pin type. In the filter's BDA template topology each pin type can only occur once, but it can occur multiple times in an actual topology. The value for the pin type corresponds to the index of the element in the zero-based array of pin types. This array of pin types is an array of KSPIN_DESCRIPTOR_EX structures.


KSPROPSETID_BdaPinEvent

KSPROPSETID_BdaPinEvent is the BDA pin event set. It is used for notifying other filters or plugins of events related to a specific pin. The network provider filter uses this event set to register for notification of events related to pins as those events occur. A BDA minidriver signals the events in this event set to notify filters or plugins that previously requested notification. A driver writer should create static structures that enable handling of this event set. Once these structures are created and registered with the BDA support library, the driver writer is not required to do anything further to support this event set.

The following events are available:

KSEVENT_BDA_PIN_CONNECTED
Notifies when a pin becomes connected.
KSEVENT_BDA_PIN_DISCONNECTED
Notifies when a pin becomes disconnected.


KSPROPSETID_BdaTopology

KSPROPSETID_BdaTopology is the BDA topology property set. It is used for querying filters about their capabilities. The BDA support library provides default methods to handle this property set. The network provider filter uses this property set to determine the template topology of the filter, and the methods, properties and events supported on each node and pin. The network provider filter uses this node and pin information to determine what kinds of operations the filter can perform on the signal and whether to add the filter to the graph. The actual topology of a filter refers to the pin and node connections that are actually made on the filter by the network provider.

The properties in this property set define what filter can do. Typically, filters are not required to intercept any of these properties. See Broadcast Driver Architecture Minidrivers for information on how the BDA minidriver for a filter can use the BDA support library of functions to provide default handling of these properties. A driver writer should create static structures that enable handling of this property set. Once these structures are created and registered with the BDA support library, the driver writer is not required to do anything further to support this property set.

The following properties are available:

KSPROPERTY_BDA_NODE_TYPES
Returns a list of the node types. In a template topology each node type can only occur once, but it can occur multiple times in an actual topology. This list of node types is an array of KSNODE_DESCRIPTOR structures.
KSPROPERTY_BDA_PIN_TYPES
Returns a list of the pin types. In a template topology each pin type can only occur once, but it can occur multiple times in an actual topology. This list of pin types is an array of KSPIN_DESCRIPTOR_EX structures.
KSPROPERTY_BDA_TEMPLATE_CONNECTIONS
List of connections between pins and nodes in a template topology. This list of connections is an array of BDA_TEMPLATE_CONNECTION structures.
KSPROPERTY_BDA_NODE_METHODS
List of methods supported on a node. The network provider will use this property to query the capabilities of each node in the BDA template connection list.
KSPROPERTY_BDA_NODE_PROPERTIES
List of properties supported on a node. The network provider will use this property to query the capabilities of each node in the BDA template connection list.
KSPROPERTY_BDA_NODE_EVENTS
List of events supported on a node. The network provider will use this property to query the capabilities of each node in the BDA template connection list.
KSPROPERTY_BDA_CONTROLLING_PIN_ID
Nodes are associated with one pin in the filter, either an input pin or an output pin. Nodes can only be accessed through the controlling pin because nodes do not have their own file handle. The network provider can use this property and the KSP_BDA_NODE_PIN structure to query for the controlling pin for each node in the BDA template connection list (KSTOPOLOGY_CONNECTION or BDA_TEMPLATE_CONNECTION array).
KSPROPERTY_BDA_NODE_DESCRIPTORS
Returns a list of node descriptors. This list is an array of KSNODE_DESCRIPTOR structures.


KSPROPSETID_BdaVoidTransform

KSPROPSETID_BdaVoidTransform is the BDA void transform property set. It is used for controlling when nodes start and stop. The network provider filter uses this property set to control the operation of nodes.

The following properties are available:

KSPROPERTY_BDA_VOID_TRANSFORM_START
Starts operation of a node.
KSPROPERTY_BDA_VOID_TRANSFORM_STOP
Stops operation of a node.


Broadcast Driver Architecture Enumerations and Structures

A BDA minidriver uses the following enumerations and structures.

ATSCComponentTypeFlags

BDA_CA_MODULE_UI

BDA_CHANGE_STATE

BinaryConvolutionCodeRate

BDA_FILTER_TEMPLATE

BDANODE_DESCRIPTOR

BDA_PID_MAP

BDA_PID_UNMAP

BDA_PIN_PAIRING

BDA_TEMPLATE_CONNECTION

BDA_TEMPLATE_PIN_JOINT

BDA_TRANSPORT_INFO

ComponentCategory

ComponentStatus

DVBSystemType

FECMethod

GuardInterval

HierarchyAlpha

KSP_BDA_FRAME_INFO

KSP_BDA_NODE_PIN

KS_DATARANGE_BDA_ANTENNA

KS_DATARANGE_BDA_TRANSPORT

KSM_PIN

KSM_PIN_PAIR

MEDIA_SAMPLE_CONTENT

ModulationType

MPEG2StreamType

PID_MAP

Polarization

SpectralInversion

TransmissionMode


ATSCComponentTypeFlags

The ATSCComponentTypeFlags enumeration contains a value that specifies a bitmask of the various properties of an ATSC stream.

typedef enum ATSCComponentTypeFlags {
    ATSCCT_AC3 = 0x00000001,
} ATSCComponentTypeFlags;

Element

ATSCCT_AC3
Bitmask that specifies an ATSC AC3 audio stream type.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


BDA_CA_MODULE_UI

The BDA_CA_MODULE_UI structure describes the user interface (UI) that conditional access (CA) plugins can display.

typedef struct _BDA_CA_MODULE_UI {
    ULONG  ulFormat;
    ULONG  ulbcDesc;
    ULONG  ulDesc[MIN_DIMENSION];
} BDA_CA_MODULE_UI, *PBDA_CA_MODULE_UI;

Members

ulFormat
Value that specifies the format of the UI.
ulbcDesc
Number of descriptors in the ulDesc array.
ulDesc
Array of descriptors for the UI.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

KSPROPSETID_BdaCA


BDA_CHANGE_STATE

The BDA_CHANGE_STATE enumeration contains values that specify the state of topology changes in a filter.

typedef enum {
    BDA_CHANGES_COMPLETE = 0,
    BDA_CHANGES_PENDING
} BDA_CHANGE_STATE, * PBDA_CHANGE_STATE;

Elements

BDA_CHANGES_COMPLETE
BDA topology changes are complete.
BDA_CHANGES_PENDING
BDA topology changes are pending.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BdaGetChangeState


BinaryConvolutionCodeRate

The BinaryConvolutionCodeRate enumeration contains values that specify the binary convolution scheme used for either the inner or outer forward error correction (FEC) of a signal demodulator node.

typedef V1_ENUM enum BinaryConvolutionCodeRate {
    BDA_BCC_RATE_NOT_SET = -1,
    BDA_BCC_RATE_NOT_DEFINED = 0,
    BDA_BCC_RATE_1_2 = 1,   // 1/2
    BDA_BCC_RATE_2_3,   // 2/3
    BDA_BCC_RATE_3_4,   // 3/4
    BDA_BCC_RATE_3_5,
    BDA_BCC_RATE_4_5,
    BDA_BCC_RATE_5_6,   // 5/6
    BDA_BCC_RATE_5_11,
    BDA_BCC_RATE_7_8,   // 7/8
    BDA_BCC_RATE_MAX,
} BinaryConvolutionCodeRate;

Elements

BDA_BCC_RATE_NOT_SET
Rate not set.
BDA_BCC_RATE_NOT_DEFINED
Rate not defined.
BDA_BCC_RATE_1_2
Rate set to 1/2.
BDA_BCC_RATE_2_3
Rate set to 2/3.
BDA_BCC_RATE_3_4
Rate set to 3/4.
BDA_BCC_RATE_3_5
Rate set to 3/5.
BDA_BCC_RATE_4_5
Rate set to 4/5.
BDA_BCC_RATE_5_6
Rate set to 5/6.
BDA_BCC_RATE_5_11
Rate set to 5/11.
BDA_BCC_RATE_7_8
Rate set to 7/8.
BDA_BCC_RATE_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

KSPROPSETID_BdaDigitalDemodulator


BDA_FILTER_TEMPLATE

The BDA_FILTER_TEMPLATE structure describes the template topology for a BDA filter.

typedef struct _BDA_FILTER_TEMPLATE {
    const KSFILTER_DESCRIPTOR *  pFilterDescriptor;
    ULONG                        ulcPinPairs;
    const BDA_PIN_PAIRING *      pPinPairs;
} BDA_FILTER_TEMPLATE,  *PBDA_FILTER_TEMPLATE;

Members

pFilterDescriptor
Points to a KSFILTER_DESCRIPTOR structure that describes a template for a filter for the BDA device.
ulcPinPairs
Number of pairs of pins in the pPinPairs array.
pPinPairs
Array of BDA_PIN_PAIRING structures that describe the topology between a pair of the filter's input and output pins.

Headers

Defined in Bdasup.h. Include Bdasup.h.

See Also

BdaCreateFilterFactory, BdaInitFilter, BDA_PIN_PAIRING, KSFILTER_DESCRIPTOR


BDANODE_DESCRIPTOR

The BDANODE_DESCRIPTOR structure describes a BDA node.

typedef struct _BDANODE_DESCRIPTOR {
    ULONG  ulBdaNodeType;
    GUID   guidFunction;
    GUID   guidName;
} BDANODE_DESCRIPTOR, *PBDANODE_DESCRIPTOR;

Members

ulBdaNodeType
The node type as the BDA template topology identifies it. The BDA node-type identifier typically corresponds to the index of the element in the zero-based array of node types. This array of node types is an array of KSNODE_DESCRIPTOR structures.
guidFunction
GUID that describes the node's function. See BDA Node Category GUIDs for a list of these GUIDs.
guidName
GUID that can be used to store a string containing the name of the node. Applications can search the registry for this GUID to obtain the node's name and then can display the name.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA Node Category GUIDs, KSNODE_DESCRIPTOR


BDA_PID_MAP

The BDA_PID_MAP structure describes a type of data to filter out of the input stream of a packet identifier (PID) filter and then pass to a downstream filter. This output consists of packets that are identified with PIDs and contain particular media content.

typedef struct _BDA_PID_MAP {
    MEDIA_SAMPLE_CONTENT  MediaSampleContent;
    ULONG                 ulcPIDs;
    ULONG                 aulPIDs[MIN_DIMENSION];
} BDA_PID_MAP, *PBDA_PID_MAP;

Members

MediaSampleContent
MEDIA_SAMPLE_CONTENT enumeration value that specifies the type of media content that packets contain.
ulcPIDs
Number of PIDs in the aulPIDs array.
aulPIDs
Array of PIDs that identify packets to map to the output of a PID filter.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA_PID_UNMAP, KSPROPSETID_BdaPIDFilter, MEDIA_SAMPLE_CONTENT, PID_MAP,


BDA_PID_UNMAP

The BDA_PID_UNMAP structure describes packet types to stop filtering from the input stream of a packet identifier (PID) filter. These packet types are identified with PIDs.

typedef struct _BDA_PID_UNMAP {
    ULONG  ulcPIDs;
    ULONG  aulPIDs[MIN_DIMENSION];
} BDA_PID_UNMAP, *PBDA_PID_UNMAP;

Members

ulcPIDs
Number of PIDs in the aulPIDs array.
aulPIDs
Array of PIDs that identify packets to unmap from the output of a PID filter.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA_PID_MAP, KSPROPSETID_BdaPIDFilter, MEDIA_SAMPLE_CONTENT, PID_MAP


BDA_PIN_PAIRING

The BDA_PIN_PAIRING structure describes the topology between a pair of input and output pins.

typedef struct _BDA_PIN_PAIRING {
    ULONG          ulInputPin;
    ULONG          ulOutputPin;
    ULONG          ulcMaxInputsPerOutput;
    ULONG          ulcMinInputsPerOutput;
    ULONG          ulcMaxOutputsPerInput;
    ULONG          ulcMinOutputsPerInput;
    ULONG          ulcTopologyJoints;
    const ULONG *  pTopologyJoints;
} BDA_PIN_PAIRING, * PBDA_PIN_PAIRING;

Members

ulInputPin
Index of the element in the zero-based array of pin types (KSPIN_DESCRIPTOR_EX array) that indicates the input pin of the pair.
ulOutputPin
Index of the element in the zero-based array of pin types (KSPIN_DESCRIPTOR_EX array) that indicates the output pin of the pair.
ulcMaxInputsPerOutput
Maximum number of input pins per output pin. The network provider creates duplicates of nodes that are controlled by the input pin depending on the value specified in ulcMaxInputsPerOutput.
ulcMinInputsPerOutput
Minimum number of input pins per output pin. The network provider creates duplicates of nodes that are controlled by the input pin depending on the value specified in ulcMinInputsPerOutput.
ulcMaxOutputsPerInput
Maximum number of output pins per input pin. The network provider creates duplicates of nodes that are controlled by the output pin depending on the value specified in ulcMaxOutputsPerInput.
ulcMinOutputsPerInput
Minimum number of output pins per input pin. The network provider creates duplicates of nodes that are controlled by the output pin depending on the value specified in ulcMinOutputsPerInput.
ulcTopologyJoints
Number of joints in the pTopologyJoints array.
pTopologyJoints
Array of joint values. The value given to a joint corresponds to the index of an element in a array of template connections (KSTOPOLOGY_CONNECTION or BDA_TEMPLATE_CONNECTION array).

Headers

Defined in Bdasup.h. Include Bdasup.h.

See Also

BDA_FILTER_TEMPLATE, BDA_TEMPLATE_CONNECTION, KSPIN_DESCRIPTOR_EX, KSTOPOLOGY_CONNECTION


BDA_TEMPLATE_CONNECTION

The BDA_TEMPLATE_CONNECTION structure describes the template for a BDA connection in terms of where it begins and ends.

typedef struct _BDA_TEMPLATE_CONNECTION {
    ULONG   FromNodeType;
    ULONG   FromNodePinType;
    ULONG   ToNodeType;
    ULONG   ToNodePinType;
}BDA_TEMPLATE_CONNECTION, *PBDA_TEMPLATE_CONNECTION;

Members

FromNodeType
Index of the element in the zero-based array of internal node types (KSNODE_DESCRIPTOR array) that indicates the node type where the connection begins or –1 to indicate that the connection begins at an upstream filter.
FromNodePinType
Index of the element in the zero-based array of pin types (KSPIN_DESCRIPTOR_EX array) that indicates the pin type where the connection begins. The array of pin types is the list of pin types that are available in the filter's template topology.
ToNodeType
Index of the element in the zero-based array of internal node types (KSNODE_DESCRIPTOR array) that indicates the node type where the connection ends or –1 to indicate that the connection ends at a downstream filter.
ToNodePinType
Index of the element in the zero-based array of pin types (KSPIN_DESCRIPTOR_EX array) that indicates the pin type where the connection ends. The array of pin types is the list of pin types that are available in the filter's template topology.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA_PIN_PAIRING, BdaPropertyTemplateConnections, KSNODE_DESCRIPTOR, KSPIN_DESCRIPTOR_EX, KSPROPSETID_BdaTopology, KSTOPOLOGY_CONNECTION


BDA_TEMPLATE_PIN_JOINT

The BDA_TEMPLATE_PIN_JOINT structure describes a joint in a template topology.

typedef struct _BDA_TEMPLATE_PIN_JOINT {
    ULONG   uliTemplateConnection;
    ULONG   ulcInstancesMax;
}BDA_TEMPLATE_PIN_JOINT, *PBDA_TEMPLATE_PIN_JOINT;

Members

uliTemplateConnection
Index of an element in a array of template connections (KSTOPOLOGY_CONNECTION or BDA_TEMPLATE_CONNECTION array) that represents the joint.
ulcInstancesMax
Maximum number of possible instances of the joint in the template topology.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA_TEMPLATE_CONNECTION, KSTOPOLOGY_CONNECTION


BDA_TRANSPORT_INFO

The BDA_TRANSPORT_INFO structure describes formatting for a stream connection.

typedef struct tagBDA_TRANSPORT_INFO {
    ULONG           ulcbPhyiscalPacket;
    ULONG           ulcbPhyiscalFrame;
    ULONG           ulcbPhyiscalFrameAlignment;
    REFERENCE_TIME  AvgTimePerFrame;
} BDA_TRANSPORT_INFO, *PBDA_TRANSPORT_INFO;

Members

ulcbPhyiscalPacket
Size, in bytes, of a physical packet (for example, the size of a satellite link payload).
ulcbPhyiscalFrame
Size, in bytes, of each physical frame (0 indicates no hardware requirement).
ulcbPhyiscalFrameAlignment
Capture buffer alignment in bytes (0 and 1 indicate no alignment requirements).
AvgTimePerFrame
REFERENCE TIME value that indicates the video frame's average display time, in 100-nanosecond units.

Headers

Defined in Bdamedia.h. Include Bdamedia.h.

Comments

A BDA_TRANSPORT_INFO structure in conjunction with a KSDATARANGE structure makes up a KS_DATARANGE_BDA_TRANSPORT data range. A data range describes a range of data formats.

Pins of filters specify the data ranges they support to enable stream connections to pins of other filters that also support those data ranges.

See Also

KSDATARANGE, KS_DATARANGE_BDA_TRANSPORT, KSPIN_DESCRIPTOR


ComponentCategory

The ComponentCategory enumeration contains values that specify a substream of the received broadcast stream.

typedef V1_ENUM enum ComponentCategory {
    CategoryNotSet = -1,
    CategoryOther = 0,
    CategoryVideo,
    CategoryAudio,
    CategoryText,
    CategoryData,
} ComponentCategory;

Elements

CategoryNotSet
Specifies that the category of the substream is not set.
CategoryOther
Specifies a category other than video, audio, text, or data.
CategoryVideo
Specifies that the category of the substream is video.
CategoryAudio
Specifies that the category of the substream is audio.
CategoryText
Specifies that the category of the substream is text.
CategoryData
Specifies that the category of the substream is data.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


ComponentStatus

The ComponentStatus enumeration contains values that specify the status of a substream of the received broadcast stream.

typedef enum ComponentStatus {
    StatusActive,
    StatusInactive,
    StatusUnavailable,
} ComponentStatus;

Elements

StatusActive
Specifies the substream is active.
StatusInactive
Specifies the substream is inactive.
StatusUnavailable
Specifies the substream is not available.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


DVBSystemType

The DVBSystemType enumeration contains values that specify the broadcast system for a particular digital video broadcast (DVB) tuning space instance.

typedef enum DVBSystemType {
    DVB_Cable,
    DVB_Terrestrial,
    DVB_Satellite,
} DVBSystemType;

Elements

DVB_Cable
Cable broadcast system.
DVB_Terrestrial
Terrestrial broadcast system.
DVB_Satellite
Satellite broadcast system.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


FECMethod

The FECMethod enumeration contains values that specify the forward error correction (FEC) type used by a signal demodulator node.

typedef V1_ENUM enum FECMethod {
    BDA_FEC_METHOD_NOT_SET = -1,
    BDA_FEC_METHOD_NOT_DEFINED = 0,
    BDA_FEC_VITERBI = 1,
    BDA_FEC_RS_204_188,
    BDA_FEC_MAX,
} FECMethod;

Elements

BDA_FEC_METHOD_NOT_SET
FEC method not set.
BDA_FEC_METHOD_NOT_DEFINED
FEC method not defined.
BDA_FEC_VITERBI
FEC is Viterbi binary convolution.
BDA_FEC_RS_204_188
FEC is Reed-Solomon 204/188 (outer FEC).
BDA_FEC_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

KSPROPSETID_BdaDigitalDemodulator


GuardInterval

The GuardInterval enumeration contains values that specify the type of guard interval used by a signal demodulator node.

typedef V1_ENUM enum GuardInterval {
    BDA_GUARD_NOT_SET = -1,
    BDA_GUARD_NOT_DEFINED = 0,
    BDA_GUARD_1_32 = 1, // Guard interval is 1/32
    BDA_GUARD_1_16, // Guard interval is 1/16
    BDA_GUARD_1_8, // Guard interval is 1/8
    BDA_GUARD_1_4, // Guard interval is 1/4
    BDA_GUARD_MAX,
} GuardInterval;

Elements

BDA_GUARD_NOT_SET
Guard interval not set.
BDA_GUARD_NOT_DEFINED
Guard interval not defined.
BDA_GUARD_1_32
Guard interval set to 1/32.
BDA_GUARD_1_16
Guard interval set to 1/16.
BDA_GUARD_1_8
Guard interval set to 1/8.
BDA_GUARD_1_4
Guard interval set to 1/4.
BDA_FEC_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


HierarchyAlpha

The HierarchyAlpha enumeration contains values that specify the hierarchy alpha used by a signal demodulator node.

typedef V1_ENUM enum HierarchyAlpha {
    BDA_HALPHA_NOT_SET = -1,
    BDA_HALPHA_NOT_DEFINED = 0,
    BDA_HALPHA_1 = 1,
    BDA_HALPHA_2,
    BDA_HALPHA_4,
    BDA_HALPHA_MAX,
} HierarchyAlpha;

Elements

BDA_HALPHA_NOT_SET
Hierarchy alpha not set.
BDA_HALPHA_NOT_DEFINED
Hierarchy alpha not defined.
BDA_HALPHA_1
Hierarchy alpha set to 1.
BDA_HALPHA_2
Hierarchy alpha set to 2.
BDA_HALPHA_4
Hierarchy alpha set to 4.
BDA_HALPHA_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


KSP_BDA_FRAME_INFO

The KSP_BDA_FRAME_INFO structure describes BDA extensions to the KSSTREAM_HEADER structure, which describes a packet of data to be read from or written to a streaming driver pin.

typedef struct tagKS_BDA_FRAME_INFO {
    ULONG  ExtendedHeaderSize;
    DWORD  dwFrameFlags;
    ULONG  ulEvent;
    ULONG  ulChannelNumber;
    ULONG  ulSubchannelNumber;
    ULONG  ulReason;
} KS_BDA_FRAME_INFO, *PKS_BDA_FRAME_INFO;

Members

ExtendedHeaderSize
Size, in bytes, of the BDA extensions described in this extended header structure.
dwFrameFlags
Flags specific to BDA extensions.
ulEvent
Identifier of an event.
ulChannelNumber
Channel number of a television program.
ulSubchannelNumber
Subchannel number of a television program.
ulReason
Identifies the reason the packet was transferred.

Headers

Defined in Bdamedia.h. Include Bdamedia.h.

See Also

KSSTREAM_HEADER


KSP_BDA_NODE_PIN

The KSP_BDA_NODE_PIN structure describes a property request to retrieve the controlling pin for a node.

typedef struct _KSP_BDA_NODE_PIN {
    KSPROPERTY      Property;
    ULONG           ulNodeType;
    ULONG           ulInputPinId;
    ULONG           ulOutputPinId;
} KSP_BDA_NODE_PIN, *PKSP_BDA_NODE_PIN;

Members

Property
KSPROPERTY structure that describes the property and request type of the property request.
ulNodeType
Index of the element in the zero-based array of internal node types (KSNODE_DESCRIPTOR array) that specifies the node type for which to retrieve the controlling pin.
ulInputPinId
Identifier of an input pin of the filter.
ulOutputPinId
Identifier of an output pin of the filter.

Headers

Defined in Bdamedia.h. Include Bdamedia.h.

See Also

BdaPropertyGetControllingPinId, KSNODE_DESCRIPTOR, KSPROPERTY, KSPROPSETID_BdaTopology


KS_DATARANGE_BDA_ANTENNA

The KS_DATARANGE_BDA_ANTENNA structure describes a range of data formats for a BDA antenna stream.

typedef struct tagKS_DATARANGE_BDA_ANTENNA {
    KSDATARANGE  DataRange;
} KS_DATARANGE_BDA_ANTENNA, *PKS_DATARANGE_BDA_ANTENNA;

Members

DataRange
KSDATARANGE structure that describes a range of data formats with the MajorFormat member specified as STATIC_KSDATAFORMAT_TYPE_BDA_ANTENNA.

Comments

A data range describes a range of data formats.

Pins of filters specify the data ranges they support to enable stream connections to pins of other filters that also support those data ranges.

Headers

Defined in Bdamedia.h. Include Bdamedia.h.

See Also

BDA Stream Format GUIDs, KSDATARANGE, KSPIN_DESCRIPTOR


KS_DATARANGE_BDA_TRANSPORT

The KS_DATARANGE_BDA_TRANSPORT structure describes a range of data formats for a BDA transport stream.

typedef struct tagKS_DATARANGE_BDA_TRANSPORT {
    KSDATARANGE         DataRange;
    BDA_TRANSPORT_INFO  BdaTransportInfo;
} KS_DATARANGE_BDA_TRANSPORT, *PKS_DATARANGE_BDA_TRANSPORT;

Members

DataRange
KSDATARANGE structure that describes a range of data formats.
BdaTransportInfo
BDA_TRANSPORT_INFO structure that describes formatting for a BDA transport stream connection.

Headers

Defined in Bdamedia.h. Include Bdamedia.h.

Comments

A BDA_TRANSPORT_INFO structure in conjunction with a KSDATARANGE structure makes up a KS_DATARANGE_BDA_TRANSPORT data range. A data range describes a range of data formats.

Pins of filters specify the data ranges they support to enable stream connections to pins of other filters that also support those data ranges.

See Also

BDA Stream Format GUIDs, BDA_TRANSPORT_INFO, KSDATARANGE, KSPIN_DESCRIPTOR


KSM_PIN

The KSM_PIN structure describes a method request to create or delete a pin factory for a filter.

typedef struct _KSM_PIN {
    KSMETHOD    Method;
    union {
        ULONG       PinId;
        ULONG       PinType;
    };
    ULONG       Reserved;
} KSM_PIN, * PKSM_PIN;

Members

Method
KSMETHOD structure that describes a method and request type of a method request.
PinId
Member of the union in KSM_PIN that contains the identifier (ID) of a pin factory of a filter.
PinType
Member of the union in KSM_PIN that contains the value that specifies the pin type.
Reserved
Reserved.

Headers

Defined in Bdasup.h. Include Bdasup.h.

Comments

When the network provider creates or deletes a pin for a filter using either KSMETHOD_BDA_CREATE_PIN_FACTORY or KSMETHOD_BDA_DELETE_PIN_FACTORY of the KSMETHODSETID_BdaDeviceConfiguration method set, the BDA minidriver for the filter gives that pin an ID. The ID for the pin is returned in KSM_PIN.

See Also

KSMETHODSETID_BdaDeviceConfiguration


KSM_PIN_PAIR

The KSM_PIN_PAIR structure describes a method request to retrieve the pin pairing structure (BDA_PIN_PAIRING) between a pair of input and output pins.

typedef struct _KSM_PIN_PAIR {
    KSMETHOD    Method;
    ULONG       InputPinId;
    ULONG       OutputPinId;
    ULONG       Reserved;
} KSM_PIN_PAIR, * PKSM_PIN_PAIR;

Members

Method
KSMETHOD structure that describes a method and request type of a method request.
InputPinId
Identifier of an input pin of the filter.
OutputPinId
Identifier of an output pin of the filter.
Reserved
Reserved.

Headers

Defined in Bdasup.h. Include Bdasup.h.

See Also

BDA_PIN_PAIRING, KSMETHOD


MEDIA_SAMPLE_CONTENT

The MEDIA_SAMPLE_CONTENT enumeration contains values that specify the type of data in a group of packets that a packet identifier (PID) filter outputs.

typedef enum {
    MEDIA_TRANSPORT_PACKET,
    MEDIA_ELEMENTARY_STREAM,
    MEDIA_MPEG2_PSI,
    MEDIA_TRANSPORT_PAYLOAD
} MEDIA_SAMPLE_CONTENT ;

Elements

MEDIA_TRANSPORT_PACKET
Packets in the output stream are complete transport stream (TS) packets. That is, the PID filter does not demultiplex packets from the input stream but just passes them through to the output.
MEDIA_ELEMENTARY_STREAM
Packets in the output stream consist of packet elementary stream (PES) payloads. That is, the PID filter demultiplexes packets from the input stream that contain either audio or video data.
MEDIA_MPEG2_PSI
Packets in the output stream consist of private data. That is, the PID filter demultiplexes packets from the input stream that contain IP data or data from a Program Allocation Table (PAT), Program Map Table (PMT), or Conditional Access Table (CAT).
MEDIA_TRANSPORT_PAYLOAD
Packets in the output stream consist of gathered TS packet payloads. That is, the PID filter demultiplexes packets from the input stream that contain, for example, PES or electronic program guide (EPG) packets.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA_PID_MAP, KSPROPSETID_BdaPIDFilter, PID_MAP


ModulationType

The ModulationType enumeration contains values that specify the type of a signal demodulator node.

typedef V1_ENUM enum ModulationType {
    BDA_MOD_NOT_SET = -1,
    BDA_MOD_NOT_DEFINED = 0,
    BDA_MOD_16QAM = 1,
    BDA_MOD_32QAM,
    BDA_MOD_64QAM,
    BDA_MOD_80QAM,
    BDA_MOD_96QAM,
    BDA_MOD_112QAM,
    BDA_MOD_128QAM,
    BDA_MOD_160QAM,
    BDA_MOD_192QAM,
    BDA_MOD_224QAM,
    BDA_MOD_256QAM,
    BDA_MOD_320QAM,
    BDA_MOD_384QAM,
    BDA_MOD_448QAM,
    BDA_MOD_512QAM,
    BDA_MOD_640QAM,
    BDA_MOD_768QAM,
    BDA_MOD_896QAM,
    BDA_MOD_1024QAM,
    BDA_MOD_QPSK,
    BDA_MOD_BPSK,
    BDA_MOD_OQPSK,
    BDA_MOD_8VSB,
    BDA_MOD_16VSB,
    BDA_MOD_ANALOG_AMPLITUDE,  // std am
    BDA_MOD_ANALOG_FREQUENCY,  // std fm
    BDA_MOD_MAX,
} ModulationType;

Elements

BDA_MOD_NOT_SET
Specifies the demodulator type is not set.
BDA_MOD_NOT_DEFINED
Specifies the demodulator type is not defined.
BDA_MOD_16QAM
Specifies 16QAM demodulator type.
BDA_MOD_32QAM
Specifies 32QAM demodulator type.
BDA_MOD_64QAM
Specifies 64QAM demodulator type.
BDA_MOD_80QAM
Specifies 80QAM demodulator type.
BDA_MOD_96QAM
Specifies 96QAM demodulator type.
BDA_MOD_112QAM
Specifies 112QAM demodulator type.
BDA_MOD_128QAM
Specifies 128QAM demodulator type.
BDA_MOD_160QAM
Specifies 160QAM demodulator type.
BDA_MOD_192QAM
Specifies 192QAM demodulator type.
BDA_MOD_224QAM
Specifies 224QAM demodulator type.
BDA_MOD_256QAM
Specifies 256QAM demodulator type.
BDA_MOD_320QAM
Specifies 320QAM demodulator type.
BDA_MOD_384QAM
Specifies 384QAM demodulator type.
BDA_MOD_448QAM
Specifies 448QAM demodulator type.
BDA_MOD_512QAM
Specifies 512QAM demodulator type.
BDA_MOD_640QAM
Specifies 640QAM demodulator type.
BDA_MOD_768QAM
Specifies 768QAM demodulator type.
BDA_MOD_896QAM
Specifies 896QAM demodulator type.
BDA_MOD_1024QAM
Specifies 1024QAM demodulator type.
BDA_MOD_QPSK
Specifies QPSK demodulator type.
BDA_MOD_BPSK
Specifies BPSK demodulator type.
BDA_MOD_OQPSK
Specifies OQPSK demodulator type.
BDA_MOD_8VSB
Specifies 8VSB demodulator type.
BDA_MOD_16VSB
Specifies 16VSB demodulator type.
BDA_MOD_ANALOG_AMPLITUDE
Specifies amplitude-modulated demodulator type.
BDA_MOD_ANALOG_FREQUENCY
Specifies frequency-modulated demodulator type.
BDA_MOD_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

KSPROPSETID_BdaDigitalDemodulator


MPEG2StreamType

The MPEG2StreamType enumeration contains values that specify an MPEG2 substream of the received broadcast stream.

typedef V1_ENUM enum MPEG2StreamType {
    BDA_UNITIALIZED_MPEG2STREAMTYPE = -1,
    Reserved1 = 0x0,
    ISO_IEC_11172_2_VIDEO     = Reserved1 + 1,
    ISO_IEC_13818_2_VIDEO     = ISO_IEC_11172_2_VIDEO + 1,
    ISO_IEC_11172_3_AUDIO     = ISO_IEC_13818_2_VIDEO + 1,
    ISO_IEC_13818_3_AUDIO     = ISO_IEC_11172_3_AUDIO + 1,
    ISO_IEC_13818_1_PRIVATE_SECTION =
                              ISO_IEC_13818_3_AUDIO + 1,
    ISO_IEC_13818_1_PES       =
                     ISO_IEC_13818_1_PRIVATE_SECTION + 1,
    ISO_IEC_13522_MHEG        = ISO_IEC_13818_1_PES + 1,
    ANNEX_A_DSM_CC            = ISO_IEC_13522_MHEG + 1,
    ITU_T_REC_H_222_1         = ANNEX_A_DSM_CC + 1,
    ISO_IEC_13818_6_TYPE_A    = ITU_T_REC_H_222_1 + 1,
    ISO_IEC_13818_6_TYPE_B    = ISO_IEC_13818_6_TYPE_A + 1,
    ISO_IEC_13818_6_TYPE_C    = ISO_IEC_13818_6_TYPE_B + 1,
    ISO_IEC_13818_6_TYPE_D    = ISO_IEC_13818_6_TYPE_C + 1,
    ISO_IEC_13818_1_AUXILIARY = ISO_IEC_13818_6_TYPE_D + 1,
    ISO_IEC_13818_1_RESERVED =
                            ISO_IEC_13818_1_AUXILIARY + 1,
    USER_PRIVATE            = ISO_IEC_13818_1_RESERVED + 1
} MPEG2StreamType;

Elements

BDA_UNITIALIZED_MPEG2STREAMTYPE
Specifies an MPEG2 stream type that is not initialized.
Reserved1
Reserved
ISO_IEC_11172_2_VIDEO
Specifies an 11172-2 video MPEG2 stream type.
ISO_IEC_13818_2_VIDEO
Specifies an 13818-2 video MPEG2 stream type.
ISO_IEC_11172_3_AUDIO
Specifies an 11172-3 audio MPEG2 stream type.
ISO_IEC_13818_3_AUDIO
Specifies an 13818-3 audio MPEG2 stream type.
ISO_IEC_13818_1_PRIVATE_SECTION
Specifies an 13818-1 private section MPEG2 stream type.
ISO_IEC_13818_1_PES
Specifies an 13818-1 PES MPEG2 stream type.
ISO_IEC_13522_MHEG
Specifies an 13522 MHEG MPEG2 stream type.
ANNEX_A_DSM_CC
Specifies an ANNEX_A_DSM_CC MPEG2 stream type.
ITU_T_REC_H_222_1
Specifies an ITU_T_REC_H_222_1 MPEG2 stream type.
ISO_IEC_13818_6_TYPE_A
Specifies an 13818-6-TYPE-A MPEG2 stream type.
ISO_IEC_13818_6_TYPE_B
Specifies an 13818-6-TYPE-B MPEG2 stream type.
ISO_IEC_13818_6_TYPE_C
Specifies an 13818-6-TYPE-C MPEG2 stream type.
ISO_IEC_13818_6_TYPE_D
Specifies an 13818-6-TYPE-D MPEG2 stream type.
ISO_IEC_13818_1_AUXILIARY
Specifies an 13818-1 auxiliary MPEG2 stream type.
ISO_IEC_13818_1_RESERVED
Specifies an 13818-1-reserved MPEG2 stream type.
USER_PRIVATE
Specifies a user-private MPEG2 stream type.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


PID_MAP

The PID_MAP structure describes a group of packets in the output stream of a packet identifier (PID) filter. This group consists of packets that are identified with an identical PID and contain particular media content.

typedef struct {
    ULONG                 ulPID ;
    MEDIA_SAMPLE_CONTENT  MediaSampleContent ;
} PID_MAP ;

Members

ulPID
Identifier of particular packets.
MediaSampleContent
MEDIA_SAMPLE_CONTENT enumeration value that specifies the type of media content that packets contain.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

BDA_PID_MAP, KSPROPSETID_BdaPIDFilter, MEDIA_SAMPLE_CONTENT


Polarization

The Polarization enumeration contains values that specify the polarity of the broadcast signal.

typedef V1_ENUM enum Polarisation {
    BDA_POLARISATION_NOT_SET = -1,
    BDA_POLARISATION_NOT_DEFINED = 0,
    BDA_POLARISATION_LINEAR_H = 1,
    BDA_POLARISATION_LINEAR_V,
    BDA_POLARISATION_CIRCULAR_L,
    BDA_POLARISATION_CIRCULAR_R,
    BDA_POLARISATION_MAX,
} Polarisation;

Elements

BDA_POLARISATION_NOT_SET
Polarization on the signal is not set.
BDA_POLARISATION_NOT_DEFINED
Polarization on the signal is not defined.
BDA_POLARISATION_LINEAR_H
Polarization on the signal is linear horizontal.
BDA_POLARISATION_LINEAR_V
Polarization on the signal is linear vertical.
BDA_POLARISATION_CIRCULAR_L
Polarization on the signal is circular left.
BDA_POLARISATION_CIRCULAR_R
Polarization on the signal is circular right.
BDA_POLARISATION_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

KSPROPSETID_BdaFrequencyFilter


SpectralInversion

The SpectralInversion enumeration contains values that specify how spectral inversion is set on a signal demodulator node.

typedef V1_ENUM enum SpectralInversion {
    BDA_SPECTRAL_INVERSION_NOT_SET = -1,
    BDA_SPECTRAL_INVERSION_NOT_DEFINED = 0,
    BDA_SPECTRAL_INVERSION_AUTOMATIC = 1,
    BDA_SPECTRAL_INVERSION_NORMAL,
    BDA_SPECTRAL_INVERSION_INVERTED,
    BDA_SPECTRAL_INVERSION_MAX
} SpectralInversion;

Elements

BDA_SPECTRAL_INVERSION_NOT_SET
Spectral inversion not set.
BDA_SPECTRAL_INVERSION_NOT_DEFINED
Spectral inversion not defined.
BDA_SPECTRAL_INVERSION_AUTOMATIC
Spectral inversion is automatic.
BDA_SPECTRAL_INVERSION_NORMAL
Spectral inversion is normal.
BDA_SPECTRAL_INVERSION_INVERTED
Spectral inversion is inverted.
BDA_SPECTRAL_INVERSION_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.

See Also

KSPROPSETID_BdaDigitalDemodulator


TransmissionMode

The TransmissionMode enumeration contains values that specify the carrier frequency of the broadcast transmission.

typedef V1_ENUM enum TransmissionMode {
    BDA_XMIT_MODE_NOT_SET = -1,
    BDA_XMIT_MODE_NOT_DEFINED = 0,
    BDA_XMIT_MODE_2K = 1,
    BDA_XMIT_MODE_8K,
    BDA_XMIT_MODE_MAX,
} TransmissionMode;

Elements

BDA_XMIT_MODE_NOT_SET
Transmission mode not set.
BDA_XMIT_MODE_NOT_DEFINED
Transmission mode not defined.
BDA_XMIT_MODE_2K
Transmission uses 1705 carriers, that is a 2K FFT.
BDA_XMIT_MODE_8K
Transmission uses 6817 carriers, that is an 8K FFT.
BDA_XMIT_MODE_MAX
Maximum value in the enumeration exceeded.

Headers

Defined in Bdatypes.h. Include Bdatypes.h.


Broadcast Driver Architecture Constants

A BDA minidriver uses the following constants.

BDA Filter Category GUIDs
BDA minidrivers use these GUIDs to specify the types of BDA filters to create.
BDA Node Category GUIDs
BDA minidrivers use these GUIDs to specify the types of BDA nodes to create.
BDA Pin Name GUIDs
BDA minidrivers use these GUIDs to specify the names of pins they support.
BDA Stream Format GUIDs
BDA minidrivers use these GUIDs to specify the data formats they support.


BDA Filter Category GUIDs

A BDA minidriver uses the BDA filter category GUIDs to specify the types of BDA filters to create. A BDA minidriver assigns these GUIDs in the array to which the Categories member of a KSFILTER_DESCRIPTOR structure points. The Bdamedia.h header file defines these GUIDs.

The following filter category GUIDs are available in BDA:

KSCATEGORY_BDA_RECEIVER_COMPONENT
A BDA minidriver assigns this GUID to specify to create a BDA receiver filter.
KSCATEGORY_BDA_NETWORK_TUNER
A BDA minidriver assigns this GUID to specify to create a BDA network tuner filter.
KSCATEGORY_BDA_NETWORK_EPG
A BDA minidriver assigns this GUID to specify to create a BDA electronic program guide (EPG) filter.
KSCATEGORY_BDA_IP_SINK
A BDA minidriver assigns this GUID to specify to create a BDA IP sink filter.
KSCATEGORY_BDA_NETWORK_PROVIDER
A BDA minidriver assigns this GUID to specify to create a BDA network provider filter.
KSCATEGORY_BDA_TRANSPORT_INFORMATION
A BDA minidriver assigns this GUID to specify to create a BDA transport information filter (TIF).


BDA Node Category GUIDs

A BDA minidriver uses the BDA node category GUIDs to specify the types of BDA nodes that are available to create. A BDA minidriver assigns one of these GUIDs in the variable to which the Type member of a KSNODE_DESCRIPTOR structure points. The Bdamedia.h header file defines these GUIDs.

The network provider uses the KSPROPERTY_BDA_NODE_TYPES property of the KSPROPSETID_BdaTopology property set to retrieve a list of nodes types available from the BDA minidriver. This list of node types is an array of KSNODE_DESCRIPTOR structures.

The following node category GUIDs are available in BDA:

KSNODE_BDA_RF_TUNER
A BDA minidriver assigns this GUID to specify that a BDA radio frequency tuner node is available.
KSNODE_BDA_QAM_DEMODULATOR
A BDA minidriver assigns this GUID to specify that a BDA QAM-type demodulator node is available.
KSNODE_BDA_QPSK_DEMODULATOR
A BDA minidriver assigns this GUID to specify that a BDA QPSK-type demodulator node is available.
KSNODE_BDA_8VSB_DEMODULATOR
A BDA minidriver assigns this GUID to specify that a BDA 8VSB-type demodulator node is available.
KSNODE_BDA_OPENCABLE_POD
A BDA minidriver assigns this GUID to specify that a BDA open-cable POD node is available.
KSNODE_BDA_PID_FILTER
A BDA minidriver assigns this GUID to specify that a BDA packet identifier (PID) filter node is available.
KSNODE_BDA_IP_SINK
A BDA minidriver assigns this GUID to specify that a BDA IP sink node is available.


BDA Pin Name GUIDs

A BDA minidriver uses BDA pin name GUIDs to specify the names and categories of pins it supports. A BDA minidriver assigns these GUIDs to the Name and Category members of a KSPIN_DESCRIPTOR structure. The Bdamedia.h header file defines these GUIDs. Pins of filters specify their names and categories to connect to pins of other filters that also specify those names and categories.

The following pin name GUIDs are available in BDA:

PINNAME_BDA_TRANSPORT
Pin name for a BDA transport pin.
PINNAME_BDA_ANALOG_VIDEO
Pin name for a BDA analog video pin.
PINNAME_BDA_ANALOG_AUDIO
Pin name for a BDA analog audio pin.
PINNAME_BDA_FM_RADIO
Pin name for a BDA FM radio pin.
PINNAME_BDA_IF_PIN
Pin name for a BDA intermediate frequency pin.
PINNAME_BDA_OPENCABLE_PSIP_PIN
Pin name for a BDA Open Cable PSIP pin.
PINNAME_IPSINK_INPUT
Pin name for an input pin to a BDA IP sink node (KSNODE_BDA_IP_SINK).
PINNAME_MPE
Pin name for a multiprotocol encapsulation (MPE) pin.


BDA Stream Format GUIDs

A BDA minidriver uses BDA stream format GUIDs to specify the data formats it supports. A BDA minidriver assigns these GUIDs to members of a KSDATARANGE structure. The Bdamedia.h header file defines these GUIDs. Pins of filters specify the ranges of data formats they support to connect to pins of other filters that also support those ranges.

The following stream GUIDs are available in BDA:

KSDATAFORMAT_TYPE_BDA_ANTENNA
A BDA minidriver assigns this GUID to the MajorFormat member of the DataRange member of a KS_DATARANGE_BDA_ANTENNA structure to enable connecting to a specific upstream filter, such as a network provider filter.
KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_SPECIFIER_BDA_TRANSPORT
A BDA minidriver assigns this GUID to the Specifier member of either a KSDATARANGE structure or the DataRange member of a KS_DATARANGE_BDA_TRANSPORT structure to enable connecting to a pin of a filter that also assigns this specifier.
KSDATAFORMAT_TYPE_BDA_IF_SIGNAL
A BDA minidriver assigns this GUID to the MajorFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this major format.
KSDATAFORMAT_TYPE_MPEG2_SECTIONS
A BDA minidriver assigns this GUID to the MajorFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this major format.
KSDATAFORMAT_SUBTYPE_ATSC_SI
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_SUBTYPE_DVB_SI
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_SUBTYPE_BDA_OPENCABLE_PSIP
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_SUBTYPE_BDA_OPENCABLE_OOB_PSIP
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_TYPE_BDA_IP
A BDA minidriver assigns this GUID to the MajorFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this major format.
KSDATAFORMAT_SUBTYPE_BDA_IP
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_SPECIFIER_BDA_IP
A BDA minidriver assigns this GUID to the Specifier member of either a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this specifier.
KSDATAFORMAT_TYPE_BDA_IP_CONTROL
A BDA minidriver assigns this GUID to the MajorFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this major format.
KSDATAFORMAT_SUBTYPE_BDA_IP_CONTROL
A BDA minidriver assigns this GUID to the SubFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this sub format.
KSDATAFORMAT_TYPE_MPE
A BDA minidriver assigns this GUID to the MajorFormat member of a KSDATARANGE structure to enable connecting to a pin of a filter that also assigns this major format.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.