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