kategoria: Asembler
[#1] Lustrzane odbicie grafiki w poziomie. Blitter.
Chcę szybko odbić blok grafiki w poziomie przy pomocy blittera.
Użycie procesora z tablicą 64k w której są odwrócone bity wydaje się najprostsze ale chcę cała operację wykonać w tle a w tym czasie CPU będzie robić inne rzeczy.
Może być kilka blitów, jakieś pomysły?
[#2] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #1

Jeśli odbicie poziome oznacza z lewa na prawą i nawzajem, to nie da się zrobić tego rozsądnie.

Też tego nie potrzebowałem ale blitter takich rzeczy nie umi. Możesz za to zrobić oddzielny blit dla każdego jednopikselowego słupa ale będzie to wielokrotnie wolniejsze od tablicy i CPU.
[#3] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@teh_KaiN, post #2

Lustrzane czyli z lewej na prawą. LUT dla CPU miałby 128kb (nie 64 jak pisałem) i zawierał słowa z odwróconą kolejnością bitów ale to nie wchodzi w grę.

Problem dokładniej wygląda tak że mam na ekranie połowę obrazu w górnej części i chcę aby w dolnej połówce było to samo ale odbite w pionie i w poziomie. Odbicie w pionie to najprostsze wykorzystanie ujemnego modulo od połowy ekranu ale jak zrobić odbicie poziome? Wszystkie triki blitter + copper dozwolone ale chciałbym przy minimalnym wykorzystaniu CPU.

Ostatnia aktualizacja: 12.01.2019 12:34:45 przez Kefir_Union
[#4] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #1

a takimi rzeczami to nie zajmuja sie ludzie ze sceny?
moze to ich warto zapytac..
[#5] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #3

blitter umie tylko shiftować prawo czytane WORDy, przy czym z lewej strony dostawia bity z poprzednio zaczytanego WORDa (znjaduje się w rejestrze bltXdat). No masz i modulo jak ustalaniu wyświetlania obrazu, ustawialny dla każdego kanału blitowania oddzielnie. Masz też do dyspozycji blit przez maskę i możesz faktycznie blitować słupami jednopikselowymi, ale zamęczysz tym Amigę. Ja bym zacisnął zęby i zrobił to używając CPU, rozkładając to w czasie na parę klatek. Ale ja jestem głupi i może czegoś nie widzę, więc może jakiś wyjadacz podpowie. ;)

Jak zaczynałem bawić się w Amigą i chciałem zrobić port jednej gry, to potrzebowałem odwracać grafikę. Ktoś mi bodaj w tym wątku podpowiedział tablicę.

EDYT: O kuźwa, w tamtym wątku nawet ludzie kulturni byli i co nieco próbowali uświadomić, wytłumaczyć. Nie to co teraz, jad w każdym poście. ;)

Ostatnia aktualizacja: 12.01.2019 13:17:16 przez teh_KaiN
[#6] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #3

Tego typu operacja wymaga kilka blitów.

Koszt jest logarytmiczny względem ilości pikseli, więc bardzo efektywny.

Idea jest taka, by zamieniać miejscami bloki grafiki - najpierw duże, 8-bitowe potem mniejsze, 4-bitowe, 2-bitowe i 1-bitowe.

Jak masz piksele: 01234567 i chcesz otrzymać 76543210 to robisz tak:

Pierwszy blit: 01234567 -> 45670123
Maska $f0.

Drugi blit: 45670123 -> 67452301
Maska $cc.

Trzeci blit: 67452301 -> 76543210
Maska $aa

I gotowe. W ten sposób obróciliśmy kolejność bitów. Jeżeli masz szersze bloki niż 16 bitów do obrócenia to musisz też poprzestawiać odpowiednie słowa w analogiczny sposób, ale wykorzystując "duże" maski w kanale A albo wykorzystując CPU do zwyczajnego kopiowania.

Co do obracania za pomocą CPU - można też wykorzystać 256-elementową tablicę i przerabiać po bajcie.

Przy okazji: witaj, miło przywitać nowego kolegę.

@Teh_KaiN
Ja bym zacisnął zęby i zrobił to używając CPU, rozkładając to w czasie na parę klatek

Ciekawy jestem czym lepiej to zrobić. Rzeczywiście chyba CPU zrobi to sprawniej. Ale warto naprawdę oszczędzać czas CPU skoro Blitter może się tym zająć.

Ostatnia aktualizacja: 12.01.2019 14:32:02 przez Hexmage960
[#7] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #6

Blok do odwrócenia ma 360x144 i 4 bitplany więc sporo. Czy jesteś w stanie oszacować czas Twojego algorytmu z użyciem tylko blittera? Przed odwróceniem kolejności bitów trzeba jeszcze odwrócić kolejność słów na ekranie na co potrzeba jakieś 9 kroków przy tej szerokości ekranu.

Użycie CPU do kopiowania nie wchodzi w grę ponieważ czas wyjdzie mniej więcej taki jak użycie LUT.

Ostatnia aktualizacja: 12.01.2019 14:49:17 przez Kefir_Union
[#8] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #7

Skoro koszt jest logarytmiczny, więc koszt dla szerokości 360 będzie rzędu log(360), a to się równa 9. Zatem będzie 9 blitów.

Oczywiście mnożysz to przez liczbę bitplanów, czyli mamy 36 blitów na danych o rozmiarze 22 słów pamięci na jeden wiersz obrazu.

Ostatnia aktualizacja: 12.01.2019 14:56:12 przez Hexmage960
[#9] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #8

Czyli minimum 2 ramki obrazu a pewnie bliżej trzech. Za wolno, potrzebuję czegoś co zmieści się w ramce.
[#10] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #9

Warto CPU wykorzystać do przestawiania słów pamięci. Koszt będzie mniejszy niż użycie Lookup-table, a ponadto przechodzisz po pikselach dokładnie raz.

Blitter można użyć do finalnego przestawiania bloków. W tym przypadku CPU i Blitter wykonają robotę podobnie efektywnie, choć Blitter musi zaglądać czterokrotnie do pamięci, a procesor tylko raz.
[#11] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #6

Blitter pracuje 16-bitowo i dokleja do danych ostatnio odczytane słowo. Jak masz kanał A = 0123'4567'89AB'CDEF, kanał D to docelowe miejsce i zrobisz maskę F0 i pójdziesz z blitterowym shiftem o 8, to dostaniesz na mintermie D=A: xxxx'xxxx'0123'4567 gdzie x to bity z poprzedniego słowa (bltXdat) wepchnięte z lewej.

Więc albo czegoś nie widzę, czegoś zapomniałem albo jednak potrzebujesz jeszcze jednego blitu z mintermem D = C|A (trochę inny bo potrzebujesz zastąpić "śmieci" z poprzedniego blita czyli coś z negacją maski), który z kolei będzie miał maskę 0F i "shiftował w lewo" czyli ustawiasz tak duży shift żeby się bltXdat ze słowem przed chwilą odczytanym przekręcił, czyli wartość shifta... 24?

Ostatnia aktualizacja: 12.01.2019 15:31:46 przez teh_KaiN
[#12] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@teh_KaiN, post #11

Więc albo czegoś nie widzę, czegoś zapomniałem albo jednak potrzebujesz jeszcze jednego blitu z mintermem D = C|A, który z kolei będzie miał maskę 0F i "shiftował w lewo" czyli ustawiasz tak duży shift żeby się bltXdat ze słowem przed chwilą odczytanym przekręcił, czyli wartość shifta... 24?

Nie zastanawiałem się głębiej nad tym. W sumie gdy pisałem tamten post myślałem, że potrzeba dwóch blitów na przestawienie.

Dzięki za spostrzeżenie. Chyba można zrobić każde przestawienie bloków bitowych jednym blitem przesuwając dane cały czas w prawo (o 8, 4, i 2 bity). Wówczas musimy zarezerwować tylko troszkę pamięci za buforem z pikselami. Przesunięcie "24-bity" załatwia się poprzez zapis do następnego słowa pamięci.

W sumie dość ciekawa i złożona kwestia. Trzeba by się zastanowić.

Ostatnia aktualizacja: 12.01.2019 15:44:32 przez Hexmage960
[#13] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #10

Z użyciem LUT też przechodzisz tylko raz po pikselach. Odczytujesz słowa na końcu i początku linii, pobierasz dla nich odwróconą kolejność z LUT a następnie zamieniasz te słowa miejscami i przesuwasz się w kierunku środka linii.
[#14] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #13

Tak, ale z LUT przechodzisz po 8 albo 16-bitowych wartościach. Więcej nie ma praktycznego sensu (już 64kB tablica jest zbyt duża).

W przypadku samej zamiany procesor może pobrać 32-bitowe dane, zamienić je wewnętrznie w swoich rejestrach za pomocą techniki, którą podałem (przestawiając bloki bitowe) i zapisać w odpowiednim miejscu.

Tę technikę można zastosować samym CPU albo CPU + Blitter.
[#15] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #14

Zamiana wewnętrzna 32-bitowych danych przez CPU już tak łatwo nie pójdzie. Rolowanie można robić na poziomie bajtu, na poziomie niższym dochodzą dodatkowe kombinacje z przesuwaniem bitów, w sumie kilkanaście instrukcji. To nie może być szybsze niż jeden MOVE.W z tablicy, szczególnie że można ją wrzucić do FASTu.
Tak w ogóle to ma działać na CPU 020.
[#16] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #15

Zamiana wewnętrzna 32-bitowych danych przez CPU już tak łatwo nie pójdzie. Rolowanie można robić na poziomie bajtu, na poziomie niższym dochodzą dodatkowe kombinacje z przesuwaniem bitów, w sumie kilkanaście instrukcji. To nie może być szybsze niż jeden MOVE.W z tablicy, szczególnie że można ją wrzucić do FASTu.
Tak w ogóle to ma działać na CPU 020.

Można pomierzyć.

Tak sobie wyobrażam algorytm dla CPU. Pętla zmieści się w cache procesora 68020.

Edit: Optymalizacja.

rotate	macro
	move.l	d0,d1
	and.l	\1,d0
	eor.l	d0,d1
	lsr.l	\2,d0
	lsl.l	\2,d1
	or.l	d1,d0
	endm

start:
	move.l	#$f0f0f0f0,d4
	move.l	#$cccccccc,d5
	move.l	#$aaaaaaaa,d6

loop:
	move.l	(a0)+,d0
	ror.w	#8,d0
	swap	d0		; 16 bitów
	ror.w	#8,d0
	rotate	d4,4
	rotate	d5,2
	rotate	d6,1
	move.l	d0,-(a1)
	cmpa.l	a0,a1
	bge.s	loop

	rts


Ostatnia aktualizacja: 12.01.2019 18:20:31 przez Hexmage960
[#17] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #16

Bardzo ładny kod, który świetnie przygotuje tablicę LUT :)

Ostatnia aktualizacja: 12.01.2019 18:49:22 przez Kefir_Union
[#18] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #1

W zasadzie nie napisałeś czy blok grafiki jest taki sam przez cały czas pokazywania go. Wtedy to najszybciej to sobie wcześniej odbić i cześć.
Nie wiadomo jaką operację chcesz robić w tle, może zwyczajnie odwrócić rolę, to co masz robić w tle dać dla CPU a to co ma działać cpu niech ogarnie copper + blitter o ile się to da.

Edyta: Na EAB znajdziesz ciekawy thread o flipie link

Ostatnia aktualizacja: 12.01.2019 21:19:18 przez asman
[#19] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@asman, post #18

Odbijam animację, która na pełnym ekranie nie zmieści się w chip.
[#20] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@asman, post #18

Czesc Kefir - kope lat!!!

Znalazlem jakis stary kod to tego sprzed lat, moze sie przyda.
Uzywa tylko d0/d1 - mozna go jeszcze przyspieszyc wrzucajac stale w and do innych rejestrow.
Mozna go tez w miare latwo przerobic na blitter.

; mirror 8bits by Docent/Union in 4bytes batches
; in d0 bits to mirror, on exit mirrored bits in d0
Mirror32Bits:
move.l d0, d1
and.l #$55555555, d0
lsl.l #1, d0
and.l #$aaaaaaaa, d1
lsr.l #1, d1
or.l d1, d0

move.l d0, d1

and.l #$33333333, d0
lsl.l #2, d0
and.l #$cccccccc, d1
lsr.l #2, d1
or.l d1, d0

move.l d0, d1

and.l #$0f0f0f0f, d0
lsl.l #4, d0
and.l #$f0f0f0f0, d1
lsr.l #4, d1
or.l d1, d0

ret

Ostatnia aktualizacja: 12.01.2019 21:55:01 przez docent
[#21] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@docent, post #20

No prosze, szybciej na forum Cię można znaleźć niż gdziekolwiek indziej.
Procka konwersji oparta o ten sam algorytm co wyżej, szybszego nie ma. LUT w FAST będzie szybszy ale to i tak nie rozwiązuje problemu bo trzeba jeszcze blitować zamiany kolejności słów w linii.
Dzięki za pomoc ale muszę wymyślić coś zupełnie innego, zmniejszyć rozmiar animacji.
[#22] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #15

Skoro ma dzialac na 68020 to oprocz wersji z tablica, raczej najszybsza bedzie jedna z wersji z instrukcjami dzialajacymi na polach bitowych. A w wersjach docenta/hexmage to lsl.l #1 mozna na add.l zamienic ale to niewiele szybsze bedzie.

Ostatnia aktualizacja: 12.01.2019 23:42:40 przez Don_Adan
[#23] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #21

LUT w FAST będzie szybszy ale to i tak nie rozwiązuje problemu bo trzeba jeszcze blitować zamiany kolejności słów w linii.

Przesyłam poprawioną wersję, która prawidłowo zamienia kolejność słów w linii:

a0 wskazuje na początek linii
a1 wskazuje na koniec linii (tuż za ostatnim długim słowem).

rotate	macro
	move.l	\1,d1
	and.l	\2,\1
	eor.l	\1,d1
	lsr.l	#\3,\1
	lsl.l	#\3,d1
	or.l	d1,\1
	endm

start:
	move.l	#$f0f0f0f0,d4
	move.l	#$cccccccc,d5
	move.l	#$aaaaaaaa,d6

loop:
	move.l	(a0),d0
	ror.w	#8,d0
	swap	d0
	ror.w	#8,d0
	rotate	d0,d4,4
	rotate	d0,d5,2
	rotate	d0,d6,1

	move.l	-(a1),d2
	ror.w	#8,d2
	swap	d2
	ror.w	#8,d2
	rotate	d2,d4,4
	rotate	d2,d5,2
	rotate	d2,d6,1

	move.l	d2,(a0)+
	move.l	d0,(a1)
	cmpa.l	a0,a1
	bgt.s	loop

	rts


Ostatnia aktualizacja: 13.01.2019 07:39:06 przez Hexmage960
[#24] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #23

Ładnie to wygląda. Zostaje jeszcze wolny rejestr D3, można wpakować do niego #8. Rezygnując z makra z parametrem 1, przerobić lsl na add.
Wracając do mojego problemu z początku posta to niestety dalej go nie rozwiązuje. Mam animację, która nie mieści się w chip. Jeśli mam ją odwracać kopiując z chip do chip to już lepiej zamieścić w chip animację z klatkami obciętymi do połowy a brakującą resztę do fastu w wersji już obróconej i kopiować ją movem.

Ostatnia aktualizacja: 13.01.2019 08:29:46 przez Kefir_Union
[#25] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #24

Mam animację, która nie mieści się w chip. Jeśli mam ją odwracać kopiując z chip do chip to już lepiej zamieścić w chip animację z klatkami obciętymi do połowy a brakującą resztę do fastu w wersji już obróconej i kopiować ją movem.

Zgoda. Można trzymać grafikę w postaci planar również w FAST i na tej pamięci dokonywać konwersji, a później dopiero wklejać do CHIP.

Dla jakiej Amigi to piszesz? Rozumiem, że dla nierozbudowanej Amigi 1200 (z pamięcią FAST).

W przypadku Amigi CD32 można skorzystać z AKIKO by znacznie przyśpieszyć działanie takich operacji na grafice.

Ostatnia aktualizacja: 13.01.2019 08:55:16 przez Hexmage960
[#26] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #25

A co ma tu do rzeczy Akiko? Przeciez nie chodzi o zadna konwersje c2p tylko o mirror obrazu...
[#27] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@docent, post #26

Przy pomocy Akiko można oszczędzić na wielu instrukcjach. Lustrzane odbicie sprowadzałoby się do:

ror.w #8,d0
swap d0
ror.w #8,d0

A Akiko by to hardwarowo wkleiło do pamięci CHIP.
[#28] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Kefir_Union, post #24

Wracając do mojego problemu z początku posta to niestety dalej go nie rozwiązuje. Mam animację, która nie mieści się w chip. Jeśli mam ją odwracać kopiując z chip do chip to już lepiej zamieścić w chip animację z klatkami obciętymi do połowy a brakującą resztę do fastu w wersji już obróconej i kopiować ją movem.

Mozesz spakowac klatki jakims algorytmem typu rle i rozpakowywac na biezaco w trakcie odgrywania - np. rozpakowujesz z gory 4 klatki do bufora w chipie i zaczynasz wyswietlac. Jak wyswietlisz 2 klatke to zaczynasz dekompresowac do 1 klatki. Taki triple buffering tylko dla wiekszej liczby klatek :)
Przelaczanie klatek na przerwaniu, dekompresja w glownej petli moze od razu takze odwracac.
[#29] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@Hexmage960, post #27

Niczego nie oszczedzisz.
Akiko nic hardwareowo nie wkleja do chipu - to tylko rejestr hw, do ktorego wrzucasz 8 kolejnych longwordow z bufora chunky i odczytujesz 8 skonwertowanych longwordow do wrzucenia do kolejnych bitplanow - i nic wiecej.

Ostatnia aktualizacja: 13.01.2019 15:17:29 przez docent
[#30] Re: Lustrzane odbicie grafiki w poziomie. Blitter.

@docent, post #29

Ale konwersja jest hardwarowa. Może źle się wyraziłem.

Niczego nie oszczedzisz.

Jest oszczędność. Odpada rotacja o 4, 2 i 1 bitów. A danych przerobić musisz dokładnie tyle samo.

Ostatnia aktualizacja: 13.01.2019 15:21:04 przez Hexmage960
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem