blob: d8adb955898786c97743ef1bc3cf8c1fb106ec88 [file] [log] [blame]
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen9ResourceULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// CTestGen9Resource Constructor
///
/////////////////////////////////////////////////////////////////////////////////////
CTestGen9Resource::CTestGen9Resource()
{
}
/////////////////////////////////////////////////////////////////////////////////////
/// CTestGen9Resource Destructor
///
/////////////////////////////////////////////////////////////////////////////////////
CTestGen9Resource::~CTestGen9Resource()
{
}
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Resource fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
/// It also calls SetupTestCase from CommonULT to initialize global context and others.
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen9Resource::SetUpTestCase()
{
GfxPlatform.eProductFamily = IGFX_SKYLAKE;
GfxPlatform.eRenderCoreFamily = IGFX_GEN9_CORE;
CommonULT::SetUpTestCase();
printf("%s\n", __FUNCTION__);
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen9Resource::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
// ********************************************************************************//
/// @brief ULT for 1D Linear Resource
TEST_F(CTestGen9Resource, Test1DLinearResource)
{
// Horizontal pixel alignment
const uint32_t HAlign = 64;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.Linear = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate more than 1 page
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1001;
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D Linear Resource Arrays
TEST_F(CTestGen9Resource, Test1DLinearResourceArrays)
{
// Horizontal pixel alignment
const uint32_t HAlign = 64;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.Linear = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.ArraySize = 4;
// Allocate more than 1 page
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1001;
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * gmmParams.ArraySize, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<true>(ResourceInfo, AlignedWidth);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D Mipped Linear Resource
TEST_F(CTestGen9Resource, Test1DLinearResourceMips)
{
// Horizontal pixel alignment
const uint32_t HAlign = 64;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.Linear = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.MaxLod = 5;
// Allocate 256x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x100;
gmmParams.BaseHeight = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
for(int mip = 1; mip <= gmmParams.MaxLod; mip++)
{
// Since 1D doesn't have a height, mips are just based on width
AlignedWidth += GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> mip, HAlign);
}
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
// Mip0 should be at offset 0. X/Y/Z Offset should be 0 for linear.
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 0; //Mip 0
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(0, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
// All mips should be right after one another linearly
uint32_t StartOfMip = 0;
for(int mip = 1; mip <= gmmParams.MaxLod; mip++)
{
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = mip;
ResourceInfo->GetOffset(OffsetInfo);
StartOfMip += GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> (mip - 1), HAlign) * GetBppValue(bpp);
EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D TileYs Resource -TRMODE_64KB
TEST_F(CTestGen9Resource, Test1DTileYsResource)
{
const uint32_t TileSize[TEST_BPP_MAX] = {65536, 32768, 16384, 8192, 4096};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[i]);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate more than 1 "tile", where applicable. Max width of the surface can only be
// 16K (see RENDER_SURFACE_STATE). Depending on the bpp, 16K width may not use more than
// 1 "tile" (only 64/128 will use "multi-tile").
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 16 * 1024; // 16K is the max width you can specify
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[i]);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D TileYS Resource Arrays
TEST_F(CTestGen9Resource, Test1DTileYsResourceArrays)
{
const uint32_t TileSize[TEST_BPP_MAX] = {65536, 32768, 16384, 8192, 4096};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.ArraySize = 4;
// Allocate more than 1 page
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 16 * 1024; // 16K is the max width you can specify
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[i]);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * gmmParams.ArraySize, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<true>(ResourceInfo, AlignedWidth);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D Mipped TileYS Resource
TEST_F(CTestGen9Resource, Test1DTileYsResourceMips)
{
const uint32_t TileSize[TEST_BPP_MAX] = {65536, 32768, 16384, 8192, 4096};
const uint32_t Mts[TEST_BPP_MAX] = {32768, 16384, 8192, 4096, 2048};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.MaxLod = 5;
// Allocate all mips in 1 tile or multiple tiles, depending on the bpp
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 16 * 1024; // 16K is the max width you can specify
gmmParams.BaseHeight = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t MaxMip;
uint32_t MipTailStart = gmmParams.MaxLod;
for(MaxMip = 0; MaxMip <= gmmParams.MaxLod; MaxMip++)
{
if((gmmParams.BaseWidth64 >> MaxMip) <= Mts[i])
{
MipTailStart = MaxMip;
break;
}
}
uint32_t AlignedWidth = 0;
for(int mip = 0; mip <= MaxMip; mip++)
{
// Since 1D doesn't have a height, mips are just based on width
AlignedWidth += GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> mip, TileSize[i]);
;
}
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
// All mips should be right after one another linearly, until the miptail
uint32_t StartOfMip = 0;
int mip;
for(mip = 0; mip < MaxMip; mip++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = mip;
ResourceInfo->GetOffset(OffsetInfo);
StartOfMip += (mip == 0 ? 0 : GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> (mip - 1), TileSize[i]) * GetBppValue(bpp));
EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
}
uint32_t MipTailOffsets[GMM_ULT_MAX_MIPMAP] = {32768, 16384, 8192, 4096, 2048, 1024, 768, 512, 448, 384, 320, 256, 192, 128, 64};
// Check for offset inside miptails.
EXPECT_EQ(MipTailStart, ResourceInfo->GetPackedMipTailStartLod());
StartOfMip += GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> (mip - 1), TileSize[i]) * GetBppValue(bpp); // Start of MipTail
for(int slot = 0; mip <= gmmParams.MaxLod; mip++, slot++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = mip;
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64); // Start of Miptail
EXPECT_EQ(MipTailOffsets[slot], OffsetInfo.Render.XOffset); // Offset within miptail
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D TileYs Resource -TRMODE_4KB
TEST_F(CTestGen9Resource, Test1DTileYfResource)
{
const uint32_t TileSize[TEST_BPP_MAX] = {4096, 2048, 1024, 512, 256};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYf = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[i]);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate more than 1 "tile"
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = TileSize[i] + 1;
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[i]);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D TileYF Resource Arrays
TEST_F(CTestGen9Resource, Test1DTileYfResourceArrays)
{
const uint32_t TileSize[TEST_BPP_MAX] = {4096, 2048, 1024, 512, 256};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYf = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.ArraySize = 4;
// Allocate more than 1 page
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 16 * 1024; // 16K is the max width you can specify
gmmParams.BaseHeight = 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[i]);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * gmmParams.ArraySize, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<true>(ResourceInfo, AlignedWidth);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 1D Mipped TileYF Resource
TEST_F(CTestGen9Resource, Test1DTileYfResourceMips)
{
const uint32_t TileSize[TEST_BPP_MAX] = {4096, 2048, 1024, 512, 256};
const uint32_t Mts[TEST_BPP_MAX] = {2048, 1024, 512, 256, 128};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_1D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYf = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.MaxLod = 8;
// Allocate all mips in 1 tile or multiple tiles, depending on the bpp
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 16 * 1024; // 16K is the max width you can specify
gmmParams.BaseHeight = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t MaxMip;
uint32_t MipTailStart = gmmParams.MaxLod;
for(MaxMip = 0; MaxMip <= gmmParams.MaxLod; MaxMip++)
{
if((gmmParams.BaseWidth64 >> MaxMip) <= Mts[i])
{
MipTailStart = MaxMip;
break;
}
}
uint32_t AlignedWidth = 0;
for(int mip = 0; mip <= MaxMip; mip++)
{
// Since 1D doesn't have a height, mips are just based on width
AlignedWidth += GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> mip, TileSize[i]);
}
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, TileSize[i]);
VerifyResourceVAlign<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitch<false>(ResourceInfo, 0); // N/A for 1D
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
// All mips should be right after one another linearly, until the miptail
uint32_t StartOfMip = 0;
int mip;
for(mip = 0; mip < MaxMip; mip++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = mip;
ResourceInfo->GetOffset(OffsetInfo);
StartOfMip += (mip == 0 ? 0 : GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> (mip - 1), TileSize[i]) * GetBppValue(bpp));
EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
}
uint32_t MipTailOffsets[12] = {2048, 1024, 768, 512, 448, 384, 320, 256, 192, 128, 64, 0};
// Check for offset inside miptails.
EXPECT_EQ(MipTailStart, ResourceInfo->GetPackedMipTailStartLod());
StartOfMip += GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> (mip - 1), TileSize[i]) * GetBppValue(bpp); // Start of MipTail
for(int slot = 0; mip <= gmmParams.MaxLod; mip++, slot++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = mip;
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64); // Start of Miptail
EXPECT_EQ(MipTailOffsets[slot], OffsetInfo.Render.XOffset); // Offset within miptail
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
// ********************************************************************************//
/// @brief ULT for 2D TileYs Resource
TEST_F(CTestGen9Resource, Test2DTileYsResource)
{
const uint32_t HAlign[TEST_BPP_MAX] = {256, 256, 128, 128, 64};
const uint32_t VAlign[TEST_BPP_MAX] = {256, 128, 128, 64, 64};
const uint32_t TileSize[TEST_BPP_MAX][2] = {{256, 256},
{512, 128},
{512, 128},
{1024, 64},
{1024, 64}};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.Flags.Gpu.Texture = 1;
//Allocate 1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0]); // As wide as 1 Tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 Tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(64)); // 1 Tile Big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not Tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate surface that requires multi tiles in two dimension
// Allocate 2 tiles in X dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(64) * 2); // 2 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = TileSize[i][1] + 1; // 1 row larger than 1 tile height
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(64) * 4); // 4 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 2D TileYs Resource with Mips
TEST_F(CTestGen9Resource, Test2DTileYsMippedResource)
{
const uint32_t HAlign[TEST_BPP_MAX] = {256, 256, 128, 128, 64};
const uint32_t VAlign[TEST_BPP_MAX] = {256, 128, 128, 64, 64};
const uint32_t TileSize[TEST_BPP_MAX][2] = {{256, 256},
{512, 128},
{512, 128},
{1024, 64},
{1024, 64}};
const uint32_t MtsWidth[TEST_BPP_MAX] = {128, 128, 64, 64, 32};
const uint32_t MtsHeight[TEST_BPP_MAX] = {256, 128, 128, 64, 64};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.MaxLod = 5;
gmmParams.ArraySize = 4;
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
uint32_t AlignedWidth = 0;
uint32_t AlignedHeight = 0;
uint32_t ExpectedPitch = 0;
uint32_t MipTailStartLod = 0;
// Valigned Mip Heights
uint32_t Mip0Height = 0;
uint32_t Mip1Height = 0;
uint32_t Mip2Height = 0;
uint32_t Mip3Height = 0;
uint32_t Mip4Height = 0;
uint32_t Mip5Height = 0;
uint32_t Mip2Higher = 0; // Sum of aligned heights of Mip2 and above
uint32_t MipTailHeight = 0;
// Haligned Mip Widths
uint32_t Mip0Width = 0;
uint32_t Mip1Width = 0;
uint32_t Mip2Width = 0;
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x120;
gmmParams.BaseHeight = 0x120;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
// find the miptail start level
{
uint32_t MipWidth = gmmParams.BaseWidth64;
uint32_t MipHeight = gmmParams.BaseHeight;
while(!(MipWidth <= MtsWidth[i] && MipHeight <= MtsHeight[i]))
{
MipTailStartLod++;
MipWidth = (uint32_t)(GMM_ULT_MAX(1, gmmParams.BaseWidth64 >> MipTailStartLod));
MipHeight = GMM_ULT_MAX(1, gmmParams.BaseHeight >> MipTailStartLod);
}
}
// Mip resource Aligned Width calculation
Mip0Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign[i]);
Mip1Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 1, HAlign[i]);
Mip2Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 2, HAlign[i]);
AlignedWidth = GMM_ULT_MAX(Mip0Width, Mip1Width + Mip2Width);
Mip0Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign[i]);
if(MipTailStartLod == 2)
{
EXPECT_EQ(2, ResourceInfo->GetPackedMipTailStartLod());
// Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
Mip1Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 1, VAlign[i]);
Mip2Height = Mip2Higher = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 2, VAlign[i]);
}
else if(MipTailStartLod == 3)
{
EXPECT_EQ(3, ResourceInfo->GetPackedMipTailStartLod());
// Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
Mip1Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 1, VAlign[i]);
Mip2Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 2, VAlign[i]);
// Miptail started lod
MipTailHeight = VAlign[i];
Mip2Higher = Mip2Height + MipTailHeight;
}
else if(MipTailStartLod == 4)
{
EXPECT_EQ(4, ResourceInfo->GetPackedMipTailStartLod());
// Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
Mip1Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 1, VAlign[i]);
Mip2Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 2, VAlign[i]);
Mip3Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 3, VAlign[i]);
// Miptail started lod
MipTailHeight = VAlign[i];
Mip2Higher = Mip2Height + Mip3Height + MipTailHeight;
}
uint32_t MaxHeight = GMM_ULT_MAX(Mip1Height, Mip2Higher);
AlignedHeight = Mip0Height + MaxHeight;
AlignedHeight = GMM_ULT_ALIGN(AlignedHeight, VAlign[i]);
ExpectedPitch = AlignedWidth * GetBppValue(bpp);
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, GMM_BYTES(32));
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
VerifyResourcePitchInTiles<true>(ResourceInfo, static_cast<uint32_t>(ExpectedPitch / TileSize[i][0]));
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * AlignedHeight * gmmParams.ArraySize, PAGE_SIZE));
VerifyResourceQPitch<false>(ResourceInfo, AlignedHeight);
// Mip 0 offsets, offset is 0,0
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.MipLevel = 0;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip0Size = ExpectedPitch * Mip0Height;
EXPECT_EQ(0, ReqInfo.Render.Offset64);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
// Mip 1 offsets
ReqInfo = {0};
ReqInfo.MipLevel = 1;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip1Offset = Mip0Size;
EXPECT_EQ(Mip1Offset, ReqInfo.Render.Offset64);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
// Mip 2 offset
ReqInfo = {0};
ReqInfo.MipLevel = 2;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip2Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
uint32_t Mip2X = GFX_ALIGN_FLOOR(uint32_t(Mip2Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip2Y = GFX_ALIGN_FLOOR(uint32_t(Mip2Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip2RenderAlignedOffset = Mip2Y * ExpectedPitch + (Mip2X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip2RenderAlignedOffset, ReqInfo.Render.Offset64);
switch(bpp)
{
case TEST_BPP_8:
EXPECT_EQ(128, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
EXPECT_EQ(256, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
// Mip 3 offset
ReqInfo = {0};
ReqInfo.MipLevel = 3;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip3Offset = 0;
switch(bpp)
{
case TEST_BPP_8:
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(128, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(64, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
Mip3Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(256, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
Mip3Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(512, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
Mip3Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
uint32_t Mip3X = GFX_ALIGN_FLOOR(uint32_t(Mip3Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip3Y = GFX_ALIGN_FLOOR(uint32_t(Mip3Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip3RenderAlignedOffset = Mip3Y * ExpectedPitch + (Mip3X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip3RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 4 offset
ReqInfo = {0};
ReqInfo.MipLevel = 4;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip4Offset = 0;
switch(bpp)
{
case TEST_BPP_8:
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(64, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(128, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
Mip4Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(64, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
Mip4Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(32, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
Mip4Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height + Mip3Height) * ExpectedPitch;
EXPECT_EQ(512, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
uint32_t Mip4X = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip4Y = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip4RenderAlignedOffset = Mip4Y * ExpectedPitch + (Mip4X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip4RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 5 offset
ReqInfo = {0};
ReqInfo.MipLevel = 4;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip5Offset = 0;
switch(bpp)
{
case TEST_BPP_8:
Mip5Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(64, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
Mip5Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(128, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
Mip5Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(64, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
Mip5Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(32, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
Mip5Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height + Mip3Height) * ExpectedPitch;
EXPECT_EQ(512, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
uint32_t Mip5X = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip5Y = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip5RenderAlignedOffset = Mip5Y * ExpectedPitch + (Mip5X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip5RenderAlignedOffset, ReqInfo.Render.Offset64);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 2D TileYf Resource
TEST_F(CTestGen9Resource, Test2DTileYfResource)
{
const uint32_t HAlign[TEST_BPP_MAX] = {64, 64, 32, 32, 16};
const uint32_t VAlign[TEST_BPP_MAX] = {64, 32, 32, 16, 16};
const uint32_t TileSize[TEST_BPP_MAX][2] = {{64, 64},
{128, 32},
{128, 32},
{256, 16},
{256, 16}};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.TiledYf = 1;
gmmParams.Flags.Gpu.Texture = 1;
//Allocate 1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0]); // As wide as 1 Tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 Tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4)); // 1 Tile Big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not Tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate surface that requires multi tiles in two dimension
// Allocate 2 tiles in X dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4) * 2); // 2 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = TileSize[i][1] + 1; // 1 row larger than 1 tile height
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4) * 4); // 4 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 2D TileYf Mipped Resource
TEST_F(CTestGen9Resource, Test2DTileYfMippedResource)
{
const uint32_t HAlign[TEST_BPP_MAX] = {64, 64, 32, 32, 16};
const uint32_t VAlign[TEST_BPP_MAX] = {64, 32, 32, 16, 16};
const uint32_t TileSize[TEST_BPP_MAX][2] = {{64, 64},
{128, 32},
{128, 32},
{256, 16},
{256, 16}};
const uint32_t MtsWidth[TEST_BPP_MAX] = {32, 32, 16, 16, 8};
const uint32_t MtsHeight[TEST_BPP_MAX] = {64, 32, 32, 16, 16};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.TiledYf = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.MaxLod = 4;
gmmParams.ArraySize = 4;
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
uint32_t AlignedWidth = 0;
uint32_t AlignedHeight = 0;
uint32_t ExpectedPitch = 0;
uint32_t MipTailStartLod = 0;
// Valigned Mip Heights
uint32_t Mip0Height = 0;
uint32_t Mip1Height = 0;
uint32_t Mip2Height = 0;
uint32_t Mip3Height = 0;
uint32_t Mip4Height = 0;
uint32_t Mip5Height = 0;
uint32_t Mip2Higher = 0; // Sum of aligned heights of Mip2 and above
uint32_t MipTailHeight = 0;
// Haligned Mip Widths
uint32_t Mip0Width = 0;
uint32_t Mip1Width = 0;
uint32_t Mip2Width = 0;
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x38;
gmmParams.BaseHeight = 0x38;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
// find the miptail start level
{
uint32_t MipWidth = gmmParams.BaseWidth64;
uint32_t MipHeight = gmmParams.BaseHeight;
while(!(MipWidth <= MtsWidth[i] && MipHeight <= MtsHeight[i]))
{
MipTailStartLod++;
MipWidth = (uint32_t)(GMM_ULT_MAX(1, gmmParams.BaseWidth64 >> MipTailStartLod));
MipHeight = GMM_ULT_MAX(1, gmmParams.BaseHeight >> MipTailStartLod);
}
}
// Mip resource Aligned Width calculation
Mip0Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign[i]);
Mip0Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign[i]);
if(MipTailStartLod == 1)
{
EXPECT_EQ(1, ResourceInfo->GetPackedMipTailStartLod());
// Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
Mip1Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 1, VAlign[i]);
AlignedWidth = Mip0Width;
}
if(MipTailStartLod == 2)
{
EXPECT_EQ(2, ResourceInfo->GetPackedMipTailStartLod());
// Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
Mip1Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 1, VAlign[i]);
Mip2Height = Mip2Higher = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 2, VAlign[i]);
Mip1Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 1, HAlign[i]);
Mip2Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 2, HAlign[i]);
AlignedWidth = GMM_ULT_MAX(Mip0Width, Mip1Width + Mip2Width);
}
if(MipTailStartLod == 3)
{
EXPECT_EQ(3, ResourceInfo->GetPackedMipTailStartLod());
// Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
Mip1Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 1, VAlign[i]);
Mip2Height = GMM_ULT_ALIGN(gmmParams.BaseHeight >> 2, VAlign[i]);
// Miptail started lod
MipTailHeight = VAlign[i];
Mip2Higher = Mip2Height + Mip3Height + MipTailHeight;
Mip1Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 1, HAlign[i]);
Mip2Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 2, HAlign[i]);
AlignedWidth = GMM_ULT_MAX(Mip0Width, Mip1Width + Mip2Width);
}
uint32_t MaxHeight = GMM_ULT_MAX(Mip1Height, Mip2Higher);
AlignedHeight = Mip0Height + MaxHeight;
AlignedHeight = GMM_ULT_ALIGN(AlignedHeight, VAlign[i]);
ExpectedPitch = AlignedWidth * GetBppValue(bpp);
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, GMM_BYTES(32));
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
VerifyResourcePitchInTiles<true>(ResourceInfo, static_cast<uint32_t>(ExpectedPitch / TileSize[i][0]));
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * AlignedHeight * gmmParams.ArraySize, PAGE_SIZE));
VerifyResourceQPitch<false>(ResourceInfo, AlignedHeight);
// Mip 0 offsets, offset is 0,0
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.MipLevel = 0;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip0Size = ExpectedPitch * Mip0Height;
EXPECT_EQ(0, ReqInfo.Render.Offset64);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
// Mip 1 offsets
ReqInfo = {0};
ReqInfo.MipLevel = 1;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip1Offset = Mip0Size;
switch(bpp)
{
case TEST_BPP_8:
EXPECT_EQ(32, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
EXPECT_EQ(64, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
EXPECT_EQ(Mip1Offset, ReqInfo.Render.Offset64);
// Mip 2 offset
ReqInfo = {0};
ReqInfo.MipLevel = 2;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip2Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
switch(bpp)
{
case TEST_BPP_8:
EXPECT_EQ(16, ReqInfo.Render.XOffset);
EXPECT_EQ(32, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
EXPECT_EQ(32, ReqInfo.Render.XOffset);
EXPECT_EQ(16, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
EXPECT_EQ(64, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
EXPECT_EQ(128, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
uint32_t Mip2X = GFX_ALIGN_FLOOR(uint32_t(Mip2Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip2Y = GFX_ALIGN_FLOOR(uint32_t(Mip2Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip2RenderAlignedOffset = Mip2Y * ExpectedPitch + (Mip2X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip2RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 3 offset
ReqInfo = {0};
ReqInfo.MipLevel = 3;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip3Offset = 0;
switch(bpp)
{
case TEST_BPP_8:
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(48, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(24, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(32, ReqInfo.Render.XOffset);
EXPECT_EQ(16, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(64, ReqInfo.Render.XOffset);
EXPECT_EQ(8, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
Mip3Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(128, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
break;
default:
break;
}
uint32_t Mip3X = GFX_ALIGN_FLOOR(uint32_t(Mip3Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip3Y = GFX_ALIGN_FLOOR(uint32_t(Mip3Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip3RenderAlignedOffset = Mip3Y * ExpectedPitch + (Mip3X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip3RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 4 offset
ReqInfo = {0};
ReqInfo.MipLevel = 4;
ReqInfo.ReqRender = 1;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip4Offset = 0;
switch(bpp)
{
case TEST_BPP_8:
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(32, ReqInfo.Render.YOffset);
break;
case TEST_BPP_16:
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(16, ReqInfo.Render.YOffset);
break;
case TEST_BPP_32:
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(24, ReqInfo.Render.YOffset);
break;
case TEST_BPP_64:
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(12, ReqInfo.Render.YOffset);
break;
case TEST_BPP_128:
Mip4Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + Mip2Height) * ExpectedPitch;
EXPECT_EQ(64, ReqInfo.Render.XOffset);
EXPECT_EQ(8, ReqInfo.Render.YOffset);
break;
default:
break;
}
uint32_t Mip4X = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset % ExpectedPitch), TileSize[i][0]);
uint32_t Mip4Y = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset / ExpectedPitch), TileSize[i][1]);
uint32_t Mip4RenderAlignedOffset = Mip4Y * ExpectedPitch + (Mip4X / TileSize[i][0]) * (TileSize[i][0] * TileSize[i][1]);
EXPECT_EQ(Mip4RenderAlignedOffset, ReqInfo.Render.Offset64);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
// ********************************************************************************//
/// @brief ULT for 3D Linear Resource
TEST_F(CTestGen9Resource, Test3DLinearResource)
{
// Horizontal/Vertical pixel alignment
const uint32_t HAlign = 16;
const uint32_t VAlign = 4;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.Linear = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
const uint32_t MinPitch = 32;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
const uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
PitchInBytes = GMM_ULT_MAX(PitchInBytes, MinPitch);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
const uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 256 x 256 x 256
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 256;
gmmParams.BaseHeight = 256;
gmmParams.Depth = 256;
const uint32_t MinPitch = 32;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
const uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
const uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight * gmmParams.Depth, PAGE_SIZE);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
VerifyResourceSize<true>(ResourceInfo, AlignedSize);
VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 3D TileX Resource
TEST_F(CTestGen9Resource, Test3DTileXResource)
{
// Horizontal/Vertical pixel alignment
const uint32_t HAlign = 16;
const uint32_t VAlign = 4;
const uint32_t TileSize[TEST_BPP_MAX][3] = {{512, 8, 1},
{512, 8, 1},
{512, 8, 1},
{512, 8, 1},
{512, 8, 1}};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledX = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0]);
VerifyResourcePitchInTiles<true>(ResourceInfo, 1);
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, 2 * TileSize[i][0]);
VerifyResourcePitchInTiles<true>(ResourceInfo, 2);
VerifyResourceSize<true>(ResourceInfo, 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = TileSize[i][1] + 1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, 2 * TileSize[i][0]);
VerifyResourcePitchInTiles<true>(ResourceInfo, 2);
VerifyResourceSize<true>(ResourceInfo, 2 * 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, 2 * TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y/Z dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = TileSize[i][1] + 1;
gmmParams.Depth = TileSize[i][2] + 1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, 2 * TileSize[i][0]);
VerifyResourcePitchInTiles<true>(ResourceInfo, 2);
VerifyResourceSize<true>(ResourceInfo, 2 * 2 * 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, 2 * TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 3D TileY Resource
TEST_F(CTestGen9Resource, Test3DTileYResource)
{
// Horizontal/Vertical pixel alignment
const uint32_t HAlign = 16;
const uint32_t VAlign = 4;
const uint32_t TileSize[TEST_BPP_MAX][3] = {{128, 32, 1},
{128, 32, 1},
{128, 32, 1},
{128, 32, 1},
{128, 32, 1}};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
const uint32_t MinPitch = 32;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
const uint32_t MinPitch = 32;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = TileSize[i][1] + 1;
gmmParams.Depth = 0x1;
const uint32_t MinPitch = 32;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1] * 2);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y/Z dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = TileSize[i][1] + 1;
gmmParams.Depth = TileSize[i][2] + 1;
const uint32_t MinPitch = 32;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileSize[i][0]);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileSize[i][0] * 2 * 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1] * 2);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 3D TileYs Resource
TEST_F(CTestGen9Resource, Test3DTileYsResource)
{
// Horizontal/Vertical pixel alignment
const uint32_t HAlign[TEST_BPP_MAX] = {64, 32, 32, 32, 16};
const uint32_t VAlign[TEST_BPP_MAX] = {32, 32, 32, 16, 16};
const uint32_t TileSize[TEST_BPP_MAX][3] = {{64, 32, 32},
{64, 32, 32},
{128, 32, 16},
{256, 16, 16},
{256, 16, 16}};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0]); // As wide as 1 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tile wide
VerifyResourceSize<false>(ResourceInfo, GMM_KBYTE(64)); // 1 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<false>(ResourceInfo, GMM_KBYTE(64) * 2); // 2 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = TileSize[i][1] + 1; // 1 row larger than 1 tile height
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<false>(ResourceInfo, GMM_KBYTE(64) * 4); // 4 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y/Z dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
gmmParams.BaseHeight = TileSize[i][1] + 1; // 1 row larger than 1 tile height
gmmParams.Depth = TileSize[i][2] + 1; // 1 plane larger than 1 tile depth
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, TileSize[i][0] * 2); // As wide as 2 tile
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(64) * 8); // 8 tile big
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 3D TileYs Mipped Resource
TEST_F(CTestGen9Resource, Test3DTileYsMippedResource)
{
// Horizontal/Vertical pixel alignment
const uint32_t HAlign[TEST_BPP_MAX] = {64, 32, 32, 32, 16};
const uint32_t VAlign[TEST_BPP_MAX] = {32, 32, 32, 16, 16};
const uint32_t TileSize[TEST_BPP_MAX][3] = {{64, 32, 32},
{64, 32, 32},
{128, 32, 16},
{256, 16, 16},
{256, 16, 16}};
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
const uint32_t ResourceWidth = 0x100;
const uint32_t ResourceHeight = 0x100;
const uint32_t ResourceDepth = 0x100;
const uint32_t MaxLod = 0x5;
TEST_BPP bpp = static_cast<TEST_BPP>(i);
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.TiledYs = 1;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = ResourceWidth;
gmmParams.BaseHeight = ResourceHeight;
gmmParams.Depth = ResourceDepth;
gmmParams.MaxLod = MaxLod;
gmmParams.Format = SetResourceFormat(bpp);
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
const uint32_t Pitch = ResourceWidth * GetBppValue(bpp);
const uint32_t Mip0Height = ResourceHeight;
// Mip0
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 0;
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(0, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
// Mip1
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 1;
ResourceInfo->GetOffset(OffsetInfo);
const uint32_t SizeOfMip0 = Pitch * ResourceHeight * TileSize[i][2];
const uint32_t Mip1Offset = SizeOfMip0;
const uint32_t Mip1Width = ResourceWidth >> 1;
const uint32_t Mip1Height = ResourceHeight >> 1;
EXPECT_EQ(Mip1Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
// Mip2
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 2;
ResourceInfo->GetOffset(OffsetInfo);
const uint32_t Mip2Height = ResourceHeight >> 2;
const uint32_t Mip2Offset = Mip1Offset + Mip1Width * GetBppValue(bpp) / TileSize[i][0] * GMM_KBYTE(64);
EXPECT_EQ(Mip2Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
// Mip3
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 3;
ResourceInfo->GetOffset(OffsetInfo);
const uint32_t Mip3Y = (Mip0Height + Mip2Height) * TileSize[i][2];
const uint32_t Mip3X = Mip1Width;
const uint32_t Mip3Offset = Mip3Y * Pitch + Mip3X * GetBppValue(bpp) / TileSize[i][0] * GMM_KBYTE(64);
EXPECT_EQ(Mip3Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(bpp == TEST_BPP_8 ? 32 : 0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
// Mip4
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 4;
ResourceInfo->GetOffset(OffsetInfo);
const uint32_t Mip3Height = ResourceHeight >> 3;
const uint32_t Mip4Y = (Mip0Height + Mip2Height + Mip3Height) * TileSize[i][2];
const uint32_t Mip4X = Mip1Width;
const uint32_t Mip4Offset = Mip4Y * Pitch + Mip4X * GetBppValue(bpp) / TileSize[i][0] * GMM_KBYTE(64);
switch(bpp)
{
case TEST_BPP_8:
EXPECT_EQ(Mip3Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(16, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_16:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(32, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_32:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(64, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_64:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(128, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_128:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
default:
break;
}
// Mip5
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 5;
ResourceInfo->GetOffset(OffsetInfo);
const uint32_t Mip4Height = ResourceHeight >> 4;
const uint32_t Mip5Y = (Mip0Height + Mip2Height + Mip3Height + Mip4Height) * TileSize[i][2];
const uint32_t Mip5X = Mip1Width;
const uint32_t Mip5Offset = Mip5Y * Pitch + Mip4X * GetBppValue(bpp) / TileSize[i][0] * GMM_KBYTE(64);
switch(bpp)
{
case TEST_BPP_8:
EXPECT_EQ(Mip3Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(16, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_16:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(16, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_32:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(16, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_64:
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(8, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
case TEST_BPP_128:
EXPECT_EQ(Mip5Offset, OffsetInfo.Render.Offset64);
EXPECT_EQ(128, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
break;
default:
break;
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 3D TileYf Resource
TEST_F(CTestGen9Resource, Test3DTileYfResource)
{
// Horizontal/Vertical pixel alignment
const uint32_t HAlign[TEST_BPP_MAX] = {16, 8, 8, 8, 4};
const uint32_t VAlign[TEST_BPP_MAX] = {16, 16, 16, 8, 8};
const uint32_t TileSize[TEST_BPP_MAX][3] = {{16, 16, 16},
{16, 16, 16},
{32, 16, 8},
{64, 8, 8},
{64, 8, 8}};
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledYf = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1x1 surface
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0], PitchAlignment));
VerifyResourcePitchInTiles<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0], PitchAlignment) / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0], PitchAlignment) / TileSize[i][0] * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment));
VerifyResourcePitchInTiles<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment) / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment) / TileSize[i][0] * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1]);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = TileSize[i][1] + 1;
gmmParams.Depth = 0x1;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment));
VerifyResourcePitchInTiles<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment) / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment) / TileSize[i][0] * 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1] * 2);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate 2 tiles in X/Y/Z dimension
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = (TileSize[i][0] / GetBppValue(bpp)) + 1;
gmmParams.BaseHeight = TileSize[i][1] + 1;
gmmParams.Depth = TileSize[i][2] + 1;
const uint32_t PitchAlignment = 32;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign[i]);
VerifyResourceVAlign<true>(ResourceInfo, VAlign[i]);
VerifyResourcePitch<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment));
VerifyResourcePitchInTiles<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment) / TileSize[i][0]);
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(TileSize[i][0] * 2, PitchAlignment) / TileSize[i][0] * 2 * 2 * GMM_KBYTE(4));
VerifyResourceQPitch<true>(ResourceInfo, TileSize[i][1] * 2);
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Cube Linear Resource
TEST_F(CTestGen9Resource, TestCubeLinearResource)
{
const uint32_t HAlign = 16;
const uint32_t VAlign = 4;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_CUBE;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.Linear = 1;
gmmParams.Flags.Gpu.Texture = 1;
// Allocate 1x1
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x1;
gmmParams.BaseHeight = 0x1;
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
uint32_t ExpectedPitch = GMM_ULT_MAX(GMM_BYTES(32), HAlign * GetBppValue(bpp)); // Min Pitch = 32 bytes
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch); // As wide as 1 tile
VerifyResourcePitchInTiles<false>(ResourceInfo, 1); // not applicable
uint32_t ExpectedQPitch = VAlign;
VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile
VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned PAGE_SIZE
GMM_ULT_ALIGN(ExpectedPitch *
__GMM_MAX_CUBE_FACE * ExpectedQPitch,
PAGE_SIZE));
for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.CubeFace = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(CubeFaceIndex * ExpectedQPitch * ExpectedPitch,
OffsetInfo.Render.Offset64); // Render offset is tile's base address on which cube face begins.
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
// Allocate arbitrary size (X/Y dimension not applicable as linear surface)
// Width and Height must be equal
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x201; // 512 + 1, help ult HAlign/VAlign/Pitch alignment logic as well.
gmmParams.BaseHeight = gmmParams.BaseWidth64; // Heigth must be equal to width.
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
uint32_t ExpectedPitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * GetBppValue(bpp); // HAligned-width in bytes.
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, GMM_BYTES(32));
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
VerifyResourcePitchInTiles<false>(ResourceInfo, 2); // not applicable
uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned PAGE_SIZE
GMM_ULT_ALIGN(ExpectedPitch *
__GMM_MAX_CUBE_FACE * ExpectedQPitch,
PAGE_SIZE));
for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.CubeFace = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(CubeFaceIndex * ExpectedQPitch * ExpectedPitch,
OffsetInfo.Render.Offset64); // Render offset is tile's base address on which cube face begins.
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Cube Linear Mipped Resource Array
TEST_F(CTestGen9Resource, TestCubeLinearMippedResourceArray)
{
const uint32_t HAlign = 16;
const uint32_t VAlign = 4;
const uint32_t MaxLod = 9;
const uint32_t ResWidth = 0x401;
const uint32_t MaxArraySize = 0x10;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_CUBE;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.Linear = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.MaxLod = MaxLod;
gmmParams.ArraySize = MaxArraySize;
// Allocate arbitrary size (X/Y dimension not applicable as linear surface)
// Width and Height must be equal
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
{
struct //Cache the value for verifying array elements/Cube face offset/Mip Offset
{
uint64_t Offset; // Note : absolute mip offset
} RenderOffset[GMM_ULT_MAX_MIPMAP] = {};
TEST_BPP bpp = static_cast<TEST_BPP>(i);
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = ResWidth; // 1024 + 1, help ult HAlign/VAlign/Pitch alignment logic as well.
gmmParams.BaseHeight = gmmParams.BaseWidth64; // Heigth must be equal to width.
gmmParams.Depth = 0x1;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
//------------------------------|
// |
// LOD0 |
// |
// |
//------------------------------|
// LOD1 | LOD2 |
// |----------|
// | LOD3 |
//-------------| LOD4 .. so on
// Mip 0
// Mip 0 decides the pitch of the entire surface
const uint32_t AlignedWidthMip0 = GMM_ULT_ALIGN(ResWidth, HAlign); // HAlign width in pixel
const uint32_t AlignedHeightMip0 = GMM_ULT_ALIGN(ResWidth, VAlign);
uint32_t ExpectedPitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * GetBppValue(bpp); // HAligned-width in bytes.
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, GMM_BYTES(32));
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
VerifyResourcePitchInTiles<false>(ResourceInfo, 2); // Not applicable
// Mip0 should be at offset 0 and tile aligned
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 0; //Mip 0
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(0, OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
//cache Mip 0 offset
RenderOffset[0].Offset = 0;
// Mip 1 should be under mip 0
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = 1; //Mip 1
ResourceInfo->GetOffset(OffsetInfo);
EXPECT_EQ(AlignedHeightMip0 * ExpectedPitch, // Render offset is the absolute address at which the mip begins
OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // Not applicable for linear surface
EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Not applicable for linear surface
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // n/a
//cache Mip 1 offset
RenderOffset[1].Offset = AlignedHeightMip0 * ExpectedPitch; //Absolute base
const uint32_t AlignedWidthMip1 = GMM_ULT_ALIGN(ResWidth >> 1, HAlign); // Align width in pixel to HAlign
const uint32_t AlignedHeightMip1 = GMM_ULT_ALIGN(ResWidth >> 1, VAlign);
uint32_t HeightOfMip;
uint32_t HeightLinesLevel2 = 0;
// Mips 2-9 should be stacked on the right of Mip1 as shown in figure above.
for(int i = 2; i <= MaxLod; i++)
{
OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.MipLevel = i;
ResourceInfo->GetOffset(OffsetInfo);
HeightOfMip = GMM_ULT_ALIGN(ResWidth >> i, VAlign);
EXPECT_EQ((AlignedHeightMip0 + HeightLinesLevel2) * ExpectedPitch + // Render offset is tile's base address on which mip begins
(AlignedWidthMip1 * GetBppValue(bpp)),
OffsetInfo.Render.Offset64);
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // Not applicable for linear surface
EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Not applicable for linear surface
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
//cache Mip i'th offset
RenderOffset[i].Offset = (AlignedHeightMip0 + HeightLinesLevel2) * ExpectedPitch +
(AlignedWidthMip1 * GetBppValue(bpp));
HeightLinesLevel2 += HeightOfMip;
}
uint32_t Max2DHeight = GMM_ULT_MAX(AlignedHeightMip1, HeightLinesLevel2);
uint32_t ExpectedQPitch = GFX_ALIGN_NP2(AlignedHeightMip0 + Max2DHeight, VAlign);
VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be Valigned-BaseHeight rows apart
VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = __GMM_MAX_CUBE_FACE x QPitch, then aligned to tile boundary
GMM_ULT_ALIGN(ExpectedPitch *
MaxArraySize * __GMM_MAX_CUBE_FACE * ExpectedQPitch,
PAGE_SIZE));
// Verify each array element's Mip offset, Cube face offset etc.
for(uint32_t ArrayIndex = 0; ArrayIndex < __GMM_MAX_CUBE_FACE; ArrayIndex++)
{
for(uint32_t CubeFaceIndex = 0; CubeFaceIndex < __GMM_MAX_CUBE_FACE; CubeFaceIndex++)
{
GMM_REQ_OFFSET_INFO OffsetInfo = {};
OffsetInfo.ReqRender = 1;
OffsetInfo.ArrayIndex = ArrayIndex;
OffsetInfo.CubeFace = static_cast<GMM_CUBE_FACE_ENUM>(CubeFaceIndex);
ResourceInfo->GetOffset(OffsetInfo);
//Verify cube face offsets
EXPECT_EQ(((6 * ArrayIndex) + CubeFaceIndex) * ExpectedQPitch * ExpectedPitch,
OffsetInfo.Render.Offset64); // Render offset is tile's base address on which cube face begins.
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0 as linear surf
EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0 as linear surf
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
uint32_t CubeFaceBaseOffset = ((6 * ArrayIndex) + CubeFaceIndex) * (ExpectedQPitch * ExpectedPitch);
//Verify mip offsets in each cube face
for(uint32_t Lod = 0; Lod <= MaxLod; Lod++)
{
OffsetInfo.MipLevel = Lod;
ResourceInfo->GetOffset(OffsetInfo);
uint32_t MipOffset = CubeFaceBaseOffset + RenderOffset[Lod].Offset;
uint32_t OffsetX = MipOffset % ExpectedPitch;
uint32_t OffsetY = MipOffset / ExpectedPitch;
uint32_t RenderAlignOffset = OffsetY * ExpectedPitch + OffsetX;
EXPECT_EQ(RenderAlignOffset, OffsetInfo.Render.Offset64); // Render offset absolute address on which cube face begins.
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0 as linear surf
EXPECT_EQ(0, OffsetInfo.Render.YOffset); // Y Offset should be 0 as linear surf
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
}
}
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Cube TileX Resource
TEST_F(CTestGen9Resource, TestCubeTileXResource)
{
// Cube is allocated as an array of 6 2D surface representing each cube face below
//===============================
// q coordinate | face |
// 0 | + x |
// 1 | - x |
// 2 | + y |
// 3 | - y |
// 4 | + z |
// 5 | - z |
//===============================
const uint32_t HAlign = 16;