[SeaBIOS] [PATCH 3/8] SeaVGABIOS/vbe: Query driver for scanline pitch

Patrick Rudolph siro at das-labor.org
Fri Mar 24 17:27:22 CET 2017


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 at das-labor.org>

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 49af7f9..6b3233e 100644
--- a/vgasrc/cbvga.c
+++ b/vgasrc/cbvga.c
@@ -124,6 +124,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
-- 
2.9.3




More information about the SeaBIOS mailing list