overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · web viewthis allows the...

98
OpenGL Installable Client Driver Version 1.101 For Microsoft’s Windows NT 4.0, Windows NT 5.0, Windows 95, and Windows 98 Reference Guide

Upload: others

Post on 23-Mar-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client DriverVersion 1.101

For Microsoft’s Windows NT 4.0, Windows NT 5.0, Windows 95, and Windows 98

Reference Guide

Page 2: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Information in this document is subject to change without notice. Companies, names, and data used in examples herein are fictitious unless otherwise noted. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation.

© 1995, 1996, 1998 Microsoft Corporation. All rights reserved.

Portions ©1998 Silicon Graphics Inc., All rights reserved.

Microsoft Corporation

Page 3: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 3

OVERVIEW........................................................................................................... 5

FEATURES ADDED TO THE OPENGL SYSTEM.............................................7

CLIENT DRIVER INTERFACE...........................................................................9

DrvCopyContext.....................................................................................................10DrvCreateContext...................................................................................................11DrvCreateLayerContext..........................................................................................12DrvDeleteContext...................................................................................................13DrvDescribeLayerPlane..........................................................................................14DrvDescribePixelFormat.........................................................................................15DrvGetLayerPaletteEntries.....................................................................................16DrvGetProcAddress................................................................................................17DrvRealizeLayerPalette..........................................................................................18DrvReleaseContext.................................................................................................19DrvSetCallbackProcs..............................................................................................20DrvSetContext........................................................................................................ 21DrvSetLayerPaletteEntries......................................................................................22DrvSetPixelFormat.................................................................................................23DrvShareLists......................................................................................................... 24DrvSwapBuffers.....................................................................................................25DrvSwapLayerBuffers............................................................................................26DrvValidateVersion................................................................................................28LAYERPLANEDESCRIPTOR...............................................................................29

DISPLAY DRIVER INTERFACE.......................................................................33

DrvDescribePixelFormat.........................................................................................34DrvSetPixelFormat.................................................................................................35DrvSwapBuffers.....................................................................................................36

OPENGL ESCAPE INTERFACE........................................................................37

OPENGL_GETINFO..............................................................................................38OPENGL_CMD......................................................................................................39

SERVICE FUNCTIONS.......................................................................................40

Driver Object Services............................................................................................41EngCreateDriverObj...............................................................................................42EngDeleteDriverObj...............................................................................................43DRIVEROBJ.......................................................................................................... 44Window Object Services.........................................................................................45EngCreateWnd.......................................................................................................46WNDOBJ_bEnum..................................................................................................49WNDOBJ_cEnumStart...........................................................................................50

Page 4: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

WNDOBJ_vSetConsumer.......................................................................................52WNDOBJ...............................................................................................................53

CLIENT DRIVER SETUP AND INSTALLATION............................................54

Registry.................................................................................................................. 54Setup...................................................................................................................... 55

SAMPLE INSTALLABLE CLIENT DRIVER....................................................56

Directory Structure.................................................................................................57Building a Display Driver with OpenGL Support....................................................58

Windows 9x........................................................................................................ 58Windows NT.......................................................................................................58

ICD Library Organization.......................................................................................59Interacting Objects.............................................................................................59Nomenclature.....................................................................................................60Where to add your code......................................................................................60State validation and function picking..................................................................61Miscellaneous concerns......................................................................................62

Interactions............................................................................................................. 63Normal Interactions............................................................................................63Exceptional Conditions.......................................................................................65

Hardware Acceleration...........................................................................................67The role of DirectDraw...........................................................................................71Texture Management..............................................................................................72

Surface Management..........................................................................................73Texture format mapping......................................................................................74

Kernel Mode Issues in Windows NT 4.0 and 5.0.....................................................75

Page 5: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 5

OverviewThe OpenGL installable client driver (ICD) allows independent hardware vendors (IHV’s) to provide accelerated OpenGL rendering by intercepting OpenGL functions in a client library (DLL). Acceleration is provided via the combination of the ICD and extensions to the video display driver. To further illustrate this arrangement, the basic architecture of the OpenGL system is shown in the following illustration.

When OpenGL renders to a device, it needs to know certain attributes of the device it is drawing to, such as color depth/format, auxiliary buffers supported,

Page 6: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

and so on. This information is referred to as the pixel format. There are two classes of OpenGL pixel formats: generic and device specific.

Generic pixel formats are supported by a software implementation of OpenGL in the OpenGL DLL (opengl32.dll). This DLL processes the OpenGL calls into Win32 calls, rendering/CAD extension calls, or draws directly into the frame buffer.

Support for device specific pixel formats is divided between the video display driver and an ICD. The physical OpenGL API entry points are still provided by the OpenGL DLL, but are redirected via the ICD interface to the Client Driver. The ICD communicates with the Video Display Driver via the OpenGL Escape Module in the Win32 Kernel Component. The level of batching and the nature of the commands passed between the client driver and the display driver via the escapes is determined by the IHV and varies with the device capabilities. An IHV with hardware that supports high level graphics primitives might choose to do some of the OpenGL processing up front in the ICD and send graphics primitive drawing commands to the display driver. On the other hand, an IHV with hardware capable of directly supporting OpenGL might choose to send the OpenGL API calls directly from the client driver to the display driver. The OpenGL escape support in the Win32 Kernel Component merely provides the communications framework; the content of the drivers and the structures passed in to the Escapes are determined by the IHV.

In addition to providing the communications channel, the Win32 Kernel Component also provides the display driver with an array of engine services to help track window information and manage resources.

Page 7: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 7

Features Added to the OpenGL SystemThe following features have been added to the OpenGL system in support of the installable client driver.

Installable Client Driver Library Entry Points:DrvCreateContext: Creates a client rendering context for a specified device

context.DrvDeleteContext: Deletes a client rendering context for a specified device

context.DrvSetContext: Makes the rendering context current for the calling thread.DrvReleaseContext: Releases the rendering context from being current for

the calling threadDrvCopyContext: Copies selected groups of rendering state from one

OpenGL rendering context to another.DrvShareLists: Allows rendering contexts to share a single display-list space.DrvValidateVersion: Allows the client driver to verify that it is

communicating with the correct version of the display driver.DrvGetProcAddress: Returns the client address of an extension function to

use with the current rendering context.DrvSetCallbackProcs: Initializes the OpenGL DLL callback function

addresses in the ICD.DrvCreateLayerContext: Creates a new OpenGL rendering context for

drawing to a specified layer plane on a given device context.DrvDescribeLayerPlane: Obtains information about the layer planes of a

given pixel format.DrvSetLayerPaletteEntries: Sets the palette entries in a given color-index

layer plane for a device context.DrvGetLayerPaletteEntries: Retrieves the palette entries from a given

color-index layer plane for a specified device context.DrvRealizeLayerPalette: Maps palette entries from a given color-index layer

plane into the physical palette or initializes the palette of an RGBA layer plane.

DrvSwapLayerBuffers: Swaps the front and back buffers in the overlay, underlay, and main planes of a device context’s window.

DrvDescribePixelFormat: This entry point allows the client driver to identify pixel formats that it is capable of accelerating.

DrvSetPixelFormat: This entry point informs the client driver that an accelerated pixel formats is being used for a particular window.

Page 8: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvSwapBuffers: This entry point instructs the client driver to copy the contents of the back buffer to the display.

Video Display Driver Entry Points:DrvDescribePixelFormat: This entry point allows the video display driver to

identify pixel formats that it is capable of accelerating.DrvSetPixelFormat: This entry point informs the video display driver that an

accelerated pixel formats is being used for a particular window.DrvSwapBuffers: This entry point instructs the video display driver to copy

the contents of the back buffer to the display.

Dedicated OpenGL Escape Function: The OpenGL Escape function passes additional information to the video display driver, such as the foreground translation object and the window object.

Window Object Services: These services allow the video display driver to be notified of visible region changes for displayed windows.

Driver Object Services: These services allow the video display driver to register objects to be deleted upon thread detachment.

Page 9: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 9

Client Driver InterfaceThe OpenGL DLL calls the following entry points of the ICD interface if the device supports the pixel format requested by the application. All prototypes and structure definitions for the client driver interface are located in the header file include/gldrv.h. The functions are listed in alphabetic order, and the structure definition of LAYERPLANEDESCRIPTOR can be found at the end of this section.

DrvCopyContextDrvCreateContextDrvCreateLayerContextDrvDeleteContextDrvDescribeLayerPlaneDrvDescribePixelFormatDrvGetProcAddressDrvGetLayerPaletteEntriesDrvRealizeLayerPaletteDrvReleaseContextDrvSetCallbackProcsDrvSetContextDrvSetLayerPaletteEntriesDrvSetPixelFormatDrvShareListsDrvSwapBuffersDrvSwapLayerBuffersDrvValidateVersionLAYERPLANEDESCRIPTOR

Page 10: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvCopyContextBOOL DrvCopyContext(dhrcSource, dhrcDest, fuMask)DHGLRC dhrcSource;DHGLRC dhrcDest;UINT fuMask;

DrvCopyContext copies selected groups of rendering state from one OpenGL driver’s rendering context to another.

dhrcSourceSpecifies the source OpenGL driver rendering context whose state information is to be copied.

dhrcDestSpecifies the destination OpenGL driver rendering context to which the information is to be copied.

fuMaskSpecifies which groups of dhrcSource’s rendering state are to be copied. It contains a bitwise-OR of the same symbolic names that are passed to glPushAttrib. You can use GL_ALL_ATTRIB_BITS to copy the entire rendering state.

DrvCopyContext enables the synchronization of rendering state between two driver rendering contexts. The rendering state between two contexts can only be copied within the same process, and the rendering contexts must be from the same OpenGL implementation. For example, you can always copy a rendering state between two rendering contexts of a given pixel format in the same process.

You can copy only the same state information available through glPushAttrib. You cannot copy some state information, such as pixel pack/unpack state, render mode state, select state, and feedback state. Opengl32 ensures that dhrcDest is not current to any thread.

Page 11: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 11

DrvCreateContextDHGLRC DrvCreateContext(hdc)HDC hdc;

DrvCreateContext creates a client rendering context for the device context specified by hdc. The unique identifier returned by DrvCreateContext will be used to identify the created context in subsequent calls to the client driver.

hdcA valid handle to a device context.

DrvCreateContext returns a non-zero unique identifier for the rendering context. If an error occurs, DrvCreateContext returns NULL.

Page 12: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvCreateLayerContextDHGLRC DrvCreateLayerContext(hdc, iLayerPlane)HDC hdc;INT iLayerPlane;

DrvCreateLayerContext creates an OpenGL driver rendering context for drawing to a layer plane on the given device context.

hdcSpecifies the device context for which the new driver rendering context will be created.

iLayerPlaneSpecifies the layer plane to which the new rendering context will be bound. Positive values of iLayerPlane identify overlay planes, where 1 is the first overlay plane over the main plane, 2 is the second overlay plane over the first overlay plane, and so on. Negative values identify underlay planes, where -1 is the first underlay plane under the main plane, -2 is the second underlay plane under the first underlay plane, and so on. The number of overlay and underlay planes is given in the bReserved field of the PIXELFORMATDESCRIPTOR structure.

DrvCreateLayerContext returns the handle to an OpenGL driver rendering context upon success; it returns NULL if it fails.

DrvCreateLayerContext creates a client rendering context for the device context specified by hdc. The unique identifier returned by DrvCreateLayerContext will be used to identify the created context in subsequent calls to the client driver.

Page 13: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 13

DrvDeleteContextBOOL DrvDeleteContext(dhglrc)DHGLRC dhglrc;

DrvDeleteContext deletes the client rendering context specified by dhglrc.

dhglrc A valid handle to a client rendering context.

DrvDeleteContext returns TRUE if the rendering context was deleted, FALSE otherwise.

Page 14: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvDescribeLayerPlaneBOOL DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd)HDC hdc;INT iPixelFormat;INT iLayerPlane;UINT nBytes;LPLAYERPLANEDESCRIPTOR plpd;

DrvDescribeLayerPlane obtains information about the layer planes of a given pixel format.

hdcSpecifies the device context of a window whose layer planes are to be described.

iPixelFormatSpecifies the pixel format of iLayerPlane.

iLayerPlaneSpecifies the overlay or underlay plane for which information is to be obtained. Positive values of iLayerPlane identify overlay planes, where 1 is the first overlay plane over the main plane, 2 is the second overlay plane over the first overlay plane, and so on. Negative values identify underlay planes, where -1 is the first underlay plane under the main plane, -2 is the second underlay plane under the first underlay plane, and so on. The number of overlay and underlay planes is given in the bReserved field of the PIXELFORMATDESCRIPTOR structure.

nBytesSpecifies the size, in bytes, of the structure pointed to by plpd. DrvDescribeLayerPlane stores layer-plane data in a LAYERPLANEDESCRIPTOR structure, and it stores no more than nBytes of data. This parameter should be the sizeof(LAYERPLANEDESCRIPTOR).

plpdPoints to a LAYERPLANEDESCRIPTOR structure in which DrvDescribeLayerPlane returns the layer plane information. The number of bytes of data copied to the structure will be stored in the nSize field of this structure.

DrvDescribeLayerPlane returns TRUE if it succeeds, and the members of the structure pointed to by plpd are set accordingly. This function returns FALSE if it fails.

Higher-numbered planes overlay lower-numbered planes.

Page 15: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 15

DrvDescribePixelFormatLONG DrvDescribePixelFormat(hdc, iPixelFormat, cjpfd, ppfd)HDC hdc,LONG iPixelFormat;ULONG cjpfd;PIXELFORMATDESCRIPTOR *ppfd;

DrvDescribePixelFormat describes the pixel format for a dhpdev device by writing the pixel description information to a structure specified by ppfd.

hdcSpecifies the device context for which the pixel format is requested.

iPixelFormatSpecifies the index number of the requested pixel format.

cjpfdSpecifies the maximum number of bytes that may be written into the structure pointed to by ppfd.

ppfdPoints to the PIXELFORMATDESCRIPTOR structure that is to receive the information describing the pixel format. This function stores the number of bytes copied to the structure in the structure’s nSize member.

If the function succeeds, it returns the maximum pixel format index. It returns zero if an error occurs, and an error code is logged.

A pixel format corresponds to a pixel configuration supported by the graphics hardware. The PIXELFORMATDESCRIPTOR structure contains information about a pixel format. PIXELFORMATDESCRIPTOR is defined in wingdi.h.

DrvDescribePixelFormat also fills in the structure pointed to by ppfd if it is successful. If ppfd is NULL, this function simply returns the maximum pixel format index and writes no data to the structure. This may be used by GDI to obtain a device context’s maximum pixel format index. The pixel formats that a device supports are identified by positive one-based integer indices starting at 1.

This client driver entry point is supported only for client drivers on Windows 95, Windows 98 and (in some cases) Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When this entry point is not supported in the client driver, it exists in the display driver.

Note

Page 16: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvGetLayerPaletteEntriesint DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr)HDC hdc;INT iLayerPlane;INT iStart;INT cEntries;COLORREF *pcr;

DrvGetLayerPaletteEntries retrieves the palette entries from a given color-index layer plane for the given device context.

hdcHandle to the device context of a window whose layer plane’s palette entries are to be described.

iLayerPlaneSpecifies the overlay or underlay plane for which information is to be obtained. Positive values of iLayerPlane identify overlay planes, where 1 is the first overlay plane over the main plane, 2 is the second overlay plane over the first overlay plane, and so on. Negative values identify underlay planes, where -1 is the first underlay plane under the main plane, -2 is the second underlay plane under the first underlay plane, and so on. The number of overlay and underlay planes is given in the bReserved field of the PIXELFORMATDESCRIPTOR structure.

iStartSpecifies the first palette entry to be retrieved.

cEntriesSpecifies the number of palette entries to be retrieved.

pcrPointer to an array of COLORREF structures in which RGB color information will be returned. The array size is cEntries.

DrvGetLayerPaletteEntries returns the number of palette entries that were retrieved for the specified layer plane of the window upon successful completion. If the function fails or no pixel format is selected, the return value is 0.

Each color-index plane in a window has a palette of size 2n, where n is the number of bit planes in the layer plane.

Page 17: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 17

DrvGetProcAddressPROC DrvGetProcAddress (lpszProc)LPCSTR lpszProc;

DrvGetProcAddress returns the client address of an extension function to use with the current rendering context. The extension function addresses are unique for each pixel format. All rendering contexts of a given pixel format share the same extension function addresses.

lpszProcPoints to a null-terminated string containing the extension function name.

DrvGetProcAddress returns the client address of the extension function if the extension is supported by the current rendering context. Otherwise, it returns NULL.

OpenGL applications do not have a direct link to the ICD. DrvGetProcAddress allows applications to call extension functions provided by the driver indirectly through the returned function addresses. The returned function addresses must be callable in the client space.

Since extension functions are callable by applications, they must validate the current rendering context. The list of supported extensions for the current rendering context must be given in glGetString.

Page 18: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvRealizeLayerPaletteint DrvRealizeLayerPalette(hdc, iLayerPlane,bRealize)HDC hdc;INT iLayerPlane;BOOL bRealize;

DrvRealizeLayerPalette maps palette entries from a given color-index layer plane into the physical palette, or initializes the palette of an RGBA layer plane.

hdcHandle to the device context of a window whose layer plane’s palette is to be realized into the physical palette.

iLayerPlaneSpecifies the overlay or underlay plane whose palette information is to be realized. Positive values of iLayerPlane identify overlay planes, where 1 is the first overlay plane over the main plane, 2 is the second overlay plane over the first overlay plane, and so on. Negative values identify underlay planes, where -1 is the first underlay plane under the main plane, -2 is the second underlay plane under the first underlay plane, and so on. The number of overlay and underlay planes is given in the bReserved field of the PIXELFORMATDESCRIPTOR structure.

bRealizeIndicates whether the palette is to be realized into the physical palette. When bRealize is TRUE, the palette entries are mapped into the physical palette where available. When bRealize is FALSE, the palette entries for the layer plane of the window are no longer needed and might be realized for use by another foreground window.

DrvRealizeLayerPalette returns TRUE upon success, even if bRealize is TRUE and the physical palette is not available. If the function fails or no pixel format is selected, the return value is FALSE.

The physical palette for a layer plane is a shared resource among windows with layer planes. When more than one window realizes a palette for a given physical layer plane, only one palette at a time is realized. When you call DrvRealizeLayerPalette, the layer palette of a foreground window is always realized.

When a window’s layer palette is realized, its palette entries are always mapped one-to-one into the physical palette. Unlike GDI’s logical palettes, there is no mapping of other windows’ layer palettes to the current physical palette in DrvRealizeLayerPalette.

DrvRealizeLayerPalette cannot be used to realize the palette of the main plane palette.

Page 19: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 19

DrvReleaseContextBOOL DrvReleaseContext(dhglrc)DHGLRC dhglrc;

DrvReleaseContext releases the rendering context specified by dhglrc from being current for the calling thread. This function returns TRUE upon success, otherwise it returns FALSE.

Page 20: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvSetCallbackProcsvoid DrvSetCallbackProcs (nProcs, pProcs)INT nProcs;PROC *pProcs;

DrvSetCallbackProcs initializes the OpenGL DLL callback function addresses in the installable client driver.

nProcsSpecifies the number of OpenGL DLL callback functions in pProcs.

pProcsSpecifies the array containing the OpenGL DLL callback function addresses.

The OpenGL DLL passes callback function addresses to this function when the driver is first loaded for the process. DrvSetCallbackProcs returns no value.

The callback functions in pProcs are given in the following order:

PFN_SETCURRENTVALUE:typedef void (APIENTRY * PFN_SETCURRENTVALUE)(VOID *pv);The SETCURRENTVALUE callback function stores a value in the current thread. Only one value is stored per thread. It provides a fast method to store per-thread data. The macro SETCURRENTVALUE(PV) further optimizes its use for alpha platforms.

PFN_GETCURRENTVALUE:typedef void * (APIENTRY * PFN_GETCURRENTVALUE)(VOID);The GETCURRENTVALUE callback function returns the value stored in the current thread by PFN_SETCURRENTVALUE. It provides a fast method to retrieve per-thread data. The macro GETCURRENTVALUE further optimizes its use for alpha platforms.

PFN_GETDHGLRC:typedef DHGLRC (APIENTRY * PFN_GETDHGLRC)(HGLRC hrc);The GETDHGLRC callback function returns the driver-specific rendering context handle for an OpenGL rendering context handle. This function returns NULL if the HGLRC is invalid or if there is no driver-specific handle. A driver can use this callback to translate rendering context handles that are passed directly to the driver through exported extensions.

Page 21: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 21

DrvSetContextPGLCLTPROCTABLE DrvSetContext(hdc, dhglrc, pfnSetProcTable)HDC hdc;DHGLRC dhglrc;PFN_SETPROCTABLE pfnSetProcTable;

DrvSetContext makes the rendering context specified by dhglrc and the device context specified by hdc current for the calling thread.

hdcA valid handle to a device context.

dhglrcA valid handle to a rendering context.

pfnSetProcTableThe address of the function to use to set the OpenGL procedure table if such action is required after the call to DrvSetContext.

DrvSetContext returns a pointer to the OpenGL procedure table to be used for the rendering context. This table contains function pointers for all OpenGL functions. GLCLTPROCTABLE is defined in the header file gldrv.h.

PFN_SETPROCTABLE is defined as follows:

typedef void (APIENTRY * PFN_SETPROCTABLE)(PGLCLTPROCTABLE pProcTable)

Page 22: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvSetLayerPaletteEntriesint DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr)HDC hdc;INT iLayerPlane;INT iStart;INT cEntries;CONST COLORREF *pcr;

DrvSetLayerPaletteEntries sets the palette entries in a given color-index layer plane for the given device context.

hdcHandle to the device context of a window whose layer plane’s palette is to be set.

iLayerPlaneSpecifies the overlay or underlay plane for which information is to be set. Positive values of iLayerPlane identify overlay planes, where 1 is the first overlay plane over the main plane, 2 is the second overlay plane over the first overlay plane, and so on. Negative values identify underlay planes, where -1 is the first underlay plane under the main plane, -2 is the second underlay plane under the first underlay plane, and so on. The number of overlay and underlay planes is given in the bReserved field of the PIXELFORMATDESCRIPTOR structure.

iStartSpecifies the first palette entry to be set.

cEntriesSpecifies the number of palette entries to be set.

pcrPointer to an array of COLORREF structures that contain RGB color information. The array size is cEntries.

DrvSetLayerPaletteEntries returns the number of palette entries that were set in the specified layer plane of the window upon successful completion. If the function fails or no pixel format is selected, the return value is 0.

Each color-index plane in a window has a palette of size 2n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette.

Initially, the layer palette contains white colors.

DrvSetLayerPaletteEntries cannot be used to set the palette entries of the main plane palette.

Page 23: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 23

DrvSetPixelFormatBOOL DrvSetPixelFormat(hdc, iPixelFormat)HDC hdc;LONG iPixelFormat;

DrvSetPixelFormat sets the pixel format of a window.

hdcSpecifies a device context associated with the window..

iPixelFormatIndex that specifies the device format to which the pixel format is to be set. The pixel formats that a device supports are identified by positive one-based integer indices starting at 1.

DrvSetPixelFormat returns TRUE if the pixel format is set successfully; it returns FALSE if an error occurs.

Setting the pixel format more than once can result in complications for the Window Manager and for multi-threaded applications. Consequently, the pixel format of a window can be set only once and must remain unchanged.

This client driver entry point is supported only for client drivers on Windows 95, Windows 98 and (in some cases) Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When this entry point is not supported in the client driver, it exists in the display driver.

Note

Page 24: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvShareListsBOOL DrvShareLists (dhglrc1, dhglrc2)DHGLRC dhglrc1;DHGLRC dhglrc2;

DrvShareLists allows rendering contexts to share a single display-list space. Rendering contexts that share a single display-list space also share a single texture object space.

dhglrc1Specifies the client rendering context with which to share display lists.

dhglrc2Specifies the client rendering context to share display lists with dhglrc1. The client rendering context dhglrc2 should not contain any existing display lists when this function is called.

DrvShareLists returns TRUE if the function succeeds. If display lists exist in dhglrc2 or an error occurs, it returns FALSE.

A newly created client rendering context has its own display-list space. DrvShareLists allows a client context to share a display-list space with other client contexts. Any number of client contexts can share a single display-list space. Once a client context shares a display-list space, it always uses the display-list space until it is deleted. A shared display-list space is deleted when the last client context using it is deleted. All display-list indexes and definitions in a shared display-list space are shared.

All client rendering contexts of a given device pixel format must be able to share display lists. Client rendering contexts of different device pixel formats may share display lists if allowed by the implementation.

If a driver implements display lists on the client side, it must ensure that shared display list operations are thread safe. It should fail or serialize the call to modify a shared display list in a thread while another thread is using it. If the driver implements display lists on the server side and the display list operations are serialized by DrvEscape, then the operations are guaranteed to be thread safe.

The version number returned by glGetString must be “1.1” or later.

Page 25: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 25

DrvSwapBuffersBOOL DrvSwapBuffers(hdc)HDC hdc;

DrvSwapBuffers instructs the driver to display the contents of the hidden buffer of the window identified by hdc.

hdcSpecifies a device context of the window.

DrvSwapBuffers can affect the display only if the pixel format for the window specified by pwo is double-buffered. The content of the hidden buffer is undefined after the swap occurs.

This function is required if the driver supports a pixel format with double buffering; that is, the PFD_DOUBLEBUFFER is set in the dwFlags field of the PIXELFORMATDESCRIPTOR.

This function returns TRUE upon success; it returns FALSE upon failure.

If a double-buffered pixel format uses split pixels for the front and back buffers, it should include the PFD_SWAP_EXCHANGE flag in the pixel format descriptor. See PIXELFORMATDESCRIPTOR for details. This client driver entry point is supported only for client drivers on Windows 95, Windows 98 and (in some cases) Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When this entry point is not supported in the client driver, it exists in the display driver.

Notes

Page 26: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvSwapLayerBuffersBOOL DrvSwapLayerBuffers(hdc, fuPlanes)HDC hdc;UINT fuPlanes;

DrvSwapLayerBuffers swaps the front and back buffers in the overlay, underlay, and main planes of the window referenced by a specified device context.

hdcSpecifies the device context of the window whose plane buffers are to be swapped.

fuPlanesSpecifies the overlay, underlay, and main planes whose front and back buffers are to be swapped. The bReserved field of the PIXELFORMATDESCRIPTOR structure specifies the number of overlay and underlay planes. This parameter is a bitwise combination of the following values.Value MeaningWGL_SWAP_MAIN_PLANE

Swaps the front and back buffers of the main plane.l

WGL_SWAP_OVERLAYi Swaps the front and back buffers of overlay plane i, where i is an integer between 1 and 15. WGL_SWAP_OVERLAY1 identifies the first overlay over the main plane, WGL_SWAP_OVERLAY2 identifies the second overlay over the first plane and so on.

WGL_SWAP_UNDERLAYi Swaps the front and back buffers of underlay plane i, where i is an integer between 1 and 15. WGL_SWAP_UNDERLAY1 identifies the first underlay under the main plane, WGL_SWAP_UNDERLAY2 identifies the second underlay under the first plane and so on.

DrvSwapLayerBuffers returns TRUE if it succeeds; otherwise, it returns FALSE.

When a layer plane doesn’t include a back buffer, calling DrvSwapLayerBuffers should have no effect on that layer plane. The state of the back buffer’s content after swapping should be indicated by returning the appropriate flag in the LAYERPLANEDESCRIPTOR structure of the

Page 27: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 27

corresponding layer plane, or in the PIXELFORMATDESCRIPTOR of the main plane. DrvSwapLayerBuffers swaps the front and back buffers in the specified layer planes simultaneously.

Some devices don’t support swapping layer planes individually; they swap all layer planes as a group. The PFD_SWAP_LAYER_BUFFERS flag of the PIXELFORMATDESCRIPTOR can be used to indicate that a device can swap individual layer planes and that DrvSwapLayerBuffers can be called.

Page 28: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvValidateVersionBOOL DrvValidateVersion(ulVersion)ULONG ulVersion;

DrvValidateVersion gives the client driver an opportunity to verify that it is communicating with the correct version of the display driver. The OpenGL Client DLL obtains an IHV-defined version number from the display driver via the OPENGL_GETINFO escape (please refer to the OpenGL Escape Interface section of this document). This number will be passed to DrvValidateVersion as ulVersion. If the client driver recognizes the version number as one it supports, it must return TRUE; otherwise, it should return FALSE.

Page 29: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 29

LAYERPLANEDESCRIPTORtypedef struct tagLAYERPLANEDESCRIPTOR {

WORD nsize;WORD nversion;DWORD dwFlags;BYTE iPixelType;BYTE cColorBits;BYTE cRedBits;BYTE cRedShift;BYTE cGreenBits;BYTE cGreenShift;BYTE cBlueBits;BYTE cBlueShift;BYTE cAlphaBits;BYTE cAlphaShift;BYTE cAccumBits;BYTE cAccumRedBits;BYTE cAccumGreenBits;BYTE cAccumBlueBits;BYTE cAccumAlphaBits;BYTE cDepthBits;BYTE cStencilBits;BYTE cAuxBuffers;BYTE iLayerPlane;BYTE bReserved;COLORREFcTransparent;

} LAYERPLANEDESCRIPTOR;

The LAYERPLANEDESCRIPTOR structure describes the pixel format of a drawing surface.

nSizeSpecifies the size of this data structure. Set this value to sizeof(LAYERPLANEDESCRIPTOR).

nVersionSpecifies the version of this data structure. Set this value to 1.

dwFlagsA set of bit flags that specify properties of the layer plane. The properties are generally not mutually exclusive; that is, you can set any combination of bit flags with the exceptions noted. The following bit flag constants are defined.

Page 30: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Value MeaningLPD_SUPPORT_OPENGL The layer plane supports OpenGL drawing.LPD_SUPPORT_GDI The layer plane supports GDI drawing. The

current implementation of OpenGL does not support this flag.

LPD_DOUBLEBUFFER The layer plane is double-buffered. A layer plane can be double-buffered even when the main plane is single-buffered and vice versa.

LPD_STEREO The layer plane is stereoscopic. A layer plane can be stereoscopic even when the main plane is monoscopic and vice versa.

LPD_SWAP_EXCHANGE In a double-buffered layer plane, swapping the color buffer exchanges the front buffer and the back buffer contents. The back buffer then contains the contents of the front buffer before the swap. This flag is a hint only and does not have to be supported by a driver..

LPD_SWAP_COPY In a double-buffered layer plane, swapping the color buffer copies the back buffer contents to the front buffer. The swap does not affect the back buffer content. This flag is a hint only and might not be provided by a driver.

LPD_TRANSPARENT The crTransparent field of this structure contains a transparent color or index value that enables underlying layers to show through this layer. All layer planes, except the lowest-numbered underlay layer, have a transparent color or index.

LPD_SHARE_DEPTH The layer plane shares the depth buffer with the main plane.

LPD_SHARE_STENCIL The layer plane shares the stencil buffer with the main plane.

LPD_SHARE_ACCUM The layer plane shares the accumulation buffer with the main plane.

iPixelTypeSpecifies the type of pixel data. The following types are defined.Value MeaningLPD_TYPE_RGBA RGBA pixels. Each pixel has four

components: red, green, blue, and alpha.LPD_TYPE_COLORINDEX Color-index pixels. Each pixel uses a color-

index value.

Page 31: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 31

cColorBitsSpecifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer.

cRedBitsSpecifies the number of red bitplanes in each RGBA color buffer.

cRedShiftSpecifies the shift count for red bitplanes in each RGBA color buffer.

cGreenBitsSpecifies the number of green bitplanes in each RGBA color buffer.

cGreenShiftSpecifies the shift count for green bitplanes in each RGBA color buffer.

cBlueBitsSpecifies the number of blue bitplanes in each RGBA color buffer.

cBlueShiftSpecifies the shift count for blue bitplanes in each RGBA color buffer.

cAlphaBitsSpecifies the number of alpha bitplanes in each RGBA color buffer.

cAlphaShiftSpecifies the shift count for alpha bitplanes in each RGBA color buffer.

cAccumBitsSpecifies the total number of bitplanes in the accumulation buffer.

cAccumRedBitsSpecifies the number of red bitplanes in the accumulation buffer.

cAccumGreenBitsSpecifies the number of green bitplanes in the accumulation buffer.

cAccumBlueBitsSpecifies the number of blue bitplanes in the accumulation buffer.

cAccumAlphaBitsSpecifies the number of alpha bitplanes in the accumulation buffer.

cDepthBitsSpecifies the depth of the depth buffer.

cStencilBitsSpecifies the depth of the stencil buffer.

cAuxBuffersSpecifies the number of auxiliary buffers. Auxiliary buffers are not supported.

iLayerTypeSpecifies the layer plane number. Positive values identify overlay planes, where 1 is the first overlay plane over the main plane, 2 is the second overlay

Page 32: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

plane over the first overlay plane, and so on. Negative values identify underlay planes, where -1 is the first underlay plane under the main plane, -2 is the second underlay plane under the first underlay plane, and so on. The number of overlay and underlay planes is given in the bReserved field of the PIXELFORMATDESCRIPTOR structure.

bReservedNot used. This field must be set to zero.

crTransparentWhen the LPD_TRANSPARENT flag is set, specifies the transparent color or index value. Typically, this value is 0.

Page 33: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 33

Display Driver InterfacePrototypes and structure definitions for these additional display driver entry points are located in header files winddi.h of the Windows NT DDK. Note that these entry points only exist on Windows NT 4.0 and, in some cases, Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When these entry points are not supported in the display driver, they exist in the client driver.

DrvDescribePixelFormatDrvSetPixelFormatDrvSwapBuffers

Page 34: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvDescribePixelFormatLONG DrvDescribePixelFormat(dhpdev, iPixelFormat, cjpfd, ppfd)DHPDEV dhpdev;LONG iPixelFormat;ULONG cjpfd;PIXELFORMATDESCRIPTOR *ppfd;

DrvDescribePixelFormat describes the pixel format for a dhpdev device by writing the pixel description information to a structure specified by ppfd.

dhpdevSpecifies the device for which the pixel format is requested.

iPixelFormatSpecifies the index number of the requested pixel format.

cjpfdSpecifies the maximum number of bytes that may be written into the structure pointed to by ppfd.

ppfdPoints to the PIXELFORMATDESCRIPTOR structure that is to receive the information describing the pixel format. This function stores the number of bytes copied to the structure in the structure’s nSize member.

If the function succeeds, it returns the maximum pixel format index. It returns zero if an error occurs, and an error code is logged.

A pixel format corresponds to a pixel configuration supported by the graphics hardware. The PIXELFORMATDESCRIPTOR structure contains information about a pixel format. PIXELFORMATDESCRIPTOR is defined in wingdi.h.

DrvDescribePixelFormat also fills in the structure pointed to by ppfd if it is successful. If ppfd is NULL, this function simply returns the maximum pixel format index and writes no data to the structure. This may be used by GDI to obtain a device context’s maximum pixel format index. The pixel formats that a device supports are identified by positive one-based integer indices starting at 1.

This display driver entry point is only supported only for display drivers on Windows NT 4.0 and (in some cases) Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When this entry point is not supported in the display driver, it exists in the client driver.

Note

Page 35: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 35

DrvSetPixelFormatBOOL DrvSetPixelFormat(pso, iPixelFormat, hwnd)SURFOBJ *pso;LONG iPixelFormat;HWND hwnd;

DrvSetPixelFormat sets the pixel format of a window.

psoPoints to the surface (SURFOBJ) that the window is associated with.

iPixelFormatIndex that specifies the device format to which the pixel format is to be set. The pixel formats that a device supports are identified by positive one-based integer indices starting at 1.

hwndIdentifies the window whose pixel format is to be set.The display driver may call the graphics engine to create a window object and register a callback routine to be invoked when the window region changes. Refer also to “Window Object Services” later in this document.

DrvSetPixelFormat returns TRUE if the pixel format is set successfully; it returns FALSE if an error occurs.

Setting the pixel format more than once can result in complications for the Window Manager and for multi-threaded applications. Consequently, the pixel format of a window can be set only once and must remain unchanged.

Refer also to the section on Window Object Services.This display driver entry point is only supported only for display drivers on Windows NT 4.0 and (in some cases) Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When this entry point is not supported in the display driver, it exists in the client driver.

Notes

Page 36: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DrvSwapBuffersBOOL DrvSwapBuffers(pso, pwo)SURFOBJ *pso;WNDOBJ *pwo;

DrvSwapBuffers instructs the driver to display the contents of the hidden buffer of the window identified by pwo on the surface specified by pso.

psoPoints to the target surface that will be modified.

pwoPoints to the window object that defines the region on the target surface with which the back buffer will be swapped.

DrvSwapBuffers can affect the display only if the pixel format for the window specified by pwo is double-buffered. The content of the hidden buffer is undefined after the swap occurs.

This function is required if the driver supports a pixel format with double buffering; that is, the PFD_DOUBLEBUFFER is set in the dwFlags field of the PIXELFORMATDESCRIPTOR.

This function returns TRUE upon success; it returns FALSE upon failure.

If a double-buffered pixel format uses split pixels for the front and back buffers, it should include the PFD_SWAP_EXCHANGE flag in the pixel format descriptor. See PIXELFORMATDESCRIPTOR for details.This display driver entry point is only supported only for display drivers on Windows NT 4.0 and (in some cases) Windows NT 5.0. The format of the registry entries on Windows NT 5.0 determines if this entry point is going to be used or not (see Client Driver Setup and Installation for details.) When this entry point is not supported in the display driver, it exists in the client driver.

Notes

Page 37: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 37

OpenGL Escape InterfaceThe OpenGL installable client driver uses the Win32 API to access non-drawing OpenGL functionality implemented as extended functions (or extensions). These extensions must be implemented within the video display driver that supports an ICD. Access to the extended functionality is gained through ExtEscape; this function is described in the “Win32 Programmer’s Reference”.

The extensions implemented by the driver, OPENGL_GETINFO and OPENGL_CMD, are defined by Microsoft and must be supported by all video display drivers that support an OpenGL installable client library.

OPENGL_GETINFOOPENGL_CMD

OpenGL extension numbers are defined in header file winddi.h. Structure definitions are contained in header file gldrv.h.

Note

Page 38: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

OPENGL_GETINFOOPENGL_GETINFO is called by the OpenGL DLL to retrieve information from the video display driver. The return value is TRUE if the video display driver supports an OpenGL installable client driver; FALSE otherwise.

The first DWORD of the ExtEscape input buffer specifies the extension by its number and is defined as:

ULONG ulSubEsc At present, the value of ulSubEsc is OPENGL_GETINFO_DRVNAME. This function retrieves the name and version of the video display driver.

The remainder of the input buffer is unused for this extended function.

The format and content of the ExtEscape output buffer will be:

ULONG ulVersion This field must be equal to 2. It allows GDI to identify a display driver that supports the non-IHV specific portions of the interface described in this document.Windows NT versions 3.51 and earlier reported 1 for this version number. Such drivers are no longer supported.

ULONG ulDriverVersion This field specifies the IHV-specific version number of the video display driver. It is used to verify that the video display driver matches the OpenGL ICD.

WCHAR awch[MAX_PATH+1] This field contains a NULL-terminated string specifying the name of the video display driver. It is used by the OpenGL DLL to find the name of the corresponding OpenGL ICD in the registry. The maximum length of this string is MAX_PATH characters.

Page 39: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 39

OPENGL_CMDOPENGL_CMD is called by the OpenGL installable client driver to process OpenGL functionality. The first four DWORDS of the ExtEscape input buffer are defined as follows:

ULONG ulSubEsc This value is IHV-specific.FLONG fl Specifies flags indicating the values of the next two

DWORDS. Possible values are combinations of the following bitmasks:OGLCMD_NEEDWNDOBJ - Indicates that the WNDOBJ field should be filled in by GDI.OGLCMD_NEEDXLATEOBJ - Indicates that the XLATEOBJ field should be filled in by GDI

WNDOBJ *pwo Points to a window object filled in by the Win32 Kernel Component if the OGLCMD_NEEDWNDOBJ flag is set in fl.

XLATEOBJ *pxlo Points to a translation object filled in by the Win32 Kernel Component if the OGLCMD_NEEDXLATEOBJ flag is set in fl.

The remainder of the input buffer is IHV-specific.

The contents of the output buffer and the return value are IHV-specific.

Page 40: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Service FunctionsThe video display driver is provided with the following additional services. All prototypes and structure definitions for the new services are located in winddi.h.

These services are only available on Windows NT operating systems.

Driver Object Services: This feature allows the video display driver to register resources that should be deleted upon thread detachment.

Window Object Services: This feature allows the video display driver to respond to changes in window regions.

Page 41: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 41

Driver Object ServicesThe driver object services consist of two functions: EngCreateDriverObj and EngDeleteDriverObj. These two functions are provided to help the display driver manage per process resources. EngCreateDriverObj allows the display driver to register a resource with GDI and to supply the address of the deletion function for that object. The returned object is associated with the current process. When a process terminates, GDI will call the deletion function for all objects associated with that process that have not been released by a prior call to EngDeleteDriverObj. EngDeleteDriverObj is used to delete the object when the driver explicitly releases the resource (that is, deletion not initiated by process termination).

For example, the video display driver could provide the following three functions to allocate and deallocate rendering contexts:

Function Name Operations Performed

IHVCreateRC Called in response to wglCreateContext.Allocates the necessary resources for the rendering context.Calls EngCreateDriverObj, passing it a unique identifier for the rendering context, and the address of the function IHVDeleteRCResources.

IHVDeleteRC Called in response to wglDeleteContext.Calls EngDeleteDriverObj.Calls IHVDeleteRCResources to free the resources.

IHVDeleteRCResources Called from IHVDeleteRC to free the resources allocated by IHVCreateRC.

If an application does not call wglDeleteContext to delete its rendering context, then, when the application terminates, GDI will call IHVDeleteRCResources, passing it the unique identifier given to EngCreateDriverObj by IHVCreateRC.

It is important that IHVDeleteRC call EngDeleteDriverObj so that GDI will not attempt to free the resource again upon application termination.

EngCreateDriverObj

EngDeleteDriverObj

DRIVEROBJ

Page 42: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

EngCreateDriverObjHDRVOBJ EngCreateDriverObj(pvObj, pfnFreeObjProc, hdev)PVOID pvObj;FREEOBJPROC pfnFreeObjProc;HDEV hdev;

EngCreateDriverObj creates a DRIVEROBJ structure that is used to track a driver-managed resource that must be released when the current client process terminates.

pvObjPoints to the driver resource that will be tracked by the DRIVEROBJ. The resource is associated with the current client process.

pFreeObjProcPoints to a driver-supplied callback function that frees the resource pointed to by pvObj. The callback function should be defined as follows, where pDriverObj points to the DRIVEROBJ structure.BOOL CALLBACK DrvobjFreeObjProc(DRIVEROBJ *pDriverObj);

hdevThe GDI handle of the physical device associated with the object.

The return value is a handle that identifies the newly-created DRIVEROBJ structure if the function is successful. Otherwise, it is zero.

Unless the driver explicitly deletes the DRIVEROBJ by calling EngDeleteDriverObj, when the process that created the DRIVEROBJ terminates, the engine frees the resource by calling the function pointed to by the pFreeObjProc parameter.

Page 43: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 43

EngDeleteDriverObjBOOL EngDeleteDriverObj(hdo, bCallBack, bLocked)HDRVOBJ hdo;IN BOOL bCallBackIN BOOL bLocked

EngDeleteDriverObj deletes the GDI-managed object (frees the handle) used for tracking a driver-managed resource.

hdoIdentifies the engine-managed object that is to be deleted. This handle was obtained from EngCreateDriverObj.

bCallBackSpecifies whether or not the free callback should be called. If TRUE, GDI will invoke the free callback before removing the DRIVEROBJ from the handle manager. If the callback function returns failure, EngDeleteDriverObj will fail.

bLockedSpecifies whether the object was locked by the driver (through EngLockDriverObj) before EngDeleteDriverObj was called.

The return value is TRUE if the function is successful; it is FALSE if the handle has not been freed. If the driver-supplied free callback function returns FALSE, then EngDeleteDriverObj will fail and the handle won’t be freed. This could happen if the cleanup callback needed to lock another DRIVEROBJ, in order to free the current DRIVEROBJ, and failed because the other DRIVEROBJ was in use by another thread.

Once the object is deleted, the associated driver resource is no longer tracked by GDI and the function pointed to by the pFreeObjProc parameter of EngCreateDriverObj will not be called upon process termination. It is the responsibility of the driver to ensure that the resource is freed.

Most drivers should be consistent in how objects are cleaned up at termination time. Consequently, they will pass TRUE for bCallback indicating to GDI that it should call the driver’s cleanup function to free this driver resource. Passing FALSE prevents GDI from calling the driver’s cleanup function.

Page 44: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

DRIVEROBJtypedef struct _DRIVEROBJ {

PVOID pvObj;FREEOBJPROC pFreeProc;HDEV hdev;

} DRIVEROBJ;

The DRIVEROBJ structure is used to track a resource allocated by a driver that wants to use GDI services. A DRIVEROBJ allows a display driver to request the GDI service in managing per-process resources. By creating a DRIVEROBJ, a display driver can insure that resources will be released when an application terminates.

pvObjPoints to the driver resource that will be tracked by the DRIVEROBJ. The resource is associated with the current client process.

pFreeProcPoints to a driver-supplied callback function that frees the resource pointed to by pvObj.

hdevThe GDI handle of the physical device associated with the object.

Some drivers, in their Escape support, allocate resources on behalf of applications. In such cases, the DRIVEROBJ structure provides a means for the application to notify the driver when it terminates. GDI will call the driver’s cleanup function for each DRIVEROBJ that was allocated in an application’s context and not deleted before the application terminated.

This structure provides a locking mechanism for exclusive access to the associated resource.

Page 45: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 45

Window Object ServicesA WNDOBJ is a driver-level window object that contains information about the position, size, and the visible client region of a window. By creating a WNDOBJ corresponding to an application's window, the driver can track the changes in that window.

EngCreateWnd

WNDOBJ_bEnum

WNDOBJ_cEnumStart

WNDOBJ_vSetConsumer

WNDOBJ

Page 46: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

EngCreateWndWNDOBJ *EngCreateWnd(pso, hwnd, pfn, fl, iPixelFormat)SURFOBJ * pso;HWND hwnd;WNDOBJCHANGEPROC pfn;FLONG fl;int iPixelFormat;

EngCreateWnd creates a window object for a window referenced by hwnd. Since creating a window object involves locking special window resources, this function should be called only in the context of the WNDOBJ_SETUP escape in DrvEscape. It was previously possible to call this in DrvSetPixelFormat, because GDI was invoking DrvSetPixelFormat as part of a Win32 SetPixelFormat call and held the necessary locks. However, with the change in pixel format management, the display driver’s DrvSetPixelFormat will never be called by the system itself. So, it is up to the driver to ensure that EngCreateWnd is called only on a path reached by the WNDOBJ_SETUP escape.

This function supports window tracking by multiple drivers. Each driver is identified by a unique pfn function pointer. For example, a live video driver can track changes to live video windows while an OpenGL driver is tracking changes to OpenGL windows.

GDI will call the pfn function with the most recent window state if a new WNDOBJ is created in DrvEscape. GDI will also notify the pfn function when a window referenced by a WNDOBJ is destroyed.

psoIdentifies the display surface.

hwndA handle to an application created window obtained from CreateWindow or an equivalent function.

pfnPoints to a driver defined callback routine that GDI calls for changes to the window in question. In the context of this routine, the WNDOBJ states will stay unchanged. The callback function should be defined as follows:

VOID CALLBACK WndobjChangeProc(WNDOBJ *pwo, FLONG fl);

where:pwo points to the window object that is currently changing and contains the new size and position of the window (pwo is NULL if fl is WOC_CHANGED);fl can be one of the values listed in the following table.

Page 47: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 47

Flag Meaning

WOC_RGN_CLIENT_DELTA The window object contains a delta client region. The delta region is valid for this call only.

WOC_RGN_CLIENT The window object contains a new visible client region.

WOC_RGN_SURFACE_DELTA The window object contains a delta surface region. The pvConsumer field of the WNDOBJ contains 0. The delta region is valid for this call only.

WOC_RGN_SURFACE The window object refers to a surface region created by GDI. The pvConsumer field of the WNDOBJ contains 0.

WOC_CHANGED Indicates that all WNDOBJ callbacks have been made for the current desktop update. GDI always notifies the driver at the end of a desktop update. Note that pwo is NULL here.

WOC_DELETE The window object is deleted as a result of the deletion of the window.

flSpecifies the type of changes to track. The bits may be one or more of the following and it must be the same for all WNDOBJ requests by this driver.

Flag Meaning

WO_RGN_CLIENT_DELTA GDI notifies the driver when the window's visible client region changes. The region that is enumerated in the callback function is a non-empty delta area that is in the new region but not in the old region. For example, GDI updates the driver with a new delta region to the callback routine as follows:

WndobjChangeProc(pwo,WOC_RGN_CLIENT_DELTA)

The delta region is valid during the callback onlyWO_RGN_CLIENT GDI notifies the driver when the window's visible

client region changes. The region that is enumerated in the callback function is the new visible client area of the window.

WO_RGN_SURFACE_DELTA GDI notifies the driver when the surface region

Page 48: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

changes. The region that is enumerated in the callback function is a non empty delta area that is in the new surface region but not in the old surface region.The delta surface region is valid during the callback only.

WO_RGN_SURFACE GDI notifies the driver when the surface region changes. The surface region is the display surface area excluding all visible client region of the windows being tracked by the driver

WO_RGN_UPDATE_ALL GDI notifies the driver for all windows it tracks when any of its window's visible client region changes. This flag must be used in conjunction with the WO_RGN_CLIENT flag.

iPixelFormatSpecifies the pixel format associated with the window object. The pixel format of a window object is fixed. This may be zero if there is no associated pixel format.

If EngCreateWnd is successful, the return value is a pointer to a WNDOBJ. The return value is -1 if the same hwnd is already being tracked by this driver function; otherwise it is 0.

Page 49: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 49

WNDOBJ_bEnumBOOL WNDOBJ_bEnum(pwo, cj, pul)WNDOBJ *pwo;ULONG cj;ULONG *pul;

The WNDOBJ_bEnum callback function gets a batch of rectangles from the visible region of a window. The order of enumeration is determined by the call to WNDOBJ_cEnumStart.

pwoPoints to a WNDOBJ structure created by calling EngCreateWnd.

cjSize of the buffer in bytes. GDI will not write beyond this limit.

pulPointer to the buffer where the data is to be returned. The following structure is written, where c is a count of the rectangles returned and arcl[] is an array of rectangles.typedef struct _ENUMRECTS{

ULONG c;RECTL arcl[1];

} ENUMRECTS;

WNDOBJ_bEnum returns TRUE if there is more data to be enumerated and the driver should repeat the call. It returns FALSE if the enumeration is complete. No error code is logged.

The loop structure for calling this routine is as follows. The count of objects written to the buffer is put into the buffer itself.

do{

bMore = WNDOBJ_bEnum(pwo,sizeof(buffer),&buffer.c);for (i=0; i<buffer.c; i++){ /* Process the data */ }

} while (bMore);

WNDOBJ_bEnum should be called only in the context of the driver callback routine supplied to GDI in the EngCreateWnd function or the DDI functions where a WNDOBJ is given.

Page 50: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

WNDOBJ_cEnumStartULONG WNDOBJ_cEnumStart(pwo, iType, iDirection, cLimit)WNDOBJ * pwo;ULONG iType;ULONG iDirection;ULONG cLimit;

WNDOBJ_cEnumStart is a callback function that sets parameters for enumeration of the rectangles in the visible region of a window.

pwoPoints to a WNDOBJ structure created by calling EngCreateWnd.

iTypeDetermines the type of data structures to be returned by WNDOBJ_bEnum. This parameter must be set to CT_RECTANGLES, indicating that the region is to be enumerated as a list of rectangles.

iDirectionDetermines the order in which the rectangles are returned. This order can be essential when an overlapping DrvBitBlt is being performed to and from the same surface. If the order is not relevant to the device driver then CD_ANY should be specified. This allows GDI to optimize its enumeration for complex regions. iDirection must be one of the following values:

Value Meaning

CD_RIGHTDOWN Left to right, top to bottom.CD_LEFTDOWN Right to left, top to bottom.CD_RIGHTUP Left to right, bottom to top.CD_LEFTUP Right to left, bottom to top.CD_LEFTWARDS Left to right, vertical direction is not defined.CD_UPWARDS Bottom to top, horizontal direction is not defined.CD_ANY Any order convenient for GDI.

cLimitAn indication of how many objects the driver is interested in caching. This is only used to decide when to stop counting rectangles when GDI is computing the return value for this function. (If the region is complex, it can take a long time to compute just how complex it is.) If cLimit is zero, no counting is done.

WNDOBJ_cEnumStart returns a count of how many objects would be enumerated, if this number does not exceed cLimit. If the count exceeds cLimit then 0xFFFFFFFF is returned. No error code is logged.

Page 51: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 51

WNDOBJ_cEnumStart should be called only in the context of the driver callback routine supplied to GDI in the EngCreateWnd function, or the DDI functions where a WNDOBJ is given.

Enumeration can be restarted by calling this routine again.

Page 52: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

WNDOBJ_vSetConsumerVOID WNDOBJ_vSetConsumer(pwo, pvConsumer)WNDOBJ * pwo;PVOID pvConsumer;

The WNDOBJ_vSetConsumer callback function sets a driver defined value in the pvConsumer field in the given WNDOBJ.

pwoPoints to a WNDOBJ structure created by calling EngCreateWnd.

pvConsumerA driver-defined value for identifying this particular WNDOBJ. It overrides the previous value stored in the WNDOBJ.

WNDOBJ_vSetConsumer should be called only in the context of the driver callback routine supplied to GDI in the EngCreateWnd function or the DDI functions where a WNDOBJ is given. It can also be called in the context of DrvSetPixelFormat function or the WNDOBJ_SETUP escape in DrvEscape function after a new WNDOBJ is created.

Page 53: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 53

WNDOBJtypedef struct _WINDOBJ {

CLIPOBJ coClient;PVOID pvConsumer;RECTL rclClient;

} WNDOBJ;

The WNDOBJ structure allows the driver to keep track of the position, size, and visible client region changes of a window. The visible client region may be enumerated by calling the WNDOBJ_cEnumStart and WNDOBJ_bEnum functions.

coClientA CLIPOBJ that describes the region of the window. If member iDComplexity is DC_RECT and the left edge in rclBounds is greater than or equal to the right edge, or the top edge is greater than or equal to the bottom edge, the client region is invisible.

pvConsumerA driver-defined value for identifying this particular WNDOBJ. This value can be set by calling the WNDOBJ_vSetConsumer function.

rclClientA lower-right exclusive rectangle of the client area of the window in screen coordinates.

A driver may associate its own data with a WNDOBJ by calling the WNDOBJ_vSetConsumer function.

As an accelerator, the driver may access public fields of the WNDOBJ. These public fields are guaranteed to remain unchanged only in the context of the driver callback routine supplied to GDI in the EngCreateWnd function or the DDI functions where a WNDOBJ is given.

Page 54: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Client Driver Setup and InstallationThe OpenGL DLL uses the Registry to determine the appropriate client driver to load. The OpenGL DLL performs the following operations in locating and loading the ICD:

Calls the OPENGL_GETINFO_DRVNAME sub-escape of the OPENGL_GETINFO extension to determine the name of the display driver.

Uses the display driver name to search the registry for the name of the client driver.

Loads the client driver. Hooks the DrvXxx client driver functions described in the “Client Driver

Interface” section, earlier in this document. Validates the driver version by checking the version numbers returned by the

OPENGL_GETINFO_DRVNAME sub-escape. This is done by checking that ulVersion is 2 and calling DrvValidateDriver with ulDriverVersion.

RegistryThe display driver name is searched for in the registry at the key:

HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsCurrentVersion\OpenGLDrivers

on Windows 95 and Windows 98, and at the key:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers

on Windows NT.

These keys contain lists of value-data pairs. Each value represents a display driver, and the associated data identifies the corresponding OpenGL client driver name.

For example, if myopengl.dll is the OpenGL ICD for the display driver mydisp.dll, the OpenGLDrivers key would have the following value-data pair:

mydisp: REG_SZ: myopengl

Only one client driver is allowed for each unique display driver name.

Windows NT 5.0 also supports an alternative registry format. If the display driver name exists as a key (instead of a string value), then the following values are searched for at that key:

DLL, Flags, Version, DriverVersion

DLL is a string value, which is the OpenGL client driver name. Version and DriverVersion are DWORD values which must match the version numbers

Page 55: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 55

returned by OPENGL_GETINFO_DRVNAME. Flags is a DWORD value representing a bitmask. Currently only bit zero is used: all other bits are reserved and must not be set. If bit zero is set then the OpenGL DLL will use the client driver entry points for DrvDescribePixelFormat, DrvSetPixelFormat, and DrvSwapBuffers. If this bit is clear then the corresponding video display driver entry points will be used instead.

SetupTwo new sections in the .INF file are supported by the Display applet of the Control Panel:

[OpenGLDrivers] [Files-DisplayOpenGLDrivers]The data in the [OpenGLDrivers] section associate a display driver with its client driver. The data in the [Files-DisplayOpenGLDrivers] section determine what files are copied for client driver. Using the same example as above, the following can be added to video.inf to allow the Display Applet to install the display and client drivers (that this is in addition to the normal information that must be in the .INF file to install a display driver):

[OpenGLDrivers]mydisp = myopengl[Files-DisplayOpenGLDrivers]myopengl = 2,myopengl.dll , SIZE=999

This information will allow the Display Applet to copy the client driver along with the display driver as well as update the Registry.

Page 56: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Sample Installable Client DriverPrevious releases of the OpenGL Installeable Client Driver kit only provided a software implementation of the OpenGL pipeline. This release also contains sample code for two drivers to provide a portable example of how the various interfaces may be used to build an ICD. The first of these drivers is a “null driver”, i.e., a driver which performs no rendering; building and benchmarking this driver is helpful when tuning a real driver. The second of these is a real sample driver for the S3 Virge chip.

The sample ICD does almost all of its work in the client driver. The video display driver components are used only track the information needed to pass rendering commands directly to the display device.

The architecture of a video display driver linked with the OpenGL support libraries is shown below:

The modules shown enclosed within the dotted line are supplied with the sample client driver.

Page 57: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 57

Directory StructureThe sample installable driver is contained in the following directories:

Directory Contents

lib The client portion of OpenGL that contains most of the functionality of OpenGL. It builds into ogldrv.dll.

kern The kernel (video display driver) of OpenGL that interfaces with the hardware. This directory contains both Windows 9x and Windows NT sample code. All driver sample code is based on a S3 Virge graphics card.

defs Various files containing definitions used by build during the build process.

docs Documentation.tools Various tools used during the build process to create automatically

generated files.

The lib (client side) directory requires special attention, since it is the more complex and it is also the place where most of the work is being done:

Directory Contents

glcore All the software rendering fallback code, including the main rasterizer.

raster A faster span-based rasterizer, and a rasterizer based on code generated at runtime (online-generated code).

include Include files that are used by the software rendering code.wgl Implementation of the interface code with wgl and opengl32.dll.lib Where the resulting library is being deposited after it’s being built.generate Scripts that are used to generate compile time generated (not online-

generated) code. Mostly used to create the OpenGL API entry points.

drivers Where the driver-specific code lives. OpenGL can be built ignoring driver-specific code, but it will use only software. The S3 Virge and null driver live here. Also a texture manager implementation based on DirectDraw lives here.

Page 58: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Building a Display Driver with OpenGL SupportWindows 9xWe have provided some sample code to be compiled with your display driver in the kern/win9x directory.

This sample code provides the necessary functionality so that opengl32.dll will realize that an ICD is present.

This is done by hooking the DIB_Control function in the graphics driver. Your driver should be changed so that instead of dispatching to GDI’s DIB_Control function, it dispatches to OGLDIB_Control, as implemented in ogl.asm. OGLDIB_Control will filter out the necessary requests and forward unrecognized escapes to GDI’s DIB_Control.

The .asm files provided also implement some driver-side code that maps and unmaps hardware registers to userspace for use by the OpenGL client ICD. This functionality is exposed to the ICD via escape calls that are filtered using the above method.

Windows NTThe sample S3 Virge driver that is provided includes all the necessary code to make the client ICD render using the S3 Virge hardware.

The changes required to your driver can be broken down into 2 parts:

1. Hooking appropriate escape, startup and shutdown functionality. The places where these hooks are needed are already #ifdef’ed in the code with SUPPORT_OPENGL defines.

2. Actual OpenGL driver code implementation. This exists in the ogl* files.

The various steps in incorporating OpenGL in your driver are outlined below:

1. Add USE_LIBCNTPR=1 to your sources files.

2. Link with libcntpr.lib.

3. If your driver does not support DrvEscape, add the following entry to your driver function dispatch table:

INDEX_DrvEscape DrvEscape

4. Add the following entries to your driver function dispatch table:

INDEX_DrvDescribePixelFormat DrvDescribePixelFormat

Page 59: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 59

INDEX_DrvSetPixelFormat DrvSetPixelFormatINDEX_DrvSwapBuffers DrvSwapBuffers

5. In your driver’s implementation of DrvEscape, if the given escape is not supported, your driver should pass it on to DrvOGLEscape so that the sample OpenGL driver can handle it. Sample code is provided in escape.c.

6. Provide a global string called pwszDriverName which contains the name of your video display driver; for example, LPWSTR pwszDriverName = L"S3V". The string must be identical to the display driver name specified in the OpenGL Drivers location in the registry.

7. Provide a table of pixel format descriptors or modify the pixel format descriptor arrays in oglpxlfmt.c.

8. In your DrvEnableSurface and DrvDisableSurface functions (in enable.c), call appropriate OpenGL functions that initialize and terminate OpenGL related functionality. Sample code is given.

ICD Library OrganizationInteracting ObjectsThe OpenGL library is internally organized in several coarse "objects" that interact with each other. This abstraction and separation of functionality helps to identify clear patterns of interactions that specify states in which OpenGL operates.

Some of these objects deal with the window system and the OS interaction, while others deal with the OpenGL machinery itself.

These objects are:

Context: The context is the encapsulation of the OpenGL state. All OpenGL rendering modes and state (both external and internal) is kept in the context. Rendering is always performed with respect to a context (i.e. some context's state has to be used in order to render).

Buffer: A buffer is an area on the screen or memory (of a certain size) that is rendered to by the context. Buffers do not necessarily have to store color information. (For example, depth buffers store depth information.)

Drawable: A drawable is an abstraction of the rendering surface, being a window or a bitmap. A drawable is composed of a collection of buffers (including a front buffer, which may or may not map directly to a visible portion of the screen), together with some additional information needed to keep all the buffers consistent.

Page 60: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

The context and the associated rendering code is a component of OpenGL which is purely window-system and OS independent. From here on, OpenGL functionality that is independent of the operating system will be called the GL core. Windows operating system-dependent functionality is part of the WGL section of the library. WGL also contains some Windows operating system-specific code that completes the system interaction.

Both the buffers and the drawables have a system-dependent and system-independent part. This separation is done in order to simplify the interaction between the GL rendering core and the rest of the system. The WGL part of the buffers and drawables code deals with buffer allocation/deallocation and window move/destroy and locking. The GL core part of the buffers and drawables code deals purely with rendering to the buffers.

The WGL context is a WGL data structure that encapsulates the GL context, and also contains some other WGL-related information to keep track of the context and its connections.

NomenclatureThe data structures involved with each of the above components are shown below:

WGL context: __WGLcontext OpenGL context: __GLcontext WGL-side drawable: __WGLdrawablePrivate GL-side drawable: __GLdrawablePrivate WGL-side buffer: __GLdrawableBuffer GL-side buffer: __GLbuffer and derivatives (__GL*buffer)

Additional information about these structures can be found in the files: opengl/lib/include/GL/glcore.h and opengl/lib/wgl/wglhrc.h.

Where to add your codeThe OpenGL DDK has been organized in such a way that the code that the IHV writes is separate from the rest of the generic implementation. The IHV will create a directory under lib/drivers and add all device-dependent code there.

Hooks are provided (using the __glDevice data structure, described below) that will enable device-specific code to be executed at process/thread creation and destruction time, and also at context creation time. This allows the driver to flexibly replace and override any relevant part of the generic code with device-specific routines. Providing such a hook at context creation time is enough,

Page 61: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 61

because of the context-centric view of the 3D rendering pipeline that OpenGL utilizes.

During context creation, device-specific code is free to initialize the context and provide specialized functionality for operations that are going to be handled differently from the generic software implementation. This is done by the use of function pointers that allow the IHV to modularly replace or override virtually every aspect of the generic software implementation with device-specific code.

Extension of the context itself (addition of new data members in the context for use by device-specific code) is done by a subclassing mechanism. This allows the generic software code to operate only on the generic part of the context, while the device-specific code has access to the whole context structure, including data which is invisible to the generic code.

The sample S3 Virge driver provides a good starting point, showing which functions can be overridden and how. One of the most important aspects of device-specific specialization is the state validation phase, which is described below.

State validation and function pickingAs discussed above, the rendering state is maintained in the context. There are two types of state within the context:

Non-derived state is any rendering state information that is set, and/or inquired, directly by the OpenGL API.

Derived state is any rendering state information computed from non-derived state during a validation phase.

Most of the derived state is composed of function pointers to functions that have been picked or selected, based on the non-derived state, for execution in different sections of the pipeline. The act of state validation is also called picking.

There are different strategies that may be employed for picking derived state. In the OpenGL DDK we adopt the strategy of late validation. When state is changed by an API call that affects the non-derived state, validation does not occur right away, but is deferred. This optimizes the state validation process for the common application scenario in which the application performs multiple successive state changes, since only one validation has to be performed for all the state changes that have been accumulated.

The state validation operation has been implemented in the OpenGL DDK so that all derived state selection decisions can be overridden by the device-specific code. In turn, the device-specific code can always fall back to generic (software) validation if it needs to by calling the appropriate generic validation function. Using this approach, a driver can separate the states it can implement in

Page 62: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

hardware, and fall back to the generic software implementation for all other states.

Validation occurs in two phases:

1. During phase 1, non-derived state is compiled to a form where function picking is simplified (via the creation of the modeFlags mask), and paths that are implemented in device-specific code are recognized as such.

2. During phase 2, if needed, the actual function pointers are picked using the information compiled in phase 1 and other non-derived state.

The different picking or validation functions that can be overridden are initialized at context creation time; the sample code in the DDK provides specific details. Most of the generic validation code may be found in lib/glcore/s_pick.c. Sample device-specific validation code may be found in lib/drivers/s3v/s3vpick.c. The relevant data structures are included in the appropriate include files (lib/include/context.h and lib/include/procs.h.)

Miscellaneous concernsMalloc debuggerThe DDK also contains some debugging code useful for finding memory leaks. It is implemented by wrapping malloc/free/realloc type functionality with some code that keeps track of every memory allocation and deallocation. Frees without a corresponding malloc produce a warning, and after process exit all unfreed memory blocks and sizes are also printed out.

When debugging the OpenGL implementation, you can look at the memory leaks produced at process termination, and place a conditional breakpoint at the malloc routine specifying the address and size for the leak you want to track down. When the debugger breaks there, you can find what code path was allocating the unfreed memory.

The code is in opengl\lib\wgl\wglcomm.c. It can be enabled by editing the file opengl\defs\localdefs and adding this definition:

GL_DEFINES=$(GL_DEFINES) -D__GL_MALLOC_DEBUG=1

Additional details are provided in comments in opengl\defs\opengldefs and opengl\defs\localdefs.

Device initializationDevice-specific context initialization is performed using the __glDevice data structure. Each driver implementation contains a single static __glDevice structure that contains device-specific functions and constants. The purpose of the __glDevice structure is to capture all such device-dependent information in one place.

Page 63: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 63

The description of __glDevice can be found in lib/include/GL/gldevice.h. Instantiations of these structures can be found in the driver directories; one for each device: lib/device/sw/swdevice.c, lib/device/s3v/s3vdevice.c and lib/device/null/nulldevice.c.

Information contained in __glDevice includes functions called at process/thread startup and shutdown, texture manager initialization, context and drawable creation; pixel format information and various device-specific constants.

InteractionsWe will separate interactions between the components defined above into two categories: normal operating condition interactions, and interactions caused by exceptional conditions.

Normal InteractionsDuring normal operation, certain well-defined connections occur between the different objects, as defined in the OpenGL specification.

A rendering context must be bound to a drawable in order for rendering to occur. A context can only be bound to one drawable at a time. This also applies to multi-threaded operation: if a context is bound to a drawable in one thread, it cannot be bound to another drawable in another thread at the same time. Also, there may only be one context bound to any given thread at one time. This model simplifies the control flow within the scope of a context. It means that there can only be one thread of execution within the scope of a context, hence a context is inherently single-threaded.

This principle does not apply with drawables, however. A drawable may have multiple contexts bound to it at the same time. Note that this implies multi-threaded operation of the drawables, since only one context can be bound at any given time in a single thread.

Unlike contexts, therefore, drawables are inherently multi-threaded objects. This means that synchronization mechanisms have to be implemented around drawable data structures in order to guarantee correct operation in a multi-threaded environment.

Buffers, being part of the drawables, also have to be multi-threaded, and must follow the same constraints.

As mentioned above, both buffers and drawables are split entities: They contain both a system-dependent and system-independent part. The system-independent part is part of the OpenGL context and therefore is single-threaded. The system-dependent part is part of WGL and therefore is multi-threaded.

Page 64: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

The WGL part of the buffer (since it is responsible for allocation and deallocation) contains the actual memory pointer (if it exists), an allocation handle (if it exists), size, position, stride (i.e., the increment from one scanline to the next) and other size-related information. All buffers are treated the same from WGL. That is, there is no distinction between a color buffer and a depth buffer, for example. WGL is only responsible for buffer allocation, not for interpreting the contents of the buffer itself.

The GL part of a buffer, however, provides a distinction as to what type a buffer is. This is done using a subclassing mechanism. The "parent" class (__GLbuffer) contains information that is common to each buffer type. The "subclasses" (for example, __GLcolorBuffer, __GLdepthBuffer, etc.) offer specialization and additional data elements specific to each buffer type. The additional methods and data, specific for each buffer, are only responsible for managing context-side information that is needed for that particular type of buffer. For example, a color buffer may contain color scale factors that are used to convert normalized color components into device-specific color ranges.

During normal operation, a given context is bound to a drawable. This connection is established at MakeCurrent time. When a context is not bound to a drawable, the GL-side portion of the drawable (and the buffers) are in a non-initialized state; they do not correspond to a WGL-side drawable (and buffers). During MakeCurrent the association is made complete and the drawable (and the buffers) are associated with their corresponding WGL equivalents. If this is a first time the drawable is referenced, the WGL-side drawable structure is created.

Since the WGL-side drawable (and buffer) information has to be multi-thread safe, whenever the GL core code accesses WGL information, it has to do that in a multi-thread-safe manner and therefore uses locks for synchronization.

There are 2 types of locks that are used within WGL:

1. The global wgl lock. This is used to serialize operation within the wgl commands themselves. For example, all MakeCurrent commands are serialized, so that only one MakeCurrent can occur at a time.

2. The drawable lock. There is one drawable lock per drawable. This lock is used to serialize data accesses to the data elements within the drawable itself. It is being used by both WGL and the GL core while accessing drawable data.

In order to avoid deadlocks, the assumption is made that the wgl lock is always taken before (i.e. it brackets) the drawable lock.

Since only WGL can call the wgl lock, this has the following repercussions:

1. WGL must take the wgl lock before considering taking the drawable lock.

Page 65: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 65

2. WGL routines that do not take the wgl lock but take the drawable lock must not call routines that take the wgl lock.

3. All the WGL functions imported to the GL core must:

(a) not take the wgl lock, or

(b) if they take the wgl lock and are exported to the GL core, they should not be called by a GL core function that takes a drawable lock.

All the GL core logic that deals with locking/unlocking buffers and other miscellaneous buffer-related logic (that will be described in the following section) can be found in glcore/s_buffer.c.

Exceptional ConditionsThere are several conditions that are related to the interaction between the drawables (buffers) and the contexts that are considered exceptional. Under normal operating conditions, the GL core is always responsible for the control flow: OpenGL commands are executed and that results in the execution of certain code paths within the GL core. When buffer-related information is needed, the core inquires the WGL portion of the library for information, then contines with its normal flow of operation.

WGL, though, also interacts with the window system. The window system operates using an event loop model. The event loop notification reaches WGL through the __wglMonitorWindowChanges function in wgl/wglcomm.c.

Exceptional conditions occur when WGL gets an event that requires notifying the GL core. Because of the GL-based flow of control of the core, there is no direct way for WGL to notify the core that an event occurred.

Another complication stemming from window system events is the fact that there can be multiple contexts bound to a single drawable. The window system will generate an event in the thread that created (and therefore owns) the window. The OpenGL context that is currently bound to that thread, though, may or may not be bound to the drawable that got the event. It would be wrong, therefore, to simply assume that the context that is current to the thread that got a window event is also bound to the drawable that got that event.

Additionally, even if we assume that we cannot use the context bound to the current thread as the one that needs to be notified, there are complications. There is nothing to guarantee that contexts bound to the drawable that just received an exceptional condition are not current to other threads. Since contexts themselves are single-threaded, we won’t be able to access those contexts in a safe manner from the thread that received the event.

Because of this, WGL should not call any GL core export functions that resize the context's side of the buffers in the window system event loop. This is true

Page 66: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

even when the context is question is bound to the window that received the event, because hat context may already be bound to another thread. Calling a GL core function on a context from a second thread will violate the assumption that contexts are single-threaded.

We solve these problems by providing "check-pointing" from the point of view of the GL core. At certain points in execution, the core will inquire to see if an event occurred in WGL. These checkpoints are only needed when the core needs to inquire drawable information from WGL, and are therefore done at drawable lock time.

The exceptional conditions are listed below:

Resize

__wglMonitorWindowChanges first receives a resize event and proceeds by doing the following 2 things:

1. Resizes the WGL-side buffers that correspond to the drawable that got the resize.

2. Sets a flag in every context that is bound in that drawable, signifying that a context-side resize needs to be performed.

When the context's time comes to get some drawable-related info, it locks the drawable (by indirectly calling __wglGLLockDrawableMutex in wgl/wgllock.c). This will call the context’s NotifyChangeBufferSize export proc which in turn updates the context's side of the buffers.

Destroy

As operation similar to resize occurs:

1. The drawablePrivate structure is destroyed.

2. A flag is set in each context signifying that the drawable has been destroyed.

The next time the drawable lock occurs, NotifyDestroyBuffers gets called. The implementation actually leverages the resize mechanism. NotifyDestroyBuffers is the same as NotifyChangeBufferSize. It updates the context's side size with the WGL side of the buffers. This works because when the WGL drawable is in this destroyed state, its size is position are set to zero. This basically causes all the context's rendering output to be nil, simulating a destroyed window, till the calling thread unbinds the context from the (now defunct) window.

SwapBuffers

The situation with SwapBuffers is slightly different. In this case, either WGL or the kernel display driver may be responsible for performing the actual buffer

Page 67: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 67

swapping. Swapping the buffers is really an operation on the drawable itself, not the contexts that are bound to it.

There may be some times, when the context may need to update some internal state signifying a buffer change. This need may be completely hardware dependent; some hardware implementations may need that, and some others may not.

For the case that some functionality like that is needed, a similar mechanism as the one above (for resize or destroy) is employed.

So, for each context that is bound to the drawable whose buffers got swapped, a flag that is set that is subsequently inquired during drawable lock time, so that the context can update its internal state.

Note that since this per-context SwapBuffers is executed asynchronously with the actual SwapBuffers call, this mechanism is not to be used as a means to perform the actual buffer swapping. Another reason why it should not be used for buffer swapping is because there may be multiple contexts bound to a drawable. In this case, performing the buffer swap on the context will mean that it will be executed multiple times, once per each context, as opposed to only once, for the drawable that all contexts are bound to.

Hardware AccelerationThis section describes how hardware acceleration is achieved in the driver kit sample implementation. This includes a description of how the hardware is accessed under both the Windows 95/98 and Windows NT operating systems, and how to mix hardware accelerated rendering with software fallback rendering.

The way that hardware is accessed by the ICD is different between Windows 95/98 and Windows NT. The two operating systems have different requirements for robustly accessing hardware from user-mode code. Different kinds of hardware have different preferred mechanisms (register sets, DMA, etc.) and we don’t provide comprehensive coverage of all these mechanisms in this document and driver kit. We recommend that IHV’s also consult other display driver documentation, available through the Windows DDK, for more general coverage of hardware access issues like DMA.

We have taken the approach of performing as much rendering as possible from user-mode code, and pushed minimal functionality into kernel-mode code. What functionality exists in the kernel (or graphics driver) varies depending on the OS platform; the differences are described below.

There are two ways that rendering can occur in the OpenGL ICD kit.

1. Using hardware. The driver sends commands to the hardware that renders to video memory.

Page 68: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

2. Using software. The driver directly accesses video memory to write pixels.

Software rendering is used as a fallback mechanism. The driver will check to see if a specific state combination is accelerated by the hardware, and if so, it will choose the hardware path. For states that are not accelerated by the hardware, a software path will be taken.

Windows 9x

Windows 9x allows a user process to map hardware addresses (and therefore registers) directly into user space. This one-time initialization is done by the graphics driver via ExtEscape calls from the OpenGL client library.

Since multiple OpenGL graphics contexts may be using the same hardware to render, some resource management of the graphics hardware has to occur. The OS does not provide any framework for synchronizing the GUI drawing (GDI) for other agents, such as the ICD or a DirectDraw or Direct3D driver, that want to access the hardware.

In this documentation and kit we provide mechanisms for synchronizing OpenGL and GDI rendering. Similar mechanisms for DirectDraw and Direct3D drivers and GDI are discussed in the DirectX DDK materials. This leaves the issue of synchronization between OpenGL and DirectDraw and Direct3D rendering. Because this kit uses DirectDraw for drawable surface management and allocation, we have built in some synchronization between OpenGL and DirectDraw (see the section on DirectDraw below for more details), but we do not provide any mechanisms for synchronization between OpenGL and Direct3D. IHV’s who want to provide good resource management for both Direct3D drivers and ICD’s can extend the techniques covered here and in the DirectX DDK materials.

In this sample code we use the Win16 (GDI) lock in order to block out rendering from GDI while the ICD is accessing the graphics hardware. We explain below how the Win16 lock is obtained.

In detail, when the ICD needs to access the hardware it performs the following series of operations:

1. Obtain the win16 lock.

2. Initialize the hardware with the necessary state.

3. Render what is needed.

4. Re-initialize the hardware for GDI rendering.

5. Release the win16 lock.

It is certainly not optimal to perform all of the above operations every time OpenGL wants to render something. The sample code supports two forms of

Page 69: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 69

primitive “batching” to amortize the cost of taking this lock: vertex arrays and vertex caching. Primitives rendered using the vertex array commands (DrawArrays, DrawElements) are processed within a single Win16 lock/unlock cycle. In addition, primitives rendered using the Begin/Vertex/End style commands will be batched up in a vertex cache, and that batch will be processed within a single Win16 lock/unlock cycle.

The ICD kit also provides prototype code for an alternative, potentially less robust mechanism that IHV’s can use in their display driver. This functionality is named sLocks. This mechanism is in the conceptual stage and has not been fully tested, and is not included by default in the driver sample code. Instead, we have provided prototype code in order to encourage IHV’s to experiment with the idea and provide us feedback, particularly about potential timing problems in this approach.

Using slocks, the graphics driver provides the user-mode part of the ICD with an area in memory to be treated as a "lock". The lock contains a lock flag indicating if the lock is taken or not, and a thread-id identifier indicating the thread that last took the lock.

The slock will act as a replacement to steps 1 and 2 while entering the lock and steps 4 and 5 while exiting.

The operation can be summarized as:

1. Obtain the slock (possibly waiting till it is released).

2. Is the lock thread-id the same as our current thread-id?

3. If yes, no other thread touched the hardware between the last time we accessed the hardware. No need to re-initialize the hardware. Continue to step 7.

4. If no, someone else (either another OpenGL thread or a system thread) used the hardware, so we need to perform full initialization. Continue with step 5.

5. Obtain the win16 lock

6. Initialize the hardware.

7. Render.

8. Re-initialize the hardware for GDI rendering.

9. If the win16 was taken, release it.

Other display driver components for GDI, DirectDraw and Direct3D must also be altered in a similar way when they access the hardware. Some care must be taken that when the display driver access the hardware, it initializes the thread-id

Page 70: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

field with a value that could not be valid for an OpenGL rendering thread. In that case, the OpenGL driver would fall back to using the full Win16 lock.

Page 71: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 71

Windows NT

Windows NT does not allow a user process to map hardware registers directly to user space. We take the approach of creating DMA packets in user space and dispatching them to the kernel graphics driver, which is then responsible for sending them to the hardware.

Windows NT graphics drivers, however, are not given full access to all kernel calls that allow direct address control. Allocating/deallocating/mapping/ unmapping hardware memory has to be done by calls from the graphics miniport driver.

Ideally, we would want the minimal number of copies of the DMA buffers from the time they are filled in to the time they are consumed by the hardware. This can be done if the call to the miniport to allocate a DMA buffer returns a buffer that is non-paged and accessible by user space. The userspace OpenGL driver, then, can fill the DMA buffer (resident in non-paged memory), and pass a pointer to it using the ExtEscape call to the graphics driver that can initiate a DMA.

The current implementation of DMA for the S3 Virge, however, is slightly different. For simplicity, we have not provided an altered miniport driver. The user space part builds a DMA packet in paged memory allocated from user space. The whole packet (not a pointer) is passed in, and consumed via the graphics driver by emulating the DMA using PIO. This provides a proof-of-concept implementation.

Since the ExtEscape calls to the driver provide an implicit serialization (i.e. only one thread of execution is within a graphics ExtEscape call at a time), we do not need to lock the surfaces when accessing the screen via DMA packets.

We only lock surfaces when OpenGL needs to use a slow, non-accelerated path that does not access hardware registers, but renders to the surfaces directly.

Special attention is required when handling window clip regions. Some hardware is capable of handling non-trivial clip regions (i.e., regions containing more than one clip rectangle, as are found, for example, with partially occluded windows). Other hardware is not capable of hanlding these regions; in particular, the S3 Virge used for our sample code only supports hardware clipping to single-rectangle clip regions. We have implemented the following solution in our sample S3 Virge driver:

The user-mode part of the ICD builds DMA packets while respecting window viewport and scissor extents; this clipping is performed in software. If the window has a non-trivial clip rectangle list, the display driver then dispatches the DMA packet multiple times, once for each window clip rectangle. In this sample implementation, each DMA packet is atomic: Enough state exists in the packet to render itself; there is no state dependency from one packet to the next. This

Page 72: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

allows a packet to be rendered multiple times without any consequences in accumulated state.

Hardware that does not have any limitations with arbitrarily complex window clip regions will probably render each DMA packet only once.

The role of DirectDrawIn the current implementation of the DDK, we are using DirectDraw as the drawable surface manager and allocator. This is done for both front buffers (buffers that map directly to an area on the screen) and some ancillary buffers (back, depth, stencil). We used DirectDraw because it provides user-space management of video memory.

IHV’s may or may not want to use DirectDraw as their surface management implementation. If they do not, then their must provide their own way of performing surface management, most probably in their graphics driver, accessed from userspace via ExtEscape calls.

Using DirectDraw presents a particular challenge. The DirectDraw interface specifies that the user must lock the surface before accessing it. It also requests that the user must keep the lock for as short a periods of time as possible. 3D graphics API’s, however, tend to require access to a surface for relatively longer periods of time, and immediate mode interfaces like OpenGL, in particular, return control to the application for indefinite intervals between API calls. If the surface lock is not maintained between API calls there is a significant performance impact to taking the lock on a per-call basis; if it is maintained, it violates the DirectDraw requirement.

The implementation of DirectDraw locks varies slightly between Windows 95/98 and Windows NT.

Windows9x

The DirectDraw implementation in Windows 9x uses the win16 (GDI) lock for locking. When a DirectDraw primary surface is locked, the Win16 lock is taken, which freezes the whole UI till the lock is released.

The DirectDraw lock is taken for both software and hardware rendering.

Windows NT

The DirectDraw implementation in Windows NT does not provide a guarantee for an exclusive lock. This means that multiple surfaces can be locked at the same time. Additionally, multiple processes can lock the same surface, possibly the primary surface, at the same time without conflict. This prohibits our using DirectDraw as a locking mechanism for accessing the hardware.

Page 73: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 73

The DirectDraw lock is taken for software rendering, but it is not used for hardware rendering, since hardware rendering is implemented using DMA packet dispatching.

An additional concern when using DirectDraw is memory overcommitment. There can be cases where video memory is depleted and no more buffers can be created in video memory. This can easily happen when resizing a window with many ancillary buffers (for example, back, depth and stencil buffers) to a larger size.

The DDK provides functionality for a secondary buffer initialization method that is used when the primary method (in this case, DirectDraw) fails. Secondary buffer initialization can occur during a buffer resize. When this happens, the buffer is initialized using the secondary method, and then a function picking operation is requested. This allows the function pointers to be re-initialized to a possibly different model of operation, caused by the different buffer implementation type.

It is common that the primary buffer allocation method is done in video memory, where the hardware can render directly to the buffer. The secondary allocation method would then be in system (paged) memory, where the hardware cannot render directly to the buffer. The function picking is required to initialize the state machine for software rendering, used in the second case.

For every resize operation thereafter, the primary buffer initialization is always tried before secondary buffer initialization, to make sure that we will switch back to hardware rendering as soon as video memory is available.

The drawable contains a list of buffers that it currently implements in hardware, based on primary/secondary buffer allocation. Additionally, the context contains a list of buffers that it needs, based on the current rendering mode. During the picking operation, these two buffer lists are correlated and if there is a resource mismatch (a buffer is needed that does not support hardware rendering), the software path is taken.

Texture ManagementTextures are another resource that may need memory allocation out of video memory. Since textures are not drawable surfaces, they are treated in a separate manner inside OpenGL.

There are also some other texture-related issues that an IHV should resolve. These issues include the mapping of the requested internal format (by the glTexImage*D functions) to an actual hardware format, and data formatting.

Page 74: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

Surface ManagementA texture manager is used to perform allocation, deallocation and memory management for textures.

Conceptually, a texture manager exists in 2 levels: a global texture manager and a local texture manager. The global texture manager runs system-wide and deals with global memory management issues. The local texture manager is thread-based and deals with only one thread of execution. Since only one context can be bound to a thread at a time, the local texture manager is also context-based.

In the current ICD kit, we have provided 2 example (local) texture managers, leaving the global texture managers to be implicit, implemented as system resources:

(a) A system memory based local manager that uses the system's heap allocator implementation and virtual memory as a global texture manager. This is only appropriate for use with devices that do not support texture mapping in hardware.

(b) A DirectDraw-based local texture manager also exists. DirectDraw itself is treated as a global texture manager.

The GL core interfaces only with the local texture manager. It's the local texture manager's responsibility to interface with the global texture manager. That's why the separation between local and global texture managers is at the conceptual level; the core only knows one texture manager. The IHV, however, needs to be aware of the distinction, particularly if the ICD is part of a display driver that also implements DirectDraw and Direct3D and needs to manage texture memory between multiple API’s and clients.

At any given time, there may be multiple copies of a texture:

One texture is the application copy. When the application calls glTexImage*D, the texture that get passed in is the application copy.

There is also the OpenGL internal copy. This one is resident in system memory and it is the one that is created during the call to glTexImage*D. The ICD cannot use the application copy, since the application may reuse or deallocate that memory after making the call. In addition, the driver may need to perform texture conversion to an internal storage format.

Finally, there is the resident copy. This is the one that resides in video memory. However, because of limited video memory, this copy can only be treated as transient. It is a "cached" copy of the internal copy of the texture, possibly using a different format than the internal copy.

Page 75: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 75

The resident copy of the texture is volatile and can be removed from video memory if memory constraints dictate so. So, the "golden" copy of the texture is the internal copy.

Software rendering is performed using the internal copy of the texture. Hardware rendering is performed using the resident copy of the texture.

For systems with AGP, where the hardware may be able to use system memory directly as texture memory, there may not be a need for a resident copy. Care should be taken, though, so that the internal copy is resident in physical memory before rendering from it using hardware.

When the core wishes to start using a texture it will try to MakeResident that texture (look at the __GLtexture description in include/texture.h for details). MakeResident causes the texture manager to create a resident copy of the texture. In the case of the DirectDraw-based texture manager, if a texture surface cannot be created, other resident textures will be made non-resident, until enough memory exists for the texture in question to become resident. Textures are made non-resident using a priority queue, resolving to a LIFO queue when all priorities are the same.

Since the local texture manager is context(thread)-based, there is no concern that another thread will (asynchronously) remove from the resident list a texture still needed by the current thread.

There are times where the GL core needs to voluntarily remove a texture from the resident list. This functionality is also provided.

Texture format mappingOpenGL allows the application to specify textures in certain formats. It also allows the application, through glTexImage*D parameters, to specify a requested internal format as a hint to the OpenGL implementation specifying the desired internal storage format for the texture.

There are several texture formats that are used in OpenGL:

1. Host format is the texture format in which the application keeps textures, and it is also the format in which the textures are passed in via the glTexImage*d calls.

2. Requested internal format is the texture format, specified by the application via the glTexImage*D calls, that it would prefer that the implementation use to store textures. Note that this format, optionally, specifies sizes for each component of the texture, giving more control to the application regarding the internal format of the textures.

3. Base internal format is a “sizeless” version of the requested internal format. For example, if an application requested an RGBA8888 format (requested

Page 76: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver

internal format), then the base internal format is RGBA. There is no texture data that corresponds directly to this format, but it is a conceptual classification that specifies how the texture will be treated for purposes such as texture blending.

4. Internal storage format is the actual format that the internal copy of the texture is kept in. This may differ from the requested internal format in both size and type.

5. Resident storage format is the format of the resident copy of the texture. This may or may not differ from the internal storage format.

The internal storage format for a particular requested format depends on the implementation. There is complete flexibility on how the internal storage format is chosen (through a lookupTextureFormat call), so the implementation can provide its own mapping. See __glDDrawTextureCreateLevel in drivers/ddraw/ddtexfmt.c for specific details.

Ideally, we would want the resident storage format to be the same as the internal storage format, but sometimes this is not attainable. The internal storage format has to be in a form that the software fallback code understands (in case there is a need to fall back to software). If the format of the textures that the hardware understands is not compatible with any of the internal storage formats that OpenGL understands, then some translation has to happen from the internal to the resident storage format.

Abstraction has been provided to translate from the internal to the resident storage formats. This is done using the copyActive functions. An example is given in drivers/ddraw/ddtexel.c with the help of the data structures in drivers/ddraw/ddtexfmt.c. In the sample S3 Virge code, some translation is performed between the internal and the resident texture formats.

Summarizing, the texture subsystem provides modularized support for the main two needs that an implementation will need to customize, namely:

1. Management of texture memory.

2. Management of texture formats.

This is done in an expandable way that allows the IHV complete flexibility together with compatibility with the existing fallback software rasterizer.

Kernel Mode Issues in Windows NT 4.0 and 5.0The kernel-mode driver environment for Windows NT 4.0 and Windows NT 5.0 is significantly different from the user-mode environment that display drivers used to run under in earlier viersions of Windows NT. Many of these differences are discussed in the documentation for general display drivers and will not be repeated here.

Page 77: Overview - pudn.comread.pudn.com/downloads6/doc/18629/opengl-icd.doc  · Web viewThis allows the generic software code to operate only on the generic part of the context, while the

OpenGL Installable Client Driver 77

However, OpenGL display drivers on Windows NT 4.0 and Windows NT 5.0 have a slightly different environment than what a generic display driver can expect.

No C-runtime is normally provided for display drivers. The library libcntpr.lib, provided with the DDK, contains a subset of the normal C-runtime that can be used in kernel mode. This subset includes the floating-point support routines, so almost all OpenGL drivers will end up linking with this library.

The OpenGL escapes OPENGL_CMD and OPENGL_GETINFO automatically provide an enhanced environment for execution. They save and restore the floating-point state on the x86 so that it’s possible to use floating-point on all platforms. In addition, they expand the stack to 60K so that OpenGL drivers have more room for more complicated call paths and stack allocations.

This enhanced environment is provided automatically only for DrvEscape calls with OPENGL_CMD and OPENGL_GETINFO. Any other routines, such as initialization, do not provide this support, so care must be taken to ensure that extended operations are only performed along paths that are reached via the OpenGL escapes.

Note