home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / misc / sclblt.asm < prev   
Encoding:
Assembly Source File  |  1997-07-15  |  11.0 KB  |  714 lines

  1. ;
  2. ;  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  3. ;
  4. ;  File: sclblt.asm
  5. ;
  6. ;    Assembler 3x3 -> 2x2 averaging downsampler.
  7. ;
  8.  
  9. include iammx.inc
  10.  
  11. .586
  12. .model FLAT
  13.  
  14. CLEAR_SRC_BUFFER    equ    0
  15. RGB555            equ    0
  16.     
  17.  
  18. if RGB555
  19. RMASK            equ    07c000h
  20. GMASK            equ    03e0h
  21. GSHIFT            equ    5 + 5 + 2
  22. else
  23. RMASK            equ    0f8000h
  24. GMASK            equ    07e0h
  25. GSHIFT            equ    5 + 6 + 2
  26. endif
  27.     
  28. BMASK            equ    01fh
  29. RBMASK            equ    (RMASK shr 4 ) or BMASK
  30. RBMASK_GMASK_shl    equ    RBMASK or ( GMASK shl 16 )
  31.  
  32. .data
  33. align 8
  34.  
  35. filtered_pix    dq    0
  36. unpckd_pxls    dd    0, 0, 0, 0, 0, 0, 
  37.             0, 0, 0, 0, 0, 0, 
  38.             0, 0, 0, 0, 0, 0
  39.  
  40. MMX_RMASK        dd    RMASK shr 4, RMASK shr 4
  41. MMX_GMASK        dd    GMASK, GMASK
  42. MMX_RBMASK_GMASK_shl    dd    RBMASK_GMASK_shl, RBMASK_GMASK_shl
  43.  
  44. MMX_BMASK    dd    BMASK, BMASK
  45. MMX_RBMASK    dd    RMASK shr 4 or BMASK, RMASK shr 4 or BMASK
  46.  
  47. MMX_hi32    dq    0ffffffff00000000h
  48. MMX_low32    dq    000000000ffffffffh
  49.  
  50. j    dd    0
  51. k    dd    0
  52. xincr    dd    0
  53. yincr    dd    0
  54. idst    dd    0
  55.  
  56.  
  57. .code
  58. sclblt1 PROC NEAR C USES eax ebx ecx edx esi edi ebp,
  59.         dst:PTR UWORD, src:PTR UWORD,
  60.         w:DWORD, h:DWORD,
  61.         ss2:DWORD, ds2:DWORD
  62.         
  63. ;        ss2:DWORD, ds2:DWORD, ss4:DWORD
  64.  
  65.  
  66.  
  67. ;    eax    ebx    ecx    edx    esi    edi    ebp
  68. ;
  69. ;     *     *     *     *    src     *     k
  70.  
  71.     xor    edx,edx
  72.     mov    esi,dword ptr [src]
  73.     
  74.     mov    dword ptr[j],edx
  75.     mov    dword ptr [yincr],1
  76.     
  77.     outer_loop:
  78.         mov    dword ptr [idst],0
  79.         mov    eax,dword ptr[j]
  80.     xor    edi,edi
  81.  
  82.     cmp    eax,dword ptr [h]
  83.     jge    outer_done
  84.     
  85.     mov    dword ptr [xincr],1
  86.     cmp    edi,dword ptr [w]
  87.     inner_loop:
  88.     
  89.     jge    inner_done
  90.     mov    dx,word ptr[esi + 2*edi]
  91.  
  92.     mov    ebx,edx
  93.     mov    ecx,edx
  94.  
  95.     shl    ebx,4
  96.     and    ecx,GMASK
  97.  
  98. if CLEAR_SRC_BUFFER
  99.     mov    word ptr[esi + 2*edi],0
  100. endif
  101.  
  102.     and    ebx,RMASK
  103.     and    dl,BMASK
  104.  
  105.     shl    ecx,2
  106.     mov    bl,dl
  107.  
  108.     mov    dx,word ptr[esi + 2*edi + 2]
  109.     or    ebx,ecx
  110.  
  111.     mov    eax,edx
  112.     mov    ecx,edx
  113.  
  114.     shl    eax,4
  115.     and    ecx,GMASK
  116.  
  117. if CLEAR_SRC_BUFFER
  118.     mov    word ptr[esi + 2*edi + 2],0
  119. endif
  120.     add    esi,[ss2]
  121.  
  122.     and    eax,RMASK
  123.     and    dl,BMASK
  124.  
  125.     shl    ecx,2
  126.     mov    al,dl
  127.  
  128.     mov    dx,word ptr[esi + 2*edi]
  129.     or    eax,ecx
  130.  
  131.     add    ebx,eax
  132.  
  133.     mov    eax,edx
  134.     mov    ecx,edx
  135.  
  136. if CLEAR_SRC_BUFFER
  137.     mov    word ptr[esi + 2*edi],0
  138. endif
  139.  
  140.     shl    eax,4
  141.     and    ecx,GMASK
  142.  
  143.     and    eax,RMASK
  144.     and    dl,BMASK
  145.  
  146.     shl    ecx,2
  147.     mov    al,dl
  148.  
  149.     or    eax,ecx
  150.  
  151.     mov    dx,word ptr[esi + 2*edi + 2]
  152.     add    ebx,eax
  153.  
  154.  
  155.     mov    eax,edx
  156.     mov    ecx,edx
  157.  
  158.     shl    eax,4
  159.     and    ecx,GMASK
  160.  
  161.     and    eax,RMASK
  162.     and    dl,BMASK
  163.  
  164. if CLEAR_SRC_BUFFER
  165.     mov    word ptr[esi + 2*edi + 2],0
  166. endif
  167.  
  168.     shl    ecx,2
  169.     mov    al,dl
  170.  
  171.     or    eax,ecx
  172.     mov    ecx,[xincr]
  173.     
  174.     add    edi,ecx
  175.     sub    ecx,3
  176.     
  177.     add    ebx,eax
  178.     neg    ecx
  179.  
  180.     mov    [xincr],ecx
  181.     sub    esi,[ss2]
  182.  
  183.     mov    eax,ebx
  184.     mov    edx,ebx
  185.  
  186.     shr    ebx,6
  187.     and    eax,GMASK shl 4
  188.  
  189.     shr    eax,4
  190.     and    ebx,RMASK shr 4
  191.  
  192.     shr    edx,2
  193.     mov    ecx,dword ptr [dst]
  194.  
  195.     and    edx,BMASK
  196.     or    ebx,eax
  197.     
  198.     mov    eax,[idst]
  199.     inc    [idst]
  200.  
  201.     or    ebx,edx
  202.     cmp    edi,dword ptr [w]
  203.  
  204.     mov    word ptr [ecx + 2*eax],bx
  205.     jmp    inner_loop
  206.  
  207.     inner_done:
  208.     mov    eax,[yincr]
  209.     add    esi,dword ptr [ss2]
  210.     
  211.     add    [j],eax
  212.     sub    eax,3
  213.     
  214.     neg    eax
  215.  
  216.     mov    [yincr],eax
  217.     add    ecx,dword ptr [ds2]
  218.     
  219.     cmp    eax,1
  220.     je    miss_add
  221.     
  222.     add    esi,dword ptr [ss2]
  223.     
  224.     miss_add:
  225.     mov    dword ptr [dst],ecx
  226.     jmp    outer_loop
  227.  
  228.     outer_done:
  229.         ret
  230.     
  231. sclblt1 ENDP
  232.     
  233. UNPACK_TWO_PIXELS    macro    col, row
  234.     mov    edx,dword ptr[esi + 2*edi + col]
  235.  
  236.     mov    ebx,edx
  237.     mov    ecx,edx
  238.  
  239.     shl    ebx,4
  240.     and    ecx,GMASK
  241.  
  242.     and    ebx,RMASK
  243.     and    dl,BMASK
  244.  
  245.     shl    ecx,2
  246.     mov    bl,dl
  247.  
  248.     shr    edx,16
  249.     or    ebx,ecx
  250.     
  251.     mov    dword ptr [unpckd_pxls + 2*col + 24*row],ebx
  252.     mov    eax,edx
  253.  
  254.     shl    eax,4
  255.     mov    ecx,edx
  256.  
  257.     and    ecx,GMASK
  258.     and    eax,RMASK
  259.  
  260.     shl    ecx,2
  261.     and    dl,BMASK
  262.  
  263.     mov    al,dl
  264.  
  265.     or    eax,ecx
  266.     
  267.     mov    dword ptr [unpckd_pxls + 2*col + 24*row + 4],eax
  268.     endm
  269.     
  270. PACK_ONE_PIXEL    macro    pix, scr1, scr2
  271.     ; Pixel sum in pix: average, pack and write pixel
  272.     
  273.     mov    scr1,pix
  274.     mov    scr2,pix
  275.  
  276.     shr    pix,6
  277.     and    scr1,GMASK shl 4
  278.  
  279.     shr    scr1,4
  280.     and    pix,RMASK shr 4
  281.  
  282.     shr    scr2,2
  283.     ;
  284.  
  285.     and    scr2,BMASK
  286.     or    pix,scr1
  287.  
  288.     or    pix,scr2
  289.     endm
  290.     
  291. FILTER_FOUR_PIXELS    macro pix, offs, scr1, scr2
  292.            mov    pix,dword ptr [unpckd_pxls + offs +  0]
  293.            mov    scr1,dword ptr [unpckd_pxls + offs +  4]
  294.     
  295.            add    pix,dword ptr [unpckd_pxls + offs + 24]
  296.            add    scr1,dword ptr [unpckd_pxls + offs + 28]
  297.     
  298.     add    pix,scr1
  299.     
  300.           PACK_ONE_PIXEL    pix, scr1, scr2
  301.     endm
  302.     
  303.  
  304. sclblt_int PROC NEAR C USES eax ebx ecx edx esi edi ebp,
  305.         dst:PTR UWORD, src:PTR UWORD,
  306.         w:DWORD, h:DWORD,
  307.         ss2:DWORD, ds2:DWORD
  308.         
  309.  
  310.  
  311. ;    eax    ebx    ecx    edx    esi    edi    ebp
  312. ;
  313. ;     *     *     *     *    src     *     k
  314.  
  315.     xor    edx,edx
  316.     mov    esi,dword ptr [src]
  317.     
  318.     mov    dword ptr[j],edx
  319.     
  320.     outer_loop:
  321.         mov    dword ptr [idst],0
  322.         mov    eax,dword ptr[j]
  323.     xor    edi,edi
  324.  
  325.     cmp    eax,dword ptr [h]
  326.     jge    outer_done
  327.     
  328.     cmp    edi,dword ptr [w]
  329.     inner_loop:
  330.         ; Read and unpack three rows of 6 pixels
  331.     
  332.     jge    inner_done
  333.     
  334.         UNPACK_TWO_PIXELS 0,0
  335.         UNPACK_TWO_PIXELS 4,0
  336.         UNPACK_TWO_PIXELS 8,0
  337.     
  338.     add    esi,[ss2]
  339.     
  340.         UNPACK_TWO_PIXELS 0,1
  341.         UNPACK_TWO_PIXELS 4,1
  342.         UNPACK_TWO_PIXELS 8,1
  343.     
  344.     add    esi,[ss2]
  345.     
  346.         UNPACK_TWO_PIXELS 0,2
  347.         UNPACK_TWO_PIXELS 4,2
  348.         UNPACK_TWO_PIXELS 8,2
  349.     
  350.     sub    esi,[ss2]
  351.     sub    esi,[ss2]
  352.     
  353.     add    edi,6
  354.     
  355.     FILTER_FOUR_PIXELS ebx, 0, eax, edx
  356.     FILTER_FOUR_PIXELS ecx, 4, eax, edx
  357.  
  358.     mov    eax,[idst]
  359.     mov    edx,[dst]
  360.     
  361.     shl    ecx,16
  362.     or    ebx,ecx
  363.     
  364.     mov    dword ptr [edx + 4*eax + 0],ebx
  365.     
  366.     
  367.     FILTER_FOUR_PIXELS ebx, 12, eax, edx
  368.     FILTER_FOUR_PIXELS ecx, 16, eax, edx
  369.  
  370.     mov    eax,[idst]
  371.     mov    edx,[dst]
  372.     
  373.     shl    ecx,16
  374.     or    ebx,ecx
  375.  
  376.     mov    dword ptr [edx + 4*eax + 4],ebx
  377.     
  378.     
  379.     FILTER_FOUR_PIXELS ebx, 24, eax, edx
  380.     FILTER_FOUR_PIXELS ecx, 28, eax, edx
  381.  
  382.     mov    eax,[idst]
  383.     mov    edx,[dst]
  384.     
  385.     add    edx,dword ptr [ds2]
  386.     
  387.     shl    ecx,16
  388.     or    ebx,ecx
  389.     
  390.     mov    dword ptr [edx + 4*eax + 0],ebx
  391.     
  392.     
  393.     FILTER_FOUR_PIXELS ebx, 36, eax, edx
  394.     FILTER_FOUR_PIXELS ecx, 40, eax, edx
  395.  
  396.     mov    eax,[idst]
  397.     mov    edx,[dst]
  398.     
  399.     add    edx,dword ptr [ds2]
  400.     
  401.     shl    ecx,16
  402.     or    ebx,ecx
  403.  
  404.     mov    dword ptr [edx + 4*eax + 4],ebx
  405.     
  406.     sub    edx,dword ptr [ds2]
  407.     add    [idst],2
  408.     
  409.     cmp    edi,dword ptr [w]
  410.     jmp    inner_loop
  411.  
  412.     inner_done:
  413.     add    [j],3
  414.     
  415.     add    esi,[ss2]
  416.     add    esi,[ss2]
  417.     add    esi,[ss2]
  418.     
  419.     add    edx,dword ptr [ds2]
  420.     add    edx,dword ptr [ds2]
  421.     
  422.     mov    dword ptr [dst],edx
  423.     jmp    outer_loop
  424.  
  425.     outer_done:
  426.         ret
  427.     
  428. sclblt_int ENDP
  429.     
  430.     
  431. MMX_UNPACK_TWO_PIXELS    macro    col, mmx_reg, next_mmx_reg
  432.     
  433.            punpcklwd mmx_reg,mm0    ; mmx_reg = pix1:pix0
  434.  
  435.     movq    mm1,mmx_reg
  436.     pslld    mmx_reg,16
  437.  
  438.     if col ne 0
  439.     movdt    next_mmx_reg,[esi + 2*edi + col]
  440.     else
  441.     add    esi,eax
  442.     endif
  443.            por    mmx_reg,mm1
  444.  
  445.     pand    mmx_reg,[MMX_RBMASK_GMASK_shl]
  446.     endm
  447.     
  448. MMX_PACK_TWO_PIXELS    macro    pix, scr
  449.     ; Pixel sum in pix: average and pack two pixels
  450.     
  451.     psrld    pix,2
  452.     nop
  453.  
  454.     pand    pix,[MMX_RBMASK_GMASK_shl]
  455.     nop
  456.     
  457.     movq    scr,pix
  458.     psrld    pix,16
  459.     
  460.     por    pix,scr
  461.     nop
  462.  
  463.            movq    scr,pix        ; pix = scr = 0,a:0,b
  464.     psrlq    pix,32        ; pix = 0,0:0,a
  465.     
  466.     punpcklwd pix, scr    ; pix = 0,0:b,a
  467.     endm
  468.     
  469. MMX_GEN_FOUR_PIXELS    macro sum1, sum2, sum3, base, indx
  470.     
  471.     movq    mm0,sum1    ; sum1 = mm0 = b:a
  472.     movq    mm1,sum2    ; sum2 = mm1 = d:c
  473.  
  474.            pand    mm1,[MMX_low32]    ; mm1 = 0:c
  475.     psllq    sum1,32        ; sum1 = a:0
  476.     
  477.     punpckhdq mm0,mm0    ; mm0 = b:b
  478.     por    mm1,sum1    ; mm1 = a:c
  479.     
  480.            pand    sum2,[MMX_hi32]    ; sum2 = d:0
  481.     paddd    mm0,mm1        ; mm0 = a+b:b+c
  482.     
  483.           MMX_PACK_TWO_PIXELS mm0, mm1
  484.     movq    mm1,sum3    ; sum3 = mm1 = f:e
  485.     
  486.     psrlq    sum3,32        ; sum3 = 0:f
  487.     nop
  488.     
  489.     punpckldq mm1,mm1    ; mm1 = e:e
  490.     por    sum2,sum3    ; sum2 = d:f
  491.     
  492.     movdf    dword ptr [base + 8*indx + 0],mm0
  493.     paddd    mm1,sum2    ; mm1 = d+e:e+f
  494.     
  495.           MMX_PACK_TWO_PIXELS mm1, sum2
  496.     pxor    mm0,mm0
  497.     
  498.     movdf    dword ptr [base + 8*indx + 4],mm1
  499.     endm
  500.     
  501.    
  502. ; MMX version
  503.  
  504. sclblt PROC NEAR C USES eax ebx ecx edx esi edi ebp,
  505.         dst:PTR UWORD, src:PTR UWORD,
  506.         w:DWORD, h:DWORD,
  507.         ss2:DWORD, ds2:DWORD
  508.         
  509.  
  510.  
  511. ;    eax    ebx    ecx    edx    esi    edi    ebp
  512. ;
  513. ;     *     *     *     *    src     *     k
  514.  
  515.     mov    esi,dword ptr [src]
  516.     xor    ecx,ecx            ; ecx = idst
  517.     
  518.     mov    dword ptr[j],edx
  519.     mov    edx,[dst]
  520.     
  521.     outer_loop:
  522.         mov    eax,dword ptr[j]
  523.     xor    edi,edi
  524.  
  525.     cmp    eax,dword ptr [h]
  526.     jge    outer_done
  527.     
  528.     cmp    edi,dword ptr [w]
  529.     jz    inner_done
  530.     inner_loop:
  531.         ; Read and unpack three rows of 6 pixels
  532.     
  533.     movdt    mm2,[esi + 2*edi + 0]
  534.     pxor    mm0,mm0
  535.     
  536.            mov    eax,[ss2]
  537.         MMX_UNPACK_TWO_PIXELS 4, mm2, mm3
  538.         MMX_UNPACK_TWO_PIXELS 8, mm3, mm4
  539.         MMX_UNPACK_TWO_PIXELS 0, mm4, xxx
  540.     
  541.     movdt    mm5,[esi + 2*edi + 0]
  542.     
  543.         MMX_UNPACK_TWO_PIXELS 4, mm5, mm6
  544.         MMX_UNPACK_TWO_PIXELS 8, mm6, mm7
  545.         MMX_UNPACK_TWO_PIXELS 0, mm7, xxx
  546.     paddd    mm2,mm5
  547.     
  548.     paddd    mm3,mm6
  549.     paddd    mm4,mm7
  550.     
  551.     MMX_GEN_FOUR_PIXELS mm2, mm3, mm4, edx, ecx
  552.     
  553.     movdt    mm2,[esi + 2*edi + 0]
  554.     
  555.         MMX_UNPACK_TWO_PIXELS 4, mm2, mm3
  556.         MMX_UNPACK_TWO_PIXELS 8, mm3, mm4
  557.         MMX_UNPACK_TWO_PIXELS 0, mm4, xxx
  558.     paddd    mm2,mm5
  559.     
  560.     sub    esi,eax
  561.     paddd    mm3,mm6
  562.     
  563.     paddd    mm4,mm7
  564.     sub    esi,eax
  565.     
  566.     sub    esi,eax
  567.     mov    eax,dword ptr [ds2]
  568.     
  569.     add    edi,6
  570.     add    edx,eax
  571.     
  572.     MMX_GEN_FOUR_PIXELS mm2, mm3, mm4, edx, ecx
  573.     
  574.     sub    edx,eax
  575.     inc    ecx
  576.     
  577.     cmp    edi,dword ptr [w]
  578.     jl    inner_loop
  579.  
  580.     inner_done:
  581.     add    [j],3
  582.     xor    ecx,ecx
  583.     
  584.     add    esi,[ss2]
  585.     add    edx,dword ptr [ds2]
  586.     
  587.     add    esi,[ss2]
  588.     add    edx,dword ptr [ds2]
  589.     
  590.     add    esi,[ss2]
  591.     jmp    outer_loop
  592.  
  593.     outer_done:
  594.         emms
  595.         ret
  596.     
  597. sclblt ENDP
  598.     
  599. MEM_UNPACK_TWO_PIXELS    macro    col, row
  600.     mov    ebx,[esi + 2*edi + col]
  601.     endm
  602.     
  603. MEM_PACK_TWO_PIXELS    macro    pix
  604.     endm
  605.     
  606. MEM_FILTER_EIGHT_PIXELS    macro pix, offs, scr
  607.     endm
  608.     
  609.    
  610. ; Memory read/writes only version
  611.  
  612. sclblt_mem PROC NEAR C USES eax ebx ecx edx esi edi ebp,
  613.         dst:PTR UWORD, src:PTR UWORD,
  614.         w:DWORD, h:DWORD,
  615.         ss2:DWORD, ds2:DWORD
  616.         
  617.  
  618.  
  619. ;    eax    ebx    ecx    edx    esi    edi    ebp
  620. ;
  621. ;     *     *     *     *    src     *     k
  622.  
  623.     xor    edx,edx
  624.     mov    esi,dword ptr [src]
  625.     
  626.     mov    dword ptr[j],edx
  627.     
  628.     outer_loop:
  629.         mov    dword ptr [idst],0
  630.         mov    eax,dword ptr[j]
  631.     xor    edi,edi
  632.  
  633.     cmp    eax,dword ptr [h]
  634.     jge    outer_done
  635.     
  636.     cmp    edi,dword ptr [w]
  637.     inner_loop:
  638.         ; Read and unpack three rows of 6 pixels
  639.     
  640.     jge    inner_done
  641.     
  642.         MEM_UNPACK_TWO_PIXELS 0,0
  643.         MEM_UNPACK_TWO_PIXELS 4,0
  644.         MEM_UNPACK_TWO_PIXELS 8,0
  645.     
  646.     add    esi,[ss2]
  647.     
  648.         MEM_UNPACK_TWO_PIXELS 0,1
  649.         MEM_UNPACK_TWO_PIXELS 4,1
  650.         MEM_UNPACK_TWO_PIXELS 8,1
  651.     
  652.     add    esi,[ss2]
  653.     
  654.         MEM_UNPACK_TWO_PIXELS 0,2
  655.         MEM_UNPACK_TWO_PIXELS 4,2
  656.         MEM_UNPACK_TWO_PIXELS 8,2
  657.     
  658.     sub    esi,[ss2]
  659.     sub    esi,[ss2]
  660.     
  661.     add    edi,6
  662.  
  663.     mov    ecx,[idst]
  664.     mov    edx,[dst]
  665.     
  666.     MEM_FILTER_EIGHT_PIXELS ebx, 0, eax
  667.     
  668.     mov    dword ptr [edx + 4*ecx + 0],ebx
  669.     
  670.     
  671.     MEM_FILTER_EIGHT_PIXELS ebx, 12, eax
  672.  
  673.     mov    dword ptr [edx + 4*ecx + 4],ebx
  674.     
  675.     
  676.     add    edx,dword ptr [ds2]
  677.     
  678.     MEM_FILTER_EIGHT_PIXELS ebx, 24, eax
  679.     
  680.     mov    dword ptr [edx + 4*ecx + 0],ebx
  681.     
  682.     
  683.     MEM_FILTER_EIGHT_PIXELS ebx, 36, eax
  684.  
  685.     mov    dword ptr [edx + 4*ecx + 4],ebx
  686.     
  687.     sub    edx,dword ptr [ds2]
  688.     add    [idst],2
  689.     
  690.     cmp    edi,dword ptr [w]
  691.     jmp    inner_loop
  692.  
  693.     inner_done:
  694.     add    [j],3
  695.     
  696.     add    esi,[ss2]
  697.     add    esi,[ss2]
  698.     add    esi,[ss2]
  699.     
  700.     add    edx,dword ptr [ds2]
  701.     add    edx,dword ptr [ds2]
  702.     
  703.     mov    dword ptr [dst],edx
  704.     jmp    outer_loop
  705.  
  706.     outer_done:
  707.         emms
  708.         ret
  709.     
  710. sclblt_mem ENDP
  711.     
  712. END
  713.     
  714.