1*35ffd701SAndroid Build Coastguard Worker /*==============================================================================
2*35ffd701SAndroid Build Coastguard Worker Copyright(c) 2017 Intel Corporation
3*35ffd701SAndroid Build Coastguard Worker
4*35ffd701SAndroid Build Coastguard Worker Permission is hereby granted, free of charge, to any person obtaining a
5*35ffd701SAndroid Build Coastguard Worker copy of this software and associated documentation files(the "Software"),
6*35ffd701SAndroid Build Coastguard Worker to deal in the Software without restriction, including without limitation
7*35ffd701SAndroid Build Coastguard Worker the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*35ffd701SAndroid Build Coastguard Worker and / or sell copies of the Software, and to permit persons to whom the
9*35ffd701SAndroid Build Coastguard Worker Software is furnished to do so, subject to the following conditions:
10*35ffd701SAndroid Build Coastguard Worker
11*35ffd701SAndroid Build Coastguard Worker The above copyright notice and this permission notice shall be included
12*35ffd701SAndroid Build Coastguard Worker in all copies or substantial portions of the Software.
13*35ffd701SAndroid Build Coastguard Worker
14*35ffd701SAndroid Build Coastguard Worker THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*35ffd701SAndroid Build Coastguard Worker OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*35ffd701SAndroid Build Coastguard Worker FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*35ffd701SAndroid Build Coastguard Worker THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*35ffd701SAndroid Build Coastguard Worker OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*35ffd701SAndroid Build Coastguard Worker ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*35ffd701SAndroid Build Coastguard Worker OTHER DEALINGS IN THE SOFTWARE.
21*35ffd701SAndroid Build Coastguard Worker ============================================================================*/
22*35ffd701SAndroid Build Coastguard Worker
23*35ffd701SAndroid Build Coastguard Worker #include "Internal/Common/GmmLibInc.h"
24*35ffd701SAndroid Build Coastguard Worker
25*35ffd701SAndroid Build Coastguard Worker
26*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
27*35ffd701SAndroid Build Coastguard Worker /// GMM Interface to return lock or render aligned offset to a mip map
28*35ffd701SAndroid Build Coastguard Worker ///
29*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
30*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO to store offset info
31*35ffd701SAndroid Build Coastguard Worker ///
32*35ffd701SAndroid Build Coastguard Worker /// @return ::GMM_STATUS
33*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
GmmTexGetMipMapOffset(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo,GMM_LIB_CONTEXT * pGmmLibContext)34*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmTexGetMipMapOffset(GMM_TEXTURE_INFO * pTexInfo,
35*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo,
36*35ffd701SAndroid Build Coastguard Worker GMM_LIB_CONTEXT * pGmmLibContext)
37*35ffd701SAndroid Build Coastguard Worker {
38*35ffd701SAndroid Build Coastguard Worker GMM_STATUS Status = GMM_SUCCESS;
39*35ffd701SAndroid Build Coastguard Worker bool RestoreRenderReq = false;
40*35ffd701SAndroid Build Coastguard Worker bool RestoreLockReq = false;
41*35ffd701SAndroid Build Coastguard Worker GMM_TEXTURE_CALC *pTextureCalc;
42*35ffd701SAndroid Build Coastguard Worker
43*35ffd701SAndroid Build Coastguard Worker GMM_DPF_ENTER;
44*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
45*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
46*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(pReqInfo->CubeFace <= __GMM_NO_CUBE_MAP);
47*35ffd701SAndroid Build Coastguard Worker
48*35ffd701SAndroid Build Coastguard Worker pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(pTexInfo, pGmmLibContext);
49*35ffd701SAndroid Build Coastguard Worker
50*35ffd701SAndroid Build Coastguard Worker if((pReqInfo->Plane >= GMM_MAX_PLANE) ||
51*35ffd701SAndroid Build Coastguard Worker (pReqInfo->Plane < GMM_NO_PLANE) ||
52*35ffd701SAndroid Build Coastguard Worker (pReqInfo->MipLevel >= GMM_MAX_MIPMAP))
53*35ffd701SAndroid Build Coastguard Worker {
54*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF(0, "Invalid parameter!");
55*35ffd701SAndroid Build Coastguard Worker return GMM_ERROR;
56*35ffd701SAndroid Build Coastguard Worker }
57*35ffd701SAndroid Build Coastguard Worker
58*35ffd701SAndroid Build Coastguard Worker if((pTexInfo->TileMode >= GMM_TILE_MODES) ||
59*35ffd701SAndroid Build Coastguard Worker (pTexInfo->TileMode < TILE_NONE))
60*35ffd701SAndroid Build Coastguard Worker {
61*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF(0, "Invalid parameter!");
62*35ffd701SAndroid Build Coastguard Worker return GMM_ERROR;
63*35ffd701SAndroid Build Coastguard Worker }
64*35ffd701SAndroid Build Coastguard Worker
65*35ffd701SAndroid Build Coastguard Worker // Retrieve offset info at pReqInfo->MipLevel
66*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->ReqLock)
67*35ffd701SAndroid Build Coastguard Worker {
68*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->ReqRender)
69*35ffd701SAndroid Build Coastguard Worker {
70*35ffd701SAndroid Build Coastguard Worker pReqInfo->ReqRender = 0;
71*35ffd701SAndroid Build Coastguard Worker RestoreRenderReq = true;
72*35ffd701SAndroid Build Coastguard Worker }
73*35ffd701SAndroid Build Coastguard Worker
74*35ffd701SAndroid Build Coastguard Worker if(pTextureCalc->GetTexLockOffset(pTexInfo, pReqInfo) != GMM_SUCCESS)
75*35ffd701SAndroid Build Coastguard Worker {
76*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF(0, "ReqLock failed!");
77*35ffd701SAndroid Build Coastguard Worker Status = GMM_ERROR;
78*35ffd701SAndroid Build Coastguard Worker }
79*35ffd701SAndroid Build Coastguard Worker }
80*35ffd701SAndroid Build Coastguard Worker
81*35ffd701SAndroid Build Coastguard Worker if(RestoreRenderReq == true)
82*35ffd701SAndroid Build Coastguard Worker pReqInfo->ReqRender = 1;
83*35ffd701SAndroid Build Coastguard Worker
84*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->ReqLock)
85*35ffd701SAndroid Build Coastguard Worker {
86*35ffd701SAndroid Build Coastguard Worker pReqInfo->ReqLock = 0;
87*35ffd701SAndroid Build Coastguard Worker RestoreLockReq = 1;
88*35ffd701SAndroid Build Coastguard Worker }
89*35ffd701SAndroid Build Coastguard Worker
90*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->ReqRender)
91*35ffd701SAndroid Build Coastguard Worker {
92*35ffd701SAndroid Build Coastguard Worker if(pTextureCalc->GetTexRenderOffset(pTexInfo, pReqInfo) != GMM_SUCCESS)
93*35ffd701SAndroid Build Coastguard Worker {
94*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF(0, "ReqRender failed!");
95*35ffd701SAndroid Build Coastguard Worker Status = GMM_ERROR;
96*35ffd701SAndroid Build Coastguard Worker }
97*35ffd701SAndroid Build Coastguard Worker }
98*35ffd701SAndroid Build Coastguard Worker
99*35ffd701SAndroid Build Coastguard Worker if(RestoreLockReq)
100*35ffd701SAndroid Build Coastguard Worker {
101*35ffd701SAndroid Build Coastguard Worker pReqInfo->ReqLock = 1;
102*35ffd701SAndroid Build Coastguard Worker }
103*35ffd701SAndroid Build Coastguard Worker
104*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->ReqStdLayout)
105*35ffd701SAndroid Build Coastguard Worker {
106*35ffd701SAndroid Build Coastguard Worker if(pTextureCalc->GetTexStdLayoutOffset(pTexInfo, pReqInfo) != GMM_SUCCESS)
107*35ffd701SAndroid Build Coastguard Worker {
108*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF(0, "ReqStdLayout failed!");
109*35ffd701SAndroid Build Coastguard Worker Status = GMM_ERROR;
110*35ffd701SAndroid Build Coastguard Worker }
111*35ffd701SAndroid Build Coastguard Worker }
112*35ffd701SAndroid Build Coastguard Worker
113*35ffd701SAndroid Build Coastguard Worker GMM_DPF_EXIT;
114*35ffd701SAndroid Build Coastguard Worker return Status;
115*35ffd701SAndroid Build Coastguard Worker }
116*35ffd701SAndroid Build Coastguard Worker
117*35ffd701SAndroid Build Coastguard Worker
118*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
119*35ffd701SAndroid Build Coastguard Worker /// Calculates StdLayout offsets and related pitches of
120*35ffd701SAndroid Build Coastguard Worker /// subresource..
121*35ffd701SAndroid Build Coastguard Worker ///
122*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
123*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO to store offset info
124*35ffd701SAndroid Build Coastguard Worker ///
125*35ffd701SAndroid Build Coastguard Worker /// @return ::GMM_STATUS
126*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
GetTexStdLayoutOffset(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo)127*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmLib::GmmTextureCalc::GetTexStdLayoutOffset(GMM_TEXTURE_INFO * pTexInfo,
128*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo)
129*35ffd701SAndroid Build Coastguard Worker {
130*35ffd701SAndroid Build Coastguard Worker uint32_t ReqArrayIndex;
131*35ffd701SAndroid Build Coastguard Worker bool NeedSurfaceSize = false;
132*35ffd701SAndroid Build Coastguard Worker
133*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(pTexInfo);
134*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(GMM_IS_64KB_TILE(pTexInfo->Flags) || pTexInfo->Flags.Info.TiledYf);
135*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(
136*35ffd701SAndroid Build Coastguard Worker (pTexInfo->Type == RESOURCE_2D) ||
137*35ffd701SAndroid Build Coastguard Worker (pTexInfo->Type == RESOURCE_3D) ||
138*35ffd701SAndroid Build Coastguard Worker (pTexInfo->Type == RESOURCE_CUBE));
139*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(GmmIsPlanar(pTexInfo->Format) == false); // Planar not support
140*35ffd701SAndroid Build Coastguard Worker
141*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->StdLayout.Offset == -1) // Special Req for Surface Size
142*35ffd701SAndroid Build Coastguard Worker {
143*35ffd701SAndroid Build Coastguard Worker NeedSurfaceSize = true;
144*35ffd701SAndroid Build Coastguard Worker ReqArrayIndex = // TODO(Medium): Add planar support.
145*35ffd701SAndroid Build Coastguard Worker (pTexInfo->ArraySize * ((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1));
146*35ffd701SAndroid Build Coastguard Worker }
147*35ffd701SAndroid Build Coastguard Worker else
148*35ffd701SAndroid Build Coastguard Worker {
149*35ffd701SAndroid Build Coastguard Worker ReqArrayIndex =
150*35ffd701SAndroid Build Coastguard Worker (pReqInfo->ArrayIndex * ((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1));
151*35ffd701SAndroid Build Coastguard Worker }
152*35ffd701SAndroid Build Coastguard Worker
153*35ffd701SAndroid Build Coastguard Worker {
154*35ffd701SAndroid Build Coastguard Worker uint32_t TileSize = 0;
155*35ffd701SAndroid Build Coastguard Worker
156*35ffd701SAndroid Build Coastguard Worker // TileYs (64) and TileYf (4)
157*35ffd701SAndroid Build Coastguard Worker if(GMM_IS_64KB_TILE(pTexInfo->Flags))
158*35ffd701SAndroid Build Coastguard Worker {
159*35ffd701SAndroid Build Coastguard Worker TileSize = GMM_KBYTE(64);
160*35ffd701SAndroid Build Coastguard Worker }
161*35ffd701SAndroid Build Coastguard Worker else if(GMM_IS_4KB_TILE(pTexInfo->Flags))
162*35ffd701SAndroid Build Coastguard Worker {
163*35ffd701SAndroid Build Coastguard Worker TileSize = GMM_KBYTE(4);
164*35ffd701SAndroid Build Coastguard Worker }
165*35ffd701SAndroid Build Coastguard Worker
166*35ffd701SAndroid Build Coastguard Worker const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
167*35ffd701SAndroid Build Coastguard Worker uint32_t BytesPerElement = pTexInfo->BitsPerPixel / CHAR_BIT;
168*35ffd701SAndroid Build Coastguard Worker GMM_TILE_MODE TileMode = pTexInfo->TileMode;
169*35ffd701SAndroid Build Coastguard Worker struct
170*35ffd701SAndroid Build Coastguard Worker {
171*35ffd701SAndroid Build Coastguard Worker uint32_t Width, Height, Depth;
172*35ffd701SAndroid Build Coastguard Worker } Element, Tile;
173*35ffd701SAndroid Build Coastguard Worker
174*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(TileMode < GMM_TILE_MODES);
175*35ffd701SAndroid Build Coastguard Worker
176*35ffd701SAndroid Build Coastguard Worker GetCompressionBlockDimensions(
177*35ffd701SAndroid Build Coastguard Worker pTexInfo->Format,
178*35ffd701SAndroid Build Coastguard Worker &Element.Width,
179*35ffd701SAndroid Build Coastguard Worker &Element.Height,
180*35ffd701SAndroid Build Coastguard Worker &Element.Depth);
181*35ffd701SAndroid Build Coastguard Worker
182*35ffd701SAndroid Build Coastguard Worker Tile.Width =
183*35ffd701SAndroid Build Coastguard Worker (pPlatform->TileInfo[TileMode].LogicalTileWidth / BytesPerElement) *
184*35ffd701SAndroid Build Coastguard Worker Element.Width;
185*35ffd701SAndroid Build Coastguard Worker
186*35ffd701SAndroid Build Coastguard Worker Tile.Height =
187*35ffd701SAndroid Build Coastguard Worker pPlatform->TileInfo[TileMode].LogicalTileHeight *
188*35ffd701SAndroid Build Coastguard Worker Element.Height;
189*35ffd701SAndroid Build Coastguard Worker
190*35ffd701SAndroid Build Coastguard Worker Tile.Depth =
191*35ffd701SAndroid Build Coastguard Worker pPlatform->TileInfo[TileMode].LogicalTileDepth *
192*35ffd701SAndroid Build Coastguard Worker Element.Depth;
193*35ffd701SAndroid Build Coastguard Worker
194*35ffd701SAndroid Build Coastguard Worker {
195*35ffd701SAndroid Build Coastguard Worker GMM_GFX_ADDRESS TargetLodOffset = 0;
196*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T PrevMipSize = 0;
197*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T SliceOffset = 0;
198*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T SlicePitch = 0;
199*35ffd701SAndroid Build Coastguard Worker uint32_t Lod;
200*35ffd701SAndroid Build Coastguard Worker uint32_t EffectiveMaxLod =
201*35ffd701SAndroid Build Coastguard Worker (ReqArrayIndex == 0) ?
202*35ffd701SAndroid Build Coastguard Worker pReqInfo->MipLevel :
203*35ffd701SAndroid Build Coastguard Worker GFX_MIN(pTexInfo->MaxLod, pTexInfo->Alignment.MipTailStartLod);
204*35ffd701SAndroid Build Coastguard Worker
205*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.Offset = 0;
206*35ffd701SAndroid Build Coastguard Worker for(Lod = 0; Lod <= EffectiveMaxLod; Lod++)
207*35ffd701SAndroid Build Coastguard Worker {
208*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T MipWidth = GmmTexGetMipWidth(pTexInfo, Lod);
209*35ffd701SAndroid Build Coastguard Worker uint32_t MipHeight = GmmTexGetMipHeight(pTexInfo, Lod);
210*35ffd701SAndroid Build Coastguard Worker uint32_t MipDepth = GmmTexGetMipDepth(pTexInfo, Lod);
211*35ffd701SAndroid Build Coastguard Worker
212*35ffd701SAndroid Build Coastguard Worker uint32_t MipCols = GFX_ULONG_CAST(
213*35ffd701SAndroid Build Coastguard Worker GFX_CEIL_DIV(
214*35ffd701SAndroid Build Coastguard Worker MipWidth,
215*35ffd701SAndroid Build Coastguard Worker Tile.Width));
216*35ffd701SAndroid Build Coastguard Worker uint32_t MipRows =
217*35ffd701SAndroid Build Coastguard Worker GFX_CEIL_DIV(
218*35ffd701SAndroid Build Coastguard Worker MipHeight,
219*35ffd701SAndroid Build Coastguard Worker Tile.Height);
220*35ffd701SAndroid Build Coastguard Worker uint32_t MipDepthTiles =
221*35ffd701SAndroid Build Coastguard Worker GFX_CEIL_DIV(
222*35ffd701SAndroid Build Coastguard Worker MipDepth,
223*35ffd701SAndroid Build Coastguard Worker Tile.Depth);
224*35ffd701SAndroid Build Coastguard Worker uint32_t RowPitch = MipCols * TileSize; // Bytes from one tile row to the next.
225*35ffd701SAndroid Build Coastguard Worker uint32_t DepthPitch = RowPitch * MipRows; // Bytes from one depth slice of tiles to the next.
226*35ffd701SAndroid Build Coastguard Worker
227*35ffd701SAndroid Build Coastguard Worker if(Lod <= pTexInfo->Alignment.MipTailStartLod)
228*35ffd701SAndroid Build Coastguard Worker {
229*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.Offset += PrevMipSize;
230*35ffd701SAndroid Build Coastguard Worker }
231*35ffd701SAndroid Build Coastguard Worker
232*35ffd701SAndroid Build Coastguard Worker if(Lod == pReqInfo->MipLevel)
233*35ffd701SAndroid Build Coastguard Worker {
234*35ffd701SAndroid Build Coastguard Worker TargetLodOffset = pReqInfo->StdLayout.Offset;
235*35ffd701SAndroid Build Coastguard Worker
236*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.TileRowPitch = RowPitch;
237*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.TileDepthPitch = DepthPitch;
238*35ffd701SAndroid Build Coastguard Worker }
239*35ffd701SAndroid Build Coastguard Worker
240*35ffd701SAndroid Build Coastguard Worker PrevMipSize = (GMM_GFX_SIZE_T)DepthPitch * MipDepthTiles;
241*35ffd701SAndroid Build Coastguard Worker SlicePitch += DepthPitch;
242*35ffd701SAndroid Build Coastguard Worker }
243*35ffd701SAndroid Build Coastguard Worker
244*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->Slice > 0)
245*35ffd701SAndroid Build Coastguard Worker {
246*35ffd701SAndroid Build Coastguard Worker SliceOffset = SlicePitch * pReqInfo->Slice;
247*35ffd701SAndroid Build Coastguard Worker }
248*35ffd701SAndroid Build Coastguard Worker
249*35ffd701SAndroid Build Coastguard Worker if(!NeedSurfaceSize && pReqInfo->MipLevel >= pTexInfo->Alignment.MipTailStartLod)
250*35ffd701SAndroid Build Coastguard Worker {
251*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.Offset += (ReqArrayIndex * (pReqInfo->StdLayout.Offset + PrevMipSize)) +
252*35ffd701SAndroid Build Coastguard Worker GetMipTailByteOffset(pTexInfo, pReqInfo->MipLevel);
253*35ffd701SAndroid Build Coastguard Worker }
254*35ffd701SAndroid Build Coastguard Worker else
255*35ffd701SAndroid Build Coastguard Worker {
256*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.Offset = ReqArrayIndex * (pReqInfo->StdLayout.Offset + PrevMipSize) +
257*35ffd701SAndroid Build Coastguard Worker TargetLodOffset;
258*35ffd701SAndroid Build Coastguard Worker }
259*35ffd701SAndroid Build Coastguard Worker
260*35ffd701SAndroid Build Coastguard Worker pReqInfo->StdLayout.Offset += SliceOffset;
261*35ffd701SAndroid Build Coastguard Worker }
262*35ffd701SAndroid Build Coastguard Worker }
263*35ffd701SAndroid Build Coastguard Worker
264*35ffd701SAndroid Build Coastguard Worker return GMM_SUCCESS;
265*35ffd701SAndroid Build Coastguard Worker }
266*35ffd701SAndroid Build Coastguard Worker
267*35ffd701SAndroid Build Coastguard Worker
268*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
269*35ffd701SAndroid Build Coastguard Worker /// Calculates offset address of a sub resource(i.e. Mip Map, Cube face, volume texture)
270*35ffd701SAndroid Build Coastguard Worker ///
271*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
272*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO to store offset info
273*35ffd701SAndroid Build Coastguard Worker ///
274*35ffd701SAndroid Build Coastguard Worker /// @return ::GMM_STATUS
275*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
GetTexLockOffset(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo)276*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmLib::GmmTextureCalc::GetTexLockOffset(GMM_TEXTURE_INFO * pTexInfo,
277*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo)
278*35ffd701SAndroid Build Coastguard Worker {
279*35ffd701SAndroid Build Coastguard Worker GMM_STATUS Result = GMM_SUCCESS;
280*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T AddressOffset;
281*35ffd701SAndroid Build Coastguard Worker uint32_t Pitch, Slice;
282*35ffd701SAndroid Build Coastguard Worker uint32_t MipHeight, MipWidth, MipLevel;
283*35ffd701SAndroid Build Coastguard Worker uint32_t NumberOfMipsInSingleRow, SliceRow;
284*35ffd701SAndroid Build Coastguard Worker
285*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
286*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
287*35ffd701SAndroid Build Coastguard Worker
288*35ffd701SAndroid Build Coastguard Worker const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
289*35ffd701SAndroid Build Coastguard Worker
290*35ffd701SAndroid Build Coastguard Worker // set default value
291*35ffd701SAndroid Build Coastguard Worker AddressOffset = 0;
292*35ffd701SAndroid Build Coastguard Worker Pitch = GFX_ULONG_CAST(pTexInfo->Pitch);
293*35ffd701SAndroid Build Coastguard Worker MipLevel = pReqInfo->MipLevel;
294*35ffd701SAndroid Build Coastguard Worker Slice = pReqInfo->Slice;
295*35ffd701SAndroid Build Coastguard Worker
296*35ffd701SAndroid Build Coastguard Worker if(GmmIsPlanar(pTexInfo->Format))
297*35ffd701SAndroid Build Coastguard Worker {
298*35ffd701SAndroid Build Coastguard Worker AddressOffset = GetMipMapByteAddress(pTexInfo, pReqInfo);
299*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Offset64 = AddressOffset;
300*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Pitch = Pitch;
301*35ffd701SAndroid Build Coastguard Worker
302*35ffd701SAndroid Build Coastguard Worker // Adjust returned pitch for non-uniform-pitch U/V queries...
303*35ffd701SAndroid Build Coastguard Worker if((pReqInfo->Plane == GMM_PLANE_U) ||
304*35ffd701SAndroid Build Coastguard Worker (pReqInfo->Plane == GMM_PLANE_V))
305*35ffd701SAndroid Build Coastguard Worker {
306*35ffd701SAndroid Build Coastguard Worker switch(pTexInfo->Format)
307*35ffd701SAndroid Build Coastguard Worker {
308*35ffd701SAndroid Build Coastguard Worker case GMM_FORMAT_I420:
309*35ffd701SAndroid Build Coastguard Worker case GMM_FORMAT_IYUV:
310*35ffd701SAndroid Build Coastguard Worker case GMM_FORMAT_YV12:
311*35ffd701SAndroid Build Coastguard Worker case GMM_FORMAT_NV11:
312*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Pitch /= 2;
313*35ffd701SAndroid Build Coastguard Worker break;
314*35ffd701SAndroid Build Coastguard Worker case GMM_FORMAT_YVU9:
315*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Pitch /= 4;
316*35ffd701SAndroid Build Coastguard Worker break;
317*35ffd701SAndroid Build Coastguard Worker default:
318*35ffd701SAndroid Build Coastguard Worker //Cool--Constant pitch across all planes.
319*35ffd701SAndroid Build Coastguard Worker break;
320*35ffd701SAndroid Build Coastguard Worker }
321*35ffd701SAndroid Build Coastguard Worker }
322*35ffd701SAndroid Build Coastguard Worker
323*35ffd701SAndroid Build Coastguard Worker return Result;
324*35ffd701SAndroid Build Coastguard Worker }
325*35ffd701SAndroid Build Coastguard Worker
326*35ffd701SAndroid Build Coastguard Worker switch(pTexInfo->Type)
327*35ffd701SAndroid Build Coastguard Worker {
328*35ffd701SAndroid Build Coastguard Worker case RESOURCE_3D:
329*35ffd701SAndroid Build Coastguard Worker {
330*35ffd701SAndroid Build Coastguard Worker if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE)
331*35ffd701SAndroid Build Coastguard Worker {
332*35ffd701SAndroid Build Coastguard Worker AddressOffset = GFX_ULONG_CAST(GetMipMapByteAddress(pTexInfo, pReqInfo));
333*35ffd701SAndroid Build Coastguard Worker
334*35ffd701SAndroid Build Coastguard Worker // Bytes from one slice to the next...
335*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Gen9PlusSlicePitch = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock);
336*35ffd701SAndroid Build Coastguard Worker }
337*35ffd701SAndroid Build Coastguard Worker else
338*35ffd701SAndroid Build Coastguard Worker {
339*35ffd701SAndroid Build Coastguard Worker MipHeight = pTexInfo->BaseHeight >> MipLevel;
340*35ffd701SAndroid Build Coastguard Worker MipWidth = GFX_ULONG_CAST(pTexInfo->BaseWidth) >> MipLevel;
341*35ffd701SAndroid Build Coastguard Worker
342*35ffd701SAndroid Build Coastguard Worker AlignTexHeightWidth(pTexInfo, &MipHeight, &MipWidth);
343*35ffd701SAndroid Build Coastguard Worker
344*35ffd701SAndroid Build Coastguard Worker // See how many mip can fit in one row
345*35ffd701SAndroid Build Coastguard Worker NumberOfMipsInSingleRow = GFX_2_TO_POWER_OF(MipLevel);
346*35ffd701SAndroid Build Coastguard Worker
347*35ffd701SAndroid Build Coastguard Worker SliceRow = Slice / NumberOfMipsInSingleRow;
348*35ffd701SAndroid Build Coastguard Worker
349*35ffd701SAndroid Build Coastguard Worker // get the base address + Slice pitch
350*35ffd701SAndroid Build Coastguard Worker AddressOffset = pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[MipLevel];
351*35ffd701SAndroid Build Coastguard Worker
352*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Mip0SlicePitch = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Texture3DOffsetInfo.Mip0SlicePitch);
353*35ffd701SAndroid Build Coastguard Worker
354*35ffd701SAndroid Build Coastguard Worker // Actual address is offset based on requested slice
355*35ffd701SAndroid Build Coastguard Worker AddressOffset += (GMM_GFX_SIZE_T)SliceRow * MipHeight * Pitch;
356*35ffd701SAndroid Build Coastguard Worker
357*35ffd701SAndroid Build Coastguard Worker // Get to particular slice
358*35ffd701SAndroid Build Coastguard Worker if(Slice % NumberOfMipsInSingleRow)
359*35ffd701SAndroid Build Coastguard Worker {
360*35ffd701SAndroid Build Coastguard Worker AddressOffset += (((GMM_GFX_SIZE_T)(Slice % NumberOfMipsInSingleRow) *
361*35ffd701SAndroid Build Coastguard Worker MipWidth * pTexInfo->BitsPerPixel) >>
362*35ffd701SAndroid Build Coastguard Worker 3);
363*35ffd701SAndroid Build Coastguard Worker }
364*35ffd701SAndroid Build Coastguard Worker }
365*35ffd701SAndroid Build Coastguard Worker break;
366*35ffd701SAndroid Build Coastguard Worker }
367*35ffd701SAndroid Build Coastguard Worker case RESOURCE_CUBE:
368*35ffd701SAndroid Build Coastguard Worker case RESOURCE_2D:
369*35ffd701SAndroid Build Coastguard Worker case RESOURCE_1D:
370*35ffd701SAndroid Build Coastguard Worker {
371*35ffd701SAndroid Build Coastguard Worker AddressOffset = GetMipMapByteAddress(pTexInfo, pReqInfo);
372*35ffd701SAndroid Build Coastguard Worker break;
373*35ffd701SAndroid Build Coastguard Worker }
374*35ffd701SAndroid Build Coastguard Worker default:
375*35ffd701SAndroid Build Coastguard Worker { // These resources dont' have multiple levels of detail
376*35ffd701SAndroid Build Coastguard Worker AddressOffset = 0;
377*35ffd701SAndroid Build Coastguard Worker break;
378*35ffd701SAndroid Build Coastguard Worker }
379*35ffd701SAndroid Build Coastguard Worker }
380*35ffd701SAndroid Build Coastguard Worker
381*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Offset64 = AddressOffset;
382*35ffd701SAndroid Build Coastguard Worker pReqInfo->Lock.Pitch = Pitch;
383*35ffd701SAndroid Build Coastguard Worker
384*35ffd701SAndroid Build Coastguard Worker return Result;
385*35ffd701SAndroid Build Coastguard Worker }
386*35ffd701SAndroid Build Coastguard Worker
387*35ffd701SAndroid Build Coastguard Worker
388*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
389*35ffd701SAndroid Build Coastguard Worker /// Function used to align width and height of texture so that it satisfy our HW
390*35ffd701SAndroid Build Coastguard Worker /// restriction
391*35ffd701SAndroid Build Coastguard Worker ///
392*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
393*35ffd701SAndroid Build Coastguard Worker /// @param[in] pHeight: ptr to height of mip
394*35ffd701SAndroid Build Coastguard Worker /// @param[in] pWidth: ptr to width of mip
395*35ffd701SAndroid Build Coastguard Worker ///
396*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
AlignTexHeightWidth(GMM_TEXTURE_INFO * pTexInfo,uint32_t * pHeight,uint32_t * pWidth)397*35ffd701SAndroid Build Coastguard Worker void GmmLib::GmmTextureCalc::AlignTexHeightWidth(GMM_TEXTURE_INFO *pTexInfo,
398*35ffd701SAndroid Build Coastguard Worker uint32_t * pHeight,
399*35ffd701SAndroid Build Coastguard Worker uint32_t * pWidth)
400*35ffd701SAndroid Build Coastguard Worker {
401*35ffd701SAndroid Build Coastguard Worker uint32_t MipWidth = 0;
402*35ffd701SAndroid Build Coastguard Worker uint32_t MipHeight = 0;
403*35ffd701SAndroid Build Coastguard Worker uint32_t UnitAlignHeight = 0;
404*35ffd701SAndroid Build Coastguard Worker uint32_t UnitAlignWidth = 0;
405*35ffd701SAndroid Build Coastguard Worker
406*35ffd701SAndroid Build Coastguard Worker uint8_t Compress = 0;
407*35ffd701SAndroid Build Coastguard Worker
408*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pTexInfo, VOIDRETURN);
409*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pWidth, VOIDRETURN);
410*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pHeight, VOIDRETURN);
411*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
412*35ffd701SAndroid Build Coastguard Worker
413*35ffd701SAndroid Build Coastguard Worker MipWidth = *pWidth;
414*35ffd701SAndroid Build Coastguard Worker MipHeight = *pHeight;
415*35ffd701SAndroid Build Coastguard Worker
416*35ffd701SAndroid Build Coastguard Worker UnitAlignWidth = pTexInfo->Alignment.HAlign;
417*35ffd701SAndroid Build Coastguard Worker UnitAlignHeight = pTexInfo->Alignment.VAlign;
418*35ffd701SAndroid Build Coastguard Worker Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
419*35ffd701SAndroid Build Coastguard Worker
420*35ffd701SAndroid Build Coastguard Worker MipWidth = GFX_MAX(MipWidth, UnitAlignWidth);
421*35ffd701SAndroid Build Coastguard Worker MipHeight = GFX_MAX(MipHeight, UnitAlignHeight);
422*35ffd701SAndroid Build Coastguard Worker
423*35ffd701SAndroid Build Coastguard Worker MipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
424*35ffd701SAndroid Build Coastguard Worker MipHeight = GFX_ALIGN(MipHeight, UnitAlignHeight);
425*35ffd701SAndroid Build Coastguard Worker
426*35ffd701SAndroid Build Coastguard Worker if(Compress)
427*35ffd701SAndroid Build Coastguard Worker {
428*35ffd701SAndroid Build Coastguard Worker uint32_t CompressHeight, CompressWidth, CompressDepth;
429*35ffd701SAndroid Build Coastguard Worker GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
430*35ffd701SAndroid Build Coastguard Worker MipWidth /= CompressWidth;
431*35ffd701SAndroid Build Coastguard Worker MipHeight /= CompressHeight;
432*35ffd701SAndroid Build Coastguard Worker }
433*35ffd701SAndroid Build Coastguard Worker else if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
434*35ffd701SAndroid Build Coastguard Worker {
435*35ffd701SAndroid Build Coastguard Worker MipWidth *= 2;
436*35ffd701SAndroid Build Coastguard Worker MipHeight /= 2;
437*35ffd701SAndroid Build Coastguard Worker }
438*35ffd701SAndroid Build Coastguard Worker
439*35ffd701SAndroid Build Coastguard Worker *pHeight = MipHeight;
440*35ffd701SAndroid Build Coastguard Worker *pWidth = MipWidth;
441*35ffd701SAndroid Build Coastguard Worker }
442*35ffd701SAndroid Build Coastguard Worker
443*35ffd701SAndroid Build Coastguard Worker
444*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
445*35ffd701SAndroid Build Coastguard Worker /// Function used to calculate the render aligned offset of a given surface
446*35ffd701SAndroid Build Coastguard Worker ///
447*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
448*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
449*35ffd701SAndroid Build Coastguard Worker ///
450*35ffd701SAndroid Build Coastguard Worker /// @return ::GMM_STATUS
451*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
GetTexRenderOffset(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo)452*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmLib::GmmTextureCalc::GetTexRenderOffset(GMM_TEXTURE_INFO * pTexInfo,
453*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo)
454*35ffd701SAndroid Build Coastguard Worker {
455*35ffd701SAndroid Build Coastguard Worker
456*35ffd701SAndroid Build Coastguard Worker const GMM_TILE_INFO * pTileInfo = NULL;
457*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T AddressOffset = 0;
458*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T RenderAlignOffset = 0;
459*35ffd701SAndroid Build Coastguard Worker uint32_t OffsetX = 0;
460*35ffd701SAndroid Build Coastguard Worker uint32_t OffsetY = 0;
461*35ffd701SAndroid Build Coastguard Worker uint32_t OffsetZ = 0;
462*35ffd701SAndroid Build Coastguard Worker const GMM_PLATFORM_INFO *pPlatform = NULL;
463*35ffd701SAndroid Build Coastguard Worker
464*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
465*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
466*35ffd701SAndroid Build Coastguard Worker
467*35ffd701SAndroid Build Coastguard Worker pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
468*35ffd701SAndroid Build Coastguard Worker pTileInfo = &pPlatform->TileInfo[pTexInfo->TileMode];
469*35ffd701SAndroid Build Coastguard Worker AddressOffset = GetMipMapByteAddress(pTexInfo, pReqInfo);
470*35ffd701SAndroid Build Coastguard Worker
471*35ffd701SAndroid Build Coastguard Worker if(GMM_IS_TILED(*pTileInfo))
472*35ffd701SAndroid Build Coastguard Worker {
473*35ffd701SAndroid Build Coastguard Worker uint32_t TileAlignedOffsetX = 0;
474*35ffd701SAndroid Build Coastguard Worker uint32_t TileAlignedOffsetY = 0;
475*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T MipTailByteOffset = 0;
476*35ffd701SAndroid Build Coastguard Worker
477*35ffd701SAndroid Build Coastguard Worker //--- Compute Tile-Aligned Offset, and Corresponding X/Y Offsets -------
478*35ffd701SAndroid Build Coastguard Worker // Render/Tiled-Aligned offsets and corresponding X/Y offsets are used
479*35ffd701SAndroid Build Coastguard Worker // to program the Surface Base Address and X/Y Offset fields of a
480*35ffd701SAndroid Build Coastguard Worker // SURFACE_STATE. For a given subresource, the tiled-aligned offset
481*35ffd701SAndroid Build Coastguard Worker // addresses the tile containing the base of the subresource; the X/Y
482*35ffd701SAndroid Build Coastguard Worker // offsets then give the additional offsets into the tile of the
483*35ffd701SAndroid Build Coastguard Worker // subresource base. (Though in SURFACE_STATE, X Offset is specified in
484*35ffd701SAndroid Build Coastguard Worker // pixels, this function will return the X Offset in bytes. Y Offset is
485*35ffd701SAndroid Build Coastguard Worker // in pixel rows.)
486*35ffd701SAndroid Build Coastguard Worker
487*35ffd701SAndroid Build Coastguard Worker if((pTexInfo->Flags.Info.TiledYf || GMM_IS_64KB_TILE(pTexInfo->Flags)) &&
488*35ffd701SAndroid Build Coastguard Worker (pReqInfo->MipLevel >= pTexInfo->Alignment.MipTailStartLod))
489*35ffd701SAndroid Build Coastguard Worker {
490*35ffd701SAndroid Build Coastguard Worker MipTailByteOffset = GetMipTailByteOffset(pTexInfo, pReqInfo->MipLevel);
491*35ffd701SAndroid Build Coastguard Worker
492*35ffd701SAndroid Build Coastguard Worker // For MipTail, Offset is really with respect to start of MipTail,
493*35ffd701SAndroid Build Coastguard Worker // so taking out individual Mipoffset within miptail region to get correct Tile aligned offset.
494*35ffd701SAndroid Build Coastguard Worker AddressOffset -= MipTailByteOffset;
495*35ffd701SAndroid Build Coastguard Worker }
496*35ffd701SAndroid Build Coastguard Worker
497*35ffd701SAndroid Build Coastguard Worker if(!pTexInfo->Flags.Info.RedecribedPlanes)
498*35ffd701SAndroid Build Coastguard Worker {
499*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T Pitch = pTexInfo->Pitch;
500*35ffd701SAndroid Build Coastguard Worker if(!pTexInfo->Pitch)
501*35ffd701SAndroid Build Coastguard Worker {
502*35ffd701SAndroid Build Coastguard Worker // If no pitch exists, but the surface is still marked as tiled, then it is a 1D TileYf/Ys surface.
503*35ffd701SAndroid Build Coastguard Worker // Technically no pitch exists for 1D surfaces, but we will fake it to make calculations work below.
504*35ffd701SAndroid Build Coastguard Worker // Since 1D surfaces only have an X-dimension, this Pitch calculation is only used for OffsetX calculation.
505*35ffd701SAndroid Build Coastguard Worker Pitch = pTexInfo->Size;
506*35ffd701SAndroid Build Coastguard Worker }
507*35ffd701SAndroid Build Coastguard Worker
508*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
509*35ffd701SAndroid Build Coastguard Worker {
510*35ffd701SAndroid Build Coastguard Worker OffsetX = GFX_ULONG_CAST(AddressOffset % Pitch);
511*35ffd701SAndroid Build Coastguard Worker TileAlignedOffsetX = GFX_ALIGN_FLOOR(OffsetX, pTileInfo->LogicalTileWidth / 2);
512*35ffd701SAndroid Build Coastguard Worker OffsetX -= TileAlignedOffsetX;
513*35ffd701SAndroid Build Coastguard Worker }
514*35ffd701SAndroid Build Coastguard Worker else
515*35ffd701SAndroid Build Coastguard Worker {
516*35ffd701SAndroid Build Coastguard Worker OffsetX = GFX_ULONG_CAST(AddressOffset % Pitch);
517*35ffd701SAndroid Build Coastguard Worker TileAlignedOffsetX = GFX_ALIGN_FLOOR(OffsetX, pTileInfo->LogicalTileWidth);
518*35ffd701SAndroid Build Coastguard Worker OffsetX -= TileAlignedOffsetX;
519*35ffd701SAndroid Build Coastguard Worker }
520*35ffd701SAndroid Build Coastguard Worker
521*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->Pitch)
522*35ffd701SAndroid Build Coastguard Worker {
523*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
524*35ffd701SAndroid Build Coastguard Worker {
525*35ffd701SAndroid Build Coastguard Worker //Expt: YOffset ignore row-interleave -- verify both 2d/3d mips
526*35ffd701SAndroid Build Coastguard Worker OffsetY = GFX_ULONG_CAST(AddressOffset / pTexInfo->Pitch);
527*35ffd701SAndroid Build Coastguard Worker OffsetY *= 2;
528*35ffd701SAndroid Build Coastguard Worker TileAlignedOffsetY = GFX_ALIGN_FLOOR(OffsetY, pTileInfo->LogicalTileHeight * 2 * pTileInfo->LogicalTileDepth);
529*35ffd701SAndroid Build Coastguard Worker OffsetY -= TileAlignedOffsetY;
530*35ffd701SAndroid Build Coastguard Worker TileAlignedOffsetY /= 2;
531*35ffd701SAndroid Build Coastguard Worker }
532*35ffd701SAndroid Build Coastguard Worker else
533*35ffd701SAndroid Build Coastguard Worker {
534*35ffd701SAndroid Build Coastguard Worker OffsetY = GFX_ULONG_CAST(AddressOffset / pTexInfo->Pitch);
535*35ffd701SAndroid Build Coastguard Worker TileAlignedOffsetY = GFX_ALIGN_FLOOR(OffsetY, pTileInfo->LogicalTileHeight * pTileInfo->LogicalTileDepth);
536*35ffd701SAndroid Build Coastguard Worker OffsetY -= TileAlignedOffsetY;
537*35ffd701SAndroid Build Coastguard Worker }
538*35ffd701SAndroid Build Coastguard Worker }
539*35ffd701SAndroid Build Coastguard Worker
540*35ffd701SAndroid Build Coastguard Worker RenderAlignOffset =
541*35ffd701SAndroid Build Coastguard Worker TileAlignedOffsetY * pTexInfo->Pitch +
542*35ffd701SAndroid Build Coastguard Worker (TileAlignedOffsetX / pTileInfo->LogicalTileWidth) * pTileInfo->LogicalSize;
543*35ffd701SAndroid Build Coastguard Worker
544*35ffd701SAndroid Build Coastguard Worker // For Gen9+, Miptail Lods should be reported in a way that
545*35ffd701SAndroid Build Coastguard Worker // - Base Address equals tile-aligned "Miptail start address"
546*35ffd701SAndroid Build Coastguard Worker // - OffsetX equals to offset (in bytes) from "Miptail start Lod" to "current Lod" in geometric X direction
547*35ffd701SAndroid Build Coastguard Worker // - OffsetY and OffsetZ are their pixel distance from "Miptail start Lod" to "current Lod" in geometric Y, Z directions
548*35ffd701SAndroid Build Coastguard Worker // Note: only Tile Yf and TileYs have Miptails and their Mips are always "tile aligned"
549*35ffd701SAndroid Build Coastguard Worker
550*35ffd701SAndroid Build Coastguard Worker if((pTexInfo->Flags.Info.TiledYf || GMM_IS_64KB_TILE(pTexInfo->Flags)) &&
551*35ffd701SAndroid Build Coastguard Worker (pReqInfo->MipLevel >= pTexInfo->Alignment.MipTailStartLod) &&
552*35ffd701SAndroid Build Coastguard Worker // Planar surfaces do not support MIPs
553*35ffd701SAndroid Build Coastguard Worker !GmmIsPlanar(pTexInfo->Format))
554*35ffd701SAndroid Build Coastguard Worker {
555*35ffd701SAndroid Build Coastguard Worker GetMipTailGeometryOffset(pTexInfo, pReqInfo->MipLevel, &OffsetX, &OffsetY, &OffsetZ);
556*35ffd701SAndroid Build Coastguard Worker }
557*35ffd701SAndroid Build Coastguard Worker }
558*35ffd701SAndroid Build Coastguard Worker else
559*35ffd701SAndroid Build Coastguard Worker {
560*35ffd701SAndroid Build Coastguard Worker // Std swizzled and UV packed planes begin at tile-aligned
561*35ffd701SAndroid Build Coastguard Worker // offsets and do not support MIPs, so no adjustment is needed
562*35ffd701SAndroid Build Coastguard Worker RenderAlignOffset = AddressOffset;
563*35ffd701SAndroid Build Coastguard Worker OffsetX = OffsetY = OffsetZ = 0;
564*35ffd701SAndroid Build Coastguard Worker }
565*35ffd701SAndroid Build Coastguard Worker }
566*35ffd701SAndroid Build Coastguard Worker else
567*35ffd701SAndroid Build Coastguard Worker {
568*35ffd701SAndroid Build Coastguard Worker // Linear case make sure Render address is DWORD aligned.
569*35ffd701SAndroid Build Coastguard Worker RenderAlignOffset = GFX_ALIGN_FLOOR(AddressOffset, GMM_BYTES(4));
570*35ffd701SAndroid Build Coastguard Worker
571*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->Pitch)
572*35ffd701SAndroid Build Coastguard Worker {
573*35ffd701SAndroid Build Coastguard Worker OffsetX = GFX_ULONG_CAST((AddressOffset - RenderAlignOffset) % pTexInfo->Pitch);
574*35ffd701SAndroid Build Coastguard Worker OffsetY = GFX_ULONG_CAST((AddressOffset - RenderAlignOffset) / pTexInfo->Pitch);
575*35ffd701SAndroid Build Coastguard Worker }
576*35ffd701SAndroid Build Coastguard Worker else
577*35ffd701SAndroid Build Coastguard Worker {
578*35ffd701SAndroid Build Coastguard Worker // One-dimensional textures (no height)
579*35ffd701SAndroid Build Coastguard Worker OffsetX = GFX_ULONG_CAST(AddressOffset - RenderAlignOffset);
580*35ffd701SAndroid Build Coastguard Worker OffsetY = 0;
581*35ffd701SAndroid Build Coastguard Worker }
582*35ffd701SAndroid Build Coastguard Worker }
583*35ffd701SAndroid Build Coastguard Worker
584*35ffd701SAndroid Build Coastguard Worker pReqInfo->Render.Offset64 = RenderAlignOffset;
585*35ffd701SAndroid Build Coastguard Worker pReqInfo->Render.XOffset = GFX_ULONG_CAST(OffsetX);
586*35ffd701SAndroid Build Coastguard Worker pReqInfo->Render.YOffset = GFX_ULONG_CAST(OffsetY);
587*35ffd701SAndroid Build Coastguard Worker pReqInfo->Render.ZOffset = GFX_ULONG_CAST(OffsetZ);
588*35ffd701SAndroid Build Coastguard Worker
589*35ffd701SAndroid Build Coastguard Worker return GMM_SUCCESS;
590*35ffd701SAndroid Build Coastguard Worker } // __GmmGetRenderAlignAddress
591*35ffd701SAndroid Build Coastguard Worker
592*35ffd701SAndroid Build Coastguard Worker
593*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
594*35ffd701SAndroid Build Coastguard Worker /// Function used to calculate byte address of a specified mip map
595*35ffd701SAndroid Build Coastguard Worker ///
596*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
597*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
598*35ffd701SAndroid Build Coastguard Worker ///
599*35ffd701SAndroid Build Coastguard Worker /// @return ::GMM_GFX_SIZE_T byte offset
600*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
GetMipMapByteAddress(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo)601*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T GmmLib::GmmTextureCalc::GetMipMapByteAddress(GMM_TEXTURE_INFO * pTexInfo,
602*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo)
603*35ffd701SAndroid Build Coastguard Worker {
604*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T ArrayQPitch, MipMapByteAddress, Pitch;
605*35ffd701SAndroid Build Coastguard Worker uint32_t MipLevel;
606*35ffd701SAndroid Build Coastguard Worker
607*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
608*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
609*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(!(pTexInfo->Flags.Gpu.CCS && !pTexInfo->Flags.Gpu.UnifiedAuxSurface));
610*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(pReqInfo->Plane < GMM_MAX_PLANE);
611*35ffd701SAndroid Build Coastguard Worker
612*35ffd701SAndroid Build Coastguard Worker MipLevel = pReqInfo->MipLevel;
613*35ffd701SAndroid Build Coastguard Worker Pitch = pTexInfo->Pitch;
614*35ffd701SAndroid Build Coastguard Worker ArrayQPitch = pReqInfo->ReqRender ?
615*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender :
616*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock;
617*35ffd701SAndroid Build Coastguard Worker
618*35ffd701SAndroid Build Coastguard Worker const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
619*35ffd701SAndroid Build Coastguard Worker
620*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->Type == RESOURCE_3D && !pTexInfo->Flags.Info.Linear)
621*35ffd701SAndroid Build Coastguard Worker {
622*35ffd701SAndroid Build Coastguard Worker ArrayQPitch *= pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileDepth;
623*35ffd701SAndroid Build Coastguard Worker }
624*35ffd701SAndroid Build Coastguard Worker
625*35ffd701SAndroid Build Coastguard Worker if((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN8_CORE) &&
626*35ffd701SAndroid Build Coastguard Worker ((pTexInfo->MSAA.NumSamples > 1) &&
627*35ffd701SAndroid Build Coastguard Worker !(pTexInfo->Flags.Gpu.Depth ||
628*35ffd701SAndroid Build Coastguard Worker pTexInfo->Flags.Gpu.SeparateStencil ||
629*35ffd701SAndroid Build Coastguard Worker GMM_IS_64KB_TILE(pTexInfo->Flags) ||
630*35ffd701SAndroid Build Coastguard Worker pTexInfo->Flags.Info.TiledYf)))
631*35ffd701SAndroid Build Coastguard Worker {
632*35ffd701SAndroid Build Coastguard Worker ArrayQPitch *= pTexInfo->MSAA.NumSamples;
633*35ffd701SAndroid Build Coastguard Worker }
634*35ffd701SAndroid Build Coastguard Worker
635*35ffd701SAndroid Build Coastguard Worker if(GmmIsPlanar(pTexInfo->Format))
636*35ffd701SAndroid Build Coastguard Worker {
637*35ffd701SAndroid Build Coastguard Worker uint32_t Plane = pReqInfo->Plane;
638*35ffd701SAndroid Build Coastguard Worker
639*35ffd701SAndroid Build Coastguard Worker uint32_t OffsetX = 0;
640*35ffd701SAndroid Build Coastguard Worker uint32_t OffsetY = 0;
641*35ffd701SAndroid Build Coastguard Worker if(Plane < GMM_MAX_PLANE)
642*35ffd701SAndroid Build Coastguard Worker {
643*35ffd701SAndroid Build Coastguard Worker OffsetX = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.X[Plane]);
644*35ffd701SAndroid Build Coastguard Worker OffsetY = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.Y[Plane]);
645*35ffd701SAndroid Build Coastguard Worker ArrayQPitch = pTexInfo->OffsetInfo.Plane.ArrayQPitch;
646*35ffd701SAndroid Build Coastguard Worker }
647*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = (OffsetY * Pitch) + OffsetX;
648*35ffd701SAndroid Build Coastguard Worker
649*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(!pReqInfo->ArrayIndex || (pReqInfo->ArrayIndex < pTexInfo->ArraySize));
650*35ffd701SAndroid Build Coastguard Worker
651*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress += (ArrayQPitch * pReqInfo->ArrayIndex);
652*35ffd701SAndroid Build Coastguard Worker }
653*35ffd701SAndroid Build Coastguard Worker else
654*35ffd701SAndroid Build Coastguard Worker {
655*35ffd701SAndroid Build Coastguard Worker switch(pTexInfo->Type)
656*35ffd701SAndroid Build Coastguard Worker {
657*35ffd701SAndroid Build Coastguard Worker case RESOURCE_CUBE:
658*35ffd701SAndroid Build Coastguard Worker {
659*35ffd701SAndroid Build Coastguard Worker uint32_t CubeFace = pReqInfo->CubeFace;
660*35ffd701SAndroid Build Coastguard Worker
661*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF( // Validate Cube Map Params...
662*35ffd701SAndroid Build Coastguard Worker (!pReqInfo->ArrayIndex || (pReqInfo->ArrayIndex < pTexInfo->ArraySize)) &&
663*35ffd701SAndroid Build Coastguard Worker (pReqInfo->CubeFace < __GMM_MAX_CUBE_FACE) &&
664*35ffd701SAndroid Build Coastguard Worker (pReqInfo->CubeFace != __GMM_NO_CUBE_MAP) &&
665*35ffd701SAndroid Build Coastguard Worker (pReqInfo->Plane == GMM_NO_PLANE) &&
666*35ffd701SAndroid Build Coastguard Worker (pReqInfo->Slice == 0),
667*35ffd701SAndroid Build Coastguard Worker "Invalid parameter!");
668*35ffd701SAndroid Build Coastguard Worker
669*35ffd701SAndroid Build Coastguard Worker // Support for CubeMap Arrays using 2D Arrays
670*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[MipLevel];
671*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress += (ArrayQPitch * ((6 * pReqInfo->ArrayIndex) + CubeFace));
672*35ffd701SAndroid Build Coastguard Worker break;
673*35ffd701SAndroid Build Coastguard Worker }
674*35ffd701SAndroid Build Coastguard Worker case RESOURCE_2D:
675*35ffd701SAndroid Build Coastguard Worker case RESOURCE_1D:
676*35ffd701SAndroid Build Coastguard Worker {
677*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[MipLevel];
678*35ffd701SAndroid Build Coastguard Worker
679*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->ArrayIndex)
680*35ffd701SAndroid Build Coastguard Worker {
681*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress += (ArrayQPitch * pReqInfo->ArrayIndex);
682*35ffd701SAndroid Build Coastguard Worker }
683*35ffd701SAndroid Build Coastguard Worker break;
684*35ffd701SAndroid Build Coastguard Worker }
685*35ffd701SAndroid Build Coastguard Worker case RESOURCE_3D:
686*35ffd701SAndroid Build Coastguard Worker {
687*35ffd701SAndroid Build Coastguard Worker if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE)
688*35ffd701SAndroid Build Coastguard Worker {
689*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[MipLevel];
690*35ffd701SAndroid Build Coastguard Worker
691*35ffd701SAndroid Build Coastguard Worker if(pReqInfo->Slice)
692*35ffd701SAndroid Build Coastguard Worker {
693*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress += (ArrayQPitch * pReqInfo->Slice);
694*35ffd701SAndroid Build Coastguard Worker }
695*35ffd701SAndroid Build Coastguard Worker }
696*35ffd701SAndroid Build Coastguard Worker else
697*35ffd701SAndroid Build Coastguard Worker {
698*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = Get3DMipByteAddress(pTexInfo, pReqInfo);
699*35ffd701SAndroid Build Coastguard Worker }
700*35ffd701SAndroid Build Coastguard Worker break;
701*35ffd701SAndroid Build Coastguard Worker }
702*35ffd701SAndroid Build Coastguard Worker default:
703*35ffd701SAndroid Build Coastguard Worker { // These resources don't have multiple levels of detail
704*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = 0;
705*35ffd701SAndroid Build Coastguard Worker break;
706*35ffd701SAndroid Build Coastguard Worker }
707*35ffd701SAndroid Build Coastguard Worker }
708*35ffd701SAndroid Build Coastguard Worker }
709*35ffd701SAndroid Build Coastguard Worker
710*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress += pTexInfo->Flags.Gpu.S3d ?
711*35ffd701SAndroid Build Coastguard Worker GetDisplayFrameOffset(pTexInfo, pReqInfo) :
712*35ffd701SAndroid Build Coastguard Worker 0;
713*35ffd701SAndroid Build Coastguard Worker
714*35ffd701SAndroid Build Coastguard Worker return MipMapByteAddress;
715*35ffd701SAndroid Build Coastguard Worker }
716*35ffd701SAndroid Build Coastguard Worker
717*35ffd701SAndroid Build Coastguard Worker
718*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
719*35ffd701SAndroid Build Coastguard Worker /// Utility function used to calculate byte address to a mip slice
720*35ffd701SAndroid Build Coastguard Worker ///
721*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
722*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
723*35ffd701SAndroid Build Coastguard Worker ///
724*35ffd701SAndroid Build Coastguard Worker /// @return byte offset
725*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
Get3DMipByteAddress(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo)726*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T GmmLib::GmmTextureCalc::Get3DMipByteAddress(GMM_TEXTURE_INFO * pTexInfo,
727*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo)
728*35ffd701SAndroid Build Coastguard Worker {
729*35ffd701SAndroid Build Coastguard Worker uint32_t MipsInThisRow, PlaneRows;
730*35ffd701SAndroid Build Coastguard Worker uint32_t MipHeight, MipWidth;
731*35ffd701SAndroid Build Coastguard Worker uint32_t UnitAlignHeight, UnitAlignWidth;
732*35ffd701SAndroid Build Coastguard Worker GMM_GFX_SIZE_T MipMapByteAddress, ExtraBytes;
733*35ffd701SAndroid Build Coastguard Worker uint32_t Slice, MipLevel, Pitch;
734*35ffd701SAndroid Build Coastguard Worker uint8_t Compress;
735*35ffd701SAndroid Build Coastguard Worker GMM_RESOURCE_FORMAT GenericFormat;
736*35ffd701SAndroid Build Coastguard Worker uint32_t CompressHeight, CompressWidth, CompressDepth;
737*35ffd701SAndroid Build Coastguard Worker
738*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pGmmLibContext, 0);
739*35ffd701SAndroid Build Coastguard Worker
740*35ffd701SAndroid Build Coastguard Worker GenericFormat = pTexInfo->Format;
741*35ffd701SAndroid Build Coastguard Worker Slice = pReqInfo->Slice;
742*35ffd701SAndroid Build Coastguard Worker MipLevel = pReqInfo->MipLevel;
743*35ffd701SAndroid Build Coastguard Worker Pitch = GFX_ULONG_CAST(pTexInfo->Pitch);
744*35ffd701SAndroid Build Coastguard Worker
745*35ffd701SAndroid Build Coastguard Worker // For slice 0 for any mip address is simple and stored in table
746*35ffd701SAndroid Build Coastguard Worker if(Slice == 0)
747*35ffd701SAndroid Build Coastguard Worker {
748*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[MipLevel];
749*35ffd701SAndroid Build Coastguard Worker }
750*35ffd701SAndroid Build Coastguard Worker // For any slice
751*35ffd701SAndroid Build Coastguard Worker else
752*35ffd701SAndroid Build Coastguard Worker {
753*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress = pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[MipLevel];
754*35ffd701SAndroid Build Coastguard Worker
755*35ffd701SAndroid Build Coastguard Worker // See how many mip can fit in one row
756*35ffd701SAndroid Build Coastguard Worker MipsInThisRow = GFX_2_TO_POWER_OF(MipLevel);
757*35ffd701SAndroid Build Coastguard Worker
758*35ffd701SAndroid Build Coastguard Worker PlaneRows = Slice / MipsInThisRow;
759*35ffd701SAndroid Build Coastguard Worker
760*35ffd701SAndroid Build Coastguard Worker // make sure we get the height and mip of base level
761*35ffd701SAndroid Build Coastguard Worker MipWidth = GFX_ULONG_CAST(pTexInfo->BaseWidth);
762*35ffd701SAndroid Build Coastguard Worker MipHeight = pTexInfo->BaseHeight;
763*35ffd701SAndroid Build Coastguard Worker
764*35ffd701SAndroid Build Coastguard Worker MipWidth >>= MipLevel;
765*35ffd701SAndroid Build Coastguard Worker MipHeight >>= MipLevel;
766*35ffd701SAndroid Build Coastguard Worker
767*35ffd701SAndroid Build Coastguard Worker UnitAlignWidth = pTexInfo->Alignment.HAlign;
768*35ffd701SAndroid Build Coastguard Worker UnitAlignHeight = pTexInfo->Alignment.VAlign;
769*35ffd701SAndroid Build Coastguard Worker Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
770*35ffd701SAndroid Build Coastguard Worker GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
771*35ffd701SAndroid Build Coastguard Worker
772*35ffd701SAndroid Build Coastguard Worker // clamp such that mip height is at least min height
773*35ffd701SAndroid Build Coastguard Worker MipHeight = GFX_MAX(MipHeight, UnitAlignHeight);
774*35ffd701SAndroid Build Coastguard Worker MipHeight = GFX_ALIGN(MipHeight, UnitAlignHeight);
775*35ffd701SAndroid Build Coastguard Worker
776*35ffd701SAndroid Build Coastguard Worker // clamp such that mip width is at least min width
777*35ffd701SAndroid Build Coastguard Worker MipWidth = GFX_MAX(MipWidth, UnitAlignWidth);
778*35ffd701SAndroid Build Coastguard Worker MipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
779*35ffd701SAndroid Build Coastguard Worker
780*35ffd701SAndroid Build Coastguard Worker if(Compress)
781*35ffd701SAndroid Build Coastguard Worker {
782*35ffd701SAndroid Build Coastguard Worker MipWidth /= CompressWidth;
783*35ffd701SAndroid Build Coastguard Worker MipHeight /= CompressHeight;
784*35ffd701SAndroid Build Coastguard Worker }
785*35ffd701SAndroid Build Coastguard Worker else if(pTexInfo->Flags.Gpu.SeparateStencil)
786*35ffd701SAndroid Build Coastguard Worker {
787*35ffd701SAndroid Build Coastguard Worker MipWidth *= 2;
788*35ffd701SAndroid Build Coastguard Worker MipHeight /= 2;
789*35ffd701SAndroid Build Coastguard Worker }
790*35ffd701SAndroid Build Coastguard Worker
791*35ffd701SAndroid Build Coastguard Worker ExtraBytes = (GMM_GFX_SIZE_T)PlaneRows * MipHeight * Pitch;
792*35ffd701SAndroid Build Coastguard Worker
793*35ffd701SAndroid Build Coastguard Worker ExtraBytes += ((GMM_GFX_SIZE_T)(Slice % MipsInThisRow) *
794*35ffd701SAndroid Build Coastguard Worker MipWidth * pTexInfo->BitsPerPixel) >>
795*35ffd701SAndroid Build Coastguard Worker 3;
796*35ffd701SAndroid Build Coastguard Worker
797*35ffd701SAndroid Build Coastguard Worker // get address offset
798*35ffd701SAndroid Build Coastguard Worker MipMapByteAddress += ExtraBytes;
799*35ffd701SAndroid Build Coastguard Worker }
800*35ffd701SAndroid Build Coastguard Worker
801*35ffd701SAndroid Build Coastguard Worker return MipMapByteAddress;
802*35ffd701SAndroid Build Coastguard Worker }
803*35ffd701SAndroid Build Coastguard Worker
804*35ffd701SAndroid Build Coastguard Worker
805*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
806*35ffd701SAndroid Build Coastguard Worker /// Utility function calculates a byte offset from the base of the allocation
807*35ffd701SAndroid Build Coastguard Worker // to L frame, R frame, or blank region.
808*35ffd701SAndroid Build Coastguard Worker ///
809*35ffd701SAndroid Build Coastguard Worker /// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
810*35ffd701SAndroid Build Coastguard Worker /// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
811*35ffd701SAndroid Build Coastguard Worker ///
812*35ffd701SAndroid Build Coastguard Worker /// @return byte offset
813*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
GetDisplayFrameOffset(GMM_TEXTURE_INFO * pTexInfo,GMM_REQ_OFFSET_INFO * pReqInfo)814*35ffd701SAndroid Build Coastguard Worker uint32_t GmmLib::GmmTextureCalc::GetDisplayFrameOffset(GMM_TEXTURE_INFO * pTexInfo,
815*35ffd701SAndroid Build Coastguard Worker GMM_REQ_OFFSET_INFO *pReqInfo)
816*35ffd701SAndroid Build Coastguard Worker {
817*35ffd701SAndroid Build Coastguard Worker uint32_t Offset;
818*35ffd701SAndroid Build Coastguard Worker
819*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
820*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
821*35ffd701SAndroid Build Coastguard Worker
822*35ffd701SAndroid Build Coastguard Worker switch(pReqInfo->Frame)
823*35ffd701SAndroid Build Coastguard Worker {
824*35ffd701SAndroid Build Coastguard Worker case GMM_DISPLAY_L:
825*35ffd701SAndroid Build Coastguard Worker Offset = 0;
826*35ffd701SAndroid Build Coastguard Worker break;
827*35ffd701SAndroid Build Coastguard Worker case GMM_DISPLAY_R:
828*35ffd701SAndroid Build Coastguard Worker Offset = pTexInfo->S3d.RFrameOffset;
829*35ffd701SAndroid Build Coastguard Worker break;
830*35ffd701SAndroid Build Coastguard Worker case GMM_DISPLAY_BLANK_AREA:
831*35ffd701SAndroid Build Coastguard Worker Offset = pTexInfo->S3d.BlankAreaOffset;
832*35ffd701SAndroid Build Coastguard Worker break;
833*35ffd701SAndroid Build Coastguard Worker default:
834*35ffd701SAndroid Build Coastguard Worker Offset = 0;
835*35ffd701SAndroid Build Coastguard Worker GMM_ASSERTDPF(0, "Unknown Frame Type!");
836*35ffd701SAndroid Build Coastguard Worker break;
837*35ffd701SAndroid Build Coastguard Worker }
838*35ffd701SAndroid Build Coastguard Worker
839*35ffd701SAndroid Build Coastguard Worker return Offset;
840*35ffd701SAndroid Build Coastguard Worker }
841*35ffd701SAndroid Build Coastguard Worker
SetPlanarOffsetInfo(GMM_TEXTURE_INFO * pTexInfo,GMM_RESCREATE_CUSTOM_PARAMS & CreateParams)842*35ffd701SAndroid Build Coastguard Worker void GmmLib::GmmTextureCalc::SetPlanarOffsetInfo(GMM_TEXTURE_INFO *pTexInfo, GMM_RESCREATE_CUSTOM_PARAMS &CreateParams)
843*35ffd701SAndroid Build Coastguard Worker {
844*35ffd701SAndroid Build Coastguard Worker const GMM_PLATFORM_INFO *pPlatform;
845*35ffd701SAndroid Build Coastguard Worker pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
846*35ffd701SAndroid Build Coastguard Worker
847*35ffd701SAndroid Build Coastguard Worker if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
848*35ffd701SAndroid Build Coastguard Worker {
849*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.IsTileAlignedPlanes = true;
850*35ffd701SAndroid Build Coastguard Worker }
851*35ffd701SAndroid Build Coastguard Worker for(uint8_t i = 1; i <= CreateParams.NoOfPlanes; i++)
852*35ffd701SAndroid Build Coastguard Worker {
853*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.X[i] = CreateParams.PlaneOffset.X[i];
854*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.Y[i] = CreateParams.PlaneOffset.Y[i];
855*35ffd701SAndroid Build Coastguard Worker }
856*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.NoOfPlanes = CreateParams.NoOfPlanes;
857*35ffd701SAndroid Build Coastguard Worker }
858*35ffd701SAndroid Build Coastguard Worker
859*35ffd701SAndroid Build Coastguard Worker #ifndef __GMM_KMD__
SetPlanarOffsetInfo_2(GMM_TEXTURE_INFO * pTexInfo,GMM_RESCREATE_CUSTOM_PARAMS_2 & CreateParams)860*35ffd701SAndroid Build Coastguard Worker void GmmLib::GmmTextureCalc::SetPlanarOffsetInfo_2(GMM_TEXTURE_INFO *pTexInfo, GMM_RESCREATE_CUSTOM_PARAMS_2 &CreateParams)
861*35ffd701SAndroid Build Coastguard Worker {
862*35ffd701SAndroid Build Coastguard Worker const GMM_PLATFORM_INFO *pPlatform;
863*35ffd701SAndroid Build Coastguard Worker pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
864*35ffd701SAndroid Build Coastguard Worker
865*35ffd701SAndroid Build Coastguard Worker if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
866*35ffd701SAndroid Build Coastguard Worker {
867*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.IsTileAlignedPlanes = true;
868*35ffd701SAndroid Build Coastguard Worker }
869*35ffd701SAndroid Build Coastguard Worker for(uint8_t i = 1; i <= CreateParams.NoOfPlanes; i++)
870*35ffd701SAndroid Build Coastguard Worker {
871*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.X[i] = CreateParams.PlaneOffset.X[i];
872*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.Y[i] = CreateParams.PlaneOffset.Y[i];
873*35ffd701SAndroid Build Coastguard Worker }
874*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.NoOfPlanes = CreateParams.NoOfPlanes;
875*35ffd701SAndroid Build Coastguard Worker }
876*35ffd701SAndroid Build Coastguard Worker #endif
877*35ffd701SAndroid Build Coastguard Worker
SetPlaneUnAlignedTexOffsetInfo(GMM_TEXTURE_INFO * pTexInfo,uint32_t YHeight,uint32_t VHeight)878*35ffd701SAndroid Build Coastguard Worker void GmmLib::GmmTextureCalc::SetPlaneUnAlignedTexOffsetInfo(GMM_TEXTURE_INFO *pTexInfo, uint32_t YHeight, uint32_t VHeight)
879*35ffd701SAndroid Build Coastguard Worker {
880*35ffd701SAndroid Build Coastguard Worker uint32_t UmdUHeight = 0, UmdVHeight = 0;
881*35ffd701SAndroid Build Coastguard Worker
882*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_Y] = YHeight;
883*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->OffsetInfo.Plane.NoOfPlanes == 2)
884*35ffd701SAndroid Build Coastguard Worker {
885*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U] = VHeight;
886*35ffd701SAndroid Build Coastguard Worker UmdUHeight = (GMM_GLOBAL_GFX_SIZE_T)((pTexInfo->Size / pTexInfo->Pitch) - pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U]);
887*35ffd701SAndroid Build Coastguard Worker }
888*35ffd701SAndroid Build Coastguard Worker else if(pTexInfo->OffsetInfo.Plane.NoOfPlanes == 3)
889*35ffd701SAndroid Build Coastguard Worker {
890*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U] =
891*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_V] = VHeight;
892*35ffd701SAndroid Build Coastguard Worker UmdUHeight = (GMM_GLOBAL_GFX_SIZE_T)(pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_V] - pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U]);
893*35ffd701SAndroid Build Coastguard Worker UmdVHeight = (GMM_GLOBAL_GFX_SIZE_T)(((pTexInfo->Size / pTexInfo->Pitch) - pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U]) / 2);
894*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR((UmdUHeight == UmdVHeight), VOIDRETURN);
895*35ffd701SAndroid Build Coastguard Worker }
896*35ffd701SAndroid Build Coastguard Worker
897*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERTPTR(((pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U] == YHeight) && (UmdUHeight == VHeight)), VOIDRETURN);
898*35ffd701SAndroid Build Coastguard Worker }
899*35ffd701SAndroid Build Coastguard Worker
IsTileAlignedPlanes(GMM_TEXTURE_INFO * pTexInfo)900*35ffd701SAndroid Build Coastguard Worker uint32_t GmmLib::GmmTextureCalc::IsTileAlignedPlanes(GMM_TEXTURE_INFO *pTexInfo)
901*35ffd701SAndroid Build Coastguard Worker {
902*35ffd701SAndroid Build Coastguard Worker return pTexInfo->OffsetInfo.Plane.IsTileAlignedPlanes;
903*35ffd701SAndroid Build Coastguard Worker }
904*35ffd701SAndroid Build Coastguard Worker
GetNumberOfPlanes(GMM_TEXTURE_INFO * pTexInfo)905*35ffd701SAndroid Build Coastguard Worker uint32_t GmmLib::GmmTextureCalc::GetNumberOfPlanes(GMM_TEXTURE_INFO *pTexInfo)
906*35ffd701SAndroid Build Coastguard Worker {
907*35ffd701SAndroid Build Coastguard Worker return pTexInfo->OffsetInfo.Plane.NoOfPlanes;
908*35ffd701SAndroid Build Coastguard Worker }
909*35ffd701SAndroid Build Coastguard Worker
GetPlaneIdForCpuBlt(GMM_TEXTURE_INFO * pTexInfo,GMM_RES_COPY_BLT * pBlt,uint32_t * PlaneId)910*35ffd701SAndroid Build Coastguard Worker void GmmLib::GmmTextureCalc::GetPlaneIdForCpuBlt(GMM_TEXTURE_INFO *pTexInfo, GMM_RES_COPY_BLT *pBlt, uint32_t *PlaneId)
911*35ffd701SAndroid Build Coastguard Worker {
912*35ffd701SAndroid Build Coastguard Worker uint32_t TotalHeight = 0;
913*35ffd701SAndroid Build Coastguard Worker
914*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->OffsetInfo.Plane.NoOfPlanes == 2)
915*35ffd701SAndroid Build Coastguard Worker {
916*35ffd701SAndroid Build Coastguard Worker TotalHeight = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_Y] +
917*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U]);
918*35ffd701SAndroid Build Coastguard Worker }
919*35ffd701SAndroid Build Coastguard Worker else if(pTexInfo->OffsetInfo.Plane.NoOfPlanes == 3)
920*35ffd701SAndroid Build Coastguard Worker {
921*35ffd701SAndroid Build Coastguard Worker TotalHeight = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_Y] +
922*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U] +
923*35ffd701SAndroid Build Coastguard Worker pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_V]);
924*35ffd701SAndroid Build Coastguard Worker }
925*35ffd701SAndroid Build Coastguard Worker else
926*35ffd701SAndroid Build Coastguard Worker {
927*35ffd701SAndroid Build Coastguard Worker TotalHeight = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_Y]); //YV12 exception
928*35ffd701SAndroid Build Coastguard Worker }
929*35ffd701SAndroid Build Coastguard Worker
930*35ffd701SAndroid Build Coastguard Worker // Determine if BLT rectange is for monolithic surface or contained in specific Y/UV plane
931*35ffd701SAndroid Build Coastguard Worker if(((pBlt->Gpu.OffsetY + pBlt->Blt.Height <= pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U]) || pTexInfo->OffsetInfo.Plane.NoOfPlanes == 1) &&
932*35ffd701SAndroid Build Coastguard Worker (pBlt->Gpu.OffsetX + pBlt->Blt.Width <= pTexInfo->BaseWidth))
933*35ffd701SAndroid Build Coastguard Worker {
934*35ffd701SAndroid Build Coastguard Worker *PlaneId = GMM_PLANE_Y;
935*35ffd701SAndroid Build Coastguard Worker }
936*35ffd701SAndroid Build Coastguard Worker else if(pBlt->Gpu.OffsetY >= pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U] &&
937*35ffd701SAndroid Build Coastguard Worker (pBlt->Gpu.OffsetY + pBlt->Blt.Height <= (pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U] + pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U])) &&
938*35ffd701SAndroid Build Coastguard Worker (pBlt->Gpu.OffsetX + pBlt->Blt.Width <= pTexInfo->BaseWidth))
939*35ffd701SAndroid Build Coastguard Worker {
940*35ffd701SAndroid Build Coastguard Worker *PlaneId = GMM_PLANE_U;
941*35ffd701SAndroid Build Coastguard Worker }
942*35ffd701SAndroid Build Coastguard Worker else if(pBlt->Gpu.OffsetY >= pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_V] &&
943*35ffd701SAndroid Build Coastguard Worker (pBlt->Gpu.OffsetY + pBlt->Blt.Height <= (pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_V] + pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U])) &&
944*35ffd701SAndroid Build Coastguard Worker (pBlt->Gpu.OffsetX + pBlt->Blt.Width <= pTexInfo->BaseWidth))
945*35ffd701SAndroid Build Coastguard Worker {
946*35ffd701SAndroid Build Coastguard Worker *PlaneId = GMM_PLANE_V;
947*35ffd701SAndroid Build Coastguard Worker }
948*35ffd701SAndroid Build Coastguard Worker
949*35ffd701SAndroid Build Coastguard Worker // For smaller surface, BLT rect may fall in Y Plane due to tile alignment but user may have requested monolithic BLT
950*35ffd701SAndroid Build Coastguard Worker if(pBlt->Gpu.OffsetX == 0 &&
951*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetY == 0 &&
952*35ffd701SAndroid Build Coastguard Worker pBlt->Blt.Height >= TotalHeight)
953*35ffd701SAndroid Build Coastguard Worker {
954*35ffd701SAndroid Build Coastguard Worker *PlaneId = GMM_MAX_PLANE;
955*35ffd701SAndroid Build Coastguard Worker }
956*35ffd701SAndroid Build Coastguard Worker }
957*35ffd701SAndroid Build Coastguard Worker
GetBltInfoPerPlane(GMM_TEXTURE_INFO * pTexInfo,GMM_RES_COPY_BLT * pBlt,uint32_t PlaneId)958*35ffd701SAndroid Build Coastguard Worker void GmmLib::GmmTextureCalc::GetBltInfoPerPlane(GMM_TEXTURE_INFO *pTexInfo, GMM_RES_COPY_BLT *pBlt, uint32_t PlaneId)
959*35ffd701SAndroid Build Coastguard Worker {
960*35ffd701SAndroid Build Coastguard Worker if(PlaneId == GMM_PLANE_Y)
961*35ffd701SAndroid Build Coastguard Worker {
962*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetX = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.X[GMM_PLANE_Y]);
963*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetY = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_Y]);
964*35ffd701SAndroid Build Coastguard Worker pBlt->Blt.Height = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_Y]);
965*35ffd701SAndroid Build Coastguard Worker }
966*35ffd701SAndroid Build Coastguard Worker else if(PlaneId == GMM_PLANE_U)
967*35ffd701SAndroid Build Coastguard Worker {
968*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetX = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.X[GMM_PLANE_U]);
969*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetY = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U]);
970*35ffd701SAndroid Build Coastguard Worker
971*35ffd701SAndroid Build Coastguard Worker pBlt->Sys.pData = (char *)pBlt->Sys.pData + uint32_t(pBlt->Blt.Height * pBlt->Sys.RowPitch);
972*35ffd701SAndroid Build Coastguard Worker pBlt->Blt.Height = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U]);
973*35ffd701SAndroid Build Coastguard Worker if(pTexInfo->Flags.Info.RedecribedPlanes)
974*35ffd701SAndroid Build Coastguard Worker {
975*35ffd701SAndroid Build Coastguard Worker __GMM_ASSERT(0);
976*35ffd701SAndroid Build Coastguard Worker }
977*35ffd701SAndroid Build Coastguard Worker }
978*35ffd701SAndroid Build Coastguard Worker else
979*35ffd701SAndroid Build Coastguard Worker {
980*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetX = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.X[GMM_PLANE_V]);
981*35ffd701SAndroid Build Coastguard Worker pBlt->Gpu.OffsetY = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_V]);
982*35ffd701SAndroid Build Coastguard Worker pBlt->Blt.Height = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U]);
983*35ffd701SAndroid Build Coastguard Worker pBlt->Sys.pData = (char *)pBlt->Sys.pData + uint32_t(pBlt->Blt.Height * pBlt->Sys.RowPitch);
984*35ffd701SAndroid Build Coastguard Worker }
985*35ffd701SAndroid Build Coastguard Worker }
986