~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/amd/addrlib/src/core/addrlib1.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
************************************************************************************************************************
3
 
*
4
 
*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
5
 
*
6
 
* Permission is hereby granted, free of charge, to any person obtaining a
7
 
* copy of this software and associated documentation files (the "Software"),
8
 
* to deal in the Software without restriction, including without limitation
9
 
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 
* and/or sell copies of the Software, and to permit persons to whom the
11
 
* Software is furnished to do so, subject to the following conditions:
12
 
*
13
 
* The above copyright notice and this permission notice shall be included in
14
 
* all copies or substantial portions of the Software.
15
 
*
16
 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 
* OTHER DEALINGS IN THE SOFTWARE
23
 
*
24
 
***********************************************************************************************************************/
25
 
 
26
 
/**
27
 
****************************************************************************************************
28
 
* @file  addr1lib.cpp
29
 
* @brief Contains the implementation for the Addr::V1::Lib base class.
30
 
****************************************************************************************************
31
 
*/
32
 
 
33
 
#include "addrinterface.h"
34
 
#include "addrlib1.h"
35
 
#include "addrcommon.h"
36
 
 
37
 
namespace Addr
38
 
{
39
 
namespace V1
40
 
{
41
 
 
42
 
////////////////////////////////////////////////////////////////////////////////////////////////////
43
 
//                               Static Const Member
44
 
////////////////////////////////////////////////////////////////////////////////////////////////////
45
 
 
46
 
const TileModeFlags Lib::ModeFlags[ADDR_TM_COUNT] =
47
 
{// T   L  1  2  3  P  Pr B
48
 
    {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
49
 
    {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
50
 
    {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
51
 
    {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
52
 
    {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
53
 
    {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
54
 
    {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
55
 
    {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
56
 
    {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
57
 
    {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
58
 
    {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
59
 
    {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
60
 
    {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
61
 
    {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
62
 
    {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
63
 
    {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
64
 
    {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
65
 
    {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
66
 
    {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
67
 
    {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
68
 
    {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
69
 
    {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
70
 
    {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
71
 
    {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
72
 
    {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
73
 
    {0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_UNKNOWN
74
 
};
75
 
 
76
 
////////////////////////////////////////////////////////////////////////////////////////////////////
77
 
//                               Constructor/Destructor
78
 
////////////////////////////////////////////////////////////////////////////////////////////////////
79
 
 
80
 
/**
81
 
****************************************************************************************************
82
 
*   Lib::AddrLib1
83
 
*
84
 
*   @brief
85
 
*       Constructor for the AddrLib1 class
86
 
*
87
 
****************************************************************************************************
88
 
*/
89
 
Lib::Lib()
90
 
    :
91
 
    Addr::Lib()
92
 
{
93
 
}
94
 
 
95
 
/**
96
 
****************************************************************************************************
97
 
*   Lib::Lib
98
 
*
99
 
*   @brief
100
 
*       Constructor for the Addr::V1::Lib class with hClient as parameter
101
 
*
102
 
****************************************************************************************************
103
 
*/
104
 
Lib::Lib(const Client* pClient)
105
 
    :
106
 
    Addr::Lib(pClient)
107
 
{
108
 
}
109
 
 
110
 
/**
111
 
****************************************************************************************************
112
 
*   Lib::~AddrLib1
113
 
*
114
 
*   @brief
115
 
*       Destructor for the AddrLib1 class
116
 
*
117
 
****************************************************************************************************
118
 
*/
119
 
Lib::~Lib()
120
 
{
121
 
}
122
 
 
123
 
/**
124
 
****************************************************************************************************
125
 
*   Lib::GetLib
126
 
*
127
 
*   @brief
128
 
*       Get AddrLib1 pointer
129
 
*
130
 
*   @return
131
 
*      An Addr::V1::Lib class pointer
132
 
****************************************************************************************************
133
 
*/
134
 
Lib* Lib::GetLib(
135
 
    ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
136
 
{
137
 
    Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
138
 
    if ((pAddrLib != NULL) &&
139
 
        ((pAddrLib->GetChipFamily() == ADDR_CHIP_FAMILY_IVLD) ||
140
 
         (pAddrLib->GetChipFamily() > ADDR_CHIP_FAMILY_VI)))
141
 
    {
142
 
        // only valid and pre-VI ASIC can use AddrLib1 function.
143
 
        ADDR_ASSERT_ALWAYS();
144
 
        hLib = NULL;
145
 
    }
146
 
    return static_cast<Lib*>(hLib);
147
 
}
148
 
 
149
 
 
150
 
////////////////////////////////////////////////////////////////////////////////////////////////////
151
 
//                               Surface Methods
152
 
////////////////////////////////////////////////////////////////////////////////////////////////////
153
 
 
154
 
 
155
 
/**
156
 
****************************************************************************************************
157
 
*   Lib::ComputeSurfaceInfo
158
 
*
159
 
*   @brief
160
 
*       Interface function stub of AddrComputeSurfaceInfo.
161
 
*
162
 
*   @return
163
 
*       ADDR_E_RETURNCODE
164
 
****************************************************************************************************
165
 
*/
166
 
ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
167
 
     const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
168
 
     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
169
 
     ) const
170
 
{
171
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
172
 
 
173
 
    if (GetFillSizeFieldsFlags() == TRUE)
174
 
    {
175
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) ||
176
 
            (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT)))
177
 
        {
178
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
179
 
        }
180
 
    }
181
 
 
182
 
    // We suggest client do sanity check but a check here is also good
183
 
    if (pIn->bpp > 128)
184
 
    {
185
 
        returnCode = ADDR_INVALIDPARAMS;
186
 
    }
187
 
 
188
 
    if ((pIn->tileMode == ADDR_TM_UNKNOWN) && (pIn->mipLevel > 0))
189
 
    {
190
 
        returnCode = ADDR_INVALIDPARAMS;
191
 
    }
192
 
 
193
 
    // Thick modes don't support multisample
194
 
    if ((Thickness(pIn->tileMode) > 1) && (pIn->numSamples > 1))
195
 
    {
196
 
        returnCode = ADDR_INVALIDPARAMS;
197
 
    }
198
 
 
199
 
    if (returnCode == ADDR_OK)
200
 
    {
201
 
        // Get a local copy of input structure and only reference pIn for unadjusted values
202
 
        ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
203
 
        ADDR_TILEINFO tileInfoNull = {0};
204
 
 
205
 
        if (UseTileInfo())
206
 
        {
207
 
            // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
208
 
            // Otherwise the default 0's in tileInfoNull are used.
209
 
            if (pIn->pTileInfo)
210
 
            {
211
 
                tileInfoNull = *pIn->pTileInfo;
212
 
            }
213
 
            localIn.pTileInfo  = &tileInfoNull;
214
 
        }
215
 
 
216
 
        localIn.numSamples = (pIn->numSamples == 0) ? 1 : pIn->numSamples;
217
 
 
218
 
        // Do mipmap check first
219
 
        // If format is BCn, pre-pad dimension to power-of-two according to HWL
220
 
        ComputeMipLevel(&localIn);
221
 
 
222
 
        if (m_configFlags.checkLast2DLevel)
223
 
        {
224
 
            // Save this level's original height in pixels
225
 
            pOut->height = pIn->height;
226
 
        }
227
 
 
228
 
        UINT_32 expandX = 1;
229
 
        UINT_32 expandY = 1;
230
 
        ElemMode elemMode;
231
 
 
232
 
        // Save outputs that may not go through HWL
233
 
        pOut->pixelBits = localIn.bpp;
234
 
        pOut->numSamples = localIn.numSamples;
235
 
        pOut->last2DLevel = FALSE;
236
 
        pOut->tcCompatible = FALSE;
237
 
 
238
 
#if !ALT_TEST
239
 
        if (localIn.numSamples > 1)
240
 
        {
241
 
            ADDR_ASSERT(localIn.mipLevel == 0);
242
 
        }
243
 
#endif
244
 
 
245
 
        if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion
246
 
        {
247
 
            // Get compression/expansion factors and element mode
248
 
            // (which indicates compression/expansion
249
 
            localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
250
 
                                                        &elemMode,
251
 
                                                        &expandX,
252
 
                                                        &expandY);
253
 
 
254
 
            // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
255
 
            // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
256
 
            // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
257
 
            // restrictions are different.
258
 
            // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
259
 
            // but we use this flag to skip RestoreSurfaceInfo below
260
 
 
261
 
            if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
262
 
            {
263
 
                ADDR_ASSERT(IsLinear(localIn.tileMode));
264
 
            }
265
 
 
266
 
            GetElemLib()->AdjustSurfaceInfo(elemMode,
267
 
                                            expandX,
268
 
                                            expandY,
269
 
                                            &localIn.bpp,
270
 
                                            &localIn.basePitch,
271
 
                                            &localIn.width,
272
 
                                            &localIn.height);
273
 
 
274
 
            // Overwrite these parameters if we have a valid format
275
 
        }
276
 
        else if (localIn.bpp != 0)
277
 
        {
278
 
            localIn.width  = (localIn.width != 0) ? localIn.width : 1;
279
 
            localIn.height = (localIn.height != 0) ? localIn.height : 1;
280
 
        }
281
 
        else // Rule out some invalid parameters
282
 
        {
283
 
            ADDR_ASSERT_ALWAYS();
284
 
 
285
 
            returnCode = ADDR_INVALIDPARAMS;
286
 
        }
287
 
 
288
 
        // Check mipmap after surface expansion
289
 
        if (returnCode == ADDR_OK)
290
 
        {
291
 
            returnCode = PostComputeMipLevel(&localIn, pOut);
292
 
        }
293
 
 
294
 
        if (returnCode == ADDR_OK)
295
 
        {
296
 
            if (UseTileIndex(localIn.tileIndex))
297
 
            {
298
 
                // Make sure pTileInfo is not NULL
299
 
                ADDR_ASSERT(localIn.pTileInfo);
300
 
 
301
 
                UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags);
302
 
 
303
 
                INT_32 macroModeIndex = TileIndexNoMacroIndex;
304
 
 
305
 
                if (localIn.tileIndex != TileIndexLinearGeneral)
306
 
                {
307
 
                    // Try finding a macroModeIndex
308
 
                    macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex,
309
 
                                                              localIn.flags,
310
 
                                                              localIn.bpp,
311
 
                                                              numSamples,
312
 
                                                              localIn.pTileInfo,
313
 
                                                              &localIn.tileMode,
314
 
                                                              &localIn.tileType);
315
 
                }
316
 
 
317
 
                // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
318
 
                if (macroModeIndex == TileIndexNoMacroIndex)
319
 
                {
320
 
                    returnCode = HwlSetupTileCfg(localIn.bpp,
321
 
                                                 localIn.tileIndex, macroModeIndex,
322
 
                                                 localIn.pTileInfo,
323
 
                                                 &localIn.tileMode, &localIn.tileType);
324
 
                }
325
 
                // If macroModeIndex is invalid, then assert this is not macro tiled
326
 
                else if (macroModeIndex == TileIndexInvalid)
327
 
                {
328
 
                    ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
329
 
                }
330
 
 
331
 
                pOut->macroModeIndex = macroModeIndex;
332
 
            }
333
 
        }
334
 
 
335
 
        if (returnCode == ADDR_OK)
336
 
        {
337
 
            localIn.flags.dccPipeWorkaround = localIn.flags.dccCompatible;
338
 
 
339
 
            if (localIn.tileMode == ADDR_TM_UNKNOWN)
340
 
            {
341
 
                // HWL layer may override tile mode if necessary
342
 
                HwlSelectTileMode(&localIn);
343
 
            }
344
 
            else
345
 
            {
346
 
                // HWL layer may override tile mode if necessary
347
 
                HwlOverrideTileMode(&localIn);
348
 
 
349
 
                // Optimize tile mode if possible
350
 
                OptimizeTileMode(&localIn);
351
 
            }
352
 
        }
353
 
 
354
 
        // Call main function to compute surface info
355
 
        if (returnCode == ADDR_OK)
356
 
        {
357
 
            returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
358
 
        }
359
 
 
360
 
        if (returnCode == ADDR_OK)
361
 
        {
362
 
            // Since bpp might be changed we just pass it through
363
 
            pOut->bpp  = localIn.bpp;
364
 
 
365
 
            // Also original width/height/bpp
366
 
            pOut->pixelPitch    = pOut->pitch;
367
 
            pOut->pixelHeight   = pOut->height;
368
 
 
369
 
#if DEBUG
370
 
            if (localIn.flags.display)
371
 
            {
372
 
                ADDR_ASSERT((pOut->pitchAlign % 32) == 0);
373
 
            }
374
 
#endif //DEBUG
375
 
 
376
 
            if (localIn.format != ADDR_FMT_INVALID)
377
 
            {
378
 
                //
379
 
                // Note: For 96 bit surface, the pixelPitch returned might be an odd number, but it
380
 
                // is okay to program texture pitch as HW's mip calculator would multiply 3 first,
381
 
                // then do the appropriate paddings (linear alignment requirement and possible the
382
 
                // nearest power-of-two for mipmaps), which results in the original pitch.
383
 
                //
384
 
                GetElemLib()->RestoreSurfaceInfo(elemMode,
385
 
                                                 expandX,
386
 
                                                 expandY,
387
 
                                                 &localIn.bpp,
388
 
                                                 &pOut->pixelPitch,
389
 
                                                 &pOut->pixelHeight);
390
 
            }
391
 
 
392
 
            if (localIn.flags.qbStereo)
393
 
            {
394
 
                if (pOut->pStereoInfo)
395
 
                {
396
 
                    ComputeQbStereoInfo(pOut);
397
 
                }
398
 
            }
399
 
 
400
 
            if (localIn.flags.volume) // For volume sliceSize equals to all z-slices
401
 
            {
402
 
                pOut->sliceSize = pOut->surfSize;
403
 
            }
404
 
            else // For array: sliceSize is likely to have slice-padding (the last one)
405
 
            {
406
 
                pOut->sliceSize = pOut->surfSize / pOut->depth;
407
 
 
408
 
                // array or cubemap
409
 
                if (pIn->numSlices > 1)
410
 
                {
411
 
                    // If this is the last slice then add the padding size to this slice
412
 
                    if (pIn->slice == (pIn->numSlices - 1))
413
 
                    {
414
 
                        pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices);
415
 
                    }
416
 
                    else if (m_configFlags.checkLast2DLevel)
417
 
                    {
418
 
                        // Reset last2DLevel flag if this is not the last array slice
419
 
                        pOut->last2DLevel = FALSE;
420
 
                    }
421
 
                }
422
 
            }
423
 
 
424
 
            pOut->pitchTileMax = pOut->pitch / 8 - 1;
425
 
            pOut->heightTileMax = pOut->height / 8 - 1;
426
 
            pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1;
427
 
        }
428
 
    }
429
 
 
430
 
    ValidBaseAlignments(pOut->baseAlign);
431
 
 
432
 
    return returnCode;
433
 
}
434
 
 
435
 
/**
436
 
****************************************************************************************************
437
 
*   Lib::ComputeSurfaceInfo
438
 
*
439
 
*   @brief
440
 
*       Interface function stub of AddrComputeSurfaceInfo.
441
 
*
442
 
*   @return
443
 
*       ADDR_E_RETURNCODE
444
 
****************************************************************************************************
445
 
*/
446
 
ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
447
 
    const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
448
 
    ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
449
 
    ) const
450
 
{
451
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
452
 
 
453
 
    if (GetFillSizeFieldsFlags() == TRUE)
454
 
    {
455
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
456
 
            (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
457
 
        {
458
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
459
 
        }
460
 
    }
461
 
 
462
 
    if (returnCode == ADDR_OK)
463
 
    {
464
 
        ADDR_TILEINFO tileInfoNull;
465
 
        ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;
466
 
 
467
 
        if (UseTileIndex(pIn->tileIndex))
468
 
        {
469
 
            input = *pIn;
470
 
            // Use temp tile info for calcalation
471
 
            input.pTileInfo = &tileInfoNull;
472
 
 
473
 
            const ADDR_SURFACE_FLAGS flags = {{0}};
474
 
            UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
475
 
 
476
 
            // Try finding a macroModeIndex
477
 
            INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
478
 
                                                             flags,
479
 
                                                             input.bpp,
480
 
                                                             numSamples,
481
 
                                                             input.pTileInfo,
482
 
                                                             &input.tileMode,
483
 
                                                             &input.tileType);
484
 
 
485
 
            // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
486
 
            if (macroModeIndex == TileIndexNoMacroIndex)
487
 
            {
488
 
                returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex, macroModeIndex,
489
 
                                             input.pTileInfo, &input.tileMode, &input.tileType);
490
 
            }
491
 
            // If macroModeIndex is invalid, then assert this is not macro tiled
492
 
            else if (macroModeIndex == TileIndexInvalid)
493
 
            {
494
 
                ADDR_ASSERT(!IsMacroTiled(input.tileMode));
495
 
            }
496
 
 
497
 
            // Change the input structure
498
 
            pIn = &input;
499
 
        }
500
 
 
501
 
        if (returnCode == ADDR_OK)
502
 
        {
503
 
            returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);
504
 
 
505
 
            if (returnCode == ADDR_OK)
506
 
            {
507
 
                pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
508
 
            }
509
 
        }
510
 
    }
511
 
 
512
 
    return returnCode;
513
 
}
514
 
 
515
 
/**
516
 
****************************************************************************************************
517
 
*   Lib::ComputeSurfaceCoordFromAddr
518
 
*
519
 
*   @brief
520
 
*       Interface function stub of ComputeSurfaceCoordFromAddr.
521
 
*
522
 
*   @return
523
 
*       ADDR_E_RETURNCODE
524
 
****************************************************************************************************
525
 
*/
526
 
ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
527
 
    const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
528
 
    ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure
529
 
    ) const
530
 
{
531
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
532
 
 
533
 
    if (GetFillSizeFieldsFlags() == TRUE)
534
 
    {
535
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
536
 
            (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
537
 
        {
538
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
539
 
        }
540
 
    }
541
 
 
542
 
    if (returnCode == ADDR_OK)
543
 
    {
544
 
        ADDR_TILEINFO tileInfoNull;
545
 
        ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input;
546
 
 
547
 
        if (UseTileIndex(pIn->tileIndex))
548
 
        {
549
 
            input = *pIn;
550
 
            // Use temp tile info for calcalation
551
 
            input.pTileInfo = &tileInfoNull;
552
 
 
553
 
            const ADDR_SURFACE_FLAGS flags = {{0}};
554
 
            UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
555
 
 
556
 
            // Try finding a macroModeIndex
557
 
            INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
558
 
                                                             flags,
559
 
                                                             input.bpp,
560
 
                                                             numSamples,
561
 
                                                             input.pTileInfo,
562
 
                                                             &input.tileMode,
563
 
                                                             &input.tileType);
564
 
 
565
 
            // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
566
 
            if (macroModeIndex == TileIndexNoMacroIndex)
567
 
            {
568
 
                returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex, macroModeIndex,
569
 
                                             input.pTileInfo, &input.tileMode, &input.tileType);
570
 
            }
571
 
            // If macroModeIndex is invalid, then assert this is not macro tiled
572
 
            else if (macroModeIndex == TileIndexInvalid)
573
 
            {
574
 
                ADDR_ASSERT(!IsMacroTiled(input.tileMode));
575
 
            }
576
 
 
577
 
            // Change the input structure
578
 
            pIn = &input;
579
 
        }
580
 
 
581
 
        if (returnCode == ADDR_OK)
582
 
        {
583
 
            returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);
584
 
        }
585
 
    }
586
 
 
587
 
    return returnCode;
588
 
}
589
 
 
590
 
/**
591
 
****************************************************************************************************
592
 
*   Lib::ComputeSliceTileSwizzle
593
 
*
594
 
*   @brief
595
 
*       Interface function stub of ComputeSliceTileSwizzle.
596
 
*
597
 
*   @return
598
 
*       ADDR_E_RETURNCODE
599
 
****************************************************************************************************
600
 
*/
601
 
ADDR_E_RETURNCODE Lib::ComputeSliceTileSwizzle(
602
 
    const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,    ///< [in] input structure
603
 
    ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut    ///< [out] output structure
604
 
    ) const
605
 
{
606
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
607
 
 
608
 
    if (GetFillSizeFieldsFlags() == TRUE)
609
 
    {
610
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) ||
611
 
            (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT)))
612
 
        {
613
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
614
 
        }
615
 
    }
616
 
 
617
 
    if (returnCode == ADDR_OK)
618
 
    {
619
 
        ADDR_TILEINFO tileInfoNull;
620
 
        ADDR_COMPUTE_SLICESWIZZLE_INPUT input;
621
 
 
622
 
        if (UseTileIndex(pIn->tileIndex))
623
 
        {
624
 
            input = *pIn;
625
 
            // Use temp tile info for calcalation
626
 
            input.pTileInfo = &tileInfoNull;
627
 
 
628
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex,
629
 
                                         input.pTileInfo, &input.tileMode);
630
 
            // Change the input structure
631
 
            pIn = &input;
632
 
        }
633
 
 
634
 
        if (returnCode == ADDR_OK)
635
 
        {
636
 
            returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);
637
 
        }
638
 
    }
639
 
 
640
 
    return returnCode;
641
 
}
642
 
 
643
 
/**
644
 
****************************************************************************************************
645
 
*   Lib::ExtractBankPipeSwizzle
646
 
*
647
 
*   @brief
648
 
*       Interface function stub of AddrExtractBankPipeSwizzle.
649
 
*
650
 
*   @return
651
 
*       ADDR_E_RETURNCODE
652
 
****************************************************************************************************
653
 
*/
654
 
ADDR_E_RETURNCODE Lib::ExtractBankPipeSwizzle(
655
 
    const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure
656
 
    ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure
657
 
    ) const
658
 
{
659
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
660
 
 
661
 
    if (GetFillSizeFieldsFlags() == TRUE)
662
 
    {
663
 
        if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) ||
664
 
            (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT)))
665
 
        {
666
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
667
 
        }
668
 
    }
669
 
 
670
 
    if (returnCode == ADDR_OK)
671
 
    {
672
 
        ADDR_TILEINFO tileInfoNull;
673
 
        ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input;
674
 
 
675
 
        if (UseTileIndex(pIn->tileIndex))
676
 
        {
677
 
            input = *pIn;
678
 
            // Use temp tile info for calcalation
679
 
            input.pTileInfo = &tileInfoNull;
680
 
 
681
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
682
 
            // Change the input structure
683
 
            pIn = &input;
684
 
        }
685
 
 
686
 
        if (returnCode == ADDR_OK)
687
 
        {
688
 
            returnCode = HwlExtractBankPipeSwizzle(pIn, pOut);
689
 
        }
690
 
    }
691
 
 
692
 
    return returnCode;
693
 
}
694
 
 
695
 
/**
696
 
****************************************************************************************************
697
 
*   Lib::CombineBankPipeSwizzle
698
 
*
699
 
*   @brief
700
 
*       Interface function stub of AddrCombineBankPipeSwizzle.
701
 
*
702
 
*   @return
703
 
*       ADDR_E_RETURNCODE
704
 
****************************************************************************************************
705
 
*/
706
 
ADDR_E_RETURNCODE Lib::CombineBankPipeSwizzle(
707
 
    const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure
708
 
    ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure
709
 
    ) const
710
 
{
711
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
712
 
 
713
 
    if (GetFillSizeFieldsFlags() == TRUE)
714
 
    {
715
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
716
 
            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
717
 
        {
718
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
719
 
        }
720
 
    }
721
 
 
722
 
    if (returnCode == ADDR_OK)
723
 
    {
724
 
        ADDR_TILEINFO tileInfoNull;
725
 
        ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input;
726
 
 
727
 
        if (UseTileIndex(pIn->tileIndex))
728
 
        {
729
 
            input = *pIn;
730
 
            // Use temp tile info for calcalation
731
 
            input.pTileInfo = &tileInfoNull;
732
 
 
733
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
734
 
            // Change the input structure
735
 
            pIn = &input;
736
 
        }
737
 
 
738
 
        if (returnCode == ADDR_OK)
739
 
        {
740
 
            returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle,
741
 
                                                   pIn->pipeSwizzle,
742
 
                                                   pIn->pTileInfo,
743
 
                                                   pIn->baseAddr,
744
 
                                                   &pOut->tileSwizzle);
745
 
        }
746
 
    }
747
 
 
748
 
    return returnCode;
749
 
}
750
 
 
751
 
/**
752
 
****************************************************************************************************
753
 
*   Lib::ComputeBaseSwizzle
754
 
*
755
 
*   @brief
756
 
*       Interface function stub of AddrCompueBaseSwizzle.
757
 
*   @return
758
 
*       ADDR_E_RETURNCODE
759
 
****************************************************************************************************
760
 
*/
761
 
ADDR_E_RETURNCODE Lib::ComputeBaseSwizzle(
762
 
    const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,
763
 
    ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const
764
 
{
765
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
766
 
 
767
 
    if (GetFillSizeFieldsFlags() == TRUE)
768
 
    {
769
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) ||
770
 
            (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT)))
771
 
        {
772
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
773
 
        }
774
 
    }
775
 
 
776
 
    if (returnCode == ADDR_OK)
777
 
    {
778
 
        ADDR_TILEINFO tileInfoNull;
779
 
        ADDR_COMPUTE_BASE_SWIZZLE_INPUT input;
780
 
 
781
 
        if (UseTileIndex(pIn->tileIndex))
782
 
        {
783
 
            input = *pIn;
784
 
            // Use temp tile info for calcalation
785
 
            input.pTileInfo = &tileInfoNull;
786
 
 
787
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
788
 
            // Change the input structure
789
 
            pIn = &input;
790
 
        }
791
 
 
792
 
        if (returnCode == ADDR_OK)
793
 
        {
794
 
            if (IsMacroTiled(pIn->tileMode))
795
 
            {
796
 
                returnCode = HwlComputeBaseSwizzle(pIn, pOut);
797
 
            }
798
 
            else
799
 
            {
800
 
                pOut->tileSwizzle = 0;
801
 
            }
802
 
        }
803
 
    }
804
 
 
805
 
    return returnCode;
806
 
}
807
 
 
808
 
/**
809
 
****************************************************************************************************
810
 
*   Lib::ComputeFmaskInfo
811
 
*
812
 
*   @brief
813
 
*       Interface function stub of ComputeFmaskInfo.
814
 
*
815
 
*   @return
816
 
*       ADDR_E_RETURNCODE
817
 
****************************************************************************************************
818
 
*/
819
 
ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
820
 
    const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure
821
 
    ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
822
 
    )
823
 
{
824
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
825
 
 
826
 
    if (GetFillSizeFieldsFlags() == TRUE)
827
 
    {
828
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
829
 
            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
830
 
        {
831
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
832
 
        }
833
 
    }
834
 
 
835
 
    // No thick MSAA
836
 
    if (Thickness(pIn->tileMode) > 1)
837
 
    {
838
 
        returnCode = ADDR_INVALIDPARAMS;
839
 
    }
840
 
 
841
 
    if (returnCode == ADDR_OK)
842
 
    {
843
 
        ADDR_TILEINFO tileInfoNull;
844
 
        ADDR_COMPUTE_FMASK_INFO_INPUT input;
845
 
 
846
 
        if (UseTileIndex(pIn->tileIndex))
847
 
        {
848
 
            input = *pIn;
849
 
 
850
 
            if (pOut->pTileInfo)
851
 
            {
852
 
                // Use temp tile info for calcalation
853
 
                input.pTileInfo = pOut->pTileInfo;
854
 
            }
855
 
            else
856
 
            {
857
 
                input.pTileInfo = &tileInfoNull;
858
 
            }
859
 
 
860
 
            ADDR_SURFACE_FLAGS flags = {{0}};
861
 
            flags.fmask = 1;
862
 
 
863
 
            // Try finding a macroModeIndex
864
 
            INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex,
865
 
                                                             flags,
866
 
                                                             HwlComputeFmaskBits(pIn, NULL),
867
 
                                                             pIn->numSamples,
868
 
                                                             input.pTileInfo,
869
 
                                                             &input.tileMode);
870
 
 
871
 
            // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
872
 
            if (macroModeIndex == TileIndexNoMacroIndex)
873
 
            {
874
 
                returnCode = HwlSetupTileCfg(0, input.tileIndex, macroModeIndex,
875
 
                                             input.pTileInfo, &input.tileMode);
876
 
            }
877
 
 
878
 
            ADDR_ASSERT(macroModeIndex != TileIndexInvalid);
879
 
 
880
 
            // Change the input structure
881
 
            pIn = &input;
882
 
        }
883
 
 
884
 
        if (returnCode == ADDR_OK)
885
 
        {
886
 
            if (pIn->numSamples > 1)
887
 
            {
888
 
                returnCode = HwlComputeFmaskInfo(pIn, pOut);
889
 
            }
890
 
            else
891
 
            {
892
 
                memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT));
893
 
 
894
 
                returnCode = ADDR_INVALIDPARAMS;
895
 
            }
896
 
        }
897
 
    }
898
 
 
899
 
    ValidBaseAlignments(pOut->baseAlign);
900
 
 
901
 
    return returnCode;
902
 
}
903
 
 
904
 
/**
905
 
****************************************************************************************************
906
 
*   Lib::ComputeFmaskAddrFromCoord
907
 
*
908
 
*   @brief
909
 
*       Interface function stub of ComputeFmaskAddrFromCoord.
910
 
*
911
 
*   @return
912
 
*       ADDR_E_RETURNCODE
913
 
****************************************************************************************************
914
 
*/
915
 
ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
916
 
    const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
917
 
    ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
918
 
    ) const
919
 
{
920
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
921
 
 
922
 
    if (GetFillSizeFieldsFlags() == TRUE)
923
 
    {
924
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) ||
925
 
            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT)))
926
 
        {
927
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
928
 
        }
929
 
    }
930
 
 
931
 
    if (returnCode == ADDR_OK)
932
 
    {
933
 
        ADDR_ASSERT(pIn->numSamples > 1);
934
 
 
935
 
        if (pIn->numSamples > 1)
936
 
        {
937
 
            returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut);
938
 
        }
939
 
        else
940
 
        {
941
 
            returnCode = ADDR_INVALIDPARAMS;
942
 
        }
943
 
    }
944
 
 
945
 
    return returnCode;
946
 
}
947
 
 
948
 
/**
949
 
****************************************************************************************************
950
 
*   Lib::ComputeFmaskCoordFromAddr
951
 
*
952
 
*   @brief
953
 
*       Interface function stub of ComputeFmaskAddrFromCoord.
954
 
*
955
 
*   @return
956
 
*       ADDR_E_RETURNCODE
957
 
****************************************************************************************************
958
 
*/
959
 
ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
960
 
    const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure
961
 
    ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut           ///< [out] output structure
962
 
    ) const
963
 
{
964
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
965
 
 
966
 
    if (GetFillSizeFieldsFlags() == TRUE)
967
 
    {
968
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) ||
969
 
            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT)))
970
 
        {
971
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
972
 
        }
973
 
    }
974
 
 
975
 
    if (returnCode == ADDR_OK)
976
 
    {
977
 
        ADDR_ASSERT(pIn->numSamples > 1);
978
 
 
979
 
        if (pIn->numSamples > 1)
980
 
        {
981
 
            returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut);
982
 
        }
983
 
        else
984
 
        {
985
 
            returnCode = ADDR_INVALIDPARAMS;
986
 
        }
987
 
    }
988
 
 
989
 
    return returnCode;
990
 
}
991
 
 
992
 
/**
993
 
****************************************************************************************************
994
 
*   Lib::ConvertTileInfoToHW
995
 
*
996
 
*   @brief
997
 
*       Convert tile info from real value to HW register value in HW layer
998
 
*
999
 
*   @return
1000
 
*       ADDR_E_RETURNCODE
1001
 
****************************************************************************************************
1002
 
*/
1003
 
ADDR_E_RETURNCODE Lib::ConvertTileInfoToHW(
1004
 
    const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
1005
 
    ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure
1006
 
    ) const
1007
 
{
1008
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1009
 
 
1010
 
    if (GetFillSizeFieldsFlags() == TRUE)
1011
 
    {
1012
 
        if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) ||
1013
 
            (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT)))
1014
 
        {
1015
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1016
 
        }
1017
 
    }
1018
 
 
1019
 
    if (returnCode == ADDR_OK)
1020
 
    {
1021
 
        ADDR_TILEINFO tileInfoNull;
1022
 
        ADDR_CONVERT_TILEINFOTOHW_INPUT input;
1023
 
        // if pIn->reverse is TRUE, indices are ignored
1024
 
        if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex))
1025
 
        {
1026
 
            input = *pIn;
1027
 
            input.pTileInfo = &tileInfoNull;
1028
 
 
1029
 
            returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex,
1030
 
                                         input.macroModeIndex, input.pTileInfo);
1031
 
 
1032
 
            pIn = &input;
1033
 
        }
1034
 
 
1035
 
        if (returnCode == ADDR_OK)
1036
 
        {
1037
 
            returnCode = HwlConvertTileInfoToHW(pIn, pOut);
1038
 
        }
1039
 
    }
1040
 
 
1041
 
    return returnCode;
1042
 
}
1043
 
 
1044
 
/**
1045
 
****************************************************************************************************
1046
 
*   Lib::ConvertTileIndex
1047
 
*
1048
 
*   @brief
1049
 
*       Convert tile index to tile mode/type/info
1050
 
*
1051
 
*   @return
1052
 
*       ADDR_E_RETURNCODE
1053
 
****************************************************************************************************
1054
 
*/
1055
 
ADDR_E_RETURNCODE Lib::ConvertTileIndex(
1056
 
    const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure
1057
 
    ADDR_CONVERT_TILEINDEX_OUTPUT* pOut      ///< [out] output structure
1058
 
    ) const
1059
 
{
1060
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1061
 
 
1062
 
    if (GetFillSizeFieldsFlags() == TRUE)
1063
 
    {
1064
 
        if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) ||
1065
 
            (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
1066
 
        {
1067
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1068
 
        }
1069
 
    }
1070
 
 
1071
 
    if (returnCode == ADDR_OK)
1072
 
    {
1073
 
 
1074
 
        returnCode = HwlSetupTileCfg(pIn->bpp, pIn->tileIndex, pIn->macroModeIndex,
1075
 
                                     pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
1076
 
 
1077
 
        if (returnCode == ADDR_OK && pIn->tileInfoHw)
1078
 
        {
1079
 
            ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
1080
 
            ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
1081
 
 
1082
 
            hwInput.pTileInfo = pOut->pTileInfo;
1083
 
            hwInput.tileIndex = -1;
1084
 
            hwOutput.pTileInfo = pOut->pTileInfo;
1085
 
 
1086
 
            returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
1087
 
        }
1088
 
    }
1089
 
 
1090
 
    return returnCode;
1091
 
}
1092
 
 
1093
 
/**
1094
 
****************************************************************************************************
1095
 
*   Lib::GetMacroModeIndex
1096
 
*
1097
 
*   @brief
1098
 
*       Get macro mode index based on input info
1099
 
*
1100
 
*   @return
1101
 
*       ADDR_E_RETURNCODE
1102
 
****************************************************************************************************
1103
 
*/
1104
 
ADDR_E_RETURNCODE Lib::GetMacroModeIndex(
1105
 
    const ADDR_GET_MACROMODEINDEX_INPUT* pIn, ///< [in] input structure
1106
 
    ADDR_GET_MACROMODEINDEX_OUTPUT*      pOut ///< [out] output structure
1107
 
    ) const
1108
 
{
1109
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1110
 
 
1111
 
    if (GetFillSizeFieldsFlags())
1112
 
    {
1113
 
        if ((pIn->size != sizeof(ADDR_GET_MACROMODEINDEX_INPUT)) ||
1114
 
            (pOut->size != sizeof(ADDR_GET_MACROMODEINDEX_OUTPUT)))
1115
 
        {
1116
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1117
 
        }
1118
 
    }
1119
 
 
1120
 
    if (returnCode == ADDR_OK)
1121
 
    {
1122
 
        ADDR_TILEINFO tileInfo = {0};
1123
 
        pOut->macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex, pIn->flags, pIn->bpp,
1124
 
                                                        pIn->numFrags, &tileInfo);
1125
 
    }
1126
 
 
1127
 
    return returnCode;
1128
 
}
1129
 
 
1130
 
/**
1131
 
****************************************************************************************************
1132
 
*   Lib::ConvertTileIndex1
1133
 
*
1134
 
*   @brief
1135
 
*       Convert tile index to tile mode/type/info
1136
 
*
1137
 
*   @return
1138
 
*       ADDR_E_RETURNCODE
1139
 
****************************************************************************************************
1140
 
*/
1141
 
ADDR_E_RETURNCODE Lib::ConvertTileIndex1(
1142
 
    const ADDR_CONVERT_TILEINDEX1_INPUT* pIn,   ///< [in] input structure
1143
 
    ADDR_CONVERT_TILEINDEX_OUTPUT* pOut         ///< [out] output structure
1144
 
    ) const
1145
 
{
1146
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1147
 
 
1148
 
    if (GetFillSizeFieldsFlags() == TRUE)
1149
 
    {
1150
 
        if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) ||
1151
 
            (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
1152
 
        {
1153
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1154
 
        }
1155
 
    }
1156
 
 
1157
 
    if (returnCode == ADDR_OK)
1158
 
    {
1159
 
        ADDR_SURFACE_FLAGS flags = {{0}};
1160
 
 
1161
 
        HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples,
1162
 
                                 pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
1163
 
 
1164
 
        if (pIn->tileInfoHw)
1165
 
        {
1166
 
            ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
1167
 
            ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
1168
 
 
1169
 
            hwInput.pTileInfo = pOut->pTileInfo;
1170
 
            hwInput.tileIndex = -1;
1171
 
            hwOutput.pTileInfo = pOut->pTileInfo;
1172
 
 
1173
 
            returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
1174
 
        }
1175
 
    }
1176
 
 
1177
 
    return returnCode;
1178
 
}
1179
 
 
1180
 
/**
1181
 
****************************************************************************************************
1182
 
*   Lib::GetTileIndex
1183
 
*
1184
 
*   @brief
1185
 
*       Get tile index from tile mode/type/info
1186
 
*
1187
 
*   @return
1188
 
*       ADDR_E_RETURNCODE
1189
 
****************************************************************************************************
1190
 
*/
1191
 
ADDR_E_RETURNCODE Lib::GetTileIndex(
1192
 
    const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure
1193
 
    ADDR_GET_TILEINDEX_OUTPUT* pOut      ///< [out] output structure
1194
 
    ) const
1195
 
{
1196
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1197
 
 
1198
 
    if (GetFillSizeFieldsFlags() == TRUE)
1199
 
    {
1200
 
        if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) ||
1201
 
            (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT)))
1202
 
        {
1203
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1204
 
        }
1205
 
    }
1206
 
 
1207
 
    if (returnCode == ADDR_OK)
1208
 
    {
1209
 
        returnCode = HwlGetTileIndex(pIn, pOut);
1210
 
    }
1211
 
 
1212
 
    return returnCode;
1213
 
}
1214
 
 
1215
 
/**
1216
 
****************************************************************************************************
1217
 
*   Lib::Thickness
1218
 
*
1219
 
*   @brief
1220
 
*       Get tile mode thickness
1221
 
*
1222
 
*   @return
1223
 
*       Tile mode thickness
1224
 
****************************************************************************************************
1225
 
*/
1226
 
UINT_32 Lib::Thickness(
1227
 
    AddrTileMode tileMode)    ///< [in] tile mode
1228
 
{
1229
 
    return ModeFlags[tileMode].thickness;
1230
 
}
1231
 
 
1232
 
 
1233
 
 
1234
 
////////////////////////////////////////////////////////////////////////////////////////////////////
1235
 
//                               CMASK/HTILE
1236
 
////////////////////////////////////////////////////////////////////////////////////////////////////
1237
 
 
1238
 
/**
1239
 
****************************************************************************************************
1240
 
*   Lib::ComputeHtileInfo
1241
 
*
1242
 
*   @brief
1243
 
*       Interface function stub of AddrComputeHtilenfo
1244
 
*
1245
 
*   @return
1246
 
*       ADDR_E_RETURNCODE
1247
 
****************************************************************************************************
1248
 
*/
1249
 
ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
1250
 
    const ADDR_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure
1251
 
    ADDR_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure
1252
 
    ) const
1253
 
{
1254
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1255
 
 
1256
 
    BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
1257
 
    BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1258
 
 
1259
 
    if (GetFillSizeFieldsFlags() == TRUE)
1260
 
    {
1261
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) ||
1262
 
            (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT)))
1263
 
        {
1264
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1265
 
        }
1266
 
    }
1267
 
 
1268
 
    if (returnCode == ADDR_OK)
1269
 
    {
1270
 
        ADDR_TILEINFO tileInfoNull;
1271
 
        ADDR_COMPUTE_HTILE_INFO_INPUT input;
1272
 
 
1273
 
        if (UseTileIndex(pIn->tileIndex))
1274
 
        {
1275
 
            input = *pIn;
1276
 
            // Use temp tile info for calcalation
1277
 
            input.pTileInfo = &tileInfoNull;
1278
 
 
1279
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1280
 
 
1281
 
            // Change the input structure
1282
 
            pIn = &input;
1283
 
        }
1284
 
 
1285
 
        if (returnCode == ADDR_OK)
1286
 
        {
1287
 
            if (pIn->flags.tcCompatible)
1288
 
            {
1289
 
                const UINT_32 sliceSize = pIn->pitch * pIn->height * 4 / (8 * 8);
1290
 
                const UINT_32 align     = HwlGetPipes(pIn->pTileInfo) * pIn->pTileInfo->banks * m_pipeInterleaveBytes;
1291
 
 
1292
 
                if (pIn->numSlices > 1)
1293
 
                {
1294
 
                    const UINT_32 surfBytes = (sliceSize * pIn->numSlices);
1295
 
 
1296
 
                    pOut->sliceSize        = sliceSize;
1297
 
                    pOut->htileBytes       = pIn->flags.skipTcCompatSizeAlign ?
1298
 
                                             surfBytes : PowTwoAlign(surfBytes, align);
1299
 
                    pOut->sliceInterleaved = ((sliceSize % align) != 0) ? TRUE : FALSE;
1300
 
                }
1301
 
                else
1302
 
                {
1303
 
                    pOut->sliceSize        = pIn->flags.skipTcCompatSizeAlign ?
1304
 
                                             sliceSize : PowTwoAlign(sliceSize, align);
1305
 
                    pOut->htileBytes       = pOut->sliceSize;
1306
 
                    pOut->sliceInterleaved = FALSE;
1307
 
                }
1308
 
 
1309
 
                pOut->nextMipLevelCompressible = ((sliceSize % align) == 0) ? TRUE : FALSE;
1310
 
 
1311
 
                pOut->pitch       = pIn->pitch;
1312
 
                pOut->height      = pIn->height;
1313
 
                pOut->baseAlign   = align;
1314
 
                pOut->macroWidth  = 0;
1315
 
                pOut->macroHeight = 0;
1316
 
                pOut->bpp         = 32;
1317
 
            }
1318
 
            else
1319
 
            {
1320
 
                pOut->bpp = ComputeHtileInfo(pIn->flags,
1321
 
                                             pIn->pitch,
1322
 
                                             pIn->height,
1323
 
                                             pIn->numSlices,
1324
 
                                             pIn->isLinear,
1325
 
                                             isWidth8,
1326
 
                                             isHeight8,
1327
 
                                             pIn->pTileInfo,
1328
 
                                             &pOut->pitch,
1329
 
                                             &pOut->height,
1330
 
                                             &pOut->htileBytes,
1331
 
                                             &pOut->macroWidth,
1332
 
                                             &pOut->macroHeight,
1333
 
                                             &pOut->sliceSize,
1334
 
                                             &pOut->baseAlign);
1335
 
            }
1336
 
        }
1337
 
    }
1338
 
 
1339
 
    ValidMetaBaseAlignments(pOut->baseAlign);
1340
 
 
1341
 
    return returnCode;
1342
 
}
1343
 
 
1344
 
/**
1345
 
****************************************************************************************************
1346
 
*   Lib::ComputeCmaskInfo
1347
 
*
1348
 
*   @brief
1349
 
*       Interface function stub of AddrComputeCmaskInfo
1350
 
*
1351
 
*   @return
1352
 
*       ADDR_E_RETURNCODE
1353
 
****************************************************************************************************
1354
 
*/
1355
 
ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
1356
 
    const ADDR_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure
1357
 
    ADDR_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure
1358
 
    ) const
1359
 
{
1360
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1361
 
 
1362
 
    if (GetFillSizeFieldsFlags() == TRUE)
1363
 
    {
1364
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) ||
1365
 
            (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT)))
1366
 
        {
1367
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1368
 
        }
1369
 
    }
1370
 
 
1371
 
    if (returnCode == ADDR_OK)
1372
 
    {
1373
 
        ADDR_TILEINFO tileInfoNull;
1374
 
        ADDR_COMPUTE_CMASK_INFO_INPUT input;
1375
 
 
1376
 
        if (UseTileIndex(pIn->tileIndex))
1377
 
        {
1378
 
            input = *pIn;
1379
 
            // Use temp tile info for calcalation
1380
 
            input.pTileInfo = &tileInfoNull;
1381
 
 
1382
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1383
 
 
1384
 
            // Change the input structure
1385
 
            pIn = &input;
1386
 
        }
1387
 
 
1388
 
        if (returnCode == ADDR_OK)
1389
 
        {
1390
 
            returnCode = ComputeCmaskInfo(pIn->flags,
1391
 
                                          pIn->pitch,
1392
 
                                          pIn->height,
1393
 
                                          pIn->numSlices,
1394
 
                                          pIn->isLinear,
1395
 
                                          pIn->pTileInfo,
1396
 
                                          &pOut->pitch,
1397
 
                                          &pOut->height,
1398
 
                                          &pOut->cmaskBytes,
1399
 
                                          &pOut->macroWidth,
1400
 
                                          &pOut->macroHeight,
1401
 
                                          &pOut->sliceSize,
1402
 
                                          &pOut->baseAlign,
1403
 
                                          &pOut->blockMax);
1404
 
        }
1405
 
    }
1406
 
 
1407
 
    ValidMetaBaseAlignments(pOut->baseAlign);
1408
 
 
1409
 
    return returnCode;
1410
 
}
1411
 
 
1412
 
/**
1413
 
****************************************************************************************************
1414
 
*   Lib::ComputeDccInfo
1415
 
*
1416
 
*   @brief
1417
 
*       Interface function to compute DCC key info
1418
 
*
1419
 
*   @return
1420
 
*       return code of HwlComputeDccInfo
1421
 
****************************************************************************************************
1422
 
*/
1423
 
ADDR_E_RETURNCODE Lib::ComputeDccInfo(
1424
 
    const ADDR_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure
1425
 
    ADDR_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure
1426
 
    ) const
1427
 
{
1428
 
    ADDR_E_RETURNCODE ret = ADDR_OK;
1429
 
 
1430
 
    if (GetFillSizeFieldsFlags() == TRUE)
1431
 
    {
1432
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) ||
1433
 
            (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT)))
1434
 
        {
1435
 
            ret = ADDR_PARAMSIZEMISMATCH;
1436
 
        }
1437
 
    }
1438
 
 
1439
 
    if (ret == ADDR_OK)
1440
 
    {
1441
 
        ADDR_COMPUTE_DCCINFO_INPUT input;
1442
 
 
1443
 
        if (UseTileIndex(pIn->tileIndex))
1444
 
        {
1445
 
            input = *pIn;
1446
 
 
1447
 
            ret = HwlSetupTileCfg(input.bpp, input.tileIndex, input.macroModeIndex,
1448
 
                                  &input.tileInfo, &input.tileMode);
1449
 
 
1450
 
            pIn = &input;
1451
 
        }
1452
 
 
1453
 
        if (ret == ADDR_OK)
1454
 
        {
1455
 
            ret = HwlComputeDccInfo(pIn, pOut);
1456
 
 
1457
 
            ValidMetaBaseAlignments(pOut->dccRamBaseAlign);
1458
 
        }
1459
 
    }
1460
 
 
1461
 
    return ret;
1462
 
}
1463
 
 
1464
 
/**
1465
 
****************************************************************************************************
1466
 
*   Lib::ComputeHtileAddrFromCoord
1467
 
*
1468
 
*   @brief
1469
 
*       Interface function stub of AddrComputeHtileAddrFromCoord
1470
 
*
1471
 
*   @return
1472
 
*       ADDR_E_RETURNCODE
1473
 
****************************************************************************************************
1474
 
*/
1475
 
ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
1476
 
    const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
1477
 
    ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
1478
 
    ) const
1479
 
{
1480
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1481
 
 
1482
 
    BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
1483
 
    BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1484
 
 
1485
 
    if (GetFillSizeFieldsFlags() == TRUE)
1486
 
    {
1487
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
1488
 
            (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))
1489
 
        {
1490
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1491
 
        }
1492
 
    }
1493
 
 
1494
 
    if (returnCode == ADDR_OK)
1495
 
    {
1496
 
        ADDR_TILEINFO tileInfoNull;
1497
 
        ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input;
1498
 
 
1499
 
        if (UseTileIndex(pIn->tileIndex))
1500
 
        {
1501
 
            input = *pIn;
1502
 
            // Use temp tile info for calcalation
1503
 
            input.pTileInfo = &tileInfoNull;
1504
 
 
1505
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1506
 
 
1507
 
            // Change the input structure
1508
 
            pIn = &input;
1509
 
        }
1510
 
 
1511
 
        if (returnCode == ADDR_OK)
1512
 
        {
1513
 
            if (pIn->flags.tcCompatible)
1514
 
            {
1515
 
                HwlComputeHtileAddrFromCoord(pIn, pOut);
1516
 
            }
1517
 
            else
1518
 
            {
1519
 
                pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
1520
 
                                                          pIn->height,
1521
 
                                                          pIn->x,
1522
 
                                                          pIn->y,
1523
 
                                                          pIn->slice,
1524
 
                                                          pIn->numSlices,
1525
 
                                                          1,
1526
 
                                                          pIn->isLinear,
1527
 
                                                          isWidth8,
1528
 
                                                          isHeight8,
1529
 
                                                          pIn->pTileInfo,
1530
 
                                                          &pOut->bitPosition);
1531
 
            }
1532
 
        }
1533
 
    }
1534
 
 
1535
 
    return returnCode;
1536
 
 
1537
 
}
1538
 
 
1539
 
/**
1540
 
****************************************************************************************************
1541
 
*   Lib::ComputeHtileCoordFromAddr
1542
 
*
1543
 
*   @brief
1544
 
*       Interface function stub of AddrComputeHtileCoordFromAddr
1545
 
*
1546
 
*   @return
1547
 
*       ADDR_E_RETURNCODE
1548
 
****************************************************************************************************
1549
 
*/
1550
 
ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
1551
 
    const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
1552
 
    ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
1553
 
    ) const
1554
 
{
1555
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1556
 
 
1557
 
    BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;
1558
 
    BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1559
 
 
1560
 
    if (GetFillSizeFieldsFlags() == TRUE)
1561
 
    {
1562
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
1563
 
            (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))
1564
 
        {
1565
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1566
 
        }
1567
 
    }
1568
 
 
1569
 
    if (returnCode == ADDR_OK)
1570
 
    {
1571
 
        ADDR_TILEINFO tileInfoNull;
1572
 
        ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input;
1573
 
 
1574
 
        if (UseTileIndex(pIn->tileIndex))
1575
 
        {
1576
 
            input = *pIn;
1577
 
            // Use temp tile info for calcalation
1578
 
            input.pTileInfo = &tileInfoNull;
1579
 
 
1580
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1581
 
 
1582
 
            // Change the input structure
1583
 
            pIn = &input;
1584
 
        }
1585
 
 
1586
 
        if (returnCode == ADDR_OK)
1587
 
        {
1588
 
            HwlComputeXmaskCoordFromAddr(pIn->addr,
1589
 
                                         pIn->bitPosition,
1590
 
                                         pIn->pitch,
1591
 
                                         pIn->height,
1592
 
                                         pIn->numSlices,
1593
 
                                         1,
1594
 
                                         pIn->isLinear,
1595
 
                                         isWidth8,
1596
 
                                         isHeight8,
1597
 
                                         pIn->pTileInfo,
1598
 
                                         &pOut->x,
1599
 
                                         &pOut->y,
1600
 
                                         &pOut->slice);
1601
 
        }
1602
 
    }
1603
 
 
1604
 
    return returnCode;
1605
 
}
1606
 
 
1607
 
/**
1608
 
****************************************************************************************************
1609
 
*   Lib::ComputeCmaskAddrFromCoord
1610
 
*
1611
 
*   @brief
1612
 
*       Interface function stub of AddrComputeCmaskAddrFromCoord
1613
 
*
1614
 
*   @return
1615
 
*       ADDR_E_RETURNCODE
1616
 
****************************************************************************************************
1617
 
*/
1618
 
ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
1619
 
    const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure
1620
 
    ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure
1621
 
    ) const
1622
 
{
1623
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1624
 
 
1625
 
    if (GetFillSizeFieldsFlags() == TRUE)
1626
 
    {
1627
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
1628
 
            (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))
1629
 
        {
1630
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1631
 
        }
1632
 
    }
1633
 
 
1634
 
    if (returnCode == ADDR_OK)
1635
 
    {
1636
 
        ADDR_TILEINFO tileInfoNull;
1637
 
        ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input;
1638
 
 
1639
 
        if (UseTileIndex(pIn->tileIndex))
1640
 
        {
1641
 
            input = *pIn;
1642
 
            // Use temp tile info for calcalation
1643
 
            input.pTileInfo = &tileInfoNull;
1644
 
 
1645
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1646
 
 
1647
 
            // Change the input structure
1648
 
            pIn = &input;
1649
 
        }
1650
 
 
1651
 
        if (returnCode == ADDR_OK)
1652
 
        {
1653
 
            if (pIn->flags.tcCompatible == TRUE)
1654
 
            {
1655
 
                returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
1656
 
            }
1657
 
            else
1658
 
            {
1659
 
                pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
1660
 
                                                          pIn->height,
1661
 
                                                          pIn->x,
1662
 
                                                          pIn->y,
1663
 
                                                          pIn->slice,
1664
 
                                                          pIn->numSlices,
1665
 
                                                          2,
1666
 
                                                          pIn->isLinear,
1667
 
                                                          FALSE, //this is cmask, isWidth8 is not needed
1668
 
                                                          FALSE, //this is cmask, isHeight8 is not needed
1669
 
                                                          pIn->pTileInfo,
1670
 
                                                          &pOut->bitPosition);
1671
 
            }
1672
 
 
1673
 
        }
1674
 
    }
1675
 
 
1676
 
    return returnCode;
1677
 
}
1678
 
 
1679
 
/**
1680
 
****************************************************************************************************
1681
 
*   Lib::ComputeCmaskCoordFromAddr
1682
 
*
1683
 
*   @brief
1684
 
*       Interface function stub of AddrComputeCmaskCoordFromAddr
1685
 
*
1686
 
*   @return
1687
 
*       ADDR_E_RETURNCODE
1688
 
****************************************************************************************************
1689
 
*/
1690
 
ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
1691
 
    const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure
1692
 
    ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure
1693
 
    ) const
1694
 
{
1695
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1696
 
 
1697
 
    if (GetFillSizeFieldsFlags() == TRUE)
1698
 
    {
1699
 
        if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) ||
1700
 
            (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT)))
1701
 
        {
1702
 
            returnCode = ADDR_PARAMSIZEMISMATCH;
1703
 
        }
1704
 
    }
1705
 
 
1706
 
    if (returnCode == ADDR_OK)
1707
 
    {
1708
 
        ADDR_TILEINFO tileInfoNull;
1709
 
        ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input;
1710
 
 
1711
 
        if (UseTileIndex(pIn->tileIndex))
1712
 
        {
1713
 
            input = *pIn;
1714
 
            // Use temp tile info for calcalation
1715
 
            input.pTileInfo = &tileInfoNull;
1716
 
 
1717
 
            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1718
 
 
1719
 
            // Change the input structure
1720
 
            pIn = &input;
1721
 
        }
1722
 
 
1723
 
        if (returnCode == ADDR_OK)
1724
 
        {
1725
 
            HwlComputeXmaskCoordFromAddr(pIn->addr,
1726
 
                                         pIn->bitPosition,
1727
 
                                         pIn->pitch,
1728
 
                                         pIn->height,
1729
 
                                         pIn->numSlices,
1730
 
                                         2,
1731
 
                                         pIn->isLinear,
1732
 
                                         FALSE,
1733
 
                                         FALSE,
1734
 
                                         pIn->pTileInfo,
1735
 
                                         &pOut->x,
1736
 
                                         &pOut->y,
1737
 
                                         &pOut->slice);
1738
 
        }
1739
 
    }
1740
 
 
1741
 
    return returnCode;
1742
 
}
1743
 
 
1744
 
/**
1745
 
****************************************************************************************************
1746
 
*   Lib::ComputeTileDataWidthAndHeight
1747
 
*
1748
 
*   @brief
1749
 
*       Compute the squared cache shape for per-tile data (CMASK and HTILE)
1750
 
*
1751
 
*   @return
1752
 
*       N/A
1753
 
*
1754
 
*   @note
1755
 
*       MacroWidth and macroHeight are measured in pixels
1756
 
****************************************************************************************************
1757
 
*/
1758
 
VOID Lib::ComputeTileDataWidthAndHeight(
1759
 
    UINT_32         bpp,             ///< [in] bits per pixel
1760
 
    UINT_32         cacheBits,       ///< [in] bits of cache
1761
 
    ADDR_TILEINFO*  pTileInfo,       ///< [in] Tile info
1762
 
    UINT_32*        pMacroWidth,     ///< [out] macro tile width
1763
 
    UINT_32*        pMacroHeight     ///< [out] macro tile height
1764
 
    ) const
1765
 
{
1766
 
    UINT_32 height = 1;
1767
 
    UINT_32 width  = cacheBits / bpp;
1768
 
    UINT_32 pipes  = HwlGetPipes(pTileInfo);
1769
 
 
1770
 
    // Double height until the macro-tile is close to square
1771
 
    // Height can only be doubled if width is even
1772
 
 
1773
 
    while ((width > height * 2 * pipes) && !(width & 1))
1774
 
    {
1775
 
        width  /= 2;
1776
 
        height *= 2;
1777
 
    }
1778
 
 
1779
 
    *pMacroWidth  = 8 * width;
1780
 
    *pMacroHeight = 8 * height * pipes;
1781
 
 
1782
 
    // Note: The above iterative comptuation is equivalent to the following
1783
 
    //
1784
 
    //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1785
 
    //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1786
 
}
1787
 
 
1788
 
/**
1789
 
****************************************************************************************************
1790
 
*   Lib::HwlComputeTileDataWidthAndHeightLinear
1791
 
*
1792
 
*   @brief
1793
 
*       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1794
 
*
1795
 
*   @return
1796
 
*       N/A
1797
 
*
1798
 
*   @note
1799
 
*       MacroWidth and macroHeight are measured in pixels
1800
 
****************************************************************************************************
1801
 
*/
1802
 
VOID Lib::HwlComputeTileDataWidthAndHeightLinear(
1803
 
    UINT_32*        pMacroWidth,     ///< [out] macro tile width
1804
 
    UINT_32*        pMacroHeight,    ///< [out] macro tile height
1805
 
    UINT_32         bpp,             ///< [in] bits per pixel
1806
 
    ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
1807
 
    ) const
1808
 
{
1809
 
    ADDR_ASSERT(bpp != 4);              // Cmask does not support linear layout prior to SI
1810
 
    *pMacroWidth  = 8 * 512 / bpp;      // Align width to 512-bit memory accesses
1811
 
    *pMacroHeight = 8 * m_pipes;        // Align height to number of pipes
1812
 
}
1813
 
 
1814
 
/**
1815
 
****************************************************************************************************
1816
 
*   Lib::ComputeHtileInfo
1817
 
*
1818
 
*   @brief
1819
 
*       Compute htile pitch,width, bytes per 2D slice
1820
 
*
1821
 
*   @return
1822
 
*       Htile bpp i.e. How many bits for an 8x8 tile
1823
 
*       Also returns by output parameters:
1824
 
*       *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1825
 
****************************************************************************************************
1826
 
*/
1827
 
UINT_32 Lib::ComputeHtileInfo(
1828
 
    ADDR_HTILE_FLAGS flags,             ///< [in] htile flags
1829
 
    UINT_32          pitchIn,           ///< [in] pitch input
1830
 
    UINT_32          heightIn,          ///< [in] height input
1831
 
    UINT_32          numSlices,         ///< [in] number of slices
1832
 
    BOOL_32          isLinear,          ///< [in] if it is linear mode
1833
 
    BOOL_32          isWidth8,          ///< [in] if htile block width is 8
1834
 
    BOOL_32          isHeight8,         ///< [in] if htile block height is 8
1835
 
    ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info
1836
 
    UINT_32*         pPitchOut,         ///< [out] pitch output
1837
 
    UINT_32*         pHeightOut,        ///< [out] height output
1838
 
    UINT_64*         pHtileBytes,       ///< [out] bytes per 2D slice
1839
 
    UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels
1840
 
    UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels
1841
 
    UINT_64*         pSliceSize,        ///< [out] slice size in bytes
1842
 
    UINT_32*         pBaseAlign         ///< [out] base alignment
1843
 
    ) const
1844
 
{
1845
 
 
1846
 
    UINT_32 macroWidth;
1847
 
    UINT_32 macroHeight;
1848
 
    UINT_32 baseAlign;
1849
 
    UINT_64 surfBytes;
1850
 
    UINT_64 sliceBytes;
1851
 
 
1852
 
    numSlices = Max(1u, numSlices);
1853
 
 
1854
 
    const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8);
1855
 
    const UINT_32 cacheBits = HtileCacheBits;
1856
 
 
1857
 
    if (isLinear)
1858
 
    {
1859
 
        HwlComputeTileDataWidthAndHeightLinear(&macroWidth,
1860
 
                                               &macroHeight,
1861
 
                                               bpp,
1862
 
                                               pTileInfo);
1863
 
    }
1864
 
    else
1865
 
    {
1866
 
        ComputeTileDataWidthAndHeight(bpp,
1867
 
                                      cacheBits,
1868
 
                                      pTileInfo,
1869
 
                                      &macroWidth,
1870
 
                                      &macroHeight);
1871
 
    }
1872
 
 
1873
 
    *pPitchOut = PowTwoAlign(pitchIn,  macroWidth);
1874
 
    *pHeightOut = PowTwoAlign(heightIn,  macroHeight);
1875
 
 
1876
 
    baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo);
1877
 
 
1878
 
    surfBytes = HwlComputeHtileBytes(*pPitchOut,
1879
 
                                     *pHeightOut,
1880
 
                                     bpp,
1881
 
                                     isLinear,
1882
 
                                     numSlices,
1883
 
                                     &sliceBytes,
1884
 
                                     baseAlign);
1885
 
 
1886
 
    *pHtileBytes = surfBytes;
1887
 
 
1888
 
    //
1889
 
    // Use SafeAssign since they are optional
1890
 
    //
1891
 
    SafeAssign(pMacroWidth, macroWidth);
1892
 
 
1893
 
    SafeAssign(pMacroHeight, macroHeight);
1894
 
 
1895
 
    SafeAssign(pSliceSize,  sliceBytes);
1896
 
 
1897
 
    SafeAssign(pBaseAlign, baseAlign);
1898
 
 
1899
 
    return bpp;
1900
 
}
1901
 
 
1902
 
/**
1903
 
****************************************************************************************************
1904
 
*   Lib::ComputeCmaskBaseAlign
1905
 
*
1906
 
*   @brief
1907
 
*       Compute cmask base alignment
1908
 
*
1909
 
*   @return
1910
 
*       Cmask base alignment
1911
 
****************************************************************************************************
1912
 
*/
1913
 
UINT_32 Lib::ComputeCmaskBaseAlign(
1914
 
    ADDR_CMASK_FLAGS flags,           ///< [in] Cmask flags
1915
 
    ADDR_TILEINFO*   pTileInfo        ///< [in] Tile info
1916
 
    ) const
1917
 
{
1918
 
    UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
1919
 
 
1920
 
    if (flags.tcCompatible)
1921
 
    {
1922
 
        ADDR_ASSERT(pTileInfo != NULL);
1923
 
        if (pTileInfo)
1924
 
        {
1925
 
            baseAlign *= pTileInfo->banks;
1926
 
        }
1927
 
    }
1928
 
 
1929
 
    return baseAlign;
1930
 
}
1931
 
 
1932
 
/**
1933
 
****************************************************************************************************
1934
 
*   Lib::ComputeCmaskBytes
1935
 
*
1936
 
*   @brief
1937
 
*       Compute cmask size in bytes
1938
 
*
1939
 
*   @return
1940
 
*       Cmask size in bytes
1941
 
****************************************************************************************************
1942
 
*/
1943
 
UINT_64 Lib::ComputeCmaskBytes(
1944
 
    UINT_32 pitch,        ///< [in] pitch
1945
 
    UINT_32 height,       ///< [in] height
1946
 
    UINT_32 numSlices     ///< [in] number of slices
1947
 
    ) const
1948
 
{
1949
 
    return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) /
1950
 
        MicroTilePixels;
1951
 
}
1952
 
 
1953
 
/**
1954
 
****************************************************************************************************
1955
 
*   Lib::ComputeCmaskInfo
1956
 
*
1957
 
*   @brief
1958
 
*       Compute cmask pitch,width, bytes per 2D slice
1959
 
*
1960
 
*   @return
1961
 
*       BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1962
 
*       macro-tile dimensions
1963
 
****************************************************************************************************
1964
 
*/
1965
 
ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
1966
 
    ADDR_CMASK_FLAGS flags,            ///< [in] cmask flags
1967
 
    UINT_32          pitchIn,           ///< [in] pitch input
1968
 
    UINT_32          heightIn,          ///< [in] height input
1969
 
    UINT_32          numSlices,         ///< [in] number of slices
1970
 
    BOOL_32          isLinear,          ///< [in] is linear mode
1971
 
    ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info
1972
 
    UINT_32*         pPitchOut,         ///< [out] pitch output
1973
 
    UINT_32*         pHeightOut,        ///< [out] height output
1974
 
    UINT_64*         pCmaskBytes,       ///< [out] bytes per 2D slice
1975
 
    UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels
1976
 
    UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels
1977
 
    UINT_64*         pSliceSize,        ///< [out] slice size in bytes
1978
 
    UINT_32*         pBaseAlign,        ///< [out] base alignment
1979
 
    UINT_32*         pBlockMax          ///< [out] block max == slice / 128 / 128 - 1
1980
 
    ) const
1981
 
{
1982
 
    UINT_32 macroWidth;
1983
 
    UINT_32 macroHeight;
1984
 
    UINT_32 baseAlign;
1985
 
    UINT_64 surfBytes;
1986
 
    UINT_64 sliceBytes;
1987
 
 
1988
 
    numSlices = Max(1u, numSlices);
1989
 
 
1990
 
    const UINT_32 bpp = CmaskElemBits;
1991
 
    const UINT_32 cacheBits = CmaskCacheBits;
1992
 
 
1993
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
1994
 
 
1995
 
    if (isLinear)
1996
 
    {
1997
 
        HwlComputeTileDataWidthAndHeightLinear(&macroWidth,
1998
 
                                               &macroHeight,
1999
 
                                               bpp,
2000
 
                                               pTileInfo);
2001
 
    }
2002
 
    else
2003
 
    {
2004
 
        ComputeTileDataWidthAndHeight(bpp,
2005
 
                                      cacheBits,
2006
 
                                      pTileInfo,
2007
 
                                      &macroWidth,
2008
 
                                      &macroHeight);
2009
 
    }
2010
 
 
2011
 
    *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1);
2012
 
    *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1);
2013
 
 
2014
 
 
2015
 
    sliceBytes = ComputeCmaskBytes(*pPitchOut,
2016
 
                                   *pHeightOut,
2017
 
                                   1);
2018
 
 
2019
 
    baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo);
2020
 
 
2021
 
    while (sliceBytes % baseAlign)
2022
 
    {
2023
 
        *pHeightOut += macroHeight;
2024
 
 
2025
 
        sliceBytes = ComputeCmaskBytes(*pPitchOut,
2026
 
                                       *pHeightOut,
2027
 
                                       1);
2028
 
    }
2029
 
 
2030
 
    surfBytes = sliceBytes * numSlices;
2031
 
 
2032
 
    *pCmaskBytes = surfBytes;
2033
 
 
2034
 
    //
2035
 
    // Use SafeAssign since they are optional
2036
 
    //
2037
 
    SafeAssign(pMacroWidth, macroWidth);
2038
 
 
2039
 
    SafeAssign(pMacroHeight, macroHeight);
2040
 
 
2041
 
    SafeAssign(pBaseAlign, baseAlign);
2042
 
 
2043
 
    SafeAssign(pSliceSize, sliceBytes);
2044
 
 
2045
 
    UINT_32 slice = (*pPitchOut) * (*pHeightOut);
2046
 
    UINT_32 blockMax = slice / 128 / 128 - 1;
2047
 
 
2048
 
#if DEBUG
2049
 
    if (slice % (64*256) != 0)
2050
 
    {
2051
 
        ADDR_ASSERT_ALWAYS();
2052
 
    }
2053
 
#endif //DEBUG
2054
 
 
2055
 
    UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax();
2056
 
 
2057
 
    if (blockMax > maxBlockMax)
2058
 
    {
2059
 
        blockMax = maxBlockMax;
2060
 
        returnCode = ADDR_INVALIDPARAMS;
2061
 
    }
2062
 
 
2063
 
    SafeAssign(pBlockMax, blockMax);
2064
 
 
2065
 
    return returnCode;
2066
 
}
2067
 
 
2068
 
/**
2069
 
****************************************************************************************************
2070
 
*   Lib::ComputeXmaskCoordYFromPipe
2071
 
*
2072
 
*   @brief
2073
 
*       Compute the Y coord from pipe number for cmask/htile
2074
 
*
2075
 
*   @return
2076
 
*       Y coordinate
2077
 
*
2078
 
****************************************************************************************************
2079
 
*/
2080
 
UINT_32 Lib::ComputeXmaskCoordYFromPipe(
2081
 
    UINT_32         pipe,       ///< [in] pipe number
2082
 
    UINT_32         x           ///< [in] x coordinate
2083
 
    ) const
2084
 
{
2085
 
    UINT_32 pipeBit0;
2086
 
    UINT_32 pipeBit1;
2087
 
    UINT_32 xBit0;
2088
 
    UINT_32 xBit1;
2089
 
    UINT_32 yBit0;
2090
 
    UINT_32 yBit1;
2091
 
 
2092
 
    UINT_32 y = 0;
2093
 
 
2094
 
    UINT_32 numPipes = m_pipes; // SI has its implementation
2095
 
    //
2096
 
    // Convert pipe + x to y coordinate.
2097
 
    //
2098
 
    switch (numPipes)
2099
 
    {
2100
 
        case 1:
2101
 
            //
2102
 
            // 1 pipe
2103
 
            //
2104
 
            // p0 = 0
2105
 
            //
2106
 
            y = 0;
2107
 
            break;
2108
 
        case 2:
2109
 
            //
2110
 
            // 2 pipes
2111
 
            //
2112
 
            // p0 = x0 ^ y0
2113
 
            //
2114
 
            // y0 = p0 ^ x0
2115
 
            //
2116
 
            pipeBit0 = pipe & 0x1;
2117
 
 
2118
 
            xBit0 = x & 0x1;
2119
 
 
2120
 
            yBit0 = pipeBit0 ^ xBit0;
2121
 
 
2122
 
            y = yBit0;
2123
 
            break;
2124
 
        case 4:
2125
 
            //
2126
 
            // 4 pipes
2127
 
            //
2128
 
            // p0 = x1 ^ y0
2129
 
            // p1 = x0 ^ y1
2130
 
            //
2131
 
            // y0 = p0 ^ x1
2132
 
            // y1 = p1 ^ x0
2133
 
            //
2134
 
            pipeBit0 =  pipe & 0x1;
2135
 
            pipeBit1 = (pipe & 0x2) >> 1;
2136
 
 
2137
 
            xBit0 =  x & 0x1;
2138
 
            xBit1 = (x & 0x2) >> 1;
2139
 
 
2140
 
            yBit0 = pipeBit0 ^ xBit1;
2141
 
            yBit1 = pipeBit1 ^ xBit0;
2142
 
 
2143
 
            y = (yBit0 |
2144
 
                 (yBit1 << 1));
2145
 
            break;
2146
 
        case 8:
2147
 
            //
2148
 
            // 8 pipes
2149
 
            //
2150
 
            // r600 and r800 have different method
2151
 
            //
2152
 
            y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x);
2153
 
            break;
2154
 
        default:
2155
 
            break;
2156
 
    }
2157
 
    return y;
2158
 
}
2159
 
 
2160
 
/**
2161
 
****************************************************************************************************
2162
 
*   Lib::HwlComputeXmaskCoordFromAddr
2163
 
*
2164
 
*   @brief
2165
 
*       Compute the coord from an address of a cmask/htile
2166
 
*
2167
 
*   @return
2168
 
*       N/A
2169
 
*
2170
 
*   @note
2171
 
*       This method is reused by htile, so rename to Xmask
2172
 
****************************************************************************************************
2173
 
*/
2174
 
VOID Lib::HwlComputeXmaskCoordFromAddr(
2175
 
    UINT_64         addr,           ///< [in] address
2176
 
    UINT_32         bitPosition,    ///< [in] bitPosition in a byte
2177
 
    UINT_32         pitch,          ///< [in] pitch
2178
 
    UINT_32         height,         ///< [in] height
2179
 
    UINT_32         numSlices,      ///< [in] number of slices
2180
 
    UINT_32         factor,         ///< [in] factor that indicates cmask or htile
2181
 
    BOOL_32         isLinear,       ///< [in] linear or tiled HTILE layout
2182
 
    BOOL_32         isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2183
 
    BOOL_32         isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2184
 
    ADDR_TILEINFO*  pTileInfo,      ///< [in] Tile info
2185
 
    UINT_32*        pX,             ///< [out] x coord
2186
 
    UINT_32*        pY,             ///< [out] y coord
2187
 
    UINT_32*        pSlice          ///< [out] slice index
2188
 
    ) const
2189
 
{
2190
 
    UINT_32 pipe;
2191
 
    UINT_32 numPipes;
2192
 
    UINT_32 numGroupBits;
2193
 
    UINT_32 numPipeBits;
2194
 
    UINT_32 macroTilePitch;
2195
 
    UINT_32 macroTileHeight;
2196
 
 
2197
 
    UINT_64 bitAddr;
2198
 
 
2199
 
    UINT_32 microTileCoordY;
2200
 
 
2201
 
    UINT_32 elemBits;
2202
 
 
2203
 
    UINT_32 pitchAligned = pitch;
2204
 
    UINT_32 heightAligned = height;
2205
 
    UINT_64 totalBytes;
2206
 
 
2207
 
    UINT_64 elemOffset;
2208
 
 
2209
 
    UINT_64 macroIndex;
2210
 
    UINT_32 microIndex;
2211
 
 
2212
 
    UINT_64 macroNumber;
2213
 
    UINT_32 microNumber;
2214
 
 
2215
 
    UINT_32 macroX;
2216
 
    UINT_32 macroY;
2217
 
    UINT_32 macroZ;
2218
 
 
2219
 
    UINT_32 microX;
2220
 
    UINT_32 microY;
2221
 
 
2222
 
    UINT_32 tilesPerMacro;
2223
 
    UINT_32 macrosPerPitch;
2224
 
    UINT_32 macrosPerSlice;
2225
 
 
2226
 
    //
2227
 
    // Extract pipe.
2228
 
    //
2229
 
    numPipes = HwlGetPipes(pTileInfo);
2230
 
    pipe = ComputePipeFromAddr(addr, numPipes);
2231
 
 
2232
 
    //
2233
 
    // Compute the number of group and pipe bits.
2234
 
    //
2235
 
    numGroupBits = Log2(m_pipeInterleaveBytes);
2236
 
    numPipeBits  = Log2(numPipes);
2237
 
 
2238
 
    UINT_32 groupBits = 8 * m_pipeInterleaveBytes;
2239
 
    UINT_32 pipes = numPipes;
2240
 
 
2241
 
 
2242
 
    //
2243
 
    // Compute the micro tile size, in bits. And macro tile pitch and height.
2244
 
    //
2245
 
    if (factor == 2) //CMASK
2246
 
    {
2247
 
        ADDR_CMASK_FLAGS flags = {{0}};
2248
 
 
2249
 
        elemBits = CmaskElemBits;
2250
 
 
2251
 
        ComputeCmaskInfo(flags,
2252
 
                         pitch,
2253
 
                         height,
2254
 
                         numSlices,
2255
 
                         isLinear,
2256
 
                         pTileInfo,
2257
 
                         &pitchAligned,
2258
 
                         &heightAligned,
2259
 
                         &totalBytes,
2260
 
                         &macroTilePitch,
2261
 
                         &macroTileHeight);
2262
 
    }
2263
 
    else  //HTILE
2264
 
    {
2265
 
        ADDR_HTILE_FLAGS flags = {{0}};
2266
 
 
2267
 
        if (factor != 1)
2268
 
        {
2269
 
            factor = 1;
2270
 
        }
2271
 
 
2272
 
        elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
2273
 
 
2274
 
        ComputeHtileInfo(flags,
2275
 
                         pitch,
2276
 
                         height,
2277
 
                         numSlices,
2278
 
                         isLinear,
2279
 
                         isWidth8,
2280
 
                         isHeight8,
2281
 
                         pTileInfo,
2282
 
                         &pitchAligned,
2283
 
                         &heightAligned,
2284
 
                         &totalBytes,
2285
 
                         &macroTilePitch,
2286
 
                         &macroTileHeight);
2287
 
    }
2288
 
 
2289
 
    // Should use aligned dims
2290
 
    //
2291
 
    pitch = pitchAligned;
2292
 
    height = heightAligned;
2293
 
 
2294
 
 
2295
 
    //
2296
 
    // Convert byte address to bit address.
2297
 
    //
2298
 
    bitAddr = BYTES_TO_BITS(addr) + bitPosition;
2299
 
 
2300
 
 
2301
 
    //
2302
 
    // Remove pipe bits from address.
2303
 
    //
2304
 
 
2305
 
    bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits);
2306
 
 
2307
 
 
2308
 
    elemOffset = bitAddr / elemBits;
2309
 
 
2310
 
    tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits;
2311
 
 
2312
 
    macrosPerPitch = pitch / (macroTilePitch/factor);
2313
 
    macrosPerSlice = macrosPerPitch * height / macroTileHeight;
2314
 
 
2315
 
    macroIndex = elemOffset / factor / tilesPerMacro;
2316
 
    microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor));
2317
 
 
2318
 
    macroNumber = macroIndex * factor + microIndex % factor;
2319
 
    microNumber = microIndex / factor;
2320
 
 
2321
 
    macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch));
2322
 
    macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch);
2323
 
    macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice));
2324
 
 
2325
 
 
2326
 
    microX = microNumber % (macroTilePitch / factor / MicroTileWidth);
2327
 
    microY = (microNumber / (macroTilePitch / factor / MicroTileHeight));
2328
 
 
2329
 
    *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth;
2330
 
    *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits);
2331
 
    *pSlice = macroZ;
2332
 
 
2333
 
    microTileCoordY = ComputeXmaskCoordYFromPipe(pipe,
2334
 
                                                 *pX/MicroTileWidth);
2335
 
 
2336
 
 
2337
 
    //
2338
 
    // Assemble final coordinates.
2339
 
    //
2340
 
    *pY += microTileCoordY * MicroTileHeight;
2341
 
 
2342
 
}
2343
 
 
2344
 
/**
2345
 
****************************************************************************************************
2346
 
*   Lib::HwlComputeXmaskAddrFromCoord
2347
 
*
2348
 
*   @brief
2349
 
*       Compute the address from an address of cmask (prior to si)
2350
 
*
2351
 
*   @return
2352
 
*       Address in bytes
2353
 
*
2354
 
****************************************************************************************************
2355
 
*/
2356
 
UINT_64 Lib::HwlComputeXmaskAddrFromCoord(
2357
 
    UINT_32        pitch,          ///< [in] pitch
2358
 
    UINT_32        height,         ///< [in] height
2359
 
    UINT_32        x,              ///< [in] x coord
2360
 
    UINT_32        y,              ///< [in] y coord
2361
 
    UINT_32        slice,          ///< [in] slice/depth index
2362
 
    UINT_32        numSlices,      ///< [in] number of slices
2363
 
    UINT_32        factor,         ///< [in] factor that indicates cmask(2) or htile(1)
2364
 
    BOOL_32        isLinear,       ///< [in] linear or tiled HTILE layout
2365
 
    BOOL_32        isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2366
 
    BOOL_32        isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2367
 
    ADDR_TILEINFO* pTileInfo,      ///< [in] Tile info
2368
 
    UINT_32*       pBitPosition    ///< [out] bit position inside a byte
2369
 
    ) const
2370
 
{
2371
 
    UINT_64 addr;
2372
 
    UINT_32 numGroupBits;
2373
 
    UINT_32 numPipeBits;
2374
 
    UINT_32 newPitch = 0;
2375
 
    UINT_32 newHeight = 0;
2376
 
    UINT_64 sliceBytes = 0;
2377
 
    UINT_64 totalBytes = 0;
2378
 
    UINT_64 sliceOffset;
2379
 
    UINT_32 pipe;
2380
 
    UINT_32 macroTileWidth;
2381
 
    UINT_32 macroTileHeight;
2382
 
    UINT_32 macroTilesPerRow;
2383
 
    UINT_32 macroTileBytes;
2384
 
    UINT_32 macroTileIndexX;
2385
 
    UINT_32 macroTileIndexY;
2386
 
    UINT_64 macroTileOffset;
2387
 
    UINT_32 pixelBytesPerRow;
2388
 
    UINT_32 pixelOffsetX;
2389
 
    UINT_32 pixelOffsetY;
2390
 
    UINT_32 pixelOffset;
2391
 
    UINT_64 totalOffset;
2392
 
    UINT_64 offsetLo;
2393
 
    UINT_64 offsetHi;
2394
 
    UINT_64 groupMask;
2395
 
 
2396
 
 
2397
 
    UINT_32 elemBits = 0;
2398
 
 
2399
 
    UINT_32 numPipes = m_pipes; // This function is accessed prior to si only
2400
 
 
2401
 
    if (factor == 2) //CMASK
2402
 
    {
2403
 
        elemBits = CmaskElemBits;
2404
 
 
2405
 
        // For asics before SI, cmask is always tiled
2406
 
        isLinear = FALSE;
2407
 
    }
2408
 
    else //HTILE
2409
 
    {
2410
 
        if (factor != 1) // Fix compile warning
2411
 
        {
2412
 
            factor = 1;
2413
 
        }
2414
 
 
2415
 
        elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
2416
 
    }
2417
 
 
2418
 
    //
2419
 
    // Compute the number of group bits and pipe bits.
2420
 
    //
2421
 
    numGroupBits = Log2(m_pipeInterleaveBytes);
2422
 
    numPipeBits  = Log2(numPipes);
2423
 
 
2424
 
    //
2425
 
    // Compute macro tile dimensions.
2426
 
    //
2427
 
    if (factor == 2) // CMASK
2428
 
    {
2429
 
        ADDR_CMASK_FLAGS flags = {{0}};
2430
 
 
2431
 
        ComputeCmaskInfo(flags,
2432
 
                         pitch,
2433
 
                         height,
2434
 
                         numSlices,
2435
 
                         isLinear,
2436
 
                         pTileInfo,
2437
 
                         &newPitch,
2438
 
                         &newHeight,
2439
 
                         &totalBytes,
2440
 
                         &macroTileWidth,
2441
 
                         &macroTileHeight);
2442
 
 
2443
 
        sliceBytes = totalBytes / numSlices;
2444
 
    }
2445
 
    else // HTILE
2446
 
    {
2447
 
        ADDR_HTILE_FLAGS flags = {{0}};
2448
 
 
2449
 
        ComputeHtileInfo(flags,
2450
 
                         pitch,
2451
 
                         height,
2452
 
                         numSlices,
2453
 
                         isLinear,
2454
 
                         isWidth8,
2455
 
                         isHeight8,
2456
 
                         pTileInfo,
2457
 
                         &newPitch,
2458
 
                         &newHeight,
2459
 
                         &totalBytes,
2460
 
                         &macroTileWidth,
2461
 
                         &macroTileHeight,
2462
 
                         &sliceBytes);
2463
 
    }
2464
 
 
2465
 
    sliceOffset = slice * sliceBytes;
2466
 
 
2467
 
    //
2468
 
    // Get the pipe.  Note that neither slice rotation nor pipe swizzling apply for CMASK.
2469
 
    //
2470
 
    pipe = ComputePipeFromCoord(x,
2471
 
                                y,
2472
 
                                0,
2473
 
                                ADDR_TM_2D_TILED_THIN1,
2474
 
                                0,
2475
 
                                FALSE,
2476
 
                                pTileInfo);
2477
 
 
2478
 
    //
2479
 
    // Compute the number of macro tiles per row.
2480
 
    //
2481
 
    macroTilesPerRow = newPitch / macroTileWidth;
2482
 
 
2483
 
    //
2484
 
    // Compute the number of bytes per macro tile.
2485
 
    //
2486
 
    macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels);
2487
 
 
2488
 
    //
2489
 
    // Compute the offset to the macro tile containing the specified coordinate.
2490
 
    //
2491
 
    macroTileIndexX = x / macroTileWidth;
2492
 
    macroTileIndexY = y / macroTileHeight;
2493
 
    macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
2494
 
 
2495
 
    //
2496
 
    // Compute the pixel offset within the macro tile.
2497
 
    //
2498
 
    pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth;
2499
 
 
2500
 
    //
2501
 
    // The nibbles are interleaved (see below), so the part of the offset relative to the x
2502
 
    // coordinate repeats halfway across the row. (Not for HTILE)
2503
 
    //
2504
 
    if (factor == 2)
2505
 
    {
2506
 
        pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth;
2507
 
    }
2508
 
    else
2509
 
    {
2510
 
        pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits);
2511
 
    }
2512
 
 
2513
 
    //
2514
 
    // Compute the y offset within the macro tile.
2515
 
    //
2516
 
    pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow;
2517
 
 
2518
 
    pixelOffset = pixelOffsetX + pixelOffsetY;
2519
 
 
2520
 
    //
2521
 
    // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2522
 
    // pipe bits in the middle of the address.
2523
 
    //
2524
 
    totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset;
2525
 
 
2526
 
    //
2527
 
    // Split the offset to put some bits below the pipe bits and some above.
2528
 
    //
2529
 
    groupMask = (1 << numGroupBits) - 1;
2530
 
    offsetLo  = totalOffset &  groupMask;
2531
 
    offsetHi  = (totalOffset & ~groupMask) << numPipeBits;
2532
 
 
2533
 
    //
2534
 
    // Assemble the address from its components.
2535
 
    //
2536
 
    addr  = offsetLo;
2537
 
    addr |= offsetHi;
2538
 
    // This is to remove warning with /analyze option
2539
 
    UINT_32 pipeBits = pipe << numGroupBits;
2540
 
    addr |= pipeBits;
2541
 
 
2542
 
    //
2543
 
    // Compute the bit position.  The lower nibble is used when the x coordinate within the macro
2544
 
    // tile is less than half of the macro tile width, and the upper nibble is used when the x
2545
 
    // coordinate within the macro tile is greater than or equal to half the macro tile width.
2546
 
    //
2547
 
    *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4;
2548
 
 
2549
 
    return addr;
2550
 
}
2551
 
 
2552
 
////////////////////////////////////////////////////////////////////////////////////////////////////
2553
 
//                               Surface Addressing Shared
2554
 
////////////////////////////////////////////////////////////////////////////////////////////////////
2555
 
 
2556
 
/**
2557
 
****************************************************************************************************
2558
 
*   Lib::ComputeSurfaceAddrFromCoordLinear
2559
 
*
2560
 
*   @brief
2561
 
*       Compute address from coord for linear surface
2562
 
*
2563
 
*   @return
2564
 
*       Address in bytes
2565
 
*
2566
 
****************************************************************************************************
2567
 
*/
2568
 
UINT_64 Lib::ComputeSurfaceAddrFromCoordLinear(
2569
 
    UINT_32  x,              ///< [in] x coord
2570
 
    UINT_32  y,              ///< [in] y coord
2571
 
    UINT_32  slice,          ///< [in] slice/depth index
2572
 
    UINT_32  sample,         ///< [in] sample index
2573
 
    UINT_32  bpp,            ///< [in] bits per pixel
2574
 
    UINT_32  pitch,          ///< [in] pitch
2575
 
    UINT_32  height,         ///< [in] height
2576
 
    UINT_32  numSlices,      ///< [in] number of slices
2577
 
    UINT_32* pBitPosition    ///< [out] bit position inside a byte
2578
 
    ) const
2579
 
{
2580
 
    const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
2581
 
 
2582
 
    UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize;
2583
 
    UINT_64 rowOffset   = static_cast<UINT_64>(y) * pitch;
2584
 
    UINT_64 pixOffset   = x;
2585
 
 
2586
 
    UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp;
2587
 
 
2588
 
    *pBitPosition = static_cast<UINT_32>(addr % 8);
2589
 
    addr /= 8;
2590
 
 
2591
 
    return addr;
2592
 
}
2593
 
 
2594
 
/**
2595
 
****************************************************************************************************
2596
 
*   Lib::ComputeSurfaceCoordFromAddrLinear
2597
 
*
2598
 
*   @brief
2599
 
*       Compute the coord from an address of a linear surface
2600
 
*
2601
 
*   @return
2602
 
*       N/A
2603
 
****************************************************************************************************
2604
 
*/
2605
 
VOID Lib::ComputeSurfaceCoordFromAddrLinear(
2606
 
    UINT_64  addr,           ///< [in] address
2607
 
    UINT_32  bitPosition,    ///< [in] bitPosition in a byte
2608
 
    UINT_32  bpp,            ///< [in] bits per pixel
2609
 
    UINT_32  pitch,          ///< [in] pitch
2610
 
    UINT_32  height,         ///< [in] height
2611
 
    UINT_32  numSlices,      ///< [in] number of slices
2612
 
    UINT_32* pX,             ///< [out] x coord
2613
 
    UINT_32* pY,             ///< [out] y coord
2614
 
    UINT_32* pSlice,         ///< [out] slice/depth index
2615
 
    UINT_32* pSample         ///< [out] sample index
2616
 
    ) const
2617
 
{
2618
 
    const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
2619
 
    const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp;
2620
 
 
2621
 
    *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch);
2622
 
    *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height);
2623
 
    *pSlice  = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices);
2624
 
    *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices);
2625
 
}
2626
 
 
2627
 
/**
2628
 
****************************************************************************************************
2629
 
*   Lib::ComputeSurfaceCoordFromAddrMicroTiled
2630
 
*
2631
 
*   @brief
2632
 
*       Compute the coord from an address of a micro tiled surface
2633
 
*
2634
 
*   @return
2635
 
*       N/A
2636
 
****************************************************************************************************
2637
 
*/
2638
 
VOID Lib::ComputeSurfaceCoordFromAddrMicroTiled(
2639
 
    UINT_64         addr,               ///< [in] address
2640
 
    UINT_32         bitPosition,        ///< [in] bitPosition in a byte
2641
 
    UINT_32         bpp,                ///< [in] bits per pixel
2642
 
    UINT_32         pitch,              ///< [in] pitch
2643
 
    UINT_32         height,             ///< [in] height
2644
 
    UINT_32         numSamples,         ///< [in] number of samples
2645
 
    AddrTileMode    tileMode,           ///< [in] tile mode
2646
 
    UINT_32         tileBase,           ///< [in] base offset within a tile
2647
 
    UINT_32         compBits,           ///< [in] component bits actually needed(for planar surface)
2648
 
    UINT_32*        pX,                 ///< [out] x coord
2649
 
    UINT_32*        pY,                 ///< [out] y coord
2650
 
    UINT_32*        pSlice,             ///< [out] slice/depth index
2651
 
    UINT_32*        pSample,            ///< [out] sample index,
2652
 
    AddrTileType    microTileType,      ///< [in] micro tiling order
2653
 
    BOOL_32         isDepthSampleOrder  ///< [in] TRUE if in depth sample order
2654
 
    ) const
2655
 
{
2656
 
    UINT_64 bitAddr;
2657
 
    UINT_32 microTileThickness;
2658
 
    UINT_32 microTileBits;
2659
 
    UINT_64 sliceBits;
2660
 
    UINT_64 rowBits;
2661
 
    UINT_32 sliceIndex;
2662
 
    UINT_32 microTileCoordX;
2663
 
    UINT_32 microTileCoordY;
2664
 
    UINT_32 pixelOffset;
2665
 
    UINT_32 pixelCoordX = 0;
2666
 
    UINT_32 pixelCoordY = 0;
2667
 
    UINT_32 pixelCoordZ = 0;
2668
 
    UINT_32 pixelCoordS = 0;
2669
 
 
2670
 
    //
2671
 
    // Convert byte address to bit address.
2672
 
    //
2673
 
    bitAddr = BYTES_TO_BITS(addr) + bitPosition;
2674
 
 
2675
 
    //
2676
 
    // Compute the micro tile size, in bits.
2677
 
    //
2678
 
    switch (tileMode)
2679
 
    {
2680
 
        case ADDR_TM_1D_TILED_THICK:
2681
 
            microTileThickness = ThickTileThickness;
2682
 
            break;
2683
 
        default:
2684
 
            microTileThickness = 1;
2685
 
            break;
2686
 
    }
2687
 
 
2688
 
    microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
2689
 
 
2690
 
    //
2691
 
    // Compute number of bits per slice and number of bits per row of micro tiles.
2692
 
    //
2693
 
    sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples;
2694
 
 
2695
 
    rowBits   = (pitch / MicroTileWidth) * microTileBits;
2696
 
 
2697
 
    //
2698
 
    // Extract the slice index.
2699
 
    //
2700
 
    sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits);
2701
 
    bitAddr -= sliceIndex * sliceBits;
2702
 
 
2703
 
    //
2704
 
    // Extract the y coordinate of the micro tile.
2705
 
    //
2706
 
    microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight;
2707
 
    bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits;
2708
 
 
2709
 
    //
2710
 
    // Extract the x coordinate of the micro tile.
2711
 
    //
2712
 
    microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth;
2713
 
 
2714
 
    //
2715
 
    // Compute the pixel offset within the micro tile.
2716
 
    //
2717
 
    pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits);
2718
 
 
2719
 
    //
2720
 
    // Extract pixel coordinates from the offset.
2721
 
    //
2722
 
    HwlComputePixelCoordFromOffset(pixelOffset,
2723
 
                                   bpp,
2724
 
                                   numSamples,
2725
 
                                   tileMode,
2726
 
                                   tileBase,
2727
 
                                   compBits,
2728
 
                                   &pixelCoordX,
2729
 
                                   &pixelCoordY,
2730
 
                                   &pixelCoordZ,
2731
 
                                   &pixelCoordS,
2732
 
                                   microTileType,
2733
 
                                   isDepthSampleOrder);
2734
 
 
2735
 
    //
2736
 
    // Assemble final coordinates.
2737
 
    //
2738
 
    *pX     = microTileCoordX + pixelCoordX;
2739
 
    *pY     = microTileCoordY + pixelCoordY;
2740
 
    *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ;
2741
 
    *pSample = pixelCoordS;
2742
 
 
2743
 
    if (microTileThickness > 1)
2744
 
    {
2745
 
        *pSample = 0;
2746
 
    }
2747
 
}
2748
 
 
2749
 
/**
2750
 
****************************************************************************************************
2751
 
*   Lib::ComputePipeFromAddr
2752
 
*
2753
 
*   @brief
2754
 
*       Compute the pipe number from an address
2755
 
*
2756
 
*   @return
2757
 
*       Pipe number
2758
 
*
2759
 
****************************************************************************************************
2760
 
*/
2761
 
UINT_32 Lib::ComputePipeFromAddr(
2762
 
    UINT_64 addr,        ///< [in] address
2763
 
    UINT_32 numPipes     ///< [in] number of banks
2764
 
    ) const
2765
 
{
2766
 
    UINT_32 pipe;
2767
 
 
2768
 
    UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms
2769
 
 
2770
 
    // R600
2771
 
    // The LSBs of the address are arranged as follows:
2772
 
    //   bank | pipe | group
2773
 
    //
2774
 
    // To get the pipe number, shift off the group bits and mask the pipe bits.
2775
 
    //
2776
 
 
2777
 
    // R800
2778
 
    // The LSBs of the address are arranged as follows:
2779
 
    //   bank | bankInterleave | pipe | pipeInterleave
2780
 
    //
2781
 
    // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2782
 
    //
2783
 
 
2784
 
    pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1);
2785
 
 
2786
 
    return pipe;
2787
 
}
2788
 
 
2789
 
/**
2790
 
****************************************************************************************************
2791
 
*   Lib::ComputeMicroTileEquation
2792
 
*
2793
 
*   @brief
2794
 
*       Compute micro tile equation
2795
 
*
2796
 
*   @return
2797
 
*       If equation can be computed
2798
 
*
2799
 
****************************************************************************************************
2800
 
*/
2801
 
ADDR_E_RETURNCODE Lib::ComputeMicroTileEquation(
2802
 
    UINT_32         log2BytesPP,    ///< [in] log2 of bytes per pixel
2803
 
    AddrTileMode    tileMode,       ///< [in] tile mode
2804
 
    AddrTileType    microTileType,  ///< [in] pixel order in display/non-display mode
2805
 
    ADDR_EQUATION*  pEquation       ///< [out] equation
2806
 
    ) const
2807
 
{
2808
 
    ADDR_E_RETURNCODE retCode = ADDR_OK;
2809
 
 
2810
 
    for (UINT_32 i = 0; i < log2BytesPP; i++)
2811
 
    {
2812
 
        pEquation->addr[i].valid = 1;
2813
 
        pEquation->addr[i].channel = 0;
2814
 
        pEquation->addr[i].index = i;
2815
 
    }
2816
 
 
2817
 
    ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[log2BytesPP];
2818
 
 
2819
 
    ADDR_CHANNEL_SETTING x0 = InitChannel(1, 0, log2BytesPP + 0);
2820
 
    ADDR_CHANNEL_SETTING x1 = InitChannel(1, 0, log2BytesPP + 1);
2821
 
    ADDR_CHANNEL_SETTING x2 = InitChannel(1, 0, log2BytesPP + 2);
2822
 
    ADDR_CHANNEL_SETTING y0 = InitChannel(1, 1, 0);
2823
 
    ADDR_CHANNEL_SETTING y1 = InitChannel(1, 1, 1);
2824
 
    ADDR_CHANNEL_SETTING y2 = InitChannel(1, 1, 2);
2825
 
    ADDR_CHANNEL_SETTING z0 = InitChannel(1, 2, 0);
2826
 
    ADDR_CHANNEL_SETTING z1 = InitChannel(1, 2, 1);
2827
 
    ADDR_CHANNEL_SETTING z2 = InitChannel(1, 2, 2);
2828
 
 
2829
 
    UINT_32 thickness = Thickness(tileMode);
2830
 
    UINT_32 bpp = 1 << (log2BytesPP + 3);
2831
 
 
2832
 
    if (microTileType != ADDR_THICK)
2833
 
    {
2834
 
        if (microTileType == ADDR_DISPLAYABLE)
2835
 
        {
2836
 
            switch (bpp)
2837
 
            {
2838
 
                case 8:
2839
 
                    pixelBit[0] = x0;
2840
 
                    pixelBit[1] = x1;
2841
 
                    pixelBit[2] = x2;
2842
 
                    pixelBit[3] = y1;
2843
 
                    pixelBit[4] = y0;
2844
 
                    pixelBit[5] = y2;
2845
 
                    break;
2846
 
                case 16:
2847
 
                    pixelBit[0] = x0;
2848
 
                    pixelBit[1] = x1;
2849
 
                    pixelBit[2] = x2;
2850
 
                    pixelBit[3] = y0;
2851
 
                    pixelBit[4] = y1;
2852
 
                    pixelBit[5] = y2;
2853
 
                    break;
2854
 
                case 32:
2855
 
                    pixelBit[0] = x0;
2856
 
                    pixelBit[1] = x1;
2857
 
                    pixelBit[2] = y0;
2858
 
                    pixelBit[3] = x2;
2859
 
                    pixelBit[4] = y1;
2860
 
                    pixelBit[5] = y2;
2861
 
                    break;
2862
 
                case 64:
2863
 
                    pixelBit[0] = x0;
2864
 
                    pixelBit[1] = y0;
2865
 
                    pixelBit[2] = x1;
2866
 
                    pixelBit[3] = x2;
2867
 
                    pixelBit[4] = y1;
2868
 
                    pixelBit[5] = y2;
2869
 
                    break;
2870
 
                case 128:
2871
 
                    pixelBit[0] = y0;
2872
 
                    pixelBit[1] = x0;
2873
 
                    pixelBit[2] = x1;
2874
 
                    pixelBit[3] = x2;
2875
 
                    pixelBit[4] = y1;
2876
 
                    pixelBit[5] = y2;
2877
 
                    break;
2878
 
                default:
2879
 
                    ADDR_ASSERT_ALWAYS();
2880
 
                    break;
2881
 
            }
2882
 
        }
2883
 
        else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2884
 
        {
2885
 
            pixelBit[0] = x0;
2886
 
            pixelBit[1] = y0;
2887
 
            pixelBit[2] = x1;
2888
 
            pixelBit[3] = y1;
2889
 
            pixelBit[4] = x2;
2890
 
            pixelBit[5] = y2;
2891
 
        }
2892
 
        else if (microTileType == ADDR_ROTATED)
2893
 
        {
2894
 
            ADDR_ASSERT(thickness == 1);
2895
 
 
2896
 
            switch (bpp)
2897
 
            {
2898
 
                case 8:
2899
 
                    pixelBit[0] = y0;
2900
 
                    pixelBit[1] = y1;
2901
 
                    pixelBit[2] = y2;
2902
 
                    pixelBit[3] = x1;
2903
 
                    pixelBit[4] = x0;
2904
 
                    pixelBit[5] = x2;
2905
 
                    break;
2906
 
                case 16:
2907
 
                    pixelBit[0] = y0;
2908
 
                    pixelBit[1] = y1;
2909
 
                    pixelBit[2] = y2;
2910
 
                    pixelBit[3] = x0;
2911
 
                    pixelBit[4] = x1;
2912
 
                    pixelBit[5] = x2;
2913
 
                    break;
2914
 
                case 32:
2915
 
                    pixelBit[0] = y0;
2916
 
                    pixelBit[1] = y1;
2917
 
                    pixelBit[2] = x0;
2918
 
                    pixelBit[3] = y2;
2919
 
                    pixelBit[4] = x1;
2920
 
                    pixelBit[5] = x2;
2921
 
                    break;
2922
 
                case 64:
2923
 
                    pixelBit[0] = y0;
2924
 
                    pixelBit[1] = x0;
2925
 
                    pixelBit[2] = y1;
2926
 
                    pixelBit[3] = x1;
2927
 
                    pixelBit[4] = x2;
2928
 
                    pixelBit[5] = y2;
2929
 
                    break;
2930
 
                default:
2931
 
                    retCode = ADDR_NOTSUPPORTED;
2932
 
                    break;
2933
 
            }
2934
 
        }
2935
 
 
2936
 
        if (thickness > 1)
2937
 
        {
2938
 
            pixelBit[6] = z0;
2939
 
            pixelBit[7] = z1;
2940
 
            pEquation->numBits = 8 + log2BytesPP;
2941
 
        }
2942
 
        else
2943
 
        {
2944
 
            pEquation->numBits = 6 + log2BytesPP;
2945
 
        }
2946
 
    }
2947
 
    else // ADDR_THICK
2948
 
    {
2949
 
        ADDR_ASSERT(thickness > 1);
2950
 
 
2951
 
        switch (bpp)
2952
 
        {
2953
 
            case 8:
2954
 
            case 16:
2955
 
                pixelBit[0] = x0;
2956
 
                pixelBit[1] = y0;
2957
 
                pixelBit[2] = x1;
2958
 
                pixelBit[3] = y1;
2959
 
                pixelBit[4] = z0;
2960
 
                pixelBit[5] = z1;
2961
 
                break;
2962
 
            case 32:
2963
 
                pixelBit[0] = x0;
2964
 
                pixelBit[1] = y0;
2965
 
                pixelBit[2] = x1;
2966
 
                pixelBit[3] = z0;
2967
 
                pixelBit[4] = y1;
2968
 
                pixelBit[5] = z1;
2969
 
                break;
2970
 
            case 64:
2971
 
            case 128:
2972
 
                pixelBit[0] = x0;
2973
 
                pixelBit[1] = y0;
2974
 
                pixelBit[2] = z0;
2975
 
                pixelBit[3] = x1;
2976
 
                pixelBit[4] = y1;
2977
 
                pixelBit[5] = z1;
2978
 
                break;
2979
 
            default:
2980
 
                ADDR_ASSERT_ALWAYS();
2981
 
                break;
2982
 
        }
2983
 
 
2984
 
        pixelBit[6] = x2;
2985
 
        pixelBit[7] = y2;
2986
 
        pEquation->numBits = 8 + log2BytesPP;
2987
 
    }
2988
 
 
2989
 
    if (thickness == 8)
2990
 
    {
2991
 
        pixelBit[8] = z2;
2992
 
        pEquation->numBits = 9 + log2BytesPP;
2993
 
    }
2994
 
 
2995
 
    // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,
2996
 
    // which is not supported by our address lib
2997
 
    pEquation->stackedDepthSlices = FALSE;
2998
 
 
2999
 
    return retCode;
3000
 
}
3001
 
 
3002
 
/**
3003
 
****************************************************************************************************
3004
 
*   Lib::ComputePixelIndexWithinMicroTile
3005
 
*
3006
 
*   @brief
3007
 
*       Compute the pixel index inside a micro tile of surface
3008
 
*
3009
 
*   @return
3010
 
*       Pixel index
3011
 
*
3012
 
****************************************************************************************************
3013
 
*/
3014
 
UINT_32 Lib::ComputePixelIndexWithinMicroTile(
3015
 
    UINT_32         x,              ///< [in] x coord
3016
 
    UINT_32         y,              ///< [in] y coord
3017
 
    UINT_32         z,              ///< [in] slice/depth index
3018
 
    UINT_32         bpp,            ///< [in] bits per pixel
3019
 
    AddrTileMode    tileMode,       ///< [in] tile mode
3020
 
    AddrTileType    microTileType   ///< [in] pixel order in display/non-display mode
3021
 
    ) const
3022
 
{
3023
 
    UINT_32 pixelBit0 = 0;
3024
 
    UINT_32 pixelBit1 = 0;
3025
 
    UINT_32 pixelBit2 = 0;
3026
 
    UINT_32 pixelBit3 = 0;
3027
 
    UINT_32 pixelBit4 = 0;
3028
 
    UINT_32 pixelBit5 = 0;
3029
 
    UINT_32 pixelBit6 = 0;
3030
 
    UINT_32 pixelBit7 = 0;
3031
 
    UINT_32 pixelBit8 = 0;
3032
 
    UINT_32 pixelNumber;
3033
 
 
3034
 
    UINT_32 x0 = _BIT(x, 0);
3035
 
    UINT_32 x1 = _BIT(x, 1);
3036
 
    UINT_32 x2 = _BIT(x, 2);
3037
 
    UINT_32 y0 = _BIT(y, 0);
3038
 
    UINT_32 y1 = _BIT(y, 1);
3039
 
    UINT_32 y2 = _BIT(y, 2);
3040
 
    UINT_32 z0 = _BIT(z, 0);
3041
 
    UINT_32 z1 = _BIT(z, 1);
3042
 
    UINT_32 z2 = _BIT(z, 2);
3043
 
 
3044
 
    UINT_32 thickness = Thickness(tileMode);
3045
 
 
3046
 
    // Compute the pixel number within the micro tile.
3047
 
 
3048
 
    if (microTileType != ADDR_THICK)
3049
 
    {
3050
 
        if (microTileType == ADDR_DISPLAYABLE)
3051
 
        {
3052
 
            switch (bpp)
3053
 
            {
3054
 
                case 8:
3055
 
                    pixelBit0 = x0;
3056
 
                    pixelBit1 = x1;
3057
 
                    pixelBit2 = x2;
3058
 
                    pixelBit3 = y1;
3059
 
                    pixelBit4 = y0;
3060
 
                    pixelBit5 = y2;
3061
 
                    break;
3062
 
                case 16:
3063
 
                    pixelBit0 = x0;
3064
 
                    pixelBit1 = x1;
3065
 
                    pixelBit2 = x2;
3066
 
                    pixelBit3 = y0;
3067
 
                    pixelBit4 = y1;
3068
 
                    pixelBit5 = y2;
3069
 
                    break;
3070
 
                case 32:
3071
 
                    pixelBit0 = x0;
3072
 
                    pixelBit1 = x1;
3073
 
                    pixelBit2 = y0;
3074
 
                    pixelBit3 = x2;
3075
 
                    pixelBit4 = y1;
3076
 
                    pixelBit5 = y2;
3077
 
                    break;
3078
 
                case 64:
3079
 
                    pixelBit0 = x0;
3080
 
                    pixelBit1 = y0;
3081
 
                    pixelBit2 = x1;
3082
 
                    pixelBit3 = x2;
3083
 
                    pixelBit4 = y1;
3084
 
                    pixelBit5 = y2;
3085
 
                    break;
3086
 
                case 128:
3087
 
                    pixelBit0 = y0;
3088
 
                    pixelBit1 = x0;
3089
 
                    pixelBit2 = x1;
3090
 
                    pixelBit3 = x2;
3091
 
                    pixelBit4 = y1;
3092
 
                    pixelBit5 = y2;
3093
 
                    break;
3094
 
                default:
3095
 
                    ADDR_ASSERT_ALWAYS();
3096
 
                    break;
3097
 
            }
3098
 
        }
3099
 
        else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
3100
 
        {
3101
 
            pixelBit0 = x0;
3102
 
            pixelBit1 = y0;
3103
 
            pixelBit2 = x1;
3104
 
            pixelBit3 = y1;
3105
 
            pixelBit4 = x2;
3106
 
            pixelBit5 = y2;
3107
 
        }
3108
 
        else if (microTileType == ADDR_ROTATED)
3109
 
        {
3110
 
            ADDR_ASSERT(thickness == 1);
3111
 
 
3112
 
            switch (bpp)
3113
 
            {
3114
 
                case 8:
3115
 
                    pixelBit0 = y0;
3116
 
                    pixelBit1 = y1;
3117
 
                    pixelBit2 = y2;
3118
 
                    pixelBit3 = x1;
3119
 
                    pixelBit4 = x0;
3120
 
                    pixelBit5 = x2;
3121
 
                    break;
3122
 
                case 16:
3123
 
                    pixelBit0 = y0;
3124
 
                    pixelBit1 = y1;
3125
 
                    pixelBit2 = y2;
3126
 
                    pixelBit3 = x0;
3127
 
                    pixelBit4 = x1;
3128
 
                    pixelBit5 = x2;
3129
 
                    break;
3130
 
                case 32:
3131
 
                    pixelBit0 = y0;
3132
 
                    pixelBit1 = y1;
3133
 
                    pixelBit2 = x0;
3134
 
                    pixelBit3 = y2;
3135
 
                    pixelBit4 = x1;
3136
 
                    pixelBit5 = x2;
3137
 
                    break;
3138
 
                case 64:
3139
 
                    pixelBit0 = y0;
3140
 
                    pixelBit1 = x0;
3141
 
                    pixelBit2 = y1;
3142
 
                    pixelBit3 = x1;
3143
 
                    pixelBit4 = x2;
3144
 
                    pixelBit5 = y2;
3145
 
                    break;
3146
 
                default:
3147
 
                    ADDR_ASSERT_ALWAYS();
3148
 
                    break;
3149
 
            }
3150
 
        }
3151
 
 
3152
 
        if (thickness > 1)
3153
 
        {
3154
 
            pixelBit6 = z0;
3155
 
            pixelBit7 = z1;
3156
 
        }
3157
 
    }
3158
 
    else // ADDR_THICK
3159
 
    {
3160
 
        ADDR_ASSERT(thickness > 1);
3161
 
 
3162
 
        switch (bpp)
3163
 
        {
3164
 
            case 8:
3165
 
            case 16:
3166
 
                pixelBit0 = x0;
3167
 
                pixelBit1 = y0;
3168
 
                pixelBit2 = x1;
3169
 
                pixelBit3 = y1;
3170
 
                pixelBit4 = z0;
3171
 
                pixelBit5 = z1;
3172
 
                break;
3173
 
            case 32:
3174
 
                pixelBit0 = x0;
3175
 
                pixelBit1 = y0;
3176
 
                pixelBit2 = x1;
3177
 
                pixelBit3 = z0;
3178
 
                pixelBit4 = y1;
3179
 
                pixelBit5 = z1;
3180
 
                break;
3181
 
            case 64:
3182
 
            case 128:
3183
 
                pixelBit0 = x0;
3184
 
                pixelBit1 = y0;
3185
 
                pixelBit2 = z0;
3186
 
                pixelBit3 = x1;
3187
 
                pixelBit4 = y1;
3188
 
                pixelBit5 = z1;
3189
 
                break;
3190
 
            default:
3191
 
                ADDR_ASSERT_ALWAYS();
3192
 
                break;
3193
 
        }
3194
 
 
3195
 
        pixelBit6 = x2;
3196
 
        pixelBit7 = y2;
3197
 
    }
3198
 
 
3199
 
    if (thickness == 8)
3200
 
    {
3201
 
        pixelBit8 = z2;
3202
 
    }
3203
 
 
3204
 
    pixelNumber = ((pixelBit0     ) |
3205
 
                   (pixelBit1 << 1) |
3206
 
                   (pixelBit2 << 2) |
3207
 
                   (pixelBit3 << 3) |
3208
 
                   (pixelBit4 << 4) |
3209
 
                   (pixelBit5 << 5) |
3210
 
                   (pixelBit6 << 6) |
3211
 
                   (pixelBit7 << 7) |
3212
 
                   (pixelBit8 << 8));
3213
 
 
3214
 
    return pixelNumber;
3215
 
}
3216
 
 
3217
 
/**
3218
 
****************************************************************************************************
3219
 
*   Lib::AdjustPitchAlignment
3220
 
*
3221
 
*   @brief
3222
 
*       Adjusts pitch alignment for flipping surface
3223
 
*
3224
 
*   @return
3225
 
*       N/A
3226
 
*
3227
 
****************************************************************************************************
3228
 
*/
3229
 
VOID Lib::AdjustPitchAlignment(
3230
 
    ADDR_SURFACE_FLAGS  flags,      ///< [in] Surface flags
3231
 
    UINT_32*            pPitchAlign ///< [out] Pointer to pitch alignment
3232
 
    ) const
3233
 
{
3234
 
    // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3235
 
    // Maybe it will be fixed in future but let's make it general for now.
3236
 
    if (flags.display || flags.overlay)
3237
 
    {
3238
 
        *pPitchAlign = PowTwoAlign(*pPitchAlign, 32);
3239
 
 
3240
 
        if(flags.display)
3241
 
        {
3242
 
            *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign);
3243
 
        }
3244
 
    }
3245
 
}
3246
 
 
3247
 
/**
3248
 
****************************************************************************************************
3249
 
*   Lib::PadDimensions
3250
 
*
3251
 
*   @brief
3252
 
*       Helper function to pad dimensions
3253
 
*
3254
 
*   @return
3255
 
*       N/A
3256
 
*
3257
 
****************************************************************************************************
3258
 
*/
3259
 
VOID Lib::PadDimensions(
3260
 
    AddrTileMode        tileMode,    ///< [in] tile mode
3261
 
    UINT_32             bpp,         ///< [in] bits per pixel
3262
 
    ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags
3263
 
    UINT_32             numSamples,  ///< [in] number of samples
3264
 
    ADDR_TILEINFO*      pTileInfo,   ///< [in,out] bank structure.
3265
 
    UINT_32             padDims,     ///< [in] Dimensions to pad valid value 1,2,3
3266
 
    UINT_32             mipLevel,    ///< [in] MipLevel
3267
 
    UINT_32*            pPitch,      ///< [in,out] pitch in pixels
3268
 
    UINT_32*            pPitchAlign, ///< [in,out] pitch align could be changed in HwlPadDimensions
3269
 
    UINT_32*            pHeight,     ///< [in,out] height in pixels
3270
 
    UINT_32             heightAlign, ///< [in] height alignment
3271
 
    UINT_32*            pSlices,     ///< [in,out] number of slices
3272
 
    UINT_32             sliceAlign   ///< [in] number of slice alignment
3273
 
    ) const
3274
 
{
3275
 
    UINT_32 pitchAlign = *pPitchAlign;
3276
 
    UINT_32 thickness = Thickness(tileMode);
3277
 
 
3278
 
    ADDR_ASSERT(padDims <= 3);
3279
 
 
3280
 
    //
3281
 
    // Override padding for mip levels
3282
 
    //
3283
 
    if (mipLevel > 0)
3284
 
    {
3285
 
        if (flags.cube)
3286
 
        {
3287
 
            // for cubemap, we only pad when client call with 6 faces as an identity
3288
 
            if (*pSlices > 1)
3289
 
            {
3290
 
                padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture
3291
 
            }
3292
 
            else
3293
 
            {
3294
 
                padDims = 2;
3295
 
            }
3296
 
        }
3297
 
    }
3298
 
 
3299
 
    // Any possibilities that padDims is 0?
3300
 
    if (padDims == 0)
3301
 
    {
3302
 
        padDims = 3;
3303
 
    }
3304
 
 
3305
 
    if (IsPow2(pitchAlign))
3306
 
    {
3307
 
        *pPitch = PowTwoAlign((*pPitch), pitchAlign);
3308
 
    }
3309
 
    else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3310
 
    {
3311
 
        *pPitch += pitchAlign - 1;
3312
 
        *pPitch /= pitchAlign;
3313
 
        *pPitch *= pitchAlign;
3314
 
    }
3315
 
 
3316
 
    if (padDims > 1)
3317
 
    {
3318
 
        if (IsPow2(heightAlign))
3319
 
        {
3320
 
            *pHeight = PowTwoAlign((*pHeight), heightAlign);
3321
 
        }
3322
 
        else
3323
 
        {
3324
 
            *pHeight += heightAlign - 1;
3325
 
            *pHeight /= heightAlign;
3326
 
            *pHeight *= heightAlign;
3327
 
        }
3328
 
    }
3329
 
 
3330
 
    if (padDims > 2 || thickness > 1)
3331
 
    {
3332
 
        // for cubemap single face, we do not pad slices.
3333
 
        // if we pad it, the slice number should be set to 6 and current mip level > 1
3334
 
        if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray))
3335
 
        {
3336
 
            *pSlices = NextPow2(*pSlices);
3337
 
        }
3338
 
 
3339
 
        // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3340
 
        if (thickness > 1)
3341
 
        {
3342
 
            *pSlices = PowTwoAlign((*pSlices), sliceAlign);
3343
 
        }
3344
 
 
3345
 
    }
3346
 
 
3347
 
    HwlPadDimensions(tileMode,
3348
 
                     bpp,
3349
 
                     flags,
3350
 
                     numSamples,
3351
 
                     pTileInfo,
3352
 
                     mipLevel,
3353
 
                     pPitch,
3354
 
                     pPitchAlign,
3355
 
                     *pHeight,
3356
 
                     heightAlign);
3357
 
}
3358
 
 
3359
 
 
3360
 
/**
3361
 
****************************************************************************************************
3362
 
*   Lib::HwlPreHandleBaseLvl3xPitch
3363
 
*
3364
 
*   @brief
3365
 
*       Pre-handler of 3x pitch (96 bit) adjustment
3366
 
*
3367
 
*   @return
3368
 
*       Expected pitch
3369
 
****************************************************************************************************
3370
 
*/
3371
 
UINT_32 Lib::HwlPreHandleBaseLvl3xPitch(
3372
 
    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
3373
 
    UINT_32                                 expPitch    ///< [in] pitch
3374
 
    ) const
3375
 
{
3376
 
    ADDR_ASSERT(pIn->width == expPitch);
3377
 
    //
3378
 
    // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3379
 
    //
3380
 
    if (ElemLib::IsExpand3x(pIn->format) &&
3381
 
        pIn->mipLevel == 0 &&
3382
 
        pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
3383
 
    {
3384
 
        expPitch /= 3;
3385
 
        expPitch = NextPow2(expPitch);
3386
 
    }
3387
 
 
3388
 
    return expPitch;
3389
 
}
3390
 
 
3391
 
/**
3392
 
****************************************************************************************************
3393
 
*   Lib::HwlPostHandleBaseLvl3xPitch
3394
 
*
3395
 
*   @brief
3396
 
*       Post-handler of 3x pitch adjustment
3397
 
*
3398
 
*   @return
3399
 
*       Expected pitch
3400
 
****************************************************************************************************
3401
 
*/
3402
 
UINT_32 Lib::HwlPostHandleBaseLvl3xPitch(
3403
 
    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input
3404
 
    UINT_32                                 expPitch    ///< [in] pitch
3405
 
    ) const
3406
 
{
3407
 
    //
3408
 
    // 96 bits surface of sub levels require element pitch of 32 bits instead
3409
 
    // So we just return pitch in 32 bit pixels without timing 3
3410
 
    //
3411
 
    if (ElemLib::IsExpand3x(pIn->format) &&
3412
 
        pIn->mipLevel == 0 &&
3413
 
        pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
3414
 
    {
3415
 
        expPitch *= 3;
3416
 
    }
3417
 
 
3418
 
    return expPitch;
3419
 
}
3420
 
 
3421
 
 
3422
 
/**
3423
 
****************************************************************************************************
3424
 
*   Lib::IsMacroTiled
3425
 
*
3426
 
*   @brief
3427
 
*       Check if the tile mode is macro tiled
3428
 
*
3429
 
*   @return
3430
 
*       TRUE if it is macro tiled (2D/2B/3D/3B)
3431
 
****************************************************************************************************
3432
 
*/
3433
 
BOOL_32 Lib::IsMacroTiled(
3434
 
    AddrTileMode tileMode)  ///< [in] tile mode
3435
 
{
3436
 
   return ModeFlags[tileMode].isMacro;
3437
 
}
3438
 
 
3439
 
/**
3440
 
****************************************************************************************************
3441
 
*   Lib::IsMacro3dTiled
3442
 
*
3443
 
*   @brief
3444
 
*       Check if the tile mode is 3D macro tiled
3445
 
*
3446
 
*   @return
3447
 
*       TRUE if it is 3D macro tiled
3448
 
****************************************************************************************************
3449
 
*/
3450
 
BOOL_32 Lib::IsMacro3dTiled(
3451
 
    AddrTileMode tileMode)  ///< [in] tile mode
3452
 
{
3453
 
    return ModeFlags[tileMode].isMacro3d;
3454
 
}
3455
 
 
3456
 
/**
3457
 
****************************************************************************************************
3458
 
*   Lib::IsMicroTiled
3459
 
*
3460
 
*   @brief
3461
 
*       Check if the tile mode is micro tiled
3462
 
*
3463
 
*   @return
3464
 
*       TRUE if micro tiled
3465
 
****************************************************************************************************
3466
 
*/
3467
 
BOOL_32 Lib::IsMicroTiled(
3468
 
    AddrTileMode tileMode)  ///< [in] tile mode
3469
 
{
3470
 
    return ModeFlags[tileMode].isMicro;
3471
 
}
3472
 
 
3473
 
/**
3474
 
****************************************************************************************************
3475
 
*   Lib::IsLinear
3476
 
*
3477
 
*   @brief
3478
 
*       Check if the tile mode is linear
3479
 
*
3480
 
*   @return
3481
 
*       TRUE if linear
3482
 
****************************************************************************************************
3483
 
*/
3484
 
BOOL_32 Lib::IsLinear(
3485
 
    AddrTileMode tileMode)  ///< [in] tile mode
3486
 
{
3487
 
    return ModeFlags[tileMode].isLinear;
3488
 
}
3489
 
 
3490
 
/**
3491
 
****************************************************************************************************
3492
 
*   Lib::IsPrtNoRotationTileMode
3493
 
*
3494
 
*   @brief
3495
 
*       Return TRUE if it is prt tile without rotation
3496
 
*   @note
3497
 
*       This function just used by CI
3498
 
****************************************************************************************************
3499
 
*/
3500
 
BOOL_32 Lib::IsPrtNoRotationTileMode(
3501
 
    AddrTileMode tileMode)
3502
 
{
3503
 
    return ModeFlags[tileMode].isPrtNoRotation;
3504
 
}
3505
 
 
3506
 
/**
3507
 
****************************************************************************************************
3508
 
*   Lib::IsPrtTileMode
3509
 
*
3510
 
*   @brief
3511
 
*       Return TRUE if it is prt tile
3512
 
*   @note
3513
 
*       This function just used by CI
3514
 
****************************************************************************************************
3515
 
*/
3516
 
BOOL_32 Lib::IsPrtTileMode(
3517
 
    AddrTileMode tileMode)
3518
 
{
3519
 
    return ModeFlags[tileMode].isPrt;
3520
 
}
3521
 
 
3522
 
/**
3523
 
****************************************************************************************************
3524
 
*   Lib::ComputeMipLevel
3525
 
*
3526
 
*   @brief
3527
 
*       Compute mipmap level width/height/slices
3528
 
*   @return
3529
 
*      N/A
3530
 
****************************************************************************************************
3531
 
*/
3532
 
VOID Lib::ComputeMipLevel(
3533
 
    ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in,out] Input structure
3534
 
    ) const
3535
 
{
3536
 
    // Check if HWL has handled
3537
 
    BOOL_32 hwlHandled = FALSE;
3538
 
 
3539
 
    if (ElemLib::IsBlockCompressed(pIn->format))
3540
 
    {
3541
 
        if (pIn->mipLevel == 0)
3542
 
        {
3543
 
            // DXTn's level 0 must be multiple of 4
3544
 
            // But there are exceptions:
3545
 
            // 1. Internal surface creation in hostblt/vsblt/etc...
3546
 
            // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3547
 
            pIn->width = PowTwoAlign(pIn->width, 4);
3548
 
            pIn->height = PowTwoAlign(pIn->height, 4);
3549
 
        }
3550
 
    }
3551
 
 
3552
 
    hwlHandled = HwlComputeMipLevel(pIn);
3553
 
}
3554
 
 
3555
 
/**
3556
 
****************************************************************************************************
3557
 
*   Lib::DegradeTo1D
3558
 
*
3559
 
*   @brief
3560
 
*       Check if surface can be degraded to 1D
3561
 
*   @return
3562
 
*       TRUE if degraded
3563
 
****************************************************************************************************
3564
 
*/
3565
 
BOOL_32 Lib::DegradeTo1D(
3566
 
    UINT_32 width,                  ///< surface width
3567
 
    UINT_32 height,                 ///< surface height
3568
 
    UINT_32 macroTilePitchAlign,    ///< macro tile pitch align
3569
 
    UINT_32 macroTileHeightAlign    ///< macro tile height align
3570
 
    )
3571
 
{
3572
 
    BOOL_32 degrade = ((width < macroTilePitchAlign) || (height < macroTileHeightAlign));
3573
 
 
3574
 
    // Check whether 2D tiling still has too much footprint
3575
 
    if (degrade == FALSE)
3576
 
    {
3577
 
        // Only check width and height as slices are aligned to thickness
3578
 
        UINT_64 unalignedSize = width * height;
3579
 
 
3580
 
        UINT_32 alignedPitch = PowTwoAlign(width, macroTilePitchAlign);
3581
 
        UINT_32 alignedHeight = PowTwoAlign(height, macroTileHeightAlign);
3582
 
        UINT_64 alignedSize = alignedPitch * alignedHeight;
3583
 
 
3584
 
        // alignedSize > 1.5 * unalignedSize
3585
 
        if (2 * alignedSize > 3 * unalignedSize)
3586
 
        {
3587
 
            degrade = TRUE;
3588
 
        }
3589
 
    }
3590
 
 
3591
 
    return degrade;
3592
 
}
3593
 
 
3594
 
/**
3595
 
****************************************************************************************************
3596
 
*   Lib::OptimizeTileMode
3597
 
*
3598
 
*   @brief
3599
 
*       Check if base level's tile mode can be optimized (degraded)
3600
 
*   @return
3601
 
*       N/A
3602
 
****************************************************************************************************
3603
 
*/
3604
 
VOID Lib::OptimizeTileMode(
3605
 
    ADDR_COMPUTE_SURFACE_INFO_INPUT*  pInOut     ///< [in, out] structure for surface info
3606
 
    ) const
3607
 
{
3608
 
    AddrTileMode tileMode = pInOut->tileMode;
3609
 
 
3610
 
    BOOL_32 doOpt = (pInOut->flags.opt4Space == TRUE) ||
3611
 
                    (pInOut->flags.minimizeAlignment == TRUE) ||
3612
 
                    (pInOut->maxBaseAlign != 0);
3613
 
 
3614
 
    BOOL_32 convertToPrt = FALSE;
3615
 
 
3616
 
    // Optimization can only be done on level 0 and samples <= 1
3617
 
    if ((doOpt == TRUE)                     &&
3618
 
        (pInOut->mipLevel == 0)             &&
3619
 
        (IsPrtTileMode(tileMode) == FALSE)  &&
3620
 
        (pInOut->flags.prt == FALSE))
3621
 
    {
3622
 
        UINT_32 width = pInOut->width;
3623
 
        UINT_32 height = pInOut->height;
3624
 
        UINT_32 thickness = Thickness(tileMode);
3625
 
        BOOL_32 macroTiledOK = TRUE;
3626
 
        UINT_32 macroWidthAlign = 0;
3627
 
        UINT_32 macroHeightAlign = 0;
3628
 
        UINT_32 macroSizeAlign = 0;
3629
 
 
3630
 
        if (IsMacroTiled(tileMode))
3631
 
        {
3632
 
            macroTiledOK = HwlGetAlignmentInfoMacroTiled(pInOut,
3633
 
                                                         &macroWidthAlign,
3634
 
                                                         &macroHeightAlign,
3635
 
                                                         &macroSizeAlign);
3636
 
        }
3637
 
 
3638
 
        if (macroTiledOK)
3639
 
        {
3640
 
            if ((pInOut->flags.display == FALSE) &&
3641
 
                (pInOut->flags.opt4Space == TRUE) &&
3642
 
                (pInOut->numSamples <= 1))
3643
 
            {
3644
 
                // Check if linear mode is optimal
3645
 
                if ((pInOut->height == 1) &&
3646
 
                    (IsLinear(tileMode) == FALSE) &&
3647
 
                    (ElemLib::IsBlockCompressed(pInOut->format) == FALSE) &&
3648
 
                    (pInOut->flags.depth == FALSE) &&
3649
 
                    (pInOut->flags.stencil == FALSE) &&
3650
 
                    (m_configFlags.disableLinearOpt == FALSE) &&
3651
 
                    (pInOut->flags.disableLinearOpt == FALSE))
3652
 
                {
3653
 
                    tileMode = ADDR_TM_LINEAR_ALIGNED;
3654
 
                }
3655
 
                else if (IsMacroTiled(tileMode) && (pInOut->flags.tcCompatible == FALSE))
3656
 
                {
3657
 
                    if (DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
3658
 
                    {
3659
 
                        tileMode = (thickness == 1) ?
3660
 
                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3661
 
                    }
3662
 
                    else if ((thickness > 1) && (pInOut->flags.disallowLargeThickDegrade == 0))
3663
 
                    {
3664
 
                        // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3665
 
                        // thinner modes, we should re-evaluate whether the corresponding
3666
 
                        // thinner modes should be degraded. If so, we choose 1D thick mode instead.
3667
 
                        tileMode = DegradeLargeThickTile(pInOut->tileMode, pInOut->bpp);
3668
 
 
3669
 
                        if (tileMode != pInOut->tileMode)
3670
 
                        {
3671
 
                            // Get thickness again after large thick degrade
3672
 
                            thickness = Thickness(tileMode);
3673
 
 
3674
 
                            ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pInOut;
3675
 
                            input.tileMode = tileMode;
3676
 
 
3677
 
                            macroTiledOK = HwlGetAlignmentInfoMacroTiled(&input,
3678
 
                                                                         &macroWidthAlign,
3679
 
                                                                         &macroHeightAlign,
3680
 
                                                                         &macroSizeAlign);
3681
 
 
3682
 
                            if (macroTiledOK &&
3683
 
                                DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
3684
 
                            {
3685
 
                                tileMode = ADDR_TM_1D_TILED_THICK;
3686
 
                            }
3687
 
                        }
3688
 
                    }
3689
 
                }
3690
 
            }
3691
 
 
3692
 
            if (macroTiledOK)
3693
 
            {
3694
 
                if ((pInOut->flags.minimizeAlignment == TRUE) &&
3695
 
                    (pInOut->numSamples <= 1) &&
3696
 
                    (IsMacroTiled(tileMode) == TRUE))
3697
 
                {
3698
 
                    UINT_32 macroSize = PowTwoAlign(width, macroWidthAlign) *
3699
 
                                        PowTwoAlign(height, macroHeightAlign);
3700
 
                    UINT_32 microSize = PowTwoAlign(width, MicroTileWidth) *
3701
 
                                        PowTwoAlign(height, MicroTileHeight);
3702
 
 
3703
 
                    if (macroSize > microSize)
3704
 
                    {
3705
 
                        tileMode = (thickness == 1) ?
3706
 
                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3707
 
                    }
3708
 
                }
3709
 
 
3710
 
                if ((pInOut->maxBaseAlign != 0) &&
3711
 
                    (IsMacroTiled(tileMode) == TRUE))
3712
 
                {
3713
 
                    if (macroSizeAlign > pInOut->maxBaseAlign)
3714
 
                    {
3715
 
                        if (pInOut->numSamples > 1)
3716
 
                        {
3717
 
                            ADDR_ASSERT(pInOut->maxBaseAlign >= Block64K);
3718
 
 
3719
 
                            convertToPrt = TRUE;
3720
 
                        }
3721
 
                        else if (pInOut->maxBaseAlign < Block64K)
3722
 
                        {
3723
 
                            tileMode = (thickness == 1) ?
3724
 
                                       ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3725
 
                        }
3726
 
                        else
3727
 
                        {
3728
 
                            convertToPrt = TRUE;
3729
 
                        }
3730
 
                    }
3731
 
                }
3732
 
            }
3733
 
        }
3734
 
    }
3735
 
 
3736
 
    if (convertToPrt)
3737
 
    {
3738
 
        if ((pInOut->flags.matchStencilTileCfg == TRUE) && (pInOut->numSamples <= 1))
3739
 
        {
3740
 
            pInOut->tileMode = ADDR_TM_1D_TILED_THIN1;
3741
 
        }
3742
 
        else
3743
 
        {
3744
 
            HwlSetPrtTileMode(pInOut);
3745
 
        }
3746
 
    }
3747
 
    else if (tileMode != pInOut->tileMode)
3748
 
    {
3749
 
        pInOut->tileMode = tileMode;
3750
 
    }
3751
 
 
3752
 
    HwlOptimizeTileMode(pInOut);
3753
 
}
3754
 
 
3755
 
/**
3756
 
****************************************************************************************************
3757
 
*   Lib::DegradeLargeThickTile
3758
 
*
3759
 
*   @brief
3760
 
*       Check if the thickness needs to be reduced if a tile is too large
3761
 
*   @return
3762
 
*       The degraded tile mode (unchanged if not degraded)
3763
 
****************************************************************************************************
3764
 
*/
3765
 
AddrTileMode Lib::DegradeLargeThickTile(
3766
 
    AddrTileMode tileMode,
3767
 
    UINT_32 bpp) const
3768
 
{
3769
 
    // Override tilemode
3770
 
    // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3771
 
    // it is better to just use THIN mode in this case
3772
 
    UINT_32 thickness = Thickness(tileMode);
3773
 
 
3774
 
    if (thickness > 1 && m_configFlags.allowLargeThickTile == 0)
3775
 
    {
3776
 
        UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3);
3777
 
 
3778
 
        if (tileSize > m_rowSize)
3779
 
        {
3780
 
            switch (tileMode)
3781
 
            {
3782
 
                case ADDR_TM_2D_TILED_XTHICK:
3783
 
                    if ((tileSize >> 1) <= m_rowSize)
3784
 
                    {
3785
 
                        tileMode = ADDR_TM_2D_TILED_THICK;
3786
 
                        break;
3787
 
                    }
3788
 
                    // else fall through
3789
 
                case ADDR_TM_2D_TILED_THICK:
3790
 
                    tileMode    = ADDR_TM_2D_TILED_THIN1;
3791
 
                    break;
3792
 
 
3793
 
                case ADDR_TM_3D_TILED_XTHICK:
3794
 
                    if ((tileSize >> 1) <= m_rowSize)
3795
 
                    {
3796
 
                        tileMode = ADDR_TM_3D_TILED_THICK;
3797
 
                        break;
3798
 
                    }
3799
 
                    // else fall through
3800
 
                case ADDR_TM_3D_TILED_THICK:
3801
 
                    tileMode    = ADDR_TM_3D_TILED_THIN1;
3802
 
                    break;
3803
 
 
3804
 
                case ADDR_TM_PRT_TILED_THICK:
3805
 
                    tileMode    = ADDR_TM_PRT_TILED_THIN1;
3806
 
                    break;
3807
 
 
3808
 
                case ADDR_TM_PRT_2D_TILED_THICK:
3809
 
                    tileMode    = ADDR_TM_PRT_2D_TILED_THIN1;
3810
 
                    break;
3811
 
 
3812
 
                case ADDR_TM_PRT_3D_TILED_THICK:
3813
 
                    tileMode    = ADDR_TM_PRT_3D_TILED_THIN1;
3814
 
                    break;
3815
 
 
3816
 
                default:
3817
 
                    break;
3818
 
            }
3819
 
        }
3820
 
    }
3821
 
 
3822
 
    return tileMode;
3823
 
}
3824
 
 
3825
 
/**
3826
 
****************************************************************************************************
3827
 
*   Lib::PostComputeMipLevel
3828
 
*   @brief
3829
 
*       Compute MipLevel info (including level 0) after surface adjustment
3830
 
*   @return
3831
 
*       ADDR_E_RETURNCODE
3832
 
****************************************************************************************************
3833
 
*/
3834
 
ADDR_E_RETURNCODE Lib::PostComputeMipLevel(
3835
 
    ADDR_COMPUTE_SURFACE_INFO_INPUT*    pIn,   ///< [in,out] Input structure
3836
 
    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut   ///< [out] Output structure
3837
 
    ) const
3838
 
{
3839
 
    // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3840
 
    // required by CFX  for Hw Compatibility between NI and SI. Otherwise it is only needed for
3841
 
    // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3842
 
 
3843
 
    if (pIn->flags.pow2Pad)
3844
 
    {
3845
 
        pIn->width      = NextPow2(pIn->width);
3846
 
        pIn->height     = NextPow2(pIn->height);
3847
 
        pIn->numSlices  = NextPow2(pIn->numSlices);
3848
 
    }
3849
 
    else if (pIn->mipLevel > 0)
3850
 
    {
3851
 
        pIn->width      = NextPow2(pIn->width);
3852
 
        pIn->height     = NextPow2(pIn->height);
3853
 
 
3854
 
        if (!pIn->flags.cube)
3855
 
        {
3856
 
            pIn->numSlices = NextPow2(pIn->numSlices);
3857
 
        }
3858
 
 
3859
 
        // for cubemap, we keep its value at first
3860
 
    }
3861
 
 
3862
 
    return ADDR_OK;
3863
 
}
3864
 
 
3865
 
/**
3866
 
****************************************************************************************************
3867
 
*   Lib::HwlSetupTileCfg
3868
 
*
3869
 
*   @brief
3870
 
*       Map tile index to tile setting.
3871
 
*   @return
3872
 
*       ADDR_E_RETURNCODE
3873
 
****************************************************************************************************
3874
 
*/
3875
 
ADDR_E_RETURNCODE Lib::HwlSetupTileCfg(
3876
 
    UINT_32         bpp,              ///< Bits per pixel
3877
 
    INT_32          index,            ///< [in] Tile index
3878
 
    INT_32          macroModeIndex,   ///< [in] Index in macro tile mode table(CI)
3879
 
    ADDR_TILEINFO*  pInfo,            ///< [out] Tile Info
3880
 
    AddrTileMode*   pMode,            ///< [out] Tile mode
3881
 
    AddrTileType*   pType             ///< [out] Tile type
3882
 
    ) const
3883
 
{
3884
 
    return ADDR_NOTSUPPORTED;
3885
 
}
3886
 
 
3887
 
/**
3888
 
****************************************************************************************************
3889
 
*   Lib::HwlGetPipes
3890
 
*
3891
 
*   @brief
3892
 
*       Get number pipes
3893
 
*   @return
3894
 
*       num pipes
3895
 
****************************************************************************************************
3896
 
*/
3897
 
UINT_32 Lib::HwlGetPipes(
3898
 
    const ADDR_TILEINFO* pTileInfo    ///< [in] Tile info
3899
 
    ) const
3900
 
{
3901
 
    //pTileInfo can be NULL when asic is 6xx and 8xx.
3902
 
    return m_pipes;
3903
 
}
3904
 
 
3905
 
/**
3906
 
****************************************************************************************************
3907
 
*   Lib::ComputeQbStereoInfo
3908
 
*
3909
 
*   @brief
3910
 
*       Get quad buffer stereo information
3911
 
*   @return
3912
 
*       N/A
3913
 
****************************************************************************************************
3914
 
*/
3915
 
VOID Lib::ComputeQbStereoInfo(
3916
 
    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [in,out] updated pOut+pStereoInfo
3917
 
    ) const
3918
 
{
3919
 
    ADDR_ASSERT(pOut->bpp >= 8);
3920
 
    ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
3921
 
 
3922
 
    // Save original height
3923
 
    pOut->pStereoInfo->eyeHeight = pOut->height;
3924
 
 
3925
 
    // Right offset
3926
 
    pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
3927
 
 
3928
 
    pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
3929
 
    // Double height
3930
 
    pOut->height <<= 1;
3931
 
    pOut->pixelHeight <<= 1;
3932
 
 
3933
 
    // Double size
3934
 
    pOut->surfSize <<= 1;
3935
 
 
3936
 
    // Right start address meets the base align since it is guaranteed by AddrLib1
3937
 
 
3938
 
    // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3939
 
}
3940
 
 
3941
 
 
3942
 
/**
3943
 
****************************************************************************************************
3944
 
*   Lib::ComputePrtInfo
3945
 
*
3946
 
*   @brief
3947
 
*       Compute prt surface related info
3948
 
*
3949
 
*   @return
3950
 
*       ADDR_E_RETURNCODE
3951
 
****************************************************************************************************
3952
 
*/
3953
 
ADDR_E_RETURNCODE Lib::ComputePrtInfo(
3954
 
    const ADDR_PRT_INFO_INPUT*  pIn,
3955
 
    ADDR_PRT_INFO_OUTPUT*       pOut) const
3956
 
{
3957
 
    ADDR_ASSERT(pOut != NULL);
3958
 
 
3959
 
    ADDR_E_RETURNCODE returnCode = ADDR_OK;
3960
 
 
3961
 
    UINT_32     expandX = 1;
3962
 
    UINT_32     expandY = 1;
3963
 
    ElemMode    elemMode;
3964
 
 
3965
 
    UINT_32     bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
3966
 
                                                    &elemMode,
3967
 
                                                    &expandX,
3968
 
                                                    &expandY);
3969
 
 
3970
 
    if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96)
3971
 
    {
3972
 
        returnCode = ADDR_INVALIDPARAMS;
3973
 
    }
3974
 
 
3975
 
    UINT_32     numFrags = pIn->numFrags;
3976
 
    ADDR_ASSERT(numFrags <= 8);
3977
 
 
3978
 
    UINT_32     tileWidth = 0;
3979
 
    UINT_32     tileHeight = 0;
3980
 
    if (returnCode == ADDR_OK)
3981
 
    {
3982
 
        // 3D texture without depth or 2d texture
3983
 
        if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1)
3984
 
        {
3985
 
            if (bpp == 8)
3986
 
            {
3987
 
                tileWidth = 256;
3988
 
                tileHeight = 256;
3989
 
            }
3990
 
            else if (bpp == 16)
3991
 
            {
3992
 
                tileWidth = 256;
3993
 
                tileHeight = 128;
3994
 
            }
3995
 
            else if (bpp == 32)
3996
 
            {
3997
 
                tileWidth = 128;
3998
 
                tileHeight = 128;
3999
 
            }
4000
 
            else if (bpp == 64)
4001
 
            {
4002
 
                // assume it is BC1/4
4003
 
                tileWidth = 512;
4004
 
                tileHeight = 256;
4005
 
 
4006
 
                if (elemMode == ADDR_UNCOMPRESSED)
4007
 
                {
4008
 
                    tileWidth = 128;
4009
 
                    tileHeight = 64;
4010
 
                }
4011
 
            }
4012
 
            else if (bpp == 128)
4013
 
            {
4014
 
                // assume it is BC2/3/5/6H/7
4015
 
                tileWidth = 256;
4016
 
                tileHeight = 256;
4017
 
 
4018
 
                if (elemMode == ADDR_UNCOMPRESSED)
4019
 
                {
4020
 
                    tileWidth = 64;
4021
 
                    tileHeight = 64;
4022
 
                }
4023
 
            }
4024
 
 
4025
 
            if (numFrags == 2)
4026
 
            {
4027
 
                tileWidth = tileWidth / 2;
4028
 
            }
4029
 
            else if (numFrags == 4)
4030
 
            {
4031
 
                tileWidth = tileWidth / 2;
4032
 
                tileHeight = tileHeight / 2;
4033
 
            }
4034
 
            else if (numFrags == 8)
4035
 
            {
4036
 
                tileWidth = tileWidth / 4;
4037
 
                tileHeight = tileHeight / 2;
4038
 
            }
4039
 
        }
4040
 
        else    // 1d
4041
 
        {
4042
 
            tileHeight = 1;
4043
 
            if (bpp == 8)
4044
 
            {
4045
 
                tileWidth = 65536;
4046
 
            }
4047
 
            else if (bpp == 16)
4048
 
            {
4049
 
                tileWidth = 32768;
4050
 
            }
4051
 
            else if (bpp == 32)
4052
 
            {
4053
 
                tileWidth = 16384;
4054
 
            }
4055
 
            else if (bpp == 64)
4056
 
            {
4057
 
                tileWidth = 8192;
4058
 
            }
4059
 
            else if (bpp == 128)
4060
 
            {
4061
 
                tileWidth = 4096;
4062
 
            }
4063
 
        }
4064
 
    }
4065
 
 
4066
 
    pOut->prtTileWidth = tileWidth;
4067
 
    pOut->prtTileHeight = tileHeight;
4068
 
 
4069
 
    return returnCode;
4070
 
}
4071
 
 
4072
 
} // V1
4073
 
} // Addr