Odd mode list

I’ve got a simple C program appended, which we can run on a couple of
machines with no problem, but of course when we run it on >mine<, we’re
getting some funky results.

My machine is a p3 500mz with Voodoo3, runs Photon fine.

Here is the command I’m running:
modetest -Ddevg-banshee.so -I0 -d0x121a,0x0005

Here is the output of modetest:
Opening [devg-banshee.so]
PCI device parameters:
bus = 0x0
vendor = 0x121A
device = 0x5
Valid display modes:
0x804: -1338924742x-1338721044, 8 bpp
0x804: -1338924742x-1338721044, 16 bpp
0x804: -1338924742x-1338721044, 24 bpp
0x804: -1338924742x-1338721044, 32 bpp

Here is output of crttrap trap:
/usr/photon/bin/devgt-iographics -dldevg-banshee.so -I0 -d0x121a,0x0005
/usr/photon/bin/devgt-iographics -dldevg-vesabios.so -I0 -d0x121a,0x0005
crttrap: wrote config file as /etc/system/config/graphics-modes

Obviously the dimensions are a bit off :slight_smile:

What’d we do wrong?

Patrick_Mueller@oti.com

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <malloc.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <graphics/display.h>

typedef struct {
char dll[80];
int pciBus;
int pciVendorID;
int pciDeviceID;
} GraphicsDeviceOptions;

typedef int (*f_mode) (disp_adapter_t *ctx, disp_modefuncs_t *fns, int
tabsize);

static void parseCommandLine(int argc, char **argv, GraphicsDeviceOptions
*options) {
int c, pci = 0;
char *token, tmp[80];

while((c = getopt( argc, argv, “D:I:d:” )) != -1) {

switch (c) {

case ‘D’:
//printf("%s\n", optarg);
strcpy(options->dll, optarg);
break;

case ‘I’:
//printf("%s\n", optarg);
options->pciBus = atoi(optarg);
pci = 1;
break;

case ‘d’:
//printf("%s\n", optarg);
strcpy(tmp, optarg);

token = strtok(tmp, “,”);
if (token == NULL) {
printf(“Invalid device and vendor IDs.\n”);
exit(1);
}
options->pciVendorID = atoh(&token[2]);
token = NULL;

token = strtok(NULL, “,”);
if (token == NULL) {
printf(“Invalid device and vendor IDs.\n”);
exit(1);
}
options->pciDeviceID = atoh(&token[2]);
token = NULL;
break;

default:
exit(1);
}
}

if (!pci) {
options->pciBus = -1;
options->pciVendorID = -1;
options->pciDeviceID = -1;
}
}

static void printModes(GraphicsDeviceOptions *options) {
f_mode mode;
disp_modefuncs_t mode_funcs;
disp_adapter_t adapter;
void *dll;
int size = 50, i = 0, rc;
disp_mode_t *list;
disp_mode_info_t info;

memset(&adapter, 0, sizeof(disp_adapter_t));

printf(“Opening [%s]\n”, options->dll);

if (options->pciBus != -1) {
printf(“PCI device parameters:\n”);
adapter.bus.pci.pci_index = options->pciBus;
adapter.bus.pci.pci_vendor_id = options->pciVendorID;
adapter.bus.pci.pci_device_id = options->pciDeviceID;
printf(“bus = 0x%X\n”, options->pciBus);
printf(“vendor = 0x%X\n”, options->pciVendorID);
printf(“device = 0x%X\n”, options->pciDeviceID);
}

dll = dlopen(options->dll, 0);
if (NULL == dll) {
printf(“dlopen() error: %s\n”, dlerror());
return;
}

mode = (f_mode)dlsym(dll, “devg_get_modefuncs”);
if (NULL == mode) {
printf(“Error getting symbol devg_get_modefuncs: %s\n”,
dlerror());
return;
}
rc = mode(&adapter, &mode_funcs, sizeof(disp_modefuncs_t));
if (-1 == rc) {
printf(“Error calling devg_get_modefuncs\n”);
return;
}

rc = mode_funcs.init(&adapter, NULL);
if (-1 == rc) {
printf(“Error calling mode_funcs.init()\n”);
fflush(stdout);
return;
}

list = calloc(size, sizeof(disp_mode_t));

mode_funcs.get_modelist(&adapter, 0, list, 0, size);

printf(“Valid display modes:\n”);
while (list _!= DISP_MODE_LISTEND) {
mode_funcs.get_modeinfo(&adapter, 0, list, &info);
printf(“0x%X: %dx%d, %d bpp\n”, info.mode, info.xres, info.yres,
DISP_BITS_PER_PIXEL(info.pixel_format));
i++;
}

free(list);

mode_funcs.fini(&adapter);
}

int main(int argc, char **argv) {
GraphicsDeviceOptions options;

if (ThreadCtl(NTO_TCTL_IO, 0) == -1) {
perror(“ThreadCtl”);
exit(1);
}

if (argc > 1) {
parseCommandLine(argc, argv, &options);
printModes(&options);
}
else {
printf(“Invalid command line.\n”);
}

return 0;
}

Patrick Mueller <patrick_mueller@oti.com> wrote:
: I’ve got a simple C program appended, which we can run on a couple of
: machines with no problem, but of course when we run it on >mine<, we’re
: getting some funky results.

: My machine is a p3 500mz with Voodoo3, runs Photon fine.

: Here is the command I’m running:
: modetest -Ddevg-banshee.so -I0 -d0x121a,0x0005

: Here is the output of modetest:
: Opening [devg-banshee.so]
: PCI device parameters:
: bus = 0x0
: vendor = 0x121A
: device = 0x5
: Valid display modes:
: 0x804: -1338924742x-1338721044, 8 bpp
: 0x804: -1338924742x-1338721044, 16 bpp
: 0x804: -1338924742x-1338721044, 24 bpp
: 0x804: -1338924742x-1338721044, 32 bpp

: Here is output of crttrap trap:
: /usr/photon/bin/devgt-iographics -dldevg-banshee.so -I0 -d0x121a,0x0005
: /usr/photon/bin/devgt-iographics -dldevg-vesabios.so -I0 -d0x121a,0x0005
: crttrap: wrote config file as /etc/system/config/graphics-modes

: Obviously the dimensions are a bit off :slight_smile:

: What’d we do wrong?


The reason that your program ran correctly on some machines and not on your
machine with the Voodoo3 is that the devg-banshee.so driver uses a direct
modeswither and therefore has a “generic” set of resolutions.

Many of our drivers, particularily for older cards, use the video BIOS to
get the modelist, modeinfo and to set the video mode. These drivers will
report back a nice mode list and table of resolutions and color depths.
However a number of drivers, including devg-banshee.so, use a direct
modeswitcher and therefore use a standard set of resolutions. (currently
1600x1200, 1280x1024, 1152x864, 1024x768, 800x600, 640x480) The get_modeinfo
function does not report the xres and yres directly, instead the flag
DISP_MODE_GENERIC is set to indicate the standard resolutions should be used.
(see mode.c of the banshee driver in the graphics DDK)

The modelist returned in these drivers (from get_modelist) has the supported
color depths “encoded”. (again see mode.c in banshee driver)

I have added some lines to your code below to check for the DISP_MODE_GENERIC
flag and if set to display the supported resolutions and color depths.

The DISP_MODE_GENERIC flag is mentioned in the documention of the graphics DDK
under the disp_mode_info_t structure.

Hopefully this helps you. I will see if we can get this scenario documented
more clearly.



: –
: ----------------------------------------------------
: Patrick_Mueller@oti.com
: ----------------------------------------------------

: #include <stdio.h>
: #include <stdlib.h>
: #include <string.h>
: #include <dlfcn.h>
: #include <malloc.h>
: #include <unistd.h>
: #include <pthread.h>
: #include <fcntl.h>
: #include <errno.h>
: #include <sys/neutrino.h>
: #include <graphics/display.h>

: typedef struct {
: char dll[80];
: int pciBus;
: int pciVendorID;
: int pciDeviceID;
: } GraphicsDeviceOptions;

: typedef int (*f_mode) (disp_adapter_t *ctx, disp_modefuncs_t *fns, int
: tabsize);

: static void parseCommandLine(int argc, char **argv, GraphicsDeviceOptions
: *options) {
: int c, pci = 0;
: char *token, tmp[80];

: while((c = getopt( argc, argv, “D:I:d:” )) != -1) {

: switch (c) {

: case ‘D’:
: //printf("%s\n", optarg);
: strcpy(options->dll, optarg);
: break;

: case ‘I’:
: //printf("%s\n", optarg);
: options->pciBus = atoi(optarg);
: pci = 1;
: break;

: case ‘d’:
: //printf("%s\n", optarg);
: strcpy(tmp, optarg);

: token = strtok(tmp, “,”);
: if (token == NULL) {
: printf(“Invalid device and vendor IDs.\n”);
: exit(1);
: }
: options->pciVendorID = atoh(&token[2]);
: token = NULL;

: token = strtok(NULL, “,”);
: if (token == NULL) {
: printf(“Invalid device and vendor IDs.\n”);
: exit(1);
: }
: options->pciDeviceID = atoh(&token[2]);
: token = NULL;
: break;

: default:
: exit(1);
: }
: }

: if (!pci) {
: options->pciBus = -1;
: options->pciVendorID = -1;
: options->pciDeviceID = -1;
: }
: }

: static void printModes(GraphicsDeviceOptions *options) {
: f_mode mode;
: disp_modefuncs_t mode_funcs;
: disp_adapter_t adapter;
: void *dll;
: int size = 50, i = 0, rc;
: disp_mode_t *list;
: disp_mode_info_t info;


int j, bpp;
static int xres[] = { 640, 800, 1024, 1152, 1280, 1600 };
static int yres[] = { 480, 600, 768, 864, 1024, 1200 };


: memset(&adapter, 0, sizeof(disp_adapter_t));

: printf(“Opening [%s]\n”, options->dll);

: if (options->pciBus != -1) {
: printf(“PCI device parameters:\n”);
: adapter.bus.pci.pci_index = options->pciBus;
: adapter.bus.pci.pci_vendor_id = options->pciVendorID;
: adapter.bus.pci.pci_device_id = options->pciDeviceID;
: printf(“bus = 0x%X\n”, options->pciBus);
: printf(“vendor = 0x%X\n”, options->pciVendorID);
: printf(“device = 0x%X\n”, options->pciDeviceID);
: }

: dll = dlopen(options->dll, 0);
: if (NULL == dll) {
: printf(“dlopen() error: %s\n”, dlerror());
: return;
: }

: mode = (f_mode)dlsym(dll, “devg_get_modefuncs”);
: if (NULL == mode) {
: printf(“Error getting symbol devg_get_modefuncs: %s\n”,
: dlerror());
: return;
: }
: rc = mode(&adapter, &mode_funcs, sizeof(disp_modefuncs_t));
: if (-1 == rc) {
: printf(“Error calling devg_get_modefuncs\n”);
: return;
: }

: rc = mode_funcs.init(&adapter, NULL);
: if (-1 == rc) {
: printf(“Error calling mode_funcs.init()\n”);
: fflush(stdout);
: return;
: }

: list = calloc(size, sizeof(disp_mode_t));


list[0]=DISP_MODE_LISTEND;


: mode_funcs.get_modelist(&adapter, 0, list, 0, size);

: printf(“Valid display modes:\n”);
: while (list _!= DISP_MODE_LISTEND) {

if(mode_funcs.get_modeinfo(&adapter, 0, list, &info)!=-1){

bpp = DISP_BITS_PER_PIXEL(info.pixel_format);
if (info.pixel_format == DISP_SURFACE_FORMAT_ARGB1555)
bpp = 15; /* To distinguish from 16bpp */

if (info.flags & DISP_MODE_GENERIC) {
for (j = 0; j < sizeof (xres) / sizeof (xres[0]); j++) {
printf("%dx%d %d\n", xres[j], yres[j], bpp);
}
} else{
printf(“0x%X: %dx%d, %d bpp\n”, info.mode, info.xres,
info.yres, DISP_BITS_PER_PIXEL(info.pixel_format));
}
i++;
}
}


: free(list);

: mode_funcs.fini(&adapter);
: }

: int main(int argc, char **argv) {
: GraphicsDeviceOptions options;

: if (ThreadCtl(NTO_TCTL_IO, 0) == -1) {
: perror(“ThreadCtl”);
: exit(1);
: }

: if (argc > 1) {
: parseCommandLine(argc, argv, &options);
: printModes(&options);
: }
: else {
: printf(“Invalid command line.\n”);
: }

: return 0;
: }