gp2x rlyeh's minimal lib

30 replies · 25,832 views

gp2x rlyeh's minimal lib
@tesla, senin kullandığın devkit iyi sanırım. Lib'lerle ilgili bir sıkıntı yaşarsan şunu indirmeyi deneyebilirsin. http://archive.gp2x.de/cgi-bin/cfiles.cgi?0,0,0,0,19,1875
@gnostic, hmmz, aklıma gelmemişti. SDL'de fazla rahata alıştım ya 🙂.
gp2x rlyeh's minimal lib
tabi hic makefile'i hic dusunmedik.. benim makefile'dan flag'ler kismi.. ihtiyacina gore parametrelerden cikartabilirsin/ekleyebilirsin:
MORE_CFLAGS  = -O3 -mcpu=arm9 -mtune=arm920t
MORE_CFLAGS += -msoft-float -ffast-math -fomit-frame-pointer -Wno-unused -Wno-format -DGCCCONSTFUNC=__attribute__((const))" 
//MORE_CFLAGS += -mthumb-interwork
MORE_CFLAGS += -DUSE_UNDERSCORE -fno-exceptions -DREGPARAM=  -DOPTIMIZED_FLAGS -D__inline__=__inline__ 
MORE_CFLAGS += -DSHM_SUPPORT_LINKS=0
MORE_CFLAGS += -Ie:/devkitGP2X/include -Ie:/devkitGP2X/include/SDL -Le:/devkitGP2X/lib
MORE_CFLAGS += -ftracer -fstrict-aliasing -mstructure-size-boundary=32 -fexpensive-optimizations
MORE_CFLAGS += -falign-functions=32 -falign-loops -falign-labels -falign-jumps
MORE_CFLAGS += -finline -finline-functions -fno-builtin -funroll-loops -floop-optimize2

&quot wrote:Bendeki sorunu cozdum. Sorun benim eşşek olmammış. -O3 ile compile ettim ve 88-90 FPS aldım. Herhalde alınabilecek olan anca budur. 🙂 Yardımlarınız için teşekkürler.
gp2x rlyeh's minimal lib
tesla wrote:Ama başka bir wiki sayfasında dediği üzere
1. FrameBuffer = 0x3101000
2. FrameBuffer = 0x3381000

dogrusu bu..
tesla wrote:1- En doğru hardware blit nasıl yapılır? Yukardaki karmaşıklık mmu hack yüzünden mi oluyor? (32 MB'ı bütün gibi ele almak)
2- SDL kullanmak istersek hangi paketi seçmeliyiz.
Ben şu ana kadar Full Devkit 2006/03/06 kullanıyordum. En geçerli olan bu sanıyordum?

1. SDL kullandigin icin, HW_SURFACE (uppermem) kullandigin surece sdl'de blit islemleri mmuhack ile (uppermem cacheleme) hizli olacaktir. (madde 2ye bak)
2. sectigin paket guzel ANCAK bildigim kadari ile o paket icinden cikan SDL lib'leri HW lib destekli degil. bu sebeple, o paketi kurduktan sonra HW blit destekli sdl lib'lerini kullandiginda sorun yasamazsin.
ayrica 2 farkli hw sdl lib'i var.. biri 6, digeri 16mb'lik sanirim.. (framebuffer size alloc size)
---
peki bunlari bir kenara atip, kendimiz hardware blit nasil yapariz?
aslinda olay oldukca kolay, zamaninda konu ile ilgili yapilan ve olayin zormus gibi gozumesine sebep olan tartismalarin ozu sudur ki;
elimizde bir hw blitter oldugunu biliyorduk ama bunun registerlarini set ettigimizde istedigimiz sonuc cikmiyordu.. paeryn sanirim FAST_IO 'yu set etmemiz gerektigini farkedinceye kadar herkes birseyler denedi..
simdii.. bu noktada, mame, noiz2a, SDL lib vs'nin source'larini cekip incelediginizde nasil yapildigini gorme sansiniz var..
ama ben yinede (biraz minilib uyumlu olarak ama tek basina calisabilecek sekilde) adim adim bir anlatayim;
1) once HW registerlara felan ulasmak icin memory device
memfd = open("/dev/mem", O_RDWR);
gp2x_memregl = (unsigned long *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0xc0000000);
gp2x_memregs = (unsigned short *)gp2x_memregl;
gp2x_2dregs = (unsigned long *)mmap(0, 0x118, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0xe0024000);

2) meshur blitter enable olayi
gp2x_memregs[0x90a >> 1] = 0xffff; // Enable all video and sound devices
gp2x_memregs[0x904 >> 1] |= (1 << 10); // Enable FASTIO for the hardware blitter

vee.. ve'si yok bu kadar 🙂
ornek bir code:
void hw_blit(unsigned short *src, int xc, int yc, int w, int h) {
    unsigned short *dst;
    unsigned short offset;

    dst = (unsigned short*)[B]0x3101000[/B] + (yc*320) + xc;
    offset = (unsigned short)((unsigned long)dst & 2);

    gp2x_2dregs[MESGDSTCTRL] = (1 << 5) | (0 << 6) | (offset << 3);
    gp2x_2dregs[MESGDSTADDR] = (unsigned long)dst & 0xfffffffc;
    gp2x_2dregs[MESGDSTSTRIDE] = 320*2;
    gp2x_2dregs[MESGSRCCTRL] = (1 << 8) | (1 << 7) | (1 << 5);
    gp2x_2dregs[MESGSRCADDR] = [B]0x3101000[/B];
    gp2x_2dregs[MESGSRCSTRIDE] = 64;
    gp2x_2dregs[MESGPATCTRL] = 0;
    gp2x_2dregs[MESGSIZE] = (h << 16) | (w << 0);
    gp2x_2dregs[MESGCTRL] = (0 << 10) | (1 << 9) | (1 << 8) | 0xCC;
    gp2x_2dregs[MESGSTATUS] = 0x0;
    do {} while (gp2x_2dregs[MESGSTATUS] & 1);
}

bunu hardwaresiz yapmak isteseydi:
fb0 = open("/dev/fb0", O_RDWR);

void sw_blit(unsigned short *src, int xc, int yc, int w, int h) {
    unsigned int x, y;
    unsigned short *dst;

    dst = fb0 + (yc*320) + xc;
    for (y=0; y<h; y++) {
        for (x=0; x<w; x++) {
            *dst++ = *src++;
        }
        dst += 320-w;
    }
}
gp2x rlyeh's minimal lib
Abi sağol oldukça faydalı oldu, banada sonunda oturup sıfırdan kendi kodumu yazma konusunda ilham verdin...
gp2x rlyeh's minimal lib
gnostic, abi seni paso yoruyoruz ama verdigin ornek direk birinci fb'i ikinciye kopyaliyor sanirsam. fonksiyona giren src parametresi hicbir yerde kullanilmiyor. ben oraya kendi yukledigim bir resmin adresini verince program blit fonksiyonundan bir daha geri donmedi.
Sanirim ust hafizayi kullanmak gerekiyor. bu konuda hic ornek bulamadim. Elinde kisa bir ornek varsa alabilir miyiz?
/*
Planet Retro - Retrocomputing News and Blogs
*/
gp2x rlyeh's minimal lib
benim hatam, src'yi MESGSRCADDR icin kullanacagiz ama absolute (fiziksel) adresini vermemiz gerekiyor ve evet ust hafizayi kullanacagiz..
calisan komple bir ornek yazip, gondereyim en temizi.. 🙂
gp2x rlyeh's minimal lib
Ben de anca girebiliyorum GP2X coding olaylarına. Bu tartışılanlar benim de çok işime yarayacak, teşekkürler.
gp2x rlyeh's minimal lib
evet.. ekteki test1 ornegini mumkun oldugunca kucuk tutmaya calistim..
SDL, minilib vs kullanmadan tek basina compile edebilirsiniz..
compile edip calistirdiginizda, ekranda plasma benzeri bir efekt goreceksiniz.
ustundede 32*32 lik bir beyaz kutu.. joystick ile bu kutuyu ekranda dolastirabilirsiniz.. (kutunun hafif flicker etmesi dogal keza double buffer yapmadan direkt framebuffer'a yaziyoruz)
code'da da goreceginiz uzere;
fb0 = ekranda aktif olarak gorunun buffer (plasma bufferi)
fb1 = bembeyaz bir ekran, buradan sadece 32*32'lik bir kismi kopyalayip ekranda dolastiriyoruz.
yapilabilecekler:
* farkli ROP islemleri ile neler yapilabiliyor onu deneyin..
* fb1 'a bir imaj koyup, onu blit edin..
*
a) 0x200000 adresinden daha yukarida bir adrese imaj yukleyin (wiki: upper memory)
b) fb0/fb1'i olmasi gerektigi gibi double buffer icin kullanin
simdi bu b maddesi icin iki yolunuz var..
1) fb0 aktif ekran.. fb1 buffer'iniz.. fb1'e cizer ve burayi komple fb0'a blit edersiniz. blit denemesi acisindan uygun.
2) fb adreslerini switch edebilirsiniz. (bkz. minilib flip)
gp2x rlyeh's minimal lib
@gnostic: son yolladigin ornek acayip faydali oldu. Neredeyse half-screen blitting = 750fps. Hardware blitter gercekten hizliymis. Tesekkurler bu kadar ugrastigin icin 😉
Bu arada dikkatleri bir konuya cekmek istiyorum. usleep galiba gp2x'de bozuk. usleep(1) anlamsiz uzun bir sure uyuyor. Duzgun bir karsiligini bilen var mi?
/*
Planet Retro - Retrocomputing News and Blogs
*/
gp2x rlyeh's minimal lib
while (gp2x_blitter[0x0034 >> 2] & 1) {
        asm volatile ("nop");
        asm volatile ("nop");
        asm volatile ("nop");
        asm volatile ("nop");
}
asm volatile ("" ::: "memory");

🙂
jimqode wrote:@gnostic: son yolladigin ornek acayip faydali oldu. Neredeyse half-screen blitting = 750fps. Hardware blitter gercekten hizliymis. Tesekkurler bu kadar ugrastigin icin 😉
Bu arada dikkatleri bir konuya cekmek istiyorum. usleep galiba gp2x'de bozuk. usleep(1) anlamsiz uzun bir sure uyuyor. Duzgun bir karsiligini bilen var mi?
gp2x rlyeh's minimal lib
Evet, ben de sonunda GP2X coding olayına girmiş bulundum (thx to Ragnor). I.F.O'yu Ragnor ile birlikte GP2X'e port ettik. şu anda yavaş da olsa çalışıyor, hem de hiç eksiksiz. Ama yavaşlık da göze epey bir batıyor. ışin en dandik tarafı ise yavaşlık stable değil. Kesik kesik yavaşlayıp hızlanma durumları söz konusu. sadece mmu hack kullanıyorum ki onu da ne derece düzgün kullandığımdan emin değilim. Makefile, optimization level v.s. olayları inceliicem, bakalım oradan birkaç FPS kazanabilirmiyiz. Ama SDL'in hızının yeteceğini hiç sanmıyorum. Eninde sonunda bu topicde geçen yöntemlere bir bir başvurmaya başliicam. Bakalım sonuç ne olacak...
gp2x rlyeh's minimal lib
hayirli olsun, super haber 😃
skate wrote:Evet, ben de sonunda GP2X coding olayına girmiş bulundum (thx to Ragnor).
gp2x rlyeh's minimal lib
ellerine sağlık Gnos, çok güzel bir tutorial olmuş, afiyetle okudum uyguladım, "20fps artıyo la bu" diyen Spritus'a da göstermek lazım 🙂
100% pure coder pr0n
gp2x rlyeh's minimal lib
Ya şu minimal library'i bir test ediim dedim, en basit 3-5 satırlık exampleları (sadece init mesela) 675 KB output verdi şok oldum (v0.B kullanıyorum). bunun neresi "minimal" ya 😉 Yani demek istediğim 675 KB bu olayın minimumu mu? SDL örnekleri de zaten 2 MB falan compile ediyordu. 64K olayını unutalım yani GP2X'de? 🙂
Not: Sanki daha önceleri birileri bu konudan bahsetmişti ama üşenmez tekrar cevaplarsınız ümidiyle history okumaya üşendim.