• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "builder.h"
18 
19 #include "file_utils.h"
20 #include "instructions.h"
21 #include "module.h"
22 #include "test_utils.h"
23 #include "gtest/gtest.h"
24 
25 namespace android {
26 namespace spirit {
27 
TEST(BuilderTest,testBuildAndSerialize)28 TEST(BuilderTest, testBuildAndSerialize) {
29   Builder b;
30 
31   Module *m = b.MakeModule();
32 
33   ASSERT_NE(nullptr, m);
34 
35   m->addCapability(Capability::Shader);
36   m->addCapability(Capability::Addresses);
37   m->setMemoryModel(AddressingModel::Physical32, MemoryModel::GLSL450);
38 
39   m->addExtInstImport("GLSL.std.450");
40 
41   // Shall we explicitly create the debug info section first?
42   m->addSource(SourceLanguage::GLSL, 450);
43   m->addSourceExtension("GL_ARB_separate_shader_objects");
44   m->addSourceExtension("GL_ARB_shading_language_420pack");
45   m->addSourceExtension("GL_GOOGLE_cpp_style_line_directive");
46   m->addSourceExtension("GL_GOOGLE_include_directive");
47   m->addString("Foo Bar Baz");
48 
49   auto FloatTy = m->getFloatType(32);
50   auto VF4Ty = m->getVectorType(FloatTy, 4);
51   auto ArrTy = m->getRuntimeArrayType(VF4Ty);
52   ArrTy->decorate(Decoration::ArrayStride)->addExtraOperand(16);
53   auto StructTy = m->getStructType(ArrTy);
54   StructTy->decorate(Decoration::BufferBlock);
55   StructTy->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
56 
57   auto StructPtrTy = m->getPointerType(StorageClass::Uniform, StructTy);
58 
59   auto InputBuffer = b.MakeVariable(StructPtrTy, StorageClass::Uniform);
60   InputBuffer->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
61   InputBuffer->decorate(Decoration::Binding)->addExtraOperand(2);
62   m->addVariable(InputBuffer);
63 
64   auto ArrTy2 = m->getRuntimeArrayType(VF4Ty);
65   ArrTy2->decorate(Decoration::ArrayStride)->addExtraOperand(16);
66 
67   auto StructTy2 = m->getStructType(ArrTy2);
68   StructTy2->decorate(Decoration::BufferBlock);
69   StructTy2->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
70 
71   auto StructPtrTy2 = m->getPointerType(StorageClass::Uniform, StructTy2);
72   auto OutputBuffer = b.MakeVariable(StructPtrTy2, StorageClass::Uniform);
73   OutputBuffer->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
74   OutputBuffer->decorate(Decoration::Binding)->addExtraOperand(1);
75   m->addVariable(OutputBuffer);
76 
77   auto VoidTy = m->getVoidType();
78   auto FuncTy = m->getFunctionType(VoidTy, nullptr, 0);
79 
80   auto UIntTy = m->getUnsignedIntType(32);
81   auto V3UIntTy = m->getVectorType(UIntTy, 3);
82   auto V3UIntPtrTy = m->getPointerType(StorageClass::Input, V3UIntTy);
83 
84   auto InvocationID = m->getInvocationId();
85 
86   auto ConstFour = m->getConstant(UIntTy, 4);
87   auto ConstOne = m->getConstant(UIntTy, 1);
88 #if 0
89   auto GSize = b.MakeVariable(V3UIntPtrTy, StorageClass::Input);
90   GSize->decorate(Decoration::BuiltIn)->addExtraOperand(BuiltIn::WorkgroupSize);
91   m->addVariable(GSize);
92 #endif
93 
94   auto GNum = m->getNumWorkgroups();
95 
96   const char *funcName = "invert";
97 
98   auto Func = b.MakeFunctionDefinition(VoidTy, FunctionControl::None, FuncTy);
99   // TODO: Add method setName() to class FunctionDefinition
100   // Func->setName(funcName);  // I.e., OpName %func funcName
101   m->addFunctionDefinition(Func);
102 
103   auto Blk = b.MakeBlock();
104   Func->addBlock(Blk);
105 
106   Blk->addInstruction(b.MakeLabel());
107 
108   auto IntTy = m->getIntType(32);
109   auto ConstZero = m->getConstant(UIntTy, 0);
110   auto UIntPtrTy = m->getPointerType(StorageClass::Input, UIntTy);
111 
112   auto IID = b.MakeLoad(V3UIntTy, InvocationID);
113   Blk->addInstruction(IID);
114 
115   auto XValue = b.MakeCompositeExtract(UIntTy, IID, {0});
116   Blk->addInstruction(XValue);
117 
118   auto YValue = b.MakeCompositeExtract(UIntTy, IID, {1});
119   Blk->addInstruction(YValue);
120 
121 #if 0
122   auto PtrToGSizeX = b.MakeAccessChain(UIntPtrTy, GSize, {ConstZero});
123   Blk->addInstruction(PtrToGSizeX);
124 
125   auto GSizeX = b.MakeLoad(UIntTy, PtrToGSizeX);
126   Blk->addInstruction(GSizeX);
127 #else
128   auto &GSizeX = ConstOne;
129 #endif
130 
131   auto Tmp1 = b.MakeIMul(UIntTy, YValue, GSizeX);
132   Blk->addInstruction(Tmp1);
133 
134   auto PtrToGNumX = b.MakeAccessChain(UIntPtrTy, GNum, {ConstZero});
135   Blk->addInstruction(PtrToGNumX);
136 
137   auto GNumX = b.MakeLoad(UIntTy, PtrToGNumX);
138   Blk->addInstruction(GNumX);
139 
140   auto OffsetY = b.MakeIMul(UIntTy, Tmp1, GNumX);
141   Blk->addInstruction(OffsetY);
142 
143   auto Index = b.MakeIAdd(UIntTy, OffsetY, XValue);
144   Blk->addInstruction(Index);
145 
146   auto VF4PtrTy = m->getPointerType(StorageClass::Function, VF4Ty);
147   auto Ptr = b.MakeAccessChain(VF4PtrTy, InputBuffer, {ConstZero, Index});
148   Blk->addInstruction(Ptr);
149 
150   auto Value = b.MakeLoad(VF4Ty, Ptr);
151   Blk->addInstruction(Value);
152 
153   // Here is the place to do something about the value. As is, this is a copy
154   // kernel.
155   auto ConstOneF = m->getConstant(FloatTy, 1.0f);
156   auto ConstOneVF4 = m->getConstantComposite(VF4Ty, ConstOneF, ConstOneF,
157                                              ConstOneF, ConstOneF);
158   auto Result = b.MakeFSub(VF4Ty, ConstOneVF4, Value);
159   Blk->addInstruction(Result);
160 
161   auto OutPtr = b.MakeAccessChain(VF4PtrTy, OutputBuffer, {ConstZero, Index});
162   Blk->addInstruction(OutPtr);
163 
164   Blk->addInstruction(b.MakeStore(OutPtr, Result));
165   Blk->addInstruction(b.MakeReturn());
166 
167   m->addEntryPoint(
168       b.MakeEntryPointDefinition(ExecutionModel::GLCompute, Func, funcName)
169           ->addToInterface(InvocationID)
170           ->addToInterface(GNum)
171           //          ->addToInterface(GSize)
172           ->setLocalSize(1, 1, 1));
173 
174   EXPECT_EQ(1, countEntity<MemoryModelInst>(m));
175   EXPECT_EQ(1, countEntity<EntryPointInst>(m));
176   EXPECT_EQ(3, countEntity<LoadInst>(m));
177   EXPECT_EQ(1, countEntity<ReturnInst>(m));
178   EXPECT_EQ(1, countEntity<ExecutionModeInst>(m));
179   EXPECT_EQ(2, countEntity<TypeRuntimeArrayInst>(m));
180   EXPECT_EQ(2, countEntity<TypeStructInst>(m));
181   EXPECT_EQ(5, countEntity<TypePointerInst>(m));
182   EXPECT_EQ(1, countEntity<StringInst>(m));
183 
184   m->consolidateAnnotations();
185 
186   auto words = Serialize<Module>(m);
187 
188   auto m1 = Deserialize<Module>(words);
189   ASSERT_NE(nullptr, m1);
190 
191   auto words1 = Serialize<Module>(m1);
192 
193   EXPECT_TRUE(words == words1);
194 }
195 
TEST(BuilderTest,testLoadAndModify)196 TEST(BuilderTest, testLoadAndModify) {
197   static const std::string testDataPath(
198       "frameworks/rs/rsov/compiler/spirit/test_data/");
199   const std::string &fullPath = getAbsolutePath(testDataPath + "greyscale.spv");
200 
201   Module *m = Deserialize<Module>(readFile<uint32_t>(fullPath.c_str()));
202 
203   ASSERT_NE(nullptr, m);
204 
205   std::unique_ptr<Module> mDeleter(m);
206 
207   Builder b;
208 
209   auto IntTy = m->getIntType(32);
210   auto FuncTy = m->getFunctionType(IntTy, {IntTy});
211 
212   auto Func = b.MakeFunctionDefinition(IntTy, FunctionControl::None, FuncTy);
213   // TODO: Add method setName() to class FunctionDefinition
214   // Func->setName(funcName);  // I.e., OpName %func funcName
215   m->addFunctionDefinition(Func);
216 
217   auto Blk = b.MakeBlock();
218   Func->addBlock(Blk);
219 
220   Blk->addInstruction(b.MakeReturn());
221 
222   m->consolidateAnnotations();
223 
224   auto words = Serialize<Module>(m);
225 
226   auto m1 = Deserialize<Module>(words);
227   ASSERT_NE(nullptr, m1);
228 
229   auto words1 = Serialize<Module>(m1);
230 
231   EXPECT_TRUE(words == words1);
232 }
233 
234 } // namespace spirit
235 } // namespace android
236