1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // cl_utils.cpp: Helper functions for the CL back end
7 
8 #include "libANGLE/renderer/cl/cl_util.h"
9 
10 #include "libANGLE/Debug.h"
11 
12 #include <cstdlib>
13 
14 namespace rx
15 {
16 
ExtractCLVersion(const std::string & version)17 cl_version ExtractCLVersion(const std::string &version)
18 {
19     const std::string::size_type spacePos = version.find(' ');
20     const std::string::size_type dotPos   = version.find('.');
21     if (spacePos == std::string::npos || dotPos == std::string::npos)
22     {
23         ERR() << "Failed to extract version from OpenCL version string: " << version;
24         return 0u;
25     }
26 
27     const long major = std::strtol(&version[spacePos + 1u], nullptr, 10);
28     const long minor = std::strtol(&version[dotPos + 1u], nullptr, 10);
29     if (major < 1 || major > 9 || minor < 0 || minor > 9)
30     {
31         ERR() << "Failed to extract version from OpenCL version string: " << version;
32         return 0u;
33     }
34     return CL_MAKE_VERSION(static_cast<cl_uint>(major), static_cast<cl_uint>(minor), 0);
35 }
36 
RemoveUnsupportedCLExtensions(std::string & extensions)37 void RemoveUnsupportedCLExtensions(std::string &extensions)
38 {
39     if (extensions.empty())
40     {
41         return;
42     }
43     using SizeT    = std::string::size_type;
44     SizeT extStart = 0u;
45     SizeT spacePos = extensions.find(' ');
46 
47     // Remove all unsupported extensions which are terminated by a space
48     while (spacePos != std::string::npos)
49     {
50         const SizeT length = spacePos - extStart;
51         if (IsCLExtensionSupported(extensions.substr(extStart, length)))
52         {
53             extStart = spacePos + 1u;
54         }
55         else
56         {
57             extensions.erase(extStart, length + 1u);
58         }
59         spacePos = extensions.find(' ', extStart);
60     }
61 
62     // Remove last extension in string, if exists and unsupported
63     if (extStart < extensions.length())
64     {
65         const SizeT length = extensions.length() - extStart;
66         if (!IsCLExtensionSupported(extensions.substr(extStart, length)))
67         {
68             extensions.erase(extStart, length);
69         }
70     }
71 
72     // Remove trailing spaces
73     while (!extensions.empty() && extensions.back() == ' ')
74     {
75         extensions.pop_back();
76     }
77 }
78 
RemoveUnsupportedCLExtensions(NameVersionVector & extensions)79 void RemoveUnsupportedCLExtensions(NameVersionVector &extensions)
80 {
81     auto extIt = extensions.cbegin();
82     while (extIt != extensions.cend())
83     {
84         if (IsCLExtensionSupported(extIt->name))
85         {
86             ++extIt;
87         }
88         else
89         {
90             extIt = extensions.erase(extIt);
91         }
92     }
93 }
94 
95 }  // namespace rx
96