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