| /*============================================================================== |
| 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 = 0; |
| 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 = 0; |
| { |
| 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); |