feat(zebin): Add support for ELF section type SHT_NOBITS

This commit adds support for parsing SHT_NOBITS zebin's ELF sections
(containing global/constant zero-initialized data).

Related-To: NEO-7196
Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
Kacper Nowak
2023-01-24 13:16:02 +00:00
committed by Compute-Runtime-Automation
parent 31154dc20b
commit fa03aa9a40
18 changed files with 421 additions and 85 deletions

View File

@@ -287,6 +287,8 @@ TEST(LinkerInputTests, WhenGettingSegmentForSectionNameThenCorrectSegmentIsRetur
auto segmentConstString = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataConstString.str());
auto segmentInstructions = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::textPrefix.str());
auto segmentInstructions2 = NEO::LinkerInput::getSegmentForSection(".text.abc");
auto segmentGlobalZeroInit = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataGlobalZeroInit.str());
auto segmentGlobalConstZeroInit = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataConstZeroInit.str());
EXPECT_EQ(NEO::SegmentType::GlobalConstants, segmentConst);
EXPECT_EQ(NEO::SegmentType::GlobalConstants, segmentGlobalConst);
@@ -294,6 +296,8 @@ TEST(LinkerInputTests, WhenGettingSegmentForSectionNameThenCorrectSegmentIsRetur
EXPECT_EQ(NEO::SegmentType::GlobalStrings, segmentConstString);
EXPECT_EQ(NEO::SegmentType::Instructions, segmentInstructions);
EXPECT_EQ(NEO::SegmentType::Instructions, segmentInstructions2);
EXPECT_EQ(NEO::SegmentType::GlobalVariablesZeroInit, segmentGlobalZeroInit);
EXPECT_EQ(NEO::SegmentType::GlobalConstantsZeroInit, segmentGlobalConstZeroInit);
}
TEST(LinkerInputTests, WhenGettingSegmentForUnknownSectionNameThenUnknownSegmentIsReturned) {
@@ -1693,6 +1697,146 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchingDataSegmentsThenThe
}
}
TEST(LinkerTests, givenValidSymbolsAndRelocationsToBssDataSectionsWhenPatchingDataSegmentsThenTheyAreProperlyPatched) {
uint64_t initGlobalConstantData[] = {0x1234}; //<- const1 - initValue should be ignored
uint64_t initGlobalVariablesData[] = {0x4321}; // <- var1 - initValue should be ignored
uint64_t constantsSegmentData[2]{0}; // size 2 * uint64_t - contains also bss at the end
uint64_t globalVariablesSegmentData[2]{0}; // size 2 * uint64_t - contains also bss at the end
NEO::MockGraphicsAllocation globalConstantsPatchableSegment{constantsSegmentData, sizeof(constantsSegmentData)};
NEO::MockGraphicsAllocation globalVariablesPatchableSegment{globalVariablesSegmentData, sizeof(globalVariablesSegmentData)};
globalConstantsPatchableSegment.gpuAddress = 0xA0000000;
globalVariablesPatchableSegment.gpuAddress = 0xB0000000;
NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo;
globalConstantsSegmentInfo.gpuAddress = static_cast<uintptr_t>(globalConstantsPatchableSegment.getGpuAddress());
globalConstantsSegmentInfo.segmentSize = globalConstantsPatchableSegment.getUnderlyingBufferSize();
globalVariablesSegmentInfo.gpuAddress = static_cast<uintptr_t>(globalVariablesPatchableSegment.getGpuAddress());
globalVariablesSegmentInfo.segmentSize = globalVariablesPatchableSegment.getUnderlyingBufferSize();
auto setUpInstructionSeg = [](std::vector<uint8_t> &instrData, NEO::Linker::PatchableSegments &patchableInstrSeg) -> void {
uint64_t initData = 0x77777777;
instrData.resize(8, static_cast<uint8_t>(initData));
auto &emplaced = patchableInstrSeg.emplace_back();
emplaced.hostPointer = instrData.data();
emplaced.segmentSize = instrData.size();
};
NEO::Linker::PatchableSegments patchableInstructionSegments;
std::vector<uint8_t> instructionsData1, instructionsData2;
setUpInstructionSeg(instructionsData1, patchableInstructionSegments);
setUpInstructionSeg(instructionsData2, patchableInstructionSegments);
WhiteBox<NEO::LinkerInput> linkerInput;
linkerInput.traits.requiresPatchingOfInstructionSegments = true;
auto &var1 = linkerInput.symbols["var1"];
var1.segment = SegmentType::GlobalVariables;
var1.offset = 0U;
var1.size = 8U;
auto &bssVar = linkerInput.symbols["bssVar"];
bssVar.segment = SegmentType::GlobalVariablesZeroInit;
bssVar.offset = 0U;
bssVar.size = 8U;
auto &const1 = linkerInput.symbols["const1"];
const1.segment = SegmentType::GlobalConstants;
const1.offset = 0U;
const1.size = 8U;
auto &bssConst = linkerInput.symbols["bssConst"];
bssConst.segment = SegmentType::GlobalConstantsZeroInit;
bssConst.offset = 0U;
bssConst.size = 8U;
/*
Segments:
Const:
0x00 0x1000 <- const 1
0x08 0x0 <- bss
Var:
0x00 0x4000 <- var 1
0x08 0x0 <- bss
Instructions:
0x0 0x0 <- will be patched with bss.const
0x08 0x0 <- will be patched with bss.global
1. Patch bss data from const segment with var 1
Patch bss data from global variables segment with const 1
2. Patch const 2 with symbol pointing to bss in const (patched in step 1).
Patch var 2 with symbol pointing to bss in variables (patched in step 1).
*/
// Relocations for step 1.
// bssConst[0] = &var1
{
NEO::LinkerInput::RelocationInfo relocation;
relocation.offset = 0U;
relocation.relocationSegment = NEO::SegmentType::GlobalConstantsZeroInit;
relocation.symbolName = "var1";
relocation.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.dataRelocations.push_back(relocation);
}
// bssGlobal[0] = &const1
{
NEO::LinkerInput::RelocationInfo relocation;
relocation.offset = 0U;
relocation.relocationSegment = NEO::SegmentType::GlobalVariablesZeroInit;
relocation.symbolName = "const1";
relocation.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.dataRelocations.push_back(relocation);
}
// Relocation for step 2.
// instructions[0] = &bssConst
{
NEO::LinkerInput::RelocationInfo relocation;
relocation.offset = 0U;
relocation.relocationSegment = NEO::SegmentType::Instructions;
relocation.symbolName = "bssConst";
relocation.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.textRelocations.push_back({relocation});
}
// instructions[1] = &bssVar
{
NEO::LinkerInput::RelocationInfo relocation;
relocation.offset = 0U;
relocation.relocationSegment = NEO::SegmentType::Instructions;
relocation.symbolName = "bssVar";
relocation.type = NEO::LinkerInput::RelocationInfo::Type::Address;
linkerInput.textRelocations.push_back({relocation});
}
NEO::Linker linker(linkerInput);
auto device = std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get()));
NEO::Linker::UnresolvedExternals unresolvedExternals;
NEO::Linker::KernelDescriptorsT kernelDescriptors;
NEO::Linker::ExternalFunctionsT externalFunctions;
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {}, {},
&globalVariablesPatchableSegment, &globalConstantsPatchableSegment, patchableInstructionSegments,
unresolvedExternals, device.get(), initGlobalConstantData, sizeof(initGlobalConstantData),
initGlobalVariablesData, sizeof(initGlobalVariablesData), kernelDescriptors, externalFunctions);
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
EXPECT_EQ(0U, unresolvedExternals.size());
auto globalConstantsSegmentAddr = reinterpret_cast<uint64_t *>(globalConstantsPatchableSegment.getUnderlyingBuffer());
auto globalVariableSegmentAddr = reinterpret_cast<uint64_t *>(globalVariablesPatchableSegment.getUnderlyingBuffer());
auto var1Addr = globalVariablesPatchableSegment.getGpuAddress();
auto const1Addr = globalConstantsPatchableSegment.getGpuAddress();
auto bssConstAddrr = globalConstantsPatchableSegment.getGpuAddress() + sizeof(initGlobalConstantData);
auto bssVarAddr = globalVariablesPatchableSegment.getGpuAddress() + sizeof(initGlobalVariablesData);
EXPECT_EQ(var1Addr, *(globalConstantsSegmentAddr + 1));
EXPECT_EQ(const1Addr, *(globalVariableSegmentAddr + 1));
EXPECT_EQ(bssConstAddrr, *(reinterpret_cast<uint64_t *>(instructionsData1.data())));
EXPECT_EQ(bssVarAddr, *(reinterpret_cast<uint64_t *>(instructionsData2.data())));
}
TEST(LinkerTests, givenInvalidSymbolWhenPatchingDataSegmentsThenRelocationIsUnresolved) {
uint64_t initGlobalConstantData[3] = {};
uint64_t initGlobalVariablesData[3] = {};
@@ -1785,7 +1929,10 @@ TEST(LinkerTests, givenInvalidRelocationSegmentWhenPatchingDataSegmentsThenReloc
NEO::Linker::UnresolvedExternals unresolvedExternals;
NEO::Linker::KernelDescriptorsT kernelDescriptors;
NEO::Linker::ExternalFunctionsT externalFunctions;
auto linkResult = linker.link({}, {}, {}, {},
NEO::Linker::SegmentInfo globalSegment;
globalSegment.segmentSize = 8u;
auto linkResult = linker.link(globalSegment, {}, {}, {},
nullptr, nullptr, {},
unresolvedExternals, device.get(), nullptr, 0, nullptr, 0, kernelDescriptors, externalFunctions);
EXPECT_EQ(NEO::LinkingStatus::LinkedPartially, linkResult);
@@ -2726,7 +2873,7 @@ TEST(LinkerTest, givenLocalFuncSymbolsWhenProcessingRelocationsThenLocalSymbolsA
emplacedOther.gpuAddress = 0x2000;
emplacedOther.kernelName = "other_kernel";
auto res = linker.processRelocations(gVariables, gConstants, expFuncs, gStrings, insSegments);
auto res = linker.processRelocations(gVariables, gConstants, expFuncs, gStrings, insSegments, 0u, 0u);
EXPECT_TRUE(res);
EXPECT_EQ(1u, linker.localRelocatedSymbols.size());
const auto &localRelocatedSymbolInfo = linker.localRelocatedSymbols.at(kernelName);

View File

@@ -152,6 +152,8 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, NEO::Elf::SectionsNamesZebin::gtpinInfo, std::string{});
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_VISA_ASM, NEO::Elf::SectionsNamesZebin::vIsaAsmPrefix.str() + "someKernel", std::string{});
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_MISC, NEO::Elf::SectionsNamesZebin::buildOptions, std::string{});
elfEncoder.appendSection(NEO::Elf::SHT_NOBITS, NEO::Elf::SectionsNamesZebin::dataConstZeroInit.str(), std::string{});
elfEncoder.appendSection(NEO::Elf::SHT_NOBITS, NEO::Elf::SectionsNamesZebin::dataGlobalZeroInit.str(), std::string{});
elfEncoder.appendSection(NEO::Elf::SHT_REL, NEO::Elf::SpecialSectionNames::relPrefix.str() + "someKernel", std::string{});
elfEncoder.appendSection(NEO::Elf::SHT_RELA, NEO::Elf::SpecialSectionNames::relaPrefix.str() + "someKernel", std::string{});
@@ -177,6 +179,8 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
ASSERT_EQ(1U, sections.symtabSections.size());
ASSERT_EQ(1U, sections.spirvSections.size());
ASSERT_EQ(1U, sections.buildOptionsSection.size());
ASSERT_EQ(1U, sections.constZeroInitDataSections.size());
ASSERT_EQ(1U, sections.globalZeroInitDataSections.size());
auto stringSection = decodedElf.sectionHeaders[decodedElf.elfFileHeader->shStrNdx];
const char *strings = stringSection.data.toArrayRef<const char>().begin();
@@ -188,6 +192,8 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::zeInfo.data(), strings + sections.zeInfoSections[0]->header->name);
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::symtab.data(), strings + sections.symtabSections[0]->header->name);
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::spv.data(), strings + sections.spirvSections[0]->header->name);
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataConstZeroInit.data(), strings + sections.constZeroInitDataSections[0]->header->name);
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataGlobalZeroInit.data(), strings + sections.globalZeroInitDataSections[0]->header->name);
}
TEST(ExtractZebinSections, GivenMispelledConstDataSectionThenAllowItButEmitError) {
@@ -236,6 +242,25 @@ TEST(ExtractZebinSections, GivenUnknownMiscSectionThenEmitWarning) {
EXPECT_STREQ(expectedWarning.c_str(), warnings.c_str());
}
TEST(ExtractZebinSections, GivenUnknownElfNobitsSectionThenEmitWarning) {
NEO::Elf::ElfEncoder<> elfEncoder;
ConstStringRef unknownNobitsSectionName = "unknown_bss_section";
elfEncoder.appendSection(NEO::Elf::SHT_NOBITS, unknownNobitsSectionName, std::string{});
auto encodedElf = elfEncoder.encode();
std::string elferrors;
std::string elfwarnings;
auto decodedElf = NEO::Elf::decodeElf(encodedElf, elferrors, elfwarnings);
NEO::ZebinSections sections;
std::string errors;
std::string warnings;
auto decodeError = NEO::extractZebinSections(decodedElf, sections, errors, warnings);
EXPECT_EQ(NEO::DecodeError::Success, decodeError);
EXPECT_TRUE(errors.empty()) << errors;
auto expectedWarning = "DeviceBinaryFormat::Zebin : unhandled SHT_NOBITS section : " + unknownNobitsSectionName.str() + " currently supports only : .bss.const and .bss.global.\n";
EXPECT_STREQ(expectedWarning.c_str(), warnings.c_str());
}
TEST(ValidateZebinSectionsCount, GivenEmptyZebinThenReturnSuccess) {
NEO::ZebinSections sections;
std::string errors;
@@ -328,6 +353,28 @@ TEST(ValidateZebinSectionsCount, GivenTwoIntelGTNoteSectionsThenFail) {
EXPECT_TRUE(warnings.empty()) << warnings;
}
TEST(ValidateZebinSectionsCount, GivenMoreThanOneConstZeroInitDataSectionThenFail) {
NEO::ZebinSections sections;
std::string errors;
std::string warnings;
sections.constZeroInitDataSections.resize(2);
auto err = NEO::validateZebinSectionsCount(sections, errors, warnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, err);
EXPECT_STREQ("DeviceBinaryFormat::Zebin : Expected at most 1 of .bss.const section, got : 2\n", errors.c_str());
EXPECT_TRUE(warnings.empty()) << warnings;
}
TEST(ValidateZebinSectionsCount, GivenMoreThanOneGlobalZeroInitDataSectionThenFail) {
NEO::ZebinSections sections;
std::string errors;
std::string warnings;
sections.globalZeroInitDataSections.resize(2);
auto err = NEO::validateZebinSectionsCount(sections, errors, warnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, err);
EXPECT_STREQ("DeviceBinaryFormat::Zebin : Expected at most 1 of .bss.global section, got : 2\n", errors.c_str());
EXPECT_TRUE(warnings.empty()) << warnings;
}
TEST(PopulateZeInfoVersion, GivenValidVersionFormatThenParsesItProperly) {
{
NEO::ConstStringRef yaml = R"===(---
@@ -2547,6 +2594,51 @@ TEST(DecodeSingleDeviceBinaryZebin, GivenConstDataSectionThenSetsUpInitDataAndSi
EXPECT_EQ(nullptr, programInfo.globalVariables.initData);
}
TEST(DecodeSingleDeviceBinaryZebin, GivenConstZeroInitDataSectionThenSetUpZeroInitSizeBasedOnHeaderData) {
NEO::MockExecutionEnvironment mockExecutionEnvironment{};
auto &gfxCoreHelper = mockExecutionEnvironment.rootDeviceEnvironments[0]->getHelper<NEO::GfxCoreHelper>();
ZebinTestData::ValidEmptyProgram zebin;
const uint8_t mockData[0x10]{0u}; // note that BSS section does not store any data in ELF
auto &bssConstHeader = zebin.appendSection(NEO::Elf::SHT_NOBITS, NEO::Elf::SectionsNamesZebin::dataConstZeroInit, mockData);
bssConstHeader.size = 16u;
NEO::ProgramInfo programInfo;
NEO::SingleDeviceBinary singleBinary;
singleBinary.deviceBinary = zebin.storage;
std::string errors;
std::string warnings;
auto error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(programInfo, singleBinary, errors, warnings, gfxCoreHelper);
EXPECT_EQ(NEO::DecodeError::Success, error);
EXPECT_TRUE(warnings.empty()) << warnings;
EXPECT_TRUE(errors.empty()) << errors;
EXPECT_EQ(16u, programInfo.globalConstants.zeroInitSize);
EXPECT_EQ(nullptr, programInfo.globalConstants.initData);
EXPECT_EQ(0u, programInfo.globalConstants.size);
}
TEST(DecodeSingleDeviceBinaryZebin, GivenGlobalZeroInitDataSectionThenSetUpZeroInitSizeBasedOnHeaderData) {
NEO::MockExecutionEnvironment mockExecutionEnvironment{};
auto &gfxCoreHelper = mockExecutionEnvironment.rootDeviceEnvironments[0]->getHelper<NEO::GfxCoreHelper>();
ZebinTestData::ValidEmptyProgram zebin;
const uint8_t mockData[0x10]{0u}; // note that BSS section does not store any data in ELF
auto &bssGlobalHeader = zebin.appendSection(NEO::Elf::SHT_NOBITS, NEO::Elf::SectionsNamesZebin::dataGlobalZeroInit, mockData);
bssGlobalHeader.size = 16u;
NEO::ProgramInfo programInfo;
NEO::SingleDeviceBinary singleBinary;
singleBinary.deviceBinary = zebin.storage;
std::string errors;
std::string warnings;
auto error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(programInfo, singleBinary, errors, warnings, gfxCoreHelper);
EXPECT_EQ(NEO::DecodeError::Success, error);
EXPECT_TRUE(warnings.empty()) << warnings;
EXPECT_TRUE(errors.empty()) << errors;
EXPECT_EQ(16u, programInfo.globalVariables.zeroInitSize);
EXPECT_EQ(nullptr, programInfo.globalVariables.initData);
EXPECT_EQ(0u, programInfo.globalVariables.size);
}
TEST(DecodeSingleDeviceBinaryZebin, GivenConstDataStringsSectionThenSetsUpInitDataAndSize) {
NEO::MockExecutionEnvironment mockExecutionEnvironment{};
auto &gfxCoreHelper = mockExecutionEnvironment.rootDeviceEnvironments[0]->getHelper<NEO::GfxCoreHelper>();

View File

@@ -1016,6 +1016,22 @@ TEST(MemoryManagerTest, givenDebugContextSaveAreaTypeWhenGetAllocationDataIsCall
EXPECT_TRUE(allocData.flags.zeroMemory);
}
TEST(MemoryManagerTest, givenAllocationTypeConstantOrGlobalSurfaceWhenGetAllocationDataIsCalledThenZeroMemoryFlagIsSet) {
MockMemoryManager mockMemoryManager;
AllocationProperties propertiesGlobal{mockRootDeviceIndex, 1, AllocationType::GLOBAL_SURFACE, mockDeviceBitfield};
AllocationProperties propertiesConstant{mockRootDeviceIndex, 1, AllocationType::CONSTANT_SURFACE, mockDeviceBitfield};
{
AllocationData allocData;
mockMemoryManager.getAllocationData(allocData, propertiesGlobal, nullptr, mockMemoryManager.createStorageInfoFromProperties(propertiesGlobal));
EXPECT_TRUE(allocData.flags.zeroMemory);
}
{
AllocationData allocData;
mockMemoryManager.getAllocationData(allocData, propertiesConstant, nullptr, mockMemoryManager.createStorageInfoFromProperties(propertiesConstant));
EXPECT_TRUE(allocData.flags.zeroMemory);
}
}
TEST(MemoryManagerTest, givenPropertiesWithOsContextWhenGetAllocationDataIsCalledThenOsContextIsSet) {
AllocationData allocData;
MockMemoryManager mockMemoryManager;

View File

@@ -31,7 +31,7 @@ TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreNotExportedTh
initData.resize(64, 7U);
GraphicsAllocation *alloc = nullptr;
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), true /* constant */, nullptr /* linker input */, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, true /* constant */, nullptr /* linker input */, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -39,7 +39,7 @@ TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreNotExportedTh
EXPECT_EQ(AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), false /* constant */, nullptr /* linker input */, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, false /* constant */, nullptr /* linker input */, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -47,7 +47,7 @@ TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreNotExportedTh
EXPECT_EQ(AllocationType::GLOBAL_SURFACE, alloc->getAllocationType());
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), true /* constant */, &emptyLinkerInput, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, true /* constant */, &emptyLinkerInput, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -55,7 +55,7 @@ TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreNotExportedTh
EXPECT_EQ(AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), false /* constant */, &emptyLinkerInput, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, false /* constant */, &emptyLinkerInput, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -77,7 +77,7 @@ TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreExportedThenM
initData.resize(64, 7U);
GraphicsAllocation *alloc = nullptr;
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), true /* constant */, &linkerInputExportGlobalConstants, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, true /* constant */, &linkerInputExportGlobalConstants, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(MemoryConstants::pageSize64k, alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -86,21 +86,21 @@ TEST(AllocateGlobalSurfaceTest, GivenSvmAllocsManagerWhenGlobalsAreExportedThenM
EXPECT_EQ(DEVICE_UNIFIED_MEMORY, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(alloc->getGpuAddress()))->memoryType);
svmAllocsManager.freeSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress())));
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), true /* constant */, &linkerInputExportGlobalVariables, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, true /* constant */, &linkerInputExportGlobalVariables, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), false /* constant */, &linkerInputExportGlobalConstants, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, false /* constant */, &linkerInputExportGlobalConstants, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(alloc->getGpuAddress()))));
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), false /* constant */, &linkerInputExportGlobalVariables, initData.data());
alloc = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, false /* constant */, &linkerInputExportGlobalVariables, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(MemoryConstants::pageSize64k, alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -120,28 +120,28 @@ TEST(AllocateGlobalSurfaceTest, GivenNullSvmAllocsManagerWhenGlobalsAreExportedT
initData.resize(64, 7U);
GraphicsAllocation *alloc = nullptr;
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), true /* constant */, &linkerInputExportGlobalConstants, initData.data());
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), 0u, true /* constant */, &linkerInputExportGlobalConstants, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
EXPECT_EQ(AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), true /* constant */, &linkerInputExportGlobalVariables, initData.data());
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), 0u, true /* constant */, &linkerInputExportGlobalVariables, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
EXPECT_EQ(AllocationType::CONSTANT_SURFACE, alloc->getAllocationType());
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), false /* constant */, &linkerInputExportGlobalConstants, initData.data());
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), 0u, false /* constant */, &linkerInputExportGlobalConstants, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
EXPECT_EQ(AllocationType::GLOBAL_SURFACE, alloc->getAllocationType());
device.getMemoryManager()->freeGraphicsMemory(alloc);
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), false /* constant */, &linkerInputExportGlobalVariables, initData.data());
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), 0u, false /* constant */, &linkerInputExportGlobalVariables, initData.data());
ASSERT_NE(nullptr, alloc);
ASSERT_EQ(initData.size(), alloc->getUnderlyingBufferSize());
EXPECT_EQ(0, memcmp(alloc->getUnderlyingBuffer(), initData.data(), initData.size()));
@@ -160,28 +160,28 @@ TEST(AllocateGlobalSurfaceTest, WhenGlobalsAreNotExportedAndAllocationFailsThenG
initData.resize(64, 7U);
GraphicsAllocation *alloc = nullptr;
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), true /* constant */, nullptr /* linker input */, initData.data());
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), 0u, true /* constant */, nullptr /* linker input */, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), false /* constant */, nullptr /* linker input */, initData.data());
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), 0u, false /* constant */, nullptr /* linker input */, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), true /* constant */, &emptyLinkerInput, initData.data());
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), 0u, true /* constant */, &emptyLinkerInput, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), false /* constant */, &emptyLinkerInput, initData.data());
alloc = allocateGlobalsSurface(&mockSvmAllocsManager, device, initData.size(), 0u, false /* constant */, &emptyLinkerInput, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), true /* constant */, nullptr /* linker input */, initData.data());
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), 0u, true /* constant */, nullptr /* linker input */, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), false /* constant */, nullptr /* linker input */, initData.data());
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), 0u, false /* constant */, nullptr /* linker input */, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), true /* constant */, &emptyLinkerInput, initData.data());
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), 0u, true /* constant */, &emptyLinkerInput, initData.data());
EXPECT_EQ(nullptr, alloc);
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), false /* constant */, &emptyLinkerInput, initData.data());
alloc = allocateGlobalsSurface(nullptr /* svmAllocsManager */, device, initData.size(), 0u, false /* constant */, &emptyLinkerInput, initData.data());
EXPECT_EQ(nullptr, alloc);
}
@@ -215,7 +215,7 @@ TEST(AllocateGlobalSurfaceTest, GivenAllocationInLocalMemoryWhichRequiresBlitter
device.getExecutionEnvironment()->rootDeviceEnvironments[0]->getMutableHardwareInfo()->capabilityTable.blitterOperationsSupported = true;
MockSVMAllocsManager svmAllocsManager(device.getMemoryManager(), false);
auto pAllocation = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), true /* constant */,
auto pAllocation = allocateGlobalsSurface(&svmAllocsManager, device, initData.size(), 0u, true /* constant */,
nullptr /* linker input */, initData.data());
ASSERT_NE(nullptr, pAllocation);
EXPECT_EQ(nullptr, svmAllocsManager.getSVMAlloc(reinterpret_cast<void *>(static_cast<uintptr_t>(pAllocation->getGpuAddress()))));
@@ -229,3 +229,38 @@ TEST(AllocateGlobalSurfaceTest, GivenAllocationInLocalMemoryWhichRequiresBlitter
}
}
}
TEST(AllocateGlobalSurfaceTest, whenAllocatingGlobalSurfaceWithNonZeroZeroInitSizeThenTransferOnlyInitDataToAllocation) {
MockDevice device{};
WhiteBox<LinkerInput> emptyLinkerInput;
emptyLinkerInput.traits.exportsGlobalConstants = true;
std::vector<uint8_t> initData;
initData.resize(64, 7u);
std::fill(initData.begin() + 32, initData.end(), 16u); // this data should not be transfered
GraphicsAllocation *alloc = nullptr;
size_t zeroInitSize = 32u;
alloc = allocateGlobalsSurface(nullptr, device, initData.size(), zeroInitSize, true, &emptyLinkerInput, initData.data());
ASSERT_NE(nullptr, alloc);
EXPECT_EQ(64u, alloc->getUnderlyingBufferSize());
auto dataPtr = reinterpret_cast<uint8_t *>(alloc->getUnderlyingBuffer());
EXPECT_EQ(0, memcmp(dataPtr, initData.data(), 32u));
EXPECT_NE(0, memcmp(dataPtr + 32, initData.data() + 32, 32u));
device.getMemoryManager()->freeGraphicsMemory(alloc);
}
TEST(AllocateGlobalSurfaceTest, whenAllocatingGlobalSurfaceWithZeroInitSizeGreaterThanZeroAndInitDataSizeSetToZeroThenDoNotTransferMemoryToAllocation) {
MockDevice device{};
auto memoryManager = std::make_unique<MockMemoryManager>(*device.getExecutionEnvironment());
device.injectMemoryManager(memoryManager.release());
ASSERT_EQ(0u, static_cast<MockMemoryManager *>(device.getMemoryManager())->copyMemoryToAllocationBanksCalled);
size_t totalSize = 64u, zeroInitSize = 64u;
GraphicsAllocation *alloc = nullptr;
alloc = allocateGlobalsSurface(nullptr, device, totalSize, zeroInitSize, true, nullptr, nullptr);
ASSERT_NE(nullptr, alloc);
EXPECT_EQ(0u, static_cast<MockMemoryManager *>(device.getMemoryManager())->copyMemoryToAllocationBanksCalled);
device.getMemoryManager()->freeGraphicsMemory(alloc);
}