ShaderParser.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/ShaderCompiler/ShaderParser.h>
  6. namespace anki {
  7. #define ANKI_PP_ERROR_MALFORMED() \
  8. ANKI_SHADER_COMPILER_LOGE("%s: Malformed expression: %s", fname.cstr(), line.cstr()); \
  9. return Error::kUserData
  10. #define ANKI_PP_ERROR_MALFORMED_MSG(msg_) \
  11. ANKI_SHADER_COMPILER_LOGE("%s: " msg_ ": %s", fname.cstr(), line.cstr()); \
  12. return Error::kUserData
  13. inline constexpr Array<CString, U32(ShaderType::kCount)> kShaderStageNames = {{"VERTEX", "HULL", "DOMAIN", "GEOMETRY", "AMPLIFICATION", "MESH",
  14. "PIXEL", "COMPUTE", "RAY_GEN", "ANY_HIT", "CLOSEST_HIT", "MISS",
  15. "INTERSECTION", "CALLABLE", "WORK_GRAPH"}};
  16. static ShaderType strToShaderType(CString str)
  17. {
  18. ShaderType shaderType = ShaderType::kCount;
  19. if(str == "vert")
  20. {
  21. shaderType = ShaderType::kVertex;
  22. }
  23. else if(str == "hull")
  24. {
  25. shaderType = ShaderType::kHull;
  26. }
  27. else if(str == "domain")
  28. {
  29. }
  30. else if(str == "geom")
  31. {
  32. shaderType = ShaderType::kGeometry;
  33. }
  34. else if(str == "ampl")
  35. {
  36. shaderType = ShaderType::kAmplification;
  37. }
  38. else if(str == "mesh")
  39. {
  40. shaderType = ShaderType::kMesh;
  41. }
  42. else if(str == "pixel")
  43. {
  44. shaderType = ShaderType::kPixel;
  45. }
  46. else if(str == "comp")
  47. {
  48. shaderType = ShaderType::kCompute;
  49. }
  50. else if(str == "rgen")
  51. {
  52. shaderType = ShaderType::kRayGen;
  53. }
  54. else if(str == "ahit")
  55. {
  56. shaderType = ShaderType::kAnyHit;
  57. }
  58. else if(str == "chit")
  59. {
  60. shaderType = ShaderType::kClosestHit;
  61. }
  62. else if(str == "miss")
  63. {
  64. shaderType = ShaderType::kMiss;
  65. }
  66. else if(str == "int")
  67. {
  68. shaderType = ShaderType::kIntersection;
  69. }
  70. else if(str == "call")
  71. {
  72. shaderType = ShaderType::kCallable;
  73. }
  74. else
  75. {
  76. shaderType = ShaderType::kCount;
  77. }
  78. return shaderType;
  79. }
  80. ShaderParser::ShaderParser(CString fname, ShaderCompilerFilesystemInterface* fsystem, ConstWeakArray<ShaderCompilerDefine> defines)
  81. : m_fname(fname)
  82. , m_fsystem(fsystem)
  83. {
  84. for(const ShaderCompilerDefine& def : defines)
  85. {
  86. m_defineNames.emplaceBack(def.m_name);
  87. m_defineValues.emplaceBack(def.m_value);
  88. }
  89. }
  90. ShaderParser::~ShaderParser()
  91. {
  92. }
  93. void ShaderParser::tokenizeLine(CString line, ShaderCompilerDynamicArray<ShaderCompilerString>& tokens) const
  94. {
  95. ANKI_ASSERT(line.getLength() > 0);
  96. ShaderCompilerString l = line;
  97. // Replace all tabs with spaces
  98. for(char& c : l)
  99. {
  100. if(c == '\t')
  101. {
  102. c = ' ';
  103. }
  104. }
  105. // Split
  106. ShaderCompilerStringList spaceTokens;
  107. spaceTokens.splitString(l, ' ', false);
  108. // Create the array
  109. for(const ShaderCompilerString& s : spaceTokens)
  110. {
  111. tokens.emplaceBack(s);
  112. }
  113. }
  114. Error ShaderParser::parsePragmaTechnique(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  115. {
  116. ANKI_ASSERT(begin && end);
  117. const PtrSize tokenCount = end - begin;
  118. if(tokenCount == 0)
  119. {
  120. ANKI_PP_ERROR_MALFORMED();
  121. }
  122. // Technique name
  123. ShaderCompilerString techniqueName;
  124. if(strToShaderType(*begin) == ShaderType::kCount)
  125. {
  126. techniqueName = *begin;
  127. ++begin;
  128. }
  129. else
  130. {
  131. techniqueName = "Unnamed";
  132. }
  133. // Stages
  134. ShaderTypeBit stages = ShaderTypeBit::kNone;
  135. while(begin != end)
  136. {
  137. const ShaderType stage = strToShaderType(*begin);
  138. if(stage == ShaderType::kCount)
  139. {
  140. break;
  141. }
  142. const ShaderTypeBit stageBit = ShaderTypeBit(1 << stage);
  143. if(!!(stageBit & stages))
  144. {
  145. ANKI_PP_ERROR_MALFORMED_MSG("Stage appeared more than once");
  146. }
  147. stages |= stageBit;
  148. ++begin;
  149. }
  150. if(!stages)
  151. {
  152. ANKI_PP_ERROR_MALFORMED_MSG("Missing stages");
  153. }
  154. // Mutators
  155. U64 activeMutators = kMaxU64;
  156. if(begin != end && *begin == "mutators")
  157. {
  158. ++begin;
  159. activeMutators = 0;
  160. while(begin != end)
  161. {
  162. if(*begin == "*")
  163. {
  164. // Enable all mutators
  165. activeMutators = kMaxU64;
  166. }
  167. else
  168. {
  169. CString mutatorName = *begin;
  170. Bool exclude = false;
  171. if(mutatorName.find("!") == 0)
  172. {
  173. // Starts with !, exclude this mutator
  174. if(mutatorName.getLength() < 2)
  175. {
  176. ANKI_PP_ERROR_MALFORMED_MSG("Found a ! alone");
  177. }
  178. mutatorName = &mutatorName[1];
  179. exclude = true;
  180. }
  181. U32 count = 0;
  182. for(const Mutator& mutator : m_mutators)
  183. {
  184. if(mutator.m_name == mutatorName)
  185. {
  186. if(!exclude)
  187. {
  188. activeMutators |= 1_U64 << U64(count);
  189. }
  190. else
  191. {
  192. activeMutators &= ~(1_U64 << U64(count));
  193. }
  194. break;
  195. }
  196. ++count;
  197. }
  198. if(count == m_mutators.getSize())
  199. {
  200. ANKI_PP_ERROR_MALFORMED_MSG("Mutator not found");
  201. }
  202. }
  203. ++begin;
  204. }
  205. }
  206. if(begin != end)
  207. {
  208. ANKI_PP_ERROR_MALFORMED();
  209. }
  210. // Find the technique
  211. Technique* technique = nullptr;
  212. for(Technique& t : m_techniques)
  213. {
  214. if(t.m_name == techniqueName)
  215. {
  216. if(!!(t.m_shaderTypes & stages))
  217. {
  218. ANKI_PP_ERROR_MALFORMED_MSG("technique with the same name and type appeared more than once");
  219. }
  220. technique = &t;
  221. break;
  222. }
  223. }
  224. // Done
  225. if(!technique)
  226. {
  227. technique = m_techniques.emplaceBack();
  228. technique->m_name = techniqueName;
  229. }
  230. technique->m_shaderTypes |= stages;
  231. for(ShaderType s : EnumBitsIterable<ShaderType, ShaderTypeBit>(stages))
  232. {
  233. technique->m_activeMutators[s] = activeMutators;
  234. }
  235. return Error::kNone;
  236. }
  237. Error ShaderParser::parsePragmaMutator(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  238. {
  239. ANKI_ASSERT(begin && end);
  240. if(begin >= end)
  241. {
  242. ANKI_PP_ERROR_MALFORMED();
  243. }
  244. m_mutators.emplaceBack();
  245. Mutator& mutator = m_mutators.getBack();
  246. // Name
  247. {
  248. if(begin >= end)
  249. {
  250. // Need to have a name
  251. ANKI_PP_ERROR_MALFORMED();
  252. }
  253. // Check for duplicate mutators
  254. for(U32 i = 0; i < m_mutators.getSize() - 1; ++i)
  255. {
  256. if(m_mutators[i].m_name == *begin)
  257. {
  258. ANKI_PP_ERROR_MALFORMED_MSG("Duplicate mutator");
  259. }
  260. }
  261. if(begin->getLength() > kMaxShaderBinaryNameLength)
  262. {
  263. ANKI_PP_ERROR_MALFORMED_MSG("Too big name");
  264. }
  265. mutator.m_name = *begin;
  266. ++begin;
  267. }
  268. // Values
  269. {
  270. // Gather them
  271. for(; begin < end; ++begin)
  272. {
  273. MutatorValue value = 0;
  274. if(tokenIsComment(begin->toCString()))
  275. {
  276. break;
  277. }
  278. if(begin->toNumber(value))
  279. {
  280. ANKI_PP_ERROR_MALFORMED();
  281. }
  282. mutator.m_values.emplaceBack(value);
  283. }
  284. std::sort(mutator.m_values.getBegin(), mutator.m_values.getEnd());
  285. // Check for duplicates
  286. for(U32 i = 1; i < mutator.m_values.getSize(); ++i)
  287. {
  288. if(mutator.m_values[i - 1] == mutator.m_values[i])
  289. {
  290. ANKI_PP_ERROR_MALFORMED_MSG("Same value appeared more than once");
  291. }
  292. }
  293. }
  294. return Error::kNone;
  295. }
  296. Error ShaderParser::parsePragmaSkipMutation(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  297. {
  298. ANKI_ASSERT(begin && end);
  299. // Some basic sanity checks
  300. const U tokenCount = U(end - begin);
  301. // One pair doesn't make sence so it's: mutator_name_0 + mutator_value_0 + mutator_name_1 + mutator_value_1
  302. constexpr U minTokenCount = 2 + 2;
  303. if(tokenCount < minTokenCount || (tokenCount % 2) != 0)
  304. {
  305. ANKI_PP_ERROR_MALFORMED();
  306. }
  307. PartialMutationSkip& skip = *m_skipMutations.emplaceBack();
  308. skip.m_partialMutation.resize(m_mutators.getSize(), std::numeric_limits<MutatorValue>::max());
  309. do
  310. {
  311. // Get mutator name
  312. const CString mutatorName = *begin;
  313. U32 mutatorIndex = kMaxU32;
  314. for(U32 i = 0; i < m_mutators.getSize(); ++i)
  315. {
  316. if(m_mutators[i].m_name == mutatorName)
  317. {
  318. mutatorIndex = i;
  319. break;
  320. }
  321. }
  322. if(mutatorIndex == kMaxU32)
  323. {
  324. ANKI_PP_ERROR_MALFORMED_MSG("Mutator not found");
  325. }
  326. // Get mutator value
  327. ++begin;
  328. const CString valueStr = *begin;
  329. MutatorValue value;
  330. if(valueStr.toNumber(value))
  331. {
  332. ANKI_PP_ERROR_MALFORMED_MSG("Malformed mutator value");
  333. }
  334. if(!mutatorHasValue(m_mutators[mutatorIndex], value))
  335. {
  336. ANKI_PP_ERROR_MALFORMED_MSG("Mutator value incorrect");
  337. }
  338. skip.m_partialMutation[mutatorIndex] = value;
  339. ++begin;
  340. } while(begin < end && !tokenIsComment(*begin));
  341. return Error::kNone;
  342. }
  343. Error ShaderParser::parseInclude(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname, U32 depth)
  344. {
  345. // Gather the path
  346. ShaderCompilerString path;
  347. for(; begin < end; ++begin)
  348. {
  349. path += *begin;
  350. }
  351. if(path.isEmpty())
  352. {
  353. ANKI_PP_ERROR_MALFORMED();
  354. }
  355. // Check
  356. const char firstChar = path[0];
  357. const char lastChar = path[path.getLength() - 1];
  358. if((firstChar == '\"' && lastChar == '\"') || (firstChar == '<' && lastChar == '>'))
  359. {
  360. ShaderCompilerString fname2(path.begin() + 1, path.begin() + path.getLength() - 1);
  361. const Bool dontIgnore =
  362. fname2.find("AnKi/Shaders/") != ShaderCompilerString::kNpos || fname2.find("ThirdParty/") != ShaderCompilerString::kNpos;
  363. if(!dontIgnore)
  364. {
  365. // The shaders can't include C++ files. Ignore the include
  366. return Error::kNone;
  367. }
  368. if(parseFile(fname2, depth + 1))
  369. {
  370. ANKI_PP_ERROR_MALFORMED_MSG("Error parsing include. See previous errors");
  371. }
  372. }
  373. else
  374. {
  375. ANKI_PP_ERROR_MALFORMED();
  376. }
  377. return Error::kNone;
  378. }
  379. Error ShaderParser::parseLine(CString line, CString fname, Bool& foundPragmaOnce, U32 depth, U32 lineNo)
  380. {
  381. // Tokenize
  382. ShaderCompilerDynamicArray<ShaderCompilerString> tokens;
  383. tokenizeLine(line, tokens);
  384. ANKI_ASSERT(tokens.getSize() > 0);
  385. const ShaderCompilerString* token = tokens.getBegin();
  386. const ShaderCompilerString* end = tokens.getEnd();
  387. // Skip the hash
  388. Bool foundAloneHash = false;
  389. if(*token == "#")
  390. {
  391. ++token;
  392. foundAloneHash = true;
  393. }
  394. if((token < end) && ((foundAloneHash && *token == "include") || *token == "#include"))
  395. {
  396. // We _must_ have an #include
  397. ANKI_CHECK(parseInclude(token + 1, end, line, fname, depth));
  398. m_sourceLines.pushBackSprintf("#line %u \"%s\"", lineNo + 1, sanitizeFilename(fname).cstr());
  399. }
  400. else if((token < end) && ((foundAloneHash && *token == "pragma") || *token == "#pragma"))
  401. {
  402. // We may have a #pragma once or a #pragma anki or something else
  403. ++token;
  404. if(*token == "once")
  405. {
  406. // Pragma once
  407. if(foundPragmaOnce)
  408. {
  409. ANKI_PP_ERROR_MALFORMED_MSG("Can't have more than one #pragma once per file");
  410. }
  411. if(token + 1 != end)
  412. {
  413. ANKI_PP_ERROR_MALFORMED();
  414. }
  415. // Add the guard unique for this file
  416. foundPragmaOnce = true;
  417. const U64 hash = fname.computeHash();
  418. m_sourceLines.pushBackSprintf("#ifndef _ANKI_INCL_GUARD_%" PRIu64 "\n"
  419. "#define _ANKI_INCL_GUARD_%" PRIu64,
  420. hash, hash);
  421. m_sourceLines.pushBackSprintf("#line %u \"%s\"", lineNo + 1, sanitizeFilename(fname).cstr());
  422. }
  423. else if(*token == "anki")
  424. {
  425. // Must be a #pragma anki
  426. ++token;
  427. if(*token == "mutator")
  428. {
  429. ANKI_CHECK(checkNoActiveStruct());
  430. ANKI_CHECK(parsePragmaMutator(token + 1, end, line, fname));
  431. }
  432. else if(*token == "technique")
  433. {
  434. ANKI_CHECK(checkNoActiveStruct());
  435. ANKI_CHECK(parsePragmaTechnique(token + 1, end, line, fname));
  436. }
  437. else if(*token == "skip_mutation")
  438. {
  439. ANKI_CHECK(checkNoActiveStruct());
  440. ANKI_CHECK(parsePragmaSkipMutation(token + 1, end, line, fname));
  441. }
  442. else if(*token == "struct")
  443. {
  444. ANKI_CHECK(checkNoActiveStruct());
  445. ANKI_CHECK(parsePragmaStructBegin(token + 1, end, line, fname));
  446. }
  447. else if(*token == "struct_end")
  448. {
  449. ANKI_CHECK(checkActiveStruct());
  450. ANKI_CHECK(parsePragmaStructEnd(token + 1, end, line, fname));
  451. }
  452. else if(*token == "member")
  453. {
  454. ANKI_CHECK(checkActiveStruct());
  455. ANKI_CHECK(parsePragmaMember(token + 1, end, line, fname));
  456. }
  457. else if(*token == "16bit")
  458. {
  459. ANKI_CHECK(parsePragma16bit(token + 1, end, line, fname));
  460. }
  461. else if(*token == "extra_compiler_args")
  462. {
  463. ANKI_CHECK(parseExtraCompilerArgs(token + 1, end, line, fname));
  464. }
  465. else
  466. {
  467. ANKI_PP_ERROR_MALFORMED();
  468. }
  469. // For good measure
  470. m_sourceLines.pushBackSprintf("#line %u \"%s\"", lineNo + 1, sanitizeFilename(fname).cstr());
  471. }
  472. else
  473. {
  474. // Some other pragma, ignore
  475. m_sourceLines.pushBack(line);
  476. }
  477. }
  478. else
  479. {
  480. // Ignore
  481. m_sourceLines.pushBack(line);
  482. }
  483. return Error::kNone;
  484. }
  485. Error ShaderParser::parsePragmaStructBegin(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  486. {
  487. const U tokenCount = U(end - begin);
  488. if(tokenCount != 1)
  489. {
  490. ANKI_PP_ERROR_MALFORMED();
  491. }
  492. GhostStruct& gstruct = *m_ghostStructs.emplaceBack();
  493. gstruct.m_name = *begin;
  494. m_sourceLines.pushBackSprintf("struct %s {", begin->cstr());
  495. ANKI_ASSERT(!m_insideStruct);
  496. m_insideStruct = true;
  497. return Error::kNone;
  498. }
  499. Error ShaderParser::parsePragmaMember(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  500. {
  501. ANKI_ASSERT(m_insideStruct);
  502. const U tokenCount = U(end - begin);
  503. if(tokenCount < 2)
  504. {
  505. ANKI_PP_ERROR_MALFORMED();
  506. }
  507. GhostStruct& structure = m_ghostStructs.getBack();
  508. Member member;
  509. // Type
  510. const CString typeStr = *begin;
  511. member.m_type = ShaderVariableDataType::kNone;
  512. if(typeStr == "F32" || typeStr == "RF32")
  513. {
  514. member.m_type = ShaderVariableDataType::kF32;
  515. }
  516. else if(typeStr == "Vec2" || typeStr == "RVec2")
  517. {
  518. member.m_type = ShaderVariableDataType::kVec2;
  519. }
  520. else if(typeStr == "Vec3" || typeStr == "RVec3")
  521. {
  522. member.m_type = ShaderVariableDataType::kVec3;
  523. }
  524. else if(typeStr == "Vec4" || typeStr == "RVec4")
  525. {
  526. member.m_type = ShaderVariableDataType::kVec4;
  527. }
  528. else if(typeStr == "U32")
  529. {
  530. member.m_type = ShaderVariableDataType::kU32;
  531. }
  532. if(member.m_type == ShaderVariableDataType::kNone)
  533. {
  534. ANKI_PP_ERROR_MALFORMED_MSG("Unrecognized type");
  535. }
  536. // Name
  537. ++begin;
  538. member.m_name = *begin;
  539. // Default values
  540. ++begin;
  541. if(begin != end)
  542. {
  543. const ShaderVariableDataTypeInfo& typeInfo = getShaderVariableDataTypeInfo(member.m_type);
  544. if(U32(end - begin) != typeInfo.m_size / sizeof(U32))
  545. {
  546. ANKI_PP_ERROR_MALFORMED_MSG("Incorrect number of initial values");
  547. }
  548. U32 offset = 0;
  549. while(begin != end)
  550. {
  551. F32 f;
  552. U32 u;
  553. if(typeInfo.m_isIntegral)
  554. {
  555. if(begin->toNumber(u))
  556. {
  557. ANKI_PP_ERROR_MALFORMED_MSG("Type conversion failed");
  558. }
  559. memcpy(member.m_defaultValues.getBegin() + offset, &u, sizeof(u));
  560. offset += sizeof(u);
  561. }
  562. else
  563. {
  564. if(begin->toNumber(f))
  565. {
  566. ANKI_PP_ERROR_MALFORMED_MSG("Type conversion failed");
  567. }
  568. memcpy(member.m_defaultValues.getBegin() + offset, &f, sizeof(f));
  569. offset += sizeof(f);
  570. }
  571. ++begin;
  572. }
  573. ANKI_ASSERT(offset == typeInfo.m_size);
  574. }
  575. // Rest
  576. member.m_offset = (structure.m_members.getSize())
  577. ? structure.m_members.getBack().m_offset + getShaderVariableDataTypeInfo(structure.m_members.getBack().m_type).m_size
  578. : 0;
  579. m_sourceLines.pushBackSprintf("#define %s_%s_OFFSETOF %u", structure.m_name.cstr(), member.m_name.cstr(), member.m_offset);
  580. m_sourceLines.pushBackSprintf("\t%s %s;", typeStr.cstr(), member.m_name.cstr());
  581. structure.m_members.emplaceBack(std::move(member));
  582. return Error::kNone;
  583. }
  584. Error ShaderParser::parsePragmaStructEnd(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  585. {
  586. ANKI_ASSERT(m_insideStruct);
  587. if(begin != end)
  588. {
  589. ANKI_PP_ERROR_MALFORMED();
  590. }
  591. GhostStruct& gstruct = m_ghostStructs.getBack();
  592. const CString structName = gstruct.m_name;
  593. if(gstruct.m_members.isEmpty())
  594. {
  595. ANKI_PP_ERROR_MALFORMED_MSG("Struct doesn't have any members");
  596. }
  597. m_sourceLines.pushBack("};");
  598. for(U32 i = 0; i < gstruct.m_members.getSize(); ++i)
  599. {
  600. const Member& m = gstruct.m_members[i];
  601. // # define XXX_LOAD()
  602. m_sourceLines.pushBackSprintf("#\tdefine %s_%s_LOAD(buff, offset) buff.Load<%s>(%s_%s_OFFSETOF + (offset))%s", structName.cstr(),
  603. m.m_name.cstr(), getShaderVariableDataTypeInfo(m.m_type).m_name, structName.cstr(), m.m_name.cstr(),
  604. (i != gstruct.m_members.getSize() - 1) ? "," : "");
  605. }
  606. // Now define the structure LOAD in HLSL
  607. m_sourceLines.pushBackSprintf("#define load%s(buff, offset) { \\", structName.cstr());
  608. for(U32 i = 0; i < gstruct.m_members.getSize(); ++i)
  609. {
  610. const Member& m = gstruct.m_members[i];
  611. m_sourceLines.pushBackSprintf("\t%s_%s_LOAD(buff, offset) \\", structName.cstr(), m.m_name.cstr());
  612. }
  613. m_sourceLines.pushBack("}");
  614. // Done
  615. m_insideStruct = false;
  616. return Error::kNone;
  617. }
  618. Error ShaderParser::parsePragma16bit(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  619. {
  620. ANKI_ASSERT(begin && end);
  621. // Check tokens
  622. if(begin != end)
  623. {
  624. ANKI_PP_ERROR_MALFORMED();
  625. }
  626. m_16bitTypes = true;
  627. return Error::kNone;
  628. }
  629. Error ShaderParser::parseExtraCompilerArgs(const ShaderCompilerString* begin, const ShaderCompilerString* end, CString line, CString fname)
  630. {
  631. ANKI_ASSERT(begin && end);
  632. if(begin >= end)
  633. {
  634. ANKI_PP_ERROR_MALFORMED();
  635. }
  636. for(; begin < end; ++begin)
  637. {
  638. if(tokenIsComment(begin->toCString()))
  639. {
  640. break;
  641. }
  642. m_extraCompilerArgs.emplaceBack(*begin);
  643. }
  644. return Error::kNone;
  645. }
  646. Error ShaderParser::parseFile(CString fname, U32 depth)
  647. {
  648. // First check the depth
  649. if(depth > kMaxIncludeDepth)
  650. {
  651. ANKI_SHADER_COMPILER_LOGE("The include depth is too high. Probably circular includance");
  652. }
  653. Bool foundPragmaOnce = false;
  654. // Load file in lines
  655. ShaderCompilerString txt;
  656. ANKI_CHECK(m_fsystem->readAllText(fname, txt));
  657. m_hash = (m_hash) ? computeHash(txt.cstr(), txt.getLength()) : appendHash(txt.cstr(), txt.getLength(), m_hash);
  658. ShaderCompilerStringList lines;
  659. lines.splitString(txt, '\n', true);
  660. if(lines.getSize() < 1)
  661. {
  662. ANKI_SHADER_COMPILER_LOGE("Source is empty");
  663. }
  664. m_sourceLines.pushBackSprintf("#line 0 \"%s\"", sanitizeFilename(fname).cstr());
  665. // Parse lines
  666. U32 lineNo = 1;
  667. for(const ShaderCompilerString& line : lines)
  668. {
  669. if(line.isEmpty())
  670. {
  671. m_sourceLines.pushBack(" ");
  672. }
  673. else if(line.find("pragma") != ShaderCompilerString::kNpos || line.find("include") != ShaderCompilerString::kNpos)
  674. {
  675. // Possibly a preprocessor directive we care
  676. ANKI_CHECK(parseLine(line.toCString(), fname, foundPragmaOnce, depth, lineNo));
  677. }
  678. else
  679. {
  680. // Just append the line
  681. m_sourceLines.pushBack(line.toCString());
  682. }
  683. ++lineNo;
  684. }
  685. if(foundPragmaOnce)
  686. {
  687. // Append the guard
  688. m_sourceLines.pushBack("#endif // Include guard");
  689. }
  690. return Error::kNone;
  691. }
  692. Error ShaderParser::parse()
  693. {
  694. ANKI_ASSERT(!m_fname.isEmpty());
  695. ANKI_ASSERT(m_sourceLines.isEmpty());
  696. const CString fname = m_fname;
  697. // Parse recursively
  698. ANKI_CHECK(parseFile(fname, 0));
  699. // Checks
  700. {
  701. if(m_techniques.getSize() == 0)
  702. {
  703. ANKI_SHADER_COMPILER_LOGE("No techniques were found");
  704. return Error::kUserData;
  705. }
  706. if(m_insideStruct)
  707. {
  708. ANKI_SHADER_COMPILER_LOGE("Forgot to end a struct");
  709. return Error::kUserData;
  710. }
  711. }
  712. // Copy the extra compiler args to a better structure
  713. if(m_extraCompilerArgs.getSize() > 0)
  714. {
  715. m_extraCompilerArgsCString.resize(m_extraCompilerArgs.getSize());
  716. for(U32 i = 0; i < m_extraCompilerArgs.getSize(); ++i)
  717. {
  718. m_extraCompilerArgsCString[i] = m_extraCompilerArgs[i];
  719. }
  720. }
  721. m_sourceLines.join("\n", m_source);
  722. m_sourceLines.destroy(); // Free mem
  723. return Error::kNone;
  724. }
  725. void ShaderParser::generateAnkiShaderHeader(ShaderType shaderType, ShaderCompilerString& header)
  726. {
  727. header.destroy();
  728. for(ShaderType type : EnumIterable<ShaderType>())
  729. {
  730. header += ShaderCompilerString().sprintf("#define ANKI_%s_SHADER %u\n", kShaderStageNames[type].cstr(), (shaderType == type) ? 1 : 0);
  731. }
  732. }
  733. void ShaderParser::generateVariant(ConstWeakArray<MutatorValue> mutation, const ShaderParserTechnique& technique, ShaderType shaderType,
  734. ShaderCompilerString& source) const
  735. {
  736. // Sanity checks
  737. ANKI_ASSERT(mutation.getSize() == m_mutators.getSize());
  738. for(U32 i = 0; i < mutation.getSize(); ++i)
  739. {
  740. ANKI_ASSERT(mutatorHasValue(m_mutators[i], mutation[i]) && "Value not found");
  741. }
  742. ANKI_ASSERT(!!(technique.m_shaderTypes & ShaderTypeBit(1 << shaderType)));
  743. source.destroy();
  744. ANKI_ASSERT(&technique >= m_techniques.getBegin() && &technique < m_techniques.getEnd());
  745. const U32 tIdx = U32(&technique - m_techniques.getBegin());
  746. for(U32 i = 0; i < m_defineNames.getSize(); ++i)
  747. {
  748. source += ShaderCompilerString().sprintf("#define %s %d\n", m_defineNames[i].cstr(), m_defineValues[i]);
  749. }
  750. for(U32 i = 0; i < mutation.getSize(); ++i)
  751. {
  752. if(!!(technique.m_activeMutators[shaderType] & (1_U64 << U64(i))))
  753. {
  754. source += ShaderCompilerString().sprintf("#define %s %d\n", m_mutators[i].m_name.cstr(), mutation[i]);
  755. }
  756. }
  757. for(U32 i = 0; i < m_techniques.getSize(); ++i)
  758. {
  759. source += ShaderCompilerString().sprintf("#define ANKI_TECHNIQUE_%s %u\n", m_techniques[i].m_name.cstr(), U32(tIdx == i));
  760. }
  761. ShaderCompilerString header;
  762. generateAnkiShaderHeader(shaderType, header);
  763. source += header;
  764. if(m_16bitTypes)
  765. {
  766. source += "#define ANKI_SUPPORTS_16BIT_TYPES 1\n";
  767. }
  768. else
  769. {
  770. source += "#define ANKI_SUPPORTS_16BIT_TYPES 0\n";
  771. }
  772. source += m_source;
  773. }
  774. Bool ShaderParser::mutatorHasValue(const ShaderParserMutator& mutator, MutatorValue value)
  775. {
  776. for(MutatorValue v : mutator.m_values)
  777. {
  778. if(value == v)
  779. {
  780. return true;
  781. }
  782. }
  783. return false;
  784. }
  785. Bool ShaderParser::skipMutation(ConstWeakArray<MutatorValue> mutation) const
  786. {
  787. ANKI_ASSERT(mutation.getSize() == m_mutators.getSize());
  788. for(const PartialMutationSkip& skip : m_skipMutations)
  789. {
  790. Bool doSkip = true;
  791. for(U32 i = 0; i < m_mutators.getSize(); ++i)
  792. {
  793. if(skip.m_partialMutation[i] == std::numeric_limits<MutatorValue>::max())
  794. {
  795. // Don't care
  796. continue;
  797. }
  798. if(skip.m_partialMutation[i] != mutation[i])
  799. {
  800. doSkip = false;
  801. break;
  802. }
  803. }
  804. if(doSkip)
  805. {
  806. return true;
  807. }
  808. }
  809. return false;
  810. }
  811. } // end namespace anki