• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // CLDeviceVk.cpp: Implements the class methods for CLDeviceVk.
7 
8 #include "libANGLE/renderer/vulkan/CLDeviceVk.h"
9 #include "libANGLE/renderer/vulkan/CLPlatformVk.h"
10 #include "libANGLE/renderer/vulkan/vk_renderer.h"
11 
12 #include "libANGLE/Display.h"
13 #include "libANGLE/cl_utils.h"
14 
15 namespace rx
16 {
17 
CLDeviceVk(const cl::Device & device,vk::Renderer * renderer)18 CLDeviceVk::CLDeviceVk(const cl::Device &device, vk::Renderer *renderer)
19     : CLDeviceImpl(device), mRenderer(renderer)
20 {
21     const VkPhysicalDeviceProperties &props = mRenderer->getPhysicalDeviceProperties();
22 
23     // Setup initial device mInfo fields
24     // TODO(aannestrand) Create cl::Caps and use for device creation
25     // http://anglebug.com/8529
26     mInfoString = {
27         {cl::DeviceInfo::Name, std::string(props.deviceName)},
28         {cl::DeviceInfo::Vendor, mRenderer->getVendorString()},
29         {cl::DeviceInfo::DriverVersion, mRenderer->getVersionString(true)},
30         {cl::DeviceInfo::Version, std::string("OpenCL 3.0 " + mRenderer->getVersionString(true))},
31         {cl::DeviceInfo::Profile, std::string("FULL_PROFILE")},
32         {cl::DeviceInfo::OpenCL_C_Version, std::string("OpenCL C 3.0 ")},
33         {cl::DeviceInfo::LatestConformanceVersionPassed, std::string("FIXME")}};
34     mInfoSizeT = {
35         {cl::DeviceInfo::MaxWorkGroupSize, props.limits.maxComputeWorkGroupInvocations},
36         {cl::DeviceInfo::MaxGlobalVariableSize, 0},
37         {cl::DeviceInfo::GlobalVariablePreferredTotalSize, 0},
38 
39         // TODO(aannestrand) Update these hardcoded platform/device queries
40         // http://anglebug.com/8511
41         {cl::DeviceInfo::MaxParameterSize, 1024},
42         {cl::DeviceInfo::ProfilingTimerResolution, 1},
43         {cl::DeviceInfo::PrintfBufferSize, 1024 * 1024},
44         {cl::DeviceInfo::PreferredWorkGroupSizeMultiple, 16},
45     };
46     mInfoULong = {
47         {cl::DeviceInfo::LocalMemSize, props.limits.maxComputeSharedMemorySize},
48         {cl::DeviceInfo::SVM_Capabilities, 0},
49         {cl::DeviceInfo::QueueOnDeviceProperties, 0},
50         {cl::DeviceInfo::PartitionAffinityDomain, 0},
51         {cl::DeviceInfo::DeviceEnqueueCapabilities, 0},
52         {cl::DeviceInfo::QueueOnHostProperties, CL_QUEUE_PROFILING_ENABLE},
53 
54         // TODO(aannestrand) Update these hardcoded platform/device queries
55         // http://anglebug.com/8511
56         {cl::DeviceInfo::HalfFpConfig, 0},
57         {cl::DeviceInfo::DoubleFpConfig, 0},
58         {cl::DeviceInfo::GlobalMemCacheSize, 0},
59         {cl::DeviceInfo::GlobalMemSize, 1024 * 1024 * 1024},
60         {cl::DeviceInfo::MaxConstantBufferSize, 64 * 1024},
61         {cl::DeviceInfo::SingleFpConfig, CL_FP_ROUND_TO_NEAREST | CL_FP_INF_NAN | CL_FP_FMA},
62         {cl::DeviceInfo::AtomicMemoryCapabilities,
63          CL_DEVICE_ATOMIC_ORDER_RELAXED | CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP},
64         {cl::DeviceInfo::AtomicFenceCapabilities, CL_DEVICE_ATOMIC_ORDER_RELAXED |
65                                                       CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM |
66                                                       CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP},
67     };
68     mInfoUInt = {
69         {cl::DeviceInfo::VendorID, props.vendorID},
70         {cl::DeviceInfo::MaxReadImageArgs, props.limits.maxPerStageDescriptorSampledImages},
71         {cl::DeviceInfo::MaxWriteImageArgs, props.limits.maxPerStageDescriptorStorageImages},
72         {cl::DeviceInfo::MaxReadWriteImageArgs, props.limits.maxPerStageDescriptorStorageImages},
73         {cl::DeviceInfo::GlobalMemCachelineSize,
74          static_cast<cl_uint>(props.limits.nonCoherentAtomSize)},
75         {cl::DeviceInfo::Available, CL_TRUE},
76         {cl::DeviceInfo::LinkerAvailable, CL_TRUE},
77         {cl::DeviceInfo::CompilerAvailable, CL_TRUE},
78         {cl::DeviceInfo::MaxOnDeviceQueues, 0},
79         {cl::DeviceInfo::MaxOnDeviceEvents, 0},
80         {cl::DeviceInfo::QueueOnDeviceMaxSize, 0},
81         {cl::DeviceInfo::QueueOnDevicePreferredSize, 0},
82         {cl::DeviceInfo::MaxPipeArgs, 0},
83         {cl::DeviceInfo::PipeMaxPacketSize, 0},
84         {cl::DeviceInfo::PipeSupport, CL_FALSE},
85         {cl::DeviceInfo::PipeMaxActiveReservations, 0},
86         {cl::DeviceInfo::ErrorCorrectionSupport, CL_FALSE},
87         {cl::DeviceInfo::PreferredInteropUserSync, CL_TRUE},
88         {cl::DeviceInfo::ExecutionCapabilities, CL_EXEC_KERNEL},
89 
90         // TODO(aannestrand) Update these hardcoded platform/device queries
91         // http://anglebug.com/8511
92         {cl::DeviceInfo::AddressBits, 64},
93         {cl::DeviceInfo::EndianLittle, CL_TRUE},
94         {cl::DeviceInfo::LocalMemType, CL_LOCAL},
95         {cl::DeviceInfo::MaxSamplers, 0},
96         {cl::DeviceInfo::MaxConstantArgs, 8},
97         {cl::DeviceInfo::MaxNumSubGroups, 0},
98         {cl::DeviceInfo::MaxComputeUnits, 4},
99         {cl::DeviceInfo::MaxClockFrequency, 555},
100         {cl::DeviceInfo::MaxWorkItemDimensions, 3},
101         {cl::DeviceInfo::MinDataTypeAlignSize, 128},
102         {cl::DeviceInfo::GlobalMemCacheType, CL_NONE},
103         {cl::DeviceInfo::HostUnifiedMemory, CL_TRUE},
104         {cl::DeviceInfo::NativeVectorWidthChar, 4},
105         {cl::DeviceInfo::NativeVectorWidthShort, 2},
106         {cl::DeviceInfo::NativeVectorWidthInt, 1},
107         {cl::DeviceInfo::NativeVectorWidthLong, 1},
108         {cl::DeviceInfo::NativeVectorWidthFloat, 1},
109         {cl::DeviceInfo::NativeVectorWidthDouble, 1},
110         {cl::DeviceInfo::NativeVectorWidthHalf, 0},
111         {cl::DeviceInfo::PartitionMaxSubDevices, 0},
112         {cl::DeviceInfo::PreferredVectorWidthInt, 1},
113         {cl::DeviceInfo::PreferredVectorWidthLong, 1},
114         {cl::DeviceInfo::PreferredVectorWidthChar, 4},
115         {cl::DeviceInfo::PreferredVectorWidthHalf, 0},
116         {cl::DeviceInfo::PreferredVectorWidthShort, 2},
117         {cl::DeviceInfo::PreferredVectorWidthFloat, 1},
118         {cl::DeviceInfo::PreferredVectorWidthDouble, 0},
119         {cl::DeviceInfo::PreferredLocalAtomicAlignment, 0},
120         {cl::DeviceInfo::PreferredGlobalAtomicAlignment, 0},
121         {cl::DeviceInfo::PreferredPlatformAtomicAlignment, 0},
122         {cl::DeviceInfo::NonUniformWorkGroupSupport, CL_TRUE},
123         {cl::DeviceInfo::GenericAddressSpaceSupport, CL_FALSE},
124         {cl::DeviceInfo::SubGroupIndependentForwardProgress, CL_FALSE},
125         {cl::DeviceInfo::WorkGroupCollectiveFunctionsSupport, CL_FALSE},
126     };
127 }
128 
129 CLDeviceVk::~CLDeviceVk() = default;
130 
createInfo(cl::DeviceType type) const131 CLDeviceImpl::Info CLDeviceVk::createInfo(cl::DeviceType type) const
132 {
133     Info info(type);
134 
135     const VkPhysicalDeviceProperties &properties = mRenderer->getPhysicalDeviceProperties();
136 
137     info.maxWorkItemSizes.push_back(properties.limits.maxComputeWorkGroupSize[0]);
138     info.maxWorkItemSizes.push_back(properties.limits.maxComputeWorkGroupSize[1]);
139     info.maxWorkItemSizes.push_back(properties.limits.maxComputeWorkGroupSize[2]);
140 
141     // TODO(aannestrand) Update these hardcoded platform/device queries
142     // http://anglebug.com/8511
143     info.maxMemAllocSize  = 1 << 30;
144     info.memBaseAddrAlign = 1024;
145 
146     // TODO(aannestrand) Add image and sampler support later
147     // http://anglebug.com/8512
148     info.imageSupport = CL_FALSE;
149 
150     info.image2D_MaxWidth          = properties.limits.maxImageDimension2D;
151     info.image2D_MaxHeight         = properties.limits.maxImageDimension2D;
152     info.image3D_MaxWidth          = properties.limits.maxImageDimension3D;
153     info.image3D_MaxHeight         = properties.limits.maxImageDimension3D;
154     info.image3D_MaxDepth          = properties.limits.maxImageDimension3D;
155     info.imageMaxBufferSize        = properties.limits.maxImageDimension1D;
156     info.imageMaxArraySize         = properties.limits.maxImageArrayLayers;
157     info.imagePitchAlignment       = 0u;
158     info.imageBaseAddressAlignment = 0u;
159 
160     info.execCapabilities     = CL_EXEC_KERNEL;
161     info.queueOnDeviceMaxSize = 0u;
162     info.builtInKernels       = "";
163     info.version              = CL_MAKE_VERSION(3, 0, 0);
164     info.versionStr           = "OpenCL 3.0 " + mRenderer->getVersionString(true);
165     info.OpenCL_C_AllVersions = {{CL_MAKE_VERSION(3, 0, 0), "OpenCL C"},
166                                  {CL_MAKE_VERSION(2, 0, 0), "OpenCL C"},
167                                  {CL_MAKE_VERSION(1, 2, 0), "OpenCL C"},
168                                  {CL_MAKE_VERSION(1, 1, 0), "OpenCL C"},
169                                  {CL_MAKE_VERSION(1, 0, 0), "OpenCL C"}};
170 
171     info.OpenCL_C_Features         = {};
172     info.extensionsWithVersion     = {};
173     info.ILsWithVersion            = {};
174     info.builtInKernelsWithVersion = {};
175     info.partitionProperties       = {};
176     info.partitionType             = {};
177     info.IL_Version                = "";
178 
179     // Below extensions are required as of OpenCL 1.1
180     info.extensions =
181         "cl_khr_byte_addressable_store "
182         "cl_khr_global_int32_base_atomics "
183         "cl_khr_global_int32_extended_atomics "
184         "cl_khr_local_int32_base_atomics "
185         "cl_khr_local_int32_extended_atomics ";
186 
187     return info;
188 }
189 
getInfoUInt(cl::DeviceInfo name,cl_uint * value) const190 angle::Result CLDeviceVk::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const
191 {
192     if (mInfoUInt.count(name))
193     {
194         *value = mInfoUInt.at(name);
195         return angle::Result::Continue;
196     }
197     ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
198 }
199 
getInfoULong(cl::DeviceInfo name,cl_ulong * value) const200 angle::Result CLDeviceVk::getInfoULong(cl::DeviceInfo name, cl_ulong *value) const
201 {
202     if (mInfoULong.count(name))
203     {
204         *value = mInfoULong.at(name);
205         return angle::Result::Continue;
206     }
207     ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
208 }
209 
getInfoSizeT(cl::DeviceInfo name,size_t * value) const210 angle::Result CLDeviceVk::getInfoSizeT(cl::DeviceInfo name, size_t *value) const
211 {
212     if (mInfoSizeT.count(name))
213     {
214         *value = mInfoSizeT.at(name);
215         return angle::Result::Continue;
216     }
217     ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
218 }
219 
getInfoStringLength(cl::DeviceInfo name,size_t * value) const220 angle::Result CLDeviceVk::getInfoStringLength(cl::DeviceInfo name, size_t *value) const
221 {
222     if (mInfoString.count(name))
223     {
224         *value = mInfoString.at(name).length() + 1;
225         return angle::Result::Continue;
226     }
227     ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
228 }
229 
getInfoString(cl::DeviceInfo name,size_t size,char * value) const230 angle::Result CLDeviceVk::getInfoString(cl::DeviceInfo name, size_t size, char *value) const
231 {
232     if (mInfoString.count(name))
233     {
234         std::strcpy(value, mInfoString.at(name).c_str());
235         return angle::Result::Continue;
236     }
237     ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
238 }
239 
createSubDevices(const cl_device_partition_property * properties,cl_uint numDevices,CreateFuncs & subDevices,cl_uint * numDevicesRet)240 angle::Result CLDeviceVk::createSubDevices(const cl_device_partition_property *properties,
241                                            cl_uint numDevices,
242                                            CreateFuncs &subDevices,
243                                            cl_uint *numDevicesRet)
244 {
245     UNIMPLEMENTED();
246     ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
247 }
248 
selectWorkGroupSize(const cl::NDRange & ndrange) const249 cl::WorkgroupSize CLDeviceVk::selectWorkGroupSize(const cl::NDRange &ndrange) const
250 {
251     // Limit total work-group size to the Vulkan device's limit
252     const VkPhysicalDeviceProperties &props = mRenderer->getPhysicalDeviceProperties();
253     uint32_t maxSize = static_cast<uint32_t>(mInfoSizeT.at(cl::DeviceInfo::MaxWorkGroupSize));
254     maxSize          = std::min(maxSize, 64u);
255 
256     bool keepIncreasing         = false;
257     cl::WorkgroupSize localSize = {1, 1, 1};
258     do
259     {
260         keepIncreasing = false;
261         for (cl_uint i = 0; i < ndrange.workDimensions; i++)
262         {
263             cl::WorkgroupSize newLocalSize = localSize;
264             newLocalSize[i] *= 2;
265 
266             // TODO: Add support for non-uniform WGS
267             // http://anglebug.com/8631
268             if (ndrange.globalWorkSize[i] % newLocalSize[i] == 0 &&
269                 newLocalSize[i] <= props.limits.maxComputeWorkGroupCount[i] &&
270                 newLocalSize[0] * newLocalSize[1] * newLocalSize[2] <= maxSize)
271             {
272                 localSize      = newLocalSize;
273                 keepIncreasing = true;
274             }
275         }
276     } while (keepIncreasing);
277 
278     return localSize;
279 }
280 
281 }  // namespace rx
282