xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/CLKernelVk.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // CLKernelVk.cpp: Implements the class methods for CLKernelVk.
7*8975f5c5SAndroid Build Coastguard Worker 
8*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLContextVk.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLDeviceVk.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLKernelVk.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLProgramVk.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_wrapper.h"
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLContext.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLKernel.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLProgram.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/cl_utils.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "spirv/unified1/NonSemanticClspvReflection.h"
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker namespace rx
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker 
CLKernelVk(const cl::Kernel & kernel,std::string & name,std::string & attributes,CLKernelArguments & args)25*8975f5c5SAndroid Build Coastguard Worker CLKernelVk::CLKernelVk(const cl::Kernel &kernel,
26*8975f5c5SAndroid Build Coastguard Worker                        std::string &name,
27*8975f5c5SAndroid Build Coastguard Worker                        std::string &attributes,
28*8975f5c5SAndroid Build Coastguard Worker                        CLKernelArguments &args)
29*8975f5c5SAndroid Build Coastguard Worker     : CLKernelImpl(kernel),
30*8975f5c5SAndroid Build Coastguard Worker       mProgram(&kernel.getProgram().getImpl<CLProgramVk>()),
31*8975f5c5SAndroid Build Coastguard Worker       mContext(&kernel.getProgram().getContext().getImpl<CLContextVk>()),
32*8975f5c5SAndroid Build Coastguard Worker       mName(name),
33*8975f5c5SAndroid Build Coastguard Worker       mAttributes(attributes),
34*8975f5c5SAndroid Build Coastguard Worker       mArgs(args)
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker     mShaderProgramHelper.setShader(gl::ShaderType::Compute,
37*8975f5c5SAndroid Build Coastguard Worker                                    mKernel.getProgram().getImpl<CLProgramVk>().getShaderModule());
38*8975f5c5SAndroid Build Coastguard Worker }
39*8975f5c5SAndroid Build Coastguard Worker 
~CLKernelVk()40*8975f5c5SAndroid Build Coastguard Worker CLKernelVk::~CLKernelVk()
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     for (auto &dsLayouts : mDescriptorSetLayouts)
43*8975f5c5SAndroid Build Coastguard Worker     {
44*8975f5c5SAndroid Build Coastguard Worker         dsLayouts.reset();
45*8975f5c5SAndroid Build Coastguard Worker     }
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker     mPipelineLayout.reset();
48*8975f5c5SAndroid Build Coastguard Worker     for (auto &pipelineHelper : mComputePipelineCache)
49*8975f5c5SAndroid Build Coastguard Worker     {
50*8975f5c5SAndroid Build Coastguard Worker         pipelineHelper.destroy(mContext->getDevice());
51*8975f5c5SAndroid Build Coastguard Worker     }
52*8975f5c5SAndroid Build Coastguard Worker     mShaderProgramHelper.destroy(mContext->getRenderer());
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker 
init()55*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelVk::init()
56*8975f5c5SAndroid Build Coastguard Worker {
57*8975f5c5SAndroid Build Coastguard Worker     vk::DescriptorSetLayoutDesc &descriptorSetLayoutDesc =
58*8975f5c5SAndroid Build Coastguard Worker         mDescriptorSetLayoutDescs[DescriptorSetIndex::KernelArguments];
59*8975f5c5SAndroid Build Coastguard Worker     VkPushConstantRange pcRange = mProgram->getDeviceProgramData(mName.c_str())->pushConstRange;
60*8975f5c5SAndroid Build Coastguard Worker     for (const auto &arg : getArgs())
61*8975f5c5SAndroid Build Coastguard Worker     {
62*8975f5c5SAndroid Build Coastguard Worker         VkDescriptorType descType = VK_DESCRIPTOR_TYPE_MAX_ENUM;
63*8975f5c5SAndroid Build Coastguard Worker         switch (arg.type)
64*8975f5c5SAndroid Build Coastguard Worker         {
65*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentStorageBuffer:
66*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentPodStorageBuffer:
67*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
68*8975f5c5SAndroid Build Coastguard Worker                 break;
69*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentUniform:
70*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentPodUniform:
71*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentPointerUniform:
72*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
73*8975f5c5SAndroid Build Coastguard Worker                 break;
74*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentPodPushConstant:
75*8975f5c5SAndroid Build Coastguard Worker                 // Get existing push constant range and see if we need to update
76*8975f5c5SAndroid Build Coastguard Worker                 if (arg.pushConstOffset + arg.pushConstantSize > pcRange.offset + pcRange.size)
77*8975f5c5SAndroid Build Coastguard Worker                 {
78*8975f5c5SAndroid Build Coastguard Worker                     pcRange.size = arg.pushConstOffset + arg.pushConstantSize - pcRange.offset;
79*8975f5c5SAndroid Build Coastguard Worker                 }
80*8975f5c5SAndroid Build Coastguard Worker                 continue;
81*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentSampledImage:
82*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
83*8975f5c5SAndroid Build Coastguard Worker                 break;
84*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentStorageImage:
85*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
86*8975f5c5SAndroid Build Coastguard Worker                 break;
87*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentSampler:
88*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_SAMPLER;
89*8975f5c5SAndroid Build Coastguard Worker                 break;
90*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentStorageTexelBuffer:
91*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
92*8975f5c5SAndroid Build Coastguard Worker                 break;
93*8975f5c5SAndroid Build Coastguard Worker             case NonSemanticClspvReflectionArgumentUniformTexelBuffer:
94*8975f5c5SAndroid Build Coastguard Worker                 descType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
95*8975f5c5SAndroid Build Coastguard Worker                 break;
96*8975f5c5SAndroid Build Coastguard Worker             default:
97*8975f5c5SAndroid Build Coastguard Worker                 continue;
98*8975f5c5SAndroid Build Coastguard Worker         }
99*8975f5c5SAndroid Build Coastguard Worker         if (descType != VK_DESCRIPTOR_TYPE_MAX_ENUM)
100*8975f5c5SAndroid Build Coastguard Worker         {
101*8975f5c5SAndroid Build Coastguard Worker             descriptorSetLayoutDesc.addBinding(arg.descriptorBinding, descType, 1,
102*8975f5c5SAndroid Build Coastguard Worker                                                VK_SHADER_STAGE_COMPUTE_BIT, nullptr);
103*8975f5c5SAndroid Build Coastguard Worker         }
104*8975f5c5SAndroid Build Coastguard Worker     }
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker     if (usesPrintf())
107*8975f5c5SAndroid Build Coastguard Worker     {
108*8975f5c5SAndroid Build Coastguard Worker         mDescriptorSetLayoutDescs[DescriptorSetIndex::Printf].addBinding(
109*8975f5c5SAndroid Build Coastguard Worker             mProgram->getDeviceProgramData(mName.c_str())
110*8975f5c5SAndroid Build Coastguard Worker                 ->reflectionData.printfBufferStorage.binding,
111*8975f5c5SAndroid Build Coastguard Worker             VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr);
112*8975f5c5SAndroid Build Coastguard Worker     }
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker     // Get pipeline layout from cache (creates if missed)
115*8975f5c5SAndroid Build Coastguard Worker     // A given kernel need not have resulted in use of all the descriptor sets. Unless the
116*8975f5c5SAndroid Build Coastguard Worker     // graphicsPipelineLibrary extension is supported, the pipeline layout need all the descriptor
117*8975f5c5SAndroid Build Coastguard Worker     // set layouts to be valide. So set them up in the order of their occurrence.
118*8975f5c5SAndroid Build Coastguard Worker     mPipelineLayoutDesc = {};
119*8975f5c5SAndroid Build Coastguard Worker     for (DescriptorSetIndex index : angle::AllEnums<DescriptorSetIndex>())
120*8975f5c5SAndroid Build Coastguard Worker     {
121*8975f5c5SAndroid Build Coastguard Worker         if (!mDescriptorSetLayoutDescs[index].empty())
122*8975f5c5SAndroid Build Coastguard Worker         {
123*8975f5c5SAndroid Build Coastguard Worker             mPipelineLayoutDesc.updateDescriptorSetLayout(index, mDescriptorSetLayoutDescs[index]);
124*8975f5c5SAndroid Build Coastguard Worker         }
125*8975f5c5SAndroid Build Coastguard Worker     }
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     // push constant setup
128*8975f5c5SAndroid Build Coastguard Worker     // push constant size must be multiple of 4
129*8975f5c5SAndroid Build Coastguard Worker     pcRange.size = roundUpPow2(pcRange.size, 4u);
130*8975f5c5SAndroid Build Coastguard Worker     // set the pod arguments data to this size
131*8975f5c5SAndroid Build Coastguard Worker     mPodArgumentsData.resize(pcRange.size);
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker     // push constant offset must be multiple of 4, round down to ensure this
134*8975f5c5SAndroid Build Coastguard Worker     pcRange.offset = roundDownPow2(pcRange.offset, 4u);
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker     mPipelineLayoutDesc.updatePushConstantRange(pcRange.stageFlags, pcRange.offset, pcRange.size);
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker 
setArg(cl_uint argIndex,size_t argSize,const void * argValue)141*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelVk::setArg(cl_uint argIndex, size_t argSize, const void *argValue)
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker     auto &arg = mArgs.at(argIndex);
144*8975f5c5SAndroid Build Coastguard Worker     if (arg.used)
145*8975f5c5SAndroid Build Coastguard Worker     {
146*8975f5c5SAndroid Build Coastguard Worker         arg.handle     = const_cast<void *>(argValue);
147*8975f5c5SAndroid Build Coastguard Worker         arg.handleSize = argSize;
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker         // For POD data, copy the contents as the app is free to delete the contents post this call.
150*8975f5c5SAndroid Build Coastguard Worker         if (arg.type == NonSemanticClspvReflectionArgumentPodPushConstant && argSize > 0 &&
151*8975f5c5SAndroid Build Coastguard Worker             argValue != nullptr)
152*8975f5c5SAndroid Build Coastguard Worker         {
153*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mPodArgumentsData.size() >= arg.pushConstantSize + arg.pushConstOffset);
154*8975f5c5SAndroid Build Coastguard Worker             memcpy(&mPodArgumentsData[arg.pushConstOffset], argValue, argSize);
155*8975f5c5SAndroid Build Coastguard Worker         }
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker         if (arg.type == NonSemanticClspvReflectionArgumentWorkgroup)
158*8975f5c5SAndroid Build Coastguard Worker         {
159*8975f5c5SAndroid Build Coastguard Worker             mSpecConstants.push_back(
160*8975f5c5SAndroid Build Coastguard Worker                 KernelSpecConstant{.ID   = arg.workgroupSpecId,
161*8975f5c5SAndroid Build Coastguard Worker                                    .data = static_cast<uint32_t>(argSize / arg.workgroupSize)});
162*8975f5c5SAndroid Build Coastguard Worker         }
163*8975f5c5SAndroid Build Coastguard Worker     }
164*8975f5c5SAndroid Build Coastguard Worker 
165*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
166*8975f5c5SAndroid Build Coastguard Worker }
167*8975f5c5SAndroid Build Coastguard Worker 
createInfo(CLKernelImpl::Info * info) const168*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelVk::createInfo(CLKernelImpl::Info *info) const
169*8975f5c5SAndroid Build Coastguard Worker {
170*8975f5c5SAndroid Build Coastguard Worker     info->functionName = mName;
171*8975f5c5SAndroid Build Coastguard Worker     info->attributes   = mAttributes;
172*8975f5c5SAndroid Build Coastguard Worker     info->numArgs      = static_cast<cl_uint>(mArgs.size());
173*8975f5c5SAndroid Build Coastguard Worker     for (const auto &arg : mArgs)
174*8975f5c5SAndroid Build Coastguard Worker     {
175*8975f5c5SAndroid Build Coastguard Worker         ArgInfo argInfo;
176*8975f5c5SAndroid Build Coastguard Worker         argInfo.name             = arg.info.name;
177*8975f5c5SAndroid Build Coastguard Worker         argInfo.typeName         = arg.info.typeName;
178*8975f5c5SAndroid Build Coastguard Worker         argInfo.accessQualifier  = arg.info.accessQualifier;
179*8975f5c5SAndroid Build Coastguard Worker         argInfo.addressQualifier = arg.info.addressQualifier;
180*8975f5c5SAndroid Build Coastguard Worker         argInfo.typeQualifier    = arg.info.typeQualifier;
181*8975f5c5SAndroid Build Coastguard Worker         info->args.push_back(std::move(argInfo));
182*8975f5c5SAndroid Build Coastguard Worker     }
183*8975f5c5SAndroid Build Coastguard Worker 
184*8975f5c5SAndroid Build Coastguard Worker     auto &ctx = mKernel.getProgram().getContext();
185*8975f5c5SAndroid Build Coastguard Worker     info->workGroups.resize(ctx.getDevices().size());
186*8975f5c5SAndroid Build Coastguard Worker     const CLProgramVk::DeviceProgramData *deviceProgramData = nullptr;
187*8975f5c5SAndroid Build Coastguard Worker     for (auto i = 0u; i < ctx.getDevices().size(); ++i)
188*8975f5c5SAndroid Build Coastguard Worker     {
189*8975f5c5SAndroid Build Coastguard Worker         auto &workGroup     = info->workGroups[i];
190*8975f5c5SAndroid Build Coastguard Worker         const auto deviceVk = &ctx.getDevices()[i]->getImpl<CLDeviceVk>();
191*8975f5c5SAndroid Build Coastguard Worker         deviceProgramData   = mProgram->getDeviceProgramData(ctx.getDevices()[i]->getNative());
192*8975f5c5SAndroid Build Coastguard Worker         if (deviceProgramData == nullptr)
193*8975f5c5SAndroid Build Coastguard Worker         {
194*8975f5c5SAndroid Build Coastguard Worker             continue;
195*8975f5c5SAndroid Build Coastguard Worker         }
196*8975f5c5SAndroid Build Coastguard Worker 
197*8975f5c5SAndroid Build Coastguard Worker         // TODO: http://anglebug.com/42267005
198*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(
199*8975f5c5SAndroid Build Coastguard Worker             deviceVk->getInfoSizeT(cl::DeviceInfo::MaxWorkGroupSize, &workGroup.workGroupSize));
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker         // TODO: http://anglebug.com/42267004
202*8975f5c5SAndroid Build Coastguard Worker         workGroup.privateMemSize = 0;
203*8975f5c5SAndroid Build Coastguard Worker         workGroup.localMemSize   = 0;
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker         workGroup.prefWorkGroupSizeMultiple = 16u;
206*8975f5c5SAndroid Build Coastguard Worker         workGroup.globalWorkSize            = {0, 0, 0};
207*8975f5c5SAndroid Build Coastguard Worker         if (deviceProgramData->reflectionData.kernelCompileWorkgroupSize.contains(mName))
208*8975f5c5SAndroid Build Coastguard Worker         {
209*8975f5c5SAndroid Build Coastguard Worker             workGroup.compileWorkGroupSize = {
210*8975f5c5SAndroid Build Coastguard Worker                 deviceProgramData->reflectionData.kernelCompileWorkgroupSize.at(mName)[0],
211*8975f5c5SAndroid Build Coastguard Worker                 deviceProgramData->reflectionData.kernelCompileWorkgroupSize.at(mName)[1],
212*8975f5c5SAndroid Build Coastguard Worker                 deviceProgramData->reflectionData.kernelCompileWorkgroupSize.at(mName)[2]};
213*8975f5c5SAndroid Build Coastguard Worker         }
214*8975f5c5SAndroid Build Coastguard Worker         else
215*8975f5c5SAndroid Build Coastguard Worker         {
216*8975f5c5SAndroid Build Coastguard Worker             workGroup.compileWorkGroupSize = {0, 0, 0};
217*8975f5c5SAndroid Build Coastguard Worker         }
218*8975f5c5SAndroid Build Coastguard Worker     }
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker 
getOrCreateComputePipeline(vk::PipelineCacheAccess * pipelineCache,const cl::NDRange & ndrange,const cl::Device & device,vk::PipelineHelper ** pipelineOut,cl::WorkgroupCount * workgroupCountOut)223*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelVk::getOrCreateComputePipeline(vk::PipelineCacheAccess *pipelineCache,
224*8975f5c5SAndroid Build Coastguard Worker                                                      const cl::NDRange &ndrange,
225*8975f5c5SAndroid Build Coastguard Worker                                                      const cl::Device &device,
226*8975f5c5SAndroid Build Coastguard Worker                                                      vk::PipelineHelper **pipelineOut,
227*8975f5c5SAndroid Build Coastguard Worker                                                      cl::WorkgroupCount *workgroupCountOut)
228*8975f5c5SAndroid Build Coastguard Worker {
229*8975f5c5SAndroid Build Coastguard Worker     const CLProgramVk::DeviceProgramData *devProgramData =
230*8975f5c5SAndroid Build Coastguard Worker         getProgram()->getDeviceProgramData(device.getNative());
231*8975f5c5SAndroid Build Coastguard Worker     ASSERT(devProgramData != nullptr);
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker     // Start with Workgroup size (WGS) from kernel attribute (if available)
234*8975f5c5SAndroid Build Coastguard Worker     cl::WorkgroupSize workgroupSize = devProgramData->getCompiledWorkgroupSize(getKernelName());
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker     if (workgroupSize == kEmptyWorkgroupSize)
237*8975f5c5SAndroid Build Coastguard Worker     {
238*8975f5c5SAndroid Build Coastguard Worker         if (ndrange.nullLocalWorkSize)
239*8975f5c5SAndroid Build Coastguard Worker         {
240*8975f5c5SAndroid Build Coastguard Worker             // NULL value was passed, in which case the OpenCL implementation will determine
241*8975f5c5SAndroid Build Coastguard Worker             // how to be break the global work-items into appropriate work-group instances.
242*8975f5c5SAndroid Build Coastguard Worker             workgroupSize = device.getImpl<CLDeviceVk>().selectWorkGroupSize(ndrange);
243*8975f5c5SAndroid Build Coastguard Worker         }
244*8975f5c5SAndroid Build Coastguard Worker         else
245*8975f5c5SAndroid Build Coastguard Worker         {
246*8975f5c5SAndroid Build Coastguard Worker             // Local work size (LWS) was valid, use that as WGS
247*8975f5c5SAndroid Build Coastguard Worker             workgroupSize = ndrange.localWorkSize;
248*8975f5c5SAndroid Build Coastguard Worker         }
249*8975f5c5SAndroid Build Coastguard Worker     }
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker     // Calculate the workgroup count
252*8975f5c5SAndroid Build Coastguard Worker     // TODO: Add support for non-uniform WGS
253*8975f5c5SAndroid Build Coastguard Worker     // http://angleproject:8631
254*8975f5c5SAndroid Build Coastguard Worker     ASSERT(workgroupSize[0] != 0);
255*8975f5c5SAndroid Build Coastguard Worker     ASSERT(workgroupSize[1] != 0);
256*8975f5c5SAndroid Build Coastguard Worker     ASSERT(workgroupSize[2] != 0);
257*8975f5c5SAndroid Build Coastguard Worker     (*workgroupCountOut)[0] = static_cast<uint32_t>((ndrange.globalWorkSize[0] / workgroupSize[0]));
258*8975f5c5SAndroid Build Coastguard Worker     (*workgroupCountOut)[1] = static_cast<uint32_t>((ndrange.globalWorkSize[1] / workgroupSize[1]));
259*8975f5c5SAndroid Build Coastguard Worker     (*workgroupCountOut)[2] = static_cast<uint32_t>((ndrange.globalWorkSize[2] / workgroupSize[2]));
260*8975f5c5SAndroid Build Coastguard Worker 
261*8975f5c5SAndroid Build Coastguard Worker     // Populate program specialization constants (if any)
262*8975f5c5SAndroid Build Coastguard Worker     uint32_t constantDataOffset = 0;
263*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint32_t> specConstantData;
264*8975f5c5SAndroid Build Coastguard Worker     std::vector<VkSpecializationMapEntry> mapEntries;
265*8975f5c5SAndroid Build Coastguard Worker     for (const auto specConstantUsed : devProgramData->reflectionData.specConstantsUsed)
266*8975f5c5SAndroid Build Coastguard Worker     {
267*8975f5c5SAndroid Build Coastguard Worker         switch (specConstantUsed)
268*8975f5c5SAndroid Build Coastguard Worker         {
269*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::WorkDimension:
270*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(ndrange.workDimensions);
271*8975f5c5SAndroid Build Coastguard Worker                 break;
272*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::WorkgroupSizeX:
273*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(static_cast<uint32_t>(workgroupSize[0]));
274*8975f5c5SAndroid Build Coastguard Worker                 break;
275*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::WorkgroupSizeY:
276*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(static_cast<uint32_t>(workgroupSize[1]));
277*8975f5c5SAndroid Build Coastguard Worker                 break;
278*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::WorkgroupSizeZ:
279*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(static_cast<uint32_t>(workgroupSize[2]));
280*8975f5c5SAndroid Build Coastguard Worker                 break;
281*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::GlobalOffsetX:
282*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(static_cast<uint32_t>(ndrange.globalWorkOffset[0]));
283*8975f5c5SAndroid Build Coastguard Worker                 break;
284*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::GlobalOffsetY:
285*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(static_cast<uint32_t>(ndrange.globalWorkOffset[1]));
286*8975f5c5SAndroid Build Coastguard Worker                 break;
287*8975f5c5SAndroid Build Coastguard Worker             case SpecConstantType::GlobalOffsetZ:
288*8975f5c5SAndroid Build Coastguard Worker                 specConstantData.push_back(static_cast<uint32_t>(ndrange.globalWorkOffset[2]));
289*8975f5c5SAndroid Build Coastguard Worker                 break;
290*8975f5c5SAndroid Build Coastguard Worker             default:
291*8975f5c5SAndroid Build Coastguard Worker                 UNIMPLEMENTED();
292*8975f5c5SAndroid Build Coastguard Worker                 continue;
293*8975f5c5SAndroid Build Coastguard Worker         }
294*8975f5c5SAndroid Build Coastguard Worker         mapEntries.push_back(VkSpecializationMapEntry{
295*8975f5c5SAndroid Build Coastguard Worker             .constantID = devProgramData->reflectionData.specConstantIDs[specConstantUsed],
296*8975f5c5SAndroid Build Coastguard Worker             .offset     = constantDataOffset,
297*8975f5c5SAndroid Build Coastguard Worker             .size       = sizeof(uint32_t)});
298*8975f5c5SAndroid Build Coastguard Worker         constantDataOffset += sizeof(uint32_t);
299*8975f5c5SAndroid Build Coastguard Worker     }
300*8975f5c5SAndroid Build Coastguard Worker     // Populate kernel specialization constants (if any)
301*8975f5c5SAndroid Build Coastguard Worker     for (const auto &specConstant : mSpecConstants)
302*8975f5c5SAndroid Build Coastguard Worker     {
303*8975f5c5SAndroid Build Coastguard Worker         specConstantData.push_back(specConstant.data);
304*8975f5c5SAndroid Build Coastguard Worker         mapEntries.push_back(VkSpecializationMapEntry{
305*8975f5c5SAndroid Build Coastguard Worker             .constantID = specConstant.ID, .offset = constantDataOffset, .size = sizeof(uint32_t)});
306*8975f5c5SAndroid Build Coastguard Worker         constantDataOffset += sizeof(uint32_t);
307*8975f5c5SAndroid Build Coastguard Worker     }
308*8975f5c5SAndroid Build Coastguard Worker     VkSpecializationInfo computeSpecializationInfo{
309*8975f5c5SAndroid Build Coastguard Worker         .mapEntryCount = static_cast<uint32_t>(mapEntries.size()),
310*8975f5c5SAndroid Build Coastguard Worker         .pMapEntries   = mapEntries.data(),
311*8975f5c5SAndroid Build Coastguard Worker         .dataSize      = specConstantData.size() * sizeof(uint32_t),
312*8975f5c5SAndroid Build Coastguard Worker         .pData         = specConstantData.data(),
313*8975f5c5SAndroid Build Coastguard Worker     };
314*8975f5c5SAndroid Build Coastguard Worker 
315*8975f5c5SAndroid Build Coastguard Worker     // Now get or create (on compute pipeline cache miss) compute pipeline and return it
316*8975f5c5SAndroid Build Coastguard Worker     return mShaderProgramHelper.getOrCreateComputePipeline(
317*8975f5c5SAndroid Build Coastguard Worker         mContext, &mComputePipelineCache, pipelineCache, getPipelineLayout(),
318*8975f5c5SAndroid Build Coastguard Worker         vk::ComputePipelineOptions{}, PipelineSource::Draw, pipelineOut, mName.c_str(),
319*8975f5c5SAndroid Build Coastguard Worker         &computeSpecializationInfo);
320*8975f5c5SAndroid Build Coastguard Worker }
321*8975f5c5SAndroid Build Coastguard Worker 
usesPrintf() const322*8975f5c5SAndroid Build Coastguard Worker bool CLKernelVk::usesPrintf() const
323*8975f5c5SAndroid Build Coastguard Worker {
324*8975f5c5SAndroid Build Coastguard Worker     return mProgram->getDeviceProgramData(mName.c_str())->getKernelFlags(mName) &
325*8975f5c5SAndroid Build Coastguard Worker            NonSemanticClspvReflectionMayUsePrintf;
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker 
allocateDescriptorSet(DescriptorSetIndex index,angle::EnumIterator<DescriptorSetIndex> layoutIndex,vk::OutsideRenderPassCommandBufferHelper * computePassCommands)328*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelVk::allocateDescriptorSet(
329*8975f5c5SAndroid Build Coastguard Worker     DescriptorSetIndex index,
330*8975f5c5SAndroid Build Coastguard Worker     angle::EnumIterator<DescriptorSetIndex> layoutIndex,
331*8975f5c5SAndroid Build Coastguard Worker     vk::OutsideRenderPassCommandBufferHelper *computePassCommands)
332*8975f5c5SAndroid Build Coastguard Worker {
333*8975f5c5SAndroid Build Coastguard Worker     return mProgram->allocateDescriptorSet(index, *mDescriptorSetLayouts[*layoutIndex],
334*8975f5c5SAndroid Build Coastguard Worker                                            computePassCommands, &mDescriptorSets[index]);
335*8975f5c5SAndroid Build Coastguard Worker }
336*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
337