mirror of https://github.com/intel/gmmlib.git
3392 lines
149 KiB
C++
3392 lines
149 KiB
C++
/*==============================================================================
|
|
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 "GmmResourceULT.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// CTestResource Constructor
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
CTestResource::CTestResource()
|
|
{
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// CTestResource Destructor
|
|
///
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
CTestResource::~CTestResource()
|
|
{
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// 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.
|
|
///
|
|
/// @see CTestResource::SetUpTestCase()
|
|
///
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
void CTestResource::SetUpTestCase()
|
|
{
|
|
printf("%s\n", __FUNCTION__);
|
|
|
|
GfxPlatform.eProductFamily = IGFX_BROADWELL;
|
|
GfxPlatform.eRenderCoreFamily = IGFX_GEN8_CORE;
|
|
|
|
CommonULT::SetUpTestCase();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Cleans up once all the tests finish execution. It also calls TearDownTestCase
|
|
/// from CommonULT to destroy global context and others.
|
|
///
|
|
/// @see CTestResource::TearDownTestCase()
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
void CTestResource::TearDownTestCase()
|
|
{
|
|
printf("%s\n", __FUNCTION__);
|
|
|
|
CommonULT::TearDownTestCase();
|
|
}
|
|
|
|
/// @brief ULT for 1D Linear Resource
|
|
TEST_F(CTestResource, Test1DLinearResource)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 64;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_1D;
|
|
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;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
|
|
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);
|
|
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<false>(ResourceInfo, 0); // Not valid for 1D
|
|
|
|
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 AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
|
|
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
|
|
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<false>(ResourceInfo, 0);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for 1D Linear Resource Arrays
|
|
TEST_F(CTestResource, Test1DLinearResourceArrays)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 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 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 = 0x100;
|
|
gmmParams.BaseHeight = 0x1;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
|
|
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);
|
|
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight * gmmParams.ArraySize, 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 1D Mipped Linear Resource
|
|
TEST_F(CTestResource, Test1DLinearResourceMips)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 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);
|
|
uint32_t AlignedHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
// Height of 1D surface will just be VAlign. So height of the whole block will be
|
|
// Height of Mip0 + Mip2 + Mip3 + Mip4 + Mip5...
|
|
AlignedHeight = gmmParams.MaxLod * AlignedHeight;
|
|
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
|
|
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
|
|
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<false>(ResourceInfo, 0); // N/A for non-arrayed surface
|
|
|
|
// 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);
|
|
|
|
// Mip1 should be after Mip0. X/Y/Z Offset should be 0 for linear.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 1; //Mip 1
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
uint32_t SizeOfMip0 = PitchInBytes * GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip2 should to the right of Mip1. X/Y/Z Offset should be 0 for linear.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 2; //Mip 2
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
uint32_t StartOfMip = SizeOfMip0 + (GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 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);
|
|
|
|
// Rest of the mips should be below mip2, each with height of HAlign. X/Y/Z Offset should be 0 for linear.
|
|
for(int mip = 3; mip <= gmmParams.MaxLod; mip++)
|
|
{
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = mip;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
StartOfMip += PitchInBytes * VAlign;
|
|
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 2D Linear Resource Arrays
|
|
TEST_F(CTestResource, Test2DLinearResourceArrays)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 64;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.Linear = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.ArraySize = 4;
|
|
|
|
// Allocate 256x256 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 = 0x100;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
|
|
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);
|
|
uint32_t AlignedSize = GMM_ULT_ALIGN(PitchInBytes * AlignedHeight * gmmParams.ArraySize, 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 2D Mipped Linear Resource
|
|
TEST_F(CTestResource, Test2DLinearResourceMips)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 64;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.Linear = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.MaxLod = 8;
|
|
|
|
// Allocate 256x256 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 = 0x100;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
|
|
uint32_t AlignedHeight;
|
|
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
|
|
PitchInBytes = GFX_MAX(PitchInBytes, MinPitch);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
|
|
uint32_t HeightOfPrevMip = AlignedHeight = gmmParams.BaseHeight;
|
|
|
|
// 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);
|
|
|
|
// Mip1 should be after Mip0. X/Y/Z Offset should be 0 for linear.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 1; //Mip 1
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
uint32_t SizeOfMip0 = PitchInBytes * GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip2 should to the right of Mip1. X/Y/Z Offset should be 0 for linear.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 2; //Mip 2
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
uint32_t StartOfMip = SizeOfMip0 + (GMM_ULT_ALIGN(gmmParams.BaseWidth64 >> 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);
|
|
|
|
// Rest of the mips should be below mip2, each with height of HAlign. X/Y/Z Offset should be 0 for linear.
|
|
for(int mip = 3; mip <= 8; mip++)
|
|
{
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = mip;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
HeightOfPrevMip = GMM_ULT_ALIGN((gmmParams.BaseHeight >> (mip - 1)), VAlign);
|
|
AlignedHeight += HeightOfPrevMip;
|
|
StartOfMip += PitchInBytes * HeightOfPrevMip;
|
|
EXPECT_EQ(StartOfMip, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
}
|
|
|
|
//Mip8 will go till Mip0Height + Mip1Height + VALIGN
|
|
AlignedHeight += VAlign;
|
|
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<false>(ResourceInfo, 0); // N/A for non-arrayed surface
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Arrayed 2D TileX Resource
|
|
TEST_F(CTestResource, Test2DTileXResourceArrays)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileWidth = 512;
|
|
const uint32_t TileHeight = 8;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledX = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.ArraySize = 4;
|
|
|
|
// 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 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = TileHeight + 1; // 1 row larger than 1 tile height
|
|
|
|
const uint32_t AlignedWidth = GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign);
|
|
uint32_t PitchInBytes = AlignedWidth * GetBppValue(bpp);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
|
|
|
|
uint32_t AlignedHeight, BlockHeight;
|
|
BlockHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
AlignedHeight = GMM_ULT_ALIGN_NP2(BlockHeight * gmmParams.ArraySize, TileHeight);
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes); // As wide as 2 tile
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth); // 2 tile wide
|
|
VerifyResourceSize<true>(ResourceInfo, PitchInBytes * AlignedHeight); // 4 tile big x 4 array size
|
|
|
|
VerifyResourceQPitch<true>(ResourceInfo, BlockHeight);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Mipped 2D TileX Resource
|
|
TEST_F(CTestResource, Test2DTileXResourceMips)
|
|
{
|
|
const uint32_t TileSize[2] = {512, 8};
|
|
enum Coords
|
|
{
|
|
X = 0,
|
|
Y = 1
|
|
};
|
|
|
|
// Test normal mip case
|
|
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
|
|
{
|
|
const uint32_t ResourceWidth = 0x400;
|
|
const uint32_t ResourceHeight = 0x400;
|
|
const uint32_t MaxLod = 10;
|
|
|
|
|
|
TEST_BPP bpp = static_cast<TEST_BPP>(i);
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.Flags.Info.TiledX = 1;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = ResourceWidth;
|
|
gmmParams.BaseHeight = ResourceHeight;
|
|
gmmParams.MaxLod = MaxLod;
|
|
gmmParams.Format = SetResourceFormat(bpp);
|
|
|
|
// Create resource
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
// Mip0 is the widest mip. So it will dictate the pitch of the whole surface
|
|
const uint32_t Pitch = ResourceWidth * GetBppValue(bpp);
|
|
uint32_t AllocationHeight = 0;
|
|
|
|
// 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);
|
|
|
|
// Mip1 should be after whole Mip0. Should still be tile aligned.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 1; // Mip 1
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
uint32_t SizeOfMip0 = Pitch * ResourceHeight;
|
|
uint32_t HeightOfPrevMip = AllocationHeight = ResourceHeight;
|
|
EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip2 should be on the right of Mip1. Should still be tile aligned.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 2; // Mip 2
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
// MipOffset = Mip1Offset + Mip1Width in tiles
|
|
uint32_t MipOffset = SizeOfMip0 + ((Pitch >> 1) / TileSize[X]) * PAGE_SIZE;
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mips 3-8 should be on tile boundary
|
|
for(int i = 3; i < 9; i++)
|
|
{
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = i;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
HeightOfPrevMip = (ResourceHeight >> (i - 1));
|
|
AllocationHeight += HeightOfPrevMip;
|
|
MipOffset += Pitch * HeightOfPrevMip;
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
|
|
// No X/Y/Z offset since mip is at tile boundary
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
}
|
|
|
|
// Mips 9 will share 1 tile with Mip 8
|
|
AllocationHeight += TileSize[Y];
|
|
uint32_t HeightOfPrevMipsInTile = 0;
|
|
{
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 9;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64); // Same as previous tile aligned mip offset
|
|
|
|
// X is 0, but Y offset will change
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
HeightOfPrevMipsInTile += (ResourceHeight >> (9 - 1));
|
|
EXPECT_EQ(HeightOfPrevMipsInTile, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
}
|
|
|
|
// Mip 10 is back on tile boundary
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 10; // Mip 10
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
MipOffset += Pitch * TileSize[Y];
|
|
AllocationHeight += TileSize[Y];
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Verify ResourceSize and Pitch
|
|
VerifyResourceSize<true>(ResourceInfo, AllocationHeight * Pitch);
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
|
|
// These are verified elsewhere
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
|
|
// Test where Mip1 + Mip2 width > Mip0 width, and where everything fits in 1 tile
|
|
for(uint32_t i = 0; i < TEST_BPP_64; i++)
|
|
{
|
|
const uint32_t ResourceWidth = 0x4;
|
|
const uint32_t ResourceHeight = 0x2;
|
|
const uint32_t MaxLod = 0x2;
|
|
|
|
TEST_BPP bpp = static_cast<TEST_BPP>(i);
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.Flags.Info.TiledX = 1;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = ResourceWidth;
|
|
gmmParams.BaseHeight = ResourceHeight;
|
|
gmmParams.MaxLod = MaxLod;
|
|
gmmParams.Format = SetResourceFormat(bpp);
|
|
|
|
// Create resource
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
// Get Alignment that GmmLib is using
|
|
const uint32_t HAlign = ResourceInfo->GetHAlign();
|
|
const uint32_t VAlign = ResourceInfo->GetVAlign();
|
|
|
|
// Mip1 + Mip2 is the widest width. So it will dictate the pitch of the whole surface
|
|
uint32_t Pitch = GetBppValue(bpp) *
|
|
(GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) + GMM_ULT_ALIGN(ResourceWidth >> 2, HAlign));
|
|
Pitch = GMM_ULT_ALIGN(Pitch, TileSize[X]);
|
|
|
|
// 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);
|
|
|
|
// Mip1 should be after whole Mip0. Not tile aligned
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 1; // Mip 1
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same tile as Mip0
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip2 should be on the right of Mip1. Not tile aligned
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 2; // Mip 2
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same Tile as Mip0
|
|
uint32_t Mip1Width = GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) * GetBppValue(bpp);
|
|
EXPECT_EQ(Mip1Width, OffsetInfo.Render.XOffset); // On right of Mip1
|
|
EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Verify ResourceSize and Pitch
|
|
VerifyResourceSize<true>(ResourceInfo, PAGE_SIZE); // everything should fit in 1 tile
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
|
|
// These are verified elsewhere
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for 2D Linear Resource
|
|
TEST_F(CTestResource, Test2DLinearResource)
|
|
{
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
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 = 0x1;
|
|
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 64;
|
|
|
|
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);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate 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;
|
|
|
|
const uint32_t MinPitch = 32;
|
|
const uint32_t PitchAlignment = 64;
|
|
|
|
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);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for 2D TileX Resource
|
|
TEST_F(CTestResource, Test2DTileXResource)
|
|
{
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileWidth = 512;
|
|
const uint32_t TileHeight = 8;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledX = 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);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, TileWidth); // 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 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = 0x1;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, TileWidth * 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 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = TileHeight + 1; // 1 row larger than 1 tile height
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, TileWidth * 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 TileY Resource
|
|
TEST_F(CTestResource, Test2DTileYResource)
|
|
{
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileWidth = 128;
|
|
const uint32_t TileHeight = 32;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledY = 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;
|
|
|
|
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 = GMM_ULT_MAX(PitchInBytes, MinPitch);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
|
|
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileWidth * GMM_KBYTE(4));
|
|
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 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = 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 = GMM_ULT_MAX(PitchInBytes, MinPitch);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
|
|
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileWidth * GMM_KBYTE(4));
|
|
|
|
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 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = TileHeight + 1; // 1 row larger than 1 tile height
|
|
|
|
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 = GMM_ULT_MAX(PitchInBytes, MinPitch);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, PitchAlignment);
|
|
PitchInBytes = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
|
|
VerifyResourceSize<true>(ResourceInfo, PitchInBytes / TileWidth * 2 * GMM_KBYTE(4));
|
|
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // Not tested
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Arrayed 2D TileY Resource
|
|
TEST_F(CTestResource, Test2DTileYResourceArrays)
|
|
{
|
|
// Horizontal/Vertical pixel alignment
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileWidth = 128;
|
|
const uint32_t TileHeight = 32;
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledY = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.ArraySize = 4;
|
|
|
|
// 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 = (TileWidth / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = TileHeight + 1; // 1 row larger than 1 tile height
|
|
uint32_t AlignedHeight, BlockHeight;
|
|
|
|
BlockHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
AlignedHeight = GMM_ULT_ALIGN_NP2(BlockHeight * gmmParams.ArraySize, TileHeight);
|
|
|
|
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 = GMM_ULT_ALIGN(PitchInBytes, TileWidth);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileWidth);
|
|
VerifyResourceSize<true>(ResourceInfo, PitchInBytes * AlignedHeight); // 4 tile big x 4 array size
|
|
VerifyResourceQPitch<true>(ResourceInfo, BlockHeight);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Mipped 2D TileY Resource
|
|
TEST_F(CTestResource, Test2DTileYResourceMips)
|
|
{
|
|
const uint32_t TileSize[2] = {128, 32};
|
|
enum Coords
|
|
{
|
|
X = 0,
|
|
Y = 1
|
|
};
|
|
|
|
// Test normal mip case
|
|
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
|
|
{
|
|
const uint32_t ResourceWidth = 0x200;
|
|
const uint32_t ResourceHeight = 0x200;
|
|
const uint32_t MaxLod = 0x9;
|
|
|
|
|
|
TEST_BPP bpp = static_cast<TEST_BPP>(i);
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.Flags.Info.TiledY = 1;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = ResourceWidth;
|
|
gmmParams.BaseHeight = ResourceHeight;
|
|
gmmParams.MaxLod = MaxLod;
|
|
gmmParams.Format = SetResourceFormat(bpp);
|
|
|
|
// Create resource
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
// Mip0 is the widest mip. So it will dictate the pitch of the whole surface
|
|
const uint32_t Pitch = ResourceWidth * GetBppValue(bpp);
|
|
uint32_t AllocationHeight = 0;
|
|
|
|
// 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);
|
|
|
|
// Mip1 should be after whole Mip0. Should still be tile aligned.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 1; // Mip 1
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
uint32_t SizeOfMip0 = Pitch * ResourceHeight;
|
|
uint32_t HeightOfPrevMip = AllocationHeight = ResourceHeight;
|
|
EXPECT_EQ(SizeOfMip0, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip2 should be on the right of Mip1. Should still be tile aligned.
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 2; // Mip 2
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
// MipOffset = Mip1Offset + Mip1Width in tiles
|
|
uint32_t MipOffset = SizeOfMip0 + ((Pitch >> 1) / TileSize[X]) * PAGE_SIZE;
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mips 3-5 should be on tile boundary
|
|
for(int i = 3; i < 6; i++)
|
|
{
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = i;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
HeightOfPrevMip = (ResourceHeight >> (i - 1));
|
|
AllocationHeight += HeightOfPrevMip;
|
|
MipOffset += Pitch * HeightOfPrevMip;
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
|
|
// No X/Y/Z offset since mip is at tile boundary
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
}
|
|
|
|
// Mips 6-8 will share 1 tile
|
|
AllocationHeight += TileSize[Y];
|
|
uint32_t HeightOfPrevMipsInTile = 0;
|
|
for(int i = 6; i < 9; i++)
|
|
{
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = i;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64); // Same as previous tile aligned mip offset
|
|
|
|
// X is 0, but Y offset will change
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
HeightOfPrevMipsInTile += (ResourceHeight >> (i - 1));
|
|
EXPECT_EQ(HeightOfPrevMipsInTile, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
}
|
|
|
|
// Mip 9 is back on tile boundary
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 9; // Mip 9
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
MipOffset += Pitch * TileSize[Y];
|
|
AllocationHeight += TileSize[Y];
|
|
EXPECT_EQ(MipOffset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Verify ResourceSize and Pitch
|
|
VerifyResourceSize<true>(ResourceInfo, AllocationHeight * Pitch);
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
|
|
// These are verified elsewhere
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
|
|
// Test where Mip1 + Mip2 width > Mip0 width, and where everything fits in 1 tile
|
|
for(uint32_t i = 0; i < TEST_BPP_64; i++)
|
|
{
|
|
const uint32_t ResourceWidth = 0x4;
|
|
const uint32_t ResourceHeight = 0x2;
|
|
const uint32_t MaxLod = 0x2;
|
|
|
|
TEST_BPP bpp = static_cast<TEST_BPP>(i);
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.Flags.Info.TiledY = 1;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = ResourceWidth;
|
|
gmmParams.BaseHeight = ResourceHeight;
|
|
gmmParams.MaxLod = MaxLod;
|
|
gmmParams.Format = SetResourceFormat(bpp);
|
|
|
|
// Create resource
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
// Get Alignment that GmmLib is using
|
|
const uint32_t HAlign = ResourceInfo->GetHAlign();
|
|
const uint32_t VAlign = ResourceInfo->GetVAlign();
|
|
|
|
// Mip1 + Mip2 is the widest width. So it will dictate the pitch of the whole surface
|
|
uint32_t Pitch = GetBppValue(bpp) *
|
|
(GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) + GMM_ULT_ALIGN(ResourceWidth >> 2, HAlign));
|
|
Pitch = GMM_ULT_ALIGN(Pitch, TileSize[X]);
|
|
|
|
// 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);
|
|
|
|
// Mip1 should be after whole Mip0. Not tile aligned
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 1; // Mip 1
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same tile as Mip0
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip2 should be on the right of Mip1. Not tile aligned
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 2; // Mip 2
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
EXPECT_EQ(0, OffsetInfo.Render.Offset64); // Same Tile as Mip0
|
|
uint32_t Mip1Width = GMM_ULT_ALIGN(ResourceWidth >> 1, HAlign) * GetBppValue(bpp);
|
|
EXPECT_EQ(Mip1Width, OffsetInfo.Render.XOffset); // On right of Mip1
|
|
EXPECT_EQ(GMM_ULT_ALIGN(ResourceHeight, VAlign), OffsetInfo.Render.YOffset); // After Mip0
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Verify ResourceSize and Pitch
|
|
VerifyResourceSize<true>(ResourceInfo, PAGE_SIZE); // everything should fit in 1 tile
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[X]);
|
|
// These are verified elsewhere
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0);
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
// ********************************************************************************//
|
|
|
|
/// @brief ULT for 3D Linear Resource
|
|
TEST_F(CTestResource, 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 = GFX_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);
|
|
|
|
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);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for 3D TileX Resource
|
|
TEST_F(CTestResource, Test3DTileXResource)
|
|
{
|
|
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));
|
|
|
|
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));
|
|
|
|
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));
|
|
|
|
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]);
|
|
const uint32_t AlignedHeight = 24; // See details in GetTotal3DHeight();
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
|
|
VerifyResourceSize<true>(ResourceInfo, AlignedHeight / TileSize[i][1] * PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for 3D TileY Resource
|
|
TEST_F(CTestResource, 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));
|
|
|
|
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));
|
|
|
|
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));
|
|
|
|
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]);
|
|
const uint32_t AlignedHeight = 96; // See details in GetTotal3DHeight();
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
VerifyResourcePitch<true>(ResourceInfo, PitchInBytes);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, PitchInBytes / TileSize[i][0]);
|
|
VerifyResourceSize<true>(ResourceInfo, AlignedHeight / TileSize[i][1] * PitchInBytes / TileSize[i][0] * GMM_KBYTE(4));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Cube Linear Resource
|
|
TEST_F(CTestResource, Test3DTileYMippedResource)
|
|
{
|
|
// 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}};
|
|
|
|
const uint32_t ResourceWidth = 0x100;
|
|
const uint32_t ResourceHeight = 0x100;
|
|
const uint32_t ResourceDepth = 0x100;
|
|
const uint32_t MaxLod = 0x9;
|
|
|
|
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
|
|
{
|
|
TEST_BPP bpp = static_cast<TEST_BPP>(i);
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_3D;
|
|
gmmParams.Flags.Info.TiledY = 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;
|
|
const uint32_t Mip0Depth = ResourceDepth;
|
|
|
|
// 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 * Mip0Height * Mip0Depth;
|
|
const uint32_t Mip1Offset = SizeOfMip0;
|
|
const uint32_t Mip1Height = Mip0Height >> 1;
|
|
const uint32_t Mip1Depth = Mip0Depth >> 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 SizeOfMip1 = (Pitch >> 1) * Mip1Height * Mip1Depth;
|
|
const uint32_t Mip2Offset = Mip1Offset + SizeOfMip1;
|
|
const uint32_t Mip2Height = Mip1Height >> 1;
|
|
const uint32_t Mip2Depth = Mip1Depth >> 1;
|
|
|
|
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 SizeOfMip2 = (Pitch >> 2) * Mip2Height * Mip2Depth;
|
|
const uint32_t Mip3Offset = Mip2Offset + SizeOfMip2;
|
|
const uint32_t Mip3Height = Mip2Height >> 1;
|
|
const uint32_t Mip3Depth = Mip2Depth >> 1;
|
|
|
|
EXPECT_EQ(Mip3Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip4 (Packed Mip)
|
|
// For those mip width/height smaller than H/VAlign, they are upscaled to align with H/VAlign
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 4;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
const uint32_t SizeOfMip3 = (Pitch >> 3) * Mip3Height * Mip3Depth;
|
|
const uint32_t Mip4Offset = Mip3Offset + SizeOfMip3;
|
|
|
|
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip 5
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 5;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(16, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip 6
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 6;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(24, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip 7
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 7;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
EXPECT_EQ(Mip4Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(28, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip8 (Start of another packed Mip)
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 8;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
const uint32_t Mip8Offset = Mip4Offset + Pitch * TileSize[i][1];
|
|
|
|
EXPECT_EQ(Mip8Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
// Mip9
|
|
OffsetInfo = {};
|
|
OffsetInfo.ReqRender = 1;
|
|
OffsetInfo.MipLevel = 9;
|
|
ResourceInfo->GetOffset(OffsetInfo);
|
|
|
|
EXPECT_EQ(Mip8Offset, OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(4, OffsetInfo.Render.YOffset);
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
// ********************************************************************************//
|
|
|
|
/// @brief ULT for Cube Linear Resource
|
|
TEST_F(CTestResource, 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
|
|
TEST_F(CTestResource, TestCubeLinearMippedResourceArray)
|
|
{
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
const uint32_t MaxLod = 9;
|
|
const uint32_t ResWidth = 0x201;
|
|
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 ExpectedQPitch = AlignedHeightMip0 + AlignedHeightMip1 + 12 * 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(CTestResource, 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;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileSize[1][2] = {512, 8};
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_CUBE;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledX = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
|
|
// Allocate 1x1 surface so that it occupies 1 Tile 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 = 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 = TileSize[0][0];
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch); // As wide as 1 tile
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tile wide
|
|
|
|
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 to tile boundary
|
|
ExpectedPitch *
|
|
GMM_ULT_ALIGN(__GMM_MAX_CUBE_FACE * ExpectedQPitch,
|
|
TileSize[0][1]));
|
|
|
|
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(GMM_ULT_ALIGN_FLOOR(CubeFaceIndex * ExpectedQPitch, TileSize[0][1]) * 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((CubeFaceIndex * ExpectedQPitch) % TileSize[0][1],
|
|
OffsetInfo.Render.YOffset); // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate 2 tiles in X dimension.
|
|
// 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 = (TileSize[0][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
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 = TileSize[0][0] * 2; // As wide as 2 tile
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
|
|
|
|
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 to tile boundary
|
|
ExpectedPitch *
|
|
GMM_ULT_ALIGN(__GMM_MAX_CUBE_FACE * ExpectedQPitch,
|
|
TileSize[0][1]));
|
|
|
|
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(GMM_ULT_ALIGN_FLOOR(CubeFaceIndex * ExpectedQPitch, TileSize[0][1]) * 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((CubeFaceIndex * ExpectedQPitch) % TileSize[0][1],
|
|
OffsetInfo.Render.YOffset); // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
|
|
/// @brief ULT for Cube TileY Resource
|
|
TEST_F(CTestResource, TestCubeTileYResource)
|
|
{
|
|
// 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;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileSize[1][2] = {128, 32};
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_CUBE;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledY = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
|
|
// Allocate 1x1 surface within a tile.
|
|
for(uint32_t i = 0; i < TEST_BPP_128; i++) //TEST_BPP_128 cannot fit in a tile as HAlign = 16
|
|
{
|
|
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[0][0]); // As wide as 1 tile
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tile wide
|
|
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4)); // All 6 faces should be accomated in a tile.
|
|
VerifyResourceQPitch<true>(ResourceInfo, VAlign); // Each face should be VAlign rows apart within a tile
|
|
|
|
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(0, OffsetInfo.Render.Offset64); // Render offset should be 0 as its on single tile.
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // X Offset should be 0
|
|
EXPECT_EQ(CubeFaceIndex * VAlign, OffsetInfo.Render.YOffset); // Y Offset should be VALIGN * CubeFace Index
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate 2 tiles in X dimension.
|
|
// Width and Height of Cube 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 = (TileSize[0][0] / GetBppValue(bpp)) + 1; // 1 pixel larger than 1 tile width
|
|
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 = TileSize[0][0] * 2; // As wide as 2 tile
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
|
|
|
|
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 to tile boundary
|
|
ExpectedPitch *
|
|
GMM_ULT_ALIGN(__GMM_MAX_CUBE_FACE * ExpectedQPitch,
|
|
TileSize[0][1]));
|
|
|
|
|
|
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(GMM_ULT_ALIGN_FLOOR(CubeFaceIndex * ExpectedQPitch, TileSize[0][1]) * 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((CubeFaceIndex * ExpectedQPitch) % TileSize[0][1],
|
|
OffsetInfo.Render.YOffset); // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Cube TileY Mipped Resource Array
|
|
TEST_F(CTestResource, TestCubeTileYMippedResourceArray)
|
|
{
|
|
const uint32_t HAlign = 16;
|
|
const uint32_t VAlign = 4;
|
|
|
|
const uint32_t TileSize[2] = {128, 32};
|
|
enum Coords
|
|
{
|
|
X = 0,
|
|
Y = 1
|
|
};
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_CUBE;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledY = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
|
|
// Allocate CUBE surface
|
|
for(uint32_t i = 0; i < TEST_BPP_MAX; i++)
|
|
{
|
|
const uint32_t ResWidth = 0x201;
|
|
const uint32_t MaxLod = 0x9;
|
|
const uint32_t MaxArraySize = 0x10;
|
|
|
|
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; // 1 pixel larger than 1 tile width
|
|
gmmParams.BaseHeight = gmmParams.BaseWidth64; // Heigth must be equal to width.
|
|
gmmParams.Depth = 0x1;
|
|
gmmParams.MaxLod = MaxLod;
|
|
gmmParams.ArraySize = MaxArraySize;
|
|
|
|
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 resource.
|
|
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(AlignedWidthMip0 * GetBppValue(bpp), TileSize[X]); // Align AlignedWidthMip0 to 128 bytes
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, ExpectedPitch / TileSize[X]); // Pitch/TileY-Width
|
|
|
|
// 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(GMM_ULT_ALIGN_FLOOR(AlignedHeightMip0, TileSize[Y]) * ExpectedPitch, // Render offset is tile's base address on which mip begins
|
|
OffsetInfo.Render.Offset64);
|
|
EXPECT_EQ(0, OffsetInfo.Render.XOffset); // Aligns with Mip0 at X = 0
|
|
EXPECT_EQ((AlignedHeightMip0) % TileSize[Y], OffsetInfo.Render.YOffset); // AlignedHeightMip0 % TileY-Height
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
//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(GMM_ULT_ALIGN_FLOOR(AlignedHeightMip0 + HeightLinesLevel2, TileSize[Y]) * ExpectedPitch + // Render offset is tile's base address on which mip begins
|
|
(AlignedWidthMip1 * GetBppValue(bpp) / TileSize[X]) * PAGE_SIZE,
|
|
OffsetInfo.Render.Offset64);
|
|
|
|
EXPECT_EQ((AlignedWidthMip1 * GetBppValue(bpp)) % TileSize[X], OffsetInfo.Render.XOffset); // Aligns with Mip0 at X = 0
|
|
EXPECT_EQ((AlignedHeightMip0 + HeightLinesLevel2) % TileSize[Y], OffsetInfo.Render.YOffset); // AlignedHeightMip0 % TileY-Height
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset);
|
|
|
|
//cache Mip i'th offset
|
|
RenderOffset[i].Offset = (AlignedHeightMip0 + HeightLinesLevel2) * ExpectedPitch +
|
|
(AlignedWidthMip1 * GetBppValue(bpp));
|
|
|
|
HeightLinesLevel2 += HeightOfMip;
|
|
}
|
|
|
|
uint32_t ExpectedQPitch = AlignedHeightMip0 + AlignedHeightMip1 + 12 * 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
|
|
ExpectedPitch *
|
|
GMM_ULT_ALIGN(MaxArraySize * __GMM_MAX_CUBE_FACE * ExpectedQPitch, TileSize[Y]));
|
|
|
|
// 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(GMM_ULT_ALIGN_FLOOR(((6 * ArrayIndex) + CubeFaceIndex) * ExpectedQPitch, TileSize[Y]) * 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((((6 * ArrayIndex) + CubeFaceIndex) * ExpectedQPitch) % TileSize[Y],
|
|
OffsetInfo.Render.YOffset); // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
|
|
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 TileAlignedOffsetX = GMM_ULT_ALIGN_FLOOR(OffsetX, TileSize[X]);
|
|
OffsetX -= TileAlignedOffsetX;
|
|
|
|
uint32_t OffsetY = MipOffset / ExpectedPitch;
|
|
uint32_t TileAlignedOffsetY = GMM_ULT_ALIGN_FLOOR(OffsetY, TileSize[Y]);
|
|
OffsetY -= TileAlignedOffsetY;
|
|
|
|
uint32_t RenderAlignOffset =
|
|
TileAlignedOffsetY * ExpectedPitch +
|
|
(TileAlignedOffsetX / TileSize[X]) * PAGE_SIZE;
|
|
|
|
|
|
EXPECT_EQ(RenderAlignOffset, OffsetInfo.Render.Offset64); // Render offset is tile's base address on which cube face begins.
|
|
EXPECT_EQ(OffsetX, OffsetInfo.Render.XOffset);
|
|
EXPECT_EQ(OffsetY, OffsetInfo.Render.YOffset); // Y Offset should be (CubeFaceIndex * QPitch) % TileHeight
|
|
EXPECT_EQ(0, OffsetInfo.Render.ZOffset); // Z offset N/A should be 0
|
|
}
|
|
}
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
// ********************************************************************************//
|
|
|
|
/// @brief ULT for Buffer Resource
|
|
TEST_F(CTestResource, TestBufferLinearResource)
|
|
{
|
|
}
|
|
|
|
// ********************************************************************************//
|
|
|
|
/// @brief ULT for Separate Stencil Resource
|
|
TEST_F(CTestResource, TestSeparateStencil)
|
|
{
|
|
const uint32_t HAlign = 8; //Separate Stencil alignment (8x8)
|
|
const uint32_t VAlign = 8;
|
|
|
|
const uint32_t StencilTileSize[1][2] = {64, 64}; //Stencil is TileW, swizzled (2*w x h/2) onto TileY
|
|
const uint32_t AllocTileSize[1][2] = {128, 32}; //Allocation-aligned to TileY since some HW units support TileW by WA'ing TileY
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledX = 1; //Any input Tiling - changed to TileW? YES, but expected one is TileW
|
|
gmmParams.Flags.Gpu.SeparateStencil = 1;
|
|
gmmParams.Format = SetResourceFormat(TEST_BPP_8); //Only R8_UNIT supported, driver assumes so, but creates resource even for other bpps requests (as bpp=8)
|
|
|
|
// Allocate 1x1 surface so that it occupies 1 Tile in X dimension
|
|
for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++) //SeparateStencil with 2D, cube, 1D, 3D with mip-maps
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i);
|
|
gmmParams.BaseWidth64 = 0x1;
|
|
gmmParams.BaseHeight = 0x1;
|
|
gmmParams.Depth = 0x1; //Depth !=1 supported for stencil? Supported on all Gens. Gen8 gives only Lod0 for mip-mapped Stencil too
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
uint32_t ExpectedPitch = StencilTileSize[0][0] * 2; // 2 TileW tiles interleaved on same row
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tileY wide
|
|
|
|
if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
|
|
{
|
|
uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign); //Interleaved rows for TielW-arrangement. No Qpitch for 3d, only for 2d-array and cube on Gen8
|
|
//it needs to be in VALign multiple, for Stencil buffer needs it as multiple of 8
|
|
VerifyResourceQPitch<true>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile
|
|
}
|
|
|
|
VerifyResourceSize<true>(ResourceInfo, GMM_KBYTE(4)); //1 Tile should be enough
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate 2 tiles in X dimension.
|
|
for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++)
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i); //Could we loop over Res_types for speacil allocation types
|
|
gmmParams.BaseWidth64 = StencilTileSize[0][0] + 0x1;
|
|
gmmParams.BaseHeight = (gmmParams.Type == RESOURCE_1D) ? 0x1 :
|
|
(gmmParams.Type == RESOURCE_CUBE) ? gmmParams.BaseWidth64 :
|
|
StencilTileSize[0][1];
|
|
gmmParams.Depth = 0x1; //HW doesn't support Depth/STC for 3D res_type, but driver has no such restriction
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
uint32_t ExpectedPitch = StencilTileSize[0][0] * 2 * 2; // Requires 2 StencilTiles, further doubled for interleaved rows 2*w = Pitch
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tiles wide
|
|
|
|
uint32_t ExpectedQPitch;
|
|
if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
|
|
{
|
|
ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign); //Interleaved rows for TileW-arrangement - but Qpitch calculated w/o interleaving in mind. No Qpitch for 3d, only for 2d-array and cube on Gen8
|
|
//GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign)/2, VAlign); //Doesn't HW expect distance in rows between 2 cube-faces (array slices) : It does so, but in logical view not physical view, so not interleaved rows.
|
|
//it needs to be in VALign multiple, for Stencil buffer needs it as multiple of 8
|
|
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) /2 (Stencil height = halved due to interleaving), then aligned to tile boundary
|
|
((gmmParams.Type == RESOURCE_CUBE) ?
|
|
ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch * __GMM_MAX_CUBE_FACE / 2, AllocTileSize[0][1]) : //cube
|
|
2 * GMM_KBYTE(4)));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate 2 tiles in X/Y dimension.
|
|
for(uint32_t i = RESOURCE_2D; i <= RESOURCE_3D; i++)
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i);
|
|
gmmParams.BaseWidth64 = StencilTileSize[0][0] + 0x1;
|
|
gmmParams.BaseHeight = StencilTileSize[0][1] + 0x1;
|
|
gmmParams.Depth = 0x1;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
uint32_t ExpectedPitch = StencilTileSize[0][0] * 2 * 2; // Requires 2 StencilTiles, double again for interleaved rows 2*w = Pitch,
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
|
|
|
|
VerifyResourceSize<true>(ResourceInfo, 2 * 2 * GMM_KBYTE(4));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate multi-tiles in X/Y/Z dimension.
|
|
for(uint32_t i = RESOURCE_3D; i <= RESOURCE_3D; i++)
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i);
|
|
gmmParams.BaseWidth64 = StencilTileSize[0][0] + 0x1;
|
|
gmmParams.BaseHeight = StencilTileSize[0][1] + 0x1;
|
|
gmmParams.Depth = StencilTileSize[0][1] + 0x1;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
uint32_t ExpectedPitch = StencilTileSize[0][0] * 2 * 2; // Requires 2 StencilTiles, doubled again for interleaved rows 2*w = Pitch, width < 1.5 Tiles
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
|
|
|
|
uint32_t TwoDQPitch, ExpectedQPitch;
|
|
{
|
|
TwoDQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign); //Interleaved rows for TileW-arrangement - but Qpitch calculated w/o interleaving in mind. No Qpitch for 3d, only for 2d-array and cube on Gen8
|
|
//GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign)/2, VAlign); //Doesn't HW expect distance in rows between 2 cube-faces (array slices) : It does so, but in logical view not physical view, so not interleaved rows.
|
|
//it needs to be in VALign multiple, for Stencil buffer needs it as multiple of 8
|
|
|
|
//VerifyResourceQPitch<false>(ResourceInfo, TwoDQPitch); //Gen8 doesn't support QPitch for RES_3D
|
|
|
|
ExpectedQPitch = gmmParams.Depth * TwoDQPitch; //Depth slices arranged as 2D-arrayed slices.
|
|
}
|
|
VerifyResourceSize<true>(ResourceInfo,
|
|
ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch / 2, AllocTileSize[0][1]));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
//Mip-mapped array case: <SNB>Stencil QPitch = h0 ie Stencil only has Lod0
|
|
//<BDW>Above limit not there, should have mip-map block height for Qpitch
|
|
}
|
|
|
|
/// @brief ULT for Hiz Depth buffer Resource
|
|
TEST_F(CTestResource, TestHiZ)
|
|
{
|
|
const uint32_t HAlign = 16; //HiZ alignment (16x8) [Depth 16bit: 8x4; ow 4x4]
|
|
const uint32_t VAlign = 4; // 8; Need to debug why driver uses VAlign/2
|
|
|
|
//const uint32_t DepthTileSize[1][2] = { 64, 64 }; //Depth/Stencil buffer should be TileY/Ys/Yf only (16,24,32 bpp only) no 3D or MSAA
|
|
const uint32_t AllocTileSize[1][2] = {128, 32}; //HiZ is TileY
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Info.TiledX = 1; //Not supported for Depth buffer, but HiZ output is TileY
|
|
gmmParams.Flags.Gpu.Depth = 1; //GPU Flags= Depth/SeparateStencil + HiZ
|
|
gmmParams.Flags.Gpu.HiZ = 1;
|
|
|
|
// Allocate 1x1 surface so that it occupies 1 Tile in X dimension
|
|
for(uint32_t j = TEST_BPP_8; j <= TEST_BPP_128; j++) //Depth bpp doesn't matter, Depth px dimensions decide HiZ size in HW
|
|
{
|
|
gmmParams.Format = SetResourceFormat(static_cast<TEST_BPP>(j)); //Only 16,24,32 supported; But driver creates the resource even for other bpps without failing
|
|
for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++) //3D doesn't support HiZ - test driver returns proper?
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i);
|
|
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 = AllocTileSize[0][0];
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 1); // 1 tileY wide
|
|
|
|
if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
|
|
{
|
|
uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
ExpectedQPitch = GMM_ULT_ALIGN(ExpectedQPitch / 2, VAlign);
|
|
|
|
VerifyResourceQPitch<false>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile, Turn on verification after clarity
|
|
}
|
|
|
|
VerifyResourceSize<true>(ResourceInfo,
|
|
GMM_KBYTE(4)); //1 Tile should be enough
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
// Allocate 2 tiles in X dimension. (muti-tiles Tiles in Y dimension for cube/array)
|
|
for(uint32_t i = RESOURCE_1D; i <= RESOURCE_CUBE; i++)
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i);
|
|
gmmParams.BaseWidth64 = AllocTileSize[0][0] + 0x1;
|
|
gmmParams.BaseHeight = (gmmParams.Type == RESOURCE_1D) ? 0x1 :
|
|
(gmmParams.Type == RESOURCE_CUBE) ? gmmParams.BaseWidth64 :
|
|
VAlign / 2;
|
|
gmmParams.ArraySize = (gmmParams.Type != RESOURCE_3D) ? VAlign : 1; // Gen8 doesn't support 3D-arrays (so HiZ not supported) [test 3d arrays once -- HiZ would fail but ResCreate doesn't?]
|
|
gmmParams.Depth = 0x1;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
uint32_t ExpectedPitch = AllocTileSize[0][0] * 2;
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tileY wide
|
|
|
|
uint32_t ExpectedQPitch = 0;
|
|
if(gmmParams.ArraySize > 1 || gmmParams.Type == RESOURCE_CUBE)
|
|
{
|
|
ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
ExpectedQPitch = GMM_ULT_ALIGN(ExpectedQPitch / 2, VAlign);
|
|
|
|
VerifyResourceQPitch<false>(ResourceInfo, ExpectedQPitch); // Each face should be VAlign rows apart within a tile. Turn on verification after clarity
|
|
}
|
|
|
|
VerifyResourceSize<true>(ResourceInfo, // PitchInBytes * Rows where Rows = (__GMM_MAX_CUBE_FACE x QPitch) /2 (Stencil height = halved due to interleaving), then aligned to tile boundary
|
|
((gmmParams.Type == RESOURCE_CUBE) ?
|
|
ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize * __GMM_MAX_CUBE_FACE, AllocTileSize[0][1]) : //cube
|
|
((gmmParams.ArraySize > 1) ?
|
|
ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, AllocTileSize[0][1]) : //array
|
|
2 * GMM_KBYTE(4))));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
// Allocate 2 tiles in X/Y dimension (non-arrayed) Multi-tiles for 3D
|
|
for(uint32_t i = RESOURCE_2D; i <= RESOURCE_3D; i++)
|
|
{
|
|
gmmParams.Type = static_cast<GMM_RESOURCE_TYPE>(i);
|
|
gmmParams.BaseWidth64 = AllocTileSize[0][0] + 0x1;
|
|
gmmParams.BaseHeight = 2 * AllocTileSize[0][1] + 0x1; //Half-Depth Height or QPitch (lod!=0), aligned to 8 required by HW
|
|
gmmParams.Depth = (gmmParams.Type == RESOURCE_2D) ? 0x1 :
|
|
VAlign + 1;
|
|
gmmParams.ArraySize = 1;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(ResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(ResourceInfo, VAlign);
|
|
uint32_t ExpectedPitch = AllocTileSize[0][0] * 2;
|
|
VerifyResourcePitch<true>(ResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, 2); // 2 tile wide
|
|
|
|
uint32_t TwoDQPitch = 0, ExpectedQPitch = 0;
|
|
if(gmmParams.Type == RESOURCE_3D)
|
|
{
|
|
TwoDQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
ExpectedQPitch = gmmParams.Depth * GMM_ULT_ALIGN(TwoDQPitch / 2, VAlign); //Depth slices arranged as 2D-arrayed slices.
|
|
}
|
|
else
|
|
{
|
|
//HiZ for 3D not supported. Driver still allocates like IVB/HSW. (should Qpitch or only overall buffer height be Valigned ?)
|
|
VerifyResourceSize<true>(ResourceInfo,
|
|
((gmmParams.Type == RESOURCE_3D) ?
|
|
ExpectedPitch * GMM_ULT_ALIGN(ExpectedQPitch, AllocTileSize[0][1]) :
|
|
2 * 2 * GMM_KBYTE(4)));
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
//Mip-mapped case:
|
|
}
|
|
|
|
/// @brief ULT for MSAA Resource
|
|
TEST_F(CTestResource, TestMSAA)
|
|
{
|
|
enum MSAA_Samples
|
|
{
|
|
MSAA_None,
|
|
MSAA_2x,
|
|
MSAA_4x,
|
|
MSAA_8x,
|
|
MSAA_16x
|
|
};
|
|
|
|
const uint32_t MCSTileSize[1][2] = {128, 32}; //MCS is TileY
|
|
|
|
//Gen8:No mip-map for MSAA (MSS and MCS), No 16x
|
|
//No MSAA for YUV/compressed formats
|
|
//Interleaved MSS (IMS) for Depth/Stencil. Arrayed MSS (CMS) for Color RT
|
|
//QPitch exists for arrayed MSS - gives distance between slices
|
|
//MSS (Arrayed): px_wL, px_hL = pixel width/height of single sample at Lod L
|
|
// MSS width = px_wL, MSS height = NumSamples*px_hL
|
|
//MSS (Interleaved): px_wL, px_hL = pixel width/height of single sample at Lod L
|
|
// Samples MSS width MSS Height
|
|
// 2x 4*ceil(px_wL/2) px_hL
|
|
// 4x 4*ceil(px_wL/2) 4*ceil(px_hL/2)
|
|
// 8x 8*ceil(px_wL/2) 4*ceil(px_hL/2)
|
|
// 16x 8*ceil(px_wL/2) 8*ceil(px_hL/2)
|
|
//MCS (bpp): 2x/4x - bpp_8, 8x - bpp_32, 16x - bpp_64
|
|
|
|
const uint32_t TestDimensions[3][2] = {
|
|
{0, 0}, //1x1x1
|
|
{1, 0}, //2 Tilesx1
|
|
{1, 1}, //2 Tilesx 2
|
|
};
|
|
|
|
uint32_t TestArraySize[2] = {1, 7};
|
|
|
|
uint32_t HAlign, VAlign, TileDimX, TileDimY, MCSHAlign, MCSVAlign, TileSize;
|
|
uint32_t ExpectedMCSBpp;
|
|
|
|
std::vector<std::tuple<int, int, int, bool, int, int>> List; //TEST_TILE_TYPE, TEST_BPP, TEST_RESOURCE_TYPE, Depth or RT, TestDimension index, TestArraySize index
|
|
auto Size = BuildInputIterator(List, 3, 2); // Size of arrays TestDimensions, TestArraySize
|
|
|
|
for(auto element : List)
|
|
{
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Flags.Info = {0};
|
|
|
|
TEST_TILE_TYPE Tiling = (TEST_TILE_TYPE)std::get<0>(element);
|
|
TEST_BPP Bpp = (TEST_BPP)std::get<1>(element);
|
|
TEST_RESOURCE_TYPE ResType = (TEST_RESOURCE_TYPE)std::get<2>(element);
|
|
bool IsRT = std::get<3>(element); // True for RT, False for Depth
|
|
int TestDimIdx = std::get<4>(element); //index into TestDimensions array
|
|
int ArrayIdx = std::get<5>(element); //index into TestArraySize
|
|
TileSize = GMM_KBYTE(4);
|
|
|
|
//Discard un-supported Tiling/Res_type/bpp for this test
|
|
if(ResType != TEST_RESOURCE_2D || Tiling > TEST_TILEY //No 1D/3D/Cube. Supported 2D mip-maps/array
|
|
|| (!IsRT && (Tiling == TEST_TILEX ||
|
|
!(Bpp == TEST_BPP_16 || Bpp == TEST_BPP_32)))) //depth supported on 16bit, 32bit formats only
|
|
continue;
|
|
|
|
SetTileFlag(gmmParams, Tiling);
|
|
SetResType(gmmParams, ResType);
|
|
SetResGpuFlags(gmmParams, IsRT);
|
|
SetResArraySize(gmmParams, TestArraySize[ArrayIdx]);
|
|
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Format = SetResourceFormat(Bpp);
|
|
for(uint32_t k = MSAA_2x; k < MSAA_16x; k++) //No 16x MSAA on Gen8
|
|
{
|
|
GetAlignmentAndTileDimensionsForMSAA(Bpp, IsRT, Tiling, (TEST_MSAA)k,
|
|
TileDimX, TileDimY, HAlign, VAlign,
|
|
ExpectedMCSBpp, MCSHAlign, MCSVAlign);
|
|
|
|
gmmParams.BaseWidth64 = TestDimensions[TestDimIdx][0] * TileDimX + 0x1;
|
|
gmmParams.BaseHeight = TestDimensions[TestDimIdx][1] * TileDimY + 0x1;
|
|
|
|
gmmParams.Depth = 0x1; //2D Res_type with Depth > 1 doesn't fail, although Tex_cacl doesn't use it
|
|
gmmParams.MSAA.NumSamples = static_cast<uint32_t>(pow((double)2, k));
|
|
gmmParams.Flags.Gpu.MCS = 0;
|
|
gmmParams.ArraySize = 1;
|
|
|
|
//MSS surface
|
|
GMM_RESOURCE_INFO *MSSResourceInfo;
|
|
MSSResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
if(MSSResourceInfo)
|
|
{
|
|
VerifyResourceHAlign<true>(MSSResourceInfo, HAlign);
|
|
VerifyResourceVAlign<true>(MSSResourceInfo, VAlign);
|
|
if(IsRT) //Arrayed MSS
|
|
{
|
|
uint32_t ExpectedPitch = 0, ExpectedQPitch = 0;
|
|
ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * (uint32_t)pow(2.0, Bpp), TileDimX); // Aligned width * bpp, aligned to TileWidth
|
|
VerifyResourcePitch<true>(MSSResourceInfo, ExpectedPitch);
|
|
if(Tiling != TEST_LINEAR)
|
|
VerifyResourcePitchInTiles<true>(MSSResourceInfo, ExpectedPitch / TileDimX);
|
|
|
|
//if (gmmParams.ArraySize > 1) - Arrayed MSS has QPitch
|
|
{
|
|
ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
|
|
VerifyResourceQPitch<true>(MSSResourceInfo, ExpectedQPitch);
|
|
}
|
|
|
|
uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.MSAA.NumSamples * gmmParams.ArraySize, TileDimY); //Align Height =ExpectedPitch * NumSamples * ExpectedQPitch, to Tile-Height
|
|
VerifyResourceSize<true>(MSSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize));
|
|
}
|
|
else // Interleaved MSS
|
|
{
|
|
uint32_t WidthMultiplier, HeightMultiplier;
|
|
GetInterleaveMSSPattern((TEST_MSAA)k, WidthMultiplier, HeightMultiplier);
|
|
gmmParams.BaseWidth64 = WidthMultiplier > 1 ? GMM_ULT_ALIGN(gmmParams.BaseWidth64, 2) : gmmParams.BaseWidth64;
|
|
gmmParams.BaseHeight = HeightMultiplier > 1 ? GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) : gmmParams.BaseHeight;
|
|
|
|
uint32_t ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64 * WidthMultiplier, HAlign) * (uint32_t)pow(2.0, Bpp), TileDimX); //AlignedWidth*bpp, then align to Tile
|
|
VerifyResourcePitch<true>(MSSResourceInfo, ExpectedPitch);
|
|
if(Tiling != TEST_LINEAR)
|
|
{
|
|
VerifyResourcePitchInTiles<true>(MSSResourceInfo, ExpectedPitch / TileDimX); // 1 tileY wide
|
|
}
|
|
|
|
uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight * HeightMultiplier, VAlign);
|
|
if(gmmParams.ArraySize > 1)
|
|
{
|
|
// it needs to be in VALign multiple
|
|
VerifyResourceQPitch<true>(MSSResourceInfo, ExpectedQPitch);
|
|
}
|
|
uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, TileDimY); //Align Height = ExpectedQPitch*ArraySize, to Tile-Height
|
|
VerifyResourceSize<true>(MSSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize)); //ExpectedPitch *ExpectedHeight
|
|
}
|
|
}
|
|
|
|
//No MCS surface if MSS creation failed
|
|
if(MSSResourceInfo)
|
|
{
|
|
gmmParams.Flags.Gpu.MCS = 1;
|
|
GMM_RESOURCE_INFO *MCSResourceInfo;
|
|
MCSResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
VerifyResourceHAlign<true>(MCSResourceInfo, MCSHAlign); // MCS alignment same as basic RT alignment
|
|
VerifyResourceVAlign<true>(MCSResourceInfo, MCSVAlign);
|
|
|
|
uint32_t ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64, MCSHAlign) * ExpectedMCSBpp, MCSTileSize[0][0]); //AlignedWidth*bpp, then tile-alignment
|
|
VerifyResourcePitch<true>(MCSResourceInfo, ExpectedPitch);
|
|
VerifyResourcePitchInTiles<true>(MCSResourceInfo, ExpectedPitch / MCSTileSize[0][0]);
|
|
|
|
uint32_t ExpectedQPitch = gmmParams.BaseHeight;
|
|
if(gmmParams.ArraySize > 1)
|
|
{
|
|
ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, MCSVAlign); //QPitch only for array
|
|
VerifyResourceQPitch<true>(MCSResourceInfo, ExpectedQPitch);
|
|
}
|
|
|
|
uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, MCSTileSize[0][1]);
|
|
VerifyResourceSize<true>(MCSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(MCSResourceInfo);
|
|
} //MCS
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(MSSResourceInfo);
|
|
} //NumSamples = k
|
|
} //Iterate through all input tuples
|
|
}
|
|
|
|
/// @brief ULT for Plannar 2D Resource - RGBP
|
|
TEST_F(CTestResource, TestPlanar2D_RGBP)
|
|
{
|
|
/* Test planar surfaces where all planes are full-sized */
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// UUUUUUUU
|
|
// UUUUUUUU
|
|
// UUUUUUUU
|
|
// UUUUUUUU
|
|
// VVVVVVVV
|
|
// VVVVVVVV
|
|
// VVVVVVVV
|
|
// VVVVVVVV
|
|
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
|
|
const uint32_t PlaneRowAlignment = 16;
|
|
|
|
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
|
|
{512, 8}, // TileX
|
|
{128, 32}}; // TileY
|
|
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
|
|
{
|
|
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x101;
|
|
gmmParams.BaseHeight = 0x101;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
|
|
gmmParams.Format = GMM_FORMAT_RGBP;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t Pitch, Height;
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
|
|
//Since Tile alignment factor is greater than GMM_IMCx_PLANE_ROW_ALIGNMENT=16
|
|
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
Height = GMM_ULT_ALIGN(Height, TileSize[TileIndex][1]) * 3 /*Y, U, V*/;
|
|
}
|
|
else
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
|
|
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment /* min16 rows*/) * 3 /*Y, U, V*/;
|
|
}
|
|
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
|
|
}
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
|
|
|
|
// Y plane should be at 0,0
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
|
|
|
|
// U plane should be at end of Y plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(Height / 3, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
|
|
// V plane should be at end of U plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
|
|
EXPECT_EQ(2 * (Height / 3), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Plannar 2D Resource - MFX_JPEG_YUV422V
|
|
TEST_F(CTestResource, TestPlanar2D_MFX_JPEG_YUV422V)
|
|
{
|
|
/* Test planar surfaces where both U and V are half the size of Y */
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// UUUUUUUU
|
|
// UUUUUUUU
|
|
// VVVVVVVV
|
|
// VVVVVVVV
|
|
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
|
|
const uint32_t PlaneRowAlignment = 16;
|
|
|
|
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
|
|
{512, 8}, // TileX
|
|
{128, 32}}; // TileY
|
|
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
|
|
{
|
|
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x101;
|
|
gmmParams.BaseHeight = 0x101;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
|
|
gmmParams.Flags.Info.Linear = 1; // GmmLib needs linear to be set as fallback for all planar surfaces
|
|
gmmParams.Format = GMM_FORMAT_MFX_JPEG_YUV422V;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t Pitch, Height;
|
|
uint32_t YHeight, VHeight;
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
|
|
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
|
|
|
|
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) / 2, PlaneRowAlignment);
|
|
VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]);
|
|
}
|
|
else
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
|
|
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) / 2, PlaneRowAlignment);
|
|
}
|
|
Height = YHeight + 2 * VHeight;
|
|
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
|
|
}
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
|
|
|
|
// Y plane should be at 0,0
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
|
|
|
|
// U plane should be at end of Y plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
|
|
// V plane should be at end of U plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
|
|
EXPECT_EQ(YHeight + VHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Plannar 2D Resource - MFX_JPEG_YUV411R
|
|
TEST_F(CTestResource, TestPlanar2D_MFX_JPEG_YUV411R)
|
|
{
|
|
/* Test planar surfaces where both U and V are quarter the size of Y */
|
|
//YYYYYYYY
|
|
//YYYYYYYY
|
|
//YYYYYYYY
|
|
//YYYYYYYY
|
|
//UUUUUUUU
|
|
//VVVVVVVV
|
|
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
|
|
const uint32_t PlaneRowAlignment = 16;
|
|
|
|
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
|
|
{512, 8}, // TileX
|
|
{128, 32}}; // TileY
|
|
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
|
|
{
|
|
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x101;
|
|
gmmParams.BaseHeight = 0x101;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
|
|
gmmParams.Format = GMM_FORMAT_MFX_JPEG_YUV411R_TYPE;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t Pitch, Height;
|
|
uint32_t YHeight, VHeight;
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
|
|
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
|
|
|
|
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 4) / 4, PlaneRowAlignment);
|
|
VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]);
|
|
}
|
|
else
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
|
|
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 4) / 4, PlaneRowAlignment);
|
|
}
|
|
|
|
Height = YHeight + 2 * VHeight;
|
|
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
|
|
}
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
|
|
|
|
// Y plane should be at 0,0
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
|
|
|
|
// U plane should be at end of Y plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
|
|
// V plane should be at end of U plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
|
|
EXPECT_EQ(YHeight + VHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Plannar 2D Resource - NV12
|
|
TEST_F(CTestResource, TestPlanar2D_NV12)
|
|
{
|
|
/* Test planar surface with hybrid UV planes where UV plane is half the size
|
|
of Y and U/V data is packed together */
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// [UV-Packing]
|
|
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
|
|
|
|
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
|
|
{512, 8}, // TileX
|
|
{128, 32}}; // TileY
|
|
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
|
|
{
|
|
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x100;
|
|
gmmParams.BaseHeight = 0x100;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
|
|
gmmParams.Format = GMM_FORMAT_NV12;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t Pitch, Height;
|
|
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
|
|
|
|
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]) +
|
|
GMM_ULT_ALIGN(gmmParams.BaseHeight / 2, TileSize[TileIndex][1]);
|
|
}
|
|
else
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
|
|
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight /*Y*/ + gmmParams.BaseHeight / 2 /*UV*/, TileSize[TileIndex][1]);
|
|
}
|
|
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
|
|
}
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
|
|
|
|
// Y plane should be at 0,0
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
|
|
|
|
// U/V plane should be at end of Y plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
|
|
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
}
|
|
else
|
|
{
|
|
EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
}
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Planar 2D Resource - IMC4
|
|
TEST_F(CTestResource, TestPlanar2D_IMC4)
|
|
{
|
|
/* Test planar surface V surface is on the right of U */
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// UUUUVVVV
|
|
// UUUUVVVV
|
|
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
|
|
const uint32_t PlaneRowAlignment = 16;
|
|
|
|
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
|
|
{512, 8}, // TileX
|
|
{128, 32}}; // TileY
|
|
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
|
|
{
|
|
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x101;
|
|
gmmParams.BaseHeight = 0x101;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
|
|
gmmParams.Format = GMM_FORMAT_IMC4;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t Pitch, Height;
|
|
uint32_t YHeight, VHeight;
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
|
|
if(Pitch / TileSize[TileIndex][0] % 2)
|
|
{
|
|
Pitch += TileSize[TileIndex][0];
|
|
}
|
|
|
|
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
VHeight = YHeight / 2;
|
|
|
|
YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
|
|
VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]); // No need of PlaneRowAlignment since last plane
|
|
}
|
|
else
|
|
{
|
|
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
|
|
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
|
|
VHeight = YHeight / 2;
|
|
}
|
|
|
|
Height = YHeight + VHeight;
|
|
|
|
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
|
|
}
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
|
|
|
|
// Y plane should be at 0,0
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
|
|
|
|
// U plane should be at end of Y plane
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(Pitch / 2, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
|
|
|
|
if(Tile != TEST_LINEAR)
|
|
{
|
|
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
}
|
|
else
|
|
{
|
|
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Planar 2D Resource - YV12
|
|
TEST_F(CTestResource, TestPlanar2D_YV12)
|
|
{
|
|
/* Test planar surface V surface follows U surface linearly */
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// YYYYYYYY
|
|
// VVVVVV.. <-- V and U planes follow the Y plane, as linear
|
|
// ..UUUUUU arrays--without respect to pitch.
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x100;
|
|
gmmParams.BaseHeight = 0x100;
|
|
gmmParams.Depth = 0x1;
|
|
gmmParams.Flags.Info.Linear = 1; // Linear only since UV plane doesn't have a pitch
|
|
gmmParams.Format = GMM_FORMAT_YV12;
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint32_t Pitch = gmmParams.BaseWidth64;
|
|
uint32_t SizeOfY = Pitch * gmmParams.BaseHeight;
|
|
uint32_t Height = (SizeOfY /*Y*/ + SizeOfY / 4 /*V*/ + SizeOfY / 4 /*U*/) / Pitch;
|
|
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<false>(ResourceInfo, 0); // N/A for linear
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
|
|
|
|
// Y plane should be at 0,0
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
|
|
|
|
// V plane follows Y
|
|
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
|
|
EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
|
|
|
|
// U plane should be at end of V plane
|
|
uint32_t UByteOffset = SizeOfY /* Y */ +
|
|
SizeOfY / 4; /* Size of V = 1/4 of Y */
|
|
EXPECT_EQ(UByteOffset % Pitch, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
|
|
EXPECT_EQ(UByteOffset / Pitch, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
|
|
/// @brief ULT for Unified aux surface
|
|
TEST_F(CTestResource, TestUnifiedAuxSurface)
|
|
{
|
|
uint32_t TileSize[] = {128, 32};
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.Flags.Gpu.CCS = 1;
|
|
gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
|
|
gmmParams.BaseWidth64 = 0x100;
|
|
gmmParams.BaseHeight = 0x100;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, TEST_TILEY);
|
|
|
|
for(uint32_t bpp = TEST_BPP_32; bpp <= TEST_BPP_128; bpp++) // 32/64/128 only
|
|
{
|
|
gmmParams.Format = SetResourceFormat(static_cast<TEST_BPP>(bpp));
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint64_t Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64 * GetBppValue(static_cast<TEST_BPP>(bpp)), TileSize[0]);
|
|
uint64_t Size = Pitch * GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]);
|
|
|
|
Size = GMM_ULT_ALIGN(Size, PAGE_SIZE);
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<false>(ResourceInfo, Pitch / TileSize[0]);
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
|
|
|
|
uint32_t AuxPitch = Pitch;
|
|
switch(bpp)
|
|
{
|
|
case TEST_BPP_32:
|
|
AuxPitch /= 8;
|
|
break;
|
|
case TEST_BPP_64:
|
|
AuxPitch /= 4;
|
|
break;
|
|
case TEST_BPP_128:
|
|
AuxPitch /= 2;
|
|
break;
|
|
}
|
|
uint64_t AuxSize = AuxPitch * GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]);
|
|
AuxSize = GMM_ULT_ALIGN(AuxSize, PAGE_SIZE);
|
|
|
|
// Verify unified aux info
|
|
EXPECT_EQ(AuxSize, ResourceInfo->GetSizeAuxSurface(GMM_AUX_CCS));
|
|
|
|
if(ResourceInfo->Is64KBPageSuitable())
|
|
{
|
|
EXPECT_EQ(GMM_ULT_ALIGN(Size, 64 * PAGE_SIZE) + AuxSize, ResourceInfo->GetSizeSurface());
|
|
}
|
|
else
|
|
{
|
|
EXPECT_EQ(Size + AuxSize, ResourceInfo->GetSizeSurface());
|
|
}
|
|
|
|
EXPECT_EQ(256, ResourceInfo->GetAuxHAlign());
|
|
EXPECT_EQ(128, ResourceInfo->GetAuxVAlign());
|
|
EXPECT_EQ(0, ResourceInfo->GetAuxQPitch());
|
|
EXPECT_EQ(AuxPitch, ResourceInfo->GetUnifiedAuxPitch());
|
|
EXPECT_EQ(AuxPitch / TileSize[0], ResourceInfo->GetRenderAuxPitchTiles());
|
|
EXPECT_EQ(Size, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS));
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|
|
}
|
|
|
|
/// @brief ULT for Compressed Resource
|
|
TEST_F(CTestResource, TestCompressedSurface)
|
|
{
|
|
uint32_t TileSize[] = {128, 32};
|
|
uint32_t CompBlock[] = {4, 4};
|
|
|
|
GMM_RESCREATE_PARAMS gmmParams = {};
|
|
gmmParams.Type = RESOURCE_2D;
|
|
gmmParams.NoGfxMemory = 1;
|
|
gmmParams.Flags.Gpu.Texture = 1;
|
|
gmmParams.BaseWidth64 = 0x100;
|
|
gmmParams.BaseHeight = 0x100;
|
|
gmmParams.Depth = 0x1;
|
|
SetTileFlag(gmmParams, TEST_TILEY);
|
|
//TODO: Programatically test all compression formats.
|
|
gmmParams.Format = GMM_FORMAT_BC1_UNORM; // BC1 is 4x4 compression block, 64bpe
|
|
|
|
GMM_RESOURCE_INFO *ResourceInfo;
|
|
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
|
|
|
|
uint64_t Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64 / CompBlock[0] * GetBppValue(TEST_BPP_64), TileSize[0]);
|
|
uint64_t Size = Pitch * GMM_ULT_ALIGN(gmmParams.BaseHeight / CompBlock[1], TileSize[1]);
|
|
Size = GMM_ULT_ALIGN(Size, PAGE_SIZE);
|
|
|
|
VerifyResourcePitch<true>(ResourceInfo, Pitch);
|
|
VerifyResourcePitchInTiles<false>(ResourceInfo, Pitch / TileSize[0]);
|
|
VerifyResourceSize<true>(ResourceInfo, Size);
|
|
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
|
|
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for non-arrayed
|
|
|
|
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
|
|
}
|