diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-08 17:32:23 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-08 17:32:23 -0500 |
| commit | 52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1 (patch) | |
| tree | a092e2e798139456d5f1b2f6b320a6c60a705205 | |
| parent | 0d7cde7c4d735ebebd39b988440f50f5889bd29f (diff) | |
| download | kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.zip kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.tar.gz kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.tar.bz2 kappa-52d2b12c32ab15f4314cf5f0b27ea24709ed1cb1.tar.xz | |
lots of optimization, new features
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | drivers/gfx-as.S | 66 | ||||
| -rw-r--r-- | drivers/gfx.c | 73 | ||||
| -rw-r--r-- | drivers/include/gfx.h | 6 | ||||
| -rw-r--r-- | kernel/irq-as.S | 64 | ||||
| -rw-r--r-- | kernel/isr-as.S | 116 | ||||
| -rw-r--r-- | kernel/main.c | 36 |
7 files changed, 268 insertions, 107 deletions
@@ -3,8 +3,8 @@ CC = gcc LD = ld INCLUDES = -Idrivers/include -Ikernel/include -Ilibc/include -Iapps/ -CFLAGS := -std=gnu99 -ffreestanding -fno-stack-protector -nostdlib -Wall -Wextra -m32 $(INCLUDES) -g -O1 -mtune=generic -msse -CFLAGS += -fexpensive-optimizations -ftree-loop-vectorize -finline-functions -fomit-frame-pointer -ftree-vectorize +CFLAGS = -std=gnu99 -ffreestanding -fno-stack-protector -nostdlib -Wall -Wextra -m32 $(INCLUDES) -g +OPTFLAGS = -fexpensive-optimizations -ftree-loop-vectorize -finline-functions -fomit-frame-pointer -ftree-vectorize -O1 -mtune=generic QEMU = qemu-system-i386 BOCHS = bochs @@ -37,13 +37,19 @@ iso: kappa.bin kappa.bin: $(OBJ) $(SOURCES) Makefile @$(LD) -T kernel/linker.ld -o kappa.bin -melf_i386 $(OBJ) @echo "LD $@" + +drivers/gfx.o: drivers/gfx.c Makefile + @echo "CC $<" + @$(CC) $(CFLAGS) -O3 -msse -c $< -o $@ + %.o: %.c Makefile - @$(CC) $(CFLAGS) -c $< -o $@ @echo "CC $<" + @$(CC) $(CFLAGS) $(OPTFLAGS) -c $< -o $@ + %.o: %.S Makefile - @$(AS) $(ASFLAGS) -c $< -o $@ @echo "AS $<" + @$(AS) $(ASFLAGS) -c $< -o $@ clean: @echo "Cleaning build directory..." @rm -f $(OBJ) kappa.iso kappa.bin diff --git a/drivers/gfx-as.S b/drivers/gfx-as.S index 70009c1..51c1db8 100644 --- a/drivers/gfx-as.S +++ b/drivers/gfx-as.S @@ -17,11 +17,73 @@ gfx_clear: addl %eax, %edx cmpl %edx, %eax jnb .L2 -.L6: +.L1: movl %ebx, (%eax) addl %ecx, %eax cmpl %eax, %edx - ja .L6 + ja .L1 .L2: popl %ebx ret + + .global gfx_hline +gfx_hline: + pushl %ebx + movl 8(%esp), %eax + movl 12(%esp), %ecx + cmpl %eax, %ecx + jge .L3 + xchgl %eax, %ecx +.L3: + movzwl fb_stride, %edx + movzbl fb_bpp, %ebx + imull 16(%esp), %edx + addl framebuffer, %edx + imull %ebx, %ecx + imull %ebx, %eax + addl %edx, %eax + addl %ecx, %edx + movl _gfx_fgcol, %ecx + cmpl %edx, %eax + jnb .L5 +.L4: + movl %ecx, (%eax) + addl %ebx, %eax + cmpl %eax, %edx + ja .L4 +.L5: + popl %ebx + ret + + .global gfx_vline +gfx_vline: + pushl %esi + pushl %ebx + movl 12(%esp), %eax + movl 16(%esp), %edx + cmpl %eax, %edx + jge .L6 + xchgl %eax, %edx +.L6: + movzwl fb_stride, %ebx + movzbl fb_bpp, %ecx + imull 20(%esp), %ecx + movl framebuffer, %esi + imull %ebx, %edx + imull %ebx, %eax + addl %ecx, %eax + addl %edx, %ecx + leal (%esi,%ecx), %edx + addl %esi, %eax + movl _gfx_fgcol, %ecx + cmpl %edx, %eax + jnb .L8 +.L7: + movl %ecx, (%eax) + addl %ebx, %eax + cmpl %eax, %edx + ja .L7 +.L8: + popl %ebx + popl %esi + ret diff --git a/drivers/gfx.c b/drivers/gfx.c index 8dc9d74..e0c5f17 100644 --- a/drivers/gfx.c +++ b/drivers/gfx.c @@ -15,6 +15,7 @@ uint16_t fb_height; /* this is BYTES per pixel */ uint8_t fb_bpp; +uint16_t fb_stride; const uint8_t *gfx_bpp = &fb_bpp; const uint16_t *gfx_width = &fb_width; @@ -73,19 +74,18 @@ void gfx_reset(void) void gfx_drawchar(int x, int y, char c) { - int stride = fb_bpp * fb_width; - uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * stride); + uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); + const uint32_t bg = _gfx_bgcol; + const uint32_t fg = _gfx_fgcol; for(int i = 0; i < FONT_HEIGHT; ++i) { - uint32_t line_buf[8] = {_gfx_bgcol}; - uint8_t mask = 0x80; - for(int j = 0; j < 8; ++j, mask >>= 1) + uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; + for(int j = 0; j < 8; ++j) { - if(gfx_font[(int)c][i] & mask) - line_buf[j] = _gfx_fgcol; + if(gfx_font[c][i] & mask_table[j]) + ((uint32_t*)line_addr)[j] = fg; } - memcpy(line_addr, line_buf, sizeof(line_buf)); - line_addr += stride; + line_addr += fb_stride; } } @@ -126,12 +126,67 @@ void gfx_puts(const char* str) } } +/* implemented in assembly */ +#if 0 +void gfx_hline(int x1, int x2, int y) +{ + /* make sure x1 is to the left of x2 */ + if(x2 < x1) + { + int temp = x1; + x1 = x2; + x2 = temp; + } + + uint8_t *base = framebuffer + y * fb_stride; + + uint8_t *dest = base + x1 * fb_bpp; + uint8_t *stop = base + x2 * fb_bpp; + const uint32_t col = _gfx_fgcol; + while(dest < stop) + { + *(uint32_t*)dest = col; + dest += fb_bpp; + } +} + +void gfx_vline(int y1, int y2, int x) +{ + /* make sure y1 is above y2 */ + if(y2 < y1) + { + int temp = y1; + y1 = y2; + y2 = temp; + } + + uint8_t *dest = framebuffer + y1 * fb_stride + x * fb_bpp; + uint8_t *stop = framebuffer + y2 * fb_stride + x * fb_bpp; + const uint32_t col = _gfx_fgcol; + while(dest < stop) + { + *(uint32_t*)dest = col; + dest += fb_stride; + } +} +#endif + +#define SWAP(x, y, tmp) (tmp=x;x=y;y=tmp;) +void gfx_fillrect(int x, int y, int w, int h) +{ + for(int i = 0; i < h; ++i) + { + gfx_hline(x, x + w, y + i); + } +} + bool gfx_init(struct vbe_info_t *vbe_mode_info) { framebuffer = (uint8_t*)vbe_mode_info->physbase; fb_width = vbe_mode_info->Xres; fb_height = vbe_mode_info->Yres; fb_bpp = vbe_mode_info->bpp / 8; + fb_stride = fb_bpp * fb_width; if(fb_bpp != 4) { printf("WARNING: BPP != 32, falling back to text mode...\n"); diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h index 42ada32..561eb3e 100644 --- a/drivers/include/gfx.h +++ b/drivers/include/gfx.h @@ -54,6 +54,12 @@ void gfx_set_background(uint32_t); uint32_t gfx_get_background(void); +void gfx_hline(int x1, int x2, int y); + +void gfx_vline(int y1, int y2, int x); + +void gfx_fillrect(int x1, int y1, int w, int h); + extern const uint16_t *gfx_width, *gfx_height; /* this is _BYTES_ per pixel, NOT BITS per pixel! */ diff --git a/kernel/irq-as.S b/kernel/irq-as.S index 12de4b6..8840299 100644 --- a/kernel/irq-as.S +++ b/kernel/irq-as.S @@ -44,96 +44,96 @@ irq_stub: _irq0: cli - push $0 - push $32 + pushl $0 + pushl $32 jmp irq_stub _irq1: cli - push $0 - push $33 + pushl $0 + pushl $33 jmp irq_stub _irq2: cli - push $0 - push $34 + pushl $0 + pushl $34 jmp irq_stub _irq3: cli - push $0 - push $35 + pushl $0 + pushl $35 jmp irq_stub _irq4: cli - push $0 - push $36 + pushl $0 + pushl $36 jmp irq_stub _irq5: cli - push $0 - push $37 + pushl $0 + pushl $37 jmp irq_stub _irq6: cli - push $0 - push $38 + pushl $0 + pushl $38 jmp irq_stub _irq7: cli - push $0 - push $39 + pushl $0 + pushl $39 jmp irq_stub _irq8: cli - push $0 - push $40 + pushl $0 + pushl $40 jmp irq_stub _irq9: cli - push $0 - push $41 + pushl $0 + pushl $41 jmp irq_stub _irq10: cli - push $0 - push $42 + pushl $0 + pushl $42 jmp irq_stub _irq11: cli - push $0 - push $43 + pushl $0 + pushl $43 jmp irq_stub _irq12: cli - push $0 - push $44 + pushl $0 + pushl $44 jmp irq_stub _irq13: cli - push $0 - push $45 + pushl $0 + pushl $45 jmp irq_stub _irq14: cli - push $0 - push $46 + pushl $0 + pushl $46 jmp irq_stub _irq15: cli - push $0 - push $47 + pushl $0 + pushl $47 jmp irq_stub diff --git a/kernel/isr-as.S b/kernel/isr-as.S index 464ec5b..858ce47 100644 --- a/kernel/isr-as.S +++ b/kernel/isr-as.S @@ -60,155 +60,155 @@ isr_stub: _isr0: cli - push $0 - push $0 + pushl $0 + pushl $0 jmp isr_stub _isr1: cli - push $0 - push $1 + pushl $0 + pushl $1 jmp isr_stub _isr2: cli - push $0 - push $2 + pushl $0 + pushl $2 jmp isr_stub _isr3: cli - push $0 - push $3 + pushl $0 + pushl $3 jmp isr_stub _isr4: cli - push $0 - push $4 + pushl $0 + pushl $4 jmp isr_stub _isr5: cli - push $0 - push $5 + pushl $0 + pushl $5 jmp isr_stub _isr6: cli - push $0 - push $6 + pushl $0 + pushl $6 jmp isr_stub _isr7: cli - push $0 - push $7 + pushl $0 + pushl $7 jmp isr_stub _isr8: cli - push $8 + pushl $8 jmp isr_stub _isr9: cli - push $0 - push $9 + pushl $0 + pushl $9 jmp isr_stub _isr10: cli - push $10 + pushl $10 jmp isr_stub _isr11: cli - push $11 + pushl $11 jmp isr_stub _isr12: cli - push $12 + pushl $12 jmp isr_stub _isr13: cli - push $13 + pushl $13 jmp isr_stub _isr14: cli - push $14 + pushl $14 jmp isr_stub _isr15: cli - push $0 - push $15 + pushl $0 + pushl $15 jmp isr_stub _isr16: cli - push $0 - push $16 + pushl $0 + pushl $16 jmp isr_stub _isr17: cli - push $0 - push $17 + pushl $0 + pushl $17 jmp isr_stub _isr18: cli - push $0 - push $18 + pushl $0 + pushl $18 jmp isr_stub _isr19: cli - push $0 - push $19 + pushl $0 + pushl $19 jmp isr_stub _isr20: cli - push $0 - push $20 + pushl $0 + pushl $20 jmp isr_stub _isr21: cli - push $0 - push $21 + pushl $0 + pushl $21 jmp isr_stub _isr22: cli - push $0 - push $22 + pushl $0 + pushl $22 jmp isr_stub _isr23: cli - push $0 - push $23 + pushl $0 + pushl $23 jmp isr_stub _isr24: cli - push $0 - push $24 + pushl $0 + pushl $24 jmp isr_stub _isr25: cli - push $0 - push $25 + pushl $0 + pushl $25 jmp isr_stub _isr26: cli - push $0 - push $26 + pushl $0 + pushl $26 jmp isr_stub _isr27: cli - push $0 - push $27 + pushl $0 + pushl $27 jmp isr_stub _isr28: cli - push $0 - push $28 + pushl $0 + pushl $28 jmp isr_stub _isr29: cli - push $0 - push $29 + pushl $0 + pushl $29 jmp isr_stub _isr30: cli - push $0 - push $30 + pushl $0 + pushl $30 jmp isr_stub _isr31: cli - push $0 - push $31 + pushl $0 + pushl $31 jmp isr_stub diff --git a/kernel/main.c b/kernel/main.c index 927a497..211be18 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -19,7 +19,7 @@ void gpf(struct regs_t regs) { printf("General protection fault!\n"); printf("EIP before fault: 0x%x\n", regs.eip); - printf("Error code: %d\n", regs.err_code); + printf("Error code: 0x%x\n", regs.err_code); panic("GPF"); } @@ -78,6 +78,7 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) gfx_drawpixel(rx, ry); } int endpix = *current_tick; + int startfill = *current_tick; for(int i=0;i<1000;++i) { @@ -97,11 +98,43 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) gfx_drawchar(rx, ry, rand()%127+1); } int endtext = *current_tick; + gfx_clear(); + + int starthline = *current_tick; + for(int i=0;i<1000000;++i) + { + gfx_hline(rand() % *gfx_width, rand() % *gfx_width, rand() % *gfx_height); + } + int endhline = *current_tick; + + gfx_clear(); + + int startvline = *current_tick; + for(int i=0;i<1000000;++i) + { + gfx_vline(rand() % *gfx_height, rand() % *gfx_height, rand() % *gfx_width); + } + int endvline = *current_tick; + + int startrect = *current_tick; + for(int i=0;i<1000;++i) + { + int x = rand() % *gfx_width; + int y = rand() % *gfx_height; + int w = rand() % (*gfx_width - x); + int h = rand() % (*gfx_height - y); + gfx_fillrect(x, y, w, h); + } + int endrect = *current_tick; + gfx_reset(); printf("--- Graphics benchmark results ---\n"); printf("Ticks for 1,000,000 random pixels: %d\n", endpix-startpix); printf("Ticks for 1,000 random fills: %d\n", endfill-startfill); printf("Ticks for 1,000,000 random chars: %d\n", endtext-starttext); + printf("Ticks for 1,000,000 random hlines: %d\n", endhline-starthline); + printf("Ticks for 1,000,000 random vlines: %d\n", endvline-startvline); + printf("Ticks for 1,000 random rects: %d\n", endrect-startrect); printf("Ticks per second: %d\n", HZ); printf("Resolution: %dx%dx%d\n", *gfx_width, *gfx_height, *gfx_bpp * 8); } @@ -119,5 +152,4 @@ void main(struct multiboot_info_t *hdr, uint32_t magic) ps2_set_leds(PS2_CAPS_LOCK); timer_delay(HZ/4); } - while(1); } |