ShaderProgramParser.cpp 24 KB

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