2017-12-21 00:45:38 +01:00
|
|
|
/*
|
2019-01-10 09:37:56 +01:00
|
|
|
* Copyright (C) 2017-2019 Intel Corporation
|
2017-12-21 00:45:38 +01:00
|
|
|
*
|
2018-09-18 09:11:08 +02:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 00:45:38 +01:00
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2018-07-16 17:11:43 +02:00
|
|
|
#include "runtime/device/device.h"
|
2018-04-18 14:59:28 +02:00
|
|
|
#include "hw_cmds.h"
|
2018-03-05 09:25:40 +01:00
|
|
|
#include "runtime/built_ins/built_ins.h"
|
2017-12-21 00:45:38 +01:00
|
|
|
#include "runtime/command_stream/command_stream_receiver.h"
|
|
|
|
|
#include "runtime/command_stream/device_command_stream.h"
|
2018-07-05 11:23:28 +02:00
|
|
|
#include "runtime/command_stream/experimental_command_buffer.h"
|
2018-02-06 11:58:05 +01:00
|
|
|
#include "runtime/command_stream/preemption.h"
|
2018-01-30 16:49:01 +01:00
|
|
|
#include "runtime/compiler_interface/compiler_interface.h"
|
2017-12-21 00:45:38 +01:00
|
|
|
#include "runtime/device/device_vector.h"
|
2018-04-18 14:59:28 +02:00
|
|
|
#include "runtime/device/driver_info.h"
|
2018-06-27 11:35:37 +02:00
|
|
|
#include "runtime/execution_environment/execution_environment.h"
|
2017-12-21 00:45:38 +01:00
|
|
|
#include "runtime/helpers/debug_helpers.h"
|
|
|
|
|
#include "runtime/helpers/options.h"
|
|
|
|
|
#include "runtime/memory_manager/memory_manager.h"
|
2018-08-27 15:48:29 +02:00
|
|
|
#include "runtime/os_interface/os_context.h"
|
2018-04-23 14:26:03 +02:00
|
|
|
#include "runtime/os_interface/os_interface.h"
|
2017-12-21 00:45:38 +01:00
|
|
|
#include "runtime/os_interface/os_time.h"
|
2018-04-23 14:26:03 +02:00
|
|
|
#include "runtime/source_level_debugger/source_level_debugger.h"
|
2017-12-21 00:45:38 +01:00
|
|
|
#include <cstring>
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
namespace OCLRT {
|
|
|
|
|
|
|
|
|
|
decltype(&PerformanceCounters::create) Device::createPerformanceCountersFunc = PerformanceCounters::create;
|
|
|
|
|
|
|
|
|
|
DeviceVector::DeviceVector(const cl_device_id *devices,
|
|
|
|
|
cl_uint numDevices) {
|
|
|
|
|
for (cl_uint i = 0; i < numDevices; i++) {
|
|
|
|
|
this->push_back(castToObject<Device>(devices[i]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DeviceVector::toDeviceIDs(std::vector<cl_device_id> &devIDs) {
|
|
|
|
|
int i = 0;
|
|
|
|
|
devIDs.resize(this->size());
|
|
|
|
|
|
|
|
|
|
for (auto &it : *this) {
|
|
|
|
|
devIDs[i] = it;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-08 13:49:09 +02:00
|
|
|
CommandStreamReceiver *createCommandStream(const HardwareInfo *pHwInfo, ExecutionEnvironment &executionEnvironment);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
|
// Global table of hardware prefixes
|
|
|
|
|
const char *hardwarePrefix[IGFX_MAX_PRODUCT] = {
|
|
|
|
|
nullptr,
|
|
|
|
|
};
|
|
|
|
|
// Global table of family names
|
|
|
|
|
const char *familyName[IGFX_MAX_CORE] = {
|
|
|
|
|
nullptr,
|
|
|
|
|
};
|
|
|
|
|
// Global table of family names
|
|
|
|
|
bool familyEnabled[IGFX_MAX_CORE] = {
|
|
|
|
|
false,
|
|
|
|
|
};
|
|
|
|
|
|
2018-09-11 11:28:19 +02:00
|
|
|
Device::Device(const HardwareInfo &hwInfo, ExecutionEnvironment *executionEnvironment, uint32_t deviceIndex)
|
|
|
|
|
: hwInfo(hwInfo), executionEnvironment(executionEnvironment), deviceIndex(deviceIndex) {
|
2017-12-21 00:45:38 +01:00
|
|
|
memset(&deviceInfo, 0, sizeof(deviceInfo));
|
|
|
|
|
deviceExtensions.reserve(1000);
|
2018-06-21 10:47:21 +02:00
|
|
|
name.reserve(100);
|
2018-02-06 11:58:05 +01:00
|
|
|
preemptionMode = PreemptionHelper::getDefaultPreemptionMode(hwInfo);
|
2018-10-01 13:36:15 -07:00
|
|
|
|
2018-07-12 15:47:48 +02:00
|
|
|
if (!getSourceLevelDebugger()) {
|
|
|
|
|
this->executionEnvironment->initSourceLevelDebugger(hwInfo);
|
2018-04-23 14:26:03 +02:00
|
|
|
}
|
2018-07-10 17:14:20 +02:00
|
|
|
this->executionEnvironment->incRefInternal();
|
2018-08-17 11:00:21 +02:00
|
|
|
auto &hwHelper = HwHelper::get(hwInfo.pPlatform->eRenderCoreFamily);
|
2018-08-23 17:42:35 +02:00
|
|
|
hwHelper.setupHardwareCapabilities(&this->hardwareCapabilities, hwInfo);
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Device::~Device() {
|
2018-07-11 16:47:49 +02:00
|
|
|
DEBUG_BREAK_IF(nullptr == executionEnvironment->memoryManager.get());
|
2017-12-21 00:45:38 +01:00
|
|
|
if (performanceCounters) {
|
|
|
|
|
performanceCounters->shutdown();
|
|
|
|
|
}
|
2018-07-16 13:01:10 +02:00
|
|
|
|
2018-11-21 09:57:51 +01:00
|
|
|
for (auto &engine : engines) {
|
2018-11-23 14:59:27 +01:00
|
|
|
if (engine.commandStreamReceiver) {
|
|
|
|
|
engine.commandStreamReceiver->flushBatchedSubmissions();
|
|
|
|
|
}
|
2018-03-09 14:48:42 +01:00
|
|
|
}
|
|
|
|
|
|
2018-07-12 15:47:48 +02:00
|
|
|
if (deviceInfo.sourceLevelDebuggerActive && executionEnvironment->sourceLevelDebugger) {
|
|
|
|
|
executionEnvironment->sourceLevelDebugger->notifyDeviceDestruction();
|
2018-05-02 14:27:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-11 16:47:49 +02:00
|
|
|
if (executionEnvironment->memoryManager) {
|
2018-01-12 14:18:53 +01:00
|
|
|
if (preemptionAllocation) {
|
2018-07-11 16:47:49 +02:00
|
|
|
executionEnvironment->memoryManager->freeGraphicsMemory(preemptionAllocation);
|
2018-01-12 14:18:53 +01:00
|
|
|
preemptionAllocation = nullptr;
|
|
|
|
|
}
|
2018-07-11 16:47:49 +02:00
|
|
|
executionEnvironment->memoryManager->waitForDeletions();
|
2018-01-22 16:43:26 +01:00
|
|
|
|
|
|
|
|
alignedFree(this->slmWindowStartAddress);
|
2018-01-17 16:23:51 +01:00
|
|
|
}
|
2018-07-10 17:14:20 +02:00
|
|
|
executionEnvironment->decRefInternal();
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
|
2018-06-29 09:12:40 +02:00
|
|
|
bool Device::createDeviceImpl(const HardwareInfo *pHwInfo, Device &outDevice) {
|
2018-07-16 17:11:43 +02:00
|
|
|
auto executionEnvironment = outDevice.executionEnvironment;
|
|
|
|
|
executionEnvironment->initGmm(pHwInfo);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
if (!createEngines(pHwInfo, outDevice)) {
|
2017-12-21 00:45:38 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
executionEnvironment->memoryManager->setDefaultEngineIndex(outDevice.defaultEngineIndex);
|
|
|
|
|
|
|
|
|
|
auto osInterface = executionEnvironment->osInterface.get();
|
2018-11-21 09:57:51 +01:00
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
if (!outDevice.osTime) {
|
|
|
|
|
outDevice.osTime = OSTime::create(osInterface);
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
2018-11-28 09:02:55 +01:00
|
|
|
outDevice.driverInfo.reset(DriverInfo::create(osInterface));
|
2018-07-16 17:11:43 +02:00
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
outDevice.initializeCaps();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
if (outDevice.osTime->getOSInterface()) {
|
2017-12-21 00:45:38 +01:00
|
|
|
if (pHwInfo->capabilityTable.instrumentationEnabled) {
|
2018-11-28 09:02:55 +01:00
|
|
|
outDevice.performanceCounters = createPerformanceCountersFunc(outDevice.osTime.get());
|
|
|
|
|
outDevice.performanceCounters->initialize(pHwInfo);
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-23 14:26:03 +02:00
|
|
|
uint32_t deviceHandle = 0;
|
2018-11-28 09:02:55 +01:00
|
|
|
if (osInterface) {
|
|
|
|
|
deviceHandle = osInterface->getDeviceHandle();
|
2018-04-23 14:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
if (outDevice.deviceInfo.sourceLevelDebuggerActive) {
|
|
|
|
|
outDevice.executionEnvironment->sourceLevelDebugger->notifyNewDevice(deviceHandle);
|
2018-04-23 14:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
outDevice.executionEnvironment->memoryManager->setForce32BitAllocations(outDevice.getDeviceInfo().force32BitAddressess);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
if (outDevice.preemptionMode == PreemptionMode::MidThread || outDevice.isSourceLevelDebuggerActive()) {
|
2018-12-11 18:56:37 +01:00
|
|
|
AllocationProperties properties(true, pHwInfo->capabilityTable.requiredPreemptionSurfaceSize, GraphicsAllocation::AllocationType::UNDECIDED);
|
2018-11-30 11:01:33 +01:00
|
|
|
properties.flags.uncacheable = outDevice.getWaTable()->waCSRUncachable;
|
|
|
|
|
properties.alignment = 256 * MemoryConstants::kiloByte;
|
|
|
|
|
outDevice.preemptionAllocation = outDevice.executionEnvironment->memoryManager->allocateGraphicsMemoryWithProperties(properties);
|
2018-11-28 09:02:55 +01:00
|
|
|
if (!outDevice.preemptionAllocation) {
|
2017-12-21 00:45:38 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
for (auto engine : outDevice.engines) {
|
|
|
|
|
auto csr = engine.commandStreamReceiver;
|
|
|
|
|
csr->setPreemptionCsrAllocation(outDevice.preemptionAllocation);
|
|
|
|
|
if (DebugManager.flags.EnableExperimentalCommandBuffer.get() > 0) {
|
|
|
|
|
csr->setExperimentalCmdBuffer(std::make_unique<ExperimentalCommandBuffer>(csr, outDevice.getDeviceInfo().profilingTimerResolution));
|
|
|
|
|
}
|
2018-07-05 11:23:28 +02:00
|
|
|
}
|
|
|
|
|
|
2017-12-21 00:45:38 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-28 09:02:55 +01:00
|
|
|
bool Device::createEngines(const HardwareInfo *pHwInfo, Device &outDevice) {
|
|
|
|
|
auto executionEnvironment = outDevice.executionEnvironment;
|
2018-12-10 10:30:39 +01:00
|
|
|
auto defaultEngineType = getChosenEngineType(*pHwInfo);
|
2018-11-28 09:02:55 +01:00
|
|
|
|
|
|
|
|
for (uint32_t deviceCsrIndex = 0; deviceCsrIndex < gpgpuEngineInstances.size(); deviceCsrIndex++) {
|
|
|
|
|
if (!executionEnvironment->initializeCommandStreamReceiver(pHwInfo, outDevice.getDeviceIndex(), deviceCsrIndex)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
executionEnvironment->initializeMemoryManager(outDevice.getEnabled64kbPages(), outDevice.getEnableLocalMemory(),
|
|
|
|
|
outDevice.getDeviceIndex(), deviceCsrIndex);
|
|
|
|
|
|
2018-12-10 10:30:39 +01:00
|
|
|
auto osContext = executionEnvironment->memoryManager->createAndRegisterOsContext(gpgpuEngineInstances[deviceCsrIndex], outDevice.preemptionMode);
|
2018-11-28 09:02:55 +01:00
|
|
|
auto commandStreamReceiver = executionEnvironment->commandStreamReceivers[outDevice.getDeviceIndex()][deviceCsrIndex].get();
|
2019-01-10 09:37:56 +01:00
|
|
|
commandStreamReceiver->setupContext(*osContext);
|
2018-11-28 09:02:55 +01:00
|
|
|
if (!commandStreamReceiver->initializeTagAllocation()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gpgpuEngineInstances[deviceCsrIndex].type == defaultEngineType && gpgpuEngineInstances[deviceCsrIndex].id == 0) {
|
|
|
|
|
outDevice.defaultEngineIndex = deviceCsrIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outDevice.engines[deviceCsrIndex] = {commandStreamReceiver, osContext};
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-21 00:45:38 +01:00
|
|
|
const HardwareInfo *Device::getDeviceInitHwInfo(const HardwareInfo *pHwInfoIn) {
|
|
|
|
|
return pHwInfoIn ? pHwInfoIn : platformDevices[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const HardwareInfo &Device::getHardwareInfo() const { return hwInfo; }
|
|
|
|
|
|
|
|
|
|
const WorkaroundTable *Device::getWaTable() const { return hwInfo.pWaTable; }
|
|
|
|
|
|
|
|
|
|
const DeviceInfo &Device::getDeviceInfo() const {
|
|
|
|
|
return deviceInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DeviceInfo *Device::getMutableDeviceInfo() {
|
|
|
|
|
return &deviceInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *Device::getSLMWindowStartAddress() {
|
|
|
|
|
prepareSLMWindow();
|
|
|
|
|
return this->slmWindowStartAddress;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Device::prepareSLMWindow() {
|
|
|
|
|
if (this->slmWindowStartAddress == nullptr) {
|
2018-07-11 16:47:49 +02:00
|
|
|
this->slmWindowStartAddress = executionEnvironment->memoryManager->allocateSystemMemory(MemoryConstants::slmWindowSize, MemoryConstants::slmWindowAlignment);
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *Device::getProductAbbrev() const {
|
|
|
|
|
return hardwarePrefix[hwInfo.pPlatform->eProductFamily];
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-17 18:11:50 +02:00
|
|
|
const std::string Device::getFamilyNameWithType() const {
|
|
|
|
|
std::string platformName = familyName[hwInfo.pPlatform->eRenderCoreFamily];
|
|
|
|
|
platformName.append(getPlatformType(hwInfo));
|
|
|
|
|
return platformName;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-21 00:45:38 +01:00
|
|
|
double Device::getProfilingTimerResolution() {
|
|
|
|
|
return osTime->getDynamicDeviceTimerResolution(hwInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int Device::getSupportedClVersion() const {
|
|
|
|
|
return hwInfo.capabilityTable.clVersionSupport;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We hide the retain and release function of BaseObject. */
|
|
|
|
|
void Device::retain() {
|
|
|
|
|
DEBUG_BREAK_IF(!isValid());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unique_ptr_if_unused<Device> Device::release() {
|
|
|
|
|
DEBUG_BREAK_IF(!isValid());
|
|
|
|
|
return unique_ptr_if_unused<Device>(this, false);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-11 10:32:17 +02:00
|
|
|
bool Device::isSimulation() const {
|
2018-06-06 10:34:51 +02:00
|
|
|
bool simulation = hwInfo.capabilityTable.isSimulation(hwInfo.pPlatform->usDeviceID);
|
2018-11-21 09:57:51 +01:00
|
|
|
if (engines[0].commandStreamReceiver->getType() != CommandStreamReceiverType::CSR_HW) {
|
2018-06-06 10:34:51 +02:00
|
|
|
simulation = true;
|
|
|
|
|
}
|
2018-07-11 10:32:17 +02:00
|
|
|
if (hwInfo.pSkuTable->ftrSimulationMode) {
|
|
|
|
|
simulation = true;
|
|
|
|
|
}
|
2018-06-06 10:34:51 +02:00
|
|
|
return simulation;
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double Device::getPlatformHostTimerResolution() const {
|
|
|
|
|
if (osTime.get())
|
|
|
|
|
return osTime->getHostTimerResolution();
|
|
|
|
|
return 0.0;
|
|
|
|
|
}
|
|
|
|
|
GFXCORE_FAMILY Device::getRenderCoreFamily() const {
|
|
|
|
|
return this->getHardwareInfo().pPlatform->eRenderCoreFamily;
|
|
|
|
|
}
|
2018-04-06 14:25:22 +02:00
|
|
|
|
2018-04-10 13:49:26 +02:00
|
|
|
bool Device::isSourceLevelDebuggerActive() const {
|
2018-04-06 14:25:22 +02:00
|
|
|
return deviceInfo.sourceLevelDebuggerActive;
|
|
|
|
|
}
|
2018-11-22 13:57:10 +01:00
|
|
|
|
|
|
|
|
void Device::initMaxPowerSavingMode() {
|
|
|
|
|
for (auto &engine : engines) {
|
2018-11-23 14:59:27 +01:00
|
|
|
if (engine.commandStreamReceiver) {
|
|
|
|
|
engine.commandStreamReceiver->peekKmdNotifyHelper()->initMaxPowerSavingMode();
|
|
|
|
|
}
|
2018-11-22 13:57:10 +01:00
|
|
|
}
|
|
|
|
|
}
|
2017-12-21 00:45:38 +01:00
|
|
|
} // namespace OCLRT
|