@Artur Jarosik, post #150
@Don_Adan, post #153

Kierunek jest dobry, ale tego kodu nie wrzucałbym as-is. Plusy: to jest sensowny pairlut fast path branchless transparency przez and/or z LUT może być szybsza niż per-pixel dla flip_h to ma większy sens niż dalsze dłubanie w C Ale są 4 ważne problemy: Obsługuje tylko parzyste szerokości. lsr.l #1,d7 ucina ostatni piksel. Dla w=1 nic nie narysuje, dla w nieparzystego zgubi ogon. Zakłada specjalny układ LUT. (a2,d1.w*4) z .w używa indeksu ze znakiem. To działa tylko jeśli a2 wskazuje środek 256 KB tabeli. Jeśli nie, indeksy 0x8000..FFFF pójdą w złe miejsce. Trzeba mieć pewność co do kolejności bajtów pary. move.w -(a4),d1 na BE ładuje parę w kolejności pamięci, niekoniecznie w takiej, jakiej oczekuje LUT dla flip_h. Jeśli LUT nie jest zbudowany dokładnie pod ten układ, piksele w parze będą zamienione. and.w d1,(a0) + or.w d1,(a0)+ to dwa read-modify-write na pamięci. Na 68060 to może być gorsze niż: move.w (a0),d3 and.w d1,d3 swap d1 or.w d1,d3 move.w d3,(a0)+ Czyli moja ocena: tak, to ma sens jako -wyspecjalizowany fast path -nie, nie w tej postaci jeszcze Ja bym to zrobił tak: zostawić ten path tylko dla w >= 2 policzyć pairs = w >> 1 dodać scalar tail dla w & 1 jawnie opisać, że map wskazuje środek LUT sprawdzić, czy LUT jest indeksowany w dobrej kolejności dla flip_h zamienić memory and/or na operacje w rejestrze i jeden zapis Najkrócej: pomysł dobry, implementacja jeszcze wymaga doszlifowania. Jeśli chcesz, mogę od razu przepisać ten wariant do bezpieczniejszej wersji z tail-handlingiem i jednym store na parę.
@Artur Jarosik, post #154
@Don_Adan, post #157
cnop 0,4 Map ds.b $10000×4
@Don_Adan, post #158
and.w (a0),d1 move.l d1,d3 swap d3 or.w d3,d1 ; lub add.w d3,d1 move.w d1,(a0)+
@Don_Adan, post #159
; mk3_blit8_mapped_rect_flip_h_pairlut_mem_68k -- experimental pairlut variant ; using memory read-modify-write on destination words. ; ; void mk3_blit8_mapped_rect_flip_h_pairlut_mem_68k(uint8_t* dst0, ; const uint8_t* src0, int w, int rows, int dst_pitch, int src_pitch, ; const uint32_t* pairlut_mid, const uint8_t* map_tail); ; =========================================================================== mk3_blit8_mapped_rect_flip_h_pairlut_mem_68k: _mk3_blit8_mapped_rect_flip_h_pairlut_mem_68k: movem.l d2-d7/a2-a4,-(sp) move.l 40(sp),a0 ; dst0 move.l 44(sp),a1 ; src0 move.l 48(sp),d7 ; w move.l 52(sp),d6 ; rows move.l 56(sp),a3 ; dst_pitch move.l 60(sp),d2 ; src_pitch move.l 64(sp),a2 ; pairlut_mid move.l 68(sp),a4 ; map_tail tst.l d6 beq.w .mrfpm_done tst.l d7 beq.w .mrfpm_done sub.l d7,a3 ; dst_pitch - w move.l d7,d5 lsr.l #1,d5 ; pairs move.l d7,d4 and.l #1,d4 ; tail subq.l #1,d6 .mrfpm_row: lea (a1,d7.l),a4 ; src_after_end for this row tst.l d5 beq.s .mrfpm_tail move.l d5,d0 subq.l #1,d0 .mrfpm_loop2: move.w -(a4),d1 move.l (a2,d1.w*4),d1 and.w d1,(a0) swap d1 or.w d1,(a0)+ dbra d0,.mrfpm_loop2 .mrfpm_tail: tst.l d4 beq.s .mrfpm_next_row moveq #0,d1 move.b -(a4),d1 beq.s .mrfpm_tail_skip move.l 68(sp),a4 ; map_tail move.b (a4,d1.w),(a0) .mrfpm_tail_skip: addq.l #1,a0 .mrfpm_next_row: adda.l a3,a0 adda.l d2,a1 dbra d6,.mrfpm_row .mrfpm_done: movem.l (sp)+,d2-d7/a2-a4 rts =========================================================================== ; mk3_blit8_mapped_rect_flip_h_pairlut_reg_68k -- experimental pairlut variant ; using register merge and one destination store per pair. ; ; void mk3_blit8_mapped_rect_flip_h_pairlut_reg_68k(uint8_t* dst0, ; const uint8_t* src0, int w, int rows, int dst_pitch, int src_pitch, ; const uint32_t* pairlut_mid, const uint8_t* map_tail); ; =========================================================================== mk3_blit8_mapped_rect_flip_h_pairlut_reg_68k: _mk3_blit8_mapped_rect_flip_h_pairlut_reg_68k: movem.l d2-d7/a2-a4,-(sp) move.l 40(sp),a0 ; dst0 move.l 44(sp),a1 ; src0 move.l 48(sp),d7 ; w move.l 52(sp),d6 ; rows move.l 56(sp),a3 ; dst_pitch move.l 60(sp),d2 ; src_pitch move.l 64(sp),a2 ; pairlut_mid move.l 68(sp),a4 ; map_tail tst.l d6 beq.w .mrfpr_done tst.l d7 beq.w .mrfpr_done sub.l d7,a3 ; dst_pitch - w move.l d7,d5 lsr.l #1,d5 ; pairs move.l d7,d4 and.l #1,d4 ; tail subq.l #1,d6 .mrfpr_row: lea (a1,d7.l),a4 ; src_after_end for this row tst.l d5 beq.s .mrfpr_tail move.l d5,d0 subq.l #1,d0 .mrfpr_loop2: move.w -(a4),d1 move.l (a2,d1.w*4),d3 move.w (a0),d1 and.w d3,d1 swap d3 or.w d3,d1 move.w d1,(a0)+ dbra d0,.mrfpr_loop2 .mrfpr_tail: tst.l d4 beq.s .mrfpr_next_row moveq #0,d1 move.b -(a4),d1 beq.s .mrfpr_tail_skip move.l 68(sp),a4 ; map_tail move.b (a4,d1.w),(a0) .mrfpr_tail_skip: addq.l #1,a0 .mrfpr_next_row: adda.l a3,a0 adda.l d2,a1 dbra d6,.mrfpr_row .mrfpr_done: movem.l (sp)+,d2-d7/a2-a4 rts
@Artur Jarosik, post #161
mrfpr_tail:
tst.l d4
beq.s .mrfpr_next_row
illegal
moveq #0,d1
move.b -(a4),d1
beq.s .mrfpr_tail_skip
move.l 68(sp),a4 ; map_tail
move.b (a4,d1.w),(a0)
.mrfpr_tail_skip:@Artur Jarosik, post #149
@Mufa dostał wersję naprawiającą brak postaci.
nowa opcja do skalowania
@Artur Jarosik, post #166
@Don_Adan, post #169
@Don_Adan, post #171
@Pawelek, post #177