fix: Fix copying with blitter

Related-To: NEO-12134, NEO-13874, NEO-14002

Thanks to this change we avoid programming y1 offset for 2D surface
above the maximum allowable value, i.e. 16 kb for blitter for BMG

Signed-off-by: Andrzej Koska <andrzej.koska@intel.com>
This commit is contained in:
Andrzej Koska 2025-02-06 10:38:51 +00:00 committed by Compute-Runtime-Automation
parent 9119a1e802
commit d0871e0e37
6 changed files with 150 additions and 0 deletions

View File

@ -74,6 +74,7 @@ struct BlitCommandsHelper {
static void appendTilingEnable(typename GfxFamily::XY_COLOR_BLT &blitCmd);
static void appendTilingType(const GMM_TILE_TYPE srcTilingType, const GMM_TILE_TYPE dstTilingType, typename GfxFamily::XY_BLOCK_COPY_BLT &blitCmd);
static void appendSliceOffsets(const BlitProperties &blitProperties, typename GfxFamily::XY_BLOCK_COPY_BLT &blitCmd, uint32_t sliceIndex, const RootDeviceEnvironment &rootDeviceEnvironment, uint32_t srcSlicePitch, uint32_t dstSlicePitch);
static void appendBaseAddressOffset(const BlitProperties &blitProperties, typename GfxFamily::XY_BLOCK_COPY_BLT &blitCmd, const bool isSource);
static void getBlitAllocationProperties(const GraphicsAllocation &allocation, uint32_t &pitch, uint32_t &qPitch, GMM_TILE_TYPE &tileType,
uint32_t &mipTailLod, uint32_t &compressionDetails,
const RootDeviceEnvironment &rootDeviceEnvironment, GMM_YUV_PLANE_ENUM plane);

View File

@ -559,6 +559,9 @@ size_t BlitCommandsHelper<GfxFamily>::getProfilingMmioCmdsSize() {
return 4 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM);
}
template <typename GfxFamily>
void BlitCommandsHelper<GfxFamily>::appendBaseAddressOffset(const BlitProperties &blitProperties, typename GfxFamily::XY_BLOCK_COPY_BLT &blitCmd, const bool isSource) {}
template <typename GfxFamily>
void BlitCommandsHelper<GfxFamily>::encodeWa(LinearStream &cmdStream, const BlitProperties &blitProperties, uint32_t &latestSentBcsWaValue) {
}

View File

@ -134,6 +134,54 @@ void BlitCommandsHelper<Family>::appendBlitCommandsBlockCopy(const BlitPropertie
blitCmd.setSourceMOCS(mocs);
}
template <>
void BlitCommandsHelper<Family>::appendBaseAddressOffset(const BlitProperties &blitProperties, typename Family::XY_BLOCK_COPY_BLT &blitCmd, const bool isSource) {
using XY_BLOCK_COPY_BLT = typename Family::XY_BLOCK_COPY_BLT;
auto surfaceType = isSource ? blitCmd.getSourceSurfaceType() : blitCmd.getDestinationSurfaceType();
if (surfaceType == XY_BLOCK_COPY_BLT::SURFACE_TYPE_SURFTYPE_2D) {
// max allowed y1 offset for 2D surface is 0x3fff,
// if it's bigger then we need to reduce it by adding offset to base address instead
GMM_REQ_OFFSET_INFO offsetInfo = {};
offsetInfo.ArrayIndex = isSource ? (blitCmd.getSourceArrayIndex() - 1) : (blitCmd.getDestinationArrayIndex() - 1);
offsetInfo.ReqRender = 1;
if (isSource) {
blitProperties.srcAllocation->getDefaultGmm()->gmmResourceInfo->getOffset(offsetInfo);
blitCmd.setSourceBaseAddress(ptrOffset(blitProperties.srcGpuAddress, offsetInfo.Render.Offset));
blitCmd.setSourceXOffset(offsetInfo.Render.XOffset);
blitCmd.setSourceYOffset(offsetInfo.Render.YOffset);
blitCmd.setSourceSurfaceDepth(1);
blitCmd.setSourceArrayIndex(1);
} else {
blitProperties.dstAllocation->getDefaultGmm()->gmmResourceInfo->getOffset(offsetInfo);
blitCmd.setDestinationBaseAddress(ptrOffset(blitProperties.dstGpuAddress, offsetInfo.Render.Offset));
blitCmd.setDestinationXOffset(offsetInfo.Render.XOffset);
blitCmd.setDestinationYOffset(offsetInfo.Render.YOffset);
blitCmd.setDestinationSurfaceDepth(1);
blitCmd.setDestinationArrayIndex(1);
}
}
}
template <>
void BlitCommandsHelper<Family>::appendSliceOffsets(const BlitProperties &blitProperties, typename Family::XY_BLOCK_COPY_BLT &blitCmd, uint32_t sliceIndex, const RootDeviceEnvironment &rootDeviceEnvironment, uint32_t srcSlicePitch, uint32_t dstSlicePitch) {
using XY_BLOCK_COPY_BLT = typename Family::XY_BLOCK_COPY_BLT;
auto srcAddress = blitProperties.srcGpuAddress;
auto dstAddress = blitProperties.dstGpuAddress;
if (blitCmd.getSourceTiling() == XY_BLOCK_COPY_BLT::TILING::TILING_LINEAR) {
blitCmd.setSourceBaseAddress(ptrOffset(srcAddress, srcSlicePitch * (sliceIndex + blitProperties.srcOffset.z)));
} else {
blitCmd.setSourceArrayIndex(sliceIndex + static_cast<uint32_t>(blitProperties.srcOffset.z) + 1);
appendBaseAddressOffset(blitProperties, blitCmd, true);
}
if (blitCmd.getDestinationTiling() == XY_BLOCK_COPY_BLT::TILING::TILING_LINEAR) {
blitCmd.setDestinationBaseAddress(ptrOffset(dstAddress, dstSlicePitch * (sliceIndex + blitProperties.dstOffset.z)));
} else {
blitCmd.setDestinationArrayIndex(sliceIndex + static_cast<uint32_t>(blitProperties.dstOffset.z) + 1);
appendBaseAddressOffset(blitProperties, blitCmd, false);
}
}
template <>
template <typename T>
void BlitCommandsHelper<Family>::appendBlitCommandsForBuffer(const BlitProperties &blitProperties, T &blitCmd, const RootDeviceEnvironment &rootDeviceEnvironment) {

View File

@ -405,6 +405,19 @@ HWTEST_F(BlitTests, givenXyCopyBltCommandWhenAppendBlitCommandsMemCopyIsCalledTh
EXPECT_EQ(memcmp(&bltCmd, &bltCmdBefore, sizeof(XY_COPY_BLT)), 0);
}
HWTEST_F(BlitTests, givenXyBlockCopyBltCommandAndSliceIndex0WhenAppendBaseAddressOffsetIsCalledThenNothingChanged) {
using XY_BLOCK_COPY_BLT = typename FamilyType::XY_BLOCK_COPY_BLT;
auto bltCmd = FamilyType::cmdInitXyBlockCopyBlt;
auto bltCmdBefore = bltCmd;
BlitProperties properties{};
NEO::BlitCommandsHelper<FamilyType>::appendBaseAddressOffset(properties, bltCmd, false);
EXPECT_EQ(memcmp(&bltCmd, &bltCmdBefore, sizeof(XY_BLOCK_COPY_BLT)), 0);
NEO::BlitCommandsHelper<FamilyType>::appendBaseAddressOffset(properties, bltCmd, true);
EXPECT_EQ(memcmp(&bltCmd, &bltCmdBefore, sizeof(XY_BLOCK_COPY_BLT)), 0);
}
using BlitColor = IsWithinProducts<IGFX_SKYLAKE, IGFX_ICELAKE_LP>;
HWTEST2_F(BlitTests, givenMemoryWhenFillPatternSizeIs4BytesThen32BitMaskISSetCorrectly, BlitColor) {

View File

@ -669,3 +669,33 @@ HWTEST2_F(BlitTests, givenDispatchDummyBlitWhenForceDummyBlitWaDisabledThenAddit
EXPECT_EQ(expectedSize, stream.getUsed());
EXPECT_EQ(nullptr, rootDeviceEnvironment.getDummyAllocation());
}
struct IsAtLeastXeHpCoreAndNotXe2HpgCoreWith2DArrayImageSupport {
template <PRODUCT_FAMILY productFamily>
static constexpr bool isMatched() {
return IsAtLeastGfxCore<IGFX_XE_HP_CORE>::isMatched<productFamily>() && !IsXe2HpgCore::isMatched<productFamily>() && NEO::HwMapper<productFamily>::GfxProduct::supportsSampler;
}
};
HWTEST2_F(BlitTests, givenXeHPOrAboveTiledResourcesWhenAppendSliceOffsetsIsCalledThenIndexesAreSet, IsAtLeastXeHpCoreAndNotXe2HpgCoreWith2DArrayImageSupport) {
using XY_BLOCK_COPY_BLT = typename FamilyType::XY_BLOCK_COPY_BLT;
auto blitCmd = FamilyType::cmdInitXyBlockCopyBlt;
blitCmd.setSourceTiling(XY_BLOCK_COPY_BLT::TILING::TILING_TILE64);
blitCmd.setDestinationTiling(XY_BLOCK_COPY_BLT::TILING::TILING_TILE64);
MockGraphicsAllocation mockAllocationSrc(0, 1u /*num gmms*/, AllocationType::internalHostMemory,
reinterpret_cast<void *>(0x1234), 0x1000, 0, sizeof(uint32_t),
MemoryPool::system4KBPages, MemoryManager::maxOsContextCount);
MockGraphicsAllocation mockAllocationDst(0, 1u /*num gmms*/, AllocationType::internalHostMemory,
reinterpret_cast<void *>(0x1234), 0x1000, 0, sizeof(uint32_t),
MemoryPool::system4KBPages, MemoryManager::maxOsContextCount);
BlitProperties properties{};
uint32_t sliceIndex = 1;
auto srcSlicePitch = static_cast<uint32_t>(properties.srcSlicePitch);
auto dstSlicePitch = static_cast<uint32_t>(properties.dstSlicePitch);
BlitCommandsHelper<FamilyType>::appendSliceOffsets(properties, blitCmd, sliceIndex, pDevice->getRootDeviceEnvironment(), srcSlicePitch, dstSlicePitch);
EXPECT_EQ(blitCmd.getDestinationArrayIndex(), sliceIndex + 1);
EXPECT_EQ(blitCmd.getSourceArrayIndex(), sliceIndex + 1);
}

View File

@ -396,3 +396,58 @@ HWTEST2_F(BlitTests, givenMemoryAndImageWhenDispatchCopyImageCallThenCommandAdde
auto itor = find<XY_BLOCK_COPY_BLT *>(cmdList.begin(), cmdList.end());
EXPECT_NE(cmdList.end(), itor);
}
HWTEST2_F(BlitTests, givenSurfaceTypeAndSliceIndexWhenAppendBaseAddressOffsetIsCalledThenBaseAddressAndArrayIndexAreCorrectlySet, IsXe2HpgCore) {
using XY_BLOCK_COPY_BLT = typename FamilyType::XY_BLOCK_COPY_BLT;
MockGraphicsAllocation mockAllocationSrc(reinterpret_cast<void *>(0x1234), 0x1000, sizeof(uint32_t));
MockGraphicsAllocation mockAllocationDst(reinterpret_cast<void *>(0x1234), 0x1000, sizeof(uint32_t));
auto gmm = std::make_unique<MockGmm>(pDevice->getGmmHelper());
mockAllocationSrc.setGmm(gmm.get(), 0u);
mockAllocationDst.setGmm(gmm.get(), 0u);
BlitProperties properties{};
properties.srcAllocation = &mockAllocationSrc;
properties.dstAllocation = &mockAllocationDst;
properties.srcGpuAddress = mockAllocationSrc.getGpuAddress();
properties.dstGpuAddress = mockAllocationDst.getGpuAddress();
properties.srcRowPitch = 1;
properties.dstRowPitch = 1;
properties.srcSize.z = 129;
properties.dstSize.z = 129;
std::array<std::tuple<typename XY_BLOCK_COPY_BLT::SURFACE_TYPE, uint32_t, uint32_t, uint32_t>, 4> testParams =
{{{XY_BLOCK_COPY_BLT::SURFACE_TYPE::SURFACE_TYPE_SURFTYPE_2D, 0u, 0u, 0u},
{XY_BLOCK_COPY_BLT::SURFACE_TYPE::SURFACE_TYPE_SURFTYPE_2D, 64u, 64u, 64u},
{XY_BLOCK_COPY_BLT::SURFACE_TYPE::SURFACE_TYPE_SURFTYPE_2D, 64u, 128u, 128u},
{XY_BLOCK_COPY_BLT::SURFACE_TYPE::SURFACE_TYPE_SURFTYPE_2D, 4096u, 1u, 1u}}};
for (const auto &isSource : {false, true}) {
for (const auto &[surfaceType, qPitch, sliceIndex, anchorSliceIndex] : testParams) {
uint32_t y1Top = 0;
uint32_t yOffset = 0;
auto blitCmd = FamilyType::cmdInitXyBlockCopyBlt;
blitCmd.setSourceTiling(XY_BLOCK_COPY_BLT::TILING::TILING_TILE4);
blitCmd.setDestinationTiling(XY_BLOCK_COPY_BLT::TILING::TILING_TILE4);
blitCmd.setSourceSurfaceType(surfaceType);
blitCmd.setDestinationSurfaceType(surfaceType);
blitCmd.setSourceBaseAddress(properties.srcGpuAddress);
blitCmd.setDestinationBaseAddress(properties.dstGpuAddress);
blitCmd.setSourceY1CoordinateTop(y1Top);
blitCmd.setDestinationY1CoordinateTop(y1Top);
blitCmd.setSourceYOffset(yOffset);
blitCmd.setDestinationYOffset(yOffset);
blitCmd.setSourceSurfaceQpitch(qPitch);
blitCmd.setDestinationSurfaceQpitch(qPitch);
blitCmd.setSourceSurfaceDepth(static_cast<uint32_t>(properties.srcSize.z));
blitCmd.setDestinationSurfaceDepth(static_cast<uint32_t>(properties.dstSize.z));
BlitCommandsHelper<FamilyType>::appendBaseAddressOffset(properties, blitCmd, isSource);
auto gpuAddress = isSource ? properties.srcGpuAddress : properties.dstGpuAddress;
if (isSource) {
EXPECT_EQ(blitCmd.getSourceBaseAddress(), gpuAddress);
EXPECT_EQ(blitCmd.getSourceSurfaceDepth(), 1u);
EXPECT_EQ(blitCmd.getSourceArrayIndex(), 1u);
} else {
EXPECT_EQ(blitCmd.getDestinationBaseAddress(), gpuAddress);
EXPECT_EQ(blitCmd.getDestinationSurfaceDepth(), 1u);
EXPECT_EQ(blitCmd.getDestinationArrayIndex(), 1u);
}
}
}
}