Альфа блиттер для DDraw

Тема в разделе "WASM.DirectX", создана пользователем geHucKa, 5 ноя 2004.

  1. geHucKa

    geHucKa New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2004
    Сообщения:
    3
    Адрес:
    Украина / Харьков
    Возможно, эта тема поднималась здесь уже раз сто, но я что-то не нашел...



    Кде взять или кто может запостить реально оптимизированный (быстрее уже никак) SUBJ для R5G6B5 цвета и отдельно хранящейся маски (в любом удобном формате)?



    Я искал исходники и кое-что нашел, но это далеко не оптимальные варианты, а некоторые откровенно примитивны (во всех отнощениях).



    Я пробовал писать свой на MMX, но опыта пока маловато и возникли некоторые вопросы: почему чтение / запись системной памяти работают так медленно (4 movq работают в 3 раза медленнее 27 математических и / или логических инструкций) и можно ли как-нибудь убыстрить их. И можно ли пока читаются следующие пиксели обрабатывать математикой предыидущие, что ли?



    Система, на всякий случай AMD-K6-2-500, 256 MB SDRAM.



    Такой же вопрос я запостил в общие вопросы на всякий случай...
     
  2. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    Вот мои, сильно не оптимизированы

    на www.win32asmcommunity.net на верно есть по лучше


    Код (Text):
    1. blit32:
    2.     mov eax,[fwidth]
    3.     shl eax,2
    4.     mov edx,[fheight]
    5.     sub [lockrc.Pitch],eax
    6. .line:  mov ecx,[fwidth]
    7.     rep movsd
    8.     add edi,[lockrc.Pitch]
    9.     dec edx
    10.     jg  .line
    11.     retn
    12. ;##################################################################### #####
    13. blit16:
    14.     mov eax,[fwidth]
    15.     add eax,eax
    16.     mov edx,[fheight]
    17.     sub [lockrc.Pitch],eax
    18. .line:  mov ecx,[fwidth]
    19. .pixel: mov eax,[esi]   ; red
    20.     mov ebx,[esi]   ; green
    21.     mov ebp,[esi]   ; blue
    22.     shr eax,08h
    23.     shr ebx,05h
    24.     shr ebp,03h
    25.     and eax,0000F800h
    26.     and ebx,000007E0h
    27.     and ebp,0000001Fh
    28.     add ebx,ebp
    29.     add eax,ebx
    30.     stosw
    31.     add esi,04h
    32.     loop    .pixel
    33.     add edi,[lockrc.Pitch]
    34.     dec edx
    35.     jg  .line
    36.     retn
    37. ;##################################################################### #####
    38. blit32a:
    39.     push    ebp
    40.     mov [stackp],esp
    41.  
    42.     mov esp,$00FF00FF
    43.     mov ebp,$0000FF00
    44.     sub edi,4
    45.  
    46.     mov eax,[fwidth]
    47.     shl eax,2
    48.     mov edx,[fheight]
    49.     sub [lockrc.Pitch],eax
    50.     mov [y],edx
    51.  
    52. .line:  mov eax,[fwidth]
    53.     mov [x],eax
    54. .pixel: movzx   edx,byte [esi+03h]  ; A---          u
    55.     mov eax,[esi]       ; -R-B           v
    56.     mov ecx,[esi]       ; --G-          u
    57.     and eax,esp         ;                v
    58.     and ecx,ebp         ;               u
    59.     imul    eax,edx         ;                v
    60.     imul    ecx,edx         ;               u
    61.     and eax,$FF00FF00       ;                u
    62.     and ecx,$00FF0000       ;               u
    63.     add edi,4           ;                v
    64.     add ecx,eax         ;               u
    65.     xor edx,$FF         ;                v
    66.  
    67.     mov eax,[edi]       ;               u
    68.     mov ebx,[edi]       ;                v
    69.     and eax,esp         ; -R-B          u
    70.     and ebx,ebp         ; --G-           v
    71.     imul    eax,edx         ;               u
    72.     imul    ebx,edx         ;                v
    73.     and eax,$FF00FF00       ;               u
    74.     and ebx,$00FF0000       ;                v
    75.     add eax,ecx         ;               u
    76.     add esi,4           ;                v
    77.     add eax,ebx         ;               u
    78.     shr eax,8           ;               u
    79.  
    80.     dec [x]         ;                v
    81.     mov [edi],eax       ;               u
    82.     jg  .pixel
    83.     add edi,[lockrc.Pitch]
    84.     dec [y]
    85.     jg  .line
    86.  
    87.     mov esp,[stackp]
    88.     pop ebp
    89.     retn
    90. ;##################################################################### #####
    91. blit32ammx:
    92.     push    ebp
    93.  
    94.     sub edi,08h
    95.  
    96.     mov eax,[fwidth]
    97.     shl eax,2
    98.     mov edx,[fheight]
    99.     sub [lockrc.Pitch],eax
    100.  
    101. .line:  mov eax,[fwidth]
    102.   .x:   add edi,08h
    103.     movq    mm6,[esi]
    104.     movq    mm0,mm6         ; alpha0
    105.     movq    mm3,mm6         ; alpha1
    106.     pxor    mm1,mm1         ; src0
    107.     pxor    mm4,mm4         ; src1
    108.     pxor    mm2,mm2         ; dest0
    109.     pxor    mm5,mm5         ; dest1
    110.     pshufw  mm0,mm0,01010101b   ; spread alpha0
    111.     pshufw  mm3,mm3,11111111b   ; spread alpha1
    112.       punpcklbw mm1,mm6         ; unpack src0
    113.       punpckhbw mm4,mm6         ; unpack src1
    114.       punpcklbw mm2,[edi]       ; unpack dest0
    115.       punpckhbw mm5,[edi]       ; unpack dest1
    116.     pand    mm0,[mmx_mulmask]   ; isolate alpha0
    117.     pand    mm3,[mmx_mulmask]   ; isolate alpha1
    118.     pand    mm1,[mmx_rgbmask]   ; isolate src0
    119.     pand    mm4,[mmx_rgbmask]   ; isolate src1
    120.     pand    mm2,[mmx_rgbmask]   ; isolate dest0
    121.     pand    mm5,[mmx_rgbmask]   ; isolate dest1
    122.     pmulhuw mm1,mm0         ; src0*alpha0
    123.     pmulhuw mm4,mm3         ; src1*alpha1
    124.     pxor    mm0,[mmx_mulmask]   ; reverse alpha0
    125.     pxor    mm3,[mmx_mulmask]   ; reverse alpha1
    126.     pmulhuw mm2,mm0         ; dest0*alpha0
    127.     pmulhuw mm5,mm3         ; dest1*alpha1
    128.     paddw   mm1,mm2         ; src0+dest0
    129.     paddw   mm4,mm5         ; src1+dest1
    130.     psrlw   mm1,8           ; truncate res0
    131.     psrlw   mm4,8           ; truncate res1
    132.        packuswb mm1,mm4         ; res0+res1
    133.     add esi,08h
    134.     sub eax,02h
    135.     movq    [edi],mm1
    136.     jg  .x
    137.     dec edx
    138.     jg  .line
    139.  
    140.     emms
    141.     pop ebp
    142.     retn
    143. ;##################################################################### #####
    144. blit16a:
    145.     push    ebp
    146.     mov [stackp],esp
    147.  
    148.     sub edi,2
    149.  
    150.     mov eax,[fwidth]
    151.     add eax,eax
    152.     mov edx,[fheight]
    153.     sub [lockrc.Pitch],eax
    154.     mov [y],edx
    155.  
    156. .line:  mov eax,[fwidth]
    157.     mov [x],eax
    158. .pixel: movzx   edx,byte [esi+03h]  ; A---          u
    159.     mov eax,[esi]       ; -R-B
    160.     mov ecx,[esi]       ; --G-
    161.     and eax,$00FF00FF
    162.     and ecx,$0000FF00
    163.     imul    eax,edx
    164.     imul    ecx,edx
    165.     mov ebx,eax
    166.     shr ecx,13
    167.     shr eax,11
    168.     shr ebx,16
    169.     and ecx,$07E0
    170.     and eax,$001F
    171.     and ebx,$F800
    172.     xor edx,$FF
    173.     add ecx,eax
    174.     add edi,2
    175.     add ecx,ebx
    176.  
    177.     shr edx,2
    178.  
    179.     movzx   eax,word [edi]      ; -R-B
    180.     movzx   ebx,word [edi]      ; --G-
    181.     and eax,$F81F
    182.     and ebx,$07E0
    183.     imul    eax,edx
    184.     imul    ebx,edx
    185.     and eax,$F81F shl 6
    186.     and ebx,$07E0 shl 6
    187.     add eax,ebx
    188.     add esi,4
    189.     shr eax,6
    190.     add eax,ecx
    191.  
    192.     dec [x]
    193.     mov [edi],ax
    194.     jg  .pixel
    195.     add edi,[lockrc.Pitch]
    196.     dec [y]
    197.     jg  .line
    198.  
    199.     mov esp,[stackp]
    200.     pop ebp
    201.     retn
    202.  
     
  3. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    забыл


    Код (Text):
    1.  
    2. mmx_rgbmask dq  $0000FF00FF00FF00
    3. mmx_mulmask dq  $FF00FF00FF00FF00
    4.  
    5. fwidth = ширина
    6. fheight = высота
    7. lockrc.Pitch = scanline (width * bytes_per_pixel)
    8.  




    почему code таги на этом борде используют variable-width font? нужно fixed-width font, типа courier new (или лучше
    Код (Text):
    1.  
    )
     
  4. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    AMD-K6-2 говоришь?



    а ты вообще не замечал что простая запись в память там медленнее чем чтение?

    дело в том что когда ты что нибудь пытаешься скэшировать, а строк в кэше нету(все модифицированы) то по вине девелоперов камня инструкция ждет сперва сохранения ячейки а потом загрузки. то есть ожидание вдвое больше что и вызывает остановку конвейера. попробуй юзать prefetchw задолго до обращения к предвыбираемой памяти.
     
  5. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Вроде как раз на на AMD-K6-2 и появилась MOVNTQ - запись в память минуя кэшь ?
     
  6. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    вроде бы на Р3 как раз. а на К6-2 prefetch и prefetchw
     
  7. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    если тебе надо запись в память поставь PWT+WC для страниц буфера. тогда строка кэша оказывается записаной сразу. но тогда трабла - WC ставится через MTRR а их всего 2 там.

    один под оперативку другой под видеоадаптерную память.
     
  8. geHucKa

    geHucKa New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2004
    Сообщения:
    3
    Адрес:
    Украина / Харьков
    2 Comrade: спасибо, но я свой на MMX написал и он лучше работает.



    2 Narkomanius: насчет последнего поста - ничего не понял... :)



    2 All: мне бы такой, чтобы он либо на всех процессорах работал, либо на P3, P4, AthlonXP, а не только на AMD-K6-2-500 - это уже антиквариат. :)



    Вообще, не пойму, как сделан такой быстрый блиттер, например, в Ricochet Extreme / Lost Worlds, ну или ещё много игр могу привести в пример. Ведь там все 100% софтварное на DDraw'e сделано. Понимаю, там использовали Dirty Rectangles, чтобы не весь кадр перерисовывать, ну и анимация там 10 - 20 раз в секунду в основном для всех спрайтов, но все равно быстрее моего работает раз в сто.



    Вообще, если кому надо, могу запостить свой код...
     
  9. geHucKa

    geHucKa New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2004
    Сообщения:
    3
    Адрес:
    Украина / Харьков
    В общем, все понятно... Производители памяти обещают гигабайты, а я с трудом могу переслать 64 (ш) х 64 (в) х 2 (16 бпп) х 4 (сурс, альфа и два раза бэк) х 12 (штук) х 30 (фпс) = 11,25 МБайт / сек. Да?
     
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    На athlon@266MHz FSB за секунду можно скопировать 900Mb.

    Причём эта цифра от частоты ядра почти не зависит.
     
  11. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    WC- write combining, задержка данных во внутренних буферах для лучшей утилизации шины. тогда запись имеет больше шансов идти 8байтными блоками а не так как пишет прога - 1,2,4 байта. просто байты попадающие в одну восьмерку комбинированно записываются за одно обращение(2 цикла шины на К6-2 без #HOLD #WT)

    PTW pagewritethrough -сквозная запись, когда данные записанные в кэш, сразу же помещаются в буфер записи. при write-back режиме буфер записи не заполняется, и запись идет по мере вытеснения строк из кэша.

    то есть когда тебе захочется прочесть что нибудь в кэш, окажется что сперва надо произвести запись, что ведет к росту латентности и остановке планировщика. Данным синдромом страдают все АМДшные процы, у интеловских Write-backа _НЕТУ_. даже если они пишут что есть. у них просто сквозная запись отложенная получается.



    чем PWT крут? тем что записав в строку кэша, ты можешь не беспокоиться о том что когда надо будет её вытеснить она будет можифицирована. такие строки немодифицированы по определению, и просто затираются.

    WC - не нужен если ты будешь производить запись кусками по 8 байт. запись будет неконвейеризована! но потери в скорости будут меньше.



    Надеюсь я ответил на твой вопрос, почему ты на своем К6-2 получил такое низкое быстродействие записи?