.[ ČeskéHry.cz ].
specialni kopirovani pameti
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
frca



Založen: 28. 07. 2007
Příspěvky: 1554

PříspěvekZaslal: 4. leden 2024, 00:09:07    Předmět: specialni kopirovani pameti Odpovědět s citátem

Zdravim, potreboval bych co nejrychleji zkopirovat kazdou ctvrtou polozku ve zdrojovem poli a ulozit je za sebe do ciloveho pole (ktere je 4x mensi). Nebo z jineho uhlu pohledu vzit pole 32-bit intu a nakopirovat ho do 8-bit intu (pricemz 3 bajty se oriznou).
Snazim se dostat linearni framebuffer do 4-strankoveho mode x. Kompilator DJGPP.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 4. leden 2024, 05:15:07    Předmět: Re: specialni kopirovani pameti Odpovědět s citátem

čau,
já bych možná zkusil něco takového (pseudo-kód):

kód:

constexpr int W = 320;
constexpr int H = 240;

// palettized colors, packed
uint colors[W*H/4];
uint packed[4][W*H/4/4];

inline uint mix_lo(uint a, uint b, uint c, uint d)
{
   return
      cast byte a | (cast byte b << 8) | (cast byte c << 16) |
      cast byte d << 24;
}

void make_compact()
{
   for (int dsti : W*H/4/4)
   {
      int i = dsti << 2;

      // x86 addressing: should boil down to dsti*4+offset
      auto a = colors[i+0];
      auto b = colors[i+1];
      auto c = colors[i+2];
      auto d = colors[i+3];

      packed[0][dsti] = mix_lo(a, b, c, d);

      a >>= 8;
      b >>= 8;
      c >>= 8;
      d >>= 8;

      packed[1][dsti] = mix_lo(a, b, c, d);

      a >>= 8;
      b >>= 8;
      c >>= 8;
      d >>= 8;

      packed[2][dsti] = mix_lo(a, b, c, d);

      a >>= 8;
      b >>= 8;
      c >>= 8;
      d >>= 8;

      packed[3][dsti] = mix_lo(a, b, c, d);
   }
}


kde colors je tvůj LFB, otázka je, jestli bude mít compiler dost registrů a jak rychlé jsou shifty na 486ce
základní myšlenka: načítat po 32-bitech, pak zabalit a uložit po 32ti bitech do "packed" bufferu v RAM
pak bude stačit jenom nastavit bitplane a zkopírovat z packed bufferů do VGA (klidně po 32-bit, stejně bude záležet akorát na rychlosti a šírce VGA sběrnice)

pokud to je pro 486, asi nevím o žádné magické instrukci, co by to nějak usnadnila, takže bych to asi nechal na překladači (třeba se mu podaří vymyslet i něco chytrého a odstranit nějaké shifty) pokud se ti nechce do inline assembly

chtělo by to vidět disassembly, co gcc vygeneruje, to by mohlo být zajímavé

samozřejmě je možné, že bude rychlejší i naivní způsob, kde se to bude číst po bajtech a lepit do 32-bit wordu a nasype se to rovnou do VGA paměti, bude asi potřeba zprofilovat všechno
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 4. leden 2024, 07:10:02    Předmět: Re: specialni kopirovani pameti Odpovědět s citátem

tak nakonec se mi to povedlo do inline assembly, je to v msvc a tam nešly použít konstanty, tak tam mám všude natvrdo 320x240:
předpokládám, že všechny buffery jsou globály a nemusí se držet v registrech.

kód:

void make_compact_asm()
{
   __asm
   {
      // dsti
      xor edi, edi

   _loop:
      lea eax, [edi*8]

      mov ebx, [colors + eax + eax + 0*4]
      mov ecx, [colors + eax + eax + 1*4]
      mov edx, [colors + eax + eax + 2*4]
      mov esi, [colors + eax + eax + 3*4]

      // mix!
      shrd eax, edx, 8
      shrd eax, esi, 8
      mov al, bl
      mov ah, cl

      // store packed0
      mov [packed + 0*320*240/4 + 4*edi], eax

      // shift
      shr ebx, 8
      shr ecx, 8
      shr edx, 8
      shr esi, 8

      // mix!
      shrd eax, edx, 8
      shrd eax, esi, 8
      mov al, bl
      mov ah, cl

      // store packed1
      mov [packed + 1*320*240/4 + 4*edi], eax

      // shift
      shr ebx, 8
      shr ecx, 8
      shr edx, 8
      shr esi, 8

      // mix!
      shrd eax, edx, 8
      shrd eax, esi, 8
      mov al, bl
      mov ah, cl

      // store packed2
      mov [packed + 2*320*240/4 + 4*edi], eax

      // shift
      shr ebx, 8
      shr ecx, 8
      shr edx, 8
      shr esi, 8

      // mix!
      shrd eax, edx, 8
      shrd eax, esi, 8
      mov al, bl
      mov ah, cl

      // store packed3
      mov [packed + 3*320*240/4 + 4*edi], eax

      inc edi
      cmp edi, 320*240/4/4
      jb _loop
   }
}



jedna smyčka dělá 16 bajtů (počítám indexovaný režim s 8-bit paletou)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 4. leden 2024, 07:23:52    Předmět: Re: specialni kopirovani pameti Odpovědět s citátem

tak ještě jedna verze, shrd je pomalé i na moderních strojích, takže jsem to trochu přeskládal a upravil, tady už to je 1.5x rychlejší než msvc místo pomalejší:

kód:

void make_compact_asm2()
{
   __asm
   {
      // dsti
      xor edi, edi

   _loop:
      lea eax, [edi*8]

      mov ebx, [colors + eax + eax + 0*4]
      mov ecx, [colors + eax + eax + 1*4]
      mov esi, [colors + eax + eax + 2*4]
      mov edx, [colors + eax + eax + 3*4]

      // mix!
      mov eax, esi
      mov ah, dl
      shl eax, 16
      mov al, bl
      mov ah, cl

      // store packed0
      mov [packed + 0*320*240/4 + 4*edi], eax

      // shift
      shr esi, 8
      shr edx, 8
      shr ebx, 8
      shr ecx, 8

      // mix!
      mov eax, esi
      mov ah, dl
      shl eax, 16
      mov al, bl
      mov ah, cl

      // store packed1
      mov [packed + 1*320*240/4 + 4*edi], eax

      // shift
      shr esi, 8
      shr edx, 8
      shr ebx, 8
      shr ecx, 8

      // mix!
      mov eax, esi
      mov ah, dl
      shl eax, 16
      mov al, bl
      mov ah, cl

      // store packed2
      mov [packed + 2*320*240/4 + 4*edi], eax

      // shift
      shr esi, 8
      shr edx, 8
      shr ebx, 8
      shr ecx, 8

      // mix!
      mov eax, esi
      mov ah, dl
      shl eax, 16
      mov al, bl
      mov ah, cl

      // store packed3
      mov [packed + 3*320*240/4 + 4*edi], eax

      inc edi
      cmp edi, 320*240/4/4
      jb _loop
   }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 4. leden 2024, 09:09:17    Předmět: Re: specialni kopirovani pameti Odpovědět s citátem

ještě jsem si uvědomil, že můžu ušetřit 6 shiftů...

kód:

void make_compact_asm3()
{
    __asm
    {
        // dsti*4
        xor edi, edi

    _loop :
        mov ebx, [colors + 4*edi + 0 * 4]
        mov ecx, [colors + 4*edi + 1 * 4]
        mov esi, [colors + 4*edi + 2 * 4]
        mov edx, [colors + 4*edi + 3 * 4]

        // mix!
        mov eax, esi
        mov ah, dl
        shl eax, 16
        mov al, bl
        mov ah, cl

        // store packed0
        mov[packed + 0 * 320 * 240 / 4 + edi], eax

        // shift
        shr esi, 8

        // mix!
        mov eax, esi
        mov ah, dh
        shl eax, 16
        mov al, bh
        mov ah, ch

        // store packed1
        mov[packed + 1 * 320 * 240 / 4 + edi], eax

        // shift
        shr esi, 8
        shr edx, 16
        shr ebx, 16
        shr ecx, 16

        // mix!
        mov eax, esi
        mov ah, dl
        shl eax, 16
        mov al, bl
        mov ah, cl

        // store packed2
        mov[packed + 2 * 320 * 240 / 4 + edi], eax

        // shift
        shr esi, 8

        // mix!
        mov eax, esi
        mov ah, dh
        shl eax, 16
        mov al, bh
        mov ah, ch

        // store packed3
        mov[packed + 3 * 320 * 240 / 4 + edi], eax

        add edi, 4
        cmp edi, 320 * 240 / 4
        jb _loop
    }
}

Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frca



Založen: 28. 07. 2007
Příspěvky: 1554

PříspěvekZaslal: 4. leden 2024, 19:28:54    Předmět: Odpovědět s citátem

Díky moc, kopírování po 32 bitech mě nějak nenapadlo.

Alignment adres u 486 a starších nehraje roli, jestli se nepletu...?
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
frca



Založen: 28. 07. 2007
Příspěvky: 1554

PříspěvekZaslal: 4. leden 2024, 22:08:00    Předmět: Odpovědět s citátem

Mám první výsledky z 486tky a hned ten první C++ zdroják jede jak z praku. Pardon za vágní popis performance, zatím nemám přesnější metodu Wink

Edit: asi 12 ms to trvá na 486/66

Ještě chci vyzkoušet to přímé kopírování do VRAM bez mezibufferu.

Edit 2: ^ je o něco pomalejší.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 5. leden 2024, 00:50:06    Předmět: Odpovědět s citátem

super!

jakože přímé kopírování je pomalejší?
jak je na tom 486ka se zarovnáním netuším, ale mohlo by stačit použít alignas

tak ještě tu poslední asm verzi by mě zajímalo docela jak to poběží, jestli jsem ručně schopný na 486ce beatnout gcc Smile

ale přepisovat to do ohavné at&t syntaxe by se mi asi taky moc nechtělo Smile

EDIT: (ještě by to šlo přeložit v netwide assembleru jako position independent a udělat self-modifying code a pak přes nějaký tool to zkonvertovat a includnout v C++ - takhle jsem v robodovi dělal sample mixing rutiny)
EDIT2: udělal jsem to, máš link v PM
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frca



Založen: 28. 07. 2007
Příspěvky: 1554

PříspěvekZaslal: 6. leden 2024, 00:04:38    Předmět: Odpovědět s citátem

Vystup djgpp s -O2 vypada nejak takto. Od oka to je skoro 2x vice radku (a tedy 2x pomalejsi?)

kód:
_make_compact:
   pushl   %ebp
   movl   %esp, %ebp
   pushl   %edi
   pushl   %esi
   movl   $_framebuf, %esi
   pushl   %ebx
   xorl   %ebx, %ebx
   .p2align 4,,7
   .p2align 3
L2:
   movl   (%esi), %ecx
   movl   12(%esi), %edi
   movl   %ecx, %edx
   movl   4(%esi), %eax
   sall   $24, %edi
   andl   $255, %edx
   orl   %edi, %edx
   movl   %eax, %edi
   sall   $8, %edi
   andl   $65535, %edi
   orl   %edi, %edx
   movl   8(%esi), %edi
   sall   $16, %edi
   andl   $16711680, %edi
   orl   %edi, %edx
   movl   %eax, %edi
   andl   $65280, %edi
   movl   %edx, _packed(,%ebx,4)
   movzbl   %ch, %edx
   orl   %edi, %edx
   movl   8(%esi), %edi
   sall   $8, %edi
   andl   $16711680, %edi
   orl   %edi, %edx
   movl   12(%esi), %edi
   shrl   $8, %edi
   sall   $24, %edi
   orl   %edi, %edx
   movl   8(%esi), %edi
   movl   %edx, _packed+19200(,%ebx,4)
   movl   %ecx, %edx
   shrl   $16, %edx
   andl   $16711680, %edi
   andl   $255, %edx
   orl   %edi, %edx
   movl   %eax, %edi
   shrl   $8, %edi
   shrl   $24, %eax
   andl   $65280, %edi
   sall   $8, %eax
   orl   %edi, %edx
   movl   12(%esi), %edi
   shrl   $16, %edi
   sall   $24, %edi
   orl   %edi, %edx
   movl   %edx, _packed+38400(,%ebx,4)
   movl   8(%esi), %edx
   shrl   $24, %edx
   sall   $16, %edx
   orl   %edx, %eax
   movl   12(%esi), %edx
   shrl   $24, %ecx
   andl   $-16777216, %edx
   orl   %edx, %ecx
   addl   $16, %esi
   orl   %ecx, %eax
   movl   %eax, _packed+57600(,%ebx,4)
   incl   %ebx
   cmpl   $4800, %ebx
   jne   L2
   popl   %ebx
   popl   %esi
   popl   %edi
   popl   %ebp
   ret

_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 6. leden 2024, 00:22:34    Předmět: Odpovědět s citátem

no to by se muselo zprofilovat, z hlavy nodhadnu. každá instrukce trvá jinak, u mě většina jsou movy

gcc kód má 60 instrukcí a 15 shiftů, můj optimalizovaný v assembly 37 a 10 shiftů, nevím co s tím udělá instruction scheduling/pipeline dependence na tom stroji, ale chtělo by to porovnat
kód co vygeneroval gcc nevypadá špatně, ale vsadil bych si že ten můj by mohl být i rychlejší - pokud ti jde primárně o výkon, což počítám, že na 486ce ano Smile

přepsat do inline assembly by neměl být problém, když už z něj. důvodu nechceš integrovat ten self-modifying kód, co jsem posílal (pokud ti jde o portování do budoucna, dalo by se to přece ifdefnout)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 6. leden 2024, 23:05:45    Předmět: Re: specialni kopirovani pameti Odpovědět s citátem

v návaznosti na PM: tady je to přepsané do at&t syntaxe,
ještě by to nějak chtělo pořešit konstanty (320*240 natvrdo), ale to už nebudu řešit:
kód:

#include <cstdint>
#include <cstdio>

using uint = uint32_t;
using byte = uint8_t;

constexpr int W = 320;
constexpr int H = 240;

// palettized colors, packed
uint colors[W*H/4];
uint packed[4][W*H/4/4];

inline uint mix_lo(uint a, uint b, uint c, uint d)
{
   return (byte)a | (byte)b << 8 | (byte) c << 16 | (byte)d << 24;
}

void make_compact()
{
   for (int dsti=0; dsti<W*H/4/4; dsti++)
   {
      int i = dsti << 2;

      auto a = colors[i+0];
      auto b = colors[i+1];
      auto c = colors[i+2];
      auto d = colors[i+3];

      packed[0][dsti] = mix_lo(a, b, c, d);

      a >>= 8;
      b >>= 8;
      c >>= 8;
      d >>= 8;

      packed[1][dsti] = mix_lo(a, b, c, d);

      a >>= 8;
      b >>= 8;
      c >>= 8;
      d >>= 8;

      packed[2][dsti] = mix_lo(a, b, c, d);

      a >>= 8;
      b >>= 8;
      c >>= 8;
      d >>= 8;

      packed[3][dsti] = mix_lo(a, b, c, d);
   }
}

void make_compact_asm3()
{
   asm volatile(
      //dsti*4
      "xor %%edi, %%edi\n"

      "_loop:\n"
      // stupid at&t: disp(base, index, scale)
      "mov %0+0*4(,%%edi,4), %%ebx\n"
      "mov %0+1*4(,%%edi,4), %%ecx\n"
      "mov %0+2*4(,%%edi,4), %%esi\n"
      "mov %0+3*4(,%%edi,4), %%edx\n"

      // mix!
      "mov %%esi, %%eax\n"
      "mov %%dl, %%ah\n"
      "shl $16, %%eax\n"
      "mov %%bl, %%al\n"
      "mov %%cl, %%ah\n"
      // store packed0
      "mov %%eax, %1+0*320*240/4(%%edi)\n"

      // shift
      "shr $8, %%esi\n"

      // mix!
      "mov %%esi, %%eax\n"
      "mov %%dh, %%ah\n"
      "shl $16, %%eax\n"
      "mov %%bh, %%al\n"
      "mov %%ch, %%ah\n"

      // store packed1
      "mov %%eax, %1+1*320*240/4(%%edi)\n"

      // shift
      "shr $8, %%esi\n"
      "shr $16, %%edx\n"
      "shr $16, %%ebx\n"
      "shr $16, %%ecx\n"

      // mix!
      "mov %%esi, %%eax\n"
      "mov %%dl, %%ah\n"
      "shl $16, %%eax\n"
      "mov %%bl, %%al\n"
      "mov %%cl, %%ah\n"

      // store packed2
      "mov %%eax, %1+2*320*240/4(%%edi)\n"

      //shift
      "shr $8, %%esi\n"

      // mix!
      "mov %%esi, %%eax\n"
      "mov %%dh, %%ah\n"
      "shl $16, %%eax\n"
      "mov %%bh, %%al\n"
      "mov %%ch, %%ah\n"

      // store packed3
      "mov %%eax, %1+3*320*240/4(%%edi)\n"

      "add $4, %%edi\n"
      "cmp $320*240/4, %%edi\n"
      "jb _loop\n"
      :
      : "m"(colors), "m"(packed)
      : "cc", "%eax", "%ebx" ,"%ecx", "%edx", "%esi", "%edi"
   );
}

int main()
{
   colors[0] = 0xfacebabeu;
   colors[1] = 0x11111111u;
   colors[2] = 0x22222222u;
   colors[3] = 0x33333333u;

   make_compact_asm3();

   printf("p0: %08x\n", (unsigned)packed[0][0]);
   printf("p1: %08x\n", (unsigned)packed[1][0]);
   printf("p2: %08x\n", (unsigned)packed[2][0]);
   printf("p3: %08x\n", (unsigned)packed[3][0]);

   return 0;
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frca



Založen: 28. 07. 2007
Příspěvky: 1554

PříspěvekZaslal: 7. leden 2024, 00:39:22    Předmět: Odpovědět s citátem

Ty jsi šílenec! Díky!

Zrychlení je nezanedbatelné.

Tady je repo: https://github.com/Franticware/dos-modex-djgpp

Je to CC0, nebo-li Public Domain.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 7. leden 2024, 03:05:28    Předmět: Odpovědět s citátem

frca napsal:
Ty jsi šílenec! Díky!

Zrychlení je nezanedbatelné.

Tady je repo: https://github.com/Franticware/dos-modex-djgpp

Je to CC0, nebo-li Public Domain.

Very Happy

super! dal jsem ti lajk, nicméně bych doporučil následující změnu (s tím už bych to klidně použil i v nějakém svém projektu, i když DOS věci mě aktuálně nelákají a HVDOSDEV loni stejně nebyl):

1) jestli čekat na vsync dát jako parametr, ne jako define, je to pružnější a užitečnější
2) používat 3 stránky místo dvou (latence bude stejná, ale umožní to fígl, co popíšu dole)

kód:

void framebuf_flip(uint8_t* VGA, int vsync)
{
    make_compact_asm3();

    static int page = 0;

    int target_page = page + 1;

    if (target_page > 2)
        target_page = 0;

    VGA += target_page * 19200;

    outp(SC_INDEX, MAP_MASK);
    outp(SC_DATA, 1);
    memcpy(VGA, packed[0], 19200);

    outp(SC_INDEX, MAP_MASK);
    outp(SC_DATA, 2);
    memcpy(VGA, packed[1], 19200);

    outp(SC_INDEX, MAP_MASK);
    outp(SC_DATA, 4);
    memcpy(VGA, packed[2], 19200);

    outp(SC_INDEX, MAP_MASK);
    outp(SC_DATA, 8);
    memcpy(VGA, packed[3], 19200);

    while (vsync && (inportb(SR) & VRETRACE))
        ;

    outpw(CRTC_INDEX, 0x000c | (0x4b00u*target_page));
    // note: could be coupled with xmode init to save this outpw
    outpw(CRTC_INDEX, 0x000d);

    while (vsync && !(inportb(SR) & VRETRACE))
        ;

    page = target_page;
}


proč použít 3 stránky místo dvou:
registr page start (0xc) se latchuje VGA hardwarem, tzn. překlopí se automaticky tak, aby to netearovalo někde na začátku nebo konci vsyncu, přesně nevím
můžeš teď renderovat bez vsyncu a bez tearingu na různých fps, pokud to je míň než 120, pak by se efekt rozbil, tzn. vyžaduje to ještě framelimiter řekněme na 100 fps
používal jsem to v robodovi, bylo to dobré, protože když nestíháš 60 tak s vsyncem máš najednou 30, když nestíháš 30 máš 20, pak 15 atd., s tímhle to je plynulejší

jediné co je bez vsyncu blbé je, že s tím nebudou fungovat dyn. změny palety (bude to sněžit) - proto je fajn ovládat vsync v runtime (např. v menu animace palety, ingame ne)

EDIT: možná by bylo elegantnější místo vsync boolu tam předávat obecně flagy a tam by mohlo být třeba jestli použít VSYNC, jestli použít 3 stránky apod., ale to už není tak důležité
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 602

PříspěvekZaslal: 7. leden 2024, 04:40:39    Předmět: Odpovědět s citátem

hmm, ještě bys mohl pls zkusit nahradit memcpy a memset za tyhle moje rutiny, používal jsem to v robodovi.
rád bych věděl, jestli to na reálné 486ce něco dá

defaultní memcpy co generuje djgpp s tím novým gcc je rep movsd, což je na moderním hw cool, ale nejsem si jistý, že to bude stejně cool i na 486
pro memset dokonce používá rep stosb, kde už přesvědčený nejsem vůbec.

samozřejmě - správná věc na moderním stroji, ale...

kód:

#ifndef MEMFAST_H
#define MEMFAST_H

#include <stddef.h>

inline void memset_fast(void *dst, int fill, int size)
{
   // unpack filler
   uint32_t ufill = uint8_t(fill);
   ufill |= ufill << 8;
   ufill |= ufill << 16;

   uint32_t *udst = (uint32_t *)dst;

   while (size >= 4*8)
   {
      udst[0] = ufill;
      udst[1] = ufill;
      udst[2] = ufill;
      udst[3] = ufill;
      udst[4] = ufill;
      udst[5] = ufill;
      udst[6] = ufill;
      udst[7] = ufill;
      udst += 8;
      size -= 4*8;
   }

   while (size >= 4)
   {
      *udst++ = ufill;
      size -= 4;
   }

   uint8_t *bdst = (uint8_t *)udst;

   while (size-- > 0)
      *bdst++ = (uint8_t)ufill;
}

inline void memcpy_fast(void *dst, const void *src, int size)
{
   uint32_t *udst = (uint32_t *)dst;
   const uint32_t *usrc = (const uint32_t *)src;

   while (size >= 4*4)
   {
      uint32_t a, b, c, d;
      a = usrc[0];
      b = usrc[1];
      c = usrc[2];
      d = usrc[3];
      udst[0] = a;
      udst[1] = b;
      udst[2] = c;
      udst[3] = d;
      usrc += 4;
      udst += 4;
      size -= 4*4;
   }

   while (size >= 4)
   {
      *udst++ = *usrc++;
      size -= 4;
   }

   uint8_t *bdst = (uint8_t *)udst;
   const uint8_t *bsrc = (uint8_t *)usrc;

   while (size-- > 0)
      *bdst++ = *bsrc++;
}

#endif


EDIT: co se koukám na ref. manuál, tak rep movsd je 12 + 3*ecx cyklů,
co jsem koukal na kód co vygeneroval gcc pro memcpy_fast tak tam by to neměl být velký rozdíl (chtělo by to změřit), ale memset_fast by měl být výrazně rychlejší, než rep stosb, který je 7+4*ecx cyklů (i kdyby to byl rep stosd, tak by měl být memset_fast rychlejší)
ten memcpy_fast by se dal ještě koukám rozrolovat víc, pokud by to stálo vůbec za to
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frca



Založen: 28. 07. 2007
Příspěvky: 1554

PříspěvekZaslal: 7. leden 2024, 08:36:17    Předmět: Odpovědět s citátem

Místo pro výměnu palety je těsně po novém framebuf_flip s vsync?
Dále, hry časuji typicky s timerem konfigurovaným na 60 Hz, takže teď by to bylo 120 Hz - to by ještě s třístránkovou metodou fungovalo? Pak by byl limiter triviální:

timer_interrupt()
{
++timer_count;
}

...
// game loop
{
while (timer_count == prev_timer_count); // wait for timer
... // game step, rendering
framebuf_flip(VGA, 0);
}

Edit: Vlastně timer/limiter na 60 Hz bude podle mě stačit. Na rychlém HW se využijí všechny frejmy módu X bez artefaktů a na pomalém VSYNC nebude nic brzdit.

Tyhle dotazy píšu pro ujištění, protože to budu i nějak dokumentovat.

Edit2: 3stránkový page flip funguje na 486 bezvadně. Je to stejně rychlé jako ten původní, ale bez artefaktů.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna