Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Dependency control scoreboard kernel for MBAFF frame
  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. // Kernel name: scoreboard_MBAFF.asm
  41. //
  42. // Dependency control scoreboard kernel for MBAFF frame
  43. //
  44. //  $Revision: 16 $
  45. //  $Date: 10/18/06 4:10p $
  46. //
  47.  
  48. // ----------------------------------------------------
  49. //  Main: scoreboard_MBAFF
  50. // ----------------------------------------------------
  51. // ----------------------------------------------------
  52. //  Scoreboard structure
  53. // ----------------------------------------------------
  54. //
  55. //      1 DWORD per thread
  56. //
  57. //      Bit 31: "Checking" thread, i.e. an intra MB that sends "check dependency" message
  58. //      Bit 30: "Completed" thread. This bit set by an "update" message from intra/inter MB.
  59. //      Bits 29:28:     Must set to 0
  60. //      Bits 27:24:     EUID
  61. //      Bits 23:18: Reserved
  62. //      Bits 17:16: TID
  63. //      Bits 15:8:      X offset of current MB
  64. //      Bits 15:5:      Reserved
  65. //      Bits 4:0: 5 bits of available neighbor MB flags
  66.  
  67. .kernel scoreboard_MBAFF
  68. SCOREBOARD_MBAFF:
  69.  
  70. #ifdef _DEBUG
  71. // WA for FULSIM so we'll know which kernel is being debugged
  72. mov (1) acc0:ud 0xffaa55a5:ud
  73. #endif
  74.  
  75. #include "header.inc"
  76. #include "scoreboard_header.inc"
  77.  
  78. //
  79. //  Now, begin source code....
  80. //
  81.  
  82. .code
  83.  
  84. #ifdef  AS_ENABLED
  85.         and.z.f0.1      (1)     NULLREG r0.2<0;1,0>:ud  TH_RES  // Is this a restarted thread previously interrupted?
  86.         (f0.1) jmpi     (1)     MBAFF_Scoreboard_Init
  87.  
  88.         #include "scoreboard_restore_AS.asm"
  89.  
  90.         jmpi (1)        MBAFF_Scoreboard_OpenGW
  91. MBAFF_Scoreboard_Init:
  92. #endif  // End AS_ENABLED
  93.  
  94. // Scoreboard must be initialized to 0xc000ffff, meaning all "completed"
  95. // And it also avoids message mis-handling for the first MB
  96.    $for(0; <32; 2) {
  97.         mov (16)        CMD_SB(%1)<1>   0xc000ffff:ud {Compr}
  98.         }
  99. #ifdef  DOUBLE_SB                                       // Scoreboard size needs to be doubled
  100.    $for(32; <64; 2) {
  101.         mov (16)        CMD_SB(%1)<1>   0xc000ffff:ud {Compr}
  102.         }
  103. #endif  // DOUBLE_SB
  104.  
  105. //----------------------------------------------------------
  106. //      Open message gateway for the scoreboard thread
  107. //
  108. //      RegBase = r4 (0x04)
  109. //      Gateway Size = 64 GRF registers (0x6)
  110. //      Dispatch ID = r0.20:ub
  111. //      Scoreboard Thread Key = 0
  112. //----------------------------------------------------------
  113. MBAFF_Scoreboard_OpenGW:
  114.     mov (8)     MSGHDRY0<1>:ud  0x00000000:ud                   // Initialize message header payload with 0
  115.  
  116.         // Send a message with register base RegBase=0x04(r4) and Gateway size = 0x6 = 64 GRF reg and Key = 0
  117.         // 000 00000100 00000 00000 110 00000000 ==> 0000 0000 1000 0000 0000 0110 0000 0000
  118. #ifdef  AS_ENABLED
  119.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800700:ud   // Allocate 128 GRFs for message gateway - for SIP to send notification MSG
  120. #else
  121.   #ifdef        DOUBLE_SB
  122.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800600:ud   // 64 GRF's for CTG-B
  123.   #else
  124.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800500:ud   // 32 GRF's for CTG-A
  125.   #endif        // DOUBLE_SB
  126. #endif
  127.  
  128.         send (8)        NULLREG  MSGHDRY0       null:ud    MSG_GW       OGWMSGDSC
  129.  
  130. //------------------------------------------------------------------------
  131. //      Send Thread Spawning Message to start dispatching macroblock threads
  132. //
  133. //------------------------------------------------------------------------
  134. #ifdef  AS_ENABLED
  135.         mov (8) acc0<1>:ud      CMD_SB(31)<8;8,1>                       // Ensure scoreboard data have been completely restored
  136. #endif  // End AS_ENABLED
  137.     mov (8)     MSGHDRY1<1>:ud          r0<8;8,1>:ud            // Initialize message header payload with R0
  138.     mov (1)     MSGHDRY1.4<1>:ud        0x00000400:ud           // Dispatch URB length = 1
  139.  
  140.         send (8)        NULLREG  MSGHDRY1       null:ud    TS   TSMSGDSC
  141.  
  142.     mov (8)     MSGHDRY0<1>:ud          0x00000000:ud           // Initialize message header payload with 0
  143.  
  144. //------------------------------------------------------------------------
  145. //      Scoreboard control data initialization
  146. //------------------------------------------------------------------------
  147. #ifdef  AS_ENABLED
  148.         or      (1)     cr0.1:ud        cr0.1:ud        AS_INT_EN               // Enable interrupt
  149.         (f0.1) jmpi     (1)     MBAFF_Scoreboard_State_Init     // Jump if not restarted thread
  150.  
  151.         // Restore scoreboard kernel control data to r1 - r3
  152.     mov (1)     m4.1:ud 64:ud                           // Starting r1
  153.     mov (1)     m4.2:ud 0x0002001f:ud           // for 3 registers
  154.     send (8)    r1.0<1>:ud      m4      null:ud DWBRMSGDSC_SC+0x00030000+AS_SAVE        // Restore r1 - r3
  155.         and (1) CMDPTR<1>:uw    MBINDEX(0)<0;1,0>       SB_MASK*4:uw    // Restore scoreboard entries for current MB
  156.  
  157. // EOT if all MBs have been decoded
  158.         cmp.e.f0.0 (1)  NULLREG TotalMB<0;1,0>:w        0:w     // Set "Last MB" flag
  159.         (-f0.0) jmpi (1)        MBAFF_Before_First_MB
  160.    END_THREAD
  161.  
  162. // Check whether it is before the first MB
  163. MBAFF_Before_First_MB:
  164.         cmp.e.f0.0 (1)  NULLREG AVAILFLAGD<1>:ud        0x08020401:ud   // in ACBD order
  165.         (f0.0) jmpi (1) MBAFF_Wavefront_Walk
  166.  
  167. MBAFF_Scoreboard_State_Init:
  168. #endif  // End AS_ENABLED
  169.         mov (2) WFLen_B<2>:w            HEIGHTINMB_1<0;1,0>:w
  170.         mov (1) AVAILFLAGD<1>:ud        0x08020401:ud   // in ACBD order
  171.         mov (1) AVAILFLAG1D<1>:ud       0x08020410:ud   // in A_C_B_D_ order
  172.         mov     (1) CASE00PTR<1>:ud     MBAFF_Notify_MSG_IP-MBAFF_No_Message_IP:ud              // Inter kernel starts
  173.         mov     (1) CASE10PTR<1>:ud     MBAFF_Dependency_Check_IP-MBAFF_No_Message_IP:ud        // Intra kernel starts
  174. #ifdef  AS_ENABLED
  175.         mov     (1) CASE11PTR<1>:ud     0:ud            // No message
  176. #else
  177.         mov     (1) CASE11PTR<1>:ud     MBAFF_MB_Loop_IP-MBAFF_No_Message_IP:ud         // No message
  178. #endif  // End AS_ENABLED
  179.         mov     (1) StartXD<1>:ud       0:ud
  180.         mov     (1) NewWFOffsetD<1>:ud  0x01ffff00:ud
  181.  
  182.         mov (8) WFStart_T(0)<1> 0xffff:w
  183.         mov (1) WFStart_T(0)<1> 0:w
  184.  
  185.         mov     (8)     a0.0<1>:uw      0x0:uw                                          // Initialize all pointers to 0
  186.  
  187. //------------------------------------------------------------------------
  188. //      Scoreboard message handling loop
  189. //------------------------------------------------------------------------
  190. //
  191. MBAFF_Scoreboard_Loop:
  192. // Calculate current wavefront length (same for top and bottom MB wavefronts)
  193.         add.ge.f0.1 (16)        acc0<1>:w       StartX<0;1,0>:w 0:w     // Used for x>2*y check
  194.         mac.g.f0.0 (16) NULLREGW        WFLenY<0;1,0>:w -2:w    // X - 2*Y > 0 ??
  195.         (f0.0) mov (2)  WFLen_B<1>:w    WFLenY<0;1,0>:w         // Use smaller vertical wavefront length
  196.         (f0.0) mov (1)  WFLen_Save<1>:w WFLenY<0;1,0>:w         // Save current wave front length
  197.         (-f0.0) asr.sat (2)     WFLen_B<1>:uw   StartX<0;1,0>:w 1:w     // Horizontal wavefront length is smaller
  198.         (-f0.0) asr.sat (1)     WFLen_Save<1>:uw        StartX<0;1,0>:w 1:w     // Save current wave front length
  199.  
  200. // Initialize 9-MB group for top macroblock wavefront
  201. #ifdef ONE_MB_WA_MBAFF
  202.         mov (2) MBINDEX(0)<1>           WFStart_T(0)<2;2,1>
  203.         (f0.1) add (4) MBINDEX(0,2)<1>          WFStart_B(0,1)<4;4,1>   -1:w
  204.         (-f0.1) add (4) MBINDEX(0,2)<1>         WFStart_B(0,0)<4;4,1>   -1:w
  205.         mov (1) MBINDEX(0,5)<1>         WFStart_B(0,1)<0;1,0>
  206.         (-f0.1) mov (1) StartX<1>:w             0:w                                     // WA for 1-MB wide pictures
  207. #else
  208.         mov (2) MBINDEX(0)<1>           WFStart_T(0)<2;2,1>                     {NoDDClr}
  209.         add (4) MBINDEX(0,2)<1>         WFStart_B(0,1)<4;4,1>   -1:w    {NoDDChk,NoDDClr}
  210.         mov (1) MBINDEX(0,5)<1>         WFStart_B(0,1)<0;1,0>           {NoDDChk,NoDDClr}
  211.         add (4) MBINDEX(0,6)<1>         WFStart_T(0,1)<4;4,1>   -1:w    {NoDDChk}       // Upper MB group (C_B_D_x)
  212. #endif
  213.  
  214. // Update WFStart_B[0]
  215.         add (8) acc0<1>:w       WFLen<0;1,0>:w  1:w                             // WFLen + 1
  216.         add (1) WFStart_B(0,0)<1>       acc0<0;1,0>:w   WFStart_T(0,0)<0;1,0>   // WFStart_T[0] + WFLen + 1
  217.  
  218. MBAFF_Start_Wavefront:
  219.         mul (16)        MBINDEX(0)<1>   MBINDEX(0)REGION(16,1)  4:w             // Adjust MB order # to be DWORD aligned
  220.         and (1) CMDPTR<1>:uw    acc0<0;1,0>:w   SB_MASK*4:uw    // Wrap around scoreboard entries for current MB
  221.  
  222. MBAFF_Wavefront_Walk:
  223.         wait    n0:ud
  224.  
  225. //      Check for combined "checking" or "completed" threads in forwarded message
  226. //      2 MSB of scoreboard message indicate:
  227. //      0b00 = "inter start" message
  228. //      0b10 = "intra start" message
  229. //      0b11 = "No Message" or "inter complete" message
  230. //      0b01 = Reserved (should never occur)
  231. //
  232. MBAFF_MB_Loop:
  233.         shr     (1)     PMSGSEL<1>:uw   r[CMDPTR,CMD_SB_REG_OFF*GRFWIB+2]<0;1,0>:uw     12:w                                    // DWORD aligned pointer to message handler
  234.         and.nz.f0.1 (8) NULLREG r[CMDPTR,CMD_SB_REG_OFF*GRFWIB]<0;1,0>:ub       AVAILFLAG<8;8,1>:ub             // f0.1 8 LSB will have the available flags in ACBDA_C_B_D_ order
  235.         mov (1) MSGHDRY0.4<1>:ud        r[CMDPTR,CMD_SB_REG_OFF*GRFWIB]<0;1,0>:ud               // Copy MB thread info from scoreboard
  236.         jmpi (1)        r[PMSGSEL, INLINE_REG_OFF*GRFWIB+16]<0;1,0>:d
  237.  
  238. //      Now determine whether this is "inter done" or "no message"
  239. //      through checking debug_counter
  240. //
  241. MBAFF_No_Message:
  242. #ifdef  AS_ENABLED
  243.         cmp.z.f0.1 (1)  NULLREG n0:ud   0       // Are all messages handled?
  244.         and.z.f0.0 (1)  NULLREG cr0.1:ud        AS_INT  // Poll interrupt bit
  245.         (-f0.1) jmpi (1)        MBAFF_MB_Loop                   // Continue polling the remaining message from current thread
  246.  
  247. // All messages have been handled
  248.         (f0.0) jmpi (1) MBAFF_Wavefront_Walk            // No interrupt occurs. Wait for next one
  249.  
  250. // Interrupt has been detected
  251. // Save all contents and terminate the scoreboard
  252. //
  253.         #include "scoreboard_save_AS.asm"
  254.  
  255.         // Save scoreboard control data as well
  256.         //
  257.     mov (1)     MSGHDR.1:ud             64:ud
  258.     mov (1)     MSGHDR.2:ud             0x0002001f:ud   // for 3 registers
  259.         $for(0; <3; 1) {
  260.         mov (8) MSGPAYLOADD(%1)<1>      CMD_SB(%1-3)REGION(8,1)
  261.         }
  262.     send (8)    NULLREG MSGHDR  null:ud DWBWMSGDSC+0x00300000+AS_SAVE   // Save r1 - r3
  263.  
  264.         send (8) NULLREG MSGHDR r0:ud EOTMSGDSC+TH_INT  // Terminate with "Thread Interrupted" bit set
  265. #endif  // End AS_ENABLED
  266.  
  267. MBAFF_Dependency_Check:
  268. //      Current thread is "checking" but not "completed" (0b10 case).
  269. //      Check for dependency clear using all availability bits
  270. //
  271.         and (8) DEPPTR<1>:uw    MBINDEX(0,1)REGION(8,1) SB_MASK*4:uw    // Wrap around scoreboard entries for current MB
  272. MBAFF_Dependency_Polling:
  273.         (f0.1) and.z.f0.1 (8)   NULLREG r[DEPPTR,CMD_SB_REG_OFF*GRFWIB+3]<1,0>:ub       DONEFLAG:uw     // f0.1 8 LSB contains dependency clear
  274.         (f0.1.any8h) jmpi (1)   MBAFF_Dependency_Polling                // Dependency not clear, keep polling..
  275.  
  276. //      "Checking" thread and dependency cleared, send a message to let the thread go
  277. //
  278. MBAFF_Notify_MSG:
  279.         send (8)        NULLREG  MSGHDRY0       null:ud    MSG_GW       FWDMSGDSC+NOTIFYMSG
  280.  
  281. //      Current macroblock has been serviced. Update to next macroblock in special zig-zag order
  282. //
  283. MBAFF_Update_CurMB:
  284.         add.ge.f0.0 (2) TotalMB<2>:w    TotalMB<4;2,2>:w        -1:w    // Set "End of wavefront" flag and decrement "TotalMB"
  285.         add (16)        MBINDEX(0)<1>   MBINDEX(0)REGION(16,1)  4:w             // Increment MB indices
  286.         and (1) CMDPTR<1>:uw    acc0<0;1,0>:w   SB_MASK*4:uw // Wrap around scoreboard entries for current MB
  287.         (f0.0.all2h) jmpi (1) MBAFF_Wavefront_Walk      // Continue wavefront walking
  288.  
  289. // Top macroblock wavefront walk done, start bottom MB wavefront
  290.         add.ge.f0.0 (1) WFLen<1>:w      WFLen_B<0;1,0>:w        0:w     {NoDDClr}               // Set bottom MB wavefront length
  291.         mov (1) WFLen_B<1>:w    -1:w    {NoDDChk}                       // Reset bottom MB wavefront length
  292.        
  293. // Initialize 9-MB group for bottom macroblock wavefront
  294.         mov (8) MBINDEX(0)<1>           WFStart_B(0)<1;4,0>                     {NoDDClr}       // Initialize with WFStart_B[0] and WFStart_B[1]
  295.         mov (4) MBINDEX(0,1)<1>         WFStart_T(0,1)<0;1,0>           {NoDDChk,NoDDClr}       // Initialize with WFStart_T[1]
  296.         mov (2) MBINDEX(0,2)<1>         WFStart_T(0)<0;1,0>                     {NoDDChk,NoDDClr}       // Initialize with WFStart_T[0]
  297.         add (4) MBINDEX(0,6)<1>         WFStart_B(0,1)<4;4,1>   -1:w    {NoDDChk}       // Upper MB group (C_B_D_x)
  298.  
  299.         (f0.0) jmpi (1) MBAFF_Start_Wavefront                           // Start bottom MB wavefront walk
  300.  
  301. //      Start new wavefront
  302. //
  303.         cmp.e.f0.1 (16) NULLREGW  StartX<0;1,0>:uw      WIDTHINMB_1<0;1,0>:uw   // Set "on picture right boundary" flag
  304.  
  305.         // Update WFStart_T and WFStart_B
  306.         add (8) acc0<1>:w       WFStart_T(0)REGION(1,0) 1:w                             // Move WFStart_T[0]+1 to acc0 to remove dependency later
  307.         mov (8) WFStart_T(0,1)<1>       WFStart_T(0)<8;8,1>     {NoDDClr}       // Shift WFStart_T(B)[0:2] to WFStart_T(B)[1:3]
  308.         mac (1) WFStart_T(0,0)<1>       WFLen_Save<0;1,0>:w     2:w {NoDDChk}   // WFStart_T[0] = WFStart_T[0] + 2*WFLen
  309.  
  310.         cmp.e.f0.0 (1)  NULLREG TotalMB<0;1,0>:w        0:w     // Set "Last MB" flag
  311.  
  312.         (f0.1) add (4)  WFLen<1>:w      WFLen<4;4,1>:w  NewWFOffset<4;4,1>:b    // + (0, -1, -1, 1)
  313.         (f0.1) add (8)  WFStart_T(0)<1> WFStart_T(0)REGION(4,1) 1:w
  314.         (-f0.1) add (1) StartX<1>:w             StartX<0;1,0>:w 1:w             // Move to right MB
  315.         (-f0.1) add (1) WFStart_T(0)<1> WFStart_T(0)REGION(1,0) 1:w
  316.  
  317.         (-f0.0) jmpi (1)        MBAFF_Scoreboard_Loop                           // Not last MB, start new wavefront walking
  318.  
  319. // All MBs have decoded. Terminate the thread now
  320. //
  321.    END_THREAD
  322.  
  323. #if !defined(COMBINED_KERNEL)           // For standalone kernel only
  324. .end_code
  325.  
  326. .end_kernel
  327. #endif
  328.  
  329. // End of scoreboard_MBAFF
  330.