got basic framebuffer

This commit is contained in:
Lauchmelder 2022-01-23 16:44:47 +01:00
parent 59f5fb2c6e
commit baa0de8847
5 changed files with 155 additions and 1 deletions

30
include/framebuffer.h Normal file
View file

@ -0,0 +1,30 @@
#pragma once
#include "stdint.h"
struct FrameBuffer
{
struct
{
uint32_t width;
uint32_t height;
} physicalDisplay;
struct
{
uint32_t width;
uint32_t height;
uint32_t xOffset;
uint32_t yOffset;
} virtualDisplay;
uint32_t pitch;
uint32_t bitsPerPixel;
uint8_t* pixels;
uint32_t size;
};
struct FrameBuffer* framebuffer_init(unsigned int width, unsigned int height);
void framebuffer_release(void);
void draw_test_image(void);

View file

@ -2,5 +2,9 @@
#include "stdint.h"
struct FrameBuffer;
uint32_t get_vc_firmware_rev(void);
uint8_t* get_board_mac_address(uint8_t* buffer);
uint8_t* get_board_mac_address(uint8_t* buffer);
void create_framebuffer(struct FrameBuffer* buffer, unsigned int width, unsigned int height);

35
src/framebuffer.c Normal file
View file

@ -0,0 +1,35 @@
#include "framebuffer.h"
#include "mb.h"
#include "memory.h"
#include "io.h"
static struct FrameBuffer framebuffer;
struct FrameBuffer* framebuffer_init(unsigned int width, unsigned int height)
{
create_framebuffer(&framebuffer, width, height);
return &framebuffer;
}
void framebuffer_release(void)
{
}
void draw_test_image(void)
{
for(uint32_t y = 0; y < framebuffer.virtualDisplay.height; y++)
{
for(uint32_t x = 0; x < framebuffer.virtualDisplay.width; x++)
{
size_t offset = y * framebuffer.pitch + (x * (framebuffer.bitsPerPixel / 8));
framebuffer.pixels[offset + 0] = 255;
framebuffer.pixels[offset + 1] = y * 255 / framebuffer.virtualDisplay.height;
framebuffer.pixels[offset + 2] = x * 255 / framebuffer.virtualDisplay.width;
framebuffer.pixels[offset + 3] = 100;
}
}
}

View file

@ -3,6 +3,7 @@
#include "string.h"
#include "memory.h"
#include "mb.h"
#include "framebuffer.h"
void print_clippy();
char* get_user_input(char* buffer);
@ -36,6 +37,18 @@ void main()
uart_puts("Started execution at 0x");
uart_puts(ultoa((long)&_start, buffer, 16));
struct FrameBuffer* framebuffer = framebuffer_init(1920, 1080);
uart_puts("\n\nFramebuffer info\n---------------\n");
uart_puts("Physical display : "); uart_puts(utoa(framebuffer->physicalDisplay.width, buffer, 10)); uart_puts("x"); uart_puts(utoa(framebuffer->physicalDisplay.height, buffer, 10)); uart_puts(" pixels\n");
uart_puts("Virtual display : "); uart_puts(utoa(framebuffer->virtualDisplay.width, buffer, 10)); uart_puts("x"); uart_puts(utoa(framebuffer->virtualDisplay.height, buffer, 10)); uart_puts(" pixels\n");
uart_puts("Virt. disp. offset: ("); uart_puts(utoa(framebuffer->virtualDisplay.xOffset, buffer, 10)); uart_puts(","); uart_puts(utoa(framebuffer->virtualDisplay.yOffset, buffer, 10)); uart_puts(")\n");
uart_puts("Pitch: : "); uart_puts(utoa(framebuffer->pitch, buffer, 10)); uart_puts(" bytes\n");
uart_puts("Bit depth : "); uart_puts(utoa(framebuffer->bitsPerPixel, buffer, 10)); uart_puts(" bits per pixel\n");
uart_puts("Memory location : 0x"); uart_puts(ultoa((unsigned long)framebuffer->pixels, buffer, 16)); uart_puts("\n");
uart_puts("Size : "); uart_puts(utoa(framebuffer->size, buffer, 10)); uart_puts(" bytes\n\n");
draw_test_image();
for(;;)
{
uart_puts("\n\nPlease enter first operand\n");

View file

@ -3,6 +3,7 @@
#include "memory.h"
#include "io.h"
#include "convert.h"
#include "framebuffer.h"
volatile uint32_t __attribute__((aligned(16))) mailbox[36];
@ -118,4 +119,75 @@ uint8_t* get_board_mac_address(uint8_t* buffer)
buffer[i] = mac_address[i];
return buffer;
}
void create_framebuffer(struct FrameBuffer* buffer, unsigned int width, unsigned int height)
{
mailbox[0] = 35 * sizeof(uint32_t); // buffer size
mailbox[1] = 0;
// Set physical display dimensions
mailbox[2] = 0x00048003;
mailbox[3] = 2 * sizeof(uint32_t);
mailbox[4] = 0;
mailbox[5] = width;
mailbox[6] = height;
// Set virtual display dimensions
mailbox[7] = 0x00048004;
mailbox[8] = 2 * sizeof(uint32_t);
mailbox[9] = 0;
mailbox[10] = width;
mailbox[11] = height;
// Set bit depth
mailbox[12] = 0x00048005;
mailbox[13] = 1 * sizeof(uint32_t);
mailbox[14] = 0;
mailbox[15] = 32;
// Set pixel order
mailbox[16] = 0x00048006;
mailbox[17] = 1 * sizeof(uint32_t);
mailbox[18] = 0;
mailbox[19] = 1;
// Set virtual offset
mailbox[20] = 0x00048009;
mailbox[21] = 2 * sizeof(uint32_t);
mailbox[22] = 0;
mailbox[23] = 0;
mailbox[24] = 0;
// Allocate buffer
mailbox[25] = 0x00040001;
mailbox[26] = 8;
mailbox[27] = 0;
mailbox[28] = 4096;
mailbox[29] = 0;
// Get pitch
mailbox[30] = 0x00040008;
mailbox[31] = 1 * sizeof(uint32_t);
mailbox[32] = 0;
mailbox[33] = 0;
mailbox[34] = 0;
mailbox_call(8);
mailbox[28] &= 0x3FFFFFFF;
buffer->physicalDisplay.width = mailbox[5];
buffer->physicalDisplay.height = mailbox[6];
buffer->virtualDisplay.width = mailbox[10];
buffer->virtualDisplay.height = mailbox[11];
buffer->virtualDisplay.xOffset = mailbox[23];
buffer->virtualDisplay.yOffset = mailbox[24];
buffer->bitsPerPixel = mailbox[15];
buffer->pitch = mailbox[33];
buffer->pixels = (uint8_t*)((uint64_t)mailbox[28]);
buffer->size = mailbox[29];
}