Temat: 1 bitplanowy triangle filler na blitterze

Zgodnie z obietnicą wrzucam trójkąta na blitterze. Można pokombinować z flagą "blitMode" - 0 oznacza tryb HOG, 1 - tryb współdzielenia szyny (dzięki sprytnemu restartowaniu blittera i tak mamy 90% szybkości trybu HOG). Wypełnienie trójkąta o współrzędnych 0,0 -> 319,199 -> 0,199 zajmuje około 30% czasu ramki.

Ostatnio edytowany przez Tomasz Wachowiak (2015-02-23 21:56:56)

Post's attachments

btriang1.zip 4.68 kb, liczba pobrań: 10 (od 2015-02-23) 

Tylko zalogowani mogą pobierać załączniki.

2

Odp: 1 bitplanowy triangle filler na blitterze

Fajnie:) Mam nadzieję, że w przyszłym tygodniu będę miał trochę czasu by zerknąć dokładniej w kod i go przeanalizować. Z tego co widziałem to jest scan line fill, gdzie wyznaczać X1,x2 dla Y'ków i rysujesz H line blitter'em, tak?
Ciekawi mnie czy robiłeś porównanie cpu / blitter dla różnych trójkątów? Robiłem podobny eksperyment kiedyś i dla dużych trójkątów było znacznie szybciej blitter'em, ale już przy małych trójkątach (które są bardziej życiowe o obiektach 3d) inicjalizacja blitter'a była bardziej kosztowna niż zysk z jego prędkości ponad cpu i bardziej opłacało mi się używać cpu dla takich sytuacji. Testy był robiony na szybko więc pewnie dało się tą inicjalizację zrobić szybciej i zniwelować efekt. Ciekaw jestem Twoich odczuć i czy robiłeś takie porównania praktyczne? (nie chodzi mi o teoretyczne timingi)

Ostatnio edytowany przez mkm (2015-02-24 08:51:55)

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF

Odp: 1 bitplanowy triangle filler na blitterze

mkm napisał/a:

Fajnie:) Mam nadzieję, że w przyszłym tygodniu będę miał trochę czasu by zerknąć dokładniej w kod i go przeanalizować. Z tego co widziałem to jest scan line fill, gdzie wyznaczać X1,x2 dla Y'ków i rysujesz H line blitter'em, tak?

Dokładnie tak.. :D

mkm napisał/a:

Ciekawi mnie czy robiłeś porównanie cpu / blitter dla różnych trójkątów? Robiłem podobny eksperyment kiedyś i dla dużych trójkątów było znacznie szybciej blitter'em, ale już przy małych trójkątach (które są bardziej życiowe o obiektach 3d) inicjalizacja blitter'a była bardziej kosztowna niż zysk z jego prędkości ponad cpu i bardziej opłacało mi się używać cpu dla takich sytuacji. Testy był robiony na szybko więc pewnie dało się tą inicjalizację zrobić szybciej i zniwelować efekt. Ciekaw jestem Twoich odczuć i czy robiłeś takie porównania praktyczne? (nie chodzi mi o teoretyczne timingi)

Spróbujemy jednak teoretycznie na początek, ok? :P Nadmiarowy kod dla blittera to:

    asr.w    #3,d3
    move.w    d1,endmsk1(a6)
    move.l    d4,xCount(a6)
    move.b    #$a0,lineNum(a6); HOG

w przypadku linii poniżej 16 pikseli i

    asr.w    #3,d3  ;8+6
    addq.w    #1,d3  ;4
                   
    swap    d3   ;4
    move.w    d5,d3  ;4

    move.w    d0,endmsk1(a6)  ;12
    move.w    d1,endmsk3(a6)  ;12
    move.l    d3,xCount(a6)     ;16
                   
    move.b    #$a0,lineNum(a6); HOG   16

w przypadku linii powyżej 16 pikseli.

Mamy więc 82 cykle na odpalenie blittera.

Na motorli dochodzi wyliczenie skoku do właściwej długości linii i sam skok. Coś takiego:

        move.l    linesAdr(a4,d3.w),a5  ;20
    jmp        (a5)  ; 8

       and.w   d0,d2   ; maski w linii pierwszej wypełniającej   +4
       and.w   d1,d3  ; maski w linii ostatniej wypałniającej     +4

Rejestry są z czapy, chodzi o wyliczenia :)

Odejmując wszystko wychodzi, że inicjalizacja blittera zabiera o 46 cykle więcej, a to jest  w przybliżeniu 4  "move.w d0,i(a6)" - wypełniania na motoroli. To daje 4*16 = 64 piksele. Tyle w najlepszym przypadku zdąży narysować motorola, zanim blitter weźmie się do pracy. Czyli gdzieś po 80-100 blitter dogoni motorolkę.

Zmiana wypełniania z blittera na motorolkę jest w sumie banalna, więc można sobie napisać procedurę i zobaczyć, czy wyliczenia się potwierdzą. :)

Wydaje mi się, że 1-bitplanowe trójkąty wykorzystuje się jednak do wypełniania prostych (i dużych) figur, bo jeśli chcemy mieć skomplikowany obiekt (który prawdopodobnie nie zmieści się jednej ramce), to warto rozważyć użycie wieloplanowego wypełniania, żeby obiekt odpowiednio pokolorować.

Ostatnio edytowany przez Tomasz Wachowiak (2015-02-24 10:03:52)

Odp: 1 bitplanowy triangle filler na blitterze

Blitterem można wypełnić kilka polygonów na raz, co powoduje że przy bardziej skomplikowanych scenach (więcej niż jedna bryła), praktycznie zawsze będzie wydajniejszy od CPU.

Atari: FireBee, (Falcon030 CT60e SuperVidel SvEthlana CTPCI), TT, (520ST Pak030 Frak PuPla Panther), (520ST 4MB ST RAM 8MB TT RAM CosmosEx SC1435), (1040STFM UltraSatan SM124), (1040STE 4MB ST RAM 8MB TT RAM CosmosEx NetUSBee SM144 SC1224), 260ST, 520 ST+, (MEGA ST SM125), (65XE Rapidus U1MB VBXE SIDE2 SIO2PC), (Jaguar SkunkBoard), Lynx II, 2x Portfolio

5

Odp: 1 bitplanowy triangle filler na blitterze

@Wachu no właśnie miałem podobne obserwacje, aż moje face'y miały relatywnie krótkie linie to nie widziałem ogólnie zysku ze scan line fill na bliterze. przy duuuuzych face'a racja zysk będzie dokładnie jak to udowodniłeś.

@Adam blitterem można wypełniać kilka obiektów na raz ale nie scan line fill'em tylko eor fill'em. technika jest tu inna. no ale wtedy blitter musi czytać i zapisywać dane przez co działa wolniej. ale jest inicjalizowany raz i tak jak mówisz wypełniasz całą scenę "na raz". wszystko ma swoje wady i zalety:) dodatkowo eor fill'em dostajesz bonus wypełniania obiektów niewypukłych.

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF

Odp: 1 bitplanowy triangle filler na blitterze

Adam Klobukowski napisał/a:

Blitterem można wypełnić kilka polygonów na raz, co powoduje że przy bardziej skomplikowanych scenach (więcej niż jedna bryła), praktycznie zawsze będzie wydajniejszy od CPU.

Jestem zaintrygowany... W jaki sposób?

Odp: 1 bitplanowy triangle filler na blitterze

mkm napisał/a:

@Wachu no właśnie miałem podobne obserwacje, aż moje face'y miały relatywnie krótkie linie to nie widziałem ogólnie zysku ze scan line fill na bliterze. przy duuuuzych face'a racja zysk będzie dokładnie jak to udowodniłeś.

:D

mkm napisał/a:

@Adam blitterem można wypełniać kilka obiektów na raz ale nie scan line fill'em tylko eor fill'em. technika jest tu inna. no ale wtedy blitter musi czytać i zapisywać dane przez co działa wolniej. ale jest inicjalizowany raz i tak jak mówisz wypełniasz całą scenę "na raz". wszystko ma swoje wady i zalety:) dodatkowo eor fill'em dostajesz bonus wypełniania obiektów niewypukłych.

Macie gdzieś jakieś materiały o tym?

8

Odp: 1 bitplanowy triangle filler na blitterze

Tomasz Wachowiak napisał/a:

Macie gdzieś jakieś materiały o tym?

Rysujesz sam obrys trojkat'a. Nie linie tylko obrys tak by mieć dla każdego X dokładnie dwa punkty Y1, Y2 zapalone na ekranie. Potem robiś EOR każdej linii z linia-1. i masz wypełniony cały blitowany obszar nie zaleznie ile obrysów i i lle face'ów tam masz. czas jest stały - czasem to dobrze a czasem to źle;) Wady: blitter musi czytac i zapisywać dane przez co działa wolniej, jesli masz mało face'ów ale na wielu bitplanach to pewnie wyjdzie wolniej. Jeśli masz dużo małych face'ów np. na 2 planach to może wyjść fajnie.

Ostatnio edytowany przez mkm (2015-02-24 10:24:00)

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF

Odp: 1 bitplanowy triangle filler na blitterze

Wachu: wygogluj eor fill. Chwile zajęło mi zrozumienie jak to działa, ale MKM mi dopomógł :)

Atari: FireBee, (Falcon030 CT60e SuperVidel SvEthlana CTPCI), TT, (520ST Pak030 Frak PuPla Panther), (520ST 4MB ST RAM 8MB TT RAM CosmosEx SC1435), (1040STFM UltraSatan SM124), (1040STE 4MB ST RAM 8MB TT RAM CosmosEx NetUSBee SM144 SC1224), 260ST, 520 ST+, (MEGA ST SM125), (65XE Rapidus U1MB VBXE SIDE2 SIO2PC), (Jaguar SkunkBoard), Lynx II, 2x Portfolio

Odp: 1 bitplanowy triangle filler na blitterze

Kurcze. Dzisiaj napiszę sobie to wypełnianie na Motoroli. Wydaję mi się, że zbyt optymistycznie podszedłem do samej prędkości blittera. Wyliczenia są raczej dobre, ale chyba warto sprawdzić to (jak pisał MKM) w praktyce.

11

Odp: 1 bitplanowy triangle filler na blitterze

z tego co widzę to masz parę rejestrów adresowych wolnych.
tak więc, tutaj mógłbyś przypisać każdej masce osobny An i zejść z 24 do 16 cykli:

                    move.w    d0,endmsk1(a6)        ;first line mask
                    move.w    d1,endmsk3(a6)        ;last line mask

tutaj również dedykowany An, dodatkowo nie ma potrzeby zmiany yCount, więc zamiast Longa możesz zapisać Word:

                    move.l    d3,xCount(a6)        ;xcount = d3, ycount = 1 at once

czyli zamiast 16 mamy 8 cykli

tu również dedykowany An:

                    move.b    #$a0,lineNum(a6); HOG   16

zamiast 16 mamy 12 cykle


Czyli z 82 cykli inicjalizacji mógłbyś zejść do 62.

Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
http://260ste.atari.org

Odp: 1 bitplanowy triangle filler na blitterze

Cyprian napisał/a:

z tego co widzę to masz parę rejestrów adresowych wolnych.
tak więc, tutaj mógłbyś przypisać każdej masce osobny An i zejść z 24 do 16 cykli:

                    move.w    d0,endmsk1(a6)        ;first line mask
                    move.w    d1,endmsk3(a6)        ;last line mask

tutaj również dedykowany An, dodatkowo nie ma potrzeby zmiany yCount, więc zamiast Longa możesz zapisać Word:

                    move.l    d3,xCount(a6)        ;xcount = d3, ycount = 1 at once

czyli zamiast 16 mamy 8 cykli

tu również dedykowany An:

                    move.b    #$a0,lineNum(a6); HOG   16

zamiast 16 mamy 12 cykle


Czyli z 82 cykli inicjalizacji mógłbyś zejść do 62.

W rzeczywistym kodzie zostaje mi jeden wolny rejestr adresowy :(, a yCount MUSI być inicjalizowany co blitta. Jednak masz rację, że z 8-12 cykli dało by się w tym kodzie jeszcze urwać.

13

Odp: 1 bitplanowy triangle filler na blitterze

faktycznie masz rację z yCount. 
Ale możesz zamienić xCount z yCount (czyli również Destination X increment oraz Destination y increment) dzięki temu xCount będzie tylko raz inicjowany a yCount przed każdym blitem.
Takie rozwiązanie zastosowałem w mojej procedurze dla sprajtów:

;BLiTTER Init
    move.l    #$00020002,(A0)+        ; source X increment / source Y increment
    move.l    A2,(A0)+            ; source address
    move.l    #-1,(A0)+            ; mask 1 /2
    move.w    #-1,(A0)+            ; mask 3
    move.l    #$00080080,(A0)+        ; destination X increment / destination Y increment
    lea        2(A0),A4            ; remember source destination
    move.l    A3,(A0)+            ; destination address
    move.w    #$0005,(A0)+        ; count X surface
    movea.l    A0,A1                ; remember count Y surface
    move.w    D0,(A0)+            ; count Y surface
    move.w    #$0204,(A0)+        ; HOP / LOP
    move.w    D4,(A0)                ; BUSY / HOG / SMUDGE / LINE NUMBER // FXSR / NFSR / SKEW


; Copy MaskSprite to Screen
    move.b    D2,(A0)                ; start blitter

    REPT    3
        lea        2(A3),A3
        move.w    A3,(A4)            ; destination address
        move.w    D0,(A1)            ; count Y surface
        move.b    D2,(A0)            ; start blitter
    ENDR

;
;BLITTER RE-INIT Sprite to Screen
    lea        $FFFF8A3C.w,A0
    move.l    A5,A3
    move.w    #$0207,$FFFF8A3A.w        ; HOP / LOP

; Copy Sprite to Screen
    move.w    A3,(A4)                ; destination address
    move.w    D0,(A1)                ; count Y surface
    move.b    D2,(A0)                ; start blitter

    REPT    3
        lea        2(A3),A3
        move.w    A3,(A4)            ; destination address
        move.w    D0,(A1)            ; count Y surface
        move.b    D2,(A0)            ; start blitter
    ENDR

Ostatnio edytowany przez Cyprian (2015-02-24 14:29:36)

Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
http://260ste.atari.org

Odp: 1 bitplanowy triangle filler na blitterze

Cyprian napisał/a:

faktycznie masz rację z yCount. 
Ale możesz zamienić xCount z yCount (czyli również Destination X increment oraz Destination y increment) dzięki temu xCount będzie tylko raz inicjowany a yCount przed każdym blitem.
Takie rozwiązanie zastosowałem w mojej procedurze dla sprajtów:

;BLiTTER Init
    move.l    #$00020002,(A0)+        ; source X increment / source Y increment
    move.l    A2,(A0)+            ; source address
    move.l    #-1,(A0)+            ; mask 1 /2
    move.w    #-1,(A0)+            ; mask 3
    move.l    #$00080080,(A0)+        ; destination X increment / destination Y increment
    lea        2(A0),A4            ; remember source destination
    move.l    A3,(A0)+            ; destination address
    move.w    #$0005,(A0)+        ; count X surface
    movea.l    A0,A1                ; remember count Y surface
    move.w    D0,(A0)+            ; count Y surface
    move.w    #$0204,(A0)+        ; HOP / LOP
    move.w    D4,(A0)                ; BUSY / HOG / SMUDGE / LINE NUMBER // FXSR / NFSR / SKEW


; Copy MaskSprite to Screen
    move.b    D2,(A0)                ; start blitter

    REPT    3
        lea        2(A3),A3
        move.w    A3,(A4)            ; destination address
        move.w    D0,(A1)            ; count Y surface
        move.b    D2,(A0)            ; start blitter
    ENDR

;
;BLITTER RE-INIT Sprite to Screen
    lea        $FFFF8A3C.w,A0
    move.l    A5,A3
    move.w    #$0207,$FFFF8A3A.w        ; HOP / LOP

; Copy Sprite to Screen
    move.w    A3,(A4)                ; destination address
    move.w    D0,(A1)                ; count Y surface
    move.b    D2,(A0)                ; start blitter

    REPT    3
        lea        2(A3),A3
        move.w    A3,(A4)            ; destination address
        move.w    D0,(A1)            ; count Y surface
        move.b    D2,(A0)            ; start blitter
    ENDR

Pamiętaj Cyprian, że xCount wraz ze wzrostem/skróceniem długości linii zwiększa się lub zmniejsza i trzeba reagować na bieżąco. :) Przy blicie spritea faktycznie można xCounta raz ustawić.
P.S. Piękny kod swoją drogą, wszystko z minimalną ilością cykli. :)

15

Odp: 1 bitplanowy triangle filler na blitterze

no tak, ale możesz dać albo:

  xCount = 40 / yCount = 1

albo:

  xCount = 1 / yCount = 40

z tego co pamiętam efekt jest ten sam operacja dokonywana jest na tych samych 40stu słowach.
Oczywiście w zależności od wariantu trzeba odpowiednio ustawić Destination X/Y increment.

---edycja---

przemyślałem to jeszcze raz,  w wariancie xCount = 1 może być problem z zastosowaniem EndMask

Ostatnio edytowany przez Cyprian (2015-02-24 15:40:19)

Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
http://260ste.atari.org

Odp: 1 bitplanowy triangle filler na blitterze

Cyprian napisał/a:

no tak, ale możesz dać albo:

  xCount = 40 / yCount = 1

albo:

  xCount = 1 / yCount = 40

z tego co pamiętam efekt jest ten sam operacja dokonywana jest na tych samych 40stu słowach.
Oczywiście w zależności od wariantu trzeba odpowiednio ustawić Destination X/Y increment.

Hehehe. A tego to nie wiedziałem. Jak widać zawsze można się czegoś nowego dowiedzieć. :D

Edit: Wystarczy wyjść, stanąć obok i spojrzeć z innej strony. :P Faktycznie wystarczy zmienić x na y i powinno działać.

Ostatnio edytowany przez Tomasz Wachowiak (2015-02-24 15:51:42)

17

Odp: 1 bitplanowy triangle filler na blitterze

w międzyczasie wyedytowałem posta:
przemyślałem to jeszcze raz,  w wariancie xCount = 1 może być problem z zastosowaniem EndMask

Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
http://260ste.atari.org

Odp: 1 bitplanowy triangle filler na blitterze

Cyprian napisał/a:

w międzyczasie wyedytowałem posta:
przemyślałem to jeszcze raz,  w wariancie xCount = 1 może być problem z zastosowaniem EndMask

Hahahhaa :D A ja już się z tobą w międzyczasie zgodziłem. Masek nie rozważałem.

19

Odp: 1 bitplanowy triangle filler na blitterze

i jeszcze coś mi wpadło do głowy. Czy faktycznie poniższa instrukcja jest potrzebna?

   move.w    d5,d3  ;4

"addq.w    #1,d3  ;4" robisz w obrębie Word a nie Long

Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
http://260ste.atari.org

Odp: 1 bitplanowy triangle filler na blitterze

Cyprian napisał/a:

i jeszcze coś mi wpadło do głowy. Czy faktycznie poniższa instrukcja jest potrzebna?

   move.w    d5,d3  ;4

"addq.w    #1,d3  ;4" robisz w obrębie Word a nie Long

Pamiętaj, że po tych operacjach w d3 jest trzymany i xCount i yCount.

21

Odp: 1 bitplanowy triangle filler na blitterze

Panowie, bardzo proszę o poprawienie cytatów zgodnie z regulaminem. Tego się czytać nie da. Timer 24h.

Czy możecie wyjaśnić, Stirlitz, dlaczego wasz służbowy adres stirlitz@rsha.gov.de ma aliasa justas@gru.su?
Nie czytam PM. Proszę używać e-mail.

22

Odp: 1 bitplanowy triangle filler na blitterze

Ostatnio odbył się kompot z produkcjami na 1bitplan (na ST). Może będzie kolejny. Wtedy z 1bitplanowym fillerem będziecie do przodu :).

23

Odp: 1 bitplanowy triangle filler na blitterze

Tomasz Wachowiak napisał/a:

P.S. Piękny kod swoją drogą, wszystko z minimalną ilością cykli. :)

a dzięki :)

Bober napisał/a:

Ostatnio odbył się kompot z produkcjami na 1bitplan (na ST). Może będzie kolejny. Wtedy z 1bitplanowym fillerem będziecie do przodu :).

ten filler można zastosować również do wielu bitplanów

Lynx I / Mega ST 1 / 7800 / Portfolio / Lynx II / Jaguar / TT030 / Mega STe / 800 XL / 1040 STe / Falcon030 / 65 XE / 520 STm / SM124 / SC1435
DDD HDD / AT Speed C16 / TF536 / SDrive / PAK68/3 / Lynx Multi Card / LDW Super 2000 / XCA12 / SkunkBoard / CosmosEx / SatanDisk / UltraSatan / USB Floppy Drive Emulator / Eiffel / SIO2PC / Crazy Dots / PAM Net
http://260ste.atari.org