builder_test.cpp revision aec1da576b4e9faed7df6c0ad8c7f92254a77144
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 25namespace android { 26namespace spirit { 27 28TEST(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 83 auto InvocationID = m->getInvocationId(); 84 85 auto ConstOne = m->getConstant(UIntTy, 1); 86#if 0 87 auto V3UIntPtrTy = m->getPointerType(StorageClass::Input, V3UIntTy); 88 auto GSize = b.MakeVariable(V3UIntPtrTy, StorageClass::Input); 89 GSize->decorate(Decoration::BuiltIn)->addExtraOperand(BuiltIn::WorkgroupSize); 90 m->addVariable(GSize); 91#endif 92 93 auto GNum = m->getNumWorkgroups(); 94 95 const char *funcName = "invert"; 96 97 auto Func = b.MakeFunctionDefinition(VoidTy, FunctionControl::None, FuncTy); 98 // TODO: Add method setName() to class FunctionDefinition 99 // Func->setName(funcName); // I.e., OpName %func funcName 100 m->addFunctionDefinition(Func); 101 102 auto Blk = b.MakeBlock(); 103 Func->addBlock(Blk); 104 105 Blk->addInstruction(b.MakeLabel()); 106 107 auto ConstZero = m->getConstant(UIntTy, 0); 108 auto UIntPtrTy = m->getPointerType(StorageClass::Input, UIntTy); 109 110 auto IID = b.MakeLoad(V3UIntTy, InvocationID); 111 Blk->addInstruction(IID); 112 113 auto XValue = b.MakeCompositeExtract(UIntTy, IID, {0}); 114 Blk->addInstruction(XValue); 115 116 auto YValue = b.MakeCompositeExtract(UIntTy, IID, {1}); 117 Blk->addInstruction(YValue); 118 119#if 0 120 auto PtrToGSizeX = b.MakeAccessChain(UIntPtrTy, GSize, {ConstZero}); 121 Blk->addInstruction(PtrToGSizeX); 122 123 auto GSizeX = b.MakeLoad(UIntTy, PtrToGSizeX); 124 Blk->addInstruction(GSizeX); 125#else 126 auto &GSizeX = ConstOne; 127#endif 128 129 auto Tmp1 = b.MakeIMul(UIntTy, YValue, GSizeX); 130 Blk->addInstruction(Tmp1); 131 132 auto PtrToGNumX = b.MakeAccessChain(UIntPtrTy, GNum, {ConstZero}); 133 Blk->addInstruction(PtrToGNumX); 134 135 auto GNumX = b.MakeLoad(UIntTy, PtrToGNumX); 136 Blk->addInstruction(GNumX); 137 138 auto OffsetY = b.MakeIMul(UIntTy, Tmp1, GNumX); 139 Blk->addInstruction(OffsetY); 140 141 auto Index = b.MakeIAdd(UIntTy, OffsetY, XValue); 142 Blk->addInstruction(Index); 143 144 auto VF4PtrTy = m->getPointerType(StorageClass::Function, VF4Ty); 145 auto Ptr = b.MakeAccessChain(VF4PtrTy, InputBuffer, {ConstZero, Index}); 146 Blk->addInstruction(Ptr); 147 148 auto Value = b.MakeLoad(VF4Ty, Ptr); 149 Blk->addInstruction(Value); 150 151 // Here is the place to do something about the value. As is, this is a copy 152 // kernel. 153 auto ConstOneF = m->getConstant(FloatTy, 1.0f); 154 auto ConstOneVF4 = m->getConstantComposite(VF4Ty, ConstOneF, ConstOneF, 155 ConstOneF, ConstOneF); 156 auto Result = b.MakeFSub(VF4Ty, ConstOneVF4, Value); 157 Blk->addInstruction(Result); 158 159 auto OutPtr = b.MakeAccessChain(VF4PtrTy, OutputBuffer, {ConstZero, Index}); 160 Blk->addInstruction(OutPtr); 161 162 Blk->addInstruction(b.MakeStore(OutPtr, Result)); 163 Blk->addInstruction(b.MakeReturn()); 164 165 m->addEntryPoint( 166 b.MakeEntryPointDefinition(ExecutionModel::GLCompute, Func, funcName) 167 ->addToInterface(InvocationID) 168 ->addToInterface(GNum) 169 // ->addToInterface(GSize) 170 ->setLocalSize(1, 1, 1)); 171 172 EXPECT_EQ(1, countEntity<MemoryModelInst>(m)); 173 EXPECT_EQ(1, countEntity<EntryPointInst>(m)); 174 EXPECT_EQ(3, countEntity<LoadInst>(m)); 175 EXPECT_EQ(1, countEntity<ReturnInst>(m)); 176 EXPECT_EQ(1, countEntity<ExecutionModeInst>(m)); 177 EXPECT_EQ(2, countEntity<TypeRuntimeArrayInst>(m)); 178 EXPECT_EQ(2, countEntity<TypeStructInst>(m)); 179 EXPECT_EQ(5, countEntity<TypePointerInst>(m)); 180 EXPECT_EQ(1, countEntity<StringInst>(m)); 181 182 m->consolidateAnnotations(); 183 184 auto words = Serialize<Module>(m); 185 186 auto m1 = Deserialize<Module>(words); 187 ASSERT_NE(nullptr, m1); 188 189 auto words1 = Serialize<Module>(m1); 190 191 EXPECT_TRUE(words == words1); 192} 193 194TEST(BuilderTest, testLoadAndModify) { 195 static const std::string testDataPath( 196 "frameworks/rs/rsov/compiler/spirit/test_data/"); 197 const std::string &fullPath = getAbsolutePath(testDataPath + "greyscale.spv"); 198 199 Module *m = Deserialize<Module>(readFile<uint32_t>(fullPath.c_str())); 200 201 ASSERT_NE(nullptr, m); 202 203 std::unique_ptr<Module> mDeleter(m); 204 205 Builder b; 206 207 auto IntTy = m->getIntType(32); 208 auto FuncTy = m->getFunctionType(IntTy, {IntTy}); 209 210 auto Func = b.MakeFunctionDefinition(IntTy, FunctionControl::None, FuncTy); 211 // TODO: Add method setName() to class FunctionDefinition 212 // Func->setName(funcName); // I.e., OpName %func funcName 213 m->addFunctionDefinition(Func); 214 215 auto Blk = b.MakeBlock(); 216 Func->addBlock(Blk); 217 218 Blk->addInstruction(b.MakeReturn()); 219 220 m->consolidateAnnotations(); 221 222 auto words = Serialize<Module>(m); 223 224 auto m1 = Deserialize<Module>(words); 225 ASSERT_NE(nullptr, m1); 226 227 auto words1 = Serialize<Module>(m1); 228 229 EXPECT_TRUE(words == words1); 230} 231 232} // namespace spirit 233} // namespace android 234