Skip to content

Commit e6d9ff1

Browse files
authored
Use actual GPU resolution in example rather than hardcoding. (#16)
Different versions of QEMU seem to have different default resolutions, so it was crashing due to an array access out of bounds.
1 parent adf5e8b commit e6d9ff1

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

examples/riscv/src/main.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,14 @@ fn virtio_blk<T: Transport>(transport: T) {
100100

101101
fn virtio_gpu<T: Transport>(transport: T) {
102102
let mut gpu = VirtIOGpu::<HalImpl, T>::new(transport).expect("failed to create gpu driver");
103+
let (width, height) = gpu.resolution().expect("failed to get resolution");
104+
let width = width as usize;
105+
let height = height as usize;
106+
info!("GPU resolution is {}x{}", width, height);
103107
let fb = gpu.setup_framebuffer().expect("failed to get fb");
104-
for y in 0..768 {
105-
for x in 0..1024 {
106-
let idx = (y * 1024 + x) * 4;
108+
for y in 0..height {
109+
for x in 0..width {
110+
let idx = (y * width + x) * 4;
107111
fb[idx] = x as u8;
108112
fb[idx + 1] = y as u8;
109113
fb[idx + 2] = (x + y) as u8;

src/gpu.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use volatile::{ReadOnly, Volatile, WriteOnly};
1515
/// and multiple scanouts (aka heads).
1616
pub struct VirtIOGpu<'a, H: Hal, T: Transport> {
1717
transport: T,
18-
rect: Rect,
18+
rect: Option<Rect>,
1919
/// DMA area of frame buffer.
2020
frame_buffer_dma: Option<DMA<H>>,
2121
/// DMA area of cursor image buffer.
@@ -60,7 +60,7 @@ impl<H: Hal, T: Transport> VirtIOGpu<'_, H, T> {
6060
transport,
6161
frame_buffer_dma: None,
6262
cursor_buffer_dma: None,
63-
rect: Rect::default(),
63+
rect: None,
6464
control_queue,
6565
cursor_queue,
6666
queue_buf_dma,
@@ -75,16 +75,17 @@ impl<H: Hal, T: Transport> VirtIOGpu<'_, H, T> {
7575
}
7676

7777
/// Get the resolution (width, height).
78-
pub fn resolution(&self) -> (u32, u32) {
79-
(self.rect.width, self.rect.height)
78+
pub fn resolution(&mut self) -> Result<(u32, u32)> {
79+
let display_info = self.get_display_info()?;
80+
Ok((display_info.rect.width, display_info.rect.height))
8081
}
8182

8283
/// Setup framebuffer
8384
pub fn setup_framebuffer(&mut self) -> Result<&mut [u8]> {
8485
// get display info
8586
let display_info = self.get_display_info()?;
8687
info!("=> {:?}", display_info);
87-
self.rect = display_info.rect;
88+
self.rect = Some(display_info.rect);
8889

8990
// create resource 2d
9091
self.resource_create_2d(
@@ -110,10 +111,11 @@ impl<H: Hal, T: Transport> VirtIOGpu<'_, H, T> {
110111

111112
/// Flush framebuffer to screen.
112113
pub fn flush(&mut self) -> Result {
114+
let rect = self.rect.ok_or(Error::NotReady)?;
113115
// copy data from guest to host
114-
self.transfer_to_host_2d(self.rect, 0, RESOURCE_ID_FB)?;
116+
self.transfer_to_host_2d(rect, 0, RESOURCE_ID_FB)?;
115117
// flush data to screen
116-
self.resource_flush(self.rect, RESOURCE_ID_FB)?;
118+
self.resource_flush(rect, RESOURCE_ID_FB)?;
117119
Ok(())
118120
}
119121

0 commit comments

Comments
 (0)