diff --git a/shared/source/os_interface/windows/wddm_memory_manager.cpp b/shared/source/os_interface/windows/wddm_memory_manager.cpp index 391e1bb6ce..d927937c19 100644 --- a/shared/source/os_interface/windows/wddm_memory_manager.cpp +++ b/shared/source/os_interface/windows/wddm_memory_manager.cpp @@ -223,6 +223,12 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryUsingKmdAndMapItToC auto cpuPtr = gmm->isCompressionEnabled ? nullptr : lockResource(wddmAllocation.get()); + if (alignGpuAddressTo64KB) { + void *tempCPUPtr = cpuPtr; + cpuPtr = alignUp(cpuPtr, std::max(allocationData.alignment, MemoryConstants::pageSize64k)); + wddmAllocation->setGpuAddress(wddmAllocation->getGpuAddress() + ptrDiff(cpuPtr, tempCPUPtr)); + } + [[maybe_unused]] auto status = true; if ((!(alignGpuAddressTo64KB) && executionEnvironment.rootDeviceEnvironments[allocationData.rootDeviceIndex]->getHardwareInfo()->capabilityTable.gpuAddressSpace >= MemoryConstants::max64BitAppAddress) || is32bit) { @@ -233,12 +239,6 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryUsingKmdAndMapItToC status = mapGpuVirtualAddress(wddmAllocation.get(), requiredGpuVa); } else { status = mapGpuVirtualAddress(wddmAllocation.get(), nullptr); - - if (alignGpuAddressTo64KB) { - void *tempCPUPtr = cpuPtr; - cpuPtr = alignUp(cpuPtr, MemoryConstants::pageSize64k); - wddmAllocation->setGpuAddress(wddmAllocation->getGpuAddress() + ptrDiff(cpuPtr, tempCPUPtr)); - } } DEBUG_BREAK_IF(!status); wddmAllocation->setCpuAddress(cpuPtr); @@ -1302,7 +1302,7 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryInDevicePool(const alignment = MemoryConstants::pageSize64k; sizeAligned = allocationData.imgInfo->size; } else { - alignment = alignmentSelector.selectAlignment(allocationData.size).alignment; + alignment = std::max(allocationData.alignment, alignmentSelector.selectAlignment(allocationData.size).alignment); sizeAligned = alignUp(allocationData.size, alignment); if (singleBankAllocation) { diff --git a/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp index a51938710e..c9783f8df8 100644 --- a/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp @@ -368,6 +368,28 @@ TEST_F(WddmMemoryManagerTests, givenAllocateGraphicsMemoryUsingKmdAndMapItToCpuV EXPECT_GT(reinterpret_cast(gmmHelper->getClientContext())->freeGpuVirtualAddressCalled, 0u); } +TEST_F(WddmMemoryManagerTests, givenAllocateGraphicsMemoryUsingKmdAndMapItToCpuVAWhenCreatingHostAllocationThenCpuAddressIsAligned) { + NEO::AllocationData allocData{}; + allocData.type = NEO::AllocationType::BUFFER_HOST_MEMORY; + allocData.size = 1; + allocData.makeGPUVaDifferentThanCPUPtr = true; + allocData.allocationMethod = GfxMemoryAllocationMethod::AllocateByKmd; + memoryManager->callBaseAllocateGraphicsMemoryUsingKmdAndMapItToCpuVA = true; + + size_t alignment = 8 * MemoryConstants::megaByte; + do { + alignment >>= 1; + allocData.alignment = alignment; + auto graphicsAllocation = memoryManager->allocateGraphicsMemoryUsingKmdAndMapItToCpuVA(allocData, true); + void *ptr = graphicsAllocation->getUnderlyingBuffer(); + EXPECT_NE(nullptr, ptr); + if (alignment != 0) { + EXPECT_EQ(reinterpret_cast(ptr) & (~(alignment - 1)), reinterpret_cast(ptr)); + } + memoryManager->freeGraphicsMemory(graphicsAllocation); + } while (alignment != 0); +} + TEST_F(WddmMemoryManagerAllocPathTests, givenAllocateGraphicsMemoryUsingKmdAndMapItToCpuVAWhen32bitThenProperAddressSet) { if constexpr (is64bit) { GTEST_SKIP(); @@ -1489,6 +1511,30 @@ TEST_F(WddmMemoryManagerSimpleTest, whenAlignmentRequirementExceedsPageSizeThenA } } +TEST_F(WddmMemoryManagerSimpleTest, givenAlignmentWhenAllocatingGraphicsAllocationInDevicePoolThenAllocationIsAligned) { + const bool enable64kbPages = false; + const bool localMemoryEnabled = true; + memoryManager = std::make_unique(enable64kbPages, localMemoryEnabled, executionEnvironment); + + MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Error; + AllocationData allocData{}; + allocData.allFlags = 0; + allocData.size = 1; + allocData.flags.allocateMemory = true; + + size_t alignment = 8 * MemoryConstants::megaByte; + do { + alignment >>= 1; + allocData.alignment = alignment; + auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status); + EXPECT_EQ(MemoryManager::AllocationStatus::Success, status); + EXPECT_NE(nullptr, allocation); + EXPECT_EQ(MemoryPool::LocalMemory, allocation->getMemoryPool()); + EXPECT_LE(alignment, allocation->getUnderlyingBufferSize()); + memoryManager->freeGraphicsMemory(allocation); + } while (alignment != 0); +} + TEST_F(WddmMemoryManagerSimpleTest, givenUseSystemMemorySetToTrueWhenAllocateInDevicePoolIsCalledThenNullptrIsReturned) { memoryManager.reset(new MockWddmMemoryManager(false, false, executionEnvironment)); MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;