1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2007-2018 Advanced Micro Devices, Inc.
3b8e80941Smrg * All Rights Reserved.
4b8e80941Smrg *
5b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining
6b8e80941Smrg * a copy of this software and associated documentation files (the
7b8e80941Smrg * "Software"), to deal in the Software without restriction, including
8b8e80941Smrg * without limitation the rights to use, copy, modify, merge, publish,
9b8e80941Smrg * distribute, sub license, and/or sell copies of the Software, and to
10b8e80941Smrg * permit persons to whom the Software is furnished to do so, subject to
11b8e80941Smrg * the following conditions:
12b8e80941Smrg *
13b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14b8e80941Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15b8e80941Smrg * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16b8e80941Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17b8e80941Smrg * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19b8e80941Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20b8e80941Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
21b8e80941Smrg *
22b8e80941Smrg * The above copyright notice and this permission notice (including the
23b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions
24b8e80941Smrg * of the Software.
25b8e80941Smrg */
26b8e80941Smrg
27b8e80941Smrg/**
28b8e80941Smrg****************************************************************************************************
29b8e80941Smrg* @file  ciaddrlib.cpp
30b8e80941Smrg* @brief Contains the implementation for the CiLib class.
31b8e80941Smrg****************************************************************************************************
32b8e80941Smrg*/
33b8e80941Smrg
34b8e80941Smrg#include "ciaddrlib.h"
35b8e80941Smrg
36b8e80941Smrg#include "si_gb_reg.h"
37b8e80941Smrg
38b8e80941Smrg#include "amdgpu_asic_addr.h"
39b8e80941Smrg
40b8e80941Smrg////////////////////////////////////////////////////////////////////////////////////////////////////
41b8e80941Smrg////////////////////////////////////////////////////////////////////////////////////////////////////
42b8e80941Smrg
43b8e80941Smrgnamespace Addr
44b8e80941Smrg{
45b8e80941Smrg
46b8e80941Smrg/**
47b8e80941Smrg****************************************************************************************************
48b8e80941Smrg*   CiHwlInit
49b8e80941Smrg*
50b8e80941Smrg*   @brief
51b8e80941Smrg*       Creates an CiLib object.
52b8e80941Smrg*
53b8e80941Smrg*   @return
54b8e80941Smrg*       Returns an CiLib object pointer.
55b8e80941Smrg****************************************************************************************************
56b8e80941Smrg*/
57b8e80941SmrgLib* CiHwlInit(const Client* pClient)
58b8e80941Smrg{
59b8e80941Smrg    return V1::CiLib::CreateObj(pClient);
60b8e80941Smrg}
61b8e80941Smrg
62b8e80941Smrgnamespace V1
63b8e80941Smrg{
64b8e80941Smrg
65b8e80941Smrg/**
66b8e80941Smrg****************************************************************************************************
67b8e80941Smrg*   Mask
68b8e80941Smrg*
69b8e80941Smrg*   @brief
70b8e80941Smrg*       Gets a mask of "width"
71b8e80941Smrg*   @return
72b8e80941Smrg*       Bit mask
73b8e80941Smrg****************************************************************************************************
74b8e80941Smrg*/
75b8e80941Smrgstatic UINT_64 Mask(
76b8e80941Smrg    UINT_32 width)  ///< Width of bits
77b8e80941Smrg{
78b8e80941Smrg    UINT_64 ret;
79b8e80941Smrg
80b8e80941Smrg    if (width >= sizeof(UINT_64)*8)
81b8e80941Smrg    {
82b8e80941Smrg        ret = ~((UINT_64) 0);
83b8e80941Smrg    }
84b8e80941Smrg    else
85b8e80941Smrg    {
86b8e80941Smrg        return (((UINT_64) 1) << width) - 1;
87b8e80941Smrg    }
88b8e80941Smrg    return ret;
89b8e80941Smrg}
90b8e80941Smrg
91b8e80941Smrg/**
92b8e80941Smrg****************************************************************************************************
93b8e80941Smrg*   GetBits
94b8e80941Smrg*
95b8e80941Smrg*   @brief
96b8e80941Smrg*       Gets bits within a range of [msb, lsb]
97b8e80941Smrg*   @return
98b8e80941Smrg*       Bits of this range
99b8e80941Smrg****************************************************************************************************
100b8e80941Smrg*/
101b8e80941Smrgstatic UINT_64 GetBits(
102b8e80941Smrg    UINT_64 bits,   ///< Source bits
103b8e80941Smrg    UINT_32 msb,    ///< Most signicant bit
104b8e80941Smrg    UINT_32 lsb)    ///< Least signicant bit
105b8e80941Smrg{
106b8e80941Smrg    UINT_64 ret = 0;
107b8e80941Smrg
108b8e80941Smrg    if (msb >= lsb)
109b8e80941Smrg    {
110b8e80941Smrg        ret = (bits >> lsb) & (Mask(1 + msb - lsb));
111b8e80941Smrg    }
112b8e80941Smrg    return ret;
113b8e80941Smrg}
114b8e80941Smrg
115b8e80941Smrg/**
116b8e80941Smrg****************************************************************************************************
117b8e80941Smrg*   RemoveBits
118b8e80941Smrg*
119b8e80941Smrg*   @brief
120b8e80941Smrg*       Removes bits within the range of [msb, lsb]
121b8e80941Smrg*   @return
122b8e80941Smrg*       Modified bits
123b8e80941Smrg****************************************************************************************************
124b8e80941Smrg*/
125b8e80941Smrgstatic UINT_64 RemoveBits(
126b8e80941Smrg    UINT_64 bits,   ///< Source bits
127b8e80941Smrg    UINT_32 msb,    ///< Most signicant bit
128b8e80941Smrg    UINT_32 lsb)    ///< Least signicant bit
129b8e80941Smrg{
130b8e80941Smrg    UINT_64 ret = bits;
131b8e80941Smrg
132b8e80941Smrg    if (msb >= lsb)
133b8e80941Smrg    {
134b8e80941Smrg        ret = GetBits(bits, lsb - 1, 0) // low bits
135b8e80941Smrg            | (GetBits(bits, 8 * sizeof(bits) - 1, msb + 1) << lsb); //high bits
136b8e80941Smrg    }
137b8e80941Smrg    return ret;
138b8e80941Smrg}
139b8e80941Smrg
140b8e80941Smrg/**
141b8e80941Smrg****************************************************************************************************
142b8e80941Smrg*   InsertBits
143b8e80941Smrg*
144b8e80941Smrg*   @brief
145b8e80941Smrg*       Inserts new bits into the range of [msb, lsb]
146b8e80941Smrg*   @return
147b8e80941Smrg*       Modified bits
148b8e80941Smrg****************************************************************************************************
149b8e80941Smrg*/
150b8e80941Smrgstatic UINT_64 InsertBits(
151b8e80941Smrg    UINT_64 bits,       ///< Source bits
152b8e80941Smrg    UINT_64 newBits,    ///< New bits to be inserted
153b8e80941Smrg    UINT_32 msb,        ///< Most signicant bit
154b8e80941Smrg    UINT_32 lsb)        ///< Least signicant bit
155b8e80941Smrg{
156b8e80941Smrg    UINT_64 ret = bits;
157b8e80941Smrg
158b8e80941Smrg    if (msb >= lsb)
159b8e80941Smrg    {
160b8e80941Smrg        ret = GetBits(bits, lsb - 1, 0) // old low bitss
161b8e80941Smrg             | (GetBits(newBits, msb - lsb, 0) << lsb) //new bits
162b8e80941Smrg             | (GetBits(bits, 8 * sizeof(bits) - 1, lsb) << (msb + 1)); //old high bits
163b8e80941Smrg    }
164b8e80941Smrg    return ret;
165b8e80941Smrg}
166b8e80941Smrg
167b8e80941Smrg/**
168b8e80941Smrg****************************************************************************************************
169b8e80941Smrg*   CiLib::CiLib
170b8e80941Smrg*
171b8e80941Smrg*   @brief
172b8e80941Smrg*       Constructor
173b8e80941Smrg*
174b8e80941Smrg****************************************************************************************************
175b8e80941Smrg*/
176b8e80941SmrgCiLib::CiLib(const Client* pClient)
177b8e80941Smrg    :
178b8e80941Smrg    SiLib(pClient),
179b8e80941Smrg    m_noOfMacroEntries(0),
180b8e80941Smrg    m_allowNonDispThickModes(FALSE)
181b8e80941Smrg{
182b8e80941Smrg    m_class = CI_ADDRLIB;
183b8e80941Smrg}
184b8e80941Smrg
185b8e80941Smrg/**
186b8e80941Smrg****************************************************************************************************
187b8e80941Smrg*   CiLib::~CiLib
188b8e80941Smrg*
189b8e80941Smrg*   @brief
190b8e80941Smrg*       Destructor
191b8e80941Smrg****************************************************************************************************
192b8e80941Smrg*/
193b8e80941SmrgCiLib::~CiLib()
194b8e80941Smrg{
195b8e80941Smrg}
196b8e80941Smrg
197b8e80941Smrg/**
198b8e80941Smrg****************************************************************************************************
199b8e80941Smrg*   CiLib::HwlComputeDccInfo
200b8e80941Smrg*
201b8e80941Smrg*   @brief
202b8e80941Smrg*       Compute DCC key size, base alignment
203b8e80941Smrg*   @return
204b8e80941Smrg*       ADDR_E_RETURNCODE
205b8e80941Smrg****************************************************************************************************
206b8e80941Smrg*/
207b8e80941SmrgADDR_E_RETURNCODE CiLib::HwlComputeDccInfo(
208b8e80941Smrg    const ADDR_COMPUTE_DCCINFO_INPUT*  pIn,
209b8e80941Smrg    ADDR_COMPUTE_DCCINFO_OUTPUT*       pOut) const
210b8e80941Smrg{
211b8e80941Smrg    ADDR_E_RETURNCODE returnCode = ADDR_OK;
212b8e80941Smrg
213b8e80941Smrg    if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode))
214b8e80941Smrg    {
215b8e80941Smrg        UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8;
216b8e80941Smrg
217b8e80941Smrg        ADDR_ASSERT(0 == (pIn->colorSurfSize & 0xff));
218b8e80941Smrg
219b8e80941Smrg        if (pIn->numSamples > 1)
220b8e80941Smrg        {
221b8e80941Smrg            UINT_32 tileSizePerSample = BITS_TO_BYTES(pIn->bpp * MicroTileWidth * MicroTileHeight);
222b8e80941Smrg            UINT_32 samplesPerSplit  = pIn->tileInfo.tileSplitBytes / tileSizePerSample;
223b8e80941Smrg
224b8e80941Smrg            if (samplesPerSplit < pIn->numSamples)
225b8e80941Smrg            {
226b8e80941Smrg                UINT_32 numSplits = pIn->numSamples / samplesPerSplit;
227b8e80941Smrg                UINT_32 fastClearBaseAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
228b8e80941Smrg
229b8e80941Smrg                ADDR_ASSERT(IsPow2(fastClearBaseAlign));
230b8e80941Smrg
231b8e80941Smrg                dccFastClearSize /= numSplits;
232b8e80941Smrg
233b8e80941Smrg                if (0 != (dccFastClearSize & (fastClearBaseAlign - 1)))
234b8e80941Smrg                {
235b8e80941Smrg                    // Disable dcc fast clear
236b8e80941Smrg                    // if key size of fisrt sample split is not pipe*interleave aligned
237b8e80941Smrg                    dccFastClearSize = 0;
238b8e80941Smrg                }
239b8e80941Smrg            }
240b8e80941Smrg        }
241b8e80941Smrg
242b8e80941Smrg        pOut->dccRamSize          = pIn->colorSurfSize >> 8;
243b8e80941Smrg        pOut->dccRamBaseAlign     = pIn->tileInfo.banks *
244b8e80941Smrg                                    HwlGetPipes(&pIn->tileInfo) *
245b8e80941Smrg                                    m_pipeInterleaveBytes;
246b8e80941Smrg        pOut->dccFastClearSize    = dccFastClearSize;
247b8e80941Smrg        pOut->dccRamSizeAligned   = TRUE;
248b8e80941Smrg
249b8e80941Smrg        ADDR_ASSERT(IsPow2(pOut->dccRamBaseAlign));
250b8e80941Smrg
251b8e80941Smrg        if (0 == (pOut->dccRamSize & (pOut->dccRamBaseAlign - 1)))
252b8e80941Smrg        {
253b8e80941Smrg            pOut->subLvlCompressible = TRUE;
254b8e80941Smrg        }
255b8e80941Smrg        else
256b8e80941Smrg        {
257b8e80941Smrg            UINT_64 dccRamSizeAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
258b8e80941Smrg
259b8e80941Smrg            if (pOut->dccRamSize == pOut->dccFastClearSize)
260b8e80941Smrg            {
261b8e80941Smrg                pOut->dccFastClearSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
262b8e80941Smrg            }
263b8e80941Smrg            if ((pOut->dccRamSize & (dccRamSizeAlign - 1)) != 0)
264b8e80941Smrg            {
265b8e80941Smrg                pOut->dccRamSizeAligned = FALSE;
266b8e80941Smrg            }
267b8e80941Smrg            pOut->dccRamSize          = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
268b8e80941Smrg            pOut->subLvlCompressible  = FALSE;
269b8e80941Smrg        }
270b8e80941Smrg    }
271b8e80941Smrg    else
272b8e80941Smrg    {
273b8e80941Smrg        returnCode = ADDR_NOTSUPPORTED;
274b8e80941Smrg    }
275b8e80941Smrg
276b8e80941Smrg    return returnCode;
277b8e80941Smrg}
278b8e80941Smrg
279b8e80941Smrg/**
280b8e80941Smrg****************************************************************************************************
281b8e80941Smrg*   CiLib::HwlComputeCmaskAddrFromCoord
282b8e80941Smrg*
283b8e80941Smrg*   @brief
284b8e80941Smrg*       Compute tc compatible Cmask address from fmask ram address
285b8e80941Smrg*
286b8e80941Smrg*   @return
287b8e80941Smrg*       ADDR_E_RETURNCODE
288b8e80941Smrg****************************************************************************************************
289b8e80941Smrg*/
290b8e80941SmrgADDR_E_RETURNCODE CiLib::HwlComputeCmaskAddrFromCoord(
291b8e80941Smrg    const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*  pIn,  ///< [in] fmask addr/bpp/tile input
292b8e80941Smrg    ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*       pOut  ///< [out] cmask address
293b8e80941Smrg    ) const
294b8e80941Smrg{
295b8e80941Smrg    ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
296b8e80941Smrg
297b8e80941Smrg    if ((m_settings.isVolcanicIslands == TRUE) &&
298b8e80941Smrg        (pIn->flags.tcCompatible == TRUE))
299b8e80941Smrg    {
300b8e80941Smrg        UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
301b8e80941Smrg        UINT_32 numOfBanks   = pIn->pTileInfo->banks;
302b8e80941Smrg        UINT_64 fmaskAddress = pIn->fmaskAddr;
303b8e80941Smrg        UINT_32 elemBits     = pIn->bpp;
304b8e80941Smrg        UINT_32 blockByte    = 64 * elemBits / 8;
305b8e80941Smrg        UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(fmaskAddress,
306b8e80941Smrg                                                                    0,
307b8e80941Smrg                                                                    0,
308b8e80941Smrg                                                                    4,   // cmask 4 bits
309b8e80941Smrg                                                                    elemBits,
310b8e80941Smrg                                                                    blockByte,
311b8e80941Smrg                                                                    m_pipeInterleaveBytes,
312b8e80941Smrg                                                                    numOfPipes,
313b8e80941Smrg                                                                    numOfBanks,
314b8e80941Smrg                                                                    1);
315b8e80941Smrg        pOut->addr = (metaNibbleAddress >> 1);
316b8e80941Smrg        pOut->bitPosition = (metaNibbleAddress % 2) ? 4 : 0;
317b8e80941Smrg        returnCode = ADDR_OK;
318b8e80941Smrg    }
319b8e80941Smrg
320b8e80941Smrg    return returnCode;
321b8e80941Smrg}
322b8e80941Smrg
323b8e80941Smrg/**
324b8e80941Smrg****************************************************************************************************
325b8e80941Smrg*   CiLib::HwlComputeHtileAddrFromCoord
326b8e80941Smrg*
327b8e80941Smrg*   @brief
328b8e80941Smrg*       Compute tc compatible Htile address from depth/stencil address
329b8e80941Smrg*
330b8e80941Smrg*   @return
331b8e80941Smrg*       ADDR_E_RETURNCODE
332b8e80941Smrg****************************************************************************************************
333b8e80941Smrg*/
334b8e80941SmrgADDR_E_RETURNCODE CiLib::HwlComputeHtileAddrFromCoord(
335b8e80941Smrg    const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*  pIn,  ///< [in] depth/stencil addr/bpp/tile input
336b8e80941Smrg    ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*       pOut  ///< [out] htile address
337b8e80941Smrg    ) const
338b8e80941Smrg{
339b8e80941Smrg    ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
340b8e80941Smrg
341b8e80941Smrg    if ((m_settings.isVolcanicIslands == TRUE) &&
342b8e80941Smrg        (pIn->flags.tcCompatible == TRUE))
343b8e80941Smrg    {
344b8e80941Smrg        UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
345b8e80941Smrg        UINT_32 numOfBanks   = pIn->pTileInfo->banks;
346b8e80941Smrg        UINT_64 zStencilAddr = pIn->zStencilAddr;
347b8e80941Smrg        UINT_32 elemBits     = pIn->bpp;
348b8e80941Smrg        UINT_32 blockByte    = 64 * elemBits / 8;
349b8e80941Smrg        UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(zStencilAddr,
350b8e80941Smrg                                                                    0,
351b8e80941Smrg                                                                    0,
352b8e80941Smrg                                                                    32,  // htile 32 bits
353b8e80941Smrg                                                                    elemBits,
354b8e80941Smrg                                                                    blockByte,
355b8e80941Smrg                                                                    m_pipeInterleaveBytes,
356b8e80941Smrg                                                                    numOfPipes,
357b8e80941Smrg                                                                    numOfBanks,
358b8e80941Smrg                                                                    1);
359b8e80941Smrg        pOut->addr = (metaNibbleAddress >> 1);
360b8e80941Smrg        pOut->bitPosition = 0;
361b8e80941Smrg        returnCode = ADDR_OK;
362b8e80941Smrg    }
363b8e80941Smrg
364b8e80941Smrg    return returnCode;
365b8e80941Smrg}
366b8e80941Smrg
367b8e80941Smrg/**
368b8e80941Smrg****************************************************************************************************
369b8e80941Smrg*   CiLib::HwlConvertChipFamily
370b8e80941Smrg*
371b8e80941Smrg*   @brief
372b8e80941Smrg*       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
373b8e80941Smrg*   @return
374b8e80941Smrg*       ChipFamily
375b8e80941Smrg****************************************************************************************************
376b8e80941Smrg*/
377b8e80941SmrgChipFamily CiLib::HwlConvertChipFamily(
378b8e80941Smrg    UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
379b8e80941Smrg    UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
380b8e80941Smrg{
381b8e80941Smrg    ChipFamily family = ADDR_CHIP_FAMILY_CI;
382b8e80941Smrg
383b8e80941Smrg    switch (uChipFamily)
384b8e80941Smrg    {
385b8e80941Smrg        case FAMILY_CI:
386b8e80941Smrg            m_settings.isSeaIsland  = 1;
387b8e80941Smrg            m_settings.isBonaire    = ASICREV_IS_BONAIRE_M(uChipRevision);
388b8e80941Smrg            m_settings.isHawaii     = ASICREV_IS_HAWAII_P(uChipRevision);
389b8e80941Smrg            break;
390b8e80941Smrg        case FAMILY_KV:
391b8e80941Smrg            m_settings.isKaveri     = 1;
392b8e80941Smrg            m_settings.isSpectre    = ASICREV_IS_SPECTRE(uChipRevision);
393b8e80941Smrg            m_settings.isSpooky     = ASICREV_IS_SPOOKY(uChipRevision);
394b8e80941Smrg            m_settings.isKalindi    = ASICREV_IS_KALINDI(uChipRevision);
395b8e80941Smrg            break;
396b8e80941Smrg        case FAMILY_VI:
397b8e80941Smrg            m_settings.isVolcanicIslands = 1;
398b8e80941Smrg            m_settings.isIceland         = ASICREV_IS_ICELAND_M(uChipRevision);
399b8e80941Smrg            m_settings.isTonga           = ASICREV_IS_TONGA_P(uChipRevision);
400b8e80941Smrg            m_settings.isFiji            = ASICREV_IS_FIJI_P(uChipRevision);
401b8e80941Smrg            m_settings.isPolaris10       = ASICREV_IS_POLARIS10_P(uChipRevision);
402b8e80941Smrg            m_settings.isPolaris11       = ASICREV_IS_POLARIS11_M(uChipRevision);
403b8e80941Smrg            m_settings.isPolaris12       = ASICREV_IS_POLARIS12_V(uChipRevision);
404b8e80941Smrg            m_settings.isVegaM           = ASICREV_IS_VEGAM_P(uChipRevision);
405b8e80941Smrg            family = ADDR_CHIP_FAMILY_VI;
406b8e80941Smrg            break;
407b8e80941Smrg        case FAMILY_CZ:
408b8e80941Smrg            m_settings.isCarrizo         = 1;
409b8e80941Smrg            m_settings.isVolcanicIslands = 1;
410b8e80941Smrg            family = ADDR_CHIP_FAMILY_VI;
411b8e80941Smrg            break;
412b8e80941Smrg        default:
413b8e80941Smrg            ADDR_ASSERT(!"This should be a unexpected Fusion");
414b8e80941Smrg            break;
415b8e80941Smrg    }
416b8e80941Smrg
417b8e80941Smrg    return family;
418b8e80941Smrg}
419b8e80941Smrg
420b8e80941Smrg/**
421b8e80941Smrg****************************************************************************************************
422b8e80941Smrg*   CiLib::HwlInitGlobalParams
423b8e80941Smrg*
424b8e80941Smrg*   @brief
425b8e80941Smrg*       Initializes global parameters
426b8e80941Smrg*
427b8e80941Smrg*   @return
428b8e80941Smrg*       TRUE if all settings are valid
429b8e80941Smrg*
430b8e80941Smrg****************************************************************************************************
431b8e80941Smrg*/
432b8e80941SmrgBOOL_32 CiLib::HwlInitGlobalParams(
433b8e80941Smrg    const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
434b8e80941Smrg{
435b8e80941Smrg    BOOL_32  valid = TRUE;
436b8e80941Smrg
437b8e80941Smrg    const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
438b8e80941Smrg
439b8e80941Smrg    valid = DecodeGbRegs(pRegValue);
440b8e80941Smrg
441b8e80941Smrg    // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
442b8e80941Smrg    // read the correct pipes from tile mode table
443b8e80941Smrg    if (m_settings.isHawaii)
444b8e80941Smrg    {
445b8e80941Smrg        m_pipes = 16;
446b8e80941Smrg    }
447b8e80941Smrg    else if (m_settings.isBonaire || m_settings.isSpectre)
448b8e80941Smrg    {
449b8e80941Smrg        m_pipes = 4;
450b8e80941Smrg    }
451b8e80941Smrg    else // Treat other KV asics to be 2-pipe
452b8e80941Smrg    {
453b8e80941Smrg        m_pipes = 2;
454b8e80941Smrg    }
455b8e80941Smrg
456b8e80941Smrg    // @todo: VI
457b8e80941Smrg    // Move this to VI code path once created
458b8e80941Smrg    if (m_settings.isTonga || m_settings.isPolaris10)
459b8e80941Smrg    {
460b8e80941Smrg        m_pipes = 8;
461b8e80941Smrg    }
462b8e80941Smrg    else if (m_settings.isIceland)
463b8e80941Smrg    {
464b8e80941Smrg        m_pipes = 2;
465b8e80941Smrg    }
466b8e80941Smrg    else if (m_settings.isFiji)
467b8e80941Smrg    {
468b8e80941Smrg        m_pipes = 16;
469b8e80941Smrg    }
470b8e80941Smrg    else if (m_settings.isPolaris11 || m_settings.isPolaris12)
471b8e80941Smrg    {
472b8e80941Smrg        m_pipes = 4;
473b8e80941Smrg    }
474b8e80941Smrg    else if (m_settings.isVegaM)
475b8e80941Smrg    {
476b8e80941Smrg        m_pipes = 16;
477b8e80941Smrg    }
478b8e80941Smrg
479b8e80941Smrg    if (valid)
480b8e80941Smrg    {
481b8e80941Smrg        valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
482b8e80941Smrg    }
483b8e80941Smrg    if (valid)
484b8e80941Smrg    {
485b8e80941Smrg        valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries);
486b8e80941Smrg    }
487b8e80941Smrg
488b8e80941Smrg    if (valid)
489b8e80941Smrg    {
490b8e80941Smrg        InitEquationTable();
491b8e80941Smrg    }
492b8e80941Smrg
493b8e80941Smrg    return valid;
494b8e80941Smrg}
495b8e80941Smrg
496b8e80941Smrg/**
497b8e80941Smrg****************************************************************************************************
498b8e80941Smrg*   CiLib::HwlPostCheckTileIndex
499b8e80941Smrg*
500b8e80941Smrg*   @brief
501b8e80941Smrg*       Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
502b8e80941Smrg*       tile mode/type/info and change the index if needed
503b8e80941Smrg*   @return
504b8e80941Smrg*       Tile index.
505b8e80941Smrg****************************************************************************************************
506b8e80941Smrg*/
507b8e80941SmrgINT_32 CiLib::HwlPostCheckTileIndex(
508b8e80941Smrg    const ADDR_TILEINFO* pInfo,     ///< [in] Tile Info
509b8e80941Smrg    AddrTileMode         mode,      ///< [in] Tile mode
510b8e80941Smrg    AddrTileType         type,      ///< [in] Tile type
511b8e80941Smrg    INT                  curIndex   ///< [in] Current index assigned in HwlSetupTileInfo
512b8e80941Smrg    ) const
513b8e80941Smrg{
514b8e80941Smrg    INT_32 index = curIndex;
515b8e80941Smrg
516b8e80941Smrg    if (mode == ADDR_TM_LINEAR_GENERAL)
517b8e80941Smrg    {
518b8e80941Smrg        index = TileIndexLinearGeneral;
519b8e80941Smrg    }
520b8e80941Smrg    else
521b8e80941Smrg    {
522b8e80941Smrg        BOOL_32 macroTiled = IsMacroTiled(mode);
523b8e80941Smrg
524b8e80941Smrg        // We need to find a new index if either of them is true
525b8e80941Smrg        // 1. curIndex is invalid
526b8e80941Smrg        // 2. tile mode is changed
527b8e80941Smrg        // 3. tile info does not match for macro tiled
528b8e80941Smrg        if ((index == TileIndexInvalid)         ||
529b8e80941Smrg            (mode != m_tileTable[index].mode)   ||
530b8e80941Smrg            (macroTiled && pInfo->pipeConfig != m_tileTable[index].info.pipeConfig))
531b8e80941Smrg        {
532b8e80941Smrg            for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
533b8e80941Smrg            {
534b8e80941Smrg                if (macroTiled)
535b8e80941Smrg                {
536b8e80941Smrg                    // macro tile modes need all to match
537b8e80941Smrg                    if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) &&
538b8e80941Smrg                        (mode == m_tileTable[index].mode) &&
539b8e80941Smrg                        (type == m_tileTable[index].type))
540b8e80941Smrg                    {
541b8e80941Smrg                        // tileSplitBytes stored in m_tileTable is only valid for depth entries
542b8e80941Smrg                        if (type == ADDR_DEPTH_SAMPLE_ORDER)
543b8e80941Smrg                        {
544b8e80941Smrg                            if (Min(m_tileTable[index].info.tileSplitBytes,
545b8e80941Smrg                                    m_rowSize) == pInfo->tileSplitBytes)
546b8e80941Smrg                            {
547b8e80941Smrg                                break;
548b8e80941Smrg                            }
549b8e80941Smrg                        }
550b8e80941Smrg                        else // other entries are determined by other 3 fields
551b8e80941Smrg                        {
552b8e80941Smrg                            break;
553b8e80941Smrg                        }
554b8e80941Smrg                    }
555b8e80941Smrg                }
556b8e80941Smrg                else if (mode == ADDR_TM_LINEAR_ALIGNED)
557b8e80941Smrg                {
558b8e80941Smrg                    // linear mode only needs tile mode to match
559b8e80941Smrg                    if (mode == m_tileTable[index].mode)
560b8e80941Smrg                    {
561b8e80941Smrg                        break;
562b8e80941Smrg                    }
563b8e80941Smrg                }
564b8e80941Smrg                else
565b8e80941Smrg                {
566b8e80941Smrg                    // micro tile modes only need tile mode and tile type to match
567b8e80941Smrg                    if (mode == m_tileTable[index].mode &&
568b8e80941Smrg                        type == m_tileTable[index].type)
569b8e80941Smrg                    {
570b8e80941Smrg                        break;
571b8e80941Smrg                    }
572b8e80941Smrg                }
573b8e80941Smrg            }
574b8e80941Smrg        }
575b8e80941Smrg    }
576b8e80941Smrg
577b8e80941Smrg    ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
578b8e80941Smrg
579b8e80941Smrg    if (index >= static_cast<INT_32>(m_noOfEntries))
580b8e80941Smrg    {
581b8e80941Smrg        index = TileIndexInvalid;
582b8e80941Smrg    }
583b8e80941Smrg
584b8e80941Smrg    return index;
585b8e80941Smrg}
586b8e80941Smrg
587b8e80941Smrg/**
588b8e80941Smrg****************************************************************************************************
589b8e80941Smrg*   CiLib::HwlSetupTileCfg
590b8e80941Smrg*
591b8e80941Smrg*   @brief
592b8e80941Smrg*       Map tile index to tile setting.
593b8e80941Smrg*   @return
594b8e80941Smrg*       ADDR_E_RETURNCODE
595b8e80941Smrg****************************************************************************************************
596b8e80941Smrg*/
597b8e80941SmrgADDR_E_RETURNCODE CiLib::HwlSetupTileCfg(
598b8e80941Smrg    UINT_32         bpp,            ///< Bits per pixel
599b8e80941Smrg    INT_32          index,          ///< Tile index
600b8e80941Smrg    INT_32          macroModeIndex, ///< Index in macro tile mode table(CI)
601b8e80941Smrg    ADDR_TILEINFO*  pInfo,          ///< [out] Tile Info
602b8e80941Smrg    AddrTileMode*   pMode,          ///< [out] Tile mode
603b8e80941Smrg    AddrTileType*   pType           ///< [out] Tile type
604b8e80941Smrg    ) const
605b8e80941Smrg{
606b8e80941Smrg    ADDR_E_RETURNCODE returnCode = ADDR_OK;
607b8e80941Smrg
608b8e80941Smrg    // Global flag to control usage of tileIndex
609b8e80941Smrg    if (UseTileIndex(index))
610b8e80941Smrg    {
611b8e80941Smrg        if (index == TileIndexLinearGeneral)
612b8e80941Smrg        {
613b8e80941Smrg            pInfo->banks = 2;
614b8e80941Smrg            pInfo->bankWidth = 1;
615b8e80941Smrg            pInfo->bankHeight = 1;
616b8e80941Smrg            pInfo->macroAspectRatio = 1;
617b8e80941Smrg            pInfo->tileSplitBytes = 64;
618b8e80941Smrg            pInfo->pipeConfig = ADDR_PIPECFG_P2;
619b8e80941Smrg        }
620b8e80941Smrg        else if (static_cast<UINT_32>(index) >= m_noOfEntries)
621b8e80941Smrg        {
622b8e80941Smrg            returnCode = ADDR_INVALIDPARAMS;
623b8e80941Smrg        }
624b8e80941Smrg        else
625b8e80941Smrg        {
626b8e80941Smrg            const TileConfig* pCfgTable = GetTileSetting(index);
627b8e80941Smrg
628b8e80941Smrg            if (pInfo != NULL)
629b8e80941Smrg            {
630b8e80941Smrg                if (IsMacroTiled(pCfgTable->mode))
631b8e80941Smrg                {
632b8e80941Smrg                    ADDR_ASSERT((macroModeIndex != TileIndexInvalid) &&
633b8e80941Smrg                                (macroModeIndex != TileIndexNoMacroIndex));
634b8e80941Smrg
635b8e80941Smrg                    UINT_32 tileSplit;
636b8e80941Smrg
637b8e80941Smrg                    *pInfo = m_macroTileTable[macroModeIndex];
638b8e80941Smrg
639b8e80941Smrg                    if (pCfgTable->type == ADDR_DEPTH_SAMPLE_ORDER)
640b8e80941Smrg                    {
641b8e80941Smrg                        tileSplit = pCfgTable->info.tileSplitBytes;
642b8e80941Smrg                    }
643b8e80941Smrg                    else
644b8e80941Smrg                    {
645b8e80941Smrg                        if (bpp > 0)
646b8e80941Smrg                        {
647b8e80941Smrg                            UINT_32 thickness = Thickness(pCfgTable->mode);
648b8e80941Smrg                            UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
649b8e80941Smrg                            // Non-depth entries store a split factor
650b8e80941Smrg                            UINT_32 sampleSplit = m_tileTable[index].info.tileSplitBytes;
651b8e80941Smrg                            tileSplit = Max(256u, sampleSplit * tileBytes1x);
652b8e80941Smrg                        }
653b8e80941Smrg                        else
654b8e80941Smrg                        {
655b8e80941Smrg                            // Return tileBytes instead if not enough info
656b8e80941Smrg                            tileSplit = pInfo->tileSplitBytes;
657b8e80941Smrg                        }
658b8e80941Smrg                    }
659b8e80941Smrg
660b8e80941Smrg                    // Clamp to row_size
661b8e80941Smrg                    pInfo->tileSplitBytes = Min(m_rowSize, tileSplit);
662b8e80941Smrg
663b8e80941Smrg                    pInfo->pipeConfig = pCfgTable->info.pipeConfig;
664b8e80941Smrg                }
665b8e80941Smrg                else // 1D and linear modes, we return default value stored in table
666b8e80941Smrg                {
667b8e80941Smrg                    *pInfo = pCfgTable->info;
668b8e80941Smrg                }
669b8e80941Smrg            }
670b8e80941Smrg
671b8e80941Smrg            if (pMode != NULL)
672b8e80941Smrg            {
673b8e80941Smrg                *pMode = pCfgTable->mode;
674b8e80941Smrg            }
675b8e80941Smrg
676b8e80941Smrg            if (pType != NULL)
677b8e80941Smrg            {
678b8e80941Smrg                *pType = pCfgTable->type;
679b8e80941Smrg            }
680b8e80941Smrg        }
681b8e80941Smrg    }
682b8e80941Smrg
683b8e80941Smrg    return returnCode;
684b8e80941Smrg}
685b8e80941Smrg
686b8e80941Smrg/**
687b8e80941Smrg****************************************************************************************************
688b8e80941Smrg*   CiLib::HwlComputeSurfaceInfo
689b8e80941Smrg*
690b8e80941Smrg*   @brief
691b8e80941Smrg*       Entry of CI's ComputeSurfaceInfo
692b8e80941Smrg*   @return
693b8e80941Smrg*       ADDR_E_RETURNCODE
694b8e80941Smrg****************************************************************************************************
695b8e80941Smrg*/
696b8e80941SmrgADDR_E_RETURNCODE CiLib::HwlComputeSurfaceInfo(
697b8e80941Smrg    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
698b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
699b8e80941Smrg    ) const
700b8e80941Smrg{
701b8e80941Smrg    // If tileIndex is invalid, force macroModeIndex to be invalid, too
702b8e80941Smrg    if (pIn->tileIndex == TileIndexInvalid)
703b8e80941Smrg    {
704b8e80941Smrg        pOut->macroModeIndex = TileIndexInvalid;
705b8e80941Smrg    }
706b8e80941Smrg
707b8e80941Smrg    ADDR_E_RETURNCODE retCode = SiLib::HwlComputeSurfaceInfo(pIn, pOut);
708b8e80941Smrg
709b8e80941Smrg    if ((pIn->mipLevel > 0) &&
710b8e80941Smrg        (pOut->tcCompatible == TRUE) &&
711b8e80941Smrg        (pOut->tileMode != pIn->tileMode) &&
712b8e80941Smrg        (m_settings.isVolcanicIslands == TRUE))
713b8e80941Smrg    {
714b8e80941Smrg        pOut->tcCompatible = CheckTcCompatibility(pOut->pTileInfo, pIn->bpp, pOut->tileMode, pOut->tileType, pOut);
715b8e80941Smrg    }
716b8e80941Smrg
717b8e80941Smrg    if (pOut->macroModeIndex == TileIndexNoMacroIndex)
718b8e80941Smrg    {
719b8e80941Smrg        pOut->macroModeIndex = TileIndexInvalid;
720b8e80941Smrg    }
721b8e80941Smrg
722b8e80941Smrg    if ((pIn->flags.matchStencilTileCfg == TRUE) &&
723b8e80941Smrg        (pIn->flags.depth == TRUE))
724b8e80941Smrg    {
725b8e80941Smrg        pOut->stencilTileIdx = TileIndexInvalid;
726b8e80941Smrg
727b8e80941Smrg        if ((MinDepth2DThinIndex <= pOut->tileIndex) &&
728b8e80941Smrg            (MaxDepth2DThinIndex >= pOut->tileIndex))
729b8e80941Smrg        {
730b8e80941Smrg            BOOL_32 depthStencil2DTileConfigMatch = DepthStencilTileCfgMatch(pIn, pOut);
731b8e80941Smrg
732b8e80941Smrg            if ((depthStencil2DTileConfigMatch == FALSE) &&
733b8e80941Smrg                (pOut->tcCompatible == TRUE))
734b8e80941Smrg            {
735b8e80941Smrg                pOut->macroModeIndex = TileIndexInvalid;
736b8e80941Smrg
737b8e80941Smrg                ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
738b8e80941Smrg                localIn.tileIndex = TileIndexInvalid;
739b8e80941Smrg                localIn.pTileInfo = NULL;
740b8e80941Smrg                localIn.flags.tcCompatible = FALSE;
741b8e80941Smrg
742b8e80941Smrg                SiLib::HwlComputeSurfaceInfo(&localIn, pOut);
743b8e80941Smrg
744b8e80941Smrg                ADDR_ASSERT((MinDepth2DThinIndex <= pOut->tileIndex) && (MaxDepth2DThinIndex >= pOut->tileIndex));
745b8e80941Smrg
746b8e80941Smrg                depthStencil2DTileConfigMatch = DepthStencilTileCfgMatch(pIn, pOut);
747b8e80941Smrg            }
748b8e80941Smrg
749b8e80941Smrg            if ((depthStencil2DTileConfigMatch == FALSE) &&
750b8e80941Smrg                (pIn->numSamples <= 1))
751b8e80941Smrg            {
752b8e80941Smrg                pOut->macroModeIndex = TileIndexInvalid;
753b8e80941Smrg
754b8e80941Smrg                ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
755b8e80941Smrg                localIn.tileMode = ADDR_TM_1D_TILED_THIN1;
756b8e80941Smrg                localIn.tileIndex = TileIndexInvalid;
757b8e80941Smrg                localIn.pTileInfo = NULL;
758b8e80941Smrg
759b8e80941Smrg                retCode = SiLib::HwlComputeSurfaceInfo(&localIn, pOut);
760b8e80941Smrg            }
761b8e80941Smrg        }
762b8e80941Smrg
763b8e80941Smrg        if (pOut->tileIndex == Depth1DThinIndex)
764b8e80941Smrg        {
765b8e80941Smrg            pOut->stencilTileIdx = Depth1DThinIndex;
766b8e80941Smrg        }
767b8e80941Smrg    }
768b8e80941Smrg
769b8e80941Smrg    return retCode;
770b8e80941Smrg}
771b8e80941Smrg
772b8e80941Smrg/**
773b8e80941Smrg****************************************************************************************************
774b8e80941Smrg*   CiLib::HwlFmaskSurfaceInfo
775b8e80941Smrg*   @brief
776b8e80941Smrg*       Entry of r800's ComputeFmaskInfo
777b8e80941Smrg*   @return
778b8e80941Smrg*       ADDR_E_RETURNCODE
779b8e80941Smrg****************************************************************************************************
780b8e80941Smrg*/
781b8e80941SmrgADDR_E_RETURNCODE CiLib::HwlComputeFmaskInfo(
782b8e80941Smrg    const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
783b8e80941Smrg    ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut   ///< [out] output structure
784b8e80941Smrg    )
785b8e80941Smrg{
786b8e80941Smrg    ADDR_E_RETURNCODE retCode = ADDR_OK;
787b8e80941Smrg
788b8e80941Smrg    ADDR_TILEINFO tileInfo = {0};
789b8e80941Smrg    ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn;
790b8e80941Smrg    fmaskIn = *pIn;
791b8e80941Smrg
792b8e80941Smrg    AddrTileMode tileMode = pIn->tileMode;
793b8e80941Smrg
794b8e80941Smrg    // Use internal tile info if pOut does not have a valid pTileInfo
795b8e80941Smrg    if (pOut->pTileInfo == NULL)
796b8e80941Smrg    {
797b8e80941Smrg        pOut->pTileInfo = &tileInfo;
798b8e80941Smrg    }
799b8e80941Smrg
800b8e80941Smrg    ADDR_ASSERT(tileMode == ADDR_TM_2D_TILED_THIN1     ||
801b8e80941Smrg                tileMode == ADDR_TM_3D_TILED_THIN1     ||
802b8e80941Smrg                tileMode == ADDR_TM_PRT_TILED_THIN1    ||
803b8e80941Smrg                tileMode == ADDR_TM_PRT_2D_TILED_THIN1 ||
804b8e80941Smrg                tileMode == ADDR_TM_PRT_3D_TILED_THIN1);
805b8e80941Smrg
806b8e80941Smrg    ADDR_ASSERT(m_tileTable[14].mode == ADDR_TM_2D_TILED_THIN1);
807b8e80941Smrg    ADDR_ASSERT(m_tileTable[15].mode == ADDR_TM_3D_TILED_THIN1);
808b8e80941Smrg
809b8e80941Smrg    // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
810b8e80941Smrg    INT_32 tileIndex = tileMode == ADDR_TM_2D_TILED_THIN1 ? 14 : 15;
811b8e80941Smrg    ADDR_SURFACE_FLAGS flags = {{0}};
812b8e80941Smrg    flags.fmask = 1;
813b8e80941Smrg
814b8e80941Smrg    INT_32 macroModeIndex = TileIndexInvalid;
815b8e80941Smrg
816b8e80941Smrg    UINT_32 numSamples = pIn->numSamples;
817b8e80941Smrg    UINT_32 numFrags = pIn->numFrags == 0 ? numSamples : pIn->numFrags;
818b8e80941Smrg
819b8e80941Smrg    UINT_32 bpp = QLog2(numFrags);
820b8e80941Smrg
821b8e80941Smrg    // EQAA needs one more bit
822b8e80941Smrg    if (numSamples > numFrags)
823b8e80941Smrg    {
824b8e80941Smrg        bpp++;
825b8e80941Smrg    }
826b8e80941Smrg
827b8e80941Smrg    if (bpp == 3)
828b8e80941Smrg    {
829b8e80941Smrg        bpp = 4;
830b8e80941Smrg    }
831b8e80941Smrg
832b8e80941Smrg    bpp = Max(8u, bpp * numSamples);
833b8e80941Smrg
834b8e80941Smrg    macroModeIndex = HwlComputeMacroModeIndex(tileIndex, flags, bpp, numSamples, pOut->pTileInfo);
835b8e80941Smrg
836b8e80941Smrg    fmaskIn.tileIndex = tileIndex;
837b8e80941Smrg    fmaskIn.pTileInfo = pOut->pTileInfo;
838b8e80941Smrg    pOut->macroModeIndex = macroModeIndex;
839b8e80941Smrg    pOut->tileIndex = tileIndex;
840b8e80941Smrg
841b8e80941Smrg    retCode = DispatchComputeFmaskInfo(&fmaskIn, pOut);
842b8e80941Smrg
843b8e80941Smrg    if (retCode == ADDR_OK)
844b8e80941Smrg    {
845b8e80941Smrg        pOut->tileIndex =
846b8e80941Smrg            HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
847b8e80941Smrg                                  pOut->tileIndex);
848b8e80941Smrg    }
849b8e80941Smrg
850b8e80941Smrg    // Resets pTileInfo to NULL if the internal tile info is used
851b8e80941Smrg    if (pOut->pTileInfo == &tileInfo)
852b8e80941Smrg    {
853b8e80941Smrg        pOut->pTileInfo = NULL;
854b8e80941Smrg    }
855b8e80941Smrg
856b8e80941Smrg    return retCode;
857b8e80941Smrg}
858b8e80941Smrg
859b8e80941Smrg/**
860b8e80941Smrg****************************************************************************************************
861b8e80941Smrg*   CiLib::HwlFmaskPreThunkSurfInfo
862b8e80941Smrg*
863b8e80941Smrg*   @brief
864b8e80941Smrg*       Some preparation before thunking a ComputeSurfaceInfo call for Fmask
865b8e80941Smrg*   @return
866b8e80941Smrg*       ADDR_E_RETURNCODE
867b8e80941Smrg****************************************************************************************************
868b8e80941Smrg*/
869b8e80941SmrgVOID CiLib::HwlFmaskPreThunkSurfInfo(
870b8e80941Smrg    const ADDR_COMPUTE_FMASK_INFO_INPUT*    pFmaskIn,   ///< [in] Input of fmask info
871b8e80941Smrg    const ADDR_COMPUTE_FMASK_INFO_OUTPUT*   pFmaskOut,  ///< [in] Output of fmask info
872b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_INPUT*        pSurfIn,    ///< [out] Input of thunked surface info
873b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pSurfOut    ///< [out] Output of thunked surface info
874b8e80941Smrg    ) const
875b8e80941Smrg{
876b8e80941Smrg    pSurfIn->tileIndex = pFmaskIn->tileIndex;
877b8e80941Smrg    pSurfOut->macroModeIndex  = pFmaskOut->macroModeIndex;
878b8e80941Smrg}
879b8e80941Smrg
880b8e80941Smrg/**
881b8e80941Smrg****************************************************************************************************
882b8e80941Smrg*   CiLib::HwlFmaskPostThunkSurfInfo
883b8e80941Smrg*
884b8e80941Smrg*   @brief
885b8e80941Smrg*       Copy hwl extra field after calling thunked ComputeSurfaceInfo
886b8e80941Smrg*   @return
887b8e80941Smrg*       ADDR_E_RETURNCODE
888b8e80941Smrg****************************************************************************************************
889b8e80941Smrg*/
890b8e80941SmrgVOID CiLib::HwlFmaskPostThunkSurfInfo(
891b8e80941Smrg    const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,   ///< [in] Output of surface info
892b8e80941Smrg    ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut           ///< [out] Output of fmask info
893b8e80941Smrg    ) const
894b8e80941Smrg{
895b8e80941Smrg    pFmaskOut->tileIndex = pSurfOut->tileIndex;
896b8e80941Smrg    pFmaskOut->macroModeIndex = pSurfOut->macroModeIndex;
897b8e80941Smrg}
898b8e80941Smrg
899b8e80941Smrg/**
900b8e80941Smrg****************************************************************************************************
901b8e80941Smrg*   CiLib::HwlDegradeThickTileMode
902b8e80941Smrg*
903b8e80941Smrg*   @brief
904b8e80941Smrg*       Degrades valid tile mode for thick modes if needed
905b8e80941Smrg*
906b8e80941Smrg*   @return
907b8e80941Smrg*       Suitable tile mode
908b8e80941Smrg****************************************************************************************************
909b8e80941Smrg*/
910b8e80941SmrgAddrTileMode CiLib::HwlDegradeThickTileMode(
911b8e80941Smrg    AddrTileMode        baseTileMode,   ///< [in] base tile mode
912b8e80941Smrg    UINT_32             numSlices,      ///< [in] current number of slices
913b8e80941Smrg    UINT_32*            pBytesPerTile   ///< [in,out] pointer to bytes per slice
914b8e80941Smrg    ) const
915b8e80941Smrg{
916b8e80941Smrg    return baseTileMode;
917b8e80941Smrg}
918b8e80941Smrg
919b8e80941Smrg/**
920b8e80941Smrg****************************************************************************************************
921b8e80941Smrg*   CiLib::HwlOptimizeTileMode
922b8e80941Smrg*
923b8e80941Smrg*   @brief
924b8e80941Smrg*       Optimize tile mode on CI
925b8e80941Smrg*
926b8e80941Smrg*   @return
927b8e80941Smrg*       N/A
928b8e80941Smrg*
929b8e80941Smrg****************************************************************************************************
930b8e80941Smrg*/
931b8e80941SmrgVOID CiLib::HwlOptimizeTileMode(
932b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_INPUT*    pInOut      ///< [in,out] input output structure
933b8e80941Smrg    ) const
934b8e80941Smrg{
935b8e80941Smrg    AddrTileMode tileMode = pInOut->tileMode;
936b8e80941Smrg
937b8e80941Smrg    // Override 2D/3D macro tile mode to PRT_* tile mode if
938b8e80941Smrg    // client driver requests this surface is equation compatible
939b8e80941Smrg    if (IsMacroTiled(tileMode) == TRUE)
940b8e80941Smrg    {
941b8e80941Smrg        if ((pInOut->flags.needEquation == TRUE) &&
942b8e80941Smrg            (pInOut->numSamples <= 1) &&
943b8e80941Smrg            (IsPrtTileMode(tileMode) == FALSE))
944b8e80941Smrg        {
945b8e80941Smrg            if ((pInOut->numSlices > 1) && ((pInOut->maxBaseAlign == 0) || (pInOut->maxBaseAlign >= Block64K)))
946b8e80941Smrg            {
947b8e80941Smrg                UINT_32 thickness = Thickness(tileMode);
948b8e80941Smrg
949b8e80941Smrg                if (thickness == 1)
950b8e80941Smrg                {
951b8e80941Smrg                    tileMode = ADDR_TM_PRT_TILED_THIN1;
952b8e80941Smrg                }
953b8e80941Smrg                else
954b8e80941Smrg                {
955b8e80941Smrg                    static const UINT_32 PrtTileBytes = 0x10000;
956b8e80941Smrg                    // First prt thick tile index in the tile mode table
957b8e80941Smrg                    static const UINT_32 PrtThickTileIndex = 22;
958b8e80941Smrg                    ADDR_TILEINFO tileInfo = {0};
959b8e80941Smrg
960b8e80941Smrg                    HwlComputeMacroModeIndex(PrtThickTileIndex,
961b8e80941Smrg                                             pInOut->flags,
962b8e80941Smrg                                             pInOut->bpp,
963b8e80941Smrg                                             pInOut->numSamples,
964b8e80941Smrg                                             &tileInfo);
965b8e80941Smrg
966b8e80941Smrg                    UINT_32 macroTileBytes = ((pInOut->bpp) >> 3) * 64 * pInOut->numSamples *
967b8e80941Smrg                                             thickness * HwlGetPipes(&tileInfo) *
968b8e80941Smrg                                             tileInfo.banks * tileInfo.bankWidth *
969b8e80941Smrg                                             tileInfo.bankHeight;
970b8e80941Smrg
971b8e80941Smrg                    if (macroTileBytes <= PrtTileBytes)
972b8e80941Smrg                    {
973b8e80941Smrg                        tileMode = ADDR_TM_PRT_TILED_THICK;
974b8e80941Smrg                    }
975b8e80941Smrg                    else
976b8e80941Smrg                    {
977b8e80941Smrg                        tileMode = ADDR_TM_PRT_TILED_THIN1;
978b8e80941Smrg                    }
979b8e80941Smrg                }
980b8e80941Smrg            }
981b8e80941Smrg        }
982b8e80941Smrg
983b8e80941Smrg        if (pInOut->maxBaseAlign != 0)
984b8e80941Smrg        {
985b8e80941Smrg            pInOut->flags.dccPipeWorkaround = FALSE;
986b8e80941Smrg        }
987b8e80941Smrg    }
988b8e80941Smrg
989b8e80941Smrg    if (tileMode != pInOut->tileMode)
990b8e80941Smrg    {
991b8e80941Smrg        pInOut->tileMode = tileMode;
992b8e80941Smrg    }
993b8e80941Smrg}
994b8e80941Smrg
995b8e80941Smrg/**
996b8e80941Smrg****************************************************************************************************
997b8e80941Smrg*   CiLib::HwlOverrideTileMode
998b8e80941Smrg*
999b8e80941Smrg*   @brief
1000b8e80941Smrg*       Override THICK to THIN, for specific formats on CI
1001b8e80941Smrg*
1002b8e80941Smrg*   @return
1003b8e80941Smrg*       N/A
1004b8e80941Smrg*
1005b8e80941Smrg****************************************************************************************************
1006b8e80941Smrg*/
1007b8e80941SmrgVOID CiLib::HwlOverrideTileMode(
1008b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_INPUT*    pInOut      ///< [in,out] input output structure
1009b8e80941Smrg    ) const
1010b8e80941Smrg{
1011b8e80941Smrg    AddrTileMode tileMode = pInOut->tileMode;
1012b8e80941Smrg    AddrTileType tileType = pInOut->tileType;
1013b8e80941Smrg
1014b8e80941Smrg    // currently, all CI/VI family do not
1015b8e80941Smrg    // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
1016b8e80941Smrg    // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
1017b8e80941Smrg    switch (tileMode)
1018b8e80941Smrg    {
1019b8e80941Smrg        case ADDR_TM_PRT_2D_TILED_THICK:
1020b8e80941Smrg        case ADDR_TM_PRT_3D_TILED_THICK:
1021b8e80941Smrg            tileMode = ADDR_TM_PRT_TILED_THICK;
1022b8e80941Smrg            break;
1023b8e80941Smrg        case ADDR_TM_PRT_2D_TILED_THIN1:
1024b8e80941Smrg        case ADDR_TM_PRT_3D_TILED_THIN1:
1025b8e80941Smrg            tileMode = ADDR_TM_PRT_TILED_THIN1;
1026b8e80941Smrg            break;
1027b8e80941Smrg        default:
1028b8e80941Smrg            break;
1029b8e80941Smrg    }
1030b8e80941Smrg
1031b8e80941Smrg    // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
1032b8e80941Smrg    if (!m_settings.isBonaire)
1033b8e80941Smrg    {
1034b8e80941Smrg        UINT_32 thickness = Thickness(tileMode);
1035b8e80941Smrg
1036b8e80941Smrg        // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
1037b8e80941Smrg        if (thickness > 1)
1038b8e80941Smrg        {
1039b8e80941Smrg            switch (pInOut->format)
1040b8e80941Smrg            {
1041b8e80941Smrg                // tcpError("Thick micro tiling is not supported for format...
1042b8e80941Smrg                case ADDR_FMT_X24_8_32_FLOAT:
1043b8e80941Smrg                case ADDR_FMT_32_AS_8:
1044b8e80941Smrg                case ADDR_FMT_32_AS_8_8:
1045b8e80941Smrg                case ADDR_FMT_32_AS_32_32_32_32:
1046b8e80941Smrg
1047b8e80941Smrg                // packed formats
1048b8e80941Smrg                case ADDR_FMT_GB_GR:
1049b8e80941Smrg                case ADDR_FMT_BG_RG:
1050b8e80941Smrg                case ADDR_FMT_1_REVERSED:
1051b8e80941Smrg                case ADDR_FMT_1:
1052b8e80941Smrg                case ADDR_FMT_BC1:
1053b8e80941Smrg                case ADDR_FMT_BC2:
1054b8e80941Smrg                case ADDR_FMT_BC3:
1055b8e80941Smrg                case ADDR_FMT_BC4:
1056b8e80941Smrg                case ADDR_FMT_BC5:
1057b8e80941Smrg                case ADDR_FMT_BC6:
1058b8e80941Smrg                case ADDR_FMT_BC7:
1059b8e80941Smrg                    switch (tileMode)
1060b8e80941Smrg                    {
1061b8e80941Smrg                        case ADDR_TM_1D_TILED_THICK:
1062b8e80941Smrg                            tileMode = ADDR_TM_1D_TILED_THIN1;
1063b8e80941Smrg                            break;
1064b8e80941Smrg
1065b8e80941Smrg                        case ADDR_TM_2D_TILED_XTHICK:
1066b8e80941Smrg                        case ADDR_TM_2D_TILED_THICK:
1067b8e80941Smrg                            tileMode = ADDR_TM_2D_TILED_THIN1;
1068b8e80941Smrg                            break;
1069b8e80941Smrg
1070b8e80941Smrg                        case ADDR_TM_3D_TILED_XTHICK:
1071b8e80941Smrg                        case ADDR_TM_3D_TILED_THICK:
1072b8e80941Smrg                            tileMode = ADDR_TM_3D_TILED_THIN1;
1073b8e80941Smrg                            break;
1074b8e80941Smrg
1075b8e80941Smrg                        case ADDR_TM_PRT_TILED_THICK:
1076b8e80941Smrg                            tileMode = ADDR_TM_PRT_TILED_THIN1;
1077b8e80941Smrg                            break;
1078b8e80941Smrg
1079b8e80941Smrg                        case ADDR_TM_PRT_2D_TILED_THICK:
1080b8e80941Smrg                            tileMode = ADDR_TM_PRT_2D_TILED_THIN1;
1081b8e80941Smrg                            break;
1082b8e80941Smrg
1083b8e80941Smrg                        case ADDR_TM_PRT_3D_TILED_THICK:
1084b8e80941Smrg                            tileMode = ADDR_TM_PRT_3D_TILED_THIN1;
1085b8e80941Smrg                            break;
1086b8e80941Smrg
1087b8e80941Smrg                        default:
1088b8e80941Smrg                            break;
1089b8e80941Smrg
1090b8e80941Smrg                    }
1091b8e80941Smrg
1092b8e80941Smrg                    // Switch tile type from thick to thin
1093b8e80941Smrg                    if (tileMode != pInOut->tileMode)
1094b8e80941Smrg                    {
1095b8e80941Smrg                        // see tileIndex: 13-18
1096b8e80941Smrg                        tileType = ADDR_NON_DISPLAYABLE;
1097b8e80941Smrg                    }
1098b8e80941Smrg
1099b8e80941Smrg                    break;
1100b8e80941Smrg                default:
1101b8e80941Smrg                    break;
1102b8e80941Smrg            }
1103b8e80941Smrg        }
1104b8e80941Smrg    }
1105b8e80941Smrg
1106b8e80941Smrg    if (tileMode != pInOut->tileMode)
1107b8e80941Smrg    {
1108b8e80941Smrg        pInOut->tileMode = tileMode;
1109b8e80941Smrg        pInOut->tileType = tileType;
1110b8e80941Smrg    }
1111b8e80941Smrg}
1112b8e80941Smrg
1113b8e80941Smrg/**
1114b8e80941Smrg****************************************************************************************************
1115b8e80941Smrg*   CiLib::HwlSelectTileMode
1116b8e80941Smrg*
1117b8e80941Smrg*   @brief
1118b8e80941Smrg*       Select tile modes.
1119b8e80941Smrg*
1120b8e80941Smrg*   @return
1121b8e80941Smrg*       N/A
1122b8e80941Smrg*
1123b8e80941Smrg****************************************************************************************************
1124b8e80941Smrg*/
1125b8e80941SmrgVOID CiLib::HwlSelectTileMode(
1126b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in,out] input output structure
1127b8e80941Smrg    ) const
1128b8e80941Smrg{
1129b8e80941Smrg    AddrTileMode tileMode;
1130b8e80941Smrg    AddrTileType tileType;
1131b8e80941Smrg
1132b8e80941Smrg    if (pInOut->flags.rotateDisplay)
1133b8e80941Smrg    {
1134b8e80941Smrg        tileMode = ADDR_TM_2D_TILED_THIN1;
1135b8e80941Smrg        tileType = ADDR_ROTATED;
1136b8e80941Smrg    }
1137b8e80941Smrg    else if (pInOut->flags.volume)
1138b8e80941Smrg    {
1139b8e80941Smrg        BOOL_32 bThin = (m_settings.isBonaire == TRUE) ||
1140b8e80941Smrg                        ((m_allowNonDispThickModes == TRUE) && (pInOut->flags.color == TRUE));
1141b8e80941Smrg
1142b8e80941Smrg        if (pInOut->numSlices >= 8)
1143b8e80941Smrg        {
1144b8e80941Smrg            tileMode = ADDR_TM_2D_TILED_XTHICK;
1145b8e80941Smrg            tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
1146b8e80941Smrg        }
1147b8e80941Smrg        else if (pInOut->numSlices >= 4)
1148b8e80941Smrg        {
1149b8e80941Smrg            tileMode = ADDR_TM_2D_TILED_THICK;
1150b8e80941Smrg            tileType = (bThin == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
1151b8e80941Smrg        }
1152b8e80941Smrg        else
1153b8e80941Smrg        {
1154b8e80941Smrg            tileMode = ADDR_TM_2D_TILED_THIN1;
1155b8e80941Smrg            tileType = ADDR_NON_DISPLAYABLE;
1156b8e80941Smrg        }
1157b8e80941Smrg    }
1158b8e80941Smrg    else
1159b8e80941Smrg    {
1160b8e80941Smrg        tileMode = ADDR_TM_2D_TILED_THIN1;
1161b8e80941Smrg
1162b8e80941Smrg        if (pInOut->flags.depth || pInOut->flags.stencil)
1163b8e80941Smrg        {
1164b8e80941Smrg            tileType = ADDR_DEPTH_SAMPLE_ORDER;
1165b8e80941Smrg        }
1166b8e80941Smrg        else if ((pInOut->bpp <= 32) ||
1167b8e80941Smrg                 (pInOut->flags.display == TRUE) ||
1168b8e80941Smrg                 (pInOut->flags.overlay == TRUE))
1169b8e80941Smrg        {
1170b8e80941Smrg            tileType = ADDR_DISPLAYABLE;
1171b8e80941Smrg        }
1172b8e80941Smrg        else
1173b8e80941Smrg        {
1174b8e80941Smrg            tileType = ADDR_NON_DISPLAYABLE;
1175b8e80941Smrg        }
1176b8e80941Smrg    }
1177b8e80941Smrg
1178b8e80941Smrg    if (pInOut->flags.prt)
1179b8e80941Smrg    {
1180b8e80941Smrg        if (Thickness(tileMode) > 1)
1181b8e80941Smrg        {
1182b8e80941Smrg            tileMode = ADDR_TM_PRT_TILED_THICK;
1183b8e80941Smrg            tileType = (m_settings.isBonaire == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
1184b8e80941Smrg        }
1185b8e80941Smrg        else
1186b8e80941Smrg        {
1187b8e80941Smrg            tileMode = ADDR_TM_PRT_TILED_THIN1;
1188b8e80941Smrg        }
1189b8e80941Smrg    }
1190b8e80941Smrg
1191b8e80941Smrg    pInOut->tileMode = tileMode;
1192b8e80941Smrg    pInOut->tileType = tileType;
1193b8e80941Smrg
1194b8e80941Smrg    if ((pInOut->flags.dccCompatible == FALSE) &&
1195b8e80941Smrg        (pInOut->flags.tcCompatible == FALSE))
1196b8e80941Smrg    {
1197b8e80941Smrg        pInOut->flags.opt4Space = TRUE;
1198b8e80941Smrg        pInOut->maxBaseAlign = Block64K;
1199b8e80941Smrg    }
1200b8e80941Smrg
1201b8e80941Smrg    // Optimize tile mode if possible
1202b8e80941Smrg    OptimizeTileMode(pInOut);
1203b8e80941Smrg
1204b8e80941Smrg    HwlOverrideTileMode(pInOut);
1205b8e80941Smrg}
1206b8e80941Smrg
1207b8e80941Smrg/**
1208b8e80941Smrg****************************************************************************************************
1209b8e80941Smrg*   CiLib::HwlSetPrtTileMode
1210b8e80941Smrg*
1211b8e80941Smrg*   @brief
1212b8e80941Smrg*       Set PRT tile mode.
1213b8e80941Smrg*
1214b8e80941Smrg*   @return
1215b8e80941Smrg*       N/A
1216b8e80941Smrg*
1217b8e80941Smrg****************************************************************************************************
1218b8e80941Smrg*/
1219b8e80941SmrgVOID CiLib::HwlSetPrtTileMode(
1220b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut     ///< [in,out] input output structure
1221b8e80941Smrg    ) const
1222b8e80941Smrg{
1223b8e80941Smrg    AddrTileMode tileMode = pInOut->tileMode;
1224b8e80941Smrg    AddrTileType tileType = pInOut->tileType;
1225b8e80941Smrg
1226b8e80941Smrg    if (Thickness(tileMode) > 1)
1227b8e80941Smrg    {
1228b8e80941Smrg        tileMode = ADDR_TM_PRT_TILED_THICK;
1229b8e80941Smrg        tileType = (m_settings.isBonaire == TRUE) ? ADDR_NON_DISPLAYABLE : ADDR_THICK;
1230b8e80941Smrg    }
1231b8e80941Smrg    else
1232b8e80941Smrg    {
1233b8e80941Smrg        tileMode = ADDR_TM_PRT_TILED_THIN1;
1234b8e80941Smrg        tileType = (tileType == ADDR_THICK) ? ADDR_NON_DISPLAYABLE : tileType;
1235b8e80941Smrg    }
1236b8e80941Smrg
1237b8e80941Smrg    pInOut->tileMode = tileMode;
1238b8e80941Smrg    pInOut->tileType = tileType;
1239b8e80941Smrg}
1240b8e80941Smrg
1241b8e80941Smrg/**
1242b8e80941Smrg****************************************************************************************************
1243b8e80941Smrg*   CiLib::HwlSetupTileInfo
1244b8e80941Smrg*
1245b8e80941Smrg*   @brief
1246b8e80941Smrg*       Setup default value of tile info for SI
1247b8e80941Smrg****************************************************************************************************
1248b8e80941Smrg*/
1249b8e80941SmrgVOID CiLib::HwlSetupTileInfo(
1250b8e80941Smrg    AddrTileMode                        tileMode,       ///< [in] Tile mode
1251b8e80941Smrg    ADDR_SURFACE_FLAGS                  flags,          ///< [in] Surface type flags
1252b8e80941Smrg    UINT_32                             bpp,            ///< [in] Bits per pixel
1253b8e80941Smrg    UINT_32                             pitch,          ///< [in] Pitch in pixels
1254b8e80941Smrg    UINT_32                             height,         ///< [in] Height in pixels
1255b8e80941Smrg    UINT_32                             numSamples,     ///< [in] Number of samples
1256b8e80941Smrg    ADDR_TILEINFO*                      pTileInfoIn,    ///< [in] Tile info input: NULL for default
1257b8e80941Smrg    ADDR_TILEINFO*                      pTileInfoOut,   ///< [out] Tile info output
1258b8e80941Smrg    AddrTileType                        inTileType,     ///< [in] Tile type
1259b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut            ///< [out] Output
1260b8e80941Smrg    ) const
1261b8e80941Smrg{
1262b8e80941Smrg    UINT_32 thickness = Thickness(tileMode);
1263b8e80941Smrg    ADDR_TILEINFO* pTileInfo = pTileInfoOut;
1264b8e80941Smrg    INT index = TileIndexInvalid;
1265b8e80941Smrg    INT macroModeIndex = TileIndexInvalid;
1266b8e80941Smrg
1267b8e80941Smrg    // Fail-safe code
1268b8e80941Smrg    if (IsLinear(tileMode) == FALSE)
1269b8e80941Smrg    {
1270b8e80941Smrg        // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
1271b8e80941Smrg        // old derived netlists (UBTS 404321)
1272b8e80941Smrg        if (thickness > 1)
1273b8e80941Smrg        {
1274b8e80941Smrg            if (m_settings.isBonaire)
1275b8e80941Smrg            {
1276b8e80941Smrg                inTileType = ADDR_NON_DISPLAYABLE;
1277b8e80941Smrg            }
1278b8e80941Smrg            else if ((m_allowNonDispThickModes == FALSE) ||
1279b8e80941Smrg                     (inTileType != ADDR_NON_DISPLAYABLE) ||
1280b8e80941Smrg                     // There is no PRT_THICK + THIN entry in tile mode table except Bonaire
1281b8e80941Smrg                     (IsPrtTileMode(tileMode) == TRUE))
1282b8e80941Smrg            {
1283b8e80941Smrg                inTileType = ADDR_THICK;
1284b8e80941Smrg            }
1285b8e80941Smrg        }
1286b8e80941Smrg        // 128 bpp tiling must be non-displayable.
1287b8e80941Smrg        // Fmask reuse color buffer's entry but bank-height field can be from another entry
1288b8e80941Smrg        // To simplify the logic, fmask entry should be picked from non-displayable ones
1289b8e80941Smrg        else if (bpp == 128 || flags.fmask)
1290b8e80941Smrg        {
1291b8e80941Smrg            inTileType = ADDR_NON_DISPLAYABLE;
1292b8e80941Smrg        }
1293b8e80941Smrg        // These two modes only have non-disp entries though they can be other micro tile modes
1294b8e80941Smrg        else if (tileMode == ADDR_TM_3D_TILED_THIN1 || tileMode == ADDR_TM_PRT_3D_TILED_THIN1)
1295b8e80941Smrg        {
1296b8e80941Smrg            inTileType = ADDR_NON_DISPLAYABLE;
1297b8e80941Smrg        }
1298b8e80941Smrg
1299b8e80941Smrg        if (flags.depth || flags.stencil)
1300b8e80941Smrg        {
1301b8e80941Smrg            inTileType = ADDR_DEPTH_SAMPLE_ORDER;
1302b8e80941Smrg        }
1303b8e80941Smrg    }
1304b8e80941Smrg
1305b8e80941Smrg    // tcCompatible flag is only meaningful for gfx8.
1306b8e80941Smrg    if (m_settings.isVolcanicIslands == FALSE)
1307b8e80941Smrg    {
1308b8e80941Smrg        flags.tcCompatible = FALSE;
1309b8e80941Smrg    }
1310b8e80941Smrg
1311b8e80941Smrg    if (IsTileInfoAllZero(pTileInfo))
1312b8e80941Smrg    {
1313b8e80941Smrg        // See table entries 0-4
1314b8e80941Smrg        if (flags.depth || flags.stencil)
1315b8e80941Smrg        {
1316b8e80941Smrg            // tileSize = thickness * bpp * numSamples * 8 * 8 / 8
1317b8e80941Smrg            UINT_32 tileSize = thickness * bpp * numSamples * 8;
1318b8e80941Smrg
1319b8e80941Smrg            // Turn off tc compatible if row_size is smaller than tile size (tile split occurs).
1320b8e80941Smrg            if (m_rowSize < tileSize)
1321b8e80941Smrg            {
1322b8e80941Smrg                flags.tcCompatible = FALSE;
1323b8e80941Smrg            }
1324b8e80941Smrg
1325b8e80941Smrg            if (flags.nonSplit | flags.tcCompatible | flags.needEquation)
1326b8e80941Smrg            {
1327b8e80941Smrg                // Texture readable depth surface should not be split
1328b8e80941Smrg                switch (tileSize)
1329b8e80941Smrg                {
1330b8e80941Smrg                    case 64:
1331b8e80941Smrg                        index = 0;
1332b8e80941Smrg                        break;
1333b8e80941Smrg                    case 128:
1334b8e80941Smrg                        index = 1;
1335b8e80941Smrg                        break;
1336b8e80941Smrg                    case 256:
1337b8e80941Smrg                        index = 2;
1338b8e80941Smrg                        break;
1339b8e80941Smrg                    case 512:
1340b8e80941Smrg                        index = 3;
1341b8e80941Smrg                        break;
1342b8e80941Smrg                    default:
1343b8e80941Smrg                        index = 4;
1344b8e80941Smrg                        break;
1345b8e80941Smrg                }
1346b8e80941Smrg            }
1347b8e80941Smrg            else
1348b8e80941Smrg            {
1349b8e80941Smrg                // Depth and stencil need to use the same index, thus the pre-defined tile_split
1350b8e80941Smrg                // can meet the requirement to choose the same macro mode index
1351b8e80941Smrg                // uncompressed depth/stencil are not supported for now
1352b8e80941Smrg                switch (numSamples)
1353b8e80941Smrg                {
1354b8e80941Smrg                    case 1:
1355b8e80941Smrg                        index = 0;
1356b8e80941Smrg                        break;
1357b8e80941Smrg                    case 2:
1358b8e80941Smrg                    case 4:
1359b8e80941Smrg                        index = 1;
1360b8e80941Smrg                        break;
1361b8e80941Smrg                    case 8:
1362b8e80941Smrg                        index = 2;
1363b8e80941Smrg                        break;
1364b8e80941Smrg                    default:
1365b8e80941Smrg                        break;
1366b8e80941Smrg                }
1367b8e80941Smrg            }
1368b8e80941Smrg        }
1369b8e80941Smrg
1370b8e80941Smrg        // See table entries 5-6
1371b8e80941Smrg        if (inTileType == ADDR_DEPTH_SAMPLE_ORDER)
1372b8e80941Smrg        {
1373b8e80941Smrg            switch (tileMode)
1374b8e80941Smrg            {
1375b8e80941Smrg                case ADDR_TM_1D_TILED_THIN1:
1376b8e80941Smrg                    index = 5;
1377b8e80941Smrg                    break;
1378b8e80941Smrg                case ADDR_TM_PRT_TILED_THIN1:
1379b8e80941Smrg                    index = 6;
1380b8e80941Smrg                    break;
1381b8e80941Smrg                default:
1382b8e80941Smrg                    break;
1383b8e80941Smrg            }
1384b8e80941Smrg        }
1385b8e80941Smrg
1386b8e80941Smrg        // See table entries 8-12
1387b8e80941Smrg        if (inTileType == ADDR_DISPLAYABLE)
1388b8e80941Smrg        {
1389b8e80941Smrg            switch (tileMode)
1390b8e80941Smrg            {
1391b8e80941Smrg                case ADDR_TM_1D_TILED_THIN1:
1392b8e80941Smrg                    index = 9;
1393b8e80941Smrg                    break;
1394b8e80941Smrg                case ADDR_TM_2D_TILED_THIN1:
1395b8e80941Smrg                    index = 10;
1396b8e80941Smrg                    break;
1397b8e80941Smrg                case ADDR_TM_PRT_TILED_THIN1:
1398b8e80941Smrg                    index = 11;
1399b8e80941Smrg                    break;
1400b8e80941Smrg                default:
1401b8e80941Smrg                    break;
1402b8e80941Smrg            }
1403b8e80941Smrg        }
1404b8e80941Smrg
1405b8e80941Smrg        // See table entries 13-18
1406b8e80941Smrg        if (inTileType == ADDR_NON_DISPLAYABLE)
1407b8e80941Smrg        {
1408b8e80941Smrg            switch (tileMode)
1409b8e80941Smrg            {
1410b8e80941Smrg                case ADDR_TM_1D_TILED_THIN1:
1411b8e80941Smrg                    index = 13;
1412b8e80941Smrg                    break;
1413b8e80941Smrg                case ADDR_TM_2D_TILED_THIN1:
1414b8e80941Smrg                    index = 14;
1415b8e80941Smrg                    break;
1416b8e80941Smrg                case ADDR_TM_3D_TILED_THIN1:
1417b8e80941Smrg                    index = 15;
1418b8e80941Smrg                    break;
1419b8e80941Smrg                case ADDR_TM_PRT_TILED_THIN1:
1420b8e80941Smrg                    index = 16;
1421b8e80941Smrg                    break;
1422b8e80941Smrg                default:
1423b8e80941Smrg                    break;
1424b8e80941Smrg            }
1425b8e80941Smrg        }
1426b8e80941Smrg
1427b8e80941Smrg        // See table entries 19-26
1428b8e80941Smrg        if (thickness > 1)
1429b8e80941Smrg        {
1430b8e80941Smrg            switch (tileMode)
1431b8e80941Smrg            {
1432b8e80941Smrg                case ADDR_TM_1D_TILED_THICK:
1433b8e80941Smrg                    // special check for bonaire, for the compatablity between old KMD and new UMD
1434b8e80941Smrg                    index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 19 : 18;
1435b8e80941Smrg                    break;
1436b8e80941Smrg                case ADDR_TM_2D_TILED_THICK:
1437b8e80941Smrg                    // special check for bonaire, for the compatablity between old KMD and new UMD
1438b8e80941Smrg                    index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 20 : 24;
1439b8e80941Smrg                    break;
1440b8e80941Smrg                case ADDR_TM_3D_TILED_THICK:
1441b8e80941Smrg                    index = 21;
1442b8e80941Smrg                    break;
1443b8e80941Smrg                case ADDR_TM_PRT_TILED_THICK:
1444b8e80941Smrg                    index = 22;
1445b8e80941Smrg                    break;
1446b8e80941Smrg                case ADDR_TM_2D_TILED_XTHICK:
1447b8e80941Smrg                    index = 25;
1448b8e80941Smrg                    break;
1449b8e80941Smrg                case ADDR_TM_3D_TILED_XTHICK:
1450b8e80941Smrg                    index = 26;
1451b8e80941Smrg                    break;
1452b8e80941Smrg                default:
1453b8e80941Smrg                    break;
1454b8e80941Smrg            }
1455b8e80941Smrg        }
1456b8e80941Smrg
1457b8e80941Smrg        // See table entries 27-30
1458b8e80941Smrg        if (inTileType == ADDR_ROTATED)
1459b8e80941Smrg        {
1460b8e80941Smrg            switch (tileMode)
1461b8e80941Smrg            {
1462b8e80941Smrg                case ADDR_TM_1D_TILED_THIN1:
1463b8e80941Smrg                    index = 27;
1464b8e80941Smrg                    break;
1465b8e80941Smrg                case ADDR_TM_2D_TILED_THIN1:
1466b8e80941Smrg                    index = 28;
1467b8e80941Smrg                    break;
1468b8e80941Smrg                case ADDR_TM_PRT_TILED_THIN1:
1469b8e80941Smrg                    index = 29;
1470b8e80941Smrg                    break;
1471b8e80941Smrg                case ADDR_TM_PRT_2D_TILED_THIN1:
1472b8e80941Smrg                    index = 30;
1473b8e80941Smrg                    break;
1474b8e80941Smrg                default:
1475b8e80941Smrg                    break;
1476b8e80941Smrg            }
1477b8e80941Smrg        }
1478b8e80941Smrg
1479b8e80941Smrg        if (m_pipes >= 8)
1480b8e80941Smrg        {
1481b8e80941Smrg            ADDR_ASSERT((index + 1) < static_cast<INT_32>(m_noOfEntries));
1482b8e80941Smrg            // Only do this when tile mode table is updated.
1483b8e80941Smrg            if (((tileMode == ADDR_TM_PRT_TILED_THIN1) || (tileMode == ADDR_TM_PRT_TILED_THICK)) &&
1484b8e80941Smrg                (m_tileTable[index + 1].mode == tileMode))
1485b8e80941Smrg            {
1486b8e80941Smrg                static const UINT_32 PrtTileBytes = 0x10000;
1487b8e80941Smrg                ADDR_TILEINFO tileInfo = {0};
1488b8e80941Smrg
1489b8e80941Smrg                HwlComputeMacroModeIndex(index, flags, bpp, numSamples, &tileInfo);
1490b8e80941Smrg
1491b8e80941Smrg                UINT_32 macroTileBytes = (bpp >> 3) * 64 * numSamples * thickness *
1492b8e80941Smrg                                         HwlGetPipes(&tileInfo) * tileInfo.banks *
1493b8e80941Smrg                                         tileInfo.bankWidth * tileInfo.bankHeight;
1494b8e80941Smrg
1495b8e80941Smrg                if (macroTileBytes != PrtTileBytes)
1496b8e80941Smrg                {
1497b8e80941Smrg                    // Switching to next tile mode entry to make sure macro tile size is 64KB
1498b8e80941Smrg                    index += 1;
1499b8e80941Smrg
1500b8e80941Smrg                    tileInfo.pipeConfig = m_tileTable[index].info.pipeConfig;
1501b8e80941Smrg
1502b8e80941Smrg                    macroTileBytes = (bpp >> 3) * 64 * numSamples * thickness *
1503b8e80941Smrg                                     HwlGetPipes(&tileInfo) * tileInfo.banks *
1504b8e80941Smrg                                     tileInfo.bankWidth * tileInfo.bankHeight;
1505b8e80941Smrg
1506b8e80941Smrg                    ADDR_ASSERT(macroTileBytes == PrtTileBytes);
1507b8e80941Smrg
1508b8e80941Smrg                    flags.tcCompatible = FALSE;
1509b8e80941Smrg                    pOut->dccUnsupport = TRUE;
1510b8e80941Smrg                }
1511b8e80941Smrg            }
1512b8e80941Smrg        }
1513b8e80941Smrg    }
1514b8e80941Smrg    else
1515b8e80941Smrg    {
1516b8e80941Smrg        // A pre-filled tile info is ready
1517b8e80941Smrg        index = pOut->tileIndex;
1518b8e80941Smrg        macroModeIndex = pOut->macroModeIndex;
1519b8e80941Smrg
1520b8e80941Smrg        // pass tile type back for post tile index compute
1521b8e80941Smrg        pOut->tileType = inTileType;
1522b8e80941Smrg
1523b8e80941Smrg        if (flags.depth || flags.stencil)
1524b8e80941Smrg        {
1525b8e80941Smrg            // tileSize = thickness * bpp * numSamples * 8 * 8 / 8
1526b8e80941Smrg            UINT_32 tileSize = thickness * bpp * numSamples * 8;
1527b8e80941Smrg
1528b8e80941Smrg            // Turn off tc compatible if row_size is smaller than tile size (tile split occurs).
1529b8e80941Smrg            if (m_rowSize < tileSize)
1530b8e80941Smrg            {
1531b8e80941Smrg                flags.tcCompatible = FALSE;
1532b8e80941Smrg            }
1533b8e80941Smrg        }
1534b8e80941Smrg
1535b8e80941Smrg        UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig);
1536b8e80941Smrg
1537b8e80941Smrg        if (m_pipes != numPipes)
1538b8e80941Smrg        {
1539b8e80941Smrg            pOut->dccUnsupport = TRUE;
1540b8e80941Smrg        }
1541b8e80941Smrg    }
1542b8e80941Smrg
1543b8e80941Smrg    // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
1544b8e80941Smrg    if ((index != TileIndexInvalid) && (macroModeIndex == TileIndexInvalid))
1545b8e80941Smrg    {
1546b8e80941Smrg        macroModeIndex = HwlComputeMacroModeIndex(index, flags, bpp, numSamples, pTileInfo);
1547b8e80941Smrg
1548b8e80941Smrg        // Copy to pOut->tileType/tileIndex/macroModeIndex
1549b8e80941Smrg        pOut->tileIndex = index;
1550b8e80941Smrg        pOut->tileType = m_tileTable[index].type; // Or inTileType, the samea
1551b8e80941Smrg        pOut->macroModeIndex = macroModeIndex;
1552b8e80941Smrg    }
1553b8e80941Smrg    else if (tileMode == ADDR_TM_LINEAR_GENERAL)
1554b8e80941Smrg    {
1555b8e80941Smrg        pOut->tileIndex = TileIndexLinearGeneral;
1556b8e80941Smrg
1557b8e80941Smrg        // Copy linear-aligned entry??
1558b8e80941Smrg        *pTileInfo = m_tileTable[8].info;
1559b8e80941Smrg    }
1560b8e80941Smrg    else if (tileMode == ADDR_TM_LINEAR_ALIGNED)
1561b8e80941Smrg    {
1562b8e80941Smrg        pOut->tileIndex = 8;
1563b8e80941Smrg        *pTileInfo = m_tileTable[8].info;
1564b8e80941Smrg    }
1565b8e80941Smrg
1566b8e80941Smrg    if (flags.tcCompatible)
1567b8e80941Smrg    {
1568b8e80941Smrg        flags.tcCompatible = CheckTcCompatibility(pTileInfo, bpp, tileMode, inTileType, pOut);
1569b8e80941Smrg    }
1570b8e80941Smrg
1571b8e80941Smrg    pOut->tcCompatible = flags.tcCompatible;
1572b8e80941Smrg}
1573b8e80941Smrg
1574b8e80941Smrg/**
1575b8e80941Smrg****************************************************************************************************
1576b8e80941Smrg*   CiLib::ReadGbTileMode
1577b8e80941Smrg*
1578b8e80941Smrg*   @brief
1579b8e80941Smrg*       Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
1580b8e80941Smrg****************************************************************************************************
1581b8e80941Smrg*/
1582b8e80941SmrgVOID CiLib::ReadGbTileMode(
1583b8e80941Smrg    UINT_32       regValue,   ///< [in] GB_TILE_MODE register
1584b8e80941Smrg    TileConfig*   pCfg        ///< [out] output structure
1585b8e80941Smrg    ) const
1586b8e80941Smrg{
1587b8e80941Smrg    GB_TILE_MODE gbTileMode;
1588b8e80941Smrg    gbTileMode.val = regValue;
1589b8e80941Smrg
1590b8e80941Smrg    pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode_new);
1591b8e80941Smrg    pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
1592b8e80941Smrg
1593b8e80941Smrg    if (pCfg->type == ADDR_DEPTH_SAMPLE_ORDER)
1594b8e80941Smrg    {
1595b8e80941Smrg        pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
1596b8e80941Smrg    }
1597b8e80941Smrg    else
1598b8e80941Smrg    {
1599b8e80941Smrg        pCfg->info.tileSplitBytes = 1 << gbTileMode.f.sample_split;
1600b8e80941Smrg    }
1601b8e80941Smrg
1602b8e80941Smrg    UINT_32 regArrayMode = gbTileMode.f.array_mode;
1603b8e80941Smrg
1604b8e80941Smrg    pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
1605b8e80941Smrg
1606b8e80941Smrg    switch (regArrayMode)
1607b8e80941Smrg    {
1608b8e80941Smrg        case 5:
1609b8e80941Smrg            pCfg->mode = ADDR_TM_PRT_TILED_THIN1;
1610b8e80941Smrg            break;
1611b8e80941Smrg        case 6:
1612b8e80941Smrg            pCfg->mode = ADDR_TM_PRT_2D_TILED_THIN1;
1613b8e80941Smrg            break;
1614b8e80941Smrg        case 8:
1615b8e80941Smrg            pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
1616b8e80941Smrg            break;
1617b8e80941Smrg        case 9:
1618b8e80941Smrg            pCfg->mode = ADDR_TM_PRT_TILED_THICK;
1619b8e80941Smrg            break;
1620b8e80941Smrg        case 0xa:
1621b8e80941Smrg            pCfg->mode = ADDR_TM_PRT_2D_TILED_THICK;
1622b8e80941Smrg            break;
1623b8e80941Smrg        case 0xb:
1624b8e80941Smrg            pCfg->mode = ADDR_TM_PRT_3D_TILED_THIN1;
1625b8e80941Smrg            break;
1626b8e80941Smrg        case 0xe:
1627b8e80941Smrg            pCfg->mode = ADDR_TM_3D_TILED_XTHICK;
1628b8e80941Smrg            break;
1629b8e80941Smrg        case 0xf:
1630b8e80941Smrg            pCfg->mode = ADDR_TM_PRT_3D_TILED_THICK;
1631b8e80941Smrg            break;
1632b8e80941Smrg        default:
1633b8e80941Smrg            break;
1634b8e80941Smrg    }
1635b8e80941Smrg
1636b8e80941Smrg    // Fail-safe code for these always convert tile info, as the non-macro modes
1637b8e80941Smrg    // return the entry of tile mode table directly without looking up macro mode table
1638b8e80941Smrg    if (!IsMacroTiled(pCfg->mode))
1639b8e80941Smrg    {
1640b8e80941Smrg        pCfg->info.banks = 2;
1641b8e80941Smrg        pCfg->info.bankWidth = 1;
1642b8e80941Smrg        pCfg->info.bankHeight = 1;
1643b8e80941Smrg        pCfg->info.macroAspectRatio = 1;
1644b8e80941Smrg        pCfg->info.tileSplitBytes = 64;
1645b8e80941Smrg    }
1646b8e80941Smrg}
1647b8e80941Smrg
1648b8e80941Smrg/**
1649b8e80941Smrg****************************************************************************************************
1650b8e80941Smrg*   CiLib::InitTileSettingTable
1651b8e80941Smrg*
1652b8e80941Smrg*   @brief
1653b8e80941Smrg*       Initialize the ADDR_TILE_CONFIG table.
1654b8e80941Smrg*   @return
1655b8e80941Smrg*       TRUE if tile table is correctly initialized
1656b8e80941Smrg****************************************************************************************************
1657b8e80941Smrg*/
1658b8e80941SmrgBOOL_32 CiLib::InitTileSettingTable(
1659b8e80941Smrg    const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
1660b8e80941Smrg    UINT_32         noOfEntries     ///< [in] Numbe of entries in the table above
1661b8e80941Smrg    )
1662b8e80941Smrg{
1663b8e80941Smrg    BOOL_32 initOk = TRUE;
1664b8e80941Smrg
1665b8e80941Smrg    ADDR_ASSERT(noOfEntries <= TileTableSize);
1666b8e80941Smrg
1667b8e80941Smrg    memset(m_tileTable, 0, sizeof(m_tileTable));
1668b8e80941Smrg
1669b8e80941Smrg    if (noOfEntries != 0)
1670b8e80941Smrg    {
1671b8e80941Smrg        m_noOfEntries = noOfEntries;
1672b8e80941Smrg    }
1673b8e80941Smrg    else
1674b8e80941Smrg    {
1675b8e80941Smrg        m_noOfEntries = TileTableSize;
1676b8e80941Smrg    }
1677b8e80941Smrg
1678b8e80941Smrg    if (pCfg) // From Client
1679b8e80941Smrg    {
1680b8e80941Smrg        for (UINT_32 i = 0; i < m_noOfEntries; i++)
1681b8e80941Smrg        {
1682b8e80941Smrg            ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
1683b8e80941Smrg        }
1684b8e80941Smrg    }
1685b8e80941Smrg    else
1686b8e80941Smrg    {
1687b8e80941Smrg        ADDR_ASSERT_ALWAYS();
1688b8e80941Smrg        initOk = FALSE;
1689b8e80941Smrg    }
1690b8e80941Smrg
1691b8e80941Smrg    if (initOk)
1692b8e80941Smrg    {
1693b8e80941Smrg        ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
1694b8e80941Smrg
1695b8e80941Smrg        if (m_settings.isBonaire == FALSE)
1696b8e80941Smrg        {
1697b8e80941Smrg            // Check if entry 18 is "thick+thin" combination
1698b8e80941Smrg            if ((m_tileTable[18].mode == ADDR_TM_1D_TILED_THICK) &&
1699b8e80941Smrg                (m_tileTable[18].type == ADDR_NON_DISPLAYABLE))
1700b8e80941Smrg            {
1701b8e80941Smrg                m_allowNonDispThickModes = TRUE;
1702b8e80941Smrg                ADDR_ASSERT(m_tileTable[24].mode == ADDR_TM_2D_TILED_THICK);
1703b8e80941Smrg            }
1704b8e80941Smrg        }
1705b8e80941Smrg        else
1706b8e80941Smrg        {
1707b8e80941Smrg            m_allowNonDispThickModes = TRUE;
1708b8e80941Smrg        }
1709b8e80941Smrg
1710b8e80941Smrg        // Assume the first entry is always programmed with full pipes
1711b8e80941Smrg        m_pipes = HwlGetPipes(&m_tileTable[0].info);
1712b8e80941Smrg    }
1713b8e80941Smrg
1714b8e80941Smrg    return initOk;
1715b8e80941Smrg}
1716b8e80941Smrg
1717b8e80941Smrg/**
1718b8e80941Smrg****************************************************************************************************
1719b8e80941Smrg*   CiLib::ReadGbMacroTileCfg
1720b8e80941Smrg*
1721b8e80941Smrg*   @brief
1722b8e80941Smrg*       Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
1723b8e80941Smrg****************************************************************************************************
1724b8e80941Smrg*/
1725b8e80941SmrgVOID CiLib::ReadGbMacroTileCfg(
1726b8e80941Smrg    UINT_32             regValue,   ///< [in] GB_MACRO_TILE_MODE register
1727b8e80941Smrg    ADDR_TILEINFO*      pCfg        ///< [out] output structure
1728b8e80941Smrg    ) const
1729b8e80941Smrg{
1730b8e80941Smrg    GB_MACROTILE_MODE gbTileMode;
1731b8e80941Smrg    gbTileMode.val = regValue;
1732b8e80941Smrg
1733b8e80941Smrg    pCfg->bankHeight = 1 << gbTileMode.f.bank_height;
1734b8e80941Smrg    pCfg->bankWidth = 1 << gbTileMode.f.bank_width;
1735b8e80941Smrg    pCfg->banks = 1 << (gbTileMode.f.num_banks + 1);
1736b8e80941Smrg    pCfg->macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
1737b8e80941Smrg}
1738b8e80941Smrg
1739b8e80941Smrg/**
1740b8e80941Smrg****************************************************************************************************
1741b8e80941Smrg*   CiLib::InitMacroTileCfgTable
1742b8e80941Smrg*
1743b8e80941Smrg*   @brief
1744b8e80941Smrg*       Initialize the ADDR_MACRO_TILE_CONFIG table.
1745b8e80941Smrg*   @return
1746b8e80941Smrg*       TRUE if macro tile table is correctly initialized
1747b8e80941Smrg****************************************************************************************************
1748b8e80941Smrg*/
1749b8e80941SmrgBOOL_32 CiLib::InitMacroTileCfgTable(
1750b8e80941Smrg    const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
1751b8e80941Smrg    UINT_32         noOfMacroEntries     ///< [in] Numbe of entries in the table above
1752b8e80941Smrg    )
1753b8e80941Smrg{
1754b8e80941Smrg    BOOL_32 initOk = TRUE;
1755b8e80941Smrg
1756b8e80941Smrg    ADDR_ASSERT(noOfMacroEntries <= MacroTileTableSize);
1757b8e80941Smrg
1758b8e80941Smrg    memset(m_macroTileTable, 0, sizeof(m_macroTileTable));
1759b8e80941Smrg
1760b8e80941Smrg    if (noOfMacroEntries != 0)
1761b8e80941Smrg    {
1762b8e80941Smrg        m_noOfMacroEntries = noOfMacroEntries;
1763b8e80941Smrg    }
1764b8e80941Smrg    else
1765b8e80941Smrg    {
1766b8e80941Smrg        m_noOfMacroEntries = MacroTileTableSize;
1767b8e80941Smrg    }
1768b8e80941Smrg
1769b8e80941Smrg    if (pCfg) // From Client
1770b8e80941Smrg    {
1771b8e80941Smrg        for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
1772b8e80941Smrg        {
1773b8e80941Smrg            ReadGbMacroTileCfg(*(pCfg + i), &m_macroTileTable[i]);
1774b8e80941Smrg
1775b8e80941Smrg            m_macroTileTable[i].tileSplitBytes = 64 << (i % 8);
1776b8e80941Smrg        }
1777b8e80941Smrg    }
1778b8e80941Smrg    else
1779b8e80941Smrg    {
1780b8e80941Smrg        ADDR_ASSERT_ALWAYS();
1781b8e80941Smrg        initOk = FALSE;
1782b8e80941Smrg    }
1783b8e80941Smrg    return initOk;
1784b8e80941Smrg}
1785b8e80941Smrg
1786b8e80941Smrg/**
1787b8e80941Smrg****************************************************************************************************
1788b8e80941Smrg*   CiLib::HwlComputeMacroModeIndex
1789b8e80941Smrg*
1790b8e80941Smrg*   @brief
1791b8e80941Smrg*       Computes macro tile mode index
1792b8e80941Smrg*   @return
1793b8e80941Smrg*       TRUE if macro tile table is correctly initialized
1794b8e80941Smrg****************************************************************************************************
1795b8e80941Smrg*/
1796b8e80941SmrgINT_32 CiLib::HwlComputeMacroModeIndex(
1797b8e80941Smrg    INT_32              tileIndex,      ///< [in] Tile mode index
1798b8e80941Smrg    ADDR_SURFACE_FLAGS  flags,          ///< [in] Surface flags
1799b8e80941Smrg    UINT_32             bpp,            ///< [in] Bit per pixel
1800b8e80941Smrg    UINT_32             numSamples,     ///< [in] Number of samples
1801b8e80941Smrg    ADDR_TILEINFO*      pTileInfo,      ///< [out] Pointer to ADDR_TILEINFO
1802b8e80941Smrg    AddrTileMode*       pTileMode,      ///< [out] Pointer to AddrTileMode
1803b8e80941Smrg    AddrTileType*       pTileType       ///< [out] Pointer to AddrTileType
1804b8e80941Smrg    ) const
1805b8e80941Smrg{
1806b8e80941Smrg    INT_32 macroModeIndex = TileIndexInvalid;
1807b8e80941Smrg
1808b8e80941Smrg    AddrTileMode tileMode = m_tileTable[tileIndex].mode;
1809b8e80941Smrg    AddrTileType tileType = m_tileTable[tileIndex].type;
1810b8e80941Smrg    UINT_32 thickness = Thickness(tileMode);
1811b8e80941Smrg
1812b8e80941Smrg    if (!IsMacroTiled(tileMode))
1813b8e80941Smrg    {
1814b8e80941Smrg        *pTileInfo = m_tileTable[tileIndex].info;
1815b8e80941Smrg        macroModeIndex = TileIndexNoMacroIndex;
1816b8e80941Smrg    }
1817b8e80941Smrg    else
1818b8e80941Smrg    {
1819b8e80941Smrg        UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
1820b8e80941Smrg        UINT_32 tileSplit;
1821b8e80941Smrg
1822b8e80941Smrg        if (m_tileTable[tileIndex].type == ADDR_DEPTH_SAMPLE_ORDER)
1823b8e80941Smrg        {
1824b8e80941Smrg            // Depth entries store real tileSplitBytes
1825b8e80941Smrg            tileSplit = m_tileTable[tileIndex].info.tileSplitBytes;
1826b8e80941Smrg        }
1827b8e80941Smrg        else
1828b8e80941Smrg        {
1829b8e80941Smrg            // Non-depth entries store a split factor
1830b8e80941Smrg            UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes;
1831b8e80941Smrg            UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x);
1832b8e80941Smrg
1833b8e80941Smrg            tileSplit = colorTileSplit;
1834b8e80941Smrg        }
1835b8e80941Smrg
1836b8e80941Smrg        UINT_32 tileSplitC = Min(m_rowSize, tileSplit);
1837b8e80941Smrg        UINT_32 tileBytes;
1838b8e80941Smrg
1839b8e80941Smrg        if (flags.fmask)
1840b8e80941Smrg        {
1841b8e80941Smrg            tileBytes = Min(tileSplitC, tileBytes1x);
1842b8e80941Smrg        }
1843b8e80941Smrg        else
1844b8e80941Smrg        {
1845b8e80941Smrg            tileBytes = Min(tileSplitC, numSamples * tileBytes1x);
1846b8e80941Smrg        }
1847b8e80941Smrg
1848b8e80941Smrg        if (tileBytes < 64)
1849b8e80941Smrg        {
1850b8e80941Smrg            tileBytes = 64;
1851b8e80941Smrg        }
1852b8e80941Smrg
1853b8e80941Smrg        macroModeIndex = Log2(tileBytes / 64);
1854b8e80941Smrg
1855b8e80941Smrg        if (flags.prt || IsPrtTileMode(tileMode))
1856b8e80941Smrg        {
1857b8e80941Smrg            macroModeIndex += PrtMacroModeOffset;
1858b8e80941Smrg            *pTileInfo = m_macroTileTable[macroModeIndex];
1859b8e80941Smrg        }
1860b8e80941Smrg        else
1861b8e80941Smrg        {
1862b8e80941Smrg            *pTileInfo = m_macroTileTable[macroModeIndex];
1863b8e80941Smrg        }
1864b8e80941Smrg
1865b8e80941Smrg        pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig;
1866b8e80941Smrg
1867b8e80941Smrg        pTileInfo->tileSplitBytes = tileSplitC;
1868b8e80941Smrg    }
1869b8e80941Smrg
1870b8e80941Smrg    if (NULL != pTileMode)
1871b8e80941Smrg    {
1872b8e80941Smrg        *pTileMode = tileMode;
1873b8e80941Smrg    }
1874b8e80941Smrg
1875b8e80941Smrg    if (NULL != pTileType)
1876b8e80941Smrg    {
1877b8e80941Smrg        *pTileType = tileType;
1878b8e80941Smrg    }
1879b8e80941Smrg
1880b8e80941Smrg    return macroModeIndex;
1881b8e80941Smrg}
1882b8e80941Smrg
1883b8e80941Smrg/**
1884b8e80941Smrg****************************************************************************************************
1885b8e80941Smrg*   CiLib::HwlComputeTileDataWidthAndHeightLinear
1886b8e80941Smrg*
1887b8e80941Smrg*   @brief
1888b8e80941Smrg*       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1889b8e80941Smrg*
1890b8e80941Smrg*   @note
1891b8e80941Smrg*       MacroWidth and macroHeight are measured in pixels
1892b8e80941Smrg****************************************************************************************************
1893b8e80941Smrg*/
1894b8e80941SmrgVOID CiLib::HwlComputeTileDataWidthAndHeightLinear(
1895b8e80941Smrg    UINT_32*        pMacroWidth,     ///< [out] macro tile width
1896b8e80941Smrg    UINT_32*        pMacroHeight,    ///< [out] macro tile height
1897b8e80941Smrg    UINT_32         bpp,             ///< [in] bits per pixel
1898b8e80941Smrg    ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
1899b8e80941Smrg    ) const
1900b8e80941Smrg{
1901b8e80941Smrg    ADDR_ASSERT(pTileInfo != NULL);
1902b8e80941Smrg
1903b8e80941Smrg    UINT_32 numTiles;
1904b8e80941Smrg
1905b8e80941Smrg    switch (pTileInfo->pipeConfig)
1906b8e80941Smrg    {
1907b8e80941Smrg        case ADDR_PIPECFG_P16_32x32_8x16:
1908b8e80941Smrg        case ADDR_PIPECFG_P16_32x32_16x16:
1909b8e80941Smrg        case ADDR_PIPECFG_P8_32x64_32x32:
1910b8e80941Smrg        case ADDR_PIPECFG_P8_32x32_16x32:
1911b8e80941Smrg        case ADDR_PIPECFG_P8_32x32_16x16:
1912b8e80941Smrg        case ADDR_PIPECFG_P8_32x32_8x16:
1913b8e80941Smrg        case ADDR_PIPECFG_P4_32x32:
1914b8e80941Smrg            numTiles = 8;
1915b8e80941Smrg            break;
1916b8e80941Smrg        default:
1917b8e80941Smrg            numTiles = 4;
1918b8e80941Smrg            break;
1919b8e80941Smrg    }
1920b8e80941Smrg
1921b8e80941Smrg    *pMacroWidth    = numTiles * MicroTileWidth;
1922b8e80941Smrg    *pMacroHeight   = numTiles * MicroTileHeight;
1923b8e80941Smrg}
1924b8e80941Smrg
1925b8e80941Smrg/**
1926b8e80941Smrg****************************************************************************************************
1927b8e80941Smrg*   CiLib::HwlComputeMetadataNibbleAddress
1928b8e80941Smrg*
1929b8e80941Smrg*   @brief
1930b8e80941Smrg*        calculate meta data address based on input information
1931b8e80941Smrg*
1932b8e80941Smrg*   &parameter
1933b8e80941Smrg*        uncompressedDataByteAddress - address of a pixel in color surface
1934b8e80941Smrg*        dataBaseByteAddress         - base address of color surface
1935b8e80941Smrg*        metadataBaseByteAddress     - base address of meta ram
1936b8e80941Smrg*        metadataBitSize             - meta key size, 8 for DCC, 4 for cmask
1937b8e80941Smrg*        elementBitSize              - element size of color surface
1938b8e80941Smrg*        blockByteSize               - compression block size, 256 for DCC
1939b8e80941Smrg*        pipeInterleaveBytes         - pipe interleave size
1940b8e80941Smrg*        numOfPipes                  - number of pipes
1941b8e80941Smrg*        numOfBanks                  - number of banks
1942b8e80941Smrg*        numOfSamplesPerSplit        - number of samples per tile split
1943b8e80941Smrg*   @return
1944b8e80941Smrg*        meta data nibble address (nibble address is used to support DCC compatible cmask)
1945b8e80941Smrg*
1946b8e80941Smrg****************************************************************************************************
1947b8e80941Smrg*/
1948b8e80941SmrgUINT_64 CiLib::HwlComputeMetadataNibbleAddress(
1949b8e80941Smrg    UINT_64 uncompressedDataByteAddress,
1950b8e80941Smrg    UINT_64 dataBaseByteAddress,
1951b8e80941Smrg    UINT_64 metadataBaseByteAddress,
1952b8e80941Smrg    UINT_32 metadataBitSize,
1953b8e80941Smrg    UINT_32 elementBitSize,
1954b8e80941Smrg    UINT_32 blockByteSize,
1955b8e80941Smrg    UINT_32 pipeInterleaveBytes,
1956b8e80941Smrg    UINT_32 numOfPipes,
1957b8e80941Smrg    UINT_32 numOfBanks,
1958b8e80941Smrg    UINT_32 numOfSamplesPerSplit) const
1959b8e80941Smrg{
1960b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1961b8e80941Smrg    /// Get pipe interleave, bank and pipe bits
1962b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1963b8e80941Smrg    UINT_32 pipeInterleaveBits  = Log2(pipeInterleaveBytes);
1964b8e80941Smrg    UINT_32 pipeBits            = Log2(numOfPipes);
1965b8e80941Smrg    UINT_32 bankBits            = Log2(numOfBanks);
1966b8e80941Smrg
1967b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1968b8e80941Smrg    /// Clear pipe and bank swizzles
1969b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1970b8e80941Smrg    UINT_32 dataMacrotileBits        = pipeInterleaveBits + pipeBits + bankBits;
1971b8e80941Smrg    UINT_32 metadataMacrotileBits    = pipeInterleaveBits + pipeBits + bankBits;
1972b8e80941Smrg
1973b8e80941Smrg    UINT_64 dataMacrotileClearMask     = ~((1L << dataMacrotileBits) - 1);
1974b8e80941Smrg    UINT_64 metadataMacrotileClearMask = ~((1L << metadataMacrotileBits) - 1);
1975b8e80941Smrg
1976b8e80941Smrg    UINT_64 dataBaseByteAddressNoSwizzle = dataBaseByteAddress & dataMacrotileClearMask;
1977b8e80941Smrg    UINT_64 metadataBaseByteAddressNoSwizzle = metadataBaseByteAddress & metadataMacrotileClearMask;
1978b8e80941Smrg
1979b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1980b8e80941Smrg    /// Modify metadata base before adding in so that when final address is divided by data ratio,
1981b8e80941Smrg    /// the base address returns to where it should be
1982b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1983b8e80941Smrg    ADDR_ASSERT((0 != metadataBitSize));
1984b8e80941Smrg    UINT_64 metadataBaseShifted = metadataBaseByteAddressNoSwizzle * blockByteSize * 8 /
1985b8e80941Smrg                                  metadataBitSize;
1986b8e80941Smrg    UINT_64 offset = uncompressedDataByteAddress -
1987b8e80941Smrg                     dataBaseByteAddressNoSwizzle +
1988b8e80941Smrg                     metadataBaseShifted;
1989b8e80941Smrg
1990b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1991b8e80941Smrg    /// Save bank data bits
1992b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1993b8e80941Smrg    UINT_32 lsb = pipeBits + pipeInterleaveBits;
1994b8e80941Smrg    UINT_32 msb = bankBits - 1 + lsb;
1995b8e80941Smrg
1996b8e80941Smrg    UINT_64 bankDataBits = GetBits(offset, msb, lsb);
1997b8e80941Smrg
1998b8e80941Smrg    ///--------------------------------------------------------------------------------------------
1999b8e80941Smrg    /// Save pipe data bits
2000b8e80941Smrg    ///--------------------------------------------------------------------------------------------
2001b8e80941Smrg    lsb = pipeInterleaveBits;
2002b8e80941Smrg    msb = pipeBits - 1 + lsb;
2003b8e80941Smrg
2004b8e80941Smrg    UINT_64 pipeDataBits = GetBits(offset, msb, lsb);
2005b8e80941Smrg
2006b8e80941Smrg    ///--------------------------------------------------------------------------------------------
2007b8e80941Smrg    /// Remove pipe and bank bits
2008b8e80941Smrg    ///--------------------------------------------------------------------------------------------
2009b8e80941Smrg    lsb = pipeInterleaveBits;
2010b8e80941Smrg    msb = dataMacrotileBits - 1;
2011b8e80941Smrg
2012b8e80941Smrg    UINT_64 offsetWithoutPipeBankBits = RemoveBits(offset, msb, lsb);
2013b8e80941Smrg
2014b8e80941Smrg    ADDR_ASSERT((0 != blockByteSize));
2015b8e80941Smrg    UINT_64 blockInBankpipe = offsetWithoutPipeBankBits / blockByteSize;
2016b8e80941Smrg
2017b8e80941Smrg    UINT_32 tileSize = 8 * 8 * elementBitSize/8 * numOfSamplesPerSplit;
2018b8e80941Smrg    UINT_32 blocksInTile = tileSize / blockByteSize;
2019b8e80941Smrg
2020b8e80941Smrg    if (0 == blocksInTile)
2021b8e80941Smrg    {
2022b8e80941Smrg        lsb = 0;
2023b8e80941Smrg    }
2024b8e80941Smrg    else
2025b8e80941Smrg    {
2026b8e80941Smrg        lsb = Log2(blocksInTile);
2027b8e80941Smrg    }
2028b8e80941Smrg    msb = bankBits - 1 + lsb;
2029b8e80941Smrg
2030b8e80941Smrg    UINT_64 blockInBankpipeWithBankBits = InsertBits(blockInBankpipe, bankDataBits, msb, lsb);
2031b8e80941Smrg
2032b8e80941Smrg    /// NOTE *2 because we are converting to Nibble address in this step
2033b8e80941Smrg    UINT_64 metaAddressInPipe = blockInBankpipeWithBankBits * 2 * metadataBitSize / 8;
2034b8e80941Smrg
2035b8e80941Smrg    ///--------------------------------------------------------------------------------------------
2036b8e80941Smrg    /// Reinsert pipe bits back into the final address
2037b8e80941Smrg    ///--------------------------------------------------------------------------------------------
2038b8e80941Smrg    lsb = pipeInterleaveBits + 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
2039b8e80941Smrg    msb = pipeBits - 1 + lsb;
2040b8e80941Smrg    UINT_64 metadataAddress = InsertBits(metaAddressInPipe, pipeDataBits, msb, lsb);
2041b8e80941Smrg
2042b8e80941Smrg    return metadataAddress;
2043b8e80941Smrg}
2044b8e80941Smrg
2045b8e80941Smrg/**
2046b8e80941Smrg****************************************************************************************************
2047b8e80941Smrg*   CiLib::HwlComputeSurfaceAlignmentsMacroTiled
2048b8e80941Smrg*
2049b8e80941Smrg*   @brief
2050b8e80941Smrg*       Hardware layer function to compute alignment request for macro tile mode
2051b8e80941Smrg*
2052b8e80941Smrg****************************************************************************************************
2053b8e80941Smrg*/
2054b8e80941SmrgVOID CiLib::HwlComputeSurfaceAlignmentsMacroTiled(
2055b8e80941Smrg    AddrTileMode                      tileMode,           ///< [in] tile mode
2056b8e80941Smrg    UINT_32                           bpp,                ///< [in] bits per pixel
2057b8e80941Smrg    ADDR_SURFACE_FLAGS                flags,              ///< [in] surface flags
2058b8e80941Smrg    UINT_32                           mipLevel,           ///< [in] mip level
2059b8e80941Smrg    UINT_32                           numSamples,         ///< [in] number of samples
2060b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut                ///< [in,out] Surface output
2061b8e80941Smrg    ) const
2062b8e80941Smrg{
2063b8e80941Smrg    // This is to workaround a H/W limitation that DCC doesn't work when pipe config is switched to
2064b8e80941Smrg    // P4. In theory, all asics that have such switching should be patched but we now only know what
2065b8e80941Smrg    // to pad for Fiji.
2066b8e80941Smrg    if ((m_settings.isFiji == TRUE) &&
2067b8e80941Smrg        (flags.dccPipeWorkaround == TRUE) &&
2068b8e80941Smrg        (flags.prt == FALSE) &&
2069b8e80941Smrg        (mipLevel == 0) &&
2070b8e80941Smrg        (tileMode == ADDR_TM_PRT_TILED_THIN1) &&
2071b8e80941Smrg        (pOut->dccUnsupport == TRUE))
2072b8e80941Smrg    {
2073b8e80941Smrg        pOut->pitchAlign   = PowTwoAlign(pOut->pitchAlign, 256);
2074b8e80941Smrg        // In case the client still requests DCC usage.
2075b8e80941Smrg        pOut->dccUnsupport = FALSE;
2076b8e80941Smrg    }
2077b8e80941Smrg}
2078b8e80941Smrg
2079b8e80941Smrg/**
2080b8e80941Smrg****************************************************************************************************
2081b8e80941Smrg*   CiLib::HwlPadDimensions
2082b8e80941Smrg*
2083b8e80941Smrg*   @brief
2084b8e80941Smrg*       Helper function to pad dimensions
2085b8e80941Smrg*
2086b8e80941Smrg****************************************************************************************************
2087b8e80941Smrg*/
2088b8e80941SmrgVOID CiLib::HwlPadDimensions(
2089b8e80941Smrg    AddrTileMode        tileMode,    ///< [in] tile mode
2090b8e80941Smrg    UINT_32             bpp,         ///< [in] bits per pixel
2091b8e80941Smrg    ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags
2092b8e80941Smrg    UINT_32             numSamples,  ///< [in] number of samples
2093b8e80941Smrg    ADDR_TILEINFO*      pTileInfo,   ///< [in] tile info
2094b8e80941Smrg    UINT_32             mipLevel,    ///< [in] mip level
2095b8e80941Smrg    UINT_32*            pPitch,      ///< [in,out] pitch in pixels
2096b8e80941Smrg    UINT_32*            pPitchAlign, ///< [in,out] pitch alignment
2097b8e80941Smrg    UINT_32             height,      ///< [in] height in pixels
2098b8e80941Smrg    UINT_32             heightAlign  ///< [in] height alignment
2099b8e80941Smrg    ) const
2100b8e80941Smrg{
2101b8e80941Smrg    if ((m_settings.isVolcanicIslands == TRUE) &&
2102b8e80941Smrg        (flags.dccCompatible == TRUE) &&
2103b8e80941Smrg        (numSamples > 1) &&
2104b8e80941Smrg        (mipLevel == 0) &&
2105b8e80941Smrg        (IsMacroTiled(tileMode) == TRUE))
2106b8e80941Smrg    {
2107b8e80941Smrg        UINT_32 tileSizePerSample = BITS_TO_BYTES(bpp * MicroTileWidth * MicroTileHeight);
2108b8e80941Smrg        UINT_32 samplesPerSplit  = pTileInfo->tileSplitBytes / tileSizePerSample;
2109b8e80941Smrg
2110b8e80941Smrg        if (samplesPerSplit < numSamples)
2111b8e80941Smrg        {
2112b8e80941Smrg            UINT_32 dccFastClearByteAlign = HwlGetPipes(pTileInfo) * m_pipeInterleaveBytes * 256;
2113b8e80941Smrg            UINT_32 bytesPerSplit = BITS_TO_BYTES((*pPitch) * height * bpp * samplesPerSplit);
2114b8e80941Smrg
2115b8e80941Smrg            ADDR_ASSERT(IsPow2(dccFastClearByteAlign));
2116b8e80941Smrg
2117b8e80941Smrg            if (0 != (bytesPerSplit & (dccFastClearByteAlign - 1)))
2118b8e80941Smrg            {
2119b8e80941Smrg                UINT_32 dccFastClearPixelAlign = dccFastClearByteAlign /
2120b8e80941Smrg                                                BITS_TO_BYTES(bpp) /
2121b8e80941Smrg                                                samplesPerSplit;
2122b8e80941Smrg                UINT_32 macroTilePixelAlign = (*pPitchAlign) * heightAlign;
2123b8e80941Smrg
2124b8e80941Smrg                if ((dccFastClearPixelAlign >= macroTilePixelAlign) &&
2125b8e80941Smrg                    ((dccFastClearPixelAlign % macroTilePixelAlign) == 0))
2126b8e80941Smrg                {
2127b8e80941Smrg                    UINT_32 dccFastClearPitchAlignInMacroTile =
2128b8e80941Smrg                        dccFastClearPixelAlign / macroTilePixelAlign;
2129b8e80941Smrg                    UINT_32 heightInMacroTile = height / heightAlign;
2130b8e80941Smrg
2131b8e80941Smrg                    while ((heightInMacroTile > 1) &&
2132b8e80941Smrg                           ((heightInMacroTile % 2) == 0) &&
2133b8e80941Smrg                           (dccFastClearPitchAlignInMacroTile > 1) &&
2134b8e80941Smrg                           ((dccFastClearPitchAlignInMacroTile % 2) == 0))
2135b8e80941Smrg                    {
2136b8e80941Smrg                        heightInMacroTile >>= 1;
2137b8e80941Smrg                        dccFastClearPitchAlignInMacroTile >>= 1;
2138b8e80941Smrg                    }
2139b8e80941Smrg
2140b8e80941Smrg                    UINT_32 dccFastClearPitchAlignInPixels =
2141b8e80941Smrg                        (*pPitchAlign) * dccFastClearPitchAlignInMacroTile;
2142b8e80941Smrg
2143b8e80941Smrg                    if (IsPow2(dccFastClearPitchAlignInPixels))
2144b8e80941Smrg                    {
2145b8e80941Smrg                        *pPitch = PowTwoAlign((*pPitch), dccFastClearPitchAlignInPixels);
2146b8e80941Smrg                    }
2147b8e80941Smrg                    else
2148b8e80941Smrg                    {
2149b8e80941Smrg                        *pPitch += (dccFastClearPitchAlignInPixels - 1);
2150b8e80941Smrg                        *pPitch /= dccFastClearPitchAlignInPixels;
2151b8e80941Smrg                        *pPitch *= dccFastClearPitchAlignInPixels;
2152b8e80941Smrg                    }
2153b8e80941Smrg
2154b8e80941Smrg                    *pPitchAlign = dccFastClearPitchAlignInPixels;
2155b8e80941Smrg                }
2156b8e80941Smrg            }
2157b8e80941Smrg        }
2158b8e80941Smrg    }
2159b8e80941Smrg}
2160b8e80941Smrg
2161b8e80941Smrg/**
2162b8e80941Smrg****************************************************************************************************
2163b8e80941Smrg*   CiLib::HwlComputeMaxBaseAlignments
2164b8e80941Smrg*
2165b8e80941Smrg*   @brief
2166b8e80941Smrg*       Gets maximum alignments
2167b8e80941Smrg*   @return
2168b8e80941Smrg*       maximum alignments
2169b8e80941Smrg****************************************************************************************************
2170b8e80941Smrg*/
2171b8e80941SmrgUINT_32 CiLib::HwlComputeMaxBaseAlignments() const
2172b8e80941Smrg{
2173b8e80941Smrg    const UINT_32 pipes = HwlGetPipes(&m_tileTable[0].info);
2174b8e80941Smrg
2175b8e80941Smrg    // Initial size is 64 KiB for PRT.
2176b8e80941Smrg    UINT_32 maxBaseAlign = 64 * 1024;
2177b8e80941Smrg
2178b8e80941Smrg    for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
2179b8e80941Smrg    {
2180b8e80941Smrg        // The maximum tile size is 16 byte-per-pixel and either 8-sample or 8-slice.
2181b8e80941Smrg        UINT_32 tileSize = m_macroTileTable[i].tileSplitBytes;
2182b8e80941Smrg
2183b8e80941Smrg        UINT_32 baseAlign = tileSize * pipes * m_macroTileTable[i].banks *
2184b8e80941Smrg                            m_macroTileTable[i].bankWidth * m_macroTileTable[i].bankHeight;
2185b8e80941Smrg
2186b8e80941Smrg        if (baseAlign > maxBaseAlign)
2187b8e80941Smrg        {
2188b8e80941Smrg            maxBaseAlign = baseAlign;
2189b8e80941Smrg        }
2190b8e80941Smrg    }
2191b8e80941Smrg
2192b8e80941Smrg    return maxBaseAlign;
2193b8e80941Smrg}
2194b8e80941Smrg
2195b8e80941Smrg/**
2196b8e80941Smrg****************************************************************************************************
2197b8e80941Smrg*   CiLib::HwlComputeMaxMetaBaseAlignments
2198b8e80941Smrg*
2199b8e80941Smrg*   @brief
2200b8e80941Smrg*       Gets maximum alignments for metadata
2201b8e80941Smrg*   @return
2202b8e80941Smrg*       maximum alignments for metadata
2203b8e80941Smrg****************************************************************************************************
2204b8e80941Smrg*/
2205b8e80941SmrgUINT_32 CiLib::HwlComputeMaxMetaBaseAlignments() const
2206b8e80941Smrg{
2207b8e80941Smrg    UINT_32 maxBank = 1;
2208b8e80941Smrg
2209b8e80941Smrg    for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
2210b8e80941Smrg    {
2211b8e80941Smrg        if ((m_settings.isVolcanicIslands) && IsMacroTiled(m_tileTable[i].mode))
2212b8e80941Smrg        {
2213b8e80941Smrg            maxBank = Max(maxBank, m_macroTileTable[i].banks);
2214b8e80941Smrg        }
2215b8e80941Smrg    }
2216b8e80941Smrg
2217b8e80941Smrg    return SiLib::HwlComputeMaxMetaBaseAlignments() * maxBank;
2218b8e80941Smrg}
2219b8e80941Smrg
2220b8e80941Smrg/**
2221b8e80941Smrg****************************************************************************************************
2222b8e80941Smrg*   CiLib::DepthStencilTileCfgMatch
2223b8e80941Smrg*
2224b8e80941Smrg*   @brief
2225b8e80941Smrg*       Try to find a tile index for stencil which makes its tile config parameters matches to depth
2226b8e80941Smrg*   @return
2227b8e80941Smrg*       TRUE if such tile index for stencil can be found
2228b8e80941Smrg****************************************************************************************************
2229b8e80941Smrg*/
2230b8e80941SmrgBOOL_32 CiLib::DepthStencilTileCfgMatch(
2231b8e80941Smrg    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
2232b8e80941Smrg    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
2233b8e80941Smrg    ) const
2234b8e80941Smrg{
2235b8e80941Smrg    BOOL_32 depthStencil2DTileConfigMatch = FALSE;
2236b8e80941Smrg
2237b8e80941Smrg    for (INT_32 stencilTileIndex = MinDepth2DThinIndex;
2238b8e80941Smrg         stencilTileIndex <= MaxDepth2DThinIndex;
2239b8e80941Smrg         stencilTileIndex++)
2240b8e80941Smrg    {
2241b8e80941Smrg        ADDR_TILEINFO tileInfo = {0};
2242b8e80941Smrg        INT_32 stencilMacroIndex = HwlComputeMacroModeIndex(stencilTileIndex,
2243b8e80941Smrg                                                            pIn->flags,
2244b8e80941Smrg                                                            8,
2245b8e80941Smrg                                                            pIn->numSamples,
2246b8e80941Smrg                                                            &tileInfo);
2247b8e80941Smrg
2248b8e80941Smrg        if (stencilMacroIndex != TileIndexNoMacroIndex)
2249b8e80941Smrg        {
2250b8e80941Smrg            if ((m_macroTileTable[stencilMacroIndex].banks ==
2251b8e80941Smrg                 m_macroTileTable[pOut->macroModeIndex].banks) &&
2252b8e80941Smrg                (m_macroTileTable[stencilMacroIndex].bankWidth ==
2253b8e80941Smrg                 m_macroTileTable[pOut->macroModeIndex].bankWidth) &&
2254b8e80941Smrg                (m_macroTileTable[stencilMacroIndex].bankHeight ==
2255b8e80941Smrg                 m_macroTileTable[pOut->macroModeIndex].bankHeight) &&
2256b8e80941Smrg                (m_macroTileTable[stencilMacroIndex].macroAspectRatio ==
2257b8e80941Smrg                 m_macroTileTable[pOut->macroModeIndex].macroAspectRatio) &&
2258b8e80941Smrg                (m_macroTileTable[stencilMacroIndex].pipeConfig ==
2259b8e80941Smrg                 m_macroTileTable[pOut->macroModeIndex].pipeConfig))
2260b8e80941Smrg            {
2261b8e80941Smrg                if ((pOut->tcCompatible == FALSE) ||
2262b8e80941Smrg                    (tileInfo.tileSplitBytes >= MicroTileWidth * MicroTileHeight * pIn->numSamples))
2263b8e80941Smrg                {
2264b8e80941Smrg                    depthStencil2DTileConfigMatch = TRUE;
2265b8e80941Smrg                    pOut->stencilTileIdx = stencilTileIndex;
2266b8e80941Smrg                    break;
2267b8e80941Smrg                }
2268b8e80941Smrg            }
2269b8e80941Smrg        }
2270b8e80941Smrg        else
2271b8e80941Smrg        {
2272b8e80941Smrg            ADDR_ASSERT_ALWAYS();
2273b8e80941Smrg        }
2274b8e80941Smrg    }
2275b8e80941Smrg
2276b8e80941Smrg    return depthStencil2DTileConfigMatch;
2277b8e80941Smrg}
2278b8e80941Smrg
2279b8e80941Smrg/**
2280b8e80941Smrg****************************************************************************************************
2281b8e80941Smrg*   CiLib::DepthStencilTileCfgMatch
2282b8e80941Smrg*
2283b8e80941Smrg*   @brief
2284b8e80941Smrg*       Check if tc compatibility is available
2285b8e80941Smrg*   @return
2286b8e80941Smrg*       If tc compatibility is not available
2287b8e80941Smrg****************************************************************************************************
2288b8e80941Smrg*/
2289b8e80941SmrgBOOL_32 CiLib::CheckTcCompatibility(
2290b8e80941Smrg    const ADDR_TILEINFO*                    pTileInfo,    ///< [in] input tile info
2291b8e80941Smrg    UINT_32                                 bpp,          ///< [in] Bits per pixel
2292b8e80941Smrg    AddrTileMode                            tileMode,     ///< [in] input tile mode
2293b8e80941Smrg    AddrTileType                            tileType,     ///< [in] input tile type
2294b8e80941Smrg    const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut          ///< [in] output surf info
2295b8e80941Smrg    ) const
2296b8e80941Smrg{
2297b8e80941Smrg    BOOL_32 tcCompatible = TRUE;
2298b8e80941Smrg
2299b8e80941Smrg    if (IsMacroTiled(tileMode))
2300b8e80941Smrg    {
2301b8e80941Smrg        if (tileType != ADDR_DEPTH_SAMPLE_ORDER)
2302b8e80941Smrg        {
2303b8e80941Smrg            // Turn off tcCompatible for color surface if tileSplit happens. Depth/stencil
2304b8e80941Smrg            // tileSplit case was handled at tileIndex selecting time.
2305b8e80941Smrg            INT_32 tileIndex = pOut->tileIndex;
2306b8e80941Smrg
2307b8e80941Smrg            if ((tileIndex == TileIndexInvalid) && (IsTileInfoAllZero(pTileInfo) == FALSE))
2308b8e80941Smrg            {
2309b8e80941Smrg                tileIndex = HwlPostCheckTileIndex(pTileInfo, tileMode, tileType, tileIndex);
2310b8e80941Smrg            }
2311b8e80941Smrg
2312b8e80941Smrg            if (tileIndex != TileIndexInvalid)
2313b8e80941Smrg            {
2314b8e80941Smrg                UINT_32 thickness = Thickness(tileMode);
2315b8e80941Smrg
2316b8e80941Smrg                ADDR_ASSERT(static_cast<UINT_32>(tileIndex) < TileTableSize);
2317b8e80941Smrg                // Non-depth entries store a split factor
2318b8e80941Smrg                UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes;
2319b8e80941Smrg                UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
2320b8e80941Smrg                UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x);
2321b8e80941Smrg
2322b8e80941Smrg                if (m_rowSize < colorTileSplit)
2323b8e80941Smrg                {
2324b8e80941Smrg                    tcCompatible = FALSE;
2325b8e80941Smrg                }
2326b8e80941Smrg            }
2327b8e80941Smrg        }
2328b8e80941Smrg    }
2329b8e80941Smrg    else
2330b8e80941Smrg    {
2331b8e80941Smrg        // Client should not enable tc compatible for linear and 1D tile modes.
2332b8e80941Smrg        tcCompatible = FALSE;
2333b8e80941Smrg    }
2334b8e80941Smrg
2335b8e80941Smrg    return tcCompatible;
2336b8e80941Smrg}
2337b8e80941Smrg
2338b8e80941Smrg} // V1
2339b8e80941Smrg} // Addr
2340