Path: blob/main_old/src/libANGLE/CLPlatform.cpp
1693 views
//1// Copyright 2021 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// CLPlatform.cpp: Implements the cl::Platform class.67#include "libANGLE/CLPlatform.h"89#include "libANGLE/CLContext.h"10#include "libANGLE/CLDevice.h"1112#include <cstring>1314namespace cl15{1617namespace18{1920bool IsDeviceTypeMatch(DeviceType select, DeviceType type)21{22// The type 'DeviceType' is a bitfield, so it matches if any selected bit is set.23// A custom device is an exception, which only matches if it was explicitely selected, see:24// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceIDs25return type == CL_DEVICE_TYPE_CUSTOM ? select == CL_DEVICE_TYPE_CUSTOM : type.isSet(select);26}2728Context::PropArray ParseContextProperties(const cl_context_properties *properties,29Platform *&platform,30bool &userSync)31{32Context::PropArray propArray;33if (properties != nullptr)34{35const cl_context_properties *propIt = properties;36while (*propIt != 0)37{38switch (*propIt++)39{40case CL_CONTEXT_PLATFORM:41platform = &reinterpret_cast<cl_platform_id>(*propIt++)->cast<Platform>();42break;43case CL_CONTEXT_INTEROP_USER_SYNC:44userSync = *propIt++ != CL_FALSE;45break;46}47}48// Include the trailing zero49++propIt;50propArray.reserve(propIt - properties);51propArray.insert(propArray.cend(), properties, propIt);52}53if (platform == nullptr)54{55platform = Platform::GetDefault();56}57return propArray;58}5960} // namespace6162void Platform::Initialize(const cl_icd_dispatch &dispatch,63rx::CLPlatformImpl::CreateFuncs &&createFuncs)64{65PlatformPtrs &platforms = GetPointers();66ASSERT(_cl_platform_id::sDispatch == nullptr && platforms.empty());67if (_cl_platform_id::sDispatch != nullptr || !platforms.empty())68{69ERR() << "Already initialized";70return;71}72Dispatch::sDispatch = &dispatch;7374platforms.reserve(createFuncs.size());75while (!createFuncs.empty())76{77platforms.emplace_back(new Platform(createFuncs.front()));78// Release initialization reference, lifetime controlled by RefPointer.79platforms.back()->release();80if (!platforms.back()->mInfo.isValid() || platforms.back()->mDevices.empty())81{82platforms.pop_back();83}84createFuncs.pop_front();85}86}8788cl_int Platform::GetPlatformIDs(cl_uint numEntries,89cl_platform_id *platforms,90cl_uint *numPlatforms)91{92const PlatformPtrs &availPlatforms = GetPlatforms();93if (numPlatforms != nullptr)94{95*numPlatforms = static_cast<cl_uint>(availPlatforms.size());96}97if (platforms != nullptr)98{99cl_uint entry = 0u;100auto platformIt = availPlatforms.cbegin();101while (entry < numEntries && platformIt != availPlatforms.cend())102{103platforms[entry++] = (*platformIt++).get();104}105}106return CL_SUCCESS;107}108109cl_int Platform::getInfo(PlatformInfo name,110size_t valueSize,111void *value,112size_t *valueSizeRet) const113{114const void *copyValue = nullptr;115size_t copySize = 0u;116117switch (name)118{119case PlatformInfo::Profile:120copyValue = mInfo.profile.c_str();121copySize = mInfo.profile.length() + 1u;122break;123case PlatformInfo::Version:124copyValue = mInfo.versionStr.c_str();125copySize = mInfo.versionStr.length() + 1u;126break;127case PlatformInfo::NumericVersion:128copyValue = &mInfo.version;129copySize = sizeof(mInfo.version);130break;131case PlatformInfo::Name:132copyValue = mInfo.name.c_str();133copySize = mInfo.name.length() + 1u;134break;135case PlatformInfo::Vendor:136copyValue = kVendor;137copySize = sizeof(kVendor);138break;139case PlatformInfo::Extensions:140copyValue = mInfo.extensions.c_str();141copySize = mInfo.extensions.length() + 1u;142break;143case PlatformInfo::ExtensionsWithVersion:144copyValue = mInfo.extensionsWithVersion.data();145copySize = mInfo.extensionsWithVersion.size() *146sizeof(decltype(mInfo.extensionsWithVersion)::value_type);147break;148case PlatformInfo::HostTimerResolution:149copyValue = &mInfo.hostTimerRes;150copySize = sizeof(mInfo.hostTimerRes);151break;152case PlatformInfo::IcdSuffix:153copyValue = kIcdSuffix;154copySize = sizeof(kIcdSuffix);155break;156default:157ASSERT(false);158return CL_INVALID_VALUE;159}160161if (value != nullptr)162{163// CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type164// as specified in the OpenCL Platform Queries table, and param_value is not a NULL value.165if (valueSize < copySize)166{167return CL_INVALID_VALUE;168}169if (copyValue != nullptr)170{171std::memcpy(value, copyValue, copySize);172}173}174if (valueSizeRet != nullptr)175{176*valueSizeRet = copySize;177}178return CL_SUCCESS;179}180181cl_int Platform::getDeviceIDs(DeviceType deviceType,182cl_uint numEntries,183cl_device_id *devices,184cl_uint *numDevices) const185{186cl_uint found = 0u;187for (const DevicePtr &device : mDevices)188{189if (IsDeviceTypeMatch(deviceType, device->getInfo().type))190{191if (devices != nullptr && found < numEntries)192{193devices[found] = device.get();194}195++found;196}197}198if (numDevices != nullptr)199{200*numDevices = found;201}202203// CL_DEVICE_NOT_FOUND if no OpenCL devices that matched device_type were found.204if (found == 0u)205{206return CL_DEVICE_NOT_FOUND;207}208209return CL_SUCCESS;210}211212cl_context Platform::CreateContext(const cl_context_properties *properties,213cl_uint numDevices,214const cl_device_id *devices,215ContextErrorCB notify,216void *userData,217cl_int &errorCode)218{219Platform *platform = nullptr;220bool userSync = false;221Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);222ASSERT(platform != nullptr);223DevicePtrs devs;224devs.reserve(numDevices);225while (numDevices-- != 0u)226{227devs.emplace_back(&(*devices++)->cast<Device>());228}229return Object::Create<Context>(errorCode, *platform, std::move(propArray), std::move(devs),230notify, userData, userSync);231}232233cl_context Platform::CreateContextFromType(const cl_context_properties *properties,234DeviceType deviceType,235ContextErrorCB notify,236void *userData,237cl_int &errorCode)238{239Platform *platform = nullptr;240bool userSync = false;241Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);242ASSERT(platform != nullptr);243return Object::Create<Context>(errorCode, *platform, std::move(propArray), deviceType, notify,244userData, userSync);245}246247cl_int Platform::unloadCompiler()248{249return mImpl->unloadCompiler();250}251252Platform::~Platform() = default;253254Platform::Platform(const rx::CLPlatformImpl::CreateFunc &createFunc)255: mImpl(createFunc(*this)),256mInfo(mImpl->createInfo()),257mDevices(createDevices(mImpl->createDevices()))258{}259260DevicePtrs Platform::createDevices(rx::CLDeviceImpl::CreateDatas &&createDatas)261{262DevicePtrs devices;263devices.reserve(createDatas.size());264while (!createDatas.empty())265{266devices.emplace_back(267new Device(*this, nullptr, createDatas.front().first, createDatas.front().second));268// Release initialization reference, lifetime controlled by RefPointer.269devices.back()->release();270if (!devices.back()->mInfo.isValid())271{272devices.pop_back();273}274createDatas.pop_front();275}276return devices;277}278279constexpr char Platform::kVendor[];280constexpr char Platform::kIcdSuffix[];281282} // namespace cl283284285