/* * Copyright (C) 2018-2020 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "command_stream/command_stream_receiver_hw.h" #include "command_stream/experimental_command_buffer.h" #include "command_stream/linear_stream.h" #include "execution_environment/root_device_environment.h" #include "helpers/hw_helper.h" #include "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 { using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL; // Two P_C for timestamps return 2 * MemorySynchronizationCommands::getSizeForPipeControlWithPostSyncOperation( *commandStreamReceiver->peekExecutionEnvironment().rootDeviceEnvironments[commandStreamReceiver->getRootDeviceIndex()]->getHardwareInfo()); } template void ExperimentalCommandBuffer::addTimeStampPipeControl() { using PIPE_CONTROL = typename GfxFamily::PIPE_CONTROL; uint64_t timeStampAddress = timestamps->getGpuAddress() + timestampsOffset; MemorySynchronizationCommands::obtainPipeControlAndProgramPostSyncOperation( *currentStream, PIPE_CONTROL::POST_SYNC_OPERATION_WRITE_TIMESTAMP, timeStampAddress, 0llu, false, *commandStreamReceiver->peekExecutionEnvironment().rootDeviceEnvironments[commandStreamReceiver->getRootDeviceIndex()]->getHardwareInfo()); //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; auto semaphoreCmd = currentStream->getSpaceForCmd(); *semaphoreCmd = GfxFamily::cmdInitMiSemaphoreWait; semaphoreCmd->setCompareOperation(MI_SEMAPHORE_WAIT::COMPARE_OPERATION_SAD_EQUAL_SDD); semaphoreCmd->setSemaphoreDataDword(*semaphoreData); semaphoreCmd->setSemaphoreGraphicsAddress(gpuAddr); } template size_t ExperimentalCommandBuffer::getExperimentalCommandsSize() noexcept { using MI_SEMAPHORE_WAIT = typename GfxFamily::MI_SEMAPHORE_WAIT; return sizeof(MI_SEMAPHORE_WAIT); } } // namespace NEO