Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5361 | serge | 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_MBAFF1>0;1,0>1>1>4;4,1>4;4,1>1>0;1,0>0;1,0>1>8;8,1>1>1>0;1,0>0;1,0>4;4,1>1>0;1,0>1>0;1,0>1>1;4,0>1>1>0;1,0>1>0;1,0>1>1>4;2,2>2>1,0>1>1>3;>0;1,0>0;1,0>1>8;8,1>0;1,0>0;1,0>1>0;1,0>1>1>0;1,0>0;1,0>1>0;1,0>1>4;4,1>1>0;1,0>1>4;4,1>1>2;2,1>1>1>0;1,0>1>4;4,1>1>4;4,1>1>2;2,1>1>0;1,0>1>0;1,0>1>0;1,0>1>0;1,0>1>0;1,0>0;1,0>1>1>1>1>1>1>1>1>1>1>1>1>0;1,0>2>1>0;1,0>0;1,0>1>1>1>1>8;8,1>1>8;8,1>1>1>1>1>1>1>64;>1>32;>0;1,0>2010> |