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