mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 21:18:24 +08:00
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:
committed by
Compute-Runtime-Automation
parent
31154dc20b
commit
fa03aa9a40
@@ -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);
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user