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