xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/CLProgramVk.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 // CLProgramVk.cpp: Implements the class methods for CLProgramVk.
7*8975f5c5SAndroid Build Coastguard Worker 
8*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLProgramVk.h"
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLContextVk.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/CLDeviceVk.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/clspv_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_helpers.h"
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLContext.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLKernel.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLProgram.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/cl_utils.h"
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker #include "common/log_utils.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
23*8975f5c5SAndroid Build Coastguard Worker 
24*8975f5c5SAndroid Build Coastguard Worker #include "clspv/Compiler.h"
25*8975f5c5SAndroid Build Coastguard Worker 
26*8975f5c5SAndroid Build Coastguard Worker #include "spirv/unified1/NonSemanticClspvReflection.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "spirv/unified1/spirv.hpp"
28*8975f5c5SAndroid Build Coastguard Worker 
29*8975f5c5SAndroid Build Coastguard Worker #include "spirv-tools/libspirv.hpp"
30*8975f5c5SAndroid Build Coastguard Worker #include "spirv-tools/optimizer.hpp"
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker namespace rx
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker namespace
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
38*8975f5c5SAndroid Build Coastguard Worker constexpr bool kAngleDebug = true;
39*8975f5c5SAndroid Build Coastguard Worker #else
40*8975f5c5SAndroid Build Coastguard Worker constexpr bool kAngleDebug = false;
41*8975f5c5SAndroid Build Coastguard Worker #endif
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker // Used by SPIRV-Tools to parse reflection info
ParseReflection(CLProgramVk::SpvReflectionData & reflectionData,const spv_parsed_instruction_t & spvInstr)44*8975f5c5SAndroid Build Coastguard Worker spv_result_t ParseReflection(CLProgramVk::SpvReflectionData &reflectionData,
45*8975f5c5SAndroid Build Coastguard Worker                              const spv_parsed_instruction_t &spvInstr)
46*8975f5c5SAndroid Build Coastguard Worker {
47*8975f5c5SAndroid Build Coastguard Worker     // Parse spir-v opcodes
48*8975f5c5SAndroid Build Coastguard Worker     switch (spvInstr.opcode)
49*8975f5c5SAndroid Build Coastguard Worker     {
50*8975f5c5SAndroid Build Coastguard Worker         // --- Clspv specific parsing for below cases ---
51*8975f5c5SAndroid Build Coastguard Worker         case spv::OpExtInst:
52*8975f5c5SAndroid Build Coastguard Worker         {
53*8975f5c5SAndroid Build Coastguard Worker             switch (spvInstr.words[4])
54*8975f5c5SAndroid Build Coastguard Worker             {
55*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionKernel:
56*8975f5c5SAndroid Build Coastguard Worker                 {
57*8975f5c5SAndroid Build Coastguard Worker                     // Extract kernel name and args - add to kernel args map
58*8975f5c5SAndroid Build Coastguard Worker                     std::string functionName = reflectionData.spvStrLookup[spvInstr.words[6]];
59*8975f5c5SAndroid Build Coastguard Worker                     uint32_t numArgs         = reflectionData.spvIntLookup[spvInstr.words[7]];
60*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelArgsMap[functionName] = CLKernelArguments();
61*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelArgsMap[functionName].resize(numArgs);
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker                     // Store kernel flags and attributes
64*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelFlags[functionName] =
65*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[8]];
66*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelAttributes[functionName] =
67*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvStrLookup[spvInstr.words[9]];
68*8975f5c5SAndroid Build Coastguard Worker 
69*8975f5c5SAndroid Build Coastguard Worker                     // Save kernel name to reflection table for later use/lookup in parser routine
70*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelIDs.insert(spvInstr.words[2]);
71*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.spvStrLookup[spvInstr.words[2]] = std::string(functionName);
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker                     // If we already parsed some args ahead of time, populate them now
74*8975f5c5SAndroid Build Coastguard Worker                     if (reflectionData.kernelArgMap.contains(functionName))
75*8975f5c5SAndroid Build Coastguard Worker                     {
76*8975f5c5SAndroid Build Coastguard Worker                         for (const auto &arg : reflectionData.kernelArgMap)
77*8975f5c5SAndroid Build Coastguard Worker                         {
78*8975f5c5SAndroid Build Coastguard Worker                             uint32_t ordinal = arg.second.ordinal;
79*8975f5c5SAndroid Build Coastguard Worker                             reflectionData.kernelArgsMap[functionName].at(ordinal) =
80*8975f5c5SAndroid Build Coastguard Worker                                 std::move(arg.second);
81*8975f5c5SAndroid Build Coastguard Worker                         }
82*8975f5c5SAndroid Build Coastguard Worker                     }
83*8975f5c5SAndroid Build Coastguard Worker                     break;
84*8975f5c5SAndroid Build Coastguard Worker                 }
85*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentInfo:
86*8975f5c5SAndroid Build Coastguard Worker                 {
87*8975f5c5SAndroid Build Coastguard Worker                     CLKernelVk::ArgInfo kernelArgInfo;
88*8975f5c5SAndroid Build Coastguard Worker                     kernelArgInfo.name = reflectionData.spvStrLookup[spvInstr.words[5]];
89*8975f5c5SAndroid Build Coastguard Worker                     // If instruction has more than 5 instruction operands (minus instruction
90*8975f5c5SAndroid Build Coastguard Worker                     // name/opcode), that means we have arg qualifiers. ArgumentInfo also counts as
91*8975f5c5SAndroid Build Coastguard Worker                     // an operand for OpExtInst. In below example, [ %e %f %g %h ] are the arg
92*8975f5c5SAndroid Build Coastguard Worker                     // qualifier operands.
93*8975f5c5SAndroid Build Coastguard Worker                     //
94*8975f5c5SAndroid Build Coastguard Worker                     // %a = OpExtInst %b %c ArgumentInfo %d [ %e %f %g %h ]
95*8975f5c5SAndroid Build Coastguard Worker                     if (spvInstr.num_operands > 5)
96*8975f5c5SAndroid Build Coastguard Worker                     {
97*8975f5c5SAndroid Build Coastguard Worker                         kernelArgInfo.typeName = reflectionData.spvStrLookup[spvInstr.words[6]];
98*8975f5c5SAndroid Build Coastguard Worker                         kernelArgInfo.addressQualifier =
99*8975f5c5SAndroid Build Coastguard Worker                             reflectionData.spvIntLookup[spvInstr.words[7]];
100*8975f5c5SAndroid Build Coastguard Worker                         kernelArgInfo.accessQualifier =
101*8975f5c5SAndroid Build Coastguard Worker                             reflectionData.spvIntLookup[spvInstr.words[8]];
102*8975f5c5SAndroid Build Coastguard Worker                         kernelArgInfo.typeQualifier =
103*8975f5c5SAndroid Build Coastguard Worker                             reflectionData.spvIntLookup[spvInstr.words[9]];
104*8975f5c5SAndroid Build Coastguard Worker                     }
105*8975f5c5SAndroid Build Coastguard Worker                     // Store kern arg for later lookup
106*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelArgInfos[spvInstr.words[2]] = std::move(kernelArgInfo);
107*8975f5c5SAndroid Build Coastguard Worker                     break;
108*8975f5c5SAndroid Build Coastguard Worker                 }
109*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentPodUniform:
110*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentPointerUniform:
111*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentPodStorageBuffer:
112*8975f5c5SAndroid Build Coastguard Worker                 {
113*8975f5c5SAndroid Build Coastguard Worker                     CLKernelArgument kernelArg;
114*8975f5c5SAndroid Build Coastguard Worker                     if (spvInstr.num_operands == 11)
115*8975f5c5SAndroid Build Coastguard Worker                     {
116*8975f5c5SAndroid Build Coastguard Worker                         const CLKernelVk::ArgInfo &kernelArgInfo =
117*8975f5c5SAndroid Build Coastguard Worker                             reflectionData.kernelArgInfos[spvInstr.words[11]];
118*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.name             = kernelArgInfo.name;
119*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.typeName         = kernelArgInfo.typeName;
120*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.addressQualifier = kernelArgInfo.addressQualifier;
121*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.accessQualifier  = kernelArgInfo.accessQualifier;
122*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.typeQualifier    = kernelArgInfo.typeQualifier;
123*8975f5c5SAndroid Build Coastguard Worker                     }
124*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.type    = spvInstr.words[4];
125*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.used    = true;
126*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.ordinal = reflectionData.spvIntLookup[spvInstr.words[6]];
127*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.op3     = reflectionData.spvIntLookup[spvInstr.words[7]];
128*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.op4     = reflectionData.spvIntLookup[spvInstr.words[8]];
129*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.op5     = reflectionData.spvIntLookup[spvInstr.words[9]];
130*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.op6     = reflectionData.spvIntLookup[spvInstr.words[10]];
131*8975f5c5SAndroid Build Coastguard Worker 
132*8975f5c5SAndroid Build Coastguard Worker                     if (reflectionData.kernelIDs.contains(spvInstr.words[5]))
133*8975f5c5SAndroid Build Coastguard Worker                     {
134*8975f5c5SAndroid Build Coastguard Worker                         CLKernelArguments &kernelArgs =
135*8975f5c5SAndroid Build Coastguard Worker                             reflectionData
136*8975f5c5SAndroid Build Coastguard Worker                                 .kernelArgsMap[reflectionData.spvStrLookup[spvInstr.words[5]]];
137*8975f5c5SAndroid Build Coastguard Worker                         kernelArgs.at(kernelArg.ordinal) = std::move(kernelArg);
138*8975f5c5SAndroid Build Coastguard Worker                     }
139*8975f5c5SAndroid Build Coastguard Worker                     else
140*8975f5c5SAndroid Build Coastguard Worker                     {
141*8975f5c5SAndroid Build Coastguard Worker                         // Reflection kernel not yet parsed, place in temp storage for now
142*8975f5c5SAndroid Build Coastguard Worker                         reflectionData
143*8975f5c5SAndroid Build Coastguard Worker                             .kernelArgMap[reflectionData.spvStrLookup[spvInstr.words[5]]] =
144*8975f5c5SAndroid Build Coastguard Worker                             std::move(kernelArg);
145*8975f5c5SAndroid Build Coastguard Worker                     }
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker                     break;
148*8975f5c5SAndroid Build Coastguard Worker                 }
149*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentUniform:
150*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentWorkgroup:
151*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentSampler:
152*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentStorageImage:
153*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentSampledImage:
154*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentStorageBuffer:
155*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentStorageTexelBuffer:
156*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentUniformTexelBuffer:
157*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentPodPushConstant:
158*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionArgumentPointerPushConstant:
159*8975f5c5SAndroid Build Coastguard Worker                 {
160*8975f5c5SAndroid Build Coastguard Worker                     CLKernelArgument kernelArg;
161*8975f5c5SAndroid Build Coastguard Worker                     if (spvInstr.num_operands == 9)
162*8975f5c5SAndroid Build Coastguard Worker                     {
163*8975f5c5SAndroid Build Coastguard Worker                         const CLKernelVk::ArgInfo &kernelArgInfo =
164*8975f5c5SAndroid Build Coastguard Worker                             reflectionData.kernelArgInfos[spvInstr.words[9]];
165*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.name             = kernelArgInfo.name;
166*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.typeName         = kernelArgInfo.typeName;
167*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.addressQualifier = kernelArgInfo.addressQualifier;
168*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.accessQualifier  = kernelArgInfo.accessQualifier;
169*8975f5c5SAndroid Build Coastguard Worker                         kernelArg.info.typeQualifier    = kernelArgInfo.typeQualifier;
170*8975f5c5SAndroid Build Coastguard Worker                     }
171*8975f5c5SAndroid Build Coastguard Worker 
172*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.type    = spvInstr.words[4];
173*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.used    = true;
174*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.ordinal = reflectionData.spvIntLookup[spvInstr.words[6]];
175*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.op3     = reflectionData.spvIntLookup[spvInstr.words[7]];
176*8975f5c5SAndroid Build Coastguard Worker                     kernelArg.op4     = reflectionData.spvIntLookup[spvInstr.words[8]];
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker                     if (reflectionData.kernelIDs.contains(spvInstr.words[5]))
179*8975f5c5SAndroid Build Coastguard Worker                     {
180*8975f5c5SAndroid Build Coastguard Worker                         CLKernelArguments &kernelArgs =
181*8975f5c5SAndroid Build Coastguard Worker                             reflectionData
182*8975f5c5SAndroid Build Coastguard Worker                                 .kernelArgsMap[reflectionData.spvStrLookup[spvInstr.words[5]]];
183*8975f5c5SAndroid Build Coastguard Worker                         kernelArgs.at(kernelArg.ordinal) = std::move(kernelArg);
184*8975f5c5SAndroid Build Coastguard Worker                     }
185*8975f5c5SAndroid Build Coastguard Worker                     else
186*8975f5c5SAndroid Build Coastguard Worker                     {
187*8975f5c5SAndroid Build Coastguard Worker                         // Reflection kernel not yet parsed, place in temp storage for now
188*8975f5c5SAndroid Build Coastguard Worker                         reflectionData
189*8975f5c5SAndroid Build Coastguard Worker                             .kernelArgMap[reflectionData.spvStrLookup[spvInstr.words[5]]] =
190*8975f5c5SAndroid Build Coastguard Worker                             std::move(kernelArg);
191*8975f5c5SAndroid Build Coastguard Worker                     }
192*8975f5c5SAndroid Build Coastguard Worker                     break;
193*8975f5c5SAndroid Build Coastguard Worker                 }
194*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPushConstantGlobalSize:
195*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPushConstantGlobalOffset:
196*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPushConstantRegionOffset:
197*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPushConstantNumWorkgroups:
198*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPushConstantRegionGroupOffset:
199*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize:
200*8975f5c5SAndroid Build Coastguard Worker                 {
201*8975f5c5SAndroid Build Coastguard Worker                     uint32_t offset = reflectionData.spvIntLookup[spvInstr.words[5]];
202*8975f5c5SAndroid Build Coastguard Worker                     uint32_t size   = reflectionData.spvIntLookup[spvInstr.words[6]];
203*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.pushConstants[spvInstr.words[4]] = {
204*8975f5c5SAndroid Build Coastguard Worker                         .stageFlags = 0, .offset = offset, .size = size};
205*8975f5c5SAndroid Build Coastguard Worker                     break;
206*8975f5c5SAndroid Build Coastguard Worker                 }
207*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionSpecConstantWorkgroupSize:
208*8975f5c5SAndroid Build Coastguard Worker                 {
209*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::WorkgroupSizeX] =
210*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[5]];
211*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::WorkgroupSizeY] =
212*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[6]];
213*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::WorkgroupSizeZ] =
214*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[7]];
215*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::WorkgroupSizeX] = true;
216*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::WorkgroupSizeY] = true;
217*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::WorkgroupSizeZ] = true;
218*8975f5c5SAndroid Build Coastguard Worker                     break;
219*8975f5c5SAndroid Build Coastguard Worker                 }
220*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize:
221*8975f5c5SAndroid Build Coastguard Worker                 {
222*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.kernelCompileWorkgroupSize
223*8975f5c5SAndroid Build Coastguard Worker                         [reflectionData.spvStrLookup[spvInstr.words[5]]] = {
224*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[6]],
225*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[7]],
226*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[8]]};
227*8975f5c5SAndroid Build Coastguard Worker                     break;
228*8975f5c5SAndroid Build Coastguard Worker                 }
229*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionSpecConstantWorkDim:
230*8975f5c5SAndroid Build Coastguard Worker                 {
231*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::WorkDimension] =
232*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[5]];
233*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::WorkDimension] = true;
234*8975f5c5SAndroid Build Coastguard Worker                     break;
235*8975f5c5SAndroid Build Coastguard Worker                 }
236*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionSpecConstantGlobalOffset:
237*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::GlobalOffsetX] =
238*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[5]];
239*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::GlobalOffsetY] =
240*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[6]];
241*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantIDs[SpecConstantType::GlobalOffsetZ] =
242*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.spvIntLookup[spvInstr.words[7]];
243*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::GlobalOffsetX] = true;
244*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::GlobalOffsetY] = true;
245*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.specConstantsUsed[SpecConstantType::GlobalOffsetZ] = true;
246*8975f5c5SAndroid Build Coastguard Worker                     break;
247*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPrintfInfo:
248*8975f5c5SAndroid Build Coastguard Worker                 {
249*8975f5c5SAndroid Build Coastguard Worker                     // Info on the format string used in the builtin printf call in kernel
250*8975f5c5SAndroid Build Coastguard Worker                     uint32_t printfID        = reflectionData.spvIntLookup[spvInstr.words[5]];
251*8975f5c5SAndroid Build Coastguard Worker                     std::string formatString = reflectionData.spvStrLookup[spvInstr.words[6]];
252*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.printfInfoMap[printfID].id              = printfID;
253*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.printfInfoMap[printfID].formatSpecifier = formatString;
254*8975f5c5SAndroid Build Coastguard Worker                     for (int i = 6; i < spvInstr.num_operands; i++)
255*8975f5c5SAndroid Build Coastguard Worker                     {
256*8975f5c5SAndroid Build Coastguard Worker                         uint16_t offset = spvInstr.operands[i].offset;
257*8975f5c5SAndroid Build Coastguard Worker                         size_t size     = reflectionData.spvIntLookup[spvInstr.words[offset]];
258*8975f5c5SAndroid Build Coastguard Worker                         reflectionData.printfInfoMap[printfID].argSizes.push_back(
259*8975f5c5SAndroid Build Coastguard Worker                             static_cast<uint32_t>(size));
260*8975f5c5SAndroid Build Coastguard Worker                     }
261*8975f5c5SAndroid Build Coastguard Worker 
262*8975f5c5SAndroid Build Coastguard Worker                     break;
263*8975f5c5SAndroid Build Coastguard Worker                 }
264*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPrintfBufferStorageBuffer:
265*8975f5c5SAndroid Build Coastguard Worker                 {
266*8975f5c5SAndroid Build Coastguard Worker                     // Info about the printf storage buffer that contains the formatted content
267*8975f5c5SAndroid Build Coastguard Worker                     uint32_t set     = reflectionData.spvIntLookup[spvInstr.words[5]];
268*8975f5c5SAndroid Build Coastguard Worker                     uint32_t binding = reflectionData.spvIntLookup[spvInstr.words[6]];
269*8975f5c5SAndroid Build Coastguard Worker                     uint32_t size    = reflectionData.spvIntLookup[spvInstr.words[7]];
270*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.printfBufferStorage = {set, binding, 0, size};
271*8975f5c5SAndroid Build Coastguard Worker                     break;
272*8975f5c5SAndroid Build Coastguard Worker                 }
273*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionPrintfBufferPointerPushConstant:
274*8975f5c5SAndroid Build Coastguard Worker                 {
275*8975f5c5SAndroid Build Coastguard Worker                     ERR() << "Shouldn't be here. Support of printf builtin function is enabled "
276*8975f5c5SAndroid Build Coastguard Worker                              "through "
277*8975f5c5SAndroid Build Coastguard Worker                              "PrintfBufferStorageBuffer. Check optins passed down to clspv";
278*8975f5c5SAndroid Build Coastguard Worker                     UNREACHABLE();
279*8975f5c5SAndroid Build Coastguard Worker                     return SPV_UNSUPPORTED;
280*8975f5c5SAndroid Build Coastguard Worker                 }
281*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionNormalizedSamplerMaskPushConstant:
282*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant:
283*8975f5c5SAndroid Build Coastguard Worker                 case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant:
284*8975f5c5SAndroid Build Coastguard Worker                 {
285*8975f5c5SAndroid Build Coastguard Worker                     uint32_t ordinal            = reflectionData.spvIntLookup[spvInstr.words[6]];
286*8975f5c5SAndroid Build Coastguard Worker                     uint32_t offset             = reflectionData.spvIntLookup[spvInstr.words[7]];
287*8975f5c5SAndroid Build Coastguard Worker                     uint32_t size               = reflectionData.spvIntLookup[spvInstr.words[8]];
288*8975f5c5SAndroid Build Coastguard Worker                     VkPushConstantRange pcRange = {.stageFlags = 0, .offset = offset, .size = size};
289*8975f5c5SAndroid Build Coastguard Worker                     reflectionData.imagePushConstants[spvInstr.words[4]].push_back(
290*8975f5c5SAndroid Build Coastguard Worker                         {.pcRange = pcRange, .ordinal = ordinal});
291*8975f5c5SAndroid Build Coastguard Worker                     break;
292*8975f5c5SAndroid Build Coastguard Worker                 }
293*8975f5c5SAndroid Build Coastguard Worker                 default:
294*8975f5c5SAndroid Build Coastguard Worker                     break;
295*8975f5c5SAndroid Build Coastguard Worker             }
296*8975f5c5SAndroid Build Coastguard Worker             break;
297*8975f5c5SAndroid Build Coastguard Worker         }
298*8975f5c5SAndroid Build Coastguard Worker         // --- Regular SPIR-V opcode parsing for below cases ---
299*8975f5c5SAndroid Build Coastguard Worker         case spv::OpString:
300*8975f5c5SAndroid Build Coastguard Worker         {
301*8975f5c5SAndroid Build Coastguard Worker             reflectionData.spvStrLookup[spvInstr.words[1]] =
302*8975f5c5SAndroid Build Coastguard Worker                 reinterpret_cast<const char *>(&spvInstr.words[2]);
303*8975f5c5SAndroid Build Coastguard Worker             break;
304*8975f5c5SAndroid Build Coastguard Worker         }
305*8975f5c5SAndroid Build Coastguard Worker         case spv::OpConstant:
306*8975f5c5SAndroid Build Coastguard Worker         {
307*8975f5c5SAndroid Build Coastguard Worker             reflectionData.spvIntLookup[spvInstr.words[2]] = spvInstr.words[3];
308*8975f5c5SAndroid Build Coastguard Worker             break;
309*8975f5c5SAndroid Build Coastguard Worker         }
310*8975f5c5SAndroid Build Coastguard Worker         default:
311*8975f5c5SAndroid Build Coastguard Worker             break;
312*8975f5c5SAndroid Build Coastguard Worker     }
313*8975f5c5SAndroid Build Coastguard Worker     return SPV_SUCCESS;
314*8975f5c5SAndroid Build Coastguard Worker }
315*8975f5c5SAndroid Build Coastguard Worker 
ProcessBuildOptions(const std::vector<std::string> & optionTokens,CLProgramVk::BuildType buildType)316*8975f5c5SAndroid Build Coastguard Worker std::string ProcessBuildOptions(const std::vector<std::string> &optionTokens,
317*8975f5c5SAndroid Build Coastguard Worker                                 CLProgramVk::BuildType buildType)
318*8975f5c5SAndroid Build Coastguard Worker {
319*8975f5c5SAndroid Build Coastguard Worker     std::string processedOptions;
320*8975f5c5SAndroid Build Coastguard Worker 
321*8975f5c5SAndroid Build Coastguard Worker     // Need to remove/replace options that are not 1-1 mapped to clspv
322*8975f5c5SAndroid Build Coastguard Worker     for (const std::string &optionToken : optionTokens)
323*8975f5c5SAndroid Build Coastguard Worker     {
324*8975f5c5SAndroid Build Coastguard Worker         if (optionToken == "-create-library" && buildType == CLProgramVk::BuildType::LINK)
325*8975f5c5SAndroid Build Coastguard Worker         {
326*8975f5c5SAndroid Build Coastguard Worker             processedOptions += " --output-format=bc";
327*8975f5c5SAndroid Build Coastguard Worker             continue;
328*8975f5c5SAndroid Build Coastguard Worker         }
329*8975f5c5SAndroid Build Coastguard Worker         processedOptions += " " + optionToken;
330*8975f5c5SAndroid Build Coastguard Worker     }
331*8975f5c5SAndroid Build Coastguard Worker 
332*8975f5c5SAndroid Build Coastguard Worker     switch (buildType)
333*8975f5c5SAndroid Build Coastguard Worker     {
334*8975f5c5SAndroid Build Coastguard Worker         case CLProgramVk::BuildType::COMPILE:
335*8975f5c5SAndroid Build Coastguard Worker             processedOptions += " --output-format=bc";
336*8975f5c5SAndroid Build Coastguard Worker             break;
337*8975f5c5SAndroid Build Coastguard Worker         case CLProgramVk::BuildType::LINK:
338*8975f5c5SAndroid Build Coastguard Worker             processedOptions += " -x ir";
339*8975f5c5SAndroid Build Coastguard Worker             break;
340*8975f5c5SAndroid Build Coastguard Worker         default:
341*8975f5c5SAndroid Build Coastguard Worker             break;
342*8975f5c5SAndroid Build Coastguard Worker     }
343*8975f5c5SAndroid Build Coastguard Worker 
344*8975f5c5SAndroid Build Coastguard Worker     return processedOptions;
345*8975f5c5SAndroid Build Coastguard Worker }
346*8975f5c5SAndroid Build Coastguard Worker 
347*8975f5c5SAndroid Build Coastguard Worker }  // namespace
348*8975f5c5SAndroid Build Coastguard Worker 
operator ()()349*8975f5c5SAndroid Build Coastguard Worker void CLAsyncBuildTask::operator()()
350*8975f5c5SAndroid Build Coastguard Worker {
351*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRACE_EVENT0("gpu.angle", "CLProgramVk::buildInternal (async)");
352*8975f5c5SAndroid Build Coastguard Worker     CLProgramVk::ScopedProgramCallback spc(mNotify);
353*8975f5c5SAndroid Build Coastguard Worker     if (!mProgramVk->buildInternal(mDevices, mOptions, mInternalOptions, mBuildType,
354*8975f5c5SAndroid Build Coastguard Worker                                    mLinkProgramsList))
355*8975f5c5SAndroid Build Coastguard Worker     {
356*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Async build failed for program (" << mProgramVk
357*8975f5c5SAndroid Build Coastguard Worker               << ")! Check the build status or build log for details.";
358*8975f5c5SAndroid Build Coastguard Worker     }
359*8975f5c5SAndroid Build Coastguard Worker }
360*8975f5c5SAndroid Build Coastguard Worker 
CLProgramVk(const cl::Program & program)361*8975f5c5SAndroid Build Coastguard Worker CLProgramVk::CLProgramVk(const cl::Program &program)
362*8975f5c5SAndroid Build Coastguard Worker     : CLProgramImpl(program),
363*8975f5c5SAndroid Build Coastguard Worker       mContext(&program.getContext().getImpl<CLContextVk>()),
364*8975f5c5SAndroid Build Coastguard Worker       mAsyncBuildEvent(std::make_shared<angle::WaitableEventDone>())
365*8975f5c5SAndroid Build Coastguard Worker {}
366*8975f5c5SAndroid Build Coastguard Worker 
init()367*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::init()
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker     cl::DevicePtrs devices;
370*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mContext->getDevices(&devices));
371*8975f5c5SAndroid Build Coastguard Worker 
372*8975f5c5SAndroid Build Coastguard Worker     // The devices associated with the program object are the devices associated with context
373*8975f5c5SAndroid Build Coastguard Worker     for (const cl::DevicePtr &device : devices)
374*8975f5c5SAndroid Build Coastguard Worker     {
375*8975f5c5SAndroid Build Coastguard Worker         mAssociatedDevicePrograms[device->getNative()] = DeviceProgramData{};
376*8975f5c5SAndroid Build Coastguard Worker     }
377*8975f5c5SAndroid Build Coastguard Worker 
378*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
379*8975f5c5SAndroid Build Coastguard Worker }
380*8975f5c5SAndroid Build Coastguard Worker 
init(const size_t * lengths,const unsigned char ** binaries,cl_int * binaryStatus)381*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::init(const size_t *lengths,
382*8975f5c5SAndroid Build Coastguard Worker                                 const unsigned char **binaries,
383*8975f5c5SAndroid Build Coastguard Worker                                 cl_int *binaryStatus)
384*8975f5c5SAndroid Build Coastguard Worker {
385*8975f5c5SAndroid Build Coastguard Worker     // The devices associated with program come from device_list param from
386*8975f5c5SAndroid Build Coastguard Worker     // clCreateProgramWithBinary
387*8975f5c5SAndroid Build Coastguard Worker     for (const cl::DevicePtr &device : mProgram.getDevices())
388*8975f5c5SAndroid Build Coastguard Worker     {
389*8975f5c5SAndroid Build Coastguard Worker         const unsigned char *binaryHandle = *binaries++;
390*8975f5c5SAndroid Build Coastguard Worker         size_t binarySize                 = *lengths++;
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker         // Check for header
393*8975f5c5SAndroid Build Coastguard Worker         if (binarySize < sizeof(ProgramBinaryOutputHeader))
394*8975f5c5SAndroid Build Coastguard Worker         {
395*8975f5c5SAndroid Build Coastguard Worker             if (binaryStatus)
396*8975f5c5SAndroid Build Coastguard Worker             {
397*8975f5c5SAndroid Build Coastguard Worker                 *binaryStatus++ = CL_INVALID_BINARY;
398*8975f5c5SAndroid Build Coastguard Worker             }
399*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_INVALID_BINARY);
400*8975f5c5SAndroid Build Coastguard Worker         }
401*8975f5c5SAndroid Build Coastguard Worker         binarySize -= sizeof(ProgramBinaryOutputHeader);
402*8975f5c5SAndroid Build Coastguard Worker 
403*8975f5c5SAndroid Build Coastguard Worker         // Check for valid binary version from header
404*8975f5c5SAndroid Build Coastguard Worker         const ProgramBinaryOutputHeader *binaryHeader =
405*8975f5c5SAndroid Build Coastguard Worker             reinterpret_cast<const ProgramBinaryOutputHeader *>(binaryHandle);
406*8975f5c5SAndroid Build Coastguard Worker         if (binaryHeader == nullptr)
407*8975f5c5SAndroid Build Coastguard Worker         {
408*8975f5c5SAndroid Build Coastguard Worker             ERR() << "NULL binary header!";
409*8975f5c5SAndroid Build Coastguard Worker             if (binaryStatus)
410*8975f5c5SAndroid Build Coastguard Worker             {
411*8975f5c5SAndroid Build Coastguard Worker                 *binaryStatus++ = CL_INVALID_BINARY;
412*8975f5c5SAndroid Build Coastguard Worker             }
413*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_INVALID_BINARY);
414*8975f5c5SAndroid Build Coastguard Worker         }
415*8975f5c5SAndroid Build Coastguard Worker         else if (binaryHeader->headerVersion < kBinaryVersion)
416*8975f5c5SAndroid Build Coastguard Worker         {
417*8975f5c5SAndroid Build Coastguard Worker             ERR() << "Binary version not compatible with runtime!";
418*8975f5c5SAndroid Build Coastguard Worker             if (binaryStatus)
419*8975f5c5SAndroid Build Coastguard Worker             {
420*8975f5c5SAndroid Build Coastguard Worker                 *binaryStatus++ = CL_INVALID_BINARY;
421*8975f5c5SAndroid Build Coastguard Worker             }
422*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_INVALID_BINARY);
423*8975f5c5SAndroid Build Coastguard Worker         }
424*8975f5c5SAndroid Build Coastguard Worker         binaryHandle += sizeof(ProgramBinaryOutputHeader);
425*8975f5c5SAndroid Build Coastguard Worker 
426*8975f5c5SAndroid Build Coastguard Worker         // See what kind of binary we have (i.e. SPIR-V or LLVM Bitcode)
427*8975f5c5SAndroid Build Coastguard Worker         // https://llvm.org/docs/BitCodeFormat.html#llvm-ir-magic-number
428*8975f5c5SAndroid Build Coastguard Worker         // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_magic_number
429*8975f5c5SAndroid Build Coastguard Worker         constexpr uint32_t LLVM_BC_MAGIC = 0xDEC04342;
430*8975f5c5SAndroid Build Coastguard Worker         constexpr uint32_t SPIRV_MAGIC   = 0x07230203;
431*8975f5c5SAndroid Build Coastguard Worker         const uint32_t &firstWord        = reinterpret_cast<const uint32_t *>(binaryHandle)[0];
432*8975f5c5SAndroid Build Coastguard Worker         bool isBC                        = firstWord == LLVM_BC_MAGIC;
433*8975f5c5SAndroid Build Coastguard Worker         bool isSPV                       = firstWord == SPIRV_MAGIC;
434*8975f5c5SAndroid Build Coastguard Worker         if (!isBC && !isSPV)
435*8975f5c5SAndroid Build Coastguard Worker         {
436*8975f5c5SAndroid Build Coastguard Worker             ERR() << "Binary is neither SPIR-V nor LLVM Bitcode!";
437*8975f5c5SAndroid Build Coastguard Worker             if (binaryStatus)
438*8975f5c5SAndroid Build Coastguard Worker             {
439*8975f5c5SAndroid Build Coastguard Worker                 *binaryStatus++ = CL_INVALID_BINARY;
440*8975f5c5SAndroid Build Coastguard Worker             }
441*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_INVALID_BINARY);
442*8975f5c5SAndroid Build Coastguard Worker         }
443*8975f5c5SAndroid Build Coastguard Worker 
444*8975f5c5SAndroid Build Coastguard Worker         // Add device binary to program
445*8975f5c5SAndroid Build Coastguard Worker         DeviceProgramData deviceBinary;
446*8975f5c5SAndroid Build Coastguard Worker         deviceBinary.binaryType  = binaryHeader->binaryType;
447*8975f5c5SAndroid Build Coastguard Worker         deviceBinary.buildStatus = binaryHeader->buildStatus;
448*8975f5c5SAndroid Build Coastguard Worker         switch (deviceBinary.binaryType)
449*8975f5c5SAndroid Build Coastguard Worker         {
450*8975f5c5SAndroid Build Coastguard Worker             case CL_PROGRAM_BINARY_TYPE_EXECUTABLE:
451*8975f5c5SAndroid Build Coastguard Worker                 deviceBinary.binary.assign(binarySize / sizeof(uint32_t), 0);
452*8975f5c5SAndroid Build Coastguard Worker                 std::memcpy(deviceBinary.binary.data(), binaryHandle, binarySize);
453*8975f5c5SAndroid Build Coastguard Worker                 break;
454*8975f5c5SAndroid Build Coastguard Worker             case CL_PROGRAM_BINARY_TYPE_LIBRARY:
455*8975f5c5SAndroid Build Coastguard Worker             case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT:
456*8975f5c5SAndroid Build Coastguard Worker                 deviceBinary.IR.assign(binarySize, 0);
457*8975f5c5SAndroid Build Coastguard Worker                 std::memcpy(deviceBinary.IR.data(), binaryHandle, binarySize);
458*8975f5c5SAndroid Build Coastguard Worker                 break;
459*8975f5c5SAndroid Build Coastguard Worker             default:
460*8975f5c5SAndroid Build Coastguard Worker                 UNREACHABLE();
461*8975f5c5SAndroid Build Coastguard Worker                 ERR() << "Invalid binary type!";
462*8975f5c5SAndroid Build Coastguard Worker                 if (binaryStatus)
463*8975f5c5SAndroid Build Coastguard Worker                 {
464*8975f5c5SAndroid Build Coastguard Worker                     *binaryStatus++ = CL_INVALID_BINARY;
465*8975f5c5SAndroid Build Coastguard Worker                 }
466*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_CL_RETURN_ERROR(CL_INVALID_BINARY);
467*8975f5c5SAndroid Build Coastguard Worker         }
468*8975f5c5SAndroid Build Coastguard Worker         mAssociatedDevicePrograms[device->getNative()] = std::move(deviceBinary);
469*8975f5c5SAndroid Build Coastguard Worker         if (binaryStatus)
470*8975f5c5SAndroid Build Coastguard Worker         {
471*8975f5c5SAndroid Build Coastguard Worker             *binaryStatus++ = CL_SUCCESS;
472*8975f5c5SAndroid Build Coastguard Worker         }
473*8975f5c5SAndroid Build Coastguard Worker     }
474*8975f5c5SAndroid Build Coastguard Worker 
475*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
476*8975f5c5SAndroid Build Coastguard Worker }
477*8975f5c5SAndroid Build Coastguard Worker 
~CLProgramVk()478*8975f5c5SAndroid Build Coastguard Worker CLProgramVk::~CLProgramVk()
479*8975f5c5SAndroid Build Coastguard Worker {
480*8975f5c5SAndroid Build Coastguard Worker     for (vk::DynamicDescriptorPoolPointer &pool : mDynamicDescriptorPools)
481*8975f5c5SAndroid Build Coastguard Worker     {
482*8975f5c5SAndroid Build Coastguard Worker         pool.reset();
483*8975f5c5SAndroid Build Coastguard Worker     }
484*8975f5c5SAndroid Build Coastguard Worker     for (DescriptorSetIndex index : angle::AllEnums<DescriptorSetIndex>())
485*8975f5c5SAndroid Build Coastguard Worker     {
486*8975f5c5SAndroid Build Coastguard Worker         mMetaDescriptorPools[index].destroy(mContext->getRenderer());
487*8975f5c5SAndroid Build Coastguard Worker     }
488*8975f5c5SAndroid Build Coastguard Worker }
489*8975f5c5SAndroid Build Coastguard Worker 
build(const cl::DevicePtrs & devices,const char * options,cl::Program * notify)490*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::build(const cl::DevicePtrs &devices,
491*8975f5c5SAndroid Build Coastguard Worker                                  const char *options,
492*8975f5c5SAndroid Build Coastguard Worker                                  cl::Program *notify)
493*8975f5c5SAndroid Build Coastguard Worker {
494*8975f5c5SAndroid Build Coastguard Worker     BuildType buildType = !mProgram.getSource().empty() ? BuildType::BUILD : BuildType::BINARY;
495*8975f5c5SAndroid Build Coastguard Worker     const cl::DevicePtrs &devicePtrs = !devices.empty() ? devices : mProgram.getDevices();
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     setBuildStatus(devicePtrs, CL_BUILD_IN_PROGRESS);
498*8975f5c5SAndroid Build Coastguard Worker 
499*8975f5c5SAndroid Build Coastguard Worker     if (notify)
500*8975f5c5SAndroid Build Coastguard Worker     {
501*8975f5c5SAndroid Build Coastguard Worker         mAsyncBuildEvent =
502*8975f5c5SAndroid Build Coastguard Worker             getPlatform()->postMultiThreadWorkerTask(std::make_shared<CLAsyncBuildTask>(
503*8975f5c5SAndroid Build Coastguard Worker                 this, devicePtrs, std::string(options ? options : ""), "", buildType,
504*8975f5c5SAndroid Build Coastguard Worker                 LinkProgramsList{}, notify));
505*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mAsyncBuildEvent != nullptr);
506*8975f5c5SAndroid Build Coastguard Worker     }
507*8975f5c5SAndroid Build Coastguard Worker     else
508*8975f5c5SAndroid Build Coastguard Worker     {
509*8975f5c5SAndroid Build Coastguard Worker         if (!buildInternal(devicePtrs, std::string(options ? options : ""), "", buildType,
510*8975f5c5SAndroid Build Coastguard Worker                            LinkProgramsList{}))
511*8975f5c5SAndroid Build Coastguard Worker         {
512*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_BUILD_PROGRAM_FAILURE);
513*8975f5c5SAndroid Build Coastguard Worker         }
514*8975f5c5SAndroid Build Coastguard Worker     }
515*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
516*8975f5c5SAndroid Build Coastguard Worker }
517*8975f5c5SAndroid Build Coastguard Worker 
compile(const cl::DevicePtrs & devices,const char * options,const cl::ProgramPtrs & inputHeaders,const char ** headerIncludeNames,cl::Program * notify)518*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::compile(const cl::DevicePtrs &devices,
519*8975f5c5SAndroid Build Coastguard Worker                                    const char *options,
520*8975f5c5SAndroid Build Coastguard Worker                                    const cl::ProgramPtrs &inputHeaders,
521*8975f5c5SAndroid Build Coastguard Worker                                    const char **headerIncludeNames,
522*8975f5c5SAndroid Build Coastguard Worker                                    cl::Program *notify)
523*8975f5c5SAndroid Build Coastguard Worker {
524*8975f5c5SAndroid Build Coastguard Worker     const cl::DevicePtrs &devicePtrs = !devices.empty() ? devices : mProgram.getDevices();
525*8975f5c5SAndroid Build Coastguard Worker 
526*8975f5c5SAndroid Build Coastguard Worker     // Ensure OS temp dir is available
527*8975f5c5SAndroid Build Coastguard Worker     std::string internalCompileOpts;
528*8975f5c5SAndroid Build Coastguard Worker     Optional<std::string> tmpDir = angle::GetTempDirectory();
529*8975f5c5SAndroid Build Coastguard Worker     if (!tmpDir.valid())
530*8975f5c5SAndroid Build Coastguard Worker     {
531*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Failed to open OS temp dir";
532*8975f5c5SAndroid Build Coastguard Worker         ANGLE_CL_RETURN_ERROR(CL_INVALID_OPERATION);
533*8975f5c5SAndroid Build Coastguard Worker     }
534*8975f5c5SAndroid Build Coastguard Worker     internalCompileOpts += inputHeaders.empty() ? "" : " -I" + tmpDir.value();
535*8975f5c5SAndroid Build Coastguard Worker 
536*8975f5c5SAndroid Build Coastguard Worker     // Dump input headers to OS temp directory
537*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < inputHeaders.size(); ++i)
538*8975f5c5SAndroid Build Coastguard Worker     {
539*8975f5c5SAndroid Build Coastguard Worker         const std::string &inputHeaderSrc =
540*8975f5c5SAndroid Build Coastguard Worker             inputHeaders.at(i)->getImpl<CLProgramVk>().mProgram.getSource();
541*8975f5c5SAndroid Build Coastguard Worker         std::string headerFilePath(angle::ConcatenatePath(tmpDir.value(), headerIncludeNames[i]));
542*8975f5c5SAndroid Build Coastguard Worker 
543*8975f5c5SAndroid Build Coastguard Worker         // Sanitize path so we can use "/" as universal path separator
544*8975f5c5SAndroid Build Coastguard Worker         angle::MakeForwardSlashThePathSeparator(headerFilePath);
545*8975f5c5SAndroid Build Coastguard Worker         size_t baseDirPos = headerFilePath.find_last_of("/");
546*8975f5c5SAndroid Build Coastguard Worker 
547*8975f5c5SAndroid Build Coastguard Worker         // Ensure parent dir(s) exists
548*8975f5c5SAndroid Build Coastguard Worker         if (!angle::CreateDirectories(headerFilePath.substr(0, baseDirPos)))
549*8975f5c5SAndroid Build Coastguard Worker         {
550*8975f5c5SAndroid Build Coastguard Worker             ERR() << "Failed to create output path(s) for header(s)!";
551*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_INVALID_OPERATION);
552*8975f5c5SAndroid Build Coastguard Worker         }
553*8975f5c5SAndroid Build Coastguard Worker         writeFile(headerFilePath.c_str(), inputHeaderSrc.data(), inputHeaderSrc.size());
554*8975f5c5SAndroid Build Coastguard Worker     }
555*8975f5c5SAndroid Build Coastguard Worker 
556*8975f5c5SAndroid Build Coastguard Worker     setBuildStatus(devicePtrs, CL_BUILD_IN_PROGRESS);
557*8975f5c5SAndroid Build Coastguard Worker 
558*8975f5c5SAndroid Build Coastguard Worker     // Perform compile
559*8975f5c5SAndroid Build Coastguard Worker     if (notify)
560*8975f5c5SAndroid Build Coastguard Worker     {
561*8975f5c5SAndroid Build Coastguard Worker         mAsyncBuildEvent = mProgram.getContext().getPlatform().getMultiThreadPool()->postWorkerTask(
562*8975f5c5SAndroid Build Coastguard Worker             std::make_shared<CLAsyncBuildTask>(
563*8975f5c5SAndroid Build Coastguard Worker                 this, devicePtrs, std::string(options ? options : ""), internalCompileOpts,
564*8975f5c5SAndroid Build Coastguard Worker                 BuildType::COMPILE, LinkProgramsList{}, notify));
565*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mAsyncBuildEvent != nullptr);
566*8975f5c5SAndroid Build Coastguard Worker     }
567*8975f5c5SAndroid Build Coastguard Worker     else
568*8975f5c5SAndroid Build Coastguard Worker     {
569*8975f5c5SAndroid Build Coastguard Worker         mAsyncBuildEvent = std::make_shared<angle::WaitableEventDone>();
570*8975f5c5SAndroid Build Coastguard Worker         if (!buildInternal(devicePtrs, std::string(options ? options : ""), internalCompileOpts,
571*8975f5c5SAndroid Build Coastguard Worker                            BuildType::COMPILE, LinkProgramsList{}))
572*8975f5c5SAndroid Build Coastguard Worker         {
573*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CL_RETURN_ERROR(CL_COMPILE_PROGRAM_FAILURE);
574*8975f5c5SAndroid Build Coastguard Worker         }
575*8975f5c5SAndroid Build Coastguard Worker     }
576*8975f5c5SAndroid Build Coastguard Worker 
577*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
578*8975f5c5SAndroid Build Coastguard Worker }
579*8975f5c5SAndroid Build Coastguard Worker 
getInfo(cl::ProgramInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const580*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::getInfo(cl::ProgramInfo name,
581*8975f5c5SAndroid Build Coastguard Worker                                    size_t valueSize,
582*8975f5c5SAndroid Build Coastguard Worker                                    void *value,
583*8975f5c5SAndroid Build Coastguard Worker                                    size_t *valueSizeRet) const
584*8975f5c5SAndroid Build Coastguard Worker {
585*8975f5c5SAndroid Build Coastguard Worker     cl_uint valUInt            = 0u;
586*8975f5c5SAndroid Build Coastguard Worker     cl_bool valBool            = CL_FALSE;
587*8975f5c5SAndroid Build Coastguard Worker     void *valPointer           = nullptr;
588*8975f5c5SAndroid Build Coastguard Worker     const void *copyValue      = nullptr;
589*8975f5c5SAndroid Build Coastguard Worker     size_t copySize            = 0u;
590*8975f5c5SAndroid Build Coastguard Worker     unsigned char **outputBins = reinterpret_cast<unsigned char **>(value);
591*8975f5c5SAndroid Build Coastguard Worker     std::string kernelNamesList;
592*8975f5c5SAndroid Build Coastguard Worker     std::vector<size_t> vBinarySizes;
593*8975f5c5SAndroid Build Coastguard Worker 
594*8975f5c5SAndroid Build Coastguard Worker     switch (name)
595*8975f5c5SAndroid Build Coastguard Worker     {
596*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramInfo::NumKernels:
597*8975f5c5SAndroid Build Coastguard Worker             for (const auto &deviceProgram : mAssociatedDevicePrograms)
598*8975f5c5SAndroid Build Coastguard Worker             {
599*8975f5c5SAndroid Build Coastguard Worker                 valUInt += static_cast<decltype(valUInt)>(deviceProgram.second.numKernels());
600*8975f5c5SAndroid Build Coastguard Worker             }
601*8975f5c5SAndroid Build Coastguard Worker             copyValue = &valUInt;
602*8975f5c5SAndroid Build Coastguard Worker             copySize  = sizeof(valUInt);
603*8975f5c5SAndroid Build Coastguard Worker             break;
604*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramInfo::BinarySizes:
605*8975f5c5SAndroid Build Coastguard Worker         {
606*8975f5c5SAndroid Build Coastguard Worker             for (const auto &deviceProgram : mAssociatedDevicePrograms)
607*8975f5c5SAndroid Build Coastguard Worker             {
608*8975f5c5SAndroid Build Coastguard Worker                 vBinarySizes.push_back(
609*8975f5c5SAndroid Build Coastguard Worker                     sizeof(ProgramBinaryOutputHeader) +
610*8975f5c5SAndroid Build Coastguard Worker                     (deviceProgram.second.binaryType == CL_PROGRAM_BINARY_TYPE_EXECUTABLE
611*8975f5c5SAndroid Build Coastguard Worker                          ? deviceProgram.second.binary.size() * sizeof(uint32_t)
612*8975f5c5SAndroid Build Coastguard Worker                          : deviceProgram.second.IR.size()));
613*8975f5c5SAndroid Build Coastguard Worker             }
614*8975f5c5SAndroid Build Coastguard Worker             valPointer = vBinarySizes.data();
615*8975f5c5SAndroid Build Coastguard Worker             copyValue  = valPointer;
616*8975f5c5SAndroid Build Coastguard Worker             copySize   = vBinarySizes.size() * sizeof(size_t);
617*8975f5c5SAndroid Build Coastguard Worker             break;
618*8975f5c5SAndroid Build Coastguard Worker         }
619*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramInfo::Binaries:
620*8975f5c5SAndroid Build Coastguard Worker             for (const auto &deviceProgram : mAssociatedDevicePrograms)
621*8975f5c5SAndroid Build Coastguard Worker             {
622*8975f5c5SAndroid Build Coastguard Worker                 const void *bin =
623*8975f5c5SAndroid Build Coastguard Worker                     deviceProgram.second.binaryType == CL_PROGRAM_BINARY_TYPE_EXECUTABLE
624*8975f5c5SAndroid Build Coastguard Worker                         ? reinterpret_cast<const void *>(deviceProgram.second.binary.data())
625*8975f5c5SAndroid Build Coastguard Worker                         : reinterpret_cast<const void *>(deviceProgram.second.IR.data());
626*8975f5c5SAndroid Build Coastguard Worker                 size_t binSize =
627*8975f5c5SAndroid Build Coastguard Worker                     deviceProgram.second.binaryType == CL_PROGRAM_BINARY_TYPE_EXECUTABLE
628*8975f5c5SAndroid Build Coastguard Worker                         ? deviceProgram.second.binary.size() * sizeof(uint32_t)
629*8975f5c5SAndroid Build Coastguard Worker                         : deviceProgram.second.IR.size();
630*8975f5c5SAndroid Build Coastguard Worker                 ProgramBinaryOutputHeader header{.headerVersion = kBinaryVersion,
631*8975f5c5SAndroid Build Coastguard Worker                                                  .binaryType    = deviceProgram.second.binaryType,
632*8975f5c5SAndroid Build Coastguard Worker                                                  .buildStatus   = deviceProgram.second.buildStatus};
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker                 if (outputBins != nullptr)
635*8975f5c5SAndroid Build Coastguard Worker                 {
636*8975f5c5SAndroid Build Coastguard Worker                     if (*outputBins != nullptr)
637*8975f5c5SAndroid Build Coastguard Worker                     {
638*8975f5c5SAndroid Build Coastguard Worker                         std::memcpy(*outputBins, &header, sizeof(ProgramBinaryOutputHeader));
639*8975f5c5SAndroid Build Coastguard Worker                         std::memcpy((*outputBins) + sizeof(ProgramBinaryOutputHeader), bin,
640*8975f5c5SAndroid Build Coastguard Worker                                     binSize);
641*8975f5c5SAndroid Build Coastguard Worker                     }
642*8975f5c5SAndroid Build Coastguard Worker                     outputBins++;
643*8975f5c5SAndroid Build Coastguard Worker                 }
644*8975f5c5SAndroid Build Coastguard Worker 
645*8975f5c5SAndroid Build Coastguard Worker                 // Spec just wants pointer size here
646*8975f5c5SAndroid Build Coastguard Worker                 copySize += sizeof(unsigned char *);
647*8975f5c5SAndroid Build Coastguard Worker             }
648*8975f5c5SAndroid Build Coastguard Worker             // We already copied the (headers + binaries) over - nothing else left to copy
649*8975f5c5SAndroid Build Coastguard Worker             copyValue = nullptr;
650*8975f5c5SAndroid Build Coastguard Worker             break;
651*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramInfo::KernelNames:
652*8975f5c5SAndroid Build Coastguard Worker             for (const auto &deviceProgram : mAssociatedDevicePrograms)
653*8975f5c5SAndroid Build Coastguard Worker             {
654*8975f5c5SAndroid Build Coastguard Worker                 kernelNamesList = deviceProgram.second.getKernelNames();
655*8975f5c5SAndroid Build Coastguard Worker             }
656*8975f5c5SAndroid Build Coastguard Worker             valPointer = kernelNamesList.data();
657*8975f5c5SAndroid Build Coastguard Worker             copyValue  = valPointer;
658*8975f5c5SAndroid Build Coastguard Worker             copySize   = kernelNamesList.size() + 1;
659*8975f5c5SAndroid Build Coastguard Worker             break;
660*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramInfo::ScopeGlobalCtorsPresent:
661*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramInfo::ScopeGlobalDtorsPresent:
662*8975f5c5SAndroid Build Coastguard Worker             // These are deprecated by version 3.0 and are currently not supported
663*8975f5c5SAndroid Build Coastguard Worker             copyValue = &valBool;
664*8975f5c5SAndroid Build Coastguard Worker             copySize  = sizeof(cl_bool);
665*8975f5c5SAndroid Build Coastguard Worker             break;
666*8975f5c5SAndroid Build Coastguard Worker         default:
667*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
668*8975f5c5SAndroid Build Coastguard Worker     }
669*8975f5c5SAndroid Build Coastguard Worker 
670*8975f5c5SAndroid Build Coastguard Worker     if ((value != nullptr) && (copyValue != nullptr))
671*8975f5c5SAndroid Build Coastguard Worker     {
672*8975f5c5SAndroid Build Coastguard Worker         std::memcpy(value, copyValue, copySize);
673*8975f5c5SAndroid Build Coastguard Worker     }
674*8975f5c5SAndroid Build Coastguard Worker 
675*8975f5c5SAndroid Build Coastguard Worker     if (valueSizeRet != nullptr)
676*8975f5c5SAndroid Build Coastguard Worker     {
677*8975f5c5SAndroid Build Coastguard Worker         *valueSizeRet = copySize;
678*8975f5c5SAndroid Build Coastguard Worker     }
679*8975f5c5SAndroid Build Coastguard Worker 
680*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
681*8975f5c5SAndroid Build Coastguard Worker }
682*8975f5c5SAndroid Build Coastguard Worker 
getBuildInfo(const cl::Device & device,cl::ProgramBuildInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const683*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::getBuildInfo(const cl::Device &device,
684*8975f5c5SAndroid Build Coastguard Worker                                         cl::ProgramBuildInfo name,
685*8975f5c5SAndroid Build Coastguard Worker                                         size_t valueSize,
686*8975f5c5SAndroid Build Coastguard Worker                                         void *value,
687*8975f5c5SAndroid Build Coastguard Worker                                         size_t *valueSizeRet) const
688*8975f5c5SAndroid Build Coastguard Worker {
689*8975f5c5SAndroid Build Coastguard Worker     cl_uint valUInt                            = 0;
690*8975f5c5SAndroid Build Coastguard Worker     cl_build_status valStatus                  = 0;
691*8975f5c5SAndroid Build Coastguard Worker     const void *copyValue                      = nullptr;
692*8975f5c5SAndroid Build Coastguard Worker     size_t copySize                            = 0;
693*8975f5c5SAndroid Build Coastguard Worker     const DeviceProgramData *deviceProgramData = getDeviceProgramData(device.getNative());
694*8975f5c5SAndroid Build Coastguard Worker 
695*8975f5c5SAndroid Build Coastguard Worker     switch (name)
696*8975f5c5SAndroid Build Coastguard Worker     {
697*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramBuildInfo::Status:
698*8975f5c5SAndroid Build Coastguard Worker             valStatus = deviceProgramData->buildStatus;
699*8975f5c5SAndroid Build Coastguard Worker             copyValue = &valStatus;
700*8975f5c5SAndroid Build Coastguard Worker             copySize  = sizeof(valStatus);
701*8975f5c5SAndroid Build Coastguard Worker             break;
702*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramBuildInfo::Log:
703*8975f5c5SAndroid Build Coastguard Worker             copyValue = deviceProgramData->buildLog.c_str();
704*8975f5c5SAndroid Build Coastguard Worker             copySize  = deviceProgramData->buildLog.size() + 1;
705*8975f5c5SAndroid Build Coastguard Worker             break;
706*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramBuildInfo::Options:
707*8975f5c5SAndroid Build Coastguard Worker             copyValue = mProgramOpts.c_str();
708*8975f5c5SAndroid Build Coastguard Worker             copySize  = mProgramOpts.size() + 1;
709*8975f5c5SAndroid Build Coastguard Worker             break;
710*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramBuildInfo::BinaryType:
711*8975f5c5SAndroid Build Coastguard Worker             valUInt   = deviceProgramData->binaryType;
712*8975f5c5SAndroid Build Coastguard Worker             copyValue = &valUInt;
713*8975f5c5SAndroid Build Coastguard Worker             copySize  = sizeof(valUInt);
714*8975f5c5SAndroid Build Coastguard Worker             break;
715*8975f5c5SAndroid Build Coastguard Worker         case cl::ProgramBuildInfo::GlobalVariableTotalSize:
716*8975f5c5SAndroid Build Coastguard Worker             // Returns 0 if device does not support program scope global variables.
717*8975f5c5SAndroid Build Coastguard Worker             valUInt   = 0;
718*8975f5c5SAndroid Build Coastguard Worker             copyValue = &valUInt;
719*8975f5c5SAndroid Build Coastguard Worker             copySize  = sizeof(valUInt);
720*8975f5c5SAndroid Build Coastguard Worker             break;
721*8975f5c5SAndroid Build Coastguard Worker         default:
722*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
723*8975f5c5SAndroid Build Coastguard Worker     }
724*8975f5c5SAndroid Build Coastguard Worker 
725*8975f5c5SAndroid Build Coastguard Worker     if ((value != nullptr) && (copyValue != nullptr))
726*8975f5c5SAndroid Build Coastguard Worker     {
727*8975f5c5SAndroid Build Coastguard Worker         memcpy(value, copyValue, std::min(valueSize, copySize));
728*8975f5c5SAndroid Build Coastguard Worker     }
729*8975f5c5SAndroid Build Coastguard Worker 
730*8975f5c5SAndroid Build Coastguard Worker     if (valueSizeRet != nullptr)
731*8975f5c5SAndroid Build Coastguard Worker     {
732*8975f5c5SAndroid Build Coastguard Worker         *valueSizeRet = copySize;
733*8975f5c5SAndroid Build Coastguard Worker     }
734*8975f5c5SAndroid Build Coastguard Worker 
735*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
736*8975f5c5SAndroid Build Coastguard Worker }
737*8975f5c5SAndroid Build Coastguard Worker 
createKernel(const cl::Kernel & kernel,const char * name,CLKernelImpl::Ptr * kernelOut)738*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::createKernel(const cl::Kernel &kernel,
739*8975f5c5SAndroid Build Coastguard Worker                                         const char *name,
740*8975f5c5SAndroid Build Coastguard Worker                                         CLKernelImpl::Ptr *kernelOut)
741*8975f5c5SAndroid Build Coastguard Worker {
742*8975f5c5SAndroid Build Coastguard Worker     // Wait for the compile to finish
743*8975f5c5SAndroid Build Coastguard Worker     mAsyncBuildEvent->wait();
744*8975f5c5SAndroid Build Coastguard Worker 
745*8975f5c5SAndroid Build Coastguard Worker     std::scoped_lock<angle::SimpleMutex> sl(mProgramMutex);
746*8975f5c5SAndroid Build Coastguard Worker     const auto devProgram = getDeviceProgramData(name);
747*8975f5c5SAndroid Build Coastguard Worker     ASSERT(devProgram != nullptr);
748*8975f5c5SAndroid Build Coastguard Worker 
749*8975f5c5SAndroid Build Coastguard Worker     // Create kernel
750*8975f5c5SAndroid Build Coastguard Worker     CLKernelArguments kernelArgs = devProgram->getKernelArguments(name);
751*8975f5c5SAndroid Build Coastguard Worker     std::string kernelAttributes = devProgram->getKernelAttributes(name);
752*8975f5c5SAndroid Build Coastguard Worker     std::string kernelName       = std::string(name ? name : "");
753*8975f5c5SAndroid Build Coastguard Worker     CLKernelVk::Ptr kernelImpl   = CLKernelVk::Ptr(
754*8975f5c5SAndroid Build Coastguard Worker         new (std::nothrow) CLKernelVk(kernel, kernelName, kernelAttributes, kernelArgs));
755*8975f5c5SAndroid Build Coastguard Worker     if (kernelImpl == nullptr)
756*8975f5c5SAndroid Build Coastguard Worker     {
757*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Could not create kernel obj!";
758*8975f5c5SAndroid Build Coastguard Worker         ANGLE_CL_RETURN_ERROR(CL_OUT_OF_HOST_MEMORY);
759*8975f5c5SAndroid Build Coastguard Worker     }
760*8975f5c5SAndroid Build Coastguard Worker 
761*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(kernelImpl->init());
762*8975f5c5SAndroid Build Coastguard Worker     *kernelOut = std::move(kernelImpl);
763*8975f5c5SAndroid Build Coastguard Worker 
764*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
765*8975f5c5SAndroid Build Coastguard Worker }
766*8975f5c5SAndroid Build Coastguard Worker 
createKernels(cl_uint numKernels,CLKernelImpl::CreateFuncs & createFuncs,cl_uint * numKernelsRet)767*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::createKernels(cl_uint numKernels,
768*8975f5c5SAndroid Build Coastguard Worker                                          CLKernelImpl::CreateFuncs &createFuncs,
769*8975f5c5SAndroid Build Coastguard Worker                                          cl_uint *numKernelsRet)
770*8975f5c5SAndroid Build Coastguard Worker {
771*8975f5c5SAndroid Build Coastguard Worker     size_t numDevKernels = 0;
772*8975f5c5SAndroid Build Coastguard Worker     for (const auto &dev : mAssociatedDevicePrograms)
773*8975f5c5SAndroid Build Coastguard Worker     {
774*8975f5c5SAndroid Build Coastguard Worker         numDevKernels += dev.second.numKernels();
775*8975f5c5SAndroid Build Coastguard Worker     }
776*8975f5c5SAndroid Build Coastguard Worker     if (numKernelsRet != nullptr)
777*8975f5c5SAndroid Build Coastguard Worker     {
778*8975f5c5SAndroid Build Coastguard Worker         *numKernelsRet = static_cast<cl_uint>(numDevKernels);
779*8975f5c5SAndroid Build Coastguard Worker     }
780*8975f5c5SAndroid Build Coastguard Worker 
781*8975f5c5SAndroid Build Coastguard Worker     if (numKernels != 0)
782*8975f5c5SAndroid Build Coastguard Worker     {
783*8975f5c5SAndroid Build Coastguard Worker         for (const auto &dev : mAssociatedDevicePrograms)
784*8975f5c5SAndroid Build Coastguard Worker         {
785*8975f5c5SAndroid Build Coastguard Worker             for (const auto &kernArgMap : dev.second.getKernelArgsMap())
786*8975f5c5SAndroid Build Coastguard Worker             {
787*8975f5c5SAndroid Build Coastguard Worker                 createFuncs.emplace_back([this, &kernArgMap](const cl::Kernel &kern) {
788*8975f5c5SAndroid Build Coastguard Worker                     CLKernelImpl::Ptr implPtr = nullptr;
789*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_CL_IMPL_TRY(this->createKernel(kern, kernArgMap.first.c_str(), &implPtr));
790*8975f5c5SAndroid Build Coastguard Worker                     return CLKernelImpl::Ptr(std::move(implPtr));
791*8975f5c5SAndroid Build Coastguard Worker                 });
792*8975f5c5SAndroid Build Coastguard Worker             }
793*8975f5c5SAndroid Build Coastguard Worker         }
794*8975f5c5SAndroid Build Coastguard Worker     }
795*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
796*8975f5c5SAndroid Build Coastguard Worker }
797*8975f5c5SAndroid Build Coastguard Worker 
getDeviceProgramData(const _cl_device_id * device) const798*8975f5c5SAndroid Build Coastguard Worker const CLProgramVk::DeviceProgramData *CLProgramVk::getDeviceProgramData(
799*8975f5c5SAndroid Build Coastguard Worker     const _cl_device_id *device) const
800*8975f5c5SAndroid Build Coastguard Worker {
801*8975f5c5SAndroid Build Coastguard Worker     if (!mAssociatedDevicePrograms.contains(device))
802*8975f5c5SAndroid Build Coastguard Worker     {
803*8975f5c5SAndroid Build Coastguard Worker         WARN() << "Device (" << device << ") is not associated with program (" << this << ") !";
804*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
805*8975f5c5SAndroid Build Coastguard Worker     }
806*8975f5c5SAndroid Build Coastguard Worker     return &mAssociatedDevicePrograms.at(device);
807*8975f5c5SAndroid Build Coastguard Worker }
808*8975f5c5SAndroid Build Coastguard Worker 
getDeviceProgramData(const char * kernelName) const809*8975f5c5SAndroid Build Coastguard Worker const CLProgramVk::DeviceProgramData *CLProgramVk::getDeviceProgramData(
810*8975f5c5SAndroid Build Coastguard Worker     const char *kernelName) const
811*8975f5c5SAndroid Build Coastguard Worker {
812*8975f5c5SAndroid Build Coastguard Worker     for (const auto &deviceProgram : mAssociatedDevicePrograms)
813*8975f5c5SAndroid Build Coastguard Worker     {
814*8975f5c5SAndroid Build Coastguard Worker         if (deviceProgram.second.containsKernel(kernelName))
815*8975f5c5SAndroid Build Coastguard Worker         {
816*8975f5c5SAndroid Build Coastguard Worker             return &deviceProgram.second;
817*8975f5c5SAndroid Build Coastguard Worker         }
818*8975f5c5SAndroid Build Coastguard Worker     }
819*8975f5c5SAndroid Build Coastguard Worker     WARN() << "Kernel name (" << kernelName << ") is not associated with program (" << this
820*8975f5c5SAndroid Build Coastguard Worker            << ") !";
821*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker 
buildInternal(const cl::DevicePtrs & devices,std::string options,std::string internalOptions,BuildType buildType,const LinkProgramsList & LinkProgramsList)824*8975f5c5SAndroid Build Coastguard Worker bool CLProgramVk::buildInternal(const cl::DevicePtrs &devices,
825*8975f5c5SAndroid Build Coastguard Worker                                 std::string options,
826*8975f5c5SAndroid Build Coastguard Worker                                 std::string internalOptions,
827*8975f5c5SAndroid Build Coastguard Worker                                 BuildType buildType,
828*8975f5c5SAndroid Build Coastguard Worker                                 const LinkProgramsList &LinkProgramsList)
829*8975f5c5SAndroid Build Coastguard Worker {
830*8975f5c5SAndroid Build Coastguard Worker     std::scoped_lock<angle::SimpleMutex> sl(mProgramMutex);
831*8975f5c5SAndroid Build Coastguard Worker 
832*8975f5c5SAndroid Build Coastguard Worker     // Cache original options string
833*8975f5c5SAndroid Build Coastguard Worker     mProgramOpts = options;
834*8975f5c5SAndroid Build Coastguard Worker 
835*8975f5c5SAndroid Build Coastguard Worker     // Process options and append any other internal (required) options for clspv
836*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> optionTokens;
837*8975f5c5SAndroid Build Coastguard Worker     angle::SplitStringAlongWhitespace(options + " " + internalOptions, &optionTokens);
838*8975f5c5SAndroid Build Coastguard Worker     const bool createLibrary     = std::find(optionTokens.begin(), optionTokens.end(),
839*8975f5c5SAndroid Build Coastguard Worker                                              "-create-library") != optionTokens.end();
840*8975f5c5SAndroid Build Coastguard Worker     std::string processedOptions = ProcessBuildOptions(optionTokens, buildType);
841*8975f5c5SAndroid Build Coastguard Worker 
842*8975f5c5SAndroid Build Coastguard Worker     // Build for each associated device
843*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < devices.size(); ++i)
844*8975f5c5SAndroid Build Coastguard Worker     {
845*8975f5c5SAndroid Build Coastguard Worker         const cl::RefPointer<cl::Device> &device = devices.at(i);
846*8975f5c5SAndroid Build Coastguard Worker         DeviceProgramData &deviceProgramData     = mAssociatedDevicePrograms[device->getNative()];
847*8975f5c5SAndroid Build Coastguard Worker 
848*8975f5c5SAndroid Build Coastguard Worker         // add clspv compiler options based on device features
849*8975f5c5SAndroid Build Coastguard Worker         processedOptions += ClspvGetCompilerOptions(&device->getImpl<CLDeviceVk>());
850*8975f5c5SAndroid Build Coastguard Worker 
851*8975f5c5SAndroid Build Coastguard Worker         if (buildType != BuildType::BINARY)
852*8975f5c5SAndroid Build Coastguard Worker         {
853*8975f5c5SAndroid Build Coastguard Worker             // Invoke clspv
854*8975f5c5SAndroid Build Coastguard Worker             switch (buildType)
855*8975f5c5SAndroid Build Coastguard Worker             {
856*8975f5c5SAndroid Build Coastguard Worker                 case BuildType::BUILD:
857*8975f5c5SAndroid Build Coastguard Worker                 case BuildType::COMPILE:
858*8975f5c5SAndroid Build Coastguard Worker                 {
859*8975f5c5SAndroid Build Coastguard Worker                     ScopedClspvContext clspvCtx;
860*8975f5c5SAndroid Build Coastguard Worker                     const char *clSrc   = mProgram.getSource().c_str();
861*8975f5c5SAndroid Build Coastguard Worker                     ClspvError clspvRet = clspvCompileFromSourcesString(
862*8975f5c5SAndroid Build Coastguard Worker                         1, NULL, static_cast<const char **>(&clSrc), processedOptions.c_str(),
863*8975f5c5SAndroid Build Coastguard Worker                         &clspvCtx.mOutputBin, &clspvCtx.mOutputBinSize, &clspvCtx.mOutputBuildLog);
864*8975f5c5SAndroid Build Coastguard Worker                     deviceProgramData.buildLog =
865*8975f5c5SAndroid Build Coastguard Worker                         clspvCtx.mOutputBuildLog != nullptr ? clspvCtx.mOutputBuildLog : "";
866*8975f5c5SAndroid Build Coastguard Worker                     if (clspvRet != CLSPV_SUCCESS)
867*8975f5c5SAndroid Build Coastguard Worker                     {
868*8975f5c5SAndroid Build Coastguard Worker                         ERR() << "OpenCL build failed with: ClspvError(" << clspvRet << ")!";
869*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.buildStatus = CL_BUILD_ERROR;
870*8975f5c5SAndroid Build Coastguard Worker                         return false;
871*8975f5c5SAndroid Build Coastguard Worker                     }
872*8975f5c5SAndroid Build Coastguard Worker 
873*8975f5c5SAndroid Build Coastguard Worker                     if (buildType == BuildType::COMPILE)
874*8975f5c5SAndroid Build Coastguard Worker                     {
875*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.IR.assign(clspvCtx.mOutputBinSize, 0);
876*8975f5c5SAndroid Build Coastguard Worker                         std::memcpy(deviceProgramData.IR.data(), clspvCtx.mOutputBin,
877*8975f5c5SAndroid Build Coastguard Worker                                     clspvCtx.mOutputBinSize);
878*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.binaryType = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
879*8975f5c5SAndroid Build Coastguard Worker                     }
880*8975f5c5SAndroid Build Coastguard Worker                     else
881*8975f5c5SAndroid Build Coastguard Worker                     {
882*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.binary.assign(clspvCtx.mOutputBinSize / sizeof(uint32_t),
883*8975f5c5SAndroid Build Coastguard Worker                                                         0);
884*8975f5c5SAndroid Build Coastguard Worker                         std::memcpy(deviceProgramData.binary.data(), clspvCtx.mOutputBin,
885*8975f5c5SAndroid Build Coastguard Worker                                     clspvCtx.mOutputBinSize);
886*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.binaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
887*8975f5c5SAndroid Build Coastguard Worker                     }
888*8975f5c5SAndroid Build Coastguard Worker                     break;
889*8975f5c5SAndroid Build Coastguard Worker                 }
890*8975f5c5SAndroid Build Coastguard Worker                 case BuildType::LINK:
891*8975f5c5SAndroid Build Coastguard Worker                 {
892*8975f5c5SAndroid Build Coastguard Worker                     ScopedClspvContext clspvCtx;
893*8975f5c5SAndroid Build Coastguard Worker                     std::vector<size_t> vSizes;
894*8975f5c5SAndroid Build Coastguard Worker                     std::vector<const char *> vBins;
895*8975f5c5SAndroid Build Coastguard Worker                     const LinkPrograms &linkPrograms = LinkProgramsList.at(i);
896*8975f5c5SAndroid Build Coastguard Worker                     for (const CLProgramVk::DeviceProgramData *linkProgramData : linkPrograms)
897*8975f5c5SAndroid Build Coastguard Worker                     {
898*8975f5c5SAndroid Build Coastguard Worker                         vSizes.push_back(linkProgramData->IR.size());
899*8975f5c5SAndroid Build Coastguard Worker                         vBins.push_back(linkProgramData->IR.data());
900*8975f5c5SAndroid Build Coastguard Worker                     }
901*8975f5c5SAndroid Build Coastguard Worker                     ClspvError clspvRet = clspvCompileFromSourcesString(
902*8975f5c5SAndroid Build Coastguard Worker                         linkPrograms.size(), vSizes.data(), vBins.data(), processedOptions.c_str(),
903*8975f5c5SAndroid Build Coastguard Worker                         &clspvCtx.mOutputBin, &clspvCtx.mOutputBinSize, &clspvCtx.mOutputBuildLog);
904*8975f5c5SAndroid Build Coastguard Worker                     deviceProgramData.buildLog =
905*8975f5c5SAndroid Build Coastguard Worker                         clspvCtx.mOutputBuildLog != nullptr ? clspvCtx.mOutputBuildLog : "";
906*8975f5c5SAndroid Build Coastguard Worker                     if (clspvRet != CLSPV_SUCCESS)
907*8975f5c5SAndroid Build Coastguard Worker                     {
908*8975f5c5SAndroid Build Coastguard Worker                         ERR() << "OpenCL build failed with: ClspvError(" << clspvRet << ")!";
909*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.buildStatus = CL_BUILD_ERROR;
910*8975f5c5SAndroid Build Coastguard Worker                         return false;
911*8975f5c5SAndroid Build Coastguard Worker                     }
912*8975f5c5SAndroid Build Coastguard Worker 
913*8975f5c5SAndroid Build Coastguard Worker                     if (createLibrary)
914*8975f5c5SAndroid Build Coastguard Worker                     {
915*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.IR.assign(clspvCtx.mOutputBinSize, 0);
916*8975f5c5SAndroid Build Coastguard Worker                         std::memcpy(deviceProgramData.IR.data(), clspvCtx.mOutputBin,
917*8975f5c5SAndroid Build Coastguard Worker                                     clspvCtx.mOutputBinSize);
918*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.binaryType = CL_PROGRAM_BINARY_TYPE_LIBRARY;
919*8975f5c5SAndroid Build Coastguard Worker                     }
920*8975f5c5SAndroid Build Coastguard Worker                     else
921*8975f5c5SAndroid Build Coastguard Worker                     {
922*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.binary.assign(clspvCtx.mOutputBinSize / sizeof(uint32_t),
923*8975f5c5SAndroid Build Coastguard Worker                                                         0);
924*8975f5c5SAndroid Build Coastguard Worker                         std::memcpy(deviceProgramData.binary.data(),
925*8975f5c5SAndroid Build Coastguard Worker                                     reinterpret_cast<char *>(clspvCtx.mOutputBin),
926*8975f5c5SAndroid Build Coastguard Worker                                     clspvCtx.mOutputBinSize);
927*8975f5c5SAndroid Build Coastguard Worker                         deviceProgramData.binaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
928*8975f5c5SAndroid Build Coastguard Worker                     }
929*8975f5c5SAndroid Build Coastguard Worker                     break;
930*8975f5c5SAndroid Build Coastguard Worker                 }
931*8975f5c5SAndroid Build Coastguard Worker                 default:
932*8975f5c5SAndroid Build Coastguard Worker                     UNREACHABLE();
933*8975f5c5SAndroid Build Coastguard Worker                     return false;
934*8975f5c5SAndroid Build Coastguard Worker             }
935*8975f5c5SAndroid Build Coastguard Worker         }
936*8975f5c5SAndroid Build Coastguard Worker 
937*8975f5c5SAndroid Build Coastguard Worker         // Extract reflection info from spv binary and populate reflection data, as well as create
938*8975f5c5SAndroid Build Coastguard Worker         // the shader module
939*8975f5c5SAndroid Build Coastguard Worker         if (deviceProgramData.binaryType == CL_PROGRAM_BINARY_TYPE_EXECUTABLE)
940*8975f5c5SAndroid Build Coastguard Worker         {
941*8975f5c5SAndroid Build Coastguard Worker             spvtools::SpirvTools spvTool(SPV_ENV_UNIVERSAL_1_5);
942*8975f5c5SAndroid Build Coastguard Worker             bool parseRet = spvTool.Parse(
943*8975f5c5SAndroid Build Coastguard Worker                 deviceProgramData.binary,
944*8975f5c5SAndroid Build Coastguard Worker                 [](const spv_endianness_t endianess, const spv_parsed_header_t &instruction) {
945*8975f5c5SAndroid Build Coastguard Worker                     return SPV_SUCCESS;
946*8975f5c5SAndroid Build Coastguard Worker                 },
947*8975f5c5SAndroid Build Coastguard Worker                 [&deviceProgramData](const spv_parsed_instruction_t &instruction) {
948*8975f5c5SAndroid Build Coastguard Worker                     return ParseReflection(deviceProgramData.reflectionData, instruction);
949*8975f5c5SAndroid Build Coastguard Worker                 });
950*8975f5c5SAndroid Build Coastguard Worker             if (!parseRet)
951*8975f5c5SAndroid Build Coastguard Worker             {
952*8975f5c5SAndroid Build Coastguard Worker                 ERR() << "Failed to parse reflection info from SPIR-V!";
953*8975f5c5SAndroid Build Coastguard Worker                 deviceProgramData.buildStatus = CL_BUILD_ERROR;
954*8975f5c5SAndroid Build Coastguard Worker                 return false;
955*8975f5c5SAndroid Build Coastguard Worker             }
956*8975f5c5SAndroid Build Coastguard Worker 
957*8975f5c5SAndroid Build Coastguard Worker             if (mShader)
958*8975f5c5SAndroid Build Coastguard Worker             {
959*8975f5c5SAndroid Build Coastguard Worker                 mShader.reset();
960*8975f5c5SAndroid Build Coastguard Worker             }
961*8975f5c5SAndroid Build Coastguard Worker             // Strip SPIR-V binary if Vk implementation does not support non-semantic info
962*8975f5c5SAndroid Build Coastguard Worker             angle::spirv::Blob spvBlob =
963*8975f5c5SAndroid Build Coastguard Worker                 !mContext->getFeatures().supportsShaderNonSemanticInfo.enabled
964*8975f5c5SAndroid Build Coastguard Worker                     ? stripReflection(&deviceProgramData)
965*8975f5c5SAndroid Build Coastguard Worker                     : deviceProgramData.binary;
966*8975f5c5SAndroid Build Coastguard Worker             ASSERT(!spvBlob.empty());
967*8975f5c5SAndroid Build Coastguard Worker             if (IsError(vk::InitShaderModule(mContext, &mShader, spvBlob.data(),
968*8975f5c5SAndroid Build Coastguard Worker                                              spvBlob.size() * sizeof(uint32_t))))
969*8975f5c5SAndroid Build Coastguard Worker             {
970*8975f5c5SAndroid Build Coastguard Worker                 ERR() << "Failed to init Vulkan Shader Module!";
971*8975f5c5SAndroid Build Coastguard Worker                 deviceProgramData.buildStatus = CL_BUILD_ERROR;
972*8975f5c5SAndroid Build Coastguard Worker                 return false;
973*8975f5c5SAndroid Build Coastguard Worker             }
974*8975f5c5SAndroid Build Coastguard Worker 
975*8975f5c5SAndroid Build Coastguard Worker             // Setup inital push constant range
976*8975f5c5SAndroid Build Coastguard Worker             uint32_t pushConstantMinOffet = UINT32_MAX, pushConstantMaxOffset = 0,
977*8975f5c5SAndroid Build Coastguard Worker                      pushConstantMaxSize = 0;
978*8975f5c5SAndroid Build Coastguard Worker             for (const auto &pushConstant : deviceProgramData.reflectionData.pushConstants)
979*8975f5c5SAndroid Build Coastguard Worker             {
980*8975f5c5SAndroid Build Coastguard Worker                 pushConstantMinOffet = pushConstant.second.offset < pushConstantMinOffet
981*8975f5c5SAndroid Build Coastguard Worker                                            ? pushConstant.second.offset
982*8975f5c5SAndroid Build Coastguard Worker                                            : pushConstantMinOffet;
983*8975f5c5SAndroid Build Coastguard Worker                 if (pushConstant.second.offset >= pushConstantMaxOffset)
984*8975f5c5SAndroid Build Coastguard Worker                 {
985*8975f5c5SAndroid Build Coastguard Worker                     pushConstantMaxOffset = pushConstant.second.offset;
986*8975f5c5SAndroid Build Coastguard Worker                     pushConstantMaxSize   = pushConstant.second.size;
987*8975f5c5SAndroid Build Coastguard Worker                 }
988*8975f5c5SAndroid Build Coastguard Worker             }
989*8975f5c5SAndroid Build Coastguard Worker             for (const auto &pushConstant : deviceProgramData.reflectionData.imagePushConstants)
990*8975f5c5SAndroid Build Coastguard Worker             {
991*8975f5c5SAndroid Build Coastguard Worker                 for (const auto imageConstant : pushConstant.second)
992*8975f5c5SAndroid Build Coastguard Worker                 {
993*8975f5c5SAndroid Build Coastguard Worker                     pushConstantMinOffet = imageConstant.pcRange.offset < pushConstantMinOffet
994*8975f5c5SAndroid Build Coastguard Worker                                                ? imageConstant.pcRange.offset
995*8975f5c5SAndroid Build Coastguard Worker                                                : pushConstantMinOffet;
996*8975f5c5SAndroid Build Coastguard Worker                     if (imageConstant.pcRange.offset >= pushConstantMaxOffset)
997*8975f5c5SAndroid Build Coastguard Worker                     {
998*8975f5c5SAndroid Build Coastguard Worker                         pushConstantMaxOffset = imageConstant.pcRange.offset;
999*8975f5c5SAndroid Build Coastguard Worker                         pushConstantMaxSize   = imageConstant.pcRange.size;
1000*8975f5c5SAndroid Build Coastguard Worker                     }
1001*8975f5c5SAndroid Build Coastguard Worker                 }
1002*8975f5c5SAndroid Build Coastguard Worker             }
1003*8975f5c5SAndroid Build Coastguard Worker             deviceProgramData.pushConstRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
1004*8975f5c5SAndroid Build Coastguard Worker             deviceProgramData.pushConstRange.offset =
1005*8975f5c5SAndroid Build Coastguard Worker                 pushConstantMinOffet == UINT32_MAX ? 0 : pushConstantMinOffet;
1006*8975f5c5SAndroid Build Coastguard Worker             deviceProgramData.pushConstRange.size = pushConstantMaxOffset + pushConstantMaxSize;
1007*8975f5c5SAndroid Build Coastguard Worker 
1008*8975f5c5SAndroid Build Coastguard Worker             if (kAngleDebug)
1009*8975f5c5SAndroid Build Coastguard Worker             {
1010*8975f5c5SAndroid Build Coastguard Worker                 if (mContext->getFeatures().clDumpVkSpirv.enabled)
1011*8975f5c5SAndroid Build Coastguard Worker                 {
1012*8975f5c5SAndroid Build Coastguard Worker                     angle::spirv::Print(deviceProgramData.binary);
1013*8975f5c5SAndroid Build Coastguard Worker                 }
1014*8975f5c5SAndroid Build Coastguard Worker             }
1015*8975f5c5SAndroid Build Coastguard Worker         }
1016*8975f5c5SAndroid Build Coastguard Worker         deviceProgramData.buildStatus = CL_BUILD_SUCCESS;
1017*8975f5c5SAndroid Build Coastguard Worker     }
1018*8975f5c5SAndroid Build Coastguard Worker     return true;
1019*8975f5c5SAndroid Build Coastguard Worker }
1020*8975f5c5SAndroid Build Coastguard Worker 
stripReflection(const DeviceProgramData * deviceProgramData)1021*8975f5c5SAndroid Build Coastguard Worker angle::spirv::Blob CLProgramVk::stripReflection(const DeviceProgramData *deviceProgramData)
1022*8975f5c5SAndroid Build Coastguard Worker {
1023*8975f5c5SAndroid Build Coastguard Worker     angle::spirv::Blob binaryStripped;
1024*8975f5c5SAndroid Build Coastguard Worker     spvtools::Optimizer opt(SPV_ENV_UNIVERSAL_1_5);
1025*8975f5c5SAndroid Build Coastguard Worker     opt.RegisterPass(spvtools::CreateStripReflectInfoPass());
1026*8975f5c5SAndroid Build Coastguard Worker     spvtools::OptimizerOptions optOptions;
1027*8975f5c5SAndroid Build Coastguard Worker     optOptions.set_run_validator(false);
1028*8975f5c5SAndroid Build Coastguard Worker     if (!opt.Run(deviceProgramData->binary.data(), deviceProgramData->binary.size(),
1029*8975f5c5SAndroid Build Coastguard Worker                  &binaryStripped, optOptions))
1030*8975f5c5SAndroid Build Coastguard Worker     {
1031*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Could not strip reflection data from binary!";
1032*8975f5c5SAndroid Build Coastguard Worker     }
1033*8975f5c5SAndroid Build Coastguard Worker     return binaryStripped;
1034*8975f5c5SAndroid Build Coastguard Worker }
1035*8975f5c5SAndroid Build Coastguard Worker 
allocateDescriptorSet(const DescriptorSetIndex setIndex,const vk::DescriptorSetLayout & descriptorSetLayout,vk::CommandBufferHelperCommon * commandBuffer,vk::DescriptorSetPointer * descriptorSetOut)1036*8975f5c5SAndroid Build Coastguard Worker angle::Result CLProgramVk::allocateDescriptorSet(const DescriptorSetIndex setIndex,
1037*8975f5c5SAndroid Build Coastguard Worker                                                  const vk::DescriptorSetLayout &descriptorSetLayout,
1038*8975f5c5SAndroid Build Coastguard Worker                                                  vk::CommandBufferHelperCommon *commandBuffer,
1039*8975f5c5SAndroid Build Coastguard Worker                                                  vk::DescriptorSetPointer *descriptorSetOut)
1040*8975f5c5SAndroid Build Coastguard Worker {
1041*8975f5c5SAndroid Build Coastguard Worker     if (mDynamicDescriptorPools[setIndex])
1042*8975f5c5SAndroid Build Coastguard Worker     {
1043*8975f5c5SAndroid Build Coastguard Worker         ANGLE_CL_IMPL_TRY_ERROR(mDynamicDescriptorPools[setIndex]->allocateDescriptorSet(
1044*8975f5c5SAndroid Build Coastguard Worker                                     mContext, descriptorSetLayout, descriptorSetOut),
1045*8975f5c5SAndroid Build Coastguard Worker                                 CL_INVALID_OPERATION);
1046*8975f5c5SAndroid Build Coastguard Worker         commandBuffer->retainResource(descriptorSetOut->get());
1047*8975f5c5SAndroid Build Coastguard Worker     }
1048*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
1049*8975f5c5SAndroid Build Coastguard Worker }
1050*8975f5c5SAndroid Build Coastguard Worker 
setBuildStatus(const cl::DevicePtrs & devices,cl_build_status status)1051*8975f5c5SAndroid Build Coastguard Worker void CLProgramVk::setBuildStatus(const cl::DevicePtrs &devices, cl_build_status status)
1052*8975f5c5SAndroid Build Coastguard Worker {
1053*8975f5c5SAndroid Build Coastguard Worker     std::scoped_lock<angle::SimpleMutex> sl(mProgramMutex);
1054*8975f5c5SAndroid Build Coastguard Worker 
1055*8975f5c5SAndroid Build Coastguard Worker     for (const auto &device : devices)
1056*8975f5c5SAndroid Build Coastguard Worker     {
1057*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mAssociatedDevicePrograms.contains(device->getNative()));
1058*8975f5c5SAndroid Build Coastguard Worker         DeviceProgramData &deviceProgram = mAssociatedDevicePrograms.at(device->getNative());
1059*8975f5c5SAndroid Build Coastguard Worker         deviceProgram.buildStatus        = status;
1060*8975f5c5SAndroid Build Coastguard Worker     }
1061*8975f5c5SAndroid Build Coastguard Worker }
1062*8975f5c5SAndroid Build Coastguard Worker 
getPrintfDescriptors(const std::string & kernelName) const1063*8975f5c5SAndroid Build Coastguard Worker const angle::HashMap<uint32_t, ClspvPrintfInfo> *CLProgramVk::getPrintfDescriptors(
1064*8975f5c5SAndroid Build Coastguard Worker     const std::string &kernelName) const
1065*8975f5c5SAndroid Build Coastguard Worker {
1066*8975f5c5SAndroid Build Coastguard Worker     const DeviceProgramData *deviceProgram = getDeviceProgramData(kernelName.c_str());
1067*8975f5c5SAndroid Build Coastguard Worker     if (deviceProgram)
1068*8975f5c5SAndroid Build Coastguard Worker     {
1069*8975f5c5SAndroid Build Coastguard Worker         return &deviceProgram->reflectionData.printfInfoMap;
1070*8975f5c5SAndroid Build Coastguard Worker     }
1071*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
1072*8975f5c5SAndroid Build Coastguard Worker }
1073*8975f5c5SAndroid Build Coastguard Worker 
1074*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
1075