Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtio GPU: Redrawing with timer interrupt on RISCV #122

Open
wrenger opened this issue Jan 2, 2024 · 1 comment
Open

Virtio GPU: Redrawing with timer interrupt on RISCV #122

wrenger opened this issue Jan 2, 2024 · 1 comment

Comments

@wrenger
Copy link

wrenger commented Jan 2, 2024

Hi, first of all, thanks for the great bindings.

I am having problems redrawing the frame buffer periodically using a timer. The first succeeds, but all further draw calls fail with an IO Error. Maybe I do not understand the procedure correctly...

pub struct VirtGPU {
    gpu: VirtIOGpu<HalImpl, MmioTransport>,
}

pub static VGPU: OnceLock<Spin<VirtGPU>> = OnceLock::new();

impl VirtGPU {
    pub fn new(transport: MmioTransport) -> Self {
        Self {
            gpu: VirtIOGpu::new(transport).expect("initialize gpu driver"),
        }
    }

    pub fn draw(&mut self) -> virtio_drivers::Result<()> {
        let (width, height) = self.gpu.resolution()?;
        let width = width as usize;
        let height = height as usize;
        serial!("GPU resolution is {width}x{height}");
        let fb = self.gpu.setup_framebuffer()?; // <- IO Error happens here
        let fb = unsafe {
            core::slice::from_raw_parts_mut(fb.as_ptr() as *mut u32, fb.len() / size_of::<u32>())
        };
        serial!("Framebuffer size is {} ({})", fb.len(), width * height);

        /// Update the framebuffer...

        self.gpu.flush()?;
        Ok(())
    }
}

The MmioTransport is initialized as in the RISCV example.
A timer interrupt calls draw periodically. The first draw call succeeds; all subsequent ones fail in setup_framebuffer.

QEMU command line:

qemu-system-riscv32 -m 2G -machine virt -device virtio-gpu-device -serial mon:stdio -gdb tcp::1234 -no-shutdown -no-reboot target/debug/kernel
@wrenger
Copy link
Author

wrenger commented Jan 2, 2024

Ok, it seems to work if the frame buffer is only set up once during initialization and then only flushed repeatedly. The downside is that this cannot respond to resolution changes...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant