blob: 82210ce2906307f5a556bdc81b8619630e0e7ca1 [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 2D Stencil (TileW) Mipped-array Resource
TEST_F(CTestGen9Resource, Test2DStencilMippedArrayedResource)
{
const uint32_t HAlign = {8};
const uint32_t VAlign = {8};
const uint32_t TileSize[2] = {64, 64}; //TileW
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledW = 1;
gmmParams.Flags.Gpu.SeparateStencil = 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;
// Valigned Mip Heights
uint32_t Mip0Height = 0;
uint32_t Mip1Height = 0;
uint32_t Mip2Height = 0;
// Haligned Mip Widths
uint32_t Mip0Width = 0;
uint32_t Mip1Width = 0;
uint32_t Mip2Width = 0;
TEST_BPP bpp = TEST_BPP_8;
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x10;
gmmParams.BaseHeight = 0x10;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
// Mip resource Aligned Width calculation
Mip0Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
Mip0Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
for(uint32_t i = 1; i <= gmmParams.MaxLod; i++)
{
uint32_t MipWidth = GMM_ULT_ALIGN(GMM_ULT_MAX(Mip0Width >> i, 1), HAlign);
uint32_t MipHeight = GMM_ULT_ALIGN(GMM_ULT_MAX(Mip0Height >> i, 1), VAlign);
if(i == 1)
{
Mip1Width = AlignedWidth = MipWidth;
Mip1Height = MipHeight;
}
else if(i == 2)
{
AlignedWidth += MipWidth;
Mip2Height = MipHeight;
}
else
{
Mip2Height += MipHeight;
}
}
uint32_t MaxHeight = GMM_ULT_MAX(Mip1Height, Mip2Height);
AlignedHeight = Mip0Height + MaxHeight;
ExpectedPitch = GMM_ULT_MAX(AlignedWidth, Mip0Width) * GetBppValue(bpp);
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, TileSize[0]);
//TileW is programmed as row-interleaved.. ie doubled pitch
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch * 2);
VerifyResourcePitchInTiles<true>(ResourceInfo, static_cast<uint32_t>(ExpectedPitch / TileSize[0]));
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * AlignedHeight * gmmParams.ArraySize, PAGE_SIZE));
VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight);
for(uint8_t i = 0; i < gmmParams.ArraySize && gmmParams.MaxLod >= 4; i++)
{
uint64_t ArrayOffset = AlignedHeight * ExpectedPitch * i;
// Mip 0 offsets, offset is 0,0
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.MipLevel = 0;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip0Size = ExpectedPitch * Mip0Height;
uint64_t SliceTileOffset = GFX_ALIGN_FLOOR(AlignedHeight * i, TileSize[1]) * TileSize[0];
uint32_t SliceY = (AlignedHeight * i) % TileSize[1];
EXPECT_EQ(SliceTileOffset, ReqInfo.Render.Offset64);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(SliceY, ReqInfo.Render.YOffset);
// Mip 1 offsets
ReqInfo = {0};
ReqInfo.MipLevel = 1;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip1Offset = Mip0Size + ArrayOffset;
uint32_t Mip1X = uint32_t(Mip1Offset % ExpectedPitch);
uint32_t Mip1Y = uint32_t(Mip1Offset / ExpectedPitch);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip1Y % TileSize[1], ReqInfo.Render.YOffset);
Mip1X = GFX_ALIGN_FLOOR(Mip1X, TileSize[0]);
Mip1Y = GFX_ALIGN_FLOOR(Mip1Y, TileSize[1]);
uint32_t Mip1RenderAlignedOffset = Mip1Y * ExpectedPitch + (Mip1X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip1RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 2 offset
ReqInfo = {0};
ReqInfo.MipLevel = 2;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip2Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch + ArrayOffset;
uint32_t Mip2X = uint32_t(Mip2Offset % ExpectedPitch);
uint32_t Mip2Y = uint32_t(Mip2Offset / ExpectedPitch);
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip2Y % TileSize[1], ReqInfo.Render.YOffset);
Mip2X = GFX_ALIGN_FLOOR(Mip2X, TileSize[0]);
Mip2Y = GFX_ALIGN_FLOOR(Mip2Y, TileSize[1]);
uint32_t Mip2RenderAlignedOffset = Mip2Y * ExpectedPitch + (Mip2X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip2RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 3 offset
ReqInfo = {0};
ReqInfo.MipLevel = 3;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip3Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + GMM_ULT_ALIGN(Mip0Height >> 2, VAlign)) * ExpectedPitch + ArrayOffset;
uint32_t Mip3X = uint32_t(Mip3Offset % ExpectedPitch);
uint32_t Mip3Y = uint32_t(Mip3Offset / ExpectedPitch);
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip3Y % TileSize[1], ReqInfo.Render.YOffset);
Mip3X = GFX_ALIGN_FLOOR(Mip3X, TileSize[0]);
Mip3Y = GFX_ALIGN_FLOOR(Mip3Y, TileSize[1]);
uint32_t Mip3RenderAlignedOffset = Mip3Y * ExpectedPitch + (Mip3X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip3RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 4 offset
ReqInfo = {0};
ReqInfo.MipLevel = 4;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip4Offset = 0;
Mip4Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + GMM_ULT_ALIGN(Mip0Height >> 2, VAlign) + GMM_ULT_ALIGN(Mip0Height >> 3, VAlign)) * ExpectedPitch + ArrayOffset;
uint32_t Mip4X = uint32_t(Mip4Offset % ExpectedPitch);
uint32_t Mip4Y = uint32_t(Mip4Offset / ExpectedPitch);
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip4Y % TileSize[1], ReqInfo.Render.YOffset);
Mip4X = GFX_ALIGN_FLOOR(Mip4X, TileSize[0]);
Mip4Y = GFX_ALIGN_FLOOR(Mip4Y, TileSize[1]);
uint32_t Mip4RenderAlignedOffset = Mip4Y * ExpectedPitch + (Mip4X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip4RenderAlignedOffset, ReqInfo.Render.Offset64);
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 2D Stencil (TileW) Mipped-array Resource, and CpuBlt
TEST_F(CTestGen9Resource, Test2DStencilArrayedCpuBltResource)
{
const uint32_t HAlign = {8};
const uint32_t VAlign = {8};
const uint32_t TileSize[2] = {64, 64}; //TileW
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledW = 1;
gmmParams.Flags.Gpu.SeparateStencil = 1;
gmmParams.MaxLod = 0;
gmmParams.ArraySize = 6;
{
uint32_t AlignedWidth = 0;
uint32_t AlignedHeight = 0;
uint32_t ExpectedPitch = 0;
// Valigned Mip Heights
uint32_t Mip0Height = 0;
uint32_t Mip1Height = 0;
uint32_t Mip2Height = 0;
// Haligned Mip Widths
uint32_t Mip0Width = 0;
uint32_t Mip1Width = 0;
uint32_t Mip2Width = 0;
TEST_BPP bpp = TEST_BPP_8;
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x4;
gmmParams.BaseHeight = 0x4;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
// Mip resource Aligned Width calculation
Mip0Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
Mip0Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
for(uint32_t i = 1; i <= gmmParams.MaxLod; i++)
{
uint32_t MipWidth = GMM_ULT_ALIGN(GMM_ULT_MAX(Mip0Width >> i, 1), HAlign);
uint32_t MipHeight = GMM_ULT_ALIGN(GMM_ULT_MAX(Mip0Height >> i, 1), VAlign);
if(i == 1)
{
Mip1Width = AlignedWidth = MipWidth;
Mip1Height = MipHeight;
}
else if(i == 2)
{
AlignedWidth += MipWidth;
Mip2Height = MipHeight;
}
else
{
Mip2Height += MipHeight;
}
}
uint32_t MaxHeight = GMM_ULT_MAX(Mip1Height, Mip2Height);
AlignedHeight = Mip0Height + MaxHeight;
ExpectedPitch = GMM_ULT_MAX(AlignedWidth, Mip0Width) * GetBppValue(bpp);
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, TileSize[0]);
//TileW is programmed as row-interleaved.. ie doubled pitch
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch * 2);
VerifyResourcePitchInTiles<true>(ResourceInfo, static_cast<uint32_t>(ExpectedPitch / TileSize[0]));
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * AlignedHeight * gmmParams.ArraySize, PAGE_SIZE));
VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight);
for(uint8_t i = 0; i < gmmParams.ArraySize && gmmParams.MaxLod >= 4; i++)
{
uint64_t ArrayOffset = AlignedHeight * ExpectedPitch * i;
// Mip 0 offsets, offset is 0,0
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.MipLevel = 0;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip0Size = ExpectedPitch * Mip0Height;
uint64_t SliceTileOffset = GFX_ALIGN_FLOOR(AlignedHeight * i, TileSize[1]) * TileSize[0];
uint32_t SliceY = (AlignedHeight * i) % TileSize[1];
EXPECT_EQ(SliceTileOffset, ReqInfo.Render.Offset64);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(SliceY, ReqInfo.Render.YOffset);
// Mip 1 offsets
ReqInfo = {0};
ReqInfo.MipLevel = 1;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip1Offset = Mip0Size + ArrayOffset;
uint32_t Mip1X = uint32_t(Mip1Offset % ExpectedPitch);
uint32_t Mip1Y = uint32_t(Mip1Offset / ExpectedPitch);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip1Y % TileSize[1], ReqInfo.Render.YOffset);
Mip1X = GFX_ALIGN_FLOOR(Mip1X, TileSize[0]);
Mip1Y = GFX_ALIGN_FLOOR(Mip1Y, TileSize[1]);
uint32_t Mip1RenderAlignedOffset = Mip1Y * ExpectedPitch + (Mip1X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip1RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 2 offset
ReqInfo = {0};
ReqInfo.MipLevel = 2;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip2Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch + ArrayOffset;
uint32_t Mip2X = uint32_t(Mip2Offset % ExpectedPitch);
uint32_t Mip2Y = uint32_t(Mip2Offset / ExpectedPitch);
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip2Y % TileSize[1], ReqInfo.Render.YOffset);
Mip2X = GFX_ALIGN_FLOOR(Mip2X, TileSize[0]);
Mip2Y = GFX_ALIGN_FLOOR(Mip2Y, TileSize[1]);
uint32_t Mip2RenderAlignedOffset = Mip2Y * ExpectedPitch + (Mip2X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip2RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 3 offset
ReqInfo = {0};
ReqInfo.MipLevel = 3;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip3Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + GMM_ULT_ALIGN(Mip0Height >> 2, VAlign)) * ExpectedPitch + ArrayOffset;
uint32_t Mip3X = uint32_t(Mip3Offset % ExpectedPitch);
uint32_t Mip3Y = uint32_t(Mip3Offset / ExpectedPitch);
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip3Y % TileSize[1], ReqInfo.Render.YOffset);
Mip3X = GFX_ALIGN_FLOOR(Mip3X, TileSize[0]);
Mip3Y = GFX_ALIGN_FLOOR(Mip3Y, TileSize[1]);
uint32_t Mip3RenderAlignedOffset = Mip3Y * ExpectedPitch + (Mip3X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip3RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 4 offset
ReqInfo = {0};
ReqInfo.MipLevel = 4;
ReqInfo.ReqRender = 1;
ReqInfo.ArrayIndex = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip4Offset = 0;
Mip4Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height + GMM_ULT_ALIGN(Mip0Height >> 2, VAlign) + GMM_ULT_ALIGN(Mip0Height >> 3, VAlign)) * ExpectedPitch + ArrayOffset;
uint32_t Mip4X = uint32_t(Mip4Offset % ExpectedPitch);
uint32_t Mip4Y = uint32_t(Mip4Offset / ExpectedPitch);
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(Mip4Y % TileSize[1], ReqInfo.Render.YOffset);
Mip4X = GFX_ALIGN_FLOOR(Mip4X, TileSize[0]);
Mip4Y = GFX_ALIGN_FLOOR(Mip4Y, TileSize[1]);
uint32_t Mip4RenderAlignedOffset = Mip4Y * ExpectedPitch + (Mip4X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip4RenderAlignedOffset, ReqInfo.Render.Offset64);
}
//Verify CpuBlt path (uses Render offset for upload)
{
#ifdef _WIN32
#define ULT_ALIGNED_MALLOC(Size, alignBytes) _aligned_malloc(Size, alignBytes)
#define ULT_ALIGNED_FREE(ptr) _aligned_free(ptr)
#else
#define ULT_ALIGNED_MALLOC(Size, alignBytes) memalign(alignBytes, Size)
#define ULT_ALIGNED_FREE(ptr) free(ptr)
#endif
#ifdef _WIN32
void *LockVA = ULT_ALIGNED_MALLOC(ResourceInfo->GetSizeSurface(), ResourceInfo->GetBaseAlignment());
memset(LockVA, 0, ResourceInfo->GetSizeSurface());
void *Sysmem = malloc(gmmParams.BaseWidth64 * gmmParams.BaseHeight);
memset(Sysmem, 0xbb, gmmParams.BaseWidth64 * gmmParams.BaseHeight);
//Test Upload
GMM_RES_COPY_BLT Blt = {0};
Blt.Gpu.pData = LockVA;
Blt.Gpu.Slice = 4;
Blt.Gpu.MipLevel = 0;
Blt.Sys.BufferSize = gmmParams.BaseWidth64 * gmmParams.BaseHeight;
Blt.Sys.pData = Sysmem;
Blt.Sys.RowPitch = gmmParams.BaseWidth64;
Blt.Sys.PixelPitch = 1;
Blt.Sys.SlicePitch = Blt.Sys.BufferSize;
Blt.Blt.Upload = 1;
Blt.Blt.BytesPerPixel = 1;
ResourceInfo->CpuBlt(&Blt);
uint64_t Offset = 0x100; /*Blt.Gpu.Slice * ResourceInfo->GetQPitchInBytes();*/ // Need SwizzledOffset
for(uint8_t byte = 0; byte < Blt.Sys.BufferSize; byte++)
{
uint8_t *Byte = ((uint8_t *)LockVA) + Offset + byte;
EXPECT_EQ(Byte[0], 0xbb);
}
free(Sysmem);
ULT_ALIGNED_FREE(LockVA);
#endif
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for 3D Stencil (TileW) Mipped-array Resource
TEST_F(CTestGen9Resource, Test3DStencilMippedResource)
{
const uint32_t HAlign = {8};
const uint32_t VAlign = {8};
const uint32_t TileSize[2] = {64, 64}; //TileW
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_3D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Info.TiledW = 1;
gmmParams.Flags.Gpu.SeparateStencil = 1;
gmmParams.MaxLod = 4;
{
uint32_t AlignedWidth = 0;
uint32_t AlignedHeight = 0;
uint32_t ExpectedPitch = 0;
// Valigned Mip Heights
uint32_t Mip0Height = 0;
uint32_t Mip1Height = 0;
uint32_t Mip2Height = 0;
// Haligned Mip Widths
uint32_t Mip0Width = 0;
uint32_t Mip1Width = 0;
uint32_t Mip2Width = 0;
TEST_BPP bpp = TEST_BPP_8;
gmmParams.Format = SetResourceFormat(bpp);
gmmParams.BaseWidth64 = 0x10;
gmmParams.BaseHeight = 0x10;
gmmParams.Depth = 0x10;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
// Mip resource Aligned Width calculation
Mip0Width = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
Mip0Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
for(uint32_t i = 1; i <= gmmParams.MaxLod; i++)
{
uint32_t MipWidth = GMM_ULT_ALIGN(Mip0Width >> i, HAlign);
uint32_t MipHeight = GMM_ULT_ALIGN(Mip0Height >> i, VAlign);
if(i == 1)
{
Mip1Width = AlignedWidth = MipWidth;
Mip1Height = MipHeight;
}
else if(i == 2)
{
AlignedWidth += MipWidth;
Mip2Height = MipHeight;
}
else
{
Mip2Height += MipHeight;
}
}
uint32_t MaxHeight = GMM_ULT_MAX(Mip1Height, Mip2Height);
AlignedHeight = Mip0Height + MaxHeight;
ExpectedPitch = AlignedWidth * GetBppValue(bpp);
ExpectedPitch = GMM_ULT_ALIGN(ExpectedPitch, TileSize[0]);
//TileW is programmed as row-interleaved.. ie doubled pitch
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch * 2);
VerifyResourcePitchInTiles<true>(ResourceInfo, static_cast<uint32_t>(ExpectedPitch / TileSize[0]));
VerifyResourceSize<true>(ResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * AlignedHeight, PAGE_SIZE) * gmmParams.Depth);
//3D QPitch must be aligned to Tile-height, div by 2 for Pitch is doubled
// i.e. Slice-offset = Qpitch*Pitch is tile-aligned.
AlignedHeight = GMM_ULT_ALIGN(AlignedHeight, TileSize[1]);
VerifyResourceQPitch<true>(ResourceInfo, AlignedHeight / 2);
for(uint8_t i = 0; i < gmmParams.Depth; i++)
{
uint64_t SliceOffset = AlignedHeight * ExpectedPitch;
// Mip 0 offsets, offset is 0,0
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.MipLevel = 0;
ReqInfo.ReqRender = 1;
ReqInfo.Slice = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip0Size = ExpectedPitch * Mip0Height;
EXPECT_EQ((0 + SliceOffset * i), ReqInfo.Render.Offset64);
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(0, ReqInfo.Render.YOffset);
// Mip 1 offsets -- uses 2d mip layout
ReqInfo = {0};
ReqInfo.MipLevel = 1;
ReqInfo.ReqRender = 1;
ReqInfo.Slice = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip1Offset = Mip0Size;
uint32_t Mip1X = GFX_ALIGN_FLOOR(uint32_t(Mip1Offset % ExpectedPitch), TileSize[0]);
uint32_t Mip1Y = GFX_ALIGN_FLOOR(uint32_t(Mip1Offset / ExpectedPitch), TileSize[1]);
uint32_t Mip1RenderAlignedOffset = Mip1Y * ExpectedPitch + (Mip1X / TileSize[0]) * (TileSize[0] * TileSize[1]) + SliceOffset * i;
EXPECT_EQ(0, ReqInfo.Render.XOffset);
EXPECT_EQ(16, ReqInfo.Render.YOffset);
EXPECT_EQ(Mip1RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 2 offset
ReqInfo = {0};
ReqInfo.MipLevel = 2;
ReqInfo.ReqRender = 1;
ReqInfo.Slice = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip2Offset = Mip1Width * GetBppValue(bpp) + (Mip0Height * ExpectedPitch) + SliceOffset * i;
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(16, ReqInfo.Render.YOffset);
uint32_t Mip2X = GFX_ALIGN_FLOOR(uint32_t(Mip2Offset % ExpectedPitch), TileSize[0]);
uint32_t Mip2Y = GFX_ALIGN_FLOOR(uint32_t(Mip2Offset / ExpectedPitch), TileSize[1]);
uint32_t Mip2RenderAlignedOffset = Mip2Y * ExpectedPitch + (Mip2X / TileSize[0]) * (TileSize[0] * TileSize[1]);
EXPECT_EQ(Mip2RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 3 offset
ReqInfo = {0};
ReqInfo.MipLevel = 3;
ReqInfo.ReqRender = 1;
ReqInfo.Slice = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip3Offset = 0;
Mip3Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(24, ReqInfo.Render.YOffset);
uint32_t Mip3X = GFX_ALIGN_FLOOR(uint32_t(Mip3Offset % ExpectedPitch), TileSize[0]);
uint32_t Mip3Y = GFX_ALIGN_FLOOR(uint32_t(Mip3Offset / ExpectedPitch), TileSize[1]);
uint32_t Mip3RenderAlignedOffset = Mip3Y * ExpectedPitch + (Mip3X / TileSize[0]) * (TileSize[0] * TileSize[1]) + SliceOffset * i;
EXPECT_EQ(Mip3RenderAlignedOffset, ReqInfo.Render.Offset64);
// Mip 4 offset
ReqInfo = {0};
ReqInfo.MipLevel = 4;
ReqInfo.ReqRender = 1;
ReqInfo.Slice = i;
ResourceInfo->GetOffset(ReqInfo);
uint32_t Mip4Offset = 0;
Mip4Offset = Mip1Width * GetBppValue(bpp) + Mip0Height * ExpectedPitch;
EXPECT_EQ(8, ReqInfo.Render.XOffset);
EXPECT_EQ(32, ReqInfo.Render.YOffset);
uint32_t Mip4X = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset % ExpectedPitch), TileSize[0]);
uint32_t Mip4Y = GFX_ALIGN_FLOOR(uint32_t(Mip4Offset / ExpectedPitch), TileSize[1]);
uint32_t Mip4RenderAlignedOffset = Mip4Y * ExpectedPitch + (Mip4X / TileSize[0]) * (TileSize[0] * TileSize[1]) + SliceOffset * i;
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</