14df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni/*
24df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Copyright 2017, The Android Open Source Project
34df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *
44df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
54df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * you may not use this file except in compliance with the License.
64df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * You may obtain a copy of the License at
74df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *
84df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *     http://www.apache.org/licenses/LICENSE-2.0
94df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni *
104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Unless required by applicable law or agreed to in writing, software
114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * See the License for the specific language governing permissions and
144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * limitations under the License.
154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni */
164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "builder.h"
183f30b6202dd5ad6ff66959131d216405850ed152Yang Ni
194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "file_utils.h"
204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "instructions.h"
214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "module.h"
224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "test_utils.h"
234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "gtest/gtest.h"
244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ninamespace android {
264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ninamespace spirit {
274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST(BuilderTest, testBuildAndSerialize) {
294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Builder b;
304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Module *m = b.MakeModule();
324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ASSERT_NE(nullptr, m);
344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addCapability(Capability::Shader);
364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addCapability(Capability::Addresses);
374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->setMemoryModel(AddressingModel::Physical32, MemoryModel::GLSL450);
384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addExtInstImport("GLSL.std.450");
404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Shall we explicitly create the debug info section first?
424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addSource(SourceLanguage::GLSL, 450);
434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addSourceExtension("GL_ARB_separate_shader_objects");
444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addSourceExtension("GL_ARB_shading_language_420pack");
454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addSourceExtension("GL_GOOGLE_cpp_style_line_directive");
464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addSourceExtension("GL_GOOGLE_include_directive");
47877083d07a7fbce460f7f083bc1d5deef4d9ed47I-Jui (Ray) Sung  m->addString("Foo Bar Baz");
484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto FloatTy = m->getFloatType(32);
504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto VF4Ty = m->getVectorType(FloatTy, 4);
514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ArrTy = m->getRuntimeArrayType(VF4Ty);
524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ArrTy->decorate(Decoration::ArrayStride)->addExtraOperand(16);
534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto StructTy = m->getStructType(ArrTy);
544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  StructTy->decorate(Decoration::BufferBlock);
554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  StructTy->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto StructPtrTy = m->getPointerType(StorageClass::Uniform, StructTy);
584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto InputBuffer = b.MakeVariable(StructPtrTy, StorageClass::Uniform);
604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  InputBuffer->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  InputBuffer->decorate(Decoration::Binding)->addExtraOperand(2);
624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addVariable(InputBuffer);
634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ArrTy2 = m->getRuntimeArrayType(VF4Ty);
654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ArrTy2->decorate(Decoration::ArrayStride)->addExtraOperand(16);
664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto StructTy2 = m->getStructType(ArrTy2);
684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  StructTy2->decorate(Decoration::BufferBlock);
694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  StructTy2->memberDecorate(0, Decoration::Offset)->addExtraOperand(0);
704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto StructPtrTy2 = m->getPointerType(StorageClass::Uniform, StructTy2);
724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto OutputBuffer = b.MakeVariable(StructPtrTy2, StorageClass::Uniform);
734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  OutputBuffer->decorate(Decoration::DescriptorSet)->addExtraOperand(0);
744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  OutputBuffer->decorate(Decoration::Binding)->addExtraOperand(1);
754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addVariable(OutputBuffer);
764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto VoidTy = m->getVoidType();
784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto FuncTy = m->getFunctionType(VoidTy, nullptr, 0);
794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto UIntTy = m->getUnsignedIntType(32);
814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto V3UIntTy = m->getVectorType(UIntTy, 3);
824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto V3UIntPtrTy = m->getPointerType(StorageClass::Input, V3UIntTy);
834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto InvocationID = m->getInvocationId();
854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ConstFour = m->getConstant(UIntTy, 4);
874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ConstOne = m->getConstant(UIntTy, 1);
884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#if 0
894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto GSize = b.MakeVariable(V3UIntPtrTy, StorageClass::Input);
904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  GSize->decorate(Decoration::BuiltIn)->addExtraOperand(BuiltIn::WorkgroupSize);
914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addVariable(GSize);
924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#endif
934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto GNum = m->getNumWorkgroups();
954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  const char *funcName = "invert";
974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Func = b.MakeFunctionDefinition(VoidTy, FunctionControl::None, FuncTy);
994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TODO: Add method setName() to class FunctionDefinition
1004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Func->setName(funcName);  // I.e., OpName %func funcName
1014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addFunctionDefinition(Func);
1024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Blk = b.MakeBlock();
1044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Func->addBlock(Blk);
1054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(b.MakeLabel());
1074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto IntTy = m->getIntType(32);
1094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ConstZero = m->getConstant(UIntTy, 0);
1104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto UIntPtrTy = m->getPointerType(StorageClass::Input, UIntTy);
1114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto IID = b.MakeLoad(V3UIntTy, InvocationID);
1134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(IID);
1144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto XValue = b.MakeCompositeExtract(UIntTy, IID, {0});
1164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(XValue);
1174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto YValue = b.MakeCompositeExtract(UIntTy, IID, {1});
1194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(YValue);
1204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#if 0
1224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto PtrToGSizeX = b.MakeAccessChain(UIntPtrTy, GSize, {ConstZero});
1234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(PtrToGSizeX);
1244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto GSizeX = b.MakeLoad(UIntTy, PtrToGSizeX);
1264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(GSizeX);
1274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#else
1284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto &GSizeX = ConstOne;
1294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#endif
1304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Tmp1 = b.MakeIMul(UIntTy, YValue, GSizeX);
1324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(Tmp1);
1334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto PtrToGNumX = b.MakeAccessChain(UIntPtrTy, GNum, {ConstZero});
1354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(PtrToGNumX);
1364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto GNumX = b.MakeLoad(UIntTy, PtrToGNumX);
1384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(GNumX);
1394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto OffsetY = b.MakeIMul(UIntTy, Tmp1, GNumX);
1414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(OffsetY);
1424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Index = b.MakeIAdd(UIntTy, OffsetY, XValue);
1444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(Index);
1454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto VF4PtrTy = m->getPointerType(StorageClass::Function, VF4Ty);
1474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Ptr = b.MakeAccessChain(VF4PtrTy, InputBuffer, {ConstZero, Index});
1484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(Ptr);
1494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Value = b.MakeLoad(VF4Ty, Ptr);
1514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(Value);
1524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Here is the place to do something about the value. As is, this is a copy
1544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // kernel.
1554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ConstOneF = m->getConstant(FloatTy, 1.0f);
1564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto ConstOneVF4 = m->getConstantComposite(VF4Ty, ConstOneF, ConstOneF,
1574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni                                             ConstOneF, ConstOneF);
1584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Result = b.MakeFSub(VF4Ty, ConstOneVF4, Value);
1594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(Result);
1604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto OutPtr = b.MakeAccessChain(VF4PtrTy, OutputBuffer, {ConstZero, Index});
1624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(OutPtr);
1634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(b.MakeStore(OutPtr, Result));
1654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(b.MakeReturn());
1664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addEntryPoint(
1684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      b.MakeEntryPointDefinition(ExecutionModel::GLCompute, Func, funcName)
1694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni          ->addToInterface(InvocationID)
1704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni          ->addToInterface(GNum)
1714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni          //          ->addToInterface(GSize)
1724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni          ->setLocalSize(1, 1, 1));
1734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(1, countEntity<MemoryModelInst>(m));
1754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(1, countEntity<EntryPointInst>(m));
1764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(3, countEntity<LoadInst>(m));
1774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(1, countEntity<ReturnInst>(m));
1784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(1, countEntity<ExecutionModeInst>(m));
1794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(2, countEntity<TypeRuntimeArrayInst>(m));
1804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(2, countEntity<TypeStructInst>(m));
1814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_EQ(5, countEntity<TypePointerInst>(m));
182877083d07a7fbce460f7f083bc1d5deef4d9ed47I-Jui (Ray) Sung  EXPECT_EQ(1, countEntity<StringInst>(m));
1834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->consolidateAnnotations();
1854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1863e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  auto words = Serialize<Module>(m);
1874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1883e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  auto m1 = Deserialize<Module>(words);
1894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ASSERT_NE(nullptr, m1);
1904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1913e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  auto words1 = Serialize<Module>(m1);
1924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_TRUE(words == words1);
1944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni}
1954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
1964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST(BuilderTest, testLoadAndModify) {
1974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  static const std::string testDataPath(
1984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni      "frameworks/rs/rsov/compiler/spirit/test_data/");
1994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  const std::string &fullPath = getAbsolutePath(testDataPath + "greyscale.spv");
2004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2013e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  Module *m = Deserialize<Module>(readFile<uint32_t>(fullPath.c_str()));
2024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ASSERT_NE(nullptr, m);
2044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  std::unique_ptr<Module> mDeleter(m);
2064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Builder b;
2084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto IntTy = m->getIntType(32);
2104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto FuncTy = m->getFunctionType(IntTy, {IntTy});
2114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Func = b.MakeFunctionDefinition(IntTy, FunctionControl::None, FuncTy);
2134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // TODO: Add method setName() to class FunctionDefinition
2144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  // Func->setName(funcName);  // I.e., OpName %func funcName
2154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->addFunctionDefinition(Func);
2164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  auto Blk = b.MakeBlock();
2184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Func->addBlock(Blk);
2194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  Blk->addInstruction(b.MakeReturn());
2214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  m->consolidateAnnotations();
2234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2243e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  auto words = Serialize<Module>(m);
2254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2263e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  auto m1 = Deserialize<Module>(words);
2274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  ASSERT_NE(nullptr, m1);
2284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2293e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni  auto words1 = Serialize<Module>(m1);
2304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni  EXPECT_TRUE(words == words1);
2324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni}
2334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni
2344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} // namespace spirit
2354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} // namespace android
236