Chapter 3. Configuring the IMPACT Channel Option Board

The IMPACT Channel Option (ICO) board allows you to transmit video output to multiple monitors from a single IMPACT system. Each monitor is assigned a different portion of the IMPACT frame buffer so that each monitor displays a unique image. You can use ICO to drive up to four monitors with RS170, VGA, or SVGA timing. Also, you can use the ICO board to produce timing formats not supported by IMPACT graphics alone. For example, while the standard field parallel formats, such as VGA, transmit data to a monitor on red, green, and blue wires, ICO can produce field sequential formats that transmit all data on a single wire. These formats provide two channels of information needed to produce stereoscopic displays on many common head-mounted displays. Also, you can use ICO to “minify” a high resolution image, and produce a softened, lower resolution image.

Before continuing to configure the ICO, make sure that you also have installed the following:

You can install one ICO board for each Indigo2 IMPACT system. The ICO board can drive up to four independent channels from a single workstation.

This chapter describes how to configure the video formats that the ICO outputs. Specifically, this chapter covers the following topics:

If you have a duel-head system and want to move windows from one head to another, see Indigo2 IMPACT Dual Head Installation Guide and Notes for Developers.

The IMPACT Channel Option Board and the Graphics Subsystem

The ICO video output is easy to configure. Just specify the number of channels and the size of the video image. You can use the standard system command, setmon, to specify the output format (see “Using the setmon Command” for more information). If you are writing code for an application, use XSGIvc() to control the video output formats (for more information, see “Writing a Programmatic Interface for ICO”).

This section explains the following topics:

ICO Graphics Integration

Figure 3-1 shows how the IMPACT Channel Option board is integrated into the graphics subsystem. The ICO subsystem interprets your video output specifications and converts the incoming digital information per your specifications. Video comes in to the ICO subsystem where it is scaled and/or partitioned into the number and size of screens you have specified. Next, it goes to the framebuffer and then to the crossbar, which acts as a switch. Lastly, the crossbar routes the analog video signals to the appropriate monitors.

Figure 3-1. IMPACT Channel Option Board and Graphics Subsystem


The number of screens into which the IMPACT Channel Option board divides the display surface is determined by several factors, including the ICO configuration that you specify and the graphics bandwidth of the Indigo2 IMPACT graphics system.

ICO Video Output Formats

Table 3-1 lists the number of ICO channels, format resolution, and timing.

Table 3-1. ICO Video Output Channels, Format, and Timing

Number of Channels

Format

Timing

4

640 x 486 Interlaced

RS-170 (NTSC RGB)

4

640 x 480 Non-interlaced

VGA

2

640 x 480 Non-interlaced

Field sequential

1

640 x 480 Non-interlaced

VGA (filtered minify mode)

2

800 x 486 Interlaced

RS-170 Field sequential

2

800 x 486 Interlaced

RS-170 Field parallel component

2a

800 x 600 Non-interlaced

SVGA

2[a]

880 x 808 Interlaced

Field sequential

2a

1024 x 946 Interlaced

Field sequential

2a

1160 x 960 Interlaced

Field sequential

[a] These modes are supported only on systems with Maximum IMPACT graphics.



Note: VGA-to-NTSC converters produce composite NTSC.

For information on cable connections between the ICO board and ICO output monitors, see “Connecting the Monitors or Head Mounted Display”. For details on the breakout box connection to a head-mounted device, see “Connecting the Head-Mounted Display”. For information on the breakout box connection for minify mode, see “Connecting to a Single Monitor: The Minify Mode”.

ICO Video Output Format Specifications

Video output format specifications are listed in Table 3-2.

Table 3-2. Video Output Format Specifications

Format Specification

Active Area

4@640x486_30i

Four screens, each 640 x 486, at 30 Hz, interlaced RS-170 (NTSC RGB)

4@640x480_60

Four screens, each 640 x 480, at 60 Hz, non-interlaced (VGA)

2@640x480_60q

Two screens, each 640 x 480, at 60 Hz, non-interlaced, field sequential

1@640x480_60

One screen, 1281 x 961 minified to 640 x 480, at 60 Hz, non-interlaced (VGA)

2@800x486_30qi

Two screens, each 800 x 486, at 30 Hz, interlaced, field sequential

2@800x486_30i

Two screens, each 800 x 486, at 30 Hz, interlaced, field parallel

2@800x600_60a

Two screens, each 800 x 600, at 60 Hz, non-interlaced (SVGA)

2@880x808_30qi[a]

Two screens, each 880 x 808, at 30 Hz, interlaced, field sequential

2@1024x946_30qia

Two screens, each 1024 x 946, at 30 Hz, interlaced, field sequential

2@1160x960_30qia

Two screens, each 1160 x 960, at 30 Hz, interlaced, field sequential

[a] These modes are supported only on systems with Maximum IMPACT graphics.



Note: ICO does not support an external genlock source. However, when ICO is in multi-screen mode, the outputs are synchronized with each other.

For information on cable connections between the ICO board and ICO output monitors, see “Connecting the Breakout Box Cable”. For details on the breakout box connection to a head-mounted display, see “Connecting the Head-Mounted Display”. For information on the breakout box connection for minify mode, see “Connecting to a Single Monitor: The Minify Mode”. For information on HSYNC and VSYNC, see “Using the HSYNC or VSYNC Connectors”.

Using the setmon Command

You can set the IMPACT Channel Option board's output video formats by using the setmon command, the same command you use to select the formats of IMPACT graphics.

This section covers the following topics:


Note: Silicon Graphics recommends that you use the X extension, XSGIvc, when writing a program that controls the video output formats. See “Writing a Programmatic Interface for ICO” for more information. Also, use a dumb terminal or remotely log in over the network to switch video modes between standard and ICO modes.

For information on moving the cursor from screen to screen, see “Using the Four-Screen Mode”.

Using setmon to Configure the IMPACT Channel Option Board

To configure and turn on the IMPACT Channel Option board, follow these steps:

  1. If your Silicon Graphics system is powered off, follow the steps in the Indigo2 IMPACT Owner's Guide to plug in the system and power it on.

  2. Log in to your account on the system.

  3. Open a shell window, if necessary, by selecting “Unix Shell” from the Desktop Toolchest. Move the cursor inside the shell window.

  4. Execute the setmon command and with the –S option. The format is

    setmon -S format
    

    The option –S is required; note that it is uppercase. The format is the specification of the desired video output format. For example, suppose you want two screens at an 800 x 486 resolution; the format specification is 2@800x486_30i. So, to display this video format, enter:

    setmon -S 2@800x486_30i
    

This specification sets up ICO multi-channel mode for two monitors, each at 800 x 486 pixels. The timing is 30 Hz and is interlaced (more than one vertical scan is used to reproduce a complete image).

To turn on ICO multi-channel mode, see “Turning On the ICO”. Output formats are listed in “ICO Video Output Format Specifications”.


Note: ICO does not support an external genlock source. However, when ICO is in multi-screen mode, the outputs are synchronized with each other.


Using setmon to Delay the Loading of the Video Format

You can delay loading the video format by using the –x option to setmon. Note that you must be the superuser (su) to use the –x option. For example:

su
setmon -x -S 2@800x486_30i

The –x option saves the specified format to be used the next time the X server is started. This format does not take effect immediately; it is loaded the next time you restart graphics, or reboot the system. For information on starting the X server and graphics mode, see “Turning On the ICO”.

For details on this command and its options, see the setmon(3) reference page.

Turning On the ICO

It's best to remotely log in over the network or use a dumb terminal when switching video modes between standard graphics and ICO modes.

To switch to ICO multi-channel mode, stop and restart the graphics subsystem:

/usr/gfx/stopgfx ; /usr/gfx/startgfx


Note: It is possible to switch to/from ICO multi-channel mode without stopping and restarting the graphics subsystem if the new framebuffer screen size is less than or equal to the old screen size.

If you wish, you can confirm that the ICO is active; for more information, refer to the section “Using gfxinfo to List Graphics Information”.


Note: When the ICO is active, IMPACT graphics do not output to the standard IMPACT monitor (1280 x 1024).


Turning Off the ICO and Returning to the Standard IMPACT Monitor

After a power-off, system reset, or reboot, the system remains in multi-channel mode. To turn off ICO and return to standard graphics mode, enter:

setmon -x format
/usr/gfx/stopgfx
/usr/gfx/startgfx

The format is the output format of the screen when not in multi-channel mode, for example, 1280x1024_60.

Using gfxinfo to List Graphics Information

You can use the gfxinfo command to display information about the graphics subsystems installed in your system. Enter the following:

setenv DISPLAY :0
/usr/gfx/gfxinfo -v

First, set up your environment so that the information is displayed on the screen from which you are typing the gfxinfo command. The –v option to gfxinfo specifies verbose output.

An example of gfxinfo output for the format, 2@800x486_30i, looks like this:

Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 800x972
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)

   Input Sync: Voltage - Video level, Source-Internal,Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 800 pixels, 486 lines, 30.00Hz (2@800x486_30i)
  Channel 2:
    Origin = (0,486)
    Video Output Size: 800 pixels, 486 lines, 30.00Hz (2@800x486_30i)

The output tells you that the ICO board is installed and its revision number: ICO board present (rev 2). You also see statistics for each channel: the origin of each viewport (0,0 for Channel 1 and 0,486 for Channel 2) and the video output size, timing, and format (800 pixels, 486 lines, 30.00Hz (2@800x486_30i)).

ICO Display Viewports

The X display surface for IMPACT Channel Option board video formats is determined by the mode in which ICO is operating. The ICO places the origin of the first viewport starting at 0,0 in the upper left corner of the window.

This section provides examples of the screen origins for various output formats:


Note: For more information on origins and display surface sizes, see “Using gfxinfo to List Graphics Information” and the gfxinfo(3G) reference page. Consult the gfxinfo output before using any formats. Silicon Graphics reserves the right to change origins as needed.

For video output channels, formats, and timing information, see Table 3-1. A programmatic interface is shown in the example program in “ICO Programming Example”.

4@640x486_30i, Component NTSC/RS-170 (RGB)

Figure 3-2 shows the maximum single display surface and origins for the viewports for the output format 4@640x486_30i. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 1280 x 972 pixels.

This format divides the frame buffer into four independent channels. The size and location of each channel are shown in the figure. Each channel is 640 x 486 pixels and is output on the R, G, and B connectors on the breakout box. The timing for these signals is compatible with RS-170. If you require a composite signal, you must use an external encoder.

Figure 3-2. Display Surface for 4@640x486_30i Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 1280x972
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)

   Input Sync:  Voltage-Video level, Source-Internal, Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 640 pixels, 486 lines, 30.00Hz (4@640x486_30i)
  Channel 2:
    Origin = (0,486)
    Video Output Size: 640 pixels, 486 lines, 30.00Hz (4@640x486_30i)
  Channel 3:
    Origin = (640,0)
    Video Output Size: 640 pixels, 486 lines, 30.00Hz (4@640x486_30i)
  Channel 4:
    Origin = (640,486)
    Video Output Size: 640 pixels, 486 lines, 30.00Hz (4@640x486_30i)

4@640x480_60, VGA

Figure 3-3 shows the maximum single display surface and origins for the viewports for the output format 4@640x480_60. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 1280 x 960 pixels.

This format divides the frame buffer into four independent channels. The size and location of each channel are shown in the figure. Each channel is 640 x 480 pixels and is output on the R, G, and B connectors on the breakout box. This format is non-interlaced with a 60Hz frame update rate. The timing for these signals is compatible with VGA resolution. Typically, this mode is used with sync-on-green. The monitors that are used with this format must be able to accept sync-on-green rather than external H and V sync. ICO can produce one channel of separate H and V sync, which is timed correctly for any of the ICO channels.

Figure 3-3. Display Surface for 4@640x480_60 Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
    Managed (“:0.0”) 1280x960
    Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
    MGRAS revision 3, RA revision 5, RB revision 4
    HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
    VC3 rev A, CMAP rev D, MC rev C
    19” monitor (id 0x1)
    ICO board present (rev 2)

    Input Sync: Voltage-Video level, Source-Internal, Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (4@640x480_60)
  Channel 2:
    Origin = (0,480)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (4@640x480_60)
  Channel 3:
    Origin = (640,0)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (4@640x480_60)
  Channel 4:
    Origin = (640,480)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (4@640x480_60)

2@640x480_60q, Field Sequential

Figure 3-4 shows the maximum single display surface and origins for the viewports for the output format 2@640x480_60q. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 640 x 960 pixels.

This format divides the frame buffer into two independent channels. The size and location of each channel are shown in the figure. Each channel is 640 x 480 pixels and is output on the R and G connectors for Channel 1 of the breakout box. This format is a non-interlaced field sequential format with a 60Hz update rate.

Figure 3-4. Display surface for 2@640x480_60q Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 640x960
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)

   Input Sync:  Voltage - Video level, Source-Internal, Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (2@640x480_60q)
  Channel 2:
    Origin = (0,480)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (2@640x480_60q)

1@640x480_60, VGA Minify

Minify mode produces a smooth image, without jagged or broken surfaces. This mode uses a rendering technique that takes a portion of a group of pixels and “minifies” them to produce a clear, smooth representation of the original image. For example, a video game developer can create a video game on an IMPACT system and output the game in ICO minify mode to see what it looks like on a typical VGA or TV screen.

Figure 3-5 shows the maximum single display surface (shaded area, 1288 x 962) and origins for the viewport (unshaded area, 1281 x 962) for the output format 1@640x480_60. The IMPACT viewport (1281 x 961) displays as 640 x 480 on the ICO monitor. Note that seven pixels at the end of each line and the bottom line on the screen are not displayed (as shown in the shaded area in Figure 3-5).

Figure 3-5. Display Surface for 1@640x480_60 Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 1288x962
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)
 
   Input Sync:  Voltage - Video level, Source-Internal, Genlocked-False
  Channel 4:
    Origin = (0,0)
    Video Output Size: 640 pixels, 480 lines, 60.00Hz (1@640x480_60)

2@800x486_30qi, RS170-Field Sequential

Figure 3-6 shows the maximum single display surface and origins for the viewports for the output format 2@800x486_30qi. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 800 x 972 pixels.

This format divides the frame buffer into two independent channels. The size and location of each channel are shown in the figure. Each channel is 800x 486 pixels and is output on the R and G connectors for Channel 1 of the breakout box. This format is an interlaced, field sequential format with a 30Hz update rate.

Figure 3-6. Display Surface for 2@800x486_30qi Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 1280x1024
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)

   Input Sync:  Voltage-Video level, Source-Internal, Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 800 pixels, 484 lines, 30.00Hz (2@800x486_30qi)
  Channel 2:
    Origin = (0,484)
    Video Output Size: 800 pixels, 484 lines, 30.00Hz (2@800x486_30qi)

2@800x600_60, SVGA

Figure 3-7 shows the maximum single display surface and origins for the viewports for the output format 2@800x600_60. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 800 x 1200 pixels.

This format divides the frame buffer into two independent channels. The size and location of each channel are shown in the figure. Each channel is 800 x 600 pixels and is output on the R, G, and B connectors on the breakout box. This non-interlaced format has a 60Hz frame update rate. The timing for these signals is compatible with SVGA resolution. Typically, this mode is used with sync-on-green. The monitors that are used with this format must be able to accept sync-on-green rather than external H and V sync. ICO can produce one channel of separate H and V sync, which is timed correctly for any of the ICO channels.

Figure 3-7. Display Surface for 2@800x600_60 Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 800x1200
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)

   Input Sync:  Voltage-Video level, Source-Internal, Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 800 pixels, 600 lines, 60.10Hz (2@800x600_60)
  Channel 2:
    Origin = (0,600)
    Video Output Size: 800 pixels, 600 lines, 60.10Hz (2@800x600_60)

2@880x808_30qi, Field Sequential

Figure 3-8 shows the maximum single display surface and origins for the viewports for the output format 2@880x808_30qi. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 880 x 1616 pixels.

This format divides the frame buffer into two independent channels. The size and location of each channel are shown in the figure. Each channel is 880 x 808 pixels and is output on the R and G connectors for Channel 1 of the breakout box. This format is an interlaced, field sequential format with a 30Hz update rate.

Figure 3-8. Display Surface for 2@880x808_30qi Output Format


The output of gfxinfo -v for this format is

 Graphics board 0 is “IMPACT” graphics.
   Managed (“:0.0”) 880x1616
   Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
   MGRAS revision 3, RA revision 5, RB revision 4
   HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
   VC3 rev A, CMAP rev D, MC rev C
   19” monitor (id 0x1)
   ICO board present (rev 2)

   Input Sync:  Voltage-Video level, Source-Internal, Genlocked-False
  Channel 1:
    Origin = (0,0)
    Video Output Size: 880 pixels, 808 lines, 30.00Hz (2@880x808_30qi)
  Channel 2:
    Origin = (0,808)
    Video Output Size: 880 pixels, 808 lines, 30.00Hz (2@880x808_30qi)

2@1024x946_30qi, Field Sequential

Figure 3-9 shows the maximum single display surface and origins for the viewports for the output format 2@1024x946_30qi. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 1024 x 1892 pixels.

This format divides the frame buffer into two independent channels. The size and location of each channel are shown in the figure. Each channel is 1024 x 946 pixels and is output on the R and G connectors for Channel 1 of the breakout box. This format is an interlaced field sequential format with a 30Hz update rate.

Figure 3-9. Display Surface for 2@1024x946_30qi Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
  Managed (“:0.0”) 1024x1892
  Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
  MGRAS revision 3, RA revision 5, RB revision 4
  HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A,
  VC3 rev A, CMAP rev D, MC rev C
  19” monitor (id 0x1)
  ICO board present (rev 2)

  Input Sync:  Voltage-Video level, Source-Internal, Genlocked-False
 Channel 1:
   Origin = (0,0)
   Video Output Size: 1024 pixels, 946 lines, 30.00Hz (2@1024x946_30qi)
 Channel 2:
   Origin = (0,946)
   Video Output Size: 1024 pixels, 946 lines, 30.00Hz (2@1024x946_30qi)

2@1160x960_30qi, Field Sequential

Figure 3-10 shows the maximum single display surface and origins for the viewports for the output format 2@1160x960_30qi. The actual display surface is the largest rectangular area that encloses the viewports. Its size is 1160 x 1920 pixels.

This format divides the frame buffer into two independent channels. The size and location of each channel are shown in the figure. Each channel is 1160 x 960 pixels and is output on the R and G connectors for Channel 1 of the breakout box. This format is an interlaced field sequential format with a 30Hz update rate.

Figure 3-10. Display Surface for 2@1160x960_30qi Output Format


The output of gfxinfo -v for this format is

Graphics board 0 is “IMPACT” graphics.
  Managed (“:0.0”) 1160x1920 
  Product ID 0x0, 2 GEs, 2 REs, 1 TRAM
  MGRAS revision 3, RA revision 5, RB revision 4
  HQ rev A, GE11 rev B, RE4 rev A, PP1 rev A, 
  VC3 rev A, CMAP rev E, MC rev C
  19” monitor (id 0x1)
  ICO board present (rev 2)

 Channel 1:
   Origin = (0,0)
   Video Output: 1160 pixels, 960 lines, 30.00Hz (2@1160x960_30qi)
 Channel 2:
   Origin = (0,960)
   Video Output: 1160 pixels, 960 lines, 30.00Hz (2@1160x960_30qi)

Writing a Programmatic Interface for ICO

This section provides an example program for ICO video output. Specifically, this section describes how to use XSGIvc() to

  • retrieve video format information

  • load video formats

  • query for channel information

  • draw to each channel specified by the video output formats

Using XSGIvc

XSGIvc() is an X extension that provides a range of services to permit programmatic control of video operations. For details on this extension, see the XSGIvc(3) reference page.

ICO Programming Example

The programming example below uses XSGIvc() to display information about channels and their setup. Specifically, this example:

  • Prints the XSGIvc information for a specified pipe

  • Prints the input sync information

  • Prints the XSGIvc information for one channel

  • Prints the XSGIvc information for one channel's gamma

    /*
     * xvcinfo.c
     *
     * Display information about xvc channels, setup.
     *
     *
     * Copyright 1996, Silicon Graphics, Inc.
     * All Rights Reserved.
     *
     * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
     * the contents of this file may not be disclosed to third parties, copied or
     * duplicated in any form, in whole or in part, without the prior written
     * permission of Silicon Graphics, Inc.
     *
     * RESTRICTED RIGHTS LEGEND:
     * Use, duplication or disclosure by the Government is subject to restrictions
     * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
     * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
     * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
     * rights reserved under the Copyright Laws of the United States.
     */
    
    #ident “$Revision: 1.6 $”
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/param.h>
    #include “xvcinfo.h”
    
    
    #define ARRAY_COUNT(arr)           ((int) (sizeof(arr) / sizeof(arr[0])))
    
    static const char * const pcUnknown = “Unknown”;
    static const char * const pcTrue = “True”;
    static const char * const pcFalse = “False”;
    static const char * const pcRed = “Red”;
    static const char * const pcGreen = “Green”;
    static const char * const pcBlue = “Blue”;
    static const char * const pcAlpha = “Alpha”;
    
    
    /*
     * Forward function declarations
     */
    static void xvcInputSyncInfo(Display *dpy, int iScreen);
    static void xvcChannelInfo(int bVerbose, Display *dpy, int iScreen, 
         int iChannelNo, const XSGIvcChannelInfo *pChannelInfo);
    static void xvcChannelGamma(Display *dpy, int iScreen, int iChannelNo, 
         const XSGIvcChannelInfo *pChannelInfo);
    static void xvcChannelMonitor(Display *dpy, int iScreen, int iChannelNo, 
         const XSGIvcChannelInfo *pChannelInfo);
    
    /* 
     * Function: xvcinfo
     * 
     * Description:  Prints the XSGIvc information for a specified pipe.
     * 
     * Parameters: 
     * 
     * iBoardnum - the pipe number for which information should be printed.
     * 
     * iVerbose - short or lengthy display.
     * 
     * printchannel - a user-defined function of type fChannelInfoProc
     * which will be called for each channel.  Pass NULL if the standard
     * channel display is desired.
     * 
     * 
     * Return: (void)
     */
    void printXvcInfo(int iBoardnum, int bVerbose, fChannelInfoProc printchannel)
    {
        Display        *dpy = 0;
    
        /* Supply the default channel printer */
        if (!printchannel)
            printchannel = xvcChannelInfo;
    
        /* 
         * It is possible the user will run gfxinfo without an X server
         * running.  Allow this behavior, exiting silently if not present.
         */
        {
              /* Construct the display name from the board number */
              char            cDisplayName[MAXHOSTNAMELEN + 10];
              char *          pcTestMachine = getenv(“XVCTESTMACHINE”);
    
              sprintf(cDisplayName, “%s:0.%d”, (pcTestMachine ? pcTestMachine : ““),
                     iBoardnum);
              dpy = XOpenDisplay(cDisplayName);
        }
    
        if (dpy) {
            Status          sQueryStatus;
            XSGIvcScreenInfo siScreenInfo;
            int             iScreen = DefaultScreen(dpy);
    
            /* Get the screen information from the server */
            sQueryStatus =
                XSGIvcQueryVideoScreenInfo(dpy,
                      iScreen,
                      &siScreenInfo);
    
    if (sQueryStatus == False) {
        fprintf(stderr,
               “Could not get video screen info, screen %d\n”,
               iScreen);
     } else {
         if (bVerbose) {
             xvcInputSyncInfo(dpy, iScreen);
         }
    
         /*
          * Print information for each channel.
          */
         {
              int             iChannelIndex;
         
     for (iChannelIndex = 0; iChannelIndex < siScreenInfo.numChannels; 
           iChannelIndex++) {
          XSGIvcChannelInfo *pciChannelInfo = 0;
        
          sQueryStatus =
             XSGIvcQueryChannelInfo(dpy,
                   iScreen,
                   iChannelIndex,
                   &pciChannelInfo);
        
          if (sQueryStatus == False) {
            fprintf(stderr,
                “Could not get channel info, screen %d, channel %d\n”,
                     iScreen,
                     iChannelIndex);
          } else {
             /*
              * Call the user-specified function to print the channel info
              */
             (*printchannel) (bVerbose, dpy, iScreen, iChannelIndex, pciChannelInfo);
             XFree(pciChannelInfo);
          }
         }
        }
       }
       XCloseDisplay(dpy);
      }
    }
    
    /* 
     * Function: xvcInputSyncInfo
     * 
     * Description:  Prints the input sync information.
     * 
     * Parameters: 
     * 
     * dpy - Display pointer
     * 
     * iScreen - Screen number used in XSGIvc calls
     * 
     * 
     * Return: (void)
     */
    static void xvcInputSyncInfo(Display *dpy, int iScreen)
    {
        int iSyncVoltage = 0;
        int iSyncSource = 0;
        Bool bIsGenlocked = False;
        Status          sQueryStatus;
        
        sQueryStatus =
            XSGIvcQueryScreenInputSyncSource(dpy,
                    iScreen,
                    &iSyncVoltage, 
                    &iSyncSource, 
                    &bIsGenlocked);
        if (sQueryStatus == False) {
            fprintf(stderr,
                     “Could not get input sync source info, screen %d\n”,
                     iScreen);
        } else {
             const char *pcSyncVoltage = pcUnknown;
             const char *pcSyncSource = pcUnknown;
    
             switch(iSyncVoltage) {
                 case XSGIVC_SYNC_VOLTAGE_VIDEO:
                      pcSyncVoltage = “Video”;
                      break;
                 case XSGIVC_SYNC_VOLTAGE_TTL:
                      pcSyncVoltage = “TTL”;
                      break;
             }
             switch(iSyncSource) {
                 case XSGIVC_SYNC_SOURCE_INTERNAL:
                      pcSyncSource = “Internal”;
                      break;
                 case XSGIVC_SYNC_SOURCE_EXTERNAL:
                      pcSyncSource = “External”;
                      break;
                 }
    
             printf(“\tInput Sync:  Voltage - %s level, Source - %s, 
                        Genlocked - %s\n”, 
                    pcSyncVoltage, 
                    pcSyncSource, 
                    bIsGenlocked ? pcTrue : pcFalse); 
           }
       }
    
    /* 
     * Function: xvcChannelInfo
     * 
     * Description:  Prints the XSGIvc information for one channel.
     * 
     * Parameters: 
     * 
     * bVerbose - short or lengthy display.
     * 
     * dpy - Display pointer
     * 
     * iScreen - Screen number used in XSGIvc calls
     * 
     * iChannelNo - the channel number to display
     * 
     * pChannelInfo - the XSGIvcChannelInfo structure for this channel.
     * 
     * 
     * Return: (void)
     */
    static void xvcChannelInfo(int bVerbose, Display *dpy, int iScreen, 
              int iChannelNo, const XSGIvcChannelInfo *pChannelInfo)
    {
        if (pChannelInfo->active) {
            printf(“\tChannel %d”, iChannelNo);
            if (iChannelNo != pChannelInfo->physicalID) {
                printf(“ (physical port %d)”, pChannelInfo->physicalID);  
        }
        printf(“:\n”);
    
        /* The video format */
        {
           int    bFBSizeChanged; /* Frame buffer size differs from format? */
    
           bFBSizeChanged =
              (pChannelInfo->source.height != pChannelInfo->vfinfo.height) ||
              (pChannelInfo->source.width != pChannelInfo->vfinfo.width);
    
          if (bFBSizeChanged) {
              /* Prefix the line */
              int   iWidth = pChannelInfo->source.width;
              int   iHeight = pChannelInfo->source.height;
              printf(“\t Channel's Source Size: %d pixels, %d lines;”,
                    iWidth,
                    iHeight);
          } else 
              /* Indent the next line */
              printf(“\t”);
          {
              int     iX = pChannelInfo->source.x;
              int     iY = pChannelInfo->source.y;
    
              printf(“ Origin = (%d,%d)\n”, 
                     iX, 
                     iY);
        }
        printf(“\t Video Output Size: %d pixels, %d lines, %.2fHz (%s)\n”,
               pChannelInfo->vfinfo.width,
               pChannelInfo->vfinfo.height,
               pChannelInfo->vfinfo.verticalRetraceRate, 
               pChannelInfo->vfinfo.name);
    }
    
    if (bVerbose) {
        {
            int      bFlagPrinted = False;
    
            printf(“\t Video Format Flags:”);
            if (pChannelInfo->vfinfo.formatFlags & XSGIVC_VFIStereo) {
                printf(“  Stereo”);
                bFlagPrinted = True;
            }
            if (pChannelInfo->vfinfo.formatFlags & XSGIVC_VFIFieldSequentialColor) {
                printf(“  Field Sequential”);
                bFlagPrinted = True;  
            }
            if (pChannelInfo->vfinfo.formatFlags & XSGIVC_VFIFullScreenStereo) {
               printf(“  Full-Screen Stereo”);
               bFlagPrinted = True;
            }
    
            if (!bFlagPrinted)
                printf(“  (none)”);
            printf(“\n”);
         }
    
         /* Sync output information */
    #if 0 /* Enable this when the function works properly */
           xvcSyncInfo(dpy, iScreen, iChannelNo, pChannelInfo);
    #endif
           xvcChannelGamma(dpy, iScreen, iChannelNo, pChannelInfo);
           xvcChannelMonitor(dpy, iScreen, iChannelNo, pChannelInfo);
         }
       }
    }
    
    /* 
     * Function: xvcChannelGamma
     * 
     * Description:  Prints the XSGIvc information for one channel's gamma.
     * 
     * Parameters: 
     * 
     * dpy - Display pointer
     * 
     * iScreen - Screen number used in XSGIvc calls
     * 
     * iChannelNo - the channel number to display
     * 
     * pChannelInfo - the XSGIvcChannelInfo structure for this channel.
     * 
     * 
     * Return: (void)
     */
    
    
    static void xvcChannelGamma(Display *dpy, int iScreen, int iChannelNo, 
                    const XSGIvcChannelInfo *pChannelInfo)
    {
        int   iGammaMap = 0;
        Status          sQueryStatus;
        
        sQueryStatus =
             XSGIvcQueryChannelGammaMap(dpy,
                    iScreen,
                    iChannelNo,
                    &iGammaMap);
        if (sQueryStatus == False) {
            fprintf(stderr,
                    “Could not get gamma info, screen %d, channel %d\n”,
                    iScreen, 
                    iChannelNo);
        } else {
             printf(“\t Using Gamma Map %d\n”, iGammaMap);
        }
    }      
    

ICO Programming Example for Performer

This section includes a sample program written for Performer that displays ICO viewports.

Performer Library Routines

The example program (that follows) uses Performer library routines including:

extern int pfuGetMCOChannels(pfPipe *p);
extern void pfuConfigMCO(pfChannel **chn, int nChans);
extern int pfuIsImpact();
extern int pfuGetICOChannels(pfPipe *p);
extern void pfuConfigICO(pfChannel **chn, int nChans);

The pfuGet routines return the number of channels the display option is currently driving. For ICO, the XSGIvc extension is used to query the server for the number of channels that are actively being driven. For MCO, this is done by deducing the VOF from the display area managed by the X server.

The pfuConfig routines set the viewports for an array of channels. ICO infers the tiling from the number of channels requested, with one caveat. The ICO hardware is queried via a XSGIvc extension. If ICO is inactive, then the requested channels are tiled horizontally across the framebuffer.

When pfuConfigICO is called, it first determines the actual number of active channels. If only one channel is actively being driven, then the requested number of channels are tiled horizontally across the screen to allow debugging of multi-channel applications without having ICO hardware. When the number of active channels is greater than 1, pfuConfigICO assumes that the caller is making a reasonable request; that is, that a 2-channel VOF is active when asking for two channels, or a 4-channel VOF is active when asking for 3 or 4 channels.

pfuIsImpact is a boolean expression that determines the GFX hardware type. It returns 0 for FALSE, and 1 for TRUE.

pfuGetMCOChannels calls pfuIsImpact and then pfuGetICOChannels, if required.

pfuConfigMCO calls pfuIsImpact and then pfuConfigICO, if required. Thus, the MCO routines are more portable; use them unless you intend your application only for IMPACT/ICO.

Performer Programming Example

 /*
 * Copyright 1996, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
 * the contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
 * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
 * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
 * rights reserved under the Copyright Laws of the United States.
 */

#include <stdlib.h>
#include <Performer/pf.h>
#include <Performer/pfutil.h>
#include <Performer/pfdu.h>

static void OpenPipeWin(pfPipeWindow *pw);
static void DrawChannel(pfChannel *chan, void *data);

/*
 *   Usage() -- print usage advice and exit. This
 *   procedure is executed in the application process.
 */
static void
Usage (void)
{
  pfNotify(PFNFY_FATAL, PFNFY_USAGE, “Usage: multichan file.ext ..\n”);
  exit(1);
}

static int maxChan = 0;

int
main (int argc, char *argv[])
{
    float           t = 0.0f;
    pfScene         *scene;
    pfPipe          *p;
    pfPipeWindow    *pw;
    /* MCO does 6 channels max; ICO does 4 channels max */
    pfChannel       *chan[6];
    pfNode          *root=NULL;
    pfSphere        bsphere;
    int             loop;
    char            str[PF_MAXSTRING];
    pfFrameStats    *fstats;

    if (argc < 2)
        Usage();

    /* Initialize Performer */
    pfInit();
    pfuInitUtil();

    /* Use default multiprocessing mode based on no. of processors.*/
    pfMultiprocess(PFMP_DEFAULT);

    /* Load all loader DSOs before pfConfig() forks */
    pfdInitConverter(argv[1]);

    /* Configure multiprocessing mode and start parallel
     * processes.
     */
    pfConfig();

    /* Attach loaded file to a pfScene. */
    scene = pfNewScene();

    /* Append to PFPATH additional standard directories where 
     * geometry and textures exist 
     */
    pfFilePath(“.:/usr/share/Performer/data”);

    /* Read a single file, of any known type. */
    if ((root = pfdLoadFile(argv[1])) == NULL) 
    {
        pfExit();
        exit(-1);
    }

    /* determine extent of scene's geometry */
    pfGetNodeBSphere (root, &bsphere);
    pfAddChild(scene, root);

    /* Create a pfLightSource and attach it to scene. */
    pfAddChild(scene, pfNewLSource());

    /* Configure and open GL window */
    p = pfGetPipe(0);
    pw = pfNewPWin(p);
    sprintf(str, “IRIS Performer”);
    pfPWinName(pw, str);
    pfPWinFullScreen(pw);
    pfPWinConfigFunc(pw, OpenPipeWin);
    pfConfigPWin(pw);
    
    /* Create and configure pfChannel(s). */
    maxChan = pfuGetMCOChannels(p);
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, “detected %d active channels”,
                            maxChan);
    /*
    ** You can also use pfuGetICOChannels(p);
    ** if you will run the program only on IMPACT/ICO systems.
    ** pfuGetMCOChannels will call pfuGetICOChannels internally
    ** if required and is thus more general.  pfuGetICOChannels will 
    ** correctly handle the case of IMPACT without an ICO.
    **
    ** Use pfuIsImpact() to determine if the GFX hardware is IMPACT.
    ** It returns 1 if true or 0 if false.
    */
    for (loop=0; loop < maxChan; loop++)
    {
        chan[loop] = pfNewChan(p);
        /*  
        **  Make chan[0] the channel group master; since we don't set a 
        **  view offset, they'll all look at the same thing.
        */
        if (loop)
        {
            pfAttachChan(chan[0], chan[loop]);
        }
        else
        {
            pfChanTravFunc(chan[loop], PFTRAV_DRAW, DrawChannel);
            pfChanScene(chan[loop], scene);
            pfChanNearFar(chan[loop], 1.0f, 10.0f * bsphere.radius);
            pfChanFOV(chan[loop], 45.0f, 0.0f);
        }
        fstats = pfGetChanFStats(chan[loop]);
        pfFStatsClass(fstats, PFSTATS_ENGFX, PFSTATS_ON);
    }

/*now set channel viewports appropriately for active VOF */
pfuConfigMCO(chan, maxChan);
/*
** You can also use pfuConfigICO(chan, maxChan);
** if you're sure you're on an IMPACT/ICO.
** pfuConfigMCO checks internally to see if it's running on
** IMPACT/ICO and calls pfuConfigICO if so....
** Thus pfuConfigMCO is more general with almost zero overhead.
*/

/* Simulate for twenty seconds. */
while (t < 20.0f)
{
    float      s, c;
    pfCoord	    view;

    /* Go to sleep until next frame time. */
    pfSync();

    /* Compute new view position. */
    t = pfGetTime();
    pfSinCos(45.0f*t, &s, &c);
    pfSetVec3(view.hpr, 45.0f*t, -10.0f, 0);
    pfSetVec3(view.xyz, 2.0f * bsphere.radius * s, 
             -2.0f * bsphere.radius *c, 
             0.5f * bsphere.radius);

    for (loop=0; loop < maxChan; loop++)
    {
         pfChanView(chan[loop], view.xyz, view.hpr);
         /*pfDrawChanStats(chan[loop]);*/
    }
    /* Initiate cull/draw for this frame. */
    pfFrame();
}

/* Terminate parallel processes and exit. */
pfExit();

return 0;
}


/*
 * OpenPipeWin() -- create a GL window: set up the window system, 
 * IRIS GL, and IRIS Performer. This procedure is executed 
 * for each window in the draw process for that pfPipe.
 */

static void
OpenPipeWin(pfPipeWindow *pw)
{
    pfLight *Sun;
    
    pfOpenPWin(pw);

    /* Create a light source in the “south-west” (QIII). */
    Sun = pfNewLight(NULL);
    pfLightPos(Sun, -0.3f, -0.3f, 1.0f, 0.0f);
}

static void
DrawChannel (pfChannel *channel, void *data)
{

    static pfVec4 clr[] = {{1.0f, 0.0f, 0.0f, 1.0f},
                          {0.0f, 1.0f, 0.0f, 1.0f},
                          {0.0f, 0.0f, 1.0f, 1.0f},
                          {1.0f, 1.0f, 1.0f, 1.0f}};
    static int i=0;

    /* Erase framebuffer and draw Earth-Sky model. */
    pfClear(PFCL_COLOR | PFCL_DEPTH, clr[i]);
    i++;
    if (i == maxChan) i = 0;
    
    /* Invoke Performer draw-processing for this frame. */
    pfDraw();

}