1 /*
2 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26
27 /**
28 ****************************************************************************************************
29 * @file siaddrlib.cpp
30 * @brief Contains the implementation for the SiLib class.
31 ****************************************************************************************************
32 */
33
34 #include "siaddrlib.h"
35 #include "si_gb_reg.h"
36
37 #include "amdgpu_asic_addr.h"
38
39 ////////////////////////////////////////////////////////////////////////////////////////////////////
40 ////////////////////////////////////////////////////////////////////////////////////////////////////
41 namespace Addr
42 {
43
44 /**
45 ****************************************************************************************************
46 * SiHwlInit
47 *
48 * @brief
49 * Creates an SiLib object.
50 *
51 * @return
52 * Returns an SiLib object pointer.
53 ****************************************************************************************************
54 */
SiHwlInit(const Client * pClient)55 Lib* SiHwlInit(const Client* pClient)
56 {
57 return V1::SiLib::CreateObj(pClient);
58 }
59
60 namespace V1
61 {
62
63 // We don't support MSAA for equation
64 const BOOL_32 SiLib::m_EquationSupport[SiLib::TileTableSize][SiLib::MaxNumElementBytes] =
65 {
66 {TRUE, TRUE, TRUE, FALSE, FALSE}, // 0, non-AA compressed depth or any stencil
67 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 1, 2xAA/4xAA compressed depth with or without stencil
68 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 2, 8xAA compressed depth with or without stencil
69 {FALSE, TRUE, FALSE, FALSE, FALSE}, // 3, 16 bpp depth PRT (non-MSAA), don't support uncompressed depth
70 {TRUE, TRUE, TRUE, FALSE, FALSE}, // 4, 1D depth
71 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 5, 16 bpp depth PRT (4xMSAA)
72 {FALSE, FALSE, TRUE, FALSE, FALSE}, // 6, 32 bpp depth PRT (non-MSAA)
73 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 7, 32 bpp depth PRT (4xMSAA)
74 {TRUE, TRUE, TRUE, TRUE, TRUE }, // 8, Linear
75 {TRUE, TRUE, TRUE, TRUE, TRUE }, // 9, 1D display
76 {TRUE, FALSE, FALSE, FALSE, FALSE}, // 10, 8 bpp color (displayable)
77 {FALSE, TRUE, FALSE, FALSE, FALSE}, // 11, 16 bpp color (displayable)
78 {FALSE, FALSE, TRUE, TRUE, FALSE}, // 12, 32/64 bpp color (displayable)
79 {TRUE, TRUE, TRUE, TRUE, TRUE }, // 13, 1D thin
80 {TRUE, FALSE, FALSE, FALSE, FALSE}, // 14, 8 bpp color non-displayable
81 {FALSE, TRUE, FALSE, FALSE, FALSE}, // 15, 16 bpp color non-displayable
82 {FALSE, FALSE, TRUE, FALSE, FALSE}, // 16, 32 bpp color non-displayable
83 {FALSE, FALSE, FALSE, TRUE, TRUE }, // 17, 64/128 bpp color non-displayable
84 {TRUE, TRUE, TRUE, TRUE, TRUE }, // 18, 1D THICK
85 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 19, 2D XTHICK
86 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 20, 2D THICK
87 {TRUE, FALSE, FALSE, FALSE, FALSE}, // 21, 8 bpp 2D PRTs (non-MSAA)
88 {FALSE, TRUE, FALSE, FALSE, FALSE}, // 22, 16 bpp 2D PRTs (non-MSAA)
89 {FALSE, FALSE, TRUE, FALSE, FALSE}, // 23, 32 bpp 2D PRTs (non-MSAA)
90 {FALSE, FALSE, FALSE, TRUE, FALSE}, // 24, 64 bpp 2D PRTs (non-MSAA)
91 {FALSE, FALSE, FALSE, FALSE, TRUE }, // 25, 128bpp 2D PRTs (non-MSAA)
92 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 26, none
93 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 27, none
94 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 28, none
95 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 29, none
96 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 30, 64bpp 2D PRTs (4xMSAA)
97 {FALSE, FALSE, FALSE, FALSE, FALSE}, // 31, none
98 };
99
100 /**
101 ****************************************************************************************************
102 * SiLib::SiLib
103 *
104 * @brief
105 * Constructor
106 *
107 ****************************************************************************************************
108 */
SiLib(const Client * pClient)109 SiLib::SiLib(const Client* pClient)
110 :
111 EgBasedLib(pClient),
112 m_noOfEntries(0),
113 m_numEquations(0)
114 {
115 memset(&m_settings, 0, sizeof(m_settings));
116 }
117
118 /**
119 ****************************************************************************************************
120 * SiLib::~SiLib
121 *
122 * @brief
123 * Destructor
124 ****************************************************************************************************
125 */
~SiLib()126 SiLib::~SiLib()
127 {
128 }
129
130 /**
131 ****************************************************************************************************
132 * SiLib::HwlGetPipes
133 *
134 * @brief
135 * Get number pipes
136 * @return
137 * num pipes
138 ****************************************************************************************************
139 */
HwlGetPipes(const ADDR_TILEINFO * pTileInfo) const140 UINT_32 SiLib::HwlGetPipes(
141 const ADDR_TILEINFO* pTileInfo ///< [in] Tile info
142 ) const
143 {
144 UINT_32 numPipes;
145
146 if (pTileInfo)
147 {
148 numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
149 }
150 else
151 {
152 ADDR_ASSERT_ALWAYS();
153 numPipes = m_pipes; // Suppose we should still have a global pipes
154 }
155
156 return numPipes;
157 }
158
159 /**
160 ****************************************************************************************************
161 * SiLib::GetPipePerSurf
162 * @brief
163 * get pipe num base on inputing tileinfo->pipeconfig
164 * @return
165 * pipe number
166 ****************************************************************************************************
167 */
GetPipePerSurf(AddrPipeCfg pipeConfig) const168 UINT_32 SiLib::GetPipePerSurf(
169 AddrPipeCfg pipeConfig ///< [in] pipe config
170 ) const
171 {
172 UINT_32 numPipes = 0;
173
174 switch (pipeConfig)
175 {
176 case ADDR_PIPECFG_P2:
177 numPipes = 2;
178 break;
179 case ADDR_PIPECFG_P4_8x16:
180 case ADDR_PIPECFG_P4_16x16:
181 case ADDR_PIPECFG_P4_16x32:
182 case ADDR_PIPECFG_P4_32x32:
183 numPipes = 4;
184 break;
185 case ADDR_PIPECFG_P8_16x16_8x16:
186 case ADDR_PIPECFG_P8_16x32_8x16:
187 case ADDR_PIPECFG_P8_32x32_8x16:
188 case ADDR_PIPECFG_P8_16x32_16x16:
189 case ADDR_PIPECFG_P8_32x32_16x16:
190 case ADDR_PIPECFG_P8_32x32_16x32:
191 case ADDR_PIPECFG_P8_32x64_32x32:
192 numPipes = 8;
193 break;
194 case ADDR_PIPECFG_P16_32x32_8x16:
195 case ADDR_PIPECFG_P16_32x32_16x16:
196 numPipes = 16;
197 break;
198 default:
199 ADDR_ASSERT(!"Invalid pipe config");
200 numPipes = m_pipes;
201 }
202 return numPipes;
203 }
204
205 /**
206 ****************************************************************************************************
207 * SiLib::ComputeBankEquation
208 *
209 * @brief
210 * Compute bank equation
211 *
212 * @return
213 * If equation can be computed
214 ****************************************************************************************************
215 */
ComputeBankEquation(UINT_32 log2BytesPP,UINT_32 threshX,UINT_32 threshY,ADDR_TILEINFO * pTileInfo,ADDR_EQUATION * pEquation) const216 ADDR_E_RETURNCODE SiLib::ComputeBankEquation(
217 UINT_32 log2BytesPP, ///< [in] log2 of bytes per pixel
218 UINT_32 threshX, ///< [in] threshold for x channel
219 UINT_32 threshY, ///< [in] threshold for y channel
220 ADDR_TILEINFO* pTileInfo, ///< [in] tile info
221 ADDR_EQUATION* pEquation ///< [out] bank equation
222 ) const
223 {
224 ADDR_E_RETURNCODE retCode = ADDR_OK;
225
226 UINT_32 pipes = HwlGetPipes(pTileInfo);
227 UINT_32 bankXStart = 3 + Log2(pipes) + Log2(pTileInfo->bankWidth);
228 UINT_32 bankYStart = 3 + Log2(pTileInfo->bankHeight);
229
230 ADDR_CHANNEL_SETTING x3 = InitChannel(1, 0, log2BytesPP + bankXStart);
231 ADDR_CHANNEL_SETTING x4 = InitChannel(1, 0, log2BytesPP + bankXStart + 1);
232 ADDR_CHANNEL_SETTING x5 = InitChannel(1, 0, log2BytesPP + bankXStart + 2);
233 ADDR_CHANNEL_SETTING x6 = InitChannel(1, 0, log2BytesPP + bankXStart + 3);
234 ADDR_CHANNEL_SETTING y3 = InitChannel(1, 1, bankYStart);
235 ADDR_CHANNEL_SETTING y4 = InitChannel(1, 1, bankYStart + 1);
236 ADDR_CHANNEL_SETTING y5 = InitChannel(1, 1, bankYStart + 2);
237 ADDR_CHANNEL_SETTING y6 = InitChannel(1, 1, bankYStart + 3);
238
239 x3.value = (threshX > bankXStart) ? x3.value : 0;
240 x4.value = (threshX > bankXStart + 1) ? x4.value : 0;
241 x5.value = (threshX > bankXStart + 2) ? x5.value : 0;
242 x6.value = (threshX > bankXStart + 3) ? x6.value : 0;
243 y3.value = (threshY > bankYStart) ? y3.value : 0;
244 y4.value = (threshY > bankYStart + 1) ? y4.value : 0;
245 y5.value = (threshY > bankYStart + 2) ? y5.value : 0;
246 y6.value = (threshY > bankYStart + 3) ? y6.value : 0;
247
248 switch (pTileInfo->banks)
249 {
250 case 16:
251 if (pTileInfo->macroAspectRatio == 1)
252 {
253 pEquation->addr[0] = y6;
254 pEquation->xor1[0] = x3;
255 pEquation->addr[1] = y5;
256 pEquation->xor1[1] = y6;
257 pEquation->xor2[1] = x4;
258 pEquation->addr[2] = y4;
259 pEquation->xor1[2] = x5;
260 pEquation->addr[3] = y3;
261 pEquation->xor1[3] = x6;
262 }
263 else if (pTileInfo->macroAspectRatio == 2)
264 {
265 pEquation->addr[0] = x3;
266 pEquation->xor1[0] = y6;
267 pEquation->addr[1] = y5;
268 pEquation->xor1[1] = y6;
269 pEquation->xor2[1] = x4;
270 pEquation->addr[2] = y4;
271 pEquation->xor1[2] = x5;
272 pEquation->addr[3] = y3;
273 pEquation->xor1[3] = x6;
274 }
275 else if (pTileInfo->macroAspectRatio == 4)
276 {
277 pEquation->addr[0] = x3;
278 pEquation->xor1[0] = y6;
279 pEquation->addr[1] = x4;
280 pEquation->xor1[1] = y5;
281 pEquation->xor2[1] = y6;
282 pEquation->addr[2] = y4;
283 pEquation->xor1[2] = x5;
284 pEquation->addr[3] = y3;
285 pEquation->xor1[3] = x6;
286 }
287 else if (pTileInfo->macroAspectRatio == 8)
288 {
289 pEquation->addr[0] = x3;
290 pEquation->xor1[0] = y6;
291 pEquation->addr[1] = x4;
292 pEquation->xor1[1] = y5;
293 pEquation->xor2[1] = y6;
294 pEquation->addr[2] = x5;
295 pEquation->xor1[2] = y4;
296 pEquation->addr[3] = y3;
297 pEquation->xor1[3] = x6;
298 }
299 else
300 {
301 ADDR_ASSERT_ALWAYS();
302 }
303 pEquation->numBits = 4;
304 break;
305 case 8:
306 if (pTileInfo->macroAspectRatio == 1)
307 {
308 pEquation->addr[0] = y5;
309 pEquation->xor1[0] = x3;
310 pEquation->addr[1] = y4;
311 pEquation->xor1[1] = y5;
312 pEquation->xor2[1] = x4;
313 pEquation->addr[2] = y3;
314 pEquation->xor1[2] = x5;
315 }
316 else if (pTileInfo->macroAspectRatio == 2)
317 {
318 pEquation->addr[0] = x3;
319 pEquation->xor1[0] = y5;
320 pEquation->addr[1] = y4;
321 pEquation->xor1[1] = y5;
322 pEquation->xor2[1] = x4;
323 pEquation->addr[2] = y3;
324 pEquation->xor1[2] = x5;
325 }
326 else if (pTileInfo->macroAspectRatio == 4)
327 {
328 pEquation->addr[0] = x3;
329 pEquation->xor1[0] = y5;
330 pEquation->addr[1] = x4;
331 pEquation->xor1[1] = y4;
332 pEquation->xor2[1] = y5;
333 pEquation->addr[2] = y3;
334 pEquation->xor1[2] = x5;
335 }
336 else
337 {
338 ADDR_ASSERT_ALWAYS();
339 }
340 pEquation->numBits = 3;
341 break;
342 case 4:
343 if (pTileInfo->macroAspectRatio == 1)
344 {
345 pEquation->addr[0] = y4;
346 pEquation->xor1[0] = x3;
347 pEquation->addr[1] = y3;
348 pEquation->xor1[1] = x4;
349 }
350 else if (pTileInfo->macroAspectRatio == 2)
351 {
352 pEquation->addr[0] = x3;
353 pEquation->xor1[0] = y4;
354 pEquation->addr[1] = y3;
355 pEquation->xor1[1] = x4;
356 }
357 else
358 {
359 pEquation->addr[0] = x3;
360 pEquation->xor1[0] = y4;
361 pEquation->addr[1] = x4;
362 pEquation->xor1[1] = y3;
363 }
364 pEquation->numBits = 2;
365 break;
366 case 2:
367 if (pTileInfo->macroAspectRatio == 1)
368 {
369 pEquation->addr[0] = y3;
370 pEquation->xor1[0] = x3;
371 }
372 else
373 {
374 pEquation->addr[0] = x3;
375 pEquation->xor1[0] = y3;
376 }
377 pEquation->numBits = 1;
378 break;
379 default:
380 pEquation->numBits = 0;
381 retCode = ADDR_NOTSUPPORTED;
382 ADDR_ASSERT_ALWAYS();
383 break;
384 }
385
386 for (UINT_32 i = 0; i < pEquation->numBits; i++)
387 {
388 if (pEquation->addr[i].value == 0)
389 {
390 if (pEquation->xor1[i].value == 0)
391 {
392 // 00X -> X00
393 pEquation->addr[i].value = pEquation->xor2[i].value;
394 pEquation->xor2[i].value = 0;
395 }
396 else
397 {
398 pEquation->addr[i].value = pEquation->xor1[i].value;
399
400 if (pEquation->xor2[i].value != 0)
401 {
402 // 0XY -> XY0
403 pEquation->xor1[i].value = pEquation->xor2[i].value;
404 pEquation->xor2[i].value = 0;
405 }
406 else
407 {
408 // 0X0 -> X00
409 pEquation->xor1[i].value = 0;
410 }
411 }
412 }
413 else if (pEquation->xor1[i].value == 0)
414 {
415 if (pEquation->xor2[i].value != 0)
416 {
417 // X0Y -> XY0
418 pEquation->xor1[i].value = pEquation->xor2[i].value;
419 pEquation->xor2[i].value = 0;
420 }
421 }
422 }
423
424 if ((pTileInfo->bankWidth == 1) &&
425 ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
426 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)))
427 {
428 retCode = ADDR_NOTSUPPORTED;
429 }
430
431 return retCode;
432 }
433
434 /**
435 ****************************************************************************************************
436 * SiLib::ComputePipeEquation
437 *
438 * @brief
439 * Compute pipe equation
440 *
441 * @return
442 * If equation can be computed
443 ****************************************************************************************************
444 */
ComputePipeEquation(UINT_32 log2BytesPP,UINT_32 threshX,UINT_32 threshY,ADDR_TILEINFO * pTileInfo,ADDR_EQUATION * pEquation) const445 ADDR_E_RETURNCODE SiLib::ComputePipeEquation(
446 UINT_32 log2BytesPP, ///< [in] Log2 of bytes per pixel
447 UINT_32 threshX, ///< [in] Threshold for X channel
448 UINT_32 threshY, ///< [in] Threshold for Y channel
449 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
450 ADDR_EQUATION* pEquation ///< [out] Pipe configure
451 ) const
452 {
453 ADDR_E_RETURNCODE retCode = ADDR_OK;
454
455 ADDR_CHANNEL_SETTING* pAddr = pEquation->addr;
456 ADDR_CHANNEL_SETTING* pXor1 = pEquation->xor1;
457 ADDR_CHANNEL_SETTING* pXor2 = pEquation->xor2;
458
459 ADDR_CHANNEL_SETTING x3 = InitChannel(1, 0, 3 + log2BytesPP);
460 ADDR_CHANNEL_SETTING x4 = InitChannel(1, 0, 4 + log2BytesPP);
461 ADDR_CHANNEL_SETTING x5 = InitChannel(1, 0, 5 + log2BytesPP);
462 ADDR_CHANNEL_SETTING x6 = InitChannel(1, 0, 6 + log2BytesPP);
463 ADDR_CHANNEL_SETTING y3 = InitChannel(1, 1, 3);
464 ADDR_CHANNEL_SETTING y4 = InitChannel(1, 1, 4);
465 ADDR_CHANNEL_SETTING y5 = InitChannel(1, 1, 5);
466 ADDR_CHANNEL_SETTING y6 = InitChannel(1, 1, 6);
467
468 x3.value = (threshX > 3) ? x3.value : 0;
469 x4.value = (threshX > 4) ? x4.value : 0;
470 x5.value = (threshX > 5) ? x5.value : 0;
471 x6.value = (threshX > 6) ? x6.value : 0;
472 y3.value = (threshY > 3) ? y3.value : 0;
473 y4.value = (threshY > 4) ? y4.value : 0;
474 y5.value = (threshY > 5) ? y5.value : 0;
475 y6.value = (threshY > 6) ? y6.value : 0;
476
477 switch (pTileInfo->pipeConfig)
478 {
479 case ADDR_PIPECFG_P2:
480 pAddr[0] = x3;
481 pXor1[0] = y3;
482 pEquation->numBits = 1;
483 break;
484 case ADDR_PIPECFG_P4_8x16:
485 pAddr[0] = x4;
486 pXor1[0] = y3;
487 pAddr[1] = x3;
488 pXor1[1] = y4;
489 pEquation->numBits = 2;
490 break;
491 case ADDR_PIPECFG_P4_16x16:
492 pAddr[0] = x3;
493 pXor1[0] = y3;
494 pXor2[0] = x4;
495 pAddr[1] = x4;
496 pXor1[1] = y4;
497 pEquation->numBits = 2;
498 break;
499 case ADDR_PIPECFG_P4_16x32:
500 pAddr[0] = x3;
501 pXor1[0] = y3;
502 pXor2[0] = x4;
503 pAddr[1] = x4;
504 pXor1[1] = y5;
505 pEquation->numBits = 2;
506 break;
507 case ADDR_PIPECFG_P4_32x32:
508 pAddr[0] = x3;
509 pXor1[0] = y3;
510 pXor2[0] = x5;
511 pAddr[1] = x5;
512 pXor1[1] = y5;
513 pEquation->numBits = 2;
514 break;
515 case ADDR_PIPECFG_P8_16x16_8x16:
516 pAddr[0] = x4;
517 pXor1[0] = y3;
518 pXor2[0] = x5;
519 pAddr[1] = x3;
520 pXor1[1] = y5;
521 pEquation->numBits = 3;
522 break;
523 case ADDR_PIPECFG_P8_16x32_8x16:
524 pAddr[0] = x4;
525 pXor1[0] = y3;
526 pXor2[0] = x5;
527 pAddr[1] = x3;
528 pXor1[1] = y4;
529 pAddr[2] = x4;
530 pXor1[2] = y5;
531 pEquation->numBits = 3;
532 break;
533 case ADDR_PIPECFG_P8_16x32_16x16:
534 pAddr[0] = x3;
535 pXor1[0] = y3;
536 pXor2[0] = x4;
537 pAddr[1] = x5;
538 pXor1[1] = y4;
539 pAddr[2] = x4;
540 pXor1[2] = y5;
541 pEquation->numBits = 3;
542 break;
543 case ADDR_PIPECFG_P8_32x32_8x16:
544 pAddr[0] = x4;
545 pXor1[0] = y3;
546 pXor2[0] = x5;
547 pAddr[1] = x3;
548 pXor1[1] = y4;
549 pAddr[2] = x5;
550 pXor1[2] = y5;
551 pEquation->numBits = 3;
552 break;
553 case ADDR_PIPECFG_P8_32x32_16x16:
554 pAddr[0] = x3;
555 pXor1[0] = y3;
556 pXor2[0] = x4;
557 pAddr[1] = x4;
558 pXor1[1] = y4;
559 pAddr[2] = x5;
560 pXor1[2] = y5;
561 pEquation->numBits = 3;
562 break;
563 case ADDR_PIPECFG_P8_32x32_16x32:
564 pAddr[0] = x3;
565 pXor1[0] = y3;
566 pXor2[0] = x4;
567 pAddr[1] = x4;
568 pXor1[1] = y6;
569 pAddr[2] = x5;
570 pXor1[2] = y5;
571 pEquation->numBits = 3;
572 break;
573 case ADDR_PIPECFG_P8_32x64_32x32:
574 pAddr[0] = x3;
575 pXor1[0] = y3;
576 pXor2[0] = x5;
577 pAddr[1] = x6;
578 pXor1[1] = y5;
579 pAddr[2] = x5;
580 pXor1[2] = y6;
581 pEquation->numBits = 3;
582 break;
583 case ADDR_PIPECFG_P16_32x32_8x16:
584 pAddr[0] = x4;
585 pXor1[0] = y3;
586 pAddr[1] = x3;
587 pXor1[1] = y4;
588 pAddr[2] = x5;
589 pXor1[2] = y6;
590 pAddr[3] = x6;
591 pXor1[3] = y5;
592 pEquation->numBits = 4;
593 break;
594 case ADDR_PIPECFG_P16_32x32_16x16:
595 pAddr[0] = x3;
596 pXor1[0] = y3;
597 pXor2[0] = x4;
598 pAddr[1] = x4;
599 pXor1[1] = y4;
600 pAddr[2] = x5;
601 pXor1[2] = y6;
602 pAddr[3] = x6;
603 pXor1[3] = y5;
604 pEquation->numBits = 4;
605 break;
606 default:
607 ADDR_UNHANDLED_CASE();
608 pEquation->numBits = 0;
609 retCode = ADDR_NOTSUPPORTED;
610 break;
611 }
612
613 if (m_settings.isVegaM && (pEquation->numBits == 4))
614 {
615 ADDR_CHANNEL_SETTING addeMsb = pAddr[0];
616 ADDR_CHANNEL_SETTING xor1Msb = pXor1[0];
617 ADDR_CHANNEL_SETTING xor2Msb = pXor2[0];
618
619 pAddr[0] = pAddr[1];
620 pXor1[0] = pXor1[1];
621 pXor2[0] = pXor2[1];
622
623 pAddr[1] = pAddr[2];
624 pXor1[1] = pXor1[2];
625 pXor2[1] = pXor2[2];
626
627 pAddr[2] = pAddr[3];
628 pXor1[2] = pXor1[3];
629 pXor2[2] = pXor2[3];
630
631 pAddr[3] = addeMsb;
632 pXor1[3] = xor1Msb;
633 pXor2[3] = xor2Msb;
634 }
635
636 for (UINT_32 i = 0; i < pEquation->numBits; i++)
637 {
638 if (pAddr[i].value == 0)
639 {
640 if (pXor1[i].value == 0)
641 {
642 pAddr[i].value = pXor2[i].value;
643 }
644 else
645 {
646 pAddr[i].value = pXor1[i].value;
647 pXor1[i].value = 0;
648 }
649 }
650 }
651
652 return retCode;
653 }
654
655 /**
656 ****************************************************************************************************
657 * SiLib::ComputePipeFromCoord
658 *
659 * @brief
660 * Compute pipe number from coordinates
661 * @return
662 * Pipe number
663 ****************************************************************************************************
664 */
ComputePipeFromCoord(UINT_32 x,UINT_32 y,UINT_32 slice,AddrTileMode tileMode,UINT_32 pipeSwizzle,BOOL_32 ignoreSE,ADDR_TILEINFO * pTileInfo) const665 UINT_32 SiLib::ComputePipeFromCoord(
666 UINT_32 x, ///< [in] x coordinate
667 UINT_32 y, ///< [in] y coordinate
668 UINT_32 slice, ///< [in] slice index
669 AddrTileMode tileMode, ///< [in] tile mode
670 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
671 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines are ignored
672 ADDR_TILEINFO* pTileInfo ///< [in] Tile info
673 ) const
674 {
675 UINT_32 pipe;
676 UINT_32 pipeBit0 = 0;
677 UINT_32 pipeBit1 = 0;
678 UINT_32 pipeBit2 = 0;
679 UINT_32 pipeBit3 = 0;
680 UINT_32 sliceRotation;
681 UINT_32 numPipes = 0;
682
683 UINT_32 tx = x / MicroTileWidth;
684 UINT_32 ty = y / MicroTileHeight;
685 UINT_32 x3 = _BIT(tx,0);
686 UINT_32 x4 = _BIT(tx,1);
687 UINT_32 x5 = _BIT(tx,2);
688 UINT_32 x6 = _BIT(tx,3);
689 UINT_32 y3 = _BIT(ty,0);
690 UINT_32 y4 = _BIT(ty,1);
691 UINT_32 y5 = _BIT(ty,2);
692 UINT_32 y6 = _BIT(ty,3);
693
694 switch (pTileInfo->pipeConfig)
695 {
696 case ADDR_PIPECFG_P2:
697 pipeBit0 = x3 ^ y3;
698 numPipes = 2;
699 break;
700 case ADDR_PIPECFG_P4_8x16:
701 pipeBit0 = x4 ^ y3;
702 pipeBit1 = x3 ^ y4;
703 numPipes = 4;
704 break;
705 case ADDR_PIPECFG_P4_16x16:
706 pipeBit0 = x3 ^ y3 ^ x4;
707 pipeBit1 = x4 ^ y4;
708 numPipes = 4;
709 break;
710 case ADDR_PIPECFG_P4_16x32:
711 pipeBit0 = x3 ^ y3 ^ x4;
712 pipeBit1 = x4 ^ y5;
713 numPipes = 4;
714 break;
715 case ADDR_PIPECFG_P4_32x32:
716 pipeBit0 = x3 ^ y3 ^ x5;
717 pipeBit1 = x5 ^ y5;
718 numPipes = 4;
719 break;
720 case ADDR_PIPECFG_P8_16x16_8x16:
721 pipeBit0 = x4 ^ y3 ^ x5;
722 pipeBit1 = x3 ^ y5;
723 numPipes = 8;
724 break;
725 case ADDR_PIPECFG_P8_16x32_8x16:
726 pipeBit0 = x4 ^ y3 ^ x5;
727 pipeBit1 = x3 ^ y4;
728 pipeBit2 = x4 ^ y5;
729 numPipes = 8;
730 break;
731 case ADDR_PIPECFG_P8_16x32_16x16:
732 pipeBit0 = x3 ^ y3 ^ x4;
733 pipeBit1 = x5 ^ y4;
734 pipeBit2 = x4 ^ y5;
735 numPipes = 8;
736 break;
737 case ADDR_PIPECFG_P8_32x32_8x16:
738 pipeBit0 = x4 ^ y3 ^ x5;
739 pipeBit1 = x3 ^ y4;
740 pipeBit2 = x5 ^ y5;
741 numPipes = 8;
742 break;
743 case ADDR_PIPECFG_P8_32x32_16x16:
744 pipeBit0 = x3 ^ y3 ^ x4;
745 pipeBit1 = x4 ^ y4;
746 pipeBit2 = x5 ^ y5;
747 numPipes = 8;
748 break;
749 case ADDR_PIPECFG_P8_32x32_16x32:
750 pipeBit0 = x3 ^ y3 ^ x4;
751 pipeBit1 = x4 ^ y6;
752 pipeBit2 = x5 ^ y5;
753 numPipes = 8;
754 break;
755 case ADDR_PIPECFG_P8_32x64_32x32:
756 pipeBit0 = x3 ^ y3 ^ x5;
757 pipeBit1 = x6 ^ y5;
758 pipeBit2 = x5 ^ y6;
759 numPipes = 8;
760 break;
761 case ADDR_PIPECFG_P16_32x32_8x16:
762 pipeBit0 = x4 ^ y3;
763 pipeBit1 = x3 ^ y4;
764 pipeBit2 = x5 ^ y6;
765 pipeBit3 = x6 ^ y5;
766 numPipes = 16;
767 break;
768 case ADDR_PIPECFG_P16_32x32_16x16:
769 pipeBit0 = x3 ^ y3 ^ x4;
770 pipeBit1 = x4 ^ y4;
771 pipeBit2 = x5 ^ y6;
772 pipeBit3 = x6 ^ y5;
773 numPipes = 16;
774 break;
775 default:
776 ADDR_UNHANDLED_CASE();
777 break;
778 }
779
780 if (m_settings.isVegaM && (numPipes == 16))
781 {
782 UINT_32 pipeMsb = pipeBit0;
783 pipeBit0 = pipeBit1;
784 pipeBit1 = pipeBit2;
785 pipeBit2 = pipeBit3;
786 pipeBit3 = pipeMsb;
787 }
788
789 pipe = pipeBit0 | (pipeBit1 << 1) | (pipeBit2 << 2) | (pipeBit3 << 3);
790
791 UINT_32 microTileThickness = Thickness(tileMode);
792
793 //
794 // Apply pipe rotation for the slice.
795 //
796 switch (tileMode)
797 {
798 case ADDR_TM_3D_TILED_THIN1: //fall through thin
799 case ADDR_TM_3D_TILED_THICK: //fall through thick
800 case ADDR_TM_3D_TILED_XTHICK:
801 sliceRotation =
802 Max(1, static_cast<INT_32>(numPipes / 2) - 1) * (slice / microTileThickness);
803 break;
804 default:
805 sliceRotation = 0;
806 break;
807 }
808 pipeSwizzle += sliceRotation;
809 pipeSwizzle &= (numPipes - 1);
810
811 pipe = pipe ^ pipeSwizzle;
812
813 return pipe;
814 }
815
816 /**
817 ****************************************************************************************************
818 * SiLib::ComputeTileCoordFromPipeAndElemIdx
819 *
820 * @brief
821 * Compute (x,y) of a tile within a macro tile from address
822 * @return
823 * Pipe number
824 ****************************************************************************************************
825 */
ComputeTileCoordFromPipeAndElemIdx(UINT_32 elemIdx,UINT_32 pipe,AddrPipeCfg pipeCfg,UINT_32 pitchInMacroTile,UINT_32 x,UINT_32 y,UINT_32 * pX,UINT_32 * pY) const826 VOID SiLib::ComputeTileCoordFromPipeAndElemIdx(
827 UINT_32 elemIdx, ///< [in] per pipe element index within a macro tile
828 UINT_32 pipe, ///< [in] pipe index
829 AddrPipeCfg pipeCfg, ///< [in] pipe config
830 UINT_32 pitchInMacroTile, ///< [in] surface pitch in macro tile
831 UINT_32 x, ///< [in] x coordinate of the (0,0) tile in a macro tile
832 UINT_32 y, ///< [in] y coordinate of the (0,0) tile in a macro tile
833 UINT_32* pX, ///< [out] x coordinate
834 UINT_32* pY ///< [out] y coordinate
835 ) const
836 {
837 UINT_32 pipebit0 = _BIT(pipe,0);
838 UINT_32 pipebit1 = _BIT(pipe,1);
839 UINT_32 pipebit2 = _BIT(pipe,2);
840 UINT_32 pipebit3 = _BIT(pipe,3);
841 UINT_32 elemIdx0 = _BIT(elemIdx,0);
842 UINT_32 elemIdx1 = _BIT(elemIdx,1);
843 UINT_32 elemIdx2 = _BIT(elemIdx,2);
844 UINT_32 x3 = 0;
845 UINT_32 x4 = 0;
846 UINT_32 x5 = 0;
847 UINT_32 x6 = 0;
848 UINT_32 y3 = 0;
849 UINT_32 y4 = 0;
850 UINT_32 y5 = 0;
851 UINT_32 y6 = 0;
852
853 switch(pipeCfg)
854 {
855 case ADDR_PIPECFG_P2:
856 x4 = elemIdx2;
857 y4 = elemIdx1 ^ x4;
858 y3 = elemIdx0 ^ x4;
859 x3 = pipebit0 ^ y3;
860 *pY = Bits2Number(2, y4, y3);
861 *pX = Bits2Number(2, x4, x3);
862 break;
863 case ADDR_PIPECFG_P4_8x16:
864 x4 = elemIdx1;
865 y4 = elemIdx0 ^ x4;
866 x3 = pipebit1 ^ y4;
867 y3 = pipebit0 ^ x4;
868 *pY = Bits2Number(2, y4, y3);
869 *pX = Bits2Number(2, x4, x3);
870 break;
871 case ADDR_PIPECFG_P4_16x16:
872 x4 = elemIdx1;
873 y3 = elemIdx0 ^ x4;
874 y4 = pipebit1 ^ x4;
875 x3 = pipebit0 ^ y3 ^ x4;
876 *pY = Bits2Number(2, y4, y3);
877 *pX = Bits2Number(2, x4, x3);
878 break;
879 case ADDR_PIPECFG_P4_16x32:
880 x3 = elemIdx0 ^ pipebit0;
881 y5 = _BIT(y,5);
882 x4 = pipebit1 ^ y5;
883 y3 = pipebit0 ^ x3 ^ x4;
884 y4 = elemIdx1 ^ x4;
885 *pY = Bits2Number(2, y4, y3);
886 *pX = Bits2Number(2, x4, x3);
887 break;
888 case ADDR_PIPECFG_P4_32x32:
889 x4 = elemIdx2;
890 y3 = elemIdx0 ^ x4;
891 y4 = elemIdx1 ^ x4;
892 if((pitchInMacroTile % 2) == 0)
893 { //even
894 y5 = _BIT(y,5);
895 x5 = pipebit1 ^ y5;
896 x3 = pipebit0 ^ y3 ^ x5;
897 *pY = Bits2Number(2, y4, y3);
898 *pX = Bits2Number(3, x5, x4, x3);
899 }
900 else
901 { //odd
902 x5 = _BIT(x,5);
903 x3 = pipebit0 ^ y3 ^ x5;
904 *pY = Bits2Number(2, y4, y3);
905 *pX = Bits2Number(2, x4, x3);
906 }
907 break;
908 case ADDR_PIPECFG_P8_16x16_8x16:
909 x4 = elemIdx0;
910 y5 = _BIT(y,5);
911 x5 = _BIT(x,5);
912 x3 = pipebit1 ^ y5;
913 y4 = pipebit2 ^ x4;
914 y3 = pipebit0 ^ x5 ^ x4;
915 *pY = Bits2Number(2, y4, y3);
916 *pX = Bits2Number(2, x4, x3);
917 break;
918 case ADDR_PIPECFG_P8_16x32_8x16:
919 x3 = elemIdx0;
920 y4 = pipebit1 ^ x3;
921 y5 = _BIT(y,5);
922 x5 = _BIT(x,5);
923 x4 = pipebit2 ^ y5;
924 y3 = pipebit0 ^ x4 ^ x5;
925 *pY = Bits2Number(2, y4, y3);
926 *pX = Bits2Number(2, x4, x3);
927 break;
928 case ADDR_PIPECFG_P8_32x32_8x16:
929 x4 = elemIdx1;
930 y4 = elemIdx0 ^ x4;
931 x3 = pipebit1 ^ y4;
932 if((pitchInMacroTile % 2) == 0)
933 { //even
934 y5 = _BIT(y,5);
935 x5 = _BIT(x,5);
936 x5 = pipebit2 ^ y5;
937 y3 = pipebit0 ^ x4 ^ x5;
938 *pY = Bits2Number(2, y4, y3);
939 *pX = Bits2Number(3, x5, x4, x3);
940 }
941 else
942 { //odd
943 x5 = _BIT(x,5);
944 y3 = pipebit0 ^ x4 ^ x5;
945 *pY = Bits2Number(2, y4, y3);
946 *pX = Bits2Number(2, x4, x3);
947 }
948 break;
949 case ADDR_PIPECFG_P8_16x32_16x16:
950 x3 = elemIdx0;
951 x5 = _BIT(x,5);
952 y5 = _BIT(y,5);
953 x4 = pipebit2 ^ y5;
954 y4 = pipebit1 ^ x5;
955 y3 = pipebit0 ^ x3 ^ x4;
956 *pY = Bits2Number(2, y4, y3);
957 *pX = Bits2Number(2, x4, x3);
958 break;
959 case ADDR_PIPECFG_P8_32x32_16x16:
960 x4 = elemIdx1;
961 y3 = elemIdx0 ^ x4;
962 x3 = y3^x4^pipebit0;
963 y4 = pipebit1 ^ x4;
964 if((pitchInMacroTile % 2) == 0)
965 { //even
966 y5 = _BIT(y,5);
967 x5 = pipebit2 ^ y5;
968 *pY = Bits2Number(2, y4, y3);
969 *pX = Bits2Number(3, x5, x4, x3);
970 }
971 else
972 { //odd
973 *pY = Bits2Number(2, y4, y3);
974 *pX = Bits2Number(2, x4, x3);
975 }
976 break;
977 case ADDR_PIPECFG_P8_32x32_16x32:
978 if((pitchInMacroTile % 2) == 0)
979 { //even
980 y5 = _BIT(y,5);
981 y6 = _BIT(y,6);
982 x4 = pipebit1 ^ y6;
983 y3 = elemIdx0 ^ x4;
984 y4 = elemIdx1 ^ x4;
985 x3 = pipebit0 ^ y3 ^ x4;
986 x5 = pipebit2 ^ y5;
987 *pY = Bits2Number(2, y4, y3);
988 *pX = Bits2Number(3, x5, x4, x3);
989 }
990 else
991 { //odd
992 y6 = _BIT(y,6);
993 x4 = pipebit1 ^ y6;
994 y3 = elemIdx0 ^ x4;
995 y4 = elemIdx1 ^ x4;
996 x3 = pipebit0 ^ y3 ^ x4;
997 *pY = Bits2Number(2, y4, y3);
998 *pX = Bits2Number(2, x4, x3);
999 }
1000 break;
1001 case ADDR_PIPECFG_P8_32x64_32x32:
1002 x4 = elemIdx2;
1003 y3 = elemIdx0 ^ x4;
1004 y4 = elemIdx1 ^ x4;
1005 if((pitchInMacroTile % 4) == 0)
1006 { //multiple of 4
1007 y5 = _BIT(y,5);
1008 y6 = _BIT(y,6);
1009 x5 = pipebit2 ^ y6;
1010 x6 = pipebit1 ^ y5;
1011 x3 = pipebit0 ^ y3 ^ x5;
1012 *pY = Bits2Number(2, y4, y3);
1013 *pX = Bits2Number(4, x6, x5, x4, x3);
1014 }
1015 else
1016 {
1017 y6 = _BIT(y,6);
1018 x5 = pipebit2 ^ y6;
1019 x3 = pipebit0 ^ y3 ^ x5;
1020 *pY = Bits2Number(2, y4, y3);
1021 *pX = Bits2Number(3, x5, x4, x3);
1022 }
1023 break;
1024 case ADDR_PIPECFG_P16_32x32_8x16:
1025 x4 = elemIdx1;
1026 y4 = elemIdx0 ^ x4;
1027 y3 = pipebit0 ^ x4;
1028 x3 = pipebit1 ^ y4;
1029 if((pitchInMacroTile % 4) == 0)
1030 { //multiple of 4
1031 y5 = _BIT(y,5);
1032 y6 = _BIT(y,6);
1033 x5 = pipebit2 ^ y6;
1034 x6 = pipebit3 ^ y5;
1035 *pY = Bits2Number(2, y4, y3);
1036 *pX = Bits2Number(4, x6, x5,x4, x3);
1037 }
1038 else
1039 {
1040 y6 = _BIT(y,6);
1041 x5 = pipebit2 ^ y6;
1042 *pY = Bits2Number(2, y4, y3);
1043 *pX = Bits2Number(3, x5, x4, x3);
1044 }
1045 break;
1046 case ADDR_PIPECFG_P16_32x32_16x16:
1047 x4 = elemIdx1;
1048 y3 = elemIdx0 ^ x4;
1049 y4 = pipebit1 ^ x4;
1050 x3 = pipebit0 ^ y3 ^ x4;
1051 if((pitchInMacroTile % 4) == 0)
1052 { //multiple of 4
1053 y5 = _BIT(y,5);
1054 y6 = _BIT(y,6);
1055 x5 = pipebit2 ^ y6;
1056 x6 = pipebit3 ^ y5;
1057 *pY = Bits2Number(2, y4, y3);
1058 *pX = Bits2Number(4, x6, x5, x4, x3);
1059 }
1060 else
1061 {
1062 y6 = _BIT(y,6);
1063 x5 = pipebit2 ^ y6;
1064 *pY = Bits2Number(2, y4, y3);
1065 *pX = Bits2Number(3, x5, x4, x3);
1066 }
1067 break;
1068 default:
1069 ADDR_UNHANDLED_CASE();
1070 }
1071 }
1072
1073 /**
1074 ****************************************************************************************************
1075 * SiLib::TileCoordToMaskElementIndex
1076 *
1077 * @brief
1078 * Compute element index from coordinates in tiles
1079 * @return
1080 * Element index
1081 ****************************************************************************************************
1082 */
TileCoordToMaskElementIndex(UINT_32 tx,UINT_32 ty,AddrPipeCfg pipeConfig,UINT_32 * macroShift,UINT_32 * elemIdxBits) const1083 UINT_32 SiLib::TileCoordToMaskElementIndex(
1084 UINT_32 tx, ///< [in] x coord, in Tiles
1085 UINT_32 ty, ///< [in] y coord, in Tiles
1086 AddrPipeCfg pipeConfig, ///< [in] pipe config
1087 UINT_32* macroShift, ///< [out] macro shift
1088 UINT_32* elemIdxBits ///< [out] tile offset bits
1089 ) const
1090 {
1091 UINT_32 elemIdx = 0;
1092 UINT_32 elemIdx0, elemIdx1, elemIdx2;
1093 UINT_32 tx0, tx1;
1094 UINT_32 ty0, ty1;
1095
1096 tx0 = _BIT(tx,0);
1097 tx1 = _BIT(tx,1);
1098 ty0 = _BIT(ty,0);
1099 ty1 = _BIT(ty,1);
1100
1101 switch(pipeConfig)
1102 {
1103 case ADDR_PIPECFG_P2:
1104 *macroShift = 3;
1105 *elemIdxBits =3;
1106 elemIdx2 = tx1;
1107 elemIdx1 = tx1 ^ ty1;
1108 elemIdx0 = tx1 ^ ty0;
1109 elemIdx = Bits2Number(3,elemIdx2,elemIdx1,elemIdx0);
1110 break;
1111 case ADDR_PIPECFG_P4_8x16:
1112 *macroShift = 2;
1113 *elemIdxBits =2;
1114 elemIdx1 = tx1;
1115 elemIdx0 = tx1 ^ ty1;
1116 elemIdx = Bits2Number(2,elemIdx1,elemIdx0);
1117 break;
1118 case ADDR_PIPECFG_P4_16x16:
1119 *macroShift = 2;
1120 *elemIdxBits =2;
1121 elemIdx0 = tx1^ty0;
1122 elemIdx1 = tx1;
1123 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1124 break;
1125 case ADDR_PIPECFG_P4_16x32:
1126 *macroShift = 2;
1127 *elemIdxBits =2;
1128 elemIdx0 = tx1^ty0;
1129 elemIdx1 = tx1^ty1;
1130 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1131 break;
1132 case ADDR_PIPECFG_P4_32x32:
1133 *macroShift = 2;
1134 *elemIdxBits =3;
1135 elemIdx0 = tx1^ty0;
1136 elemIdx1 = tx1^ty1;
1137 elemIdx2 = tx1;
1138 elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
1139 break;
1140 case ADDR_PIPECFG_P8_16x16_8x16:
1141 *macroShift = 1;
1142 *elemIdxBits =1;
1143 elemIdx0 = tx1;
1144 elemIdx = elemIdx0;
1145 break;
1146 case ADDR_PIPECFG_P8_16x32_8x16:
1147 *macroShift = 1;
1148 *elemIdxBits =1;
1149 elemIdx0 = tx0;
1150 elemIdx = elemIdx0;
1151 break;
1152 case ADDR_PIPECFG_P8_32x32_8x16:
1153 *macroShift = 1;
1154 *elemIdxBits =2;
1155 elemIdx1 = tx1;
1156 elemIdx0 = tx1^ty1;
1157 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1158 break;
1159 case ADDR_PIPECFG_P8_16x32_16x16:
1160 *macroShift = 1;
1161 *elemIdxBits =1;
1162 elemIdx0 = tx0;
1163 elemIdx = elemIdx0;
1164 break;
1165 case ADDR_PIPECFG_P8_32x32_16x16:
1166 *macroShift = 1;
1167 *elemIdxBits =2;
1168 elemIdx0 = tx1^ty0;
1169 elemIdx1 = tx1;
1170 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1171 break;
1172 case ADDR_PIPECFG_P8_32x32_16x32:
1173 *macroShift = 1;
1174 *elemIdxBits =2;
1175 elemIdx0 = tx1^ty0;
1176 elemIdx1 = tx1^ty1;
1177 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1178 break;
1179 case ADDR_PIPECFG_P8_32x64_32x32:
1180 *macroShift = 1;
1181 *elemIdxBits =3;
1182 elemIdx0 = tx1^ty0;
1183 elemIdx1 = tx1^ty1;
1184 elemIdx2 = tx1;
1185 elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0);
1186 break;
1187 case ADDR_PIPECFG_P16_32x32_8x16:
1188 *macroShift = 0;
1189 *elemIdxBits =2;
1190 elemIdx0 = tx1^ty1;
1191 elemIdx1 = tx1;
1192 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1193 break;
1194 case ADDR_PIPECFG_P16_32x32_16x16:
1195 *macroShift = 0;
1196 *elemIdxBits =2;
1197 elemIdx0 = tx1^ty0;
1198 elemIdx1 = tx1;
1199 elemIdx = Bits2Number(2, elemIdx1, elemIdx0);
1200 break;
1201 default:
1202 ADDR_UNHANDLED_CASE();
1203 break;
1204 }
1205
1206 return elemIdx;
1207 }
1208
1209 /**
1210 ****************************************************************************************************
1211 * SiLib::HwlComputeTileDataWidthAndHeightLinear
1212 *
1213 * @brief
1214 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1215 *
1216 * @return
1217 * N/A
1218 *
1219 * @note
1220 * MacroWidth and macroHeight are measured in pixels
1221 ****************************************************************************************************
1222 */
HwlComputeTileDataWidthAndHeightLinear(UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_32 bpp,ADDR_TILEINFO * pTileInfo) const1223 VOID SiLib::HwlComputeTileDataWidthAndHeightLinear(
1224 UINT_32* pMacroWidth, ///< [out] macro tile width
1225 UINT_32* pMacroHeight, ///< [out] macro tile height
1226 UINT_32 bpp, ///< [in] bits per pixel
1227 ADDR_TILEINFO* pTileInfo ///< [in] tile info
1228 ) const
1229 {
1230 ADDR_ASSERT(pTileInfo != NULL);
1231 UINT_32 macroWidth;
1232 UINT_32 macroHeight;
1233
1234 /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles
1235 /// but for P8_32x64_32x32, it must be padded out to 8 tiles
1236 /// Actually there are more pipe configs which need 8-tile padding but SI family
1237 /// has a bug which is fixed in CI family
1238 if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32) ||
1239 (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
1240 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x32_16x16))
1241 {
1242 macroWidth = 8*MicroTileWidth;
1243 macroHeight = 8*MicroTileHeight;
1244 }
1245 else
1246 {
1247 macroWidth = 4*MicroTileWidth;
1248 macroHeight = 4*MicroTileHeight;
1249 }
1250
1251 *pMacroWidth = macroWidth;
1252 *pMacroHeight = macroHeight;
1253 }
1254
1255 /**
1256 ****************************************************************************************************
1257 * SiLib::HwlComputeHtileBytes
1258 *
1259 * @brief
1260 * Compute htile size in bytes
1261 *
1262 * @return
1263 * Htile size in bytes
1264 ****************************************************************************************************
1265 */
HwlComputeHtileBytes(UINT_32 pitch,UINT_32 height,UINT_32 bpp,BOOL_32 isLinear,UINT_32 numSlices,UINT_64 * pSliceBytes,UINT_32 baseAlign) const1266 UINT_64 SiLib::HwlComputeHtileBytes(
1267 UINT_32 pitch, ///< [in] pitch
1268 UINT_32 height, ///< [in] height
1269 UINT_32 bpp, ///< [in] bits per pixel
1270 BOOL_32 isLinear, ///< [in] if it is linear mode
1271 UINT_32 numSlices, ///< [in] number of slices
1272 UINT_64* pSliceBytes, ///< [out] bytes per slice
1273 UINT_32 baseAlign ///< [in] base alignments
1274 ) const
1275 {
1276 return ComputeHtileBytes(pitch, height, bpp, isLinear, numSlices, pSliceBytes, baseAlign);
1277 }
1278
1279 /**
1280 ****************************************************************************************************
1281 * SiLib::HwlComputeXmaskAddrFromCoord
1282 *
1283 * @brief
1284 * Compute address from coordinates for htile/cmask
1285 * @return
1286 * Byte address
1287 ****************************************************************************************************
1288 */
HwlComputeXmaskAddrFromCoord(UINT_32 pitch,UINT_32 height,UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 numSlices,UINT_32 factor,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pBitPosition) const1289 UINT_64 SiLib::HwlComputeXmaskAddrFromCoord(
1290 UINT_32 pitch, ///< [in] pitch
1291 UINT_32 height, ///< [in] height
1292 UINT_32 x, ///< [in] x coord
1293 UINT_32 y, ///< [in] y coord
1294 UINT_32 slice, ///< [in] slice/depth index
1295 UINT_32 numSlices, ///< [in] number of slices
1296 UINT_32 factor, ///< [in] factor that indicates cmask(2) or htile(1)
1297 BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout
1298 BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1299 BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
1300 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
1301 UINT_32* pBitPosition ///< [out] bit position inside a byte
1302 ) const
1303 {
1304 UINT_32 tx = x / MicroTileWidth;
1305 UINT_32 ty = y / MicroTileHeight;
1306 UINT_32 newPitch;
1307 UINT_32 newHeight;
1308 UINT_64 totalBytes;
1309 UINT_32 macroWidth;
1310 UINT_32 macroHeight;
1311 UINT_64 pSliceBytes;
1312 UINT_32 pBaseAlign;
1313 UINT_32 tileNumPerPipe;
1314 UINT_32 elemBits;
1315
1316 if (factor == 2) //CMASK
1317 {
1318 ADDR_CMASK_FLAGS flags = {{0}};
1319
1320 tileNumPerPipe = 256;
1321
1322 ComputeCmaskInfo(flags,
1323 pitch,
1324 height,
1325 numSlices,
1326 isLinear,
1327 pTileInfo,
1328 &newPitch,
1329 &newHeight,
1330 &totalBytes,
1331 ¯oWidth,
1332 ¯oHeight);
1333 elemBits = CmaskElemBits;
1334 }
1335 else //HTile
1336 {
1337 ADDR_HTILE_FLAGS flags = {{0}};
1338
1339 tileNumPerPipe = 512;
1340
1341 ComputeHtileInfo(flags,
1342 pitch,
1343 height,
1344 numSlices,
1345 isLinear,
1346 TRUE,
1347 TRUE,
1348 pTileInfo,
1349 &newPitch,
1350 &newHeight,
1351 &totalBytes,
1352 ¯oWidth,
1353 ¯oHeight,
1354 &pSliceBytes,
1355 &pBaseAlign);
1356 elemBits = 32;
1357 }
1358
1359 const UINT_32 pitchInTile = newPitch / MicroTileWidth;
1360 const UINT_32 heightInTile = newHeight / MicroTileWidth;
1361 UINT_64 macroOffset; // Per pipe starting offset of the macro tile in which this tile lies.
1362 UINT_64 microNumber; // Per pipe starting offset of the macro tile in which this tile lies.
1363 UINT_32 microX;
1364 UINT_32 microY;
1365 UINT_64 microOffset;
1366 UINT_32 microShift;
1367 UINT_64 totalOffset;
1368 UINT_32 elemIdxBits;
1369 UINT_32 elemIdx =
1370 TileCoordToMaskElementIndex(tx, ty, pTileInfo->pipeConfig, µShift, &elemIdxBits);
1371
1372 UINT_32 numPipes = HwlGetPipes(pTileInfo);
1373
1374 if (isLinear)
1375 { //linear addressing
1376 // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full
1377 // slice memory foot print instead of divided by numPipes.
1378 microX = tx / 4; // Macro Tile is 4x4
1379 microY = ty / 4 ;
1380 microNumber = static_cast<UINT_64>(microX + microY * (pitchInTile / 4)) << microShift;
1381
1382 UINT_32 sliceBits = pitchInTile * heightInTile;
1383
1384 // do htile single slice alignment if the flag is true
1385 if (m_configFlags.useHtileSliceAlign && (factor == 1)) //Htile
1386 {
1387 sliceBits = PowTwoAlign(sliceBits, BITS_TO_BYTES(HtileCacheBits) * numPipes / elemBits);
1388 }
1389 macroOffset = slice * (sliceBits / numPipes) * elemBits ;
1390 }
1391 else
1392 { //tiled addressing
1393 const UINT_32 macroWidthInTile = macroWidth / MicroTileWidth; // Now in unit of Tiles
1394 const UINT_32 macroHeightInTile = macroHeight / MicroTileHeight;
1395 const UINT_32 pitchInCL = pitchInTile / macroWidthInTile;
1396 const UINT_32 heightInCL = heightInTile / macroHeightInTile;
1397
1398 const UINT_32 macroX = x / macroWidth;
1399 const UINT_32 macroY = y / macroHeight;
1400 const UINT_32 macroNumber = macroX + macroY * pitchInCL + slice * pitchInCL * heightInCL;
1401
1402 // Per pipe starting offset of the cache line in which this tile lies.
1403 microX = (x % macroWidth) / MicroTileWidth / 4; // Macro Tile is 4x4
1404 microY = (y % macroHeight) / MicroTileHeight / 4 ;
1405 microNumber = static_cast<UINT_64>(microX + microY * (macroWidth / MicroTileWidth / 4)) << microShift;
1406
1407 macroOffset = macroNumber * tileNumPerPipe * elemBits;
1408 }
1409
1410 if(elemIdxBits == microShift)
1411 {
1412 microNumber += elemIdx;
1413 }
1414 else
1415 {
1416 microNumber >>= elemIdxBits;
1417 microNumber <<= elemIdxBits;
1418 microNumber += elemIdx;
1419 }
1420
1421 microOffset = elemBits * microNumber;
1422 totalOffset = microOffset + macroOffset;
1423
1424 UINT_32 pipe = ComputePipeFromCoord(x, y, 0, ADDR_TM_2D_TILED_THIN1, 0, FALSE, pTileInfo);
1425 UINT_64 addrInBits = totalOffset % (m_pipeInterleaveBytes * 8) +
1426 pipe * (m_pipeInterleaveBytes * 8) +
1427 totalOffset / (m_pipeInterleaveBytes * 8) * (m_pipeInterleaveBytes * 8) * numPipes;
1428 *pBitPosition = static_cast<UINT_32>(addrInBits) % 8;
1429 UINT_64 addr = addrInBits / 8;
1430
1431 return addr;
1432 }
1433
1434 /**
1435 ****************************************************************************************************
1436 * SiLib::HwlComputeXmaskCoordFromAddr
1437 *
1438 * @brief
1439 * Compute the coord from an address of a cmask/htile
1440 *
1441 * @return
1442 * N/A
1443 *
1444 * @note
1445 * This method is reused by htile, so rename to Xmask
1446 ****************************************************************************************************
1447 */
HwlComputeXmaskCoordFromAddr(UINT_64 addr,UINT_32 bitPosition,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 factor,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice) const1448 VOID SiLib::HwlComputeXmaskCoordFromAddr(
1449 UINT_64 addr, ///< [in] address
1450 UINT_32 bitPosition, ///< [in] bitPosition in a byte
1451 UINT_32 pitch, ///< [in] pitch
1452 UINT_32 height, ///< [in] height
1453 UINT_32 numSlices, ///< [in] number of slices
1454 UINT_32 factor, ///< [in] factor that indicates cmask or htile
1455 BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout
1456 BOOL_32 isWidth8, ///< [in] Not used by SI
1457 BOOL_32 isHeight8, ///< [in] Not used by SI
1458 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
1459 UINT_32* pX, ///< [out] x coord
1460 UINT_32* pY, ///< [out] y coord
1461 UINT_32* pSlice ///< [out] slice index
1462 ) const
1463 {
1464 UINT_32 newPitch;
1465 UINT_32 newHeight;
1466 UINT_64 totalBytes;
1467 UINT_32 clWidth;
1468 UINT_32 clHeight;
1469 UINT_32 tileNumPerPipe;
1470 UINT_64 sliceBytes;
1471
1472 *pX = 0;
1473 *pY = 0;
1474 *pSlice = 0;
1475
1476 if (factor == 2) //CMASK
1477 {
1478 ADDR_CMASK_FLAGS flags = {{0}};
1479
1480 tileNumPerPipe = 256;
1481
1482 ComputeCmaskInfo(flags,
1483 pitch,
1484 height,
1485 numSlices,
1486 isLinear,
1487 pTileInfo,
1488 &newPitch,
1489 &newHeight,
1490 &totalBytes,
1491 &clWidth,
1492 &clHeight);
1493 }
1494 else //HTile
1495 {
1496 ADDR_HTILE_FLAGS flags = {{0}};
1497
1498 tileNumPerPipe = 512;
1499
1500 ComputeHtileInfo(flags,
1501 pitch,
1502 height,
1503 numSlices,
1504 isLinear,
1505 TRUE,
1506 TRUE,
1507 pTileInfo,
1508 &newPitch,
1509 &newHeight,
1510 &totalBytes,
1511 &clWidth,
1512 &clHeight,
1513 &sliceBytes);
1514 }
1515
1516 const UINT_32 pitchInTile = newPitch / MicroTileWidth;
1517 const UINT_32 heightInTile = newHeight / MicroTileWidth;
1518 const UINT_32 pitchInMacroTile = pitchInTile / 4;
1519 UINT_32 macroShift;
1520 UINT_32 elemIdxBits;
1521 // get macroShift and elemIdxBits
1522 TileCoordToMaskElementIndex(0, 0, pTileInfo->pipeConfig, ¯oShift, &elemIdxBits);
1523
1524 const UINT_32 numPipes = HwlGetPipes(pTileInfo);
1525 const UINT_32 pipe = (UINT_32)((addr / m_pipeInterleaveBytes) % numPipes);
1526 // per pipe
1527 UINT_64 localOffset = (addr % m_pipeInterleaveBytes) +
1528 (addr / m_pipeInterleaveBytes / numPipes)* m_pipeInterleaveBytes;
1529
1530 UINT_32 tileIndex;
1531 if (factor == 2) //CMASK
1532 {
1533 tileIndex = (UINT_32)(localOffset * 2 + (bitPosition != 0));
1534 }
1535 else
1536 {
1537 tileIndex = (UINT_32)(localOffset / 4);
1538 }
1539
1540 UINT_32 macroOffset;
1541 if (isLinear)
1542 {
1543 UINT_32 sliceSizeInTile = pitchInTile * heightInTile;
1544
1545 // do htile single slice alignment if the flag is true
1546 if (m_configFlags.useHtileSliceAlign && (factor == 1)) //Htile
1547 {
1548 sliceSizeInTile = PowTwoAlign(sliceSizeInTile, static_cast<UINT_32>(sliceBytes) / 64);
1549 }
1550 *pSlice = tileIndex / (sliceSizeInTile / numPipes);
1551 macroOffset = tileIndex % (sliceSizeInTile / numPipes);
1552 }
1553 else
1554 {
1555 const UINT_32 clWidthInTile = clWidth / MicroTileWidth; // Now in unit of Tiles
1556 const UINT_32 clHeightInTile = clHeight / MicroTileHeight;
1557 const UINT_32 pitchInCL = pitchInTile / clWidthInTile;
1558 const UINT_32 heightInCL = heightInTile / clHeightInTile;
1559 const UINT_32 clIndex = tileIndex / tileNumPerPipe;
1560
1561 UINT_32 clX = clIndex % pitchInCL;
1562 UINT_32 clY = (clIndex % (heightInCL * pitchInCL)) / pitchInCL;
1563
1564 *pX = clX * clWidthInTile * MicroTileWidth;
1565 *pY = clY * clHeightInTile * MicroTileHeight;
1566 *pSlice = clIndex / (heightInCL * pitchInCL);
1567
1568 macroOffset = tileIndex % tileNumPerPipe;
1569 }
1570
1571 UINT_32 elemIdx = macroOffset & 7;
1572 macroOffset >>= elemIdxBits;
1573
1574 if (elemIdxBits != macroShift)
1575 {
1576 macroOffset <<= (elemIdxBits - macroShift);
1577
1578 UINT_32 pipebit1 = _BIT(pipe,1);
1579 UINT_32 pipebit2 = _BIT(pipe,2);
1580 UINT_32 pipebit3 = _BIT(pipe,3);
1581 if (pitchInMacroTile % 2)
1582 { //odd
1583 switch (pTileInfo->pipeConfig)
1584 {
1585 case ADDR_PIPECFG_P4_32x32:
1586 macroOffset |= pipebit1;
1587 break;
1588 case ADDR_PIPECFG_P8_32x32_8x16:
1589 case ADDR_PIPECFG_P8_32x32_16x16:
1590 case ADDR_PIPECFG_P8_32x32_16x32:
1591 macroOffset |= pipebit2;
1592 break;
1593 default:
1594 break;
1595 }
1596
1597 }
1598
1599 if (pitchInMacroTile % 4)
1600 {
1601 if (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)
1602 {
1603 macroOffset |= (pipebit1<<1);
1604 }
1605 if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) ||
1606 (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16)
1607 )
1608 {
1609 macroOffset |= (pipebit3<<1);
1610 }
1611 }
1612 }
1613
1614 UINT_32 macroX;
1615 UINT_32 macroY;
1616
1617 if (isLinear)
1618 {
1619 macroX = macroOffset % pitchInMacroTile;
1620 macroY = macroOffset / pitchInMacroTile;
1621 }
1622 else
1623 {
1624 const UINT_32 clWidthInMacroTile = clWidth / (MicroTileWidth * 4);
1625 macroX = macroOffset % clWidthInMacroTile;
1626 macroY = macroOffset / clWidthInMacroTile;
1627 }
1628
1629 *pX += macroX * 4 * MicroTileWidth;
1630 *pY += macroY * 4 * MicroTileHeight;
1631
1632 UINT_32 microX;
1633 UINT_32 microY;
1634 ComputeTileCoordFromPipeAndElemIdx(elemIdx, pipe, pTileInfo->pipeConfig, pitchInMacroTile,
1635 *pX, *pY, µX, µY);
1636
1637 *pX += microX * MicroTileWidth;
1638 *pY += microY * MicroTileWidth;
1639 }
1640
1641 /**
1642 ****************************************************************************************************
1643 * SiLib::HwlGetPitchAlignmentLinear
1644 * @brief
1645 * Get pitch alignment
1646 * @return
1647 * pitch alignment
1648 ****************************************************************************************************
1649 */
HwlGetPitchAlignmentLinear(UINT_32 bpp,ADDR_SURFACE_FLAGS flags) const1650 UINT_32 SiLib::HwlGetPitchAlignmentLinear(
1651 UINT_32 bpp, ///< [in] bits per pixel
1652 ADDR_SURFACE_FLAGS flags ///< [in] surface flags
1653 ) const
1654 {
1655 UINT_32 pitchAlign;
1656
1657 // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment
1658 if (flags.interleaved)
1659 {
1660 pitchAlign = Max(64u, m_pipeInterleaveBytes / BITS_TO_BYTES(bpp));
1661
1662 }
1663 else
1664 {
1665 pitchAlign = Max(8u, 64 / BITS_TO_BYTES(bpp));
1666 }
1667
1668 return pitchAlign;
1669 }
1670
1671 /**
1672 ****************************************************************************************************
1673 * SiLib::HwlGetSizeAdjustmentLinear
1674 *
1675 * @brief
1676 * Adjust linear surface pitch and slice size
1677 *
1678 * @return
1679 * Logical slice size in bytes
1680 ****************************************************************************************************
1681 */
HwlGetSizeAdjustmentLinear(AddrTileMode tileMode,UINT_32 bpp,UINT_32 numSamples,UINT_32 baseAlign,UINT_32 pitchAlign,UINT_32 * pPitch,UINT_32 * pHeight,UINT_32 * pHeightAlign) const1682 UINT_64 SiLib::HwlGetSizeAdjustmentLinear(
1683 AddrTileMode tileMode, ///< [in] tile mode
1684 UINT_32 bpp, ///< [in] bits per pixel
1685 UINT_32 numSamples, ///< [in] number of samples
1686 UINT_32 baseAlign, ///< [in] base alignment
1687 UINT_32 pitchAlign, ///< [in] pitch alignment
1688 UINT_32* pPitch, ///< [in,out] pointer to pitch
1689 UINT_32* pHeight, ///< [in,out] pointer to height
1690 UINT_32* pHeightAlign ///< [in,out] pointer to height align
1691 ) const
1692 {
1693 UINT_64 sliceSize;
1694 if (tileMode == ADDR_TM_LINEAR_GENERAL)
1695 {
1696 sliceSize = BITS_TO_BYTES(static_cast<UINT_64>(*pPitch) * (*pHeight) * bpp * numSamples);
1697 }
1698 else
1699 {
1700 UINT_32 pitch = *pPitch;
1701 UINT_32 height = *pHeight;
1702
1703 UINT_32 pixelsPerPipeInterleave = m_pipeInterleaveBytes / BITS_TO_BYTES(bpp);
1704 UINT_32 sliceAlignInPixel = pixelsPerPipeInterleave < 64 ? 64 : pixelsPerPipeInterleave;
1705
1706 // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value)
1707 UINT_64 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
1708
1709 while (pixelPerSlice % sliceAlignInPixel)
1710 {
1711 pitch += pitchAlign;
1712 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples;
1713 }
1714
1715 *pPitch = pitch;
1716
1717 UINT_32 heightAlign = 1;
1718
1719 while ((pitch * heightAlign) % sliceAlignInPixel)
1720 {
1721 heightAlign++;
1722 }
1723
1724 *pHeightAlign = heightAlign;
1725
1726 sliceSize = BITS_TO_BYTES(pixelPerSlice * bpp);
1727 }
1728
1729 return sliceSize;
1730 }
1731
1732 /**
1733 ****************************************************************************************************
1734 * SiLib::HwlPreHandleBaseLvl3xPitch
1735 *
1736 * @brief
1737 * Pre-handler of 3x pitch (96 bit) adjustment
1738 *
1739 * @return
1740 * Expected pitch
1741 ****************************************************************************************************
1742 */
HwlPreHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const1743 UINT_32 SiLib::HwlPreHandleBaseLvl3xPitch(
1744 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
1745 UINT_32 expPitch ///< [in] pitch
1746 ) const
1747 {
1748 ADDR_ASSERT(pIn->width == expPitch);
1749
1750 // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to
1751 // do here
1752 if (pIn->flags.pow2Pad == FALSE)
1753 {
1754 Addr::V1::Lib::HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
1755 }
1756 else
1757 {
1758 ADDR_ASSERT(IsPow2(expPitch));
1759 }
1760
1761 return expPitch;
1762 }
1763
1764 /**
1765 ****************************************************************************************************
1766 * SiLib::HwlPostHandleBaseLvl3xPitch
1767 *
1768 * @brief
1769 * Post-handler of 3x pitch adjustment
1770 *
1771 * @return
1772 * Expected pitch
1773 ****************************************************************************************************
1774 */
HwlPostHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const1775 UINT_32 SiLib::HwlPostHandleBaseLvl3xPitch(
1776 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
1777 UINT_32 expPitch ///< [in] pitch
1778 ) const
1779 {
1780 /**
1781 * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should
1782 * be able to compute a correct pitch from it as h/w address library is doing the job.
1783 */
1784 // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here
1785 if (pIn->flags.pow2Pad == FALSE)
1786 {
1787 Addr::V1::Lib::HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
1788 }
1789
1790 return expPitch;
1791 }
1792
1793 /**
1794 ****************************************************************************************************
1795 * SiLib::HwlGetPitchAlignmentMicroTiled
1796 *
1797 * @brief
1798 * Compute 1D tiled surface pitch alignment
1799 *
1800 * @return
1801 * pitch alignment
1802 ****************************************************************************************************
1803 */
HwlGetPitchAlignmentMicroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples) const1804 UINT_32 SiLib::HwlGetPitchAlignmentMicroTiled(
1805 AddrTileMode tileMode, ///< [in] tile mode
1806 UINT_32 bpp, ///< [in] bits per pixel
1807 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
1808 UINT_32 numSamples ///< [in] number of samples
1809 ) const
1810 {
1811 UINT_32 pitchAlign;
1812
1813 if (flags.qbStereo)
1814 {
1815 pitchAlign = EgBasedLib::HwlGetPitchAlignmentMicroTiled(tileMode,bpp,flags,numSamples);
1816 }
1817 else
1818 {
1819 pitchAlign = 8;
1820 }
1821
1822 return pitchAlign;
1823 }
1824
1825 /**
1826 ****************************************************************************************************
1827 * SiLib::HwlGetSizeAdjustmentMicroTiled
1828 *
1829 * @brief
1830 * Adjust 1D tiled surface pitch and slice size
1831 *
1832 * @return
1833 * Logical slice size in bytes
1834 ****************************************************************************************************
1835 */
HwlGetSizeAdjustmentMicroTiled(UINT_32 thickness,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,UINT_32 baseAlign,UINT_32 pitchAlign,UINT_32 * pPitch,UINT_32 * pHeight) const1836 UINT_64 SiLib::HwlGetSizeAdjustmentMicroTiled(
1837 UINT_32 thickness, ///< [in] thickness
1838 UINT_32 bpp, ///< [in] bits per pixel
1839 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
1840 UINT_32 numSamples, ///< [in] number of samples
1841 UINT_32 baseAlign, ///< [in] base alignment
1842 UINT_32 pitchAlign, ///< [in] pitch alignment
1843 UINT_32* pPitch, ///< [in,out] pointer to pitch
1844 UINT_32* pHeight ///< [in,out] pointer to height
1845 ) const
1846 {
1847 UINT_64 logicalSliceSize;
1848 UINT_64 physicalSliceSize;
1849
1850 UINT_32 pitch = *pPitch;
1851 UINT_32 height = *pHeight;
1852
1853 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
1854 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1855
1856 // Physical slice: multiplied by thickness
1857 physicalSliceSize = logicalSliceSize * thickness;
1858
1859 // Pitch alignment is always 8, so if slice size is not padded to base alignment
1860 // (pipe_interleave_size), we need to increase pitch
1861 while ((physicalSliceSize % baseAlign) != 0)
1862 {
1863 pitch += pitchAlign;
1864
1865 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1866
1867 physicalSliceSize = logicalSliceSize * thickness;
1868 }
1869
1870 #if !ALT_TEST
1871 //
1872 // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since
1873 // the stencil plane may have larger pitch if the slice size is smaller than base alignment.
1874 //
1875 // Note: this actually does not work for mipmap but mipmap depth texture is not really
1876 // sampled with mipmap.
1877 //
1878 if (flags.depth && (flags.noStencil == FALSE))
1879 {
1880 ADDR_ASSERT(numSamples == 1);
1881
1882 UINT_64 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height; // 1 byte stencil
1883
1884 while ((logicalSiceSizeStencil % baseAlign) != 0)
1885 {
1886 pitch += pitchAlign; // Stencil plane's pitch alignment is the same as depth plane's
1887
1888 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height;
1889 }
1890
1891 if (pitch != *pPitch)
1892 {
1893 // If this is a mipmap, this padded one cannot be sampled as a whole mipmap!
1894 logicalSliceSize = logicalSiceSizeStencil * BITS_TO_BYTES(bpp);
1895 }
1896 }
1897 #endif
1898 *pPitch = pitch;
1899
1900 // No adjust for pHeight
1901
1902 return logicalSliceSize;
1903 }
1904
1905 /**
1906 ****************************************************************************************************
1907 * SiLib::HwlConvertChipFamily
1908 *
1909 * @brief
1910 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
1911 * @return
1912 * ChipFamily
1913 ****************************************************************************************************
1914 */
HwlConvertChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)1915 ChipFamily SiLib::HwlConvertChipFamily(
1916 UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h
1917 UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h
1918 {
1919 ChipFamily family = ADDR_CHIP_FAMILY_SI;
1920
1921 switch (uChipFamily)
1922 {
1923 case FAMILY_SI:
1924 m_settings.isSouthernIsland = 1;
1925 m_settings.isTahiti = ASICREV_IS_TAHITI_P(uChipRevision);
1926 m_settings.isPitCairn = ASICREV_IS_PITCAIRN_PM(uChipRevision);
1927 m_settings.isCapeVerde = ASICREV_IS_CAPEVERDE_M(uChipRevision);
1928 m_settings.isOland = ASICREV_IS_OLAND_M(uChipRevision);
1929 m_settings.isHainan = ASICREV_IS_HAINAN_V(uChipRevision);
1930 break;
1931 default:
1932 ADDR_ASSERT(!"No Chip found");
1933 break;
1934 }
1935
1936 return family;
1937 }
1938
1939 /**
1940 ****************************************************************************************************
1941 * SiLib::HwlSetupTileInfo
1942 *
1943 * @brief
1944 * Setup default value of tile info for SI
1945 ****************************************************************************************************
1946 */
HwlSetupTileInfo(AddrTileMode tileMode,ADDR_SURFACE_FLAGS flags,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,ADDR_TILEINFO * pTileInfoIn,ADDR_TILEINFO * pTileInfoOut,AddrTileType inTileType,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1947 VOID SiLib::HwlSetupTileInfo(
1948 AddrTileMode tileMode, ///< [in] Tile mode
1949 ADDR_SURFACE_FLAGS flags, ///< [in] Surface type flags
1950 UINT_32 bpp, ///< [in] Bits per pixel
1951 UINT_32 pitch, ///< [in] Pitch in pixels
1952 UINT_32 height, ///< [in] Height in pixels
1953 UINT_32 numSamples, ///< [in] Number of samples
1954 ADDR_TILEINFO* pTileInfoIn, ///< [in] Tile info input: NULL for default
1955 ADDR_TILEINFO* pTileInfoOut, ///< [out] Tile info output
1956 AddrTileType inTileType, ///< [in] Tile type
1957 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output
1958 ) const
1959 {
1960 UINT_32 thickness = Thickness(tileMode);
1961 ADDR_TILEINFO* pTileInfo = pTileInfoOut;
1962 INT index = TileIndexInvalid;
1963
1964 // Fail-safe code
1965 if (IsLinear(tileMode) == FALSE)
1966 {
1967 // 128 bpp/thick tiling must be non-displayable.
1968 // Fmask reuse color buffer's entry but bank-height field can be from another entry
1969 // To simplify the logic, fmask entry should be picked from non-displayable ones
1970 if (bpp == 128 || thickness > 1 || flags.fmask || flags.prt)
1971 {
1972 inTileType = ADDR_NON_DISPLAYABLE;
1973 }
1974
1975 if (flags.depth || flags.stencil)
1976 {
1977 inTileType = ADDR_DEPTH_SAMPLE_ORDER;
1978 }
1979 }
1980
1981 // Partial valid fields are not allowed for SI.
1982 if (IsTileInfoAllZero(pTileInfo))
1983 {
1984 if (IsMacroTiled(tileMode))
1985 {
1986 if (flags.prt)
1987 {
1988 if (numSamples == 1)
1989 {
1990 if (flags.depth)
1991 {
1992 switch (bpp)
1993 {
1994 case 16:
1995 index = 3;
1996 break;
1997 case 32:
1998 index = 6;
1999 break;
2000 default:
2001 ADDR_ASSERT_ALWAYS();
2002 break;
2003 }
2004 }
2005 else
2006 {
2007 switch (bpp)
2008 {
2009 case 8:
2010 index = 21;
2011 break;
2012 case 16:
2013 index = 22;
2014 break;
2015 case 32:
2016 index = 23;
2017 break;
2018 case 64:
2019 index = 24;
2020 break;
2021 case 128:
2022 index = 25;
2023 break;
2024 default:
2025 break;
2026 }
2027
2028 if (thickness > 1)
2029 {
2030 ADDR_ASSERT(bpp != 128);
2031 index += 5;
2032 }
2033 }
2034 }
2035 else
2036 {
2037 ADDR_ASSERT(numSamples == 4);
2038
2039 if (flags.depth)
2040 {
2041 switch (bpp)
2042 {
2043 case 16:
2044 index = 5;
2045 break;
2046 case 32:
2047 index = 7;
2048 break;
2049 default:
2050 ADDR_ASSERT_ALWAYS();
2051 break;
2052 }
2053 }
2054 else
2055 {
2056 switch (bpp)
2057 {
2058 case 8:
2059 index = 23;
2060 break;
2061 case 16:
2062 index = 24;
2063 break;
2064 case 32:
2065 index = 25;
2066 break;
2067 case 64:
2068 index = 30;
2069 break;
2070 default:
2071 ADDR_ASSERT_ALWAYS();
2072 break;
2073 }
2074 }
2075 }
2076 }//end of PRT part
2077 // See table entries 0-7
2078 else if (flags.depth || flags.stencil)
2079 {
2080 if (flags.compressZ)
2081 {
2082 if (flags.stencil)
2083 {
2084 index = 0;
2085 }
2086 else
2087 {
2088 // optimal tile index for compressed depth/stencil.
2089 switch (numSamples)
2090 {
2091 case 1:
2092 index = 0;
2093 break;
2094 case 2:
2095 case 4:
2096 index = 1;
2097 break;
2098 case 8:
2099 index = 2;
2100 break;
2101 default:
2102 break;
2103 }
2104 }
2105 }
2106 else // unCompressZ
2107 {
2108 index = 3;
2109 }
2110 }
2111 else //non PRT & non Depth & non Stencil
2112 {
2113 // See table entries 9-12
2114 if (inTileType == ADDR_DISPLAYABLE)
2115 {
2116 switch (bpp)
2117 {
2118 case 8:
2119 index = 10;
2120 break;
2121 case 16:
2122 index = 11;
2123 break;
2124 case 32:
2125 index = 12;
2126 break;
2127 case 64:
2128 index = 12;
2129 break;
2130 default:
2131 break;
2132 }
2133 }
2134 else
2135 {
2136 // See table entries 13-17
2137 if (thickness == 1)
2138 {
2139 if (flags.fmask)
2140 {
2141 UINT_32 fmaskPixelSize = bpp * numSamples;
2142
2143 switch (fmaskPixelSize)
2144 {
2145 case 8:
2146 index = 14;
2147 break;
2148 case 16:
2149 index = 15;
2150 break;
2151 case 32:
2152 index = 16;
2153 break;
2154 case 64:
2155 index = 17;
2156 break;
2157 default:
2158 ADDR_ASSERT_ALWAYS();
2159 }
2160 }
2161 else
2162 {
2163 switch (bpp)
2164 {
2165 case 8:
2166 index = 14;
2167 break;
2168 case 16:
2169 index = 15;
2170 break;
2171 case 32:
2172 index = 16;
2173 break;
2174 case 64:
2175 index = 17;
2176 break;
2177 case 128:
2178 index = 17;
2179 break;
2180 default:
2181 break;
2182 }
2183 }
2184 }
2185 else // thick tiling - entries 18-20
2186 {
2187 switch (thickness)
2188 {
2189 case 4:
2190 index = 20;
2191 break;
2192 case 8:
2193 index = 19;
2194 break;
2195 default:
2196 break;
2197 }
2198 }
2199 }
2200 }
2201 }
2202 else
2203 {
2204 if (tileMode == ADDR_TM_LINEAR_ALIGNED)
2205 {
2206 index = 8;
2207 }
2208 else if (tileMode == ADDR_TM_LINEAR_GENERAL)
2209 {
2210 index = TileIndexLinearGeneral;
2211 }
2212 else
2213 {
2214 if (flags.depth || flags.stencil)
2215 {
2216 index = 4;
2217 }
2218 else if (inTileType == ADDR_DISPLAYABLE)
2219 {
2220 index = 9;
2221 }
2222 else if (thickness == 1)
2223 {
2224 index = 13;
2225 }
2226 else
2227 {
2228 index = 18;
2229 }
2230 }
2231 }
2232
2233 if (index >= 0 && index <= 31)
2234 {
2235 *pTileInfo = m_tileTable[index].info;
2236 pOut->tileType = m_tileTable[index].type;
2237 }
2238
2239 if (index == TileIndexLinearGeneral)
2240 {
2241 *pTileInfo = m_tileTable[8].info;
2242 pOut->tileType = m_tileTable[8].type;
2243 }
2244 }
2245 else
2246 {
2247 if (pTileInfoIn)
2248 {
2249 if (flags.stencil && pTileInfoIn->tileSplitBytes == 0)
2250 {
2251 // Stencil always uses index 0
2252 *pTileInfo = m_tileTable[0].info;
2253 }
2254 }
2255 // Pass through tile type
2256 pOut->tileType = inTileType;
2257 }
2258
2259 pOut->tileIndex = index;
2260 pOut->prtTileIndex = flags.prt;
2261 }
2262
2263 /**
2264 ****************************************************************************************************
2265 * SiLib::DecodeGbRegs
2266 *
2267 * @brief
2268 * Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks
2269 *
2270 * @return
2271 * TRUE if all settings are valid
2272 *
2273 ****************************************************************************************************
2274 */
DecodeGbRegs(const ADDR_REGISTER_VALUE * pRegValue)2275 BOOL_32 SiLib::DecodeGbRegs(
2276 const ADDR_REGISTER_VALUE* pRegValue) ///< [in] create input
2277 {
2278 GB_ADDR_CONFIG reg;
2279 BOOL_32 valid = TRUE;
2280
2281 reg.val = pRegValue->gbAddrConfig;
2282
2283 switch (reg.f.pipe_interleave_size)
2284 {
2285 case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
2286 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
2287 break;
2288 case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
2289 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
2290 break;
2291 default:
2292 valid = FALSE;
2293 ADDR_UNHANDLED_CASE();
2294 break;
2295 }
2296
2297 switch (reg.f.row_size)
2298 {
2299 case ADDR_CONFIG_1KB_ROW:
2300 m_rowSize = ADDR_ROWSIZE_1KB;
2301 break;
2302 case ADDR_CONFIG_2KB_ROW:
2303 m_rowSize = ADDR_ROWSIZE_2KB;
2304 break;
2305 case ADDR_CONFIG_4KB_ROW:
2306 m_rowSize = ADDR_ROWSIZE_4KB;
2307 break;
2308 default:
2309 valid = FALSE;
2310 ADDR_UNHANDLED_CASE();
2311 break;
2312 }
2313
2314 switch (pRegValue->noOfBanks)
2315 {
2316 case 0:
2317 m_banks = 4;
2318 break;
2319 case 1:
2320 m_banks = 8;
2321 break;
2322 case 2:
2323 m_banks = 16;
2324 break;
2325 default:
2326 valid = FALSE;
2327 ADDR_UNHANDLED_CASE();
2328 break;
2329 }
2330
2331 switch (pRegValue->noOfRanks)
2332 {
2333 case 0:
2334 m_ranks = 1;
2335 break;
2336 case 1:
2337 m_ranks = 2;
2338 break;
2339 default:
2340 valid = FALSE;
2341 ADDR_UNHANDLED_CASE();
2342 break;
2343 }
2344
2345 m_logicalBanks = m_banks * m_ranks;
2346
2347 ADDR_ASSERT(m_logicalBanks <= 16);
2348
2349 return valid;
2350 }
2351
2352 /**
2353 ****************************************************************************************************
2354 * SiLib::HwlInitGlobalParams
2355 *
2356 * @brief
2357 * Initializes global parameters
2358 *
2359 * @return
2360 * TRUE if all settings are valid
2361 *
2362 ****************************************************************************************************
2363 */
HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)2364 BOOL_32 SiLib::HwlInitGlobalParams(
2365 const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
2366 {
2367 BOOL_32 valid = TRUE;
2368 const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
2369
2370 valid = DecodeGbRegs(pRegValue);
2371
2372 if (valid)
2373 {
2374 if (m_settings.isTahiti || m_settings.isPitCairn)
2375 {
2376 m_pipes = 8;
2377 }
2378 else if (m_settings.isCapeVerde || m_settings.isOland)
2379 {
2380 m_pipes = 4;
2381 }
2382 else
2383 {
2384 // Hainan is 2-pipe (m_settings.isHainan == 1)
2385 m_pipes = 2;
2386 }
2387
2388 valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
2389
2390 if (valid)
2391 {
2392 InitEquationTable();
2393 }
2394
2395 m_maxSamples = 16;
2396 }
2397
2398 return valid;
2399 }
2400
2401 /**
2402 ****************************************************************************************************
2403 * SiLib::HwlConvertTileInfoToHW
2404 * @brief
2405 * Entry of si's ConvertTileInfoToHW
2406 * @return
2407 * ADDR_E_RETURNCODE
2408 ****************************************************************************************************
2409 */
HwlConvertTileInfoToHW(const ADDR_CONVERT_TILEINFOTOHW_INPUT * pIn,ADDR_CONVERT_TILEINFOTOHW_OUTPUT * pOut) const2410 ADDR_E_RETURNCODE SiLib::HwlConvertTileInfoToHW(
2411 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
2412 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
2413 ) const
2414 {
2415 ADDR_E_RETURNCODE retCode = ADDR_OK;
2416
2417 retCode = EgBasedLib::HwlConvertTileInfoToHW(pIn, pOut);
2418
2419 if (retCode == ADDR_OK)
2420 {
2421 if (pIn->reverse == FALSE)
2422 {
2423 if (pIn->pTileInfo->pipeConfig == ADDR_PIPECFG_INVALID)
2424 {
2425 retCode = ADDR_INVALIDPARAMS;
2426 }
2427 else
2428 {
2429 pOut->pTileInfo->pipeConfig =
2430 static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig - 1);
2431 }
2432 }
2433 else
2434 {
2435 pOut->pTileInfo->pipeConfig =
2436 static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig + 1);
2437 }
2438 }
2439
2440 return retCode;
2441 }
2442
2443 /**
2444 ****************************************************************************************************
2445 * SiLib::HwlComputeXmaskCoordYFrom8Pipe
2446 *
2447 * @brief
2448 * Compute the Y coord which will be added to Xmask Y
2449 * coord.
2450 * @return
2451 * Y coord
2452 ****************************************************************************************************
2453 */
HwlComputeXmaskCoordYFrom8Pipe(UINT_32 pipe,UINT_32 x) const2454 UINT_32 SiLib::HwlComputeXmaskCoordYFrom8Pipe(
2455 UINT_32 pipe, ///< [in] pipe id
2456 UINT_32 x ///< [in] tile coord x, which is original x coord / 8
2457 ) const
2458 {
2459 // This function should never be called since it is 6xx/8xx specfic.
2460 // Keep this empty implementation to avoid any mis-use.
2461 ADDR_ASSERT_ALWAYS();
2462
2463 return 0;
2464 }
2465
2466 /**
2467 ****************************************************************************************************
2468 * SiLib::HwlComputeSurfaceCoord2DFromBankPipe
2469 *
2470 * @brief
2471 * Compute surface x,y coordinates from bank/pipe info
2472 * @return
2473 * N/A
2474 ****************************************************************************************************
2475 */
HwlComputeSurfaceCoord2DFromBankPipe(AddrTileMode tileMode,UINT_32 * pX,UINT_32 * pY,UINT_32 slice,UINT_32 bank,UINT_32 pipe,UINT_32 bankSwizzle,UINT_32 pipeSwizzle,UINT_32 tileSlices,BOOL_32 ignoreSE,ADDR_TILEINFO * pTileInfo) const2476 VOID SiLib::HwlComputeSurfaceCoord2DFromBankPipe(
2477 AddrTileMode tileMode, ///< [in] tile mode
2478 UINT_32* pX, ///< [in,out] x coordinate
2479 UINT_32* pY, ///< [in,out] y coordinate
2480 UINT_32 slice, ///< [in] slice index
2481 UINT_32 bank, ///< [in] bank number
2482 UINT_32 pipe, ///< [in] pipe number
2483 UINT_32 bankSwizzle,///< [in] bank swizzle
2484 UINT_32 pipeSwizzle,///< [in] pipe swizzle
2485 UINT_32 tileSlices, ///< [in] slices in a micro tile
2486 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines are ignored
2487 ADDR_TILEINFO* pTileInfo ///< [in] bank structure. **All fields to be valid on entry**
2488 ) const
2489 {
2490 UINT_32 xBit;
2491 UINT_32 yBit;
2492 UINT_32 yBit3 = 0;
2493 UINT_32 yBit4 = 0;
2494 UINT_32 yBit5 = 0;
2495 UINT_32 yBit6 = 0;
2496
2497 UINT_32 xBit3 = 0;
2498 UINT_32 xBit4 = 0;
2499 UINT_32 xBit5 = 0;
2500
2501 UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
2502
2503 CoordFromBankPipe xyBits = {0};
2504 ComputeSurfaceCoord2DFromBankPipe(tileMode, *pX, *pY, slice, bank, pipe,
2505 bankSwizzle, pipeSwizzle, tileSlices, pTileInfo,
2506 &xyBits);
2507 yBit3 = xyBits.yBit3;
2508 yBit4 = xyBits.yBit4;
2509 yBit5 = xyBits.yBit5;
2510 yBit6 = xyBits.yBit6;
2511
2512 xBit3 = xyBits.xBit3;
2513 xBit4 = xyBits.xBit4;
2514 xBit5 = xyBits.xBit5;
2515
2516 yBit = xyBits.yBits;
2517
2518 UINT_32 yBitTemp = 0;
2519
2520 if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
2521 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32))
2522 {
2523 ADDR_ASSERT(pTileInfo->bankWidth == 1 && pTileInfo->macroAspectRatio > 1);
2524 UINT_32 yBitToCheck = QLog2(pTileInfo->banks) - 1;
2525
2526 ADDR_ASSERT(yBitToCheck <= 3);
2527
2528 yBitTemp = _BIT(yBit, yBitToCheck);
2529
2530 xBit3 = 0;
2531 }
2532
2533 yBit = Bits2Number(4, yBit6, yBit5, yBit4, yBit3);
2534 xBit = Bits2Number(3, xBit5, xBit4, xBit3);
2535
2536 *pY += yBit * pTileInfo->bankHeight * MicroTileHeight;
2537 *pX += xBit * numPipes * pTileInfo->bankWidth * MicroTileWidth;
2538
2539 //calculate the bank and pipe bits in x, y
2540 UINT_32 xTile; //x in micro tile
2541 UINT_32 x3 = 0;
2542 UINT_32 x4 = 0;
2543 UINT_32 x5 = 0;
2544 UINT_32 x6 = 0;
2545 UINT_32 y = *pY;
2546
2547 UINT_32 pipeBit0 = _BIT(pipe,0);
2548 UINT_32 pipeBit1 = _BIT(pipe,1);
2549 UINT_32 pipeBit2 = _BIT(pipe,2);
2550
2551 UINT_32 y3 = _BIT(y, 3);
2552 UINT_32 y4 = _BIT(y, 4);
2553 UINT_32 y5 = _BIT(y, 5);
2554 UINT_32 y6 = _BIT(y, 6);
2555
2556 // bankbit0 after ^x4^x5
2557 UINT_32 bankBit00 = _BIT(bank,0);
2558 UINT_32 bankBit0 = 0;
2559
2560 switch (pTileInfo->pipeConfig)
2561 {
2562 case ADDR_PIPECFG_P2:
2563 x3 = pipeBit0 ^ y3;
2564 break;
2565 case ADDR_PIPECFG_P4_8x16:
2566 x4 = pipeBit0 ^ y3;
2567 x3 = pipeBit0 ^ y4;
2568 break;
2569 case ADDR_PIPECFG_P4_16x16:
2570 x4 = pipeBit1 ^ y4;
2571 x3 = pipeBit0 ^ y3 ^ x4;
2572 break;
2573 case ADDR_PIPECFG_P4_16x32:
2574 x4 = pipeBit1 ^ y4;
2575 x3 = pipeBit0 ^ y3 ^ x4;
2576 break;
2577 case ADDR_PIPECFG_P4_32x32:
2578 x5 = pipeBit1 ^ y5;
2579 x3 = pipeBit0 ^ y3 ^ x5;
2580 bankBit0 = yBitTemp ^ x5;
2581 x4 = bankBit00 ^ x5 ^ bankBit0;
2582 *pX += x5 * 4 * 1 * 8; // x5 * num_pipes * bank_width * 8;
2583 break;
2584 case ADDR_PIPECFG_P8_16x16_8x16:
2585 x3 = pipeBit1 ^ y5;
2586 x4 = pipeBit2 ^ y4;
2587 x5 = pipeBit0 ^ y3 ^ x4;
2588 break;
2589 case ADDR_PIPECFG_P8_16x32_8x16:
2590 x3 = pipeBit1 ^ y4;
2591 x4 = pipeBit2 ^ y5;
2592 x5 = pipeBit0 ^ y3 ^ x4;
2593 break;
2594 case ADDR_PIPECFG_P8_32x32_8x16:
2595 x3 = pipeBit1 ^ y4;
2596 x5 = pipeBit2 ^ y5;
2597 x4 = pipeBit0 ^ y3 ^ x5;
2598 break;
2599 case ADDR_PIPECFG_P8_16x32_16x16:
2600 x4 = pipeBit2 ^ y5;
2601 x5 = pipeBit1 ^ y4;
2602 x3 = pipeBit0 ^ y3 ^ x4;
2603 break;
2604 case ADDR_PIPECFG_P8_32x32_16x16:
2605 x5 = pipeBit2 ^ y5;
2606 x4 = pipeBit1 ^ y4;
2607 x3 = pipeBit0 ^ y3 ^ x4;
2608 break;
2609 case ADDR_PIPECFG_P8_32x32_16x32:
2610 x5 = pipeBit2 ^ y5;
2611 x4 = pipeBit1 ^ y6;
2612 x3 = pipeBit0 ^ y3 ^ x4;
2613 break;
2614 case ADDR_PIPECFG_P8_32x64_32x32:
2615 x6 = pipeBit1 ^ y5;
2616 x5 = pipeBit2 ^ y6;
2617 x3 = pipeBit0 ^ y3 ^ x5;
2618 bankBit0 = yBitTemp ^ x6;
2619 x4 = bankBit00 ^ x5 ^ bankBit0;
2620 *pX += x6 * 8 * 1 * 8; // x6 * num_pipes * bank_width * 8;
2621 break;
2622 default:
2623 ADDR_ASSERT_ALWAYS();
2624 }
2625
2626 xTile = Bits2Number(3, x5, x4, x3);
2627
2628 *pX += xTile << 3;
2629 }
2630
2631 /**
2632 ****************************************************************************************************
2633 * SiLib::HwlPreAdjustBank
2634 *
2635 * @brief
2636 * Adjust bank before calculating address acoording to bank/pipe
2637 * @return
2638 * Adjusted bank
2639 ****************************************************************************************************
2640 */
HwlPreAdjustBank(UINT_32 tileX,UINT_32 bank,ADDR_TILEINFO * pTileInfo) const2641 UINT_32 SiLib::HwlPreAdjustBank(
2642 UINT_32 tileX, ///< [in] x coordinate in unit of tile
2643 UINT_32 bank, ///< [in] bank
2644 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2645 ) const
2646 {
2647 if (((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) ||
2648 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)) && (pTileInfo->bankWidth == 1))
2649 {
2650 UINT_32 bankBit0 = _BIT(bank, 0);
2651 UINT_32 x4 = _BIT(tileX, 1);
2652 UINT_32 x5 = _BIT(tileX, 2);
2653
2654 bankBit0 = bankBit0 ^ x4 ^ x5;
2655 bank |= bankBit0;
2656
2657 ADDR_ASSERT(pTileInfo->macroAspectRatio > 1);
2658 }
2659
2660 return bank;
2661 }
2662
2663 /**
2664 ****************************************************************************************************
2665 * SiLib::HwlComputeSurfaceInfo
2666 *
2667 * @brief
2668 * Entry of si's ComputeSurfaceInfo
2669 * @return
2670 * ADDR_E_RETURNCODE
2671 ****************************************************************************************************
2672 */
HwlComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2673 ADDR_E_RETURNCODE SiLib::HwlComputeSurfaceInfo(
2674 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
2675 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
2676 ) const
2677 {
2678 pOut->tileIndex = pIn->tileIndex;
2679
2680 ADDR_E_RETURNCODE retCode = EgBasedLib::HwlComputeSurfaceInfo(pIn, pOut);
2681
2682 UINT_32 tileIndex = static_cast<UINT_32>(pOut->tileIndex);
2683
2684 if (((pIn->flags.needEquation == TRUE) ||
2685 (pIn->flags.preferEquation == TRUE)) &&
2686 (pIn->numSamples <= 1) &&
2687 (tileIndex < TileTableSize))
2688 {
2689 static const UINT_32 SiUncompressDepthTileIndex = 3;
2690
2691 if ((pIn->numSlices > 1) &&
2692 (IsMacroTiled(pOut->tileMode) == TRUE) &&
2693 ((m_chipFamily == ADDR_CHIP_FAMILY_SI) ||
2694 (IsPrtTileMode(pOut->tileMode) == FALSE)))
2695 {
2696 pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
2697 }
2698 else if ((pIn->flags.prt == FALSE) &&
2699 (m_uncompressDepthEqIndex != 0) &&
2700 (tileIndex == SiUncompressDepthTileIndex))
2701 {
2702 pOut->equationIndex = m_uncompressDepthEqIndex + Log2(pIn->bpp >> 3);
2703 }
2704 else
2705 {
2706
2707 pOut->equationIndex = m_equationLookupTable[Log2(pIn->bpp >> 3)][tileIndex];
2708 }
2709
2710 if (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX)
2711 {
2712 pOut->blockWidth = m_blockWidth[pOut->equationIndex];
2713
2714 pOut->blockHeight = m_blockHeight[pOut->equationIndex];
2715
2716 pOut->blockSlices = m_blockSlices[pOut->equationIndex];
2717 }
2718 }
2719 else
2720 {
2721 pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
2722 }
2723
2724 return retCode;
2725 }
2726
2727 /**
2728 ****************************************************************************************************
2729 * SiLib::HwlComputeMipLevel
2730 * @brief
2731 * Compute MipLevel info (including level 0)
2732 * @return
2733 * TRUE if HWL's handled
2734 ****************************************************************************************************
2735 */
HwlComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn) const2736 BOOL_32 SiLib::HwlComputeMipLevel(
2737 ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in,out] Input structure
2738 ) const
2739 {
2740 // basePitch is calculated from level 0 so we only check this for mipLevel > 0
2741 if (pIn->mipLevel > 0)
2742 {
2743 // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if
2744 // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being
2745 // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2.
2746 if (ElemLib::IsExpand3x(pIn->format) == FALSE)
2747 {
2748 // Sublevel pitches are generated from base level pitch instead of width on SI
2749 // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain
2750 ADDR_ASSERT((pIn->flags.pow2Pad == FALSE) ||
2751 ((pIn->basePitch != 0) && IsPow2(pIn->basePitch)));
2752 }
2753
2754 if (pIn->basePitch != 0)
2755 {
2756 pIn->width = Max(1u, pIn->basePitch >> pIn->mipLevel);
2757 }
2758 }
2759
2760 // pow2Pad is done in PostComputeMipLevel
2761
2762 return TRUE;
2763 }
2764
2765 /**
2766 ****************************************************************************************************
2767 * SiLib::HwlCheckLastMacroTiledLvl
2768 *
2769 * @brief
2770 * Sets pOut->last2DLevel to TRUE if it is
2771 * @note
2772 *
2773 ****************************************************************************************************
2774 */
HwlCheckLastMacroTiledLvl(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2775 VOID SiLib::HwlCheckLastMacroTiledLvl(
2776 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
2777 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] Output structure (used as input, too)
2778 ) const
2779 {
2780 // pow2Pad covers all mipmap cases
2781 if (pIn->flags.pow2Pad)
2782 {
2783 ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2784
2785 UINT_32 nextPitch;
2786 UINT_32 nextHeight;
2787 UINT_32 nextSlices;
2788
2789 AddrTileMode nextTileMode;
2790
2791 if (pIn->mipLevel == 0 || pIn->basePitch == 0)
2792 {
2793 // Base level or fail-safe case (basePitch == 0)
2794 nextPitch = pOut->pitch >> 1;
2795 }
2796 else
2797 {
2798 // Sub levels
2799 nextPitch = pIn->basePitch >> (pIn->mipLevel + 1);
2800 }
2801
2802 // nextHeight must be shifted from this level's original height rather than a pow2 padded
2803 // one but this requires original height stored somewhere (pOut->height)
2804 ADDR_ASSERT(pOut->height != 0);
2805
2806 // next level's height is just current level's >> 1 in pixels
2807 nextHeight = pOut->height >> 1;
2808 // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block
2809 // compressed foramts
2810 if (ElemLib::IsBlockCompressed(pIn->format))
2811 {
2812 nextHeight = (nextHeight + 3) / 4;
2813 }
2814 nextHeight = NextPow2(nextHeight);
2815
2816 // nextSlices may be 0 if this level's is 1
2817 if (pIn->flags.volume)
2818 {
2819 nextSlices = Max(1u, pIn->numSlices >> 1);
2820 }
2821 else
2822 {
2823 nextSlices = pIn->numSlices;
2824 }
2825
2826 nextTileMode = ComputeSurfaceMipLevelTileMode(pIn->tileMode,
2827 pIn->bpp,
2828 nextPitch,
2829 nextHeight,
2830 nextSlices,
2831 pIn->numSamples,
2832 pOut->blockWidth,
2833 pOut->blockHeight,
2834 pOut->pTileInfo);
2835
2836 pOut->last2DLevel = IsMicroTiled(nextTileMode);
2837 }
2838 }
2839
2840 /**
2841 ****************************************************************************************************
2842 * SiLib::HwlDegradeThickTileMode
2843 *
2844 * @brief
2845 * Degrades valid tile mode for thick modes if needed
2846 *
2847 * @return
2848 * Suitable tile mode
2849 ****************************************************************************************************
2850 */
HwlDegradeThickTileMode(AddrTileMode baseTileMode,UINT_32 numSlices,UINT_32 * pBytesPerTile) const2851 AddrTileMode SiLib::HwlDegradeThickTileMode(
2852 AddrTileMode baseTileMode, ///< base tile mode
2853 UINT_32 numSlices, ///< current number of slices
2854 UINT_32* pBytesPerTile ///< [in,out] pointer to bytes per slice
2855 ) const
2856 {
2857 return EgBasedLib::HwlDegradeThickTileMode(baseTileMode, numSlices, pBytesPerTile);
2858 }
2859
2860 /**
2861 ****************************************************************************************************
2862 * SiLib::HwlTileInfoEqual
2863 *
2864 * @brief
2865 * Return TRUE if all field are equal
2866 * @note
2867 * Only takes care of current HWL's data
2868 ****************************************************************************************************
2869 */
HwlTileInfoEqual(const ADDR_TILEINFO * pLeft,const ADDR_TILEINFO * pRight) const2870 BOOL_32 SiLib::HwlTileInfoEqual(
2871 const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
2872 const ADDR_TILEINFO* pRight ///<[in] Right compare operand
2873 ) const
2874 {
2875 BOOL_32 equal = FALSE;
2876
2877 if (pLeft->pipeConfig == pRight->pipeConfig)
2878 {
2879 equal = EgBasedLib::HwlTileInfoEqual(pLeft, pRight);
2880 }
2881
2882 return equal;
2883 }
2884
2885 /**
2886 ****************************************************************************************************
2887 * SiLib::GetTileSettings
2888 *
2889 * @brief
2890 * Get tile setting infos by index.
2891 * @return
2892 * Tile setting info.
2893 ****************************************************************************************************
2894 */
GetTileSetting(UINT_32 index) const2895 const TileConfig* SiLib::GetTileSetting(
2896 UINT_32 index ///< [in] Tile index
2897 ) const
2898 {
2899 ADDR_ASSERT(index < m_noOfEntries);
2900 return &m_tileTable[index];
2901 }
2902
2903 /**
2904 ****************************************************************************************************
2905 * SiLib::HwlPostCheckTileIndex
2906 *
2907 * @brief
2908 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
2909 * tile mode/type/info and change the index if needed
2910 * @return
2911 * Tile index.
2912 ****************************************************************************************************
2913 */
HwlPostCheckTileIndex(const ADDR_TILEINFO * pInfo,AddrTileMode mode,AddrTileType type,INT curIndex) const2914 INT_32 SiLib::HwlPostCheckTileIndex(
2915 const ADDR_TILEINFO* pInfo, ///< [in] Tile Info
2916 AddrTileMode mode, ///< [in] Tile mode
2917 AddrTileType type, ///< [in] Tile type
2918 INT curIndex ///< [in] Current index assigned in HwlSetupTileInfo
2919 ) const
2920 {
2921 INT_32 index = curIndex;
2922
2923 if (mode == ADDR_TM_LINEAR_GENERAL)
2924 {
2925 index = TileIndexLinearGeneral;
2926 }
2927 else
2928 {
2929 BOOL_32 macroTiled = IsMacroTiled(mode);
2930
2931 // We need to find a new index if either of them is true
2932 // 1. curIndex is invalid
2933 // 2. tile mode is changed
2934 // 3. tile info does not match for macro tiled
2935 if ((index == TileIndexInvalid ||
2936 (mode != m_tileTable[index].mode) ||
2937 (macroTiled && (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) == FALSE))))
2938 {
2939 for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
2940 {
2941 if (macroTiled)
2942 {
2943 // macro tile modes need all to match
2944 if (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) &&
2945 (mode == m_tileTable[index].mode) &&
2946 (type == m_tileTable[index].type))
2947 {
2948 break;
2949 }
2950 }
2951 else if (mode == ADDR_TM_LINEAR_ALIGNED)
2952 {
2953 // linear mode only needs tile mode to match
2954 if (mode == m_tileTable[index].mode)
2955 {
2956 break;
2957 }
2958 }
2959 else
2960 {
2961 // micro tile modes only need tile mode and tile type to match
2962 if (mode == m_tileTable[index].mode &&
2963 type == m_tileTable[index].type)
2964 {
2965 break;
2966 }
2967 }
2968 }
2969 }
2970 }
2971
2972 ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
2973
2974 if (index >= static_cast<INT_32>(m_noOfEntries))
2975 {
2976 index = TileIndexInvalid;
2977 }
2978
2979 return index;
2980 }
2981
2982 /**
2983 ****************************************************************************************************
2984 * SiLib::HwlSetupTileCfg
2985 *
2986 * @brief
2987 * Map tile index to tile setting.
2988 * @return
2989 * ADDR_E_RETURNCODE
2990 ****************************************************************************************************
2991 */
HwlSetupTileCfg(UINT_32 bpp,INT_32 index,INT_32 macroModeIndex,ADDR_TILEINFO * pInfo,AddrTileMode * pMode,AddrTileType * pType) const2992 ADDR_E_RETURNCODE SiLib::HwlSetupTileCfg(
2993 UINT_32 bpp, ///< Bits per pixel
2994 INT_32 index, ///< Tile index
2995 INT_32 macroModeIndex, ///< Index in macro tile mode table(CI)
2996 ADDR_TILEINFO* pInfo, ///< [out] Tile Info
2997 AddrTileMode* pMode, ///< [out] Tile mode
2998 AddrTileType* pType ///< [out] Tile type
2999 ) const
3000 {
3001 ADDR_E_RETURNCODE returnCode = ADDR_OK;
3002
3003 // Global flag to control usage of tileIndex
3004 if (UseTileIndex(index))
3005 {
3006 if (index == TileIndexLinearGeneral)
3007 {
3008 if (pMode)
3009 {
3010 *pMode = ADDR_TM_LINEAR_GENERAL;
3011 }
3012
3013 if (pType)
3014 {
3015 *pType = ADDR_DISPLAYABLE;
3016 }
3017
3018 if (pInfo)
3019 {
3020 pInfo->banks = 2;
3021 pInfo->bankWidth = 1;
3022 pInfo->bankHeight = 1;
3023 pInfo->macroAspectRatio = 1;
3024 pInfo->tileSplitBytes = 64;
3025 pInfo->pipeConfig = ADDR_PIPECFG_P2;
3026 }
3027 }
3028 else if (static_cast<UINT_32>(index) >= m_noOfEntries)
3029 {
3030 returnCode = ADDR_INVALIDPARAMS;
3031 }
3032 else
3033 {
3034 const TileConfig* pCfgTable = GetTileSetting(index);
3035
3036 if (pInfo)
3037 {
3038 *pInfo = pCfgTable->info;
3039 }
3040 else
3041 {
3042 if (IsMacroTiled(pCfgTable->mode))
3043 {
3044 returnCode = ADDR_INVALIDPARAMS;
3045 }
3046 }
3047
3048 if (pMode)
3049 {
3050 *pMode = pCfgTable->mode;
3051 }
3052
3053 if (pType)
3054 {
3055 *pType = pCfgTable->type;
3056 }
3057 }
3058 }
3059
3060 return returnCode;
3061 }
3062
3063 /**
3064 ****************************************************************************************************
3065 * SiLib::ReadGbTileMode
3066 *
3067 * @brief
3068 * Convert GB_TILE_MODE HW value to TileConfig.
3069 * @return
3070 * NA.
3071 ****************************************************************************************************
3072 */
ReadGbTileMode(UINT_32 regValue,TileConfig * pCfg) const3073 VOID SiLib::ReadGbTileMode(
3074 UINT_32 regValue, ///< [in] GB_TILE_MODE register
3075 TileConfig* pCfg ///< [out] output structure
3076 ) const
3077 {
3078 GB_TILE_MODE gbTileMode;
3079 gbTileMode.val = regValue;
3080
3081 pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode);
3082 pCfg->info.bankHeight = 1 << gbTileMode.f.bank_height;
3083 pCfg->info.bankWidth = 1 << gbTileMode.f.bank_width;
3084 pCfg->info.banks = 1 << (gbTileMode.f.num_banks + 1);
3085 pCfg->info.macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
3086 pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
3087 pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
3088
3089 UINT_32 regArrayMode = gbTileMode.f.array_mode;
3090
3091 pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
3092
3093 if (regArrayMode == 8) //ARRAY_2D_TILED_XTHICK
3094 {
3095 pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
3096 }
3097 else if (regArrayMode >= 14) //ARRAY_3D_TILED_XTHICK
3098 {
3099 pCfg->mode = static_cast<AddrTileMode>(pCfg->mode + 3);
3100 }
3101 }
3102
3103 /**
3104 ****************************************************************************************************
3105 * SiLib::InitTileSettingTable
3106 *
3107 * @brief
3108 * Initialize the ADDR_TILE_CONFIG table.
3109 * @return
3110 * TRUE if tile table is correctly initialized
3111 ****************************************************************************************************
3112 */
InitTileSettingTable(const UINT_32 * pCfg,UINT_32 noOfEntries)3113 BOOL_32 SiLib::InitTileSettingTable(
3114 const UINT_32* pCfg, ///< [in] Pointer to table of tile configs
3115 UINT_32 noOfEntries ///< [in] Numbe of entries in the table above
3116 )
3117 {
3118 BOOL_32 initOk = TRUE;
3119
3120 ADDR_ASSERT(noOfEntries <= TileTableSize);
3121
3122 memset(m_tileTable, 0, sizeof(m_tileTable));
3123
3124 if (noOfEntries != 0)
3125 {
3126 m_noOfEntries = noOfEntries;
3127 }
3128 else
3129 {
3130 m_noOfEntries = TileTableSize;
3131 }
3132
3133 if (pCfg) // From Client
3134 {
3135 for (UINT_32 i = 0; i < m_noOfEntries; i++)
3136 {
3137 ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
3138 }
3139 }
3140 else
3141 {
3142 ADDR_ASSERT_ALWAYS();
3143 initOk = FALSE;
3144 }
3145
3146 if (initOk)
3147 {
3148 ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
3149 }
3150
3151 return initOk;
3152 }
3153
3154 /**
3155 ****************************************************************************************************
3156 * SiLib::HwlGetTileIndex
3157 *
3158 * @brief
3159 * Return the virtual/real index for given mode/type/info
3160 * @return
3161 * ADDR_OK if successful.
3162 ****************************************************************************************************
3163 */
HwlGetTileIndex(const ADDR_GET_TILEINDEX_INPUT * pIn,ADDR_GET_TILEINDEX_OUTPUT * pOut) const3164 ADDR_E_RETURNCODE SiLib::HwlGetTileIndex(
3165 const ADDR_GET_TILEINDEX_INPUT* pIn,
3166 ADDR_GET_TILEINDEX_OUTPUT* pOut) const
3167 {
3168 ADDR_E_RETURNCODE returnCode = ADDR_OK;
3169
3170 pOut->index = HwlPostCheckTileIndex(pIn->pTileInfo, pIn->tileMode, pIn->tileType);
3171
3172 return returnCode;
3173 }
3174
3175 /**
3176 ****************************************************************************************************
3177 * SiLib::HwlFmaskPreThunkSurfInfo
3178 *
3179 * @brief
3180 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask
3181 * @return
3182 * ADDR_E_RETURNCODE
3183 ****************************************************************************************************
3184 */
HwlFmaskPreThunkSurfInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pFmaskIn,const ADDR_COMPUTE_FMASK_INFO_OUTPUT * pFmaskOut,ADDR_COMPUTE_SURFACE_INFO_INPUT * pSurfIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pSurfOut) const3185 VOID SiLib::HwlFmaskPreThunkSurfInfo(
3186 const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn, ///< [in] Input of fmask info
3187 const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut, ///< [in] Output of fmask info
3188 ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn, ///< [out] Input of thunked surface info
3189 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut ///< [out] Output of thunked surface info
3190 ) const
3191 {
3192 pSurfIn->tileIndex = pFmaskIn->tileIndex;
3193 }
3194
3195 /**
3196 ****************************************************************************************************
3197 * SiLib::HwlFmaskPostThunkSurfInfo
3198 *
3199 * @brief
3200 * Copy hwl extra field after calling thunked ComputeSurfaceInfo
3201 * @return
3202 * ADDR_E_RETURNCODE
3203 ****************************************************************************************************
3204 */
HwlFmaskPostThunkSurfInfo(const ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pSurfOut,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pFmaskOut) const3205 VOID SiLib::HwlFmaskPostThunkSurfInfo(
3206 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut, ///< [in] Output of surface info
3207 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut ///< [out] Output of fmask info
3208 ) const
3209 {
3210 pFmaskOut->macroModeIndex = TileIndexInvalid;
3211 pFmaskOut->tileIndex = pSurfOut->tileIndex;
3212 }
3213
3214 /**
3215 ****************************************************************************************************
3216 * SiLib::HwlComputeFmaskBits
3217 * @brief
3218 * Computes fmask bits
3219 * @return
3220 * Fmask bits
3221 ****************************************************************************************************
3222 */
HwlComputeFmaskBits(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,UINT_32 * pNumSamples) const3223 UINT_32 SiLib::HwlComputeFmaskBits(
3224 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,
3225 UINT_32* pNumSamples
3226 ) const
3227 {
3228 UINT_32 numSamples = pIn->numSamples;
3229 UINT_32 numFrags = GetNumFragments(numSamples, pIn->numFrags);
3230 UINT_32 bpp;
3231
3232 if (numFrags != numSamples) // EQAA
3233 {
3234 ADDR_ASSERT(numFrags <= 8);
3235
3236 if (pIn->resolved == FALSE)
3237 {
3238 if (numFrags == 1)
3239 {
3240 bpp = 1;
3241 numSamples = numSamples == 16 ? 16 : 8;
3242 }
3243 else if (numFrags == 2)
3244 {
3245 ADDR_ASSERT(numSamples >= 4);
3246
3247 bpp = 2;
3248 numSamples = numSamples;
3249 }
3250 else if (numFrags == 4)
3251 {
3252 ADDR_ASSERT(numSamples >= 4);
3253
3254 bpp = 4;
3255 numSamples = numSamples;
3256 }
3257 else // numFrags == 8
3258 {
3259 ADDR_ASSERT(numSamples == 16);
3260
3261 bpp = 4;
3262 numSamples = numSamples;
3263 }
3264 }
3265 else
3266 {
3267 if (numFrags == 1)
3268 {
3269 bpp = (numSamples == 16) ? 16 : 8;
3270 numSamples = 1;
3271 }
3272 else if (numFrags == 2)
3273 {
3274 ADDR_ASSERT(numSamples >= 4);
3275
3276 bpp = numSamples*2;
3277 numSamples = 1;
3278 }
3279 else if (numFrags == 4)
3280 {
3281 ADDR_ASSERT(numSamples >= 4);
3282
3283 bpp = numSamples*4;
3284 numSamples = 1;
3285 }
3286 else // numFrags == 8
3287 {
3288 ADDR_ASSERT(numSamples >= 16);
3289
3290 bpp = 16*4;
3291 numSamples = 1;
3292 }
3293 }
3294 }
3295 else // Normal AA
3296 {
3297 if (pIn->resolved == FALSE)
3298 {
3299 bpp = ComputeFmaskNumPlanesFromNumSamples(numSamples);
3300 numSamples = numSamples == 2 ? 8 : numSamples;
3301 }
3302 else
3303 {
3304 // The same as 8XX
3305 bpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
3306 numSamples = 1; // 1x sample
3307 }
3308 }
3309
3310 SafeAssign(pNumSamples, numSamples);
3311
3312 return bpp;
3313 }
3314
3315 /**
3316 ****************************************************************************************************
3317 * SiLib::HwlOptimizeTileMode
3318 *
3319 * @brief
3320 * Optimize tile mode on SI
3321 *
3322 * @return
3323 * N/A
3324 *
3325 ****************************************************************************************************
3326 */
HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3327 VOID SiLib::HwlOptimizeTileMode(
3328 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
3329 ) const
3330 {
3331 AddrTileMode tileMode = pInOut->tileMode;
3332
3333 if ((pInOut->flags.needEquation == TRUE) &&
3334 (IsMacroTiled(tileMode) == TRUE) &&
3335 (pInOut->numSamples <= 1))
3336 {
3337 UINT_32 thickness = Thickness(tileMode);
3338
3339 if (thickness > 1)
3340 {
3341 tileMode = ADDR_TM_1D_TILED_THICK;
3342 }
3343 else if (pInOut->numSlices > 1)
3344 {
3345 tileMode = ADDR_TM_1D_TILED_THIN1;
3346 }
3347 else
3348 {
3349 tileMode = ADDR_TM_2D_TILED_THIN1;
3350 }
3351 }
3352
3353 if (tileMode != pInOut->tileMode)
3354 {
3355 pInOut->tileMode = tileMode;
3356 }
3357 }
3358
3359 /**
3360 ****************************************************************************************************
3361 * SiLib::HwlOverrideTileMode
3362 *
3363 * @brief
3364 * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI.
3365 *
3366 * @return
3367 * N/A
3368 *
3369 ****************************************************************************************************
3370 */
HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3371 VOID SiLib::HwlOverrideTileMode(
3372 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
3373 ) const
3374 {
3375 AddrTileMode tileMode = pInOut->tileMode;
3376
3377 switch (tileMode)
3378 {
3379 case ADDR_TM_PRT_TILED_THIN1:
3380 tileMode = ADDR_TM_2D_TILED_THIN1;
3381 break;
3382
3383 case ADDR_TM_PRT_TILED_THICK:
3384 tileMode = ADDR_TM_2D_TILED_THICK;
3385 break;
3386
3387 case ADDR_TM_PRT_2D_TILED_THICK:
3388 tileMode = ADDR_TM_2D_TILED_THICK;
3389 break;
3390
3391 case ADDR_TM_PRT_3D_TILED_THICK:
3392 tileMode = ADDR_TM_3D_TILED_THICK;
3393 break;
3394
3395 default:
3396 break;
3397 }
3398
3399 if (tileMode != pInOut->tileMode)
3400 {
3401 pInOut->tileMode = tileMode;
3402 // Only PRT tile modes are overridden for now. Revisit this once new modes are added above.
3403 pInOut->flags.prt = TRUE;
3404 }
3405 }
3406
3407 /**
3408 ****************************************************************************************************
3409 * SiLib::HwlSetPrtTileMode
3410 *
3411 * @brief
3412 * Set prt tile modes.
3413 *
3414 * @return
3415 * N/A
3416 *
3417 ****************************************************************************************************
3418 */
HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3419 VOID SiLib::HwlSetPrtTileMode(
3420 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
3421 ) const
3422 {
3423 pInOut->tileMode = ADDR_TM_2D_TILED_THIN1;
3424 pInOut->tileType = (pInOut->tileType == ADDR_DEPTH_SAMPLE_ORDER) ?
3425 ADDR_DEPTH_SAMPLE_ORDER : ADDR_NON_DISPLAYABLE;
3426 pInOut->flags.prt = TRUE;
3427 }
3428
3429 /**
3430 ****************************************************************************************************
3431 * SiLib::HwlSelectTileMode
3432 *
3433 * @brief
3434 * Select tile modes.
3435 *
3436 * @return
3437 * N/A
3438 *
3439 ****************************************************************************************************
3440 */
HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3441 VOID SiLib::HwlSelectTileMode(
3442 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in,out] input output structure
3443 ) const
3444 {
3445 AddrTileMode tileMode;
3446 AddrTileType tileType;
3447
3448 if (pInOut->flags.volume)
3449 {
3450 if (pInOut->numSlices >= 8)
3451 {
3452 tileMode = ADDR_TM_2D_TILED_XTHICK;
3453 }
3454 else if (pInOut->numSlices >= 4)
3455 {
3456 tileMode = ADDR_TM_2D_TILED_THICK;
3457 }
3458 else
3459 {
3460 tileMode = ADDR_TM_2D_TILED_THIN1;
3461 }
3462 tileType = ADDR_NON_DISPLAYABLE;
3463 }
3464 else
3465 {
3466 tileMode = ADDR_TM_2D_TILED_THIN1;
3467
3468 if (pInOut->flags.depth || pInOut->flags.stencil)
3469 {
3470 tileType = ADDR_DEPTH_SAMPLE_ORDER;
3471 }
3472 else if ((pInOut->bpp <= 32) ||
3473 (pInOut->flags.display == TRUE) ||
3474 (pInOut->flags.overlay == TRUE))
3475 {
3476 tileType = ADDR_DISPLAYABLE;
3477 }
3478 else
3479 {
3480 tileType = ADDR_NON_DISPLAYABLE;
3481 }
3482 }
3483
3484 if (pInOut->flags.prt)
3485 {
3486 tileMode = ADDR_TM_2D_TILED_THIN1;
3487 tileType = (tileType == ADDR_DISPLAYABLE) ? ADDR_NON_DISPLAYABLE : tileType;
3488 }
3489
3490 pInOut->tileMode = tileMode;
3491 pInOut->tileType = tileType;
3492
3493 // Optimize tile mode if possible
3494 pInOut->flags.opt4Space = TRUE;
3495
3496 // Optimize tile mode if possible
3497 OptimizeTileMode(pInOut);
3498
3499 HwlOverrideTileMode(pInOut);
3500 }
3501
3502 /**
3503 ****************************************************************************************************
3504 * SiLib::HwlComputeMaxBaseAlignments
3505 *
3506 * @brief
3507 * Gets maximum alignments
3508 * @return
3509 * maximum alignments
3510 ****************************************************************************************************
3511 */
HwlComputeMaxBaseAlignments() const3512 UINT_32 SiLib::HwlComputeMaxBaseAlignments() const
3513 {
3514 const UINT_32 pipes = HwlGetPipes(&m_tileTable[0].info);
3515
3516 // Initial size is 64 KiB for PRT.
3517 UINT_32 maxBaseAlign = 64 * 1024;
3518
3519 for (UINT_32 i = 0; i < m_noOfEntries; i++)
3520 {
3521 if ((IsMacroTiled(m_tileTable[i].mode) == TRUE) &&
3522 (IsPrtTileMode(m_tileTable[i].mode) == FALSE))
3523 {
3524 // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
3525 UINT_32 tileSize = Min(m_tileTable[i].info.tileSplitBytes,
3526 MicroTilePixels * 8 * 16);
3527
3528 UINT_32 baseAlign = tileSize * pipes * m_tileTable[i].info.banks *
3529 m_tileTable[i].info.bankWidth * m_tileTable[i].info.bankHeight;
3530
3531 if (baseAlign > maxBaseAlign)
3532 {
3533 maxBaseAlign = baseAlign;
3534 }
3535 }
3536 }
3537
3538 return maxBaseAlign;
3539 }
3540
3541 /**
3542 ****************************************************************************************************
3543 * SiLib::HwlComputeMaxMetaBaseAlignments
3544 *
3545 * @brief
3546 * Gets maximum alignments for metadata
3547 * @return
3548 * maximum alignments for metadata
3549 ****************************************************************************************************
3550 */
HwlComputeMaxMetaBaseAlignments() const3551 UINT_32 SiLib::HwlComputeMaxMetaBaseAlignments() const
3552 {
3553 UINT_32 maxPipe = 1;
3554
3555 for (UINT_32 i = 0; i < m_noOfEntries; i++)
3556 {
3557 maxPipe = Max(maxPipe, HwlGetPipes(&m_tileTable[i].info));
3558 }
3559
3560 return m_pipeInterleaveBytes * maxPipe;
3561 }
3562
3563 /**
3564 ****************************************************************************************************
3565 * SiLib::HwlComputeSurfaceAlignmentsMacroTiled
3566 *
3567 * @brief
3568 * Hardware layer function to compute alignment request for macro tile mode
3569 *
3570 * @return
3571 * N/A
3572 *
3573 ****************************************************************************************************
3574 */
HwlComputeSurfaceAlignmentsMacroTiled(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 mipLevel,UINT_32 numSamples,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3575 VOID SiLib::HwlComputeSurfaceAlignmentsMacroTiled(
3576 AddrTileMode tileMode, ///< [in] tile mode
3577 UINT_32 bpp, ///< [in] bits per pixel
3578 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
3579 UINT_32 mipLevel, ///< [in] mip level
3580 UINT_32 numSamples, ///< [in] number of samples
3581 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] Surface output
3582 ) const
3583 {
3584 if ((mipLevel == 0) && (flags.prt))
3585 {
3586 UINT_32 macroTileSize = pOut->blockWidth * pOut->blockHeight * numSamples * bpp / 8;
3587
3588 if (macroTileSize < PrtTileSize)
3589 {
3590 UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
3591
3592 ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
3593
3594 pOut->pitchAlign *= numMacroTiles;
3595 pOut->baseAlign *= numMacroTiles;
3596 }
3597 }
3598 }
3599
3600 /**
3601 ****************************************************************************************************
3602 * SiLib::InitEquationTable
3603 *
3604 * @brief
3605 * Initialize Equation table.
3606 *
3607 * @return
3608 * N/A
3609 ****************************************************************************************************
3610 */
InitEquationTable()3611 VOID SiLib::InitEquationTable()
3612 {
3613 ADDR_EQUATION_KEY equationKeyTable[EquationTableSize];
3614 memset(equationKeyTable, 0, sizeof(equationKeyTable));
3615
3616 memset(m_equationTable, 0, sizeof(m_equationTable));
3617
3618 memset(m_blockWidth, 0, sizeof(m_blockWidth));
3619
3620 memset(m_blockHeight, 0, sizeof(m_blockHeight));
3621
3622 memset(m_blockSlices, 0, sizeof(m_blockSlices));
3623
3624 // Loop all possible bpp
3625 for (UINT_32 log2ElementBytes = 0; log2ElementBytes < MaxNumElementBytes; log2ElementBytes++)
3626 {
3627 // Get bits per pixel
3628 UINT_32 bpp = 1 << (log2ElementBytes + 3);
3629
3630 // Loop all possible tile index
3631 for (INT_32 tileIndex = 0; tileIndex < static_cast<INT_32>(m_noOfEntries); tileIndex++)
3632 {
3633 UINT_32 equationIndex = ADDR_INVALID_EQUATION_INDEX;
3634
3635 TileConfig tileConfig = m_tileTable[tileIndex];
3636
3637 ADDR_SURFACE_FLAGS flags = {{0}};
3638
3639 // Compute tile info, hardcode numSamples to 1 because MSAA is not supported
3640 // in swizzle pattern equation
3641 HwlComputeMacroModeIndex(tileIndex, flags, bpp, 1, &tileConfig.info, NULL, NULL);
3642
3643 // Check if the input is supported
3644 if (IsEquationSupported(bpp, tileConfig, tileIndex, log2ElementBytes) == TRUE)
3645 {
3646 ADDR_EQUATION_KEY key = {{0}};
3647
3648 // Generate swizzle equation key from bpp and tile config
3649 key.fields.log2ElementBytes = log2ElementBytes;
3650 key.fields.tileMode = tileConfig.mode;
3651 // Treat depth micro tile type and non-display micro tile type as the same key
3652 // because they have the same equation actually
3653 key.fields.microTileType = (tileConfig.type == ADDR_DEPTH_SAMPLE_ORDER) ?
3654 ADDR_NON_DISPLAYABLE : tileConfig.type;
3655 key.fields.pipeConfig = tileConfig.info.pipeConfig;
3656 key.fields.numBanksLog2 = Log2(tileConfig.info.banks);
3657 key.fields.bankWidth = tileConfig.info.bankWidth;
3658 key.fields.bankHeight = tileConfig.info.bankHeight;
3659 key.fields.macroAspectRatio = tileConfig.info.macroAspectRatio;
3660 key.fields.prt = ((m_chipFamily == ADDR_CHIP_FAMILY_SI) &&
3661 ((1 << tileIndex) & SiPrtTileIndexMask)) ? 1 : 0;
3662
3663 // Find in the table if the equation has been built based on the key
3664 for (UINT_32 i = 0; i < m_numEquations; i++)
3665 {
3666 if (key.value == equationKeyTable[i].value)
3667 {
3668 equationIndex = i;
3669 break;
3670 }
3671 }
3672
3673 // If found, just fill the index into the lookup table and no need
3674 // to generate the equation again. Otherwise, generate the equation.
3675 if (equationIndex == ADDR_INVALID_EQUATION_INDEX)
3676 {
3677 ADDR_EQUATION equation;
3678 ADDR_E_RETURNCODE retCode;
3679
3680 memset(&equation, 0, sizeof(ADDR_EQUATION));
3681
3682 // Generate the equation
3683 if (IsMicroTiled(tileConfig.mode))
3684 {
3685 retCode = ComputeMicroTileEquation(log2ElementBytes,
3686 tileConfig.mode,
3687 tileConfig.type,
3688 &equation);
3689 }
3690 else
3691 {
3692 retCode = ComputeMacroTileEquation(log2ElementBytes,
3693 tileConfig.mode,
3694 tileConfig.type,
3695 &tileConfig.info,
3696 &equation);
3697 }
3698 // Only fill the equation into the table if the return code is ADDR_OK,
3699 // otherwise if the return code is not ADDR_OK, it indicates this is not
3700 // a valid input, we do nothing but just fill invalid equation index
3701 // into the lookup table.
3702 if (retCode == ADDR_OK)
3703 {
3704 equationIndex = m_numEquations;
3705 ADDR_ASSERT(equationIndex < EquationTableSize);
3706
3707 m_blockSlices[equationIndex] = Thickness(tileConfig.mode);
3708
3709 if (IsMicroTiled(tileConfig.mode))
3710 {
3711 m_blockWidth[equationIndex] = MicroTileWidth;
3712 m_blockHeight[equationIndex] = MicroTileHeight;
3713 }
3714 else
3715 {
3716 const ADDR_TILEINFO* pTileInfo = &tileConfig.info;
3717
3718 m_blockWidth[equationIndex] =
3719 HwlGetPipes(pTileInfo) * MicroTileWidth * pTileInfo->bankWidth *
3720 pTileInfo->macroAspectRatio;
3721 m_blockHeight[equationIndex] =
3722 MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
3723 pTileInfo->macroAspectRatio;
3724
3725 if (key.fields.prt)
3726 {
3727 UINT_32 macroTileSize =
3728 m_blockWidth[equationIndex] * m_blockHeight[equationIndex] *
3729 bpp / 8;
3730
3731 if (macroTileSize < PrtTileSize)
3732 {
3733 UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
3734
3735 ADDR_ASSERT(macroTileSize == (1u << equation.numBits));
3736 ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
3737
3738 UINT_32 numBits = Log2(numMacroTiles);
3739
3740 UINT_32 xStart = Log2(m_blockWidth[equationIndex]) +
3741 log2ElementBytes;
3742
3743 m_blockWidth[equationIndex] *= numMacroTiles;
3744
3745 for (UINT_32 i = 0; i < numBits; i++)
3746 {
3747 equation.addr[equation.numBits + i].valid = 1;
3748 equation.addr[equation.numBits + i].index = xStart + i;
3749 }
3750
3751 equation.numBits += numBits;
3752 }
3753 }
3754 }
3755
3756 equationKeyTable[equationIndex] = key;
3757 m_equationTable[equationIndex] = equation;
3758
3759 m_numEquations++;
3760 }
3761 }
3762 }
3763
3764 // Fill the index into the lookup table, if the combination is not supported
3765 // fill the invalid equation index
3766 m_equationLookupTable[log2ElementBytes][tileIndex] = equationIndex;
3767 }
3768
3769 if (m_chipFamily == ADDR_CHIP_FAMILY_SI)
3770 {
3771 // For tile index 3 which is shared between PRT depth and uncompressed depth
3772 m_uncompressDepthEqIndex = m_numEquations;
3773
3774 for (UINT_32 log2ElemBytes = 0; log2ElemBytes < MaxNumElementBytes; log2ElemBytes++)
3775 {
3776 TileConfig tileConfig = m_tileTable[3];
3777 ADDR_EQUATION equation;
3778 ADDR_E_RETURNCODE retCode;
3779
3780 memset(&equation, 0, sizeof(ADDR_EQUATION));
3781
3782 retCode = ComputeMacroTileEquation(log2ElemBytes,
3783 tileConfig.mode,
3784 tileConfig.type,
3785 &tileConfig.info,
3786 &equation);
3787
3788 if (retCode == ADDR_OK)
3789 {
3790 UINT_32 equationIndex = m_numEquations;
3791 ADDR_ASSERT(equationIndex < EquationTableSize);
3792
3793 m_blockSlices[equationIndex] = 1;
3794
3795 const ADDR_TILEINFO* pTileInfo = &tileConfig.info;
3796
3797 m_blockWidth[equationIndex] =
3798 HwlGetPipes(pTileInfo) * MicroTileWidth * pTileInfo->bankWidth *
3799 pTileInfo->macroAspectRatio;
3800 m_blockHeight[equationIndex] =
3801 MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
3802 pTileInfo->macroAspectRatio;
3803
3804 m_equationTable[equationIndex] = equation;
3805
3806 m_numEquations++;
3807 }
3808 }
3809 }
3810 }
3811 }
3812
3813 /**
3814 ****************************************************************************************************
3815 * SiLib::IsEquationSupported
3816 *
3817 * @brief
3818 * Check if it is supported for given bpp and tile config to generate a equation.
3819 *
3820 * @return
3821 * TRUE if supported
3822 ****************************************************************************************************
3823 */
IsEquationSupported(UINT_32 bpp,TileConfig tileConfig,INT_32 tileIndex,UINT_32 elementBytesLog2) const3824 BOOL_32 SiLib::IsEquationSupported(
3825 UINT_32 bpp, ///< Bits per pixel
3826 TileConfig tileConfig, ///< Tile config
3827 INT_32 tileIndex, ///< Tile index
3828 UINT_32 elementBytesLog2 ///< Log2 of element bytes
3829 ) const
3830 {
3831 BOOL_32 supported = TRUE;
3832
3833 // Linear tile mode is not supported in swizzle pattern equation
3834 if (IsLinear(tileConfig.mode))
3835 {
3836 supported = FALSE;
3837 }
3838 // These tile modes are for Tex2DArray and Tex3D which has depth (num_slice > 1) use,
3839 // which is not supported in swizzle pattern equation due to slice rotation
3840 else if ((tileConfig.mode == ADDR_TM_2D_TILED_THICK) ||
3841 (tileConfig.mode == ADDR_TM_2D_TILED_XTHICK) ||
3842 (tileConfig.mode == ADDR_TM_3D_TILED_THIN1) ||
3843 (tileConfig.mode == ADDR_TM_3D_TILED_THICK) ||
3844 (tileConfig.mode == ADDR_TM_3D_TILED_XTHICK))
3845 {
3846 supported = FALSE;
3847 }
3848 // Only 8bpp(stencil), 16bpp and 32bpp is supported for depth
3849 else if ((tileConfig.type == ADDR_DEPTH_SAMPLE_ORDER) && (bpp > 32))
3850 {
3851 supported = FALSE;
3852 }
3853 // Tile split is not supported in swizzle pattern equation
3854 else if (IsMacroTiled(tileConfig.mode))
3855 {
3856 UINT_32 thickness = Thickness(tileConfig.mode);
3857 if (((bpp >> 3) * MicroTilePixels * thickness) > tileConfig.info.tileSplitBytes)
3858 {
3859 supported = FALSE;
3860 }
3861
3862 if ((supported == TRUE) && (m_chipFamily == ADDR_CHIP_FAMILY_SI))
3863 {
3864 supported = m_EquationSupport[tileIndex][elementBytesLog2];
3865 }
3866 }
3867
3868 return supported;
3869 }
3870
3871 } // V1
3872 } // Addr
3873