/* * Copyright (C) 2017-2019 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "runtime/command_stream/command_stream_receiver_hw.h" #include "runtime/device/device.h" #include "runtime/execution_environment/execution_environment.h" #include "runtime/memory_manager/os_agnostic_memory_manager.h" #include "runtime/os_interface/os_context.h" #include "unit_tests/helpers/dispatch_flags_helper.h" #include "unit_tests/mocks/mock_experimental_command_buffer.h" #include #include namespace NEO { class GmmPageTableMngr; template class UltCommandStreamReceiver : public CommandStreamReceiverHw, public NonCopyableOrMovableClass { using BaseClass = CommandStreamReceiverHw; public: using BaseClass::dshState; using BaseClass::getScratchPatchAddress; using BaseClass::getScratchSpaceController; using BaseClass::indirectHeap; using BaseClass::iohState; using BaseClass::perDssBackedBuffer; using BaseClass::programPreamble; using BaseClass::programStateSip; using BaseClass::requiresInstructionCacheFlush; using BaseClass::rootDeviceIndex; using BaseClass::sshState; using BaseClass::CommandStreamReceiver::bindingTableBaseAddressRequired; using BaseClass::CommandStreamReceiver::cleanupResources; using BaseClass::CommandStreamReceiver::commandStream; using BaseClass::CommandStreamReceiver::dispatchMode; using BaseClass::CommandStreamReceiver::executionEnvironment; using BaseClass::CommandStreamReceiver::experimentalCmdBuffer; using BaseClass::CommandStreamReceiver::flushStamp; using BaseClass::CommandStreamReceiver::GSBAFor32BitProgrammed; using BaseClass::CommandStreamReceiver::internalAllocationStorage; using BaseClass::CommandStreamReceiver::isPreambleSent; using BaseClass::CommandStreamReceiver::isStateSipSent; using BaseClass::CommandStreamReceiver::lastMediaSamplerConfig; using BaseClass::CommandStreamReceiver::lastPreemptionMode; using BaseClass::CommandStreamReceiver::lastSentCoherencyRequest; using BaseClass::CommandStreamReceiver::lastSentL3Config; using BaseClass::CommandStreamReceiver::lastSentThreadArbitrationPolicy; using BaseClass::CommandStreamReceiver::lastVmeSubslicesConfig; using BaseClass::CommandStreamReceiver::latestFlushedTaskCount; using BaseClass::CommandStreamReceiver::latestSentStatelessMocsConfig; using BaseClass::CommandStreamReceiver::latestSentTaskCount; using BaseClass::CommandStreamReceiver::mediaVfeStateDirty; using BaseClass::CommandStreamReceiver::osContext; using BaseClass::CommandStreamReceiver::perfCounterAllocator; using BaseClass::CommandStreamReceiver::profilingTimeStampAllocator; using BaseClass::CommandStreamReceiver::requiredPrivateScratchSize; using BaseClass::CommandStreamReceiver::requiredScratchSize; using BaseClass::CommandStreamReceiver::requiredThreadArbitrationPolicy; using BaseClass::CommandStreamReceiver::samplerCacheFlushRequired; using BaseClass::CommandStreamReceiver::scratchSpaceController; using BaseClass::CommandStreamReceiver::stallingPipeControlOnNextFlushRequired; using BaseClass::CommandStreamReceiver::submissionAggregator; using BaseClass::CommandStreamReceiver::taskCount; using BaseClass::CommandStreamReceiver::taskLevel; using BaseClass::CommandStreamReceiver::timestampPacketAllocator; using BaseClass::CommandStreamReceiver::timestampPacketWriteEnabled; using BaseClass::CommandStreamReceiver::waitForTaskCountAndCleanAllocationList; virtual ~UltCommandStreamReceiver() override { } UltCommandStreamReceiver(ExecutionEnvironment &executionEnvironment, uint32_t rootDeviceIndex) : BaseClass(executionEnvironment, rootDeviceIndex), recursiveLockCounter(0), recordedDispatchFlags(DispatchFlagsHelper::createDefaultDispatchFlags()) {} static CommandStreamReceiver *create(bool withAubDump, ExecutionEnvironment &executionEnvironment, uint32_t rootDeviceIndex) { return new UltCommandStreamReceiver(executionEnvironment, rootDeviceIndex); } virtual GmmPageTableMngr *createPageTableManager() override { createPageTableManagerCalled = true; return nullptr; } void makeSurfacePackNonResident(ResidencyContainer &allocationsForResidency) override { makeSurfacePackNonResidentCalled++; BaseClass::makeSurfacePackNonResident(allocationsForResidency); } bool flush(BatchBuffer &batchBuffer, ResidencyContainer &allocationsForResidency) override { if (recordFlusheBatchBuffer) { latestFlushedBatchBuffer = batchBuffer; } latestSentTaskCountValueDuringFlush = latestSentTaskCount; return BaseClass::flush(batchBuffer, allocationsForResidency); } CompletionStamp flushTask(LinearStream &commandStream, size_t commandStreamStart, const IndirectHeap &dsh, const IndirectHeap &ioh, const IndirectHeap &ssh, uint32_t taskLevel, DispatchFlags &dispatchFlags, Device &device) override { recordedDispatchFlags = dispatchFlags; this->lastFlushedCommandStream = &commandStream; return BaseClass::flushTask(commandStream, commandStreamStart, dsh, ioh, ssh, taskLevel, dispatchFlags, device); } size_t getPreferredTagPoolSize() const override { return BaseClass::getPreferredTagPoolSize() + 1; } void setPreemptionAllocation(GraphicsAllocation *allocation) { this->preemptionAllocation = allocation; } bool waitForCompletionWithTimeout(bool enableTimeout, int64_t timeoutMicroseconds, uint32_t taskCountToWait) override { latestWaitForCompletionWithTimeoutTaskCount.store(taskCountToWait); return BaseClass::waitForCompletionWithTimeout(enableTimeout, timeoutMicroseconds, taskCountToWait); } void overrideCsrSizeReqFlags(CsrSizeRequestFlags &flags) { this->csrSizeRequestFlags = flags; } GraphicsAllocation *getPreemptionAllocation() const { return this->preemptionAllocation; } void makeResident(GraphicsAllocation &gfxAllocation) override { if (storeMakeResidentAllocations) { std::map::iterator it = makeResidentAllocations.find(&gfxAllocation); if (it == makeResidentAllocations.end()) { std::pair::iterator, bool> result; result = makeResidentAllocations.insert(std::pair(&gfxAllocation, 1)); DEBUG_BREAK_IF(!result.second); } else { makeResidentAllocations[&gfxAllocation]++; } } BaseClass::makeResident(gfxAllocation); } bool isMadeResident(GraphicsAllocation *graphicsAllocation) const { return makeResidentAllocations.find(graphicsAllocation) != makeResidentAllocations.end(); } bool isMadeResident(GraphicsAllocation *graphicsAllocation, uint32_t taskCount) const { auto it = makeResidentAllocations.find(graphicsAllocation); if (it == makeResidentAllocations.end()) { return false; } return (it->first->getTaskCount(osContext->getContextId()) == taskCount); } std::map makeResidentAllocations; bool storeMakeResidentAllocations = false; AubSubCaptureStatus checkAndActivateAubSubCapture(const MultiDispatchInfo &dispatchInfo) override { auto status = CommandStreamReceiverHw::checkAndActivateAubSubCapture(dispatchInfo); checkAndActivateAubSubCaptureCalled = true; return status; } void addAubComment(const char *message) override { CommandStreamReceiverHw::addAubComment(message); aubCommentMessages.push_back(message); addAubCommentCalled = true; } bool flushBatchedSubmissions() override { flushBatchedSubmissionsCalled = true; return CommandStreamReceiverHw::flushBatchedSubmissions(); } void initProgrammingFlags() override { CommandStreamReceiverHw::initProgrammingFlags(); initProgrammingFlagsCalled = true; } std::unique_lock obtainUniqueOwnership() override { recursiveLockCounter++; return CommandStreamReceiverHw::obtainUniqueOwnership(); } uint32_t blitBuffer(const BlitPropertiesContainer &blitPropertiesContainer, bool blocking) override { blitBufferCalled++; return CommandStreamReceiverHw::blitBuffer(blitPropertiesContainer, blocking); } bool createPerDssBackedBuffer(Device &device) override { createPerDssBackedBufferCalled++; bool result = BaseClass::createPerDssBackedBuffer(device); if (!perDssBackedBuffer) { AllocationProperties properties{device.getRootDeviceIndex(), MemoryConstants::pageSize, GraphicsAllocation::AllocationType::INTERNAL_HEAP}; perDssBackedBuffer = executionEnvironment.memoryManager->allocateGraphicsMemoryWithProperties(properties); } return result; } bool isMultiOsContextCapable() const override { return multiOsContextCapable; } std::atomic recursiveLockCounter; bool createPageTableManagerCalled = false; bool recordFlusheBatchBuffer = false; bool checkAndActivateAubSubCaptureCalled = false; bool addAubCommentCalled = false; std::vector aubCommentMessages; bool flushBatchedSubmissionsCalled = false; uint32_t makeSurfacePackNonResidentCalled = false; bool initProgrammingFlagsCalled = false; LinearStream *lastFlushedCommandStream = nullptr; BatchBuffer latestFlushedBatchBuffer = {}; uint32_t latestSentTaskCountValueDuringFlush = 0; uint32_t blitBufferCalled = 0; uint32_t createPerDssBackedBufferCalled = 0; std::atomic latestWaitForCompletionWithTimeoutTaskCount{0}; DispatchFlags recordedDispatchFlags; bool multiOsContextCapable = false; }; } // namespace NEO