From: James S. <jsi...@su...> - 2001-01-16 19:22:55
|
Hi folks!! Since 2.4 is now out and the new console system is becoming stable its time to discuss the new api for fbcon again. I updated skeletonfb for a example and posted here. Feel free to addd input to the design. /* * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device * * Modified to new api Jan 2001 by James Simmons (jsi...@li...) * * Created 28 Dec 1997 by Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/mm.h> #include <linux/tty.h> #include <linux/malloc.h> #include <linux/delay.h> #include <linux/fb.h> #include <linux/init.h> /* This header contains struct xxx_par for your graphics card */ #include <video/skeletion.h> /* * This is just simple sample code. * * No warranty that it actually compiles. * Even less warranty that it actually works :-) */ static struct fb_fix_screeninfo xxxfb_fix __initdata = { "FB's name", (unsigned long) NULL, 0, FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 1, 1, 1, 0, (unsigned long) NULL, 0, FB_ACCEL_NONE }; /* * Modern graphical hardware not only supports pipelines but some * also support multiple monitors where each display can have its * its own unique data. In this case each display could be * represented by a seperate framebuffer device thus a seperate * struct fb_info. In this case all of the par structures for the * graphics card would be shared between each struct fb_info. This * allows when one display changes it video resolution (info->var) * the other displays know instantly. Each display can always be * aware of the entire hardware state that affects it. I hope this * covers every possible hardware design. If not feel free to send * me more design types. */ /* * If your driver supports multiple boards, you should make these * arrays, or allocate them dynamically (using kmalloc()). */ static struct fb_info info; /* * This struct represents the state of a rendering pipe. A modern * graphics card can have more than one pipe per card depending * on the hardware design. So the same holds true if you have * multiple pipes. Use arrays or allocate them dynamically. * * Read video/skeleton.h for more information about graphics pipes. */ static struct xxx_par __initdata current_par; static u32 xxxfb_pseudo_palette[17]; static int inverse = 0; int xxxfb_init(void); int xxxfb_setup(char*); /* ------------------- chipset specific functions -------------------------- */ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { const struct xxx_par *par = (const struct xxx_par *) info->par; /* * We test to see if the hardware can support var. Struct xxx_par will * have the information needed to see if it does. Note we don't change * par nor info->var. This function can be called on its own if we * intent to only test a mode and not set it. Return 0 if it is a * acceptable mode. */ /* ... */ return 0; } static void xxxfb_set_par(struct fb_info *info) { /* * xxx_fb_check_var tested the mode we want to set the hardware to. * If it passes it then is set to info->var. Now we set the hardware * (and struct par) according to info->var. */ /* ... */ } /* * Set a single color register. The values supplied have a 16 bit * magnitude. Return != 0 for invalid regno. This routine assumes * your graphics hardware is packed pixel based (most are :-). * Return != 0 for invalid regno. */ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, const struct fb_info *info) { if (regno >= 256) /* no. of hw registers */ return 1; /* * Program hardware... do anything you want with transp */ /* grayscale works only partially under directcolor */ if (info->var.grayscale) { /* grayscale = 0.30*R + 0.59*G + 0.11*B */ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; } /* Directcolor: * var->{color}.offset contains start of bitfield * var->{color}.length contains length of bitfield * {hardwarespecific} contains width of DAC * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) * DAC[X] is programmed to (red, green, blue) * * Pseudocolor: * uses offset = 0 && length = DAC register width. * var->{color}.offset is 0 * var->{color}.length contains widht of DAC * cmap is not used * DAC[X] is programmed to (red, green, blue) * Truecolor: * does not use DAC. * var->{color}.offset contains start of bitfield * var->{color}.length contains length of bitfield * cmap is programmed to (red << red.offset) | (green << green.offset) | * (blue << blue.offset) | (transp << transp.offset) * DAC does not exist */ #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) switch (info->fix.visual) { case FB_VISUAL_TRUECOLOR: case FB_VISUAL_PSEUDOCOLOR: red = CNVT_TOHW(red, info->var.red.length); green = CNVT_TOHW(green, info->var.green.length); blue = CNVT_TOHW(blue, info->var.blue.length); transp = CNVT_TOHW(transp, info->var.transp.length); break; case FB_VISUAL_DIRECTCOLOR: /* example here assumes 8 bit DAC. Might be different * for your hardware */ red = CNVT_TOHW(red, 8); green = CNVT_TOHW(green, 8); blue = CNVT_TOHW(blue, 8); /* hey, there is bug in transp handling... */ transp = CNVT_TOHW(transp, 8); break; } #undef CNVT_TOHW /* Truecolor has hardware independent palette */ if (info->fix.visual == FB_VISUAL_TRUECOLOR) { u32 v; if (regno >= 16) return 1; v = (red << info->var.red.offset) | (green << info->var.green.offset) | (blue << info->var.blue.offset) | (transp << info->var.transp.offset); if (info->var.bits_per_pixel == 16) ((u16*)(info->pseudo_palette))[regno] = v; else ((u32*)(info->pseudo_palette))[regno] = v; return 0; } /* ... */ return 0; } static int xxxfb_pan_display(struct fb_var_screeninfo *var, const struct fb_info *info) { /* * Pan (or wrap, depending on the `vmode' field) the display using the * `xoffset' and `yoffset' fields of the `var' structure. * If the values don't fit, return -EINVAL. */ /* ... */ return 0; } static int xxxfb_blank(int blank_mode, const struct fb_info *info) { /* * Blank the screen if blank_mode != 0, else unblank. If blank == NULL * then the caller blanks by setting the CLUT (Color Look Up Table) to all * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due * to e.g. a video mode which doesn't support it. Implements VESA suspend * and powerdown modes on hardware that supports disabling hsync/vsync: * blank_mode == 2: suspend vsync * blank_mode == 3: suspend hsync * blank_mode == 4: powerdown */ /* ... */ return 0; } /* ------------ Accelerated Functions --------------------- */ /* * We provide our own functions if we have hardware acceleration * or non packed pixel format layouts. */ void xxxfb_rectfill(struct fb_info *p, int x1, int y1, unsigned int width, unsigned int height, unsigned long color, int rop) { } void xxxfb_copyarea(struct fb_info *p, int sx, int sy, unsigned int width, unsigned int height, int dx, int dy) { } void xxxfb_imageblit(struct fb_info *p, unsigned int width, unsigned int height, unsigned long *image, int image_depth, int dx, int dy) { } /* ------------ Hardware Independent Functions ------------ */ /* * Initialization */ int __init xxxfb_init(void) { int retval; /* * Here we set the screen_base to the vitrual memory address * for the framebuffer. Usually we obtain the resource address * from the bus layer and then translate it to virtual memory * space via ioremap. Consult ioport.h. */ info.screen_base = framebuffer_virtual_memory; info.node = -1; info.fbops = &xxxfb_ops; info.fix = xxxfb_fix; info.par = xxx_par; info.pseudo_palette = xxxfb_pseudo_palette; info.flags = FBINFO_FLAG_DEFAULT; /* This should give a reasonable default video mode */ if (!mode_option) mode_option = "640x480@60"; retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8); if (!retval || retval == 4) return -EINVAL; info.cmap = fb_default_cmap(1<<info.var.bits_per_pixel); if (register_framebuffer(&info) < 0) return -EINVAL; printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(info.node), info.fix.id); /* uncomment this if your driver cannot be unloaded */ /* MOD_INC_USE_COUNT; */ return 0; } /* * Cleanup */ void xxxfb_cleanup(struct fb_info *info) { /* * If your driver supports multiple boards, you should unregister and * clean up all instances. */ unregister_framebuffer(info); /* ... */ } /* * Setup */ int __init xxxfb_setup(char *options) { /* Parse user speficied options (`video=xxxfb:') */ } /* ------------------------------------------------------------------------- */ /* * Frame buffer operations */ /* If all you need is that - just don't define ->fb_open */ static int xxxfb_open(const struct fb_info *info, int user) { return 0; } /* If all you need is that - just don't define ->fb_release */ static int xxxfb_release(const struct fb_info *info, int user) { return 0; } static struct fb_ops xxxfb_ops = { owner: THIS_MODULE, fb_open: xxxfb_open, /* only if you need it to do something */ fb_release: xxxfb_release, /* only if you need it to do something */ fb_check_var: xxxfb_check_var, fb_set_par: xxxfb_set_par, fb_setcolreg: xxxfb_setcolreg, fb_blank: xxxfb_blank, fb_pan_display: xxxfb_pan_display, fb_rectfill: xxxfb_rectfill, /* optional */ fb_copyarea: xxxfb_copyarea, /* optional */ fb_imageblit: xxxfb_imageblit, /* optional */ fb_ioctl: xxxfb_ioctl, /* optional */ fb_mmap: xxxfb_mmap, /* optional */ }; /* ------------------------------------------------------------------------- */ /* * Modularization */ #ifdef MODULE int init_module(void) { return xxxfb_init(); } void cleanup_module(void) { xxxfb_cleanup(void); } #endif /* MODULE */ /* * linux/include/video/skeletonfb.h -- example graphics header. See other * files in that directory. * * Copyright 2001 James Simmons (jsi...@li...) * * This files is designed to be independent of the fbdev layer. This header * is provided so userland applications can have a standard set of headers * to program graphics hardware with as well as other kernel subsystems * that need to program the video hardware. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. * */ struct xxx_par { /* * The hardware specific data in this structure uniquely defines a * graphics card pipe's state. What is a graphics pipe and a * graphics pipeline ? The automotive assembly line is a classic * example of a pipeline. Each car goes through a series of stages * on its way to the exit gates. At any given time many cars could * be in some stage of completion. Each stage is know as a pipe. * Rendering can also function in the same way. For rendering each * stage must be performed in a specific order but each stage itself * can operate independent of the previous stage because each stage * stage can operate on a different set of data sent to the graphics * card. This allows several rendering operations to occur at the * same time. * * Todays hardware comes in a variety of setups. With this variety * comes different ways pipes can exist. Most low end graphical * cards lack a graphics pipeline. It can be thought of as a * assembly line with only one car allowed on it at a time. Some * hardware exist where the cards have more than one GPU (graphical * processing unit). If each GPU can have different hardware states * that are independent of each other then each CPU has a single * pipe and they can work as a pipeline. Also their exist hardware * where you can chain video cards together and feed them to one * display device. Here each video card acts as a seperate pipe * and we can achieve a pipeline effect. Be aware it might be * possible to disable and enable individual pipes. */ }; |
From: Pete Z. <za...@me...> - 2001-01-16 20:06:06
|
> Since 2.4 is now out and the new console system is becoming stable its > time to discuss the new api for fbcon again. I updated skeletonfb for a > example and posted here. Feel free to addd input to the design. Would you provide an executive summary of undelying reasons for the changes? For instance, "To remove race conditions inherent in the old API around functions such-and-such", or "to reduce complexity implementing feature this-and-athat". I cannot easily understand what you are trying to accomplish. -- Pete |
From: James S. <jsi...@su...> - 2001-01-16 21:14:41
|
On Tue, 16 Jan 2001, Pete Zaitcev wrote: > > Since 2.4 is now out and the new console system is becoming stable its > > time to discuss the new api for fbcon again. I updated skeletonfb for a > > example and posted here. Feel free to addd input to the design. > > Would you provide an executive summary of undelying reasons > for the changes? For instance, "To remove race conditions > inherent in the old API around functions such-and-such", > or "to reduce complexity implementing feature this-and-athat". > I cannot easily understand what you are trying to accomplish. The main reason was to remove all the console related stuff of the fbdev drivers. The reasons for this was: 1) If changes or important bug fixes where to happen to the higher fbcon layers every fbdev driver would have to be changed. With the new api if changes happen to fbcon.c and friends we don't have to rewrite every fbdev driver. 2) Make driver developement easier. 3) Alot of the console code in each fbdev driver is basically the same. So we have huge amounts of code duplication. |
From: Takashi Oe <to...@un...> - 2001-01-16 20:54:42
|
On 1/16/01 1:23 PM, James Simmons wrote: > > Hi folks!! > > Since 2.4 is now out and the new console system is becoming stable its > time to discuss the new api for fbcon again. I updated skeletonfb for a > example and posted here. Feel free to addd input to the design. [...] > /* > * Set a single color register. The values supplied have a 16 bit > * magnitude. Return != 0 for invalid regno. This routine assumes > * your graphics hardware is packed pixel based (most are :-). > * Return != 0 for invalid regno. > */ > static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, > unsigned blue, unsigned transp, > const struct fb_info *info) Could there be a multiple color version as well? For 2.4, I have my own fb_set_cmap to do that since a cmap access requires a synchronization with vsync for the first one on my machine, and I don't want to do the synchronization for every cmap change. Want to do: - vsync - multiple cmap change rather than: - vsync - a cmap change - vsync - a cmap change - .... If there is a way to override fb_set_cmap (or a new api's equivalent) calling setcolreg, that would be okay, too. [...] > info.pseudo_palette = xxxfb_pseudo_palette; How is this psuedo_palette used for new api? Takashi Oe |
From: James S. <jsi...@su...> - 2001-01-16 21:42:54
|
> > /* > > * Set a single color register. The values supplied have a 16 bit > > * magnitude. Return != 0 for invalid regno. This routine assumes > > * your graphics hardware is packed pixel based (most are :-). > > * Return != 0 for invalid regno. > > */ > > static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, > > unsigned blue, unsigned transp, > > const struct fb_info *info) > > Could there be a multiple color version as well? For 2.4, I have my own > fb_set_cmap to do that since a cmap access requires a synchronization with > vsync for the first one on my machine, and I don't want to do the > synchronization for every cmap change. > > Want to do: > - vsync > - multiple cmap change > rather than: > - vsync > - a cmap change > - vsync > - a cmap change > - .... > > If there is a way to override fb_set_cmap (or a new api's equilvalent) > calling setcolreg, that would be okay, too. Hum. I would prefere a setcolreg solution more. fb_set_cmap in fbcmap.c is more for grabbing the info from userland then setting the hardware. > [...] > > info.pseudo_palette = xxxfb_pseudo_palette; > > How is this psuedo_palette used for new api? It is actually for the higher up fbcon layer. Traditional VTs only had psuedocolor modes so we have to fake it for video modes that don't have color maps. We can do things like: bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]; Personally I hate it and wish their was another way around this. |
From: Geert U. <ge...@li...> - 2001-01-17 08:34:47
|
On Tue, 16 Jan 2001, James Simmons wrote: > > How is this psuedo_palette used for new api? > > It is actually for the higher up fbcon layer. Traditional VTs only had > psuedocolor modes so we have to fake it for video modes that don't have > color maps. We can do things like: > > bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]; ^^^^^^^^^^^^^^ info->pseudo_palette > > Personally I hate it and wish their was another way around this. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li... In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds |
From: Geert U. <ge...@li...> - 2001-01-17 08:34:21
|
On Tue, 16 Jan 2001, Takashi Oe wrote: > On 1/16/01 1:23 PM, James Simmons wrote: > > Since 2.4 is now out and the new console system is becoming stable its > > time to discuss the new api for fbcon again. I updated skeletonfb for a > > example and posted here. Feel free to addd input to the design. > > [...] > > /* > > * Set a single color register. The values supplied have a 16 bit > > * magnitude. Return != 0 for invalid regno. This routine assumes > > * your graphics hardware is packed pixel based (most are :-). > > * Return != 0 for invalid regno. > > */ > > static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, > > unsigned blue, unsigned transp, > > const struct fb_info *info) > > Could there be a multiple color version as well? For 2.4, I have my own > fb_set_cmap to do that since a cmap access requires a synchronization with > vsync for the first one on my machine, and I don't want to do the > synchronization for every cmap change. > > Want to do: > - vsync > - multiple cmap change > rather than: > - vsync > - a cmap change > - vsync > - a cmap change > - .... > > If there is a way to override fb_set_cmap (or a new api's equivalent) > calling setcolreg, that would be okay, too. Can't you buffer the xxxfb_setcolreg() calls and execute them in the vsync interrupt handler? Busy waiting until vsync is a bad idea. > > info.pseudo_palette = xxxfb_pseudo_palette; > > How is this psuedo_palette used for new api? I'm wondering as well. Fbcon-* is going away in favor of the `accels', right? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li... In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds |
From: Takashi Oe <to...@un...> - 2001-01-17 15:19:25
|
On 1/17/01 2:33 AM, Geert Uytterhoeven wrote: > On Tue, 16 Jan 2001, Takashi Oe wrote: >> Could there be a multiple color version as well? For 2.4, I have my own >> fb_set_cmap to do that since a cmap access requires a synchronization with >> vsync for the first one on my machine, and I don't want to do the >> synchronization for every cmap change. >> [...] > Can't you buffer the xxxfb_setcolreg() calls and execute them in the vsync > interrupt handler? Busy waiting until vsync is a bad idea. Yes, the vsync irq handler is the way it's done currently for one fb. Howerver, there is another regrettably more popular fb with the same requirement without the vsync irq routed to cpu; that is, the busy waiting seems to be the only way.... Takashi Oe |
From: James S. <jsi...@su...> - 2001-01-17 20:11:31
|
> On 1/17/01 2:33 AM, Geert Uytterhoeven wrote: > > > On Tue, 16 Jan 2001, Takashi Oe wrote: > >> Could there be a multiple color version as well? For 2.4, I have my own > >> fb_set_cmap to do that since a cmap access requires a synchronization with > >> vsync for the first one on my machine, and I don't want to do the > >> synchronization for every cmap change. > >> > [...] > > Can't you buffer the xxxfb_setcolreg() calls and execute them in the vsync > > interrupt handler? Busy waiting until vsync is a bad idea. > > Yes, the vsync irq handler is the way it's done currently for one fb. > Howerver, there is another regrettably more popular fb with the same > requirement without the vsync irq routed to cpu; that is, the busy waiting > seems to be the only way.... Okay. This answered my previous question. It pretty much comes down to choosing between xxxfb_setcolreg or xxxfb_set_cmap. Their are pros and cons to having each: xxxfb_setcolreg PRO: can change a individual register without having to monkey with the entire CLUT. CONS: Hardware designs. Some hardware require vsync when changing the color palette. xxxfb_set_cmap PRO: More flexiable with bizarre hardware. Also works nice with hardware that has more than one CLUT. In this case we can cache a bunch of color maps and switch the index around. CONS: Can't change a subset of teh CLUT table easily. |
From: James S. <jsi...@su...> - 2001-01-17 19:56:38
|
> > If there is a way to override fb_set_cmap (or a new api's equivalent) > > calling setcolreg, that would be okay, too. > > Can't you buffer the xxxfb_setcolreg() calls and execute them in the vsync > interrupt handler? Busy waiting until vsync is a bad idea. This is a good idea but what if we run into hardware where you have to poll a bit for a vbl that requires this :-( Does such hardware exist? > > > info.pseudo_palette = xxxfb_pseudo_palette; > > > > How is this psuedo_palette used for new api? > > I'm wondering as well. Fbcon-* is going away in favor of the `accels', right? It should be going away. We need a cleaner way to translate from VT emulated psuedo palette to native color handling. |
From: Geert U. <ge...@li...> - 2001-01-17 08:32:31
|
On Tue, 16 Jan 2001, James Simmons wrote: > Since 2.4 is now out and the new console system is becoming stable its > time to discuss the new api for fbcon again. I updated skeletonfb for a > example and posted here. Feel free to addd input to the design. > > /* > * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device > * > * Modified to new api Jan 2001 by James Simmons (jsi...@li...) > * > * Created 28 Dec 1997 by Geert Uytterhoeven > * > * This file is subject to the terms and conditions of the GNU General Public > * License. See the file COPYING in the main directory of this archive > * for more details. > */ > > #include <linux/module.h> > #include <linux/kernel.h> > #include <linux/errno.h> > #include <linux/string.h> > #include <linux/mm.h> > #include <linux/tty.h> > #include <linux/malloc.h> > #include <linux/delay.h> > #include <linux/fb.h> > #include <linux/init.h> > > /* This header contains struct xxx_par for your graphics card */ > #include <video/skeletion.h> > > /* > * This is just simple sample code. > * > * No warranty that it actually compiles. > * Even less warranty that it actually works :-) > */ > > static struct fb_fix_screeninfo xxxfb_fix __initdata = { > "FB's name", (unsigned long) NULL, 0, FB_TYPE_PACKED_PIXELS, 0, > FB_VISUAL_PSEUDOCOLOR, 1, 1, 1, 0, (unsigned long) NULL, 0, FB_ACCEL_NONE > }; > > /* > * Modern graphical hardware not only supports pipelines but some > * also support multiple monitors where each display can have its > * its own unique data. In this case each display could be > * represented by a seperate framebuffer device thus a seperate > * struct fb_info. In this case all of the par structures for the > * graphics card would be shared between each struct fb_info. This > * allows when one display changes it video resolution (info->var) > * the other displays know instantly. Each display can always be > * aware of the entire hardware state that affects it. I hope this > * covers every possible hardware design. If not feel free to send > * me more design types. > */ > > /* > * If your driver supports multiple boards, you should make these > * arrays, or allocate them dynamically (using kmalloc()). > */ > static struct fb_info info; > /* > * This struct represents the state of a rendering pipe. A modern > * graphics card can have more than one pipe per card depending > * on the hardware design. So the same holds true if you have > * multiple pipes. Use arrays or allocate them dynamically. > * > * Read video/skeleton.h for more information about graphics pipes. > */ > static struct xxx_par __initdata current_par; > > static u32 xxxfb_pseudo_palette[17]; > static int inverse = 0; > > int xxxfb_init(void); > int xxxfb_setup(char*); > > /* ------------------- chipset specific functions -------------------------- */ > > static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) > { > const struct xxx_par *par = (const struct xxx_par *) info->par; > /* > * We test to see if the hardware can support var. Struct xxx_par will > * have the information needed to see if it does. Note we don't change > * par nor info->var. This function can be called on its own if we > * intent to only test a mode and not set it. Return 0 if it is a > * acceptable mode. > */ > > /* ... */ > return 0; > } > > static void xxxfb_set_par(struct fb_info *info) > { > /* > * xxx_fb_check_var tested the mode we want to set the hardware to. > * If it passes it then is set to info->var. Now we set the hardware ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Who sets this? fbmem.c? Or is there a var argument missing for this function? > * (and struct par) according to info->var. > */ > > /* ... */ > } I think it's still safer to use one function for both testing and setting, since for multi-headed cards both heads depend on each other: check_and_test(var, info, test_only) { get_lock() /* multi-headed cards only */ ... do test ... if (test_only) { release_lock() /* multi-headed cards only */ return; } ... do set ... release_lock() /* multi-headed cards only */ } > void xxxfb_imageblit(struct fb_info *p, unsigned int width, > unsigned int height, unsigned long *image, > int image_depth, int dx, int dy) > { > } I still like to have the possibility to blit an array of images, for drawing multiple characters (fbcon_putcs()). Drawing individual characters is too slow on some hardware (e.g. Amiga bitplanes: each 8-pixel wide character needs to access 1 byte in each plane, while drawing 4 (AGA, 32-bit wide bus) or 2 (ECS, 16-bit wide bus) characters needs the same number of memory accesses. > /* This should give a reasonable default video mode */ > if (!mode_option) > mode_option = "640x480@60"; Not needed. fb_find_mode() will do this automagically if mode_option is NULL. > static struct fb_ops xxxfb_ops = { > owner: THIS_MODULE, > fb_open: xxxfb_open, /* only if you need it to do something */ > fb_release: xxxfb_release, /* only if you need it to do something */ > fb_check_var: xxxfb_check_var, > fb_set_par: xxxfb_set_par, > fb_setcolreg: xxxfb_setcolreg, > fb_blank: xxxfb_blank, > fb_pan_display: xxxfb_pan_display, > fb_rectfill: xxxfb_rectfill, /* optional */ > fb_copyarea: xxxfb_copyarea, /* optional */ > fb_imageblit: xxxfb_imageblit, /* optional */ > fb_ioctl: xxxfb_ioctl, /* optional */ > fb_mmap: xxxfb_mmap, /* optional */ > }; Aren't xxxfb_{rectfill,copyarea,imageblit} mandatory, because fbcon-* will go away? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li... In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds |
From: James S. <jsi...@su...> - 2001-01-17 19:42:12
|
> > static void xxxfb_set_par(struct fb_info *info) > > { > > /* > > * xxx_fb_check_var tested the mode we want to set the hardware to. > > * If it passes it then is set to info->var. Now we set the hardware > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > Who sets this? fbmem.c? Or is there a var argument missing for this function? From fbmem.c : int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info) { int err, oldbpp; if (memcmp(&info->var, var, sizeof(var))) { if ((err = info->fbops->fb_check_var(var, info))) return err; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { oldbpp = info->var.bits_per_pixel; info->var = *var; info->fbops->fb_set_par(info); if (oldbpp != var->bits_per_pixel) { if ((err = fb_set_cmap(&info->cmap, 1, info))) return err; } } var->activate = 0; } return 0; } With this generic set_var function we compare the passed in var with the current var in info. We check if the hardware can handle the mode using par in info but we don't alter par. Once check_var approves AND we want to set the video mode we set info->var to the passed in var and then call set_par. The reason I don't have a par in set_var and pass it to check_var is because I felt it was a waste to create a new par and then throw it away if we just want to check the video mode. Also par could be a array of data structures representing different hardware states the graphics card could be in. The bonus is for fb_find_mode we can just call fbops->fb_check_var directly. > I think it's still safer to use one function for both testing and setting, > since for multi-headed cards both heads depend on each other: > > check_and_test(var, info, test_only) > { > get_lock() /* multi-headed cards only */ > ... do test ... > > if (test_only) { > release_lock() /* multi-headed cards only */ > return; > } > > ... do set ... > release_lock() /* multi-headed cards only */ > } This is fb_set_var in a nutshell minus the locking which we need. In the case of multi-head cards we have more than one fb_info but have one par which is shared between them. If one attempts to change it resolution we can used the values in par to see if it is possible. The one thing we have to be extra careful with is if two processes try to change both resolutions on each display at the same time. The other question is what to do in the following situation: display A in mode a display B in mode b VC switch display A in mode c display B in mode d When we change to mode c it is acceptable to mode b but not to mode d. Do we disallow the VT switch? > > void xxxfb_imageblit(struct fb_info *p, unsigned int width, > > unsigned int height, unsigned long *image, > > int image_depth, int dx, int dy) > > { > > } > > I still like to have the possibility to blit an array of images, for drawing > multiple characters (fbcon_putcs()). Drawing individual characters is too slow > on some hardware (e.g. Amiga bitplanes: each 8-pixel wide character needs to > access 1 byte in each plane, while drawing 4 (AGA, 32-bit wide bus) or 2 (ECS, > 16-bit wide bus) characters needs the same number of memory accesses. I agree. fbcon_putcs would have to be smart in how to construct a image to pass to the blit function. The blit function can take in any size image. That is why the width and height fields. If done right you can draw huge images to the display in very short time. For the generic packed pixel case I word align the data and then transfer unsigned long size data at a time to the graphics card. On a 32 bit machine in 8 bpp then means 4 pixels are drawn in one cycle. I'm sure we can do the same thing for Amiga interleaved bitplanes. I also figured out really fast really fast rectfill and copyarea for ilbm. Since each plane is a 0 or 1 at position X in the pixel and each plane comes afetr each other in video memory we can for each plane work with a bunch of 0s or just a bunch of 1s. P.S I never did figure out how Amiga interleaved bitplanes are layed out. How do you fill in one pixel of some color to the display? Once I have that figured out I can write a really fast rectfill, copyarea, and imageblit for it. > > /* This should give a reasonable default video mode */ > > if (!mode_option) > > mode_option = "640x480@60"; > > Not needed. fb_find_mode() will do this automagically if mode_option is NULL. Okay. Updated. > > fb_pan_display: xxxfb_pan_display, > > fb_rectfill: xxxfb_rectfill, /* optional */ > > fb_copyarea: xxxfb_copyarea, /* optional */ > > fb_imageblit: xxxfb_imageblit, /* optional */ > > fb_ioctl: xxxfb_ioctl, /* optional */ > > fb_mmap: xxxfb_mmap, /* optional */ > > }; > > Aren't xxxfb_{rectfill,copyarea,imageblit} mandatory, because fbcon-* will go > away? Yes but for the standard packed pixel non accelerated graphics cards we have cfbrectfill, cfbcopyarea, and cfbimageblit to use. If the driver doesn't provide these functions then we use these cfb* functions. I even stored each function in a seperate file just in case we run into cards that support one or two of the three accelerated functions. |
From: Geert U. <ge...@li...> - 2001-01-18 08:29:41
|
On Wed, 17 Jan 2001, James Simmons wrote: > I never did figure out how Amiga interleaved bitplanes are layed out. How > do you fill in one pixel of some color to the display? Once I have that > figured out I can write a really fast rectfill, copyarea, and imageblit > for it. OK, I'll tell you how the Amiga display hardware works. Amiga always uses bitplanes (1-8) - You have 8 bitplane pointers (bplpt[8]), through which display data is fetched (with auto-increment), one for each bitplane. - You have 2 bitplane modulo registers (bpl1mod and bpl2mod), which are added to the even resp. odd bitplane pointers at the end of each scanline (FYI: You have 2 of them to support `dual playfield mode', in which you have 2 independent playfields formed by the even and odd bitplanes. This is not supported by amifb). This provides quite some flexibility, since you can store individual bitplanes in memory wherever you want. For `normal bitplanes' (all bitplanes stored in memory after each other, handled by `fbcon-afb'), you set: bplpt[i] = start+i*(width*height/8); bpl1mod = bpl2mod = 0; For `interleaved bitplanes' (all bitplanes for one scanline are stored after each other, followed by the bitplanes for the next scanline, and so on), you set: bplpt[i] = start+i*width/8; bpl1mod = bpl2mod = width/8*(depth-1); The advantage of ilbm over afb is that you can copy and clear rectangular areas using only one blit (= copy of a rectangular area in memory), while for afb you need as many blits as you have bitplanes, so you need less blitter setup. Furthermore you see less artefacts during scrolling. The disadvantage is that XF68_FBDev is quite buggy for ilbm. It should be possible to merge fbcon-afb and fbcon-ilbm. The only difference is the value you have to add to go to the next scanline or the next bitplane. > > > fb_pan_display: xxxfb_pan_display, > > > fb_rectfill: xxxfb_rectfill, /* optional */ > > > fb_copyarea: xxxfb_copyarea, /* optional */ > > > fb_imageblit: xxxfb_imageblit, /* optional */ > > > fb_ioctl: xxxfb_ioctl, /* optional */ > > > fb_mmap: xxxfb_mmap, /* optional */ > > > }; > > > > Aren't xxxfb_{rectfill,copyarea,imageblit} mandatory, because fbcon-* will go > > away? > > Yes but for the standard packed pixel non accelerated graphics cards we > have cfbrectfill, cfbcopyarea, and cfbimageblit to use. If the driver > doesn't provide these functions then we use these cfb* functions. I even > stored each function in a seperate file just in case we run into cards > that support one or two of the three accelerated functions. Wouldn't it be better to let the driver always fill in the pointers, even if it needs the cfb* ops? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li... In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds |
From: James S. <jsi...@su...> - 2001-01-18 23:14:34
|
Thanks for the bitplanes info. I'm going to figure out some routines to do a rectfill, copyarea, and a imageblit. > > Yes but for the standard packed pixel non accelerated graphics cards we > > have cfbrectfill, cfbcopyarea, and cfbimageblit to use. If the driver > > doesn't provide these functions then we use these cfb* functions. I even > > stored each function in a seperate file just in case we run into cards > > that support one or two of the three accelerated functions. > > Wouldn't it be better to let the driver always fill in the pointers, even if it > needs the cfb* ops? The reason I was thinking this was just in case we end up with ioctls for these 3 accel functions. We wouldn't want userland to be able to call them if they could be done in userland using software emulation. |
From: Sven L. <lu...@dp...> - 2001-01-18 13:00:54
|
About this pipeline business : what if i wanted to write a fbdev for, for example, the 3Dlabs Oxygen GVX420 board ? For you information this board contains 3 different chip, A gamma 2 chip, acting as agp bridge and T&L engine, and 2 Permedia4 chips, doing 3D setup and rasterization. They can be configuredto be shared for rasterizing the same framebuffer, splitting the scanline between them, or to support dual head. Each Pm4 has one pipeline, i think. The additional problem, is that you can address the rasterizer chip either directly (they have FB and Command register pci aperture, and a separate pci id) or trough the Gamma chip, for example, for when doing 3D, you send command to the gamma, which process them (T&L) and then forward the low level commands to one or both Permedia4 chip. If you want ot use one or both accesses, you would need to synchronize correctly between them. Friendly, Sven Luther |
From: James S. <jsi...@su...> - 2001-01-19 00:31:29
|
> what if i wanted to write a fbdev for, for example, the 3Dlabs Oxygen GVX420 > board ? > > For you information this board contains 3 different chip, A gamma 2 chip, > acting as agp bridge and T&L engine, and 2 Permedia4 chips, doing 3D setup and > rasterization. They can be configuredto be shared for rasterizing the same > framebuffer, splitting the scanline between them, or to support dual head. I assume T&L is texture and lighting engine. > Each Pm4 has one pipeline, i think. First a pipeline is a collect of pipes. Each pipe takes data and changes it a certain way. This occurs until we reach the end of the pipeline when we get the final desired rastered image. Well that depends. Can data be processed by one Pm4 chip and then passed to the second Pm4 chip to be processed by another stage? A good example would be say a triangle strip was passed to the the first chip to say be rotated. Then that data is passed onto the second chip to be tranformed to give the appearance of a prespective view. In this case their is one pipeline with 2 pipes. Now if this doesn't occur and each chip processes data independent of each other then their is two pipelines with one pipe each. This is of course assuming each GPU, the Pm4's, can't handle more than one graphics command at a time. Is the T&L shared between both GPU's. I really have to look at the hardware specs to say exactly. As you can see for a mor advance card like the Oxygen things get more a bit more complex. > The additional problem, is that you can address the rasterizer chip either > directly (they have FB and Command register pci aperture, and a separate pci > id) or trough the Gamma chip, for example, for when doing 3D, you send command > to the gamma, which process them (T&L) and then forward the low level commands > to one or both Permedia4 chip. If you want ot use one or both accesses, you > would need to synchronize correctly between them. Okay I'm taking a shot in the dark since I don't have the specs but I'm assuming the Gamma chip is for DMA, especially since you mentioned that it manages the agp port, and the Command register space is for MMIO programming. Yes you do you have to manage access to both of them. Internal to the fbdev driver this is pretty simple. When userland wants to play around with this stuff then you need a RRM (rendering resource manager) to balance access. As 2.4.X stands right now you can't use the DMA with fbcon but I will be working on this problem right now. |
From: Sven L. <lu...@dp...> - 2001-01-19 09:14:04
|
On Thu, Jan 18, 2001 at 04:31:36PM -0800, James Simmons wrote: > > > what if i wanted to write a fbdev for, for example, the 3Dlabs Oxygen GVX420 > > board ? > > > > For you information this board contains 3 different chip, A gamma 2 chip, > > acting as agp bridge and T&L engine, and 2 Permedia4 chips, doing 3D setup and > > rasterization. They can be configuredto be shared for rasterizing the same > > framebuffer, splitting the scanline between them, or to support dual head. > > I assume T&L is texture and lighting engine. Yes, that and some other stuff, i cannot say more though. > > Each Pm4 has one pipeline, i think. > > First a pipeline is a collect of pipes. Each pipe takes data and changes > it a certain way. This occurs until we reach the end of the pipeline when > we get the final desired rastered image. Ok, i understand this. each pipe can also be called unit, isn't it ? > Well that depends. Can data be processed by one Pm4 chip and then passed > to the second Pm4 chip to be processed by another stage? A good example No, but they can handle part of the same image, or process the exact same image doubly. > would be say a triangle strip was passed to the the first chip to say be > rotated. Then that data is passed onto the second chip to be tranformed to No, rotate is done by the gamma. > give the appearance of a prespective view. In this case their is one mmm, i can have stereoscopic view from one pm4. I guess you can also have two identic copies of the image in both pm4, each rendering to one output. not sure though. > pipeline with 2 pipes. Now if this doesn't occur and each chip processes > data independent of each other then their is two pipelines with one pipe I think what trully happens is that it can be configured as only one pipe, or as two independent pipes, isn't it ? > each. This is of course assuming each GPU, the Pm4's, can't handle more > than one graphics command at a time. Is the T&L shared between both Not true, they can have more than one framebuffer (upto 4 i think). > GPU's. I really have to look at the hardware specs to say exactly. As you > can see for a mor advance card like the Oxygen things get more a bit more > complex. You will need an NDA to get access to the specs though :((( But i thought that as long as you are planing a new API, it may as well take this kind of cases into acount. I may be writting a fbdev for the appian J2000 (two pm3 and 1 gamma, the pm3 cannot be shared for 1 display though, only in dual head, but the gamma can provide 3D Accel for both display). > > The additional problem, is that you can address the rasterizer chip either > > directly (they have FB and Command register pci aperture, and a separate pci > > id) or trough the Gamma chip, for example, for when doing 3D, you send command > > to the gamma, which process them (T&L) and then forward the low level commands > > to one or both Permedia4 chip. If you want ot use one or both accesses, you > > would need to synchronize correctly between them. > > Okay I'm taking a shot in the dark since I don't have the specs but I'm > assuming the Gamma chip is for DMA, especially since you mentioned that > it manages the agp port, and the Command register space is for MMIO mmm, ... To share some light on the circunstances, i am doing the Xfree driver for it. You are wrong, both the gamma and the permedia chips can do DMA (with kernel or DRI help), command MMIO (register writing) or direct fifo access (well you send pairs of register address and command data down the pipeline, sort of busy dma-like behavior without a dma engine). > programming. Yes you do you have to manage access to both of them. I have access to both type of command with both type of chips. > Internal to the fbdev driver this is pretty simple. When userland wants to > play around with this stuff then you need a RRM (rendering resource > manager) to balance access. As 2.4.X stands right now you can't use the > DMA with fbcon but I will be working on this problem right now. My problem, is that you will have to be synchronizing in a way that is common between fbdev/whatever and X. under X i am planning to do 2D access directly to the rasterizer chip, but use the gamma for DRI/3D. Friendly, Sven Luther |
From: James S. <jsi...@su...> - 2001-01-22 20:10:58
|
> Ok, i understand this. each pipe can also be called unit, isn't it ? Yes. I also have heard it called a stage. > > Well that depends. Can data be processed by one Pm4 chip and then passed > > to the second Pm4 chip to be processed by another stage? A good example > > No, but they can handle part of the same image, or process the exact same > image doubly. Don't think image. Think vertice object passed into the accel engine to be operated on. Rastering the image is just the last stage of the pipeline that translates for processed vertice data into pixel image on screen. > No, rotate is done by the gamma. [snip]... Okay. That was just for a example. > You will need an NDA to get access to the specs though :((( I plan to get around to this card eventually. > But i thought that as long as you are planing a new API, it may as well take > this kind of cases into acount. That is why I though about this approach. > You are wrong, both the gamma and the permedia chips can do DMA (with kernel > or DRI help), command MMIO (register writing) or direct fifo access (well you > send pairs of register address and command data down the pipeline, sort of > busy dma-like behavior without a dma engine). Okay. Now I have a good understanding of what is going on. Most higher end cards have a dual pipeline line approach. One for 2D stuff and one for 3D stuff. The reason it is done this way is because the 3D stuff can take a long time to process when compared to the 2D stuff. This would make the X server very non responsive. With a dual pipeline approach you can a a independent pipeline that handles 2D so the X server is still snappy while still processing 3D stuff for different OpenGL clients. > My problem, is that you will have to be synchronizing in a way that is common > between fbdev/whatever and X. under X i am planning to do 2D access directly > to the rasterizer chip, but use the gamma for DRI/3D. For 2.5.X I plan to have it such that when you open /dev/fb that fbcon shuts down (replaced by dummycon). This way fbcon and DRI or whatever don't step on each others feet. |
From: Geert U. <ge...@li...> - 2001-02-04 20:20:06
|
On Mon, 22 Jan 2001, James Simmons wrote: > > My problem, is that you will have to be synchronizing in a way that is common > > between fbdev/whatever and X. under X i am planning to do 2D access directly > > to the rasterizer chip, but use the gamma for DRI/3D. > > For 2.5.X I plan to have it such that when you open /dev/fb that fbcon > shuts down (replaced by dummycon). This way fbcon and DRI or whatever > don't step on each others feet. I've been thinking about this. Why switch back to dummycon? You can keep on using fbcon, but disable rendering to the frame buffer. That way you don't have to handle the transfer of the shadow screen from fbcon to dummycon and vice versa. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li... In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds |
From: James S. <jsi...@su...> - 2001-02-05 20:23:35
|
> > For 2.5.X I plan to have it such that when you open /dev/fb that fbcon > > shuts down (replaced by dummycon). This way fbcon and DRI or whatever > > don't step on each others feet. > > I've been thinking about this. Why switch back to dummycon? You can keep on > using fbcon, but disable rendering to the frame buffer. That way you don't have > to handle the transfer of the shadow screen from fbcon to dummycon and vice > versa. You forget I have fbdev working with vgacon. I need to preserve the state vgacon is in. Once /dev/fb is closed we can restore the state of vgacon. |