mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 14:02:58 +08:00
refactor: move i915 ioctl helper to dedicated file
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
8ca8d72a4c
commit
d8f6551b6b
@@ -55,6 +55,7 @@ set(NEO_CORE_OS_INTERFACE_LINUX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/i915_upstream.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_i915.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ioctl_helper_prelim.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}ioctl_helper_getter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/engine_info.h
|
||||
|
||||
@@ -8,20 +8,13 @@
|
||||
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/execution_environment/execution_environment.h"
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/helpers/compiler_product_helper.h"
|
||||
#include "shared/source/helpers/constants.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/helpers/ptr_math.h"
|
||||
#include "shared/source/helpers/register_offsets.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/source/os_interface/linux/drm_wrappers.h"
|
||||
#include "shared/source/os_interface/linux/engine_info.h"
|
||||
#include "shared/source/os_interface/linux/i915.h"
|
||||
#include "shared/source/os_interface/linux/memory_info.h"
|
||||
#include "shared/source/os_interface/linux/os_context_linux.h"
|
||||
#include "shared/source/os_interface/os_time.h"
|
||||
|
||||
#include "drm/drm.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sstream>
|
||||
@@ -32,31 +25,6 @@ int IoctlHelper::ioctl(DrmIoctl request, void *arg) {
|
||||
return drm.ioctl(request, arg);
|
||||
}
|
||||
|
||||
void IoctlHelper::fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) {
|
||||
|
||||
auto &drmExecObject = *reinterpret_cast<drm_i915_gem_exec_object2 *>(execObject.data);
|
||||
drmExecObject.handle = handle;
|
||||
drmExecObject.relocation_count = 0; // No relocations, we are SoftPinning
|
||||
drmExecObject.relocs_ptr = 0ul;
|
||||
drmExecObject.alignment = 0;
|
||||
drmExecObject.offset = gpuAddress;
|
||||
drmExecObject.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
|
||||
|
||||
if (debugManager.flags.UseAsyncDrmExec.get() == 1) {
|
||||
drmExecObject.flags |= static_cast<decltype(drmExecObject.flags)>(EXEC_OBJECT_ASYNC);
|
||||
}
|
||||
|
||||
if (isMarkedForCapture) {
|
||||
drmExecObject.flags |= static_cast<decltype(drmExecObject.flags)>(EXEC_OBJECT_CAPTURE);
|
||||
}
|
||||
drmExecObject.rsvd1 = drmContextId;
|
||||
drmExecObject.rsvd2 = 0;
|
||||
|
||||
if (bindInfo) {
|
||||
drmExecObject.handle = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
void IoctlHelper::setupIpVersion() {
|
||||
auto &rootDeviceEnvironment = drm.getRootDeviceEnvironment();
|
||||
auto &hwInfo = *rootDeviceEnvironment.getMutableHardwareInfo();
|
||||
@@ -64,605 +32,39 @@ void IoctlHelper::setupIpVersion() {
|
||||
hwInfo.ipVersion.value = compilerProductHelper.getHwIpVersion(hwInfo);
|
||||
}
|
||||
|
||||
void IoctlHelper::logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) {
|
||||
auto &drmExecObject = *reinterpret_cast<const drm_i915_gem_exec_object2 *>(execObject.data);
|
||||
logger << "Buffer Object = { handle: BO-" << drmExecObject.handle
|
||||
<< ", address range: 0x" << reinterpret_cast<void *>(drmExecObject.offset)
|
||||
<< " - 0x" << reinterpret_cast<void *>(ptrOffset(drmExecObject.offset, size))
|
||||
<< ", flags: " << std::hex << drmExecObject.flags << std::dec
|
||||
<< ", size: " << size << " }\n";
|
||||
}
|
||||
|
||||
void IoctlHelper::fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId) {
|
||||
auto &drmExecBuffer = *reinterpret_cast<drm_i915_gem_execbuffer2 *>(execBuffer.data);
|
||||
drmExecBuffer.buffers_ptr = buffersPtr;
|
||||
drmExecBuffer.buffer_count = bufferCount;
|
||||
drmExecBuffer.batch_start_offset = startOffset;
|
||||
drmExecBuffer.batch_len = size;
|
||||
drmExecBuffer.flags = flags;
|
||||
drmExecBuffer.rsvd1 = drmContextId;
|
||||
}
|
||||
|
||||
void IoctlHelper::logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) {
|
||||
auto &drmExecBuffer = *reinterpret_cast<const drm_i915_gem_execbuffer2 *>(execBuffer.data);
|
||||
logger << "drm_i915_gem_execbuffer2 { "
|
||||
<< "buffer_ptr: " + std::to_string(drmExecBuffer.buffers_ptr)
|
||||
<< ", buffer_count: " + std::to_string(drmExecBuffer.buffer_count)
|
||||
<< ", batch_start_offset: " + std::to_string(drmExecBuffer.batch_start_offset)
|
||||
<< ", batch_len: " + std::to_string(drmExecBuffer.batch_len)
|
||||
<< ", flags: " + std::to_string(drmExecBuffer.flags)
|
||||
<< ", rsvd1: " + std::to_string(drmExecBuffer.rsvd1)
|
||||
<< " }\n";
|
||||
}
|
||||
|
||||
int IoctlHelper::createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex) {
|
||||
|
||||
const auto numberOfCCS = drm.getRootDeviceEnvironment().getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled;
|
||||
const bool debuggableContext = drm.isContextDebugSupported() && drm.getRootDeviceEnvironment().executionEnvironment.isDebuggingEnabled() && !osContext.isInternalEngine();
|
||||
const bool debuggableContextCooperative = drm.getRootDeviceEnvironment().executionEnvironment.getDebuggingMode() == DebuggingMode::offline ? false : (debuggableContext && numberOfCCS > 0);
|
||||
auto drmContextId = drm.createDrmContext(drmVmId, drm.isVmBindAvailable(), osContext.isCooperativeEngine() || debuggableContextCooperative);
|
||||
if (drmContextId < 0) {
|
||||
return drmContextId;
|
||||
}
|
||||
|
||||
if (drm.areNonPersistentContextsSupported()) {
|
||||
drm.setNonPersistentContext(drmContextId);
|
||||
}
|
||||
|
||||
drm.setUnrecoverableContext(drmContextId);
|
||||
|
||||
if (debuggableContext) {
|
||||
drm.setContextDebugFlag(drmContextId);
|
||||
}
|
||||
|
||||
if (drm.isPreemptionSupported() && osContext.isLowPriority()) {
|
||||
drm.setLowPriorityContextParam(drmContextId);
|
||||
}
|
||||
auto engineFlag = drm.bindDrmContext(drmContextId, deviceIndex, osContext.getEngineType(), osContext.isEngineInstanced());
|
||||
osContext.setEngineFlag(engineFlag);
|
||||
return drmContextId;
|
||||
}
|
||||
|
||||
std::vector<EngineCapabilities> IoctlHelper::translateToEngineCaps(const std::vector<uint64_t> &data) {
|
||||
auto engineInfo = reinterpret_cast<const drm_i915_query_engine_info *>(data.data());
|
||||
std::vector<EngineCapabilities> engines;
|
||||
engines.reserve(engineInfo->num_engines);
|
||||
for (uint32_t i = 0; i < engineInfo->num_engines; i++) {
|
||||
EngineCapabilities engine{};
|
||||
engine.capabilities = engineInfo->engines[i].capabilities;
|
||||
engine.engine.engineClass = engineInfo->engines[i].engine.engine_class;
|
||||
engine.engine.engineInstance = engineInfo->engines[i].engine.engine_instance;
|
||||
engines.push_back(engine);
|
||||
}
|
||||
return engines;
|
||||
}
|
||||
|
||||
std::vector<MemoryRegion> IoctlHelper::translateToMemoryRegions(const std::vector<uint64_t> ®ionInfo) {
|
||||
auto *data = reinterpret_cast<const drm_i915_query_memory_regions *>(regionInfo.data());
|
||||
auto memRegions = std::vector<MemoryRegion>(data->num_regions);
|
||||
for (uint32_t i = 0; i < data->num_regions; i++) {
|
||||
memRegions[i].probedSize = data->regions[i].probed_size;
|
||||
memRegions[i].unallocatedSize = data->regions[i].unallocated_size;
|
||||
memRegions[i].region.memoryClass = data->regions[i].region.memory_class;
|
||||
memRegions[i].region.memoryInstance = data->regions[i].region.memory_instance;
|
||||
}
|
||||
return memRegions;
|
||||
}
|
||||
|
||||
bool IoctlHelper::setDomainCpu(uint32_t handle, bool writeEnable) {
|
||||
drm_i915_gem_set_domain setDomain{};
|
||||
setDomain.handle = handle;
|
||||
setDomain.read_domains = I915_GEM_DOMAIN_CPU;
|
||||
setDomain.write_domain = writeEnable ? I915_GEM_DOMAIN_CPU : 0;
|
||||
return this->ioctl(DrmIoctl::gemSetDomain, &setDomain) == 0;
|
||||
}
|
||||
|
||||
uint32_t IoctlHelper::getFlagsForPrimeHandleToFd() const {
|
||||
return DRM_CLOEXEC | DRM_RDWR;
|
||||
}
|
||||
|
||||
unsigned int IoctlHelper::getIoctlRequestValueBase(DrmIoctl ioctlRequest) const {
|
||||
switch (ioctlRequest) {
|
||||
case DrmIoctl::getparam:
|
||||
return DRM_IOCTL_I915_GETPARAM;
|
||||
case DrmIoctl::gemExecbuffer2:
|
||||
return DRM_IOCTL_I915_GEM_EXECBUFFER2;
|
||||
case DrmIoctl::gemWait:
|
||||
return DRM_IOCTL_I915_GEM_WAIT;
|
||||
case DrmIoctl::gemClose:
|
||||
return DRM_IOCTL_GEM_CLOSE;
|
||||
case DrmIoctl::gemUserptr:
|
||||
return DRM_IOCTL_I915_GEM_USERPTR;
|
||||
case DrmIoctl::gemCreate:
|
||||
return DRM_IOCTL_I915_GEM_CREATE;
|
||||
case DrmIoctl::gemSetDomain:
|
||||
return DRM_IOCTL_I915_GEM_SET_DOMAIN;
|
||||
case DrmIoctl::gemSetTiling:
|
||||
return DRM_IOCTL_I915_GEM_SET_TILING;
|
||||
case DrmIoctl::gemGetTiling:
|
||||
return DRM_IOCTL_I915_GEM_GET_TILING;
|
||||
case DrmIoctl::gemContextCreateExt:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT;
|
||||
case DrmIoctl::gemContextDestroy:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_DESTROY;
|
||||
case DrmIoctl::regRead:
|
||||
return DRM_IOCTL_I915_REG_READ;
|
||||
case DrmIoctl::getResetStats:
|
||||
return DRM_IOCTL_I915_GET_RESET_STATS;
|
||||
case DrmIoctl::gemContextGetparam:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM;
|
||||
case DrmIoctl::gemContextSetparam:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM;
|
||||
case DrmIoctl::query:
|
||||
return DRM_IOCTL_I915_QUERY;
|
||||
case DrmIoctl::primeFdToHandle:
|
||||
return DRM_IOCTL_PRIME_FD_TO_HANDLE;
|
||||
case DrmIoctl::primeHandleToFd:
|
||||
return DRM_IOCTL_PRIME_HANDLE_TO_FD;
|
||||
case DrmIoctl::gemMmapOffset:
|
||||
return DRM_IOCTL_I915_GEM_MMAP_OFFSET;
|
||||
case DrmIoctl::gemVmCreate:
|
||||
return DRM_IOCTL_I915_GEM_VM_CREATE;
|
||||
case DrmIoctl::gemVmDestroy:
|
||||
return DRM_IOCTL_I915_GEM_VM_DESTROY;
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
return 0u;
|
||||
}
|
||||
}
|
||||
|
||||
int IoctlHelper::getDrmParamValueBase(DrmParam drmParam) const {
|
||||
switch (drmParam) {
|
||||
case DrmParam::contextCreateExtSetparam:
|
||||
return I915_CONTEXT_CREATE_EXT_SETPARAM;
|
||||
case DrmParam::contextCreateFlagsUseExtensions:
|
||||
return I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS;
|
||||
case DrmParam::contextEnginesExtLoadBalance:
|
||||
return I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE;
|
||||
case DrmParam::contextParamEngines:
|
||||
return I915_CONTEXT_PARAM_ENGINES;
|
||||
case DrmParam::contextParamGttSize:
|
||||
return I915_CONTEXT_PARAM_GTT_SIZE;
|
||||
case DrmParam::contextParamPersistence:
|
||||
return I915_CONTEXT_PARAM_PERSISTENCE;
|
||||
case DrmParam::contextParamPriority:
|
||||
return I915_CONTEXT_PARAM_PRIORITY;
|
||||
case DrmParam::contextParamRecoverable:
|
||||
return I915_CONTEXT_PARAM_RECOVERABLE;
|
||||
case DrmParam::contextParamSseu:
|
||||
return I915_CONTEXT_PARAM_SSEU;
|
||||
case DrmParam::contextParamVm:
|
||||
return I915_CONTEXT_PARAM_VM;
|
||||
case DrmParam::engineClassRender:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER;
|
||||
case DrmParam::engineClassCopy:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY;
|
||||
case DrmParam::engineClassVideo:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO;
|
||||
case DrmParam::engineClassVideoEnhance:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE;
|
||||
case DrmParam::engineClassInvalid:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_INVALID;
|
||||
case DrmParam::engineClassInvalidNone:
|
||||
return I915_ENGINE_CLASS_INVALID_NONE;
|
||||
case DrmParam::execBlt:
|
||||
return I915_EXEC_BLT;
|
||||
case DrmParam::execDefault:
|
||||
return I915_EXEC_DEFAULT;
|
||||
case DrmParam::execNoReloc:
|
||||
return I915_EXEC_NO_RELOC;
|
||||
case DrmParam::execRender:
|
||||
return I915_EXEC_RENDER;
|
||||
case DrmParam::memoryClassDevice:
|
||||
return drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE;
|
||||
case DrmParam::memoryClassSystem:
|
||||
return drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM;
|
||||
case DrmParam::mmapOffsetWb:
|
||||
return I915_MMAP_OFFSET_WB;
|
||||
case DrmParam::mmapOffsetWc:
|
||||
return I915_MMAP_OFFSET_WC;
|
||||
case DrmParam::paramChipsetId:
|
||||
return I915_PARAM_CHIPSET_ID;
|
||||
case DrmParam::paramRevision:
|
||||
return I915_PARAM_REVISION;
|
||||
case DrmParam::paramHasExecSoftpin:
|
||||
return I915_PARAM_HAS_EXEC_SOFTPIN;
|
||||
case DrmParam::paramHasPooledEu:
|
||||
return I915_PARAM_HAS_POOLED_EU;
|
||||
case DrmParam::paramHasScheduler:
|
||||
return I915_PARAM_HAS_SCHEDULER;
|
||||
case DrmParam::paramEuTotal:
|
||||
return I915_PARAM_EU_TOTAL;
|
||||
case DrmParam::paramSubsliceTotal:
|
||||
return I915_PARAM_SUBSLICE_TOTAL;
|
||||
case DrmParam::paramMinEuInPool:
|
||||
return I915_PARAM_MIN_EU_IN_POOL;
|
||||
case DrmParam::paramCsTimestampFrequency:
|
||||
return I915_PARAM_CS_TIMESTAMP_FREQUENCY;
|
||||
case DrmParam::queryEngineInfo:
|
||||
return DRM_I915_QUERY_ENGINE_INFO;
|
||||
case DrmParam::queryMemoryRegions:
|
||||
return DRM_I915_QUERY_MEMORY_REGIONS;
|
||||
case DrmParam::queryTopologyInfo:
|
||||
return DRM_I915_QUERY_TOPOLOGY_INFO;
|
||||
case DrmParam::schedulerCapPreemption:
|
||||
return I915_SCHEDULER_CAP_PREEMPTION;
|
||||
case DrmParam::tilingNone:
|
||||
return I915_TILING_NONE;
|
||||
case DrmParam::tilingY:
|
||||
return I915_TILING_Y;
|
||||
case DrmParam::paramOATimestampFrequency:
|
||||
return I915_PARAM_OA_TIMESTAMP_FREQUENCY;
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string IoctlHelper::getDrmParamStringBase(DrmParam drmParam) const {
|
||||
switch (drmParam) {
|
||||
case DrmParam::paramChipsetId:
|
||||
return "I915_PARAM_CHIPSET_ID";
|
||||
case DrmParam::paramRevision:
|
||||
return "I915_PARAM_REVISION";
|
||||
case DrmParam::paramHasExecSoftpin:
|
||||
return "I915_PARAM_HAS_EXEC_SOFTPIN";
|
||||
case DrmParam::paramHasPooledEu:
|
||||
return "I915_PARAM_HAS_POOLED_EU";
|
||||
case DrmParam::paramHasScheduler:
|
||||
return "I915_PARAM_HAS_SCHEDULER";
|
||||
case DrmParam::paramEuTotal:
|
||||
return "I915_PARAM_EU_TOTAL";
|
||||
case DrmParam::paramSubsliceTotal:
|
||||
return "I915_PARAM_SUBSLICE_TOTAL";
|
||||
case DrmParam::paramMinEuInPool:
|
||||
return "I915_PARAM_MIN_EU_IN_POOL";
|
||||
case DrmParam::paramCsTimestampFrequency:
|
||||
return "I915_PARAM_CS_TIMESTAMP_FREQUENCY";
|
||||
case DrmParam::paramOATimestampFrequency:
|
||||
return "I915_PARAM_OA_TIMESTAMP_FREQUENCY";
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string IoctlHelper::getIoctlStringBase(DrmIoctl ioctlRequest) const {
|
||||
switch (ioctlRequest) {
|
||||
case DrmIoctl::gemExecbuffer2:
|
||||
return "DRM_IOCTL_I915_GEM_EXECBUFFER2";
|
||||
case DrmIoctl::gemWait:
|
||||
return "DRM_IOCTL_I915_GEM_WAIT";
|
||||
case DrmIoctl::gemClose:
|
||||
return "DRM_IOCTL_GEM_CLOSE";
|
||||
case DrmIoctl::gemUserptr:
|
||||
return "DRM_IOCTL_I915_GEM_USERPTR";
|
||||
case DrmIoctl::getparam:
|
||||
return "DRM_IOCTL_I915_GETPARAM";
|
||||
case DrmIoctl::gemCreate:
|
||||
return "DRM_IOCTL_I915_GEM_CREATE";
|
||||
case DrmIoctl::gemSetDomain:
|
||||
return "DRM_IOCTL_I915_GEM_SET_DOMAIN";
|
||||
case DrmIoctl::gemSetTiling:
|
||||
return "DRM_IOCTL_I915_GEM_SET_TILING";
|
||||
case DrmIoctl::gemGetTiling:
|
||||
return "DRM_IOCTL_I915_GEM_GET_TILING";
|
||||
case DrmIoctl::gemContextCreateExt:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT";
|
||||
case DrmIoctl::gemContextDestroy:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY";
|
||||
case DrmIoctl::regRead:
|
||||
return "DRM_IOCTL_I915_REG_READ";
|
||||
case DrmIoctl::getResetStats:
|
||||
return "DRM_IOCTL_I915_GET_RESET_STATS";
|
||||
case DrmIoctl::gemContextGetparam:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM";
|
||||
case DrmIoctl::gemContextSetparam:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM";
|
||||
case DrmIoctl::query:
|
||||
return "DRM_IOCTL_I915_QUERY";
|
||||
case DrmIoctl::primeFdToHandle:
|
||||
return "DRM_IOCTL_PRIME_FD_TO_HANDLE";
|
||||
case DrmIoctl::primeHandleToFd:
|
||||
return "DRM_IOCTL_PRIME_HANDLE_TO_FD";
|
||||
case DrmIoctl::gemMmapOffset:
|
||||
return "DRM_IOCTL_I915_GEM_MMAP_OFFSET";
|
||||
case DrmIoctl::gemVmCreate:
|
||||
return "DRM_IOCTL_I915_GEM_VM_CREATE";
|
||||
case DrmIoctl::gemVmDestroy:
|
||||
return "DRM_IOCTL_I915_GEM_VM_DESTROY";
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string IoctlHelper::getFileForMaxGpuFrequency() const {
|
||||
return "/gt_max_freq_mhz";
|
||||
}
|
||||
|
||||
std::string IoctlHelper::getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const {
|
||||
return "/gt/gt" + std::to_string(subDeviceId) + "/rps_max_freq_mhz";
|
||||
}
|
||||
|
||||
std::string IoctlHelper::getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const {
|
||||
return "/gt/gt" + std::to_string(subDeviceId) + "/mem_RP0_freq_mhz";
|
||||
}
|
||||
|
||||
bool IoctlHelper::checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const {
|
||||
return (error == EINTR || error == EAGAIN || error == EBUSY || error == -EBUSY);
|
||||
}
|
||||
|
||||
std::unique_ptr<MemoryInfo> IoctlHelper::createMemoryInfo() {
|
||||
auto request = getDrmParamValue(DrmParam::queryMemoryRegions);
|
||||
auto dataQuery = drm.query<uint64_t>(request, 0);
|
||||
if (!dataQuery.empty()) {
|
||||
auto memRegions = translateToMemoryRegions(dataQuery);
|
||||
return std::make_unique<MemoryInfo>(memRegions, drm);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool IoctlHelper::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) {
|
||||
|
||||
auto request = this->getDrmParamValue(DrmParam::queryTopologyInfo);
|
||||
auto dataQuery = drm.query<uint64_t>(request, 0);
|
||||
if (dataQuery.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto topologyInfo = reinterpret_cast<QueryTopologyInfo *>(dataQuery.data());
|
||||
|
||||
TopologyMapping mapping;
|
||||
auto retVal = this->translateTopologyInfo(topologyInfo, topologyData, mapping);
|
||||
topologyData.maxEuPerSubSlice = topologyInfo->maxEusPerSubslice;
|
||||
|
||||
topologyMap.clear();
|
||||
topologyMap[0] = mapping;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool IoctlHelper::translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping) {
|
||||
int sliceCount = 0;
|
||||
int subSliceCount = 0;
|
||||
int euCount = 0;
|
||||
int maxSliceCount = 0;
|
||||
int maxSubSliceCountPerSlice = 0;
|
||||
std::vector<int> sliceIndices;
|
||||
sliceIndices.reserve(maxSliceCount);
|
||||
|
||||
for (int x = 0; x < queryTopologyInfo->maxSlices; x++) {
|
||||
bool isSliceEnable = (queryTopologyInfo->data[x / 8] >> (x % 8)) & 1;
|
||||
if (!isSliceEnable) {
|
||||
continue;
|
||||
}
|
||||
sliceIndices.push_back(x);
|
||||
sliceCount++;
|
||||
|
||||
std::vector<int> subSliceIndices;
|
||||
subSliceIndices.reserve(queryTopologyInfo->maxSubslices);
|
||||
|
||||
for (int y = 0; y < queryTopologyInfo->maxSubslices; y++) {
|
||||
size_t yOffset = (queryTopologyInfo->subsliceOffset + static_cast<size_t>(x * queryTopologyInfo->subsliceStride) + y / 8);
|
||||
bool isSubSliceEnabled = (queryTopologyInfo->data[yOffset] >> (y % 8)) & 1;
|
||||
if (!isSubSliceEnabled) {
|
||||
continue;
|
||||
}
|
||||
subSliceCount++;
|
||||
subSliceIndices.push_back(y);
|
||||
|
||||
for (int z = 0; z < queryTopologyInfo->maxEusPerSubslice; z++) {
|
||||
size_t zOffset = (queryTopologyInfo->euOffset + static_cast<size_t>((x * queryTopologyInfo->maxSubslices + y) * queryTopologyInfo->euStride) + z / 8);
|
||||
bool isEUEnabled = (queryTopologyInfo->data[zOffset] >> (z % 8)) & 1;
|
||||
if (!isEUEnabled) {
|
||||
continue;
|
||||
}
|
||||
euCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (subSliceIndices.size()) {
|
||||
maxSubSliceCountPerSlice = std::max(maxSubSliceCountPerSlice, subSliceIndices[subSliceIndices.size() - 1] + 1);
|
||||
}
|
||||
|
||||
// single slice available
|
||||
if (sliceCount == 1) {
|
||||
mapping.subsliceIndices = std::move(subSliceIndices);
|
||||
}
|
||||
}
|
||||
|
||||
if (sliceIndices.size()) {
|
||||
maxSliceCount = sliceIndices[sliceIndices.size() - 1] + 1;
|
||||
mapping.sliceIndices = std::move(sliceIndices);
|
||||
}
|
||||
|
||||
if (sliceCount != 1) {
|
||||
mapping.subsliceIndices.clear();
|
||||
}
|
||||
|
||||
topologyData.sliceCount = sliceCount;
|
||||
topologyData.subSliceCount = subSliceCount;
|
||||
topologyData.euCount = euCount;
|
||||
topologyData.maxSliceCount = maxSliceCount;
|
||||
topologyData.maxSubSliceCount = maxSubSliceCountPerSlice;
|
||||
|
||||
return (sliceCount && subSliceCount && euCount);
|
||||
}
|
||||
|
||||
std::unique_ptr<EngineInfo> IoctlHelper::createEngineInfo(bool isSysmanEnabled) {
|
||||
auto request = getDrmParamValue(DrmParam::queryEngineInfo);
|
||||
auto enginesQuery = drm.query<uint64_t>(request, 0);
|
||||
if (enginesQuery.empty()) {
|
||||
return {};
|
||||
}
|
||||
auto engines = translateToEngineCaps(enginesQuery);
|
||||
auto hwInfo = drm.getRootDeviceEnvironment().getMutableHardwareInfo();
|
||||
|
||||
auto memInfo = drm.getMemoryInfo();
|
||||
|
||||
if (!memInfo) {
|
||||
return std::make_unique<EngineInfo>(&drm, engines);
|
||||
}
|
||||
|
||||
auto &memoryRegions = memInfo->getDrmRegionInfos();
|
||||
|
||||
auto tileCount = 0u;
|
||||
std::vector<DistanceInfo> distanceInfos;
|
||||
for (const auto ®ion : memoryRegions) {
|
||||
if (getDrmParamValue(DrmParam::memoryClassDevice) == region.region.memoryClass) {
|
||||
tileCount++;
|
||||
DistanceInfo distanceInfo{};
|
||||
distanceInfo.region = region.region;
|
||||
|
||||
for (const auto &engine : engines) {
|
||||
if (engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassCompute) ||
|
||||
engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassRender) ||
|
||||
engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassCopy)) {
|
||||
distanceInfo.engine = engine.engine;
|
||||
distanceInfos.push_back(distanceInfo);
|
||||
} else if (isSysmanEnabled) {
|
||||
|
||||
if (engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassVideo) ||
|
||||
engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassVideoEnhance)) {
|
||||
distanceInfo.engine = engine.engine;
|
||||
distanceInfos.push_back(distanceInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tileCount == 0u) {
|
||||
return std::make_unique<EngineInfo>(&drm, engines);
|
||||
}
|
||||
|
||||
std::vector<QueryItem> queryItems{distanceInfos.size()};
|
||||
auto ret = queryDistances(queryItems, distanceInfos);
|
||||
if (ret != 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const bool queryUnsupported = std::all_of(queryItems.begin(), queryItems.end(),
|
||||
[](const QueryItem &item) { return item.length == -EINVAL; });
|
||||
if (queryUnsupported) {
|
||||
DEBUG_BREAK_IF(tileCount != 1);
|
||||
return std::make_unique<EngineInfo>(&drm, engines);
|
||||
}
|
||||
|
||||
memInfo->assignRegionsFromDistances(distanceInfos);
|
||||
|
||||
auto &multiTileArchInfo = hwInfo->gtSystemInfo.MultiTileArchInfo;
|
||||
multiTileArchInfo.IsValid = true;
|
||||
multiTileArchInfo.TileCount = tileCount;
|
||||
multiTileArchInfo.TileMask = static_cast<uint8_t>(maxNBitValue(tileCount));
|
||||
|
||||
return std::make_unique<EngineInfo>(&drm, tileCount, distanceInfos, queryItems, engines);
|
||||
}
|
||||
|
||||
void IoctlHelper::fillBindInfoForIpcHandle(uint32_t handle, size_t size) {}
|
||||
|
||||
bool IoctlHelper::getFdFromVmExport(uint32_t vmId, uint32_t flags, int32_t *fd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t IoctlHelper::createGem(uint64_t size, uint32_t memoryBanks) {
|
||||
GemCreate gemCreate = {};
|
||||
gemCreate.size = size;
|
||||
[[maybe_unused]] auto ret = ioctl(DrmIoctl::gemCreate, &gemCreate);
|
||||
DEBUG_BREAK_IF(ret != 0);
|
||||
return gemCreate.handle;
|
||||
}
|
||||
|
||||
bool IoctlHelper::setGemTiling(void *setTiling) {
|
||||
return this->ioctl(DrmIoctl::gemSetTiling, setTiling) == 0;
|
||||
}
|
||||
|
||||
bool IoctlHelper::getGemTiling(void *setTiling) {
|
||||
return this->ioctl(DrmIoctl::gemGetTiling, setTiling) == 0;
|
||||
}
|
||||
|
||||
bool getGpuTime32(::NEO::Drm &drm, uint64_t *timestamp) {
|
||||
RegisterRead reg = {};
|
||||
reg.offset = RegisterOffsets::globalTimestampLdw;
|
||||
|
||||
if (drm.ioctl(DrmIoctl::regRead, ®)) {
|
||||
return false;
|
||||
}
|
||||
*timestamp = reg.value >> 32;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getGpuTime36(::NEO::Drm &drm, uint64_t *timestamp) {
|
||||
RegisterRead reg = {};
|
||||
reg.offset = RegisterOffsets::globalTimestampLdw | 1;
|
||||
|
||||
if (drm.ioctl(DrmIoctl::regRead, ®)) {
|
||||
return false;
|
||||
}
|
||||
*timestamp = reg.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getGpuTimeSplitted(::NEO::Drm &drm, uint64_t *timestamp) {
|
||||
RegisterRead regHi = {};
|
||||
RegisterRead regLo = {};
|
||||
uint64_t tmpHi;
|
||||
int err = 0, loop = 3;
|
||||
|
||||
regHi.offset = RegisterOffsets::globalTimestampUn;
|
||||
regLo.offset = RegisterOffsets::globalTimestampLdw;
|
||||
|
||||
err += drm.ioctl(DrmIoctl::regRead, ®Hi);
|
||||
do {
|
||||
tmpHi = regHi.value;
|
||||
err += drm.ioctl(DrmIoctl::regRead, ®Lo);
|
||||
err += drm.ioctl(DrmIoctl::regRead, ®Hi);
|
||||
} while (err == 0 && regHi.value != tmpHi && --loop);
|
||||
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*timestamp = regLo.value | (regHi.value << 32);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IoctlHelper::initializeGetGpuTimeFunction() {
|
||||
RegisterRead reg = {};
|
||||
int err;
|
||||
|
||||
reg.offset = (RegisterOffsets::globalTimestampLdw | 1);
|
||||
err = this->ioctl(DrmIoctl::regRead, ®);
|
||||
if (err) {
|
||||
reg.offset = RegisterOffsets::globalTimestampUn;
|
||||
err = this->ioctl(DrmIoctl::regRead, ®);
|
||||
if (err) {
|
||||
this->getGpuTime = &getGpuTime32;
|
||||
} else {
|
||||
this->getGpuTime = &getGpuTimeSplitted;
|
||||
}
|
||||
} else {
|
||||
this->getGpuTime = &getGpuTime36;
|
||||
}
|
||||
}
|
||||
|
||||
bool IoctlHelper::setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) {
|
||||
if (pGpuCpuTime == nullptr || osTime == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->getGpuTime == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->getGpuTime(drm, &pGpuCpuTime->gpuTimeStamp)) {
|
||||
return false;
|
||||
}
|
||||
if (!osTime->getCpuTime(&pGpuCpuTime->cpuTimeinNS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -85,7 +85,7 @@ class IoctlHelper {
|
||||
virtual bool isChunkingAvailable() = 0;
|
||||
virtual bool isVmBindAvailable() = 0;
|
||||
virtual int createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, uint64_t patIndex, std::optional<uint32_t> vmId, int32_t pairHandle, bool isChunked, uint32_t numOfChunks) = 0;
|
||||
virtual uint32_t createGem(uint64_t size, uint32_t memoryBanks);
|
||||
virtual uint32_t createGem(uint64_t size, uint32_t memoryBanks) = 0;
|
||||
virtual CacheRegion closAlloc() = 0;
|
||||
virtual uint16_t closAllocWays(CacheRegion closIndex, uint16_t cacheLevel, uint16_t numWays) = 0;
|
||||
virtual CacheRegion closFree(CacheRegion closIndex) = 0;
|
||||
@@ -98,8 +98,8 @@ class IoctlHelper {
|
||||
virtual bool setVmBoAdvise(int32_t handle, uint32_t attribute, void *region) = 0;
|
||||
virtual bool setVmBoAdviseForChunking(int32_t handle, uint64_t start, uint64_t length, uint32_t attribute, void *region) = 0;
|
||||
virtual bool setVmPrefetch(uint64_t start, uint64_t length, uint32_t region, uint32_t vmId) = 0;
|
||||
virtual bool setGemTiling(void *setTiling);
|
||||
virtual bool getGemTiling(void *setTiling);
|
||||
virtual bool setGemTiling(void *setTiling) = 0;
|
||||
virtual bool getGemTiling(void *setTiling) = 0;
|
||||
virtual uint32_t getDirectSubmissionFlag() = 0;
|
||||
virtual std::unique_ptr<uint8_t[]> prepareVmBindExt(const StackVec<uint32_t, 2> &bindExtHandles) = 0;
|
||||
virtual uint64_t getFlagsForVmBind(bool bindCapture, bool bindImmediate, bool bindMakeResident) = 0;
|
||||
@@ -134,25 +134,20 @@ class IoctlHelper {
|
||||
virtual std::string getIoctlString(DrmIoctl ioctlRequest) const = 0;
|
||||
|
||||
virtual bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const;
|
||||
virtual std::vector<MemoryRegion> translateToMemoryRegions(const std::vector<uint64_t> ®ionInfo);
|
||||
virtual int createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex) = 0;
|
||||
|
||||
virtual int createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex);
|
||||
std::vector<EngineCapabilities> translateToEngineCaps(const std::vector<uint64_t> &data);
|
||||
|
||||
virtual void fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture);
|
||||
virtual void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size);
|
||||
|
||||
virtual void fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId);
|
||||
virtual void logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger);
|
||||
virtual int getDrmParamValueBase(DrmParam drmParam) const;
|
||||
virtual void fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) = 0;
|
||||
virtual void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) = 0;
|
||||
virtual void fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId) = 0;
|
||||
virtual void logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) = 0;
|
||||
virtual int getDrmParamValueBase(DrmParam drmParam) const = 0;
|
||||
unsigned int getIoctlRequestValueBase(DrmIoctl ioctlRequest) const;
|
||||
bool setDomainCpu(uint32_t handle, bool writeEnable);
|
||||
virtual bool setDomainCpu(uint32_t handle, bool writeEnable) = 0;
|
||||
|
||||
std::string getDrmParamStringBase(DrmParam param) const;
|
||||
std::string getIoctlStringBase(DrmIoctl ioctlRequest) const;
|
||||
virtual std::string getFileForMaxGpuFrequency() const;
|
||||
virtual std::string getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const;
|
||||
virtual std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const;
|
||||
virtual std::string getFileForMaxGpuFrequency() const = 0;
|
||||
virtual std::string getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const = 0;
|
||||
virtual std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const = 0;
|
||||
virtual bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) = 0;
|
||||
virtual bool isWaitBeforeBindRequired(bool bind) const = 0;
|
||||
virtual void *pciBarrierMmap() { return nullptr; };
|
||||
@@ -160,24 +155,55 @@ class IoctlHelper {
|
||||
virtual bool isImmediateVmBindRequired() const { return false; }
|
||||
|
||||
uint32_t getFlagsForPrimeHandleToFd() const;
|
||||
virtual std::unique_ptr<MemoryInfo> createMemoryInfo();
|
||||
virtual std::unique_ptr<EngineInfo> createEngineInfo(bool isSysmanEnabled);
|
||||
virtual bool getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap);
|
||||
bool translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping);
|
||||
virtual void fillBindInfoForIpcHandle(uint32_t handle, size_t size);
|
||||
virtual bool getFdFromVmExport(uint32_t vmId, uint32_t flags, int32_t *fd);
|
||||
virtual std::unique_ptr<MemoryInfo> createMemoryInfo() = 0;
|
||||
virtual std::unique_ptr<EngineInfo> createEngineInfo(bool isSysmanEnabled) = 0;
|
||||
virtual bool getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) = 0;
|
||||
virtual void fillBindInfoForIpcHandle(uint32_t handle, size_t size) = 0;
|
||||
virtual bool getFdFromVmExport(uint32_t vmId, uint32_t flags, int32_t *fd) = 0;
|
||||
|
||||
virtual void initializeGetGpuTimeFunction();
|
||||
virtual bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime);
|
||||
bool (*getGpuTime)(::NEO::Drm &, uint64_t *) = nullptr;
|
||||
virtual bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) = 0;
|
||||
|
||||
protected:
|
||||
Drm &drm;
|
||||
};
|
||||
|
||||
class IoctlHelperUpstream : public IoctlHelper {
|
||||
class IoctlHelperI915 : public IoctlHelper {
|
||||
public:
|
||||
using IoctlHelper::IoctlHelper;
|
||||
void fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) override;
|
||||
void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) override;
|
||||
void fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId) override;
|
||||
void logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) override;
|
||||
int getDrmParamValueBase(DrmParam drmParam) const override;
|
||||
std::vector<EngineCapabilities> translateToEngineCaps(const std::vector<uint64_t> &data);
|
||||
std::unique_ptr<EngineInfo> createEngineInfo(bool isSysmanEnabled) override;
|
||||
std::unique_ptr<MemoryInfo> createMemoryInfo() override;
|
||||
bool setDomainCpu(uint32_t handle, bool writeEnable) override;
|
||||
unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest) const override;
|
||||
std::string getDrmParamString(DrmParam param) const override;
|
||||
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
|
||||
int createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex) override;
|
||||
std::string getFileForMaxGpuFrequency() const override;
|
||||
std::string getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const override;
|
||||
std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const override;
|
||||
bool getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) override;
|
||||
void fillBindInfoForIpcHandle(uint32_t handle, size_t size) override;
|
||||
bool getFdFromVmExport(uint32_t vmId, uint32_t flags, int32_t *fd) override;
|
||||
uint32_t createGem(uint64_t size, uint32_t memoryBanks) override;
|
||||
bool setGemTiling(void *setTiling) override;
|
||||
bool getGemTiling(void *setTiling) override;
|
||||
bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) override;
|
||||
|
||||
protected:
|
||||
virtual std::vector<MemoryRegion> translateToMemoryRegions(const std::vector<uint64_t> ®ionInfo);
|
||||
bool translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping);
|
||||
MOCKABLE_VIRTUAL void initializeGetGpuTimeFunction();
|
||||
bool (*getGpuTime)(::NEO::Drm &, uint64_t *) = nullptr;
|
||||
};
|
||||
|
||||
class IoctlHelperUpstream : public IoctlHelperI915 {
|
||||
public:
|
||||
using IoctlHelperI915::IoctlHelperI915;
|
||||
|
||||
bool initialize() override;
|
||||
bool isSetPairAvailable() override;
|
||||
@@ -226,7 +252,6 @@ class IoctlHelperUpstream : public IoctlHelper {
|
||||
bool isDebugAttachAvailable() override;
|
||||
unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest) const override;
|
||||
int getDrmParamValue(DrmParam drmParam) const override;
|
||||
std::string getDrmParamString(DrmParam param) const override;
|
||||
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
|
||||
bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) override;
|
||||
bool isWaitBeforeBindRequired(bool bind) const override;
|
||||
@@ -250,7 +275,7 @@ class IoctlHelperImpl : public IoctlHelperUpstream {
|
||||
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
|
||||
};
|
||||
|
||||
class IoctlHelperPrelim20 : public IoctlHelper {
|
||||
class IoctlHelperPrelim20 : public IoctlHelperI915 {
|
||||
public:
|
||||
IoctlHelperPrelim20(Drm &drmArg);
|
||||
|
||||
|
||||
631
shared/source/os_interface/linux/ioctl_helper_i915.cpp
Normal file
631
shared/source/os_interface/linux/ioctl_helper_i915.cpp
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/execution_environment/execution_environment.h"
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/helpers/constants.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/helpers/ptr_math.h"
|
||||
#include "shared/source/helpers/register_offsets.h"
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
#include "shared/source/os_interface/linux/drm_wrappers.h"
|
||||
#include "shared/source/os_interface/linux/engine_info.h"
|
||||
#include "shared/source/os_interface/linux/i915.h"
|
||||
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||
#include "shared/source/os_interface/linux/memory_info.h"
|
||||
#include "shared/source/os_interface/linux/os_context_linux.h"
|
||||
#include "shared/source/os_interface/os_time.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
void IoctlHelperI915::fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) {
|
||||
|
||||
auto &drmExecObject = *reinterpret_cast<drm_i915_gem_exec_object2 *>(execObject.data);
|
||||
drmExecObject.handle = handle;
|
||||
drmExecObject.relocation_count = 0; // No relocations, we are SoftPinning
|
||||
drmExecObject.relocs_ptr = 0ul;
|
||||
drmExecObject.alignment = 0;
|
||||
drmExecObject.offset = gpuAddress;
|
||||
drmExecObject.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
|
||||
|
||||
if (debugManager.flags.UseAsyncDrmExec.get() == 1) {
|
||||
drmExecObject.flags |= static_cast<decltype(drmExecObject.flags)>(EXEC_OBJECT_ASYNC);
|
||||
}
|
||||
|
||||
if (isMarkedForCapture) {
|
||||
drmExecObject.flags |= static_cast<decltype(drmExecObject.flags)>(EXEC_OBJECT_CAPTURE);
|
||||
}
|
||||
drmExecObject.rsvd1 = drmContextId;
|
||||
drmExecObject.rsvd2 = 0;
|
||||
|
||||
if (bindInfo) {
|
||||
drmExecObject.handle = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
void IoctlHelperI915::logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) {
|
||||
auto &drmExecObject = *reinterpret_cast<const drm_i915_gem_exec_object2 *>(execObject.data);
|
||||
logger << "Buffer Object = { handle: BO-" << drmExecObject.handle
|
||||
<< ", address range: 0x" << reinterpret_cast<void *>(drmExecObject.offset)
|
||||
<< " - 0x" << reinterpret_cast<void *>(ptrOffset(drmExecObject.offset, size))
|
||||
<< ", flags: " << std::hex << drmExecObject.flags << std::dec
|
||||
<< ", size: " << size << " }\n";
|
||||
}
|
||||
|
||||
void IoctlHelperI915::fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId) {
|
||||
auto &drmExecBuffer = *reinterpret_cast<drm_i915_gem_execbuffer2 *>(execBuffer.data);
|
||||
drmExecBuffer.buffers_ptr = buffersPtr;
|
||||
drmExecBuffer.buffer_count = bufferCount;
|
||||
drmExecBuffer.batch_start_offset = startOffset;
|
||||
drmExecBuffer.batch_len = size;
|
||||
drmExecBuffer.flags = flags;
|
||||
drmExecBuffer.rsvd1 = drmContextId;
|
||||
}
|
||||
|
||||
void IoctlHelperI915::logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) {
|
||||
auto &drmExecBuffer = *reinterpret_cast<const drm_i915_gem_execbuffer2 *>(execBuffer.data);
|
||||
logger << "drm_i915_gem_execbuffer2 { "
|
||||
<< "buffer_ptr: " + std::to_string(drmExecBuffer.buffers_ptr)
|
||||
<< ", buffer_count: " + std::to_string(drmExecBuffer.buffer_count)
|
||||
<< ", batch_start_offset: " + std::to_string(drmExecBuffer.batch_start_offset)
|
||||
<< ", batch_len: " + std::to_string(drmExecBuffer.batch_len)
|
||||
<< ", flags: " + std::to_string(drmExecBuffer.flags)
|
||||
<< ", rsvd1: " + std::to_string(drmExecBuffer.rsvd1)
|
||||
<< " }\n";
|
||||
}
|
||||
|
||||
int IoctlHelperI915::getDrmParamValueBase(DrmParam drmParam) const {
|
||||
switch (drmParam) {
|
||||
case DrmParam::contextCreateExtSetparam:
|
||||
return I915_CONTEXT_CREATE_EXT_SETPARAM;
|
||||
case DrmParam::contextCreateFlagsUseExtensions:
|
||||
return I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS;
|
||||
case DrmParam::contextEnginesExtLoadBalance:
|
||||
return I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE;
|
||||
case DrmParam::contextParamEngines:
|
||||
return I915_CONTEXT_PARAM_ENGINES;
|
||||
case DrmParam::contextParamGttSize:
|
||||
return I915_CONTEXT_PARAM_GTT_SIZE;
|
||||
case DrmParam::contextParamPersistence:
|
||||
return I915_CONTEXT_PARAM_PERSISTENCE;
|
||||
case DrmParam::contextParamPriority:
|
||||
return I915_CONTEXT_PARAM_PRIORITY;
|
||||
case DrmParam::contextParamRecoverable:
|
||||
return I915_CONTEXT_PARAM_RECOVERABLE;
|
||||
case DrmParam::contextParamSseu:
|
||||
return I915_CONTEXT_PARAM_SSEU;
|
||||
case DrmParam::contextParamVm:
|
||||
return I915_CONTEXT_PARAM_VM;
|
||||
case DrmParam::engineClassRender:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER;
|
||||
case DrmParam::engineClassCopy:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY;
|
||||
case DrmParam::engineClassVideo:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO;
|
||||
case DrmParam::engineClassVideoEnhance:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE;
|
||||
case DrmParam::engineClassInvalid:
|
||||
return drm_i915_gem_engine_class::I915_ENGINE_CLASS_INVALID;
|
||||
case DrmParam::engineClassInvalidNone:
|
||||
return I915_ENGINE_CLASS_INVALID_NONE;
|
||||
case DrmParam::execBlt:
|
||||
return I915_EXEC_BLT;
|
||||
case DrmParam::execDefault:
|
||||
return I915_EXEC_DEFAULT;
|
||||
case DrmParam::execNoReloc:
|
||||
return I915_EXEC_NO_RELOC;
|
||||
case DrmParam::execRender:
|
||||
return I915_EXEC_RENDER;
|
||||
case DrmParam::memoryClassDevice:
|
||||
return drm_i915_gem_memory_class::I915_MEMORY_CLASS_DEVICE;
|
||||
case DrmParam::memoryClassSystem:
|
||||
return drm_i915_gem_memory_class::I915_MEMORY_CLASS_SYSTEM;
|
||||
case DrmParam::mmapOffsetWb:
|
||||
return I915_MMAP_OFFSET_WB;
|
||||
case DrmParam::mmapOffsetWc:
|
||||
return I915_MMAP_OFFSET_WC;
|
||||
case DrmParam::paramChipsetId:
|
||||
return I915_PARAM_CHIPSET_ID;
|
||||
case DrmParam::paramRevision:
|
||||
return I915_PARAM_REVISION;
|
||||
case DrmParam::paramHasExecSoftpin:
|
||||
return I915_PARAM_HAS_EXEC_SOFTPIN;
|
||||
case DrmParam::paramHasPooledEu:
|
||||
return I915_PARAM_HAS_POOLED_EU;
|
||||
case DrmParam::paramHasScheduler:
|
||||
return I915_PARAM_HAS_SCHEDULER;
|
||||
case DrmParam::paramEuTotal:
|
||||
return I915_PARAM_EU_TOTAL;
|
||||
case DrmParam::paramSubsliceTotal:
|
||||
return I915_PARAM_SUBSLICE_TOTAL;
|
||||
case DrmParam::paramMinEuInPool:
|
||||
return I915_PARAM_MIN_EU_IN_POOL;
|
||||
case DrmParam::paramCsTimestampFrequency:
|
||||
return I915_PARAM_CS_TIMESTAMP_FREQUENCY;
|
||||
case DrmParam::queryEngineInfo:
|
||||
return DRM_I915_QUERY_ENGINE_INFO;
|
||||
case DrmParam::queryMemoryRegions:
|
||||
return DRM_I915_QUERY_MEMORY_REGIONS;
|
||||
case DrmParam::queryTopologyInfo:
|
||||
return DRM_I915_QUERY_TOPOLOGY_INFO;
|
||||
case DrmParam::schedulerCapPreemption:
|
||||
return I915_SCHEDULER_CAP_PREEMPTION;
|
||||
case DrmParam::tilingNone:
|
||||
return I915_TILING_NONE;
|
||||
case DrmParam::tilingY:
|
||||
return I915_TILING_Y;
|
||||
case DrmParam::paramOATimestampFrequency:
|
||||
return I915_PARAM_OA_TIMESTAMP_FREQUENCY;
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<EngineCapabilities> IoctlHelperI915::translateToEngineCaps(const std::vector<uint64_t> &data) {
|
||||
auto engineInfo = reinterpret_cast<const drm_i915_query_engine_info *>(data.data());
|
||||
std::vector<EngineCapabilities> engines;
|
||||
engines.reserve(engineInfo->num_engines);
|
||||
for (uint32_t i = 0; i < engineInfo->num_engines; i++) {
|
||||
EngineCapabilities engine{};
|
||||
engine.capabilities = engineInfo->engines[i].capabilities;
|
||||
engine.engine.engineClass = engineInfo->engines[i].engine.engine_class;
|
||||
engine.engine.engineInstance = engineInfo->engines[i].engine.engine_instance;
|
||||
engines.push_back(engine);
|
||||
}
|
||||
return engines;
|
||||
}
|
||||
|
||||
std::vector<MemoryRegion> IoctlHelperI915::translateToMemoryRegions(const std::vector<uint64_t> ®ionInfo) {
|
||||
auto *data = reinterpret_cast<const drm_i915_query_memory_regions *>(regionInfo.data());
|
||||
auto memRegions = std::vector<MemoryRegion>(data->num_regions);
|
||||
for (uint32_t i = 0; i < data->num_regions; i++) {
|
||||
memRegions[i].probedSize = data->regions[i].probed_size;
|
||||
memRegions[i].unallocatedSize = data->regions[i].unallocated_size;
|
||||
memRegions[i].region.memoryClass = data->regions[i].region.memory_class;
|
||||
memRegions[i].region.memoryInstance = data->regions[i].region.memory_instance;
|
||||
}
|
||||
return memRegions;
|
||||
}
|
||||
|
||||
std::unique_ptr<EngineInfo> IoctlHelperI915::createEngineInfo(bool isSysmanEnabled) {
|
||||
auto request = getDrmParamValue(DrmParam::queryEngineInfo);
|
||||
auto enginesQuery = drm.query<uint64_t>(request, 0);
|
||||
if (enginesQuery.empty()) {
|
||||
return {};
|
||||
}
|
||||
auto engines = translateToEngineCaps(enginesQuery);
|
||||
auto hwInfo = drm.getRootDeviceEnvironment().getMutableHardwareInfo();
|
||||
|
||||
auto memInfo = drm.getMemoryInfo();
|
||||
|
||||
if (!memInfo) {
|
||||
return std::make_unique<EngineInfo>(&drm, engines);
|
||||
}
|
||||
|
||||
auto &memoryRegions = memInfo->getDrmRegionInfos();
|
||||
|
||||
auto tileCount = 0u;
|
||||
std::vector<DistanceInfo> distanceInfos;
|
||||
for (const auto ®ion : memoryRegions) {
|
||||
if (getDrmParamValue(DrmParam::memoryClassDevice) == region.region.memoryClass) {
|
||||
tileCount++;
|
||||
DistanceInfo distanceInfo{};
|
||||
distanceInfo.region = region.region;
|
||||
|
||||
for (const auto &engine : engines) {
|
||||
if (engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassCompute) ||
|
||||
engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassRender) ||
|
||||
engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassCopy)) {
|
||||
distanceInfo.engine = engine.engine;
|
||||
distanceInfos.push_back(distanceInfo);
|
||||
} else if (isSysmanEnabled) {
|
||||
|
||||
if (engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassVideo) ||
|
||||
engine.engine.engineClass == getDrmParamValue(DrmParam::engineClassVideoEnhance)) {
|
||||
distanceInfo.engine = engine.engine;
|
||||
distanceInfos.push_back(distanceInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tileCount == 0u) {
|
||||
return std::make_unique<EngineInfo>(&drm, engines);
|
||||
}
|
||||
|
||||
std::vector<QueryItem> queryItems{distanceInfos.size()};
|
||||
auto ret = queryDistances(queryItems, distanceInfos);
|
||||
if (ret != 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const bool queryUnsupported = std::all_of(queryItems.begin(), queryItems.end(),
|
||||
[](const QueryItem &item) { return item.length == -EINVAL; });
|
||||
if (queryUnsupported) {
|
||||
DEBUG_BREAK_IF(tileCount != 1);
|
||||
return std::make_unique<EngineInfo>(&drm, engines);
|
||||
}
|
||||
|
||||
memInfo->assignRegionsFromDistances(distanceInfos);
|
||||
|
||||
auto &multiTileArchInfo = hwInfo->gtSystemInfo.MultiTileArchInfo;
|
||||
multiTileArchInfo.IsValid = true;
|
||||
multiTileArchInfo.TileCount = tileCount;
|
||||
multiTileArchInfo.TileMask = static_cast<uint8_t>(maxNBitValue(tileCount));
|
||||
|
||||
return std::make_unique<EngineInfo>(&drm, tileCount, distanceInfos, queryItems, engines);
|
||||
}
|
||||
|
||||
bool IoctlHelperI915::setDomainCpu(uint32_t handle, bool writeEnable) {
|
||||
drm_i915_gem_set_domain setDomain{};
|
||||
setDomain.handle = handle;
|
||||
setDomain.read_domains = I915_GEM_DOMAIN_CPU;
|
||||
setDomain.write_domain = writeEnable ? I915_GEM_DOMAIN_CPU : 0;
|
||||
return this->ioctl(DrmIoctl::gemSetDomain, &setDomain) == 0;
|
||||
}
|
||||
|
||||
unsigned int IoctlHelperI915::getIoctlRequestValue(DrmIoctl ioctlRequest) const {
|
||||
switch (ioctlRequest) {
|
||||
case DrmIoctl::getparam:
|
||||
return DRM_IOCTL_I915_GETPARAM;
|
||||
case DrmIoctl::gemExecbuffer2:
|
||||
return DRM_IOCTL_I915_GEM_EXECBUFFER2;
|
||||
case DrmIoctl::gemWait:
|
||||
return DRM_IOCTL_I915_GEM_WAIT;
|
||||
case DrmIoctl::gemUserptr:
|
||||
return DRM_IOCTL_I915_GEM_USERPTR;
|
||||
case DrmIoctl::gemCreate:
|
||||
return DRM_IOCTL_I915_GEM_CREATE;
|
||||
case DrmIoctl::gemSetDomain:
|
||||
return DRM_IOCTL_I915_GEM_SET_DOMAIN;
|
||||
case DrmIoctl::gemSetTiling:
|
||||
return DRM_IOCTL_I915_GEM_SET_TILING;
|
||||
case DrmIoctl::gemGetTiling:
|
||||
return DRM_IOCTL_I915_GEM_GET_TILING;
|
||||
case DrmIoctl::gemContextCreateExt:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT;
|
||||
case DrmIoctl::gemContextDestroy:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_DESTROY;
|
||||
case DrmIoctl::regRead:
|
||||
return DRM_IOCTL_I915_REG_READ;
|
||||
case DrmIoctl::getResetStats:
|
||||
return DRM_IOCTL_I915_GET_RESET_STATS;
|
||||
case DrmIoctl::gemContextGetparam:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM;
|
||||
case DrmIoctl::gemContextSetparam:
|
||||
return DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM;
|
||||
case DrmIoctl::query:
|
||||
return DRM_IOCTL_I915_QUERY;
|
||||
case DrmIoctl::gemMmapOffset:
|
||||
return DRM_IOCTL_I915_GEM_MMAP_OFFSET;
|
||||
case DrmIoctl::gemVmCreate:
|
||||
return DRM_IOCTL_I915_GEM_VM_CREATE;
|
||||
case DrmIoctl::gemVmDestroy:
|
||||
return DRM_IOCTL_I915_GEM_VM_DESTROY;
|
||||
default:
|
||||
return getIoctlRequestValueBase(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<MemoryInfo> IoctlHelperI915::createMemoryInfo() {
|
||||
auto request = getDrmParamValue(DrmParam::queryMemoryRegions);
|
||||
auto dataQuery = drm.query<uint64_t>(request, 0);
|
||||
if (!dataQuery.empty()) {
|
||||
auto memRegions = translateToMemoryRegions(dataQuery);
|
||||
return std::make_unique<MemoryInfo>(memRegions, drm);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string IoctlHelperI915::getDrmParamString(DrmParam drmParam) const {
|
||||
switch (drmParam) {
|
||||
case DrmParam::paramChipsetId:
|
||||
return "I915_PARAM_CHIPSET_ID";
|
||||
case DrmParam::paramRevision:
|
||||
return "I915_PARAM_REVISION";
|
||||
case DrmParam::paramHasExecSoftpin:
|
||||
return "I915_PARAM_HAS_EXEC_SOFTPIN";
|
||||
case DrmParam::paramHasPooledEu:
|
||||
return "I915_PARAM_HAS_POOLED_EU";
|
||||
case DrmParam::paramHasScheduler:
|
||||
return "I915_PARAM_HAS_SCHEDULER";
|
||||
case DrmParam::paramEuTotal:
|
||||
return "I915_PARAM_EU_TOTAL";
|
||||
case DrmParam::paramSubsliceTotal:
|
||||
return "I915_PARAM_SUBSLICE_TOTAL";
|
||||
case DrmParam::paramMinEuInPool:
|
||||
return "I915_PARAM_MIN_EU_IN_POOL";
|
||||
case DrmParam::paramCsTimestampFrequency:
|
||||
return "I915_PARAM_CS_TIMESTAMP_FREQUENCY";
|
||||
case DrmParam::paramOATimestampFrequency:
|
||||
return "I915_PARAM_OA_TIMESTAMP_FREQUENCY";
|
||||
default:
|
||||
UNRECOVERABLE_IF(true);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string IoctlHelperI915::getIoctlString(DrmIoctl ioctlRequest) const {
|
||||
switch (ioctlRequest) {
|
||||
case DrmIoctl::gemExecbuffer2:
|
||||
return "DRM_IOCTL_I915_GEM_EXECBUFFER2";
|
||||
case DrmIoctl::gemWait:
|
||||
return "DRM_IOCTL_I915_GEM_WAIT";
|
||||
case DrmIoctl::gemUserptr:
|
||||
return "DRM_IOCTL_I915_GEM_USERPTR";
|
||||
case DrmIoctl::getparam:
|
||||
return "DRM_IOCTL_I915_GETPARAM";
|
||||
case DrmIoctl::gemCreate:
|
||||
return "DRM_IOCTL_I915_GEM_CREATE";
|
||||
case DrmIoctl::gemSetDomain:
|
||||
return "DRM_IOCTL_I915_GEM_SET_DOMAIN";
|
||||
case DrmIoctl::gemSetTiling:
|
||||
return "DRM_IOCTL_I915_GEM_SET_TILING";
|
||||
case DrmIoctl::gemGetTiling:
|
||||
return "DRM_IOCTL_I915_GEM_GET_TILING";
|
||||
case DrmIoctl::gemContextCreateExt:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT";
|
||||
case DrmIoctl::gemContextDestroy:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY";
|
||||
case DrmIoctl::regRead:
|
||||
return "DRM_IOCTL_I915_REG_READ";
|
||||
case DrmIoctl::getResetStats:
|
||||
return "DRM_IOCTL_I915_GET_RESET_STATS";
|
||||
case DrmIoctl::gemContextGetparam:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM";
|
||||
case DrmIoctl::gemContextSetparam:
|
||||
return "DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM";
|
||||
case DrmIoctl::query:
|
||||
return "DRM_IOCTL_I915_QUERY";
|
||||
case DrmIoctl::gemMmapOffset:
|
||||
return "DRM_IOCTL_I915_GEM_MMAP_OFFSET";
|
||||
case DrmIoctl::gemVmCreate:
|
||||
return "DRM_IOCTL_I915_GEM_VM_CREATE";
|
||||
case DrmIoctl::gemVmDestroy:
|
||||
return "DRM_IOCTL_I915_GEM_VM_DESTROY";
|
||||
default:
|
||||
return getIoctlStringBase(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
int IoctlHelperI915::createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex) {
|
||||
|
||||
const auto numberOfCCS = drm.getRootDeviceEnvironment().getHardwareInfo()->gtSystemInfo.CCSInfo.NumberOfCCSEnabled;
|
||||
const bool debuggableContext = drm.isContextDebugSupported() && drm.getRootDeviceEnvironment().executionEnvironment.isDebuggingEnabled() && !osContext.isInternalEngine();
|
||||
const bool debuggableContextCooperative = drm.getRootDeviceEnvironment().executionEnvironment.getDebuggingMode() == DebuggingMode::offline ? false : (debuggableContext && numberOfCCS > 0);
|
||||
auto drmContextId = drm.createDrmContext(drmVmId, drm.isVmBindAvailable(), osContext.isCooperativeEngine() || debuggableContextCooperative);
|
||||
if (drmContextId < 0) {
|
||||
return drmContextId;
|
||||
}
|
||||
|
||||
if (drm.areNonPersistentContextsSupported()) {
|
||||
drm.setNonPersistentContext(drmContextId);
|
||||
}
|
||||
|
||||
drm.setUnrecoverableContext(drmContextId);
|
||||
|
||||
if (debuggableContext) {
|
||||
drm.setContextDebugFlag(drmContextId);
|
||||
}
|
||||
|
||||
if (drm.isPreemptionSupported() && osContext.isLowPriority()) {
|
||||
drm.setLowPriorityContextParam(drmContextId);
|
||||
}
|
||||
auto engineFlag = drm.bindDrmContext(drmContextId, deviceIndex, osContext.getEngineType(), osContext.isEngineInstanced());
|
||||
osContext.setEngineFlag(engineFlag);
|
||||
return drmContextId;
|
||||
}
|
||||
|
||||
std::string IoctlHelperI915::getFileForMaxGpuFrequency() const {
|
||||
return "/gt_max_freq_mhz";
|
||||
}
|
||||
|
||||
std::string IoctlHelperI915::getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const {
|
||||
return "/gt/gt" + std::to_string(subDeviceId) + "/rps_max_freq_mhz";
|
||||
}
|
||||
|
||||
std::string IoctlHelperI915::getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const {
|
||||
return "/gt/gt" + std::to_string(subDeviceId) + "/mem_RP0_freq_mhz";
|
||||
}
|
||||
bool IoctlHelperI915::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData, TopologyMap &topologyMap) {
|
||||
|
||||
auto request = this->getDrmParamValue(DrmParam::queryTopologyInfo);
|
||||
auto dataQuery = drm.query<uint64_t>(request, 0);
|
||||
if (dataQuery.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto topologyInfo = reinterpret_cast<QueryTopologyInfo *>(dataQuery.data());
|
||||
|
||||
TopologyMapping mapping;
|
||||
auto retVal = this->translateTopologyInfo(topologyInfo, topologyData, mapping);
|
||||
topologyData.maxEuPerSubSlice = topologyInfo->maxEusPerSubslice;
|
||||
|
||||
topologyMap.clear();
|
||||
topologyMap[0] = mapping;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool IoctlHelperI915::translateTopologyInfo(const QueryTopologyInfo *queryTopologyInfo, DrmQueryTopologyData &topologyData, TopologyMapping &mapping) {
|
||||
int sliceCount = 0;
|
||||
int subSliceCount = 0;
|
||||
int euCount = 0;
|
||||
int maxSliceCount = 0;
|
||||
int maxSubSliceCountPerSlice = 0;
|
||||
std::vector<int> sliceIndices;
|
||||
sliceIndices.reserve(maxSliceCount);
|
||||
|
||||
for (int x = 0; x < queryTopologyInfo->maxSlices; x++) {
|
||||
bool isSliceEnable = (queryTopologyInfo->data[x / 8] >> (x % 8)) & 1;
|
||||
if (!isSliceEnable) {
|
||||
continue;
|
||||
}
|
||||
sliceIndices.push_back(x);
|
||||
sliceCount++;
|
||||
|
||||
std::vector<int> subSliceIndices;
|
||||
subSliceIndices.reserve(queryTopologyInfo->maxSubslices);
|
||||
|
||||
for (int y = 0; y < queryTopologyInfo->maxSubslices; y++) {
|
||||
size_t yOffset = (queryTopologyInfo->subsliceOffset + static_cast<size_t>(x * queryTopologyInfo->subsliceStride) + y / 8);
|
||||
bool isSubSliceEnabled = (queryTopologyInfo->data[yOffset] >> (y % 8)) & 1;
|
||||
if (!isSubSliceEnabled) {
|
||||
continue;
|
||||
}
|
||||
subSliceCount++;
|
||||
subSliceIndices.push_back(y);
|
||||
|
||||
for (int z = 0; z < queryTopologyInfo->maxEusPerSubslice; z++) {
|
||||
size_t zOffset = (queryTopologyInfo->euOffset + static_cast<size_t>((x * queryTopologyInfo->maxSubslices + y) * queryTopologyInfo->euStride) + z / 8);
|
||||
bool isEUEnabled = (queryTopologyInfo->data[zOffset] >> (z % 8)) & 1;
|
||||
if (!isEUEnabled) {
|
||||
continue;
|
||||
}
|
||||
euCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (subSliceIndices.size()) {
|
||||
maxSubSliceCountPerSlice = std::max(maxSubSliceCountPerSlice, subSliceIndices[subSliceIndices.size() - 1] + 1);
|
||||
}
|
||||
|
||||
// single slice available
|
||||
if (sliceCount == 1) {
|
||||
mapping.subsliceIndices = std::move(subSliceIndices);
|
||||
}
|
||||
}
|
||||
|
||||
if (sliceIndices.size()) {
|
||||
maxSliceCount = sliceIndices[sliceIndices.size() - 1] + 1;
|
||||
mapping.sliceIndices = std::move(sliceIndices);
|
||||
}
|
||||
|
||||
if (sliceCount != 1) {
|
||||
mapping.subsliceIndices.clear();
|
||||
}
|
||||
|
||||
topologyData.sliceCount = sliceCount;
|
||||
topologyData.subSliceCount = subSliceCount;
|
||||
topologyData.euCount = euCount;
|
||||
topologyData.maxSliceCount = maxSliceCount;
|
||||
topologyData.maxSubSliceCount = maxSubSliceCountPerSlice;
|
||||
|
||||
return (sliceCount && subSliceCount && euCount);
|
||||
}
|
||||
|
||||
void IoctlHelperI915::fillBindInfoForIpcHandle(uint32_t handle, size_t size) {}
|
||||
|
||||
bool IoctlHelperI915::getFdFromVmExport(uint32_t vmId, uint32_t flags, int32_t *fd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t IoctlHelperI915::createGem(uint64_t size, uint32_t memoryBanks) {
|
||||
GemCreate gemCreate = {};
|
||||
gemCreate.size = size;
|
||||
[[maybe_unused]] auto ret = ioctl(DrmIoctl::gemCreate, &gemCreate);
|
||||
DEBUG_BREAK_IF(ret != 0);
|
||||
return gemCreate.handle;
|
||||
}
|
||||
|
||||
bool IoctlHelperI915::setGemTiling(void *setTiling) {
|
||||
return this->ioctl(DrmIoctl::gemSetTiling, setTiling) == 0;
|
||||
}
|
||||
|
||||
bool IoctlHelperI915::getGemTiling(void *setTiling) {
|
||||
return this->ioctl(DrmIoctl::gemGetTiling, setTiling) == 0;
|
||||
}
|
||||
|
||||
bool getGpuTime32(::NEO::Drm &drm, uint64_t *timestamp) {
|
||||
RegisterRead reg = {};
|
||||
reg.offset = RegisterOffsets::globalTimestampLdw;
|
||||
|
||||
if (drm.ioctl(DrmIoctl::regRead, ®)) {
|
||||
return false;
|
||||
}
|
||||
*timestamp = reg.value >> 32;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getGpuTime36(::NEO::Drm &drm, uint64_t *timestamp) {
|
||||
RegisterRead reg = {};
|
||||
reg.offset = RegisterOffsets::globalTimestampLdw | 1;
|
||||
|
||||
if (drm.ioctl(DrmIoctl::regRead, ®)) {
|
||||
return false;
|
||||
}
|
||||
*timestamp = reg.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getGpuTimeSplitted(::NEO::Drm &drm, uint64_t *timestamp) {
|
||||
RegisterRead regHi = {};
|
||||
RegisterRead regLo = {};
|
||||
uint64_t tmpHi;
|
||||
int err = 0, loop = 3;
|
||||
|
||||
regHi.offset = RegisterOffsets::globalTimestampUn;
|
||||
regLo.offset = RegisterOffsets::globalTimestampLdw;
|
||||
|
||||
err += drm.ioctl(DrmIoctl::regRead, ®Hi);
|
||||
do {
|
||||
tmpHi = regHi.value;
|
||||
err += drm.ioctl(DrmIoctl::regRead, ®Lo);
|
||||
err += drm.ioctl(DrmIoctl::regRead, ®Hi);
|
||||
} while (err == 0 && regHi.value != tmpHi && --loop);
|
||||
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*timestamp = regLo.value | (regHi.value << 32);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IoctlHelperI915::initializeGetGpuTimeFunction() {
|
||||
RegisterRead reg = {};
|
||||
int err;
|
||||
|
||||
reg.offset = (RegisterOffsets::globalTimestampLdw | 1);
|
||||
err = this->ioctl(DrmIoctl::regRead, ®);
|
||||
if (err) {
|
||||
reg.offset = RegisterOffsets::globalTimestampUn;
|
||||
err = this->ioctl(DrmIoctl::regRead, ®);
|
||||
if (err) {
|
||||
this->getGpuTime = &getGpuTime32;
|
||||
} else {
|
||||
this->getGpuTime = &getGpuTimeSplitted;
|
||||
}
|
||||
} else {
|
||||
this->getGpuTime = &getGpuTime36;
|
||||
}
|
||||
}
|
||||
|
||||
bool IoctlHelperI915::setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) {
|
||||
if (pGpuCpuTime == nullptr || osTime == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->getGpuTime == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->getGpuTime(drm, &pGpuCpuTime->gpuTimeStamp)) {
|
||||
return false;
|
||||
}
|
||||
if (!osTime->getCpuTime(&pGpuCpuTime->cpuTimeinNS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace NEO
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
namespace NEO {
|
||||
|
||||
IoctlHelperPrelim20::IoctlHelperPrelim20(Drm &drmArg) : IoctlHelper(drmArg) {
|
||||
IoctlHelperPrelim20::IoctlHelperPrelim20(Drm &drmArg) : IoctlHelperI915(drmArg) {
|
||||
const auto &productHelper = this->drm.getRootDeviceEnvironment().getHelper<ProductHelper>();
|
||||
handleExecBufferInNonBlockMode = productHelper.isNonBlockingGpuSubmissionSupported();
|
||||
if (debugManager.flags.ForceNonblockingExecbufferCalls.get() != -1) {
|
||||
@@ -132,7 +132,7 @@ bool IoctlHelperPrelim20::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQ
|
||||
}
|
||||
|
||||
// fallback to DRM_I915_QUERY_TOPOLOGY_INFO
|
||||
return IoctlHelper::getTopologyDataAndMap(hwInfo, topologyData, topologyMap);
|
||||
return IoctlHelperI915::getTopologyDataAndMap(hwInfo, topologyData, topologyMap);
|
||||
}
|
||||
|
||||
bool IoctlHelperPrelim20::isVmBindAvailable() {
|
||||
@@ -767,7 +767,7 @@ unsigned int IoctlHelperPrelim20::getIoctlRequestValue(DrmIoctl ioctlRequest) co
|
||||
case DrmIoctl::gemCacheReserve:
|
||||
return PRELIM_DRM_IOCTL_I915_GEM_CACHE_RESERVE;
|
||||
default:
|
||||
return getIoctlRequestValueBase(ioctlRequest);
|
||||
return IoctlHelperI915::getIoctlRequestValue(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -784,7 +784,7 @@ int IoctlHelperPrelim20::getDrmParamValue(DrmParam drmParam) const {
|
||||
case DrmParam::queryComputeSlices:
|
||||
return PRELIM_DRM_I915_QUERY_COMPUTE_SUBSLICES;
|
||||
default:
|
||||
return getDrmParamValueBase(drmParam);
|
||||
return IoctlHelperI915::getDrmParamValueBase(drmParam);
|
||||
}
|
||||
}
|
||||
std::string IoctlHelperPrelim20::getDrmParamString(DrmParam drmParam) const {
|
||||
@@ -794,7 +794,7 @@ std::string IoctlHelperPrelim20::getDrmParamString(DrmParam drmParam) const {
|
||||
case DrmParam::paramHasPageFault:
|
||||
return "PRELIM_I915_PARAM_HAS_PAGE_FAULT";
|
||||
default:
|
||||
return getDrmParamStringBase(drmParam);
|
||||
return IoctlHelperI915::getDrmParamString(drmParam);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,7 +825,7 @@ std::string IoctlHelperPrelim20::getIoctlString(DrmIoctl ioctlRequest) const {
|
||||
case DrmIoctl::gemCacheReserve:
|
||||
return "PRELIM_DRM_IOCTL_I915_GEM_CACHE_RESERVE";
|
||||
default:
|
||||
return getIoctlStringBase(ioctlRequest);
|
||||
return IoctlHelperI915::getIoctlString(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ unsigned int IoctlHelperUpstream::getIoctlRequestValue(DrmIoctl ioctlRequest) co
|
||||
case DrmIoctl::gemCreateExt:
|
||||
return DRM_IOCTL_I915_GEM_CREATE_EXT;
|
||||
default:
|
||||
return getIoctlRequestValueBase(ioctlRequest);
|
||||
return IoctlHelperI915::getIoctlRequestValue(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,18 +287,15 @@ int IoctlHelperUpstream::getDrmParamValue(DrmParam drmParam) const {
|
||||
case DrmParam::queryComputeSlices:
|
||||
return 0;
|
||||
default:
|
||||
return getDrmParamValueBase(drmParam);
|
||||
return IoctlHelperI915::getDrmParamValueBase(drmParam);
|
||||
}
|
||||
}
|
||||
std::string IoctlHelperUpstream::getDrmParamString(DrmParam param) const {
|
||||
return getDrmParamStringBase(param);
|
||||
}
|
||||
std::string IoctlHelperUpstream::getIoctlString(DrmIoctl ioctlRequest) const {
|
||||
switch (ioctlRequest) {
|
||||
case DrmIoctl::gemCreateExt:
|
||||
return "DRM_IOCTL_I915_GEM_CREATE_EXT";
|
||||
default:
|
||||
return getIoctlStringBase(ioctlRequest);
|
||||
return IoctlHelperI915::getIoctlString(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ std::string IoctlHelperImpl<gfxProduct>::getIoctlString(DrmIoctl ioctlRequest) c
|
||||
case DrmIoctl::dg1GemCreateExt:
|
||||
return "DRM_IOCTL_I915_GEM_CREATE_EXT";
|
||||
default:
|
||||
return getIoctlStringBase(ioctlRequest);
|
||||
return IoctlHelperUpstream::getIoctlString(ioctlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,10 @@ bool IoctlHelperXe::isVmBindAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IoctlHelperXe::setDomainCpu(uint32_t handle, bool writeEnable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename DataType>
|
||||
std::vector<DataType> IoctlHelperXe::queryData(uint32_t queryId) {
|
||||
struct drm_xe_device_query deviceQuery = {};
|
||||
|
||||
@@ -113,7 +113,6 @@ class IoctlHelperXe : public IoctlHelper {
|
||||
void getTopologyMap(size_t nTiles, std::vector<std::bitset<8>> *dssInfo, TopologyMap &topologyMap);
|
||||
|
||||
bool setGpuCpuTimes(TimeStampData *pGpuCpuTime, OSTime *osTime) override;
|
||||
void initializeGetGpuTimeFunction() override{};
|
||||
bool getTimestampFrequency(uint64_t &frequency);
|
||||
|
||||
void fillBindInfoForIpcHandle(uint32_t handle, size_t size) override;
|
||||
@@ -123,6 +122,7 @@ class IoctlHelperXe : public IoctlHelper {
|
||||
void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) override;
|
||||
void fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId) override;
|
||||
void logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) override;
|
||||
bool setDomainCpu(uint32_t handle, bool writeEnable) override;
|
||||
uint16_t getCpuCachingMode();
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user