/* * Copyright (C) 2020 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/command_stream/linear_stream.h" #include "shared/source/direct_submission/linux/drm_direct_submission.h" #include "shared/source/os_interface/linux/drm_allocation.h" #include "shared/source/os_interface/linux/drm_buffer_object.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/source/os_interface/linux/os_context_linux.h" #include namespace NEO { template inline std::unique_ptr> DirectSubmissionHw::create(Device &device, OsContext &osContext) { return std::make_unique>(device, osContext); } template DrmDirectSubmission::DrmDirectSubmission(Device &device, OsContext &osContext) : DirectSubmissionHw(device, osContext){}; template inline DrmDirectSubmission::~DrmDirectSubmission() { if (this->ringStart) { this->wait(static_cast(this->currentTagData.tagValue)); this->stopRingBuffer(); auto bb = static_cast(this->ringBuffer)->getBO(); bb->wait(-1); } this->deallocateResources(); } template bool DrmDirectSubmission::allocateOsResources() { this->currentTagData.tagAddress = this->semaphoreGpuVa + MemoryConstants::cacheLineSize; this->currentTagData.tagValue = 0u; this->tagAddress = reinterpret_cast(reinterpret_cast(this->semaphorePtr) + MemoryConstants::cacheLineSize); return true; } template bool DrmDirectSubmission::submit(uint64_t gpuAddress, size_t size) { auto bb = static_cast(this->ringCommandStream.getGraphicsAllocation())->getBO(); auto osContextLinux = static_cast(&this->osContext); auto execFlags = osContextLinux->getEngineFlag() | I915_EXEC_NO_RELOC; auto &drmContextIds = osContextLinux->getDrmContextIds(); drm_i915_gem_exec_object2 execObject{}; bool ret = false; uint32_t drmContextId = 0u; for (auto drmIterator = 0u; drmIterator < osContextLinux->getDeviceBitfield().size(); drmIterator++) { if (osContextLinux->getDeviceBitfield().test(drmIterator)) { ret |= !!bb->exec(static_cast(size), 0, execFlags, false, &this->osContext, drmIterator, drmContextIds[drmContextId], nullptr, 0, &execObject); drmContextId++; } } return !ret; } template bool DrmDirectSubmission::handleResidency() { return true; } template void DrmDirectSubmission::handleSwitchRingBuffers() { if (this->ringStart) { if (this->completionRingBuffers[this->currentRingBuffer] != 0) { this->wait(static_cast(this->completionRingBuffers[this->currentRingBuffer])); } } } template uint64_t DrmDirectSubmission::updateTagValue() { this->currentTagData.tagValue++; this->completionRingBuffers[this->currentRingBuffer] = this->currentTagData.tagValue; return 0ull; } template void DrmDirectSubmission::getTagAddressValue(TagData &tagData) { tagData.tagAddress = this->currentTagData.tagAddress; tagData.tagValue = this->currentTagData.tagValue + 1; } template void DrmDirectSubmission::wait(uint32_t taskCountToWait) { while (taskCountToWait > *this->tagAddress) { } } } // namespace NEO