• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  */
26 
27 /**
28 ****************************************************************************************************
29 * @file  addrlib.cpp
30 * @brief Contains the implementation for the Addr::Lib class.
31 ****************************************************************************************************
32 */
33 
34 #include "addrinterface.h"
35 #include "addrlib.h"
36 #include "addrcommon.h"
37 
38 #if defined(__APPLE__)
39 
div64_32(UINT_64 n,UINT_32 base)40 UINT_32 div64_32(UINT_64 n, UINT_32 base)
41 {
42     UINT_64 rem = n;
43     UINT_64 b = base;
44     UINT_64 res, d = 1;
45     UINT_32 high = rem >> 32;
46 
47     res = 0;
48     if (high >= base)
49     {
50         high /= base;
51         res = (UINT_64) high << 32;
52         rem -= (UINT_64) (high * base) << 32;
53     }
54 
55     while (((INT_64)b > 0) && (b < rem))
56     {
57         b = b + b;
58         d = d + d;
59     }
60 
61     do
62     {
63         if (rem >= b)
64         {
65             rem -= b;
66             res += d;
67         }
68         b >>= 1;
69         d >>= 1;
70     } while (d);
71 
72     n = res;
73     return rem;
74 }
75 
76 extern "C"
__umoddi3(UINT_64 n,UINT_32 base)77 UINT_32 __umoddi3(UINT_64 n, UINT_32 base)
78 {
79     return div64_32(n, base);
80 }
81 
82 #endif // __APPLE__
83 
84 namespace Addr
85 {
86 
87 ////////////////////////////////////////////////////////////////////////////////////////////////////
88 //                               Constructor/Destructor
89 ////////////////////////////////////////////////////////////////////////////////////////////////////
90 
91 /**
92 ****************************************************************************************************
93 *   Lib::Lib
94 *
95 *   @brief
96 *       Constructor for the AddrLib class
97 *
98 ****************************************************************************************************
99 */
Lib()100 Lib::Lib() :
101     m_class(BASE_ADDRLIB),
102     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
103     m_chipRevision(0),
104     m_version(ADDRLIB_VERSION),
105     m_pipes(0),
106     m_banks(0),
107     m_pipeInterleaveBytes(0),
108     m_rowSize(0),
109     m_minPitchAlignPixels(1),
110     m_maxSamples(8),
111     m_pElemLib(NULL)
112 {
113     m_configFlags.value = 0;
114 }
115 
116 /**
117 ****************************************************************************************************
118 *   Lib::Lib
119 *
120 *   @brief
121 *       Constructor for the AddrLib class with hClient as parameter
122 *
123 ****************************************************************************************************
124 */
Lib(const Client * pClient)125 Lib::Lib(const Client* pClient) :
126     Object(pClient),
127     m_class(BASE_ADDRLIB),
128     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
129     m_chipRevision(0),
130     m_version(ADDRLIB_VERSION),
131     m_pipes(0),
132     m_banks(0),
133     m_pipeInterleaveBytes(0),
134     m_rowSize(0),
135     m_minPitchAlignPixels(1),
136     m_maxSamples(8),
137     m_pElemLib(NULL)
138 {
139     m_configFlags.value = 0;
140 }
141 
142 /**
143 ****************************************************************************************************
144 *   Lib::~AddrLib
145 *
146 *   @brief
147 *       Destructor for the AddrLib class
148 *
149 ****************************************************************************************************
150 */
~Lib()151 Lib::~Lib()
152 {
153     if (m_pElemLib)
154     {
155         delete m_pElemLib;
156         m_pElemLib = NULL;
157     }
158 }
159 
160 
161 ////////////////////////////////////////////////////////////////////////////////////////////////////
162 //                               Initialization/Helper
163 ////////////////////////////////////////////////////////////////////////////////////////////////////
164 
165 /**
166 ****************************************************************************************************
167 *   Lib::Create
168 *
169 *   @brief
170 *       Creates and initializes AddrLib object.
171 *
172 *   @return
173 *       ADDR_E_RETURNCODE
174 ****************************************************************************************************
175 */
Create(const ADDR_CREATE_INPUT * pCreateIn,ADDR_CREATE_OUTPUT * pCreateOut)176 ADDR_E_RETURNCODE Lib::Create(
177     const ADDR_CREATE_INPUT* pCreateIn,     ///< [in] pointer to ADDR_CREATE_INPUT
178     ADDR_CREATE_OUTPUT*      pCreateOut)    ///< [out] pointer to ADDR_CREATE_OUTPUT
179 {
180     Lib* pLib = NULL;
181     ADDR_E_RETURNCODE returnCode = ADDR_OK;
182 
183     if (pCreateIn->createFlags.fillSizeFields == TRUE)
184     {
185         if ((pCreateIn->size != sizeof(ADDR_CREATE_INPUT)) ||
186             (pCreateOut->size != sizeof(ADDR_CREATE_OUTPUT)))
187         {
188             returnCode = ADDR_PARAMSIZEMISMATCH;
189         }
190     }
191 
192     if ((returnCode == ADDR_OK)                    &&
193         (pCreateIn->callbacks.allocSysMem != NULL) &&
194         (pCreateIn->callbacks.freeSysMem != NULL))
195     {
196         Client client = {
197             pCreateIn->hClient,
198             pCreateIn->callbacks
199         };
200 
201         switch (pCreateIn->chipEngine)
202         {
203             case CIASICIDGFXENGINE_SOUTHERNISLAND:
204                 switch (pCreateIn->chipFamily)
205                 {
206                     case FAMILY_SI:
207                         pLib = SiHwlInit(&client);
208                         break;
209                     case FAMILY_VI:
210                     case FAMILY_CZ: // VI based fusion(carrizo)
211                     case FAMILY_CI:
212                     case FAMILY_KV: // CI based fusion
213                         pLib = CiHwlInit(&client);
214                         break;
215                     default:
216                         ADDR_ASSERT_ALWAYS();
217                         break;
218                 }
219                 break;
220             case CIASICIDGFXENGINE_ARCTICISLAND:
221                 switch (pCreateIn->chipFamily)
222                 {
223                     case FAMILY_AI:
224                     case FAMILY_RV:
225                         pLib = Gfx9HwlInit(&client);
226                         break;
227                     default:
228                         ADDR_ASSERT_ALWAYS();
229                         break;
230                 }
231                 break;
232             default:
233                 ADDR_ASSERT_ALWAYS();
234                 break;
235         }
236     }
237 
238     if (pLib != NULL)
239     {
240         BOOL_32 initValid;
241 
242         // Pass createFlags to configFlags first since these flags may be overwritten
243         pLib->m_configFlags.noCubeMipSlicesPad  = pCreateIn->createFlags.noCubeMipSlicesPad;
244         pLib->m_configFlags.fillSizeFields      = pCreateIn->createFlags.fillSizeFields;
245         pLib->m_configFlags.useTileIndex        = pCreateIn->createFlags.useTileIndex;
246         pLib->m_configFlags.useCombinedSwizzle  = pCreateIn->createFlags.useCombinedSwizzle;
247         pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;
248         pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;
249         pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
250         pLib->m_configFlags.disableLinearOpt    = FALSE;
251 
252         pLib->SetChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
253 
254         pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);
255 
256         // Global parameters initialized and remaining configFlags bits are set as well
257         initValid = pLib->HwlInitGlobalParams(pCreateIn);
258 
259         if (initValid)
260         {
261             pLib->m_pElemLib = ElemLib::Create(pLib);
262         }
263         else
264         {
265             pLib->m_pElemLib = NULL; // Don't go on allocating element lib
266             returnCode = ADDR_INVALIDGBREGVALUES;
267         }
268 
269         if (pLib->m_pElemLib == NULL)
270         {
271             delete pLib;
272             pLib = NULL;
273             ADDR_ASSERT_ALWAYS();
274         }
275         else
276         {
277             pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);
278         }
279     }
280 
281     pCreateOut->hLib = pLib;
282 
283     if ((pLib != NULL) &&
284         (returnCode == ADDR_OK))
285     {
286         pCreateOut->numEquations =
287             pLib->HwlGetEquationTableInfo(&pCreateOut->pEquationTable);
288     }
289 
290     if ((pLib == NULL) &&
291         (returnCode == ADDR_OK))
292     {
293         // Unknown failures, we return the general error code
294         returnCode = ADDR_ERROR;
295     }
296 
297     return returnCode;
298 }
299 
300 /**
301 ****************************************************************************************************
302 *   Lib::SetChipFamily
303 *
304 *   @brief
305 *       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
306 *   @return
307 *      N/A
308 ****************************************************************************************************
309 */
SetChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)310 VOID Lib::SetChipFamily(
311     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
312     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
313 {
314     ChipFamily family = HwlConvertChipFamily(uChipFamily, uChipRevision);
315 
316     ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);
317 
318     m_chipFamily   = family;
319     m_chipRevision = uChipRevision;
320 }
321 
322 /**
323 ****************************************************************************************************
324 *   Lib::SetMinPitchAlignPixels
325 *
326 *   @brief
327 *       Set m_minPitchAlignPixels with input param
328 *
329 *   @return
330 *      N/A
331 ****************************************************************************************************
332 */
SetMinPitchAlignPixels(UINT_32 minPitchAlignPixels)333 VOID Lib::SetMinPitchAlignPixels(
334     UINT_32 minPitchAlignPixels)    ///< [in] minmum pitch alignment in pixels
335 {
336     m_minPitchAlignPixels = (minPitchAlignPixels == 0) ? 1 : minPitchAlignPixels;
337 }
338 
339 /**
340 ****************************************************************************************************
341 *   Lib::GetLib
342 *
343 *   @brief
344 *       Get AddrLib pointer
345 *
346 *   @return
347 *      An AddrLib class pointer
348 ****************************************************************************************************
349 */
GetLib(ADDR_HANDLE hLib)350 Lib* Lib::GetLib(
351     ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
352 {
353     return static_cast<Addr::Lib*>(hLib);
354 }
355 
356 /**
357 ****************************************************************************************************
358 *   Lib::GetMaxAlignments
359 *
360 *   @brief
361 *       Gets maximum alignments
362 *
363 *   @return
364 *       ADDR_E_RETURNCODE
365 ****************************************************************************************************
366 */
GetMaxAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT * pOut) const367 ADDR_E_RETURNCODE Lib::GetMaxAlignments(
368     ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut    ///< [out] output structure
369     ) const
370 {
371     ADDR_E_RETURNCODE returnCode = ADDR_OK;
372 
373     if (GetFillSizeFieldsFlags() == TRUE)
374     {
375         if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))
376         {
377             returnCode = ADDR_PARAMSIZEMISMATCH;
378         }
379     }
380 
381     if (returnCode == ADDR_OK)
382     {
383         returnCode = HwlGetMaxAlignments(pOut);
384     }
385 
386     return returnCode;
387 }
388 
389 /**
390 ****************************************************************************************************
391 *   Lib::Bits2Number
392 *
393 *   @brief
394 *       Cat a array of binary bit to a number
395 *
396 *   @return
397 *       The number combined with the array of bits
398 ****************************************************************************************************
399 */
Bits2Number(UINT_32 bitNum,...)400 UINT_32 Lib::Bits2Number(
401     UINT_32 bitNum,     ///< [in] how many bits
402     ...)                ///< [in] varaible bits value starting from MSB
403 {
404     UINT_32 number = 0;
405     UINT_32 i;
406     va_list bits_ptr;
407 
408     va_start(bits_ptr, bitNum);
409 
410     for(i = 0; i < bitNum; i++)
411     {
412         number |= va_arg(bits_ptr, UINT_32);
413         number <<= 1;
414     }
415 
416     number >>= 1;
417 
418     va_end(bits_ptr);
419 
420     return number;
421 }
422 
423 
424 ////////////////////////////////////////////////////////////////////////////////////////////////////
425 //                               Element lib
426 ////////////////////////////////////////////////////////////////////////////////////////////////////
427 
428 
429 /**
430 ****************************************************************************************************
431 *   Lib::Flt32ToColorPixel
432 *
433 *   @brief
434 *       Convert a FLT_32 value to a depth/stencil pixel value
435 *   @return
436 *       ADDR_E_RETURNCODE
437 ****************************************************************************************************
438 */
Flt32ToDepthPixel(const ELEM_FLT32TODEPTHPIXEL_INPUT * pIn,ELEM_FLT32TODEPTHPIXEL_OUTPUT * pOut) const439 ADDR_E_RETURNCODE Lib::Flt32ToDepthPixel(
440     const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
441     ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
442 {
443     ADDR_E_RETURNCODE returnCode = ADDR_OK;
444 
445     if (GetFillSizeFieldsFlags() == TRUE)
446     {
447         if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
448             (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
449         {
450             returnCode = ADDR_PARAMSIZEMISMATCH;
451         }
452     }
453 
454     if (returnCode == ADDR_OK)
455     {
456         GetElemLib()->Flt32ToDepthPixel(pIn->format, pIn->comps, pOut->pPixel);
457 
458         UINT_32 depthBase = 0;
459         UINT_32 stencilBase = 0;
460         UINT_32 depthBits = 0;
461         UINT_32 stencilBits = 0;
462 
463         switch (pIn->format)
464         {
465             case ADDR_DEPTH_16:
466                 depthBits = 16;
467                 break;
468             case ADDR_DEPTH_X8_24:
469             case ADDR_DEPTH_8_24:
470             case ADDR_DEPTH_X8_24_FLOAT:
471             case ADDR_DEPTH_8_24_FLOAT:
472                 depthBase = 8;
473                 depthBits = 24;
474                 stencilBits = 8;
475                 break;
476             case ADDR_DEPTH_32_FLOAT:
477                 depthBits = 32;
478                 break;
479             case ADDR_DEPTH_X24_8_32_FLOAT:
480                 depthBase = 8;
481                 depthBits = 32;
482                 stencilBits = 8;
483                 break;
484             default:
485                 break;
486         }
487 
488         // Overwrite base since R800 has no "tileBase"
489         if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
490         {
491             depthBase = 0;
492             stencilBase = 0;
493         }
494 
495         depthBase *= 64;
496         stencilBase *= 64;
497 
498         pOut->stencilBase = stencilBase;
499         pOut->depthBase = depthBase;
500         pOut->depthBits = depthBits;
501         pOut->stencilBits = stencilBits;
502     }
503 
504     return returnCode;
505 }
506 
507 /**
508 ****************************************************************************************************
509 *   Lib::Flt32ToColorPixel
510 *
511 *   @brief
512 *       Convert a FLT_32 value to a red/green/blue/alpha pixel value
513 *   @return
514 *       ADDR_E_RETURNCODE
515 ****************************************************************************************************
516 */
Flt32ToColorPixel(const ELEM_FLT32TOCOLORPIXEL_INPUT * pIn,ELEM_FLT32TOCOLORPIXEL_OUTPUT * pOut) const517 ADDR_E_RETURNCODE Lib::Flt32ToColorPixel(
518     const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
519     ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
520 {
521     ADDR_E_RETURNCODE returnCode = ADDR_OK;
522 
523     if (GetFillSizeFieldsFlags() == TRUE)
524     {
525         if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
526             (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
527         {
528             returnCode = ADDR_PARAMSIZEMISMATCH;
529         }
530     }
531 
532     if (returnCode == ADDR_OK)
533     {
534         GetElemLib()->Flt32ToColorPixel(pIn->format,
535                                         pIn->surfNum,
536                                         pIn->surfSwap,
537                                         pIn->comps,
538                                         pOut->pPixel);
539     }
540 
541     return returnCode;
542 }
543 
544 
545 /**
546 ****************************************************************************************************
547 *   Lib::GetExportNorm
548 *
549 *   @brief
550 *       Check one format can be EXPORT_NUM
551 *   @return
552 *       TRUE if EXPORT_NORM can be used
553 ****************************************************************************************************
554 */
GetExportNorm(const ELEM_GETEXPORTNORM_INPUT * pIn) const555 BOOL_32 Lib::GetExportNorm(
556     const ELEM_GETEXPORTNORM_INPUT* pIn) const
557 {
558     ADDR_E_RETURNCODE returnCode = ADDR_OK;
559 
560     BOOL_32 enabled = FALSE;
561 
562     if (GetFillSizeFieldsFlags() == TRUE)
563     {
564         if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
565         {
566             returnCode = ADDR_PARAMSIZEMISMATCH;
567         }
568     }
569 
570     if (returnCode == ADDR_OK)
571     {
572         enabled = GetElemLib()->PixGetExportNorm(pIn->format, pIn->num, pIn->swap);
573     }
574 
575     return enabled;
576 }
577 
578 } // Addr
579