Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Intra predict 8X8 luma block
  3.  * Copyright © <2010>, Intel Corporation.
  4.  *
  5.  * This program is licensed under the terms and conditions of the
  6.  * Eclipse Public License (EPL), version 1.0.  The full text of the EPL is at
  7.  * http://www.opensource.org/licenses/eclipse-1.0.php.
  8.  *
  9.  */
  10. #if !defined(__INTRA_PRED_8X8_Y__)              // Make sure this is only included once
  11. #define __INTRA_PRED_8X8_Y__
  12.  
  13. // Module name: intra_Pred_8X8_Y.asm
  14. //
  15. // Intra predict 8X8 luma block
  16. //
  17. //--------------------------------------------------------------------------
  18. //  Input data:
  19. //
  20. //  REF_TOP:    Top reference data stored in BYTE with p[-1,-1] at REF_TOP(0,-1), p[-1,-1] and [15,-1] adjusted
  21. //  REF_LEFT:   Left reference data stored in BYTE with p[-1,0] at REF_LEFT(0,2), REF_LEFT(0,1) (p[-1,-1]) adjusted
  22. //      PRED_MODE:      Intra prediction mode stored in 4 LSBs
  23. //      INTRA_PRED_AVAIL:       Top/Left available flag, (Bit0: Left, Bit1: Top)
  24. //
  25. //      Output data:
  26. //
  27. //      REG_INTRA_8X8_PRED: Predicted 8X8 block data
  28. //--------------------------------------------------------------------------
  29.  
  30. #define INTRA_REF       REG_INTRA_TEMP_1
  31. #define REF_TMP         REG_INTRA_TEMP_2
  32.  
  33. intra_Pred_8x8_Y:
  34.  
  35. //      Reference sample filtering
  36. //
  37.         // Set up boundary pixels for unified filtering
  38.         mov (1)         REF_TOP(0,16)<1>        REF_TOP(0,15)REGION(1,0)        // p[16,-1] = p[15,-1]
  39.         mov     (8)             REF_LEFT(0,2+8)<1>      REF_LEFT(0,2+7)REGION(1,0)      // p[-1,8] = p[-1,7]
  40.  
  41.         // Top reference sample filtering (!!Consider instruction compression later)
  42.         add (16)        acc0<1>:w       REF_TOP(0,-1)REGION(16,1)       2:w             // p[x-1,-1]+2
  43.         mac (16)        acc0<1>:w       REF_TOP(0)REGION(16,1)          2:w             // p[x-1,-1]+2*p[x,-1]+2
  44.         mac (16)        acc0<1>:w       REF_TOP(0,1)REGION(16,1)        1:w             // p[x-1,-1]+2*p[x,-1]+p[x+1,-1]+2
  45.         shr     (16)    REF_TMP<1>:w    acc0:2:w             // (p[x-1,-1]+2*p[x,-1]+p[x+1,-1]+2)>>2
  46.  
  47.         // Left reference sample filtering
  48.         add (16)        acc0<1>:w       REF_LEFT(0)REGION(16,1)         2:w             // p[-1,y-1]+2
  49.         mac (16)        acc0<1>:w       REF_LEFT(0,1)REGION(16,1)       2:w             // p[-1,y-1]+2*p[-1,y]+2
  50.         mac (16)        acc0<1>:w       REF_LEFT(0,2)REGION(16,1)       1:w             // p[-1,y-1]+2*p[-1,y]+p[-1,y+1]+2
  51.         shr     (16)    INTRA_REF<1>:w  acc0:2:w             // (p[-1,y-1]+2*p[-1,y]+p[-1,y+1]+2)>>2
  52.  
  53.         // Re-assign filtered reference samples
  54.         mov     (16)    REF_TOP(0)<1>   REF_TMP<32;16,2>:ub                     // p'[x,-1], x=0...15
  55.         mov     (8)             REF_LEFT(0)<1>  INTRA_REF.2<16;8,2>:ub          // p'[-1,y], y=0...7
  56.         mov     (1)             REF_TOP(0,-1)<1>        INTRA_REF<0;1,0>:ub             // p'[-1,-1]
  57.  
  58. //      Select intra_8x8 prediction mode
  59. //
  60.         and     (1)     PINTRAPRED_Y<1>:w       PRED_MODE<0;1,0>:w      0x0F:w
  61.         // WA for "jmpi" restriction
  62.         mov (1) REG_INTRA_TEMP_1<1>:ud  r[PINTRAPRED_Y, INTRA_8X8_OFFSET]:ub
  63.         jmpi (1) REG_INTRA_TEMP_1<0;1,0>:d
  64.  
  65. // Mode 0
  66. #define PTMP    a0.6
  67. #define PTMP_D  a0.3
  68. INTRA_8X8_VERTICAL:
  69.     $for(0,0; <4; 1,32) {
  70.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REF_TOP(0)<0;8,1>
  71.         }
  72.         RETURN
  73.  
  74. // Mode 1
  75. INTRA_8X8_HORIZONTAL:
  76.     $for(0,0; <8; 2,32) {
  77.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REF_LEFT(0,%1)<1;8,0>
  78.         }
  79.         RETURN
  80.  
  81. // Mode 2
  82. INTRA_8X8_DC:
  83. // Rearrange reference samples for unified DC prediction code
  84. //
  85.     and.nz.f0.0 (16)    NULLREG         INTRA_PRED_AVAIL<0;1,0>:w       2:w     // Top macroblock available for intra prediction?
  86.     and.nz.f0.1 (8)             NULLREG         INTRA_PRED_AVAIL<0;1,0>:w       1:w     // Left macroblock available for intra prediction?
  87.         (-f0.0.any16h) mov (16) REF_TOP_W(0)<1> 0x8080:uw
  88.         (-f0.1.any8h) mov (8)   REF_LEFT(0)<1>  REF_TOP(0)REGION(8,1)
  89.         (-f0.0.any8h) mov (8)   REF_TOP(0)<1>   REF_LEFT(0)REGION(8,1)
  90.  
  91. // Perform DC prediction
  92. //
  93.         add (8)         PRED_YW(15)<1>  REF_TOP(0)REGION(8,1)   REF_LEFT(0)REGION(8,1)
  94.         add (4)         PRED_YW(15)<1>  PRED_YW(15)REGION(4,1)  PRED_YW(15,4)REGION(4,1)
  95.         add (2)         PRED_YW(15)<1>  PRED_YW(15)REGION(2,1)  PRED_YW(15,2)REGION(2,1)
  96.         add (16)        acc0<1>:w               PRED_YW(15)REGION(1,0)  PRED_YW(15,1)REGION(1,0)
  97.         add     (16)    acc0<1>:w               acc0:8:w
  98.         shr (16)        REG_INTRA_TEMP_0<1>:w   acc0:4:w
  99.  
  100.         // Add error block
  101.     $for(0,0; <4; 1,32) {
  102.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REG_INTRA_TEMP_0<16;16,1>:w
  103.         }
  104.         RETURN
  105.  
  106. // Mode 3
  107. INTRA_8X8_DIAG_DOWN_LEFT:
  108.         mov     (8)             REF_TOP(0,16)<1>        REF_TOP(0,15)REGION(8,1)        // p[16,-1] = p[15,-1]
  109.         add (16)        acc0<1>:w               REF_TOP(0,2)REGION(16,1)        2:w             // p[x+2]+2
  110.         mac (16)        acc0<1>:w               REF_TOP(0,1)REGION(16,1)        2:w             // 2*p[x+1]+p[x+2]+2
  111.         mac (16)        acc0<1>:w               REF_TOP(0)REGION(16,1)          1:w             // p[x]+2*p[x+1]+p[x+2]+2
  112.         shr (16)        REG_INTRA_TEMP_0<1>:w   acc0<16;16,1>:w         2:w             // (p[x]+2*p[x+1]+p[x+2]+2)>>2
  113.  
  114.         // Add error block
  115.     $for(0,0; <8; 2,32) {
  116.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REG_INTRA_TEMP_0.%1<1;8,1>:w
  117.         }
  118.         RETURN
  119.  
  120. // Mode 4
  121. INTRA_8X8_DIAG_DOWN_RIGHT:
  122. #define INTRA_REF       REG_INTRA_TEMP_1
  123. #define REF_TMP         REG_INTRA_TEMP_2
  124.  
  125. //      Set inverse shift count
  126.         shl     (4)             REF_TMP<1>:ud   REF_LEFT_D(0,1)REGION(1,0)      INV_SHIFT<4;4,1>:b      // Reverse order bottom 4 pixels of left ref.
  127.         shl     (4)             REF_TMP.4<1>:ud REF_LEFT_D(0)REGION(1,0)        INV_SHIFT<4;4,1>:b      // Reverse order top 4 pixels of left ref.
  128.         mov     (8)             INTRA_REF<1>:ub REF_TMP.3<32;8,4>:ub
  129.         mov     (16)    INTRA_REF.8<1>:ub       REF_TOP(0,-1)REGION(16,1)       // INTRA_REF holds all reference data
  130.  
  131.         add (16)        acc0<1>:w               INTRA_REF.2<16;16,1>:ub         2:w             // p[x+2]+2
  132.         mac (16)        acc0<1>:w               INTRA_REF.1<16;16,1>:ub         2:w             // 2*p[x+1]+p[x+2]+2
  133.         mac (16)        acc0<1>:w               INTRA_REF<16;16,1>:ub           1:w             // p[x]+2*p[x+1]+p[x+2]+2
  134.         shr (16)        INTRA_REF<1>:w  acc0<16;16,1>:w                         2:w             // (p[x]+2*p[x+1]+p[x+2]+2)>>2
  135.  
  136. //      Store data in reversed order
  137.         add (2)         PBWDCOPY_8<1>:w INV_TRANS48<2;2,1>:b    INTRA_TEMP_1*GRFWIB:w   // Must match with INTRA_REF
  138.  
  139.         // Add error block
  140.     $for(0,96; <8; 2,-32) {
  141.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PBWDCOPY_8,%1*2]<8,1>:w       r[PERROR,%2]<16;16,1>:w
  142.         }
  143.         RETURN
  144.  
  145. // Mode 5
  146. INTRA_8X8_VERT_RIGHT:
  147. #define INTRA_REF       REG_INTRA_TEMP_1
  148. #define REF_TMP         REG_INTRA_TEMP_2
  149. #define REF_TMP1        REG_INTRA_TEMP_3
  150.  
  151. //      Set inverse shift count
  152.         shl     (4)             REF_TMP<1>:ud   REF_LEFT_D(0,1)REGION(1,0)      INV_SHIFT<4;4,1>:b      // Reverse order bottom 4 pixels of left ref.
  153.         shl     (4)             REF_TMP.4<1>:ud REF_LEFT_D(0)REGION(1,0)        INV_SHIFT<4;4,1>:b      // Reverse order top 4 pixels of left ref.
  154.         mov     (8)             INTRA_REF<1>:ub REF_TMP.3<32;8,4>:ub
  155.         mov     (16)    INTRA_REF.8<1>:ub       REF_TOP(0,-1)REGION(16,1)       // INTRA_REF holds all reference data
  156.  
  157.         // Even rows
  158.         avg (16)        PRED_YW(14)<1>  INTRA_REF.8<16;16,1>    INTRA_REF.9<16;16,1>    // avg(p[x-1],p[x])
  159.         // Odd rows
  160.         add (16)        acc0<1>:w               INTRA_REF.3<16;16,1>:ub         2:w             // p[x]+2
  161.         mac (16)        acc0<1>:w               INTRA_REF.2<16;16,1>:ub         2:w             // 2*p[x-1]+p[x]+2
  162.         mac (16)        acc0<1>:w               INTRA_REF.1<16;16,1>:ub         1:w             // p[x-2]+2*p[x-1]+p[x]+2
  163.         shr (16)        REF_TMP<1>:w    acc0:2:w             // (p[x-2]+2*p[x-1]+p[x]+2)>>2
  164.  
  165.         mov     (8)             INTRA_REF<1>:ub         REF_TMP<16;8,2>:ub              // Keep zVR = -1,-2,-3,-4,-5,-6,-7 sequencially
  166.         mov     (8)             INTRA_REF.6<2>:ub       REF_TMP.12<16;8,2>:ub   // Keep zVR = -1,1,3,5,7,9,11,13 at even byte
  167.         mov     (8)             INTRA_REF.7<2>:ub       PRED_Y(14)REGION(8,2)   // Combining zVR = 0,2,4,6,8,10,12,14 at odd byte
  168.  
  169.         add (2)         PBWDCOPY_8<1>:w INV_TRANS8<2;2,1>:b     INTRA_TEMP_1*GRFWIB:w   // Must match with INTRA_REF
  170.  
  171.         // Add error block
  172.     $for(0,96; <8; 2,-32) {
  173.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PBWDCOPY_8,%1]<8,2>:ub        r[PERROR,%2]<16;16,1>:w
  174.         }
  175.         RETURN
  176.  
  177. // Mode 6
  178. INTRA_8X8_HOR_DOWN:
  179. //      Set inverse shift count
  180.         shl     (4)             REF_TMP<1>:ud   REF_LEFT_D(0,1)REGION(1,0)      INV_SHIFT<4;4,1>:b      // Reverse order bottom 4 pixels of left ref.
  181.         shl     (4)             REF_TMP.4<1>:ud REF_LEFT_D(0)REGION(1,0)        INV_SHIFT<4;4,1>:b      // Reverse order top 4 pixels of left ref.
  182.         mov     (8)             INTRA_REF<1>:ub REF_TMP.3<16;4,4>:ub
  183.         mov     (16)    INTRA_REF.8<1>:ub       REF_TOP(0,-1)REGION(16,1)       // INTRA_REF holds all reference data
  184.  
  185.         // Odd pixels
  186.         add (16)        acc0<1>:w       INTRA_REF.2<16;16,1>:ub         2:w             // p[y]+2
  187.         mac (16)        acc0<1>:w       INTRA_REF.1<16;16,1>:ub         2:w             // 2*p[y-1]+p[y]+2
  188.         mac (16)        acc0<1>:w       INTRA_REF.0<16;16,1>:ub         1:w             // p[y-2]+2*p[y-1]+p[y]+2
  189.         shr (16)        PRED_YW(14)<1>  acc0:2:w             // (p[y-2]+2*p[y-1]+p[y]+2)>>2
  190.         // Even pixels
  191.         avg (16)        INTRA_REF<1>:w  INTRA_REF<16;16,1>:ub   INTRA_REF.1<16;16,1>:ub // avg(p[y-1],p[y])
  192.  
  193.         mov     (8)             INTRA_REF.1<2>:ub       PRED_Y(14)REGION(8,2)           // Combining odd pixels to form byte type
  194.         mov     (8)             INTRA_REF.16<1>:ub      PRED_Y(14,16)REGION(8,2)        // Keep zVR = -2,-3,-4,-5,-6,-7 unchanged
  195.         // Now INTRA_REF.0 - INTRA_REF.21 contain predicted data
  196.  
  197.         add (2)         PBWDCOPY_8<1>:w INV_TRANS48<2;2,1>:b    INTRA_TEMP_1*GRFWIB:w   // Must match with INTRA_REF
  198.  
  199.         // Add error block
  200.     $for(0,96; <13; 4,-32) {
  201.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PBWDCOPY_8,%1]<8,1>:ub        r[PERROR,%2]<16;16,1>:w
  202.         }
  203.         RETURN
  204.  
  205. // Mode 7
  206. INTRA_8X8_VERT_LEFT:
  207.         // Even rows
  208.         avg (16)                PRED_YW(14)<1>  REF_TOP(0)REGION(16,1)  REF_TOP(0,1)REGION(16,1)        // avg(p[x],p[x+1])
  209.         // Odd rows
  210.         add (16)                acc0<1>:w               REF_TOP(0,2)REGION(16,1)        2:w             // p[x+2]+2
  211.         mac (16)                acc0<1>:w               REF_TOP(0,1)REGION(16,1)        2:w             // 2*p[x+1]+p[x+2]+2
  212.         mac (16)                acc0<1>:w               REF_TOP(0)REGION(16,1)          1:w             // p[x]+2*p[x+1]+p[x+2]+2
  213.         shr (16)                PRED_YW(15)<1>  acc0<1;8,1>:w   2:w             // (p[x]+2*p[x+1]+p[x+2]+2)>>2
  214.  
  215.         // Add error block
  216.     $for(0,0; <4; 1,32) {
  217.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  PRED_YW(14,%1)<16;8,1>  r[PERROR,%2]<16;16,1>:w
  218.         }
  219.         RETURN
  220.  
  221. // Mode 8
  222. INTRA_8X8_HOR_UP:
  223. //      Set extra left reference pixels for unified prediction
  224.         mov     (8)             REF_LEFT(0,8)<1>        REF_LEFT(0,7)REGION(1,0)        // Copy p[-1,7] to p[-1,y],y=8...15
  225.  
  226.         // Even pixels
  227.         avg (16)        PRED_YW(14)<1>  REF_LEFT(0)REGION(16,1) REF_LEFT(0,1)REGION(16,1)       // avg(p[y],p[y+1])
  228.         // Odd pixels
  229.         add (16)        acc0<1>:w               REF_LEFT(0,2)REGION(16,1)       2:w             // p[y+2]+2
  230.         mac (16)        acc0<1>:w               REF_LEFT(0,1)REGION(16,1)       2:w             // 2*p[y+1]+p[y+2]+2
  231.         mac (16)        acc0<1>:w               REF_LEFT(0)REGION(16,1)         1:w             // p[y]+2*p[y+1]+p[y+2]+2
  232.         shr (16)        PRED_YW(15)<1>  acc0<1;8,1>:w   2:w             // (p[y]+2*p[y+1]+p[y+2]+2)>>2
  233.  
  234.         // Merge even/odd pixels
  235.         // The predicted data need to be stored in byte type (22 bytes are required)
  236.         mov (16)        PRED_Y(14,1)<2> PRED_Y(15)REGION(16,2)
  237.  
  238.         // Add error block
  239.     $for(0,0; <4; 1,32) {
  240.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  PRED_Y(14,%1*4)<2;8,1>  r[PERROR,%2]<16;16,1>:w
  241.         }
  242.         RETURN
  243.  
  244. // End of intra_Pred_8X8_Y
  245.  
  246. #endif  // !defined(__INTRA_PRED_8X8_Y__)
  247.