xref: /aosp_15_r20/external/gmmlib/Source/GmmLib/ULT/GmmResourceULT.cpp (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
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 "GmmResourceULT.h"
24 
25 /////////////////////////////////////////////////////////////////////////////////////
26 /// CTestResource Constructor
27 /////////////////////////////////////////////////////////////////////////////////////
CTestResource()28 CTestResource::CTestResource()
29 {
30 }
31 
32 
33 /////////////////////////////////////////////////////////////////////////////////////
34 /// CTestResource Destructor
35 ///
36 /////////////////////////////////////////////////////////////////////////////////////
~CTestResource()37 CTestResource::~CTestResource()
38 {
39 }
40 
41 /////////////////////////////////////////////////////////////////////////////////////
42 /// Sets up common environment for Resource fixture tests. this is called once per
43 /// test case before executing all tests under resource fixture test case.
44 ///  It also calls SetupTestCase from CommonULT to initialize global context and others.
45 ///
46 /// @see    CTestResource::SetUpTestCase()
47 ///
48 /////////////////////////////////////////////////////////////////////////////////////
SetUpTestCase()49 void CTestResource::SetUpTestCase()
50 {
51     printf("%s\n", __FUNCTION__);
52 
53     GfxPlatform.eProductFamily    = IGFX_BROADWELL;
54     GfxPlatform.eRenderCoreFamily = IGFX_GEN8_CORE;
55 
56     CommonULT::SetUpTestCase();
57 }
58 
59 /////////////////////////////////////////////////////////////////////////////////////
60 /// Cleans up once all the tests finish execution.  It also calls TearDownTestCase
61 /// from CommonULT to destroy global context and others.
62 ///
63 /// @see    CTestResource::TearDownTestCase()
64 /////////////////////////////////////////////////////////////////////////////////////
TearDownTestCase()65 void CTestResource::TearDownTestCase()
66 {
67     printf("%s\n", __FUNCTION__);
68 
69     CommonULT::TearDownTestCase();
70 }
71 
72 /// @brief ULT for 1D Linear Resource
TEST_F(CTestResource,Test1DLinearResource)73 TEST_F(CTestResource, Test1DLinearResource)
74 {
75     // Horizontal/Vertical pixel alignment
76     const uint32_t HAlign         = 16;
77     const uint32_t VAlign         = 4;
78     const uint32_t MinPitch       = 32;
79     const uint32_t PitchAlignment = 64;
80 
81     GMM_RESCREATE_PARAMS gmmParams = {};
82     gmmParams.Type                 = RESOURCE_1D;
83     gmmParams.NoGfxMemory          = 1;
84     gmmParams.Flags.Info.Linear    = 1;
85     gmmParams.Flags.Gpu.Texture    = 1;
86 
87     // Allocate 1x1x1 surface
88     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
89     {
90         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
91         gmmParams.Format      = SetResourceFormat(bpp);
92         gmmParams.BaseWidth64 = 0x1;
93         gmmParams.BaseHeight  = 0x1;
94 
95         GMM_RESOURCE_INFO *ResourceInfo;
96         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
97 
98         uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
99         uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
100         uint32_t PitchInBytes  = AlignedWidth * GetBppValue(bpp);
101         PitchInBytes           = GFX_MAX(PitchInBytes, MinPitch);
102         PitchInBytes           = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
103         uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
104 
105         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
106         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
107         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
108         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
109         VerifyResourceQPitch<false>(ResourceInfo, 0); // Not valid for 1D
110 
111         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
112     }
113 
114 
115     // Allocate more than 1 page
116     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
117     {
118         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
119         gmmParams.Format      = SetResourceFormat(bpp);
120         gmmParams.BaseWidth64 = 0x1001;
121         gmmParams.BaseHeight  = 1;
122 
123         GMM_RESOURCE_INFO *ResourceInfo;
124         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
125 
126         uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
127         uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
128         uint32_t PitchInBytes  = AlignedWidth * GetBppValue(bpp);
129         PitchInBytes           = GFX_MAX(PitchInBytes, MinPitch);
130         PitchInBytes           = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
131         uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
132 
133         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
134         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
135         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
136         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
137         VerifyResourceQPitch<false>(ResourceInfo, 0);
138 
139         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
140     }
141 }
142 
143 /// @brief ULT for 1D Linear Resource Arrays
TEST_F(CTestResource,Test1DLinearResourceArrays)144 TEST_F(CTestResource, Test1DLinearResourceArrays)
145 {
146     // Horizontal/Vertical pixel alignment
147     const uint32_t HAlign         = 16;
148     const uint32_t VAlign         = 4;
149     const uint32_t MinPitch       = 32;
150     const uint32_t PitchAlignment = 64;
151 
152     GMM_RESCREATE_PARAMS gmmParams = {};
153     gmmParams.Type                 = RESOURCE_1D;
154     gmmParams.NoGfxMemory          = 1;
155     gmmParams.Flags.Info.Linear    = 1;
156     gmmParams.Flags.Gpu.Texture    = 1;
157     gmmParams.ArraySize            = 4;
158 
159     // Allocate 1x1x1 surface
160     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
161     {
162         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
163         gmmParams.Format      = SetResourceFormat(bpp);
164         gmmParams.BaseWidth64 = 0x100;
165         gmmParams.BaseHeight  = 0x1;
166 
167         GMM_RESOURCE_INFO *ResourceInfo;
168         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
169 
170         uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
171         uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
172         uint32_t PitchInBytes  = AlignedWidth * GetBppValue(bpp);
173         PitchInBytes           = GFX_MAX(PitchInBytes, MinPitch);
174         PitchInBytes           = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
175         uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight * gmmParams.ArraySize, PAGE_SIZE);
176 
177         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
178         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
179         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
180         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
181         VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight);
182 
183         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
184     }
185 }
186 
187 /// @brief ULT for 1D Mipped Linear Resource
TEST_F(CTestResource,Test1DLinearResourceMips)188 TEST_F(CTestResource, Test1DLinearResourceMips)
189 {
190     // Horizontal/Vertical pixel alignment
191     const uint32_t HAlign         = 16;
192     const uint32_t VAlign         = 4;
193     const uint32_t MinPitch       = 32;
194     const uint32_t PitchAlignment = 64;
195 
196     GMM_RESCREATE_PARAMS gmmParams = {};
197     gmmParams.Type                 = RESOURCE_1D;
198     gmmParams.NoGfxMemory          = 1;
199     gmmParams.Flags.Info.Linear    = 1;
200     gmmParams.Flags.Gpu.Texture    = 1;
201     gmmParams.MaxLod               = 5;
202 
203     // Allocate 256x1 surface
204     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
205     {
206         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
207         gmmParams.Format      = SetResourceFormat(bpp);
208         gmmParams.BaseWidth64 = 0x100;
209         gmmParams.BaseHeight  = 0x1;
210 
211         GMM_RESOURCE_INFO *ResourceInfo;
212         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
213 
214         uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
215         uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
216         // Height of 1D surface will just be VAlign. So height of the whole block will be
217         // Height of Mip0 + Mip2 + Mip3 + Mip4 + Mip5...
218         AlignedHeight         = gmmParams.MaxLod * AlignedHeight;
219         uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
220         PitchInBytes          = GFX_MAX(PitchInBytes, MinPitch);
221         PitchInBytes          = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
222         uint32_t AlignedSize  = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
223 
224         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
225         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
226         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
227         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
228         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed surface
229 
230         // Mip0 should be at offset 0. X/Y/Z Offset should be 0 for linear.
231         GMM_REQ_OFFSET_INFO OffsetInfo = {};
232         OffsetInfo.ReqRender           = 1;
233         OffsetInfo.MipLevel            = 0; //Mip 0
234         ResourceInfo->GetOffset(OffsetInfo);
235         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
236         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
237         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
238         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
239 
240         // Mip1 should be after Mip0.  X/Y/Z Offset should be 0 for linear.
241         OffsetInfo           = {};
242         OffsetInfo.ReqRender = 1;
243         OffsetInfo.MipLevel  = 1; //Mip 1
244         ResourceInfo->GetOffset(OffsetInfo);
245         uint32_t SizeOfMip0 = PitchInBytes * GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
246         EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
247         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
248         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
249         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
250 
251         // Mip2 should to the right of Mip1.  X/Y/Z Offset should be 0 for linear.
252         OffsetInfo           = {};
253         OffsetInfo.ReqRender = 1;
254         OffsetInfo.MipLevel  = 2; //Mip 2
255         ResourceInfo->GetOffset(OffsetInfo);
256         uint32_t StartOfMip = SizeOfMip0 + (GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 1, HAlign) * GetBppValue(bpp));
257         EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
258         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
259         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
260         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
261 
262         // Rest of the mips should be below mip2, each with height of HAlign. X/Y/Z Offset should be 0 for linear.
263         for(int mip = 3; mip <= gmmParams.MaxLod; mip++)
264         {
265             OffsetInfo           = {};
266             OffsetInfo.ReqRender = 1;
267             OffsetInfo.MipLevel  = mip;
268             ResourceInfo->GetOffset(OffsetInfo);
269             StartOfMip += PitchInBytes * VAlign;
270             EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
271             EXPECT_EQ(0, OffsetInfo.Render.XOffset);
272             EXPECT_EQ(0, OffsetInfo.Render.YOffset);
273             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
274         }
275 
276         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
277     }
278 }
279 
280 
281 // ********************************************************************************//
282 
283 /// @brief ULT for 2D Linear Resource Arrays
TEST_F(CTestResource,Test2DLinearResourceArrays)284 TEST_F(CTestResource, Test2DLinearResourceArrays)
285 {
286     // Horizontal/Vertical pixel alignment
287     const uint32_t HAlign         = 16;
288     const uint32_t VAlign         = 4;
289     const uint32_t MinPitch       = 32;
290     const uint32_t PitchAlignment = 64;
291 
292     GMM_RESCREATE_PARAMS gmmParams = {};
293     gmmParams.Type                 = RESOURCE_2D;
294     gmmParams.NoGfxMemory          = 1;
295     gmmParams.Flags.Info.Linear    = 1;
296     gmmParams.Flags.Gpu.Texture    = 1;
297     gmmParams.ArraySize            = 4;
298 
299     // Allocate 256x256 surface
300     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
301     {
302         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
303         gmmParams.Format      = SetResourceFormat(bpp);
304         gmmParams.BaseWidth64 = 0x100;
305         gmmParams.BaseHeight  = 0x100;
306 
307         GMM_RESOURCE_INFO *ResourceInfo;
308         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
309 
310         uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
311         uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
312         uint32_t PitchInBytes  = AlignedWidth * GetBppValue(bpp);
313         PitchInBytes           = GFX_MAX(PitchInBytes, MinPitch);
314         PitchInBytes           = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
315         uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight * gmmParams.ArraySize, PAGE_SIZE);
316 
317         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
318         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
319         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
320         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
321         VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight);
322 
323         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
324     }
325 }
326 
327 /// @brief ULT for 2D Mipped Linear Resource
TEST_F(CTestResource,Test2DLinearResourceMips)328 TEST_F(CTestResource, Test2DLinearResourceMips)
329 {
330     // Horizontal/Vertical pixel alignment
331     const uint32_t HAlign         = 16;
332     const uint32_t VAlign         = 4;
333     const uint32_t MinPitch       = 32;
334     const uint32_t PitchAlignment = 64;
335 
336     GMM_RESCREATE_PARAMS gmmParams = {};
337     gmmParams.Type                 = RESOURCE_2D;
338     gmmParams.NoGfxMemory          = 1;
339     gmmParams.Flags.Info.Linear    = 1;
340     gmmParams.Flags.Gpu.Texture    = 1;
341     gmmParams.MaxLod               = 8;
342 
343     // Allocate 256x256 surface
344     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
345     {
346         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
347         gmmParams.Format      = SetResourceFormat(bpp);
348         gmmParams.BaseWidth64 = 0x100;
349         gmmParams.BaseHeight  = 0x100;
350 
351         GMM_RESOURCE_INFO *ResourceInfo;
352         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
353 
354         uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
355         uint32_t AlignedHeight;
356         uint32_t PitchInBytes    = AlignedWidth * GetBppValue(bpp);
357         PitchInBytes             = GFX_MAX(PitchInBytes, MinPitch);
358         PitchInBytes             = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
359         uint32_t HeightOfPrevMip = AlignedHeight = gmmParams.BaseHeight;
360 
361         // Mip0 should be at offset 0. X/Y/Z Offset should be 0 for linear.
362         GMM_REQ_OFFSET_INFO OffsetInfo = {};
363         OffsetInfo.ReqRender           = 1;
364         OffsetInfo.MipLevel            = 0; //Mip 0
365         ResourceInfo->GetOffset(OffsetInfo);
366         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
367         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
368         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
369         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
370 
371         // Mip1 should be after Mip0.  X/Y/Z Offset should be 0 for linear.
372         OffsetInfo           = {};
373         OffsetInfo.ReqRender = 1;
374         OffsetInfo.MipLevel  = 1; //Mip 1
375         ResourceInfo->GetOffset(OffsetInfo);
376         uint32_t SizeOfMip0 = PitchInBytes * GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
377         EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
378         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
379         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
380         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
381 
382         // Mip2 should to the right of Mip1.  X/Y/Z Offset should be 0 for linear.
383         OffsetInfo           = {};
384         OffsetInfo.ReqRender = 1;
385         OffsetInfo.MipLevel  = 2; //Mip 2
386         ResourceInfo->GetOffset(OffsetInfo);
387         uint32_t StartOfMip = SizeOfMip0 + (GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 1, HAlign) * GetBppValue(bpp));
388         EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
389         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
390         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
391         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
392 
393         // Rest of the mips should be below mip2, each with height of HAlign. X/Y/Z Offset should be 0 for linear.
394         for(int mip = 3; mip <= 8; mip++)
395         {
396             OffsetInfo           = {};
397             OffsetInfo.ReqRender = 1;
398             OffsetInfo.MipLevel  = mip;
399             ResourceInfo->GetOffset(OffsetInfo);
400             HeightOfPrevMip = GMM_ULT_ALIGN((gmmParams.BaseHeight >> (mip - 1)), VAlign);
401             AlignedHeight += HeightOfPrevMip;
402             StartOfMip += PitchInBytes * HeightOfPrevMip;
403             EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
404             EXPECT_EQ(0, OffsetInfo.Render.XOffset);
405             EXPECT_EQ(0, OffsetInfo.Render.YOffset);
406             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
407         }
408 
409         //Mip8 will go till Mip0Height + Mip1Height + VALIGN
410         AlignedHeight += VAlign;
411         uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
412 
413         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
414         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
415         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
416         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
417         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed surface
418 
419         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
420     }
421 }
422 
423 /// @brief ULT for Arrayed 2D TileX Resource
TEST_F(CTestResource,Test2DTileXResourceArrays)424 TEST_F(CTestResource, Test2DTileXResourceArrays)
425 {
426     // Horizontal/Vertical pixel alignment
427     const uint32_t HAlign = 16;
428     const uint32_t VAlign = 4;
429 
430     const uint32_t TileWidth  = 512;
431     const uint32_t TileHeight = 8;
432 
433     GMM_RESCREATE_PARAMS gmmParams = {};
434     gmmParams.Type                 = RESOURCE_2D;
435     gmmParams.NoGfxMemory          = 1;
436     gmmParams.Flags.Info.TiledX    = 1;
437     gmmParams.Flags.Gpu.Texture    = 1;
438     gmmParams.ArraySize            = 4;
439 
440     // Allocate 2 tiles in X/Y dimension
441     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
442     {
443         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
444         gmmParams.Format      = SetResourceFormat(bpp);
445         gmmParams.BaseWidth64 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
446         gmmParams.BaseHeight  = TileHeight + 1;                     // 1 row larger than 1 tile height
447 
448         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
449         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
450         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
451 
452         uint32_t AlignedHeight, BlockHeight;
453         BlockHeight   = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
454         AlignedHeight = GMM_ULT_ALIGN_NP2(BlockHeight * gmmParams.ArraySize, TileHeight);
455 
456         GMM_RESOURCE_INFO *ResourceInfo;
457         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
458 
459         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
460         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
461         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);                    // As wide as 2 tile
462         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth); // 2 tile wide
463         VerifyResourceSize<true>(ResourceInfo, PitchInBytes * AlignedHeight);     // 4 tile big x 4 array size
464 
465         VerifyResourceQPitch<true>(ResourceInfo, BlockHeight);
466 
467         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
468     }
469 }
470 
471 /// @brief ULT for Mipped 2D TileX Resource
TEST_F(CTestResource,Test2DTileXResourceMips)472 TEST_F(CTestResource, Test2DTileXResourceMips)
473 {
474     const uint32_t TileSize[2] = {512, 8};
475     enum Coords
476     {
477         X = 0,
478         Y = 1
479     };
480 
481     // Test normal mip case
482     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
483     {
484         const uint32_t ResourceWidth  = 0x400;
485         const uint32_t ResourceHeight = 0x400;
486         const uint32_t MaxLod         = 10;
487 
488 
489         TEST_BPP             bpp       = static_cast<TEST_BPP>(i);
490         GMM_RESCREATE_PARAMS gmmParams = {};
491         gmmParams.Type                 = RESOURCE_2D;
492         gmmParams.Flags.Info.TiledX    = 1;
493         gmmParams.NoGfxMemory          = 1;
494         gmmParams.Flags.Gpu.Texture    = 1;
495         gmmParams.BaseWidth64          = ResourceWidth;
496         gmmParams.BaseHeight           = ResourceHeight;
497         gmmParams.MaxLod               = MaxLod;
498         gmmParams.Format               = SetResourceFormat(bpp);
499 
500         // Create resource
501         GMM_RESOURCE_INFO *ResourceInfo;
502         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
503 
504         // Mip0 is the widest mip. So it will dictate the pitch of the whole surface
505         const uint32_t Pitch            = ResourceWidth * GetBppValue(bpp);
506         uint32_t       AllocationHeight = 0;
507 
508         // Mip0 should be at offset 0 and tile aligned
509         GMM_REQ_OFFSET_INFO OffsetInfo = {};
510         OffsetInfo.ReqRender           = 1;
511         OffsetInfo.MipLevel            = 0; //Mip 0
512         ResourceInfo->GetOffset(OffsetInfo);
513         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
514         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
515         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
516         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
517 
518         // Mip1 should be after whole Mip0. Should still be tile aligned.
519         OffsetInfo           = {};
520         OffsetInfo.ReqRender = 1;
521         OffsetInfo.MipLevel  = 1; // Mip 1
522         ResourceInfo->GetOffset(OffsetInfo);
523         uint32_t SizeOfMip0      = Pitch * ResourceHeight;
524         uint32_t HeightOfPrevMip = AllocationHeight = ResourceHeight;
525         EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
526         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
527         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
528         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
529 
530         // Mip2 should be on the right of Mip1. Should still be tile aligned.
531         OffsetInfo           = {};
532         OffsetInfo.ReqRender = 1;
533         OffsetInfo.MipLevel  = 2; // Mip 2
534         ResourceInfo->GetOffset(OffsetInfo);
535         // MipOffset = Mip1Offset + Mip1Width in tiles
536         uint32_t MipOffset = SizeOfMip0 + ((Pitch >> 1) / TileSize[X]) * PAGE_SIZE;
537         EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
538         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
539         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
540         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
541 
542         // Mips 3-8 should be on tile boundary
543         for(int i = 3; i < 9; i++)
544         {
545             OffsetInfo           = {};
546             OffsetInfo.ReqRender = 1;
547             OffsetInfo.MipLevel  = i;
548             ResourceInfo->GetOffset(OffsetInfo);
549 
550             HeightOfPrevMip = (ResourceHeight >> (i - 1));
551             AllocationHeight += HeightOfPrevMip;
552             MipOffset += Pitch * HeightOfPrevMip;
553             EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
554             // No X/Y/Z offset since mip is at tile boundary
555             EXPECT_EQ(0, OffsetInfo.Render.XOffset);
556             EXPECT_EQ(0, OffsetInfo.Render.YOffset);
557             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
558         }
559 
560         // Mips 9 will share 1 tile with Mip 8
561         AllocationHeight += TileSize[Y];
562         uint32_t HeightOfPrevMipsInTile = 0;
563         {
564             OffsetInfo           = {};
565             OffsetInfo.ReqRender = 1;
566             OffsetInfo.MipLevel  = 9;
567             ResourceInfo->GetOffset(OffsetInfo);
568 
569             EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64); // Same as previous tile aligned mip offset
570 
571             // X is 0, but Y offset will change
572             EXPECT_EQ(0, OffsetInfo.Render.XOffset);
573             HeightOfPrevMipsInTile += (ResourceHeight >> (9 - 1));
574             EXPECT_EQ(HeightOfPrevMipsInTile, OffsetInfo.Render.YOffset);
575             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
576         }
577 
578         // Mip 10 is back on tile boundary
579         OffsetInfo           = {};
580         OffsetInfo.ReqRender = 1;
581         OffsetInfo.MipLevel  = 10; // Mip 10
582         ResourceInfo->GetOffset(OffsetInfo);
583 
584         MipOffset += Pitch * TileSize[Y];
585         AllocationHeight += TileSize[Y];
586         EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
587         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
588         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
589         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
590 
591         // Verify ResourceSize and Pitch
592         VerifyResourceSize<true>(ResourceInfo, AllocationHeight * Pitch);
593         VerifyResourcePitch<true>(ResourceInfo, Pitch);
594         VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
595         // These are verified elsewhere
596         VerifyResourceHAlign<false>(ResourceInfo, 0);
597         VerifyResourceVAlign<false>(ResourceInfo, 0);
598         VerifyResourceQPitch<false>(ResourceInfo, 0);
599 
600         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
601     }
602 
603 
604     // Test where Mip1 + Mip2 width > Mip0 width, and where everything fits in 1 tile
605     for(uint32_t i = 0; i < TEST_BPP_64; i++)
606     {
607         const uint32_t ResourceWidth  = 0x4;
608         const uint32_t ResourceHeight = 0x2;
609         const uint32_t MaxLod         = 0x2;
610 
611         TEST_BPP             bpp       = static_cast<TEST_BPP>(i);
612         GMM_RESCREATE_PARAMS gmmParams = {};
613         gmmParams.Type                 = RESOURCE_2D;
614         gmmParams.Flags.Info.TiledX    = 1;
615         gmmParams.NoGfxMemory          = 1;
616         gmmParams.Flags.Gpu.Texture    = 1;
617         gmmParams.BaseWidth64          = ResourceWidth;
618         gmmParams.BaseHeight           = ResourceHeight;
619         gmmParams.MaxLod               = MaxLod;
620         gmmParams.Format               = SetResourceFormat(bpp);
621 
622         // Create resource
623         GMM_RESOURCE_INFO *ResourceInfo;
624         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
625 
626         // Get Alignment that GmmLib is using
627         const uint32_t HAlign = ResourceInfo->GetHAlign();
628         const uint32_t VAlign = ResourceInfo->GetVAlign();
629 
630         // Mip1 + Mip2 is the widest width. So it will dictate the pitch of the whole surface
631         uint32_t Pitch = GetBppValue(bpp) *
632                          (GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) + GMM_ULT_ALIGN(ResourceWidth >> 2, HAlign));
633         Pitch = GMM_ULT_ALIGN(Pitch, TileSize[X]);
634 
635         // Mip0 should be at offset 0 and tile aligned
636         GMM_REQ_OFFSET_INFO OffsetInfo = {};
637         OffsetInfo.ReqRender           = 1;
638         OffsetInfo.MipLevel            = 0; //Mip 0
639         ResourceInfo->GetOffset(OffsetInfo);
640         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
641         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
642         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
643         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
644 
645         // Mip1 should be after whole Mip0. Not tile aligned
646         OffsetInfo           = {};
647         OffsetInfo.ReqRender = 1;
648         OffsetInfo.MipLevel  = 1; // Mip 1
649         ResourceInfo->GetOffset(OffsetInfo);
650         EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same tile as Mip0
651         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
652         EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
653         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
654 
655         // Mip2 should be on the right of Mip1. Not tile aligned
656         OffsetInfo           = {};
657         OffsetInfo.ReqRender = 1;
658         OffsetInfo.MipLevel  = 2; // Mip 2
659         ResourceInfo->GetOffset(OffsetInfo);
660         EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same Tile as Mip0
661         uint32_t Mip1Width = GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) * GetBppValue(bpp);
662         EXPECT_EQ(Mip1Width, OffsetInfo.Render.XOffset);                             // On right of Mip1
663         EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
664         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
665 
666         // Verify ResourceSize and Pitch
667         VerifyResourceSize<true>(ResourceInfo, PAGE_SIZE); // everything should fit in 1 tile
668         VerifyResourcePitch<true>(ResourceInfo, Pitch);
669         VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
670         // These are verified elsewhere
671         VerifyResourceHAlign<false>(ResourceInfo, 0);
672         VerifyResourceVAlign<false>(ResourceInfo, 0);
673         VerifyResourceQPitch<false>(ResourceInfo, 0);
674 
675         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
676     }
677 }
678 
679 /// @brief ULT for 2D Linear Resource
TEST_F(CTestResource,Test2DLinearResource)680 TEST_F(CTestResource, Test2DLinearResource)
681 {
682     const uint32_t HAlign = 16;
683     const uint32_t VAlign = 4;
684 
685     GMM_RESCREATE_PARAMS gmmParams = {};
686     gmmParams.Type                 = RESOURCE_2D;
687     gmmParams.NoGfxMemory          = 1;
688     gmmParams.Flags.Info.Linear    = 1;
689     gmmParams.Flags.Gpu.Texture    = 1;
690 
691     //Allocate 1x1 surface
692     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
693     {
694         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
695         gmmParams.Format      = SetResourceFormat(bpp);
696         gmmParams.BaseWidth64 = 0x1;
697         gmmParams.BaseHeight  = 0x1;
698 
699         const uint32_t MinPitch       = 32;
700         const uint32_t PitchAlignment = 64;
701 
702         GMM_RESOURCE_INFO *ResourceInfo;
703         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
704 
705         const uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
706         const uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
707         uint32_t       PitchInBytes  = AlignedWidth * GetBppValue(bpp);
708         PitchInBytes                 = GMM_ULT_MAX(PitchInBytes, MinPitch);
709         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
710         const uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
711 
712         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
713         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
714         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
715         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
716 
717         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
718     }
719 
720     // Allocate 256 x 256
721     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
722     {
723         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
724         gmmParams.Format      = SetResourceFormat(bpp);
725         gmmParams.BaseWidth64 = 256;
726         gmmParams.BaseHeight  = 256;
727 
728         const uint32_t MinPitch       = 32;
729         const uint32_t PitchAlignment = 64;
730 
731         GMM_RESOURCE_INFO *ResourceInfo;
732         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
733 
734         const uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
735         const uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
736         uint32_t       PitchInBytes  = AlignedWidth * GetBppValue(bpp);
737         PitchInBytes                 = GMM_ULT_MAX(PitchInBytes, MinPitch);
738         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
739         const uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
740 
741         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
742         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
743         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
744         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
745 
746         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
747     }
748 }
749 
750 /// @brief ULT for 2D TileX Resource
TEST_F(CTestResource,Test2DTileXResource)751 TEST_F(CTestResource, Test2DTileXResource)
752 {
753     const uint32_t HAlign = 16;
754     const uint32_t VAlign = 4;
755 
756     const uint32_t TileWidth  = 512;
757     const uint32_t TileHeight = 8;
758 
759     GMM_RESCREATE_PARAMS gmmParams = {};
760     gmmParams.Type                 = RESOURCE_2D;
761     gmmParams.NoGfxMemory          = 1;
762     gmmParams.Flags.Info.TiledX    = 1;
763     gmmParams.Flags.Gpu.Texture    = 1;
764 
765     //Allocate 1x1 surface
766     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
767     {
768         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
769         gmmParams.Format      = SetResourceFormat(bpp);
770         gmmParams.BaseWidth64 = 0x1;
771         gmmParams.BaseHeight  = 0x1;
772 
773         GMM_RESOURCE_INFO *ResourceInfo;
774         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
775 
776         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
777         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
778         VerifyResourcePitch<true>(ResourceInfo, TileWidth);   // As wide as 1 Tile
779         VerifyResourcePitchInTiles<true>(ResourceInfo, 1);    // 1 Tile wide
780         VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4)); // 1 Tile Big
781         VerifyResourceQPitch<false>(ResourceInfo, 0);         // Not Tested
782 
783         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
784     }
785 
786     // Allocate surface that requires multi tiles in two dimension
787     // Allocate 2 tiles in X dimension
788     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
789     {
790         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
791         gmmParams.Format      = SetResourceFormat(bpp);
792         gmmParams.BaseWidth64 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
793         gmmParams.BaseHeight  = 0x1;
794 
795         GMM_RESOURCE_INFO *ResourceInfo;
796         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
797 
798         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
799         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
800         VerifyResourcePitch<true>(ResourceInfo, TileWidth * 2);   // As wide as 2 tile
801         VerifyResourcePitchInTiles<true>(ResourceInfo, 2);        // 2 tile wide
802         VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4) * 2); // 2 tile big
803 
804         VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
805 
806         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
807     }
808 
809     // Allocate 2 tiles in X/Y dimension
810     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
811     {
812         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
813         gmmParams.Format      = SetResourceFormat(bpp);
814         gmmParams.BaseWidth64 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
815         gmmParams.BaseHeight  = TileHeight + 1;                     // 1 row larger than 1 tile height
816 
817         GMM_RESOURCE_INFO *ResourceInfo;
818         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
819 
820         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
821         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
822         VerifyResourcePitch<true>(ResourceInfo, TileWidth * 2);   // As wide as 2 tile
823         VerifyResourcePitchInTiles<true>(ResourceInfo, 2);        // 2 tile wide
824         VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4) * 4); // 4 tile big
825 
826         VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
827 
828         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
829     }
830 }
831 
832 /// @brief ULT for 2D TileY Resource
TEST_F(CTestResource,Test2DTileYResource)833 TEST_F(CTestResource, Test2DTileYResource)
834 {
835     const uint32_t HAlign = 16;
836     const uint32_t VAlign = 4;
837 
838     const uint32_t TileWidth  = 128;
839     const uint32_t TileHeight = 32;
840 
841     GMM_RESCREATE_PARAMS gmmParams = {};
842     gmmParams.Type                 = RESOURCE_2D;
843     gmmParams.NoGfxMemory          = 1;
844     gmmParams.Flags.Info.TiledY    = 1;
845     gmmParams.Flags.Gpu.Texture    = 1;
846 
847     //Allocate 1x1 surface
848     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
849     {
850         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
851         gmmParams.Format      = SetResourceFormat(bpp);
852         gmmParams.BaseWidth64 = 0x1;
853         gmmParams.BaseHeight  = 0x1;
854 
855         const uint32_t MinPitch       = 32;
856         const uint32_t PitchAlignment = 32;
857 
858         GMM_RESOURCE_INFO *ResourceInfo;
859         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
860 
861         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
862         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
863         PitchInBytes                = GMM_ULT_MAX(PitchInBytes, MinPitch);
864         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
865         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
866 
867         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
868         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
869         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
870         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
871         VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileWidth * GMM_KBYTE(4));
872         VerifyResourceQPitch<false>(ResourceInfo, 0); // Not Tested
873 
874         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
875     }
876 
877     // Allocate surface that requires multi tiles in two dimension
878     // Allocate 2 tiles in X dimension
879     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
880     {
881         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
882         gmmParams.Format      = SetResourceFormat(bpp);
883         gmmParams.BaseWidth64 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
884         gmmParams.BaseHeight  = 0x1;
885 
886         const uint32_t MinPitch       = 32;
887         const uint32_t PitchAlignment = 32;
888 
889         GMM_RESOURCE_INFO *ResourceInfo;
890         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
891 
892         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
893         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
894         PitchInBytes                = GMM_ULT_MAX(PitchInBytes, MinPitch);
895         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
896         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
897 
898         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
899         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
900         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
901         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
902         VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileWidth * GMM_KBYTE(4));
903 
904         VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
905 
906         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
907     }
908 
909     // Allocate 2 tiles in X/Y dimension
910     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
911     {
912         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
913         gmmParams.Format      = SetResourceFormat(bpp);
914         gmmParams.BaseWidth64 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
915         gmmParams.BaseHeight  = TileHeight + 1;                     // 1 row larger than 1 tile height
916 
917         const uint32_t MinPitch       = 32;
918         const uint32_t PitchAlignment = 32;
919 
920         GMM_RESOURCE_INFO *ResourceInfo;
921         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
922 
923         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
924         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
925         PitchInBytes                = GMM_ULT_MAX(PitchInBytes, MinPitch);
926         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
927         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
928 
929         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
930         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
931         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
932         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
933         VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileWidth * 2 * GMM_KBYTE(4));
934 
935         VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
936 
937         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
938     }
939 }
940 
941 /// @brief ULT for Arrayed 2D TileY Resource
TEST_F(CTestResource,Test2DTileYResourceArrays)942 TEST_F(CTestResource, Test2DTileYResourceArrays)
943 {
944     // Horizontal/Vertical pixel alignment
945     const uint32_t HAlign = 16;
946     const uint32_t VAlign = 4;
947 
948     const uint32_t TileWidth  = 128;
949     const uint32_t TileHeight = 32;
950 
951     GMM_RESCREATE_PARAMS gmmParams = {};
952     gmmParams.Type                 = RESOURCE_2D;
953     gmmParams.NoGfxMemory          = 1;
954     gmmParams.Flags.Info.TiledY    = 1;
955     gmmParams.Flags.Gpu.Texture    = 1;
956     gmmParams.ArraySize            = 4;
957 
958     // Allocate 2 tiles in X/Y dimension
959     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
960     {
961         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
962         gmmParams.Format      = SetResourceFormat(bpp);
963         gmmParams.BaseWidth64 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
964         gmmParams.BaseHeight  = TileHeight + 1;                     // 1 row larger than 1 tile height
965         uint32_t AlignedHeight, BlockHeight;
966 
967         BlockHeight   = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
968         AlignedHeight = GMM_ULT_ALIGN_NP2(BlockHeight * gmmParams.ArraySize, TileHeight);
969 
970         GMM_RESOURCE_INFO *ResourceInfo;
971         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
972 
973         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
974         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
975         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
976 
977         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
978         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
979         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
980         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
981         VerifyResourceSize<true>(ResourceInfo, PitchInBytes * AlignedHeight); // 4 tile big x 4 array size
982         VerifyResourceQPitch<true>(ResourceInfo, BlockHeight);
983 
984         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
985     }
986 }
987 
988 /// @brief ULT for Mipped 2D TileY Resource
TEST_F(CTestResource,Test2DTileYResourceMips)989 TEST_F(CTestResource, Test2DTileYResourceMips)
990 {
991     const uint32_t TileSize[2] = {128, 32};
992     enum Coords
993     {
994         X = 0,
995         Y = 1
996     };
997 
998     // Test normal mip case
999     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1000     {
1001         const uint32_t ResourceWidth  = 0x200;
1002         const uint32_t ResourceHeight = 0x200;
1003         const uint32_t MaxLod         = 0x9;
1004 
1005 
1006         TEST_BPP             bpp       = static_cast<TEST_BPP>(i);
1007         GMM_RESCREATE_PARAMS gmmParams = {};
1008         gmmParams.Type                 = RESOURCE_2D;
1009         gmmParams.Flags.Info.TiledY    = 1;
1010         gmmParams.NoGfxMemory          = 1;
1011         gmmParams.Flags.Gpu.Texture    = 1;
1012         gmmParams.BaseWidth64          = ResourceWidth;
1013         gmmParams.BaseHeight           = ResourceHeight;
1014         gmmParams.MaxLod               = MaxLod;
1015         gmmParams.Format               = SetResourceFormat(bpp);
1016 
1017         // Create resource
1018         GMM_RESOURCE_INFO *ResourceInfo;
1019         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1020 
1021         // Mip0 is the widest mip. So it will dictate the pitch of the whole surface
1022         const uint32_t Pitch            = ResourceWidth * GetBppValue(bpp);
1023         uint32_t       AllocationHeight = 0;
1024 
1025         // Mip0 should be at offset 0 and tile aligned
1026         GMM_REQ_OFFSET_INFO OffsetInfo = {};
1027         OffsetInfo.ReqRender           = 1;
1028         OffsetInfo.MipLevel            = 0; //Mip 0
1029         ResourceInfo->GetOffset(OffsetInfo);
1030         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
1031         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1032         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1033         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1034 
1035         // Mip1 should be after whole Mip0. Should still be tile aligned.
1036         OffsetInfo           = {};
1037         OffsetInfo.ReqRender = 1;
1038         OffsetInfo.MipLevel  = 1; // Mip 1
1039         ResourceInfo->GetOffset(OffsetInfo);
1040         uint32_t SizeOfMip0      = Pitch * ResourceHeight;
1041         uint32_t HeightOfPrevMip = AllocationHeight = ResourceHeight;
1042         EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
1043         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1044         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1045         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1046 
1047         // Mip2 should be on the right of Mip1. Should still be tile aligned.
1048         OffsetInfo           = {};
1049         OffsetInfo.ReqRender = 1;
1050         OffsetInfo.MipLevel  = 2; // Mip 2
1051         ResourceInfo->GetOffset(OffsetInfo);
1052         // MipOffset = Mip1Offset + Mip1Width in tiles
1053         uint32_t MipOffset = SizeOfMip0 + ((Pitch >> 1) / TileSize[X]) * PAGE_SIZE;
1054         EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
1055         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1056         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1057         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1058 
1059         // Mips 3-5 should be on tile boundary
1060         for(int i = 3; i < 6; i++)
1061         {
1062             OffsetInfo           = {};
1063             OffsetInfo.ReqRender = 1;
1064             OffsetInfo.MipLevel  = i;
1065             ResourceInfo->GetOffset(OffsetInfo);
1066 
1067             HeightOfPrevMip = (ResourceHeight >> (i - 1));
1068             AllocationHeight += HeightOfPrevMip;
1069             MipOffset += Pitch * HeightOfPrevMip;
1070             EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
1071             // No X/Y/Z offset since mip is at tile boundary
1072             EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1073             EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1074             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1075         }
1076 
1077         // Mips 6-8 will share 1 tile
1078         AllocationHeight += TileSize[Y];
1079         uint32_t HeightOfPrevMipsInTile = 0;
1080         for(int i = 6; i < 9; i++)
1081         {
1082             OffsetInfo           = {};
1083             OffsetInfo.ReqRender = 1;
1084             OffsetInfo.MipLevel  = i;
1085             ResourceInfo->GetOffset(OffsetInfo);
1086 
1087             EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64); // Same as previous tile aligned mip offset
1088 
1089             // X is 0, but Y offset will change
1090             EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1091             HeightOfPrevMipsInTile += (ResourceHeight >> (i - 1));
1092             EXPECT_EQ(HeightOfPrevMipsInTile, OffsetInfo.Render.YOffset);
1093             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1094         }
1095 
1096         // Mip 9 is back on tile boundary
1097         OffsetInfo           = {};
1098         OffsetInfo.ReqRender = 1;
1099         OffsetInfo.MipLevel  = 9; // Mip 9
1100         ResourceInfo->GetOffset(OffsetInfo);
1101 
1102         MipOffset += Pitch * TileSize[Y];
1103         AllocationHeight += TileSize[Y];
1104         EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
1105         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1106         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1107         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1108 
1109         // Verify ResourceSize and Pitch
1110         VerifyResourceSize<true>(ResourceInfo, AllocationHeight * Pitch);
1111         VerifyResourcePitch<true>(ResourceInfo, Pitch);
1112         VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
1113         // These are verified elsewhere
1114         VerifyResourceHAlign<false>(ResourceInfo, 0);
1115         VerifyResourceVAlign<false>(ResourceInfo, 0);
1116         VerifyResourceQPitch<false>(ResourceInfo, 0);
1117 
1118         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1119     }
1120 
1121 
1122     // Test where Mip1 + Mip2 width > Mip0 width, and where everything fits in 1 tile
1123     for(uint32_t i = 0; i < TEST_BPP_64; i++)
1124     {
1125         const uint32_t ResourceWidth  = 0x4;
1126         const uint32_t ResourceHeight = 0x2;
1127         const uint32_t MaxLod         = 0x2;
1128 
1129         TEST_BPP             bpp       = static_cast<TEST_BPP>(i);
1130         GMM_RESCREATE_PARAMS gmmParams = {};
1131         gmmParams.Type                 = RESOURCE_2D;
1132         gmmParams.Flags.Info.TiledY    = 1;
1133         gmmParams.NoGfxMemory          = 1;
1134         gmmParams.Flags.Gpu.Texture    = 1;
1135         gmmParams.BaseWidth64          = ResourceWidth;
1136         gmmParams.BaseHeight           = ResourceHeight;
1137         gmmParams.MaxLod               = MaxLod;
1138         gmmParams.Format               = SetResourceFormat(bpp);
1139 
1140         // Create resource
1141         GMM_RESOURCE_INFO *ResourceInfo;
1142         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1143 
1144         // Get Alignment that GmmLib is using
1145         const uint32_t HAlign = ResourceInfo->GetHAlign();
1146         const uint32_t VAlign = ResourceInfo->GetVAlign();
1147 
1148         // Mip1 + Mip2 is the widest width. So it will dictate the pitch of the whole surface
1149         uint32_t Pitch = GetBppValue(bpp) *
1150                          (GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) + GMM_ULT_ALIGN(ResourceWidth >> 2, HAlign));
1151         Pitch = GMM_ULT_ALIGN(Pitch, TileSize[X]);
1152 
1153         // Mip0 should be at offset 0 and tile aligned
1154         GMM_REQ_OFFSET_INFO OffsetInfo = {};
1155         OffsetInfo.ReqRender           = 1;
1156         OffsetInfo.MipLevel            = 0; //Mip 0
1157         ResourceInfo->GetOffset(OffsetInfo);
1158         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
1159         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1160         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1161         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1162 
1163         // Mip1 should be after whole Mip0. Not tile aligned
1164         OffsetInfo           = {};
1165         OffsetInfo.ReqRender = 1;
1166         OffsetInfo.MipLevel  = 1; // Mip 1
1167         ResourceInfo->GetOffset(OffsetInfo);
1168         EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same tile as Mip0
1169         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1170         EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
1171         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1172 
1173         // Mip2 should be on the right of Mip1. Not tile aligned
1174         OffsetInfo           = {};
1175         OffsetInfo.ReqRender = 1;
1176         OffsetInfo.MipLevel  = 2; // Mip 2
1177         ResourceInfo->GetOffset(OffsetInfo);
1178         EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same Tile as Mip0
1179         uint32_t Mip1Width = GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) * GetBppValue(bpp);
1180         EXPECT_EQ(Mip1Width, OffsetInfo.Render.XOffset);                             // On right of Mip1
1181         EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
1182         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1183 
1184         // Verify ResourceSize and Pitch
1185         VerifyResourceSize<true>(ResourceInfo, PAGE_SIZE); // everything should fit in 1 tile
1186         VerifyResourcePitch<true>(ResourceInfo, Pitch);
1187         VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
1188         // These are verified elsewhere
1189         VerifyResourceHAlign<false>(ResourceInfo, 0);
1190         VerifyResourceVAlign<false>(ResourceInfo, 0);
1191         VerifyResourceQPitch<false>(ResourceInfo, 0);
1192 
1193         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1194     }
1195 }
1196 
1197 // ********************************************************************************//
1198 
1199 /// @brief ULT for 3D Linear Resource
TEST_F(CTestResource,Test3DLinearResource)1200 TEST_F(CTestResource, Test3DLinearResource)
1201 {
1202     // Horizontal/Vertical pixel alignment
1203     const uint32_t HAlign = 16;
1204     const uint32_t VAlign = 4;
1205 
1206     GMM_RESCREATE_PARAMS gmmParams = {};
1207     gmmParams.Type                 = RESOURCE_3D;
1208     gmmParams.NoGfxMemory          = 1;
1209     gmmParams.Flags.Info.Linear    = 1;
1210     gmmParams.Flags.Gpu.Texture    = 1;
1211 
1212     // Allocate 1x1x1 surface
1213     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1214     {
1215         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1216         gmmParams.Format      = SetResourceFormat(bpp);
1217         gmmParams.BaseWidth64 = 0x1;
1218         gmmParams.BaseHeight  = 0x1;
1219         gmmParams.Depth       = 0x1;
1220 
1221         const uint32_t MinPitch       = 32;
1222         const uint32_t PitchAlignment = 32;
1223 
1224         GMM_RESOURCE_INFO *ResourceInfo;
1225         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1226 
1227         const uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1228         const uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
1229         uint32_t       PitchInBytes  = AlignedWidth * GetBppValue(bpp);
1230         PitchInBytes                 = GFX_MAX(PitchInBytes, MinPitch);
1231         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1232         const uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
1233 
1234         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1235         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1236         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1237         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
1238 
1239         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1240     }
1241 
1242     // Allocate 256 x 256 x 256
1243     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1244     {
1245         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1246         gmmParams.Format      = SetResourceFormat(bpp);
1247         gmmParams.BaseWidth64 = 256;
1248         gmmParams.BaseHeight  = 256;
1249         gmmParams.Depth       = 256;
1250 
1251         const uint32_t MinPitch       = 32;
1252         const uint32_t PitchAlignment = 32;
1253 
1254         GMM_RESOURCE_INFO *ResourceInfo;
1255         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1256 
1257         const uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1258         const uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
1259         uint32_t       PitchInBytes  = AlignedWidth * GetBppValue(bpp);
1260         PitchInBytes                 = GFX_MAX(PitchInBytes, MinPitch);
1261         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1262         const uint32_t AlignedSize   = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight * gmmParams.Depth, PAGE_SIZE);
1263 
1264         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1265         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1266         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1267         VerifyResourceSize<true>(ResourceInfo, AlignedSize);
1268 
1269         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1270     }
1271 }
1272 
1273 /// @brief ULT for 3D TileX Resource
TEST_F(CTestResource,Test3DTileXResource)1274 TEST_F(CTestResource, Test3DTileXResource)
1275 {
1276     const uint32_t HAlign                    = 16;
1277     const uint32_t VAlign                    = 4;
1278     const uint32_t TileSize[TEST_BPP_MAX][3] = {{512, 8, 1},
1279                                                 {512, 8, 1},
1280                                                 {512, 8, 1},
1281                                                 {512, 8, 1},
1282                                                 {512, 8, 1}};
1283 
1284     GMM_RESCREATE_PARAMS gmmParams = {};
1285     gmmParams.Type                 = RESOURCE_3D;
1286     gmmParams.NoGfxMemory          = 1;
1287     gmmParams.Flags.Info.TiledX    = 1;
1288     gmmParams.Flags.Gpu.Texture    = 1;
1289 
1290     // Allocate 1x1x1 surface
1291     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1292     {
1293         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1294         gmmParams.Format      = SetResourceFormat(bpp);
1295         gmmParams.BaseWidth64 = 0x1;
1296         gmmParams.BaseHeight  = 0x1;
1297         gmmParams.Depth       = 0x1;
1298 
1299         GMM_RESOURCE_INFO *ResourceInfo;
1300         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1301 
1302         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1303         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1304         VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0]);
1305         VerifyResourcePitchInTiles<true>(ResourceInfo, 1);
1306         VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4));
1307 
1308         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1309     }
1310 
1311     // Allocate 2 tiles in X dimension
1312     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1313     {
1314         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1315         gmmParams.Format      = SetResourceFormat(bpp);
1316         gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
1317         gmmParams.BaseHeight  = 0x1;
1318         gmmParams.Depth       = 0x1;
1319 
1320         GMM_RESOURCE_INFO *ResourceInfo;
1321         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1322 
1323         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1324         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1325         VerifyResourcePitch<true>(ResourceInfo, 2 * TileSize[i][0]);
1326         VerifyResourcePitchInTiles<true>(ResourceInfo, 2);
1327         VerifyResourceSize<true>(ResourceInfo, 2 * GMM_KBYTE(4));
1328 
1329         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1330     }
1331 
1332     // Allocate 2 tiles in X/Y dimension
1333     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1334     {
1335         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1336         gmmParams.Format      = SetResourceFormat(bpp);
1337         gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
1338         gmmParams.BaseHeight  = TileSize[i][1] + 1;
1339         gmmParams.Depth       = 0x1;
1340 
1341         GMM_RESOURCE_INFO *ResourceInfo;
1342         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1343 
1344         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1345         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1346         VerifyResourcePitch<true>(ResourceInfo, 2 * TileSize[i][0]);
1347         VerifyResourcePitchInTiles<true>(ResourceInfo, 2);
1348         VerifyResourceSize<true>(ResourceInfo, 2 * 2 * GMM_KBYTE(4));
1349 
1350         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1351     }
1352 
1353     // Allocate 2 tiles in X/Y/Z dimension
1354     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1355     {
1356         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1357         gmmParams.Format      = SetResourceFormat(bpp);
1358         gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
1359         gmmParams.BaseHeight  = TileSize[i][1] + 1;
1360         gmmParams.Depth       = TileSize[i][2] + 1;
1361 
1362         const uint32_t MinPitch       = 32;
1363         const uint32_t PitchAlignment = 32;
1364 
1365         GMM_RESOURCE_INFO *ResourceInfo;
1366         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1367 
1368         const uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1369         uint32_t       PitchInBytes  = AlignedWidth * GetBppValue(bpp);
1370         PitchInBytes                 = GFX_MAX(PitchInBytes, MinPitch);
1371         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1372         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
1373         const uint32_t AlignedHeight = 24; // See details in GetTotal3DHeight();
1374 
1375         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1376         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1377         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1378         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
1379         VerifyResourceSize<true>(ResourceInfo, AlignedHeight / TileSize[i][1] * PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
1380 
1381         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1382     }
1383 }
1384 
1385 /// @brief ULT for 3D TileY Resource
TEST_F(CTestResource,Test3DTileYResource)1386 TEST_F(CTestResource, Test3DTileYResource)
1387 {
1388     // Horizontal/Vertical pixel alignment
1389     const uint32_t HAlign                    = 16;
1390     const uint32_t VAlign                    = 4;
1391     const uint32_t TileSize[TEST_BPP_MAX][3] = {{128, 32, 1},
1392                                                 {128, 32, 1},
1393                                                 {128, 32, 1},
1394                                                 {128, 32, 1},
1395                                                 {128, 32, 1}};
1396 
1397     GMM_RESCREATE_PARAMS gmmParams = {};
1398     gmmParams.Type                 = RESOURCE_3D;
1399     gmmParams.NoGfxMemory          = 1;
1400     gmmParams.Flags.Info.TiledY    = 1;
1401     gmmParams.Flags.Gpu.Texture    = 1;
1402 
1403     // Allocate 1x1x1 surface
1404     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1405     {
1406         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1407         gmmParams.Format      = SetResourceFormat(bpp);
1408         gmmParams.BaseWidth64 = 0x1;
1409         gmmParams.BaseHeight  = 0x1;
1410         gmmParams.Depth       = 0x1;
1411 
1412         const uint32_t MinPitch       = 32;
1413         const uint32_t PitchAlignment = 32;
1414 
1415         GMM_RESOURCE_INFO *ResourceInfo;
1416         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1417 
1418         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1419         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
1420         PitchInBytes                = GFX_MAX(PitchInBytes, MinPitch);
1421         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1422         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
1423 
1424         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1425         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1426         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1427         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
1428         VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
1429 
1430         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1431     }
1432 
1433     // Allocate 2 tiles in X dimension
1434     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1435     {
1436         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1437         gmmParams.Format      = SetResourceFormat(bpp);
1438         gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
1439         gmmParams.BaseHeight  = 0x1;
1440         gmmParams.Depth       = 0x1;
1441 
1442         const uint32_t MinPitch       = 32;
1443         const uint32_t PitchAlignment = 32;
1444 
1445         GMM_RESOURCE_INFO *ResourceInfo;
1446         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1447 
1448         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1449         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
1450         PitchInBytes                = GFX_MAX(PitchInBytes, MinPitch);
1451         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1452         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
1453 
1454         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1455         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1456         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1457         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
1458         VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
1459 
1460         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1461     }
1462 
1463     // Allocate 2 tiles in X/Y dimension
1464     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1465     {
1466         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1467         gmmParams.Format      = SetResourceFormat(bpp);
1468         gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
1469         gmmParams.BaseHeight  = TileSize[i][1] + 1;
1470         gmmParams.Depth       = 0x1;
1471 
1472         const uint32_t MinPitch       = 32;
1473         const uint32_t PitchAlignment = 32;
1474 
1475         GMM_RESOURCE_INFO *ResourceInfo;
1476         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1477 
1478         const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1479         uint32_t       PitchInBytes = AlignedWidth * GetBppValue(bpp);
1480         PitchInBytes                = GFX_MAX(PitchInBytes, MinPitch);
1481         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1482         PitchInBytes                = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
1483 
1484         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1485         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1486         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1487         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
1488         VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * 2 * GMM_KBYTE(4));
1489 
1490         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1491     }
1492 
1493     // Allocate 2 tiles in X/Y/Z dimension
1494     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1495     {
1496         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1497         gmmParams.Format      = SetResourceFormat(bpp);
1498         gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
1499         gmmParams.BaseHeight  = TileSize[i][1] + 1;
1500         gmmParams.Depth       = TileSize[i][2] + 1;
1501 
1502         const uint32_t MinPitch       = 32;
1503         const uint32_t PitchAlignment = 32;
1504 
1505         GMM_RESOURCE_INFO *ResourceInfo;
1506         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1507 
1508         const uint32_t AlignedWidth  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
1509         uint32_t       PitchInBytes  = AlignedWidth * GetBppValue(bpp);
1510         PitchInBytes                 = GFX_MAX(PitchInBytes, MinPitch);
1511         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
1512         PitchInBytes                 = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
1513         const uint32_t AlignedHeight = 96; // See details in GetTotal3DHeight();
1514 
1515         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1516         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1517         VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
1518         VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
1519         VerifyResourceSize<true>(ResourceInfo, AlignedHeight / TileSize[i][1] * PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
1520 
1521         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1522     }
1523 }
1524 
1525 /// @brief ULT for Cube Linear Resource
TEST_F(CTestResource,Test3DTileYMippedResource)1526 TEST_F(CTestResource, Test3DTileYMippedResource)
1527 {
1528     // Horizontal/Vertical pixel alignment
1529     const uint32_t HAlign                    = 16;
1530     const uint32_t VAlign                    = 4;
1531     const uint32_t TileSize[TEST_BPP_MAX][3] = {{128, 32, 1},
1532                                                 {128, 32, 1},
1533                                                 {128, 32, 1},
1534                                                 {128, 32, 1},
1535                                                 {128, 32, 1}};
1536 
1537     const uint32_t ResourceWidth  = 0x100;
1538     const uint32_t ResourceHeight = 0x100;
1539     const uint32_t ResourceDepth  = 0x100;
1540     const uint32_t MaxLod         = 0x9;
1541 
1542     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1543     {
1544         TEST_BPP             bpp       = static_cast<TEST_BPP>(i);
1545         GMM_RESCREATE_PARAMS gmmParams = {};
1546         gmmParams.Type                 = RESOURCE_3D;
1547         gmmParams.Flags.Info.TiledY    = 1;
1548         gmmParams.NoGfxMemory          = 1;
1549         gmmParams.Flags.Gpu.Texture    = 1;
1550         gmmParams.BaseWidth64          = ResourceWidth;
1551         gmmParams.BaseHeight           = ResourceHeight;
1552         gmmParams.Depth                = ResourceDepth;
1553         gmmParams.MaxLod               = MaxLod;
1554         gmmParams.Format               = SetResourceFormat(bpp);
1555 
1556         GMM_RESOURCE_INFO *ResourceInfo;
1557         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1558 
1559         const uint32_t Pitch      = ResourceWidth * GetBppValue(bpp);
1560         const uint32_t Mip0Height = ResourceHeight;
1561         const uint32_t Mip0Depth  = ResourceDepth;
1562 
1563         // Mip0
1564         GMM_REQ_OFFSET_INFO OffsetInfo = {};
1565         OffsetInfo.ReqRender           = 1;
1566         OffsetInfo.MipLevel            = 0;
1567         ResourceInfo->GetOffset(OffsetInfo);
1568 
1569         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
1570         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1571         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1572         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1573 
1574         // Mip1
1575         OffsetInfo           = {};
1576         OffsetInfo.ReqRender = 1;
1577         OffsetInfo.MipLevel  = 1;
1578         ResourceInfo->GetOffset(OffsetInfo);
1579 
1580         const uint32_t SizeOfMip0 = Pitch * Mip0Height * Mip0Depth;
1581         const uint32_t Mip1Offset = SizeOfMip0;
1582         const uint32_t Mip1Height = Mip0Height >> 1;
1583         const uint32_t Mip1Depth  = Mip0Depth >> 1;
1584 
1585         EXPECT_EQ(Mip1Offset, OffsetInfo.Render.Offset64);
1586         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1587         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1588         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1589 
1590         // Mip2
1591         OffsetInfo           = {};
1592         OffsetInfo.ReqRender = 1;
1593         OffsetInfo.MipLevel  = 2;
1594         ResourceInfo->GetOffset(OffsetInfo);
1595 
1596         const uint32_t SizeOfMip1 = (Pitch >> 1) * Mip1Height * Mip1Depth;
1597         const uint32_t Mip2Offset = Mip1Offset + SizeOfMip1;
1598         const uint32_t Mip2Height = Mip1Height >> 1;
1599         const uint32_t Mip2Depth  = Mip1Depth >> 1;
1600 
1601         EXPECT_EQ(Mip2Offset, OffsetInfo.Render.Offset64);
1602         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1603         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1604         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1605 
1606         // Mip3
1607         OffsetInfo           = {};
1608         OffsetInfo.ReqRender = 1;
1609         OffsetInfo.MipLevel  = 3;
1610         ResourceInfo->GetOffset(OffsetInfo);
1611 
1612         const uint32_t SizeOfMip2 = (Pitch >> 2) * Mip2Height * Mip2Depth;
1613         const uint32_t Mip3Offset = Mip2Offset + SizeOfMip2;
1614         const uint32_t Mip3Height = Mip2Height >> 1;
1615         const uint32_t Mip3Depth  = Mip2Depth >> 1;
1616 
1617         EXPECT_EQ(Mip3Offset, OffsetInfo.Render.Offset64);
1618         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1619         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1620         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1621 
1622         // Mip4 (Packed Mip)
1623         // For those mip width/height smaller than H/VAlign, they are upscaled to align with H/VAlign
1624         OffsetInfo           = {};
1625         OffsetInfo.ReqRender = 1;
1626         OffsetInfo.MipLevel  = 4;
1627         ResourceInfo->GetOffset(OffsetInfo);
1628 
1629         const uint32_t SizeOfMip3 = (Pitch >> 3) * Mip3Height * Mip3Depth;
1630         const uint32_t Mip4Offset = Mip3Offset + SizeOfMip3;
1631 
1632         EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
1633         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1634         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1635         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1636 
1637         // Mip 5
1638         OffsetInfo           = {};
1639         OffsetInfo.ReqRender = 1;
1640         OffsetInfo.MipLevel  = 5;
1641         ResourceInfo->GetOffset(OffsetInfo);
1642 
1643         EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
1644         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1645         EXPECT_EQ(16, OffsetInfo.Render.YOffset);
1646         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1647 
1648         // Mip 6
1649         OffsetInfo           = {};
1650         OffsetInfo.ReqRender = 1;
1651         OffsetInfo.MipLevel  = 6;
1652         ResourceInfo->GetOffset(OffsetInfo);
1653 
1654         EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
1655         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1656         EXPECT_EQ(24, OffsetInfo.Render.YOffset);
1657         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1658 
1659         // Mip 7
1660         OffsetInfo           = {};
1661         OffsetInfo.ReqRender = 1;
1662         OffsetInfo.MipLevel  = 7;
1663         ResourceInfo->GetOffset(OffsetInfo);
1664 
1665         EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
1666         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1667         EXPECT_EQ(28, OffsetInfo.Render.YOffset);
1668         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1669 
1670         // Mip8 (Start of another packed Mip)
1671         OffsetInfo           = {};
1672         OffsetInfo.ReqRender = 1;
1673         OffsetInfo.MipLevel  = 8;
1674         ResourceInfo->GetOffset(OffsetInfo);
1675 
1676         const uint32_t Mip8Offset = Mip4Offset + Pitch * TileSize[i][1];
1677 
1678         EXPECT_EQ(Mip8Offset, OffsetInfo.Render.Offset64);
1679         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1680         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1681         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1682 
1683         // Mip9
1684         OffsetInfo           = {};
1685         OffsetInfo.ReqRender = 1;
1686         OffsetInfo.MipLevel  = 9;
1687         ResourceInfo->GetOffset(OffsetInfo);
1688 
1689         EXPECT_EQ(Mip8Offset, OffsetInfo.Render.Offset64);
1690         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1691         EXPECT_EQ(4, OffsetInfo.Render.YOffset);
1692         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1693 
1694         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1695     }
1696 }
1697 
1698 // ********************************************************************************//
1699 
1700 /// @brief ULT for Cube Linear Resource
TEST_F(CTestResource,TestCubeLinearResource)1701 TEST_F(CTestResource, TestCubeLinearResource)
1702 {
1703     const uint32_t HAlign = 16;
1704     const uint32_t VAlign = 4;
1705 
1706     GMM_RESCREATE_PARAMS gmmParams = {};
1707     gmmParams.Type                 = RESOURCE_CUBE;
1708     gmmParams.NoGfxMemory          = 1;
1709     gmmParams.Flags.Info.Linear    = 1;
1710     gmmParams.Flags.Gpu.Texture    = 1;
1711 
1712     // Allocate 1x1
1713     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1714     {
1715         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1716         gmmParams.Format      = SetResourceFormat(bpp);
1717         gmmParams.BaseWidth64 = 0x1;
1718         gmmParams.BaseHeight  = 0x1;
1719         gmmParams.Depth       = 0x1;
1720 
1721         GMM_RESOURCE_INFO *ResourceInfo;
1722         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1723 
1724         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1725         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1726 
1727         uint32_t ExpectedPitch = GMM_ULT_MAX(GMM_BYTES(32), HAlign * GetBppValue(bpp)); // Min Pitch = 32 bytes
1728         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);                         // As wide as 1 tile
1729         VerifyResourcePitchInTiles<false>(ResourceInfo, 1);                             // not applicable
1730 
1731         uint32_t ExpectedQPitch = VAlign;
1732         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile
1733 
1734         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned PAGE_SIZE
1735                                  GMM_ULT_ALIGN(ExpectedPitch *
1736                                                __GMM_MAX_CUBE_FACE * ExpectedQPitch,
1737                                                PAGE_SIZE));
1738 
1739         for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
1740         {
1741             GMM_REQ_OFFSET_INFO OffsetInfo = {};
1742             OffsetInfo.ReqRender           = 1;
1743             OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
1744             ResourceInfo->GetOffset(OffsetInfo);
1745 
1746             EXPECT_EQ(CubeFaceIndex * ExpectedQPitch * ExpectedPitch,
1747                       OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
1748             EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
1749             EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0
1750             EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
1751         }
1752 
1753         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1754     }
1755 
1756     // Allocate arbitrary size (X/Y dimension not applicable as linear surface)
1757     // Width and Height must be equal
1758     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1759     {
1760         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1761         gmmParams.Format      = SetResourceFormat(bpp);
1762         gmmParams.BaseWidth64 = 0x201;                 // 512 + 1, help ult HAlign/VAlign/Pitch alignment logic as well.
1763         gmmParams.BaseHeight  = gmmParams.BaseWidth64; // Heigth must be equal to width.
1764         gmmParams.Depth       = 0x1;
1765 
1766         GMM_RESOURCE_INFO *ResourceInfo;
1767         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1768 
1769         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1770         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1771 
1772         uint32_t ExpectedPitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * GetBppValue(bpp); // HAligned-width in bytes.
1773         ExpectedPitch          = GMM_ULT_ALIGN(ExpectedPitch, GMM_BYTES(32));
1774         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
1775         VerifyResourcePitchInTiles<false>(ResourceInfo, 2); // not applicable
1776 
1777         uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
1778         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
1779 
1780         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned PAGE_SIZE
1781                                  GMM_ULT_ALIGN(ExpectedPitch *
1782                                                __GMM_MAX_CUBE_FACE * ExpectedQPitch,
1783                                                PAGE_SIZE));
1784 
1785         for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
1786         {
1787             GMM_REQ_OFFSET_INFO OffsetInfo = {};
1788             OffsetInfo.ReqRender           = 1;
1789             OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
1790             ResourceInfo->GetOffset(OffsetInfo);
1791 
1792             EXPECT_EQ(CubeFaceIndex * ExpectedQPitch * ExpectedPitch,
1793                       OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
1794             EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
1795             EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0
1796             EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
1797         }
1798 
1799         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1800     }
1801 }
1802 
1803 /// @brief ULT for Cube Linear Mipped Resource
TEST_F(CTestResource,TestCubeLinearMippedResourceArray)1804 TEST_F(CTestResource, TestCubeLinearMippedResourceArray)
1805 {
1806     const uint32_t HAlign       = 16;
1807     const uint32_t VAlign       = 4;
1808     const uint32_t MaxLod       = 9;
1809     const uint32_t ResWidth     = 0x201;
1810     const uint32_t MaxArraySize = 0x10;
1811 
1812 
1813     GMM_RESCREATE_PARAMS gmmParams = {};
1814     gmmParams.Type                 = RESOURCE_CUBE;
1815     gmmParams.NoGfxMemory          = 1;
1816     gmmParams.Flags.Info.Linear    = 1;
1817     gmmParams.Flags.Gpu.Texture    = 1;
1818     gmmParams.MaxLod               = MaxLod;
1819     gmmParams.ArraySize            = MaxArraySize;
1820 
1821     // Allocate arbitrary size (X/Y dimension not applicable as linear surface)
1822     // Width and Height must be equal
1823     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
1824     {
1825         struct //Cache the value for verifying array elements/Cube face offset/Mip Offset
1826         {
1827             uint64_t Offset; // Note : absolute mip offset
1828         } RenderOffset[GMM_ULT_MAX_MIPMAP] = {};
1829 
1830         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
1831         gmmParams.Format      = SetResourceFormat(bpp);
1832         gmmParams.BaseWidth64 = ResWidth;              // 1024 + 1, help ult HAlign/VAlign/Pitch alignment logic as well.
1833         gmmParams.BaseHeight  = gmmParams.BaseWidth64; // Heigth must be equal to width.
1834         gmmParams.Depth       = 0x1;
1835 
1836         GMM_RESOURCE_INFO *ResourceInfo;
1837         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
1838 
1839         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
1840         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
1841 
1842         //------------------------------|
1843         //                              |
1844         //          LOD0                |
1845         //                              |
1846         //                              |
1847         //------------------------------|
1848         //    LOD1     |    LOD2  |
1849         //             |----------|
1850         //             | LOD3 |
1851         //-------------| LOD4 .. so on
1852 
1853         // Mip 0
1854         // Mip 0 decides the pitch of the entire surface
1855         const uint32_t AlignedWidthMip0  = GMM_ULT_ALIGN(ResWidth, HAlign); // HAlign width in pixel
1856         const uint32_t AlignedHeightMip0 = GMM_ULT_ALIGN(ResWidth, VAlign);
1857         uint32_t       ExpectedPitch     = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * GetBppValue(bpp); // HAligned-width in bytes.
1858         ExpectedPitch                    = GMM_ULT_ALIGN(ExpectedPitch, GMM_BYTES(32));
1859         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
1860         VerifyResourcePitchInTiles<false>(ResourceInfo, 2); // Not applicable
1861 
1862         // Mip0 should be at offset 0 and tile aligned
1863         GMM_REQ_OFFSET_INFO OffsetInfo = {};
1864         OffsetInfo.ReqRender           = 1;
1865         OffsetInfo.MipLevel            = 0; //Mip 0
1866         ResourceInfo->GetOffset(OffsetInfo);
1867         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
1868         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
1869         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
1870         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1871 
1872         //cache Mip 0 offset
1873         RenderOffset[0].Offset = 0;
1874 
1875         // Mip 1 should be under mip 0
1876         OffsetInfo           = {};
1877         OffsetInfo.ReqRender = 1;
1878         OffsetInfo.MipLevel  = 1; //Mip 1
1879         ResourceInfo->GetOffset(OffsetInfo);
1880 
1881         EXPECT_EQ(AlignedHeightMip0 * ExpectedPitch, // Render offset is the absolute address at which the mip begins
1882                   OffsetInfo.Render.Offset64);
1883         EXPECT_EQ(0, OffsetInfo.Render.XOffset); // Not applicable for linear surface
1884         EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Not applicable for linear surface
1885         EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // n/a
1886 
1887         //cache Mip 1 offset
1888         RenderOffset[1].Offset = AlignedHeightMip0 * ExpectedPitch; //Absolute base
1889 
1890         const uint32_t AlignedWidthMip1  = GMM_ULT_ALIGN(ResWidth >> 1, HAlign); // Align width in pixel to HAlign
1891         const uint32_t AlignedHeightMip1 = GMM_ULT_ALIGN(ResWidth >> 1, VAlign);
1892 
1893         uint32_t HeightOfMip;
1894         uint32_t HeightLinesLevel2 = 0;
1895 
1896         // Mips 2-9 should be stacked on the right of Mip1 as shown in figure above.
1897         for(int i = 2; i <= MaxLod; i++)
1898         {
1899             OffsetInfo           = {};
1900             OffsetInfo.ReqRender = 1;
1901             OffsetInfo.MipLevel  = i;
1902             ResourceInfo->GetOffset(OffsetInfo);
1903 
1904             HeightOfMip = GMM_ULT_ALIGN(ResWidth >> i, VAlign);
1905 
1906             EXPECT_EQ((AlignedHeightMip0 + HeightLinesLevel2) * ExpectedPitch + // Render offset is tile's base address on which mip begins
1907                       (AlignedWidthMip1 * GetBppValue(bpp)),
1908                       OffsetInfo.Render.Offset64);
1909 
1910             EXPECT_EQ(0, OffsetInfo.Render.XOffset); // Not applicable for linear surface
1911             EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Not applicable for linear surface
1912             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
1913 
1914             //cache Mip i'th offset
1915             RenderOffset[i].Offset = (AlignedHeightMip0 + HeightLinesLevel2) * ExpectedPitch +
1916                                      (AlignedWidthMip1 * GetBppValue(bpp));
1917 
1918             HeightLinesLevel2 += HeightOfMip;
1919         }
1920 
1921         uint32_t ExpectedQPitch = AlignedHeightMip0 + AlignedHeightMip1 + 12 * VAlign;
1922         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
1923 
1924         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned to tile boundary
1925                                  GMM_ULT_ALIGN(ExpectedPitch *
1926                                                MaxArraySize * __GMM_MAX_CUBE_FACE * ExpectedQPitch,
1927                                                PAGE_SIZE));
1928 
1929         // Verify each array element's  Mip offset, Cube face offset etc.
1930         for(uint32_t ArrayIndex = 0; ArrayIndex < __GMM_MAX_CUBE_FACE; ArrayIndex++)
1931         {
1932             for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
1933             {
1934                 GMM_REQ_OFFSET_INFO OffsetInfo = {};
1935                 OffsetInfo.ReqRender           = 1;
1936                 OffsetInfo.ArrayIndex          = ArrayIndex;
1937                 OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
1938                 ResourceInfo->GetOffset(OffsetInfo);
1939 
1940                 //Verify cube face offsets
1941                 EXPECT_EQ(((6 * ArrayIndex) + CubeFaceIndex) * ExpectedQPitch * ExpectedPitch,
1942                           OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
1943                 EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0 as linear surf
1944                 EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0 as linear surf
1945                 EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
1946 
1947                 uint32_t CubeFaceBaseOffset = ((6 * ArrayIndex) + CubeFaceIndex) * (ExpectedQPitch * ExpectedPitch);
1948 
1949                 //Verify mip offsets in each cube face
1950                 for(uint32_t Lod = 0; Lod <= MaxLod; Lod++)
1951                 {
1952                     OffsetInfo.MipLevel = Lod;
1953                     ResourceInfo->GetOffset(OffsetInfo);
1954 
1955                     uint32_t MipOffset = CubeFaceBaseOffset + RenderOffset[Lod].Offset;
1956 
1957                     uint32_t OffsetX = MipOffset % ExpectedPitch;
1958                     uint32_t OffsetY = MipOffset / ExpectedPitch;
1959 
1960                     uint32_t RenderAlignOffset = OffsetY * ExpectedPitch + OffsetX;
1961 
1962                     EXPECT_EQ(RenderAlignOffset, OffsetInfo.Render.Offset64); // Render offset absolute address on which cube face begins.
1963                     EXPECT_EQ(0, OffsetInfo.Render.XOffset);                  // X Offset should be 0 as linear surf
1964                     EXPECT_EQ(0, OffsetInfo.Render.YOffset);                  // Y Offset should be 0 as linear surf
1965                     EXPECT_EQ(0, OffsetInfo.Render.ZOffset);                  // Z offset N/A should be 0
1966                 }
1967             }
1968         }
1969 
1970         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
1971     }
1972 }
1973 
1974 /// @brief ULT for Cube TileX Resource
TEST_F(CTestResource,TestCubeTileXResource)1975 TEST_F(CTestResource, TestCubeTileXResource)
1976 {
1977     // Cube is allocated as an array of 6 2D surface representing each cube face below
1978     //===============================
1979     //  q  coordinate  |    face    |
1980     //      0          |    + x     |
1981     //      1          |    - x     |
1982     //      2          |    + y     |
1983     //      3          |    - y     |
1984     //      4          |    + z     |
1985     //      5          |    - z     |
1986     //===============================
1987 
1988     const uint32_t HAlign = 16;
1989     const uint32_t VAlign = 4;
1990 
1991     const uint32_t TileSize[1][2] = {512, 8};
1992 
1993     GMM_RESCREATE_PARAMS gmmParams = {};
1994     gmmParams.Type                 = RESOURCE_CUBE;
1995     gmmParams.NoGfxMemory          = 1;
1996     gmmParams.Flags.Info.TiledX    = 1;
1997     gmmParams.Flags.Gpu.Texture    = 1;
1998 
1999     // Allocate 1x1 surface so that it occupies 1 Tile in X dimension
2000     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
2001     {
2002         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
2003         gmmParams.Format      = SetResourceFormat(bpp);
2004         gmmParams.BaseWidth64 = 0x1;
2005         gmmParams.BaseHeight  = 0x1;
2006         gmmParams.Depth       = 0x1;
2007 
2008         GMM_RESOURCE_INFO *ResourceInfo;
2009         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2010 
2011         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2012         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2013         uint32_t ExpectedPitch = TileSize[0][0];
2014         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch); // As wide as 1 tile
2015         VerifyResourcePitchInTiles<true>(ResourceInfo, 1);      // 1 tile wide
2016 
2017         uint32_t ExpectedQPitch = VAlign;
2018         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile
2019 
2020         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned to tile boundary
2021                                  ExpectedPitch *
2022                                  GMM_ULT_ALIGN(__GMM_MAX_CUBE_FACE * ExpectedQPitch,
2023                                                TileSize[0][1]));
2024 
2025         for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
2026         {
2027             GMM_REQ_OFFSET_INFO OffsetInfo = {};
2028             OffsetInfo.ReqRender           = 1;
2029             OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
2030             ResourceInfo->GetOffset(OffsetInfo);
2031 
2032             EXPECT_EQ(GMM_ULT_ALIGN_FLOOR(CubeFaceIndex * ExpectedQPitch, TileSize[0][1]) * ExpectedPitch,
2033                       OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
2034             EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
2035             EXPECT_EQ((CubeFaceIndex * ExpectedQPitch) % TileSize[0][1],
2036                       OffsetInfo.Render.YOffset);    // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
2037             EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
2038         }
2039 
2040         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2041     }
2042 
2043     // Allocate 2 tiles in X dimension.
2044     // Width and Height must be equal
2045     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
2046     {
2047         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
2048         gmmParams.Format      = SetResourceFormat(bpp);
2049         gmmParams.BaseWidth64 = (TileSize[0][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
2050         gmmParams.BaseHeight  = gmmParams.BaseWidth64;                   // Heigth must be equal to width.
2051         gmmParams.Depth       = 0x1;
2052 
2053         GMM_RESOURCE_INFO *ResourceInfo;
2054         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2055 
2056         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2057         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2058 
2059         uint32_t ExpectedPitch = TileSize[0][0] * 2; // As wide as 2 tile
2060         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2061         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
2062 
2063         uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
2064         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
2065 
2066         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned to tile boundary
2067                                  ExpectedPitch *
2068                                  GMM_ULT_ALIGN(__GMM_MAX_CUBE_FACE * ExpectedQPitch,
2069                                                TileSize[0][1]));
2070 
2071         for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
2072         {
2073             GMM_REQ_OFFSET_INFO OffsetInfo = {};
2074             OffsetInfo.ReqRender           = 1;
2075             OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
2076             ResourceInfo->GetOffset(OffsetInfo);
2077             EXPECT_EQ(GMM_ULT_ALIGN_FLOOR(CubeFaceIndex * ExpectedQPitch, TileSize[0][1]) * ExpectedPitch,
2078                       OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
2079             EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
2080             EXPECT_EQ((CubeFaceIndex * ExpectedQPitch) % TileSize[0][1],
2081                       OffsetInfo.Render.YOffset);    // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
2082             EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
2083         }
2084 
2085         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2086     }
2087 }
2088 
2089 
2090 /// @brief ULT for Cube TileY Resource
TEST_F(CTestResource,TestCubeTileYResource)2091 TEST_F(CTestResource, TestCubeTileYResource)
2092 {
2093     // Cube is allocated as an array of 6 2D surface representing each cube face below
2094     //===============================
2095     //   q coordinate  |    face    |
2096     //      0          |    + x     |
2097     //      1          |    - x     |
2098     //      2          |    + y     |
2099     //      3          |    - y     |
2100     //      4          |    + z     |
2101     //      5          |    - z     |
2102     //===============================
2103 
2104     const uint32_t HAlign = 16;
2105     const uint32_t VAlign = 4;
2106 
2107     const uint32_t TileSize[1][2] = {128, 32};
2108 
2109     GMM_RESCREATE_PARAMS gmmParams = {};
2110     gmmParams.Type                 = RESOURCE_CUBE;
2111     gmmParams.NoGfxMemory          = 1;
2112     gmmParams.Flags.Info.TiledY    = 1;
2113     gmmParams.Flags.Gpu.Texture    = 1;
2114 
2115     // Allocate 1x1 surface within a tile.
2116     for(uint32_t i = 0; i < TEST_BPP_128; i++) //TEST_BPP_128 cannot fit in a tile as HAlign = 16
2117     {
2118         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
2119         gmmParams.Format      = SetResourceFormat(bpp);
2120         gmmParams.BaseWidth64 = 0x1;
2121         gmmParams.BaseHeight  = 0x1;
2122         gmmParams.Depth       = 0x1;
2123 
2124         GMM_RESOURCE_INFO *ResourceInfo;
2125         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2126 
2127         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2128         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2129         VerifyResourcePitch<true>(ResourceInfo, TileSize[0][0]); // As wide as 1 tile
2130         VerifyResourcePitchInTiles<true>(ResourceInfo, 1);       // 1 tile wide
2131         VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4));    // All 6 faces should be accomated in a tile.
2132         VerifyResourceQPitch<true>(ResourceInfo, VAlign);        // Each face should be VAlign rows apart within a tile
2133 
2134         for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
2135         {
2136             GMM_REQ_OFFSET_INFO OffsetInfo = {};
2137             OffsetInfo.ReqRender           = 1;
2138             OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
2139             ResourceInfo->GetOffset(OffsetInfo);
2140             EXPECT_EQ(0, OffsetInfo.Render.Offset64);                     // Render offset should be 0 as its on single tile.
2141             EXPECT_EQ(0, OffsetInfo.Render.XOffset);                      // X Offset should be 0
2142             EXPECT_EQ(CubeFaceIndex * VAlign, OffsetInfo.Render.YOffset); // Y Offset should be VALIGN * CubeFace Index
2143             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
2144         }
2145 
2146         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2147     }
2148 
2149     // Allocate 2 tiles in X dimension.
2150     // Width and Height of Cube must be equal
2151     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
2152     {
2153         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
2154         gmmParams.Format      = SetResourceFormat(bpp);
2155         gmmParams.BaseWidth64 = (TileSize[0][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
2156         gmmParams.BaseHeight  = gmmParams.BaseWidth64;                   // Heigth must be equal to width.
2157         gmmParams.Depth       = 0x1;
2158 
2159         GMM_RESOURCE_INFO *ResourceInfo;
2160         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2161 
2162         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2163         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2164 
2165         uint32_t ExpectedPitch = TileSize[0][0] * 2; // As wide as 2 tile
2166         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2167         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
2168 
2169         uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
2170         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
2171 
2172         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned to tile boundary
2173                                  ExpectedPitch *
2174                                  GMM_ULT_ALIGN(__GMM_MAX_CUBE_FACE * ExpectedQPitch,
2175                                                TileSize[0][1]));
2176 
2177 
2178         for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
2179         {
2180             GMM_REQ_OFFSET_INFO OffsetInfo = {};
2181             OffsetInfo.ReqRender           = 1;
2182             OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
2183             ResourceInfo->GetOffset(OffsetInfo);
2184             EXPECT_EQ(GMM_ULT_ALIGN_FLOOR(CubeFaceIndex * ExpectedQPitch, TileSize[0][1]) * ExpectedPitch,
2185                       OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
2186             EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
2187             EXPECT_EQ((CubeFaceIndex * ExpectedQPitch) % TileSize[0][1],
2188                       OffsetInfo.Render.YOffset);    // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
2189             EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
2190         }
2191 
2192         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2193     }
2194 }
2195 
2196 /// @brief ULT for Cube TileY Mipped Resource Array
TEST_F(CTestResource,TestCubeTileYMippedResourceArray)2197 TEST_F(CTestResource, TestCubeTileYMippedResourceArray)
2198 {
2199     const uint32_t HAlign = 16;
2200     const uint32_t VAlign = 4;
2201 
2202     const uint32_t TileSize[2] = {128, 32};
2203     enum Coords
2204     {
2205         X = 0,
2206         Y = 1
2207     };
2208 
2209     GMM_RESCREATE_PARAMS gmmParams = {};
2210     gmmParams.Type                 = RESOURCE_CUBE;
2211     gmmParams.NoGfxMemory          = 1;
2212     gmmParams.Flags.Info.TiledY    = 1;
2213     gmmParams.Flags.Gpu.Texture    = 1;
2214 
2215     // Allocate CUBE surface
2216     for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
2217     {
2218         const uint32_t ResWidth     = 0x201;
2219         const uint32_t MaxLod       = 0x9;
2220         const uint32_t MaxArraySize = 0x10;
2221 
2222         struct //Cache the value for verifying array elements/Cube face offset/Mip Offset
2223         {
2224             uint64_t Offset; // Note : absolute mip offset
2225         } RenderOffset[GMM_ULT_MAX_MIPMAP];
2226 
2227         TEST_BPP bpp          = static_cast<TEST_BPP>(i);
2228         gmmParams.Format      = SetResourceFormat(bpp);
2229         gmmParams.BaseWidth64 = ResWidth;              // 1 pixel larger than 1 tile width
2230         gmmParams.BaseHeight  = gmmParams.BaseWidth64; // Heigth must be equal to width.
2231         gmmParams.Depth       = 0x1;
2232         gmmParams.MaxLod      = MaxLod;
2233         gmmParams.ArraySize   = MaxArraySize;
2234 
2235         GMM_RESOURCE_INFO *ResourceInfo;
2236         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2237 
2238         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2239         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2240 
2241         //------------------------------|
2242         //                              |
2243         //          LOD0                |
2244         //                              |
2245         //                              |
2246         //------------------------------|
2247         //    LOD1     |    LOD2  |
2248         //             |----------|
2249         //             | LOD3 |
2250         //-------------| LOD4 .. so on
2251 
2252         //Mip 0
2253         //Mip 0 decides the pitch of the entire resource.
2254         const uint32_t AlignedWidthMip0  = GMM_ULT_ALIGN(ResWidth, HAlign); // HAlign width in pixel
2255         const uint32_t AlignedHeightMip0 = GMM_ULT_ALIGN(ResWidth, VAlign);
2256         uint32_t       ExpectedPitch     = GMM_ULT_ALIGN(AlignedWidthMip0 * GetBppValue(bpp), TileSize[X]); // Align AlignedWidthMip0 to 128 bytes
2257         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2258         VerifyResourcePitchInTiles<true>(ResourceInfo, ExpectedPitch / TileSize[X]); // Pitch/TileY-Width
2259 
2260         // Mip0 should be at offset 0 and tile aligned
2261         GMM_REQ_OFFSET_INFO OffsetInfo = {};
2262         OffsetInfo.ReqRender           = 1;
2263         OffsetInfo.MipLevel            = 0; //Mip 0
2264         ResourceInfo->GetOffset(OffsetInfo);
2265         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
2266         EXPECT_EQ(0, OffsetInfo.Render.XOffset);
2267         EXPECT_EQ(0, OffsetInfo.Render.YOffset);
2268         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
2269 
2270         //cache Mip 0 offset
2271         RenderOffset[0].Offset = 0;
2272 
2273         // Mip 1 should be under mip 0
2274         OffsetInfo           = {};
2275         OffsetInfo.ReqRender = 1;
2276         OffsetInfo.MipLevel  = 1; //Mip 1
2277         ResourceInfo->GetOffset(OffsetInfo);
2278 
2279         EXPECT_EQ(GMM_ULT_ALIGN_FLOOR(AlignedHeightMip0, TileSize[Y]) * ExpectedPitch, // Render offset is tile's base address on which mip begins
2280                   OffsetInfo.Render.Offset64);
2281         EXPECT_EQ(0, OffsetInfo.Render.XOffset);                                 // Aligns with Mip0 at X = 0
2282         EXPECT_EQ((AlignedHeightMip0) % TileSize[Y], OffsetInfo.Render.YOffset); // AlignedHeightMip0 % TileY-Height
2283         EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
2284 
2285         //cache Mip 1 offset
2286         RenderOffset[1].Offset = AlignedHeightMip0 * ExpectedPitch; //Absolute base
2287 
2288         const uint32_t AlignedWidthMip1  = GMM_ULT_ALIGN(ResWidth >> 1, HAlign); // Align width in pixel to HAlign
2289         const uint32_t AlignedHeightMip1 = GMM_ULT_ALIGN(ResWidth >> 1, VAlign);
2290 
2291         uint32_t HeightOfMip;
2292         uint32_t HeightLinesLevel2 = 0;
2293 
2294         // Mips 2-9 should be stacked on the right of Mip1 as shown in figure above.
2295         for(int i = 2; i <= MaxLod; i++)
2296         {
2297             OffsetInfo           = {};
2298             OffsetInfo.ReqRender = 1;
2299             OffsetInfo.MipLevel  = i;
2300             ResourceInfo->GetOffset(OffsetInfo);
2301 
2302             HeightOfMip = GMM_ULT_ALIGN(ResWidth >> i, VAlign);
2303 
2304             EXPECT_EQ(GMM_ULT_ALIGN_FLOOR(AlignedHeightMip0 + HeightLinesLevel2, TileSize[Y]) * ExpectedPitch + // Render offset is tile's base address on which mip begins
2305                       (AlignedWidthMip1 * GetBppValue(bpp) / TileSize[X]) * PAGE_SIZE,
2306                       OffsetInfo.Render.Offset64);
2307 
2308             EXPECT_EQ((AlignedWidthMip1 * GetBppValue(bpp)) % TileSize[X], OffsetInfo.Render.XOffset);   // Aligns with Mip0 at X = 0
2309             EXPECT_EQ((AlignedHeightMip0 + HeightLinesLevel2) % TileSize[Y], OffsetInfo.Render.YOffset); // AlignedHeightMip0 % TileY-Height
2310             EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
2311 
2312             //cache Mip i'th offset
2313             RenderOffset[i].Offset = (AlignedHeightMip0 + HeightLinesLevel2) * ExpectedPitch +
2314                                      (AlignedWidthMip1 * GetBppValue(bpp));
2315 
2316             HeightLinesLevel2 += HeightOfMip;
2317         }
2318 
2319         uint32_t ExpectedQPitch = AlignedHeightMip0 + AlignedHeightMip1 + 12 * VAlign;
2320         VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
2321 
2322         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned to tile boundary
2323                                  ExpectedPitch *
2324                                  GMM_ULT_ALIGN(MaxArraySize * __GMM_MAX_CUBE_FACE * ExpectedQPitch, TileSize[Y]));
2325 
2326         // Verify each array element's  Mip offset, Cube face offset etc.
2327         for(uint32_t ArrayIndex = 0; ArrayIndex < __GMM_MAX_CUBE_FACE; ArrayIndex++)
2328         {
2329             for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
2330             {
2331                 GMM_REQ_OFFSET_INFO OffsetInfo = {};
2332                 OffsetInfo.ReqRender           = 1;
2333                 OffsetInfo.ArrayIndex          = ArrayIndex;
2334                 OffsetInfo.CubeFace            = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
2335                 ResourceInfo->GetOffset(OffsetInfo);
2336 
2337                 //Verify cube face offsets
2338                 EXPECT_EQ(GMM_ULT_ALIGN_FLOOR(((6 * ArrayIndex) + CubeFaceIndex) * ExpectedQPitch, TileSize[Y]) * ExpectedPitch,
2339                           OffsetInfo.Render.Offset64);   // Render offset is tile's base address on which cube face begins.
2340                 EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
2341                 EXPECT_EQ((((6 * ArrayIndex) + CubeFaceIndex) * ExpectedQPitch) % TileSize[Y],
2342                           OffsetInfo.Render.YOffset);    // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
2343                 EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
2344 
2345                 uint32_t CubeFaceBaseOffset = ((6 * ArrayIndex) + CubeFaceIndex) * (ExpectedQPitch * ExpectedPitch);
2346 
2347                 //Verify mip offsets in each cube face
2348                 for(uint32_t Lod = 0; Lod <= MaxLod; Lod++)
2349                 {
2350                     OffsetInfo.MipLevel = Lod;
2351                     ResourceInfo->GetOffset(OffsetInfo);
2352 
2353                     uint32_t MipOffset = CubeFaceBaseOffset + RenderOffset[Lod].Offset;
2354 
2355                     uint32_t OffsetX            = MipOffset % ExpectedPitch;
2356                     uint32_t TileAlignedOffsetX = GMM_ULT_ALIGN_FLOOR(OffsetX, TileSize[X]);
2357                     OffsetX -= TileAlignedOffsetX;
2358 
2359                     uint32_t OffsetY            = MipOffset / ExpectedPitch;
2360                     uint32_t TileAlignedOffsetY = GMM_ULT_ALIGN_FLOOR(OffsetY, TileSize[Y]);
2361                     OffsetY -= TileAlignedOffsetY;
2362 
2363                     uint32_t RenderAlignOffset =
2364                     TileAlignedOffsetY * ExpectedPitch +
2365                     (TileAlignedOffsetX / TileSize[X]) * PAGE_SIZE;
2366 
2367 
2368                     EXPECT_EQ(RenderAlignOffset, OffsetInfo.Render.Offset64); // Render offset is tile's base address on which cube face begins.
2369                     EXPECT_EQ(OffsetX, OffsetInfo.Render.XOffset);
2370                     EXPECT_EQ(OffsetY, OffsetInfo.Render.YOffset); // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
2371                     EXPECT_EQ(0, OffsetInfo.Render.ZOffset);       // Z offset N/A should be 0
2372                 }
2373             }
2374         }
2375 
2376         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2377     }
2378 }
2379 // ********************************************************************************//
2380 
2381 /// @brief ULT for Buffer Resource
TEST_F(CTestResource,TestBufferLinearResource)2382 TEST_F(CTestResource, TestBufferLinearResource)
2383 {
2384 }
2385 
2386 // ********************************************************************************//
2387 
2388 /// @brief ULT for Separate Stencil Resource
TEST_F(CTestResource,TestSeparateStencil)2389 TEST_F(CTestResource, TestSeparateStencil)
2390 {
2391     const uint32_t HAlign = 8; //Separate Stencil alignment (8x8)
2392     const uint32_t VAlign = 8;
2393 
2394     const uint32_t StencilTileSize[1][2] = {64, 64};  //Stencil is TileW, swizzled (2*w x h/2) onto TileY
2395     const uint32_t AllocTileSize[1][2]   = {128, 32}; //Allocation-aligned to TileY since some HW units support TileW by WA'ing TileY
2396 
2397     GMM_RESCREATE_PARAMS gmmParams      = {};
2398     gmmParams.NoGfxMemory               = 1;
2399     gmmParams.Flags.Info.TiledX         = 1; //Any input Tiling - changed to TileW? YES, but expected one is TileW
2400     gmmParams.Flags.Gpu.SeparateStencil = 1;
2401     gmmParams.Format                    = SetResourceFormat(TEST_BPP_8); //Only R8_UNIT supported, driver assumes so, but creates resource even for other bpps requests (as bpp=8)
2402 
2403     // Allocate 1x1 surface so that it occupies 1 Tile in X dimension
2404     for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++) //SeparateStencil with 2D, cube, 1D, 3D with mip-maps
2405     {
2406         gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i);
2407         gmmParams.BaseWidth64 = 0x1;
2408         gmmParams.BaseHeight  = 0x1;
2409         gmmParams.Depth       = 0x1; //Depth !=1 supported for stencil? Supported on all Gens. Gen8 gives only Lod0 for mip-mapped Stencil too
2410 
2411         GMM_RESOURCE_INFO *ResourceInfo;
2412         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2413 
2414         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2415         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2416         uint32_t ExpectedPitch = StencilTileSize[0][0] * 2; // 2 TileW tiles interleaved on same row
2417         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2418         VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tileY wide
2419 
2420         if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
2421         {
2422             uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign); //Interleaved rows for TielW-arrangement. No Qpitch for 3d, only for 2d-array and cube on Gen8
2423             //it needs to be in VALign multiple, for Stencil buffer needs it as multiple of 8
2424             VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile
2425         }
2426 
2427         VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4)); //1 Tile should be enough
2428 
2429         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2430     }
2431 
2432     // Allocate 2 tiles in X dimension.
2433     for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++)
2434     {
2435         gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i); //Could we loop over Res_types for speacil allocation types
2436         gmmParams.BaseWidth64 = StencilTileSize[0][0] + 0x1;
2437         gmmParams.BaseHeight  = (gmmParams.Type == RESOURCE_1D) ? 0x1 :
2438                                                                  (gmmParams.Type == RESOURCE_CUBE) ? gmmParams.BaseWidth64 :
2439                                                                                                      StencilTileSize[0][1];
2440         gmmParams.Depth = 0x1; //HW doesn't support Depth/STC for 3D res_type, but driver has no such restriction
2441 
2442         GMM_RESOURCE_INFO *ResourceInfo;
2443         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2444 
2445         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2446         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2447         uint32_t ExpectedPitch = StencilTileSize[0][0] * 2 * 2; // Requires 2 StencilTiles, further doubled for interleaved rows 2*w = Pitch
2448         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2449         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tiles wide
2450 
2451         uint32_t ExpectedQPitch = 0;
2452         if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
2453         {
2454             ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign); //Interleaved rows for TileW-arrangement - but Qpitch calculated w/o interleaving in mind. No Qpitch for 3d, only for 2d-array and cube on Gen8
2455             //GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign)/2, VAlign); //Doesn't HW expect distance in rows between 2 cube-faces (array slices) : It does so, but in logical view not physical view, so not interleaved rows.
2456             //it needs to be in VALign multiple, for Stencil buffer needs it as multiple of 8
2457             VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile
2458         }
2459 
2460         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = (__GMM_MAX_CUBE_FACE x QPitch) /2 (Stencil height = halved due to interleaving), then aligned to tile boundary
2461                                  ((gmmParams.Type == RESOURCE_CUBE) ?
2462                                   ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch * __GMM_MAX_CUBE_FACE / 2, AllocTileSize[0][1]) : //cube
2463                                   2 * GMM_KBYTE(4)));
2464 
2465         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2466     }
2467 
2468     // Allocate 2 tiles in X/Y dimension.
2469     for(uint32_t i = RESOURCE_2D; i <= RESOURCE_3D; i++)
2470     {
2471         gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i);
2472         gmmParams.BaseWidth64 = StencilTileSize[0][0] + 0x1;
2473         gmmParams.BaseHeight  = StencilTileSize[0][1] + 0x1;
2474         gmmParams.Depth       = 0x1;
2475 
2476         GMM_RESOURCE_INFO *ResourceInfo;
2477         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2478 
2479         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2480         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2481         uint32_t ExpectedPitch = StencilTileSize[0][0] * 2 * 2; // Requires 2 StencilTiles, double again for interleaved rows 2*w = Pitch,
2482         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2483         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
2484 
2485         VerifyResourceSize<true>(ResourceInfo, 2 * 2 * GMM_KBYTE(4));
2486 
2487         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2488     }
2489 
2490     // Allocate multi-tiles in X/Y/Z dimension.
2491     for(uint32_t i = RESOURCE_3D; i <= RESOURCE_3D; i++)
2492     {
2493         gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i);
2494         gmmParams.BaseWidth64 = StencilTileSize[0][0] + 0x1;
2495         gmmParams.BaseHeight  = StencilTileSize[0][1] + 0x1;
2496         gmmParams.Depth       = StencilTileSize[0][1] + 0x1;
2497 
2498         GMM_RESOURCE_INFO *ResourceInfo;
2499         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2500 
2501         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2502         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2503         uint32_t ExpectedPitch = StencilTileSize[0][0] * 2 * 2; // Requires 2 StencilTiles, doubled again for interleaved rows 2*w = Pitch, width < 1.5 Tiles
2504         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2505         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
2506 
2507         uint32_t TwoDQPitch, ExpectedQPitch = 0;
2508         {
2509             TwoDQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign); //Interleaved rows for TileW-arrangement - but Qpitch calculated w/o interleaving in mind. No Qpitch for 3d, only for 2d-array and cube on Gen8
2510             //GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign)/2, VAlign); //Doesn't HW expect distance in rows between 2 cube-faces (array slices) : It does so, but in logical view not physical view, so not interleaved rows.
2511             //it needs to be in VALign multiple, for Stencil buffer needs it as multiple of 8
2512 
2513             //VerifyResourceQPitch<false>(ResourceInfo, TwoDQPitch);       //Gen8 doesn't support QPitch for RES_3D
2514 
2515             ExpectedQPitch = gmmParams.Depth * TwoDQPitch; //Depth slices arranged as 2D-arrayed slices.
2516         }
2517         VerifyResourceSize<true>(ResourceInfo,
2518                                  ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch / 2, AllocTileSize[0][1]));
2519 
2520         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2521     }
2522 
2523     //Mip-mapped array case: <SNB>Stencil QPitch = h0 ie Stencil only has Lod0
2524     //<BDW>Above limit not there, should have mip-map block height for Qpitch
2525 }
2526 
2527 /// @brief ULT for Hiz Depth buffer Resource
TEST_F(CTestResource,TestHiZ)2528 TEST_F(CTestResource, TestHiZ)
2529 {
2530     const uint32_t HAlign = 16; //HiZ alignment (16x8) [Depth 16bit: 8x4; ow 4x4]
2531     const uint32_t VAlign = 4;  // 8; Need to debug why driver uses VAlign/2
2532 
2533     //const uint32_t DepthTileSize[1][2] = { 64, 64 };  //Depth/Stencil buffer should be TileY/Ys/Yf only (16,24,32 bpp only) no 3D or MSAA
2534     const uint32_t AllocTileSize[1][2] = {128, 32}; //HiZ is TileY
2535 
2536     GMM_RESCREATE_PARAMS gmmParams = {};
2537     gmmParams.NoGfxMemory          = 1;
2538     gmmParams.Flags.Info.TiledX    = 1; //Not supported for Depth buffer, but HiZ output is TileY
2539     gmmParams.Flags.Gpu.Depth      = 1; //GPU Flags= Depth/SeparateStencil + HiZ
2540     gmmParams.Flags.Gpu.HiZ        = 1;
2541 
2542     // Allocate 1x1 surface so that it occupies 1 Tile in X dimension
2543     for(uint32_t j = TEST_BPP_8; j <= TEST_BPP_128; j++) //Depth bpp doesn't matter, Depth px dimensions decide HiZ size in HW
2544     {
2545         gmmParams.Format = SetResourceFormat(static_cast<TEST_BPP>(j)); //Only 16,24,32 supported; But driver creates the resource even for other bpps without failing
2546         for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++)          //3D doesn't support HiZ - test driver returns proper?
2547         {
2548             gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i);
2549             gmmParams.BaseWidth64 = 0x1;
2550             gmmParams.BaseHeight  = 0x1;
2551             gmmParams.Depth       = 0x1;
2552 
2553             GMM_RESOURCE_INFO *ResourceInfo;
2554             ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2555 
2556             VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2557             VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2558             uint32_t ExpectedPitch = AllocTileSize[0][0];
2559             VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2560             VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tileY wide
2561 
2562             if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
2563             {
2564                 uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
2565                 ExpectedQPitch          = GMM_ULT_ALIGN(ExpectedQPitch / 2, VAlign);
2566 
2567                 VerifyResourceQPitch<false>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile, Turn on verification after clarity
2568             }
2569 
2570             VerifyResourceSize<true>(ResourceInfo,
2571                                      GMM_KBYTE(4)); //1 Tile should be enough
2572 
2573             pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2574         }
2575     }
2576     // Allocate 2 tiles in X dimension. (muti-tiles Tiles in Y dimension for cube/array)
2577     for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++)
2578     {
2579         gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i);
2580         gmmParams.BaseWidth64 = AllocTileSize[0][0] + 0x1;
2581         gmmParams.BaseHeight  = (gmmParams.Type == RESOURCE_1D) ? 0x1 :
2582                                                                  (gmmParams.Type == RESOURCE_CUBE) ? gmmParams.BaseWidth64 :
2583                                                                                                      VAlign / 2;
2584         gmmParams.ArraySize = (gmmParams.Type != RESOURCE_3D) ? VAlign : 1; // Gen8 doesn't support 3D-arrays (so HiZ not supported) [test 3d arrays once -- HiZ would fail but ResCreate doesn't?]
2585         gmmParams.Depth     = 0x1;
2586 
2587         GMM_RESOURCE_INFO *ResourceInfo;
2588         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2589 
2590         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2591         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2592         uint32_t ExpectedPitch = AllocTileSize[0][0] * 2;
2593         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2594         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tileY wide
2595 
2596         uint32_t ExpectedQPitch = 0;
2597         if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
2598         {
2599             ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
2600             ExpectedQPitch = GMM_ULT_ALIGN(ExpectedQPitch / 2, VAlign);
2601 
2602             VerifyResourceQPitch<false>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile. Turn on verification after clarity
2603         }
2604 
2605         VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = (__GMM_MAX_CUBE_FACE x QPitch) /2 (Stencil height = halved due to interleaving), then aligned to tile boundary
2606                                  ((gmmParams.Type == RESOURCE_CUBE) ?
2607                                   ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize * __GMM_MAX_CUBE_FACE, AllocTileSize[0][1]) : //cube
2608                                   ((gmmParams.ArraySize > 1) ?
2609                                    ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, AllocTileSize[0][1]) : //array
2610                                    2 * GMM_KBYTE(4))));
2611 
2612         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2613     }
2614 
2615     // Allocate 2 tiles in X/Y dimension (non-arrayed) Multi-tiles for 3D
2616     for(uint32_t i = RESOURCE_2D; i <= RESOURCE_3D; i++)
2617     {
2618         gmmParams.Type        = static_cast<GMM_RESOURCE_TYPE>(i);
2619         gmmParams.BaseWidth64 = AllocTileSize[0][0] + 0x1;
2620         gmmParams.BaseHeight  = 2 * AllocTileSize[0][1] + 0x1; //Half-Depth Height or QPitch (lod!=0), aligned to 8 required by HW
2621         gmmParams.Depth       = (gmmParams.Type == RESOURCE_2D) ? 0x1 :
2622                                                             VAlign + 1;
2623         gmmParams.ArraySize = 1;
2624 
2625         GMM_RESOURCE_INFO *ResourceInfo;
2626         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2627 
2628         VerifyResourceHAlign<true>(ResourceInfo, HAlign);
2629         VerifyResourceVAlign<true>(ResourceInfo, VAlign);
2630         uint32_t ExpectedPitch = AllocTileSize[0][0] * 2;
2631         VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
2632         VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
2633 
2634         uint32_t TwoDQPitch = 0, ExpectedQPitch = 0;
2635         if(gmmParams.Type == RESOURCE_3D)
2636         {
2637             TwoDQPitch     = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
2638             ExpectedQPitch = gmmParams.Depth * GMM_ULT_ALIGN(TwoDQPitch / 2, VAlign); //Depth slices arranged as 2D-arrayed slices.
2639         }
2640         else
2641         {
2642             //HiZ for 3D not supported. Driver still allocates like IVB/HSW. (should Qpitch or only overall buffer height be Valigned ?)
2643             VerifyResourceSize<true>(ResourceInfo,
2644                                      ((gmmParams.Type == RESOURCE_3D) ?
2645                                       ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch, AllocTileSize[0][1]) :
2646                                       2 * 2 * GMM_KBYTE(4)));
2647         }
2648 
2649         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2650     }
2651 
2652     //Mip-mapped case:
2653 }
2654 
2655 /// @brief ULT for MSAA Resource
TEST_F(CTestResource,TestMSAA)2656 TEST_F(CTestResource, TestMSAA)
2657 {
2658     enum MSAA_Samples
2659     {
2660         MSAA_None,
2661         MSAA_2x,
2662         MSAA_4x,
2663         MSAA_8x,
2664         MSAA_16x
2665     };
2666 
2667     const uint32_t MCSTileSize[1][2] = {128, 32}; //MCS is TileY
2668 
2669     //Gen8:No mip-map for MSAA (MSS and MCS), No 16x
2670     //No MSAA for YUV/compressed formats
2671     //Interleaved MSS (IMS) for Depth/Stencil. Arrayed MSS (CMS) for Color RT
2672     //QPitch exists for arrayed MSS - gives distance between slices
2673     //MSS (Arrayed): px_wL, px_hL = pixel width/height of single sample at Lod L
2674     //                 MSS width = px_wL, MSS height = NumSamples*px_hL
2675     //MSS (Interleaved): px_wL, px_hL = pixel width/height of single sample at Lod L
2676     // Samples         MSS width                MSS Height
2677     //   2x            4*ceil(px_wL/2)             px_hL
2678     //   4x            4*ceil(px_wL/2)           4*ceil(px_hL/2)
2679     //   8x            8*ceil(px_wL/2)           4*ceil(px_hL/2)
2680     //  16x            8*ceil(px_wL/2)           8*ceil(px_hL/2)
2681     //MCS (bpp): 2x/4x - bpp_8, 8x - bpp_32, 16x - bpp_64
2682 
2683     const uint32_t TestDimensions[3][2] = {
2684     {0, 0}, //1x1x1
2685     {1, 0}, //2 Tilesx1
2686     {1, 1}, //2 Tilesx 2
2687     };
2688 
2689     uint32_t TestArraySize[2] = {1, 7};
2690 
2691     uint32_t HAlign, VAlign, TileDimX, TileDimY, MCSHAlign, MCSVAlign, TileSize;
2692     uint32_t ExpectedMCSBpp;
2693 
2694     std::vector<std::tuple<int, int, int, bool, int, int>> List; //TEST_TILE_TYPE, TEST_BPP, TEST_RESOURCE_TYPE, Depth or RT, TestDimension index, TestArraySize index
2695     auto Size = BuildInputIterator(List, 3, 2, false);                  // Size of arrays TestDimensions, TestArraySize
2696 
2697     for(auto element : List)
2698     {
2699         GMM_RESCREATE_PARAMS gmmParams = {};
2700         gmmParams.Flags.Info           = {0};
2701 
2702         TEST_TILE_TYPE     Tiling     = (TEST_TILE_TYPE)std::get<0>(element);
2703         TEST_BPP           Bpp        = (TEST_BPP)std::get<1>(element);
2704         TEST_RESOURCE_TYPE ResType    = (TEST_RESOURCE_TYPE)std::get<2>(element);
2705         bool               IsRT       = std::get<3>(element); // True for RT, False for Depth
2706         int                TestDimIdx = std::get<4>(element); //index into TestDimensions array
2707         int                ArrayIdx   = std::get<5>(element); //index into TestArraySize
2708         TileSize                      = GMM_KBYTE(4);
2709 
2710         //Discard un-supported Tiling/Res_type/bpp for this test
2711         if(ResType != TEST_RESOURCE_2D || Tiling > TEST_TILEY           //No 1D/3D/Cube. Supported 2D mip-maps/array
2712            || (!IsRT && (Tiling == TEST_TILEX ||
2713                          !(Bpp == TEST_BPP_16 || Bpp == TEST_BPP_32)))) //depth supported on 16bit, 32bit formats only
2714             continue;
2715 
2716         SetTileFlag(gmmParams, Tiling);
2717         SetResType(gmmParams, ResType);
2718         SetResGpuFlags(gmmParams, IsRT);
2719         SetResArraySize(gmmParams, TestArraySize[ArrayIdx]);
2720 
2721         gmmParams.NoGfxMemory = 1;
2722         gmmParams.Format      = SetResourceFormat(Bpp);
2723         for(uint32_t k = MSAA_2x; k < MSAA_16x; k++) //No 16x MSAA on Gen8
2724         {
2725             GetAlignmentAndTileDimensionsForMSAA(Bpp, IsRT, Tiling, (TEST_MSAA)k,
2726                                                  TileDimX, TileDimY, HAlign, VAlign,
2727                                                  ExpectedMCSBpp, MCSHAlign, MCSVAlign);
2728 
2729             gmmParams.BaseWidth64 = TestDimensions[TestDimIdx][0] * TileDimX + 0x1;
2730             gmmParams.BaseHeight  = TestDimensions[TestDimIdx][1] * TileDimY + 0x1;
2731 
2732             gmmParams.Depth           = 0x1; //2D Res_type with Depth > 1 doesn't fail, although Tex_cacl doesn't use it
2733             gmmParams.MSAA.NumSamples = static_cast<uint32_t>(pow((double)2, k));
2734             gmmParams.Flags.Gpu.MCS   = 0;
2735             gmmParams.ArraySize       = 1;
2736 
2737             //MSS surface
2738             GMM_RESOURCE_INFO *MSSResourceInfo;
2739             MSSResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2740 
2741             if(MSSResourceInfo)
2742             {
2743                 VerifyResourceHAlign<true>(MSSResourceInfo, HAlign);
2744                 VerifyResourceVAlign<true>(MSSResourceInfo, VAlign);
2745                 if(IsRT) //Arrayed MSS
2746                 {
2747                     uint32_t ExpectedPitch = 0, ExpectedQPitch = 0;
2748                     ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * (uint32_t)pow(2.0, Bpp), TileDimX); // Aligned width * bpp, aligned to TileWidth
2749                     VerifyResourcePitch<true>(MSSResourceInfo, ExpectedPitch);
2750                     if(Tiling != TEST_LINEAR)
2751                         VerifyResourcePitchInTiles<true>(MSSResourceInfo, ExpectedPitch / TileDimX);
2752 
2753                     //if (gmmParams.ArraySize > 1) - Arrayed MSS has QPitch
2754                     {
2755                         ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
2756                         VerifyResourceQPitch<true>(MSSResourceInfo, ExpectedQPitch);
2757                     }
2758 
2759                     uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.MSAA.NumSamples * gmmParams.ArraySize, TileDimY); //Align Height =ExpectedPitch * NumSamples * ExpectedQPitch, to Tile-Height
2760                     VerifyResourceSize<true>(MSSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize));
2761                 }
2762                 else // Interleaved MSS
2763                 {
2764                     uint32_t WidthMultiplier, HeightMultiplier;
2765                     GetInterleaveMSSPattern((TEST_MSAA)k, WidthMultiplier, HeightMultiplier, IsRT, Bpp);
2766                     gmmParams.BaseWidth64 = WidthMultiplier > 1 ? GMM_ULT_ALIGN(gmmParams.BaseWidth64, 2) : gmmParams.BaseWidth64;
2767                     gmmParams.BaseHeight  = HeightMultiplier > 1 ? GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) : gmmParams.BaseHeight;
2768 
2769                     uint32_t ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64 * WidthMultiplier, HAlign) * (uint32_t)pow(2.0, Bpp), TileDimX); //AlignedWidth*bpp, then align to Tile
2770                     VerifyResourcePitch<true>(MSSResourceInfo, ExpectedPitch);
2771                     if(Tiling != TEST_LINEAR)
2772                     {
2773                         VerifyResourcePitchInTiles<true>(MSSResourceInfo, ExpectedPitch / TileDimX); // 1 tileY wide
2774                     }
2775 
2776                     uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight * HeightMultiplier, VAlign);
2777                     if(gmmParams.ArraySize > 1)
2778                     {
2779                         // it needs to be in VALign multiple
2780                         VerifyResourceQPitch<true>(MSSResourceInfo, ExpectedQPitch);
2781                     }
2782                     uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, TileDimY);            //Align Height = ExpectedQPitch*ArraySize, to Tile-Height
2783                     VerifyResourceSize<true>(MSSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize)); //ExpectedPitch *ExpectedHeight
2784                 }
2785             }
2786 
2787             //No MCS surface if MSS creation failed
2788             if(MSSResourceInfo)
2789             {
2790                 gmmParams.Flags.Gpu.MCS = 1;
2791                 GMM_RESOURCE_INFO *MCSResourceInfo;
2792                 MCSResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2793 
2794                 VerifyResourceHAlign<true>(MCSResourceInfo, MCSHAlign); // MCS alignment same as basic RT alignment
2795                 VerifyResourceVAlign<true>(MCSResourceInfo, MCSVAlign);
2796 
2797                 uint32_t ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64, MCSHAlign) * ExpectedMCSBpp, MCSTileSize[0][0]); //AlignedWidth*bpp, then tile-alignment
2798                 VerifyResourcePitch<true>(MCSResourceInfo, ExpectedPitch);
2799                 VerifyResourcePitchInTiles<true>(MCSResourceInfo, ExpectedPitch / MCSTileSize[0][0]);
2800 
2801                 uint32_t ExpectedQPitch = gmmParams.BaseHeight;
2802                 if(gmmParams.ArraySize > 1)
2803                 {
2804                     ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, MCSVAlign); //QPitch only for array
2805                     VerifyResourceQPitch<true>(MCSResourceInfo, ExpectedQPitch);
2806                 }
2807 
2808                 uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, MCSTileSize[0][1]);
2809                 VerifyResourceSize<true>(MCSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize));
2810 
2811                 pGmmULTClientContext->DestroyResInfoObject(MCSResourceInfo);
2812             } //MCS
2813 
2814             pGmmULTClientContext->DestroyResInfoObject(MSSResourceInfo);
2815         } //NumSamples = k
2816     }     //Iterate through all input tuples
2817 }
2818 
2819 /// @brief ULT for Plannar 2D Resource - RGBP
TEST_F(CTestResource,TestPlanar2D_RGBP)2820 TEST_F(CTestResource, TestPlanar2D_RGBP)
2821 {
2822     /* Test planar surfaces where all planes are full-sized */
2823     // YYYYYYYY
2824     // YYYYYYYY
2825     // YYYYYYYY
2826     // YYYYYYYY
2827     // UUUUUUUU
2828     // UUUUUUUU
2829     // UUUUUUUU
2830     // UUUUUUUU
2831     // VVVVVVVV
2832     // VVVVVVVV
2833     // VVVVVVVV
2834     // VVVVVVVV
2835     const TEST_TILE_TYPE TileTypes[]       = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
2836     const uint32_t       PlaneRowAlignment = 16;
2837 
2838     const uint32_t TileSize[3][2] = {{1, 1},     //Linear
2839                                      {512, 8},   // TileX
2840                                      {128, 32}}; // TileY
2841     for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
2842     {
2843         TEST_TILE_TYPE Tile = TileTypes[TileIndex];
2844 
2845         GMM_RESCREATE_PARAMS gmmParams = {};
2846         gmmParams.Type                 = RESOURCE_2D;
2847         gmmParams.NoGfxMemory          = 1;
2848         gmmParams.Flags.Gpu.Texture    = 1;
2849         gmmParams.BaseWidth64          = 0x101;
2850         gmmParams.BaseHeight           = 0x101;
2851         gmmParams.Depth                = 0x1;
2852         SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
2853         gmmParams.Format = GMM_FORMAT_RGBP;
2854 
2855         GMM_RESOURCE_INFO *ResourceInfo;
2856         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2857 
2858         uint32_t Pitch, Height;
2859         if(Tile != TEST_LINEAR)
2860         {
2861             Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
2862             //Since Tile alignment factor is greater than GMM_IMCx_PLANE_ROW_ALIGNMENT=16
2863             Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
2864             Height = GMM_ULT_ALIGN(Height, TileSize[TileIndex][1]) * 3 /*Y, U, V*/;
2865         }
2866         else
2867         {
2868             Pitch  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
2869             Height = gmmParams.BaseHeight * 3 /*Y, U, V*/;
2870         }
2871         uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
2872 
2873         VerifyResourcePitch<true>(ResourceInfo, Pitch);
2874         if(Tile != TEST_LINEAR)
2875         {
2876             VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
2877         }
2878         VerifyResourceSize<true>(ResourceInfo, Size);
2879         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
2880         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
2881         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
2882 
2883         // Y plane should be at 0,0
2884         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
2885         EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
2886 
2887         // U plane should be at end of Y plane
2888         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
2889         EXPECT_EQ(Height / 3, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
2890 
2891         // V plane should be at end of U plane
2892         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
2893         EXPECT_EQ(2 * (Height / 3), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
2894 
2895         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
2896     }
2897 }
2898 
2899 /// @brief ULT for Plannar 2D Resource Unaligned - RGBP
TEST_F(CTestResource,TestPlanar2D_RGBP_Unaligned)2900 TEST_F(CTestResource, TestPlanar2D_RGBP_Unaligned)
2901 {
2902     /* Test planar surfaces where all planes are full-sized */
2903     // YYYYYYYY
2904     // YYYYYYYY
2905     // YYYYYYYY
2906     // YYYYYYYY
2907     // UUUUUUUU
2908     // UUUUUUUU
2909     // UUUUUUUU
2910     // UUUUUUUU
2911     // VVVVVVVV
2912     // VVVVVVVV
2913     // VVVVVVVV
2914     // VVVVVVVV
2915     const TEST_TILE_TYPE TileTypes[]       = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
2916     const uint32_t       PlaneRowAlignment = 16;
2917 
2918     const uint32_t TileSize[3][2] = {{1, 1},     //Linear
2919                                      {512, 8},   // TileX
2920                                      {128, 32}}; // TileY
2921     for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
2922     {
2923         TEST_TILE_TYPE Tile = TileTypes[TileIndex];
2924 
2925         GMM_RESCREATE_PARAMS gmmParams = {};
2926         gmmParams.Type                 = RESOURCE_2D;
2927         gmmParams.NoGfxMemory          = 1;
2928         gmmParams.Flags.Gpu.Texture    = 1;
2929         gmmParams.BaseWidth64          = 480;
2930         gmmParams.BaseHeight           = 300;
2931         gmmParams.Depth                = 0x1;
2932         SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
2933         gmmParams.Format = GMM_FORMAT_RGBP;
2934 
2935         GMM_RESOURCE_INFO *ResourceInfo;
2936         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
2937 
2938         uint32_t Pitch, Height;
2939         if(Tile != TEST_LINEAR)
2940         {
2941             Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
2942             //Since Tile alignment factor is greater than GMM_IMCx_PLANE_ROW_ALIGNMENT=16
2943             Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
2944             Height = GMM_ULT_ALIGN(Height, TileSize[TileIndex][1]) * 3 /*Y, U, V*/;
2945         }
2946         else
2947         {
2948             Pitch  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
2949             Height = gmmParams.BaseHeight * 3 /*Y, U, V*/;
2950         }
2951         uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
2952 
2953         VerifyResourcePitch<true>(ResourceInfo, Pitch);
2954         if(Tile != TEST_LINEAR)
2955         {
2956             VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
2957         }
2958 
2959         VerifyResourceSize<true>(ResourceInfo, Size);
2960         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
2961         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
2962         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
2963 
2964         // Y plane should be at 0,0
2965         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
2966         EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
2967 
2968         // U plane should be at end of Y plane
2969         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
2970         EXPECT_EQ(Height / 3, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
2971 
2972         // V plane should be at end of U plane
2973         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
2974         EXPECT_EQ(2 * (Height / 3), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
2975 
2976         //Resource Offset
2977         //Y PLANE
2978         GMM_REQ_OFFSET_INFO OffsetInfo = {};
2979         OffsetInfo.ReqRender           = 1;
2980         OffsetInfo.MipLevel            = 0; //Mip 0
2981         OffsetInfo.Plane               = GMM_PLANE_Y;
2982         ResourceInfo->GetOffset(OffsetInfo);
2983         EXPECT_EQ(0, OffsetInfo.Render.Offset64);
2984 
2985         //U PLANE
2986         OffsetInfo.ReqRender = 1;
2987         OffsetInfo.MipLevel  = 0; //Mip 0
2988         OffsetInfo.Plane     = GMM_PLANE_U;
2989         ResourceInfo->GetOffset(OffsetInfo);
2990         EXPECT_EQ(Pitch * (Height / 3), OffsetInfo.Render.Offset64);
2991 
2992         // V PLANE
2993         OffsetInfo.ReqRender = 1;
2994         OffsetInfo.MipLevel  = 0; //Mip 0
2995         OffsetInfo.Plane     = GMM_PLANE_V;
2996         ResourceInfo->GetOffset(OffsetInfo);
2997         EXPECT_EQ(2 * Pitch * (Height / 3), OffsetInfo.Render.Offset64);
2998 
2999         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3000     }
3001 }
3002 
3003 /// @brief ULT for Plannar 2D Resource - MFX_JPEG_YUV422V
TEST_F(CTestResource,TestPlanar2D_MFX_JPEG_YUV422V)3004 TEST_F(CTestResource, TestPlanar2D_MFX_JPEG_YUV422V)
3005 {
3006     /* Test planar surfaces where both U and V are half the size of Y */
3007     // YYYYYYYY
3008     // YYYYYYYY
3009     // YYYYYYYY
3010     // YYYYYYYY
3011     // UUUUUUUU
3012     // UUUUUUUU
3013     // VVVVVVVV
3014     // VVVVVVVV
3015     const TEST_TILE_TYPE TileTypes[]       = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
3016     const uint32_t       PlaneRowAlignment = 16;
3017 
3018     const uint32_t TileSize[3][2] = {{1, 1},     //Linear
3019                                      {512, 8},   // TileX
3020                                      {128, 32}}; // TileY
3021     for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
3022     {
3023         TEST_TILE_TYPE Tile = TileTypes[TileIndex];
3024 
3025         GMM_RESCREATE_PARAMS gmmParams = {};
3026         gmmParams.Type                 = RESOURCE_2D;
3027         gmmParams.NoGfxMemory          = 1;
3028         gmmParams.Flags.Gpu.Texture    = 1;
3029         gmmParams.BaseWidth64          = 0x101;
3030         gmmParams.BaseHeight           = 0x101;
3031         gmmParams.Depth                = 0x1;
3032         SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
3033         gmmParams.Flags.Info.Linear = 1; // GmmLib needs linear to be set as fallback for all planar surfaces
3034         gmmParams.Format            = GMM_FORMAT_MFX_JPEG_YUV422V;
3035 
3036         GMM_RESOURCE_INFO *ResourceInfo;
3037         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3038 
3039         uint32_t Pitch, Height;
3040         uint32_t YHeight, VHeight;
3041         if(Tile != TEST_LINEAR)
3042         {
3043             Pitch   = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
3044             YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
3045             YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
3046 
3047             VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) / 2, PlaneRowAlignment);
3048             VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]);
3049         }
3050         else
3051         {
3052             Pitch   = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
3053             YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
3054             VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) / 2, PlaneRowAlignment);
3055         }
3056         Height        = YHeight + 2 * VHeight;
3057         uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
3058 
3059         VerifyResourcePitch<true>(ResourceInfo, Pitch);
3060         if(Tile != TEST_LINEAR)
3061         {
3062             VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
3063         }
3064         VerifyResourceSize<true>(ResourceInfo, Size);
3065         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3066         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3067         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
3068 
3069         // Y plane should be at 0,0
3070         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
3071         EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
3072 
3073         // U plane should be at end of Y plane
3074         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
3075         EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3076 
3077         // V plane should be at end of U plane
3078         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
3079         EXPECT_EQ(YHeight + VHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3080 
3081         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3082     }
3083 }
3084 
3085 /// @brief ULT for Plannar 2D Resource - MFX_JPEG_YUV411R
TEST_F(CTestResource,TestPlanar2D_MFX_JPEG_YUV411R)3086 TEST_F(CTestResource, TestPlanar2D_MFX_JPEG_YUV411R)
3087 {
3088     /* Test planar surfaces where both U and V are quarter the size of Y */
3089     //YYYYYYYY
3090     //YYYYYYYY
3091     //YYYYYYYY
3092     //YYYYYYYY
3093     //UUUUUUUU
3094     //VVVVVVVV
3095     const TEST_TILE_TYPE TileTypes[]       = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
3096     const uint32_t       PlaneRowAlignment = 16;
3097 
3098     const uint32_t TileSize[3][2] = {{1, 1},     //Linear
3099                                      {512, 8},   // TileX
3100                                      {128, 32}}; // TileY
3101     for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
3102     {
3103         TEST_TILE_TYPE Tile = TileTypes[TileIndex];
3104 
3105         GMM_RESCREATE_PARAMS gmmParams = {};
3106         gmmParams.Type                 = RESOURCE_2D;
3107         gmmParams.NoGfxMemory          = 1;
3108         gmmParams.Flags.Gpu.Texture    = 1;
3109         gmmParams.BaseWidth64          = 0x101;
3110         gmmParams.BaseHeight           = 0x101;
3111         gmmParams.Depth                = 0x1;
3112         SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
3113         gmmParams.Format = GMM_FORMAT_MFX_JPEG_YUV411R_TYPE;
3114 
3115         GMM_RESOURCE_INFO *ResourceInfo;
3116         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3117 
3118         uint32_t Pitch, Height;
3119         uint32_t YHeight, VHeight;
3120         if(Tile != TEST_LINEAR)
3121         {
3122             Pitch   = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
3123             YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
3124             YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
3125 
3126             VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 4) / 4, PlaneRowAlignment);
3127             VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]);
3128         }
3129         else
3130         {
3131             Pitch   = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
3132             YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
3133             VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 4) / 4, PlaneRowAlignment);
3134         }
3135 
3136         Height        = YHeight + 2 * VHeight;
3137         uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
3138 
3139         VerifyResourcePitch<true>(ResourceInfo, Pitch);
3140         if(Tile != TEST_LINEAR)
3141         {
3142             VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
3143         }
3144         VerifyResourceSize<true>(ResourceInfo, Size);
3145         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3146         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3147         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
3148 
3149         // Y plane should be at 0,0
3150         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
3151         EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
3152 
3153         // U plane should be at end of Y plane
3154         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
3155         EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3156 
3157         // V plane should be at end of U plane
3158         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
3159         EXPECT_EQ(YHeight + VHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3160 
3161         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3162     }
3163 }
3164 
3165 /// @brief ULT for Plannar 2D Resource - NV12
TEST_F(CTestResource,TestPlanar2D_NV12)3166 TEST_F(CTestResource, TestPlanar2D_NV12)
3167 {
3168     /* Test planar surface with hybrid UV planes where UV plane is half the size
3169        of Y and U/V data is packed together */
3170     // YYYYYYYY
3171     // YYYYYYYY
3172     // YYYYYYYY
3173     // YYYYYYYY
3174     // [UV-Packing]
3175     const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
3176 
3177     const uint32_t TileSize[3][2] = {{1, 1},     //Linear
3178                                      {512, 8},   // TileX
3179                                      {128, 32}}; // TileY
3180     for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
3181     {
3182         TEST_TILE_TYPE Tile = TileTypes[TileIndex];
3183 
3184         GMM_RESCREATE_PARAMS gmmParams = {};
3185         gmmParams.Type                 = RESOURCE_2D;
3186         gmmParams.NoGfxMemory          = 1;
3187         gmmParams.Flags.Gpu.Texture    = 1;
3188         gmmParams.BaseWidth64          = 0x100;
3189         gmmParams.BaseHeight           = 0x100;
3190         gmmParams.Depth                = 0x1;
3191         SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
3192         gmmParams.Format = GMM_FORMAT_NV12;
3193 
3194         GMM_RESOURCE_INFO *ResourceInfo;
3195         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3196 
3197         uint32_t Pitch, Height;
3198 
3199         if(Tile != TEST_LINEAR)
3200         {
3201             Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
3202 
3203             Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]) +
3204                      GMM_ULT_ALIGN(gmmParams.BaseHeight / 2, TileSize[TileIndex][1]);
3205         }
3206         else
3207         {
3208             Pitch  = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
3209             Height = GMM_ULT_ALIGN(gmmParams.BaseHeight /*Y*/ + gmmParams.BaseHeight / 2 /*UV*/, TileSize[TileIndex][1]);
3210         }
3211         uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
3212 
3213         VerifyResourcePitch<true>(ResourceInfo, Pitch);
3214         if(Tile != TEST_LINEAR)
3215         {
3216             VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
3217         }
3218         VerifyResourceSize<true>(ResourceInfo, Size);
3219         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3220         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3221         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
3222 
3223         // Y plane should be at 0,0
3224         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
3225         EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
3226 
3227         // U/V plane should be at end of Y plane
3228         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
3229         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
3230 
3231         if(Tile != TEST_LINEAR)
3232         {
3233             EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3234             EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3235         }
3236         else
3237         {
3238             EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3239             EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3240         }
3241 
3242         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3243     }
3244 }
3245 
3246 /// @brief ULT for Planar 2D Resource - IMC4
TEST_F(CTestResource,TestPlanar2D_IMC4)3247 TEST_F(CTestResource, TestPlanar2D_IMC4)
3248 {
3249     /* Test planar surface V surface is on the right of U */
3250     // YYYYYYYY
3251     // YYYYYYYY
3252     // YYYYYYYY
3253     // YYYYYYYY
3254     // UUUUVVVV
3255     // UUUUVVVV
3256     const TEST_TILE_TYPE TileTypes[]       = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
3257     const uint32_t       PlaneRowAlignment = 16;
3258 
3259     const uint32_t TileSize[3][2] = {{1, 1},     //Linear
3260                                      {512, 8},   // TileX
3261                                      {128, 32}}; // TileY
3262     for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
3263     {
3264         TEST_TILE_TYPE Tile = TileTypes[TileIndex];
3265 
3266         GMM_RESCREATE_PARAMS gmmParams = {};
3267         gmmParams.Type                 = RESOURCE_2D;
3268         gmmParams.NoGfxMemory          = 1;
3269         gmmParams.Flags.Gpu.Texture    = 1;
3270         gmmParams.BaseWidth64          = 0x101;
3271         gmmParams.BaseHeight           = 0x101;
3272         gmmParams.Depth                = 0x1;
3273         SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
3274         gmmParams.Format = GMM_FORMAT_IMC4;
3275 
3276         GMM_RESOURCE_INFO *ResourceInfo;
3277         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3278 
3279         uint32_t Pitch, Height;
3280         uint32_t YHeight, VHeight;
3281         if(Tile != TEST_LINEAR)
3282         {
3283             Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
3284             if(Pitch / TileSize[TileIndex][0] % 2)
3285             {
3286                 Pitch += TileSize[TileIndex][0];
3287             }
3288 
3289             YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
3290             VHeight = YHeight / 2;
3291 
3292             YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
3293             VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]); // No need of PlaneRowAlignment since last plane
3294         }
3295         else
3296         {
3297             Pitch   = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
3298             YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
3299             VHeight = YHeight / 2;
3300         }
3301 
3302         Height = YHeight + VHeight;
3303 
3304         uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
3305 
3306         VerifyResourcePitch<true>(ResourceInfo, Pitch);
3307         if(Tile != TEST_LINEAR)
3308         {
3309             VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
3310         }
3311         VerifyResourceSize<true>(ResourceInfo, Size);
3312         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3313         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3314         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
3315 
3316         // Y plane should be at 0,0
3317         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
3318         EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
3319 
3320         // U plane should be at end of Y plane
3321         EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
3322         EXPECT_EQ(Pitch / 2, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
3323 
3324         if(Tile != TEST_LINEAR)
3325         {
3326             EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3327             EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3328         }
3329         else
3330         {
3331             EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3332             EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3333         }
3334 
3335         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3336     }
3337 }
3338 
3339 /// @brief ULT for Planar 2D Resource - YV12
TEST_F(CTestResource,TestPlanar2D_YV12)3340 TEST_F(CTestResource, TestPlanar2D_YV12)
3341 {
3342     /* Test planar surface V surface follows U surface linearly */
3343     // YYYYYYYY
3344     // YYYYYYYY
3345     // YYYYYYYY
3346     // YYYYYYYY
3347     // VVVVVV..  <-- V and U planes follow the Y plane, as linear
3348     // ..UUUUUU      arrays--without respect to pitch.
3349     GMM_RESCREATE_PARAMS gmmParams = {};
3350     gmmParams.Type                 = RESOURCE_2D;
3351     gmmParams.NoGfxMemory          = 1;
3352     gmmParams.Flags.Gpu.Texture    = 1;
3353     gmmParams.BaseWidth64          = 0x100;
3354     gmmParams.BaseHeight           = 0x100;
3355     gmmParams.Depth                = 0x1;
3356     gmmParams.Flags.Info.Linear    = 1; // Linear only since UV plane doesn't have a pitch
3357     gmmParams.Format               = GMM_FORMAT_YV12;
3358 
3359     GMM_RESOURCE_INFO *ResourceInfo;
3360     ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3361 
3362     uint32_t Pitch   = gmmParams.BaseWidth64;
3363     uint32_t SizeOfY = Pitch * gmmParams.BaseHeight;
3364     uint32_t Height  = (SizeOfY /*Y*/ + SizeOfY / 4 /*V*/ + SizeOfY / 4 /*U*/) / Pitch;
3365     uint32_t Size    = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
3366 
3367     VerifyResourcePitch<true>(ResourceInfo, Pitch);
3368     VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
3369     VerifyResourceSize<true>(ResourceInfo, Size);
3370     VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3371     VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3372     VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
3373 
3374     // Y plane should be at 0,0
3375     EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
3376     EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
3377 
3378     // V plane follows Y
3379     EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
3380     EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
3381 
3382     // U plane should be at end of V plane
3383     uint32_t UByteOffset = SizeOfY /* Y */ +
3384                            SizeOfY / 4; /* Size of V = 1/4 of Y */
3385     EXPECT_EQ(UByteOffset % Pitch, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
3386     EXPECT_EQ(UByteOffset / Pitch, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
3387 
3388     pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3389 }
3390 
3391 /// @brief ULT for Unified aux surface
TEST_F(CTestResource,TestUnifiedAuxSurface)3392 TEST_F(CTestResource, TestUnifiedAuxSurface)
3393 {
3394     uint32_t TileSize[] = {128, 32};
3395 
3396     GMM_RESCREATE_PARAMS gmmParams        = {};
3397     gmmParams.Type                        = RESOURCE_2D;
3398     gmmParams.NoGfxMemory                 = 1;
3399     gmmParams.Flags.Gpu.Texture           = 1;
3400     gmmParams.Flags.Gpu.CCS               = 1;
3401     gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
3402     gmmParams.BaseWidth64                 = 0x100;
3403     gmmParams.BaseHeight                  = 0x100;
3404     gmmParams.Depth                       = 0x1;
3405     SetTileFlag(gmmParams, TEST_TILEY);
3406 
3407     for(uint32_t bpp = TEST_BPP_32; bpp <= TEST_BPP_128; bpp++) // 32/64/128 only
3408     {
3409         gmmParams.Format = SetResourceFormat(static_cast<TEST_BPP>(bpp));
3410 
3411         GMM_RESOURCE_INFO *ResourceInfo;
3412         ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3413 
3414         uint64_t Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64 * GetBppValue(static_cast<TEST_BPP>(bpp)), TileSize[0]);
3415         uint64_t Size  = Pitch * GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]);
3416 
3417         Size = GMM_ULT_ALIGN(Size, PAGE_SIZE);
3418 
3419         VerifyResourcePitch<true>(ResourceInfo, Pitch);
3420         VerifyResourcePitchInTiles<false>(ResourceInfo, Pitch / TileSize[0]);
3421         VerifyResourceSize<true>(ResourceInfo, Size);
3422         VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3423         VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3424         VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
3425 
3426         uint32_t AuxPitch = Pitch;
3427         switch(bpp)
3428         {
3429             case TEST_BPP_32:
3430                 AuxPitch /= 8;
3431                 break;
3432             case TEST_BPP_64:
3433                 AuxPitch /= 4;
3434                 break;
3435             case TEST_BPP_128:
3436                 AuxPitch /= 2;
3437                 break;
3438         }
3439         uint64_t AuxSize = AuxPitch * GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]);
3440         AuxSize          = GMM_ULT_ALIGN(AuxSize, PAGE_SIZE);
3441 
3442         // Verify unified aux info
3443         EXPECT_EQ(AuxSize, ResourceInfo->GetSizeAuxSurface(GMM_AUX_CCS));
3444 
3445         if(ResourceInfo->Is64KBPageSuitable())
3446         {
3447             EXPECT_EQ(GMM_ULT_ALIGN(Size, 64 * PAGE_SIZE) + AuxSize, ResourceInfo->GetSizeSurface());
3448         }
3449         else
3450         {
3451             EXPECT_EQ(Size + AuxSize, ResourceInfo->GetSizeSurface());
3452         }
3453 
3454         EXPECT_EQ(256, ResourceInfo->GetAuxHAlign());
3455         EXPECT_EQ(128, ResourceInfo->GetAuxVAlign());
3456         EXPECT_EQ(0, ResourceInfo->GetAuxQPitch());
3457         EXPECT_EQ(AuxPitch, ResourceInfo->GetUnifiedAuxPitch());
3458         EXPECT_EQ(AuxPitch / TileSize[0], ResourceInfo->GetRenderAuxPitchTiles());
3459         EXPECT_EQ(Size, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS));
3460 
3461         pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3462     }
3463 }
3464 
3465 /// @brief ULT for Compressed Resource
TEST_F(CTestResource,TestCompressedSurface)3466 TEST_F(CTestResource, TestCompressedSurface)
3467 {
3468     uint32_t TileSize[]  = {128, 32};
3469     uint32_t CompBlock[] = {4, 4};
3470 
3471     GMM_RESCREATE_PARAMS gmmParams = {};
3472     gmmParams.Type                 = RESOURCE_2D;
3473     gmmParams.NoGfxMemory          = 1;
3474     gmmParams.Flags.Gpu.Texture    = 1;
3475     gmmParams.BaseWidth64          = 0x100;
3476     gmmParams.BaseHeight           = 0x100;
3477     gmmParams.Depth                = 0x1;
3478     SetTileFlag(gmmParams, TEST_TILEY);
3479     //TODO: Programatically test all compression formats.
3480     gmmParams.Format = GMM_FORMAT_BC1_UNORM; // BC1 is 4x4 compression block, 64bpe
3481 
3482     GMM_RESOURCE_INFO *ResourceInfo;
3483     ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
3484 
3485     uint64_t Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64 / CompBlock[0] * GetBppValue(TEST_BPP_64), TileSize[0]);
3486     uint64_t Size  = Pitch * GMM_ULT_ALIGN(gmmParams.BaseHeight / CompBlock[1], TileSize[1]);
3487     Size           = GMM_ULT_ALIGN(Size, PAGE_SIZE);
3488 
3489     VerifyResourcePitch<true>(ResourceInfo, Pitch);
3490     VerifyResourcePitchInTiles<false>(ResourceInfo, Pitch / TileSize[0]);
3491     VerifyResourceSize<true>(ResourceInfo, Size);
3492     VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3493     VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
3494     VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
3495 
3496     pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
3497 }
3498