Содержащиеся в
Найти другие документы
Ресурсы поддержки
| Загрузить это руководство в формате PDF
Implementing the Skeleton Pixel-Level Graphics Handler
3
- This chapter describes how to modify the skeleton source files provided with the XGL DDK product to create a pixel-level XGL graphics handler for your hardware device.
About Pixel-Level Rendering
- The XGL graphics porting interface (GPI) consists of three layers of device pipeline interfaces, called LI-1, LI-2, and LI-3. The pixel layer of the XGL GPI is the lowest layer of the device pipeline. This layer, LI-3, is responsible for rendering pixels, vectors, and spans, but it leaves geometry processing and scan conversion to the XGL software pipeline. All device pipelines must implement routines for the LI-3 layer, since this layer is not implemented in the software pipeline.
- To facilitate LI-3 implementation, the XGL GPI provides a utility object called RefDpCtx. The RefDpCtx object contains non-optimized implementations of all the LI-3 routines and several LI-1 routines. RefDpCtx writes to the hardware via one or more pixel objects called PixRects. A PixRect object is an abstraction of a buffer managed by the device, for example, the image buffer, Z-buffer, or accumulation buffer. PixRects represent the frame buffer pixel values to RefDpCtx. The PixRect object has methods to read and write pixels to the device, and RefDpCtx uses these methods to set pixel values on the device.
- Your pipeline needs PixRects for the image buffer for a 2D pipeline, and for the image buffer, Z-buffer, and accumulation buffer for a 3D pipeline. The type of PixRect that you use to represent a particular buffer reflects your hardware. In
- order to implement your graphics handler, you need to know the characteristics of your hardware. In particular, before you can write an LI-3 implementation with RefDpCtx, you must determine whether your hardware is memory-mapped and whether the Z-buffer and accumulation buffer are supported in hardware or handled in software.
- When a pixel-level graphics handler uses RefDpCtx for rendering, all geometry and scan conversion functions are performed in the XGL software pipeline. The software pipeline returns LI-3 vector and span data, which the RefDpCtx object converts to pixel values. The device pipeline only accesses the hardware to read and write single pixel values.
- Implementing LI-3 using RefDpCtx is a simple, quick way to port XGL to your hardware. Although rendering is slow, RefDpCtx provides complete coverage of functionality, as it supports texture mapping, blending, and transparency. Your XGL graphics handler will probably accelerate some primitives at the LI-1 and LI-2 layers, but implementing the LI-3 layer through the RefDpCtx object is an easy way to begin porting XGL to your hardware.
Steps for Implementing Pixel-Level Rendering
- To implement LI-3 rendering with the skeleton files, follow these general steps:
-
- Choose a name for your graphics handler.
- Copy the skeleton files and rename them to the name of your pipeline.
- Edit the Makefile to rename the pipeline binary.
- Edit several skeleton device pipeline interface files to correspond to the capabilities of your device.
- Set hardware addresses to implement PixRect support.
- Build the pipeline.
- Test the pipeline.
- The remainder of this chapter shows you how to complete these tasks.
· Choosing a Name for the Graphics Handler
- First, choose a name for your graphics handler. A XGL graphics handler must be named according to the following convention:
-
-
xgl<COMPANY NAME><device name>.so.<major version>
- where:
-
-
<COMPANY NAME> is a 4-letter capitalized abbreviation for the company that implements the device pipeline.
-
<device name> is the abbreviated name of the device, which should be an abbreviated form of the name of the corresponding kernel device driver located in the /dev directory.
-
<major version> is the major release number of the DDK associated with the particular release of XGL that is compatible with this device pipeline.
- For example, a Sun Microsystems Cg6 device pipeline for version 4 of the XGL GPI is named xglSUNWcg6.so.4, where SUNW is the company symbol, cg6 is the device name, and 4 is the major version number. For your pipeline, you only need to choose a company name and device name. The xgl and version number portions of the graphics handler name are added automatically by the Makefile.
- The XGL versioning scheme is implemented as part of the device-independent library and as part of the DDK. The DDK header file xgli/DdkVersion.h defines the version number, which contains major and minor parts. When the pipeline is compiled, the major and minor version numbers are stamped in the pipeline file. The skeleton pipeline file DpLibSkeleton.cc includes the DdkVersion.h header file, as should your pipeline. For more information on versioning rules, see the XGL Device Pipeline Porting Guide.
· Copying and Renaming the Skeleton Files
- The skeleton files provide the derived classes you need for your pipeline. To use the skeleton files, follow these steps:
-
-
Execute the convert_skeleton script located in <DDK_DIR>/xgl/bin. The convert_skeleton script creates a new directory hierarchy for your pipeline files and names the directory with your device name. The script then copies the skeleton files from the <DDK_DIR>/src/dd/skeleton directory to the new directory and renames the files with your device name.
- The convert_skeleton script also updates all function names and variables to use the device name. As an example, for a pipeline named My_pipeline, the command would be:
-
<DDK_DIR>/bin/convert_skeleton [My_pipeline]
|
-
-
Change directory to your pipeline directory.
-
To check that your pipeline builds, execute the make opt command. The make opt command creates the objs directory for the skeleton pipeline object files and compiles and links the pipeline.
- If the new pipeline builds without errors, you are ready to begin modifying the skeleton files for your pipeline.
-
Note - In the remainder of this guide, skeleton pipeline refers to your pipeline.
· Editing Files to Rename the Pipeline Binary
- You need to change the SYMBOL variable in several skeleton files to your company name.
-
-
Edit the skeleton pipeline Makefile to change SYMBOL to your company symbol in upper case letters.
Edit the following line:
-
LIB_NAME = xglSYMBOLskeleton
|
-
-
Change directory to the include directory.
-
Edit the xgl_errors_Skeleton.po file to change SYMBOL to your company symbol in upper case letters.
Edit the following lines:
-
domain "xglSYMBOLskeleton"
msgid "SYMBOLskeleton-1"
msgid "SYMBOLskeleton-2"
|
-
-
Execute the make extract command to convert the error file text to the error file binary.
· Editing the Skeleton Pipeline Interface Files
- In this step, you will modify the skeleton header and source files for the device pipeline interface objects to match the capabilities of your hardware. The device pipeline interface objects connect the device-independent code with the device pipeline renderers. To enable you to implement a pixel-level graphics handler quickly, the XGL DDK product has provided a set of partially implemented files for these objects. All you need to do to render pixels on your device is add device-specific information to the generic skeleton pipeline interface files and, if necessary, write several functions.
-
Table 3-1 shows which skeleton device pipeline files require modification and which are provided ready to use. For more information on the device pipeline interface objects, see the XGL Device Pipeline Porting Guide. Comments in the skeleton source files provide information on how the skeleton pipeline implements these objects.
-
Table 3-1
| Object | Source Files | Need Changes? |
| XglDpLib | DpLibSkeleton.h
DpLibSkeleton.cc | No |
| XglDpMgr | DpMgrSkeleton.h
DpMgrSkeleton.cc | Yes |
| XglDpDev | DpDevSkeleton.h
DpDevSkeleton.cc | Yes |
XglDpCtx2d
XglDpCtx3d | DpCtx*Skeleton.h
DpCtx*Skeleton.cc | Not at this time. See Chapter 4. |
- To edit the device pipeline interface files, follow these steps:
· Step 1: Edit the DpMgrSkeleton header and source files.
- You need to update the XglDpMgr header and source files to add code for hardware initialization and update the inquire() method.
-
-
In the DpMgrSkeleton.h file, add any variables needed by hardware initialization routines.
For example, you might need a structure to represent your hardware. This structure could contain the base register address, screen dimensions, and other information relevant to the physical device.
-
In the DpMgrSkeleton.cc constructor, set the Boolean values for memoryMappedImageBuffer and memoryMappedZBuffer to TRUE if the image buffer or Z buffer are memory mapped.
-
In the DpMgrSkeleton.cc constructor, set the Boolean values hwZBuffer and hwAccumBuffer to TRUE if your hardware has a hardware Z buffer or hardware accumulation buffer.
The value of these variables are tested in the DpDevSkeleton object; they determine what type of PixRects are instantiated for your pipeline. If your hardware has a hardware Z buffer, but you want to get your port working quickly, leave the hwZBuffer variable set to FALSE to use the software pipeline Z buffer.
-
In the DpMgrSkeleton.cc constructor, insert hardware initialization code.
The XglDpMgr class constructor is called once for each instance of your hardware device, so this is a convenient place to map in registers or frame buffer memory. For an example of hardware initialization for a GX device, which has a memory mapped image buffer and uses a software Z buffer, see the reference pipeline code for the GX frame buffer or see Appendix A, "Example Hardware Initialization Code" on page 43.
-
In the DpMgrSkeleton.cc destructor, insert code to free any allocated resources.
-
-
Update the values in the DpMgrSkeleton.cc method inquire() to match the attributes of a window on your device.
The inquire() routine returns information on the acceleration features underlying a window and corresponds to the XGL API function xgl_inquire(). Applications use the information returned by xgl_inquire() to determine what is accelerated on the device they are running on. It is important to note that although inquire() appears to hold information about the frame buffer as a whole, the application that inquires about the device is actually requesting information on the window it is running in. For example, if your device accelerates more than one color type or provides double buffering on only one window at a time, your inquire() routine will need to determine what acceleration features were provided in a particular window in order to return accurate information to the application. To implement the inquire() method, do the following:
-
- Set the value of the name variable to the name or symbol for your company. For example, the company symbol for Sun is SUNW, and the name for the GX device is cg6. Thus, on a GX device, the xgl_inquire() function returns inq_info->name = SUNW:cg6.
- Update other values in the inquire() routine to match your hardware.
Tip ->
- You may want to implement acceleration on your device before updating the values in inquire(). Be sure to update this routine; one way that applications know how to use your hardware is by checking the values returned in xgl_inquire().
· Step 2: Edit the XglDpDev source file.
- You need to override device specific functions provided in the DpDev source file.
-
-
Override the optional methods in DpDevSkeleton.cc to correspond to the functionality of your device.
DpDevSkeleton.cc provides virtual functions for the set of optional methods inherited from the DpDev class hierarchy. Override these methods if the default behaviors or returned values do not match those of your device. For example, if your hardware handles double buffering, you have
- to override the DpDev virtual functions setBuffersRequested(), setBufDisplay(), and setBufDraw() to do what is appropriate for your hardware.
- Note that the DpDevSkeleton function updateDev() handles updating the hardware when the user switches rasters. updateDev() updates the device-specific attributes by getting the current values of the raster attributes from device-independent XGL and calling the functions that you have overridden.
-
-
Insert code to free any allocated resources in the DpDevSkeleton destructor.
· Implementing PixRect Support
- The RefDpCtx utility object assumes that the pipeline is able to set individual pixel values to the hardware. The PixRect objects provide RefDpCtx with the base address of the hardware or software memory.
- Setting up PixRect support in the skeleton pipeline has been designed so that you only have to:
-
- Set Boolean variables that indicate whether your hardware image buffer or Z buffer are memory mapped, and set additional Boolean variables that indicate whether your device has a hardware Z buffer or accumulation buffer. You should have already set these Boolean values in the DpMgrSkeleton.cc file.
- Set the hardware address for the image buffer, and, if applicable, for a hardware Z buffer or hardware accumulation buffer. Where you set these addresses depends on whether your hardware is memory mapped or not.
PixRect Support for a Memory-Mappable Device
- PixRect support for memory-mapped devices is provided in the XglPixRect subclass XglPixRectMemAssigned. This class provides a method that creates a PixRect object on existing hardware memory.
- In the DpMgrSkeleton.h file, a PixRect of type XglPixRectMemAssigned is already allocated to represent the entire frame buffer. This PixRect is used as a resouce for the window PixRect. It contains low-level information about the frame buffer address and size.
-
* To associate the frame buffer PixRect with your device, edit the DpMgrSkeleton.cc constructor to set the fb_address variable to the base address of your frame buffer.
- The DpMgrSkeleton class constructor uses Xlib calls to get the height and width of your frame buffer and the depth of the window. In DpMgrSkeleton.cc, the XglPixRectMemAssigned method reassign() initializes this PixRect with the correct information for your hardware.
PixRect Support for a Non-Memory-Mappable Device
- If your device is not memory mappable, or if only one buffer is accessible at a time, you must subclass from PixRect.h and override methods to do what is needed to access the hardware. The skeleton pipeline provides a subclassed PixRect class in the files PixRectSkeleton.h and PixRectSkeleton.cc. You can use these files to implement your device-specific PixRect class.
- To implement your device's version of the PixRect class, edit PixRectSkeleton.cc as follows:
-
-
Override the setValue() method with code to write the value of a single pixel to the screen.
-
Override the getValue() method with code to return the value of a single pixel.
-
If both the image buffer and the Z buffer are non-memory-mapped, edit the validateBuffer() method to set the hardware registers to the appropriate buffer.
When both the image buffer and Z buffer are not memory-mapped, validateBuffer() determines whether the image buffer or Z buffer is the current buffer and sets the hardware registers to the appropriate buffer. The setValue() and getValue() methods then render to or read from the correct buffer.
-
If your frame buffer is more than 32 bits deep, override the methods
-
-
getValueByPointer() and setValueByPointer().
· Building the Device Pipeline
- Now you can build your LI-3 pipeline using the Makefile provided with the skeleton pipeline. Your pipeline will render to your hardware at the LI-3 level using RefDpCtx and the PixRect setValue() and getValue() calls.
-
-
To build an optimized pipeline, execute the make opt command. The pipeline binary is located in the lib/pipelines directory.
Note that an optimized pipeline cannot be debugged easily. To build a debuggable pipeline, execute the make debug command.
-
If you modified the xgl_errors_Skeleton.po file to add device-specific error messages, execute the make extract command.
This command creates the .mo error file binary for internationalization of error messages.
· Testing the Device Pipeline
- To test your pipeline, you can run the install_check program in the SDK demo directory or run any application program. The install_check program displays some information about the hardware. To run install_check, key in $XGLHOME/demo/install_check.
- You can also run the Denizen Test Suite provided with the XGL DDK product. The Denizen Test Suite is a set of verification programs that enables you to test the accuracy of your implementation. Denizen is a set of shell scripts and C programs that uses the XGL library to render objects and evaluate results. It creates a log of events, errors, and failures that can be compared to logs provided by XGL.
- The Denizen Test Suite is installed from the DDK CD. Its default installation location is /opt/SUNWddk/ddk_2.5.1/xgl/src/test_suite/denizen. This directory contains reference images used for comparison testing, documentation on the test programs, and the run_denizen.sh shell script that executes the Denizen test suite. The README file contains information on run_denizen.sh.
- To run Denizen, follow these steps:
-
-
Set the required environment variables as noted in the INSTRUCTIONS file in the denizen directory.
Be sure to set the FB_NAME environment variable to your pipeline name.
-
-
Execute the run_denizen.sh script.
The run_denizen.sh script runs the entire set of Denizen tests. To run one or more test areas, you can execute run_denizen.sh <test area>.
- For more detailed information on running Denizen and comparing test results, see the XGL Test Suite User's Guide.
|
|