From c80353587f83f7a9a8d5d8aacb8a4ebc6c369232 Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Wed, 18 Nov 2020 11:17:45 +0000 Subject: [PATCH] Patch bindless offset Related-To: NEO-4724 Signed-off-by: Maciej Plewka --- level_zero/core/source/kernel/kernel_hw.h | 10 +- level_zero/core/source/kernel/kernel_imp.cpp | 21 +- level_zero/core/source/kernel/kernel_imp.h | 1 + .../core/test/unit_tests/mocks/mock_kernel.h | 31 +++ .../unit_tests/sources/kernel/test_kernel.cpp | 217 ++++++++++++++++++ .../unit_test/device/sub_device_tests.cpp | 10 + shared/source/device/device.h | 2 + shared/source/device/root_device.h | 3 +- shared/source/device/sub_device.cpp | 3 + shared/source/device/sub_device.h | 1 + 10 files changed, 292 insertions(+), 7 deletions(-) diff --git a/level_zero/core/source/kernel/kernel_hw.h b/level_zero/core/source/kernel/kernel_hw.h index cd44e649a3..bb002e3e30 100644 --- a/level_zero/core/source/kernel/kernel_hw.h +++ b/level_zero/core/source/kernel/kernel_hw.h @@ -8,6 +8,8 @@ #pragma once #include "shared/source/command_container/command_encoder.h" +#include "shared/source/helpers/bindless_heaps_helper.h" +#include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/string.h" #include "level_zero/core/source/kernel/kernel_imp.h" @@ -42,8 +44,12 @@ struct KernelHw : public KernelImp { DEBUG_BREAK_IF(baseAddress != (baseAddress & sshAlignmentMask)); offset = 0; } - - auto surfaceStateAddress = ptrOffset(surfaceStateHeapData.get(), argInfo.bindful); + void *surfaceStateAddress = nullptr; + if (NEO::isValidOffset(argInfo.bindless)) { + surfaceStateAddress = patchBindlessSurfaceState(alloc, argInfo.bindless); + } else { + surfaceStateAddress = ptrOffset(surfaceStateHeapData.get(), argInfo.bindful); + } uint64_t bufferAddressForSsh = baseAddress; auto alignment = NEO::EncodeSurfaceState::getSurfaceBaseAddressAlignment(); size_t bufferSizeForSsh = ptrDiff(alloc->getGpuAddress(), bufferAddressForSsh); diff --git a/level_zero/core/source/kernel/kernel_imp.cpp b/level_zero/core/source/kernel/kernel_imp.cpp index 447df9f26d..c213b18ff5 100644 --- a/level_zero/core/source/kernel/kernel_imp.cpp +++ b/level_zero/core/source/kernel/kernel_imp.cpp @@ -9,6 +9,7 @@ #include "shared/source/helpers/basic_math.h" #include "shared/source/helpers/blit_commands_helper.h" +#include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/kernel_helpers.h" #include "shared/source/helpers/register_offsets.h" #include "shared/source/helpers/string.h" @@ -464,7 +465,7 @@ ze_result_t KernelImp::setArgBufferWithAlloc(uint32_t argIndex, uintptr_t argVal const auto val = argVal; NEO::patchPointer(ArrayRef(crossThreadData.get(), crossThreadDataSize), arg, val); - if (NEO::isValidOffset(arg.bindful)) { + if (NEO::isValidOffset(arg.bindful) || NEO::isValidOffset(arg.bindless)) { setBufferSurfaceState(argIndex, reinterpret_cast(val), allocation); } residencyContainer[argIndex] = allocation; @@ -525,7 +526,11 @@ ze_result_t KernelImp::setArgImage(uint32_t argIndex, size_t argSize, const void } const auto image = Image::fromHandle(*static_cast(argVal)); - image->copySurfaceStateToSSH(surfaceStateHeapData.get(), arg.bindful); + if (kernelImmData->getDescriptor().kernelAttributes.imageAddressingMode == NEO::KernelDescriptor::Bindless) { + image->copySurfaceStateToSSH(patchBindlessSurfaceState(image->getAllocation(), arg.bindless), 0u); + } else { + image->copySurfaceStateToSSH(surfaceStateHeapData.get(), arg.bindful); + } residencyContainer[argIndex] = image->getAllocation(); auto imageInfo = image->getImageInfo(); @@ -707,7 +712,17 @@ void KernelImp::setDebugSurface() { *device->getNEODevice()); } } - +void *KernelImp::patchBindlessSurfaceState(NEO::GraphicsAllocation *alloc, uint32_t bindless) { + auto &hwHelper = NEO::HwHelper::get(this->module->getDevice()->getHwInfo().platform.eRenderCoreFamily); + auto surfaceStateSize = hwHelper.getRenderSurfaceStateSize(); + NEO::BindlessHeapsHelper *bindlessHeapsHelper = this->module->getDevice()->getNEODevice()->getBindlessHeapsHelper(); + auto ssInHeap = bindlessHeapsHelper->allocateSSInHeap(surfaceStateSize, alloc, NEO::BindlessHeapsHelper::GLOBAL_SSH); + this->residencyContainer.push_back(ssInHeap.heapAllocation); + auto patchLocation = ptrOffset(getCrossThreadData(), bindless); + auto patchValue = hwHelper.getBindlessSurfaceExtendedMessageDescriptorValue(static_cast(ssInHeap.surfaceStateOffset)); + patchWithRequiredSize(const_cast(patchLocation), sizeof(patchValue), patchValue); + return ssInHeap.ssPtr; +} void KernelImp::patchWorkgroupSizeInCrossThreadData(uint32_t x, uint32_t y, uint32_t z) { const NEO::KernelDescriptor &desc = kernelImmData->getDescriptor(); auto dst = ArrayRef(crossThreadData.get(), crossThreadDataSize); diff --git a/level_zero/core/source/kernel/kernel_imp.h b/level_zero/core/source/kernel/kernel_imp.h index 5fefdff483..39e14d8a86 100644 --- a/level_zero/core/source/kernel/kernel_imp.h +++ b/level_zero/core/source/kernel/kernel_imp.h @@ -112,6 +112,7 @@ struct KernelImp : Kernel { void createPrintfBuffer(); void setDebugSurface(); virtual void evaluateIfRequiresGenerationOfLocalIdsByRuntime(const NEO::KernelDescriptor &kernelDescriptor) = 0; + void *patchBindlessSurfaceState(NEO::GraphicsAllocation *alloc, uint32_t bindless); const KernelImmutableData *kernelImmData = nullptr; Module *module = nullptr; diff --git a/level_zero/core/test/unit_tests/mocks/mock_kernel.h b/level_zero/core/test/unit_tests/mocks/mock_kernel.h index 8573d0fa9e..2b3e007291 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_kernel.h +++ b/level_zero/core/test/unit_tests/mocks/mock_kernel.h @@ -10,6 +10,7 @@ #include "shared/source/kernel/kernel_descriptor.h" #include "shared/source/kernel/kernel_descriptor_from_patchtokens.h" +#include "level_zero/core/source/kernel/kernel_hw.h" #include "level_zero/core/source/kernel/kernel_imp.h" #include "level_zero/core/test/unit_tests/mock.h" #include "level_zero/core/test/unit_tests/white_box.h" @@ -44,6 +45,7 @@ struct WhiteBox<::L0::Kernel> : public ::L0::KernelImp { using ::L0::KernelImp::kernelRequiresGenerationOfLocalIdsByRuntime; using ::L0::KernelImp::module; using ::L0::KernelImp::numThreadsPerThreadGroup; + using ::L0::KernelImp::patchBindlessSurfaceState; using ::L0::KernelImp::perThreadDataForWholeThreadGroup; using ::L0::KernelImp::perThreadDataSize; using ::L0::KernelImp::perThreadDataSizeForWholeThreadGroup; @@ -61,6 +63,34 @@ struct WhiteBox<::L0::Kernel> : public ::L0::KernelImp { WhiteBox() : ::L0::KernelImp(nullptr) {} }; +template +struct WhiteBoxKernelHw : public KernelHw { + using BaseClass = KernelHw; + using BaseClass::BaseClass; + using ::L0::KernelImp::createPrintfBuffer; + using ::L0::KernelImp::crossThreadData; + using ::L0::KernelImp::crossThreadDataSize; + using ::L0::KernelImp::groupSize; + using ::L0::KernelImp::kernelImmData; + using ::L0::KernelImp::kernelRequiresGenerationOfLocalIdsByRuntime; + using ::L0::KernelImp::module; + using ::L0::KernelImp::numThreadsPerThreadGroup; + using ::L0::KernelImp::patchBindlessSurfaceState; + using ::L0::KernelImp::perThreadDataForWholeThreadGroup; + using ::L0::KernelImp::perThreadDataSize; + using ::L0::KernelImp::perThreadDataSizeForWholeThreadGroup; + using ::L0::KernelImp::printfBuffer; + using ::L0::KernelImp::requiredWorkgroupOrder; + using ::L0::KernelImp::residencyContainer; + using ::L0::KernelImp::surfaceStateHeapData; + using ::L0::KernelImp::unifiedMemoryControls; + + void evaluateIfRequiresGenerationOfLocalIdsByRuntime(const NEO::KernelDescriptor &kernelDescriptor) override {} + + std::unique_ptr clone() const override { return nullptr; } + + WhiteBoxKernelHw() : ::L0::KernelHw(nullptr) {} +}; template <> struct Mock<::L0::Kernel> : public WhiteBox<::L0::Kernel> { @@ -84,6 +114,7 @@ struct Mock<::L0::Kernel> : public WhiteBox<::L0::Kernel> { NEO::populateKernelDescriptor(descriptor, kernelTokens, 8); immutableData.kernelDescriptor = &descriptor; + crossThreadData.reset(new uint8_t[100]); } ~Mock() override { delete immutableData.isaGraphicsAllocation.release(); diff --git a/level_zero/core/test/unit_tests/sources/kernel/test_kernel.cpp b/level_zero/core/test/unit_tests/sources/kernel/test_kernel.cpp index e6268f2c36..8ed7bc92cc 100644 --- a/level_zero/core/test/unit_tests/sources/kernel/test_kernel.cpp +++ b/level_zero/core/test/unit_tests/sources/kernel/test_kernel.cpp @@ -5,14 +5,19 @@ * */ +#include "shared/source/device_binary_format/patchtokens_decoder.h" +#include "shared/test/unit_test/device_binary_format/patchtokens_tests.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/mock_graphics_allocation.h" #include "opencl/source/program/kernel_info.h" +#include "opencl/source/program/kernel_info_from_patchtokens.h" #include "test.h" #include "level_zero/core/source/image/image_format_desc_helper.h" #include "level_zero/core/source/image/image_hw.h" +#include "level_zero/core/source/kernel/kernel_hw.h" #include "level_zero/core/source/module/module_imp.h" #include "level_zero/core/source/sampler/sampler_hw.h" #include "level_zero/core/test/unit_tests/fixtures/device_fixture.h" @@ -21,6 +26,8 @@ #include "level_zero/core/test/unit_tests/mocks/mock_kernel.h" #include "level_zero/core/test/unit_tests/mocks/mock_module.h" +void NEO::populateKernelDescriptor(KernelDescriptor &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes); + namespace L0 { namespace ult { @@ -573,5 +580,215 @@ TEST_F(KernelIsaTests, givenGlobalBuffersWhenCreatingKernelImmutableDataThenBuff EXPECT_EQ(1, std::count(resCont.begin(), resCont.end(), &globalConstBuffer)); } +using KernelImpPatchBindlessTest = Test; + +TEST_F(KernelImpPatchBindlessTest, GivenKernelImpWhenPatchBindlessOffsetCalledThenOffsetPatchedCorrectly) { + Mock kernel; + WhiteBox<::L0::DeviceImp> mockDevice; + mockDevice.neoDevice = neoDevice; + neoDevice->incRefInternal(); + neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex())); + Mock mockModule(&mockDevice, nullptr); + kernel.module = &mockModule; + NEO::MockGraphicsAllocation alloc; + uint32_t bindless = 0x40; + auto &hwHelper = NEO::HwHelper::get(device->getHwInfo().platform.eRenderCoreFamily); + size_t size = hwHelper.getRenderSurfaceStateSize(); + auto expectedSsInHeap = device->getNEODevice()->getBindlessHeapsHelper()->allocateSSInHeap(size, &alloc, NEO::BindlessHeapsHelper::GLOBAL_SSH); + auto patchLocation = ptrOffset(kernel.getCrossThreadData(), bindless); + auto patchValue = hwHelper.getBindlessSurfaceExtendedMessageDescriptorValue(static_cast(expectedSsInHeap.surfaceStateOffset)); + + auto ssPtr = kernel.patchBindlessSurfaceState(&alloc, bindless); + + EXPECT_EQ(ssPtr, expectedSsInHeap.ssPtr); + EXPECT_TRUE(memcmp(const_cast(patchLocation), &patchValue, sizeof(patchValue)) == 0); + EXPECT_TRUE(std::find(kernel.getResidencyContainer().begin(), kernel.getResidencyContainer().end(), expectedSsInHeap.heapAllocation) != kernel.getResidencyContainer().end()); +} + +HWTEST2_F(KernelImpPatchBindlessTest, GivenKernelImpWhenSetSurfaceStateBindlessThenSurfaceStateUpdated, MatchAny) { + using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; + + ze_kernel_desc_t desc = {}; + desc.pKernelName = kernelName.c_str(); + + WhiteBoxKernelHw mockKernel; + mockKernel.module = module.get(); + mockKernel.initialize(&desc); + auto &arg = const_cast(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].template as()); + arg.bindless = 0x40; + arg.bindful = undefined; + + neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex())); + + auto &hwHelper = NEO::HwHelper::get(device->getHwInfo().platform.eRenderCoreFamily); + size_t size = hwHelper.getRenderSurfaceStateSize(); + uint64_t gpuAddress = 0x2000; + void *buffer = reinterpret_cast(gpuAddress); + + NEO::MockGraphicsAllocation mockAllocation(buffer, gpuAddress, size); + auto expectedSsInHeap = device->getNEODevice()->getBindlessHeapsHelper()->allocateSSInHeap(size, &mockAllocation, NEO::BindlessHeapsHelper::GLOBAL_SSH); + + memset(expectedSsInHeap.ssPtr, 0, size); + auto surfaceStateBefore = *reinterpret_cast(expectedSsInHeap.ssPtr); + mockKernel.setBufferSurfaceState(0, buffer, &mockAllocation); + + auto surfaceStateAfter = *reinterpret_cast(expectedSsInHeap.ssPtr); + + EXPECT_FALSE(memcmp(&surfaceStateAfter, &surfaceStateBefore, size) == 0); +} + +HWTEST2_F(KernelImpPatchBindlessTest, GivenKernelImpWhenSetSurfaceStateBindfulThenSurfaceStateNotUpdated, MatchAny) { + using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; + ze_kernel_desc_t desc = {}; + desc.pKernelName = kernelName.c_str(); + + WhiteBoxKernelHw mockKernel; + mockKernel.module = module.get(); + mockKernel.initialize(&desc); + + auto &arg = const_cast(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].template as()); + arg.bindless = undefined; + arg.bindful = 0x40; + + neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex())); + + auto &hwHelper = NEO::HwHelper::get(device->getHwInfo().platform.eRenderCoreFamily); + size_t size = hwHelper.getRenderSurfaceStateSize(); + uint64_t gpuAddress = 0x2000; + void *buffer = reinterpret_cast(gpuAddress); + + NEO::MockGraphicsAllocation mockAllocation(buffer, gpuAddress, size); + auto expectedSsInHeap = device->getNEODevice()->getBindlessHeapsHelper()->allocateSSInHeap(size, &mockAllocation, NEO::BindlessHeapsHelper::GLOBAL_SSH); + + memset(expectedSsInHeap.ssPtr, 0, size); + auto surfaceStateBefore = *reinterpret_cast(expectedSsInHeap.ssPtr); + mockKernel.setBufferSurfaceState(0, buffer, &mockAllocation); + + auto surfaceStateAfter = *reinterpret_cast(expectedSsInHeap.ssPtr); + + EXPECT_TRUE(memcmp(&surfaceStateAfter, &surfaceStateBefore, size) == 0); +} + +struct MyMockKernel : public Mock { + void setBufferSurfaceState(uint32_t argIndex, void *address, NEO::GraphicsAllocation *alloc) override { + setSurfaceStateCalled = true; + } + bool setSurfaceStateCalled = false; +}; + +TEST_F(KernelImpPatchBindlessTest, GivenValidBindlessOffsetWhenSetArgBufferWithAllocThensetBufferSurfaceStateCalled) { + ze_kernel_desc_t desc = {}; + desc.pKernelName = kernelName.c_str(); + MyMockKernel mockKernel; + + mockKernel.module = module.get(); + mockKernel.initialize(&desc); + + auto &arg = const_cast(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].as()); + arg.bindless = 0x40; + arg.bindful = undefined; + + NEO::MockGraphicsAllocation alloc; + + mockKernel.setArgBufferWithAlloc(0, 0x1234, &alloc); + + EXPECT_TRUE(mockKernel.setSurfaceStateCalled); +} + +TEST_F(KernelImpPatchBindlessTest, GivenValidBindfulOffsetWhenSetArgBufferWithAllocThensetBufferSurfaceStateCalled) { + ze_kernel_desc_t desc = {}; + desc.pKernelName = kernelName.c_str(); + MyMockKernel mockKernel; + + mockKernel.module = module.get(); + mockKernel.initialize(&desc); + + auto &arg = const_cast(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].as()); + arg.bindless = undefined; + arg.bindful = 0x40; + + NEO::MockGraphicsAllocation alloc; + + mockKernel.setArgBufferWithAlloc(0, 0x1234, &alloc); + + EXPECT_TRUE(mockKernel.setSurfaceStateCalled); +} + +TEST_F(KernelImpPatchBindlessTest, GivenUndefiedBidfulAndBindlesstOffsetWhenSetArgBufferWithAllocThenSetBufferSurfaceStateIsNotCalled) { + ze_kernel_desc_t desc = {}; + desc.pKernelName = kernelName.c_str(); + MyMockKernel mockKernel; + + mockKernel.module = module.get(); + mockKernel.initialize(&desc); + + auto &arg = const_cast(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].as()); + arg.bindless = undefined; + arg.bindful = undefined; + + NEO::MockGraphicsAllocation alloc; + + mockKernel.setArgBufferWithAlloc(0, 0x1234, &alloc); + + EXPECT_FALSE(mockKernel.setSurfaceStateCalled); +} +template +struct MyMockImage : public WhiteBox<::L0::ImageCoreFamily> { + //MyMockImage() : WhiteBox<::L0::ImageCoreFamily>(); + void copySurfaceStateToSSH(void *surfaceStateHeap, const uint32_t surfaceStateOffset) override { + passedSurfaceStateHeap = surfaceStateHeap; + passedSurfaceStateOffset = surfaceStateOffset; + } + void *passedSurfaceStateHeap = nullptr; + uint32_t passedSurfaceStateOffset = 0; +}; + +HWTEST2_F(SetKernelArg, givenImageAndBindlessKernelWhenSetArgImageThenCopySurfaceStateToSSHCalledWithCorrectArgs, ImageSupport) { + createKernel(); + + neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex())); + auto &imageArg = const_cast(kernel->kernelImmData->getDescriptor().payloadMappings.explicitArgs[3].template as()); + auto &addressingMode = kernel->kernelImmData->getDescriptor().kernelAttributes.imageAddressingMode; + const_cast(addressingMode) = NEO::KernelDescriptor::Bindless; + imageArg.bindless = 0x0; + imageArg.bindful = undefined; + ze_image_desc_t desc = {}; + auto &hwHelper = NEO::HwHelper::get(neoDevice->getHardwareInfo().platform.eRenderCoreFamily); + auto surfaceStateSize = hwHelper.getRenderSurfaceStateSize(); + + auto imageHW = std::make_unique>(); + auto ret = imageHW->initialize(device, &desc); + auto handle = imageHW->toHandle(); + ASSERT_EQ(ZE_RESULT_SUCCESS, ret); + + auto expectedSsInHeap = neoDevice->bindlessHeapHelper->allocateSSInHeap(surfaceStateSize, imageHW->getAllocation(), BindlessHeapsHelper::BindlesHeapType::GLOBAL_SSH); + + kernel->setArgImage(3, sizeof(imageHW.get()), &handle); + + EXPECT_EQ(imageHW->passedSurfaceStateHeap, expectedSsInHeap.ssPtr); + EXPECT_EQ(imageHW->passedSurfaceStateOffset, 0u); +} + +HWTEST2_F(SetKernelArg, givenImageAndBindfulKernelWhenSetArgImageThenCopySurfaceStateToSSHCalledWithCorrectArgs, ImageSupport) { + createKernel(); + + auto &imageArg = const_cast(kernel->kernelImmData->getDescriptor().payloadMappings.explicitArgs[3].template as()); + auto addressingMode = const_cast(kernel->kernelImmData->getDescriptor().kernelAttributes.imageAddressingMode); + addressingMode = NEO::KernelDescriptor::Bindful; + imageArg.bindless = undefined; + imageArg.bindful = 0x40; + ze_image_desc_t desc = {}; + + auto imageHW = std::make_unique>(); + auto ret = imageHW->initialize(device, &desc); + auto handle = imageHW->toHandle(); + ASSERT_EQ(ZE_RESULT_SUCCESS, ret); + + kernel->setArgImage(3, sizeof(imageHW.get()), &handle); + + EXPECT_EQ(imageHW->passedSurfaceStateHeap, kernel->getSurfaceStateHeapData()); + EXPECT_EQ(imageHW->passedSurfaceStateOffset, imageArg.bindful); +} + } // namespace ult } // namespace L0 diff --git a/opencl/test/unit_test/device/sub_device_tests.cpp b/opencl/test/unit_test/device/sub_device_tests.cpp index 27a51e5266..c8b00dd1b0 100644 --- a/opencl/test/unit_test/device/sub_device_tests.cpp +++ b/opencl/test/unit_test/device/sub_device_tests.cpp @@ -274,3 +274,13 @@ TEST(SubDevicesTest, whenInitializeRootCsrThenDirectSubmissionIsNotInitialized) auto csr = device->getEngine(1u).commandStreamReceiver; EXPECT_FALSE(csr->isDirectSubmissionEnabled()); } + +TEST(SubDevicesTest, givenCreateMultipleSubDevicesFlagSetWhenBindlessHeapHelperCreatedThenSubDeviceReturnRootDeviceMember) { + DebugManagerStateRestore restorer; + DebugManager.flags.CreateMultipleSubDevices.set(2); + VariableBackup mockDeviceFlagBackup(&MockDevice::createSingleDevice, false); + auto device = std::unique_ptr(MockDevice::createWithNewExecutionEnvironment(defaultHwInfo.get())); + + device->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(device->getMemoryManager(), device->getNumAvailableDevices() > 1, device->getRootDeviceIndex())); + EXPECT_EQ(device->getBindlessHeapsHelper(), device->subdevices.at(0)->getBindlessHeapsHelper()); +} diff --git a/shared/source/device/device.h b/shared/source/device/device.h index 1b4a663b8b..6b3c4af7c0 100644 --- a/shared/source/device/device.h +++ b/shared/source/device/device.h @@ -10,6 +10,7 @@ #include "shared/source/device/device_info.h" #include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/helpers/bindless_heaps_helper.h" #include "shared/source/helpers/common_types.h" #include "shared/source/helpers/engine_control.h" #include "shared/source/helpers/engine_node_helper.h" @@ -93,6 +94,7 @@ class Device : public ReferenceTrackedObject { virtual Device *getDeviceById(uint32_t deviceId) const = 0; virtual Device *getParentDevice() const = 0; virtual DeviceBitfield getDeviceBitfield() const = 0; + virtual BindlessHeapsHelper *getBindlessHeapsHelper() const = 0; static decltype(&PerformanceCounters::create) createPerformanceCountersFunc; diff --git a/shared/source/device/root_device.h b/shared/source/device/root_device.h index e7beb7361b..755964e4c6 100644 --- a/shared/source/device/root_device.h +++ b/shared/source/device/root_device.h @@ -11,7 +11,6 @@ namespace NEO { class SubDevice; -class BindlessHeapsHelper; class RootDevice : public Device { public: @@ -23,7 +22,7 @@ class RootDevice : public Device { Device *getDeviceById(uint32_t deviceId) const override; Device *getParentDevice() const override; uint32_t getNumSubDevices() const; - BindlessHeapsHelper *getBindlessHeapsHelper() const; + BindlessHeapsHelper *getBindlessHeapsHelper() const override; protected: DeviceBitfield getDeviceBitfield() const override; diff --git a/shared/source/device/sub_device.cpp b/shared/source/device/sub_device.cpp index c5d9b39a45..b41334603d 100644 --- a/shared/source/device/sub_device.cpp +++ b/shared/source/device/sub_device.cpp @@ -46,6 +46,9 @@ Device *SubDevice::getDeviceById(uint32_t deviceId) const { Device *SubDevice::getParentDevice() const { return &rootDevice; } +BindlessHeapsHelper *SubDevice::getBindlessHeapsHelper() const { + return rootDevice.getBindlessHeapsHelper(); +} uint64_t SubDevice::getGlobalMemorySize(uint32_t deviceBitfield) const { auto globalMemorySize = Device::getGlobalMemorySize(static_cast(maxNBitValue(rootDevice.getNumSubDevices()))); diff --git a/shared/source/device/sub_device.h b/shared/source/device/sub_device.h index 60efb4b52f..62a728ca96 100644 --- a/shared/source/device/sub_device.h +++ b/shared/source/device/sub_device.h @@ -20,6 +20,7 @@ class SubDevice : public Device { uint32_t getRootDeviceIndex() const override; Device *getDeviceById(uint32_t deviceId) const override; Device *getParentDevice() const override; + BindlessHeapsHelper *getBindlessHeapsHelper() const override; uint32_t getSubDeviceIndex() const;