diff --git a/core/command_container/command_encoder.h b/core/command_container/command_encoder.h index 3a9042ec68..7f6a8217ef 100644 --- a/core/command_container/command_encoder.h +++ b/core/command_container/command_encoder.h @@ -181,4 +181,15 @@ struct EncodeAtomic { DATA_SIZE dataSize); }; +template +struct EncodeBatchBufferStartOrEnd { + using MI_BATCH_BUFFER_START = typename GfxFamily::MI_BATCH_BUFFER_START; + using MI_BATCH_BUFFER_END = typename GfxFamily::MI_BATCH_BUFFER_END; + + static void programBatchBufferStart(LinearStream *commandStream, + uint64_t address, + bool secondLevel); + static void programBatchBufferEnd(CommandContainer &container); +}; + } // namespace NEO diff --git a/core/command_container/command_encoder.inl b/core/command_container/command_encoder.inl index 8fde4f713b..8b6cd0912c 100644 --- a/core/command_container/command_encoder.inl +++ b/core/command_container/command_encoder.inl @@ -314,4 +314,25 @@ void EncodeAtomic::programMiAtomic(MI_ATOMIC *atomic, uint64_t writeAddr atomic->setMemoryAddressHigh(static_cast(writeAddress >> 32)); } +template +void EncodeBatchBufferStartOrEnd::programBatchBufferStart(LinearStream *commandStream, + uint64_t address, + bool secondLevel) { + MI_BATCH_BUFFER_START cmd = Family::cmdInitBatchBufferStart; + if (secondLevel) { + cmd.setSecondLevelBatchBuffer(MI_BATCH_BUFFER_START::SECOND_LEVEL_BATCH_BUFFER_SECOND_LEVEL_BATCH); + } + cmd.setAddressSpaceIndicator(MI_BATCH_BUFFER_START::ADDRESS_SPACE_INDICATOR_PPGTT); + cmd.setBatchBufferStartAddressGraphicsaddress472(address); + auto buffer = commandStream->getSpaceForCmd(); + *reinterpret_cast(buffer) = cmd; +} + +template +void EncodeBatchBufferStartOrEnd::programBatchBufferEnd(CommandContainer &container) { + MI_BATCH_BUFFER_END cmd = Family::cmdInitBatchBufferEnd; + auto buffer = container.getCommandStream()->getSpace(sizeof(cmd)); + *reinterpret_cast(buffer) = cmd; +} + } // namespace NEO diff --git a/core/gen11/command_encoder_gen11.cpp b/core/gen11/command_encoder_gen11.cpp index d558de1ba0..bc90b42ca8 100644 --- a/core/gen11/command_encoder_gen11.cpp +++ b/core/gen11/command_encoder_gen11.cpp @@ -27,4 +27,5 @@ template struct EncodeStoreMMIO; template struct EncodeSurfaceState; template struct EncodeAtomic; template struct EncodeSempahore; +template struct EncodeBatchBufferStartOrEnd; } // namespace NEO diff --git a/core/gen12lp/command_encoder_gen12lp.cpp b/core/gen12lp/command_encoder_gen12lp.cpp index 0cb57183a1..15495d57ec 100644 --- a/core/gen12lp/command_encoder_gen12lp.cpp +++ b/core/gen12lp/command_encoder_gen12lp.cpp @@ -47,5 +47,6 @@ template struct EncodeStoreMMIO; template struct EncodeSurfaceState; template struct EncodeAtomic; template struct EncodeSempahore; +template struct EncodeBatchBufferStartOrEnd; } // namespace NEO diff --git a/core/gen8/command_encoder_gen8.cpp b/core/gen8/command_encoder_gen8.cpp index 63592db707..0674ea2743 100644 --- a/core/gen8/command_encoder_gen8.cpp +++ b/core/gen8/command_encoder_gen8.cpp @@ -28,5 +28,6 @@ template struct EncodeStoreMMIO; template struct EncodeSurfaceState; template struct EncodeAtomic; template struct EncodeSempahore; +template struct EncodeBatchBufferStartOrEnd; } // namespace NEO \ No newline at end of file diff --git a/core/gen9/command_encoder_gen9.cpp b/core/gen9/command_encoder_gen9.cpp index b502082605..9fbe5047fd 100644 --- a/core/gen9/command_encoder_gen9.cpp +++ b/core/gen9/command_encoder_gen9.cpp @@ -28,4 +28,5 @@ template struct EncodeStoreMMIO; template struct EncodeSurfaceState; template struct EncodeAtomic; template struct EncodeSempahore; +template struct EncodeBatchBufferStartOrEnd; } // namespace NEO diff --git a/core/unit_tests/encoders/CMakeLists.txt b/core/unit_tests/encoders/CMakeLists.txt index c9635cbe9a..3aebcb29f7 100644 --- a/core/unit_tests/encoders/CMakeLists.txt +++ b/core/unit_tests/encoders/CMakeLists.txt @@ -7,6 +7,7 @@ set(NEO_CORE_ENCODERS_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/test_encode_atomic.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_encode_command_buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_encode_dispatch_kernel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_encode_flush.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_encode_math.cpp diff --git a/core/unit_tests/encoders/test_encode_command_buffer.cpp b/core/unit_tests/encoders/test_encode_command_buffer.cpp new file mode 100644 index 0000000000..ad5c58c570 --- /dev/null +++ b/core/unit_tests/encoders/test_encode_command_buffer.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "core/command_container/cmdcontainer.h" +#include "core/command_container/command_encoder.h" +#include "test.h" +#include "unit_tests/fixtures/device_fixture.h" +#include "unit_tests/gen_common/gen_cmd_parse.h" + +using namespace NEO; + +using EncodeBatchBufferStartOrEndTest = Test; + +HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBEndThenCommandIsAdded) { + CommandContainer cmdContainer; + cmdContainer.initialize(pDevice); + EncodeBatchBufferStartOrEnd::programBatchBufferEnd(cmdContainer); + + GenCmdList commands; + CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed()); + + using MI_BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END; + auto itor = find(commands.begin(), commands.end()); + ASSERT_NE(itor, commands.end()); +} + +HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBStartThenCommandIsAdded) { + CommandContainer cmdContainer; + cmdContainer.initialize(pDevice); + EncodeBatchBufferStartOrEnd::programBatchBufferStart(cmdContainer.getCommandStream(), 0, true); + + GenCmdList commands; + CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed()); + + using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START; + auto itor = find(commands.begin(), commands.end()); + ASSERT_NE(itor, commands.end()); +} + +HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBStartWithSecondLevelParameterThenCommandIsProgrammedCorrectly) { + CommandContainer cmdContainer; + cmdContainer.initialize(pDevice); + EncodeBatchBufferStartOrEnd::programBatchBufferStart(cmdContainer.getCommandStream(), 0, true); + + GenCmdList commands; + CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed()); + + using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START; + auto itor = find(commands.begin(), commands.end()); + ASSERT_NE(itor, commands.end()); + { + auto cmd = genCmdCast(*itor); + EXPECT_EQ(MI_BATCH_BUFFER_START::SECOND_LEVEL_BATCH_BUFFER_SECOND_LEVEL_BATCH, cmd->getSecondLevelBatchBuffer()); + } +} + +HWTEST_F(EncodeBatchBufferStartOrEndTest, givenCommandContainerWhenEncodeBBStartWithFirstLevelParameterThenCommandIsProgrammedCorrectly) { + CommandContainer cmdContainer; + cmdContainer.initialize(pDevice); + EncodeBatchBufferStartOrEnd::programBatchBufferStart(cmdContainer.getCommandStream(), 0, false); + + GenCmdList commands; + CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed()); + + using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START; + auto itor = find(commands.begin(), commands.end()); + ASSERT_NE(itor, commands.end()); + { + auto cmd = genCmdCast(*itor); + EXPECT_EQ(MI_BATCH_BUFFER_START::SECOND_LEVEL_BATCH_BUFFER_FIRST_LEVEL_BATCH, cmd->getSecondLevelBatchBuffer()); + } +} + +HWTEST_F(EncodeBatchBufferStartOrEndTest, givenGpuAddressWhenEncodeBBStartThenAddressIsProgrammedCorrectly) { + CommandContainer cmdContainer; + cmdContainer.initialize(pDevice); + + uint64_t gpuAddress = 12 * MemoryConstants::pageSize; + EncodeBatchBufferStartOrEnd::programBatchBufferStart(cmdContainer.getCommandStream(), gpuAddress, false); + + GenCmdList commands; + CmdParse::parseCommandBuffer(commands, ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0), cmdContainer.getCommandStream()->getUsed()); + + using MI_BATCH_BUFFER_START = typename FamilyType::MI_BATCH_BUFFER_START; + auto itor = find(commands.begin(), commands.end()); + ASSERT_NE(itor, commands.end()); + { + auto cmd = genCmdCast(*itor); + EXPECT_EQ(gpuAddress, cmd->getBatchBufferStartAddressGraphicsaddress472()); + } +} \ No newline at end of file