From b048d0e557eaf9a65e279a53687f5832a627619d Mon Sep 17 00:00:00 2001 From: Kamil Kopryk Date: Wed, 7 May 2025 11:07:21 +0000 Subject: [PATCH] fix: set correct bindless offsets for L0 bindless images extension with heapless Additionally reorder members in bindless heaps helper. Related-To: NEO-14710 Signed-off-by: Kamil Kopryk --- level_zero/core/source/image/image_imp.cpp | 6 ++- .../source/helpers/bindless_heaps_helper.cpp | 13 ++++-- shared/source/helpers/bindless_heaps_helper.h | 46 +++++++++---------- .../common/mocks/mock_bindless_heaps_helper.h | 3 +- .../helpers/bindless_heaps_helper_tests.cpp | 36 +++++++++++++-- 5 files changed, 71 insertions(+), 33 deletions(-) diff --git a/level_zero/core/source/image/image_imp.cpp b/level_zero/core/source/image/image_imp.cpp index 6eba9e8b51..5ce78ac178 100644 --- a/level_zero/core/source/image/image_imp.cpp +++ b/level_zero/core/source/image/image_imp.cpp @@ -256,8 +256,10 @@ ze_result_t ImageImp::getDeviceOffset(uint64_t *deviceOffset) { return ZE_RESULT_ERROR_NOT_AVAILABLE; } - DEBUG_BREAK_IF(this->getBindlessSlot() == nullptr); - *deviceOffset = this->getBindlessSlot()->surfaceStateOffset; + auto bindlessSlot = this->getBindlessSlot(); + + DEBUG_BREAK_IF(bindlessSlot == nullptr); + *deviceOffset = bindlessSlot->surfaceStateOffset; return ZE_RESULT_SUCCESS; } diff --git a/shared/source/helpers/bindless_heaps_helper.cpp b/shared/source/helpers/bindless_heaps_helper.cpp index 5f61d32ded..cdd6bd6b35 100644 --- a/shared/source/helpers/bindless_heaps_helper.cpp +++ b/shared/source/helpers/bindless_heaps_helper.cpp @@ -11,6 +11,7 @@ #include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/root_device_environment.h" #include "shared/source/gmm_helper/gmm_helper.h" +#include "shared/source/helpers/compiler_product_helper.h" #include "shared/source/helpers/driver_model_type.h" #include "shared/source/helpers/gfx_core_helper.h" #include "shared/source/helpers/string.h" @@ -49,11 +50,11 @@ constexpr size_t heapRegularSize = reservedRangeSize - heapFrontWindowSize; using BindlesHeapType = BindlessHeapsHelper::BindlesHeapType; BindlessHeapsHelper::BindlessHeapsHelper(Device *rootDevice, bool isMultiOsContextCapable) : rootDevice(rootDevice), - surfaceStateSize(rootDevice->getRootDeviceEnvironment().getHelper().getRenderSurfaceStateSize()), + deviceBitfield(rootDevice->getDeviceBitfield()), memManager(rootDevice->getMemoryManager()), - isMultiOsContextCapable(isMultiOsContextCapable), + surfaceStateSize(rootDevice->getRootDeviceEnvironment().getHelper().getRenderSurfaceStateSize()), rootDeviceIndex(rootDevice->getRootDeviceIndex()), - deviceBitfield(rootDevice->getDeviceBitfield()) { + isMultiOsContextCapable(isMultiOsContextCapable) { for (auto heapType = 0; heapType < BindlesHeapType::numHeapTypes; heapType++) { auto size = MemoryConstants::pageSize64k; @@ -77,6 +78,9 @@ BindlessHeapsHelper::BindlessHeapsHelper(Device *rootDevice, bool isMultiOsConte memcpy_s(borderColorStates->getUnderlyingBuffer(), sizeof(borderColorDefault), borderColorDefault, sizeof(borderColorDefault)); float borderColorAlpha[4] = {0, 0, 0, 1.0}; memcpy_s(ptrOffset(borderColorStates->getUnderlyingBuffer(), borderColorAlphaOffset), sizeof(borderColorAlpha), borderColorAlpha, sizeof(borderColorDefault)); + + auto &hwInfo = *rootDevice->getRootDeviceEnvironment().getHardwareInfo(); + this->heaplessEnabled = rootDevice->getRootDeviceEnvironment().getHelper().isHeaplessModeEnabled(hwInfo); } std::optional BindlessHeapsHelper::reserveMemoryRange(size_t size, size_t alignment, HeapIndex heapIndex) { @@ -235,6 +239,9 @@ SurfaceStateInHeapInfo BindlessHeapsHelper::allocateSSInHeap(size_t ssSize, Grap memset(ptrInHeap, 0, ssSize); auto bindlessOffset = heap->getGraphicsAllocation()->getGpuAddress() - heap->getGraphicsAllocation()->getGpuBaseAddress() + heap->getUsed() - ssSize; + if (this->heaplessEnabled) { + bindlessOffset += heap->getGraphicsAllocation()->getGpuBaseAddress(); + } bindlesInfo = SurfaceStateInHeapInfo{heap->getGraphicsAllocation(), bindlessOffset, ptrInHeap, ssSize}; } diff --git a/shared/source/helpers/bindless_heaps_helper.h b/shared/source/helpers/bindless_heaps_helper.h index 99b604ec39..51e90569b8 100644 --- a/shared/source/helpers/bindless_heaps_helper.h +++ b/shared/source/helpers/bindless_heaps_helper.h @@ -74,37 +74,35 @@ class BindlessHeapsHelper : NEO::NonCopyableAndNonMovableClass { std::optional reserveMemoryRange(size_t size, size_t alignment, HeapIndex heapIndex); bool initializeReservedMemory(); bool isReservedMemoryModeAvailable(); - - protected: - Device *rootDevice = nullptr; - const size_t surfaceStateSize; bool growHeap(BindlesHeapType heapType); - MemoryManager *memManager = nullptr; - bool isMultiOsContextCapable = false; - const uint32_t rootDeviceIndex; - std::unique_ptr surfaceStateHeaps[BindlesHeapType::numHeapTypes]; - GraphicsAllocation *borderColorStates; - std::vector ssHeapsAllocations; - size_t reuseSlotCountThreshold = 512; - uint32_t allocatePoolIndex = 0; - uint32_t releasePoolIndex = 0; - bool allocateFromReusePool = false; + Device *rootDevice = nullptr; + DeviceBitfield deviceBitfield; + GraphicsAllocation *borderColorStates; + MemoryManager *memManager = nullptr; std::array, 2> surfaceStateInHeapVectorReuse[2]; std::bitset<64> stateCacheDirtyForContext; - - std::mutex mtx; - DeviceBitfield deviceBitfield; - bool globalBindlessDsh = false; - - bool useReservedMemory = false; - bool reservedMemoryInitialized = false; - uint64_t reservedRangeBase = 0; - std::unique_ptr heapFrontWindow; std::unique_ptr heapRegular; - + std::unique_ptr surfaceStateHeaps[BindlesHeapType::numHeapTypes]; std::vector reservedRanges; + std::vector ssHeapsAllocations; + + const size_t surfaceStateSize; + size_t reuseSlotCountThreshold = 512; + const uint32_t rootDeviceIndex; + uint32_t allocatePoolIndex = 0; + uint32_t releasePoolIndex = 0; + uint64_t reservedRangeBase = 0; + + std::mutex mtx; + + bool allocateFromReusePool = false; + bool globalBindlessDsh = false; + bool heaplessEnabled = false; + bool isMultiOsContextCapable = false; + bool reservedMemoryInitialized = false; + bool useReservedMemory = false; }; static_assert(NEO::NonCopyableAndNonMovable); diff --git a/shared/test/common/mocks/mock_bindless_heaps_helper.h b/shared/test/common/mocks/mock_bindless_heaps_helper.h index 56bdfcf6ea..8028159bf4 100644 --- a/shared/test/common/mocks/mock_bindless_heaps_helper.h +++ b/shared/test/common/mocks/mock_bindless_heaps_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Intel Corporation + * Copyright (C) 2021-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -36,6 +36,7 @@ class MockBindlesHeapsHelper : public BindlessHeapsHelper { using BaseClass::globalBindlessDsh; using BaseClass::growHeap; using BaseClass::heapFrontWindow; + using BaseClass::heaplessEnabled; using BaseClass::heapRegular; using BaseClass::initializeReservedMemory; using BaseClass::isMultiOsContextCapable; diff --git a/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp b/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp index d058dbce0c..5e2ec8106a 100644 --- a/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp +++ b/shared/test/unit_test/helpers/bindless_heaps_helper_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2024 Intel Corporation + * Copyright (C) 2020-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -216,23 +216,49 @@ TEST_F(BindlessHeapsHelperTests, givenBindlessHeapHelperWhenGetAlphaBorderColorO } TEST_F(BindlessHeapsHelperTests, givenBindlessHeapHelperWhenAllocateSsInSpecialHeapThenFirstSlotIsAtOffsetZero) { + auto bindlessHeapHelper = std::make_unique(getDevice(), false); + if (bindlessHeapHelper->heaplessEnabled) { + GTEST_SKIP(); + } + MockGraphicsAllocation alloc; size_t size = 0x40; auto ssInHeapInfo = bindlessHeapHelper->allocateSSInHeap(size, &alloc, BindlessHeapsHelper::BindlesHeapType::specialSsh); EXPECT_EQ(0u, ssInHeapInfo.surfaceStateOffset); + + EXPECT_EQ(ssInHeapInfo.heapAllocation->getGpuAddress(), ssInHeapInfo.heapAllocation->getGpuBaseAddress()); + EXPECT_EQ(bindlessHeapHelper->getGlobalHeapsBase(), ssInHeapInfo.heapAllocation->getGpuBaseAddress()); +} + +TEST_F(BindlessHeapsHelperTests, givenHeaplessAndBindlessHeapHelperWhenAllocateSsInSpecialHeapThenFirstSlotIsAtOffsetOfHeapBaseAddress) { + + auto bindlessHeapHelper = std::make_unique(getDevice(), false); + if (!bindlessHeapHelper->heaplessEnabled) { + GTEST_SKIP(); + } + MockGraphicsAllocation alloc; + size_t size = 0x40; + auto ssInHeapInfo = bindlessHeapHelper->allocateSSInHeap(size, &alloc, BindlessHeapsHelper::BindlesHeapType::specialSsh); + + EXPECT_EQ(ssInHeapInfo.heapAllocation->getGpuBaseAddress(), ssInHeapInfo.surfaceStateOffset); EXPECT_EQ(ssInHeapInfo.heapAllocation->getGpuAddress(), ssInHeapInfo.heapAllocation->getGpuBaseAddress()); EXPECT_EQ(bindlessHeapHelper->getGlobalHeapsBase(), ssInHeapInfo.heapAllocation->getGpuBaseAddress()); } TEST_F(BindlessHeapsHelperTests, givenBindlessHeapHelperWhenAllocateSsInGlobalHeapThenOffsetLessThanHeapSize) { + auto bindlessHeapHelper = std::make_unique(getDevice(), false); MockGraphicsAllocation alloc; size_t size = 0x40; auto ssInHeapInfo = bindlessHeapHelper->allocateSSInHeap(size, &alloc, BindlessHeapsHelper::BindlesHeapType::globalSsh); EXPECT_LE(0u, ssInHeapInfo.surfaceStateOffset); - EXPECT_GT(MemoryConstants::max32BitAddress, ssInHeapInfo.surfaceStateOffset); + if (bindlessHeapHelper->heaplessEnabled) { + EXPECT_GT(MemoryConstants::max32BitAddress, ssInHeapInfo.surfaceStateOffset - ssInHeapInfo.heapAllocation->getGpuBaseAddress()); + } else { + EXPECT_GT(MemoryConstants::max32BitAddress, ssInHeapInfo.surfaceStateOffset); + } } TEST_F(BindlessHeapsHelperTests, givenBindlessHeapHelperWhenAllocateSsInGlobalDshThenOffsetLessThanHeapSize) { @@ -241,7 +267,11 @@ TEST_F(BindlessHeapsHelperTests, givenBindlessHeapHelperWhenAllocateSsInGlobalDs size_t size = 0x40; auto ssInHeapInfo = bindlessHeapHelper->allocateSSInHeap(size, &alloc, BindlessHeapsHelper::BindlesHeapType::globalDsh); EXPECT_LE(0u, ssInHeapInfo.surfaceStateOffset); - EXPECT_GT(MemoryConstants::max32BitAddress, ssInHeapInfo.surfaceStateOffset); + if (bindlessHeapHelper->heaplessEnabled) { + EXPECT_GT(MemoryConstants::max32BitAddress, ssInHeapInfo.surfaceStateOffset - ssInHeapInfo.heapAllocation->getGpuBaseAddress()); + } else { + EXPECT_GT(MemoryConstants::max32BitAddress, ssInHeapInfo.surfaceStateOffset); + } } TEST_F(BindlessHeapsHelperTests, givenBindlessHeapHelperWhenFreeGraphicsMemoryIsCalledThenSSinHeapInfoShouldBePlacedInReuseVector) {