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.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sub license, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial portions
  15.  * of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  20.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  21.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * This file was originally licensed under the following license
  26.  *
  27.  *  Licensed under the Apache License, Version 2.0 (the "License");
  28.  *  you may not use this file except in compliance with the License.
  29.  *  You may obtain a copy of the License at
  30.  *
  31.  *      http://www.apache.org/licenses/LICENSE-2.0
  32.  *
  33.  *  Unless required by applicable law or agreed to in writing, software
  34.  *  distributed under the License is distributed on an "AS IS" BASIS,
  35.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  36.  *  See the License for the specific language governing permissions and
  37.  *  limitations under the License.
  38.  *
  39.  */
  40. #if !defined(__INTRA_PRED_8X8_Y__)              // Make sure this is only included once
  41. #define __INTRA_PRED_8X8_Y__
  42.  
  43. // Module name: intra_Pred_8X8_Y.asm
  44. //
  45. // Intra predict 8X8 luma block
  46. //
  47. //--------------------------------------------------------------------------
  48. //  Input data:
  49. //
  50. //  REF_TOP:    Top reference data stored in BYTE with p[-1,-1] at REF_TOP(0,-1), p[-1,-1] and [15,-1] adjusted
  51. //  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
  52. //      PRED_MODE:      Intra prediction mode stored in 4 LSBs
  53. //      INTRA_PRED_AVAIL:       Top/Left available flag, (Bit0: Left, Bit1: Top)
  54. //
  55. //      Output data:
  56. //
  57. //      REG_INTRA_8X8_PRED: Predicted 8X8 block data
  58. //--------------------------------------------------------------------------
  59.  
  60. #define INTRA_REF       REG_INTRA_TEMP_1
  61. #define REF_TMP         REG_INTRA_TEMP_2
  62.  
  63. intra_Pred_8x8_Y:
  64.  
  65. //      Reference sample filtering
  66. //
  67.         // Set up boundary pixels for unified filtering
  68.         mov (1)         REF_TOP(0,16)<1>        REF_TOP(0,15)REGION(1,0)        // p[16,-1] = p[15,-1]
  69.         mov     (8)             REF_LEFT(0,2+8)<1>      REF_LEFT(0,2+7)REGION(1,0)      // p[-1,8] = p[-1,7]
  70.  
  71.         // Top reference sample filtering (!!Consider instruction compression later)
  72.         add (16)        acc0<1>:w       REF_TOP(0,-1)REGION(16,1)       2:w             // p[x-1,-1]+2
  73.         mac (16)        acc0<1>:w       REF_TOP(0)REGION(16,1)          2:w             // p[x-1,-1]+2*p[x,-1]+2
  74.         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
  75.         shr     (16)    REF_TMP<1>:w    acc0:2:w             // (p[x-1,-1]+2*p[x,-1]+p[x+1,-1]+2)>>2
  76.  
  77.         // Left reference sample filtering
  78.         add (16)        acc0<1>:w       REF_LEFT(0)REGION(16,1)         2:w             // p[-1,y-1]+2
  79.         mac (16)        acc0<1>:w       REF_LEFT(0,1)REGION(16,1)       2:w             // p[-1,y-1]+2*p[-1,y]+2
  80.         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
  81.         shr     (16)    INTRA_REF<1>:w  acc0:2:w             // (p[-1,y-1]+2*p[-1,y]+p[-1,y+1]+2)>>2
  82.  
  83.         // Re-assign filtered reference samples
  84.         mov     (16)    REF_TOP(0)<1>   REF_TMP<32;16,2>:ub                     // p'[x,-1], x=0...15
  85.         mov     (8)             REF_LEFT(0)<1>  INTRA_REF.2<16;8,2>:ub          // p'[-1,y], y=0...7
  86.         mov     (1)             REF_TOP(0,-1)<1>        INTRA_REF<0;1,0>:ub             // p'[-1,-1]
  87.  
  88. //      Select intra_8x8 prediction mode
  89. //
  90.         and     (1)     PINTRAPRED_Y<1>:w       PRED_MODE<0;1,0>:w      0x0F:w
  91.         // WA for "jmpi" restriction
  92.         mov (1) REG_INTRA_TEMP_1<1>:ud  r[PINTRAPRED_Y, INTRA_8X8_OFFSET]:ub
  93.         jmpi (1) REG_INTRA_TEMP_1<0;1,0>:d
  94.  
  95. // Mode 0
  96. #define PTMP    a0.6
  97. #define PTMP_D  a0.3
  98. INTRA_8X8_VERTICAL:
  99.     $for(0,0; <4; 1,32) {
  100.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REF_TOP(0)<0;8,1>
  101.         }
  102.         RETURN
  103.  
  104. // Mode 1
  105. INTRA_8X8_HORIZONTAL:
  106.     $for(0,0; <8; 2,32) {
  107.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REF_LEFT(0,%1)<1;8,0>
  108.         }
  109.         RETURN
  110.  
  111. // Mode 2
  112. INTRA_8X8_DC:
  113. // Rearrange reference samples for unified DC prediction code
  114. //
  115.     and.nz.f0.0 (16)    NULLREG         INTRA_PRED_AVAIL<0;1,0>:w       2:w     // Top macroblock available for intra prediction?
  116.     and.nz.f0.1 (8)             NULLREG         INTRA_PRED_AVAIL<0;1,0>:w       1:w     // Left macroblock available for intra prediction?
  117.         (-f0.0.any16h) mov (16) REF_TOP_W(0)<1> 0x8080:uw
  118.         (-f0.1.any8h) mov (8)   REF_LEFT(0)<1>  REF_TOP(0)REGION(8,1)
  119.         (-f0.0.any8h) mov (8)   REF_TOP(0)<1>   REF_LEFT(0)REGION(8,1)
  120.  
  121. // Perform DC prediction
  122. //
  123.         add (8)         PRED_YW(15)<1>  REF_TOP(0)REGION(8,1)   REF_LEFT(0)REGION(8,1)
  124.         add (4)         PRED_YW(15)<1>  PRED_YW(15)REGION(4,1)  PRED_YW(15,4)REGION(4,1)
  125.         add (2)         PRED_YW(15)<1>  PRED_YW(15)REGION(2,1)  PRED_YW(15,2)REGION(2,1)
  126.         add (16)        acc0<1>:w               PRED_YW(15)REGION(1,0)  PRED_YW(15,1)REGION(1,0)
  127.         add     (16)    acc0<1>:w               acc0:8:w
  128.         shr (16)        REG_INTRA_TEMP_0<1>:w   acc0:4:w
  129.  
  130.         // Add error block
  131.     $for(0,0; <4; 1,32) {
  132.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PERROR,%2]<16;16,1>:w REG_INTRA_TEMP_0<16;16,1>:w
  133.         }
  134.         RETURN
  135.  
  136. // Mode 3
  137. INTRA_8X8_DIAG_DOWN_LEFT:
  138.         mov     (8)             REF_TOP(0,16)<1>        REF_TOP(0,15)REGION(8,1)        // p[16,-1] = p[15,-1]
  139.         add (16)        acc0<1>:w               REF_TOP(0,2)REGION(16,1)        2:w             // p[x+2]+2
  140.         mac (16)        acc0<1>:w               REF_TOP(0,1)REGION(16,1)        2:w             // 2*p[x+1]+p[x+2]+2
  141.         mac (16)        acc0<1>:w               REF_TOP(0)REGION(16,1)          1:w             // p[x]+2*p[x+1]+p[x+2]+2
  142.         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
  143.  
  144.         // Add error block
  145.     $for(0,0; <8; 2,32) {
  146.         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
  147.         }
  148.         RETURN
  149.  
  150. // Mode 4
  151. INTRA_8X8_DIAG_DOWN_RIGHT:
  152. #define INTRA_REF       REG_INTRA_TEMP_1
  153. #define REF_TMP         REG_INTRA_TEMP_2
  154.  
  155. //      Set inverse shift count
  156.         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.
  157.         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.
  158.         mov     (8)             INTRA_REF<1>:ub REF_TMP.3<32;8,4>:ub
  159.         mov     (16)    INTRA_REF.8<1>:ub       REF_TOP(0,-1)REGION(16,1)       // INTRA_REF holds all reference data
  160.  
  161.         add (16)        acc0<1>:w               INTRA_REF.2<16;16,1>:ub         2:w             // p[x+2]+2
  162.         mac (16)        acc0<1>:w               INTRA_REF.1<16;16,1>:ub         2:w             // 2*p[x+1]+p[x+2]+2
  163.         mac (16)        acc0<1>:w               INTRA_REF<16;16,1>:ub           1:w             // p[x]+2*p[x+1]+p[x+2]+2
  164.         shr (16)        INTRA_REF<1>:w  acc0<16;16,1>:w                         2:w             // (p[x]+2*p[x+1]+p[x+2]+2)>>2
  165.  
  166. //      Store data in reversed order
  167.         add (2)         PBWDCOPY_8<1>:w INV_TRANS48<2;2,1>:b    INTRA_TEMP_1*GRFWIB:w   // Must match with INTRA_REF
  168.  
  169.         // Add error block
  170.     $for(0,96; <8; 2,-32) {
  171.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PBWDCOPY_8,%1*2]<8,1>:w       r[PERROR,%2]<16;16,1>:w
  172.         }
  173.         RETURN
  174.  
  175. // Mode 5
  176. INTRA_8X8_VERT_RIGHT:
  177. #define INTRA_REF       REG_INTRA_TEMP_1
  178. #define REF_TMP         REG_INTRA_TEMP_2
  179. #define REF_TMP1        REG_INTRA_TEMP_3
  180.  
  181. //      Set inverse shift count
  182.         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.
  183.         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.
  184.         mov     (8)             INTRA_REF<1>:ub REF_TMP.3<32;8,4>:ub
  185.         mov     (16)    INTRA_REF.8<1>:ub       REF_TOP(0,-1)REGION(16,1)       // INTRA_REF holds all reference data
  186.  
  187.         // Even rows
  188.         avg (16)        PRED_YW(14)<1>  INTRA_REF.8<16;16,1>    INTRA_REF.9<16;16,1>    // avg(p[x-1],p[x])
  189.         // Odd rows
  190.         add (16)        acc0<1>:w               INTRA_REF.3<16;16,1>:ub         2:w             // p[x]+2
  191.         mac (16)        acc0<1>:w               INTRA_REF.2<16;16,1>:ub         2:w             // 2*p[x-1]+p[x]+2
  192.         mac (16)        acc0<1>:w               INTRA_REF.1<16;16,1>:ub         1:w             // p[x-2]+2*p[x-1]+p[x]+2
  193.         shr (16)        REF_TMP<1>:w    acc0:2:w             // (p[x-2]+2*p[x-1]+p[x]+2)>>2
  194.  
  195.         mov     (8)             INTRA_REF<1>:ub         REF_TMP<16;8,2>:ub              // Keep zVR = -1,-2,-3,-4,-5,-6,-7 sequencially
  196.         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
  197.         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
  198.  
  199.         add (2)         PBWDCOPY_8<1>:w INV_TRANS8<2;2,1>:b     INTRA_TEMP_1*GRFWIB:w   // Must match with INTRA_REF
  200.  
  201.         // Add error block
  202.     $for(0,96; <8; 2,-32) {
  203.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PBWDCOPY_8,%1]<8,2>:ub        r[PERROR,%2]<16;16,1>:w
  204.         }
  205.         RETURN
  206.  
  207. // Mode 6
  208. INTRA_8X8_HOR_DOWN:
  209. //      Set inverse shift count
  210.         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.
  211.         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.
  212.         mov     (8)             INTRA_REF<1>:ub REF_TMP.3<16;4,4>:ub
  213.         mov     (16)    INTRA_REF.8<1>:ub       REF_TOP(0,-1)REGION(16,1)       // INTRA_REF holds all reference data
  214.  
  215.         // Odd pixels
  216.         add (16)        acc0<1>:w       INTRA_REF.2<16;16,1>:ub         2:w             // p[y]+2
  217.         mac (16)        acc0<1>:w       INTRA_REF.1<16;16,1>:ub         2:w             // 2*p[y-1]+p[y]+2
  218.         mac (16)        acc0<1>:w       INTRA_REF.0<16;16,1>:ub         1:w             // p[y-2]+2*p[y-1]+p[y]+2
  219.         shr (16)        PRED_YW(14)<1>  acc0:2:w             // (p[y-2]+2*p[y-1]+p[y]+2)>>2
  220.         // Even pixels
  221.         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])
  222.  
  223.         mov     (8)             INTRA_REF.1<2>:ub       PRED_Y(14)REGION(8,2)           // Combining odd pixels to form byte type
  224.         mov     (8)             INTRA_REF.16<1>:ub      PRED_Y(14,16)REGION(8,2)        // Keep zVR = -2,-3,-4,-5,-6,-7 unchanged
  225.         // Now INTRA_REF.0 - INTRA_REF.21 contain predicted data
  226.  
  227.         add (2)         PBWDCOPY_8<1>:w INV_TRANS48<2;2,1>:b    INTRA_TEMP_1*GRFWIB:w   // Must match with INTRA_REF
  228.  
  229.         // Add error block
  230.     $for(0,96; <13; 4,-32) {
  231.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  r[PBWDCOPY_8,%1]<8,1>:ub        r[PERROR,%2]<16;16,1>:w
  232.         }
  233.         RETURN
  234.  
  235. // Mode 7
  236. INTRA_8X8_VERT_LEFT:
  237.         // Even rows
  238.         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])
  239.         // Odd rows
  240.         add (16)                acc0<1>:w               REF_TOP(0,2)REGION(16,1)        2:w             // p[x+2]+2
  241.         mac (16)                acc0<1>:w               REF_TOP(0,1)REGION(16,1)        2:w             // 2*p[x+1]+p[x+2]+2
  242.         mac (16)                acc0<1>:w               REF_TOP(0)REGION(16,1)          1:w             // p[x]+2*p[x+1]+p[x+2]+2
  243.         shr (16)                PRED_YW(15)<1>  acc0<1;8,1>:w   2:w             // (p[x]+2*p[x+1]+p[x+2]+2)>>2
  244.  
  245.         // Add error block
  246.     $for(0,0; <4; 1,32) {
  247.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  PRED_YW(14,%1)<16;8,1>  r[PERROR,%2]<16;16,1>:w
  248.         }
  249.         RETURN
  250.  
  251. // Mode 8
  252. INTRA_8X8_HOR_UP:
  253. //      Set extra left reference pixels for unified prediction
  254.         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
  255.  
  256.         // Even pixels
  257.         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])
  258.         // Odd pixels
  259.         add (16)        acc0<1>:w               REF_LEFT(0,2)REGION(16,1)       2:w             // p[y+2]+2
  260.         mac (16)        acc0<1>:w               REF_LEFT(0,1)REGION(16,1)       2:w             // 2*p[y+1]+p[y+2]+2
  261.         mac (16)        acc0<1>:w               REF_LEFT(0)REGION(16,1)         1:w             // p[y]+2*p[y+1]+p[y+2]+2
  262.         shr (16)        PRED_YW(15)<1>  acc0<1;8,1>:w   2:w             // (p[y]+2*p[y+1]+p[y+2]+2)>>2
  263.  
  264.         // Merge even/odd pixels
  265.         // The predicted data need to be stored in byte type (22 bytes are required)
  266.         mov (16)        PRED_Y(14,1)<2> PRED_Y(15)REGION(16,2)
  267.  
  268.         // Add error block
  269.     $for(0,0; <4; 1,32) {
  270.         add.sat (16)    r[PPREDBUF_Y,%2]<2>:ub  PRED_Y(14,%1*4)<2;8,1>  r[PERROR,%2]<16;16,1>:w
  271.         }
  272.         RETURN
  273.  
  274. // End of intra_Pred_8X8_Y
  275.  
  276. #endif  // !defined(__INTRA_PRED_8X8_Y__)
  277.