feature: add memsetAllocation helper with blitter support

Related-To: NEO-12287
Signed-off-by: Fabian Zwoliński <fabian.zwolinski@intel.com>
This commit is contained in:
Fabian Zwoliński
2025-10-09 15:20:22 +00:00
committed by Compute-Runtime-Automation
parent c8b64f1970
commit 226846323f
15 changed files with 751 additions and 4 deletions

View File

@@ -456,9 +456,13 @@ void BlitCommandsHelper<GfxFamily>::dispatchBlitCommands(const BlitProperties &b
if (blitProperties.isImageOperation()) { if (blitProperties.isImageOperation()) {
dispatchBlitCommandsForImageRegion(blitProperties, linearStream, rootDeviceEnvironment); dispatchBlitCommandsForImageRegion(blitProperties, linearStream, rootDeviceEnvironment);
} else { } else {
bool preferCopyBufferRegion = isCopyRegionPreferred(blitProperties.copySize, rootDeviceEnvironment, blitProperties.isSystemMemoryPoolUsed); if (blitProperties.blitDirection == BlitterConstants::BlitDirection::fill) {
preferCopyBufferRegion ? dispatchBlitCommandsForBufferRegion(blitProperties, linearStream, rootDeviceEnvironment) dispatchBlitMemoryFill(blitProperties, linearStream, rootDeviceEnvironment);
: dispatchBlitCommandsForBufferPerRow(blitProperties, linearStream, rootDeviceEnvironment); } else {
bool preferCopyBufferRegion = isCopyRegionPreferred(blitProperties.copySize, rootDeviceEnvironment, blitProperties.isSystemMemoryPoolUsed);
preferCopyBufferRegion ? dispatchBlitCommandsForBufferRegion(blitProperties, linearStream, rootDeviceEnvironment)
: dispatchBlitCommandsForBufferPerRow(blitProperties, linearStream, rootDeviceEnvironment);
}
} }
} }

View File

@@ -18,6 +18,7 @@ namespace NEO {
namespace BlitHelperFunctions { namespace BlitHelperFunctions {
BlitMemoryToAllocationFunc blitMemoryToAllocation = BlitHelper::blitMemoryToAllocation; BlitMemoryToAllocationFunc blitMemoryToAllocation = BlitHelper::blitMemoryToAllocation;
BlitMemsetAllocationFunc blitMemsetAllocation = BlitHelper::blitMemsetAllocation;
} // namespace BlitHelperFunctions } // namespace BlitHelperFunctions
BlitOperationResult BlitHelper::blitMemoryToAllocation(const Device &device, GraphicsAllocation *memory, size_t offset, const void *hostPtr, BlitOperationResult BlitHelper::blitMemoryToAllocation(const Device &device, GraphicsAllocation *memory, size_t offset, const void *hostPtr,
@@ -74,4 +75,59 @@ BlitOperationResult BlitHelper::blitMemoryToAllocationBanks(const Device &device
return BlitOperationResult::success; return BlitOperationResult::success;
} }
BlitOperationResult BlitHelper::blitMemsetAllocation(const Device &device, GraphicsAllocation *memory, size_t offset, int value, size_t size) {
auto memoryBanks = memory->storageInfo.getMemoryBanks();
return blitMemsetAllocationBanks(device, memory, offset, value, size, memoryBanks);
}
BlitOperationResult BlitHelper::blitMemsetAllocationBanks(const Device &device, GraphicsAllocation *memory, size_t offset, int value,
size_t size, DeviceBitfield memoryBanks) {
const auto &hwInfo = device.getHardwareInfo();
if (!hwInfo.capabilityTable.blitterOperationsSupported) {
return BlitOperationResult::unsupported;
}
auto &gfxCoreHelper = device.getGfxCoreHelper();
UNRECOVERABLE_IF(memoryBanks.none());
auto pRootDevice = device.getRootDevice();
uint8_t byteValue = static_cast<uint8_t>(value);
uint32_t patternToCommand[4] = {};
memcpy_s(patternToCommand, sizeof(patternToCommand), &byteValue, 1);
for (uint8_t tileId = 0u; tileId < 4u; tileId++) {
if (!memoryBanks.test(tileId)) {
continue;
}
UNRECOVERABLE_IF(!pRootDevice->getDeviceBitfield().test(tileId));
auto pDeviceForBlit = pRootDevice->getNearestGenericSubDevice(tileId);
auto &selectorCopyEngine = pDeviceForBlit->getSelectorCopyEngine();
auto deviceBitfield = pDeviceForBlit->getDeviceBitfield();
auto internalUsage = true;
auto bcsEngineType = EngineHelpers::getBcsEngineType(pDeviceForBlit->getRootDeviceEnvironment(), deviceBitfield, selectorCopyEngine, internalUsage);
auto bcsEngineUsage = gfxCoreHelper.preferInternalBcsEngine() ? EngineUsage::internal : EngineUsage::regular;
auto bcsEngine = pDeviceForBlit->tryGetEngine(bcsEngineType, bcsEngineUsage);
if (!bcsEngine) {
return BlitOperationResult::unsupported;
}
bcsEngine->commandStreamReceiver->initializeResources(false, device.getPreemptionMode());
bcsEngine->commandStreamReceiver->initDirectSubmission();
BlitPropertiesContainer blitPropertiesContainer;
blitPropertiesContainer.push_back(
BlitProperties::constructPropertiesForMemoryFill(
memory, 0, size, patternToCommand, 1, offset));
const auto newTaskCount = bcsEngine->commandStreamReceiver->flushBcsTask(blitPropertiesContainer, true, *pDeviceForBlit);
if (newTaskCount == CompletionStamp::gpuHang) {
return BlitOperationResult::gpuHang;
}
}
return BlitOperationResult::success;
}
} // namespace NEO } // namespace NEO

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2023 Intel Corporation * Copyright (C) 2023-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -29,7 +29,13 @@ using BlitMemoryToAllocationFunc = std::function<BlitOperationResult(const Devic
size_t offset, size_t offset,
const void *hostPtr, const void *hostPtr,
const Vec3<size_t> &size)>; const Vec3<size_t> &size)>;
using BlitMemsetAllocationFunc = std::function<BlitOperationResult(const Device &device,
GraphicsAllocation *memory,
size_t offset,
int value,
size_t size)>;
extern BlitMemoryToAllocationFunc blitMemoryToAllocation; extern BlitMemoryToAllocationFunc blitMemoryToAllocation;
extern BlitMemsetAllocationFunc blitMemsetAllocation;
} // namespace BlitHelperFunctions } // namespace BlitHelperFunctions
struct BlitHelper { struct BlitHelper {
@@ -37,6 +43,10 @@ struct BlitHelper {
const Vec3<size_t> &size); const Vec3<size_t> &size);
static BlitOperationResult blitMemoryToAllocationBanks(const Device &device, GraphicsAllocation *memory, size_t offset, const void *hostPtr, static BlitOperationResult blitMemoryToAllocationBanks(const Device &device, GraphicsAllocation *memory, size_t offset, const void *hostPtr,
const Vec3<size_t> &size, DeviceBitfield memoryBanks); const Vec3<size_t> &size, DeviceBitfield memoryBanks);
static BlitOperationResult blitMemsetAllocation(const Device &device, GraphicsAllocation *memory, size_t offset, int value,
size_t size);
static BlitOperationResult blitMemsetAllocationBanks(const Device &device, GraphicsAllocation *memory, size_t offset, int value,
size_t size, DeviceBitfield memoryBanks);
}; };
} // namespace NEO } // namespace NEO

View File

@@ -1023,6 +1023,33 @@ bool MemoryManager::copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllo
(graphicsAllocation->getUnderlyingBufferSize() - destinationOffset), memoryToCopy, sizeToCopy); (graphicsAllocation->getUnderlyingBufferSize() - destinationOffset), memoryToCopy, sizeToCopy);
return true; return true;
} }
bool MemoryManager::memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet) {
if (!graphicsAllocation->getUnderlyingBuffer()) {
return false;
}
DEBUG_BREAK_IF(graphicsAllocation->storageInfo.getNumBanks() > 1 &&
!GraphicsAllocation::isDebugSurfaceAllocationType(graphicsAllocation->getAllocationType()));
for (auto i = 0u; i < graphicsAllocation->storageInfo.getNumBanks(); ++i) {
memset(ptrOffset(static_cast<uint8_t *>(graphicsAllocation->getUnderlyingBuffer()) + i * graphicsAllocation->getUnderlyingBufferSize(),
destinationOffset),
value, sizeToSet);
if (!GraphicsAllocation::isDebugSurfaceAllocationType(graphicsAllocation->getAllocationType())) {
break;
}
}
return true;
}
bool MemoryManager::memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) {
DEBUG_BREAK_IF(graphicsAllocation->storageInfo.getNumBanks() > 1 && handleMask.count() > 0);
memset(ptrOffset(static_cast<uint8_t *>(graphicsAllocation->getUnderlyingBuffer()), destinationOffset), value, sizeToSet);
return true;
}
void MemoryManager::waitForEnginesCompletion(GraphicsAllocation &graphicsAllocation) { void MemoryManager::waitForEnginesCompletion(GraphicsAllocation &graphicsAllocation) {
for (auto &engine : getRegisteredEngines(graphicsAllocation.getRootDeviceIndex())) { for (auto &engine : getRegisteredEngines(graphicsAllocation.getRootDeviceIndex())) {
auto osContextId = engine.osContext->getContextId(); auto osContextId = engine.osContext->getContextId();
@@ -1293,6 +1320,20 @@ bool MemoryTransferHelper::transferMemoryToAllocationBanks(bool useBlitter, cons
return true; return true;
} }
bool MemoryTransferHelper::memsetAllocation(bool useBlitter, const Device &device, GraphicsAllocation *dstAllocation,
size_t dstOffset, int value, size_t size) {
auto blitSuccess = false;
if (useBlitter) {
blitSuccess = BlitHelperFunctions::blitMemsetAllocation(device, dstAllocation, dstOffset, value, size) == BlitOperationResult::success;
}
if (!blitSuccess) {
return device.getMemoryManager()->memsetAllocation(dstAllocation, dstOffset, value, size);
}
return true;
}
uint64_t MemoryManager::adjustToggleBitFlagForGpuVa(AllocationType inputAllocationType, uint64_t gpuAddress) { uint64_t MemoryManager::adjustToggleBitFlagForGpuVa(AllocationType inputAllocationType, uint64_t gpuAddress) {
if (debugManager.flags.ToggleBitIn57GpuVa.get() != "unk") { if (debugManager.flags.ToggleBitIn57GpuVa.get() != "unk") {
auto toggleBitIn57GpuVaEntries = StringHelpers::split(debugManager.flags.ToggleBitIn57GpuVa.get(), ","); auto toggleBitIn57GpuVaEntries = StringHelpers::split(debugManager.flags.ToggleBitIn57GpuVa.get(), ",");

View File

@@ -98,6 +98,8 @@ namespace MemoryTransferHelper {
bool transferMemoryToAllocation(bool useBlitter, const Device &device, GraphicsAllocation *dstAllocation, size_t dstOffset, const void *srcMemory, size_t srcSize); bool transferMemoryToAllocation(bool useBlitter, const Device &device, GraphicsAllocation *dstAllocation, size_t dstOffset, const void *srcMemory, size_t srcSize);
bool transferMemoryToAllocationBanks(bool useBlitter, const Device &device, GraphicsAllocation *dstAllocation, size_t dstOffset, const void *srcMemory, bool transferMemoryToAllocationBanks(bool useBlitter, const Device &device, GraphicsAllocation *dstAllocation, size_t dstOffset, const void *srcMemory,
size_t srcSize, DeviceBitfield dstMemoryBanks); size_t srcSize, DeviceBitfield dstMemoryBanks);
bool memsetAllocation(bool useBlitter, const Device &device, GraphicsAllocation *dstAllocation, size_t dstOffset,
int value, size_t size);
} // namespace MemoryTransferHelper } // namespace MemoryTransferHelper
class MemoryManager { class MemoryManager {
@@ -254,6 +256,8 @@ class MemoryManager {
virtual bool copyMemoryToAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy); virtual bool copyMemoryToAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy);
virtual bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask); virtual bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask);
virtual bool memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet);
virtual bool memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask);
HeapIndex selectHeap(const GraphicsAllocation *allocation, bool hasPointer, bool isFullRangeSVM, bool useFrontWindow); HeapIndex selectHeap(const GraphicsAllocation *allocation, bool hasPointer, bool isFullRangeSVM, bool useFrontWindow);
static std::unique_ptr<MemoryManager> createMemoryManager(ExecutionEnvironment &executionEnvironment, DriverModelType driverModel); static std::unique_ptr<MemoryManager> createMemoryManager(ExecutionEnvironment &executionEnvironment, DriverModelType driverModel);
virtual void *reserveCpuAddressRange(size_t size, uint32_t rootDeviceIndex) { return nullptr; }; virtual void *reserveCpuAddressRange(size_t size, uint32_t rootDeviceIndex) { return nullptr; };

View File

@@ -1911,6 +1911,32 @@ bool DrmMemoryManager::copyMemoryToAllocationBanks(GraphicsAllocation *graphicsA
return true; return true;
} }
bool DrmMemoryManager::memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet) {
if (graphicsAllocation->getUnderlyingBuffer() && (graphicsAllocation->storageInfo.getNumBanks() == 1 || GraphicsAllocation::isDebugSurfaceAllocationType(graphicsAllocation->getAllocationType()))) {
return MemoryManager::memsetAllocation(graphicsAllocation, destinationOffset, value, sizeToSet);
}
return memsetAllocationBanks(graphicsAllocation, destinationOffset, value, sizeToSet, maxNBitValue(graphicsAllocation->storageInfo.getNumBanks()));
}
bool DrmMemoryManager::memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) {
if (MemoryPoolHelper::isSystemMemoryPool(graphicsAllocation->getMemoryPool())) {
return false;
}
auto drmAllocation = static_cast<DrmAllocation *>(graphicsAllocation);
for (auto handleId = 0u; handleId < graphicsAllocation->storageInfo.getNumBanks(); handleId++) {
if (!handleMask.test(handleId)) {
continue;
}
auto ptr = lockBufferObject(drmAllocation->getBOs()[handleId]);
if (!ptr) {
return false;
}
memset(ptrOffset(ptr, destinationOffset), value, sizeToSet);
this->unlockBufferObject(drmAllocation->getBOs()[handleId]);
}
return true;
}
void DrmMemoryManager::unlockBufferObject(BufferObject *bo) { void DrmMemoryManager::unlockBufferObject(BufferObject *bo) {
if (bo == nullptr) { if (bo == nullptr) {
return; return;

View File

@@ -72,6 +72,8 @@ class DrmMemoryManager : public MemoryManager {
DrmGemCloseWorker *peekGemCloseWorker() const { return this->gemCloseWorker.get(); } DrmGemCloseWorker *peekGemCloseWorker() const { return this->gemCloseWorker.get(); }
bool copyMemoryToAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy) override; bool copyMemoryToAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy) override;
bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override; bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override;
bool memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet) override;
bool memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) override;
MOCKABLE_VIRTUAL int obtainFdFromHandle(int boHandle, uint32_t rootDeviceindex); MOCKABLE_VIRTUAL int obtainFdFromHandle(int boHandle, uint32_t rootDeviceindex);
AddressRange reserveGpuAddress(const uint64_t requiredStartAddress, size_t size, const RootDeviceIndicesContainer &rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) override; AddressRange reserveGpuAddress(const uint64_t requiredStartAddress, size_t size, const RootDeviceIndicesContainer &rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) override;

View File

@@ -1260,6 +1260,34 @@ bool WddmMemoryManager::copyMemoryToAllocationBanks(GraphicsAllocation *graphics
return true; return true;
} }
bool WddmMemoryManager::memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet) {
if (graphicsAllocation->getUnderlyingBuffer() && (graphicsAllocation->storageInfo.getNumBanks() == 1 || GraphicsAllocation::isDebugSurfaceAllocationType(graphicsAllocation->getAllocationType()))) {
return MemoryManager::memsetAllocation(graphicsAllocation, destinationOffset, value, sizeToSet);
}
return memsetAllocationBanks(graphicsAllocation, destinationOffset, value, sizeToSet, maxNBitValue(graphicsAllocation->storageInfo.getNumBanks()));
}
bool WddmMemoryManager::memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) {
if (MemoryPoolHelper::isSystemMemoryPool(graphicsAllocation->getMemoryPool())) {
return false;
}
auto &wddm = getWddm(graphicsAllocation->getRootDeviceIndex());
auto wddmAllocation = static_cast<WddmAllocation *>(graphicsAllocation);
for (auto handleId = 0u; handleId < graphicsAllocation->storageInfo.getNumBanks(); handleId++) {
if (!handleMask.test(handleId)) {
continue;
}
auto ptr = wddm.lockResource(wddmAllocation->getHandles()[handleId], wddmAllocation->needsMakeResidentBeforeLock(), wddmAllocation->getAlignedSize());
if (!ptr) {
return false;
}
memset(ptrOffset(ptr, destinationOffset), value, sizeToSet);
wddm.unlockResource(wddmAllocation->getHandles()[handleId], wddmAllocation->needsMakeResidentBeforeLock());
}
wddmAllocation->setExplicitlyMadeResident(wddmAllocation->needsMakeResidentBeforeLock());
return true;
}
void createColouredGmms(GmmHelper *gmmHelper, WddmAllocation &allocation, const StorageInfo &storageInfo, bool compression) { void createColouredGmms(GmmHelper *gmmHelper, WddmAllocation &allocation, const StorageInfo &storageInfo, bool compression) {
auto remainingSize = allocation.getAlignedSize(); auto remainingSize = allocation.getAlignedSize();
auto handles = storageInfo.getNumBanks(); auto handles = storageInfo.getNumBanks();

View File

@@ -57,6 +57,9 @@ class WddmMemoryManager : public MemoryManager, NEO::NonCopyableAndNonMovableCla
bool copyMemoryToAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy) override; bool copyMemoryToAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy) override;
bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override; bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override;
bool memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet) override;
bool memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) override;
void *reserveCpuAddressRange(size_t size, uint32_t rootDeviceIndex) override; void *reserveCpuAddressRange(size_t size, uint32_t rootDeviceIndex) override;
void releaseReservedCpuAddressRange(void *reserved, size_t size, uint32_t rootDeviceIndex) override; void releaseReservedCpuAddressRange(void *reserved, size_t size, uint32_t rootDeviceIndex) override;
bool isCpuCopyRequired(const void *ptr) override; bool isCpuCopyRequired(const void *ptr) override;

View File

@@ -281,6 +281,11 @@ class MockMemoryManager : public MemoryManagerCreate<OsAgnosticMemoryManager> {
StackVec<CopyMemoryToAllocationBanksParams, 2> copyMemoryToAllocationBanksParamsPassed{}; StackVec<CopyMemoryToAllocationBanksParams, 2> copyMemoryToAllocationBanksParamsPassed{};
bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override; bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override;
bool memsetAllocation(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet) override {
memsetAllocationCalled++;
return MemoryManager::memsetAllocation(graphicsAllocation, destinationOffset, value, sizeToSet);
}
MemoryManager::AllocationStatus populateOsHandles(OsHandleStorage &handleStorage, uint32_t rootDeviceIndex) override { MemoryManager::AllocationStatus populateOsHandles(OsHandleStorage &handleStorage, uint32_t rootDeviceIndex) override {
populateOsHandlesCalled++; populateOsHandlesCalled++;
populateOsHandlesParamsPassed.push_back({handleStorage, rootDeviceIndex}); populateOsHandlesParamsPassed.push_back({handleStorage, rootDeviceIndex});
@@ -360,6 +365,7 @@ class MockMemoryManager : public MemoryManagerCreate<OsAgnosticMemoryManager> {
MockGraphicsAllocation *mockGa; MockGraphicsAllocation *mockGa;
size_t ipcAllocationSize = 4096u; size_t ipcAllocationSize = 4096u;
uint32_t copyMemoryToAllocationBanksCalled = 0u; uint32_t copyMemoryToAllocationBanksCalled = 0u;
uint32_t memsetAllocationCalled = 0u;
uint32_t populateOsHandlesCalled = 0u; uint32_t populateOsHandlesCalled = 0u;
uint32_t allocateGraphicsMemoryForNonSvmHostPtrCalled = 0u; uint32_t allocateGraphicsMemoryForNonSvmHostPtrCalled = 0u;
uint32_t freeGraphicsMemoryCalled = 0u; uint32_t freeGraphicsMemoryCalled = 0u;

View File

@@ -91,6 +91,11 @@ class MockWddmMemoryManager : public MemoryManagerCreate<WddmMemoryManager> {
return BaseClass::copyMemoryToAllocationBanks(graphicsAllocation, destinationOffset, memoryToCopy, sizeToCopy, handleMask); return BaseClass::copyMemoryToAllocationBanks(graphicsAllocation, destinationOffset, memoryToCopy, sizeToCopy, handleMask);
} }
bool memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) override {
memsetAllocationBanksCalled++;
return BaseClass::memsetAllocationBanks(graphicsAllocation, destinationOffset, value, sizeToSet, handleMask);
}
void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation, bool isImportedAllocation) override { void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation, bool isImportedAllocation) override {
BaseClass::freeGraphicsMemoryImpl(gfxAllocation, isImportedAllocation); BaseClass::freeGraphicsMemoryImpl(gfxAllocation, isImportedAllocation);
} }
@@ -105,6 +110,7 @@ class MockWddmMemoryManager : public MemoryManagerCreate<WddmMemoryManager> {
BaseClass::registerAllocationInOs(gfxAllocation); BaseClass::registerAllocationInOs(gfxAllocation);
} }
uint32_t copyMemoryToAllocationBanksCalled = 0u; uint32_t copyMemoryToAllocationBanksCalled = 0u;
uint32_t memsetAllocationBanksCalled = 0u;
uint32_t freeGraphicsMemoryImplCalled = 0u; uint32_t freeGraphicsMemoryImplCalled = 0u;
uint32_t registerAllocationInOsCalled = 0; uint32_t registerAllocationInOsCalled = 0;
bool allocationGraphicsMemory64kbCreated = false; bool allocationGraphicsMemory64kbCreated = false;

View File

@@ -41,7 +41,9 @@
#include "shared/test/common/mocks/mock_memory_manager.h" #include "shared/test/common/mocks/mock_memory_manager.h"
#include "shared/test/common/mocks/mock_os_context.h" #include "shared/test/common/mocks/mock_os_context.h"
#include "shared/test/common/mocks/mock_release_helper.h" #include "shared/test/common/mocks/mock_release_helper.h"
#include "shared/test/common/mocks/ult_device_factory.h"
#include "shared/test/common/test_macros/hw_test.h" #include "shared/test/common/test_macros/hw_test.h"
#include "shared/test/common/test_macros/test_checks_shared.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
@@ -121,6 +123,18 @@ TEST(MemoryManagerTest, givenAllocationWithNullCpuPtrThenMemoryCopyToAllocationR
EXPECT_FALSE(memoryManager.copyMemoryToAllocation(&allocation, offset, nullptr, 0)); EXPECT_FALSE(memoryManager.copyMemoryToAllocation(&allocation, offset, nullptr, 0));
} }
TEST(MemoryManagerTest, givenAllocationWithNullCpuPtrThenMemsetAllocationReturnsFalse) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, false, executionEnvironment);
constexpr uint8_t allocationSize = 10;
uint8_t allocationStorage[allocationSize] = {0};
MockGraphicsAllocation allocation{allocationStorage, allocationSize};
allocation.cpuPtr = nullptr;
constexpr size_t offset = 0;
EXPECT_FALSE(memoryManager.memsetAllocation(&allocation, offset, 2, 0));
}
TEST(MemoryManagerTest, givenDeviceGraphicsAllocationWhenMapCalledThenDontResetCpuAddress) { TEST(MemoryManagerTest, givenDeviceGraphicsAllocationWhenMapCalledThenDontResetCpuAddress) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, false, executionEnvironment); MockMemoryManager memoryManager(false, false, executionEnvironment);
@@ -2675,6 +2689,39 @@ TEST(MemoryManagerCopyMemoryTest, givenValidAllocationAndMemoryWhenCopyMemoryToA
EXPECT_EQ(memory, allocationStorage[offset]); EXPECT_EQ(memory, allocationStorage[offset]);
} }
TEST(MemoryManagerMemsetTest, givenValidAllocationWhenMemsetAllocationThenDataIsFilled) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, false, executionEnvironment);
constexpr uint8_t allocationSize = 10;
uint8_t allocationStorage[allocationSize] = {0};
MockGraphicsAllocation allocation{allocationStorage, allocationSize};
uint8_t value = 0x42;
EXPECT_EQ(0u, allocationStorage[0]);
size_t offset = 2;
size_t size = 1;
EXPECT_TRUE(memoryManager.memsetAllocation(&allocation, offset, value, size));
EXPECT_EQ(value, allocationStorage[offset]);
}
TEST(MemoryManagerMemsetTest, givenValidAllocationWhenMemsetAllocationBanksThenDataIsFilled) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
MockMemoryManager memoryManager(false, false, executionEnvironment);
constexpr uint8_t allocationSize = 10;
uint8_t allocationStorage[allocationSize] = {0};
MockGraphicsAllocation allocation{allocationStorage, allocationSize};
uint8_t value = 0x42;
EXPECT_EQ(0u, allocationStorage[0]);
size_t offset = 2;
size_t size = 1;
DeviceBitfield handleMask{};
EXPECT_TRUE(memoryManager.memsetAllocationBanks(&allocation, offset, value, size, handleMask));
EXPECT_EQ(value, allocationStorage[offset]);
}
TEST_F(MemoryAllocatorTest, whenReservingAddressRangeThenExpectProperAddressAndReleaseWhenFreeing) { TEST_F(MemoryAllocatorTest, whenReservingAddressRangeThenExpectProperAddressAndReleaseWhenFreeing) {
size_t size = 0x1000; size_t size = 0x1000;
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), size}); auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{csr->getRootDeviceIndex(), size});
@@ -3202,6 +3249,118 @@ TEST(MemoryTransferHelperTest, givenBlitOperationSupportedWhenBcsEngineNotAvaila
EXPECT_EQ(BlitOperationResult::unsupported, BlitHelperFunctions::blitMemoryToAllocation(*device, &graphicsAllocation, 0, srcData, {dataSize, 1, 1})); EXPECT_EQ(BlitOperationResult::unsupported, BlitHelperFunctions::blitMemoryToAllocation(*device, &graphicsAllocation, 0, srcData, {dataSize, 1, 1}));
} }
TEST(MemoryTransferHelperTest, givenBlitterSuccessWhenMemsetAllocationThenCpuMemsetIsNotCalled) {
VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
UltDeviceFactory deviceFactory{1, 2};
MockDevice &device = *deviceFactory.rootDevices[0];
auto memoryManager = static_cast<MockMemoryManager *>(device.getMemoryManager());
REQUIRE_BLITTER_OR_SKIP(device.getRootDeviceEnvironment());
constexpr uint32_t dataSize = 16;
uint8_t destData[dataSize] = {};
MockGraphicsAllocation graphicsAllocation{destData, sizeof(destData)};
graphicsAllocation.storageInfo.memoryBanks = 1;
graphicsAllocation.setAllocationType(AllocationType::bufferHostMemory);
const size_t offset = 0u;
const int value = 2;
auto result = MemoryTransferHelper::memsetAllocation(true, device, &graphicsAllocation, offset, value, dataSize);
EXPECT_TRUE(result);
EXPECT_EQ(0u, memoryManager->memsetAllocationCalled);
}
TEST(MemoryTransferMemsetAllocationHelperTest, givenMemsetAllocationWhenBlitterNotSupportedThenFallbackToMemsetOnCPU) {
constexpr uint32_t dataSize = 16;
uint8_t destData[dataSize] = {};
std::fill_n(destData, dataSize, 0xFF);
MockGraphicsAllocation graphicsAllocation{destData, sizeof(destData)};
graphicsAllocation.setAllocationType(AllocationType::bufferHostMemory);
auto hwInfo = *defaultHwInfo;
hwInfo.capabilityTable.blitterOperationsSupported = false;
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
const size_t offset = 0u;
const int value = 2;
EXPECT_EQ(BlitOperationResult::unsupported, BlitHelperFunctions::blitMemsetAllocation(*device, &graphicsAllocation, offset, value, dataSize));
auto result = MemoryTransferHelper::memsetAllocation(true, *device, &graphicsAllocation, offset, value, dataSize);
EXPECT_TRUE(result);
for (size_t i = 0; i < dataSize; i++) {
EXPECT_EQ(value, destData[i]) << "Byte at index " << i << " mismatch";
}
}
TEST(MemoryTransferMemsetAllocationHelperTest, givenBlitOperationSupportedWhenBcsEngineNotAvailableThenReturnUnsupported) {
constexpr uint32_t dataSize = 16;
uint8_t destData[dataSize] = {};
MockGraphicsAllocation graphicsAllocation{destData, sizeof(destData)};
graphicsAllocation.storageInfo.memoryBanks = 1;
graphicsAllocation.setAllocationType(AllocationType::buffer);
auto hwInfo = *defaultHwInfo;
hwInfo.capabilityTable.blitterOperationsSupported = true;
hwInfo.featureTable.ftrBcsInfo = 0;
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
auto bcsEngine = device->tryGetEngine(aub_stream::EngineType::ENGINE_BCS, EngineUsage::regular);
EXPECT_EQ(nullptr, bcsEngine);
const size_t offset = 0u;
const int value = 2;
EXPECT_EQ(BlitOperationResult::unsupported, BlitHelperFunctions::blitMemsetAllocation(*device, &graphicsAllocation, offset, value, dataSize));
}
TEST(MemoryTransferMemsetAllocationHelperTest, givenMemsetAllocationWithOffsetThenFillsCorrectRegion) {
constexpr uint32_t dataSize = 32;
uint8_t destData[dataSize] = {};
std::fill_n(destData, dataSize, 0xFF);
MockGraphicsAllocation graphicsAllocation{destData, sizeof(destData)};
graphicsAllocation.setAllocationType(AllocationType::bufferHostMemory);
auto hwInfo = *defaultHwInfo;
hwInfo.capabilityTable.blitterOperationsSupported = false;
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
const size_t offset = 8u;
const int value = 0x42;
const size_t size = 16u;
auto result = MemoryTransferHelper::memsetAllocation(false, *device, &graphicsAllocation, offset, value, size);
EXPECT_TRUE(result);
// Pre-offset region unchanged
for (size_t i = 0; i < offset; i++) {
EXPECT_EQ(0xFF, destData[i]);
}
// Verify the filled region
for (size_t i = offset; i < offset + size; i++) {
EXPECT_EQ(value, destData[i]);
}
// Post-fill region unchanged
for (size_t i = offset + size; i < dataSize; i++) {
EXPECT_EQ(0xFF, destData[i]);
}
}
TEST(MemoryManagerTest, givenMemoryManagerWithLocalMemoryWhenCreatingMultiGraphicsAllocationInSystemMemoryThenForceSystemMemoryPlacement) { TEST(MemoryManagerTest, givenMemoryManagerWithLocalMemoryWhenCreatingMultiGraphicsAllocationInSystemMemoryThenForceSystemMemoryPlacement) {
MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); MockExecutionEnvironment executionEnvironment(defaultHwInfo.get());
executionEnvironment.initGmm(); executionEnvironment.initGmm();

View File

@@ -2453,6 +2453,216 @@ TEST_F(DrmMemoryManagerCopyMemoryToAllocationPrelimTest, givenDrmMemoryManagerWh
drmMemoryManager.freeGraphicsMemory(allocation); drmMemoryManager.freeGraphicsMemory(allocation);
} }
using DrmMemoryManagerMemsetAllocationPrelimTest = DrmMemoryManagerLocalMemoryPrelimTest;
struct DrmMemoryManagerToTestMemsetAllocation : public DrmMemoryManager {
using DrmMemoryManager::allocateGraphicsMemoryInDevicePool;
DrmMemoryManagerToTestMemsetAllocation(ExecutionEnvironment &executionEnvironment, bool localMemoryEnabled, size_t lockableLocalMemorySize)
: DrmMemoryManager(GemCloseWorkerMode::gemCloseWorkerInactive, false, false, executionEnvironment) {
std::fill(this->localMemorySupported.begin(), this->localMemorySupported.end(), localMemoryEnabled);
lockedLocalMemorySize = lockableLocalMemorySize;
}
void *lockResourceImpl(GraphicsAllocation &graphicsAllocation) override {
if (lockedLocalMemorySize > 0) {
lockedLocalMemory[0].reset(new uint8_t[lockedLocalMemorySize]);
return lockedLocalMemory[0].get();
}
return nullptr;
}
void *lockBufferObject(BufferObject *bo) override {
if (lockedLocalMemorySize > 0) {
deviceIndex = (deviceIndex < 3) ? deviceIndex + 1u : 0u;
lockedLocalMemory[deviceIndex].reset(new uint8_t[lockedLocalMemorySize]);
return lockedLocalMemory[deviceIndex].get();
}
return nullptr;
}
void unlockBufferObject(BufferObject *bo) override {
}
void unlockResourceImpl(GraphicsAllocation &graphicsAllocation) override {
}
bool memsetAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, int value, size_t sizeToSet, DeviceBitfield handleMask) override {
memsetAllocationBanksCalled++;
return DrmMemoryManager::memsetAllocationBanks(graphicsAllocation, destinationOffset, value, sizeToSet, handleMask);
}
std::array<std::unique_ptr<uint8_t[]>, 4> lockedLocalMemory;
uint32_t deviceIndex = 3;
size_t lockedLocalMemorySize = 0;
uint32_t memsetAllocationBanksCalled = 0;
};
TEST_F(DrmMemoryManagerMemsetAllocationPrelimTest, givenDrmMemoryManagerWhenMemsetAllocationReturnsSuccessThenAllocationIsFilledWithCorrectData) {
size_t offset = 3;
size_t allocationSize = MemoryConstants::pageSize;
size_t destinationAllocationSize = allocationSize + offset;
DrmMemoryManagerToTestMemsetAllocation drmMemoryManager(*executionEnvironment, true, destinationAllocationSize);
int value = 0x42;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = allocationSize;
allocData.flags.allocateMemory = true;
allocData.type = AllocationType::kernelIsa;
allocData.rootDeviceIndex = rootDeviceIndex;
allocData.storageInfo.memoryBanks.set(0, true);
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
auto allocation = drmMemoryManager.allocateGraphicsMemoryInDevicePool(allocData, status);
ASSERT_NE(nullptr, allocation);
auto ret = drmMemoryManager.memsetAllocation(allocation, offset, value, allocationSize);
EXPECT_TRUE(ret);
auto ptr = ptrOffset(drmMemoryManager.lockedLocalMemory[0].get(), offset);
for (size_t i = 0; i < allocationSize; i++) {
EXPECT_EQ(value, static_cast<uint8_t *>(ptr)[i]);
}
drmMemoryManager.freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerMemsetAllocationPrelimTest, givenDrmMemoryManagerWhenMemsetMultiTileAllocationThenCallMemsetAllocationBanks) {
size_t allocationSize = MemoryConstants::pageSize;
DrmMemoryManagerToTestMemsetAllocation drmMemoryManager(*executionEnvironment, true, allocationSize);
int value = 0x42;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = allocationSize;
allocData.flags.allocateMemory = true;
allocData.type = AllocationType::constantSurface;
allocData.rootDeviceIndex = rootDeviceIndex;
allocData.storageInfo.memoryBanks = 0b11;
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
auto allocation = drmMemoryManager.allocateGraphicsMemoryInDevicePool(allocData, status);
ASSERT_NE(nullptr, allocation);
char data = 0;
allocation->setCpuPtrAndGpuAddress(&data, allocation->getGpuAddress());
auto ret = drmMemoryManager.memsetAllocation(allocation, 0, value, allocationSize);
EXPECT_TRUE(ret);
EXPECT_EQ(1u, drmMemoryManager.memsetAllocationBanksCalled);
drmMemoryManager.freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerMemsetAllocationPrelimTest, givenDrmMemoryManagerWhenMemsetAllocationFailsToLockResourceThenItReturnsFalse) {
DrmMemoryManagerToTestMemsetAllocation drmMemoryManager(*executionEnvironment, true, 0);
size_t allocationSize = MemoryConstants::pageSize;
int value = 0x42;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = allocationSize;
allocData.flags.allocateMemory = true;
allocData.type = AllocationType::kernelIsa;
allocData.rootDeviceIndex = rootDeviceIndex;
allocData.storageInfo.memoryBanks.set(0, true);
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
auto allocation = drmMemoryManager.allocateGraphicsMemoryInDevicePool(allocData, status);
ASSERT_NE(nullptr, allocation);
auto ret = drmMemoryManager.memsetAllocation(allocation, 0, value, allocationSize);
EXPECT_FALSE(ret);
drmMemoryManager.freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerMemsetAllocationPrelimTest, givenDrmMemoryManagerWhenMemsetAllocationWithCpuPtrThenAllocationIsFilledWithCorrectData) {
size_t offset = 3;
size_t allocationSize = MemoryConstants::pageSize;
size_t destinationAllocationSize = allocationSize + offset;
DrmMemoryManagerToTestMemsetAllocation drmMemoryManager(*executionEnvironment, false, 0);
int value = 0x42;
auto allocation = drmMemoryManager.allocateGraphicsMemoryWithProperties({mockRootDeviceIndex, destinationAllocationSize, AllocationType::kernelIsa, mockDeviceBitfield});
ASSERT_NE(nullptr, allocation);
auto ret = drmMemoryManager.memsetAllocation(allocation, offset, value, allocationSize);
EXPECT_TRUE(ret);
auto ptr = ptrOffset(allocation->getUnderlyingBuffer(), offset);
for (size_t i = 0; i < allocationSize; i++) {
EXPECT_EQ(value, static_cast<uint8_t *>(ptr)[i]);
}
drmMemoryManager.freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerMemsetAllocationPrelimTest, givenDrmMemoryManagerWhenMemsetAllocationOnAllMemoryBanksReturnsSuccessThenAllocationIsFilledWithCorrectData) {
size_t offset = 3;
size_t allocationSize = MemoryConstants::pageSize;
size_t destinationAllocationSize = allocationSize + offset;
DrmMemoryManagerToTestMemsetAllocation drmMemoryManager(*executionEnvironment, true, destinationAllocationSize);
int value = 0x42;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = allocationSize;
allocData.flags.allocateMemory = true;
allocData.type = AllocationType::kernelIsa;
allocData.storageInfo.memoryBanks = maxNBitValue(MemoryBanks::getBankForLocalMemory(3));
allocData.rootDeviceIndex = rootDeviceIndex;
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
auto allocation = drmMemoryManager.allocateGraphicsMemoryInDevicePool(allocData, status);
ASSERT_NE(nullptr, allocation);
auto ret = drmMemoryManager.memsetAllocation(allocation, offset, value, allocationSize);
EXPECT_TRUE(ret);
for (auto index = 0u; index < 3; index++) {
auto ptr = ptrOffset(drmMemoryManager.lockedLocalMemory[index].get(), offset);
for (size_t i = 0; i < allocationSize; i++) {
EXPECT_EQ(value, static_cast<uint8_t *>(ptr)[i]);
}
}
drmMemoryManager.freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerMemsetAllocationPrelimTest, givenDrmMemoryManagerWhenMemsetAllocationOnSelectiveMemoryBanksThenOnlySelectedBanksAreFilled) {
size_t offset = 3;
size_t allocationSize = MemoryConstants::pageSize;
size_t destinationAllocationSize = allocationSize + offset;
DrmMemoryManagerToTestMemsetAllocation drmMemoryManager(*executionEnvironment, true, destinationAllocationSize);
int value = 0x42;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = allocationSize;
allocData.flags.allocateMemory = true;
allocData.type = AllocationType::kernelIsa;
allocData.storageInfo.memoryBanks = maxNBitValue(MemoryBanks::getBankForLocalMemory(3));
allocData.rootDeviceIndex = rootDeviceIndex;
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
auto allocation = drmMemoryManager.allocateGraphicsMemoryInDevicePool(allocData, status);
ASSERT_NE(nullptr, allocation);
DeviceBitfield memsetBanks = 0b0101;
auto ret = drmMemoryManager.memsetAllocationBanks(allocation, offset, value, allocationSize, memsetBanks);
EXPECT_TRUE(ret);
for (auto lockedIndex = 0u; lockedIndex < 2u; lockedIndex++) {
ASSERT_NE(nullptr, drmMemoryManager.lockedLocalMemory[lockedIndex]);
auto ptr = ptrOffset(drmMemoryManager.lockedLocalMemory[lockedIndex].get(), offset);
for (size_t i = 0; i < allocationSize; i++) {
EXPECT_EQ(value, static_cast<uint8_t *>(ptr)[i]);
}
}
// Banks 1 and 3 were never locked
EXPECT_EQ(nullptr, drmMemoryManager.lockedLocalMemory[2]);
EXPECT_EQ(nullptr, drmMemoryManager.lockedLocalMemory[3]);
drmMemoryManager.freeGraphicsMemory(allocation);
}
typedef Test<DrmMemoryManagerFixturePrelim> DrmMemoryManagerTestPrelim; typedef Test<DrmMemoryManagerFixturePrelim> DrmMemoryManagerTestPrelim;
HWTEST_TEMPLATED_F(DrmMemoryManagerTestPrelim, whenSettingNumHandlesThenTheyAreRetrievedCorrectly) { HWTEST_TEMPLATED_F(DrmMemoryManagerTestPrelim, whenSettingNumHandlesThenTheyAreRetrievedCorrectly) {
@@ -3409,6 +3619,40 @@ TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, givenDrmMemoryManagerWhenCopyDebug
} }
} }
TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, givenDrmMemoryManagerWhenMemsetMultiTileDebugSurfaceAllocationThenCallMemsetAllocation) {
AllocationData allocationData{};
allocationData.size = MemoryConstants::pageSize;
allocationData.rootDeviceIndex = 0;
allocationData.storageInfo.memoryBanks = 0b11; // Two banks
allocationData.gpuAddress = 0x1000;
int value = 0x42;
AllocationType debugSurfaces[] = {AllocationType::debugContextSaveArea, AllocationType::debugSbaTrackingBuffer};
for (auto type : debugSurfaces) {
allocationData.type = type;
auto allocation = memoryManager->createMultiHostDebugSurfaceAllocation(allocationData);
EXPECT_NE(nullptr, allocation);
// For two banks, host size should be twice the allocation size
EXPECT_EQ(2 * MemoryConstants::pageSize, allocation->getMmapSize());
EXPECT_NE(nullptr, allocation->getMmapPtr());
auto ret = memoryManager->memsetAllocation(allocation, 0, value, allocationData.size);
EXPECT_TRUE(ret);
auto ptr = static_cast<uint8_t *>(allocation->getMmapPtr());
for (size_t i = 0; i < allocationData.size; i++) {
EXPECT_EQ(value, ptr[i]) << "Bank 0, byte at index " << i << " mismatch";
}
for (size_t i = 0; i < allocationData.size; i++) {
EXPECT_EQ(value, ptr[allocationData.size + i]) << "Bank 1, byte at index " << i << " mismatch";
}
memoryManager->freeGraphicsMemory(allocation);
}
}
TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, givenMoreThanOneSubDevicesWhenAllocatingDebugSbaTrackingBufferWithGpuVaThenAllTilesAreHandled) { TEST_F(DrmMemoryManagerLocalMemoryPrelimTest, givenMoreThanOneSubDevicesWhenAllocatingDebugSbaTrackingBufferWithGpuVaThenAllTilesAreHandled) {
// Configure mock to use mock behavior for createBufferObjectInMemoryRegion // Configure mock to use mock behavior for createBufferObjectInMemoryRegion
memoryManager->createBufferObjectInMemoryRegionCallBase = false; memoryManager->createBufferObjectInMemoryRegionCallBase = false;

View File

@@ -5623,6 +5623,21 @@ HWTEST_TEMPLATED_F(DrmMemoryManagerTest, givenDrmMemoryManagerWithoutLocalMemory
memoryManager.freeGraphicsMemory(allocation); memoryManager.freeGraphicsMemory(allocation);
} }
HWTEST_TEMPLATED_F(DrmMemoryManagerTest, givenDrmMemoryManagerWithoutLocalMemoryAndCpuPtrWhenMemsetAllocationThenReturnFalse) {
TestedDrmMemoryManager memoryManager(false, false, false, *executionEnvironment);
mock->ioctlExpected.gemUserptr = 1;
mock->ioctlExpected.gemWait = 1;
mock->ioctlExpected.gemClose = 1;
auto allocation = memoryManager.allocateGraphicsMemoryWithProperties({rootDeviceIndex, MemoryConstants::pageSize, AllocationType::buffer, device->getDeviceBitfield()});
ASSERT_NE(nullptr, allocation);
allocation->setCpuPtrAndGpuAddress(nullptr, 0u);
auto ret = memoryManager.memsetAllocation(allocation, 0, 2, MemoryConstants::pageSize);
EXPECT_FALSE(ret);
memoryManager.freeGraphicsMemory(allocation);
}
HWTEST_TEMPLATED_F(DrmMemoryManagerTest, givenNullDefaultAllocWhenCreateGraphicsAllocationFromExistingStorageThenDoNotImportHandle) { HWTEST_TEMPLATED_F(DrmMemoryManagerTest, givenNullDefaultAllocWhenCreateGraphicsAllocationFromExistingStorageThenDoNotImportHandle) {
TestedDrmMemoryManager memoryManager(false, false, false, *executionEnvironment); TestedDrmMemoryManager memoryManager(false, false, false, *executionEnvironment);
mock->ioctlExpected.primeFdToHandle = 0; mock->ioctlExpected.primeFdToHandle = 0;

View File

@@ -1524,6 +1524,32 @@ TEST_F(WddmMemoryManagerSimpleTest, givenLocalMemoryKernelIsaWithMemoryCopiedWhe
EXPECT_EQ(0u, mockTemporaryResources->evictResourceResult.called); EXPECT_EQ(0u, mockTemporaryResources->evictResourceResult.called);
} }
} }
TEST_F(WddmMemoryManagerSimpleTest, givenLocalMemoryKernelIsaWithMemorySetWhenDestroyingAllocationIfDeviceRequiresMakeResidentPriorToLockThenRemoveFromTemporaryResources) {
DebugManagerStateRestore restorer;
debugManager.flags.EnableLocalMemory.set(1);
AllocationProperties properties{0, true, MemoryConstants::pageSize, AllocationType::kernelIsa, false, false, 0};
properties.subDevicesBitfield.set(0);
memoryManager->localMemorySupported[properties.rootDeviceIndex] = true;
auto allocation = static_cast<WddmAllocation *>(memoryManager->allocateGraphicsMemoryWithProperties(properties));
ASSERT_NE(nullptr, allocation);
int value = 0x42;
memoryManager->memsetAllocation(allocation, 0, value, MemoryConstants::pageSize);
auto makeResidentPriorToLockRequired = memoryManager->peekExecutionEnvironment().rootDeviceEnvironments[0u]->getHelper<GfxCoreHelper>().makeResidentBeforeLockNeeded(allocation->needsMakeResidentBeforeLock());
EXPECT_EQ(makeResidentPriorToLockRequired, allocation->needsMakeResidentBeforeLock());
EXPECT_EQ(makeResidentPriorToLockRequired, allocation->isExplicitlyMadeResident());
memoryManager->freeGraphicsMemory(allocation);
if (makeResidentPriorToLockRequired) {
EXPECT_EQ(1u, mockTemporaryResources->removeResourceResult.called);
EXPECT_EQ(1u, mockTemporaryResources->evictResourceResult.called);
} else {
EXPECT_EQ(0u, mockTemporaryResources->removeResourceResult.called);
EXPECT_EQ(0u, mockTemporaryResources->evictResourceResult.called);
}
}
TEST_F(WddmMemoryManagerSimpleTest, whenDestroyingNotLockedAllocationThatDoesntNeedMakeResidentBeforeLockThenDontEvictAllocationFromWddmTemporaryResources) { TEST_F(WddmMemoryManagerSimpleTest, whenDestroyingNotLockedAllocationThatDoesntNeedMakeResidentBeforeLockThenDontEvictAllocationFromWddmTemporaryResources) {
DebugManagerStateRestore restorer; DebugManagerStateRestore restorer;
debugManager.flags.ForcePreferredAllocationMethod.set(static_cast<int32_t>(GfxMemoryAllocationMethod::useUmdSystemPtr)); debugManager.flags.ForcePreferredAllocationMethod.set(static_cast<int32_t>(GfxMemoryAllocationMethod::useUmdSystemPtr));
@@ -2610,6 +2636,39 @@ HWTEST_F(WddmMemoryManagerSimpleTest, givenWddmMemoryManagerWhenCopyNotDebugSurf
memoryManager->freeGraphicsMemory(allocation); memoryManager->freeGraphicsMemory(allocation);
} }
HWTEST_F(WddmMemoryManagerSimpleTest, givenWddmMemoryManagerWhenMemsetMultiTileDebugSurfaceAllocationThenCallMemsetAllocation) {
DebugManagerStateRestore restorer;
debugManager.flags.ForcePreferredAllocationMethod.set(static_cast<int32_t>(GfxMemoryAllocationMethod::useUmdSystemPtr));
size_t allocationSize = MemoryConstants::pageSize;
int value = 0x42;
AllocationType debugSurfaces[] = {AllocationType::debugContextSaveArea, AllocationType::debugSbaTrackingBuffer};
for (auto type : debugSurfaces) {
AllocationProperties debugSurfaceProperties{0, true, allocationSize, type, false, false, 0b11};
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(debugSurfaceProperties);
ASSERT_NE(nullptr, allocation);
auto ret = memoryManager->memsetAllocation(allocation, 0, value, allocationSize);
EXPECT_TRUE(ret);
EXPECT_EQ(0u, memoryManager->memsetAllocationBanksCalled);
memoryManager->freeGraphicsMemory(allocation);
}
}
HWTEST_F(WddmMemoryManagerSimpleTest, givenWddmMemoryManagerWhenMemsetNotDebugSurfaceMultiTileAllocationThenCallMemsetAllocationBanks) {
size_t allocationSize = MemoryConstants::pageSize;
int value = 0x42;
AllocationProperties props{0, true, allocationSize, AllocationType::kernelIsa, false, false, 0};
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(props);
ASSERT_NE(nullptr, allocation);
allocation->storageInfo.memoryBanks = 0b11;
memoryManager->memsetAllocation(allocation, 0, value, allocationSize);
EXPECT_EQ(1u, memoryManager->memsetAllocationBanksCalled);
memoryManager->freeGraphicsMemory(allocation);
}
HWTEST2_F(WddmMemoryManagerSimpleTest, givenPreferCompressionFlagWhenAllocating64kbAllocationThenCreateGmmWithAuxFlags, IsAtMostXeHpgCore) { HWTEST2_F(WddmMemoryManagerSimpleTest, givenPreferCompressionFlagWhenAllocating64kbAllocationThenCreateGmmWithAuxFlags, IsAtMostXeHpgCore) {
auto hwInfo = executionEnvironment.rootDeviceEnvironments[0]->getMutableHardwareInfo(); auto hwInfo = executionEnvironment.rootDeviceEnvironments[0]->getMutableHardwareInfo();
hwInfo->capabilityTable.ftrRenderCompressedBuffers = true; hwInfo->capabilityTable.ftrRenderCompressedBuffers = true;
@@ -2636,10 +2695,14 @@ struct WddmWithMockedLock : public WddmMock {
if (handle < storageLocked.size()) { if (handle < storageLocked.size()) {
storageLocked.set(handle); storageLocked.set(handle);
} }
if (handleToFail == handle) {
return nullptr;
}
return storages[handle]; return storages[handle];
} }
std::bitset<4> storageLocked{}; std::bitset<4> storageLocked{};
uint8_t storages[EngineLimits::maxHandleCount][MemoryConstants::pageSize64k] = {}; uint8_t storages[EngineLimits::maxHandleCount][MemoryConstants::pageSize64k] = {};
D3DKMT_HANDLE handleToFail = std::numeric_limits<D3DKMT_HANDLE>::max();
}; };
TEST(WddmMemoryManagerCopyMemoryToAllocationBanksTest, givenAllocationWithMultiTilePlacementWhenCopyDataSpecificMemoryBanksThenLockOnlySpecificStorages) { TEST(WddmMemoryManagerCopyMemoryToAllocationBanksTest, givenAllocationWithMultiTilePlacementWhenCopyDataSpecificMemoryBanksThenLockOnlySpecificStorages) {
@@ -2678,6 +2741,86 @@ TEST(WddmMemoryManagerCopyMemoryToAllocationBanksTest, givenAllocationWithMultiT
EXPECT_EQ(0, memcmp(ptrOffset(wddm->storages[3], offset), dataToCopy.data(), dataToCopy.size())); EXPECT_EQ(0, memcmp(ptrOffset(wddm->storages[3], offset), dataToCopy.data(), dataToCopy.size()));
} }
TEST(WddmMemoryManagerMemsetAllocationBanksTest, givenAllocationWithMultiTilePlacementWhenMemsetSpecificMemoryBanksThenLockOnlySpecificStorages) {
size_t offset = 3;
size_t allocationSize = 32;
int value = 0x42;
auto hwInfo = *defaultHwInfo;
hwInfo.featureTable.flags.ftrLocalMemory = true;
MockExecutionEnvironment executionEnvironment(&hwInfo);
executionEnvironment.initGmm();
auto wddm = new WddmWithMockedLock(*executionEnvironment.rootDeviceEnvironments[0]);
wddm->init();
MemoryManagerCreate<WddmMemoryManager> memoryManager(true, true, executionEnvironment);
MockWddmAllocation mockAllocation(executionEnvironment.rootDeviceEnvironments[0]->getGmmHelper());
mockAllocation.storageInfo.memoryBanks = 0b1111;
DeviceBitfield memoryBanksToSet = 0b1010;
mockAllocation.handles.resize(4);
for (auto index = 0u; index < 4; index++) {
wddm->storageLocked.set(index, false);
if (mockAllocation.storageInfo.memoryBanks.test(index)) {
mockAllocation.handles[index] = index;
}
}
auto ret = memoryManager.memsetAllocationBanks(&mockAllocation, offset, value, allocationSize, memoryBanksToSet);
EXPECT_TRUE(ret);
EXPECT_FALSE(wddm->storageLocked.test(0));
ASSERT_TRUE(wddm->storageLocked.test(1));
EXPECT_FALSE(wddm->storageLocked.test(2));
ASSERT_TRUE(wddm->storageLocked.test(3));
auto ptr1 = ptrOffset(wddm->storages[1], offset);
for (size_t i = 0; i < allocationSize; i++) {
EXPECT_EQ(value, static_cast<uint8_t *>(ptr1)[i]) << "Bank 1, byte at index " << i << " mismatch";
}
auto ptr3 = ptrOffset(wddm->storages[3], offset);
for (size_t i = 0; i < allocationSize; i++) {
EXPECT_EQ(value, static_cast<uint8_t *>(ptr3)[i]) << "Bank 3, byte at index " << i << " mismatch";
}
}
TEST(WddmMemoryManagerMemsetAllocationBanksTest, givenAllocationWhenLockResourceFailsThenMemsetAllocationBanksReturnsFalse) {
size_t offset = 3;
size_t allocationSize = 32;
int value = 0x42;
auto hwInfo = *defaultHwInfo;
hwInfo.featureTable.flags.ftrLocalMemory = true;
MockExecutionEnvironment executionEnvironment(&hwInfo);
executionEnvironment.initGmm();
auto wddm = new WddmWithMockedLock(*executionEnvironment.rootDeviceEnvironments[0]);
wddm->init();
MemoryManagerCreate<WddmMemoryManager> memoryManager(true, true, executionEnvironment);
MockWddmAllocation mockAllocation(executionEnvironment.rootDeviceEnvironments[0]->getGmmHelper());
mockAllocation.storageInfo.memoryBanks = 0b1111;
DeviceBitfield memoryBanksToSet = 0b1111;
mockAllocation.handles.resize(4);
for (auto index = 0u; index < 4; index++) {
wddm->storageLocked.set(index, false);
if (mockAllocation.storageInfo.memoryBanks.test(index)) {
mockAllocation.handles[index] = index;
}
}
wddm->handleToFail = 2;
auto ret = memoryManager.memsetAllocationBanks(&mockAllocation, offset, value, allocationSize, memoryBanksToSet);
EXPECT_FALSE(ret);
EXPECT_TRUE(wddm->storageLocked.test(0));
EXPECT_TRUE(wddm->storageLocked.test(1));
EXPECT_TRUE(wddm->storageLocked.test(2)); // Attempted to lock but failed
EXPECT_FALSE(wddm->storageLocked.test(3)); // Never reached due to early return
}
class WddmMemoryManagerTest : public ::Test<GdiDllFixture> { class WddmMemoryManagerTest : public ::Test<GdiDllFixture> {
public: public:
void SetUp() override { void SetUp() override {