Напишите 16х16 растрового изображения в буфер кадра


Следующий код записывает растрового изображения 16x16 для фреймбуфера, используя до AVX2 инструкции. Я уверен, что это может быть улучшено с AVX512 но меня интересуют только улучшения, используя AVX2 и ниже. Конкретно, я хочу знать, если есть более эффективный способ сделать это. Каждый бит в битовой карте представляет собой пиксель и требует атрибута типа DWORD должно быть написано. Каждые 2 байта из 32 байт данных не 16 пикселей строки всего 16 строк. Приведенный ниже код делает 8 нагрузок и 32 магазина для каждого 16х16 написано.

FColor  dd  0x00ffffff  ; white
BColor  dd  0x000000ff  ; blue

ALIGN 32
bitshift_to_MSB   dd 24, 25, 26, 27, 28, 29, 30, 31

; 95 * 32 byte bitmaps (SPACE to '~')

CH_ARIAL db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
.
.
.
0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,


    ; rdi = framebuffer address to write to
    ; edx = printable ascii character (assumed to be between 32 and 126
    sub     edx, 32
    shl     edx, 5
    mov     ecx, 8

    vpbroadcastd    ymm4, [FColor]
    vpbroadcastd    ymm3, [BColor]
    vmovdqa         ymm2,  yword [bitshift_to_MSB]
@@:
    vpbroadcastd    ymm0, dword [CH_ARIAL + edx]        ; broadcasts dword (32 bits, for 2 x 16 pixel rows)
    vpsllvd         ymm1, ymm0, ymm2                    ; shifts left according to ymm2 to set dword MSB based on 1st byte
    vblendvps       ymm1, ymm3, ymm4, ymm1              ; set dwords in ymm1 = (each dword MSB)?ymm4:ymm3
    vmovdqa         [rdi], ymm1

    vpsrld          ymm0, ymm0, 8                       ; shift 2nd byte of each dword to first position
    vpsllvd         ymm1, ymm0, ymm2
    vblendvps       ymm1, ymm3, ymm4, ymm1   
    vmovdqa         [rdi+32], ymm1

    add     rdi, 1920*4                                 ; mov down to next row of pixels

    vpsrld          ymm0, ymm0, 8                       
    vpsllvd         ymm1, ymm0, ymm2
    vblendvps       ymm1, ymm3, ymm4, ymm1   
    vmovdqa         [rdi], ymm1

    vpsrld          ymm0, ymm0, 8                       
    vpsllvd         ymm1, ymm0, ymm2
    vblendvps       ymm1, ymm3, ymm4, ymm1   
    vmovdqa         [rdi+32], ymm1

    add     edx, 4
    add     rdi, 1920*4
    dec     ecx
    jnz     @b


87
2
задан 17 февраля 2018 в 01:02 Источник Поделиться
Комментарии