/* * Copyright (C) 2018-2023 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/command_container/command_encoder.h" #include "shared/source/command_stream/command_stream_receiver_hw.h" #include "shared/source/command_stream/experimental_command_buffer.h" #include "shared/source/command_stream/linear_stream.h" #include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/root_device_environment.h" #include "shared/source/helpers/gfx_core_helper.h" #include "shared/source/helpers/pipe_control_args.h" #include "shared/source/memory_manager/graphics_allocation.h" namespace NEO { template void ExperimentalCommandBuffer::injectBufferStart(LinearStream &parentStream, size_t cmdBufferOffset) { using MI_BATCH_BUFFER_START = typename GfxFamily::MI_BATCH_BUFFER_START; auto pCmd = parentStream.getSpaceForCmd(); auto commandStreamReceiverHw = static_cast *>(commandStreamReceiver); commandStreamReceiverHw->addBatchBufferStart(pCmd, currentStream->getGraphicsAllocation()->getGpuAddress() + cmdBufferOffset, true); } template size_t ExperimentalCommandBuffer::getRequiredInjectionSize() noexcept { using MI_BATCH_BUFFER_START = typename GfxFamily::MI_BATCH_BUFFER_START; return sizeof(MI_BATCH_BUFFER_START); } template size_t ExperimentalCommandBuffer::programExperimentalCommandBuffer() { using MI_BATCH_BUFFER_END = typename GfxFamily::MI_BATCH_BUFFER_END; getCS(getTotalExperimentalSize()); size_t returnOffset = currentStream->getUsed(); // begin timestamp addTimeStampPipeControl(); addExperimentalCommands(); // end timestamp addTimeStampPipeControl(); // end auto pCmd = currentStream->getSpaceForCmd(); *pCmd = GfxFamily::cmdInitBatchBufferEnd; return returnOffset; } template size_t ExperimentalCommandBuffer::getTotalExperimentalSize() noexcept { using MI_BATCH_BUFFER_END = typename GfxFamily::MI_BATCH_BUFFER_END; size_t size = sizeof(MI_BATCH_BUFFER_END) + getTimeStampPipeControlSize() + getExperimentalCommandsSize(); return size; } template size_t ExperimentalCommandBuffer::getTimeStampPipeControlSize() noexcept { // Two P_C for timestamps return 2 * MemorySynchronizationCommands::getSizeForBarrierWithPostSyncOperation( *commandStreamReceiver->peekExecutionEnvironment().rootDeviceEnvironments[commandStreamReceiver->getRootDeviceIndex()], false); } template void ExperimentalCommandBuffer::addTimeStampPipeControl() { uint64_t timeStampAddress = timestamps->getGpuAddress() + timestampsOffset; PipeControlArgs args; MemorySynchronizationCommands::addBarrierWithPostSyncOperation( *currentStream, PostSyncMode::Timestamp, timeStampAddress, 0llu, *commandStreamReceiver->peekExecutionEnvironment().rootDeviceEnvironments[commandStreamReceiver->getRootDeviceIndex()], args); // moving to next chunk timestampsOffset += sizeof(uint64_t); DEBUG_BREAK_IF(timestamps->getUnderlyingBufferSize() < timestampsOffset); } template void ExperimentalCommandBuffer::addExperimentalCommands() { using MI_SEMAPHORE_WAIT = typename GfxFamily::MI_SEMAPHORE_WAIT; uint32_t *semaphoreData = reinterpret_cast(ptrOffset(experimentalAllocation->getUnderlyingBuffer(), experimentalAllocationOffset)); *semaphoreData = 1; uint64_t gpuAddr = experimentalAllocation->getGpuAddress() + experimentalAllocationOffset; EncodeSemaphore::programMiSemaphoreWait(currentStream->getSpaceForCmd(), gpuAddr, *semaphoreData, MI_SEMAPHORE_WAIT::COMPARE_OPERATION_SAD_EQUAL_SDD, false, false, false, false); } template size_t ExperimentalCommandBuffer::getExperimentalCommandsSize() noexcept { return NEO::EncodeSemaphore::getSizeMiSemaphoreWait(); } } // namespace NEO