From 6bb4112d1e6a8b3ceaf99c2d335e3f4732a6b385 Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Mon, 19 Oct 2020 10:02:28 +0200 Subject: [PATCH] Create heap helper for bindless Related-To: NEO-4724 Change-Id: I62527a3ad06dce5d886b6ecfebd3c9abc46f6741 Signed-off-by: Maciej Plewka --- .../core/test/unit_tests/CMakeLists.txt | 2 + .../unit_tests/sources/device/test_device.cpp | 14 +- .../unit_tests/sources/driver/test_driver.cpp | 16 +- shared/source/device/device.cpp | 1 + shared/source/device/root_device.cpp | 10 +- shared/source/device/root_device.h | 3 + shared/source/helpers/CMakeLists.txt | 2 + .../source/helpers/bindless_heaps_helper.cpp | 95 ++++++++++++ shared/source/helpers/bindless_heaps_helper.h | 52 +++++++ shared/test/unit_test/fixtures/CMakeLists.txt | 2 + .../fixtures/front_window_fixture.cpp | 27 ++++ .../unit_test/fixtures/front_window_fixture.h | 27 ++++ shared/test/unit_test/helpers/CMakeLists.txt | 1 + .../helpers/bindless_heaps_helper_tests.cpp | 145 ++++++++++++++++++ .../special_heap_pool_tests.cpp | 21 +-- shared/test/unit_test/mocks/mock_device.h | 1 + 16 files changed, 384 insertions(+), 35 deletions(-) create mode 100644 shared/source/helpers/bindless_heaps_helper.cpp create mode 100644 shared/source/helpers/bindless_heaps_helper.h create mode 100644 shared/test/unit_test/fixtures/front_window_fixture.cpp create mode 100644 shared/test/unit_test/fixtures/front_window_fixture.h create mode 100644 shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp diff --git a/level_zero/core/test/unit_tests/CMakeLists.txt b/level_zero/core/test/unit_tests/CMakeLists.txt index da566f27ba..b36d9e4026 100644 --- a/level_zero/core/test/unit_tests/CMakeLists.txt +++ b/level_zero/core/test/unit_tests/CMakeLists.txt @@ -26,6 +26,8 @@ add_executable(${TARGET_NAME} ${NEO_SOURCE_DIR}/shared/test/unit_test/helpers/memory_management.cpp ${NEO_SOURCE_DIR}/shared/test/unit_test/helpers/memory_leak_listener.h ${NEO_SOURCE_DIR}/shared/test/unit_test/helpers/memory_leak_listener.cpp + ${NEO_SOURCE_DIR}/shared/test/unit_test/mocks/ult_device_factory.cpp + ${NEO_SOURCE_DIR}/shared/test/unit_test/mocks/ult_device_factory.h ${L0_CORE_ENABLERS} ) diff --git a/level_zero/core/test/unit_tests/sources/device/test_device.cpp b/level_zero/core/test/unit_tests/sources/device/test_device.cpp index 38d33156d1..31f47fcad3 100644 --- a/level_zero/core/test/unit_tests/sources/device/test_device.cpp +++ b/level_zero/core/test/unit_tests/sources/device/test_device.cpp @@ -5,9 +5,12 @@ * */ +#include "shared/source/device/root_device.h" +#include "shared/source/helpers/bindless_heaps_helper.h" #include "shared/source/os_interface/hw_info_config.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" #include "shared/test/unit_test/mocks/mock_device.h" +#include "shared/test/unit_test/mocks/ult_device_factory.h" #include "test.h" @@ -377,13 +380,13 @@ struct MultipleDevicesTest : public ::testing::Test { executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(NEO::defaultHwInfo.get()); } + memoryManager = new ::testing::NiceMock(*executionEnvironment); + executionEnvironment->memoryManager.reset(memoryManager); + deviceFactory = std::make_unique(numRootDevices, numSubDevices, *executionEnvironment); + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { - devices.push_back(std::unique_ptr(NEO::MockDevice::createWithExecutionEnvironment(NEO::defaultHwInfo.get(), executionEnvironment, i))); + devices.push_back(std::unique_ptr(deviceFactory->rootDevices[i])); } - - memoryManager = new ::testing::NiceMock(*devices[0].get()->getExecutionEnvironment()); - devices[0].get()->getExecutionEnvironment()->memoryManager.reset(memoryManager); - driverHandle = std::make_unique>(); driverHandle->initialize(std::move(devices)); } @@ -391,6 +394,7 @@ struct MultipleDevicesTest : public ::testing::Test { DebugManagerStateRestore restorer; std::unique_ptr> driverHandle; MockMemoryManagerMultiDevice *memoryManager = nullptr; + std::unique_ptr deviceFactory; const uint32_t numRootDevices = 2u; const uint32_t numSubDevices = 2u; diff --git a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp index c738652354..0ecb046980 100644 --- a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp @@ -9,6 +9,7 @@ #include "shared/source/os_interface/device_factory.h" #include "shared/source/os_interface/hw_info_config.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" +#include "shared/test/unit_test/mocks/ult_device_factory.h" #include "opencl/test/unit_test/mocks/mock_io_functions.h" #include "test.h" @@ -241,26 +242,23 @@ struct DriverTestMultipleFamilySupport : public ::testing::Test { void SetUp() override { VariableBackup mockDeviceFlagBackup(&MockDevice::createSingleDevice, false); - NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment(); - executionEnvironment->prepareRootDeviceEnvironments(numRootDevices); - for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { - executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(NEO::defaultHwInfo.get()); - } - - for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { - devices.push_back(std::unique_ptr(NEO::MockDevice::createWithExecutionEnvironment(NEO::defaultHwInfo.get(), executionEnvironment, i))); + deviceFactory = std::make_unique(numRootDevices, numSubDevices); + for (auto i = 0u; i < numRootDevices; i++) { + devices.push_back(std::unique_ptr(deviceFactory->rootDevices[i])); if (i < numSupportedRootDevices) { devices[i]->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.levelZeroSupported = true; } else { + deviceFactory->rootDevices.erase(deviceFactory->rootDevices.begin() + i); devices[i]->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.levelZeroSupported = false; } } } - DebugManagerStateRestore restorer; std::vector> devices; + std::unique_ptr deviceFactory; const uint32_t numRootDevices = 3u; + const uint32_t numSubDevices = 2u; const uint32_t numSupportedRootDevices = 2u; }; diff --git a/shared/source/device/device.cpp b/shared/source/device/device.cpp index 8810a3efd1..6905bcdfa0 100644 --- a/shared/source/device/device.cpp +++ b/shared/source/device/device.cpp @@ -42,6 +42,7 @@ Device::~Device() { commandStreamReceivers.clear(); executionEnvironment->memoryManager->waitForDeletions(); + executionEnvironment->decRefInternal(); } diff --git a/shared/source/device/root_device.cpp b/shared/source/device/root_device.cpp index 5cbe68b08a..f2a1331b2b 100644 --- a/shared/source/device/root_device.cpp +++ b/shared/source/device/root_device.cpp @@ -11,6 +11,8 @@ #include "shared/source/command_stream/preemption.h" #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/device/sub_device.h" +#include "shared/source/helpers/api_specific_config.h" +#include "shared/source/helpers/bindless_heaps_helper.h" #include "shared/source/helpers/hw_helper.h" #include "shared/source/memory_manager/memory_manager.h" @@ -20,6 +22,7 @@ extern CommandStreamReceiver *createCommandStream(ExecutionEnvironment &executio RootDevice::RootDevice(ExecutionEnvironment *executionEnvironment, uint32_t rootDeviceIndex) : Device(executionEnvironment), rootDeviceIndex(rootDeviceIndex) {} RootDevice::~RootDevice() { + bindlessHeapHelper.reset(); for (auto subdevice : subdevices) { if (subdevice) { delete subdevice; @@ -31,6 +34,9 @@ uint32_t RootDevice::getNumSubDevices() const { return static_cast(subdevices.size()); } +BindlessHeapsHelper *RootDevice::getBindlessHeapsHelper() const { + return bindlessHeapHelper.get(); +} uint32_t RootDevice::getRootDeviceIndex() const { return rootDeviceIndex; } @@ -77,7 +83,9 @@ bool RootDevice::createDeviceImpl() { if (!status) { return status; } - + if (ApiSpecificConfig::getBindlessConfiguration()) { + bindlessHeapHelper = std::make_unique(getMemoryManager(), getNumAvailableDevices() > 1, rootDeviceIndex); + } return true; } DeviceBitfield RootDevice::getDeviceBitfield() const { diff --git a/shared/source/device/root_device.h b/shared/source/device/root_device.h index 58066ec72e..e7beb7361b 100644 --- a/shared/source/device/root_device.h +++ b/shared/source/device/root_device.h @@ -11,6 +11,7 @@ namespace NEO { class SubDevice; +class BindlessHeapsHelper; class RootDevice : public Device { public: @@ -22,6 +23,7 @@ class RootDevice : public Device { Device *getDeviceById(uint32_t deviceId) const override; Device *getParentDevice() const override; uint32_t getNumSubDevices() const; + BindlessHeapsHelper *getBindlessHeapsHelper() const; protected: DeviceBitfield getDeviceBitfield() const override; @@ -32,5 +34,6 @@ class RootDevice : public Device { std::vector subdevices; const uint32_t rootDeviceIndex; + std::unique_ptr bindlessHeapHelper; }; } // namespace NEO diff --git a/shared/source/helpers/CMakeLists.txt b/shared/source/helpers/CMakeLists.txt index 8b4426bc3d..0e2a2c19f7 100644 --- a/shared/source/helpers/CMakeLists.txt +++ b/shared/source/helpers/CMakeLists.txt @@ -13,6 +13,8 @@ set(NEO_CORE_HELPERS ${CMAKE_CURRENT_SOURCE_DIR}/array_count.h ${CMAKE_CURRENT_SOURCE_DIR}/aux_translation.h ${CMAKE_CURRENT_SOURCE_DIR}/basic_math.h + ${CMAKE_CURRENT_SOURCE_DIR}/bindless_heaps_helper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/bindless_heaps_helper.h ${CMAKE_CURRENT_SOURCE_DIR}/bit_helpers.h ${CMAKE_CURRENT_SOURCE_DIR}/blit_commands_helper_base.inl ${CMAKE_CURRENT_SOURCE_DIR}/blit_commands_helper_bdw_plus.inl diff --git a/shared/source/helpers/bindless_heaps_helper.cpp b/shared/source/helpers/bindless_heaps_helper.cpp new file mode 100644 index 0000000000..2caeeaac2e --- /dev/null +++ b/shared/source/helpers/bindless_heaps_helper.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/bindless_heaps_helper.h" + +#include "shared/source/helpers/string.h" +#include "shared/source/indirect_heap/indirect_heap.h" +#include "shared/source/memory_manager/memory_manager.h" + +namespace NEO { + +constexpr size_t globalSshAllocationSize = 4 * MemoryConstants::pageSize64k; + +BindlessHeapsHelper::BindlessHeapsHelper(MemoryManager *memManager, bool isMultiOsContextCapable, const uint32_t rootDeviceIndex) : memManager(memManager), isMultiOsContextCapable(isMultiOsContextCapable), rootDeviceIndex(rootDeviceIndex) { + auto specialHeapAllocation = getHeapAllocation(MemoryConstants::pageSize64k, MemoryConstants::pageSize64k); + UNRECOVERABLE_IF(specialHeapAllocation == nullptr); + ssHeapsAllocations.push_back(specialHeapAllocation); + specialSsh = std::make_unique(specialHeapAllocation, false); + + auto globalSshAllocation = getHeapAllocation(globalSshAllocationSize, MemoryConstants::pageSize64k); + UNRECOVERABLE_IF(globalSshAllocation == nullptr); + ssHeapsAllocations.push_back(globalSshAllocation); + globalSsh = std::make_unique(globalSshAllocation, false); + + borderColorStates = getHeapAllocation(MemoryConstants::pageSize, MemoryConstants::pageSize); + UNRECOVERABLE_IF(borderColorStates == nullptr); + float borderColorDefault[4] = {0, 0, 0, 0}; + memcpy_s(borderColorStates->getUnderlyingBuffer(), sizeof(borderColorDefault), borderColorDefault, sizeof(borderColorDefault)); + float borderColorAlpha[4] = {0, 0, 0, 1.0}; + memcpy_s(ptrOffset(borderColorStates->getUnderlyingBuffer(), sizeof(borderColorDefault)), sizeof(borderColorAlpha), borderColorAlpha, sizeof(borderColorAlpha)); +} + +BindlessHeapsHelper::~BindlessHeapsHelper() { + for (auto *allocation : ssHeapsAllocations) { + memManager->freeGraphicsMemory(allocation); + } + memManager->freeGraphicsMemory(borderColorStates); + ssHeapsAllocations.clear(); +} + +GraphicsAllocation *BindlessHeapsHelper::getHeapAllocation(size_t heapSize, size_t alignment) { + auto allocationType = GraphicsAllocation::AllocationType::LINEAR_STREAM; + NEO::AllocationProperties properties{rootDeviceIndex, true, heapSize, allocationType, isMultiOsContextCapable, false}; + properties.flags.use32BitFrontWindow = true; + properties.alignment = alignment; + + return this->memManager->allocateGraphicsMemoryWithProperties(properties); +} + +SurfaceStateInHeapInfo *BindlessHeapsHelper::allocateSSInHeap(size_t ssSize, void *ssPtr, GraphicsAllocation *surfaceAllocation) { + auto ssAllocatedInfo = surfaceStateInHeapAllocationMap.find(surfaceAllocation); + if (ssAllocatedInfo != surfaceStateInHeapAllocationMap.end()) { + return ssAllocatedInfo->second.get(); + } + void *ptrInHeap = getSpaceInSsh(ssSize); + memcpy_s(ptrInHeap, ssSize, ssPtr, ssSize); + auto bindlessOffset = globalSsh->getGraphicsAllocation()->getGpuAddress() - globalSsh->getGraphicsAllocation()->getGpuBaseAddress() + globalSsh->getUsed() - ssSize; + std::pair> pair(surfaceAllocation, std::make_unique(SurfaceStateInHeapInfo{globalSsh->getGraphicsAllocation(), bindlessOffset})); + auto bindlesInfo = pair.second.get(); + surfaceStateInHeapAllocationMap.insert(std::move(pair)); + return bindlesInfo; +} + +void *BindlessHeapsHelper::getSpaceInSsh(size_t ssSize) { + if (globalSsh->getAvailableSpace() < ssSize) { + growGlobalSSh(); + } + return globalSsh->getSpace(ssSize); +} + +uint64_t BindlessHeapsHelper::getGlobalSshBase() { + return globalSsh->getGraphicsAllocation()->getGpuBaseAddress(); +} + +uint32_t BindlessHeapsHelper::getDefaultBorderColorOffset() { + return static_cast(borderColorStates->getGpuAddress() - borderColorStates->getGpuBaseAddress()); +} +uint32_t BindlessHeapsHelper::getAlphaBorderColorOffset() { + return getDefaultBorderColorOffset() + 4 * sizeof(float); +} + +void BindlessHeapsHelper::growGlobalSSh() { + auto newAlloc = getHeapAllocation(globalSshAllocationSize, MemoryConstants::pageSize64k); + UNRECOVERABLE_IF(newAlloc == nullptr); + ssHeapsAllocations.push_back(newAlloc); + globalSsh->replaceGraphicsAllocation(newAlloc); + globalSsh->replaceBuffer(newAlloc->getUnderlyingBuffer(), + newAlloc->getUnderlyingBufferSize()); +} + +} // namespace NEO \ No newline at end of file diff --git a/shared/source/helpers/bindless_heaps_helper.h b/shared/source/helpers/bindless_heaps_helper.h new file mode 100644 index 0000000000..d110161c79 --- /dev/null +++ b/shared/source/helpers/bindless_heaps_helper.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/constants.h" +#include "shared/source/helpers/heap_helper.h" +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include +#include +#include + +namespace NEO { + +constexpr size_t ssAligment = MemoryConstants::cacheLineSize; + +class IndirectHeap; +class GraphicsAllocation; + +struct SurfaceStateInHeapInfo { + GraphicsAllocation *heapAllocation; + uint64_t surfaceStateOffset; +}; + +class BindlessHeapsHelper { + public: + BindlessHeapsHelper(MemoryManager *memManager, bool isMultiOsContextCapable, const uint32_t rootDeviceIndex); + ~BindlessHeapsHelper(); + GraphicsAllocation *getHeapAllocation(size_t heapSize, size_t alignment); + + SurfaceStateInHeapInfo *allocateSSInHeap(size_t ssSize, void *ssPtr, GraphicsAllocation *surfaceAllocation); + uint64_t getGlobalSshBase(); + void *getSpaceInSsh(size_t ssSize); + uint32_t getDefaultBorderColorOffset(); + uint32_t getAlphaBorderColorOffset(); + + protected: + void growGlobalSSh(); + MemoryManager *memManager = nullptr; + bool isMultiOsContextCapable = false; + const uint32_t rootDeviceIndex; + std::unique_ptr specialSsh; + std::unique_ptr globalSsh; + GraphicsAllocation *borderColorStates; + std::vector ssHeapsAllocations; + std::unordered_map> surfaceStateInHeapAllocationMap; +}; +} // namespace NEO \ No newline at end of file diff --git a/shared/test/unit_test/fixtures/CMakeLists.txt b/shared/test/unit_test/fixtures/CMakeLists.txt index 6358d3e54f..a34bfb069b 100644 --- a/shared/test/unit_test/fixtures/CMakeLists.txt +++ b/shared/test/unit_test/fixtures/CMakeLists.txt @@ -10,6 +10,8 @@ target_sources(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/device_fixture.cpp ${CMAKE_CURRENT_SOURCE_DIR}/device_fixture.h ${CMAKE_CURRENT_SOURCE_DIR}/direct_submission_fixture.h + ${CMAKE_CURRENT_SOURCE_DIR}/front_window_fixture.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/front_window_fixture.h ${CMAKE_CURRENT_SOURCE_DIR}/preemption_fixture.cpp ${CMAKE_CURRENT_SOURCE_DIR}/preemption_fixture.h ) diff --git a/shared/test/unit_test/fixtures/front_window_fixture.cpp b/shared/test/unit_test/fixtures/front_window_fixture.cpp new file mode 100644 index 0000000000..45f8dedae6 --- /dev/null +++ b/shared/test/unit_test/fixtures/front_window_fixture.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/unit_test/fixtures/front_window_fixture.h" + +#include "shared/source/gmm_helper/gmm_helper.h" +#include "shared/test/unit_test/helpers/debug_manager_state_restore.h" + +#include "test.h" + +using namespace NEO; + +MemManagerFixture::FrontWindowMemManagerMock::FrontWindowMemManagerMock(NEO::ExecutionEnvironment &executionEnvironment) : MockMemoryManager(executionEnvironment) {} +void MemManagerFixture::FrontWindowMemManagerMock::forceLimitedRangeAllocator(uint32_t rootDeviceIndex, uint64_t range) { getGfxPartition(rootDeviceIndex)->init(range, 0, 0, gfxPartitions.size(), true); } +void MemManagerFixture::SetUp() { + DebugManagerStateRestore dbgRestorer; + DebugManager.flags.UseExternalAllocatorForSshAndDsh.set(true); + DeviceFixture::SetUp(); + memManager = std::unique_ptr(new FrontWindowMemManagerMock(*pDevice->getExecutionEnvironment())); +} +void MemManagerFixture::TearDown() { + DeviceFixture::TearDown(); +} \ No newline at end of file diff --git a/shared/test/unit_test/fixtures/front_window_fixture.h b/shared/test/unit_test/fixtures/front_window_fixture.h new file mode 100644 index 0000000000..8e2f063588 --- /dev/null +++ b/shared/test/unit_test/fixtures/front_window_fixture.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/unit_test/fixtures/device_fixture.h" + +#include "opencl/test/unit_test/mocks/mock_memory_manager.h" +#include "test.h" + +namespace NEO { + +class MemManagerFixture : public DeviceFixture { + public: + struct FrontWindowMemManagerMock : public MockMemoryManager { + FrontWindowMemManagerMock(NEO::ExecutionEnvironment &executionEnvironment); + void forceLimitedRangeAllocator(uint32_t rootDeviceIndex, uint64_t range); + }; + + void SetUp(); + void TearDown(); + + std::unique_ptr memManager; +}; +} // namespace NEO \ No newline at end of file diff --git a/shared/test/unit_test/helpers/CMakeLists.txt b/shared/test/unit_test/helpers/CMakeLists.txt index 19cab378a3..d648bb0422 100644 --- a/shared/test/unit_test/helpers/CMakeLists.txt +++ b/shared/test/unit_test/helpers/CMakeLists.txt @@ -6,6 +6,7 @@ set(NEO_CORE_HELPERS_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/bindless_heaps_helper_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/blit_commands_helper_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/blit_commands_helper_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/blit_commands_helper_tests_gen12lp.cpp diff --git a/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp b/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp new file mode 100644 index 0000000000..95656e6ac7 --- /dev/null +++ b/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2017-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/bindless_heaps_helper.h" +#include "shared/test/unit_test/fixtures/front_window_fixture.h" +#include "shared/test/unit_test/helpers/debug_manager_state_restore.h" +#include "shared/test/unit_test/mocks/mock_device.h" +#include "shared/test/unit_test/mocks/ult_device_factory.h" + +#include "opencl/test/unit_test/mocks/mock_graphics_allocation.h" +#include "test.h" + +using namespace NEO; + +class MockBindlesHeapsHelper : public BindlessHeapsHelper { + public: + using BaseClass = BindlessHeapsHelper; + MockBindlesHeapsHelper(MemoryManager *memManager, bool isMultiOsContextCapable, const uint32_t rootDeviceIndex) : BaseClass(memManager, isMultiOsContextCapable, rootDeviceIndex) {} + using BaseClass::borderColorStates; + using BaseClass::globalSsh; + using BaseClass::growGlobalSSh; + using BaseClass::isMultiOsContextCapable; + using BaseClass::memManager; + using BaseClass::rootDeviceIndex; + using BaseClass::specialSsh; + using BaseClass::ssHeapsAllocations; + using BaseClass::surfaceStateInHeapAllocationMap; +}; + +TEST(BindlessHeapsHelper, givenBindlessModeFlagEnabledWhenCreatingRootDevicesThenBindlesHeapHelperCreated) { + DebugManagerStateRestore dbgRestorer; + DebugManager.flags.UseBindlessMode.set(1); + std::unique_ptr deviceFactory(new UltDeviceFactory(1, 1)); + EXPECT_NE(deviceFactory->rootDevices[0]->getBindlessHeapsHelper(), nullptr); +} + +TEST(BindlessHeapsHelper, givenBindlessModeFlagDisabledWhenCreatingRootDevicesThenBindlesHeapHelperCreated) { + DebugManagerStateRestore dbgRestorer; + DebugManager.flags.UseBindlessMode.set(0); + std::unique_ptr deviceFactory(new UltDeviceFactory(1, 1)); + EXPECT_EQ(deviceFactory->rootDevices[0]->getBindlessHeapsHelper(), nullptr); +} + +using BindlessHeapsHelperTests = Test; + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenItsCreatedThenSpecialSshAllocatedAtHeapBegining) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + auto specialSshAllocation = bindlessHeapHelper->specialSsh->getGraphicsAllocation(); + EXPECT_EQ(specialSshAllocation->getGpuAddress(), specialSshAllocation->getGpuBaseAddress()); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenAllocatSsInHeapThenHeapUsedSpaceGrow) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + auto usedBefore = bindlessHeapHelper->globalSsh->getUsed(); + + MockGraphicsAllocation alloc; + size_t size = 0x40; + auto ss = std::make_unique(size); + memset(ss.get(), 35, size); + bindlessHeapHelper->allocateSSInHeap(size, ss.get(), &alloc); + auto usedAfter = bindlessHeapHelper->globalSsh->getUsed(); + EXPECT_GT(usedAfter, usedBefore); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenAllocateSsInHeapThenMemoryAtReturnedOffsetIsCorrect) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + + MockGraphicsAllocation alloc; + size_t size = 0x40; + auto ss = std::make_unique(size); + memset(ss.get(), 35, size); + bindlessHeapHelper->allocateSSInHeap(size, ss.get(), &alloc); + + auto allocInHeapPtr = bindlessHeapHelper->globalSsh->getGraphicsAllocation()->getUnderlyingBuffer(); + EXPECT_EQ(memcmp(ss.get(), allocInHeapPtr, size), 0); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenAllocateSsInHeapTwiceForTheSameAllocationThenTheSameOffsetReturned) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + + MockGraphicsAllocation alloc; + size_t size = 0x40; + auto ss = std::make_unique(size); + memset(ss.get(), 35, size); + auto ssInHeapInfo1 = bindlessHeapHelper->allocateSSInHeap(size, ss.get(), &alloc); + auto ssInHeapInfo2 = bindlessHeapHelper->allocateSSInHeap(size, ss.get(), &alloc); + + EXPECT_EQ(ssInHeapInfo1->surfaceStateOffset, ssInHeapInfo2->surfaceStateOffset); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenAllocateSsInHeapTwiceForDifferentAllocationThenDifferentOffsetsReturned) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + + MockGraphicsAllocation alloc1; + MockGraphicsAllocation alloc2; + size_t size = 0x40; + auto ss = std::make_unique(size); + memset(ss.get(), 35, size); + auto ssInHeapInfo1 = bindlessHeapHelper->allocateSSInHeap(size, ss.get(), &alloc1); + auto ssInHeapInfo2 = bindlessHeapHelper->allocateSSInHeap(size, ss.get(), &alloc2); + + EXPECT_NE(ssInHeapInfo1->surfaceStateOffset, ssInHeapInfo2->surfaceStateOffset); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenAllocateMoreSsThanNewHeapAllocationCreated) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + size_t ssSize = 0x40; + auto ssCount = bindlessHeapHelper->globalSsh->getAvailableSpace() / ssSize; + auto graphicsAllocations = std::make_unique(ssCount); + auto ssAllocationBefore = bindlessHeapHelper->globalSsh->getGraphicsAllocation(); + auto ss = std::make_unique(ssSize); + memset(ss.get(), 35, ssSize); + for (uint32_t i = 0; i < ssCount; i++) { + bindlessHeapHelper->allocateSSInHeap(ssSize, ss.get(), &graphicsAllocations[i]); + } + MockGraphicsAllocation alloc; + bindlessHeapHelper->allocateSSInHeap(ssSize, ss.get(), &alloc); + + auto ssAllocationAfter = bindlessHeapHelper->globalSsh->getGraphicsAllocation(); + + EXPECT_NE(ssAllocationBefore, ssAllocationAfter); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenCreatedThenAllocationsHaveTheSameBaseAddress) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + for (auto allocation : bindlessHeapHelper->ssHeapsAllocations) { + EXPECT_EQ(allocation->getGpuBaseAddress(), bindlessHeapHelper->getGlobalSshBase()); + } +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenGetDefaultBorderColorOffsetCalledThenCorrectOffsetReturned) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + auto expectedOffset = bindlessHeapHelper->borderColorStates->getGpuAddress() - bindlessHeapHelper->borderColorStates->getGpuBaseAddress(); + EXPECT_EQ(bindlessHeapHelper->getDefaultBorderColorOffset(), expectedOffset); +} + +TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenGetAlphaBorderColorOffsetCalledThenCorrectOffsetReturned) { + auto bindlessHeapHelper = std::make_unique(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); + auto expectedOffset = bindlessHeapHelper->borderColorStates->getGpuAddress() - bindlessHeapHelper->borderColorStates->getGpuBaseAddress() + 4 * sizeof(float); + EXPECT_EQ(bindlessHeapHelper->getAlphaBorderColorOffset(), expectedOffset); +} \ No newline at end of file diff --git a/shared/test/unit_test/memory_manager/special_heap_pool_tests.cpp b/shared/test/unit_test/memory_manager/special_heap_pool_tests.cpp index 20f8d35f57..5f564b92e1 100644 --- a/shared/test/unit_test/memory_manager/special_heap_pool_tests.cpp +++ b/shared/test/unit_test/memory_manager/special_heap_pool_tests.cpp @@ -6,7 +6,7 @@ */ #include "shared/source/gmm_helper/gmm_helper.h" -#include "shared/test/unit_test/fixtures/device_fixture.h" +#include "shared/test/unit_test/fixtures/front_window_fixture.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" #include "opencl/test/unit_test/mocks/mock_memory_manager.h" @@ -14,25 +14,6 @@ namespace NEO { -class MemManagerFixture : public DeviceFixture { - public: - struct FrontWindowMemManagerMock : public MockMemoryManager { - FrontWindowMemManagerMock(NEO::ExecutionEnvironment &executionEnvironment) : MockMemoryManager(executionEnvironment) {} - void forceLimitedRangeAllocator(uint32_t rootDeviceIndex, uint64_t range) { getGfxPartition(rootDeviceIndex)->init(range, 0, 0, gfxPartitions.size(), true); } - }; - - void SetUp() { - DebugManagerStateRestore dbgRestorer; - DebugManager.flags.UseExternalAllocatorForSshAndDsh.set(true); - DeviceFixture::SetUp(); - memManager = std::unique_ptr(new FrontWindowMemManagerMock(*pDevice->getExecutionEnvironment())); - } - void TearDown() { - DeviceFixture::TearDown(); - } - std::unique_ptr memManager; -}; - using FrontWindowAllocatorTests = Test; TEST_F(FrontWindowAllocatorTests, givenAllocateInFrontWindowPoolFlagWhenAllocate32BitGraphicsMemoryThenAllocateAtHeapBegining) { diff --git a/shared/test/unit_test/mocks/mock_device.h b/shared/test/unit_test/mocks/mock_device.h index 60d596e2cb..3814a70360 100644 --- a/shared/test/unit_test/mocks/mock_device.h +++ b/shared/test/unit_test/mocks/mock_device.h @@ -46,6 +46,7 @@ class MockDevice : public RootDevice { using Device::executionEnvironment; using Device::getGlobalMemorySize; using Device::initializeCaps; + using RootDevice::bindlessHeapHelper; using RootDevice::createEngines; using RootDevice::defaultEngineIndex; using RootDevice::getDeviceBitfield;