Query the driver for the real scanline pitch in bytes.
As cbvga doesn't change the pitch on mode change, always return the same pitch, that might exceed width times Bytes-per-pixel.
Signed-off-by: Patrick Rudolph siro@das-labor.org --- vgasrc/bochsvga.c | 5 +++++ vgasrc/bochsvga.h | 1 + vgasrc/cbvga.c | 7 +++++++ vgasrc/clext.c | 5 +++++ vgasrc/stdvga.c | 5 +++++ vgasrc/vbe.c | 2 +- vgasrc/vgahw.h | 10 ++++++++++ vgasrc/vgautil.h | 3 +++ 8 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index ec5d101..458b3a8 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -310,6 +310,11 @@ bochsvga_save_restore(int cmd, u16 seg, void *data) return ret + (VBE_DISPI_INDEX_Y_OFFSET-VBE_DISPI_INDEX_XRES+1)*sizeof(u16); }
+int +bochsvga_get_linesize(struct vgamode_s *vmode_g) +{ + return DIV_ROUND_UP(vmode_g->width * vga_bpp(vmode_g), 8); +}
/**************************************************************** * Mode setting diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index ae5f75d..40ce6f1 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -52,6 +52,7 @@ int bochsvga_get_dacformat(struct vgamode_s *vmode_g); int bochsvga_set_dacformat(struct vgamode_s *vmode_g, int val); int bochsvga_save_restore(int cmd, u16 seg, void *data); int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags); +int bochsvga_get_linesize(struct vgamode_s *vmode_g); int bochsvga_setup(void);
#endif // bochsvga.h diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c index 87ec77e..50e6e69 100644 --- a/vgasrc/cbvga.c +++ b/vgasrc/cbvga.c @@ -123,6 +123,13 @@ cbvga_set_mode(struct vgamode_s *vmode_g, int flags) return 0; }
+int +cbvga_get_linesize(struct vgamode_s *vmode_g) +{ + /* Can't change mode, always report active pitch. */ + return GET_GLOBAL(CBlinelength); +} + #define CB_TAG_FRAMEBUFFER 0x0012 struct cb_framebuffer { u32 tag; diff --git a/vgasrc/clext.c b/vgasrc/clext.c index da8b790..08bc9b5 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -376,6 +376,11 @@ clext_save_restore(int cmd, u16 seg, void *data) return stdvga_save_restore(cmd, seg, data); }
+int +clext_get_linesize(struct vgamode_s *vmode_g) +{ + return DIV_ROUND_UP(vmode_g->width * vga_bpp(vmode_g), 8); +}
/**************************************************************** * Mode setting diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index 886deca..0e24297 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -321,6 +321,11 @@ stdvga_set_dacformat(struct vgamode_s *vmode_g, int val) return -1; }
+int +stdvga_get_linesize(struct vgamode_s *vmode_g) +{ + return DIV_ROUND_UP(vmode_g->width * vga_bpp(vmode_g), 8); +}
/**************************************************************** * Save/Restore state diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index facad19..724c1ba 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -107,7 +107,7 @@ vbe_104f01(struct bregs *regs) // Basic information about mode. int width = GET_GLOBAL(vmode_g->width); int height = GET_GLOBAL(vmode_g->height); - int linesize = DIV_ROUND_UP(width * vga_bpp(vmode_g), 8); + int linesize = vgahw_get_linesize(vmode_g); SET_FARVAR(seg, info->bytes_per_scanline, linesize); SET_FARVAR(seg, info->xres, width); SET_FARVAR(seg, info->yres, height); diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index dab2b4d..5839643 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -139,4 +139,14 @@ static inline int vgahw_save_restore(int cmd, u16 seg, void *data) { return stdvga_save_restore(cmd, seg, data); }
+static inline int vgahw_get_linesize(struct vgamode_s *vmode_g) { + if (CONFIG_VGA_CIRRUS) + return clext_get_linesize(vmode_g); + if (CONFIG_VGA_BOCHS) + return bochsvga_get_linesize(vmode_g); + if (CONFIG_VGA_COREBOOT) + return cbvga_get_linesize(vmode_g); + return stdvga_get_linesize(vmode_g); +} + #endif // vgahw.h diff --git a/vgasrc/vgautil.h b/vgasrc/vgautil.h index 08c4e8d..4b6f5b9 100644 --- a/vgasrc/vgautil.h +++ b/vgasrc/vgautil.h @@ -17,6 +17,7 @@ int cbvga_get_dacformat(struct vgamode_s *vmode_g); int cbvga_set_dacformat(struct vgamode_s *vmode_g, int val); int cbvga_save_restore(int cmd, u16 seg, void *data); int cbvga_set_mode(struct vgamode_s *vmode_g, int flags); +int cbvga_get_linesize(struct vgamode_s *vmode_g); int cbvga_setup(void);
// clext.c @@ -30,6 +31,7 @@ int clext_get_displaystart(struct vgamode_s *vmode_g); int clext_set_displaystart(struct vgamode_s *vmode_g, int val); int clext_save_restore(int cmd, u16 seg, void *data); int clext_set_mode(struct vgamode_s *vmode_g, int flags); +int clext_get_linesize(struct vgamode_s *vmode_g); struct bregs; void clext_1012(struct bregs *regs); int clext_setup(void); @@ -63,6 +65,7 @@ void stdvga_list_modes(u16 seg, u16 *dest, u16 *last); void stdvga_build_video_param(void); void stdvga_override_crtc(int mode, u8 *crtc); int stdvga_set_mode(struct vgamode_s *vmode_g, int flags); +int stdvga_get_linesize(struct vgamode_s *vmode_g); void stdvga_set_packed_palette(void);
// swcursor.c