Skip to content

Commit c803535

Browse files
Patch bindless offset
Related-To: NEO-4724 Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
1 parent 223de6d commit c803535

File tree

10 files changed

+292
-7
lines changed

10 files changed

+292
-7
lines changed

level_zero/core/source/kernel/kernel_hw.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#pragma once
99

1010
#include "shared/source/command_container/command_encoder.h"
11+
#include "shared/source/helpers/bindless_heaps_helper.h"
12+
#include "shared/source/helpers/hw_helper.h"
1113
#include "shared/source/helpers/string.h"
1214

1315
#include "level_zero/core/source/kernel/kernel_imp.h"
@@ -42,8 +44,12 @@ struct KernelHw : public KernelImp {
4244
DEBUG_BREAK_IF(baseAddress != (baseAddress & sshAlignmentMask));
4345
offset = 0;
4446
}
45-
46-
auto surfaceStateAddress = ptrOffset(surfaceStateHeapData.get(), argInfo.bindful);
47+
void *surfaceStateAddress = nullptr;
48+
if (NEO::isValidOffset(argInfo.bindless)) {
49+
surfaceStateAddress = patchBindlessSurfaceState(alloc, argInfo.bindless);
50+
} else {
51+
surfaceStateAddress = ptrOffset(surfaceStateHeapData.get(), argInfo.bindful);
52+
}
4753
uint64_t bufferAddressForSsh = baseAddress;
4854
auto alignment = NEO::EncodeSurfaceState<GfxFamily>::getSurfaceBaseAddressAlignment();
4955
size_t bufferSizeForSsh = ptrDiff(alloc->getGpuAddress(), bufferAddressForSsh);

level_zero/core/source/kernel/kernel_imp.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "shared/source/helpers/basic_math.h"
1111
#include "shared/source/helpers/blit_commands_helper.h"
12+
#include "shared/source/helpers/hw_info.h"
1213
#include "shared/source/helpers/kernel_helpers.h"
1314
#include "shared/source/helpers/register_offsets.h"
1415
#include "shared/source/helpers/string.h"
@@ -464,7 +465,7 @@ ze_result_t KernelImp::setArgBufferWithAlloc(uint32_t argIndex, uintptr_t argVal
464465
const auto val = argVal;
465466

466467
NEO::patchPointer(ArrayRef<uint8_t>(crossThreadData.get(), crossThreadDataSize), arg, val);
467-
if (NEO::isValidOffset(arg.bindful)) {
468+
if (NEO::isValidOffset(arg.bindful) || NEO::isValidOffset(arg.bindless)) {
468469
setBufferSurfaceState(argIndex, reinterpret_cast<void *>(val), allocation);
469470
}
470471
residencyContainer[argIndex] = allocation;
@@ -525,7 +526,11 @@ ze_result_t KernelImp::setArgImage(uint32_t argIndex, size_t argSize, const void
525526
}
526527

527528
const auto image = Image::fromHandle(*static_cast<const ze_image_handle_t *>(argVal));
528-
image->copySurfaceStateToSSH(surfaceStateHeapData.get(), arg.bindful);
529+
if (kernelImmData->getDescriptor().kernelAttributes.imageAddressingMode == NEO::KernelDescriptor::Bindless) {
530+
image->copySurfaceStateToSSH(patchBindlessSurfaceState(image->getAllocation(), arg.bindless), 0u);
531+
} else {
532+
image->copySurfaceStateToSSH(surfaceStateHeapData.get(), arg.bindful);
533+
}
529534
residencyContainer[argIndex] = image->getAllocation();
530535

531536
auto imageInfo = image->getImageInfo();
@@ -707,7 +712,17 @@ void KernelImp::setDebugSurface() {
707712
*device->getNEODevice());
708713
}
709714
}
710-
715+
void *KernelImp::patchBindlessSurfaceState(NEO::GraphicsAllocation *alloc, uint32_t bindless) {
716+
auto &hwHelper = NEO::HwHelper::get(this->module->getDevice()->getHwInfo().platform.eRenderCoreFamily);
717+
auto surfaceStateSize = hwHelper.getRenderSurfaceStateSize();
718+
NEO::BindlessHeapsHelper *bindlessHeapsHelper = this->module->getDevice()->getNEODevice()->getBindlessHeapsHelper();
719+
auto ssInHeap = bindlessHeapsHelper->allocateSSInHeap(surfaceStateSize, alloc, NEO::BindlessHeapsHelper::GLOBAL_SSH);
720+
this->residencyContainer.push_back(ssInHeap.heapAllocation);
721+
auto patchLocation = ptrOffset(getCrossThreadData(), bindless);
722+
auto patchValue = hwHelper.getBindlessSurfaceExtendedMessageDescriptorValue(static_cast<uint32_t>(ssInHeap.surfaceStateOffset));
723+
patchWithRequiredSize(const_cast<uint8_t *>(patchLocation), sizeof(patchValue), patchValue);
724+
return ssInHeap.ssPtr;
725+
}
711726
void KernelImp::patchWorkgroupSizeInCrossThreadData(uint32_t x, uint32_t y, uint32_t z) {
712727
const NEO::KernelDescriptor &desc = kernelImmData->getDescriptor();
713728
auto dst = ArrayRef<uint8_t>(crossThreadData.get(), crossThreadDataSize);

level_zero/core/source/kernel/kernel_imp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct KernelImp : Kernel {
112112
void createPrintfBuffer();
113113
void setDebugSurface();
114114
virtual void evaluateIfRequiresGenerationOfLocalIdsByRuntime(const NEO::KernelDescriptor &kernelDescriptor) = 0;
115+
void *patchBindlessSurfaceState(NEO::GraphicsAllocation *alloc, uint32_t bindless);
115116

116117
const KernelImmutableData *kernelImmData = nullptr;
117118
Module *module = nullptr;

level_zero/core/test/unit_tests/mocks/mock_kernel.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "shared/source/kernel/kernel_descriptor.h"
1111
#include "shared/source/kernel/kernel_descriptor_from_patchtokens.h"
1212

13+
#include "level_zero/core/source/kernel/kernel_hw.h"
1314
#include "level_zero/core/source/kernel/kernel_imp.h"
1415
#include "level_zero/core/test/unit_tests/mock.h"
1516
#include "level_zero/core/test/unit_tests/white_box.h"
@@ -44,6 +45,7 @@ struct WhiteBox<::L0::Kernel> : public ::L0::KernelImp {
4445
using ::L0::KernelImp::kernelRequiresGenerationOfLocalIdsByRuntime;
4546
using ::L0::KernelImp::module;
4647
using ::L0::KernelImp::numThreadsPerThreadGroup;
48+
using ::L0::KernelImp::patchBindlessSurfaceState;
4749
using ::L0::KernelImp::perThreadDataForWholeThreadGroup;
4850
using ::L0::KernelImp::perThreadDataSize;
4951
using ::L0::KernelImp::perThreadDataSizeForWholeThreadGroup;
@@ -61,6 +63,34 @@ struct WhiteBox<::L0::Kernel> : public ::L0::KernelImp {
6163

6264
WhiteBox() : ::L0::KernelImp(nullptr) {}
6365
};
66+
template <GFXCORE_FAMILY gfxCoreFamily>
67+
struct WhiteBoxKernelHw : public KernelHw<gfxCoreFamily> {
68+
using BaseClass = KernelHw<gfxCoreFamily>;
69+
using BaseClass::BaseClass;
70+
using ::L0::KernelImp::createPrintfBuffer;
71+
using ::L0::KernelImp::crossThreadData;
72+
using ::L0::KernelImp::crossThreadDataSize;
73+
using ::L0::KernelImp::groupSize;
74+
using ::L0::KernelImp::kernelImmData;
75+
using ::L0::KernelImp::kernelRequiresGenerationOfLocalIdsByRuntime;
76+
using ::L0::KernelImp::module;
77+
using ::L0::KernelImp::numThreadsPerThreadGroup;
78+
using ::L0::KernelImp::patchBindlessSurfaceState;
79+
using ::L0::KernelImp::perThreadDataForWholeThreadGroup;
80+
using ::L0::KernelImp::perThreadDataSize;
81+
using ::L0::KernelImp::perThreadDataSizeForWholeThreadGroup;
82+
using ::L0::KernelImp::printfBuffer;
83+
using ::L0::KernelImp::requiredWorkgroupOrder;
84+
using ::L0::KernelImp::residencyContainer;
85+
using ::L0::KernelImp::surfaceStateHeapData;
86+
using ::L0::KernelImp::unifiedMemoryControls;
87+
88+
void evaluateIfRequiresGenerationOfLocalIdsByRuntime(const NEO::KernelDescriptor &kernelDescriptor) override {}
89+
90+
std::unique_ptr<Kernel> clone() const override { return nullptr; }
91+
92+
WhiteBoxKernelHw() : ::L0::KernelHw<gfxCoreFamily>(nullptr) {}
93+
};
6494

6595
template <>
6696
struct Mock<::L0::Kernel> : public WhiteBox<::L0::Kernel> {
@@ -84,6 +114,7 @@ struct Mock<::L0::Kernel> : public WhiteBox<::L0::Kernel> {
84114

85115
NEO::populateKernelDescriptor(descriptor, kernelTokens, 8);
86116
immutableData.kernelDescriptor = &descriptor;
117+
crossThreadData.reset(new uint8_t[100]);
87118
}
88119
~Mock() override {
89120
delete immutableData.isaGraphicsAllocation.release();

level_zero/core/test/unit_tests/sources/kernel/test_kernel.cpp

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55
*
66
*/
77

8+
#include "shared/source/device_binary_format/patchtokens_decoder.h"
9+
#include "shared/test/unit_test/device_binary_format/patchtokens_tests.h"
10+
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
811
#include "shared/test/unit_test/mocks/mock_device.h"
912
#include "shared/test/unit_test/mocks/mock_graphics_allocation.h"
1013

1114
#include "opencl/source/program/kernel_info.h"
15+
#include "opencl/source/program/kernel_info_from_patchtokens.h"
1216
#include "test.h"
1317

1418
#include "level_zero/core/source/image/image_format_desc_helper.h"
1519
#include "level_zero/core/source/image/image_hw.h"
20+
#include "level_zero/core/source/kernel/kernel_hw.h"
1621
#include "level_zero/core/source/module/module_imp.h"
1722
#include "level_zero/core/source/sampler/sampler_hw.h"
1823
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
@@ -21,6 +26,8 @@
2126
#include "level_zero/core/test/unit_tests/mocks/mock_kernel.h"
2227
#include "level_zero/core/test/unit_tests/mocks/mock_module.h"
2328

29+
void NEO::populateKernelDescriptor(KernelDescriptor &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes);
30+
2431
namespace L0 {
2532
namespace ult {
2633

@@ -573,5 +580,215 @@ TEST_F(KernelIsaTests, givenGlobalBuffersWhenCreatingKernelImmutableDataThenBuff
573580
EXPECT_EQ(1, std::count(resCont.begin(), resCont.end(), &globalConstBuffer));
574581
}
575582

583+
using KernelImpPatchBindlessTest = Test<ModuleFixture>;
584+
585+
TEST_F(KernelImpPatchBindlessTest, GivenKernelImpWhenPatchBindlessOffsetCalledThenOffsetPatchedCorrectly) {
586+
Mock<Kernel> kernel;
587+
WhiteBox<::L0::DeviceImp> mockDevice;
588+
mockDevice.neoDevice = neoDevice;
589+
neoDevice->incRefInternal();
590+
neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex()));
591+
Mock<Module> mockModule(&mockDevice, nullptr);
592+
kernel.module = &mockModule;
593+
NEO::MockGraphicsAllocation alloc;
594+
uint32_t bindless = 0x40;
595+
auto &hwHelper = NEO::HwHelper::get(device->getHwInfo().platform.eRenderCoreFamily);
596+
size_t size = hwHelper.getRenderSurfaceStateSize();
597+
auto expectedSsInHeap = device->getNEODevice()->getBindlessHeapsHelper()->allocateSSInHeap(size, &alloc, NEO::BindlessHeapsHelper::GLOBAL_SSH);
598+
auto patchLocation = ptrOffset(kernel.getCrossThreadData(), bindless);
599+
auto patchValue = hwHelper.getBindlessSurfaceExtendedMessageDescriptorValue(static_cast<uint32_t>(expectedSsInHeap.surfaceStateOffset));
600+
601+
auto ssPtr = kernel.patchBindlessSurfaceState(&alloc, bindless);
602+
603+
EXPECT_EQ(ssPtr, expectedSsInHeap.ssPtr);
604+
EXPECT_TRUE(memcmp(const_cast<uint8_t *>(patchLocation), &patchValue, sizeof(patchValue)) == 0);
605+
EXPECT_TRUE(std::find(kernel.getResidencyContainer().begin(), kernel.getResidencyContainer().end(), expectedSsInHeap.heapAllocation) != kernel.getResidencyContainer().end());
606+
}
607+
608+
HWTEST2_F(KernelImpPatchBindlessTest, GivenKernelImpWhenSetSurfaceStateBindlessThenSurfaceStateUpdated, MatchAny) {
609+
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
610+
611+
ze_kernel_desc_t desc = {};
612+
desc.pKernelName = kernelName.c_str();
613+
614+
WhiteBoxKernelHw<gfxCoreFamily> mockKernel;
615+
mockKernel.module = module.get();
616+
mockKernel.initialize(&desc);
617+
auto &arg = const_cast<NEO::ArgDescPointer &>(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].template as<NEO::ArgDescPointer>());
618+
arg.bindless = 0x40;
619+
arg.bindful = undefined<SurfaceStateHeapOffset>;
620+
621+
neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex()));
622+
623+
auto &hwHelper = NEO::HwHelper::get(device->getHwInfo().platform.eRenderCoreFamily);
624+
size_t size = hwHelper.getRenderSurfaceStateSize();
625+
uint64_t gpuAddress = 0x2000;
626+
void *buffer = reinterpret_cast<void *>(gpuAddress);
627+
628+
NEO::MockGraphicsAllocation mockAllocation(buffer, gpuAddress, size);
629+
auto expectedSsInHeap = device->getNEODevice()->getBindlessHeapsHelper()->allocateSSInHeap(size, &mockAllocation, NEO::BindlessHeapsHelper::GLOBAL_SSH);
630+
631+
memset(expectedSsInHeap.ssPtr, 0, size);
632+
auto surfaceStateBefore = *reinterpret_cast<RENDER_SURFACE_STATE *>(expectedSsInHeap.ssPtr);
633+
mockKernel.setBufferSurfaceState(0, buffer, &mockAllocation);
634+
635+
auto surfaceStateAfter = *reinterpret_cast<RENDER_SURFACE_STATE *>(expectedSsInHeap.ssPtr);
636+
637+
EXPECT_FALSE(memcmp(&surfaceStateAfter, &surfaceStateBefore, size) == 0);
638+
}
639+
640+
HWTEST2_F(KernelImpPatchBindlessTest, GivenKernelImpWhenSetSurfaceStateBindfulThenSurfaceStateNotUpdated, MatchAny) {
641+
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
642+
ze_kernel_desc_t desc = {};
643+
desc.pKernelName = kernelName.c_str();
644+
645+
WhiteBoxKernelHw<gfxCoreFamily> mockKernel;
646+
mockKernel.module = module.get();
647+
mockKernel.initialize(&desc);
648+
649+
auto &arg = const_cast<NEO::ArgDescPointer &>(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].template as<NEO::ArgDescPointer>());
650+
arg.bindless = undefined<CrossThreadDataOffset>;
651+
arg.bindful = 0x40;
652+
653+
neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex()));
654+
655+
auto &hwHelper = NEO::HwHelper::get(device->getHwInfo().platform.eRenderCoreFamily);
656+
size_t size = hwHelper.getRenderSurfaceStateSize();
657+
uint64_t gpuAddress = 0x2000;
658+
void *buffer = reinterpret_cast<void *>(gpuAddress);
659+
660+
NEO::MockGraphicsAllocation mockAllocation(buffer, gpuAddress, size);
661+
auto expectedSsInHeap = device->getNEODevice()->getBindlessHeapsHelper()->allocateSSInHeap(size, &mockAllocation, NEO::BindlessHeapsHelper::GLOBAL_SSH);
662+
663+
memset(expectedSsInHeap.ssPtr, 0, size);
664+
auto surfaceStateBefore = *reinterpret_cast<RENDER_SURFACE_STATE *>(expectedSsInHeap.ssPtr);
665+
mockKernel.setBufferSurfaceState(0, buffer, &mockAllocation);
666+
667+
auto surfaceStateAfter = *reinterpret_cast<RENDER_SURFACE_STATE *>(expectedSsInHeap.ssPtr);
668+
669+
EXPECT_TRUE(memcmp(&surfaceStateAfter, &surfaceStateBefore, size) == 0);
670+
}
671+
672+
struct MyMockKernel : public Mock<Kernel> {
673+
void setBufferSurfaceState(uint32_t argIndex, void *address, NEO::GraphicsAllocation *alloc) override {
674+
setSurfaceStateCalled = true;
675+
}
676+
bool setSurfaceStateCalled = false;
677+
};
678+
679+
TEST_F(KernelImpPatchBindlessTest, GivenValidBindlessOffsetWhenSetArgBufferWithAllocThensetBufferSurfaceStateCalled) {
680+
ze_kernel_desc_t desc = {};
681+
desc.pKernelName = kernelName.c_str();
682+
MyMockKernel mockKernel;
683+
684+
mockKernel.module = module.get();
685+
mockKernel.initialize(&desc);
686+
687+
auto &arg = const_cast<NEO::ArgDescPointer &>(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>());
688+
arg.bindless = 0x40;
689+
arg.bindful = undefined<SurfaceStateHeapOffset>;
690+
691+
NEO::MockGraphicsAllocation alloc;
692+
693+
mockKernel.setArgBufferWithAlloc(0, 0x1234, &alloc);
694+
695+
EXPECT_TRUE(mockKernel.setSurfaceStateCalled);
696+
}
697+
698+
TEST_F(KernelImpPatchBindlessTest, GivenValidBindfulOffsetWhenSetArgBufferWithAllocThensetBufferSurfaceStateCalled) {
699+
ze_kernel_desc_t desc = {};
700+
desc.pKernelName = kernelName.c_str();
701+
MyMockKernel mockKernel;
702+
703+
mockKernel.module = module.get();
704+
mockKernel.initialize(&desc);
705+
706+
auto &arg = const_cast<NEO::ArgDescPointer &>(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>());
707+
arg.bindless = undefined<CrossThreadDataOffset>;
708+
arg.bindful = 0x40;
709+
710+
NEO::MockGraphicsAllocation alloc;
711+
712+
mockKernel.setArgBufferWithAlloc(0, 0x1234, &alloc);
713+
714+
EXPECT_TRUE(mockKernel.setSurfaceStateCalled);
715+
}
716+
717+
TEST_F(KernelImpPatchBindlessTest, GivenUndefiedBidfulAndBindlesstOffsetWhenSetArgBufferWithAllocThenSetBufferSurfaceStateIsNotCalled) {
718+
ze_kernel_desc_t desc = {};
719+
desc.pKernelName = kernelName.c_str();
720+
MyMockKernel mockKernel;
721+
722+
mockKernel.module = module.get();
723+
mockKernel.initialize(&desc);
724+
725+
auto &arg = const_cast<NEO::ArgDescPointer &>(mockKernel.kernelImmData->getDescriptor().payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>());
726+
arg.bindless = undefined<CrossThreadDataOffset>;
727+
arg.bindful = undefined<SurfaceStateHeapOffset>;
728+
729+
NEO::MockGraphicsAllocation alloc;
730+
731+
mockKernel.setArgBufferWithAlloc(0, 0x1234, &alloc);
732+
733+
EXPECT_FALSE(mockKernel.setSurfaceStateCalled);
734+
}
735+
template <GFXCORE_FAMILY gfxCoreFamily>
736+
struct MyMockImage : public WhiteBox<::L0::ImageCoreFamily<gfxCoreFamily>> {
737+
//MyMockImage() : WhiteBox<::L0::ImageCoreFamily<gfxCoreFamily>>();
738+
void copySurfaceStateToSSH(void *surfaceStateHeap, const uint32_t surfaceStateOffset) override {
739+
passedSurfaceStateHeap = surfaceStateHeap;
740+
passedSurfaceStateOffset = surfaceStateOffset;
741+
}
742+
void *passedSurfaceStateHeap = nullptr;
743+
uint32_t passedSurfaceStateOffset = 0;
744+
};
745+
746+
HWTEST2_F(SetKernelArg, givenImageAndBindlessKernelWhenSetArgImageThenCopySurfaceStateToSSHCalledWithCorrectArgs, ImageSupport) {
747+
createKernel();
748+
749+
neoDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(neoDevice->getMemoryManager(), neoDevice->getNumAvailableDevices() > 1, neoDevice->getRootDeviceIndex()));
750+
auto &imageArg = const_cast<NEO::ArgDescImage &>(kernel->kernelImmData->getDescriptor().payloadMappings.explicitArgs[3].template as<NEO::ArgDescImage>());
751+
auto &addressingMode = kernel->kernelImmData->getDescriptor().kernelAttributes.imageAddressingMode;
752+
const_cast<NEO::KernelDescriptor::AddressingMode &>(addressingMode) = NEO::KernelDescriptor::Bindless;
753+
imageArg.bindless = 0x0;
754+
imageArg.bindful = undefined<SurfaceStateHeapOffset>;
755+
ze_image_desc_t desc = {};
756+
auto &hwHelper = NEO::HwHelper::get(neoDevice->getHardwareInfo().platform.eRenderCoreFamily);
757+
auto surfaceStateSize = hwHelper.getRenderSurfaceStateSize();
758+
759+
auto imageHW = std::make_unique<MyMockImage<gfxCoreFamily>>();
760+
auto ret = imageHW->initialize(device, &desc);
761+
auto handle = imageHW->toHandle();
762+
ASSERT_EQ(ZE_RESULT_SUCCESS, ret);
763+
764+
auto expectedSsInHeap = neoDevice->bindlessHeapHelper->allocateSSInHeap(surfaceStateSize, imageHW->getAllocation(), BindlessHeapsHelper::BindlesHeapType::GLOBAL_SSH);
765+
766+
kernel->setArgImage(3, sizeof(imageHW.get()), &handle);
767+
768+
EXPECT_EQ(imageHW->passedSurfaceStateHeap, expectedSsInHeap.ssPtr);
769+
EXPECT_EQ(imageHW->passedSurfaceStateOffset, 0u);
770+
}
771+
772+
HWTEST2_F(SetKernelArg, givenImageAndBindfulKernelWhenSetArgImageThenCopySurfaceStateToSSHCalledWithCorrectArgs, ImageSupport) {
773+
createKernel();
774+
775+
auto &imageArg = const_cast<NEO::ArgDescImage &>(kernel->kernelImmData->getDescriptor().payloadMappings.explicitArgs[3].template as<NEO::ArgDescImage>());
776+
auto addressingMode = const_cast<NEO::KernelDescriptor::AddressingMode &>(kernel->kernelImmData->getDescriptor().kernelAttributes.imageAddressingMode);
777+
addressingMode = NEO::KernelDescriptor::Bindful;
778+
imageArg.bindless = undefined<CrossThreadDataOffset>;
779+
imageArg.bindful = 0x40;
780+
ze_image_desc_t desc = {};
781+
782+
auto imageHW = std::make_unique<MyMockImage<gfxCoreFamily>>();
783+
auto ret = imageHW->initialize(device, &desc);
784+
auto handle = imageHW->toHandle();
785+
ASSERT_EQ(ZE_RESULT_SUCCESS, ret);
786+
787+
kernel->setArgImage(3, sizeof(imageHW.get()), &handle);
788+
789+
EXPECT_EQ(imageHW->passedSurfaceStateHeap, kernel->getSurfaceStateHeapData());
790+
EXPECT_EQ(imageHW->passedSurfaceStateOffset, imageArg.bindful);
791+
}
792+
576793
} // namespace ult
577794
} // namespace L0

opencl/test/unit_test/device/sub_device_tests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,13 @@ TEST(SubDevicesTest, whenInitializeRootCsrThenDirectSubmissionIsNotInitialized)
274274
auto csr = device->getEngine(1u).commandStreamReceiver;
275275
EXPECT_FALSE(csr->isDirectSubmissionEnabled());
276276
}
277+
278+
TEST(SubDevicesTest, givenCreateMultipleSubDevicesFlagSetWhenBindlessHeapHelperCreatedThenSubDeviceReturnRootDeviceMember) {
279+
DebugManagerStateRestore restorer;
280+
DebugManager.flags.CreateMultipleSubDevices.set(2);
281+
VariableBackup<bool> mockDeviceFlagBackup(&MockDevice::createSingleDevice, false);
282+
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
283+
284+
device->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(device->getMemoryManager(), device->getNumAvailableDevices() > 1, device->getRootDeviceIndex()));
285+
EXPECT_EQ(device->getBindlessHeapsHelper(), device->subdevices.at(0)->getBindlessHeapsHelper());
286+
}

0 commit comments

Comments
 (0)