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