Hardware Blitter? Any success?
#1
Posted 14 December 2005 - 10:50 AM
I tried in many ways to do some basic rectangle-filling or area copy, but nothing happens. I just set a lot of registers, but i don't know how to "trigger" the real operation.
Any suggestion will be appreciated :)
#2
Posted 14 December 2005 - 01:28 PM
Rlyeh has said he will have accelerated blitting routines out this week. I'm waiting for those since I cannot work it out myself.
#3
Posted 14 December 2005 - 06:17 PM
I think that bit 8 of MESGSRCCTRL determines whether or not the blitter fetches it's own data or relies on the CPU to pump data to MESGFIFO maybe setting this bit will start a transfer?
Otherwise you could try setting bit 10 of MESGCTRL to clear the FIFO.
Hopefully I'll get a chance to mess around with it when I figured out the toolchain, set up the compiler etc. etc.
I'll let you know if I figure anything out.
#4
Posted 14 December 2005 - 07:41 PM
#include <errno.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
FILE *out;
void *trymmap (void *start, size_t length, int prot, int flags, int fd, off_t offset)
{
char *p;
int aa;
fprintf (out, "mmap(%X, %X, %X, %X, %X, %X) ... ", (unsigned int)start, length, prot, flags, fd, (unsigned int)offset);
p = mmap (start, length, prot, flags, fd, offset);
if (p == (char *)0xFFFFFFFF)
{
aa = errno;
fprintf (out, "failed. errno = %d\n", aa);
}
else
{
fprintf (out, "OK! (%X)\n", (unsigned int)p);
}
return p;
}
int main(int argc, char *argv[]) {
//open fb0 and mem
out = stdout;
int fb0 = open("/dev/fb0", O_RDWR);
int mem = open("/dev/mem", O_RDWR);
//find physical address of fb
struct fb_fix_screeninfo fixed_info;
ioctl(fb0, FBIOGET_FSCREENINFO, &fixed_info);
//mmap fb to screen
unsigned short *screen = trymmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, mem, fixed_info.smem_start);
//mmap regs
unsigned long *reg1l = trymmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, mem, 0xc0000000);
unsigned short *reg1s = (unsigned short *)reg1l;
unsigned long *reg2l = trymmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, mem, 0xE0020000);
unsigned short *reg2s = (unsigned short *)reg2l;
reg1s[0x28DA>>1]=0x04AB; // 16bpp
reg1s[0x290C>>1]=320*2; // line width in bytes
// draw something in (0,0)-(31, 31)
int i, j;
for (i=0; i<32; i++) {
for (j=0; j<32; j++) {
screen[i*320 + j] = i<<11 | j<<6 | (i+j)>>1;
}
}
sleep(3);
reg1l[0x090a>>2] = 0xFFFFFFFF;
// copy (0,0)-(31, 31) in (32,32)-(63,63)
// Dest control
reg2l[0x0000 >> 2] = 0 << 6 |
1 << 5 |
0 << 0;
// Dest base
reg2l[0x0004 >> 2] = fixed_info.smem_start + (32*2)*320 + (32*2);
// Dest stride
reg2l[0x0008 >> 2] = 320 * 2;
// Source control
reg2l[0x000C >> 2] = 1 << 8 |
1 << 7 |
1 << 5 |
0 << 0;
// Source base
reg2l[0x0010 >> 2] = fixed_info.smem_start;
// Source stride
reg2l[0x0014 >> 2] = 320 * 2;
// Source FG
reg2l[0x0018 >> 2] = 0x0000FFFF;
// Source BG
reg2l[0x001C >> 2] = 0x00000000;
// Pattern control
reg2l[0x0020 >> 2] = 0x01 >> 6 |
0x01 >> 5 |
0x02 >> 3 |
0x00 >> 0;
// Pattern reg
reg2l[0x0080 >> 2] = 0xFFFFFFFF;
// Pattern FG
reg2l[0x0024 >> 2] = 0x0000FFFF;
// Pattern BG
reg2l[0x0028 >> 2] = 0x0000FFFF;
// Size
reg2l[0x002C >> 2] = 32 << 16 | 32 << 0;
// Control reg
reg2l[0x0030 >> 2] = 0x00 << 16 |
0x00 << 11 |
0x01 << 10 |
0x01 << 9 |
0x01 << 8 |
0xFF << 0;
sleep(3);
munmap(reg1l, 0x10000);
munmap(reg2l, 0x10000);
munmap(screen, 320*240*2);
close(mem);
close(fb0);
chdir("/usr/gp2x"); //go to menu
execl("gp2xmenu","gp2xmenu",NULL);
}
Should draw a rainbow square, sleep 3 seconds, copy it, sleep 3 seconds, and quit.
Currently, it just draws, sleeps 3 seconds, does nothing at all :( , sleeps 3 seconds and quits.
#5
Posted 14 December 2005 - 08:56 PM
Oscaruzzo, on Dec 14 2005, 08:41 PM, said:
The only thing I noticed is that you seem to be shifting the wrong way when you write to the pattern control register.
You could try clearing the screen to a weird colour (like pink) first so you can see if any data is written to the frame buffer.
This post has been edited by TheDoktor: 14 December 2005 - 08:56 PM
#6
Posted 15 December 2005 - 12:50 AM
I put in a loop to check the busy bit of the blitter and it seems to get stuck there.
This is what I wrote:
// wait for the blitter to be free
while(reg2l[0x0034 >> 2] & 1) // check busy bit
{
sleep(1);
}
this was before any of the registers were set and it seems to get stuck here.
The only thing I can think of is that the blitter needs to get enabled or something somewhere else. I'll do a scan of the docs and see what I can find.
#10
Posted 15 December 2005 - 07:35 AM
icurafu, on Dec 15 2005, 05:35 AM, said:
Errr man page says
unsigned int sleep(unsigned int seconds);
;)
#11
Posted 15 December 2005 - 07:39 AM
TheDoktor, on Dec 14 2005, 10:56 PM, said:
Good idea. I'll try it this evening... But the "busy bit" you mention really bothers me, i guess there must be some way to enable the blitter...
I tried to activate a bunch of random clock with
reg1l[0x090a>>2] = 0xFFFFFFFF;
but doesn't seem to help.
#13
Posted 15 December 2005 - 10:48 AM
Oscaruzzo, on Dec 15 2005, 08:39 AM, said:
TheDoktor, on Dec 14 2005, 10:56 PM, said:
Good idea. I'll try it this evening... But the "busy bit" you mention really bothers me, i guess there must be some way to enable the blitter...
I tried to activate a bunch of random clock with
reg1l[0x090a>>2] = 0xFFFFFFFF;
but doesn't seem to help.
I tried clearing the screen to blue but no data is being written.
Another thing I was thinking was how does writing to these registers work with the CPU data cache? I remember when I was getting started on the PS2 & DC I had problems writing to hardware registers because I was writing to cached memory and the data was staying in the CPU cache and not going to the hardware.
I also noticed that your ROP code should probably be 0xCC for a straight src copy but that didn't make it work either!
I'll hack around a bit more today is I have time and if I find anything I'll post it straight away.
#15
Posted 15 December 2005 - 12:42 PM
Galleon, on Dec 15 2005, 06:20 AM, said:
Indeed, 3d graphics are 2D triangles with a depth buffer. If you are lucky you get the matrix multiplication thrown in, but its not necessary, as processors can do 4x4 matrix math quick enough. Luckily the Blue Book nicely prints its matrix operations for OpenGL so a straight poirt is easy.

Sign In
Register
Help

MultiQuote