kategoria: ANSI C
[#1] Blitterowe zagadki
Siedzę nad tym od 3 dni i nie mogę zrozumieć co tu się dzieje. Nie interesuje mnie żadne inne rozwiązanie problemu, tylko sama przyczyna pojawiania się krzaków.

Załóżmy hipotetyczną sytuację, że jest sobie bitmapa 16x15 (wysokość nieistotna), której zawartość prezentuje się następująco:


W niechlujnym powiększeniu:


Prostokąt jest szeroki na 10 pikseli. I teraz, chcę sobie przeblitować tę bitmapę wycinając z niej prostokąt o szerokości 11 (jedna kolumna pusta za prostokątem) i narzucając shift, odpowiednio ustawiając rejestry blittera. I robię to i częściowo działa:



Niedziałające przypadki są robione trybem descending (wiem że można ascending ale to nie jest tematem tej dyskusji). Rozpatrzmy pierwszy bugujący się przykład:

źródło jest ustawiane jako początek bitmapy, szerokość blitu dwa wordy, modulo po każdej linii -2. Maska lewa 0x0000, maska prawa 0xFFFF << 5. Wycinek z moich logów:

Blit width: 32 (2 words)
LMask: 0x0, RMask: 0xFFE0
Shift: 10
Modulo: src -2

Wygląda to tak, jakby maska z lewej nie działała. O co chodzi? Nadmienię, że moja funkcja blitująca radzi sobie z prawie wszystkim (nawet z wieloma rodzajami descending mode) i możliwe, że to jest ostatni przypadek, który wadliwie działa.

Nie chcę rzucać kodu, bo jest w nim straszny bajzel. Ma ktoś pomysł, skąd te śmieci? Niby przez blit długości dwóch wordów wchodzi na dane następnej linii, ale nie powinien ich pobierać bo lewa maska (w tym przypadku rejestr bltlwm) jest ustawiona na 0.

Ostatnia aktualizacja: 19.07.2015 12:28:08 przez teh_KaiN
[#2] Re: Blitterowe zagadki

@teh_KaiN, post #1

Dużo rzeczy tutaj nie rozumiem. Co masz na mysli pisząc 'przeblitować' ? Chodzi Ci o skopiowanie tego prostokata 11x15 na ekran ( operacja na bliterze D= A) ? Czy masz na myśli tzw cookie-cut (operacja D = AB + aC) ?
Napisz co wpisujesz do rejestrów blittera, jak zapisany jest obrazek, i jaki ekran jest i czy to AGA i jaki masz fmode na AGA.
[#3] Re: Blitterowe zagadki

@teh_KaiN, post #1

Na mój gust to zapomniałeś uwzględnić zasady używania trybu descending.

Otóż w trybie descending blitter zmniejsza adresy, odejmuje modulo i przesuwa w lewo.

Oznacza to, że musisz ustawić adres źródła na koniec bitmapy oraz zmodyfikować przesunięcie i najpewniej też maskę. Jak dokładnie zmienić maskę, musiałbym się zastanowić, zawsze miałem problemy ze zrozumieniem tego.

Ostatnia aktualizacja: 19.07.2015 14:04:38 przez Hexmage960
[#4] Re: Blitterowe zagadki

@asman, post #2

@HexMage - o niczym nie zapomniałem. :) Zauważ, że bitmapa źródłowa jest szeroka na 1 słowo, a długość blitu jest ustawiona na 2 słowa. To "-2" po blicie drugiego słowa cofa (w DESC robi -(-2) czyli +2, a zatem przesuwa do przodu) wskaźnik danych, przez co nie jest pomijany co drugi wiersz bitmapy. Czemu blit ma 2 wordy i inne tego typu rozważania - nie czas i miejsce na to.

@asman - nieświadomie mi pomogłeś rozwiązać zagadkę. :)

O co chodziło? Teraz na spokojnie chciałem jeszcze raz wszystko opisać, dla uproszczenia wyłączyłem cookie cut. I co? I zaczęło bez niego działać. Okazało się, że miałem w funkcji od fontów minterm ustawiony na współpracę z funkcją BltBitMap, której zamiennik właśnie piszę.
[#5] Re: Blitterowe zagadki

@teh_KaiN, post #4

Z drugiej strony - jakiej czarnej magii używa funkcja BltBitMap, że pozwala mintermem C0 (D = A*B, bez uwzględnienia w formule C) kopiować dane o szerokości np. 7px i pozostałe 9 pikseli słowa nie stają się zerami? Jest na to jakiś hardware'owy patent, czy ona to sobie jakoś wewnętrznie przetwarza i oszukuje? ;)

Ostatnia aktualizacja: 19.07.2015 15:36:03 przez teh_KaiN
[#6] Re: Blitterowe zagadki

@teh_KaiN, post #5

Przecież sam sobie odopowiedziałeś. D = AB, czyli jeśli A jest źródło a B jest przeznaczenie (ekran na przykład, oczywiście D to też ekran) to masz klasyczne orowanie i cześć.
[#7] Re: Blitterowe zagadki

@asman, post #6

To chyba nie może działać. Niech A - źródło nowych danych, B - źródło starych danych. Jeśli B - same zera, to za pomocą D= A*B nie jesteś w stanie na D przełożyć danych z A.

Jeśli się nie mylę to potrzebna jest i tak na jednym kanale maska, np. na A - bltapt zerowy, bltadat 0xFFFF i regulacja krawędzi maskami bltafwm i bltalwm. Wtedy B - źródło nowych danych, C - źródło aktualnych danych i jesteś w stanie to wytrzaskać operacją D = A*B + (~A)*C.
[#8] Re: Blitterowe zagadki

@teh_KaiN, post #7

Faktycznie, coś z prędkości pomyliłem. Zamiast AB myślałem o A + B.
[#9] Re: Blitterowe zagadki

@asman, post #8

Czyli wychodzi na to, że tam jakieś wyższe szamaństwo się odbywa za plecami użytkownika. Kolejny powód żeby nie używać systemowej funkcji tylko mieć swoją własną, szybszą.

Ostatnia aktualizacja: 19.07.2015 18:57:54 przez teh_KaiN
[#10] Re: Blitterowe zagadki

@teh_KaiN, post #9

Ależ wszystko jest w porządku z mintermem 0xc0. Zerknij sobie (ja właśnie przeczytałem) do dokumentacji RKRM, do rozdziału o funkcjach z rodziny BltBitMap().

0xc0 reprezentuje zwykłe kopiowanie ponieważ:

0xc0 = 0x80 + 0x40, zaś 0x80 oznacza (B * C), a 0x40 - (B * ~C). W rezultacie 0xc0 oznacza (B * C) + (B * ~C) = B(C + ~C) = B(1) = B.

W wyniku otrzymujemy D = B dla mintermu 0xc0, więc wszystko gra.

B wskazuje na bitmapę źródłową, zaś C na docelową, można ich używać w mintermie.
[#11] Re: Blitterowe zagadki

@Hexmage960, post #10

Dobrze, tylko ta funkcja działa trochę inaczej (sprawdzałem przed chwilą).

B (src): 0000 1111 1111 0000
C (dst stare): 1010 1010 1010 1010

robiąc blit z offsetem źródła i celu 4, szerokością 8 i mintermem C0 otrzymujemy:
D: 1010 1111 1111 1010

a według D := B wychodzi:
D: 0000 1111 1111 0000
co nie jest prawdziwym sposobem działania tej funkcji dla zadanego mintermu. Sprawę rozwiązałaby stała maska w kanale A, ścięta z lewej i prawej maskami pierwszego i ostatniego słowa. Także podtrzymuję, że ta funkcja czyni szamaństwo w tle. ;)

Ostatnia aktualizacja: 19.07.2015 20:08:04 przez teh_KaiN
[#12] Re: Blitterowe zagadki

@teh_KaiN, post #11

co nie jest prawdziwym sposobem działania tej funkcji dla zadanego mintermu. Sprawę rozwiązałaby stała maska w kanale A, ścięta z lewej i prawej maskami pierwszego i ostatniego słowa. Także podtrzymuję, że ta funkcja czyni szamaństwo w tle. ;)

Przyznaję Ci rację.
[#13] Re: Blitterowe zagadki

@teh_KaiN, post #9

A mógłbyś mi przesłać przykładzik z tym minternem $c0, który ukazuje te "wyższe szamaństwo", bo coś nie chce mi się wierzyć w to. Język przykładu nie ma znaczenia, może być C, asm, blitz. Dzięki
[#14] Re: Blitterowe zagadki

@asman, post #13

Nie mam pod ręką żadnego krótkiego przykładu, ale w dowolnym kodzie jaki tylko dasz radę wystrugać zrób:

1. Zainicjuj bitmapę źródłową np. 32x32 pSrc
2. Strzel BltBitMap(pSrc, 5,5, pDst, 5,5, 20, 20, 0xC0, 255, 0);

Pojawi Ci się na pDst prostokąt wielkości 20x20 bez czarnych krawędzi na boku, jak by to miało miejsce w przypadku blitowania samodzielnym ustawianiem rejestrów.

Jeśli uzbroisz się w cierpliwość to może za 3 dni będę w stanie skleić jakiś krótki przykład.
[#15] Re: Blitterowe zagadki

@teh_KaiN, post #14

Uzbroiłem się w cierpliwość. Po prawdzie to dopiero w niedziele będę miał dostęp do kompa tak by coś sprawdzić na WinUAE albo na a600/a1200.
[#16] Re: Blitterowe zagadki

@asman, post #15

Trochę po czasie, ale co tam.

Tutaj znajduje się mój zamiennik BltBitMap, który przyjmuje dokładnie takie same argumenty prócz ostatniego. Możesz ją sobie potestować względem blitów BltBitMap i jawnie wychodzi dodatkowa ingerencja tej drugiej w dane. Jedyne, co potrzebujesz dorzucić to brakujące define'y i blitSetRegs, która ustawia rejestry blittera.

Analiza prędkości w komentarzach odnosi się do A1200 cycle exact. Ciekawe, czy dużego kopa dałoby przepisanie funkcji na asembler?

Ostatnia aktualizacja: 27.07.2015 14:39:21 przez teh_KaiN
[#17] Re: Blitterowe zagadki

@teh_KaiN, post #16

Znalazłem chwilę i Twój zamiennik słabo działa. To znaczy nic nie mam na ekranie
jak wywołuje BltBitMap z graphics.library to mam kwadrat na ekranie.
Być może coś źle robię, tylko nie wiem co.
By ruszyły mi Twoje źródła to wywaliłem blitChecka, zmieniłem tBitMap na struct BitMap i zamieniłem USEC na SRCC (tą z blit.h). Aha, ja to sprawdzam pod WinUAE AGA 030.

Edit pod WinUAE ECS też nic nie mam na ekranie.


Ostatnia aktualizacja: 02.08.2015 20:30:32 przez asman
[#18] Re: Blitterowe zagadki

@asman, post #17

To coś jest nie tak. W wolnej chwili przygotuję mały kod.
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