diff --git a/shared/source/os_interface/linux/engine_info.cpp b/shared/source/os_interface/linux/engine_info.cpp index 64d4356975..65a1cbd883 100644 --- a/shared/source/os_interface/linux/engine_info.cpp +++ b/shared/source/os_interface/linux/engine_info.cpp @@ -75,6 +75,31 @@ EngineInfo::EngineInfo(Drm *drm, const std::vector &engineIn setSupportedEnginesInfo(rootDeviceEnvironment, computeEngines, bcsInfoMask); } +EngineInfo::EngineInfo(Drm *drm, const StackVec, 2> &engineClassInstancePerTile) : tileToEngineToInstanceMap(engineClassInstancePerTile.size()) { + auto ioctlHelper = drm->getIoctlHelper(); + auto &rootDeviceEnvironment = drm->getRootDeviceEnvironment(); + auto computeEnginesPerTile = 0u; + auto copyEnginesPerTile = 0u; + for (auto tile = 0u; tile < engineClassInstancePerTile.size(); tile++) { + copyEnginesPerTile = 0u; + computeEnginesPerTile = 0u; + for (const auto &engine : engineClassInstancePerTile[tile]) { + tileToEngineMap.emplace(tile, engine); + if (engine.engineClass == ioctlHelper->getDrmParamValue(DrmParam::EngineClassRender)) { + tileToEngineToInstanceMap[tile][EngineHelpers::remapEngineTypeToHwSpecific(aub_stream::EngineType::ENGINE_RCS, rootDeviceEnvironment)] = engine; + } else if (engine.engineClass == ioctlHelper->getDrmParamValue(DrmParam::EngineClassCopy)) { + tileToEngineToInstanceMap[tile][DrmEngineMappingHelper::engineMapping[copyEnginesPerTile]] = engine; + copyEnginesPerTile++; + } else if (engine.engineClass == ioctlHelper->getDrmParamValue(DrmParam::EngineClassCompute)) { + tileToEngineToInstanceMap[tile][static_cast(aub_stream::ENGINE_CCS + computeEnginesPerTile)] = engine; + computeEnginesPerTile++; + } + } + } + BcsInfoMask bcsInfoMask = maxNBitValue(copyEnginesPerTile); + setSupportedEnginesInfo(rootDeviceEnvironment, computeEnginesPerTile, bcsInfoMask); +} + EngineInfo::EngineInfo(Drm *drm, uint32_t tileCount, const std::vector &distanceInfos, const std::vector &queryItems, const std::vector &engineInfos) : engines(engineInfos), tileToEngineToInstanceMap(tileCount) { auto tile = 0u; diff --git a/shared/source/os_interface/linux/engine_info.h b/shared/source/os_interface/linux/engine_info.h index a96881b9e9..45fd92ffe6 100644 --- a/shared/source/os_interface/linux/engine_info.h +++ b/shared/source/os_interface/linux/engine_info.h @@ -25,6 +25,7 @@ struct EngineInfo { public: using EngineToInstanceMap = std::map; + EngineInfo(Drm *drm, const StackVec, 2> &engineClassInstancePerTile); EngineInfo(Drm *drm, const std::vector &engineInfos); EngineInfo(Drm *drm, uint32_t tileCount, const std::vector &distanceInfos, const std::vector &queryItems, const std::vector &engineInfos); diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index bde49c3d0c..aaff7bbd2b 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -146,7 +146,7 @@ class IoctlHelper { uint32_t getFlagsForPrimeHandleToFd() const; std::unique_ptr createMemoryInfo(); - std::unique_ptr createEngineInfo(bool isSysmanEnabled); + virtual std::unique_ptr createEngineInfo(bool isSysmanEnabled); protected: Drm &drm; diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index 17e2427286..e4c673ee44 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -19,6 +19,7 @@ #include "shared/source/helpers/register_offsets.h" #include "shared/source/helpers/string.h" #include "shared/source/os_interface/linux/drm_neo.h" +#include "shared/source/os_interface/linux/engine_info.h" #include "shared/source/os_interface/linux/os_context_linux.h" #include "drm/i915_drm_prelim.h" @@ -62,9 +63,6 @@ int IoctlHelperXe::xeGetQuery(Query *data) { case static_cast(DrmParam::QueryMemoryRegions): queryData = &memQueryFakei915; break; - case static_cast(DrmParam::QueryEngineInfo): - queryData = &engineFakei915; - break; case static_cast(DrmParam::QueryHwconfigTable): queryData = &hwconfigFakei915; break; @@ -150,187 +148,162 @@ IoctlHelperXe::IoctlHelperXe(Drm &drmArg) : IoctlHelper(drmArg) { bool IoctlHelperXe::initialize() { bool ret = false; xeLog("IoctlHelperXe::initialize\n", ""); - if (!numberHwEngines) { - DebugManager.flags.ForceUserptrAlignment.set(64); - DebugManager.flags.UseVmBind.set(1); - DebugManager.flags.EnableImmediateVmBindExt.set(1); - DebugManager.flags.UseNewQueryTopoIoctl.set(0); - DebugManager.flags.RenderCompressedBuffersEnabled.set(0); + DebugManager.flags.ForceUserptrAlignment.set(64); + DebugManager.flags.UseVmBind.set(1); + DebugManager.flags.EnableImmediateVmBindExt.set(1); + DebugManager.flags.UseNewQueryTopoIoctl.set(0); + DebugManager.flags.RenderCompressedBuffersEnabled.set(0); - struct drm_xe_device_query queryEngine = {}; - queryEngine.query = DRM_XE_DEVICE_QUERY_ENGINES; + struct drm_xe_device_query queryConfig = {}; + queryConfig.query = DRM_XE_DEVICE_QUERY_CONFIG; - IoctlHelper::ioctl(DrmIoctl::Query, &queryEngine); - - hwEngines = std::make_unique(queryEngine.size); - queryEngine.data = castToUint64(hwEngines.get()); - IoctlHelper::ioctl(DrmIoctl::Query, &queryEngine); - - numberHwEngines = queryEngine.size / - sizeof(struct drm_xe_engine_class_instance); - struct drm_xe_engine_class_instance *currentEngine; - engineFakei915.resize(sizeof(drm_i915_query_engine_info) + (numberHwEngines * sizeof(drm_i915_engine_info))); - struct drm_i915_query_engine_info *i915EngineInfo = reinterpret_cast(engineFakei915.data()); - i915EngineInfo->num_engines = numberHwEngines; - for (int i = 0; i < numberHwEngines && (currentEngine = &hwEngines.get()[i]); ++i) { - xeLog("\t%s:%d\n", xeGetClassName(currentEngine->engine_class), currentEngine->engine_instance); - i915EngineInfo->engines[i].engine.engine_class = currentEngine->engine_class; - i915EngineInfo->engines[i].engine.engine_instance = currentEngine->engine_instance; - i915EngineInfo->engines[i].flags = 1; - } - - xeLog("numberHwEngines=%d\n", numberHwEngines); - if (numberHwEngines) { - - struct drm_xe_device_query queryConfig = {}; - queryConfig.query = DRM_XE_DEVICE_QUERY_CONFIG; - - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - auto data = std::vector(sizeof(drm_xe_query_config) + sizeof(uint64_t) * queryConfig.size, 0); - struct drm_xe_query_config *config = reinterpret_cast(data.data()); - queryConfig.data = castToUint64(config); - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - xeLog("XE_QUERY_CONFIG_REV_AND_DEVICE_ID\t%#llx\n", - config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID]); - xeLog(" REV_ID\t\t\t\t%#llx\n", - config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16); - xeLog(" DEVICE_ID\t\t\t\t%#llx\n", - config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff); - xeLog("XE_QUERY_CONFIG_FLAGS\t\t\t%#llx\n", - config->info[XE_QUERY_CONFIG_FLAGS]); - xeLog(" XE_QUERY_CONFIG_FLAGS_HAS_VRAM\t%s\n", - config->info[XE_QUERY_CONFIG_FLAGS] & - XE_QUERY_CONFIG_FLAGS_HAS_VRAM - ? "ON" - : "OFF"); - xeLog(" XE_QUERY_CONFIG_FLAGS_USE_GUC\t\t%s\n", - config->info[XE_QUERY_CONFIG_FLAGS] & - XE_QUERY_CONFIG_FLAGS_USE_GUC - ? "ON" - : "OFF"); - xeLog("XE_QUERY_CONFIG_MIN_ALIGNEMENT\t\t%#llx\n", - config->info[XE_QUERY_CONFIG_MIN_ALIGNEMENT]); - xeLog("XE_QUERY_CONFIG_VA_BITS\t\t%#llx\n", - config->info[XE_QUERY_CONFIG_VA_BITS]); - xeLog("XE_QUERY_CONFIG_GT_COUNT\t\t%llu\n", - config->info[XE_QUERY_CONFIG_GT_COUNT]); - xeLog("XE_QUERY_CONFIG_MEM_REGION_COUNT\t%llu\n", - config->info[XE_QUERY_CONFIG_MEM_REGION_COUNT]); - - chipsetId = config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff; - revId = static_cast(config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16); - hasVram = config->info[XE_QUERY_CONFIG_FLAGS] & XE_QUERY_CONFIG_FLAGS_HAS_VRAM ? 1 : 0; - addressWidth = static_cast(config->info[XE_QUERY_CONFIG_VA_BITS]); - - memset(&queryConfig, 0, sizeof(queryConfig)); - queryConfig.query = DRM_XE_DEVICE_QUERY_GTS; - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - auto dataGts = std::vector(sizeof(drm_xe_query_config) + sizeof(uint64_t) * queryConfig.size, 0); - struct drm_xe_query_gts *gts = reinterpret_cast(dataGts.data()); - queryConfig.data = castToUint64(gts); - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - for (uint32_t i = 0; i < gts->num_gt; i++) { - xeMemoryRegions |= gts->gts[i].native_mem_regions | gts->gts[i].slow_mem_regions; - xeTimestampFrequency = gts->gts[i].clock_freq; - } - xeLog("xeMemoryRegions 0x%llx\n", xeMemoryRegions); - - memset(&queryConfig, 0, sizeof(queryConfig)); - queryConfig.query = DRM_XE_DEVICE_QUERY_MEM_USAGE; - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - auto dataMem = std::vector(sizeof(drm_xe_query_config) + sizeof(uint64_t) * queryConfig.size, 0); - struct drm_xe_query_mem_usage *configMem = reinterpret_cast(dataMem.data()); - queryConfig.data = castToUint64(configMem); - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - - memQueryFakei915.resize(sizeof(drm_i915_query_memory_regions) + (configMem->num_regions * sizeof(drm_i915_memory_region_info))); - struct drm_i915_query_memory_regions *i915MemQuery = reinterpret_cast(memQueryFakei915.data()); - i915MemQuery->num_regions = configMem->num_regions; - for (uint32_t i = 0; i < configMem->num_regions; i++) { - const char *memName = NULL; - uint16_t memClass = 0; - uint16_t memInst = configMem->regions[i].instance; - - switch (configMem->regions[i].mem_class) { - case XE_MEM_REGION_CLASS_SYSMEM: - memName = "SYSMEM"; - memClass = getDrmParamValue(DrmParam::MemoryClassSystem); - break; - case XE_MEM_REGION_CLASS_VRAM: - memName = "VRAM"; - memClass = getDrmParamValue(DrmParam::MemoryClassDevice); - memInst--; - break; - default: - xeLog("Unhandled Xe memory class", ""); - UNRECOVERABLE_IF(true); - break; - } - i915MemQuery->regions[i].region.memory_class = memClass; - i915MemQuery->regions[i].region.memory_instance = memInst; - i915MemQuery->regions[i].probed_size = configMem->regions[i].total_size; - i915MemQuery->regions[i].unallocated_size = configMem->regions[i].total_size - configMem->regions[i].used; - xeLog(" %s c=0x%x i=%d T=%llx U=0x%llx / i915: %d %d\n", - memName, configMem->regions[i].mem_class, configMem->regions[i].instance, - configMem->regions[i].total_size, configMem->regions[i].used, memClass, memInst); - } - - memset(&queryConfig, 0, sizeof(queryConfig)); - queryConfig.query = DRM_XE_DEVICE_QUERY_HWCONFIG; - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - hwconfigFakei915.resize(queryConfig.size); - queryConfig.data = castToUint64(hwconfigFakei915.data()); - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - - memset(&queryConfig, 0, sizeof(queryConfig)); - queryConfig.query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY; - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - std::vector topology(queryConfig.size); - queryConfig.data = castToUint64(topology.data()); - IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); - std::vector geomDss; - std::vector computeDss; - std::vector euDss; - uint32_t topologySize = queryConfig.size; - uint8_t *dataPtr = reinterpret_cast(topology.data()); - while (topologySize >= sizeof(struct drm_xe_query_topology_mask)) { - struct drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); - uint32_t itemSize = sizeof(struct drm_xe_query_topology_mask) + topo->num_bytes; - std::vector *toFill = nullptr; - - switch (topo->type) { - case XE_TOPO_DSS_GEOMETRY: - toFill = &geomDss; - break; - case XE_TOPO_DSS_COMPUTE: - toFill = &computeDss; - break; - case XE_TOPO_EU_PER_DSS: - toFill = &euDss; - break; - default: - xeLog("Un handle GT Topo type: %d\n", topo->type); - break; - } - if (toFill != nullptr) { - for (uint32_t j = 0; j < topo->num_bytes; j++) - toFill->push_back(topo->mask[j]); - } - topologySize -= itemSize; - dataPtr += itemSize; - } - topologyFakei915 = xeRebuildi915Topology(&geomDss, &computeDss, &euDss); - if (topologyFakei915.size()) { - ret = true; - } else { - xeLog("can't get i915 topology\n", ""); - UNRECOVERABLE_IF(true); - } - auto hwInfo = this->drm.getRootDeviceEnvironment().getMutableHardwareInfo(); - hwInfo->platform.usDeviceID = chipsetId; - hwInfo->platform.usRevId = revId; - } + auto retVal = IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + if (retVal != 0 || queryConfig.size == 0) { + return false; } + auto data = std::vector(sizeof(drm_xe_query_config) + sizeof(uint64_t) * queryConfig.size, 0); + struct drm_xe_query_config *config = reinterpret_cast(data.data()); + queryConfig.data = castToUint64(config); + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + xeLog("XE_QUERY_CONFIG_REV_AND_DEVICE_ID\t%#llx\n", + config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID]); + xeLog(" REV_ID\t\t\t\t%#llx\n", + config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16); + xeLog(" DEVICE_ID\t\t\t\t%#llx\n", + config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff); + xeLog("XE_QUERY_CONFIG_FLAGS\t\t\t%#llx\n", + config->info[XE_QUERY_CONFIG_FLAGS]); + xeLog(" XE_QUERY_CONFIG_FLAGS_HAS_VRAM\t%s\n", + config->info[XE_QUERY_CONFIG_FLAGS] & + XE_QUERY_CONFIG_FLAGS_HAS_VRAM + ? "ON" + : "OFF"); + xeLog(" XE_QUERY_CONFIG_FLAGS_USE_GUC\t\t%s\n", + config->info[XE_QUERY_CONFIG_FLAGS] & + XE_QUERY_CONFIG_FLAGS_USE_GUC + ? "ON" + : "OFF"); + xeLog("XE_QUERY_CONFIG_MIN_ALIGNEMENT\t\t%#llx\n", + config->info[XE_QUERY_CONFIG_MIN_ALIGNEMENT]); + xeLog("XE_QUERY_CONFIG_VA_BITS\t\t%#llx\n", + config->info[XE_QUERY_CONFIG_VA_BITS]); + xeLog("XE_QUERY_CONFIG_GT_COUNT\t\t%llu\n", + config->info[XE_QUERY_CONFIG_GT_COUNT]); + xeLog("XE_QUERY_CONFIG_MEM_REGION_COUNT\t%llu\n", + config->info[XE_QUERY_CONFIG_MEM_REGION_COUNT]); + + chipsetId = config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] & 0xffff; + revId = static_cast(config->info[XE_QUERY_CONFIG_REV_AND_DEVICE_ID] >> 16); + hasVram = config->info[XE_QUERY_CONFIG_FLAGS] & XE_QUERY_CONFIG_FLAGS_HAS_VRAM ? 1 : 0; + addressWidth = static_cast(config->info[XE_QUERY_CONFIG_VA_BITS]); + + memset(&queryConfig, 0, sizeof(queryConfig)); + queryConfig.query = DRM_XE_DEVICE_QUERY_GTS; + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + auto dataGts = std::vector(sizeof(drm_xe_query_config) + sizeof(uint64_t) * queryConfig.size, 0); + struct drm_xe_query_gts *gts = reinterpret_cast(dataGts.data()); + queryConfig.data = castToUint64(gts); + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + for (uint32_t i = 0; i < gts->num_gt; i++) { + xeMemoryRegions |= gts->gts[i].native_mem_regions | gts->gts[i].slow_mem_regions; + xeTimestampFrequency = gts->gts[i].clock_freq; + } + xeLog("xeMemoryRegions 0x%llx\n", xeMemoryRegions); + + memset(&queryConfig, 0, sizeof(queryConfig)); + queryConfig.query = DRM_XE_DEVICE_QUERY_MEM_USAGE; + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + auto dataMem = std::vector(sizeof(drm_xe_query_config) + sizeof(uint64_t) * queryConfig.size, 0); + struct drm_xe_query_mem_usage *configMem = reinterpret_cast(dataMem.data()); + queryConfig.data = castToUint64(configMem); + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + + memQueryFakei915.resize(sizeof(drm_i915_query_memory_regions) + (configMem->num_regions * sizeof(drm_i915_memory_region_info))); + struct drm_i915_query_memory_regions *i915MemQuery = reinterpret_cast(memQueryFakei915.data()); + i915MemQuery->num_regions = configMem->num_regions; + for (uint32_t i = 0; i < configMem->num_regions; i++) { + const char *memName = NULL; + uint16_t memClass = 0; + uint16_t memInst = configMem->regions[i].instance; + + switch (configMem->regions[i].mem_class) { + case XE_MEM_REGION_CLASS_SYSMEM: + memName = "SYSMEM"; + memClass = getDrmParamValue(DrmParam::MemoryClassSystem); + break; + case XE_MEM_REGION_CLASS_VRAM: + memName = "VRAM"; + memClass = getDrmParamValue(DrmParam::MemoryClassDevice); + memInst--; + break; + default: + xeLog("Unhandled Xe memory class", ""); + UNRECOVERABLE_IF(true); + break; + } + i915MemQuery->regions[i].region.memory_class = memClass; + i915MemQuery->regions[i].region.memory_instance = memInst; + i915MemQuery->regions[i].probed_size = configMem->regions[i].total_size; + i915MemQuery->regions[i].unallocated_size = configMem->regions[i].total_size - configMem->regions[i].used; + xeLog(" %s c=0x%x i=%d T=%llx U=0x%llx / i915: %d %d\n", + memName, configMem->regions[i].mem_class, configMem->regions[i].instance, + configMem->regions[i].total_size, configMem->regions[i].used, memClass, memInst); + } + + memset(&queryConfig, 0, sizeof(queryConfig)); + queryConfig.query = DRM_XE_DEVICE_QUERY_HWCONFIG; + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + hwconfigFakei915.resize(queryConfig.size); + queryConfig.data = castToUint64(hwconfigFakei915.data()); + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + + memset(&queryConfig, 0, sizeof(queryConfig)); + queryConfig.query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY; + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + std::vector topology(queryConfig.size); + queryConfig.data = castToUint64(topology.data()); + IoctlHelper::ioctl(DrmIoctl::Query, &queryConfig); + std::vector geomDss; + std::vector computeDss; + std::vector euDss; + uint32_t topologySize = queryConfig.size; + uint8_t *dataPtr = reinterpret_cast(topology.data()); + while (topologySize >= sizeof(struct drm_xe_query_topology_mask)) { + struct drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); + uint32_t itemSize = sizeof(struct drm_xe_query_topology_mask) + topo->num_bytes; + std::vector *toFill = nullptr; + + switch (topo->type) { + case XE_TOPO_DSS_GEOMETRY: + toFill = &geomDss; + break; + case XE_TOPO_DSS_COMPUTE: + toFill = &computeDss; + break; + case XE_TOPO_EU_PER_DSS: + toFill = &euDss; + break; + default: + xeLog("Un handle GT Topo type: %d\n", topo->type); + break; + } + if (toFill != nullptr) { + for (uint32_t j = 0; j < topo->num_bytes; j++) + toFill->push_back(topo->mask[j]); + } + topologySize -= itemSize; + dataPtr += itemSize; + } + topologyFakei915 = xeRebuildi915Topology(&geomDss, &computeDss, &euDss); + if (topologyFakei915.size()) { + ret = true; + } else { + xeLog("can't get i915 topology\n", ""); + UNRECOVERABLE_IF(true); + } + auto hwInfo = this->drm.getRootDeviceEnvironment().getMutableHardwareInfo(); + hwInfo->platform.usDeviceID = chipsetId; + hwInfo->platform.usRevId = revId; return ret; } @@ -346,6 +319,55 @@ bool IoctlHelperXe::isVmBindAvailable() { return true; } +std::vector IoctlHelperXe::queryData(uint32_t queryId) { + struct drm_xe_device_query deviceQuery = {}; + deviceQuery.query = queryId; + + IoctlHelper::ioctl(DrmIoctl::Query, &deviceQuery); + + std::vector retVal(deviceQuery.size); + + deviceQuery.data = castToUint64(retVal.data()); + IoctlHelper::ioctl(DrmIoctl::Query, &deviceQuery); + + return retVal; +} + +std::unique_ptr IoctlHelperXe::createEngineInfo(bool isSysmanEnabled) { + auto enginesData = queryData(DRM_XE_DEVICE_QUERY_ENGINES); + + auto numberHwEngines = enginesData.size() / + sizeof(struct drm_xe_engine_class_instance); + + xeLog("numberHwEngines=%d\n", numberHwEngines); + auto queriedEngines = reinterpret_cast(enginesData.data()); + + StackVec, 2> enginesPerTile{}; + + for (auto i = 0u; i < numberHwEngines; i++) { + auto tile = queriedEngines[i].gt_id; + EngineClassInstance engineClassInstance{}; + engineClassInstance.engineClass = queriedEngines[i].engine_class; + engineClassInstance.engineInstance = queriedEngines[i].engine_instance; + xeLog("\t%s:%d\n", xeGetClassName(engineClassInstance.engineClass), engineClassInstance.engineInstance); + + if (engineClassInstance.engineClass == getDrmParamValue(DrmParam::EngineClassCompute) || + engineClassInstance.engineClass == getDrmParamValue(DrmParam::EngineClassRender) || + engineClassInstance.engineClass == getDrmParamValue(DrmParam::EngineClassCopy) || + (isSysmanEnabled && (engineClassInstance.engineClass == getDrmParamValue(DrmParam::EngineClassVideo) || + engineClassInstance.engineClass == getDrmParamValue(DrmParam::EngineClassVideoEnhance)))) { + + if (enginesPerTile.size() <= tile) { + enginesPerTile.resize(tile + 1); + } + enginesPerTile[tile].push_back(engineClassInstance); + allEngines.push_back(queriedEngines[i]); + } + } + + return std::make_unique(&drm, enginesPerTile); +} + int IoctlHelperXe::createGemExt(const MemRegionsVec &memClassInstances, size_t allocSize, uint32_t &handle, std::optional vmId, int32_t pairHandle) { struct drm_xe_gem_create create = {}; uint32_t regionsSize = static_cast(memClassInstances.size()); @@ -555,24 +577,6 @@ uint64_t IoctlHelperXe::getFlagsForVmBind(bool bindCapture, bool bindImmediate, int IoctlHelperXe::queryDistances(std::vector &queryItems, std::vector &distanceInfos) { xeLog(" -> IoctlHelperXe::%s\n", __FUNCTION__); - if (distanceInfos.size() == 0) { - DistanceInfo d; - struct drm_xe_engine_class_instance *currentEngine; - for (int i = 0; i < numberHwEngines && (currentEngine = &hwEngines.get()[i]); ++i) { - switch (currentEngine->engine_class) { - case DRM_XE_ENGINE_CLASS_RENDER: - case DRM_XE_ENGINE_CLASS_COPY: - case DRM_XE_ENGINE_CLASS_COMPUTE: - d.distance = 0; - d.engine.engineClass = currentEngine->engine_class; - d.engine.engineInstance = currentEngine->engine_instance; - d.region.memoryClass = XE_MEM_REGION_CLASS_VRAM; - d.region.memoryInstance = 0; - distanceInfos.push_back(d); - break; - } - } - } return 0; } @@ -1356,13 +1360,12 @@ std::string IoctlHelperXe::getFileForMaxMemoryFrequencyOfSubDevice(int subDevice struct drm_xe_engine_class_instance * IoctlHelperXe::xeFindMatchingEngine(uint16_t engineClass, uint16_t engineInstance) { - struct drm_xe_engine_class_instance *currentEngine = nullptr; - for (int i = 0; i < numberHwEngines && (currentEngine = &hwEngines.get()[i]); ++i) { - if (currentEngine->engine_class == engineClass && - (engineInstance == XE_FIND_INVALID_INSTANCE || currentEngine->engine_instance == engineInstance)) { - xeLog("\t select: %s:%d (%d)\n", xeGetClassName(currentEngine->engine_class), - currentEngine->engine_instance, engineInstance); - return currentEngine; + for (auto &engine : allEngines) { + if (engine.engine_class == engineClass && + (engineInstance == XE_FIND_INVALID_INSTANCE || engine.engine_instance == engineInstance)) { + xeLog("\t select: %s:%d (%d)\n", xeGetClassName(engine.engine_class), + engine.engine_instance, engineInstance); + return &engine; } } return nullptr; diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h index 196cf4f160..ba916132a0 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.h +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.h @@ -94,6 +94,7 @@ class IoctlHelperXe : public IoctlHelper { std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const override; bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) override; bool isWaitBeforeBindRequired(bool bind) const override; + std::unique_ptr createEngineInfo(bool isSysmanEnabled) override; std::vector xeRebuildi915Topology(std::vector *geomDss, std::vector *computeDss, std::vector *euDss); @@ -114,6 +115,7 @@ class IoctlHelperXe : public IoctlHelper { const char *xeGetClassName(int className); const char *xeGetBindOpName(int bindOp); const char *xeGetengineClassName(uint32_t engineClass); + std::vector queryData(uint32_t queryId); protected: int chipsetId = 0; @@ -123,8 +125,6 @@ class IoctlHelperXe : public IoctlHelper { uint32_t xeVmId = 0; uint32_t userPtrHandle = 0; uint32_t addressWidth = 48; - int numberHwEngines = 0; - std::unique_ptr hwEngines; int xeFileHandle = 0; std::mutex xeLock; std::vector bindInfo; @@ -132,10 +132,10 @@ class IoctlHelperXe : public IoctlHelper { uint64_t xeMemoryRegions = 0; uint32_t xeTimestampFrequency = 0; std::vector memQueryFakei915; - std::vector engineFakei915; std::vector hwconfigFakei915; std::vector topologyFakei915; std::vector contextParamEngine; + std::vector allEngines; }; } // namespace NEO diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp index add837a580..1ab19e3568 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp @@ -6,6 +6,7 @@ */ #include "shared/source/helpers/register_offsets.h" +#include "shared/source/os_interface/linux/engine_info.h" #include "shared/source/os_interface/linux/i915_prelim.h" #include "shared/source/os_interface/linux/ioctl_helper.h" #include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h" @@ -23,6 +24,7 @@ using NEO::PrelimI915::drm_syncobj_destroy; using NEO::PrelimI915::drm_syncobj_wait; struct MockIoctlHelperXe : IoctlHelperXe { + using IoctlHelperXe::IoctlHelperXe; using IoctlHelperXe::xeDecanonize; using IoctlHelperXe::xeGetBindOpName; using IoctlHelperXe::xeGetClassName; @@ -515,9 +517,13 @@ class DrmMockXe : public DrmMockCustom { ret = -2; break; case DrmIoctl::Query: { - struct drm_xe_device_query *v = static_cast(arg); - switch (v->query) { + struct drm_xe_device_query *deviceQuery = static_cast(arg); + switch (deviceQuery->query) { case DRM_XE_DEVICE_QUERY_ENGINES: + if (deviceQuery->data) { + memcpy_s(reinterpret_cast(deviceQuery->data), deviceQuery->size, queryEngines, sizeof(queryEngines)); + } + deviceQuery->size = sizeof(queryEngines); break; } ret = 0; @@ -531,6 +537,16 @@ class DrmMockXe : public DrmMockCustom { } int forceIoctlAnswer = 0; int setIoctlAnswer = 0; + const drm_xe_engine_class_instance queryEngines[9] = { + {DRM_XE_ENGINE_CLASS_RENDER, 0, 0}, + {DRM_XE_ENGINE_CLASS_COPY, 1, 0}, + {DRM_XE_ENGINE_CLASS_COPY, 2, 0}, + {DRM_XE_ENGINE_CLASS_COMPUTE, 3, 0}, + {DRM_XE_ENGINE_CLASS_COMPUTE, 4, 0}, + {DRM_XE_ENGINE_CLASS_COMPUTE, 5, 1}, + {DRM_XE_ENGINE_CLASS_COMPUTE, 6, 1}, + {DRM_XE_ENGINE_CLASS_VIDEO_DECODE, 7, 1}, + {DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE, 8, 0}}; }; TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) { @@ -538,7 +554,7 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) { DebugManagerStateRestore restorer; auto executionEnvironment = std::make_unique(); DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; - auto xeIoctlHelper = std::make_unique(drm); + auto xeIoctlHelper = std::make_unique(drm); auto mockXeIoctlHelper = static_cast(xeIoctlHelper.get()); drm.reset(); @@ -685,3 +701,95 @@ TEST(IoctlHelperXeTest, whenCallingIoctlThenProperValueIsReturned) { EXPECT_THROW(mockXeIoctlHelper->ioctl(DrmIoctl::GemContextCreateExt, NULL), std::runtime_error); drm.reset(); } +TEST(IoctlHelperXeTest, whenCreatingEngineInfoThenProperEnginesAreDiscovered) { + DebugManagerStateRestore restorer; + auto executionEnvironment = std::make_unique(); + DrmMockXe drm{*executionEnvironment->rootDeviceEnvironments[0]}; + auto xeIoctlHelper = std::make_unique(drm); + + for (const auto &isSysmanEnabled : ::testing::Bool()) { + auto engineInfo = xeIoctlHelper->createEngineInfo(isSysmanEnabled); + + EXPECT_NE(nullptr, engineInfo); + + auto rcsEngineType = EngineHelpers::remapEngineTypeToHwSpecific(aub_stream::EngineType::ENGINE_RCS, *executionEnvironment->rootDeviceEnvironments[0]); + auto rcsEngine = engineInfo->getEngineInstance(0, rcsEngineType); + EXPECT_NE(nullptr, rcsEngine); + EXPECT_EQ(0, rcsEngine->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_RENDER), rcsEngine->engineClass); + EXPECT_EQ(0u, engineInfo->getEngineTileIndex(*rcsEngine)); + + EXPECT_EQ(nullptr, engineInfo->getEngineInstance(1, rcsEngineType)); + + auto bcsEngine = engineInfo->getEngineInstance(0, aub_stream::EngineType::ENGINE_BCS); + EXPECT_NE(nullptr, bcsEngine); + EXPECT_EQ(1, bcsEngine->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_COPY), bcsEngine->engineClass); + EXPECT_EQ(0u, engineInfo->getEngineTileIndex(*bcsEngine)); + + EXPECT_EQ(nullptr, engineInfo->getEngineInstance(1, aub_stream::EngineType::ENGINE_BCS)); + + auto bcs1Engine = engineInfo->getEngineInstance(0, aub_stream::EngineType::ENGINE_BCS1); + EXPECT_NE(nullptr, bcs1Engine); + EXPECT_EQ(2, bcs1Engine->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_COPY), bcs1Engine->engineClass); + EXPECT_EQ(0u, engineInfo->getEngineTileIndex(*bcs1Engine)); + + EXPECT_EQ(nullptr, engineInfo->getEngineInstance(1, aub_stream::EngineType::ENGINE_BCS1)); + + auto ccsEngine0 = engineInfo->getEngineInstance(0, aub_stream::EngineType::ENGINE_CCS); + EXPECT_NE(nullptr, ccsEngine0); + EXPECT_EQ(3, ccsEngine0->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_COMPUTE), ccsEngine0->engineClass); + EXPECT_EQ(0u, engineInfo->getEngineTileIndex(*ccsEngine0)); + + auto ccsEngine1 = engineInfo->getEngineInstance(1, aub_stream::EngineType::ENGINE_CCS); + EXPECT_NE(nullptr, ccsEngine1); + EXPECT_EQ(5, ccsEngine1->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_COMPUTE), ccsEngine1->engineClass); + EXPECT_EQ(1u, engineInfo->getEngineTileIndex(*ccsEngine1)); + + auto ccs1Engine0 = engineInfo->getEngineInstance(0, aub_stream::EngineType::ENGINE_CCS1); + EXPECT_NE(nullptr, ccs1Engine0); + EXPECT_EQ(4, ccs1Engine0->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_COMPUTE), ccs1Engine0->engineClass); + EXPECT_EQ(0u, engineInfo->getEngineTileIndex(*ccs1Engine0)); + + auto ccs1Engine1 = engineInfo->getEngineInstance(1, aub_stream::EngineType::ENGINE_CCS1); + EXPECT_NE(nullptr, ccs1Engine1); + EXPECT_EQ(6, ccs1Engine1->engineInstance); + EXPECT_EQ(static_cast(DRM_XE_ENGINE_CLASS_COMPUTE), ccs1Engine1->engineClass); + EXPECT_EQ(1u, engineInfo->getEngineTileIndex(*ccs1Engine1)); + + std::vector enginesOnTile0; + std::vector enginesOnTile1; + engineInfo->getListOfEnginesOnATile(0, enginesOnTile0); + engineInfo->getListOfEnginesOnATile(1, enginesOnTile1); + + for (const auto &engine : enginesOnTile0) { + EXPECT_NE(static_cast(DRM_XE_ENGINE_CLASS_VIDEO_DECODE), engine.engineClass); + } + + bool foundVideDecodeEngine = false; + for (const auto &engine : enginesOnTile1) { + if (engine.engineClass == DRM_XE_ENGINE_CLASS_VIDEO_DECODE) { + EXPECT_EQ(7, engine.engineInstance); + foundVideDecodeEngine = true; + } + } + EXPECT_EQ(isSysmanEnabled, foundVideDecodeEngine); + + bool foundVideoEnhanceEngine = false; + for (const auto &engine : enginesOnTile0) { + if (engine.engineClass == DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE) { + EXPECT_EQ(8, engine.engineInstance); + foundVideoEnhanceEngine = true; + } + } + EXPECT_EQ(isSysmanEnabled, foundVideoEnhanceEngine); + + for (const auto &engine : enginesOnTile1) { + EXPECT_NE(static_cast(DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE), engine.engineClass); + } + } +} \ No newline at end of file