1/****************************************************************************
2* Copyright (C) 2014-2016 Intel Corporation.   All Rights Reserved.
3*
4* Permission is hereby granted, free of charge, to any person obtaining a
5* copy of this software and associated documentation files (the "Software"),
6* to deal in the Software without restriction, including without limitation
7* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8* and/or sell copies of the Software, and to permit persons to whom the
9* Software is furnished to do so, subject to the following conditions:
10*
11* The above copyright notice and this permission notice (including the next
12* paragraph) shall be included in all copies or substantial portions of the
13* Software.
14*
15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21* IN THE SOFTWARE.
22*
23* @file LoadTile.cpp
24*
25* @brief Functionality for Load
26*
27******************************************************************************/
28#include "LoadTile.h"
29
30
31static void BUCKETS_START(UINT id)
32{
33#ifdef KNOB_ENABLE_RDTSC
34    gBucketMgr.StartBucket(id);
35#endif
36}
37
38static void BUCKETS_STOP(UINT id)
39{
40#ifdef KNOB_ENABLE_RDTSC
41    gBucketMgr.StopBucket(id);
42#endif
43}
44
45// on demand buckets for load tiles
46static std::vector<int> sBuckets(NUM_SWR_FORMATS, -1);
47static std::mutex sBucketMutex;
48
49//////////////////////////////////////////////////////////////////////////
50/// @brief Loads a full hottile from a render surface
51/// @param hPrivateContext - Handle to private DC
52/// @param dstFormat - Format for hot tile.
53/// @param renderTargetIndex - Index to src render target
54/// @param x, y - Coordinates to raster tile.
55/// @param pDstHotTile - Pointer to Hot Tile
56void SwrLoadHotTile(
57    HANDLE hWorkerPrivateData,
58    const SWR_SURFACE_STATE *pSrcSurface,
59    SWR_FORMAT dstFormat,
60    SWR_RENDERTARGET_ATTACHMENT renderTargetIndex,
61    uint32_t x, uint32_t y, uint32_t renderTargetArrayIndex,
62    uint8_t *pDstHotTile)
63{
64    PFN_LOAD_TILES pfnLoadTiles = NULL;
65
66    // don't need to load null surfaces
67    if (pSrcSurface->type == SURFACE_NULL)
68    {
69        return;
70    }
71
72    // force 0 if requested renderTargetArrayIndex is OOB
73    if (renderTargetArrayIndex >= pSrcSurface->depth)
74    {
75        renderTargetArrayIndex = 0;
76    }
77
78    if (renderTargetIndex < SWR_ATTACHMENT_DEPTH)
79    {
80        switch (pSrcSurface->tileMode)
81        {
82        case SWR_TILE_NONE:
83            pfnLoadTiles = sLoadTilesColorTable_SWR_TILE_NONE[pSrcSurface->format];
84            break;
85        case SWR_TILE_MODE_YMAJOR:
86            pfnLoadTiles = sLoadTilesColorTable_SWR_TILE_MODE_YMAJOR[pSrcSurface->format];
87            break;
88        case SWR_TILE_MODE_XMAJOR:
89            pfnLoadTiles = sLoadTilesColorTable_SWR_TILE_MODE_XMAJOR[pSrcSurface->format];
90            break;
91        case SWR_TILE_MODE_WMAJOR:
92            SWR_ASSERT(pSrcSurface->format == R8_UINT);
93            pfnLoadTiles = LoadMacroTile<TilingTraits<SWR_TILE_MODE_WMAJOR, 8>, R8_UINT, R8_UINT>::Load;
94            break;
95        default:
96            SWR_INVALID("Unsupported tiling mode");
97            break;
98        }
99    }
100    else if (renderTargetIndex == SWR_ATTACHMENT_DEPTH)
101    {
102        // Currently depth can map to linear and tile-y.
103        switch (pSrcSurface->tileMode)
104        {
105        case SWR_TILE_NONE:
106            pfnLoadTiles = sLoadTilesDepthTable_SWR_TILE_NONE[pSrcSurface->format];
107            break;
108        case SWR_TILE_MODE_YMAJOR:
109            pfnLoadTiles = sLoadTilesDepthTable_SWR_TILE_MODE_YMAJOR[pSrcSurface->format];
110            break;
111        default:
112            SWR_INVALID("Unsupported tiling mode");
113            break;
114        }
115    }
116    else
117    {
118        SWR_ASSERT(renderTargetIndex == SWR_ATTACHMENT_STENCIL);
119        SWR_ASSERT(pSrcSurface->format == R8_UINT);
120        switch (pSrcSurface->tileMode)
121        {
122        case SWR_TILE_NONE:
123            pfnLoadTiles = LoadMacroTile<TilingTraits<SWR_TILE_NONE, 8>, R8_UINT, R8_UINT>::Load;
124            break;
125        case SWR_TILE_MODE_WMAJOR:
126            pfnLoadTiles = LoadMacroTile<TilingTraits<SWR_TILE_MODE_WMAJOR, 8>, R8_UINT, R8_UINT>::Load;
127            break;
128        default:
129            SWR_INVALID("Unsupported tiling mode");
130            break;
131        }
132    }
133
134    if (pfnLoadTiles == nullptr)
135    {
136        SWR_INVALID("Unsupported format for load tile");
137        return;
138    }
139
140    // Load a macro tile.
141#ifdef KNOB_ENABLE_RDTSC
142    if (sBuckets[pSrcSurface->format] == -1)
143    {
144        // guard sBuckets update since storetiles is called by multiple threads
145        sBucketMutex.lock();
146        if (sBuckets[pSrcSurface->format] == -1)
147        {
148            const SWR_FORMAT_INFO& info = GetFormatInfo(pSrcSurface->format);
149            BUCKET_DESC desc{ info.name, "", false, 0xffffffff };
150            sBuckets[pSrcSurface->format] = gBucketMgr.RegisterBucket(desc);
151        }
152        sBucketMutex.unlock();
153    }
154#endif
155
156    BUCKETS_START(sBuckets[pSrcSurface->format]);
157    pfnLoadTiles(pSrcSurface, pDstHotTile, x, y, renderTargetArrayIndex);
158    BUCKETS_STOP(sBuckets[pSrcSurface->format]);
159}
160
161
162void InitSimLoadTilesTable()
163{
164    InitLoadTilesTable_Linear();
165    InitLoadTilesTable_XMajor();
166    InitLoadTilesTable_YMajor();
167}
168