ShaderProgramParser.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. // Copyright (C) 2009-2023, 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/ShaderProgramParser.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", "TESSELLATION_CONTROL", "TESSELLATION_EVALUATION",
  14. "GEOMETRY", "TASK", "MESH", "FRAGMENT", "COMPUTE", "RAY_GEN",
  15. "ANY_HIT", "CLOSEST_HIT", "MISS", "INTERSECTION", "CALLABLE"}};
  16. inline constexpr char kShaderHeader[] = R"(#define ANKI_%s_SHADER 1
  17. #define ANKI_PLATFORM_MOBILE %d
  18. #define ANKI_FORCE_FULL_FP_PRECISION %d
  19. #define kMaxBindlessTextures %uu
  20. #define kMaxBindlessReadonlyTextureBuffers %uu
  21. )";
  22. static const U64 kShaderHeaderHash = computeHash(kShaderHeader, sizeof(kShaderHeader));
  23. ShaderProgramParser::ShaderProgramParser(CString fname, ShaderProgramFilesystemInterface* fsystem, const ShaderCompilerOptions& compilerOptions)
  24. : m_fname(fname)
  25. , m_fsystem(fsystem)
  26. , m_compilerOptions(compilerOptions)
  27. {
  28. }
  29. ShaderProgramParser::~ShaderProgramParser()
  30. {
  31. }
  32. void ShaderProgramParser::tokenizeLine(CString line, DynamicArray<String>& tokens) const
  33. {
  34. ANKI_ASSERT(line.getLength() > 0);
  35. String l = line;
  36. // Replace all tabs with spaces
  37. for(char& c : l)
  38. {
  39. if(c == '\t')
  40. {
  41. c = ' ';
  42. }
  43. }
  44. // Split
  45. StringList spaceTokens;
  46. spaceTokens.splitString(l, ' ', false);
  47. // Create the array
  48. for(const String& s : spaceTokens)
  49. {
  50. tokens.emplaceBack(s);
  51. }
  52. }
  53. Error ShaderProgramParser::parsePragmaStart(const String* begin, const String* end, CString line, CString fname)
  54. {
  55. ANKI_ASSERT(begin && end);
  56. if(begin >= end)
  57. {
  58. ANKI_PP_ERROR_MALFORMED();
  59. }
  60. ShaderType shaderType = ShaderType::kCount;
  61. if(*begin == "vert")
  62. {
  63. shaderType = ShaderType::kVertex;
  64. }
  65. else if(*begin == "tessc")
  66. {
  67. shaderType = ShaderType::kTessellationControl;
  68. }
  69. else if(*begin == "tesse")
  70. {
  71. }
  72. else if(*begin == "geom")
  73. {
  74. shaderType = ShaderType::kGeometry;
  75. }
  76. else if(*begin == "task")
  77. {
  78. shaderType = ShaderType::kTask;
  79. }
  80. else if(*begin == "mesh")
  81. {
  82. shaderType = ShaderType::kMesh;
  83. }
  84. else if(*begin == "frag")
  85. {
  86. shaderType = ShaderType::kFragment;
  87. }
  88. else if(*begin == "comp")
  89. {
  90. shaderType = ShaderType::kCompute;
  91. }
  92. else if(*begin == "rgen")
  93. {
  94. shaderType = ShaderType::kRayGen;
  95. }
  96. else if(*begin == "ahit")
  97. {
  98. shaderType = ShaderType::kAnyHit;
  99. }
  100. else if(*begin == "chit")
  101. {
  102. shaderType = ShaderType::kClosestHit;
  103. }
  104. else if(*begin == "miss")
  105. {
  106. shaderType = ShaderType::kMiss;
  107. }
  108. else if(*begin == "int")
  109. {
  110. shaderType = ShaderType::kIntersection;
  111. }
  112. else if(*begin == "call")
  113. {
  114. shaderType = ShaderType::kCallable;
  115. }
  116. else
  117. {
  118. ANKI_PP_ERROR_MALFORMED();
  119. }
  120. m_codeLines.pushBackSprintf("#ifdef ANKI_%s_SHADER", kShaderStageNames[shaderType].cstr());
  121. ++begin;
  122. if(begin != end)
  123. {
  124. // Should be the last token
  125. ANKI_PP_ERROR_MALFORMED();
  126. }
  127. // Set the mask
  128. const ShaderTypeBit mask = ShaderTypeBit(1 << shaderType);
  129. if(!!(mask & m_shaderTypes))
  130. {
  131. ANKI_PP_ERROR_MALFORMED_MSG("Can't have #pragma start <shader> appearing more than once");
  132. }
  133. m_shaderTypes |= mask;
  134. // Check bounds
  135. if(m_insideShader)
  136. {
  137. ANKI_PP_ERROR_MALFORMED_MSG("Can't have #pragma start before you close the previous pragma start");
  138. }
  139. m_insideShader = true;
  140. return Error::kNone;
  141. }
  142. Error ShaderProgramParser::parsePragmaEnd(const String* begin, const String* end, CString line, CString fname)
  143. {
  144. ANKI_ASSERT(begin && end);
  145. // Check tokens
  146. if(begin != end)
  147. {
  148. ANKI_PP_ERROR_MALFORMED();
  149. }
  150. // Check bounds
  151. if(!m_insideShader)
  152. {
  153. ANKI_PP_ERROR_MALFORMED_MSG("Can't have #pragma end before you open with a pragma start");
  154. }
  155. m_insideShader = false;
  156. // Write code
  157. m_codeLines.pushBack("#endif // Shader guard");
  158. return Error::kNone;
  159. }
  160. Error ShaderProgramParser::parsePragmaMutator(const String* begin, const String* end, CString line, CString fname)
  161. {
  162. ANKI_ASSERT(begin && end);
  163. if(begin >= end)
  164. {
  165. ANKI_PP_ERROR_MALFORMED();
  166. }
  167. m_mutators.emplaceBack();
  168. Mutator& mutator = m_mutators.getBack();
  169. // Name
  170. {
  171. if(begin >= end)
  172. {
  173. // Need to have a name
  174. ANKI_PP_ERROR_MALFORMED();
  175. }
  176. // Check for duplicate mutators
  177. for(U32 i = 0; i < m_mutators.getSize() - 1; ++i)
  178. {
  179. if(m_mutators[i].m_name == *begin)
  180. {
  181. ANKI_PP_ERROR_MALFORMED_MSG("Duplicate mutator");
  182. }
  183. }
  184. if(begin->getLength() > kMaxShaderBinaryNameLength)
  185. {
  186. ANKI_PP_ERROR_MALFORMED_MSG("Too big name");
  187. }
  188. mutator.m_name = *begin;
  189. ++begin;
  190. }
  191. // Values
  192. {
  193. // Gather them
  194. for(; begin < end; ++begin)
  195. {
  196. MutatorValue value = 0;
  197. if(tokenIsComment(begin->toCString()))
  198. {
  199. break;
  200. }
  201. if(begin->toNumber(value))
  202. {
  203. ANKI_PP_ERROR_MALFORMED();
  204. }
  205. mutator.m_values.emplaceBack(value);
  206. }
  207. std::sort(mutator.m_values.getBegin(), mutator.m_values.getEnd());
  208. // Check for duplicates
  209. for(U32 i = 1; i < mutator.m_values.getSize(); ++i)
  210. {
  211. if(mutator.m_values[i - 1] == mutator.m_values[i])
  212. {
  213. ANKI_PP_ERROR_MALFORMED_MSG("Same value appeared more than once");
  214. }
  215. }
  216. }
  217. return Error::kNone;
  218. }
  219. Error ShaderProgramParser::parsePragmaLibraryName(const String* begin, const String* end, CString line, CString fname)
  220. {
  221. ANKI_ASSERT(begin && end);
  222. if(begin >= end)
  223. {
  224. ANKI_PP_ERROR_MALFORMED();
  225. }
  226. if(m_libName.getLength() > 0)
  227. {
  228. ANKI_PP_ERROR_MALFORMED_MSG("Library name already set");
  229. }
  230. m_libName = *begin;
  231. return Error::kNone;
  232. }
  233. Error ShaderProgramParser::parsePragmaRayType(const String* begin, const String* end, CString line, CString fname)
  234. {
  235. ANKI_ASSERT(begin && end);
  236. if(begin >= end)
  237. {
  238. ANKI_PP_ERROR_MALFORMED();
  239. }
  240. if(m_rayType != kMaxU32)
  241. {
  242. ANKI_PP_ERROR_MALFORMED_MSG("Ray type already set");
  243. }
  244. ANKI_CHECK(begin->toNumber(m_rayType));
  245. if(m_rayType > 128)
  246. {
  247. ANKI_PP_ERROR_MALFORMED_MSG("Ray type has a very large value");
  248. }
  249. return Error::kNone;
  250. }
  251. Error ShaderProgramParser::parsePragmaReflect(const String* begin, const String* end, CString line, CString fname)
  252. {
  253. ANKI_ASSERT(begin && end);
  254. if(begin >= end)
  255. {
  256. ANKI_PP_ERROR_MALFORMED();
  257. }
  258. m_symbolsToReflect.pushBack(*begin);
  259. return Error::kNone;
  260. }
  261. Error ShaderProgramParser::parsePragmaSkipMutation(const String* begin, const String* end, CString line, CString fname)
  262. {
  263. ANKI_ASSERT(begin && end);
  264. // Some basic sanity checks
  265. const U tokenCount = U(end - begin);
  266. // One pair doesn't make sence so it's: mutator_name_0 + mutator_value_0 + mutator_name_1 + mutator_value_1
  267. constexpr U minTokenCount = 2 + 2;
  268. if(tokenCount < minTokenCount || (tokenCount % 2) != 0)
  269. {
  270. ANKI_PP_ERROR_MALFORMED();
  271. }
  272. PartialMutationSkip& skip = *m_skipMutations.emplaceBack();
  273. skip.m_partialMutation.resize(m_mutators.getSize(), std::numeric_limits<MutatorValue>::max());
  274. do
  275. {
  276. // Get mutator name
  277. const CString mutatorName = *begin;
  278. U32 mutatorIndex = kMaxU32;
  279. for(U32 i = 0; i < m_mutators.getSize(); ++i)
  280. {
  281. if(m_mutators[i].m_name == mutatorName)
  282. {
  283. mutatorIndex = i;
  284. break;
  285. }
  286. }
  287. if(mutatorIndex == kMaxU32)
  288. {
  289. ANKI_PP_ERROR_MALFORMED_MSG("Mutator not found");
  290. }
  291. // Get mutator value
  292. ++begin;
  293. const CString valueStr = *begin;
  294. MutatorValue value;
  295. if(valueStr.toNumber(value))
  296. {
  297. ANKI_PP_ERROR_MALFORMED_MSG("Malformed mutator value");
  298. }
  299. if(!mutatorHasValue(m_mutators[mutatorIndex], value))
  300. {
  301. ANKI_PP_ERROR_MALFORMED_MSG("Mutator value incorrect");
  302. }
  303. skip.m_partialMutation[mutatorIndex] = value;
  304. ++begin;
  305. } while(begin < end && !tokenIsComment(*begin));
  306. return Error::kNone;
  307. }
  308. Error ShaderProgramParser::parseInclude(const String* begin, const String* end, CString line, CString fname, U32 depth)
  309. {
  310. // Gather the path
  311. String path;
  312. for(; begin < end; ++begin)
  313. {
  314. path += *begin;
  315. }
  316. if(path.isEmpty())
  317. {
  318. ANKI_PP_ERROR_MALFORMED();
  319. }
  320. // Check
  321. const char firstChar = path[0];
  322. const char lastChar = path[path.getLength() - 1];
  323. if((firstChar == '\"' && lastChar == '\"') || (firstChar == '<' && lastChar == '>'))
  324. {
  325. String fname2(path.begin() + 1, path.begin() + path.getLength() - 1);
  326. const Bool dontIgnore = fname2.find("AnKi/Shaders/") != String::kNpos || fname2.find("ThirdParty/") != String::kNpos;
  327. if(!dontIgnore)
  328. {
  329. // The shaders can't include C++ files. Ignore the include
  330. return Error::kNone;
  331. }
  332. if(parseFile(fname2, depth + 1))
  333. {
  334. ANKI_PP_ERROR_MALFORMED_MSG("Error parsing include. See previous errors");
  335. }
  336. }
  337. else
  338. {
  339. ANKI_PP_ERROR_MALFORMED();
  340. }
  341. return Error::kNone;
  342. }
  343. Error ShaderProgramParser::parseLine(CString line, CString fname, Bool& foundPragmaOnce, U32 depth, U32 lineNumber)
  344. {
  345. // Tokenize
  346. DynamicArray<String> tokens;
  347. tokenizeLine(line, tokens);
  348. ANKI_ASSERT(tokens.getSize() > 0);
  349. const String* token = tokens.getBegin();
  350. const String* end = tokens.getEnd();
  351. // Skip the hash
  352. Bool foundAloneHash = false;
  353. if(*token == "#")
  354. {
  355. ++token;
  356. foundAloneHash = true;
  357. }
  358. if((token < end) && ((foundAloneHash && *token == "include") || *token == "#include"))
  359. {
  360. // We _must_ have an #include
  361. ANKI_CHECK(parseInclude(token + 1, end, line, fname, depth));
  362. m_codeLines.pushBackSprintf("#line %u \"%s\"", lineNumber + 2, fname.cstr());
  363. }
  364. else if((token < end) && ((foundAloneHash && *token == "pragma") || *token == "#pragma"))
  365. {
  366. // We may have a #pragma once or a #pragma anki or something else
  367. ++token;
  368. if(*token == "once")
  369. {
  370. // Pragma once
  371. if(foundPragmaOnce)
  372. {
  373. ANKI_PP_ERROR_MALFORMED_MSG("Can't have more than one #pragma once per file");
  374. }
  375. if(token + 1 != end)
  376. {
  377. ANKI_PP_ERROR_MALFORMED();
  378. }
  379. // Add the guard unique for this file
  380. foundPragmaOnce = true;
  381. const U64 hash = fname.computeHash();
  382. m_codeLines.pushBackSprintf("#ifndef _ANKI_INCL_GUARD_%" PRIu64 "\n"
  383. "#define _ANKI_INCL_GUARD_%" PRIu64,
  384. hash, hash);
  385. }
  386. else if(*token == "anki")
  387. {
  388. // Must be a #pragma anki
  389. ++token;
  390. Bool addLineBack = true;
  391. if(*token == "mutator")
  392. {
  393. ANKI_CHECK(checkNoActiveStruct());
  394. ANKI_CHECK(parsePragmaMutator(token + 1, end, line, fname));
  395. }
  396. else if(*token == "start")
  397. {
  398. ANKI_CHECK(checkNoActiveStruct());
  399. ANKI_CHECK(parsePragmaStart(token + 1, end, line, fname));
  400. addLineBack = false;
  401. }
  402. else if(*token == "end")
  403. {
  404. ANKI_CHECK(checkNoActiveStruct());
  405. ANKI_CHECK(parsePragmaEnd(token + 1, end, line, fname));
  406. addLineBack = false;
  407. }
  408. else if(*token == "skip_mutation")
  409. {
  410. ANKI_CHECK(checkNoActiveStruct());
  411. ANKI_CHECK(parsePragmaSkipMutation(token + 1, end, line, fname));
  412. }
  413. else if(*token == "library")
  414. {
  415. ANKI_CHECK(checkNoActiveStruct());
  416. ANKI_CHECK(parsePragmaLibraryName(token + 1, end, line, fname));
  417. }
  418. else if(*token == "ray_type")
  419. {
  420. ANKI_CHECK(checkNoActiveStruct());
  421. ANKI_CHECK(parsePragmaRayType(token + 1, end, line, fname));
  422. }
  423. else if(*token == "reflect")
  424. {
  425. ANKI_CHECK(checkNoActiveStruct());
  426. ANKI_CHECK(parsePragmaReflect(token + 1, end, line, fname));
  427. }
  428. else if(*token == "struct")
  429. {
  430. if(*(token + 1) == "end")
  431. {
  432. ANKI_CHECK(checkActiveStruct());
  433. ANKI_CHECK(parsePragmaStructEnd(token + 1, end, line, fname));
  434. m_codeLines.pushBackSprintf("#line %u \"%s\"", lineNumber, fname.cstr());
  435. }
  436. else
  437. {
  438. ANKI_CHECK(checkNoActiveStruct());
  439. ANKI_CHECK(parsePragmaStructBegin(token + 1, end, line, fname));
  440. }
  441. }
  442. else if(*token == "member")
  443. {
  444. ANKI_CHECK(checkActiveStruct());
  445. ANKI_CHECK(parsePragmaMember(token + 1, end, line, fname));
  446. }
  447. else if(*token == "16bit")
  448. {
  449. ANKI_CHECK(parsePragma16bit(token + 1, end, line, fname));
  450. }
  451. else
  452. {
  453. ANKI_PP_ERROR_MALFORMED();
  454. }
  455. if(addLineBack)
  456. {
  457. // Add the line as a comment because of hashing of the source
  458. m_codeLines.pushBackSprintf("//%s", line.cstr());
  459. }
  460. }
  461. else
  462. {
  463. // Some other pragma, ignore
  464. m_codeLines.pushBack(line);
  465. }
  466. }
  467. else
  468. {
  469. // Ignore
  470. m_codeLines.pushBack(line);
  471. }
  472. return Error::kNone;
  473. }
  474. Error ShaderProgramParser::parsePragmaStructBegin(const String* begin, const String* end, CString line, CString fname)
  475. {
  476. const U tokenCount = U(end - begin);
  477. if(tokenCount != 1)
  478. {
  479. ANKI_PP_ERROR_MALFORMED();
  480. }
  481. GhostStruct& gstruct = *m_ghostStructs.emplaceBack();
  482. gstruct.m_name = *begin;
  483. // Add a '_' to the struct name.
  484. //
  485. // Scenario:
  486. // - The shader may have a "pragma reflect" of the struct
  487. // - The SPIRV also contains the struct
  488. //
  489. // What happens:
  490. // - The struct is in SPIRV and it will be reflected
  491. // - The struct is also in ghost structs and it will be reflected
  492. //
  493. // This is undesirable because it will complicates reflection. So eliminate the struct from SPIRV by renaming it
  494. m_codeLines.pushBackSprintf("struct %s_ {", begin->cstr());
  495. ANKI_ASSERT(!m_insideStruct);
  496. m_insideStruct = true;
  497. return Error::kNone;
  498. }
  499. Error ShaderProgramParser::parsePragmaMember(const String* begin, const String* end, CString line, CString fname)
  500. {
  501. ANKI_ASSERT(m_insideStruct);
  502. const U tokenCount = U(end - begin);
  503. if(tokenCount == 0)
  504. {
  505. ANKI_PP_ERROR_MALFORMED();
  506. }
  507. Member& member = *m_ghostStructs.getBack().m_members.emplaceBack();
  508. // Relaxed
  509. Bool relaxed = false;
  510. if(*begin == "ANKI_RP")
  511. {
  512. relaxed = true;
  513. ++begin;
  514. }
  515. // Type
  516. if(begin == end)
  517. {
  518. ANKI_PP_ERROR_MALFORMED();
  519. }
  520. const CString typeStr = *begin;
  521. member.m_type = ShaderVariableDataType::kNone;
  522. if(typeStr == "F32" || typeStr == "RF32")
  523. {
  524. member.m_type = ShaderVariableDataType::kF32;
  525. }
  526. else if(typeStr == "Vec2" || typeStr == "RVec2")
  527. {
  528. member.m_type = ShaderVariableDataType::kVec2;
  529. }
  530. else if(typeStr == "Vec3" || typeStr == "RVec3")
  531. {
  532. member.m_type = ShaderVariableDataType::kVec3;
  533. }
  534. else if(typeStr == "Vec4" || typeStr == "RVec4")
  535. {
  536. member.m_type = ShaderVariableDataType::kVec4;
  537. }
  538. else if(typeStr == "U32")
  539. {
  540. member.m_type = ShaderVariableDataType::kU32;
  541. }
  542. if(member.m_type == ShaderVariableDataType::kNone)
  543. {
  544. ANKI_PP_ERROR_MALFORMED_MSG("Unrecognized type");
  545. }
  546. ++begin;
  547. // Name
  548. if(begin == end)
  549. {
  550. ANKI_PP_ERROR_MALFORMED();
  551. }
  552. member.m_name = *begin;
  553. ++begin;
  554. // if MUTATOR_NAME is MUTATOR_VALUE
  555. if(begin != end)
  556. {
  557. // "if"
  558. if(*begin != "if")
  559. {
  560. ANKI_PP_ERROR_MALFORMED();
  561. }
  562. ++begin;
  563. // MUTATOR_NAME
  564. if(begin == end)
  565. {
  566. ANKI_PP_ERROR_MALFORMED();
  567. }
  568. const CString mutatorName = *begin;
  569. for(U32 i = 0; i < m_mutators.getSize(); ++i)
  570. {
  571. if(m_mutators[i].m_name == mutatorName)
  572. {
  573. member.m_dependentMutator = i;
  574. break;
  575. }
  576. }
  577. if(member.m_dependentMutator == kMaxU32)
  578. {
  579. ANKI_PP_ERROR_MALFORMED_MSG("Mutator not found");
  580. }
  581. ++begin;
  582. // "is"
  583. if(begin == end)
  584. {
  585. ANKI_PP_ERROR_MALFORMED();
  586. }
  587. if(*begin != "is")
  588. {
  589. ANKI_PP_ERROR_MALFORMED();
  590. }
  591. ++begin;
  592. // MUTATOR_VALUE
  593. if(begin == end)
  594. {
  595. ANKI_PP_ERROR_MALFORMED();
  596. }
  597. ANKI_CHECK(begin->toNumber(member.m_mutatorValue));
  598. if(!mutatorHasValue(m_mutators[member.m_dependentMutator], member.m_mutatorValue))
  599. {
  600. ANKI_PP_ERROR_MALFORMED_MSG("Wrong mutator value");
  601. }
  602. ++begin;
  603. }
  604. if(begin != end)
  605. {
  606. ANKI_PP_ERROR_MALFORMED();
  607. }
  608. // Code
  609. if(member.m_dependentMutator != kMaxU32)
  610. {
  611. m_codeLines.pushBackSprintf("#if %s == %d", m_mutators[member.m_dependentMutator].m_name.cstr(), member.m_mutatorValue);
  612. }
  613. m_codeLines.pushBackSprintf("#\tdefine %s_%s_DEFINED 1", m_ghostStructs.getBack().m_name.cstr(), member.m_name.cstr());
  614. m_codeLines.pushBackSprintf("\t%s %s %s;", (relaxed) ? "ANKI_RP" : "", typeStr.cstr(), member.m_name.cstr());
  615. if(member.m_dependentMutator != kMaxU32)
  616. {
  617. m_codeLines.pushBack("#endif");
  618. }
  619. return Error::kNone;
  620. }
  621. Error ShaderProgramParser::parsePragmaStructEnd(const String* begin, const String* end, CString line, CString fname)
  622. {
  623. ANKI_ASSERT(m_insideStruct);
  624. const U tokenCount = U(end - begin);
  625. if(tokenCount != 1)
  626. {
  627. ANKI_PP_ERROR_MALFORMED();
  628. }
  629. GhostStruct& gstruct = m_ghostStructs.getBack();
  630. const CString structName = gstruct.m_name;
  631. if(gstruct.m_members.isEmpty())
  632. {
  633. ANKI_PP_ERROR_MALFORMED_MSG("The struct doesn't have any members");
  634. }
  635. m_codeLines.pushBack("};");
  636. for(U32 i = 0; i < gstruct.m_members.getSize(); ++i)
  637. {
  638. const Member& m = gstruct.m_members[i];
  639. // #define XXX_OFFSETOF
  640. if(i == 0)
  641. {
  642. m_codeLines.pushBackSprintf("#define %s_%s_OFFSETOF 0u", gstruct.m_name.cstr(), m.m_name.cstr());
  643. }
  644. else
  645. {
  646. const Member& prev = gstruct.m_members[i - 1];
  647. m_codeLines.pushBackSprintf("#define %s_%s_OFFSETOF (%s_%s_OFFSETOF + %s_%s_SIZEOF)", structName.cstr(), m.m_name.cstr(),
  648. structName.cstr(), prev.m_name.cstr(), structName.cstr(), prev.m_name.cstr());
  649. }
  650. // #if XXX_DEFINED
  651. m_codeLines.pushBackSprintf("#if defined(%s_%s_DEFINED)", structName.cstr(), m.m_name.cstr());
  652. // # define XXX_SIZEOF
  653. m_codeLines.pushBackSprintf("#\tdefine %s_%s_SIZEOF %uu", structName.cstr(), m.m_name.cstr(), getShaderVariableDataTypeInfo(m.m_type).m_size);
  654. // # define XXX_LOAD()
  655. m_codeLines.pushBackSprintf("#\tdefine %s_%s_LOAD(buff, offset) buff.Load<%s>(%s_%s_OFFSETOF + (offset))%s", structName.cstr(),
  656. m.m_name.cstr(), getShaderVariableDataTypeInfo(m.m_type).m_name, structName.cstr(), m.m_name.cstr(),
  657. (i != gstruct.m_members.getSize() - 1) ? "," : "");
  658. // #else
  659. m_codeLines.pushBack("#else");
  660. // # define XXX_SIZEOF 0
  661. m_codeLines.pushBackSprintf("#\tdefine %s_%s_SIZEOF 0u", structName.cstr(), m.m_name.cstr());
  662. // # define XXX_LOAD()
  663. m_codeLines.pushBackSprintf("#\tdefine %s_%s_LOAD(buff, offset)", structName.cstr(), m.m_name.cstr());
  664. // #endif
  665. m_codeLines.pushBack("#endif");
  666. }
  667. // Now define the structure LOAD in HLSL
  668. m_codeLines.pushBackSprintf("#define load%s(buff, offset) { \\", structName.cstr());
  669. for(U32 i = 0; i < gstruct.m_members.getSize(); ++i)
  670. {
  671. const Member& m = gstruct.m_members[i];
  672. m_codeLines.pushBackSprintf("\t%s_%s_LOAD(buff, offset) \\", structName.cstr(), m.m_name.cstr());
  673. }
  674. m_codeLines.pushBack("}");
  675. // Define the actual struct
  676. m_codeLines.pushBackSprintf("#define %s %s_", structName.cstr(), structName.cstr());
  677. m_insideStruct = false;
  678. return Error::kNone;
  679. }
  680. Error ShaderProgramParser::parsePragma16bit(const String* begin, const String* end, CString line, CString fname)
  681. {
  682. ANKI_ASSERT(begin && end);
  683. // Check tokens
  684. if(begin != end)
  685. {
  686. ANKI_PP_ERROR_MALFORMED();
  687. }
  688. m_16bitTypes = true;
  689. return Error::kNone;
  690. }
  691. Error ShaderProgramParser::parseFile(CString fname, U32 depth)
  692. {
  693. // First check the depth
  694. if(depth > kMaxIncludeDepth)
  695. {
  696. ANKI_SHADER_COMPILER_LOGE("The include depth is too high. Probably circular includance");
  697. }
  698. Bool foundPragmaOnce = false;
  699. // Load file in lines
  700. String txt;
  701. ANKI_CHECK(m_fsystem->readAllText(fname, txt));
  702. StringList lines;
  703. lines.splitString(txt, '\n', true);
  704. if(lines.getSize() < 1)
  705. {
  706. ANKI_SHADER_COMPILER_LOGE("Source is empty");
  707. }
  708. m_codeLines.pushBackSprintf("#line 0 \"%s\"", fname.cstr());
  709. // Parse lines
  710. U32 lineCount = 0;
  711. for(const String& line : lines)
  712. {
  713. if(line.isEmpty())
  714. {
  715. m_codeLines.pushBack(" ");
  716. }
  717. else if(line.find("pragma") != String::kNpos || line.find("include") != String::kNpos)
  718. {
  719. // Possibly a preprocessor directive we care
  720. ANKI_CHECK(parseLine(line.toCString(), fname, foundPragmaOnce, depth, lineCount));
  721. }
  722. else
  723. {
  724. // Just append the line
  725. m_codeLines.pushBack(line.toCString());
  726. }
  727. ++lineCount;
  728. }
  729. if(foundPragmaOnce)
  730. {
  731. // Append the guard
  732. m_codeLines.pushBack("#endif // Include guard");
  733. }
  734. return Error::kNone;
  735. }
  736. Error ShaderProgramParser::parse()
  737. {
  738. ANKI_ASSERT(!m_fname.isEmpty());
  739. ANKI_ASSERT(m_codeLines.isEmpty());
  740. const CString fname = m_fname;
  741. // Parse recursively
  742. ANKI_CHECK(parseFile(fname, 0));
  743. // Checks
  744. {
  745. if(!m_shaderTypes)
  746. {
  747. ANKI_SHADER_COMPILER_LOGE("Haven't found any shader types");
  748. return Error::kUserData;
  749. }
  750. if(!!(m_shaderTypes & ShaderTypeBit::kCompute))
  751. {
  752. if(m_shaderTypes != ShaderTypeBit::kCompute)
  753. {
  754. ANKI_SHADER_COMPILER_LOGE("Can't combine compute shader with other types of shaders");
  755. return Error::kUserData;
  756. }
  757. }
  758. else if(!!(m_shaderTypes & ShaderTypeBit::kAllGraphics))
  759. {
  760. if(!(m_shaderTypes & ShaderTypeBit::kVertex))
  761. {
  762. ANKI_SHADER_COMPILER_LOGE("Missing vertex shader");
  763. return Error::kUserData;
  764. }
  765. if(!(m_shaderTypes & ShaderTypeBit::kFragment))
  766. {
  767. ANKI_SHADER_COMPILER_LOGE("Missing fragment shader");
  768. return Error::kUserData;
  769. }
  770. }
  771. if(m_insideShader)
  772. {
  773. ANKI_SHADER_COMPILER_LOGE("Forgot a \"pragma anki end\"");
  774. return Error::kUserData;
  775. }
  776. }
  777. // Create the code lines
  778. if(m_codeLines.getSize())
  779. {
  780. m_codeLines.join("\n", m_codeSource);
  781. m_codeLines.destroy();
  782. }
  783. // Create the hash
  784. {
  785. if(m_codeSource.getLength())
  786. {
  787. m_codeSourceHash = appendHash(m_codeSource.getBegin(), m_codeSource.getLength(), kShaderHeaderHash);
  788. }
  789. if(m_libName.getLength() > 0)
  790. {
  791. m_codeSourceHash = appendHash(m_libName.getBegin(), m_libName.getLength(), m_codeSourceHash);
  792. }
  793. m_codeSourceHash = appendHash(&m_rayType, sizeof(m_rayType), m_codeSourceHash);
  794. }
  795. return Error::kNone;
  796. }
  797. void ShaderProgramParser::generateAnkiShaderHeader(ShaderType shaderType, const ShaderCompilerOptions& compilerOptions, String& header)
  798. {
  799. header.sprintf(kShaderHeader, kShaderStageNames[shaderType].cstr(), compilerOptions.m_mobilePlatform,
  800. compilerOptions.m_forceFullFloatingPointPrecision, kMaxBindlessTextures, kMaxBindlessReadonlyTextureBuffers);
  801. }
  802. Error ShaderProgramParser::generateVariant(ConstWeakArray<MutatorValue> mutation, ShaderProgramParserVariant& variant) const
  803. {
  804. // Sanity checks
  805. ANKI_ASSERT(m_codeSource.getLength() > 0);
  806. ANKI_ASSERT(mutation.getSize() == m_mutators.getSize());
  807. for(U32 i = 0; i < mutation.getSize(); ++i)
  808. {
  809. ANKI_ASSERT(mutatorHasValue(m_mutators[i], mutation[i]) && "Value not found");
  810. }
  811. // Init variant
  812. ::new(&variant) ShaderProgramParserVariant();
  813. // Create the mutator defines
  814. String mutatorDefines;
  815. for(U32 i = 0; i < mutation.getSize(); ++i)
  816. {
  817. mutatorDefines += String().sprintf("#define %s %d\n", m_mutators[i].m_name.cstr(), mutation[i]);
  818. }
  819. // Generate souce per stage
  820. for(ShaderType shaderType : EnumIterable<ShaderType>())
  821. {
  822. if(!(ShaderTypeBit(1u << shaderType) & m_shaderTypes))
  823. {
  824. continue;
  825. }
  826. // Create the header
  827. String header;
  828. generateAnkiShaderHeader(shaderType, m_compilerOptions, header);
  829. // Create the final source without the bindings
  830. String finalSource;
  831. finalSource += header;
  832. if(m_16bitTypes)
  833. {
  834. finalSource += "#define ANKI_SUPPORTS_16BIT_TYPES 1\n";
  835. }
  836. else
  837. {
  838. finalSource += "#define ANKI_SUPPORTS_16BIT_TYPES 0\n";
  839. }
  840. finalSource += mutatorDefines;
  841. finalSource += m_codeSource;
  842. // Move the source
  843. variant.m_sources[shaderType] = std::move(finalSource);
  844. }
  845. return Error::kNone;
  846. }
  847. Bool ShaderProgramParser::mutatorHasValue(const ShaderProgramParserMutator& mutator, MutatorValue value)
  848. {
  849. for(MutatorValue v : mutator.m_values)
  850. {
  851. if(value == v)
  852. {
  853. return true;
  854. }
  855. }
  856. return false;
  857. }
  858. Bool ShaderProgramParser::skipMutation(ConstWeakArray<MutatorValue> mutation) const
  859. {
  860. ANKI_ASSERT(mutation.getSize() == m_mutators.getSize());
  861. for(const PartialMutationSkip& skip : m_skipMutations)
  862. {
  863. Bool doSkip = true;
  864. for(U32 i = 0; i < m_mutators.getSize(); ++i)
  865. {
  866. if(skip.m_partialMutation[i] == std::numeric_limits<MutatorValue>::max())
  867. {
  868. // Don't care
  869. continue;
  870. }
  871. if(skip.m_partialMutation[i] != mutation[i])
  872. {
  873. doSkip = false;
  874. break;
  875. }
  876. }
  877. if(doSkip)
  878. {
  879. return true;
  880. }
  881. }
  882. return false;
  883. }
  884. } // end namespace anki