1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #include "SpirvShader.hpp"
16*03ce13f7SAndroid Build Coastguard Worker
17*03ce13f7SAndroid Build Coastguard Worker #include "SpirvProfiler.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "SpirvShaderDebug.hpp"
19*03ce13f7SAndroid Build Coastguard Worker
20*03ce13f7SAndroid Build Coastguard Worker #include "Device/Context.hpp"
21*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp"
22*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkPipelineLayout.hpp"
23*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkRenderPass.hpp"
24*03ce13f7SAndroid Build Coastguard Worker
25*03ce13f7SAndroid Build Coastguard Worker #include "marl/defer.h"
26*03ce13f7SAndroid Build Coastguard Worker
27*03ce13f7SAndroid Build Coastguard Worker #include <spirv/unified1/spirv.hpp>
28*03ce13f7SAndroid Build Coastguard Worker
29*03ce13f7SAndroid Build Coastguard Worker namespace sw {
30*03ce13f7SAndroid Build Coastguard Worker
Spirv(VkShaderStageFlagBits pipelineStage,const char * entryPointName,const SpirvBinary & insns)31*03ce13f7SAndroid Build Coastguard Worker Spirv::Spirv(
32*03ce13f7SAndroid Build Coastguard Worker VkShaderStageFlagBits pipelineStage,
33*03ce13f7SAndroid Build Coastguard Worker const char *entryPointName,
34*03ce13f7SAndroid Build Coastguard Worker const SpirvBinary &insns)
35*03ce13f7SAndroid Build Coastguard Worker : insns{ insns }
36*03ce13f7SAndroid Build Coastguard Worker , inputs{ MAX_INTERFACE_COMPONENTS }
37*03ce13f7SAndroid Build Coastguard Worker , outputs{ MAX_INTERFACE_COMPONENTS }
38*03ce13f7SAndroid Build Coastguard Worker {
39*03ce13f7SAndroid Build Coastguard Worker ASSERT(insns.size() > 0);
40*03ce13f7SAndroid Build Coastguard Worker
41*03ce13f7SAndroid Build Coastguard Worker // The identifiers of all OpVariables that define the entry point's IO variables.
42*03ce13f7SAndroid Build Coastguard Worker std::unordered_set<Object::ID> interfaceIds;
43*03ce13f7SAndroid Build Coastguard Worker
44*03ce13f7SAndroid Build Coastguard Worker Function::ID currentFunction;
45*03ce13f7SAndroid Build Coastguard Worker Block::ID currentBlock;
46*03ce13f7SAndroid Build Coastguard Worker InsnIterator blockStart;
47*03ce13f7SAndroid Build Coastguard Worker
48*03ce13f7SAndroid Build Coastguard Worker for(auto insn : *this)
49*03ce13f7SAndroid Build Coastguard Worker {
50*03ce13f7SAndroid Build Coastguard Worker spv::Op opcode = insn.opcode();
51*03ce13f7SAndroid Build Coastguard Worker
52*03ce13f7SAndroid Build Coastguard Worker switch(opcode)
53*03ce13f7SAndroid Build Coastguard Worker {
54*03ce13f7SAndroid Build Coastguard Worker case spv::OpEntryPoint:
55*03ce13f7SAndroid Build Coastguard Worker {
56*03ce13f7SAndroid Build Coastguard Worker spv::ExecutionModel executionModel = spv::ExecutionModel(insn.word(1));
57*03ce13f7SAndroid Build Coastguard Worker Function::ID entryPoint = Function::ID(insn.word(2));
58*03ce13f7SAndroid Build Coastguard Worker const char *name = insn.string(3);
59*03ce13f7SAndroid Build Coastguard Worker VkShaderStageFlagBits stage = executionModelToStage(executionModel);
60*03ce13f7SAndroid Build Coastguard Worker
61*03ce13f7SAndroid Build Coastguard Worker if(stage == pipelineStage && strcmp(name, entryPointName) == 0)
62*03ce13f7SAndroid Build Coastguard Worker {
63*03ce13f7SAndroid Build Coastguard Worker ASSERT_MSG(this->entryPoint == 0, "Duplicate entry point with name '%s' and stage %d", name, int(stage));
64*03ce13f7SAndroid Build Coastguard Worker this->entryPoint = entryPoint;
65*03ce13f7SAndroid Build Coastguard Worker this->executionModel = executionModel;
66*03ce13f7SAndroid Build Coastguard Worker
67*03ce13f7SAndroid Build Coastguard Worker auto interfaceIdsOffset = 3 + insn.stringSizeInWords(3);
68*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = interfaceIdsOffset; i < insn.wordCount(); i++)
69*03ce13f7SAndroid Build Coastguard Worker {
70*03ce13f7SAndroid Build Coastguard Worker interfaceIds.emplace(insn.word(i));
71*03ce13f7SAndroid Build Coastguard Worker }
72*03ce13f7SAndroid Build Coastguard Worker }
73*03ce13f7SAndroid Build Coastguard Worker }
74*03ce13f7SAndroid Build Coastguard Worker break;
75*03ce13f7SAndroid Build Coastguard Worker
76*03ce13f7SAndroid Build Coastguard Worker case spv::OpExecutionMode:
77*03ce13f7SAndroid Build Coastguard Worker case spv::OpExecutionModeId:
78*03ce13f7SAndroid Build Coastguard Worker ProcessExecutionMode(insn);
79*03ce13f7SAndroid Build Coastguard Worker break;
80*03ce13f7SAndroid Build Coastguard Worker
81*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorate:
82*03ce13f7SAndroid Build Coastguard Worker {
83*03ce13f7SAndroid Build Coastguard Worker TypeOrObjectID targetId = insn.word(1);
84*03ce13f7SAndroid Build Coastguard Worker auto decoration = static_cast<spv::Decoration>(insn.word(2));
85*03ce13f7SAndroid Build Coastguard Worker uint32_t value = insn.wordCount() > 3 ? insn.word(3) : 0;
86*03ce13f7SAndroid Build Coastguard Worker
87*03ce13f7SAndroid Build Coastguard Worker decorations[targetId].Apply(decoration, value);
88*03ce13f7SAndroid Build Coastguard Worker
89*03ce13f7SAndroid Build Coastguard Worker switch(decoration)
90*03ce13f7SAndroid Build Coastguard Worker {
91*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationDescriptorSet:
92*03ce13f7SAndroid Build Coastguard Worker descriptorDecorations[targetId].DescriptorSet = value;
93*03ce13f7SAndroid Build Coastguard Worker break;
94*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationBinding:
95*03ce13f7SAndroid Build Coastguard Worker descriptorDecorations[targetId].Binding = value;
96*03ce13f7SAndroid Build Coastguard Worker break;
97*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationInputAttachmentIndex:
98*03ce13f7SAndroid Build Coastguard Worker descriptorDecorations[targetId].InputAttachmentIndex = value;
99*03ce13f7SAndroid Build Coastguard Worker break;
100*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationSample:
101*03ce13f7SAndroid Build Coastguard Worker analysis.ContainsSampleQualifier = true;
102*03ce13f7SAndroid Build Coastguard Worker break;
103*03ce13f7SAndroid Build Coastguard Worker default:
104*03ce13f7SAndroid Build Coastguard Worker // Only handling descriptor decorations here.
105*03ce13f7SAndroid Build Coastguard Worker break;
106*03ce13f7SAndroid Build Coastguard Worker }
107*03ce13f7SAndroid Build Coastguard Worker
108*03ce13f7SAndroid Build Coastguard Worker if(decoration == spv::DecorationCentroid)
109*03ce13f7SAndroid Build Coastguard Worker {
110*03ce13f7SAndroid Build Coastguard Worker analysis.NeedsCentroid = true;
111*03ce13f7SAndroid Build Coastguard Worker }
112*03ce13f7SAndroid Build Coastguard Worker }
113*03ce13f7SAndroid Build Coastguard Worker break;
114*03ce13f7SAndroid Build Coastguard Worker
115*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemberDecorate:
116*03ce13f7SAndroid Build Coastguard Worker {
117*03ce13f7SAndroid Build Coastguard Worker Type::ID targetId = insn.word(1);
118*03ce13f7SAndroid Build Coastguard Worker auto memberIndex = insn.word(2);
119*03ce13f7SAndroid Build Coastguard Worker auto decoration = static_cast<spv::Decoration>(insn.word(3));
120*03ce13f7SAndroid Build Coastguard Worker uint32_t value = insn.wordCount() > 4 ? insn.word(4) : 0;
121*03ce13f7SAndroid Build Coastguard Worker
122*03ce13f7SAndroid Build Coastguard Worker auto &d = memberDecorations[targetId];
123*03ce13f7SAndroid Build Coastguard Worker if(memberIndex >= d.size())
124*03ce13f7SAndroid Build Coastguard Worker d.resize(memberIndex + 1); // on demand; exact size would require another pass...
125*03ce13f7SAndroid Build Coastguard Worker
126*03ce13f7SAndroid Build Coastguard Worker d[memberIndex].Apply(decoration, value);
127*03ce13f7SAndroid Build Coastguard Worker
128*03ce13f7SAndroid Build Coastguard Worker if(decoration == spv::DecorationCentroid)
129*03ce13f7SAndroid Build Coastguard Worker {
130*03ce13f7SAndroid Build Coastguard Worker analysis.NeedsCentroid = true;
131*03ce13f7SAndroid Build Coastguard Worker }
132*03ce13f7SAndroid Build Coastguard Worker }
133*03ce13f7SAndroid Build Coastguard Worker break;
134*03ce13f7SAndroid Build Coastguard Worker
135*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorateId:
136*03ce13f7SAndroid Build Coastguard Worker {
137*03ce13f7SAndroid Build Coastguard Worker auto decoration = static_cast<spv::Decoration>(insn.word(2));
138*03ce13f7SAndroid Build Coastguard Worker
139*03ce13f7SAndroid Build Coastguard Worker // Currently OpDecorateId only supports UniformId, which provides information for
140*03ce13f7SAndroid Build Coastguard Worker // potential optimizations that we don't perform, and CounterBuffer, which is used
141*03ce13f7SAndroid Build Coastguard Worker // by HLSL to build the graphics pipeline with shader reflection. At the driver level,
142*03ce13f7SAndroid Build Coastguard Worker // the CounterBuffer decoration does nothing, so we can safely ignore both decorations.
143*03ce13f7SAndroid Build Coastguard Worker ASSERT(decoration == spv::DecorationUniformId || decoration == spv::DecorationCounterBuffer);
144*03ce13f7SAndroid Build Coastguard Worker }
145*03ce13f7SAndroid Build Coastguard Worker break;
146*03ce13f7SAndroid Build Coastguard Worker
147*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorateString:
148*03ce13f7SAndroid Build Coastguard Worker {
149*03ce13f7SAndroid Build Coastguard Worker auto decoration = static_cast<spv::Decoration>(insn.word(2));
150*03ce13f7SAndroid Build Coastguard Worker
151*03ce13f7SAndroid Build Coastguard Worker // We assume these are for HLSL semantics, ignore them (b/214576937).
152*03ce13f7SAndroid Build Coastguard Worker ASSERT(decoration == spv::DecorationUserSemantic || decoration == spv::DecorationUserTypeGOOGLE);
153*03ce13f7SAndroid Build Coastguard Worker }
154*03ce13f7SAndroid Build Coastguard Worker break;
155*03ce13f7SAndroid Build Coastguard Worker
156*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemberDecorateString:
157*03ce13f7SAndroid Build Coastguard Worker {
158*03ce13f7SAndroid Build Coastguard Worker auto decoration = static_cast<spv::Decoration>(insn.word(3));
159*03ce13f7SAndroid Build Coastguard Worker
160*03ce13f7SAndroid Build Coastguard Worker // We assume these are for HLSL semantics, ignore them (b/214576937).
161*03ce13f7SAndroid Build Coastguard Worker ASSERT(decoration == spv::DecorationUserSemantic || decoration == spv::DecorationUserTypeGOOGLE);
162*03ce13f7SAndroid Build Coastguard Worker }
163*03ce13f7SAndroid Build Coastguard Worker break;
164*03ce13f7SAndroid Build Coastguard Worker
165*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorationGroup:
166*03ce13f7SAndroid Build Coastguard Worker // Nothing to do here. We don't need to record the definition of the group; we'll just have
167*03ce13f7SAndroid Build Coastguard Worker // the bundle of decorations float around. If we were to ever walk the decorations directly,
168*03ce13f7SAndroid Build Coastguard Worker // we might think about introducing this as a real Object.
169*03ce13f7SAndroid Build Coastguard Worker break;
170*03ce13f7SAndroid Build Coastguard Worker
171*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupDecorate:
172*03ce13f7SAndroid Build Coastguard Worker {
173*03ce13f7SAndroid Build Coastguard Worker uint32_t group = insn.word(1);
174*03ce13f7SAndroid Build Coastguard Worker const auto &groupDecorations = decorations[group];
175*03ce13f7SAndroid Build Coastguard Worker const auto &descriptorGroupDecorations = descriptorDecorations[group];
176*03ce13f7SAndroid Build Coastguard Worker for(auto i = 2u; i < insn.wordCount(); i++)
177*03ce13f7SAndroid Build Coastguard Worker {
178*03ce13f7SAndroid Build Coastguard Worker // Remaining operands are targets to apply the group to.
179*03ce13f7SAndroid Build Coastguard Worker uint32_t target = insn.word(i);
180*03ce13f7SAndroid Build Coastguard Worker decorations[target].Apply(groupDecorations);
181*03ce13f7SAndroid Build Coastguard Worker descriptorDecorations[target].Apply(descriptorGroupDecorations);
182*03ce13f7SAndroid Build Coastguard Worker }
183*03ce13f7SAndroid Build Coastguard Worker }
184*03ce13f7SAndroid Build Coastguard Worker break;
185*03ce13f7SAndroid Build Coastguard Worker
186*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupMemberDecorate:
187*03ce13f7SAndroid Build Coastguard Worker {
188*03ce13f7SAndroid Build Coastguard Worker const auto &srcDecorations = decorations[insn.word(1)];
189*03ce13f7SAndroid Build Coastguard Worker for(auto i = 2u; i < insn.wordCount(); i += 2)
190*03ce13f7SAndroid Build Coastguard Worker {
191*03ce13f7SAndroid Build Coastguard Worker // remaining operands are pairs of <id>, literal for members to apply to.
192*03ce13f7SAndroid Build Coastguard Worker auto &d = memberDecorations[insn.word(i)];
193*03ce13f7SAndroid Build Coastguard Worker auto memberIndex = insn.word(i + 1);
194*03ce13f7SAndroid Build Coastguard Worker if(memberIndex >= d.size())
195*03ce13f7SAndroid Build Coastguard Worker d.resize(memberIndex + 1); // on demand resize, see above...
196*03ce13f7SAndroid Build Coastguard Worker d[memberIndex].Apply(srcDecorations);
197*03ce13f7SAndroid Build Coastguard Worker }
198*03ce13f7SAndroid Build Coastguard Worker }
199*03ce13f7SAndroid Build Coastguard Worker break;
200*03ce13f7SAndroid Build Coastguard Worker
201*03ce13f7SAndroid Build Coastguard Worker case spv::OpLabel:
202*03ce13f7SAndroid Build Coastguard Worker {
203*03ce13f7SAndroid Build Coastguard Worker ASSERT(currentBlock == 0);
204*03ce13f7SAndroid Build Coastguard Worker currentBlock = Block::ID(insn.word(1));
205*03ce13f7SAndroid Build Coastguard Worker blockStart = insn;
206*03ce13f7SAndroid Build Coastguard Worker }
207*03ce13f7SAndroid Build Coastguard Worker break;
208*03ce13f7SAndroid Build Coastguard Worker
209*03ce13f7SAndroid Build Coastguard Worker // Termination instructions:
210*03ce13f7SAndroid Build Coastguard Worker case spv::OpKill:
211*03ce13f7SAndroid Build Coastguard Worker case spv::OpTerminateInvocation:
212*03ce13f7SAndroid Build Coastguard Worker analysis.ContainsDiscard = true;
213*03ce13f7SAndroid Build Coastguard Worker // [[fallthrough]]
214*03ce13f7SAndroid Build Coastguard Worker
215*03ce13f7SAndroid Build Coastguard Worker case spv::OpUnreachable:
216*03ce13f7SAndroid Build Coastguard Worker
217*03ce13f7SAndroid Build Coastguard Worker // Branch Instructions (subset of Termination Instructions):
218*03ce13f7SAndroid Build Coastguard Worker case spv::OpBranch:
219*03ce13f7SAndroid Build Coastguard Worker case spv::OpBranchConditional:
220*03ce13f7SAndroid Build Coastguard Worker case spv::OpSwitch:
221*03ce13f7SAndroid Build Coastguard Worker case spv::OpReturn:
222*03ce13f7SAndroid Build Coastguard Worker {
223*03ce13f7SAndroid Build Coastguard Worker ASSERT(currentBlock != 0);
224*03ce13f7SAndroid Build Coastguard Worker ASSERT(currentFunction != 0);
225*03ce13f7SAndroid Build Coastguard Worker
226*03ce13f7SAndroid Build Coastguard Worker auto blockEnd = insn;
227*03ce13f7SAndroid Build Coastguard Worker blockEnd++;
228*03ce13f7SAndroid Build Coastguard Worker functions[currentFunction].blocks[currentBlock] = Block(blockStart, blockEnd);
229*03ce13f7SAndroid Build Coastguard Worker currentBlock = Block::ID(0);
230*03ce13f7SAndroid Build Coastguard Worker }
231*03ce13f7SAndroid Build Coastguard Worker break;
232*03ce13f7SAndroid Build Coastguard Worker
233*03ce13f7SAndroid Build Coastguard Worker case spv::OpDemoteToHelperInvocation:
234*03ce13f7SAndroid Build Coastguard Worker analysis.ContainsDiscard = true;
235*03ce13f7SAndroid Build Coastguard Worker break;
236*03ce13f7SAndroid Build Coastguard Worker
237*03ce13f7SAndroid Build Coastguard Worker case spv::OpLoopMerge:
238*03ce13f7SAndroid Build Coastguard Worker case spv::OpSelectionMerge:
239*03ce13f7SAndroid Build Coastguard Worker break; // Nothing to do in analysis pass.
240*03ce13f7SAndroid Build Coastguard Worker
241*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVoid:
242*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeBool:
243*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeInt:
244*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFloat:
245*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
246*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
247*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeImage:
248*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampler:
249*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampledImage:
250*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
251*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
252*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
253*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypePointer:
254*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeForwardPointer:
255*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFunction:
256*03ce13f7SAndroid Build Coastguard Worker DeclareType(insn);
257*03ce13f7SAndroid Build Coastguard Worker break;
258*03ce13f7SAndroid Build Coastguard Worker
259*03ce13f7SAndroid Build Coastguard Worker case spv::OpVariable:
260*03ce13f7SAndroid Build Coastguard Worker {
261*03ce13f7SAndroid Build Coastguard Worker Type::ID typeId = insn.word(1);
262*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
263*03ce13f7SAndroid Build Coastguard Worker auto storageClass = static_cast<spv::StorageClass>(insn.word(3));
264*03ce13f7SAndroid Build Coastguard Worker
265*03ce13f7SAndroid Build Coastguard Worker auto &object = defs[resultId];
266*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::Pointer;
267*03ce13f7SAndroid Build Coastguard Worker object.definition = insn;
268*03ce13f7SAndroid Build Coastguard Worker
269*03ce13f7SAndroid Build Coastguard Worker ASSERT(getType(typeId).definition.opcode() == spv::OpTypePointer);
270*03ce13f7SAndroid Build Coastguard Worker ASSERT(getType(typeId).storageClass == storageClass);
271*03ce13f7SAndroid Build Coastguard Worker
272*03ce13f7SAndroid Build Coastguard Worker switch(storageClass)
273*03ce13f7SAndroid Build Coastguard Worker {
274*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassInput:
275*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassOutput:
276*03ce13f7SAndroid Build Coastguard Worker if(interfaceIds.count(resultId))
277*03ce13f7SAndroid Build Coastguard Worker {
278*03ce13f7SAndroid Build Coastguard Worker ProcessInterfaceVariable(object);
279*03ce13f7SAndroid Build Coastguard Worker }
280*03ce13f7SAndroid Build Coastguard Worker break;
281*03ce13f7SAndroid Build Coastguard Worker
282*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassUniform:
283*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassStorageBuffer:
284*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassPhysicalStorageBuffer:
285*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::DescriptorSet;
286*03ce13f7SAndroid Build Coastguard Worker break;
287*03ce13f7SAndroid Build Coastguard Worker
288*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassPushConstant:
289*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassPrivate:
290*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassFunction:
291*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassUniformConstant:
292*03ce13f7SAndroid Build Coastguard Worker break; // Correctly handled.
293*03ce13f7SAndroid Build Coastguard Worker
294*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassWorkgroup:
295*03ce13f7SAndroid Build Coastguard Worker {
296*03ce13f7SAndroid Build Coastguard Worker auto &elTy = getType(getType(typeId).element);
297*03ce13f7SAndroid Build Coastguard Worker auto sizeInBytes = elTy.componentCount * static_cast<uint32_t>(sizeof(float));
298*03ce13f7SAndroid Build Coastguard Worker workgroupMemory.allocate(resultId, sizeInBytes);
299*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::Pointer;
300*03ce13f7SAndroid Build Coastguard Worker }
301*03ce13f7SAndroid Build Coastguard Worker break;
302*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassAtomicCounter:
303*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassImage:
304*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("StorageClass %d not yet supported", (int)storageClass);
305*03ce13f7SAndroid Build Coastguard Worker break;
306*03ce13f7SAndroid Build Coastguard Worker
307*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassCrossWorkgroup:
308*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V OpenCL Execution Model (StorageClassCrossWorkgroup)");
309*03ce13f7SAndroid Build Coastguard Worker break;
310*03ce13f7SAndroid Build Coastguard Worker
311*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassGeneric:
312*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V GenericPointer Capability (StorageClassGeneric)");
313*03ce13f7SAndroid Build Coastguard Worker break;
314*03ce13f7SAndroid Build Coastguard Worker
315*03ce13f7SAndroid Build Coastguard Worker default:
316*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Unexpected StorageClass %d", storageClass); // See Appendix A of the Vulkan spec.
317*03ce13f7SAndroid Build Coastguard Worker break;
318*03ce13f7SAndroid Build Coastguard Worker }
319*03ce13f7SAndroid Build Coastguard Worker }
320*03ce13f7SAndroid Build Coastguard Worker break;
321*03ce13f7SAndroid Build Coastguard Worker
322*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstant:
323*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstant:
324*03ce13f7SAndroid Build Coastguard Worker CreateConstant(insn).constantValue[0] = insn.word(3);
325*03ce13f7SAndroid Build Coastguard Worker break;
326*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantFalse:
327*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantFalse:
328*03ce13f7SAndroid Build Coastguard Worker CreateConstant(insn).constantValue[0] = 0; // Represent Boolean false as zero.
329*03ce13f7SAndroid Build Coastguard Worker break;
330*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantTrue:
331*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantTrue:
332*03ce13f7SAndroid Build Coastguard Worker CreateConstant(insn).constantValue[0] = ~0u; // Represent Boolean true as all bits set.
333*03ce13f7SAndroid Build Coastguard Worker break;
334*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantNull:
335*03ce13f7SAndroid Build Coastguard Worker case spv::OpUndef:
336*03ce13f7SAndroid Build Coastguard Worker {
337*03ce13f7SAndroid Build Coastguard Worker // TODO: consider a real LLVM-level undef. For now, zero is a perfectly good value.
338*03ce13f7SAndroid Build Coastguard Worker // OpConstantNull forms a constant of arbitrary type, all zeros.
339*03ce13f7SAndroid Build Coastguard Worker auto &object = CreateConstant(insn);
340*03ce13f7SAndroid Build Coastguard Worker auto &objectTy = getType(object);
341*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < objectTy.componentCount; i++)
342*03ce13f7SAndroid Build Coastguard Worker {
343*03ce13f7SAndroid Build Coastguard Worker object.constantValue[i] = 0;
344*03ce13f7SAndroid Build Coastguard Worker }
345*03ce13f7SAndroid Build Coastguard Worker }
346*03ce13f7SAndroid Build Coastguard Worker break;
347*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantComposite:
348*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantComposite:
349*03ce13f7SAndroid Build Coastguard Worker {
350*03ce13f7SAndroid Build Coastguard Worker auto &object = CreateConstant(insn);
351*03ce13f7SAndroid Build Coastguard Worker auto offset = 0u;
352*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < insn.wordCount() - 3; i++)
353*03ce13f7SAndroid Build Coastguard Worker {
354*03ce13f7SAndroid Build Coastguard Worker auto &constituent = getObject(insn.word(i + 3));
355*03ce13f7SAndroid Build Coastguard Worker auto &constituentTy = getType(constituent);
356*03ce13f7SAndroid Build Coastguard Worker for(auto j = 0u; j < constituentTy.componentCount; j++)
357*03ce13f7SAndroid Build Coastguard Worker {
358*03ce13f7SAndroid Build Coastguard Worker object.constantValue[offset++] = constituent.constantValue[j];
359*03ce13f7SAndroid Build Coastguard Worker }
360*03ce13f7SAndroid Build Coastguard Worker }
361*03ce13f7SAndroid Build Coastguard Worker
362*03ce13f7SAndroid Build Coastguard Worker auto objectId = Object::ID(insn.word(2));
363*03ce13f7SAndroid Build Coastguard Worker auto decorationsIt = decorations.find(objectId);
364*03ce13f7SAndroid Build Coastguard Worker if(decorationsIt != decorations.end() &&
365*03ce13f7SAndroid Build Coastguard Worker decorationsIt->second.BuiltIn == spv::BuiltInWorkgroupSize)
366*03ce13f7SAndroid Build Coastguard Worker {
367*03ce13f7SAndroid Build Coastguard Worker // https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#interfaces-builtin-variables :
368*03ce13f7SAndroid Build Coastguard Worker // Decorating an object with the WorkgroupSize built-in
369*03ce13f7SAndroid Build Coastguard Worker // decoration will make that object contain the dimensions
370*03ce13f7SAndroid Build Coastguard Worker // of a local workgroup. If an object is decorated with the
371*03ce13f7SAndroid Build Coastguard Worker // WorkgroupSize decoration, this must take precedence over
372*03ce13f7SAndroid Build Coastguard Worker // any execution mode set for LocalSize.
373*03ce13f7SAndroid Build Coastguard Worker // The object decorated with WorkgroupSize must be declared
374*03ce13f7SAndroid Build Coastguard Worker // as a three-component vector of 32-bit integers.
375*03ce13f7SAndroid Build Coastguard Worker ASSERT(getType(object).componentCount == 3);
376*03ce13f7SAndroid Build Coastguard Worker executionModes.WorkgroupSizeX = object.constantValue[0];
377*03ce13f7SAndroid Build Coastguard Worker executionModes.WorkgroupSizeY = object.constantValue[1];
378*03ce13f7SAndroid Build Coastguard Worker executionModes.WorkgroupSizeZ = object.constantValue[2];
379*03ce13f7SAndroid Build Coastguard Worker executionModes.useWorkgroupSizeId = false;
380*03ce13f7SAndroid Build Coastguard Worker }
381*03ce13f7SAndroid Build Coastguard Worker }
382*03ce13f7SAndroid Build Coastguard Worker break;
383*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantOp:
384*03ce13f7SAndroid Build Coastguard Worker EvalSpecConstantOp(insn);
385*03ce13f7SAndroid Build Coastguard Worker break;
386*03ce13f7SAndroid Build Coastguard Worker
387*03ce13f7SAndroid Build Coastguard Worker case spv::OpCapability:
388*03ce13f7SAndroid Build Coastguard Worker {
389*03ce13f7SAndroid Build Coastguard Worker auto capability = static_cast<spv::Capability>(insn.word(1));
390*03ce13f7SAndroid Build Coastguard Worker switch(capability)
391*03ce13f7SAndroid Build Coastguard Worker {
392*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityMatrix: capabilities.Matrix = true; break;
393*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityShader: capabilities.Shader = true; break;
394*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageImageMultisample: capabilities.StorageImageMultisample = true; break;
395*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityClipDistance: capabilities.ClipDistance = true; break;
396*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityCullDistance: capabilities.CullDistance = true; break;
397*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityImageCubeArray: capabilities.ImageCubeArray = true; break;
398*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilitySampleRateShading: capabilities.SampleRateShading = true; break;
399*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityInputAttachment: capabilities.InputAttachment = true; break;
400*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilitySampled1D: capabilities.Sampled1D = true; break;
401*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityImage1D: capabilities.Image1D = true; break;
402*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilitySampledBuffer: capabilities.SampledBuffer = true; break;
403*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilitySampledCubeArray: capabilities.SampledCubeArray = true; break;
404*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityImageBuffer: capabilities.ImageBuffer = true; break;
405*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityImageMSArray: capabilities.ImageMSArray = true; break;
406*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageImageExtendedFormats: capabilities.StorageImageExtendedFormats = true; break;
407*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityImageQuery: capabilities.ImageQuery = true; break;
408*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDerivativeControl: capabilities.DerivativeControl = true; break;
409*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDotProductInputAll: capabilities.DotProductInputAll = true; break;
410*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDotProductInput4x8Bit: capabilities.DotProductInput4x8Bit = true; break;
411*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDotProductInput4x8BitPacked: capabilities.DotProductInput4x8BitPacked = true; break;
412*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDotProduct: capabilities.DotProduct = true; break;
413*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityInterpolationFunction: capabilities.InterpolationFunction = true; break;
414*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageImageWriteWithoutFormat: capabilities.StorageImageWriteWithoutFormat = true; break;
415*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniform: capabilities.GroupNonUniform = true; break;
416*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniformVote: capabilities.GroupNonUniformVote = true; break;
417*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniformArithmetic: capabilities.GroupNonUniformArithmetic = true; break;
418*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniformBallot: capabilities.GroupNonUniformBallot = true; break;
419*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniformShuffle: capabilities.GroupNonUniformShuffle = true; break;
420*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniformShuffleRelative: capabilities.GroupNonUniformShuffleRelative = true; break;
421*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityGroupNonUniformQuad: capabilities.GroupNonUniformQuad = true; break;
422*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDeviceGroup: capabilities.DeviceGroup = true; break;
423*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityMultiView: capabilities.MultiView = true; break;
424*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilitySignedZeroInfNanPreserve: capabilities.SignedZeroInfNanPreserve = true; break;
425*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityDemoteToHelperInvocation: capabilities.DemoteToHelperInvocation = true; break;
426*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStencilExportEXT: capabilities.StencilExportEXT = true; break;
427*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityVulkanMemoryModel: capabilities.VulkanMemoryModel = true; break;
428*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityVulkanMemoryModelDeviceScope: capabilities.VulkanMemoryModelDeviceScope = true; break;
429*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityShaderNonUniform: capabilities.ShaderNonUniform = true; break;
430*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityRuntimeDescriptorArray: capabilities.RuntimeDescriptorArray = true; break;
431*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageBufferArrayNonUniformIndexing: capabilities.StorageBufferArrayNonUniformIndexing = true; break;
432*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageTexelBufferArrayNonUniformIndexing: capabilities.StorageTexelBufferArrayNonUniformIndexing = true; break;
433*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityUniformTexelBufferArrayNonUniformIndexing: capabilities.UniformTexelBufferArrayNonUniformIndexing = true; break;
434*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityUniformTexelBufferArrayDynamicIndexing: capabilities.UniformTexelBufferArrayDynamicIndexing = true; break;
435*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageTexelBufferArrayDynamicIndexing: capabilities.StorageTexelBufferArrayDynamicIndexing = true; break;
436*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityUniformBufferArrayNonUniformIndexing: capabilities.UniformBufferArrayNonUniformIndex = true; break;
437*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilitySampledImageArrayNonUniformIndexing: capabilities.SampledImageArrayNonUniformIndexing = true; break;
438*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityStorageImageArrayNonUniformIndexing: capabilities.StorageImageArrayNonUniformIndexing = true; break;
439*03ce13f7SAndroid Build Coastguard Worker case spv::CapabilityPhysicalStorageBufferAddresses: capabilities.PhysicalStorageBufferAddresses = true; break;
440*03ce13f7SAndroid Build Coastguard Worker default:
441*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("Unsupported capability %u", insn.word(1));
442*03ce13f7SAndroid Build Coastguard Worker }
443*03ce13f7SAndroid Build Coastguard Worker
444*03ce13f7SAndroid Build Coastguard Worker // Various capabilities will be declared, but none affect our code generation at this point.
445*03ce13f7SAndroid Build Coastguard Worker }
446*03ce13f7SAndroid Build Coastguard Worker break;
447*03ce13f7SAndroid Build Coastguard Worker
448*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemoryModel:
449*03ce13f7SAndroid Build Coastguard Worker {
450*03ce13f7SAndroid Build Coastguard Worker addressingModel = static_cast<spv::AddressingModel>(insn.word(1));
451*03ce13f7SAndroid Build Coastguard Worker memoryModel = static_cast<spv::MemoryModel>(insn.word(2));
452*03ce13f7SAndroid Build Coastguard Worker }
453*03ce13f7SAndroid Build Coastguard Worker break;
454*03ce13f7SAndroid Build Coastguard Worker
455*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunction:
456*03ce13f7SAndroid Build Coastguard Worker {
457*03ce13f7SAndroid Build Coastguard Worker auto functionId = Function::ID(insn.word(2));
458*03ce13f7SAndroid Build Coastguard Worker ASSERT_MSG(currentFunction == 0, "Functions %d and %d overlap", currentFunction.value(), functionId.value());
459*03ce13f7SAndroid Build Coastguard Worker currentFunction = functionId;
460*03ce13f7SAndroid Build Coastguard Worker auto &function = functions[functionId];
461*03ce13f7SAndroid Build Coastguard Worker function.result = Type::ID(insn.word(1));
462*03ce13f7SAndroid Build Coastguard Worker function.type = Type::ID(insn.word(4));
463*03ce13f7SAndroid Build Coastguard Worker // Scan forward to find the function's label.
464*03ce13f7SAndroid Build Coastguard Worker for(auto it = insn; it != end(); it++)
465*03ce13f7SAndroid Build Coastguard Worker {
466*03ce13f7SAndroid Build Coastguard Worker if(it.opcode() == spv::OpLabel)
467*03ce13f7SAndroid Build Coastguard Worker {
468*03ce13f7SAndroid Build Coastguard Worker function.entry = Block::ID(it.word(1));
469*03ce13f7SAndroid Build Coastguard Worker break;
470*03ce13f7SAndroid Build Coastguard Worker }
471*03ce13f7SAndroid Build Coastguard Worker }
472*03ce13f7SAndroid Build Coastguard Worker ASSERT_MSG(function.entry != 0, "Function<%d> has no label", currentFunction.value());
473*03ce13f7SAndroid Build Coastguard Worker }
474*03ce13f7SAndroid Build Coastguard Worker break;
475*03ce13f7SAndroid Build Coastguard Worker
476*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunctionEnd:
477*03ce13f7SAndroid Build Coastguard Worker currentFunction = 0;
478*03ce13f7SAndroid Build Coastguard Worker break;
479*03ce13f7SAndroid Build Coastguard Worker
480*03ce13f7SAndroid Build Coastguard Worker case spv::OpExtInstImport:
481*03ce13f7SAndroid Build Coastguard Worker {
482*03ce13f7SAndroid Build Coastguard Worker static constexpr std::pair<const char *, Extension::Name> extensionsByName[] = {
483*03ce13f7SAndroid Build Coastguard Worker { "GLSL.std.450", Extension::GLSLstd450 },
484*03ce13f7SAndroid Build Coastguard Worker { "NonSemantic.", Extension::NonSemanticInfo },
485*03ce13f7SAndroid Build Coastguard Worker };
486*03ce13f7SAndroid Build Coastguard Worker static constexpr auto extensionCount = sizeof(extensionsByName) / sizeof(extensionsByName[0]);
487*03ce13f7SAndroid Build Coastguard Worker
488*03ce13f7SAndroid Build Coastguard Worker auto id = Extension::ID(insn.word(1));
489*03ce13f7SAndroid Build Coastguard Worker auto name = insn.string(2);
490*03ce13f7SAndroid Build Coastguard Worker auto ext = Extension{ Extension::Unknown };
491*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0; i < extensionCount; i++)
492*03ce13f7SAndroid Build Coastguard Worker {
493*03ce13f7SAndroid Build Coastguard Worker if(0 == strncmp(name, extensionsByName[i].first, strlen(extensionsByName[i].first)))
494*03ce13f7SAndroid Build Coastguard Worker {
495*03ce13f7SAndroid Build Coastguard Worker ext = Extension{ extensionsByName[i].second };
496*03ce13f7SAndroid Build Coastguard Worker break;
497*03ce13f7SAndroid Build Coastguard Worker }
498*03ce13f7SAndroid Build Coastguard Worker }
499*03ce13f7SAndroid Build Coastguard Worker if(ext.name == Extension::Unknown)
500*03ce13f7SAndroid Build Coastguard Worker {
501*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V Extension: %s", name);
502*03ce13f7SAndroid Build Coastguard Worker break;
503*03ce13f7SAndroid Build Coastguard Worker }
504*03ce13f7SAndroid Build Coastguard Worker extensionsByID.emplace(id, ext);
505*03ce13f7SAndroid Build Coastguard Worker extensionsImported.emplace(ext.name);
506*03ce13f7SAndroid Build Coastguard Worker }
507*03ce13f7SAndroid Build Coastguard Worker break;
508*03ce13f7SAndroid Build Coastguard Worker case spv::OpName:
509*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemberName:
510*03ce13f7SAndroid Build Coastguard Worker case spv::OpSource:
511*03ce13f7SAndroid Build Coastguard Worker case spv::OpSourceContinued:
512*03ce13f7SAndroid Build Coastguard Worker case spv::OpSourceExtension:
513*03ce13f7SAndroid Build Coastguard Worker case spv::OpLine:
514*03ce13f7SAndroid Build Coastguard Worker case spv::OpNoLine:
515*03ce13f7SAndroid Build Coastguard Worker case spv::OpModuleProcessed:
516*03ce13f7SAndroid Build Coastguard Worker // No semantic impact
517*03ce13f7SAndroid Build Coastguard Worker break;
518*03ce13f7SAndroid Build Coastguard Worker
519*03ce13f7SAndroid Build Coastguard Worker case spv::OpString:
520*03ce13f7SAndroid Build Coastguard Worker strings.emplace(insn.word(1), insn.string(2));
521*03ce13f7SAndroid Build Coastguard Worker break;
522*03ce13f7SAndroid Build Coastguard Worker
523*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunctionParameter:
524*03ce13f7SAndroid Build Coastguard Worker // These should have all been removed by preprocessing passes. If we see them here,
525*03ce13f7SAndroid Build Coastguard Worker // our assumptions are wrong and we will probably generate wrong code.
526*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s should have already been lowered.", OpcodeName(opcode));
527*03ce13f7SAndroid Build Coastguard Worker break;
528*03ce13f7SAndroid Build Coastguard Worker
529*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunctionCall:
530*03ce13f7SAndroid Build Coastguard Worker // TODO(b/141246700): Add full support for spv::OpFunctionCall
531*03ce13f7SAndroid Build Coastguard Worker break;
532*03ce13f7SAndroid Build Coastguard Worker
533*03ce13f7SAndroid Build Coastguard Worker case spv::OpFConvert:
534*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V Float16 or Float64 Capability (OpFConvert)");
535*03ce13f7SAndroid Build Coastguard Worker break;
536*03ce13f7SAndroid Build Coastguard Worker
537*03ce13f7SAndroid Build Coastguard Worker case spv::OpSConvert:
538*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V Int16 or Int64 Capability (OpSConvert)");
539*03ce13f7SAndroid Build Coastguard Worker break;
540*03ce13f7SAndroid Build Coastguard Worker
541*03ce13f7SAndroid Build Coastguard Worker case spv::OpUConvert:
542*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V Int16 or Int64 Capability (OpUConvert)");
543*03ce13f7SAndroid Build Coastguard Worker break;
544*03ce13f7SAndroid Build Coastguard Worker
545*03ce13f7SAndroid Build Coastguard Worker case spv::OpLoad:
546*03ce13f7SAndroid Build Coastguard Worker case spv::OpAccessChain:
547*03ce13f7SAndroid Build Coastguard Worker case spv::OpInBoundsAccessChain:
548*03ce13f7SAndroid Build Coastguard Worker case spv::OpPtrAccessChain:
549*03ce13f7SAndroid Build Coastguard Worker case spv::OpSampledImage:
550*03ce13f7SAndroid Build Coastguard Worker case spv::OpImage:
551*03ce13f7SAndroid Build Coastguard Worker case spv::OpCopyObject:
552*03ce13f7SAndroid Build Coastguard Worker case spv::OpCopyLogical:
553*03ce13f7SAndroid Build Coastguard Worker {
554*03ce13f7SAndroid Build Coastguard Worker // Propagate the descriptor decorations to the result.
555*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
556*03ce13f7SAndroid Build Coastguard Worker Object::ID pointerId = insn.word(3);
557*03ce13f7SAndroid Build Coastguard Worker const auto &d = descriptorDecorations.find(pointerId);
558*03ce13f7SAndroid Build Coastguard Worker
559*03ce13f7SAndroid Build Coastguard Worker if(d != descriptorDecorations.end())
560*03ce13f7SAndroid Build Coastguard Worker {
561*03ce13f7SAndroid Build Coastguard Worker descriptorDecorations[resultId] = d->second;
562*03ce13f7SAndroid Build Coastguard Worker }
563*03ce13f7SAndroid Build Coastguard Worker
564*03ce13f7SAndroid Build Coastguard Worker DefineResult(insn);
565*03ce13f7SAndroid Build Coastguard Worker
566*03ce13f7SAndroid Build Coastguard Worker if(opcode == spv::OpAccessChain || opcode == spv::OpInBoundsAccessChain || opcode == spv::OpPtrAccessChain)
567*03ce13f7SAndroid Build Coastguard Worker {
568*03ce13f7SAndroid Build Coastguard Worker int indexId = (insn.opcode() == spv::OpPtrAccessChain) ? 5 : 4;
569*03ce13f7SAndroid Build Coastguard Worker Decorations dd{};
570*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForAccessChain(&dd, &descriptorDecorations[resultId], pointerId, Span(insn, indexId, insn.wordCount() - indexId));
571*03ce13f7SAndroid Build Coastguard Worker // Note: offset is the one thing that does *not* propagate, as the access chain accounts for it.
572*03ce13f7SAndroid Build Coastguard Worker dd.HasOffset = false;
573*03ce13f7SAndroid Build Coastguard Worker decorations[resultId].Apply(dd);
574*03ce13f7SAndroid Build Coastguard Worker }
575*03ce13f7SAndroid Build Coastguard Worker }
576*03ce13f7SAndroid Build Coastguard Worker break;
577*03ce13f7SAndroid Build Coastguard Worker
578*03ce13f7SAndroid Build Coastguard Worker case spv::OpCompositeConstruct:
579*03ce13f7SAndroid Build Coastguard Worker case spv::OpCompositeInsert:
580*03ce13f7SAndroid Build Coastguard Worker case spv::OpCompositeExtract:
581*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorShuffle:
582*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorTimesScalar:
583*03ce13f7SAndroid Build Coastguard Worker case spv::OpMatrixTimesScalar:
584*03ce13f7SAndroid Build Coastguard Worker case spv::OpMatrixTimesVector:
585*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorTimesMatrix:
586*03ce13f7SAndroid Build Coastguard Worker case spv::OpMatrixTimesMatrix:
587*03ce13f7SAndroid Build Coastguard Worker case spv::OpOuterProduct:
588*03ce13f7SAndroid Build Coastguard Worker case spv::OpTranspose:
589*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorExtractDynamic:
590*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorInsertDynamic:
591*03ce13f7SAndroid Build Coastguard Worker // Unary ops
592*03ce13f7SAndroid Build Coastguard Worker case spv::OpNot:
593*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitFieldInsert:
594*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitFieldSExtract:
595*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitFieldUExtract:
596*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitReverse:
597*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitCount:
598*03ce13f7SAndroid Build Coastguard Worker case spv::OpSNegate:
599*03ce13f7SAndroid Build Coastguard Worker case spv::OpFNegate:
600*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalNot:
601*03ce13f7SAndroid Build Coastguard Worker case spv::OpQuantizeToF16:
602*03ce13f7SAndroid Build Coastguard Worker // Binary ops
603*03ce13f7SAndroid Build Coastguard Worker case spv::OpIAdd:
604*03ce13f7SAndroid Build Coastguard Worker case spv::OpISub:
605*03ce13f7SAndroid Build Coastguard Worker case spv::OpIMul:
606*03ce13f7SAndroid Build Coastguard Worker case spv::OpSDiv:
607*03ce13f7SAndroid Build Coastguard Worker case spv::OpUDiv:
608*03ce13f7SAndroid Build Coastguard Worker case spv::OpFAdd:
609*03ce13f7SAndroid Build Coastguard Worker case spv::OpFSub:
610*03ce13f7SAndroid Build Coastguard Worker case spv::OpFMul:
611*03ce13f7SAndroid Build Coastguard Worker case spv::OpFDiv:
612*03ce13f7SAndroid Build Coastguard Worker case spv::OpFMod:
613*03ce13f7SAndroid Build Coastguard Worker case spv::OpFRem:
614*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdEqual:
615*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordEqual:
616*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdNotEqual:
617*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordNotEqual:
618*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdLessThan:
619*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordLessThan:
620*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdGreaterThan:
621*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordGreaterThan:
622*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdLessThanEqual:
623*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordLessThanEqual:
624*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdGreaterThanEqual:
625*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordGreaterThanEqual:
626*03ce13f7SAndroid Build Coastguard Worker case spv::OpSMod:
627*03ce13f7SAndroid Build Coastguard Worker case spv::OpSRem:
628*03ce13f7SAndroid Build Coastguard Worker case spv::OpUMod:
629*03ce13f7SAndroid Build Coastguard Worker case spv::OpIEqual:
630*03ce13f7SAndroid Build Coastguard Worker case spv::OpINotEqual:
631*03ce13f7SAndroid Build Coastguard Worker case spv::OpUGreaterThan:
632*03ce13f7SAndroid Build Coastguard Worker case spv::OpSGreaterThan:
633*03ce13f7SAndroid Build Coastguard Worker case spv::OpUGreaterThanEqual:
634*03ce13f7SAndroid Build Coastguard Worker case spv::OpSGreaterThanEqual:
635*03ce13f7SAndroid Build Coastguard Worker case spv::OpULessThan:
636*03ce13f7SAndroid Build Coastguard Worker case spv::OpSLessThan:
637*03ce13f7SAndroid Build Coastguard Worker case spv::OpULessThanEqual:
638*03ce13f7SAndroid Build Coastguard Worker case spv::OpSLessThanEqual:
639*03ce13f7SAndroid Build Coastguard Worker case spv::OpShiftRightLogical:
640*03ce13f7SAndroid Build Coastguard Worker case spv::OpShiftRightArithmetic:
641*03ce13f7SAndroid Build Coastguard Worker case spv::OpShiftLeftLogical:
642*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitwiseOr:
643*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitwiseXor:
644*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitwiseAnd:
645*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalOr:
646*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalAnd:
647*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalEqual:
648*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalNotEqual:
649*03ce13f7SAndroid Build Coastguard Worker case spv::OpUMulExtended:
650*03ce13f7SAndroid Build Coastguard Worker case spv::OpSMulExtended:
651*03ce13f7SAndroid Build Coastguard Worker case spv::OpIAddCarry:
652*03ce13f7SAndroid Build Coastguard Worker case spv::OpISubBorrow:
653*03ce13f7SAndroid Build Coastguard Worker case spv::OpDot:
654*03ce13f7SAndroid Build Coastguard Worker case spv::OpSDot:
655*03ce13f7SAndroid Build Coastguard Worker case spv::OpUDot:
656*03ce13f7SAndroid Build Coastguard Worker case spv::OpSUDot:
657*03ce13f7SAndroid Build Coastguard Worker case spv::OpSDotAccSat:
658*03ce13f7SAndroid Build Coastguard Worker case spv::OpUDotAccSat:
659*03ce13f7SAndroid Build Coastguard Worker case spv::OpSUDotAccSat:
660*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertFToU:
661*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertFToS:
662*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertSToF:
663*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertUToF:
664*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitcast:
665*03ce13f7SAndroid Build Coastguard Worker case spv::OpSelect:
666*03ce13f7SAndroid Build Coastguard Worker case spv::OpIsInf:
667*03ce13f7SAndroid Build Coastguard Worker case spv::OpIsNan:
668*03ce13f7SAndroid Build Coastguard Worker case spv::OpAny:
669*03ce13f7SAndroid Build Coastguard Worker case spv::OpAll:
670*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdx:
671*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdxCoarse:
672*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdy:
673*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdyCoarse:
674*03ce13f7SAndroid Build Coastguard Worker case spv::OpFwidth:
675*03ce13f7SAndroid Build Coastguard Worker case spv::OpFwidthCoarse:
676*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdxFine:
677*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdyFine:
678*03ce13f7SAndroid Build Coastguard Worker case spv::OpFwidthFine:
679*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicLoad:
680*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIAdd:
681*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicISub:
682*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicSMin:
683*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicSMax:
684*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicUMin:
685*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicUMax:
686*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicAnd:
687*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicOr:
688*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicXor:
689*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIIncrement:
690*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIDecrement:
691*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicExchange:
692*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicCompareExchange:
693*03ce13f7SAndroid Build Coastguard Worker case spv::OpPhi:
694*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleImplicitLod:
695*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleExplicitLod:
696*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleDrefImplicitLod:
697*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleDrefExplicitLod:
698*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjImplicitLod:
699*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjExplicitLod:
700*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjDrefImplicitLod:
701*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjDrefExplicitLod:
702*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageGather:
703*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageDrefGather:
704*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageFetch:
705*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQuerySizeLod:
706*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQuerySize:
707*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQueryLod:
708*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQueryLevels:
709*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQuerySamples:
710*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageRead:
711*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageTexelPointer:
712*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformElect:
713*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformAll:
714*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformAny:
715*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformAllEqual:
716*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBroadcast:
717*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBroadcastFirst:
718*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformQuadBroadcast:
719*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformQuadSwap:
720*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallot:
721*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformInverseBallot:
722*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotBitExtract:
723*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotBitCount:
724*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotFindLSB:
725*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotFindMSB:
726*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffle:
727*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffleXor:
728*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffleUp:
729*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffleDown:
730*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformIAdd:
731*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFAdd:
732*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformIMul:
733*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFMul:
734*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformSMin:
735*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformUMin:
736*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFMin:
737*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformSMax:
738*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformUMax:
739*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFMax:
740*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBitwiseAnd:
741*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBitwiseOr:
742*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBitwiseXor:
743*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformLogicalAnd:
744*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformLogicalOr:
745*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformLogicalXor:
746*03ce13f7SAndroid Build Coastguard Worker case spv::OpArrayLength:
747*03ce13f7SAndroid Build Coastguard Worker case spv::OpIsHelperInvocationEXT:
748*03ce13f7SAndroid Build Coastguard Worker // Instructions that yield an intermediate value or divergent pointer
749*03ce13f7SAndroid Build Coastguard Worker DefineResult(insn);
750*03ce13f7SAndroid Build Coastguard Worker break;
751*03ce13f7SAndroid Build Coastguard Worker
752*03ce13f7SAndroid Build Coastguard Worker case spv::OpExtInst:
753*03ce13f7SAndroid Build Coastguard Worker switch(getExtension(insn.word(3)).name)
754*03ce13f7SAndroid Build Coastguard Worker {
755*03ce13f7SAndroid Build Coastguard Worker case Extension::GLSLstd450:
756*03ce13f7SAndroid Build Coastguard Worker DefineResult(insn);
757*03ce13f7SAndroid Build Coastguard Worker break;
758*03ce13f7SAndroid Build Coastguard Worker case Extension::NonSemanticInfo:
759*03ce13f7SAndroid Build Coastguard Worker // An extended set name which is prefixed with "NonSemantic." is
760*03ce13f7SAndroid Build Coastguard Worker // guaranteed to contain only non-semantic instructions and all
761*03ce13f7SAndroid Build Coastguard Worker // OpExtInst instructions referencing this set can be ignored.
762*03ce13f7SAndroid Build Coastguard Worker break;
763*03ce13f7SAndroid Build Coastguard Worker default:
764*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Unexpected Extension name %d", int(getExtension(insn.word(3)).name));
765*03ce13f7SAndroid Build Coastguard Worker break;
766*03ce13f7SAndroid Build Coastguard Worker }
767*03ce13f7SAndroid Build Coastguard Worker break;
768*03ce13f7SAndroid Build Coastguard Worker
769*03ce13f7SAndroid Build Coastguard Worker case spv::OpStore:
770*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicStore:
771*03ce13f7SAndroid Build Coastguard Worker case spv::OpCopyMemory:
772*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemoryBarrier:
773*03ce13f7SAndroid Build Coastguard Worker // Don't need to do anything during analysis pass
774*03ce13f7SAndroid Build Coastguard Worker break;
775*03ce13f7SAndroid Build Coastguard Worker
776*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageWrite:
777*03ce13f7SAndroid Build Coastguard Worker analysis.ContainsImageWrite = true;
778*03ce13f7SAndroid Build Coastguard Worker break;
779*03ce13f7SAndroid Build Coastguard Worker
780*03ce13f7SAndroid Build Coastguard Worker case spv::OpControlBarrier:
781*03ce13f7SAndroid Build Coastguard Worker analysis.ContainsControlBarriers = true;
782*03ce13f7SAndroid Build Coastguard Worker break;
783*03ce13f7SAndroid Build Coastguard Worker
784*03ce13f7SAndroid Build Coastguard Worker case spv::OpExtension:
785*03ce13f7SAndroid Build Coastguard Worker {
786*03ce13f7SAndroid Build Coastguard Worker const char *ext = insn.string(1);
787*03ce13f7SAndroid Build Coastguard Worker // Part of core SPIR-V 1.3. Vulkan 1.1 implementations must also accept the pre-1.3
788*03ce13f7SAndroid Build Coastguard Worker // extension per Appendix A, `Vulkan Environment for SPIR-V`.
789*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_storage_buffer_storage_class")) break;
790*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_shader_draw_parameters")) break;
791*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_16bit_storage")) break;
792*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_variable_pointers")) break;
793*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_device_group")) break;
794*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_multiview")) break;
795*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_EXT_demote_to_helper_invocation")) break;
796*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_terminate_invocation")) break;
797*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_EXT_shader_stencil_export")) break;
798*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_float_controls")) break;
799*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_integer_dot_product")) break;
800*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_non_semantic_info")) break;
801*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_physical_storage_buffer")) break;
802*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_KHR_vulkan_memory_model")) break;
803*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_GOOGLE_decorate_string")) break;
804*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_GOOGLE_hlsl_functionality1")) break;
805*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_GOOGLE_user_type")) break;
806*03ce13f7SAndroid Build Coastguard Worker if(!strcmp(ext, "SPV_EXT_descriptor_indexing")) break;
807*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("SPIR-V Extension: %s", ext);
808*03ce13f7SAndroid Build Coastguard Worker }
809*03ce13f7SAndroid Build Coastguard Worker break;
810*03ce13f7SAndroid Build Coastguard Worker
811*03ce13f7SAndroid Build Coastguard Worker default:
812*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("%s", OpcodeName(opcode));
813*03ce13f7SAndroid Build Coastguard Worker }
814*03ce13f7SAndroid Build Coastguard Worker }
815*03ce13f7SAndroid Build Coastguard Worker
816*03ce13f7SAndroid Build Coastguard Worker ASSERT_MSG(entryPoint != 0, "Entry point '%s' not found", entryPointName);
817*03ce13f7SAndroid Build Coastguard Worker for(auto &it : functions)
818*03ce13f7SAndroid Build Coastguard Worker {
819*03ce13f7SAndroid Build Coastguard Worker it.second.AssignBlockFields();
820*03ce13f7SAndroid Build Coastguard Worker }
821*03ce13f7SAndroid Build Coastguard Worker
822*03ce13f7SAndroid Build Coastguard Worker #ifdef SPIRV_SHADER_CFG_GRAPHVIZ_DOT_FILEPATH
823*03ce13f7SAndroid Build Coastguard Worker {
824*03ce13f7SAndroid Build Coastguard Worker char path[1024];
825*03ce13f7SAndroid Build Coastguard Worker snprintf(path, sizeof(path), SPIRV_SHADER_CFG_GRAPHVIZ_DOT_FILEPATH, codeSerialID);
826*03ce13f7SAndroid Build Coastguard Worker WriteCFGGraphVizDotFile(path);
827*03ce13f7SAndroid Build Coastguard Worker }
828*03ce13f7SAndroid Build Coastguard Worker #endif
829*03ce13f7SAndroid Build Coastguard Worker }
830*03ce13f7SAndroid Build Coastguard Worker
~Spirv()831*03ce13f7SAndroid Build Coastguard Worker Spirv::~Spirv()
832*03ce13f7SAndroid Build Coastguard Worker {
833*03ce13f7SAndroid Build Coastguard Worker }
834*03ce13f7SAndroid Build Coastguard Worker
DeclareType(InsnIterator insn)835*03ce13f7SAndroid Build Coastguard Worker void Spirv::DeclareType(InsnIterator insn)
836*03ce13f7SAndroid Build Coastguard Worker {
837*03ce13f7SAndroid Build Coastguard Worker Type::ID resultId = insn.word(1);
838*03ce13f7SAndroid Build Coastguard Worker
839*03ce13f7SAndroid Build Coastguard Worker auto &type = types[resultId];
840*03ce13f7SAndroid Build Coastguard Worker type.definition = insn;
841*03ce13f7SAndroid Build Coastguard Worker type.componentCount = ComputeTypeSize(insn);
842*03ce13f7SAndroid Build Coastguard Worker
843*03ce13f7SAndroid Build Coastguard Worker // A structure is a builtin block if it has a builtin
844*03ce13f7SAndroid Build Coastguard Worker // member. All members of such a structure are builtins.
845*03ce13f7SAndroid Build Coastguard Worker spv::Op opcode = insn.opcode();
846*03ce13f7SAndroid Build Coastguard Worker switch(opcode)
847*03ce13f7SAndroid Build Coastguard Worker {
848*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
849*03ce13f7SAndroid Build Coastguard Worker {
850*03ce13f7SAndroid Build Coastguard Worker auto d = memberDecorations.find(resultId);
851*03ce13f7SAndroid Build Coastguard Worker if(d != memberDecorations.end())
852*03ce13f7SAndroid Build Coastguard Worker {
853*03ce13f7SAndroid Build Coastguard Worker for(auto &m : d->second)
854*03ce13f7SAndroid Build Coastguard Worker {
855*03ce13f7SAndroid Build Coastguard Worker if(m.HasBuiltIn)
856*03ce13f7SAndroid Build Coastguard Worker {
857*03ce13f7SAndroid Build Coastguard Worker type.isBuiltInBlock = true;
858*03ce13f7SAndroid Build Coastguard Worker break;
859*03ce13f7SAndroid Build Coastguard Worker }
860*03ce13f7SAndroid Build Coastguard Worker }
861*03ce13f7SAndroid Build Coastguard Worker }
862*03ce13f7SAndroid Build Coastguard Worker }
863*03ce13f7SAndroid Build Coastguard Worker break;
864*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypePointer:
865*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeForwardPointer:
866*03ce13f7SAndroid Build Coastguard Worker {
867*03ce13f7SAndroid Build Coastguard Worker Type::ID elementTypeId = insn.word((opcode == spv::OpTypeForwardPointer) ? 1 : 3);
868*03ce13f7SAndroid Build Coastguard Worker type.element = elementTypeId;
869*03ce13f7SAndroid Build Coastguard Worker type.isBuiltInBlock = getType(elementTypeId).isBuiltInBlock;
870*03ce13f7SAndroid Build Coastguard Worker type.storageClass = static_cast<spv::StorageClass>(insn.word(2));
871*03ce13f7SAndroid Build Coastguard Worker }
872*03ce13f7SAndroid Build Coastguard Worker break;
873*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
874*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
875*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
876*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
877*03ce13f7SAndroid Build Coastguard Worker {
878*03ce13f7SAndroid Build Coastguard Worker Type::ID elementTypeId = insn.word(2);
879*03ce13f7SAndroid Build Coastguard Worker type.element = elementTypeId;
880*03ce13f7SAndroid Build Coastguard Worker }
881*03ce13f7SAndroid Build Coastguard Worker break;
882*03ce13f7SAndroid Build Coastguard Worker default:
883*03ce13f7SAndroid Build Coastguard Worker break;
884*03ce13f7SAndroid Build Coastguard Worker }
885*03ce13f7SAndroid Build Coastguard Worker }
886*03ce13f7SAndroid Build Coastguard Worker
CreateConstant(InsnIterator insn)887*03ce13f7SAndroid Build Coastguard Worker Spirv::Object &Spirv::CreateConstant(InsnIterator insn)
888*03ce13f7SAndroid Build Coastguard Worker {
889*03ce13f7SAndroid Build Coastguard Worker Type::ID typeId = insn.word(1);
890*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
891*03ce13f7SAndroid Build Coastguard Worker auto &object = defs[resultId];
892*03ce13f7SAndroid Build Coastguard Worker auto &objectTy = getType(typeId);
893*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::Constant;
894*03ce13f7SAndroid Build Coastguard Worker object.definition = insn;
895*03ce13f7SAndroid Build Coastguard Worker object.constantValue.resize(objectTy.componentCount);
896*03ce13f7SAndroid Build Coastguard Worker
897*03ce13f7SAndroid Build Coastguard Worker return object;
898*03ce13f7SAndroid Build Coastguard Worker }
899*03ce13f7SAndroid Build Coastguard Worker
ProcessInterfaceVariable(Object & object)900*03ce13f7SAndroid Build Coastguard Worker void Spirv::ProcessInterfaceVariable(Object &object)
901*03ce13f7SAndroid Build Coastguard Worker {
902*03ce13f7SAndroid Build Coastguard Worker auto &objectTy = getType(object);
903*03ce13f7SAndroid Build Coastguard Worker ASSERT(objectTy.storageClass == spv::StorageClassInput || objectTy.storageClass == spv::StorageClassOutput);
904*03ce13f7SAndroid Build Coastguard Worker
905*03ce13f7SAndroid Build Coastguard Worker ASSERT(objectTy.opcode() == spv::OpTypePointer);
906*03ce13f7SAndroid Build Coastguard Worker auto pointeeTy = getType(objectTy.element);
907*03ce13f7SAndroid Build Coastguard Worker
908*03ce13f7SAndroid Build Coastguard Worker auto &builtinInterface = (objectTy.storageClass == spv::StorageClassInput) ? inputBuiltins : outputBuiltins;
909*03ce13f7SAndroid Build Coastguard Worker auto &userDefinedInterface = (objectTy.storageClass == spv::StorageClassInput) ? inputs : outputs;
910*03ce13f7SAndroid Build Coastguard Worker
911*03ce13f7SAndroid Build Coastguard Worker ASSERT(object.opcode() == spv::OpVariable);
912*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = object.definition.word(2);
913*03ce13f7SAndroid Build Coastguard Worker
914*03ce13f7SAndroid Build Coastguard Worker if(objectTy.isBuiltInBlock)
915*03ce13f7SAndroid Build Coastguard Worker {
916*03ce13f7SAndroid Build Coastguard Worker // Walk the builtin block, registering each of its members separately.
917*03ce13f7SAndroid Build Coastguard Worker auto m = memberDecorations.find(objectTy.element);
918*03ce13f7SAndroid Build Coastguard Worker ASSERT(m != memberDecorations.end()); // Otherwise we wouldn't have marked the type chain
919*03ce13f7SAndroid Build Coastguard Worker auto &structType = pointeeTy.definition;
920*03ce13f7SAndroid Build Coastguard Worker auto memberIndex = 0u;
921*03ce13f7SAndroid Build Coastguard Worker auto offset = 0u;
922*03ce13f7SAndroid Build Coastguard Worker
923*03ce13f7SAndroid Build Coastguard Worker for(auto &member : m->second)
924*03ce13f7SAndroid Build Coastguard Worker {
925*03ce13f7SAndroid Build Coastguard Worker auto &memberType = getType(structType.word(2 + memberIndex));
926*03ce13f7SAndroid Build Coastguard Worker
927*03ce13f7SAndroid Build Coastguard Worker if(member.HasBuiltIn)
928*03ce13f7SAndroid Build Coastguard Worker {
929*03ce13f7SAndroid Build Coastguard Worker builtinInterface[member.BuiltIn] = { resultId, offset, memberType.componentCount };
930*03ce13f7SAndroid Build Coastguard Worker }
931*03ce13f7SAndroid Build Coastguard Worker
932*03ce13f7SAndroid Build Coastguard Worker offset += memberType.componentCount;
933*03ce13f7SAndroid Build Coastguard Worker ++memberIndex;
934*03ce13f7SAndroid Build Coastguard Worker }
935*03ce13f7SAndroid Build Coastguard Worker
936*03ce13f7SAndroid Build Coastguard Worker return;
937*03ce13f7SAndroid Build Coastguard Worker }
938*03ce13f7SAndroid Build Coastguard Worker
939*03ce13f7SAndroid Build Coastguard Worker auto d = decorations.find(resultId);
940*03ce13f7SAndroid Build Coastguard Worker if(d != decorations.end() && d->second.HasBuiltIn)
941*03ce13f7SAndroid Build Coastguard Worker {
942*03ce13f7SAndroid Build Coastguard Worker builtinInterface[d->second.BuiltIn] = { resultId, 0, pointeeTy.componentCount };
943*03ce13f7SAndroid Build Coastguard Worker }
944*03ce13f7SAndroid Build Coastguard Worker else
945*03ce13f7SAndroid Build Coastguard Worker {
946*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::InterfaceVariable;
947*03ce13f7SAndroid Build Coastguard Worker VisitInterface(resultId,
948*03ce13f7SAndroid Build Coastguard Worker [&userDefinedInterface](const Decorations &d, AttribType type) {
949*03ce13f7SAndroid Build Coastguard Worker // Populate a single scalar slot in the interface from a collection of decorations and the intended component type.
950*03ce13f7SAndroid Build Coastguard Worker int32_t scalarSlot = (d.Location << 2) | d.Component;
951*03ce13f7SAndroid Build Coastguard Worker ASSERT(scalarSlot >= 0 &&
952*03ce13f7SAndroid Build Coastguard Worker scalarSlot < static_cast<int32_t>(userDefinedInterface.size()));
953*03ce13f7SAndroid Build Coastguard Worker
954*03ce13f7SAndroid Build Coastguard Worker auto &slot = userDefinedInterface[scalarSlot];
955*03ce13f7SAndroid Build Coastguard Worker slot.Type = type;
956*03ce13f7SAndroid Build Coastguard Worker slot.Flat = d.Flat;
957*03ce13f7SAndroid Build Coastguard Worker slot.NoPerspective = d.NoPerspective;
958*03ce13f7SAndroid Build Coastguard Worker slot.Centroid = d.Centroid;
959*03ce13f7SAndroid Build Coastguard Worker });
960*03ce13f7SAndroid Build Coastguard Worker }
961*03ce13f7SAndroid Build Coastguard Worker }
962*03ce13f7SAndroid Build Coastguard Worker
GetNumInputComponents(int32_t location) const963*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::GetNumInputComponents(int32_t location) const
964*03ce13f7SAndroid Build Coastguard Worker {
965*03ce13f7SAndroid Build Coastguard Worker ASSERT(location >= 0);
966*03ce13f7SAndroid Build Coastguard Worker
967*03ce13f7SAndroid Build Coastguard Worker // Verify how many component(s) per input
968*03ce13f7SAndroid Build Coastguard Worker // 1 to 4, for float, vec2, vec3, vec4.
969*03ce13f7SAndroid Build Coastguard Worker // Note that matrices are divided over multiple inputs
970*03ce13f7SAndroid Build Coastguard Worker uint32_t num_components_per_input = 0;
971*03ce13f7SAndroid Build Coastguard Worker for(; num_components_per_input < 4; ++num_components_per_input)
972*03ce13f7SAndroid Build Coastguard Worker {
973*03ce13f7SAndroid Build Coastguard Worker if(inputs[(location << 2) | num_components_per_input].Type == ATTRIBTYPE_UNUSED)
974*03ce13f7SAndroid Build Coastguard Worker {
975*03ce13f7SAndroid Build Coastguard Worker break;
976*03ce13f7SAndroid Build Coastguard Worker }
977*03ce13f7SAndroid Build Coastguard Worker }
978*03ce13f7SAndroid Build Coastguard Worker
979*03ce13f7SAndroid Build Coastguard Worker return num_components_per_input;
980*03ce13f7SAndroid Build Coastguard Worker }
981*03ce13f7SAndroid Build Coastguard Worker
GetPackedInterpolant(int32_t location) const982*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::GetPackedInterpolant(int32_t location) const
983*03ce13f7SAndroid Build Coastguard Worker {
984*03ce13f7SAndroid Build Coastguard Worker ASSERT(location >= 0);
985*03ce13f7SAndroid Build Coastguard Worker const uint32_t maxInterpolant = (location << 2);
986*03ce13f7SAndroid Build Coastguard Worker
987*03ce13f7SAndroid Build Coastguard Worker // Return the number of used components only at location
988*03ce13f7SAndroid Build Coastguard Worker uint32_t packedInterpolant = 0;
989*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < maxInterpolant; ++i)
990*03ce13f7SAndroid Build Coastguard Worker {
991*03ce13f7SAndroid Build Coastguard Worker if(inputs[i].Type != ATTRIBTYPE_UNUSED)
992*03ce13f7SAndroid Build Coastguard Worker {
993*03ce13f7SAndroid Build Coastguard Worker ++packedInterpolant;
994*03ce13f7SAndroid Build Coastguard Worker }
995*03ce13f7SAndroid Build Coastguard Worker }
996*03ce13f7SAndroid Build Coastguard Worker
997*03ce13f7SAndroid Build Coastguard Worker return packedInterpolant;
998*03ce13f7SAndroid Build Coastguard Worker }
999*03ce13f7SAndroid Build Coastguard Worker
ProcessExecutionMode(InsnIterator insn)1000*03ce13f7SAndroid Build Coastguard Worker void Spirv::ProcessExecutionMode(InsnIterator insn)
1001*03ce13f7SAndroid Build Coastguard Worker {
1002*03ce13f7SAndroid Build Coastguard Worker Function::ID function = insn.word(1);
1003*03ce13f7SAndroid Build Coastguard Worker if(function != entryPoint)
1004*03ce13f7SAndroid Build Coastguard Worker {
1005*03ce13f7SAndroid Build Coastguard Worker return;
1006*03ce13f7SAndroid Build Coastguard Worker }
1007*03ce13f7SAndroid Build Coastguard Worker
1008*03ce13f7SAndroid Build Coastguard Worker auto mode = static_cast<spv::ExecutionMode>(insn.word(2));
1009*03ce13f7SAndroid Build Coastguard Worker switch(mode)
1010*03ce13f7SAndroid Build Coastguard Worker {
1011*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeEarlyFragmentTests:
1012*03ce13f7SAndroid Build Coastguard Worker executionModes.EarlyFragmentTests = true;
1013*03ce13f7SAndroid Build Coastguard Worker break;
1014*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeDepthReplacing:
1015*03ce13f7SAndroid Build Coastguard Worker executionModes.DepthReplacing = true;
1016*03ce13f7SAndroid Build Coastguard Worker break;
1017*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeDepthGreater:
1018*03ce13f7SAndroid Build Coastguard Worker // TODO(b/177915067): Can be used to optimize depth test, currently unused.
1019*03ce13f7SAndroid Build Coastguard Worker executionModes.DepthGreater = true;
1020*03ce13f7SAndroid Build Coastguard Worker break;
1021*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeDepthLess:
1022*03ce13f7SAndroid Build Coastguard Worker // TODO(b/177915067): Can be used to optimize depth test, currently unused.
1023*03ce13f7SAndroid Build Coastguard Worker executionModes.DepthLess = true;
1024*03ce13f7SAndroid Build Coastguard Worker break;
1025*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeDepthUnchanged:
1026*03ce13f7SAndroid Build Coastguard Worker // TODO(b/177915067): Can be used to optimize depth test, currently unused.
1027*03ce13f7SAndroid Build Coastguard Worker executionModes.DepthUnchanged = true;
1028*03ce13f7SAndroid Build Coastguard Worker break;
1029*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeStencilRefReplacingEXT:
1030*03ce13f7SAndroid Build Coastguard Worker executionModes.StencilRefReplacing = true;
1031*03ce13f7SAndroid Build Coastguard Worker break;
1032*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeLocalSize:
1033*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeLocalSizeId:
1034*03ce13f7SAndroid Build Coastguard Worker executionModes.WorkgroupSizeX = insn.word(3);
1035*03ce13f7SAndroid Build Coastguard Worker executionModes.WorkgroupSizeY = insn.word(4);
1036*03ce13f7SAndroid Build Coastguard Worker executionModes.WorkgroupSizeZ = insn.word(5);
1037*03ce13f7SAndroid Build Coastguard Worker executionModes.useWorkgroupSizeId = (mode == spv::ExecutionModeLocalSizeId);
1038*03ce13f7SAndroid Build Coastguard Worker break;
1039*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeOriginUpperLeft:
1040*03ce13f7SAndroid Build Coastguard Worker // This is always the case for a Vulkan shader. Do nothing.
1041*03ce13f7SAndroid Build Coastguard Worker break;
1042*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModeSignedZeroInfNanPreserve:
1043*03ce13f7SAndroid Build Coastguard Worker // We currently don't perform any aggressive fast-math optimizations.
1044*03ce13f7SAndroid Build Coastguard Worker break;
1045*03ce13f7SAndroid Build Coastguard Worker default:
1046*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Execution mode: %d", int(mode));
1047*03ce13f7SAndroid Build Coastguard Worker }
1048*03ce13f7SAndroid Build Coastguard Worker }
1049*03ce13f7SAndroid Build Coastguard Worker
getWorkgroupSizeX() const1050*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::getWorkgroupSizeX() const
1051*03ce13f7SAndroid Build Coastguard Worker {
1052*03ce13f7SAndroid Build Coastguard Worker return executionModes.useWorkgroupSizeId ? getObject(executionModes.WorkgroupSizeX).constantValue[0] : executionModes.WorkgroupSizeX.value();
1053*03ce13f7SAndroid Build Coastguard Worker }
1054*03ce13f7SAndroid Build Coastguard Worker
getWorkgroupSizeY() const1055*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::getWorkgroupSizeY() const
1056*03ce13f7SAndroid Build Coastguard Worker {
1057*03ce13f7SAndroid Build Coastguard Worker return executionModes.useWorkgroupSizeId ? getObject(executionModes.WorkgroupSizeY).constantValue[0] : executionModes.WorkgroupSizeY.value();
1058*03ce13f7SAndroid Build Coastguard Worker }
1059*03ce13f7SAndroid Build Coastguard Worker
getWorkgroupSizeZ() const1060*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::getWorkgroupSizeZ() const
1061*03ce13f7SAndroid Build Coastguard Worker {
1062*03ce13f7SAndroid Build Coastguard Worker return executionModes.useWorkgroupSizeId ? getObject(executionModes.WorkgroupSizeZ).constantValue[0] : executionModes.WorkgroupSizeZ.value();
1063*03ce13f7SAndroid Build Coastguard Worker }
1064*03ce13f7SAndroid Build Coastguard Worker
ComputeTypeSize(InsnIterator insn)1065*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::ComputeTypeSize(InsnIterator insn)
1066*03ce13f7SAndroid Build Coastguard Worker {
1067*03ce13f7SAndroid Build Coastguard Worker // Types are always built from the bottom up (with the exception of forward ptrs, which
1068*03ce13f7SAndroid Build Coastguard Worker // don't appear in Vulkan shaders. Therefore, we can always assume our component parts have
1069*03ce13f7SAndroid Build Coastguard Worker // already been described (and so their sizes determined)
1070*03ce13f7SAndroid Build Coastguard Worker switch(insn.opcode())
1071*03ce13f7SAndroid Build Coastguard Worker {
1072*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVoid:
1073*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampler:
1074*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeImage:
1075*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampledImage:
1076*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeForwardPointer:
1077*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFunction:
1078*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
1079*03ce13f7SAndroid Build Coastguard Worker // Objects that don't consume any space.
1080*03ce13f7SAndroid Build Coastguard Worker // Descriptor-backed objects currently only need exist at compile-time.
1081*03ce13f7SAndroid Build Coastguard Worker // Runtime arrays don't appear in places where their size would be interesting
1082*03ce13f7SAndroid Build Coastguard Worker return 0;
1083*03ce13f7SAndroid Build Coastguard Worker
1084*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeBool:
1085*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFloat:
1086*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeInt:
1087*03ce13f7SAndroid Build Coastguard Worker // All the fundamental types are 1 component. If we ever add support for 8/16/64-bit components,
1088*03ce13f7SAndroid Build Coastguard Worker // we might need to change this, but only 32 bit components are required for Vulkan 1.1.
1089*03ce13f7SAndroid Build Coastguard Worker return 1;
1090*03ce13f7SAndroid Build Coastguard Worker
1091*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
1092*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
1093*03ce13f7SAndroid Build Coastguard Worker // Vectors and matrices both consume element count * element size.
1094*03ce13f7SAndroid Build Coastguard Worker return getType(insn.word(2)).componentCount * insn.word(3);
1095*03ce13f7SAndroid Build Coastguard Worker
1096*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
1097*03ce13f7SAndroid Build Coastguard Worker {
1098*03ce13f7SAndroid Build Coastguard Worker // Element count * element size. Array sizes come from constant ids.
1099*03ce13f7SAndroid Build Coastguard Worker auto arraySize = GetConstScalarInt(insn.word(3));
1100*03ce13f7SAndroid Build Coastguard Worker return getType(insn.word(2)).componentCount * arraySize;
1101*03ce13f7SAndroid Build Coastguard Worker }
1102*03ce13f7SAndroid Build Coastguard Worker
1103*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
1104*03ce13f7SAndroid Build Coastguard Worker {
1105*03ce13f7SAndroid Build Coastguard Worker uint32_t size = 0;
1106*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 2u; i < insn.wordCount(); i++)
1107*03ce13f7SAndroid Build Coastguard Worker {
1108*03ce13f7SAndroid Build Coastguard Worker size += getType(insn.word(i)).componentCount;
1109*03ce13f7SAndroid Build Coastguard Worker }
1110*03ce13f7SAndroid Build Coastguard Worker return size;
1111*03ce13f7SAndroid Build Coastguard Worker }
1112*03ce13f7SAndroid Build Coastguard Worker
1113*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypePointer:
1114*03ce13f7SAndroid Build Coastguard Worker // Runtime representation of a pointer is a per-lane index.
1115*03ce13f7SAndroid Build Coastguard Worker // Note: clients are expected to look through the pointer if they want the pointee size instead.
1116*03ce13f7SAndroid Build Coastguard Worker return 1;
1117*03ce13f7SAndroid Build Coastguard Worker
1118*03ce13f7SAndroid Build Coastguard Worker default:
1119*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s", OpcodeName(insn.opcode()));
1120*03ce13f7SAndroid Build Coastguard Worker return 0;
1121*03ce13f7SAndroid Build Coastguard Worker }
1122*03ce13f7SAndroid Build Coastguard Worker }
1123*03ce13f7SAndroid Build Coastguard Worker
VisitInterfaceInner(Type::ID id,Decorations d,const InterfaceVisitor & f) const1124*03ce13f7SAndroid Build Coastguard Worker int Spirv::VisitInterfaceInner(Type::ID id, Decorations d, const InterfaceVisitor &f) const
1125*03ce13f7SAndroid Build Coastguard Worker {
1126*03ce13f7SAndroid Build Coastguard Worker // Recursively walks variable definition and its type tree, taking into account
1127*03ce13f7SAndroid Build Coastguard Worker // any explicit Location or Component decorations encountered; where explicit
1128*03ce13f7SAndroid Build Coastguard Worker // Locations or Components are not specified, assigns them sequentially.
1129*03ce13f7SAndroid Build Coastguard Worker // Collected decorations are carried down toward the leaves and across
1130*03ce13f7SAndroid Build Coastguard Worker // siblings; Effect of decorations intentionally does not flow back up the tree.
1131*03ce13f7SAndroid Build Coastguard Worker //
1132*03ce13f7SAndroid Build Coastguard Worker // F is a functor to be called with the effective decoration set for every component.
1133*03ce13f7SAndroid Build Coastguard Worker //
1134*03ce13f7SAndroid Build Coastguard Worker // Returns the next available location, and calls f().
1135*03ce13f7SAndroid Build Coastguard Worker
1136*03ce13f7SAndroid Build Coastguard Worker // This covers the rules in Vulkan 1.1 spec, 14.1.4 Location Assignment.
1137*03ce13f7SAndroid Build Coastguard Worker
1138*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForId(&d, id);
1139*03ce13f7SAndroid Build Coastguard Worker
1140*03ce13f7SAndroid Build Coastguard Worker const auto &obj = getType(id);
1141*03ce13f7SAndroid Build Coastguard Worker switch(obj.opcode())
1142*03ce13f7SAndroid Build Coastguard Worker {
1143*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypePointer:
1144*03ce13f7SAndroid Build Coastguard Worker return VisitInterfaceInner(obj.definition.word(3), d, f);
1145*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
1146*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < obj.definition.word(3); i++, d.Location++)
1147*03ce13f7SAndroid Build Coastguard Worker {
1148*03ce13f7SAndroid Build Coastguard Worker // consumes same components of N consecutive locations
1149*03ce13f7SAndroid Build Coastguard Worker VisitInterfaceInner(obj.definition.word(2), d, f);
1150*03ce13f7SAndroid Build Coastguard Worker }
1151*03ce13f7SAndroid Build Coastguard Worker return d.Location;
1152*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
1153*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < obj.definition.word(3); i++, d.Component++)
1154*03ce13f7SAndroid Build Coastguard Worker {
1155*03ce13f7SAndroid Build Coastguard Worker // consumes N consecutive components in the same location
1156*03ce13f7SAndroid Build Coastguard Worker VisitInterfaceInner(obj.definition.word(2), d, f);
1157*03ce13f7SAndroid Build Coastguard Worker }
1158*03ce13f7SAndroid Build Coastguard Worker return d.Location + 1;
1159*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFloat:
1160*03ce13f7SAndroid Build Coastguard Worker f(d, ATTRIBTYPE_FLOAT);
1161*03ce13f7SAndroid Build Coastguard Worker return d.Location + 1;
1162*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeInt:
1163*03ce13f7SAndroid Build Coastguard Worker f(d, obj.definition.word(3) ? ATTRIBTYPE_INT : ATTRIBTYPE_UINT);
1164*03ce13f7SAndroid Build Coastguard Worker return d.Location + 1;
1165*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeBool:
1166*03ce13f7SAndroid Build Coastguard Worker f(d, ATTRIBTYPE_UINT);
1167*03ce13f7SAndroid Build Coastguard Worker return d.Location + 1;
1168*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
1169*03ce13f7SAndroid Build Coastguard Worker {
1170*03ce13f7SAndroid Build Coastguard Worker // iterate over members, which may themselves have Location/Component decorations
1171*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < obj.definition.wordCount() - 2; i++)
1172*03ce13f7SAndroid Build Coastguard Worker {
1173*03ce13f7SAndroid Build Coastguard Worker Decorations dMember = d;
1174*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForIdMember(&dMember, id, i);
1175*03ce13f7SAndroid Build Coastguard Worker d.Location = VisitInterfaceInner(obj.definition.word(i + 2), dMember, f);
1176*03ce13f7SAndroid Build Coastguard Worker d.Component = 0; // Implicit locations always have component=0
1177*03ce13f7SAndroid Build Coastguard Worker }
1178*03ce13f7SAndroid Build Coastguard Worker return d.Location;
1179*03ce13f7SAndroid Build Coastguard Worker }
1180*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
1181*03ce13f7SAndroid Build Coastguard Worker {
1182*03ce13f7SAndroid Build Coastguard Worker auto arraySize = GetConstScalarInt(obj.definition.word(3));
1183*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < arraySize; i++)
1184*03ce13f7SAndroid Build Coastguard Worker {
1185*03ce13f7SAndroid Build Coastguard Worker d.Location = VisitInterfaceInner(obj.definition.word(2), d, f);
1186*03ce13f7SAndroid Build Coastguard Worker }
1187*03ce13f7SAndroid Build Coastguard Worker return d.Location;
1188*03ce13f7SAndroid Build Coastguard Worker }
1189*03ce13f7SAndroid Build Coastguard Worker default:
1190*03ce13f7SAndroid Build Coastguard Worker // Intentionally partial; most opcodes do not participate in type hierarchies
1191*03ce13f7SAndroid Build Coastguard Worker return 0;
1192*03ce13f7SAndroid Build Coastguard Worker }
1193*03ce13f7SAndroid Build Coastguard Worker }
1194*03ce13f7SAndroid Build Coastguard Worker
VisitInterface(Object::ID id,const InterfaceVisitor & f) const1195*03ce13f7SAndroid Build Coastguard Worker void Spirv::VisitInterface(Object::ID id, const InterfaceVisitor &f) const
1196*03ce13f7SAndroid Build Coastguard Worker {
1197*03ce13f7SAndroid Build Coastguard Worker // Walk a variable definition and call f for each component in it.
1198*03ce13f7SAndroid Build Coastguard Worker Decorations d = GetDecorationsForId(id);
1199*03ce13f7SAndroid Build Coastguard Worker
1200*03ce13f7SAndroid Build Coastguard Worker auto def = getObject(id).definition;
1201*03ce13f7SAndroid Build Coastguard Worker ASSERT(def.opcode() == spv::OpVariable);
1202*03ce13f7SAndroid Build Coastguard Worker VisitInterfaceInner(def.word(1), d, f);
1203*03ce13f7SAndroid Build Coastguard Worker }
1204*03ce13f7SAndroid Build Coastguard Worker
ApplyDecorationsForAccessChain(Decorations * d,DescriptorDecorations * dd,Object::ID baseId,const Span & indexIds) const1205*03ce13f7SAndroid Build Coastguard Worker void Spirv::ApplyDecorationsForAccessChain(Decorations *d, DescriptorDecorations *dd, Object::ID baseId, const Span &indexIds) const
1206*03ce13f7SAndroid Build Coastguard Worker {
1207*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForId(d, baseId);
1208*03ce13f7SAndroid Build Coastguard Worker auto &baseObject = getObject(baseId);
1209*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForId(d, baseObject.typeId());
1210*03ce13f7SAndroid Build Coastguard Worker auto typeId = getType(baseObject).element;
1211*03ce13f7SAndroid Build Coastguard Worker
1212*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < indexIds.size(); i++)
1213*03ce13f7SAndroid Build Coastguard Worker {
1214*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForId(d, typeId);
1215*03ce13f7SAndroid Build Coastguard Worker auto &type = getType(typeId);
1216*03ce13f7SAndroid Build Coastguard Worker switch(type.opcode())
1217*03ce13f7SAndroid Build Coastguard Worker {
1218*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
1219*03ce13f7SAndroid Build Coastguard Worker {
1220*03ce13f7SAndroid Build Coastguard Worker int memberIndex = GetConstScalarInt(indexIds[i]);
1221*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForIdMember(d, typeId, memberIndex);
1222*03ce13f7SAndroid Build Coastguard Worker typeId = type.definition.word(2u + memberIndex);
1223*03ce13f7SAndroid Build Coastguard Worker }
1224*03ce13f7SAndroid Build Coastguard Worker break;
1225*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
1226*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
1227*03ce13f7SAndroid Build Coastguard Worker if(dd->InputAttachmentIndex >= 0)
1228*03ce13f7SAndroid Build Coastguard Worker {
1229*03ce13f7SAndroid Build Coastguard Worker dd->InputAttachmentIndex += GetConstScalarInt(indexIds[i]);
1230*03ce13f7SAndroid Build Coastguard Worker }
1231*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1232*03ce13f7SAndroid Build Coastguard Worker break;
1233*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
1234*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1235*03ce13f7SAndroid Build Coastguard Worker break;
1236*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
1237*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1238*03ce13f7SAndroid Build Coastguard Worker d->InsideMatrix = true;
1239*03ce13f7SAndroid Build Coastguard Worker break;
1240*03ce13f7SAndroid Build Coastguard Worker default:
1241*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s", OpcodeName(type.definition.opcode()));
1242*03ce13f7SAndroid Build Coastguard Worker }
1243*03ce13f7SAndroid Build Coastguard Worker }
1244*03ce13f7SAndroid Build Coastguard Worker }
1245*03ce13f7SAndroid Build Coastguard Worker
WalkExplicitLayoutAccessChain(Object::ID baseId,Object::ID elementId,const Span & indexIds,bool nonUniform) const1246*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer SpirvEmitter::WalkExplicitLayoutAccessChain(Object::ID baseId, Object::ID elementId, const Span &indexIds, bool nonUniform) const
1247*03ce13f7SAndroid Build Coastguard Worker {
1248*03ce13f7SAndroid Build Coastguard Worker // Produce a offset into external memory in sizeof(float) units
1249*03ce13f7SAndroid Build Coastguard Worker
1250*03ce13f7SAndroid Build Coastguard Worker auto &baseObject = shader.getObject(baseId);
1251*03ce13f7SAndroid Build Coastguard Worker Type::ID typeId = shader.getType(baseObject).element;
1252*03ce13f7SAndroid Build Coastguard Worker Decorations d = shader.GetDecorationsForId(baseObject.typeId());
1253*03ce13f7SAndroid Build Coastguard Worker SIMD::Int arrayIndex = 0;
1254*03ce13f7SAndroid Build Coastguard Worker
1255*03ce13f7SAndroid Build Coastguard Worker uint32_t start = 0;
1256*03ce13f7SAndroid Build Coastguard Worker if(baseObject.kind == Object::Kind::DescriptorSet)
1257*03ce13f7SAndroid Build Coastguard Worker {
1258*03ce13f7SAndroid Build Coastguard Worker auto type = shader.getType(typeId).definition.opcode();
1259*03ce13f7SAndroid Build Coastguard Worker if(type == spv::OpTypeArray || type == spv::OpTypeRuntimeArray)
1260*03ce13f7SAndroid Build Coastguard Worker {
1261*03ce13f7SAndroid Build Coastguard Worker auto &obj = shader.getObject(indexIds[0]);
1262*03ce13f7SAndroid Build Coastguard Worker ASSERT(obj.kind == Object::Kind::Constant || obj.kind == Object::Kind::Intermediate);
1263*03ce13f7SAndroid Build Coastguard Worker if(obj.kind == Object::Kind::Constant)
1264*03ce13f7SAndroid Build Coastguard Worker {
1265*03ce13f7SAndroid Build Coastguard Worker arrayIndex = shader.GetConstScalarInt(indexIds[0]);
1266*03ce13f7SAndroid Build Coastguard Worker }
1267*03ce13f7SAndroid Build Coastguard Worker else
1268*03ce13f7SAndroid Build Coastguard Worker {
1269*03ce13f7SAndroid Build Coastguard Worker nonUniform |= shader.GetDecorationsForId(indexIds[0]).NonUniform;
1270*03ce13f7SAndroid Build Coastguard Worker arrayIndex = getIntermediate(indexIds[0]).Int(0);
1271*03ce13f7SAndroid Build Coastguard Worker }
1272*03ce13f7SAndroid Build Coastguard Worker
1273*03ce13f7SAndroid Build Coastguard Worker start = 1;
1274*03ce13f7SAndroid Build Coastguard Worker typeId = shader.getType(typeId).element;
1275*03ce13f7SAndroid Build Coastguard Worker }
1276*03ce13f7SAndroid Build Coastguard Worker }
1277*03ce13f7SAndroid Build Coastguard Worker
1278*03ce13f7SAndroid Build Coastguard Worker auto ptr = GetPointerToData(baseId, arrayIndex, nonUniform);
1279*03ce13f7SAndroid Build Coastguard Worker OffsetToElement(ptr, elementId, d.ArrayStride);
1280*03ce13f7SAndroid Build Coastguard Worker
1281*03ce13f7SAndroid Build Coastguard Worker int constantOffset = 0;
1282*03ce13f7SAndroid Build Coastguard Worker
1283*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = start; i < indexIds.size(); i++)
1284*03ce13f7SAndroid Build Coastguard Worker {
1285*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(typeId);
1286*03ce13f7SAndroid Build Coastguard Worker shader.ApplyDecorationsForId(&d, typeId);
1287*03ce13f7SAndroid Build Coastguard Worker
1288*03ce13f7SAndroid Build Coastguard Worker switch(type.definition.opcode())
1289*03ce13f7SAndroid Build Coastguard Worker {
1290*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
1291*03ce13f7SAndroid Build Coastguard Worker {
1292*03ce13f7SAndroid Build Coastguard Worker int memberIndex = shader.GetConstScalarInt(indexIds[i]);
1293*03ce13f7SAndroid Build Coastguard Worker shader.ApplyDecorationsForIdMember(&d, typeId, memberIndex);
1294*03ce13f7SAndroid Build Coastguard Worker ASSERT(d.HasOffset);
1295*03ce13f7SAndroid Build Coastguard Worker constantOffset += d.Offset;
1296*03ce13f7SAndroid Build Coastguard Worker typeId = type.definition.word(2u + memberIndex);
1297*03ce13f7SAndroid Build Coastguard Worker }
1298*03ce13f7SAndroid Build Coastguard Worker break;
1299*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
1300*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
1301*03ce13f7SAndroid Build Coastguard Worker {
1302*03ce13f7SAndroid Build Coastguard Worker // TODO: b/127950082: Check bounds.
1303*03ce13f7SAndroid Build Coastguard Worker ASSERT(d.HasArrayStride);
1304*03ce13f7SAndroid Build Coastguard Worker auto &obj = shader.getObject(indexIds[i]);
1305*03ce13f7SAndroid Build Coastguard Worker if(obj.kind == Object::Kind::Constant)
1306*03ce13f7SAndroid Build Coastguard Worker {
1307*03ce13f7SAndroid Build Coastguard Worker constantOffset += d.ArrayStride * shader.GetConstScalarInt(indexIds[i]);
1308*03ce13f7SAndroid Build Coastguard Worker }
1309*03ce13f7SAndroid Build Coastguard Worker else
1310*03ce13f7SAndroid Build Coastguard Worker {
1311*03ce13f7SAndroid Build Coastguard Worker ptr += SIMD::Int(d.ArrayStride) * getIntermediate(indexIds[i]).Int(0);
1312*03ce13f7SAndroid Build Coastguard Worker }
1313*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1314*03ce13f7SAndroid Build Coastguard Worker }
1315*03ce13f7SAndroid Build Coastguard Worker break;
1316*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
1317*03ce13f7SAndroid Build Coastguard Worker {
1318*03ce13f7SAndroid Build Coastguard Worker // TODO: b/127950082: Check bounds.
1319*03ce13f7SAndroid Build Coastguard Worker ASSERT(d.HasMatrixStride);
1320*03ce13f7SAndroid Build Coastguard Worker d.InsideMatrix = true;
1321*03ce13f7SAndroid Build Coastguard Worker auto columnStride = (d.HasRowMajor && d.RowMajor) ? static_cast<int32_t>(sizeof(float)) : d.MatrixStride;
1322*03ce13f7SAndroid Build Coastguard Worker auto &obj = shader.getObject(indexIds[i]);
1323*03ce13f7SAndroid Build Coastguard Worker if(obj.kind == Object::Kind::Constant)
1324*03ce13f7SAndroid Build Coastguard Worker {
1325*03ce13f7SAndroid Build Coastguard Worker constantOffset += columnStride * shader.GetConstScalarInt(indexIds[i]);
1326*03ce13f7SAndroid Build Coastguard Worker }
1327*03ce13f7SAndroid Build Coastguard Worker else
1328*03ce13f7SAndroid Build Coastguard Worker {
1329*03ce13f7SAndroid Build Coastguard Worker ptr += SIMD::Int(columnStride) * getIntermediate(indexIds[i]).Int(0);
1330*03ce13f7SAndroid Build Coastguard Worker }
1331*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1332*03ce13f7SAndroid Build Coastguard Worker }
1333*03ce13f7SAndroid Build Coastguard Worker break;
1334*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
1335*03ce13f7SAndroid Build Coastguard Worker {
1336*03ce13f7SAndroid Build Coastguard Worker auto elemStride = (d.InsideMatrix && d.HasRowMajor && d.RowMajor) ? d.MatrixStride : static_cast<int32_t>(sizeof(float));
1337*03ce13f7SAndroid Build Coastguard Worker auto &obj = shader.getObject(indexIds[i]);
1338*03ce13f7SAndroid Build Coastguard Worker if(obj.kind == Object::Kind::Constant)
1339*03ce13f7SAndroid Build Coastguard Worker {
1340*03ce13f7SAndroid Build Coastguard Worker constantOffset += elemStride * shader.GetConstScalarInt(indexIds[i]);
1341*03ce13f7SAndroid Build Coastguard Worker }
1342*03ce13f7SAndroid Build Coastguard Worker else
1343*03ce13f7SAndroid Build Coastguard Worker {
1344*03ce13f7SAndroid Build Coastguard Worker ptr += SIMD::Int(elemStride) * getIntermediate(indexIds[i]).Int(0);
1345*03ce13f7SAndroid Build Coastguard Worker }
1346*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1347*03ce13f7SAndroid Build Coastguard Worker }
1348*03ce13f7SAndroid Build Coastguard Worker break;
1349*03ce13f7SAndroid Build Coastguard Worker default:
1350*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s", shader.OpcodeName(type.definition.opcode()));
1351*03ce13f7SAndroid Build Coastguard Worker }
1352*03ce13f7SAndroid Build Coastguard Worker }
1353*03ce13f7SAndroid Build Coastguard Worker
1354*03ce13f7SAndroid Build Coastguard Worker ptr += constantOffset;
1355*03ce13f7SAndroid Build Coastguard Worker return ptr;
1356*03ce13f7SAndroid Build Coastguard Worker }
1357*03ce13f7SAndroid Build Coastguard Worker
WalkAccessChain(Object::ID baseId,Object::ID elementId,const Span & indexIds,bool nonUniform) const1358*03ce13f7SAndroid Build Coastguard Worker SIMD::Pointer SpirvEmitter::WalkAccessChain(Object::ID baseId, Object::ID elementId, const Span &indexIds, bool nonUniform) const
1359*03ce13f7SAndroid Build Coastguard Worker {
1360*03ce13f7SAndroid Build Coastguard Worker // TODO: avoid doing per-lane work in some cases if we can?
1361*03ce13f7SAndroid Build Coastguard Worker auto &baseObject = shader.getObject(baseId);
1362*03ce13f7SAndroid Build Coastguard Worker Type::ID typeId = shader.getType(baseObject).element;
1363*03ce13f7SAndroid Build Coastguard Worker Decorations d = shader.GetDecorationsForId(baseObject.typeId());
1364*03ce13f7SAndroid Build Coastguard Worker auto storageClass = shader.getType(baseObject).storageClass;
1365*03ce13f7SAndroid Build Coastguard Worker bool interleavedByLane = IsStorageInterleavedByLane(storageClass);
1366*03ce13f7SAndroid Build Coastguard Worker
1367*03ce13f7SAndroid Build Coastguard Worker auto ptr = getPointer(baseId);
1368*03ce13f7SAndroid Build Coastguard Worker OffsetToElement(ptr, elementId, d.ArrayStride);
1369*03ce13f7SAndroid Build Coastguard Worker
1370*03ce13f7SAndroid Build Coastguard Worker int constantOffset = 0;
1371*03ce13f7SAndroid Build Coastguard Worker
1372*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < indexIds.size(); i++)
1373*03ce13f7SAndroid Build Coastguard Worker {
1374*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(typeId);
1375*03ce13f7SAndroid Build Coastguard Worker switch(type.opcode())
1376*03ce13f7SAndroid Build Coastguard Worker {
1377*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
1378*03ce13f7SAndroid Build Coastguard Worker {
1379*03ce13f7SAndroid Build Coastguard Worker int memberIndex = shader.GetConstScalarInt(indexIds[i]);
1380*03ce13f7SAndroid Build Coastguard Worker int offsetIntoStruct = 0;
1381*03ce13f7SAndroid Build Coastguard Worker for(auto j = 0; j < memberIndex; j++)
1382*03ce13f7SAndroid Build Coastguard Worker {
1383*03ce13f7SAndroid Build Coastguard Worker auto memberType = type.definition.word(2u + j);
1384*03ce13f7SAndroid Build Coastguard Worker offsetIntoStruct += shader.getType(memberType).componentCount * sizeof(float);
1385*03ce13f7SAndroid Build Coastguard Worker }
1386*03ce13f7SAndroid Build Coastguard Worker constantOffset += offsetIntoStruct;
1387*03ce13f7SAndroid Build Coastguard Worker typeId = type.definition.word(2u + memberIndex);
1388*03ce13f7SAndroid Build Coastguard Worker }
1389*03ce13f7SAndroid Build Coastguard Worker break;
1390*03ce13f7SAndroid Build Coastguard Worker
1391*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
1392*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
1393*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
1394*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
1395*03ce13f7SAndroid Build Coastguard Worker {
1396*03ce13f7SAndroid Build Coastguard Worker // TODO(b/127950082): Check bounds.
1397*03ce13f7SAndroid Build Coastguard Worker if(storageClass == spv::StorageClassUniformConstant)
1398*03ce13f7SAndroid Build Coastguard Worker {
1399*03ce13f7SAndroid Build Coastguard Worker // indexing into an array of descriptors.
1400*03ce13f7SAndroid Build Coastguard Worker auto d = shader.descriptorDecorations.at(baseId);
1401*03ce13f7SAndroid Build Coastguard Worker ASSERT(d.DescriptorSet >= 0);
1402*03ce13f7SAndroid Build Coastguard Worker ASSERT(d.Binding >= 0);
1403*03ce13f7SAndroid Build Coastguard Worker uint32_t descriptorSize = routine->pipelineLayout->getDescriptorSize(d.DescriptorSet, d.Binding);
1404*03ce13f7SAndroid Build Coastguard Worker
1405*03ce13f7SAndroid Build Coastguard Worker auto &obj = shader.getObject(indexIds[i]);
1406*03ce13f7SAndroid Build Coastguard Worker if(obj.kind == Object::Kind::Constant)
1407*03ce13f7SAndroid Build Coastguard Worker {
1408*03ce13f7SAndroid Build Coastguard Worker ptr += descriptorSize * shader.GetConstScalarInt(indexIds[i]);
1409*03ce13f7SAndroid Build Coastguard Worker }
1410*03ce13f7SAndroid Build Coastguard Worker else
1411*03ce13f7SAndroid Build Coastguard Worker {
1412*03ce13f7SAndroid Build Coastguard Worker nonUniform |= shader.GetDecorationsForId(indexIds[i]).NonUniform;
1413*03ce13f7SAndroid Build Coastguard Worker SIMD::Int intermediate = getIntermediate(indexIds[i]).Int(0);
1414*03ce13f7SAndroid Build Coastguard Worker if(nonUniform)
1415*03ce13f7SAndroid Build Coastguard Worker {
1416*03ce13f7SAndroid Build Coastguard Worker // NonUniform array data can deal with pointers not bound by a 32-bit address
1417*03ce13f7SAndroid Build Coastguard Worker // space, so we need to ensure we're using an array pointer, and not a base+offset
1418*03ce13f7SAndroid Build Coastguard Worker // pointer.
1419*03ce13f7SAndroid Build Coastguard Worker std::vector<Pointer<Byte>> pointers(SIMD::Width);
1420*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < SIMD::Width; i++)
1421*03ce13f7SAndroid Build Coastguard Worker {
1422*03ce13f7SAndroid Build Coastguard Worker pointers[i] = ptr.getPointerForLane(i);
1423*03ce13f7SAndroid Build Coastguard Worker }
1424*03ce13f7SAndroid Build Coastguard Worker ptr = SIMD::Pointer(pointers);
1425*03ce13f7SAndroid Build Coastguard Worker ptr += descriptorSize * intermediate;
1426*03ce13f7SAndroid Build Coastguard Worker }
1427*03ce13f7SAndroid Build Coastguard Worker else
1428*03ce13f7SAndroid Build Coastguard Worker {
1429*03ce13f7SAndroid Build Coastguard Worker ptr += descriptorSize * Extract(intermediate, 0);
1430*03ce13f7SAndroid Build Coastguard Worker }
1431*03ce13f7SAndroid Build Coastguard Worker }
1432*03ce13f7SAndroid Build Coastguard Worker }
1433*03ce13f7SAndroid Build Coastguard Worker else
1434*03ce13f7SAndroid Build Coastguard Worker {
1435*03ce13f7SAndroid Build Coastguard Worker auto stride = shader.getType(type.element).componentCount * static_cast<uint32_t>(sizeof(float));
1436*03ce13f7SAndroid Build Coastguard Worker
1437*03ce13f7SAndroid Build Coastguard Worker if(interleavedByLane)
1438*03ce13f7SAndroid Build Coastguard Worker {
1439*03ce13f7SAndroid Build Coastguard Worker stride *= SIMD::Width;
1440*03ce13f7SAndroid Build Coastguard Worker }
1441*03ce13f7SAndroid Build Coastguard Worker
1442*03ce13f7SAndroid Build Coastguard Worker if(shader.getObject(indexIds[i]).kind == Object::Kind::Constant)
1443*03ce13f7SAndroid Build Coastguard Worker {
1444*03ce13f7SAndroid Build Coastguard Worker ptr += stride * shader.GetConstScalarInt(indexIds[i]);
1445*03ce13f7SAndroid Build Coastguard Worker }
1446*03ce13f7SAndroid Build Coastguard Worker else
1447*03ce13f7SAndroid Build Coastguard Worker {
1448*03ce13f7SAndroid Build Coastguard Worker ptr += SIMD::Int(stride) * getIntermediate(indexIds[i]).Int(0);
1449*03ce13f7SAndroid Build Coastguard Worker }
1450*03ce13f7SAndroid Build Coastguard Worker }
1451*03ce13f7SAndroid Build Coastguard Worker typeId = type.element;
1452*03ce13f7SAndroid Build Coastguard Worker }
1453*03ce13f7SAndroid Build Coastguard Worker break;
1454*03ce13f7SAndroid Build Coastguard Worker
1455*03ce13f7SAndroid Build Coastguard Worker default:
1456*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s", shader.OpcodeName(type.opcode()));
1457*03ce13f7SAndroid Build Coastguard Worker }
1458*03ce13f7SAndroid Build Coastguard Worker }
1459*03ce13f7SAndroid Build Coastguard Worker
1460*03ce13f7SAndroid Build Coastguard Worker if(constantOffset != 0)
1461*03ce13f7SAndroid Build Coastguard Worker {
1462*03ce13f7SAndroid Build Coastguard Worker if(interleavedByLane)
1463*03ce13f7SAndroid Build Coastguard Worker {
1464*03ce13f7SAndroid Build Coastguard Worker constantOffset *= SIMD::Width;
1465*03ce13f7SAndroid Build Coastguard Worker }
1466*03ce13f7SAndroid Build Coastguard Worker
1467*03ce13f7SAndroid Build Coastguard Worker ptr += constantOffset;
1468*03ce13f7SAndroid Build Coastguard Worker }
1469*03ce13f7SAndroid Build Coastguard Worker
1470*03ce13f7SAndroid Build Coastguard Worker return ptr;
1471*03ce13f7SAndroid Build Coastguard Worker }
1472*03ce13f7SAndroid Build Coastguard Worker
WalkLiteralAccessChain(Type::ID typeId,const Span & indexes) const1473*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::WalkLiteralAccessChain(Type::ID typeId, const Span &indexes) const
1474*03ce13f7SAndroid Build Coastguard Worker {
1475*03ce13f7SAndroid Build Coastguard Worker uint32_t componentOffset = 0;
1476*03ce13f7SAndroid Build Coastguard Worker
1477*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < indexes.size(); i++)
1478*03ce13f7SAndroid Build Coastguard Worker {
1479*03ce13f7SAndroid Build Coastguard Worker auto &type = getType(typeId);
1480*03ce13f7SAndroid Build Coastguard Worker switch(type.opcode())
1481*03ce13f7SAndroid Build Coastguard Worker {
1482*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
1483*03ce13f7SAndroid Build Coastguard Worker {
1484*03ce13f7SAndroid Build Coastguard Worker int memberIndex = indexes[i];
1485*03ce13f7SAndroid Build Coastguard Worker int offsetIntoStruct = 0;
1486*03ce13f7SAndroid Build Coastguard Worker for(auto j = 0; j < memberIndex; j++)
1487*03ce13f7SAndroid Build Coastguard Worker {
1488*03ce13f7SAndroid Build Coastguard Worker auto memberType = type.definition.word(2u + j);
1489*03ce13f7SAndroid Build Coastguard Worker offsetIntoStruct += getType(memberType).componentCount;
1490*03ce13f7SAndroid Build Coastguard Worker }
1491*03ce13f7SAndroid Build Coastguard Worker componentOffset += offsetIntoStruct;
1492*03ce13f7SAndroid Build Coastguard Worker typeId = type.definition.word(2u + memberIndex);
1493*03ce13f7SAndroid Build Coastguard Worker }
1494*03ce13f7SAndroid Build Coastguard Worker break;
1495*03ce13f7SAndroid Build Coastguard Worker
1496*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
1497*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
1498*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
1499*03ce13f7SAndroid Build Coastguard Worker {
1500*03ce13f7SAndroid Build Coastguard Worker auto elementType = type.definition.word(2);
1501*03ce13f7SAndroid Build Coastguard Worker auto stride = getType(elementType).componentCount;
1502*03ce13f7SAndroid Build Coastguard Worker componentOffset += stride * indexes[i];
1503*03ce13f7SAndroid Build Coastguard Worker typeId = elementType;
1504*03ce13f7SAndroid Build Coastguard Worker }
1505*03ce13f7SAndroid Build Coastguard Worker break;
1506*03ce13f7SAndroid Build Coastguard Worker
1507*03ce13f7SAndroid Build Coastguard Worker default:
1508*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s", OpcodeName(type.opcode()));
1509*03ce13f7SAndroid Build Coastguard Worker }
1510*03ce13f7SAndroid Build Coastguard Worker }
1511*03ce13f7SAndroid Build Coastguard Worker
1512*03ce13f7SAndroid Build Coastguard Worker return componentOffset;
1513*03ce13f7SAndroid Build Coastguard Worker }
1514*03ce13f7SAndroid Build Coastguard Worker
Apply(spv::Decoration decoration,uint32_t arg)1515*03ce13f7SAndroid Build Coastguard Worker void Spirv::Decorations::Apply(spv::Decoration decoration, uint32_t arg)
1516*03ce13f7SAndroid Build Coastguard Worker {
1517*03ce13f7SAndroid Build Coastguard Worker switch(decoration)
1518*03ce13f7SAndroid Build Coastguard Worker {
1519*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationLocation:
1520*03ce13f7SAndroid Build Coastguard Worker HasLocation = true;
1521*03ce13f7SAndroid Build Coastguard Worker Location = static_cast<int32_t>(arg);
1522*03ce13f7SAndroid Build Coastguard Worker break;
1523*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationComponent:
1524*03ce13f7SAndroid Build Coastguard Worker HasComponent = true;
1525*03ce13f7SAndroid Build Coastguard Worker Component = arg;
1526*03ce13f7SAndroid Build Coastguard Worker break;
1527*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationBuiltIn:
1528*03ce13f7SAndroid Build Coastguard Worker HasBuiltIn = true;
1529*03ce13f7SAndroid Build Coastguard Worker BuiltIn = static_cast<spv::BuiltIn>(arg);
1530*03ce13f7SAndroid Build Coastguard Worker break;
1531*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationFlat:
1532*03ce13f7SAndroid Build Coastguard Worker Flat = true;
1533*03ce13f7SAndroid Build Coastguard Worker break;
1534*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationNoPerspective:
1535*03ce13f7SAndroid Build Coastguard Worker NoPerspective = true;
1536*03ce13f7SAndroid Build Coastguard Worker break;
1537*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationCentroid:
1538*03ce13f7SAndroid Build Coastguard Worker Centroid = true;
1539*03ce13f7SAndroid Build Coastguard Worker break;
1540*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationBlock:
1541*03ce13f7SAndroid Build Coastguard Worker Block = true;
1542*03ce13f7SAndroid Build Coastguard Worker break;
1543*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationBufferBlock:
1544*03ce13f7SAndroid Build Coastguard Worker BufferBlock = true;
1545*03ce13f7SAndroid Build Coastguard Worker break;
1546*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationOffset:
1547*03ce13f7SAndroid Build Coastguard Worker HasOffset = true;
1548*03ce13f7SAndroid Build Coastguard Worker Offset = static_cast<int32_t>(arg);
1549*03ce13f7SAndroid Build Coastguard Worker break;
1550*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationArrayStride:
1551*03ce13f7SAndroid Build Coastguard Worker HasArrayStride = true;
1552*03ce13f7SAndroid Build Coastguard Worker ArrayStride = static_cast<int32_t>(arg);
1553*03ce13f7SAndroid Build Coastguard Worker break;
1554*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationMatrixStride:
1555*03ce13f7SAndroid Build Coastguard Worker HasMatrixStride = true;
1556*03ce13f7SAndroid Build Coastguard Worker MatrixStride = static_cast<int32_t>(arg);
1557*03ce13f7SAndroid Build Coastguard Worker break;
1558*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationRelaxedPrecision:
1559*03ce13f7SAndroid Build Coastguard Worker RelaxedPrecision = true;
1560*03ce13f7SAndroid Build Coastguard Worker break;
1561*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationRowMajor:
1562*03ce13f7SAndroid Build Coastguard Worker HasRowMajor = true;
1563*03ce13f7SAndroid Build Coastguard Worker RowMajor = true;
1564*03ce13f7SAndroid Build Coastguard Worker break;
1565*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationColMajor:
1566*03ce13f7SAndroid Build Coastguard Worker HasRowMajor = true;
1567*03ce13f7SAndroid Build Coastguard Worker RowMajor = false;
1568*03ce13f7SAndroid Build Coastguard Worker break;
1569*03ce13f7SAndroid Build Coastguard Worker case spv::DecorationNonUniform:
1570*03ce13f7SAndroid Build Coastguard Worker NonUniform = true;
1571*03ce13f7SAndroid Build Coastguard Worker break;
1572*03ce13f7SAndroid Build Coastguard Worker default:
1573*03ce13f7SAndroid Build Coastguard Worker // Intentionally partial, there are many decorations we just don't care about.
1574*03ce13f7SAndroid Build Coastguard Worker break;
1575*03ce13f7SAndroid Build Coastguard Worker }
1576*03ce13f7SAndroid Build Coastguard Worker }
1577*03ce13f7SAndroid Build Coastguard Worker
Apply(const Decorations & src)1578*03ce13f7SAndroid Build Coastguard Worker void Spirv::Decorations::Apply(const Decorations &src)
1579*03ce13f7SAndroid Build Coastguard Worker {
1580*03ce13f7SAndroid Build Coastguard Worker // Apply a decoration group to this set of decorations
1581*03ce13f7SAndroid Build Coastguard Worker if(src.HasBuiltIn)
1582*03ce13f7SAndroid Build Coastguard Worker {
1583*03ce13f7SAndroid Build Coastguard Worker HasBuiltIn = true;
1584*03ce13f7SAndroid Build Coastguard Worker BuiltIn = src.BuiltIn;
1585*03ce13f7SAndroid Build Coastguard Worker }
1586*03ce13f7SAndroid Build Coastguard Worker
1587*03ce13f7SAndroid Build Coastguard Worker if(src.HasLocation)
1588*03ce13f7SAndroid Build Coastguard Worker {
1589*03ce13f7SAndroid Build Coastguard Worker HasLocation = true;
1590*03ce13f7SAndroid Build Coastguard Worker Location = src.Location;
1591*03ce13f7SAndroid Build Coastguard Worker }
1592*03ce13f7SAndroid Build Coastguard Worker
1593*03ce13f7SAndroid Build Coastguard Worker if(src.HasComponent)
1594*03ce13f7SAndroid Build Coastguard Worker {
1595*03ce13f7SAndroid Build Coastguard Worker HasComponent = true;
1596*03ce13f7SAndroid Build Coastguard Worker Component = src.Component;
1597*03ce13f7SAndroid Build Coastguard Worker }
1598*03ce13f7SAndroid Build Coastguard Worker
1599*03ce13f7SAndroid Build Coastguard Worker if(src.HasOffset)
1600*03ce13f7SAndroid Build Coastguard Worker {
1601*03ce13f7SAndroid Build Coastguard Worker HasOffset = true;
1602*03ce13f7SAndroid Build Coastguard Worker Offset = src.Offset;
1603*03ce13f7SAndroid Build Coastguard Worker }
1604*03ce13f7SAndroid Build Coastguard Worker
1605*03ce13f7SAndroid Build Coastguard Worker if(src.HasArrayStride)
1606*03ce13f7SAndroid Build Coastguard Worker {
1607*03ce13f7SAndroid Build Coastguard Worker HasArrayStride = true;
1608*03ce13f7SAndroid Build Coastguard Worker ArrayStride = src.ArrayStride;
1609*03ce13f7SAndroid Build Coastguard Worker }
1610*03ce13f7SAndroid Build Coastguard Worker
1611*03ce13f7SAndroid Build Coastguard Worker if(src.HasMatrixStride)
1612*03ce13f7SAndroid Build Coastguard Worker {
1613*03ce13f7SAndroid Build Coastguard Worker HasMatrixStride = true;
1614*03ce13f7SAndroid Build Coastguard Worker MatrixStride = src.MatrixStride;
1615*03ce13f7SAndroid Build Coastguard Worker }
1616*03ce13f7SAndroid Build Coastguard Worker
1617*03ce13f7SAndroid Build Coastguard Worker if(src.HasRowMajor)
1618*03ce13f7SAndroid Build Coastguard Worker {
1619*03ce13f7SAndroid Build Coastguard Worker HasRowMajor = true;
1620*03ce13f7SAndroid Build Coastguard Worker RowMajor = src.RowMajor;
1621*03ce13f7SAndroid Build Coastguard Worker }
1622*03ce13f7SAndroid Build Coastguard Worker
1623*03ce13f7SAndroid Build Coastguard Worker Flat |= src.Flat;
1624*03ce13f7SAndroid Build Coastguard Worker NoPerspective |= src.NoPerspective;
1625*03ce13f7SAndroid Build Coastguard Worker Centroid |= src.Centroid;
1626*03ce13f7SAndroid Build Coastguard Worker Block |= src.Block;
1627*03ce13f7SAndroid Build Coastguard Worker BufferBlock |= src.BufferBlock;
1628*03ce13f7SAndroid Build Coastguard Worker RelaxedPrecision |= src.RelaxedPrecision;
1629*03ce13f7SAndroid Build Coastguard Worker InsideMatrix |= src.InsideMatrix;
1630*03ce13f7SAndroid Build Coastguard Worker NonUniform |= src.NonUniform;
1631*03ce13f7SAndroid Build Coastguard Worker }
1632*03ce13f7SAndroid Build Coastguard Worker
Apply(const sw::Spirv::DescriptorDecorations & src)1633*03ce13f7SAndroid Build Coastguard Worker void Spirv::DescriptorDecorations::Apply(const sw::Spirv::DescriptorDecorations &src)
1634*03ce13f7SAndroid Build Coastguard Worker {
1635*03ce13f7SAndroid Build Coastguard Worker if(src.DescriptorSet >= 0)
1636*03ce13f7SAndroid Build Coastguard Worker {
1637*03ce13f7SAndroid Build Coastguard Worker DescriptorSet = src.DescriptorSet;
1638*03ce13f7SAndroid Build Coastguard Worker }
1639*03ce13f7SAndroid Build Coastguard Worker
1640*03ce13f7SAndroid Build Coastguard Worker if(src.Binding >= 0)
1641*03ce13f7SAndroid Build Coastguard Worker {
1642*03ce13f7SAndroid Build Coastguard Worker Binding = src.Binding;
1643*03ce13f7SAndroid Build Coastguard Worker }
1644*03ce13f7SAndroid Build Coastguard Worker
1645*03ce13f7SAndroid Build Coastguard Worker if(src.InputAttachmentIndex >= 0)
1646*03ce13f7SAndroid Build Coastguard Worker {
1647*03ce13f7SAndroid Build Coastguard Worker InputAttachmentIndex = src.InputAttachmentIndex;
1648*03ce13f7SAndroid Build Coastguard Worker }
1649*03ce13f7SAndroid Build Coastguard Worker }
1650*03ce13f7SAndroid Build Coastguard Worker
GetDecorationsForId(TypeOrObjectID id) const1651*03ce13f7SAndroid Build Coastguard Worker Spirv::Decorations Spirv::GetDecorationsForId(TypeOrObjectID id) const
1652*03ce13f7SAndroid Build Coastguard Worker {
1653*03ce13f7SAndroid Build Coastguard Worker Decorations d;
1654*03ce13f7SAndroid Build Coastguard Worker ApplyDecorationsForId(&d, id);
1655*03ce13f7SAndroid Build Coastguard Worker
1656*03ce13f7SAndroid Build Coastguard Worker return d;
1657*03ce13f7SAndroid Build Coastguard Worker }
1658*03ce13f7SAndroid Build Coastguard Worker
ApplyDecorationsForId(Decorations * d,TypeOrObjectID id) const1659*03ce13f7SAndroid Build Coastguard Worker void Spirv::ApplyDecorationsForId(Decorations *d, TypeOrObjectID id) const
1660*03ce13f7SAndroid Build Coastguard Worker {
1661*03ce13f7SAndroid Build Coastguard Worker auto it = decorations.find(id);
1662*03ce13f7SAndroid Build Coastguard Worker if(it != decorations.end())
1663*03ce13f7SAndroid Build Coastguard Worker {
1664*03ce13f7SAndroid Build Coastguard Worker d->Apply(it->second);
1665*03ce13f7SAndroid Build Coastguard Worker }
1666*03ce13f7SAndroid Build Coastguard Worker }
1667*03ce13f7SAndroid Build Coastguard Worker
ApplyDecorationsForIdMember(Decorations * d,Type::ID id,uint32_t member) const1668*03ce13f7SAndroid Build Coastguard Worker void Spirv::ApplyDecorationsForIdMember(Decorations *d, Type::ID id, uint32_t member) const
1669*03ce13f7SAndroid Build Coastguard Worker {
1670*03ce13f7SAndroid Build Coastguard Worker auto it = memberDecorations.find(id);
1671*03ce13f7SAndroid Build Coastguard Worker if(it != memberDecorations.end() && member < it->second.size())
1672*03ce13f7SAndroid Build Coastguard Worker {
1673*03ce13f7SAndroid Build Coastguard Worker d->Apply(it->second[member]);
1674*03ce13f7SAndroid Build Coastguard Worker }
1675*03ce13f7SAndroid Build Coastguard Worker }
1676*03ce13f7SAndroid Build Coastguard Worker
DefineResult(const InsnIterator & insn)1677*03ce13f7SAndroid Build Coastguard Worker void Spirv::DefineResult(const InsnIterator &insn)
1678*03ce13f7SAndroid Build Coastguard Worker {
1679*03ce13f7SAndroid Build Coastguard Worker Type::ID typeId = insn.word(1);
1680*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
1681*03ce13f7SAndroid Build Coastguard Worker auto &object = defs[resultId];
1682*03ce13f7SAndroid Build Coastguard Worker
1683*03ce13f7SAndroid Build Coastguard Worker switch(getType(typeId).opcode())
1684*03ce13f7SAndroid Build Coastguard Worker {
1685*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampledImage:
1686*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::SampledImage;
1687*03ce13f7SAndroid Build Coastguard Worker break;
1688*03ce13f7SAndroid Build Coastguard Worker
1689*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypePointer:
1690*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeImage:
1691*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampler:
1692*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::Pointer;
1693*03ce13f7SAndroid Build Coastguard Worker break;
1694*03ce13f7SAndroid Build Coastguard Worker
1695*03ce13f7SAndroid Build Coastguard Worker default:
1696*03ce13f7SAndroid Build Coastguard Worker object.kind = Object::Kind::Intermediate;
1697*03ce13f7SAndroid Build Coastguard Worker }
1698*03ce13f7SAndroid Build Coastguard Worker
1699*03ce13f7SAndroid Build Coastguard Worker object.definition = insn;
1700*03ce13f7SAndroid Build Coastguard Worker }
1701*03ce13f7SAndroid Build Coastguard Worker
getOutOfBoundsBehavior(Object::ID pointerId,const vk::PipelineLayout * pipelineLayout) const1702*03ce13f7SAndroid Build Coastguard Worker OutOfBoundsBehavior SpirvShader::getOutOfBoundsBehavior(Object::ID pointerId, const vk::PipelineLayout *pipelineLayout) const
1703*03ce13f7SAndroid Build Coastguard Worker {
1704*03ce13f7SAndroid Build Coastguard Worker auto it = descriptorDecorations.find(pointerId);
1705*03ce13f7SAndroid Build Coastguard Worker if(it != descriptorDecorations.end())
1706*03ce13f7SAndroid Build Coastguard Worker {
1707*03ce13f7SAndroid Build Coastguard Worker const auto &d = it->second;
1708*03ce13f7SAndroid Build Coastguard Worker if((d.DescriptorSet >= 0) && (d.Binding >= 0))
1709*03ce13f7SAndroid Build Coastguard Worker {
1710*03ce13f7SAndroid Build Coastguard Worker auto descriptorType = pipelineLayout->getDescriptorType(d.DescriptorSet, d.Binding);
1711*03ce13f7SAndroid Build Coastguard Worker if(descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1712*03ce13f7SAndroid Build Coastguard Worker {
1713*03ce13f7SAndroid Build Coastguard Worker return OutOfBoundsBehavior::UndefinedBehavior;
1714*03ce13f7SAndroid Build Coastguard Worker }
1715*03ce13f7SAndroid Build Coastguard Worker }
1716*03ce13f7SAndroid Build Coastguard Worker }
1717*03ce13f7SAndroid Build Coastguard Worker
1718*03ce13f7SAndroid Build Coastguard Worker auto &pointer = getObject(pointerId);
1719*03ce13f7SAndroid Build Coastguard Worker auto &pointerTy = getType(pointer);
1720*03ce13f7SAndroid Build Coastguard Worker switch(pointerTy.storageClass)
1721*03ce13f7SAndroid Build Coastguard Worker {
1722*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassUniform:
1723*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassStorageBuffer:
1724*03ce13f7SAndroid Build Coastguard Worker // Buffer resource access. robustBufferAccess feature applies.
1725*03ce13f7SAndroid Build Coastguard Worker return robustBufferAccess ? OutOfBoundsBehavior::RobustBufferAccess
1726*03ce13f7SAndroid Build Coastguard Worker : OutOfBoundsBehavior::UndefinedBehavior;
1727*03ce13f7SAndroid Build Coastguard Worker
1728*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassPhysicalStorageBuffer:
1729*03ce13f7SAndroid Build Coastguard Worker return OutOfBoundsBehavior::UndefinedBehavior;
1730*03ce13f7SAndroid Build Coastguard Worker
1731*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassImage:
1732*03ce13f7SAndroid Build Coastguard Worker // VK_EXT_image_robustness requires nullifying out-of-bounds accesses.
1733*03ce13f7SAndroid Build Coastguard Worker // TODO(b/162327166): Only perform bounds checks when VK_EXT_image_robustness is enabled.
1734*03ce13f7SAndroid Build Coastguard Worker return OutOfBoundsBehavior::Nullify;
1735*03ce13f7SAndroid Build Coastguard Worker
1736*03ce13f7SAndroid Build Coastguard Worker case spv::StorageClassInput:
1737*03ce13f7SAndroid Build Coastguard Worker if(executionModel == spv::ExecutionModelVertex)
1738*03ce13f7SAndroid Build Coastguard Worker {
1739*03ce13f7SAndroid Build Coastguard Worker // Vertex attributes follow robustBufferAccess rules.
1740*03ce13f7SAndroid Build Coastguard Worker return robustBufferAccess ? OutOfBoundsBehavior::RobustBufferAccess
1741*03ce13f7SAndroid Build Coastguard Worker : OutOfBoundsBehavior::UndefinedBehavior;
1742*03ce13f7SAndroid Build Coastguard Worker }
1743*03ce13f7SAndroid Build Coastguard Worker // Fall through to default case.
1744*03ce13f7SAndroid Build Coastguard Worker default:
1745*03ce13f7SAndroid Build Coastguard Worker // TODO(b/192310780): StorageClassFunction out-of-bounds accesses are undefined behavior.
1746*03ce13f7SAndroid Build Coastguard Worker // TODO(b/137183137): Optimize if the pointer resulted from OpInBoundsAccessChain.
1747*03ce13f7SAndroid Build Coastguard Worker // TODO(b/131224163): Optimize cases statically known to be within bounds.
1748*03ce13f7SAndroid Build Coastguard Worker return OutOfBoundsBehavior::UndefinedValue;
1749*03ce13f7SAndroid Build Coastguard Worker }
1750*03ce13f7SAndroid Build Coastguard Worker
1751*03ce13f7SAndroid Build Coastguard Worker return OutOfBoundsBehavior::Nullify;
1752*03ce13f7SAndroid Build Coastguard Worker }
1753*03ce13f7SAndroid Build Coastguard Worker
getInputAttachmentFormat(const vk::Attachments & attachments,int32_t index) const1754*03ce13f7SAndroid Build Coastguard Worker vk::Format SpirvShader::getInputAttachmentFormat(const vk::Attachments &attachments, int32_t index) const
1755*03ce13f7SAndroid Build Coastguard Worker {
1756*03ce13f7SAndroid Build Coastguard Worker if(isUsedWithDynamicRendering)
1757*03ce13f7SAndroid Build Coastguard Worker {
1758*03ce13f7SAndroid Build Coastguard Worker // If no index is given in the shader, it refers to the depth/stencil
1759*03ce13f7SAndroid Build Coastguard Worker // attachment.
1760*03ce13f7SAndroid Build Coastguard Worker if(index < 0 || index == depthInputIndex || index == stencilInputIndex)
1761*03ce13f7SAndroid Build Coastguard Worker {
1762*03ce13f7SAndroid Build Coastguard Worker return attachments.depthStencilFormat();
1763*03ce13f7SAndroid Build Coastguard Worker }
1764*03ce13f7SAndroid Build Coastguard Worker
1765*03ce13f7SAndroid Build Coastguard Worker // See if the input index is mapped to an attachment. If it isn't, the
1766*03ce13f7SAndroid Build Coastguard Worker // mapping is identity.
1767*03ce13f7SAndroid Build Coastguard Worker int32_t attachmentIndex = index;
1768*03ce13f7SAndroid Build Coastguard Worker if(inputIndexToColorIndex.count(index) > 0)
1769*03ce13f7SAndroid Build Coastguard Worker {
1770*03ce13f7SAndroid Build Coastguard Worker attachmentIndex = inputIndexToColorIndex.at(index);
1771*03ce13f7SAndroid Build Coastguard Worker }
1772*03ce13f7SAndroid Build Coastguard Worker
1773*03ce13f7SAndroid Build Coastguard Worker // Map the index to its location. This is where read-only input attachments
1774*03ce13f7SAndroid Build Coastguard Worker // that aren't mapped to any color attachment cannot be supported the way
1775*03ce13f7SAndroid Build Coastguard Worker // SwiftShader currently works (see comment above `inputIndexToColorIndex`).
1776*03ce13f7SAndroid Build Coastguard Worker ASSERT(attachmentIndex >= 0 && attachmentIndex < sw::MAX_COLOR_BUFFERS);
1777*03ce13f7SAndroid Build Coastguard Worker const int32_t location = attachments.indexToLocation[attachmentIndex];
1778*03ce13f7SAndroid Build Coastguard Worker
1779*03ce13f7SAndroid Build Coastguard Worker return attachments.colorFormat(location);
1780*03ce13f7SAndroid Build Coastguard Worker }
1781*03ce13f7SAndroid Build Coastguard Worker
1782*03ce13f7SAndroid Build Coastguard Worker return inputAttachmentFormats[index];
1783*03ce13f7SAndroid Build Coastguard Worker }
1784*03ce13f7SAndroid Build Coastguard Worker
1785*03ce13f7SAndroid Build Coastguard Worker // emit-time
1786*03ce13f7SAndroid Build Coastguard Worker
emitProlog(SpirvRoutine * routine) const1787*03ce13f7SAndroid Build Coastguard Worker void SpirvShader::emitProlog(SpirvRoutine *routine) const
1788*03ce13f7SAndroid Build Coastguard Worker {
1789*03ce13f7SAndroid Build Coastguard Worker for(auto insn : *this)
1790*03ce13f7SAndroid Build Coastguard Worker {
1791*03ce13f7SAndroid Build Coastguard Worker switch(insn.opcode())
1792*03ce13f7SAndroid Build Coastguard Worker {
1793*03ce13f7SAndroid Build Coastguard Worker case spv::OpVariable:
1794*03ce13f7SAndroid Build Coastguard Worker {
1795*03ce13f7SAndroid Build Coastguard Worker auto resultPointerType = getType(insn.resultTypeId());
1796*03ce13f7SAndroid Build Coastguard Worker auto pointeeType = getType(resultPointerType.element);
1797*03ce13f7SAndroid Build Coastguard Worker
1798*03ce13f7SAndroid Build Coastguard Worker if(pointeeType.componentCount > 0)
1799*03ce13f7SAndroid Build Coastguard Worker {
1800*03ce13f7SAndroid Build Coastguard Worker routine->createVariable(insn.resultId(), pointeeType.componentCount);
1801*03ce13f7SAndroid Build Coastguard Worker }
1802*03ce13f7SAndroid Build Coastguard Worker }
1803*03ce13f7SAndroid Build Coastguard Worker break;
1804*03ce13f7SAndroid Build Coastguard Worker
1805*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleImplicitLod:
1806*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleExplicitLod:
1807*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleDrefImplicitLod:
1808*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleDrefExplicitLod:
1809*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjImplicitLod:
1810*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjExplicitLod:
1811*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjDrefImplicitLod:
1812*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjDrefExplicitLod:
1813*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageFetch:
1814*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageGather:
1815*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageDrefGather:
1816*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageWrite:
1817*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQueryLod:
1818*03ce13f7SAndroid Build Coastguard Worker {
1819*03ce13f7SAndroid Build Coastguard Worker // The 'inline' sampler caches must be created in the prolog to initialize the tags.
1820*03ce13f7SAndroid Build Coastguard Worker uint32_t instructionPosition = insn.distanceFrom(this->begin());
1821*03ce13f7SAndroid Build Coastguard Worker routine->samplerCache.emplace(instructionPosition, SpirvRoutine::SamplerCache{});
1822*03ce13f7SAndroid Build Coastguard Worker }
1823*03ce13f7SAndroid Build Coastguard Worker break;
1824*03ce13f7SAndroid Build Coastguard Worker
1825*03ce13f7SAndroid Build Coastguard Worker default:
1826*03ce13f7SAndroid Build Coastguard Worker // Nothing else produces interface variables, so can all be safely ignored.
1827*03ce13f7SAndroid Build Coastguard Worker break;
1828*03ce13f7SAndroid Build Coastguard Worker }
1829*03ce13f7SAndroid Build Coastguard Worker }
1830*03ce13f7SAndroid Build Coastguard Worker }
1831*03ce13f7SAndroid Build Coastguard Worker
emit(SpirvRoutine * routine,const RValue<SIMD::Int> & activeLaneMask,const RValue<SIMD::Int> & storesAndAtomicsMask,const vk::DescriptorSet::Bindings & descriptorSets,const vk::Attachments * attachments,unsigned int multiSampleCount) const1832*03ce13f7SAndroid Build Coastguard Worker void SpirvShader::emit(SpirvRoutine *routine, const RValue<SIMD::Int> &activeLaneMask, const RValue<SIMD::Int> &storesAndAtomicsMask, const vk::DescriptorSet::Bindings &descriptorSets, const vk::Attachments *attachments, unsigned int multiSampleCount) const
1833*03ce13f7SAndroid Build Coastguard Worker {
1834*03ce13f7SAndroid Build Coastguard Worker SpirvEmitter::emit(*this, routine, entryPoint, activeLaneMask, storesAndAtomicsMask, attachments, descriptorSets, multiSampleCount);
1835*03ce13f7SAndroid Build Coastguard Worker }
1836*03ce13f7SAndroid Build Coastguard Worker
SpirvShader(VkShaderStageFlagBits stage,const char * entryPointName,const SpirvBinary & insns,const vk::RenderPass * renderPass,uint32_t subpassIndex,const VkRenderingInputAttachmentIndexInfoKHR * inputAttachmentMapping,bool robustBufferAccess)1837*03ce13f7SAndroid Build Coastguard Worker SpirvShader::SpirvShader(VkShaderStageFlagBits stage,
1838*03ce13f7SAndroid Build Coastguard Worker const char *entryPointName,
1839*03ce13f7SAndroid Build Coastguard Worker const SpirvBinary &insns,
1840*03ce13f7SAndroid Build Coastguard Worker const vk::RenderPass *renderPass,
1841*03ce13f7SAndroid Build Coastguard Worker uint32_t subpassIndex,
1842*03ce13f7SAndroid Build Coastguard Worker const VkRenderingInputAttachmentIndexInfoKHR *inputAttachmentMapping,
1843*03ce13f7SAndroid Build Coastguard Worker bool robustBufferAccess)
1844*03ce13f7SAndroid Build Coastguard Worker : Spirv(stage, entryPointName, insns)
1845*03ce13f7SAndroid Build Coastguard Worker , robustBufferAccess(robustBufferAccess)
1846*03ce13f7SAndroid Build Coastguard Worker , isUsedWithDynamicRendering(renderPass == nullptr)
1847*03ce13f7SAndroid Build Coastguard Worker {
1848*03ce13f7SAndroid Build Coastguard Worker if(renderPass)
1849*03ce13f7SAndroid Build Coastguard Worker {
1850*03ce13f7SAndroid Build Coastguard Worker // capture formats of any input attachments present
1851*03ce13f7SAndroid Build Coastguard Worker auto subpass = renderPass->getSubpass(subpassIndex);
1852*03ce13f7SAndroid Build Coastguard Worker inputAttachmentFormats.reserve(subpass.inputAttachmentCount);
1853*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < subpass.inputAttachmentCount; i++)
1854*03ce13f7SAndroid Build Coastguard Worker {
1855*03ce13f7SAndroid Build Coastguard Worker auto attachmentIndex = subpass.pInputAttachments[i].attachment;
1856*03ce13f7SAndroid Build Coastguard Worker inputAttachmentFormats.push_back(attachmentIndex != VK_ATTACHMENT_UNUSED
1857*03ce13f7SAndroid Build Coastguard Worker ? renderPass->getAttachment(attachmentIndex).format
1858*03ce13f7SAndroid Build Coastguard Worker : VK_FORMAT_UNDEFINED);
1859*03ce13f7SAndroid Build Coastguard Worker }
1860*03ce13f7SAndroid Build Coastguard Worker }
1861*03ce13f7SAndroid Build Coastguard Worker else if(inputAttachmentMapping)
1862*03ce13f7SAndroid Build Coastguard Worker {
1863*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < inputAttachmentMapping->colorAttachmentCount; i++)
1864*03ce13f7SAndroid Build Coastguard Worker {
1865*03ce13f7SAndroid Build Coastguard Worker auto inputIndex = inputAttachmentMapping->pColorAttachmentInputIndices != nullptr ? inputAttachmentMapping->pColorAttachmentInputIndices[i] : i;
1866*03ce13f7SAndroid Build Coastguard Worker if(inputIndex != VK_ATTACHMENT_UNUSED)
1867*03ce13f7SAndroid Build Coastguard Worker {
1868*03ce13f7SAndroid Build Coastguard Worker inputIndexToColorIndex[inputIndex] = i;
1869*03ce13f7SAndroid Build Coastguard Worker }
1870*03ce13f7SAndroid Build Coastguard Worker }
1871*03ce13f7SAndroid Build Coastguard Worker
1872*03ce13f7SAndroid Build Coastguard Worker if(inputAttachmentMapping->pDepthInputAttachmentIndex)
1873*03ce13f7SAndroid Build Coastguard Worker {
1874*03ce13f7SAndroid Build Coastguard Worker auto attachmentIndex = *inputAttachmentMapping->pDepthInputAttachmentIndex;
1875*03ce13f7SAndroid Build Coastguard Worker if(attachmentIndex != VK_ATTACHMENT_UNUSED)
1876*03ce13f7SAndroid Build Coastguard Worker {
1877*03ce13f7SAndroid Build Coastguard Worker depthInputIndex = attachmentIndex;
1878*03ce13f7SAndroid Build Coastguard Worker }
1879*03ce13f7SAndroid Build Coastguard Worker }
1880*03ce13f7SAndroid Build Coastguard Worker
1881*03ce13f7SAndroid Build Coastguard Worker if(inputAttachmentMapping->pStencilInputAttachmentIndex)
1882*03ce13f7SAndroid Build Coastguard Worker {
1883*03ce13f7SAndroid Build Coastguard Worker auto attachmentIndex = *inputAttachmentMapping->pStencilInputAttachmentIndex;
1884*03ce13f7SAndroid Build Coastguard Worker if(attachmentIndex != VK_ATTACHMENT_UNUSED)
1885*03ce13f7SAndroid Build Coastguard Worker {
1886*03ce13f7SAndroid Build Coastguard Worker stencilInputIndex = attachmentIndex;
1887*03ce13f7SAndroid Build Coastguard Worker }
1888*03ce13f7SAndroid Build Coastguard Worker }
1889*03ce13f7SAndroid Build Coastguard Worker }
1890*03ce13f7SAndroid Build Coastguard Worker }
1891*03ce13f7SAndroid Build Coastguard Worker
~SpirvShader()1892*03ce13f7SAndroid Build Coastguard Worker SpirvShader::~SpirvShader()
1893*03ce13f7SAndroid Build Coastguard Worker {
1894*03ce13f7SAndroid Build Coastguard Worker }
1895*03ce13f7SAndroid Build Coastguard Worker
SpirvEmitter(const SpirvShader & shader,SpirvRoutine * routine,Spirv::Function::ID entryPoint,RValue<SIMD::Int> activeLaneMask,RValue<SIMD::Int> storesAndAtomicsMask,const vk::Attachments * attachments,const vk::DescriptorSet::Bindings & descriptorSets,unsigned int multiSampleCount)1896*03ce13f7SAndroid Build Coastguard Worker SpirvEmitter::SpirvEmitter(const SpirvShader &shader,
1897*03ce13f7SAndroid Build Coastguard Worker SpirvRoutine *routine,
1898*03ce13f7SAndroid Build Coastguard Worker Spirv::Function::ID entryPoint,
1899*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> activeLaneMask,
1900*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> storesAndAtomicsMask,
1901*03ce13f7SAndroid Build Coastguard Worker const vk::Attachments *attachments,
1902*03ce13f7SAndroid Build Coastguard Worker const vk::DescriptorSet::Bindings &descriptorSets,
1903*03ce13f7SAndroid Build Coastguard Worker unsigned int multiSampleCount)
1904*03ce13f7SAndroid Build Coastguard Worker : shader(shader)
1905*03ce13f7SAndroid Build Coastguard Worker , routine(routine)
1906*03ce13f7SAndroid Build Coastguard Worker , function(entryPoint)
1907*03ce13f7SAndroid Build Coastguard Worker , activeLaneMaskValue(activeLaneMask.value())
1908*03ce13f7SAndroid Build Coastguard Worker , storesAndAtomicsMaskValue(storesAndAtomicsMask.value())
1909*03ce13f7SAndroid Build Coastguard Worker , attachments(attachments)
1910*03ce13f7SAndroid Build Coastguard Worker , descriptorSets(descriptorSets)
1911*03ce13f7SAndroid Build Coastguard Worker , multiSampleCount(multiSampleCount)
1912*03ce13f7SAndroid Build Coastguard Worker {
1913*03ce13f7SAndroid Build Coastguard Worker }
1914*03ce13f7SAndroid Build Coastguard Worker
emit(const SpirvShader & shader,SpirvRoutine * routine,Spirv::Function::ID entryPoint,RValue<SIMD::Int> activeLaneMask,RValue<SIMD::Int> storesAndAtomicsMask,const vk::Attachments * attachments,const vk::DescriptorSet::Bindings & descriptorSets,unsigned int multiSampleCount)1915*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::emit(const SpirvShader &shader,
1916*03ce13f7SAndroid Build Coastguard Worker SpirvRoutine *routine,
1917*03ce13f7SAndroid Build Coastguard Worker Spirv::Function::ID entryPoint,
1918*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> activeLaneMask,
1919*03ce13f7SAndroid Build Coastguard Worker RValue<SIMD::Int> storesAndAtomicsMask,
1920*03ce13f7SAndroid Build Coastguard Worker const vk::Attachments *attachments,
1921*03ce13f7SAndroid Build Coastguard Worker const vk::DescriptorSet::Bindings &descriptorSets,
1922*03ce13f7SAndroid Build Coastguard Worker unsigned int multiSampleCount)
1923*03ce13f7SAndroid Build Coastguard Worker {
1924*03ce13f7SAndroid Build Coastguard Worker SpirvEmitter state(shader, routine, entryPoint, activeLaneMask, storesAndAtomicsMask, attachments, descriptorSets, multiSampleCount);
1925*03ce13f7SAndroid Build Coastguard Worker
1926*03ce13f7SAndroid Build Coastguard Worker // Create phi variables
1927*03ce13f7SAndroid Build Coastguard Worker for(auto insn : shader)
1928*03ce13f7SAndroid Build Coastguard Worker {
1929*03ce13f7SAndroid Build Coastguard Worker if(insn.opcode() == spv::OpPhi)
1930*03ce13f7SAndroid Build Coastguard Worker {
1931*03ce13f7SAndroid Build Coastguard Worker auto type = shader.getType(insn.resultTypeId());
1932*03ce13f7SAndroid Build Coastguard Worker state.phis.emplace(insn.resultId(), std::vector<SIMD::Float>(type.componentCount));
1933*03ce13f7SAndroid Build Coastguard Worker }
1934*03ce13f7SAndroid Build Coastguard Worker }
1935*03ce13f7SAndroid Build Coastguard Worker
1936*03ce13f7SAndroid Build Coastguard Worker // Emit everything up to the first label
1937*03ce13f7SAndroid Build Coastguard Worker // TODO: Separate out dispatch of block from non-block instructions?
1938*03ce13f7SAndroid Build Coastguard Worker for(auto insn : shader)
1939*03ce13f7SAndroid Build Coastguard Worker {
1940*03ce13f7SAndroid Build Coastguard Worker if(insn.opcode() == spv::OpLabel)
1941*03ce13f7SAndroid Build Coastguard Worker {
1942*03ce13f7SAndroid Build Coastguard Worker break;
1943*03ce13f7SAndroid Build Coastguard Worker }
1944*03ce13f7SAndroid Build Coastguard Worker
1945*03ce13f7SAndroid Build Coastguard Worker state.EmitInstruction(insn);
1946*03ce13f7SAndroid Build Coastguard Worker }
1947*03ce13f7SAndroid Build Coastguard Worker
1948*03ce13f7SAndroid Build Coastguard Worker // Emit all the blocks starting from entryPoint.
1949*03ce13f7SAndroid Build Coastguard Worker state.EmitBlocks(shader.getFunction(entryPoint).entry);
1950*03ce13f7SAndroid Build Coastguard Worker }
1951*03ce13f7SAndroid Build Coastguard Worker
EmitInstructions(InsnIterator begin,InsnIterator end)1952*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitInstructions(InsnIterator begin, InsnIterator end)
1953*03ce13f7SAndroid Build Coastguard Worker {
1954*03ce13f7SAndroid Build Coastguard Worker for(auto insn = begin; insn != end; insn++)
1955*03ce13f7SAndroid Build Coastguard Worker {
1956*03ce13f7SAndroid Build Coastguard Worker EmitInstruction(insn);
1957*03ce13f7SAndroid Build Coastguard Worker
1958*03ce13f7SAndroid Build Coastguard Worker if(shader.IsTerminator(insn.opcode()))
1959*03ce13f7SAndroid Build Coastguard Worker {
1960*03ce13f7SAndroid Build Coastguard Worker break;
1961*03ce13f7SAndroid Build Coastguard Worker }
1962*03ce13f7SAndroid Build Coastguard Worker }
1963*03ce13f7SAndroid Build Coastguard Worker }
1964*03ce13f7SAndroid Build Coastguard Worker
EmitInstruction(InsnIterator insn)1965*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitInstruction(InsnIterator insn)
1966*03ce13f7SAndroid Build Coastguard Worker {
1967*03ce13f7SAndroid Build Coastguard Worker auto opcode = insn.opcode();
1968*03ce13f7SAndroid Build Coastguard Worker
1969*03ce13f7SAndroid Build Coastguard Worker #if SPIRV_SHADER_ENABLE_DBG
1970*03ce13f7SAndroid Build Coastguard Worker {
1971*03ce13f7SAndroid Build Coastguard Worker auto text = spvtools::spvInstructionBinaryToText(
1972*03ce13f7SAndroid Build Coastguard Worker vk::SPIRV_VERSION,
1973*03ce13f7SAndroid Build Coastguard Worker insn.data(),
1974*03ce13f7SAndroid Build Coastguard Worker insn.wordCount(),
1975*03ce13f7SAndroid Build Coastguard Worker shader.insns.data(),
1976*03ce13f7SAndroid Build Coastguard Worker shader.insns.size(),
1977*03ce13f7SAndroid Build Coastguard Worker SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
1978*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}", text);
1979*03ce13f7SAndroid Build Coastguard Worker }
1980*03ce13f7SAndroid Build Coastguard Worker #endif // ENABLE_DBG_MSGS
1981*03ce13f7SAndroid Build Coastguard Worker
1982*03ce13f7SAndroid Build Coastguard Worker if(shader.IsTerminator(opcode))
1983*03ce13f7SAndroid Build Coastguard Worker {
1984*03ce13f7SAndroid Build Coastguard Worker switch(opcode)
1985*03ce13f7SAndroid Build Coastguard Worker {
1986*03ce13f7SAndroid Build Coastguard Worker case spv::OpBranch:
1987*03ce13f7SAndroid Build Coastguard Worker return EmitBranch(insn);
1988*03ce13f7SAndroid Build Coastguard Worker
1989*03ce13f7SAndroid Build Coastguard Worker case spv::OpBranchConditional:
1990*03ce13f7SAndroid Build Coastguard Worker return EmitBranchConditional(insn);
1991*03ce13f7SAndroid Build Coastguard Worker
1992*03ce13f7SAndroid Build Coastguard Worker case spv::OpSwitch:
1993*03ce13f7SAndroid Build Coastguard Worker return EmitSwitch(insn);
1994*03ce13f7SAndroid Build Coastguard Worker
1995*03ce13f7SAndroid Build Coastguard Worker case spv::OpUnreachable:
1996*03ce13f7SAndroid Build Coastguard Worker return EmitUnreachable(insn);
1997*03ce13f7SAndroid Build Coastguard Worker
1998*03ce13f7SAndroid Build Coastguard Worker case spv::OpReturn:
1999*03ce13f7SAndroid Build Coastguard Worker return EmitReturn(insn);
2000*03ce13f7SAndroid Build Coastguard Worker
2001*03ce13f7SAndroid Build Coastguard Worker case spv::OpKill:
2002*03ce13f7SAndroid Build Coastguard Worker case spv::OpTerminateInvocation:
2003*03ce13f7SAndroid Build Coastguard Worker return EmitTerminateInvocation(insn);
2004*03ce13f7SAndroid Build Coastguard Worker
2005*03ce13f7SAndroid Build Coastguard Worker default:
2006*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Unknown terminal instruction %s", shader.OpcodeName(opcode));
2007*03ce13f7SAndroid Build Coastguard Worker break;
2008*03ce13f7SAndroid Build Coastguard Worker }
2009*03ce13f7SAndroid Build Coastguard Worker }
2010*03ce13f7SAndroid Build Coastguard Worker else // Non-terminal instructions
2011*03ce13f7SAndroid Build Coastguard Worker {
2012*03ce13f7SAndroid Build Coastguard Worker switch(opcode)
2013*03ce13f7SAndroid Build Coastguard Worker {
2014*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVoid:
2015*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeInt:
2016*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFloat:
2017*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeBool:
2018*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeVector:
2019*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeArray:
2020*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeRuntimeArray:
2021*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeMatrix:
2022*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeStruct:
2023*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypePointer:
2024*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeForwardPointer:
2025*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeFunction:
2026*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeImage:
2027*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampledImage:
2028*03ce13f7SAndroid Build Coastguard Worker case spv::OpTypeSampler:
2029*03ce13f7SAndroid Build Coastguard Worker case spv::OpExecutionMode:
2030*03ce13f7SAndroid Build Coastguard Worker case spv::OpExecutionModeId:
2031*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemoryModel:
2032*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunction:
2033*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunctionEnd:
2034*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstant:
2035*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantNull:
2036*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantTrue:
2037*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantFalse:
2038*03ce13f7SAndroid Build Coastguard Worker case spv::OpConstantComposite:
2039*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstant:
2040*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantTrue:
2041*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantFalse:
2042*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantComposite:
2043*03ce13f7SAndroid Build Coastguard Worker case spv::OpSpecConstantOp:
2044*03ce13f7SAndroid Build Coastguard Worker case spv::OpUndef:
2045*03ce13f7SAndroid Build Coastguard Worker case spv::OpExtension:
2046*03ce13f7SAndroid Build Coastguard Worker case spv::OpCapability:
2047*03ce13f7SAndroid Build Coastguard Worker case spv::OpEntryPoint:
2048*03ce13f7SAndroid Build Coastguard Worker case spv::OpExtInstImport:
2049*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorate:
2050*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemberDecorate:
2051*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupDecorate:
2052*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupMemberDecorate:
2053*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorationGroup:
2054*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorateId:
2055*03ce13f7SAndroid Build Coastguard Worker case spv::OpDecorateString:
2056*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemberDecorateString:
2057*03ce13f7SAndroid Build Coastguard Worker case spv::OpName:
2058*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemberName:
2059*03ce13f7SAndroid Build Coastguard Worker case spv::OpSource:
2060*03ce13f7SAndroid Build Coastguard Worker case spv::OpSourceContinued:
2061*03ce13f7SAndroid Build Coastguard Worker case spv::OpSourceExtension:
2062*03ce13f7SAndroid Build Coastguard Worker case spv::OpNoLine:
2063*03ce13f7SAndroid Build Coastguard Worker case spv::OpModuleProcessed:
2064*03ce13f7SAndroid Build Coastguard Worker case spv::OpString:
2065*03ce13f7SAndroid Build Coastguard Worker // Nothing to do at emit time. These are either fully handled at analysis time,
2066*03ce13f7SAndroid Build Coastguard Worker // or don't require any work at all.
2067*03ce13f7SAndroid Build Coastguard Worker return;
2068*03ce13f7SAndroid Build Coastguard Worker
2069*03ce13f7SAndroid Build Coastguard Worker case spv::OpLine:
2070*03ce13f7SAndroid Build Coastguard Worker return; // TODO(b/251802301)
2071*03ce13f7SAndroid Build Coastguard Worker
2072*03ce13f7SAndroid Build Coastguard Worker case spv::OpLabel:
2073*03ce13f7SAndroid Build Coastguard Worker return;
2074*03ce13f7SAndroid Build Coastguard Worker
2075*03ce13f7SAndroid Build Coastguard Worker case spv::OpVariable:
2076*03ce13f7SAndroid Build Coastguard Worker return EmitVariable(insn);
2077*03ce13f7SAndroid Build Coastguard Worker
2078*03ce13f7SAndroid Build Coastguard Worker case spv::OpLoad:
2079*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicLoad:
2080*03ce13f7SAndroid Build Coastguard Worker return EmitLoad(insn);
2081*03ce13f7SAndroid Build Coastguard Worker
2082*03ce13f7SAndroid Build Coastguard Worker case spv::OpStore:
2083*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicStore:
2084*03ce13f7SAndroid Build Coastguard Worker return EmitStore(insn);
2085*03ce13f7SAndroid Build Coastguard Worker
2086*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIAdd:
2087*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicISub:
2088*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicSMin:
2089*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicSMax:
2090*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicUMin:
2091*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicUMax:
2092*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicAnd:
2093*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicOr:
2094*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicXor:
2095*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIIncrement:
2096*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIDecrement:
2097*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicExchange:
2098*03ce13f7SAndroid Build Coastguard Worker return EmitAtomicOp(insn);
2099*03ce13f7SAndroid Build Coastguard Worker
2100*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicCompareExchange:
2101*03ce13f7SAndroid Build Coastguard Worker return EmitAtomicCompareExchange(insn);
2102*03ce13f7SAndroid Build Coastguard Worker
2103*03ce13f7SAndroid Build Coastguard Worker case spv::OpAccessChain:
2104*03ce13f7SAndroid Build Coastguard Worker case spv::OpInBoundsAccessChain:
2105*03ce13f7SAndroid Build Coastguard Worker case spv::OpPtrAccessChain:
2106*03ce13f7SAndroid Build Coastguard Worker return EmitAccessChain(insn);
2107*03ce13f7SAndroid Build Coastguard Worker
2108*03ce13f7SAndroid Build Coastguard Worker case spv::OpCompositeConstruct:
2109*03ce13f7SAndroid Build Coastguard Worker return EmitCompositeConstruct(insn);
2110*03ce13f7SAndroid Build Coastguard Worker
2111*03ce13f7SAndroid Build Coastguard Worker case spv::OpCompositeInsert:
2112*03ce13f7SAndroid Build Coastguard Worker return EmitCompositeInsert(insn);
2113*03ce13f7SAndroid Build Coastguard Worker
2114*03ce13f7SAndroid Build Coastguard Worker case spv::OpCompositeExtract:
2115*03ce13f7SAndroid Build Coastguard Worker return EmitCompositeExtract(insn);
2116*03ce13f7SAndroid Build Coastguard Worker
2117*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorShuffle:
2118*03ce13f7SAndroid Build Coastguard Worker return EmitVectorShuffle(insn);
2119*03ce13f7SAndroid Build Coastguard Worker
2120*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorExtractDynamic:
2121*03ce13f7SAndroid Build Coastguard Worker return EmitVectorExtractDynamic(insn);
2122*03ce13f7SAndroid Build Coastguard Worker
2123*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorInsertDynamic:
2124*03ce13f7SAndroid Build Coastguard Worker return EmitVectorInsertDynamic(insn);
2125*03ce13f7SAndroid Build Coastguard Worker
2126*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorTimesScalar:
2127*03ce13f7SAndroid Build Coastguard Worker case spv::OpMatrixTimesScalar:
2128*03ce13f7SAndroid Build Coastguard Worker return EmitVectorTimesScalar(insn);
2129*03ce13f7SAndroid Build Coastguard Worker
2130*03ce13f7SAndroid Build Coastguard Worker case spv::OpMatrixTimesVector:
2131*03ce13f7SAndroid Build Coastguard Worker return EmitMatrixTimesVector(insn);
2132*03ce13f7SAndroid Build Coastguard Worker
2133*03ce13f7SAndroid Build Coastguard Worker case spv::OpVectorTimesMatrix:
2134*03ce13f7SAndroid Build Coastguard Worker return EmitVectorTimesMatrix(insn);
2135*03ce13f7SAndroid Build Coastguard Worker
2136*03ce13f7SAndroid Build Coastguard Worker case spv::OpMatrixTimesMatrix:
2137*03ce13f7SAndroid Build Coastguard Worker return EmitMatrixTimesMatrix(insn);
2138*03ce13f7SAndroid Build Coastguard Worker
2139*03ce13f7SAndroid Build Coastguard Worker case spv::OpOuterProduct:
2140*03ce13f7SAndroid Build Coastguard Worker return EmitOuterProduct(insn);
2141*03ce13f7SAndroid Build Coastguard Worker
2142*03ce13f7SAndroid Build Coastguard Worker case spv::OpTranspose:
2143*03ce13f7SAndroid Build Coastguard Worker return EmitTranspose(insn);
2144*03ce13f7SAndroid Build Coastguard Worker
2145*03ce13f7SAndroid Build Coastguard Worker case spv::OpNot:
2146*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitFieldInsert:
2147*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitFieldSExtract:
2148*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitFieldUExtract:
2149*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitReverse:
2150*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitCount:
2151*03ce13f7SAndroid Build Coastguard Worker case spv::OpSNegate:
2152*03ce13f7SAndroid Build Coastguard Worker case spv::OpFNegate:
2153*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalNot:
2154*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertFToU:
2155*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertFToS:
2156*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertSToF:
2157*03ce13f7SAndroid Build Coastguard Worker case spv::OpConvertUToF:
2158*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitcast:
2159*03ce13f7SAndroid Build Coastguard Worker case spv::OpIsInf:
2160*03ce13f7SAndroid Build Coastguard Worker case spv::OpIsNan:
2161*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdx:
2162*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdxCoarse:
2163*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdy:
2164*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdyCoarse:
2165*03ce13f7SAndroid Build Coastguard Worker case spv::OpFwidth:
2166*03ce13f7SAndroid Build Coastguard Worker case spv::OpFwidthCoarse:
2167*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdxFine:
2168*03ce13f7SAndroid Build Coastguard Worker case spv::OpDPdyFine:
2169*03ce13f7SAndroid Build Coastguard Worker case spv::OpFwidthFine:
2170*03ce13f7SAndroid Build Coastguard Worker case spv::OpQuantizeToF16:
2171*03ce13f7SAndroid Build Coastguard Worker return EmitUnaryOp(insn);
2172*03ce13f7SAndroid Build Coastguard Worker
2173*03ce13f7SAndroid Build Coastguard Worker case spv::OpIAdd:
2174*03ce13f7SAndroid Build Coastguard Worker case spv::OpISub:
2175*03ce13f7SAndroid Build Coastguard Worker case spv::OpIMul:
2176*03ce13f7SAndroid Build Coastguard Worker case spv::OpSDiv:
2177*03ce13f7SAndroid Build Coastguard Worker case spv::OpUDiv:
2178*03ce13f7SAndroid Build Coastguard Worker case spv::OpFAdd:
2179*03ce13f7SAndroid Build Coastguard Worker case spv::OpFSub:
2180*03ce13f7SAndroid Build Coastguard Worker case spv::OpFMul:
2181*03ce13f7SAndroid Build Coastguard Worker case spv::OpFDiv:
2182*03ce13f7SAndroid Build Coastguard Worker case spv::OpFMod:
2183*03ce13f7SAndroid Build Coastguard Worker case spv::OpFRem:
2184*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdEqual:
2185*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordEqual:
2186*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdNotEqual:
2187*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordNotEqual:
2188*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdLessThan:
2189*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordLessThan:
2190*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdGreaterThan:
2191*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordGreaterThan:
2192*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdLessThanEqual:
2193*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordLessThanEqual:
2194*03ce13f7SAndroid Build Coastguard Worker case spv::OpFOrdGreaterThanEqual:
2195*03ce13f7SAndroid Build Coastguard Worker case spv::OpFUnordGreaterThanEqual:
2196*03ce13f7SAndroid Build Coastguard Worker case spv::OpSMod:
2197*03ce13f7SAndroid Build Coastguard Worker case spv::OpSRem:
2198*03ce13f7SAndroid Build Coastguard Worker case spv::OpUMod:
2199*03ce13f7SAndroid Build Coastguard Worker case spv::OpIEqual:
2200*03ce13f7SAndroid Build Coastguard Worker case spv::OpINotEqual:
2201*03ce13f7SAndroid Build Coastguard Worker case spv::OpUGreaterThan:
2202*03ce13f7SAndroid Build Coastguard Worker case spv::OpSGreaterThan:
2203*03ce13f7SAndroid Build Coastguard Worker case spv::OpUGreaterThanEqual:
2204*03ce13f7SAndroid Build Coastguard Worker case spv::OpSGreaterThanEqual:
2205*03ce13f7SAndroid Build Coastguard Worker case spv::OpULessThan:
2206*03ce13f7SAndroid Build Coastguard Worker case spv::OpSLessThan:
2207*03ce13f7SAndroid Build Coastguard Worker case spv::OpULessThanEqual:
2208*03ce13f7SAndroid Build Coastguard Worker case spv::OpSLessThanEqual:
2209*03ce13f7SAndroid Build Coastguard Worker case spv::OpShiftRightLogical:
2210*03ce13f7SAndroid Build Coastguard Worker case spv::OpShiftRightArithmetic:
2211*03ce13f7SAndroid Build Coastguard Worker case spv::OpShiftLeftLogical:
2212*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitwiseOr:
2213*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitwiseXor:
2214*03ce13f7SAndroid Build Coastguard Worker case spv::OpBitwiseAnd:
2215*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalOr:
2216*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalAnd:
2217*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalEqual:
2218*03ce13f7SAndroid Build Coastguard Worker case spv::OpLogicalNotEqual:
2219*03ce13f7SAndroid Build Coastguard Worker case spv::OpUMulExtended:
2220*03ce13f7SAndroid Build Coastguard Worker case spv::OpSMulExtended:
2221*03ce13f7SAndroid Build Coastguard Worker case spv::OpIAddCarry:
2222*03ce13f7SAndroid Build Coastguard Worker case spv::OpISubBorrow:
2223*03ce13f7SAndroid Build Coastguard Worker return EmitBinaryOp(insn);
2224*03ce13f7SAndroid Build Coastguard Worker
2225*03ce13f7SAndroid Build Coastguard Worker case spv::OpDot:
2226*03ce13f7SAndroid Build Coastguard Worker case spv::OpSDot:
2227*03ce13f7SAndroid Build Coastguard Worker case spv::OpUDot:
2228*03ce13f7SAndroid Build Coastguard Worker case spv::OpSUDot:
2229*03ce13f7SAndroid Build Coastguard Worker case spv::OpSDotAccSat:
2230*03ce13f7SAndroid Build Coastguard Worker case spv::OpUDotAccSat:
2231*03ce13f7SAndroid Build Coastguard Worker case spv::OpSUDotAccSat:
2232*03ce13f7SAndroid Build Coastguard Worker return EmitDot(insn);
2233*03ce13f7SAndroid Build Coastguard Worker
2234*03ce13f7SAndroid Build Coastguard Worker case spv::OpSelect:
2235*03ce13f7SAndroid Build Coastguard Worker return EmitSelect(insn);
2236*03ce13f7SAndroid Build Coastguard Worker
2237*03ce13f7SAndroid Build Coastguard Worker case spv::OpExtInst:
2238*03ce13f7SAndroid Build Coastguard Worker return EmitExtendedInstruction(insn);
2239*03ce13f7SAndroid Build Coastguard Worker
2240*03ce13f7SAndroid Build Coastguard Worker case spv::OpAny:
2241*03ce13f7SAndroid Build Coastguard Worker return EmitAny(insn);
2242*03ce13f7SAndroid Build Coastguard Worker
2243*03ce13f7SAndroid Build Coastguard Worker case spv::OpAll:
2244*03ce13f7SAndroid Build Coastguard Worker return EmitAll(insn);
2245*03ce13f7SAndroid Build Coastguard Worker
2246*03ce13f7SAndroid Build Coastguard Worker case spv::OpPhi:
2247*03ce13f7SAndroid Build Coastguard Worker return EmitPhi(insn);
2248*03ce13f7SAndroid Build Coastguard Worker
2249*03ce13f7SAndroid Build Coastguard Worker case spv::OpSelectionMerge:
2250*03ce13f7SAndroid Build Coastguard Worker case spv::OpLoopMerge:
2251*03ce13f7SAndroid Build Coastguard Worker return;
2252*03ce13f7SAndroid Build Coastguard Worker
2253*03ce13f7SAndroid Build Coastguard Worker case spv::OpFunctionCall:
2254*03ce13f7SAndroid Build Coastguard Worker return EmitFunctionCall(insn);
2255*03ce13f7SAndroid Build Coastguard Worker
2256*03ce13f7SAndroid Build Coastguard Worker case spv::OpDemoteToHelperInvocation:
2257*03ce13f7SAndroid Build Coastguard Worker return EmitDemoteToHelperInvocation(insn);
2258*03ce13f7SAndroid Build Coastguard Worker
2259*03ce13f7SAndroid Build Coastguard Worker case spv::OpIsHelperInvocationEXT:
2260*03ce13f7SAndroid Build Coastguard Worker return EmitIsHelperInvocation(insn);
2261*03ce13f7SAndroid Build Coastguard Worker
2262*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleImplicitLod:
2263*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleExplicitLod:
2264*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleDrefImplicitLod:
2265*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleDrefExplicitLod:
2266*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjImplicitLod:
2267*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjExplicitLod:
2268*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjDrefImplicitLod:
2269*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageSampleProjDrefExplicitLod:
2270*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageGather:
2271*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageDrefGather:
2272*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageFetch:
2273*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQueryLod:
2274*03ce13f7SAndroid Build Coastguard Worker return EmitImageSample(ImageInstruction(insn, shader, *this));
2275*03ce13f7SAndroid Build Coastguard Worker
2276*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQuerySizeLod:
2277*03ce13f7SAndroid Build Coastguard Worker return EmitImageQuerySizeLod(insn);
2278*03ce13f7SAndroid Build Coastguard Worker
2279*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQuerySize:
2280*03ce13f7SAndroid Build Coastguard Worker return EmitImageQuerySize(insn);
2281*03ce13f7SAndroid Build Coastguard Worker
2282*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQueryLevels:
2283*03ce13f7SAndroid Build Coastguard Worker return EmitImageQueryLevels(insn);
2284*03ce13f7SAndroid Build Coastguard Worker
2285*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageQuerySamples:
2286*03ce13f7SAndroid Build Coastguard Worker return EmitImageQuerySamples(insn);
2287*03ce13f7SAndroid Build Coastguard Worker
2288*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageRead:
2289*03ce13f7SAndroid Build Coastguard Worker return EmitImageRead(ImageInstruction(insn, shader, *this));
2290*03ce13f7SAndroid Build Coastguard Worker
2291*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageWrite:
2292*03ce13f7SAndroid Build Coastguard Worker return EmitImageWrite(ImageInstruction(insn, shader, *this));
2293*03ce13f7SAndroid Build Coastguard Worker
2294*03ce13f7SAndroid Build Coastguard Worker case spv::OpImageTexelPointer:
2295*03ce13f7SAndroid Build Coastguard Worker return EmitImageTexelPointer(ImageInstruction(insn, shader, *this));
2296*03ce13f7SAndroid Build Coastguard Worker
2297*03ce13f7SAndroid Build Coastguard Worker case spv::OpSampledImage:
2298*03ce13f7SAndroid Build Coastguard Worker return EmitSampledImage(insn);
2299*03ce13f7SAndroid Build Coastguard Worker
2300*03ce13f7SAndroid Build Coastguard Worker case spv::OpImage:
2301*03ce13f7SAndroid Build Coastguard Worker return EmitImage(insn);
2302*03ce13f7SAndroid Build Coastguard Worker
2303*03ce13f7SAndroid Build Coastguard Worker case spv::OpCopyObject:
2304*03ce13f7SAndroid Build Coastguard Worker case spv::OpCopyLogical:
2305*03ce13f7SAndroid Build Coastguard Worker return EmitCopyObject(insn);
2306*03ce13f7SAndroid Build Coastguard Worker
2307*03ce13f7SAndroid Build Coastguard Worker case spv::OpCopyMemory:
2308*03ce13f7SAndroid Build Coastguard Worker return EmitCopyMemory(insn);
2309*03ce13f7SAndroid Build Coastguard Worker
2310*03ce13f7SAndroid Build Coastguard Worker case spv::OpControlBarrier:
2311*03ce13f7SAndroid Build Coastguard Worker return EmitControlBarrier(insn);
2312*03ce13f7SAndroid Build Coastguard Worker
2313*03ce13f7SAndroid Build Coastguard Worker case spv::OpMemoryBarrier:
2314*03ce13f7SAndroid Build Coastguard Worker return EmitMemoryBarrier(insn);
2315*03ce13f7SAndroid Build Coastguard Worker
2316*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformElect:
2317*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformAll:
2318*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformAny:
2319*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformAllEqual:
2320*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBroadcast:
2321*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBroadcastFirst:
2322*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformQuadBroadcast:
2323*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformQuadSwap:
2324*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallot:
2325*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformInverseBallot:
2326*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotBitExtract:
2327*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotBitCount:
2328*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotFindLSB:
2329*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBallotFindMSB:
2330*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffle:
2331*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffleXor:
2332*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffleUp:
2333*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformShuffleDown:
2334*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformIAdd:
2335*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFAdd:
2336*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformIMul:
2337*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFMul:
2338*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformSMin:
2339*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformUMin:
2340*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFMin:
2341*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformSMax:
2342*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformUMax:
2343*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformFMax:
2344*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBitwiseAnd:
2345*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBitwiseOr:
2346*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformBitwiseXor:
2347*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformLogicalAnd:
2348*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformLogicalOr:
2349*03ce13f7SAndroid Build Coastguard Worker case spv::OpGroupNonUniformLogicalXor:
2350*03ce13f7SAndroid Build Coastguard Worker return EmitGroupNonUniform(insn);
2351*03ce13f7SAndroid Build Coastguard Worker
2352*03ce13f7SAndroid Build Coastguard Worker case spv::OpArrayLength:
2353*03ce13f7SAndroid Build Coastguard Worker return EmitArrayLength(insn);
2354*03ce13f7SAndroid Build Coastguard Worker
2355*03ce13f7SAndroid Build Coastguard Worker default:
2356*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Unknown non-terminal instruction %s", shader.OpcodeName(opcode));
2357*03ce13f7SAndroid Build Coastguard Worker break;
2358*03ce13f7SAndroid Build Coastguard Worker }
2359*03ce13f7SAndroid Build Coastguard Worker }
2360*03ce13f7SAndroid Build Coastguard Worker }
2361*03ce13f7SAndroid Build Coastguard Worker
EmitAccessChain(InsnIterator insn)2362*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitAccessChain(InsnIterator insn)
2363*03ce13f7SAndroid Build Coastguard Worker {
2364*03ce13f7SAndroid Build Coastguard Worker Type::ID typeId = insn.word(1);
2365*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
2366*03ce13f7SAndroid Build Coastguard Worker bool nonUniform = shader.GetDecorationsForId(resultId).NonUniform;
2367*03ce13f7SAndroid Build Coastguard Worker Object::ID baseId = insn.word(3);
2368*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(typeId);
2369*03ce13f7SAndroid Build Coastguard Worker ASSERT(type.componentCount == 1);
2370*03ce13f7SAndroid Build Coastguard Worker ASSERT(shader.getObject(resultId).kind == Object::Kind::Pointer);
2371*03ce13f7SAndroid Build Coastguard Worker
2372*03ce13f7SAndroid Build Coastguard Worker Object::ID elementId = (insn.opcode() == spv::OpPtrAccessChain) ? insn.word(4) : 0;
2373*03ce13f7SAndroid Build Coastguard Worker int indexId = (insn.opcode() == spv::OpPtrAccessChain) ? 5 : 4;
2374*03ce13f7SAndroid Build Coastguard Worker // TODO(b/236280746): Eliminate lookahead by optimizing inside SIMD::Pointer.
2375*03ce13f7SAndroid Build Coastguard Worker for(auto it = insn; it != shader.end(); it++)
2376*03ce13f7SAndroid Build Coastguard Worker {
2377*03ce13f7SAndroid Build Coastguard Worker if(it.opcode() == spv::OpLoad)
2378*03ce13f7SAndroid Build Coastguard Worker {
2379*03ce13f7SAndroid Build Coastguard Worker Object::ID pointerId = it.word(3);
2380*03ce13f7SAndroid Build Coastguard Worker if(pointerId.value() == resultId.value())
2381*03ce13f7SAndroid Build Coastguard Worker {
2382*03ce13f7SAndroid Build Coastguard Worker nonUniform |= shader.GetDecorationsForId(it.word(2)).NonUniform;
2383*03ce13f7SAndroid Build Coastguard Worker break;
2384*03ce13f7SAndroid Build Coastguard Worker }
2385*03ce13f7SAndroid Build Coastguard Worker }
2386*03ce13f7SAndroid Build Coastguard Worker }
2387*03ce13f7SAndroid Build Coastguard Worker
2388*03ce13f7SAndroid Build Coastguard Worker if(Spirv::IsExplicitLayout(type.storageClass))
2389*03ce13f7SAndroid Build Coastguard Worker {
2390*03ce13f7SAndroid Build Coastguard Worker auto ptr = WalkExplicitLayoutAccessChain(baseId, elementId, Span(insn, indexId, insn.wordCount() - indexId), nonUniform);
2391*03ce13f7SAndroid Build Coastguard Worker createPointer(resultId, ptr);
2392*03ce13f7SAndroid Build Coastguard Worker }
2393*03ce13f7SAndroid Build Coastguard Worker else
2394*03ce13f7SAndroid Build Coastguard Worker {
2395*03ce13f7SAndroid Build Coastguard Worker auto ptr = WalkAccessChain(baseId, elementId, Span(insn, indexId, insn.wordCount() - indexId), nonUniform);
2396*03ce13f7SAndroid Build Coastguard Worker createPointer(resultId, ptr);
2397*03ce13f7SAndroid Build Coastguard Worker }
2398*03ce13f7SAndroid Build Coastguard Worker }
2399*03ce13f7SAndroid Build Coastguard Worker
EmitCompositeConstruct(InsnIterator insn)2400*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitCompositeConstruct(InsnIterator insn)
2401*03ce13f7SAndroid Build Coastguard Worker {
2402*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2403*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2404*03ce13f7SAndroid Build Coastguard Worker auto offset = 0u;
2405*03ce13f7SAndroid Build Coastguard Worker
2406*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < insn.wordCount() - 3; i++)
2407*03ce13f7SAndroid Build Coastguard Worker {
2408*03ce13f7SAndroid Build Coastguard Worker Object::ID srcObjectId = insn.word(3u + i);
2409*03ce13f7SAndroid Build Coastguard Worker auto &srcObject = shader.getObject(srcObjectId);
2410*03ce13f7SAndroid Build Coastguard Worker auto &srcObjectTy = shader.getType(srcObject);
2411*03ce13f7SAndroid Build Coastguard Worker Operand srcObjectAccess(shader, *this, srcObjectId);
2412*03ce13f7SAndroid Build Coastguard Worker
2413*03ce13f7SAndroid Build Coastguard Worker for(auto j = 0u; j < srcObjectTy.componentCount; j++)
2414*03ce13f7SAndroid Build Coastguard Worker {
2415*03ce13f7SAndroid Build Coastguard Worker dst.move(offset++, srcObjectAccess.Float(j));
2416*03ce13f7SAndroid Build Coastguard Worker }
2417*03ce13f7SAndroid Build Coastguard Worker }
2418*03ce13f7SAndroid Build Coastguard Worker }
2419*03ce13f7SAndroid Build Coastguard Worker
EmitCompositeInsert(InsnIterator insn)2420*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitCompositeInsert(InsnIterator insn)
2421*03ce13f7SAndroid Build Coastguard Worker {
2422*03ce13f7SAndroid Build Coastguard Worker Type::ID resultTypeId = insn.word(1);
2423*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(resultTypeId);
2424*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2425*03ce13f7SAndroid Build Coastguard Worker auto &newPartObject = shader.getObject(insn.word(3));
2426*03ce13f7SAndroid Build Coastguard Worker auto &newPartObjectTy = shader.getType(newPartObject);
2427*03ce13f7SAndroid Build Coastguard Worker auto firstNewComponent = shader.WalkLiteralAccessChain(resultTypeId, Span(insn, 5, insn.wordCount() - 5));
2428*03ce13f7SAndroid Build Coastguard Worker
2429*03ce13f7SAndroid Build Coastguard Worker Operand srcObjectAccess(shader, *this, insn.word(4));
2430*03ce13f7SAndroid Build Coastguard Worker Operand newPartObjectAccess(shader, *this, insn.word(3));
2431*03ce13f7SAndroid Build Coastguard Worker
2432*03ce13f7SAndroid Build Coastguard Worker // old components before
2433*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < firstNewComponent; i++)
2434*03ce13f7SAndroid Build Coastguard Worker {
2435*03ce13f7SAndroid Build Coastguard Worker dst.move(i, srcObjectAccess.Float(i));
2436*03ce13f7SAndroid Build Coastguard Worker }
2437*03ce13f7SAndroid Build Coastguard Worker // new part
2438*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < newPartObjectTy.componentCount; i++)
2439*03ce13f7SAndroid Build Coastguard Worker {
2440*03ce13f7SAndroid Build Coastguard Worker dst.move(firstNewComponent + i, newPartObjectAccess.Float(i));
2441*03ce13f7SAndroid Build Coastguard Worker }
2442*03ce13f7SAndroid Build Coastguard Worker // old components after
2443*03ce13f7SAndroid Build Coastguard Worker for(auto i = firstNewComponent + newPartObjectTy.componentCount; i < type.componentCount; i++)
2444*03ce13f7SAndroid Build Coastguard Worker {
2445*03ce13f7SAndroid Build Coastguard Worker dst.move(i, srcObjectAccess.Float(i));
2446*03ce13f7SAndroid Build Coastguard Worker }
2447*03ce13f7SAndroid Build Coastguard Worker }
2448*03ce13f7SAndroid Build Coastguard Worker
EmitCompositeExtract(InsnIterator insn)2449*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitCompositeExtract(InsnIterator insn)
2450*03ce13f7SAndroid Build Coastguard Worker {
2451*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2452*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2453*03ce13f7SAndroid Build Coastguard Worker auto &compositeObject = shader.getObject(insn.word(3));
2454*03ce13f7SAndroid Build Coastguard Worker Type::ID compositeTypeId = compositeObject.definition.word(1);
2455*03ce13f7SAndroid Build Coastguard Worker auto firstComponent = shader.WalkLiteralAccessChain(compositeTypeId, Span(insn, 4, insn.wordCount() - 4));
2456*03ce13f7SAndroid Build Coastguard Worker
2457*03ce13f7SAndroid Build Coastguard Worker Operand compositeObjectAccess(shader, *this, insn.word(3));
2458*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < type.componentCount; i++)
2459*03ce13f7SAndroid Build Coastguard Worker {
2460*03ce13f7SAndroid Build Coastguard Worker dst.move(i, compositeObjectAccess.Float(firstComponent + i));
2461*03ce13f7SAndroid Build Coastguard Worker }
2462*03ce13f7SAndroid Build Coastguard Worker }
2463*03ce13f7SAndroid Build Coastguard Worker
EmitVectorShuffle(InsnIterator insn)2464*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitVectorShuffle(InsnIterator insn)
2465*03ce13f7SAndroid Build Coastguard Worker {
2466*03ce13f7SAndroid Build Coastguard Worker // Note: number of components in result, first vector, and second vector are all independent.
2467*03ce13f7SAndroid Build Coastguard Worker uint32_t resultSize = shader.getType(insn.resultTypeId()).componentCount;
2468*03ce13f7SAndroid Build Coastguard Worker uint32_t firstVectorSize = shader.getObjectType(insn.word(3)).componentCount;
2469*03ce13f7SAndroid Build Coastguard Worker
2470*03ce13f7SAndroid Build Coastguard Worker auto &result = createIntermediate(insn.resultId(), resultSize);
2471*03ce13f7SAndroid Build Coastguard Worker Operand firstVector(shader, *this, insn.word(3));
2472*03ce13f7SAndroid Build Coastguard Worker Operand secondVector(shader, *this, insn.word(4));
2473*03ce13f7SAndroid Build Coastguard Worker
2474*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0u; i < resultSize; i++)
2475*03ce13f7SAndroid Build Coastguard Worker {
2476*03ce13f7SAndroid Build Coastguard Worker uint32_t selector = insn.word(5 + i);
2477*03ce13f7SAndroid Build Coastguard Worker if(selector == 0xFFFFFFFF) // Undefined value.
2478*03ce13f7SAndroid Build Coastguard Worker {
2479*03ce13f7SAndroid Build Coastguard Worker result.move(i, SIMD::Float());
2480*03ce13f7SAndroid Build Coastguard Worker }
2481*03ce13f7SAndroid Build Coastguard Worker else if(selector < firstVectorSize)
2482*03ce13f7SAndroid Build Coastguard Worker {
2483*03ce13f7SAndroid Build Coastguard Worker result.move(i, firstVector.Float(selector));
2484*03ce13f7SAndroid Build Coastguard Worker }
2485*03ce13f7SAndroid Build Coastguard Worker else
2486*03ce13f7SAndroid Build Coastguard Worker {
2487*03ce13f7SAndroid Build Coastguard Worker result.move(i, secondVector.Float(selector - firstVectorSize));
2488*03ce13f7SAndroid Build Coastguard Worker }
2489*03ce13f7SAndroid Build Coastguard Worker }
2490*03ce13f7SAndroid Build Coastguard Worker }
2491*03ce13f7SAndroid Build Coastguard Worker
EmitVectorExtractDynamic(InsnIterator insn)2492*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitVectorExtractDynamic(InsnIterator insn)
2493*03ce13f7SAndroid Build Coastguard Worker {
2494*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2495*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2496*03ce13f7SAndroid Build Coastguard Worker auto &srcType = shader.getObjectType(insn.word(3));
2497*03ce13f7SAndroid Build Coastguard Worker
2498*03ce13f7SAndroid Build Coastguard Worker Operand src(shader, *this, insn.word(3));
2499*03ce13f7SAndroid Build Coastguard Worker Operand index(shader, *this, insn.word(4));
2500*03ce13f7SAndroid Build Coastguard Worker
2501*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt v = SIMD::UInt(0);
2502*03ce13f7SAndroid Build Coastguard Worker
2503*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < srcType.componentCount; i++)
2504*03ce13f7SAndroid Build Coastguard Worker {
2505*03ce13f7SAndroid Build Coastguard Worker v |= CmpEQ(index.UInt(0), SIMD::UInt(i)) & src.UInt(i);
2506*03ce13f7SAndroid Build Coastguard Worker }
2507*03ce13f7SAndroid Build Coastguard Worker
2508*03ce13f7SAndroid Build Coastguard Worker dst.move(0, v);
2509*03ce13f7SAndroid Build Coastguard Worker }
2510*03ce13f7SAndroid Build Coastguard Worker
EmitVectorInsertDynamic(InsnIterator insn)2511*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitVectorInsertDynamic(InsnIterator insn)
2512*03ce13f7SAndroid Build Coastguard Worker {
2513*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2514*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2515*03ce13f7SAndroid Build Coastguard Worker
2516*03ce13f7SAndroid Build Coastguard Worker Operand src(shader, *this, insn.word(3));
2517*03ce13f7SAndroid Build Coastguard Worker Operand component(shader, *this, insn.word(4));
2518*03ce13f7SAndroid Build Coastguard Worker Operand index(shader, *this, insn.word(5));
2519*03ce13f7SAndroid Build Coastguard Worker
2520*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < type.componentCount; i++)
2521*03ce13f7SAndroid Build Coastguard Worker {
2522*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt mask = CmpEQ(SIMD::UInt(i), index.UInt(0));
2523*03ce13f7SAndroid Build Coastguard Worker dst.move(i, (src.UInt(i) & ~mask) | (component.UInt(0) & mask));
2524*03ce13f7SAndroid Build Coastguard Worker }
2525*03ce13f7SAndroid Build Coastguard Worker }
2526*03ce13f7SAndroid Build Coastguard Worker
EmitSelect(InsnIterator insn)2527*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitSelect(InsnIterator insn)
2528*03ce13f7SAndroid Build Coastguard Worker {
2529*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2530*03ce13f7SAndroid Build Coastguard Worker auto result = shader.getObject(insn.resultId());
2531*03ce13f7SAndroid Build Coastguard Worker auto cond = Operand(shader, *this, insn.word(3));
2532*03ce13f7SAndroid Build Coastguard Worker auto condIsScalar = (cond.componentCount == 1);
2533*03ce13f7SAndroid Build Coastguard Worker
2534*03ce13f7SAndroid Build Coastguard Worker if(result.kind == Object::Kind::Pointer)
2535*03ce13f7SAndroid Build Coastguard Worker {
2536*03ce13f7SAndroid Build Coastguard Worker ASSERT(condIsScalar);
2537*03ce13f7SAndroid Build Coastguard Worker ASSERT(type.storageClass == spv::StorageClassPhysicalStorageBuffer);
2538*03ce13f7SAndroid Build Coastguard Worker
2539*03ce13f7SAndroid Build Coastguard Worker auto &lhs = getPointer(insn.word(4));
2540*03ce13f7SAndroid Build Coastguard Worker auto &rhs = getPointer(insn.word(5));
2541*03ce13f7SAndroid Build Coastguard Worker createPointer(insn.resultId(), SIMD::Pointer::IfThenElse(cond.Int(0), lhs, rhs));
2542*03ce13f7SAndroid Build Coastguard Worker
2543*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(3), cond);
2544*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(4), lhs);
2545*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(5), rhs);
2546*03ce13f7SAndroid Build Coastguard Worker }
2547*03ce13f7SAndroid Build Coastguard Worker else
2548*03ce13f7SAndroid Build Coastguard Worker {
2549*03ce13f7SAndroid Build Coastguard Worker auto lhs = Operand(shader, *this, insn.word(4));
2550*03ce13f7SAndroid Build Coastguard Worker auto rhs = Operand(shader, *this, insn.word(5));
2551*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2552*03ce13f7SAndroid Build Coastguard Worker
2553*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < type.componentCount; i++)
2554*03ce13f7SAndroid Build Coastguard Worker {
2555*03ce13f7SAndroid Build Coastguard Worker auto sel = cond.Int(condIsScalar ? 0 : i);
2556*03ce13f7SAndroid Build Coastguard Worker dst.move(i, (sel & lhs.Int(i)) | (~sel & rhs.Int(i))); // TODO: IfThenElse()
2557*03ce13f7SAndroid Build Coastguard Worker }
2558*03ce13f7SAndroid Build Coastguard Worker
2559*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(2), dst);
2560*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(3), cond);
2561*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(4), lhs);
2562*03ce13f7SAndroid Build Coastguard Worker SPIRV_SHADER_DBG("{0}: {1}", insn.word(5), rhs);
2563*03ce13f7SAndroid Build Coastguard Worker }
2564*03ce13f7SAndroid Build Coastguard Worker }
2565*03ce13f7SAndroid Build Coastguard Worker
EmitAny(InsnIterator insn)2566*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitAny(InsnIterator insn)
2567*03ce13f7SAndroid Build Coastguard Worker {
2568*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2569*03ce13f7SAndroid Build Coastguard Worker ASSERT(type.componentCount == 1);
2570*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2571*03ce13f7SAndroid Build Coastguard Worker auto &srcType = shader.getObjectType(insn.word(3));
2572*03ce13f7SAndroid Build Coastguard Worker auto src = Operand(shader, *this, insn.word(3));
2573*03ce13f7SAndroid Build Coastguard Worker
2574*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt result = src.UInt(0);
2575*03ce13f7SAndroid Build Coastguard Worker
2576*03ce13f7SAndroid Build Coastguard Worker for(auto i = 1u; i < srcType.componentCount; i++)
2577*03ce13f7SAndroid Build Coastguard Worker {
2578*03ce13f7SAndroid Build Coastguard Worker result |= src.UInt(i);
2579*03ce13f7SAndroid Build Coastguard Worker }
2580*03ce13f7SAndroid Build Coastguard Worker
2581*03ce13f7SAndroid Build Coastguard Worker dst.move(0, result);
2582*03ce13f7SAndroid Build Coastguard Worker }
2583*03ce13f7SAndroid Build Coastguard Worker
EmitAll(InsnIterator insn)2584*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitAll(InsnIterator insn)
2585*03ce13f7SAndroid Build Coastguard Worker {
2586*03ce13f7SAndroid Build Coastguard Worker auto &type = shader.getType(insn.resultTypeId());
2587*03ce13f7SAndroid Build Coastguard Worker ASSERT(type.componentCount == 1);
2588*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2589*03ce13f7SAndroid Build Coastguard Worker auto &srcType = shader.getObjectType(insn.word(3));
2590*03ce13f7SAndroid Build Coastguard Worker auto src = Operand(shader, *this, insn.word(3));
2591*03ce13f7SAndroid Build Coastguard Worker
2592*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt result = src.UInt(0);
2593*03ce13f7SAndroid Build Coastguard Worker
2594*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 1; i < srcType.componentCount; i++)
2595*03ce13f7SAndroid Build Coastguard Worker {
2596*03ce13f7SAndroid Build Coastguard Worker result &= src.UInt(i);
2597*03ce13f7SAndroid Build Coastguard Worker }
2598*03ce13f7SAndroid Build Coastguard Worker
2599*03ce13f7SAndroid Build Coastguard Worker dst.move(0, result);
2600*03ce13f7SAndroid Build Coastguard Worker }
2601*03ce13f7SAndroid Build Coastguard Worker
EmitAtomicOp(InsnIterator insn)2602*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitAtomicOp(InsnIterator insn)
2603*03ce13f7SAndroid Build Coastguard Worker {
2604*03ce13f7SAndroid Build Coastguard Worker auto &resultType = shader.getType(Type::ID(insn.word(1)));
2605*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
2606*03ce13f7SAndroid Build Coastguard Worker Object::ID pointerId = insn.word(3);
2607*03ce13f7SAndroid Build Coastguard Worker Object::ID semanticsId = insn.word(5);
2608*03ce13f7SAndroid Build Coastguard Worker auto memorySemantics = static_cast<spv::MemorySemanticsMask>(shader.getObject(semanticsId).constantValue[0]);
2609*03ce13f7SAndroid Build Coastguard Worker auto memoryOrder = shader.MemoryOrder(memorySemantics);
2610*03ce13f7SAndroid Build Coastguard Worker // Where no value is provided (increment/decrement) use an implicit value of 1.
2611*03ce13f7SAndroid Build Coastguard Worker auto value = (insn.wordCount() == 7) ? Operand(shader, *this, insn.word(6)).UInt(0) : RValue<SIMD::UInt>(1);
2612*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(resultId, resultType.componentCount);
2613*03ce13f7SAndroid Build Coastguard Worker auto ptr = getPointer(pointerId);
2614*03ce13f7SAndroid Build Coastguard Worker
2615*03ce13f7SAndroid Build Coastguard Worker SIMD::Int mask = activeLaneMask() & storesAndAtomicsMask();
2616*03ce13f7SAndroid Build Coastguard Worker
2617*03ce13f7SAndroid Build Coastguard Worker if((shader.getObject(pointerId).opcode() == spv::OpImageTexelPointer) && ptr.isBasePlusOffset)
2618*03ce13f7SAndroid Build Coastguard Worker {
2619*03ce13f7SAndroid Build Coastguard Worker mask &= ptr.isInBounds(sizeof(int32_t), OutOfBoundsBehavior::Nullify);
2620*03ce13f7SAndroid Build Coastguard Worker }
2621*03ce13f7SAndroid Build Coastguard Worker
2622*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt result(0);
2623*03ce13f7SAndroid Build Coastguard Worker for(int j = 0; j < SIMD::Width; j++)
2624*03ce13f7SAndroid Build Coastguard Worker {
2625*03ce13f7SAndroid Build Coastguard Worker If(Extract(mask, j) != 0)
2626*03ce13f7SAndroid Build Coastguard Worker {
2627*03ce13f7SAndroid Build Coastguard Worker auto laneValue = Extract(value, j);
2628*03ce13f7SAndroid Build Coastguard Worker UInt v;
2629*03ce13f7SAndroid Build Coastguard Worker switch(insn.opcode())
2630*03ce13f7SAndroid Build Coastguard Worker {
2631*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIAdd:
2632*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIIncrement:
2633*03ce13f7SAndroid Build Coastguard Worker v = AddAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2634*03ce13f7SAndroid Build Coastguard Worker break;
2635*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicISub:
2636*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicIDecrement:
2637*03ce13f7SAndroid Build Coastguard Worker v = SubAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2638*03ce13f7SAndroid Build Coastguard Worker break;
2639*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicAnd:
2640*03ce13f7SAndroid Build Coastguard Worker v = AndAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2641*03ce13f7SAndroid Build Coastguard Worker break;
2642*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicOr:
2643*03ce13f7SAndroid Build Coastguard Worker v = OrAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2644*03ce13f7SAndroid Build Coastguard Worker break;
2645*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicXor:
2646*03ce13f7SAndroid Build Coastguard Worker v = XorAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2647*03ce13f7SAndroid Build Coastguard Worker break;
2648*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicSMin:
2649*03ce13f7SAndroid Build Coastguard Worker v = As<UInt>(MinAtomic(Pointer<Int>(ptr.getPointerForLane(j)), As<Int>(laneValue), memoryOrder));
2650*03ce13f7SAndroid Build Coastguard Worker break;
2651*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicSMax:
2652*03ce13f7SAndroid Build Coastguard Worker v = As<UInt>(MaxAtomic(Pointer<Int>(ptr.getPointerForLane(j)), As<Int>(laneValue), memoryOrder));
2653*03ce13f7SAndroid Build Coastguard Worker break;
2654*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicUMin:
2655*03ce13f7SAndroid Build Coastguard Worker v = MinAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2656*03ce13f7SAndroid Build Coastguard Worker break;
2657*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicUMax:
2658*03ce13f7SAndroid Build Coastguard Worker v = MaxAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2659*03ce13f7SAndroid Build Coastguard Worker break;
2660*03ce13f7SAndroid Build Coastguard Worker case spv::OpAtomicExchange:
2661*03ce13f7SAndroid Build Coastguard Worker v = ExchangeAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, memoryOrder);
2662*03ce13f7SAndroid Build Coastguard Worker break;
2663*03ce13f7SAndroid Build Coastguard Worker default:
2664*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("%s", shader.OpcodeName(insn.opcode()));
2665*03ce13f7SAndroid Build Coastguard Worker break;
2666*03ce13f7SAndroid Build Coastguard Worker }
2667*03ce13f7SAndroid Build Coastguard Worker result = Insert(result, v, j);
2668*03ce13f7SAndroid Build Coastguard Worker }
2669*03ce13f7SAndroid Build Coastguard Worker }
2670*03ce13f7SAndroid Build Coastguard Worker
2671*03ce13f7SAndroid Build Coastguard Worker dst.move(0, result);
2672*03ce13f7SAndroid Build Coastguard Worker }
2673*03ce13f7SAndroid Build Coastguard Worker
EmitAtomicCompareExchange(InsnIterator insn)2674*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitAtomicCompareExchange(InsnIterator insn)
2675*03ce13f7SAndroid Build Coastguard Worker {
2676*03ce13f7SAndroid Build Coastguard Worker // Separate from EmitAtomicOp due to different instruction encoding
2677*03ce13f7SAndroid Build Coastguard Worker auto &resultType = shader.getType(Type::ID(insn.word(1)));
2678*03ce13f7SAndroid Build Coastguard Worker Object::ID resultId = insn.word(2);
2679*03ce13f7SAndroid Build Coastguard Worker
2680*03ce13f7SAndroid Build Coastguard Worker auto memorySemanticsEqual = static_cast<spv::MemorySemanticsMask>(shader.getObject(insn.word(5)).constantValue[0]);
2681*03ce13f7SAndroid Build Coastguard Worker auto memoryOrderEqual = shader.MemoryOrder(memorySemanticsEqual);
2682*03ce13f7SAndroid Build Coastguard Worker auto memorySemanticsUnequal = static_cast<spv::MemorySemanticsMask>(shader.getObject(insn.word(6)).constantValue[0]);
2683*03ce13f7SAndroid Build Coastguard Worker auto memoryOrderUnequal = shader.MemoryOrder(memorySemanticsUnequal);
2684*03ce13f7SAndroid Build Coastguard Worker
2685*03ce13f7SAndroid Build Coastguard Worker auto value = Operand(shader, *this, insn.word(7));
2686*03ce13f7SAndroid Build Coastguard Worker auto comparator = Operand(shader, *this, insn.word(8));
2687*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(resultId, resultType.componentCount);
2688*03ce13f7SAndroid Build Coastguard Worker auto ptr = getPointer(insn.word(3));
2689*03ce13f7SAndroid Build Coastguard Worker
2690*03ce13f7SAndroid Build Coastguard Worker SIMD::UInt x(0);
2691*03ce13f7SAndroid Build Coastguard Worker auto mask = activeLaneMask() & storesAndAtomicsMask();
2692*03ce13f7SAndroid Build Coastguard Worker for(int j = 0; j < SIMD::Width; j++)
2693*03ce13f7SAndroid Build Coastguard Worker {
2694*03ce13f7SAndroid Build Coastguard Worker If(Extract(mask, j) != 0)
2695*03ce13f7SAndroid Build Coastguard Worker {
2696*03ce13f7SAndroid Build Coastguard Worker auto laneValue = Extract(value.UInt(0), j);
2697*03ce13f7SAndroid Build Coastguard Worker auto laneComparator = Extract(comparator.UInt(0), j);
2698*03ce13f7SAndroid Build Coastguard Worker UInt v = CompareExchangeAtomic(Pointer<UInt>(ptr.getPointerForLane(j)), laneValue, laneComparator, memoryOrderEqual, memoryOrderUnequal);
2699*03ce13f7SAndroid Build Coastguard Worker x = Insert(x, v, j);
2700*03ce13f7SAndroid Build Coastguard Worker }
2701*03ce13f7SAndroid Build Coastguard Worker }
2702*03ce13f7SAndroid Build Coastguard Worker
2703*03ce13f7SAndroid Build Coastguard Worker dst.move(0, x);
2704*03ce13f7SAndroid Build Coastguard Worker }
2705*03ce13f7SAndroid Build Coastguard Worker
EmitCopyObject(InsnIterator insn)2706*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitCopyObject(InsnIterator insn)
2707*03ce13f7SAndroid Build Coastguard Worker {
2708*03ce13f7SAndroid Build Coastguard Worker auto src = Operand(shader, *this, insn.word(3));
2709*03ce13f7SAndroid Build Coastguard Worker if(src.isPointer())
2710*03ce13f7SAndroid Build Coastguard Worker {
2711*03ce13f7SAndroid Build Coastguard Worker createPointer(insn.resultId(), src.Pointer());
2712*03ce13f7SAndroid Build Coastguard Worker }
2713*03ce13f7SAndroid Build Coastguard Worker else if(src.isSampledImage())
2714*03ce13f7SAndroid Build Coastguard Worker {
2715*03ce13f7SAndroid Build Coastguard Worker createSampledImage(insn.resultId(), src.SampledImage());
2716*03ce13f7SAndroid Build Coastguard Worker }
2717*03ce13f7SAndroid Build Coastguard Worker else
2718*03ce13f7SAndroid Build Coastguard Worker {
2719*03ce13f7SAndroid Build Coastguard Worker auto type = shader.getType(insn.resultTypeId());
2720*03ce13f7SAndroid Build Coastguard Worker auto &dst = createIntermediate(insn.resultId(), type.componentCount);
2721*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < type.componentCount; i++)
2722*03ce13f7SAndroid Build Coastguard Worker {
2723*03ce13f7SAndroid Build Coastguard Worker dst.move(i, src.Int(i));
2724*03ce13f7SAndroid Build Coastguard Worker }
2725*03ce13f7SAndroid Build Coastguard Worker }
2726*03ce13f7SAndroid Build Coastguard Worker }
2727*03ce13f7SAndroid Build Coastguard Worker
EmitArrayLength(InsnIterator insn)2728*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitArrayLength(InsnIterator insn)
2729*03ce13f7SAndroid Build Coastguard Worker {
2730*03ce13f7SAndroid Build Coastguard Worker auto structPtrId = Object::ID(insn.word(3));
2731*03ce13f7SAndroid Build Coastguard Worker auto arrayFieldIdx = insn.word(4);
2732*03ce13f7SAndroid Build Coastguard Worker
2733*03ce13f7SAndroid Build Coastguard Worker auto &resultType = shader.getType(insn.resultTypeId());
2734*03ce13f7SAndroid Build Coastguard Worker ASSERT(resultType.componentCount == 1);
2735*03ce13f7SAndroid Build Coastguard Worker ASSERT(resultType.definition.opcode() == spv::OpTypeInt);
2736*03ce13f7SAndroid Build Coastguard Worker
2737*03ce13f7SAndroid Build Coastguard Worker auto &structPtrTy = shader.getObjectType(structPtrId);
2738*03ce13f7SAndroid Build Coastguard Worker auto &structTy = shader.getType(structPtrTy.element);
2739*03ce13f7SAndroid Build Coastguard Worker auto arrayId = Type::ID(structTy.definition.word(2 + arrayFieldIdx));
2740*03ce13f7SAndroid Build Coastguard Worker
2741*03ce13f7SAndroid Build Coastguard Worker auto &result = createIntermediate(insn.resultId(), 1);
2742*03ce13f7SAndroid Build Coastguard Worker auto structBase = GetPointerToData(structPtrId, 0, false);
2743*03ce13f7SAndroid Build Coastguard Worker
2744*03ce13f7SAndroid Build Coastguard Worker Decorations structDecorations = {};
2745*03ce13f7SAndroid Build Coastguard Worker shader.ApplyDecorationsForIdMember(&structDecorations, structPtrTy.element, arrayFieldIdx);
2746*03ce13f7SAndroid Build Coastguard Worker ASSERT(structDecorations.HasOffset);
2747*03ce13f7SAndroid Build Coastguard Worker
2748*03ce13f7SAndroid Build Coastguard Worker auto arrayBase = structBase + structDecorations.Offset;
2749*03ce13f7SAndroid Build Coastguard Worker auto arraySizeInBytes = SIMD::Int(arrayBase.limit()) - arrayBase.offsets();
2750*03ce13f7SAndroid Build Coastguard Worker
2751*03ce13f7SAndroid Build Coastguard Worker Decorations arrayDecorations = shader.GetDecorationsForId(arrayId);
2752*03ce13f7SAndroid Build Coastguard Worker ASSERT(arrayDecorations.HasArrayStride);
2753*03ce13f7SAndroid Build Coastguard Worker auto arrayLength = arraySizeInBytes / SIMD::Int(arrayDecorations.ArrayStride);
2754*03ce13f7SAndroid Build Coastguard Worker
2755*03ce13f7SAndroid Build Coastguard Worker result.move(0, SIMD::Int(arrayLength));
2756*03ce13f7SAndroid Build Coastguard Worker }
2757*03ce13f7SAndroid Build Coastguard Worker
EmitExtendedInstruction(InsnIterator insn)2758*03ce13f7SAndroid Build Coastguard Worker void SpirvEmitter::EmitExtendedInstruction(InsnIterator insn)
2759*03ce13f7SAndroid Build Coastguard Worker {
2760*03ce13f7SAndroid Build Coastguard Worker auto ext = shader.getExtension(insn.word(3));
2761*03ce13f7SAndroid Build Coastguard Worker switch(ext.name)
2762*03ce13f7SAndroid Build Coastguard Worker {
2763*03ce13f7SAndroid Build Coastguard Worker case Spirv::Extension::GLSLstd450:
2764*03ce13f7SAndroid Build Coastguard Worker return EmitExtGLSLstd450(insn);
2765*03ce13f7SAndroid Build Coastguard Worker case Spirv::Extension::NonSemanticInfo:
2766*03ce13f7SAndroid Build Coastguard Worker // An extended set name which is prefixed with "NonSemantic." is
2767*03ce13f7SAndroid Build Coastguard Worker // guaranteed to contain only non-semantic instructions and all
2768*03ce13f7SAndroid Build Coastguard Worker // OpExtInst instructions referencing this set can be ignored.
2769*03ce13f7SAndroid Build Coastguard Worker break;
2770*03ce13f7SAndroid Build Coastguard Worker default:
2771*03ce13f7SAndroid Build Coastguard Worker UNREACHABLE("Unknown Extension::Name<%d>", int(ext.name));
2772*03ce13f7SAndroid Build Coastguard Worker }
2773*03ce13f7SAndroid Build Coastguard Worker }
2774*03ce13f7SAndroid Build Coastguard Worker
GetConstScalarInt(Object::ID id) const2775*03ce13f7SAndroid Build Coastguard Worker uint32_t Spirv::GetConstScalarInt(Object::ID id) const
2776*03ce13f7SAndroid Build Coastguard Worker {
2777*03ce13f7SAndroid Build Coastguard Worker auto &scopeObj = getObject(id);
2778*03ce13f7SAndroid Build Coastguard Worker ASSERT(scopeObj.kind == Object::Kind::Constant);
2779*03ce13f7SAndroid Build Coastguard Worker ASSERT(getType(scopeObj).componentCount == 1);
2780*03ce13f7SAndroid Build Coastguard Worker
2781*03ce13f7SAndroid Build Coastguard Worker return scopeObj.constantValue[0];
2782*03ce13f7SAndroid Build Coastguard Worker }
2783*03ce13f7SAndroid Build Coastguard Worker
emitEpilog(SpirvRoutine * routine) const2784*03ce13f7SAndroid Build Coastguard Worker void SpirvShader::emitEpilog(SpirvRoutine *routine) const
2785*03ce13f7SAndroid Build Coastguard Worker {
2786*03ce13f7SAndroid Build Coastguard Worker for(auto insn : *this)
2787*03ce13f7SAndroid Build Coastguard Worker {
2788*03ce13f7SAndroid Build Coastguard Worker if(insn.opcode() == spv::OpVariable)
2789*03ce13f7SAndroid Build Coastguard Worker {
2790*03ce13f7SAndroid Build Coastguard Worker auto &object = getObject(insn.resultId());
2791*03ce13f7SAndroid Build Coastguard Worker auto &objectTy = getType(object);
2792*03ce13f7SAndroid Build Coastguard Worker
2793*03ce13f7SAndroid Build Coastguard Worker if(object.kind == Object::Kind::InterfaceVariable && objectTy.storageClass == spv::StorageClassOutput)
2794*03ce13f7SAndroid Build Coastguard Worker {
2795*03ce13f7SAndroid Build Coastguard Worker auto &dst = routine->getVariable(insn.resultId());
2796*03ce13f7SAndroid Build Coastguard Worker int offset = 0;
2797*03ce13f7SAndroid Build Coastguard Worker
2798*03ce13f7SAndroid Build Coastguard Worker VisitInterface(insn.resultId(),
2799*03ce13f7SAndroid Build Coastguard Worker [&](const Decorations &d, AttribType type) {
2800*03ce13f7SAndroid Build Coastguard Worker auto scalarSlot = d.Location << 2 | d.Component;
2801*03ce13f7SAndroid Build Coastguard Worker routine->outputs[scalarSlot] = dst[offset++];
2802*03ce13f7SAndroid Build Coastguard Worker });
2803*03ce13f7SAndroid Build Coastguard Worker }
2804*03ce13f7SAndroid Build Coastguard Worker }
2805*03ce13f7SAndroid Build Coastguard Worker }
2806*03ce13f7SAndroid Build Coastguard Worker }
2807*03ce13f7SAndroid Build Coastguard Worker
executionModelToStage(spv::ExecutionModel model)2808*03ce13f7SAndroid Build Coastguard Worker VkShaderStageFlagBits Spirv::executionModelToStage(spv::ExecutionModel model)
2809*03ce13f7SAndroid Build Coastguard Worker {
2810*03ce13f7SAndroid Build Coastguard Worker switch(model)
2811*03ce13f7SAndroid Build Coastguard Worker {
2812*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModelVertex: return VK_SHADER_STAGE_VERTEX_BIT;
2813*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelTessellationControl: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
2814*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelTessellationEvaluation: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
2815*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelGeometry: return VK_SHADER_STAGE_GEOMETRY_BIT;
2816*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModelFragment: return VK_SHADER_STAGE_FRAGMENT_BIT;
2817*03ce13f7SAndroid Build Coastguard Worker case spv::ExecutionModelGLCompute: return VK_SHADER_STAGE_COMPUTE_BIT;
2818*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelKernel: return VkShaderStageFlagBits(0); // Not supported by vulkan.
2819*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelTaskNV: return VK_SHADER_STAGE_TASK_BIT_NV;
2820*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelMeshNV: return VK_SHADER_STAGE_MESH_BIT_NV;
2821*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelRayGenerationNV: return VK_SHADER_STAGE_RAYGEN_BIT_NV;
2822*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelIntersectionNV: return VK_SHADER_STAGE_INTERSECTION_BIT_NV;
2823*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelAnyHitNV: return VK_SHADER_STAGE_ANY_HIT_BIT_NV;
2824*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelClosestHitNV: return VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV;
2825*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelMissNV: return VK_SHADER_STAGE_MISS_BIT_NV;
2826*03ce13f7SAndroid Build Coastguard Worker // case spv::ExecutionModelCallableNV: return VK_SHADER_STAGE_CALLABLE_BIT_NV;
2827*03ce13f7SAndroid Build Coastguard Worker default:
2828*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("ExecutionModel: %d", int(model));
2829*03ce13f7SAndroid Build Coastguard Worker return VkShaderStageFlagBits(0);
2830*03ce13f7SAndroid Build Coastguard Worker }
2831*03ce13f7SAndroid Build Coastguard Worker }
2832*03ce13f7SAndroid Build Coastguard Worker
Operand(const Spirv & shader,const SpirvEmitter & state,Object::ID objectId)2833*03ce13f7SAndroid Build Coastguard Worker SpirvEmitter::Operand::Operand(const Spirv &shader, const SpirvEmitter &state, Object::ID objectId)
2834*03ce13f7SAndroid Build Coastguard Worker : Operand(state, shader.getObject(objectId))
2835*03ce13f7SAndroid Build Coastguard Worker {}
2836*03ce13f7SAndroid Build Coastguard Worker
Operand(const SpirvEmitter & state,const Object & object)2837*03ce13f7SAndroid Build Coastguard Worker SpirvEmitter::Operand::Operand(const SpirvEmitter &state, const Object &object)
2838*03ce13f7SAndroid Build Coastguard Worker : constant(object.kind == Object::Kind::Constant ? object.constantValue.data() : nullptr)
2839*03ce13f7SAndroid Build Coastguard Worker , intermediate(object.kind == Object::Kind::Intermediate ? &state.getIntermediate(object.id()) : nullptr)
2840*03ce13f7SAndroid Build Coastguard Worker , pointer(object.kind == Object::Kind::Pointer ? &state.getPointer(object.id()) : nullptr)
2841*03ce13f7SAndroid Build Coastguard Worker , sampledImage(object.kind == Object::Kind::SampledImage ? &state.getSampledImage(object.id()) : nullptr)
2842*03ce13f7SAndroid Build Coastguard Worker , componentCount(intermediate ? intermediate->componentCount : object.constantValue.size())
2843*03ce13f7SAndroid Build Coastguard Worker {
2844*03ce13f7SAndroid Build Coastguard Worker ASSERT(intermediate || constant || pointer || sampledImage);
2845*03ce13f7SAndroid Build Coastguard Worker }
2846*03ce13f7SAndroid Build Coastguard Worker
Operand(const Intermediate & value)2847*03ce13f7SAndroid Build Coastguard Worker SpirvEmitter::Operand::Operand(const Intermediate &value)
2848*03ce13f7SAndroid Build Coastguard Worker : intermediate(&value)
2849*03ce13f7SAndroid Build Coastguard Worker , componentCount(value.componentCount)
2850*03ce13f7SAndroid Build Coastguard Worker {
2851*03ce13f7SAndroid Build Coastguard Worker }
2852*03ce13f7SAndroid Build Coastguard Worker
isConstantZero() const2853*03ce13f7SAndroid Build Coastguard Worker bool Spirv::Object::isConstantZero() const
2854*03ce13f7SAndroid Build Coastguard Worker {
2855*03ce13f7SAndroid Build Coastguard Worker if(kind != Kind::Constant)
2856*03ce13f7SAndroid Build Coastguard Worker {
2857*03ce13f7SAndroid Build Coastguard Worker return false;
2858*03ce13f7SAndroid Build Coastguard Worker }
2859*03ce13f7SAndroid Build Coastguard Worker
2860*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < constantValue.size(); i++)
2861*03ce13f7SAndroid Build Coastguard Worker {
2862*03ce13f7SAndroid Build Coastguard Worker if(constantValue[i] != 0)
2863*03ce13f7SAndroid Build Coastguard Worker {
2864*03ce13f7SAndroid Build Coastguard Worker return false;
2865*03ce13f7SAndroid Build Coastguard Worker }
2866*03ce13f7SAndroid Build Coastguard Worker }
2867*03ce13f7SAndroid Build Coastguard Worker
2868*03ce13f7SAndroid Build Coastguard Worker return true;
2869*03ce13f7SAndroid Build Coastguard Worker }
2870*03ce13f7SAndroid Build Coastguard Worker
SpirvRoutine(const vk::PipelineLayout * pipelineLayout)2871*03ce13f7SAndroid Build Coastguard Worker SpirvRoutine::SpirvRoutine(const vk::PipelineLayout *pipelineLayout)
2872*03ce13f7SAndroid Build Coastguard Worker : pipelineLayout(pipelineLayout)
2873*03ce13f7SAndroid Build Coastguard Worker {
2874*03ce13f7SAndroid Build Coastguard Worker }
2875*03ce13f7SAndroid Build Coastguard Worker
setImmutableInputBuiltins(const SpirvShader * shader)2876*03ce13f7SAndroid Build Coastguard Worker void SpirvRoutine::setImmutableInputBuiltins(const SpirvShader *shader)
2877*03ce13f7SAndroid Build Coastguard Worker {
2878*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInSubgroupLocalInvocationId, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2879*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 1);
2880*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 1, 2, 3));
2881*03ce13f7SAndroid Build Coastguard Worker });
2882*03ce13f7SAndroid Build Coastguard Worker
2883*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInSubgroupEqMask, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2884*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 4);
2885*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(1, 2, 4, 8));
2886*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2887*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 2] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2888*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2889*03ce13f7SAndroid Build Coastguard Worker });
2890*03ce13f7SAndroid Build Coastguard Worker
2891*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInSubgroupGeMask, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2892*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 4);
2893*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(15, 14, 12, 8));
2894*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2895*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 2] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2896*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2897*03ce13f7SAndroid Build Coastguard Worker });
2898*03ce13f7SAndroid Build Coastguard Worker
2899*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInSubgroupGtMask, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2900*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 4);
2901*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(14, 12, 8, 0));
2902*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2903*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 2] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2904*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2905*03ce13f7SAndroid Build Coastguard Worker });
2906*03ce13f7SAndroid Build Coastguard Worker
2907*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInSubgroupLeMask, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2908*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 4);
2909*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(1, 3, 7, 15));
2910*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2911*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 2] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2912*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2913*03ce13f7SAndroid Build Coastguard Worker });
2914*03ce13f7SAndroid Build Coastguard Worker
2915*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInSubgroupLtMask, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2916*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 4);
2917*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(0, 1, 3, 7));
2918*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2919*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 2] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2920*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2921*03ce13f7SAndroid Build Coastguard Worker });
2922*03ce13f7SAndroid Build Coastguard Worker
2923*03ce13f7SAndroid Build Coastguard Worker setInputBuiltin(shader, spv::BuiltInDeviceIndex, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
2924*03ce13f7SAndroid Build Coastguard Worker ASSERT(builtin.SizeInComponents == 1);
2925*03ce13f7SAndroid Build Coastguard Worker // Only a single physical device is supported.
2926*03ce13f7SAndroid Build Coastguard Worker value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
2927*03ce13f7SAndroid Build Coastguard Worker });
2928*03ce13f7SAndroid Build Coastguard Worker }
2929*03ce13f7SAndroid Build Coastguard Worker
2930*03ce13f7SAndroid Build Coastguard Worker } // namespace sw
2931