1 /*==============================================================================
2 Copyright(c) 2017 Intel Corporation
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 shall be included
12 in all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 ============================================================================*/
22 
23 #include "Internal/Common/GmmLibInc.h"
24 
25 
26 /////////////////////////////////////////////////////////////////////////////////////
27 /// Allocates the 2D mip layout for surface state programming.
28 ///
29 /// @param[in]  pTexInfo: ptr to ::GMM_TEXTURE_INFO,
30 /// @param[in]  pRestrictions: ptr to surface alignment and size restrictions
31 ///
32 /// @return     ::GMM_STATUS
33 /////////////////////////////////////////////////////////////////////////////////////
FillTex2D(GMM_TEXTURE_INFO * pTexInfo,__GMM_BUFFER_TYPE * pRestrictions)34 GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::FillTex2D(GMM_TEXTURE_INFO * pTexInfo,
35                                                              __GMM_BUFFER_TYPE *pRestrictions)
36 {
37     uint32_t   Width, Height, BitsPerPixel;
38     uint32_t   HAlign, VAlign;
39     uint32_t   CompressHeight, CompressWidth, CompressDepth;
40     uint32_t   AlignedWidth, BlockHeight, ExpandedArraySize, Pitch;
41     uint8_t    Compress = 0;
42     GMM_STATUS Status;
43 
44     GMM_DPF_ENTER;
45 
46     __GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
47     __GMM_ASSERTPTR(pRestrictions, GMM_ERROR);
48 
49     const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
50 
51     BitsPerPixel = pTexInfo->BitsPerPixel;
52     Height       = pTexInfo->BaseHeight;
53     Width        = GFX_ULONG_CAST(pTexInfo->BaseWidth);
54 
55     pTexInfo->MSAA.NumSamples = GFX_MAX(pTexInfo->MSAA.NumSamples, 1);
56 
57     ExpandedArraySize =
58     GFX_MAX(pTexInfo->ArraySize, 1) *
59     ((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1) * // Cubemaps simply 6-element, 2D arrays.
60     ((pTexInfo->Flags.Gpu.Depth || pTexInfo->Flags.Gpu.SeparateStencil) ?
61      1 :
62      pTexInfo->MSAA.NumSamples); // MSAA (non-Depth/Stencil) RT samples stored as array planes.
63 
64     //
65     // Check for color separation
66     //
67     if(pTexInfo->Flags.Gpu.ColorSeparation || pTexInfo->Flags.Gpu.ColorSeparationRGBX)
68     {
69         bool csRestrictionsMet = (((ExpandedArraySize <= 2) &&
70                                    (ExpandedArraySize == pTexInfo->ArraySize) &&
71                                    ((pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM) ||
72                                     (pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM_SRGB) ||
73                                     (pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM) ||
74                                     (pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM_SRGB) ||
75                                     (pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM) ||
76                                     (pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM_SRGB)) &&
77                                    ((pTexInfo->Flags.Gpu.ColorSeparation && (Width % 16) == 0) ||
78                                     (pTexInfo->Flags.Gpu.ColorSeparationRGBX && (Width % 12) == 0))));
79 
80         if(csRestrictionsMet)
81         {
82             ExpandedArraySize = GMM_COLOR_SEPARATION_ARRAY_SIZE;
83         }
84         else
85         {
86             pTexInfo->Flags.Gpu.ColorSeparation     = 0;
87             pTexInfo->Flags.Gpu.ColorSeparationRGBX = 0;
88         }
89     }
90 
91     HAlign = pTexInfo->Alignment.HAlign;
92     VAlign = pTexInfo->Alignment.VAlign;
93     GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
94 
95     Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
96 
97     // Calculate Block Surface Height
98     /////////////////////////////////
99 
100     if(ExpandedArraySize > 1)
101     {
102         uint32_t Height0, Height1, Mip0BlockHeight, Slice0Delta = 0;
103 
104         Height0 = __GMM_EXPAND_HEIGHT(this, Height, VAlign, pTexInfo);
105         Height1 = __GMM_EXPAND_HEIGHT(this, Height >> 1, VAlign, pTexInfo);
106 
107         Mip0BlockHeight = BlockHeight = (pTexInfo->MaxLod > 0) ?
108                                         Height0 + Height1 + 12 * VAlign :
109                                         Height0;
110         BlockHeight -= (pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) ? Height0 : 0;
111 
112         if(pTexInfo->Flags.Gpu.S3dDx && pGmmLibContext->GetSkuTable().FtrDisplayEngineS3d)
113         {
114             BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
115         }
116 
117         // QPitch for compressed surface must be multiple of BlockHeight and 4...
118         if(Compress && (CompressHeight % 4))
119         {
120             uint32_t LCM    = CompressHeight * ((CompressHeight % 2) ? 4 : 2);
121             BlockHeight     = GFX_ALIGN_NP2(BlockHeight, LCM);
122             Mip0BlockHeight = GFX_ALIGN_NP2(Mip0BlockHeight, LCM);
123         }
124 
125         // Gen8 QPitch programming refers to the logical view, not physical.
126         pTexInfo->Alignment.QPitch = BlockHeight;
127 
128         if(Compress)
129         {
130             BlockHeight /= CompressHeight;
131             Mip0BlockHeight /= CompressHeight;
132         }
133         else if(pTexInfo->Flags.Gpu.SeparateStencil)
134         {
135             BlockHeight /= 2;
136         }
137         else if(pTexInfo->Flags.Gpu.CCS)
138         {
139             if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
140             {
141                 BlockHeight /= 32;
142             }
143             else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
144             {
145                 BlockHeight /= 16;
146             }
147         }
148 
149         Slice0Delta = (pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) ? (Mip0BlockHeight - BlockHeight) : 0;
150         BlockHeight *= ExpandedArraySize;
151         BlockHeight += Slice0Delta;
152     }
153     else
154     {
155         pTexInfo->Alignment.QPitch = 0;
156 
157         BlockHeight = Get2DMipMapHeight(pTexInfo);
158     }
159 
160     ///////////////////////////////////
161     // Calculate Pitch
162     ///////////////////////////////////
163 
164     AlignedWidth = __GMM_EXPAND_WIDTH(this, Width, HAlign, pTexInfo);
165 
166     // Calculate special pitch case of small dimensions where LOD1 + LOD2 widths
167     // are greater than LOD0. e.g. dimensions 4x4 and MinPitch == 1
168     if(pTexInfo->MaxLod >= 2)
169     {
170         uint32_t AlignedWidthLod1, AlignedWidthLod2;
171 
172         AlignedWidthLod1 = __GMM_EXPAND_WIDTH(this, Width >> 1, HAlign, pTexInfo);
173         AlignedWidthLod2 = __GMM_EXPAND_WIDTH(this, Width >> 2, HAlign, pTexInfo);
174 
175 	if((pGmmLibContext->GetWaTable().WaAstcCorruptionForOddCompressedBlockSizeX || pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) && pPlatform->FormatTable[pTexInfo->Format].ASTC && CompressWidth == 5)
176         {
177             uint32_t Width1   = (Width == 1) ? 1 : (Width >> 1);
178             uint32_t Modulo10 = Width1 % 10;
179             if(Modulo10 >= 1 && Modulo10 <= CompressWidth)
180             {
181                 AlignedWidthLod2 += 3 * CompressWidth;
182             }
183         }
184         AlignedWidth = GFX_MAX(AlignedWidth, AlignedWidthLod1 + AlignedWidthLod2);
185     }
186 
187     if(Compress)
188     {
189         AlignedWidth /= CompressWidth;
190     }
191     else if(pTexInfo->Flags.Gpu.SeparateStencil)
192     {
193         AlignedWidth *= 2;
194     }
195     else if(pTexInfo->Flags.Gpu.CCS)
196     {
197         if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
198         {
199             switch(pTexInfo->BitsPerPixel)
200             {
201                 case 32:
202                     AlignedWidth /= 8;
203                     break;
204                 case 64:
205                     AlignedWidth /= 4;
206                     break;
207                 case 128:
208                     AlignedWidth /= 2;
209                     break;
210                 default:
211                     __GMM_ASSERT(0);
212             }
213         }
214         else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
215         {
216             switch(pTexInfo->BitsPerPixel)
217             {
218                 case 32:
219                     AlignedWidth /= 16;
220                     break;
221                 case 64:
222                     AlignedWidth /= 8;
223                     break;
224                 case 128:
225                     AlignedWidth /= 4;
226                     break;
227                 default:
228                     __GMM_ASSERT(0);
229             }
230         }
231     }
232     else if(pTexInfo->Flags.Gpu.ColorSeparation)
233     {
234         AlignedWidth *= pTexInfo->ArraySize;
235         __GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_WIDTH_DIVISION));
236         AlignedWidth /= GMM_COLOR_SEPARATION_WIDTH_DIVISION;
237     }
238     else if(pTexInfo->Flags.Gpu.ColorSeparationRGBX)
239     {
240         AlignedWidth *= pTexInfo->ArraySize;
241         __GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION));
242         AlignedWidth /= GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION;
243     }
244 
245     // Default pitch
246     Pitch = AlignedWidth * BitsPerPixel >> 3;
247 
248     // Make sure the pitch satisfy linear min pitch requirment
249     Pitch = GFX_MAX(Pitch, pRestrictions->MinPitch);
250 
251     // Make sure pitch satisfy alignment restriction
252     Pitch = GFX_ALIGN(Pitch, pRestrictions->PitchAlignment);
253 
254     ////////////////////
255     // Adjust for Tiling
256     ////////////////////
257     if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
258     {
259         Pitch       = GFX_ALIGN(Pitch, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth);
260         BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
261 
262         // If Tiled Resource or Undefined64KBSwizzle resource, align to 64KB tile size
263         if((pTexInfo->Flags.Gpu.TiledResource || pTexInfo->Flags.Info.Undefined64KBSwizzle) &&
264            (pTexInfo->Flags.Info.TiledY))
265         {
266             uint32_t ColFactor = 0, RowFactor = 0;
267             uint32_t TRTileWidth = 0, TRTileHeight = 0;
268 
269             GmmGetD3DToHwTileConversion(pTexInfo, &ColFactor, &RowFactor);
270             TRTileWidth  = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth * ColFactor;
271             TRTileHeight = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight * RowFactor;
272 
273             Pitch       = GFX_ALIGN(Pitch, TRTileWidth);
274             BlockHeight = GFX_ALIGN(BlockHeight, TRTileHeight);
275         }
276     }
277 
278     GMM_ASSERTDPF(pTexInfo->Flags.Info.LayoutBelow || !pTexInfo->Flags.Info.LayoutRight, "MIPLAYOUT_RIGHT not supported after Gen6!");
279     pTexInfo->Flags.Info.LayoutBelow = 1;
280     pTexInfo->Flags.Info.LayoutRight = 0;
281 
282     // If a texture is YUV packed, 96, or 48 bpp then one row plus 16 bytes of
283     // padding needs to be added. Since this will create a none pitch aligned
284     // surface the padding is aligned to the next row
285     if(GmmIsYUVPacked(pTexInfo->Format) ||
286        (pTexInfo->BitsPerPixel == GMM_BITS(96)) ||
287        (pTexInfo->BitsPerPixel == GMM_BITS(48)))
288     {
289         BlockHeight += GMM_SCANLINES(1) + GFX_CEIL_DIV(GMM_BYTES(16), Pitch);
290     }
291 
292     // Align height to even row to cover for HW over-fetch
293     BlockHeight = GFX_ALIGN(BlockHeight, __GMM_EVEN_ROW);
294 
295     if((Status = // <-- Note assignment.
296         FillTexPitchAndSize(
297         pTexInfo, Pitch, BlockHeight, pRestrictions)) == GMM_SUCCESS)
298     {
299         Fill2DTexOffsetAddress(pTexInfo);
300 
301         // Init to no-packed mips. It'll be initialized when app calls to get packed
302         // mips. Calculate packed mips here if there's a chance apps won't call to
303         // get packed mips.
304         pTexInfo->Alignment.PackedMipStartLod = GMM_TILED_RESOURCE_NO_PACKED_MIPS;
305     }
306 
307     if(pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips)
308     {
309         uint32_t i             = 0;
310         uint64_t SkipMip0Tiles = 0;
311         SkipMip0Tiles          = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[1] /
312                         (pTexInfo->Pitch * pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
313         SkipMip0Tiles *= pTexInfo->Pitch * pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight;
314         pTexInfo->Size -= SkipMip0Tiles;
315         for(i = 0; i <= pTexInfo->MaxLod; i++)
316         {
317             pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[i] -= SkipMip0Tiles;
318         }
319     }
320     GMM_DPF_EXIT;
321 
322     return (Status);
323 }
324 
325 
326 /////////////////////////////////////////////////////////////////////////////////////
327 /// Calculates the address offset for each mip map of 2D texture and store them into
328 /// the GMM_TEXTURE_INFO for surf state programming.
329 ///
330 /// @param[in]  pTexInfo: ptr to ::GMM_TEXTURE_INFO,
331 ///
332 /////////////////////////////////////////////////////////////////////////////////////
Fill2DTexOffsetAddress(GMM_TEXTURE_INFO * pTexInfo)333 void GmmLib::GmmGen8TextureCalc::Fill2DTexOffsetAddress(GMM_TEXTURE_INFO *pTexInfo)
334 {
335     uint32_t i;
336 
337     GMM_DPF_ENTER;
338 
339     // QPitch: Array Element-to-Element, or Cube Face-to-Face Pitch...
340     if((pTexInfo->ArraySize <= 1) &&
341        (pTexInfo->Type != RESOURCE_CUBE) &&
342        !(pTexInfo->Flags.Gpu.ColorSeparation ||
343          pTexInfo->Flags.Gpu.ColorSeparationRGBX))
344     {
345         pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender = 0;
346         pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock   = 0;
347     }
348     else
349     {
350         uint32_t ArrayQPitch;
351         uint32_t CompressHeight, CompressWidth, CompressDepth;
352 
353         GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
354 
355         ArrayQPitch = pTexInfo->Alignment.QPitch;
356 
357         if(GmmIsCompressed(pGmmLibContext, pTexInfo->Format))
358         {
359             ArrayQPitch /= CompressHeight;
360         }
361         else if(pTexInfo->Flags.Gpu.SeparateStencil)
362         {
363             ArrayQPitch /= 2;
364         }
365         else if(pTexInfo->Flags.Gpu.CCS)
366         {
367             if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
368             {
369                 ArrayQPitch /= 32;
370             }
371             else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
372             {
373                 ArrayQPitch /= 16;
374             }
375         }
376 
377         pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender = ArrayQPitch * pTexInfo->Pitch;
378         pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock   = ArrayQPitch * pTexInfo->Pitch;
379     }
380 
381     for(i = 0; i <= pTexInfo->MaxLod; i++)
382     {
383         pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[i] = Get2DTexOffsetAddressPerMip(pTexInfo, i);
384     }
385 
386     GMM_DPF_EXIT;
387 }
388 
389 /////////////////////////////////////////////////////////////////////////////////////
390 /// Allocates the 1D mip layout for surface state programming.
391 ///
392 /// @param[in]  pTexInfo: ptr to ::GMM_TEXTURE_INFO,
393 /// @param[in]  pRestrictions: ptr to surface alignment and size restrictions
394 ///
395 /// @return     ::GMM_STATUS
396 /////////////////////////////////////////////////////////////////////////////////////
FillTex1D(GMM_TEXTURE_INFO * pTexInfo,__GMM_BUFFER_TYPE * pRestrictions)397 GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::FillTex1D(GMM_TEXTURE_INFO * pTexInfo,
398                                                              __GMM_BUFFER_TYPE *pRestrictions)
399 {
400     return FillTex2D(pTexInfo, pRestrictions);
401 }
402 
403 /////////////////////////////////////////////////////////////////////////////////////
404 /// Calculates the cube layout for surface state programming.
405 ///
406 /// @param[in]  pTexInfo: ptr to ::GMM_TEXTURE_INFO,
407 /// @param[in]  pRestrictions: ptr to surface alignment and size restrictions
408 ///
409 /// @return     ::GMM_STATUS
410 /////////////////////////////////////////////////////////////////////////////////////
FillTexCube(GMM_TEXTURE_INFO * pTexInfo,__GMM_BUFFER_TYPE * pRestrictions)411 GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::FillTexCube(GMM_TEXTURE_INFO * pTexInfo,
412                                                                __GMM_BUFFER_TYPE *pRestrictions)
413 {
414     return FillTex2D(pTexInfo, pRestrictions);
415 }
416 
417 /////////////////////////////////////////////////////////////////////////////////////
418 /// This function does any special-case conversion from client-provided pseudo creation
419 /// parameters to actual parameters for CCS.
420 ///
421 /// @param[in]  pTexInfo: Reference to ::GMM_TEXTURE_INFO
422 ///
423 /// @return     ::GMM_STATUS
424 /////////////////////////////////////////////////////////////////////////////////////
MSAACCSUsage(GMM_TEXTURE_INFO * pTexInfo)425 GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::MSAACCSUsage(GMM_TEXTURE_INFO *pTexInfo)
426 {
427     GMM_STATUS Status = GMM_SUCCESS;
428 
429     if(pTexInfo->MSAA.NumSamples > 1) // CCS for MSAA Compression
430     {
431         Status = MSAACompression(pTexInfo);
432     }
433     else // Non-MSAA CCS Use (i.e. Render Target Fast Clear)
434     {
435         if(!pTexInfo->Flags.Info.TiledW &&
436            ((!pTexInfo->Flags.Info.Linear) ||
437             (GMM_IS_4KB_TILE(pTexInfo->Flags) || GMM_IS_64KB_TILE(pTexInfo->Flags) ||
438              (pTexInfo->Type == RESOURCE_BUFFER && pTexInfo->Flags.Info.Linear))) && //!Yf - deprecate Yf
439            ((pTexInfo->BitsPerPixel == 32) ||
440             (pTexInfo->BitsPerPixel == 64) ||
441             (pTexInfo->BitsPerPixel == 128)))
442         {
443             // For non-MSAA CCS usage, the four tables of
444             // requirements:
445             // (1) RT Alignment (GMM Don't Care: Occurs Naturally)
446             // (2) ClearRect Alignment
447             // (3) ClearRect Scaling (GMM Don't Care: GHAL3D Matter)
448             // (4) Non-MSAA CCS Sizing
449 
450             // Gen8+:
451             // Since mip-mapped and arrayed surfaces are supported, we
452             // deal with alignment later at per mip level. Here, we set
453             // tiling type only. TileX is not supported on Gen9+.
454             // Pre-Gen8:
455             // (!) For all the above, there are separate entries for
456             // 32/64/128bpp--and then deals with PIXEL widths--Here,
457             // though, we will unify by considering 8bpp table entries
458             // (unlisted--i.e. do the math)--and deal with BYTE widths.
459 
460             // (1) RT Alignment -- The surface width and height don't
461             // need to be padded to RT CL granularity. On HSW, all tiled
462             // RT's will have appropriate alignment (given 4KB surface
463             // base and no mip-map support) and appropriate padding
464             // (due to tile padding). On BDW+, GMM uses H/VALIGN that
465             // will guarantee the MCS RT alignment for all subresources.
466 
467             // (2) ClearRect Alignment -- I.e. FastClears must be done
468             // with certain granularity:
469             //  TileY:  512 Bytes x 128 Lines
470             //  TileX: 1024 Bytes x  64 Lines
471             // So a CCS must be sized to match that granularity (though
472             // the RT itself need not be fully padded to that
473             // granularity to use FastClear).
474 
475             // (4) Non-MSAA CCS Sizing -- CCS sizing is based on the
476             // size of the FastClear (with granularity padding) for the
477             // paired RT. CCS's (byte widths and heights) are scaled
478             // down from their RT's by:
479             //  TileY: 32 x 32
480             //  TileX: 64 x 16
481 
482             // ### Example #############################################
483             // RT:         800x600, 32bpp, TileY
484             // 8bpp:      3200x600
485             // FastClear: 3584x640 (for TileY FastClear Granularity of 512x128)
486             // CCS:       112x20 (for TileY RT:CCS Sizing Downscale of 32x32)
487 
488             pTexInfo->Flags.Gpu.__NonMsaaTileYCcs = pTexInfo->Flags.Info.TiledY || pTexInfo->Flags.Info.TiledYf || pTexInfo->Flags.Info.TiledYs;
489             pTexInfo->Flags.Gpu.__NonMsaaTileXCcs = pTexInfo->Flags.Info.TiledX;
490         }
491         else
492         {
493             GMM_ASSERTDPF(0, "Illegal CCS creation parameters!");
494             Status = GMM_ERROR;
495         }
496     }
497     return Status;
498 }
499