BsSLFXCompiler.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsSLFXCompiler.h"
  4. #include "BsGpuProgram.h"
  5. #include <regex>
  6. #include "BsShader.h"
  7. #include "BsTechnique.h"
  8. #include "BsPass.h"
  9. #include "BsSamplerState.h"
  10. #include "BsRenderAPI.h"
  11. #include "BsDebug.h"
  12. #include "BsShaderManager.h"
  13. #include "BsShaderInclude.h"
  14. #include "BsMatrix4.h"
  15. #include "BsBuiltinResources.h"
  16. extern "C" {
  17. #include "BsMMAlloc.h"
  18. #include "BsParserFX.h"
  19. #include "BsLexerFX.h"
  20. }
  21. using namespace std;
  22. namespace BansheeEngine
  23. {
  24. // Print out the FX AST, only for debug purposes
  25. void SLFXDebugPrint(ASTFXNode* node, String indent)
  26. {
  27. LOGDBG(indent + "NODE " + toString(node->type));
  28. for (int i = 0; i < node->options->count; i++)
  29. {
  30. OptionDataType odt = OPTION_LOOKUP[(int)node->options->entries[i].type].dataType;
  31. if (odt == ODT_Complex)
  32. {
  33. LOGDBG(indent + toString(i) + ". " + toString(node->options->entries[i].type));
  34. SLFXDebugPrint(node->options->entries[i].value.nodePtr, indent + "\t");
  35. continue;
  36. }
  37. String value;
  38. switch (odt)
  39. {
  40. case ODT_Bool:
  41. value = toString(node->options->entries[i].value.intValue != 0);
  42. break;
  43. case ODT_Int:
  44. value = toString(node->options->entries[i].value.intValue);
  45. break;
  46. case ODT_Float:
  47. value = toString(node->options->entries[i].value.floatValue);
  48. break;
  49. case ODT_String:
  50. value = node->options->entries[i].value.strValue;
  51. break;
  52. case ODT_Matrix:
  53. {
  54. Matrix4 mat4 = *(Matrix4*)(node->options->entries[i].value.matrixValue);
  55. value = toString(mat4);
  56. }
  57. break;
  58. }
  59. LOGDBG(indent + toString(i) + ". " + toString(node->options->entries[i].type) + " = " + value);
  60. }
  61. }
  62. BSLFXCompileResult BSLFXCompiler::compile(const String& source)
  63. {
  64. BSLFXCompileResult output;
  65. String parsedSource = source;
  66. ParseState* parseState = parseStateCreate();
  67. Vector<CodeBlock> codeBlocks = parseCodeBlocks(parsedSource);
  68. parseFX(parseState, parsedSource.c_str());
  69. if (parseState->hasError > 0)
  70. {
  71. output.errorMessage = parseState->errorMessage;
  72. output.errorLine = parseState->errorLine;
  73. output.errorColumn = parseState->errorColumn;
  74. parseStateDelete(parseState);
  75. }
  76. else
  77. {
  78. // Only enable for debug purposes
  79. //SLFXDebugPrint(parseState->rootNode, "");
  80. output = parseShader("Shader", parseState, codeBlocks);
  81. StringStream gpuProgError;
  82. bool hasError = false;
  83. if (output.shader != nullptr)
  84. {
  85. TechniquePtr bestTechnique = output.shader->getBestTechnique();
  86. if (bestTechnique != nullptr)
  87. {
  88. UINT32 numPasses = bestTechnique->getNumPasses();
  89. for (UINT32 i = 0; i < numPasses; i++)
  90. {
  91. PassPtr pass = bestTechnique->getPass(i);
  92. auto checkCompileStatus = [&](const String& prefix, const GpuProgramPtr& prog)
  93. {
  94. if (prog != nullptr)
  95. {
  96. prog->blockUntilCoreInitialized();
  97. if (!prog->isCompiled())
  98. {
  99. hasError = true;
  100. gpuProgError << prefix <<": " << prog->getCompileErrorMessage() << std::endl;
  101. }
  102. }
  103. };
  104. checkCompileStatus("Vertex program", pass->getVertexProgram());
  105. checkCompileStatus("Fragment program", pass->getFragmentProgram());
  106. checkCompileStatus("Geometry program", pass->getGeometryProgram());
  107. checkCompileStatus("Hull program", pass->getHullProgram());
  108. checkCompileStatus("Domain program", pass->getDomainProgram());
  109. checkCompileStatus("Compute program", pass->getComputeProgram());
  110. }
  111. }
  112. }
  113. if (hasError)
  114. {
  115. output.shader = nullptr;
  116. output.errorMessage = "Failed compiling GPU program(s): " + gpuProgError.str();
  117. output.errorLine = 0;
  118. output.errorColumn = 0;
  119. }
  120. }
  121. return output;
  122. }
  123. void BSLFXCompiler::parseFX(ParseState* parseState, const char* source)
  124. {
  125. yyscan_t scanner;
  126. YY_BUFFER_STATE state;
  127. if (yylex_init_extra(parseState, &scanner))
  128. return;
  129. // If debug output from lexer is needed uncomment this and add %debug option to lexer file
  130. yyset_debug(true, scanner);
  131. // If debug output from parser is needed uncomment this and add %debug option to parser file
  132. yydebug = true;
  133. state = yy_scan_string(source, scanner);
  134. if (yyparse(parseState, scanner))
  135. return;
  136. yy_delete_buffer(state, scanner);
  137. yylex_destroy(scanner);
  138. }
  139. Vector<BSLFXCompiler::CodeBlock> BSLFXCompiler::parseCodeBlocks(String& source)
  140. {
  141. std::regex pattern = std::regex(R"((Vertex|Fragment|Geometry|Hull|Domain|Compute|Common)\s*=\s*\{)");
  142. std::smatch matches;
  143. Vector<CodeBlock> codeBlocks;
  144. UINT32 offset = 0;
  145. while (std::regex_search(source.cbegin() + offset, source.cend(), matches, pattern))
  146. {
  147. UINT32 idx = (UINT32)codeBlocks.size();
  148. codeBlocks.push_back(CodeBlock());
  149. CodeBlock& newBlock = codeBlocks.back();
  150. std::string type = matches[1].str();
  151. if (type == "Vertex")
  152. newBlock.type = CodeBlockType::Vertex;
  153. else if (type == "Fragment")
  154. newBlock.type = CodeBlockType::Fragment;
  155. else if (type == "Geometry")
  156. newBlock.type = CodeBlockType::Geometry;
  157. else if (type == "Hull")
  158. newBlock.type = CodeBlockType::Hull;
  159. else if (type == "Domain")
  160. newBlock.type = CodeBlockType::Domain;
  161. else if (type == "Compute")
  162. newBlock.type = CodeBlockType::Compute;
  163. else if (type == "Common")
  164. newBlock.type = CodeBlockType::Common;
  165. offset += (UINT32)matches.position() + (UINT32)matches.length();
  166. StringStream newDataStream;
  167. newDataStream << "Index = " + toString(idx) + ";";
  168. StringStream codeStream;
  169. UINT32 ummatchedBrackets = 1;
  170. for (UINT32 i = offset; i < (UINT32)source.length(); i++)
  171. {
  172. if (source[i] == '{')
  173. ummatchedBrackets++;
  174. if (source[i] == '}')
  175. ummatchedBrackets--;
  176. if (ummatchedBrackets == 0)
  177. break;
  178. if (source[i] == '\r' || source[i] == '\n')
  179. newDataStream << source[i];
  180. codeStream << source[i];
  181. }
  182. newBlock.code = codeStream.str();
  183. source.erase(source.cbegin() + offset, source.cbegin() + offset + (UINT32)newBlock.code.size());
  184. String newData = newDataStream.str();
  185. source.insert(offset, newData);
  186. offset += (UINT32)newData.size();
  187. }
  188. return codeBlocks;
  189. }
  190. void BSLFXCompiler::getTechniqueIdentifier(ASTFXNode* technique, StringID& renderer, String& language)
  191. {
  192. renderer = RendererAny;
  193. language = "Any";
  194. for (int i = 0; i < technique->options->count; i++)
  195. {
  196. NodeOption* option = &technique->options->entries[i];
  197. switch (option->type)
  198. {
  199. case OT_Renderer:
  200. renderer = parseRenderer(removeQuotes(option->value.strValue));
  201. break;
  202. case OT_Language:
  203. language = removeQuotes(option->value.strValue);
  204. break;
  205. }
  206. }
  207. }
  208. bool BSLFXCompiler::doTechniquesMatch(ASTFXNode* into, ASTFXNode* from)
  209. {
  210. StringID intoRenderer = RendererAny;
  211. String intoLanguage = "Any";
  212. StringID fromRenderer = RendererAny;
  213. String fromLanguage = "Any";
  214. getTechniqueIdentifier(into, intoRenderer, intoLanguage);
  215. getTechniqueIdentifier(from, fromRenderer, fromLanguage);
  216. return (intoRenderer == fromRenderer || fromRenderer == RendererAny) && (intoLanguage == fromLanguage || fromLanguage == "Any");
  217. }
  218. StringID BSLFXCompiler::parseRenderer(const String& name)
  219. {
  220. if (name == "Any")
  221. return RendererAny;
  222. else if (name == "Default")
  223. return RendererDefault;
  224. return RendererAny;
  225. }
  226. void BSLFXCompiler::parseLanguage(const String& name, StringID& renderAPI, String& language)
  227. {
  228. if (name == "HLSL" || name == "HLSL11")
  229. {
  230. renderAPI = RenderAPIDX11;
  231. language = "hlsl";
  232. }
  233. else if (name == "HLSL9")
  234. {
  235. renderAPI = RenderAPIDX9;
  236. language = "hlsl9";
  237. }
  238. else if (name == "GLSL")
  239. {
  240. renderAPI = RenderAPIOpenGL;
  241. language = "glsl";
  242. }
  243. else // "Any"
  244. {
  245. renderAPI = RenderAPIAny;
  246. language = "";
  247. }
  248. }
  249. GpuParamBlockUsage BSLFXCompiler::parseBlockUsage(BufferUsageValue usage)
  250. {
  251. if (usage == BUV_Dynamic)
  252. return GPBU_DYNAMIC;
  253. return GPBU_STATIC;
  254. }
  255. UINT32 BSLFXCompiler::parseFilterMode(FilterValue filter)
  256. {
  257. switch (filter)
  258. {
  259. case FV_Point:
  260. return FO_POINT;
  261. case FV_Linear:
  262. return FO_LINEAR;
  263. case FV_Anisotropic:
  264. return FO_ANISOTROPIC;
  265. case FV_PointCmp:
  266. return FO_POINT | FO_USE_COMPARISON;
  267. case FV_LinearCmp:
  268. return FO_LINEAR | FO_USE_COMPARISON;
  269. case FV_AnisotropicCmp:
  270. return FO_ANISOTROPIC | FO_USE_COMPARISON;
  271. }
  272. return FO_NONE;
  273. }
  274. CompareFunction BSLFXCompiler::parseCompFunc(CompFuncValue compFunc)
  275. {
  276. switch (compFunc)
  277. {
  278. case CFV_Pass:
  279. return CMPF_ALWAYS_PASS;
  280. case CFV_Fail:
  281. return CMPF_ALWAYS_FAIL;
  282. case CFV_LT:
  283. return CMPF_LESS;
  284. case CFV_LTE:
  285. return CMPF_LESS_EQUAL;
  286. case CFV_EQ:
  287. return CMPF_EQUAL;
  288. case CFV_NEQ:
  289. return CMPF_NOT_EQUAL;
  290. case CFV_GT:
  291. return CMPF_GREATER;
  292. case CFV_GTE:
  293. return CMPF_GREATER_EQUAL;
  294. }
  295. return CMPF_ALWAYS_PASS;
  296. }
  297. TextureAddressingMode BSLFXCompiler::parseAddrMode(AddrModeValue addrMode)
  298. {
  299. switch (addrMode)
  300. {
  301. case AMV_Wrap:
  302. return TAM_WRAP;
  303. case AMV_Mirror:
  304. return TAM_MIRROR;
  305. case AMV_Clamp:
  306. return TAM_CLAMP;
  307. case AMV_Border:
  308. return TAM_BORDER;
  309. }
  310. return TAM_WRAP;
  311. }
  312. BlendFactor BSLFXCompiler::parseBlendFactor(OpValue factor)
  313. {
  314. switch (factor)
  315. {
  316. case OV_One:
  317. return BF_ONE;
  318. case OV_Zero:
  319. return BF_ZERO;
  320. case OV_DestColor:
  321. return BF_DEST_COLOR;
  322. case OV_SrcColor:
  323. return BF_SOURCE_COLOR;
  324. case OV_InvDestColor:
  325. return BF_INV_DEST_COLOR;
  326. case OV_InvSrcColor:
  327. return BF_INV_SOURCE_COLOR;
  328. case OV_DestAlpha:
  329. return BF_DEST_ALPHA;
  330. case OV_SrcAlpha:
  331. return BF_SOURCE_ALPHA;
  332. case OV_InvDestAlpha:
  333. return BF_INV_DEST_ALPHA;
  334. case OV_InvSrcAlpha:
  335. return BF_INV_SOURCE_ALPHA;
  336. }
  337. return BF_ONE;
  338. }
  339. BlendOperation BSLFXCompiler::parseBlendOp(BlendOpValue op)
  340. {
  341. switch (op)
  342. {
  343. case BOV_Add:
  344. return BO_ADD;
  345. case BOV_Max:
  346. return BO_MAX;
  347. case BOV_Min:
  348. return BO_MIN;
  349. case BOV_Subtract:
  350. return BO_SUBTRACT;
  351. case BOV_RevSubtract:
  352. return BO_REVERSE_SUBTRACT;
  353. }
  354. return BO_ADD;
  355. }
  356. void BSLFXCompiler::parseParamType(ParamType type, bool& isObjType, UINT32& typeId)
  357. {
  358. struct ParamData
  359. {
  360. UINT32 type;
  361. bool isObjType;
  362. };
  363. static bool initialized = false;
  364. static ParamData lookup[PT_Count];
  365. if (!initialized)
  366. {
  367. lookup[PT_Float] = { { GPDT_FLOAT1 }, false };
  368. lookup[PT_Float2] = { { GPDT_FLOAT2 }, false };
  369. lookup[PT_Float3] = { { GPDT_FLOAT3 }, false };
  370. lookup[PT_Float4] = { { GPDT_FLOAT4 }, false };
  371. lookup[PT_Int] = { { GPDT_INT1 }, false };
  372. lookup[PT_Int2] = { { GPDT_INT2 }, false };
  373. lookup[PT_Int3] = { { GPDT_INT3 }, false };
  374. lookup[PT_Int4] = { { GPDT_INT4 }, false };
  375. lookup[PT_Mat2x2] = { { GPDT_MATRIX_2X2 }, false };
  376. lookup[PT_Mat2x3] = { { GPDT_MATRIX_2X3 }, false };
  377. lookup[PT_Mat2x4] = { { GPDT_MATRIX_2X4 }, false };
  378. lookup[PT_Mat3x2] = { { GPDT_MATRIX_3X2 }, false };
  379. lookup[PT_Mat3x3] = { { GPDT_MATRIX_3X3 }, false };
  380. lookup[PT_Mat3x4] = { { GPDT_MATRIX_3X4 }, false };
  381. lookup[PT_Mat4x2] = { { GPDT_MATRIX_4X2 }, false };
  382. lookup[PT_Mat4x3] = { { GPDT_MATRIX_4X3 }, false };
  383. lookup[PT_Mat4x4] = { { GPDT_MATRIX_4X4 }, false };
  384. lookup[PT_Sampler1D] = { { GPOT_SAMPLER1D }, true };
  385. lookup[PT_Sampler2D] = { { GPOT_SAMPLER2D }, true };
  386. lookup[PT_Sampler3D] = { { GPOT_SAMPLER3D }, true };
  387. lookup[PT_SamplerCUBE] = { { GPOT_SAMPLERCUBE }, true };
  388. lookup[PT_Sampler2DMS] = { { GPOT_SAMPLER2DMS }, true };
  389. lookup[PT_Texture1D] = { { GPOT_TEXTURE1D }, true };
  390. lookup[PT_Texture2D] = { { GPOT_TEXTURE2D }, true };
  391. lookup[PT_Texture3D] = { { GPOT_TEXTURE3D }, true };
  392. lookup[PT_TextureCUBE] = { { GPOT_TEXTURECUBE }, true };
  393. lookup[PT_Texture2DMS] = { { GPOT_TEXTURE2DMS }, true };
  394. lookup[PT_ByteBuffer] = { { GPOT_BYTE_BUFFER }, true };
  395. lookup[PT_StructBuffer] = { { GPOT_STRUCTURED_BUFFER }, true };
  396. lookup[PT_TypedBufferRW] = { { GPOT_RWTYPED_BUFFER }, true };
  397. lookup[PT_ByteBufferRW] = { { GPOT_RWBYTE_BUFFER }, true };
  398. lookup[PT_StructBufferRW] = { { GPOT_RWSTRUCTURED_BUFFER }, true };
  399. lookup[PT_AppendBuffer] = { { GPOT_RWAPPEND_BUFFER }, true };
  400. lookup[PT_ConsumeBuffer] = { { GPOT_RWCONSUME_BUFFER }, true };
  401. initialized = true;
  402. }
  403. isObjType = lookup[type].isObjType;
  404. typeId = lookup[type].type;
  405. }
  406. StencilOperation BSLFXCompiler::parseStencilOp(OpValue op)
  407. {
  408. switch (op)
  409. {
  410. case OV_Keep:
  411. return SOP_KEEP;
  412. case OV_Zero:
  413. return SOP_ZERO;
  414. case OV_Replace:
  415. return SOP_REPLACE;
  416. case OV_Incr:
  417. return SOP_INCREMENT;
  418. case OV_Decr:
  419. return SOP_DECREMENT;
  420. case OV_IncrWrap:
  421. return SOP_INCREMENT_WRAP;
  422. case OV_DecrWrap:
  423. return SOP_DECREMENT_WRAP;
  424. case OV_Invert:
  425. return SOP_INVERT;
  426. }
  427. return SOP_KEEP;
  428. }
  429. CullingMode BSLFXCompiler::parseCullMode(CullModeValue cm)
  430. {
  431. switch (cm)
  432. {
  433. case CMV_None:
  434. return CULL_NONE;
  435. case CMV_CW:
  436. return CULL_CLOCKWISE;
  437. case CMV_CCW:
  438. return CULL_COUNTERCLOCKWISE;
  439. }
  440. return CULL_COUNTERCLOCKWISE;
  441. }
  442. PolygonMode BSLFXCompiler::parseFillMode(FillModeValue fm)
  443. {
  444. if (fm == FMV_Wire)
  445. return PM_WIREFRAME;
  446. return PM_SOLID;
  447. }
  448. void BSLFXCompiler::parseStencilFront(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode)
  449. {
  450. if (stencilOpNode == nullptr || stencilOpNode->type != NT_StencilOp)
  451. return;
  452. for (int i = 0; i < stencilOpNode->options->count; i++)
  453. {
  454. NodeOption* option = &stencilOpNode->options->entries[i];
  455. switch (option->type)
  456. {
  457. case OT_Fail:
  458. desc.frontStencilFailOp = parseStencilOp((OpValue)option->value.intValue);
  459. break;
  460. case OT_ZFail:
  461. desc.frontStencilZFailOp = parseStencilOp((OpValue)option->value.intValue);
  462. break;
  463. case OT_PassOp:
  464. desc.frontStencilPassOp = parseStencilOp((OpValue)option->value.intValue);
  465. break;
  466. case OT_CompareFunc:
  467. desc.frontStencilComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  468. break;
  469. }
  470. }
  471. }
  472. void BSLFXCompiler::parseStencilBack(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode)
  473. {
  474. if (stencilOpNode == nullptr || stencilOpNode->type != NT_StencilOp)
  475. return;
  476. for (int i = 0; i < stencilOpNode->options->count; i++)
  477. {
  478. NodeOption* option = &stencilOpNode->options->entries[i];
  479. switch (option->type)
  480. {
  481. case OT_Fail:
  482. desc.backStencilFailOp = parseStencilOp((OpValue)option->value.intValue);
  483. break;
  484. case OT_ZFail:
  485. desc.backStencilZFailOp = parseStencilOp((OpValue)option->value.intValue);
  486. break;
  487. case OT_PassOp:
  488. desc.backStencilPassOp = parseStencilOp((OpValue)option->value.intValue);
  489. break;
  490. case OT_CompareFunc:
  491. desc.backStencilComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  492. break;
  493. }
  494. }
  495. }
  496. void BSLFXCompiler::parseAddrMode(SAMPLER_STATE_DESC& desc, ASTFXNode* addrModeNode)
  497. {
  498. if (addrModeNode == nullptr || addrModeNode->type != NT_AddrMode)
  499. return;
  500. for (int i = 0; i < addrModeNode->options->count; i++)
  501. {
  502. NodeOption* option = &addrModeNode->options->entries[i];
  503. switch (option->type)
  504. {
  505. case OT_U:
  506. desc.addressMode.u = parseAddrMode((AddrModeValue)option->value.intValue);
  507. break;
  508. case OT_V:
  509. desc.addressMode.v = parseAddrMode((AddrModeValue)option->value.intValue);
  510. break;
  511. case OT_W:
  512. desc.addressMode.w = parseAddrMode((AddrModeValue)option->value.intValue);
  513. break;
  514. }
  515. }
  516. }
  517. void BSLFXCompiler::parseColorBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode)
  518. {
  519. if (blendDefNode == nullptr || blendDefNode->type != NT_BlendDef)
  520. return;
  521. for (int i = 0; i < blendDefNode->options->count; i++)
  522. {
  523. NodeOption* option = &blendDefNode->options->entries[i];
  524. switch (option->type)
  525. {
  526. case OT_Source:
  527. desc.srcBlend = parseBlendFactor((OpValue)option->value.intValue);
  528. break;
  529. case OT_Dest:
  530. desc.dstBlend = parseBlendFactor((OpValue)option->value.intValue);
  531. break;
  532. case OT_Op:
  533. desc.blendOp = parseBlendOp((BlendOpValue)option->value.intValue);
  534. break;
  535. }
  536. }
  537. }
  538. void BSLFXCompiler::parseAlphaBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode)
  539. {
  540. if (blendDefNode == nullptr || blendDefNode->type != NT_BlendDef)
  541. return;
  542. for (int i = 0; i < blendDefNode->options->count; i++)
  543. {
  544. NodeOption* option = &blendDefNode->options->entries[i];
  545. switch (option->type)
  546. {
  547. case OT_Source:
  548. desc.srcBlendAlpha = parseBlendFactor((OpValue)option->value.intValue);
  549. break;
  550. case OT_Dest:
  551. desc.dstBlendAlpha = parseBlendFactor((OpValue)option->value.intValue);
  552. break;
  553. case OT_Op:
  554. desc.blendOpAlpha = parseBlendOp((BlendOpValue)option->value.intValue);
  555. break;
  556. }
  557. }
  558. }
  559. void BSLFXCompiler::parseRenderTargetBlendState(BLEND_STATE_DESC& desc, ASTFXNode* targetNode)
  560. {
  561. if (targetNode == nullptr || targetNode->type != NT_Target)
  562. return;
  563. UINT32 index = 0;
  564. for (int i = 0; i < targetNode->options->count; i++)
  565. {
  566. NodeOption* option = &targetNode->options->entries[i];
  567. switch (option->type)
  568. {
  569. case OT_Index:
  570. index = option->value.intValue;
  571. break;
  572. }
  573. }
  574. if (index >= BS_MAX_MULTIPLE_RENDER_TARGETS)
  575. return;
  576. RENDER_TARGET_BLEND_STATE_DESC& rtDesc = desc.renderTargetDesc[index];
  577. for (int i = 0; i < targetNode->options->count; i++)
  578. {
  579. NodeOption* option = &targetNode->options->entries[i];
  580. switch (option->type)
  581. {
  582. case OT_Blend:
  583. rtDesc.blendEnable = option->value.intValue > 0;
  584. break;
  585. case OT_Color:
  586. parseColorBlendDef(rtDesc, option->value.nodePtr);
  587. break;
  588. case OT_Alpha:
  589. parseAlphaBlendDef(rtDesc, option->value.nodePtr);
  590. break;
  591. case OT_WriteMask:
  592. rtDesc.renderTargetWriteMask = option->value.intValue;
  593. break;
  594. }
  595. }
  596. }
  597. bool BSLFXCompiler::parseBlendState(BLEND_STATE_DESC& desc, ASTFXNode* passNode)
  598. {
  599. if (passNode == nullptr || (passNode->type != NT_Pass && passNode->type != NT_Technique))
  600. return false;
  601. bool default = true;
  602. for (int i = 0; i < passNode->options->count; i++)
  603. {
  604. NodeOption* option = &passNode->options->entries[i];
  605. switch (option->type)
  606. {
  607. case OT_AlphaToCoverage:
  608. desc.alphaToCoverageEnable = option->value.intValue > 0;
  609. default = false;
  610. break;
  611. case OT_IndependantBlend:
  612. desc.independantBlendEnable = option->value.intValue > 0;
  613. default = false;
  614. break;
  615. case OT_Target:
  616. parseRenderTargetBlendState(desc, option->value.nodePtr);
  617. default = false;
  618. break;
  619. }
  620. }
  621. return !default;
  622. }
  623. bool BSLFXCompiler::parseRasterizerState(RASTERIZER_STATE_DESC& desc, ASTFXNode* passNode)
  624. {
  625. if (passNode == nullptr || (passNode->type != NT_Pass && passNode->type != NT_Technique))
  626. return false;
  627. bool default = true;
  628. for (int i = 0; i < passNode->options->count; i++)
  629. {
  630. NodeOption* option = &passNode->options->entries[i];
  631. switch (option->type)
  632. {
  633. case OT_FillMode:
  634. desc.polygonMode = parseFillMode((FillModeValue)option->value.intValue);
  635. default = false;
  636. break;
  637. case OT_CullMode:
  638. desc.cullMode = parseCullMode((CullModeValue)option->value.intValue);
  639. default = false;
  640. break;
  641. case OT_DepthBias:
  642. desc.depthBias = option->value.floatValue;
  643. default = false;
  644. break;
  645. case OT_SDepthBias:
  646. desc.slopeScaledDepthBias = option->value.floatValue;
  647. default = false;
  648. break;
  649. case OT_DepthClip:
  650. desc.depthClipEnable = option->value.intValue > 0;
  651. default = false;
  652. break;
  653. case OT_Scissor:
  654. desc.scissorEnable = option->value.intValue > 0;
  655. default = false;
  656. break;
  657. case OT_Multisample:
  658. desc.multisampleEnable = option->value.intValue > 0;
  659. default = false;
  660. break;
  661. case OT_AALine:
  662. desc.antialiasedLineEnable = option->value.intValue > 0;
  663. default = false;
  664. break;
  665. }
  666. }
  667. return !default;
  668. }
  669. bool BSLFXCompiler::parseDepthStencilState(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* passNode)
  670. {
  671. if (passNode == nullptr || (passNode->type != NT_Pass && passNode->type != NT_Technique))
  672. return false;
  673. bool default = true;
  674. for (int i = 0; i < passNode->options->count; i++)
  675. {
  676. NodeOption* option = &passNode->options->entries[i];
  677. switch (option->type)
  678. {
  679. case OT_DepthRead:
  680. desc.depthReadEnable = option->value.intValue > 0;
  681. default = false;
  682. break;
  683. case OT_DepthWrite:
  684. desc.depthWriteEnable = option->value.intValue > 0;
  685. default = false;
  686. break;
  687. case OT_CompareFunc:
  688. desc.depthComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  689. default = false;
  690. break;
  691. case OT_Stencil:
  692. desc.stencilEnable = option->value.intValue > 0;
  693. default = false;
  694. break;
  695. case OT_StencilReadMask:
  696. desc.stencilReadMask = (UINT8)option->value.intValue;
  697. default = false;
  698. break;
  699. case OT_StencilWriteMask:
  700. desc.stencilWriteMask = (UINT8)option->value.intValue;
  701. default = false;
  702. break;
  703. case OT_StencilOpFront:
  704. parseStencilFront(desc, option->value.nodePtr);
  705. default = false;
  706. break;
  707. case OT_StencilOpBack:
  708. parseStencilBack(desc, option->value.nodePtr);
  709. default = false;
  710. break;
  711. }
  712. }
  713. return !default;
  714. }
  715. SamplerStatePtr BSLFXCompiler::parseSamplerState(ASTFXNode* samplerStateNode)
  716. {
  717. if (samplerStateNode == nullptr || samplerStateNode->type != NT_SamplerState)
  718. return nullptr;
  719. SAMPLER_STATE_DESC desc;
  720. bool default = true;
  721. for (int i = 0; i < samplerStateNode->options->count; i++)
  722. {
  723. NodeOption* option = &samplerStateNode->options->entries[i];
  724. switch (option->type)
  725. {
  726. case OT_AddrMode:
  727. parseAddrMode(desc, option->value.nodePtr);
  728. default = false;
  729. break;
  730. case OT_MinFilter:
  731. desc.minFilter = (FilterOptions)parseFilterMode((FilterValue)option->value.intValue);
  732. default = false;
  733. break;
  734. case OT_MagFilter:
  735. desc.magFilter = (FilterOptions)parseFilterMode((FilterValue)option->value.intValue);
  736. default = false;
  737. break;
  738. case OT_MipFilter:
  739. desc.mipFilter = (FilterOptions)parseFilterMode((FilterValue)option->value.intValue);
  740. default = false;
  741. break;
  742. case OT_MaxAniso:
  743. desc.maxAniso = option->value.intValue;
  744. default = false;
  745. break;
  746. case OT_MipBias:
  747. desc.mipmapBias = option->value.floatValue;
  748. default = false;
  749. break;
  750. case OT_MipMin:
  751. desc.mipMin = option->value.floatValue;
  752. default = false;
  753. break;
  754. case OT_MipMax:
  755. desc.mipMax = option->value.floatValue;
  756. default = false;
  757. break;
  758. case OT_BorderColor:
  759. desc.borderColor = Color(option->value.matrixValue[0], option->value.matrixValue[1],
  760. option->value.matrixValue[2], option->value.matrixValue[3]);
  761. default = false;
  762. break;
  763. case OT_CompareFunc:
  764. desc.comparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  765. default = false;
  766. break;
  767. }
  768. }
  769. if (default)
  770. return nullptr;
  771. return SamplerState::create(desc);
  772. }
  773. void BSLFXCompiler::parseCodeBlock(ASTFXNode* codeNode, const Vector<CodeBlock>& codeBlocks, PassData& passData)
  774. {
  775. if (codeNode == nullptr || codeNode->type != NT_Code)
  776. return;
  777. UINT32 index = (UINT32)-1;
  778. for (int j = 0; j < codeNode->options->count; j++)
  779. {
  780. if (codeNode->options->entries[j].type == OT_Index)
  781. index = codeNode->options->entries[j].value.intValue;
  782. }
  783. if (index != (UINT32)-1 && index < (UINT32)codeBlocks.size())
  784. {
  785. const CodeBlock& codeBlock = codeBlocks[index];
  786. switch (codeBlock.type)
  787. {
  788. case CodeBlockType::Vertex:
  789. passData.vertexCode += codeBlock.code;
  790. break;
  791. case CodeBlockType::Fragment:
  792. passData.fragmentCode += codeBlock.code;
  793. break;
  794. case CodeBlockType::Geometry:
  795. passData.geometryCode += codeBlock.code;
  796. break;
  797. case CodeBlockType::Hull:
  798. passData.hullCode += codeBlock.code;
  799. break;
  800. case CodeBlockType::Domain:
  801. passData.domainCode += codeBlock.code;
  802. break;
  803. case CodeBlockType::Compute:
  804. passData.computeCode += codeBlock.code;
  805. break;
  806. case CodeBlockType::Common:
  807. passData.commonCode += codeBlock.code;
  808. break;
  809. }
  810. }
  811. }
  812. void BSLFXCompiler::parsePass(ASTFXNode* passNode, const Vector<CodeBlock>& codeBlocks, PassData& passData)
  813. {
  814. if (passNode == nullptr || passNode->type != NT_Pass)
  815. return;
  816. passData.blendIsDefault &= !parseBlendState(passData.blendDesc, passNode);
  817. passData.rasterizerIsDefault &= !parseRasterizerState(passData.rasterizerDesc, passNode);
  818. passData.depthStencilIsDefault &= !parseDepthStencilState(passData.depthStencilDesc, passNode);
  819. for (int i = 0; i < passNode->options->count; i++)
  820. {
  821. NodeOption* option = &passNode->options->entries[i];
  822. switch (option->type)
  823. {
  824. case OT_StencilRef:
  825. passData.stencilRefValue = option->value.intValue;
  826. break;
  827. case OT_Code:
  828. parseCodeBlock(option->value.nodePtr, codeBlocks, passData);
  829. break;
  830. }
  831. }
  832. }
  833. void BSLFXCompiler::parseTechnique(ASTFXNode* techniqueNode, const Vector<CodeBlock>& codeBlocks, TechniqueData& techniqueData)
  834. {
  835. if (techniqueNode == nullptr || techniqueNode->type != NT_Technique)
  836. return;
  837. PassData commonPassData;
  838. UINT32 nextPassIdx = 0;
  839. for (int i = 0; i < techniqueNode->options->count; i++)
  840. {
  841. NodeOption* option = &techniqueNode->options->entries[i];
  842. switch (option->type)
  843. {
  844. case OT_Pass:
  845. {
  846. UINT32 passIdx = nextPassIdx;
  847. ASTFXNode* passNode = option->value.nodePtr;
  848. for (int j = 0; j < passNode->options->count; j++)
  849. {
  850. NodeOption* passOption = &passNode->options->entries[j];
  851. switch (passOption->type)
  852. {
  853. case OT_Index:
  854. passIdx = passOption->value.intValue;
  855. break;
  856. }
  857. }
  858. PassData* passData = nullptr;
  859. for (auto& entry : techniqueData.passes)
  860. {
  861. if (entry.seqIdx == passIdx)
  862. passData = &entry;
  863. }
  864. if (passData == nullptr)
  865. {
  866. techniqueData.passes.push_back(PassData());
  867. passData = &techniqueData.passes.back();
  868. passData->seqIdx = passIdx;
  869. }
  870. nextPassIdx = std::max(nextPassIdx, passIdx) + 1;
  871. passData->blendIsDefault &= !parseBlendState(passData->blendDesc, techniqueNode);
  872. passData->rasterizerIsDefault &= !parseRasterizerState(passData->rasterizerDesc, techniqueNode);
  873. passData->depthStencilIsDefault &= !parseDepthStencilState(passData->depthStencilDesc, techniqueNode);
  874. passData->vertexCode = commonPassData.vertexCode + passData->vertexCode;
  875. passData->fragmentCode = commonPassData.fragmentCode + passData->fragmentCode;
  876. passData->geometryCode = commonPassData.geometryCode + passData->geometryCode;
  877. passData->hullCode = commonPassData.hullCode + passData->hullCode;
  878. passData->domainCode = commonPassData.domainCode + passData->domainCode;
  879. passData->commonCode = commonPassData.commonCode + passData->commonCode;
  880. parsePass(passNode, codeBlocks, *passData);
  881. }
  882. break;
  883. case OT_Renderer:
  884. techniqueData.renderer = parseRenderer(removeQuotes(option->value.strValue));
  885. break;
  886. case OT_Language:
  887. parseLanguage(removeQuotes(option->value.strValue), techniqueData.renderAPI, techniqueData.language);
  888. break;
  889. case OT_Code:
  890. parseCodeBlock(option->value.nodePtr, codeBlocks, commonPassData);
  891. break;
  892. }
  893. }
  894. }
  895. void BSLFXCompiler::parseParameters(SHADER_DESC& desc, ASTFXNode* parametersNode)
  896. {
  897. if (parametersNode == nullptr || parametersNode->type != NT_Parameters)
  898. return;
  899. for (int i = 0; i < parametersNode->options->count; i++)
  900. {
  901. NodeOption* option = &parametersNode->options->entries[i];
  902. if (option->type != OT_Parameter)
  903. continue;
  904. ASTFXNode* parameter = option->value.nodePtr;
  905. String name;
  906. String alias;
  907. UINT32 typeId = 0;
  908. bool isObjType = false;
  909. StringID semantic;
  910. SamplerStatePtr samplerState = nullptr;
  911. float defaultValue[16];
  912. HTexture defaultTexture;
  913. bool hasDefaultValue = false;
  914. for (int j = 0; j < parameter->options->count; j++)
  915. {
  916. NodeOption* paramOption = &parameter->options->entries[j];
  917. switch (paramOption->type)
  918. {
  919. case OT_Identifier:
  920. name = paramOption->value.strValue;
  921. break;
  922. case OT_Alias:
  923. alias = removeQuotes(paramOption->value.strValue);
  924. break;
  925. case OT_ParamType:
  926. parseParamType((ParamType)paramOption->value.intValue, isObjType, typeId);
  927. break;
  928. case OT_ParamValue:
  929. memcpy(defaultValue, paramOption->value.matrixValue, sizeof(defaultValue));
  930. hasDefaultValue = true;
  931. break;
  932. case OT_ParamStrValue:
  933. {
  934. String defaultTextureName = removeQuotes(paramOption->value.strValue);
  935. defaultTexture = getBuiltinTexture(defaultTextureName);
  936. hasDefaultValue = true;
  937. }
  938. break;
  939. case OT_Auto:
  940. semantic = removeQuotes(paramOption->value.strValue);
  941. break;
  942. case OT_SamplerState:
  943. samplerState = parseSamplerState(paramOption->value.nodePtr);
  944. break;
  945. }
  946. }
  947. if (name.empty())
  948. continue;
  949. auto addParameter = [&](const String& paramName, const String& gpuVarName)
  950. {
  951. if (isObjType)
  952. {
  953. GpuParamObjectType objType = (GpuParamObjectType)typeId;
  954. if (Shader::isSampler(objType))
  955. {
  956. if(hasDefaultValue)
  957. desc.addParameter(paramName, gpuVarName, objType, samplerState, semantic);
  958. else
  959. desc.addParameter(paramName, gpuVarName, objType, semantic);
  960. }
  961. else if(Shader::isTexture(objType))
  962. {
  963. if(hasDefaultValue)
  964. desc.addParameter(paramName, gpuVarName, objType, defaultTexture, semantic);
  965. else
  966. desc.addParameter(paramName, gpuVarName, objType, semantic);
  967. }
  968. else
  969. desc.addParameter(paramName, gpuVarName, objType, semantic);
  970. }
  971. else
  972. {
  973. if (hasDefaultValue)
  974. desc.addParameter(paramName, gpuVarName, (GpuParamDataType)typeId, semantic, 1, 0, (UINT8*)defaultValue);
  975. else
  976. desc.addParameter(paramName, gpuVarName, (GpuParamDataType)typeId, semantic);
  977. }
  978. };
  979. addParameter(name, name);
  980. if (!alias.empty())
  981. addParameter(name, alias);
  982. }
  983. }
  984. void BSLFXCompiler::parseBlocks(SHADER_DESC& desc, ASTFXNode* blocksNode)
  985. {
  986. if (blocksNode == nullptr || blocksNode->type != NT_Blocks)
  987. return;
  988. for (int i = 0; i < blocksNode->options->count; i++)
  989. {
  990. NodeOption* option = &blocksNode->options->entries[i];
  991. if (option->type != OT_Block)
  992. continue;
  993. ASTFXNode* parameter = option->value.nodePtr;
  994. String name;
  995. bool shared = false;
  996. GpuParamBlockUsage usage = GPBU_STATIC;
  997. StringID semantic;
  998. for (int j = 0; j < parameter->options->count; j++)
  999. {
  1000. NodeOption* paramOption = &parameter->options->entries[j];
  1001. switch (paramOption->type)
  1002. {
  1003. case OT_Identifier:
  1004. name = paramOption->value.strValue;
  1005. break;
  1006. case OT_Shared:
  1007. shared = paramOption->value.intValue > 0;
  1008. break;
  1009. case OT_Usage:
  1010. usage = parseBlockUsage((BufferUsageValue)paramOption->value.intValue);
  1011. break;
  1012. case OT_Auto:
  1013. semantic = removeQuotes(paramOption->value.strValue);
  1014. break;
  1015. }
  1016. }
  1017. if (name.empty())
  1018. continue;
  1019. desc.setParamBlockAttribs(name, shared, usage, semantic);
  1020. }
  1021. }
  1022. BSLFXCompileResult BSLFXCompiler::parseShader(const String& name, ParseState* parseState, Vector<CodeBlock>& codeBlocks)
  1023. {
  1024. BSLFXCompileResult output;
  1025. if (parseState->rootNode == nullptr || parseState->rootNode->type != NT_Shader)
  1026. {
  1027. output.errorMessage = "Root not is null or not a shader.";
  1028. return output;
  1029. }
  1030. SHADER_DESC shaderDesc;
  1031. Vector<pair<ASTFXNode*, TechniqueData>> techniqueData;
  1032. for (int i = 0; i < parseState->rootNode->options->count; i++)
  1033. {
  1034. NodeOption* option = &parseState->rootNode->options->entries[i];
  1035. switch (option->type)
  1036. {
  1037. case OT_Separable:
  1038. shaderDesc.separablePasses = option->value.intValue > 1;
  1039. break;
  1040. case OT_Queue:
  1041. shaderDesc.queuePriority = option->value.intValue;
  1042. break;
  1043. case OT_Priority:
  1044. shaderDesc.queuePriority = option->value.intValue;
  1045. break;
  1046. case OT_Transparent:
  1047. shaderDesc.flags |= (UINT32)ShaderFlags::Transparent;
  1048. break;
  1049. case OT_Technique:
  1050. {
  1051. auto iterFind = std::find_if(techniqueData.begin(), techniqueData.end(),
  1052. [&] (auto x)
  1053. {
  1054. return doTechniquesMatch(x.first, option->value.nodePtr);
  1055. });
  1056. TechniqueData* data = nullptr;
  1057. if (iterFind != techniqueData.end())
  1058. data = &iterFind->second;
  1059. else
  1060. {
  1061. techniqueData.push_back(std::make_pair(option->value.nodePtr, TechniqueData()));
  1062. data = &techniqueData.back().second;
  1063. }
  1064. parseTechnique(option->value.nodePtr, codeBlocks, *data);
  1065. break;
  1066. }
  1067. case OT_Parameters:
  1068. parseParameters(shaderDesc, option->value.nodePtr);
  1069. break;
  1070. case OT_Blocks:
  1071. parseBlocks(shaderDesc, option->value.nodePtr);
  1072. break;
  1073. }
  1074. }
  1075. Vector<TechniquePtr> techniques;
  1076. for(auto& entry : techniqueData)
  1077. {
  1078. const TechniqueData& techniqueData = entry.second;
  1079. Map<UINT32, PassPtr, std::greater<UINT32>> passes;
  1080. for (auto& passData : entry.second.passes)
  1081. {
  1082. PASS_DESC passDesc;
  1083. if (!passData.blendIsDefault)
  1084. passDesc.blendState = BlendState::create(passData.blendDesc);
  1085. if (!passData.rasterizerIsDefault)
  1086. passDesc.rasterizerState = RasterizerState::create(passData.rasterizerDesc);
  1087. if (!passData.depthStencilIsDefault)
  1088. passDesc.depthStencilState = DepthStencilState::create(passData.depthStencilDesc);
  1089. if (!passData.vertexCode.empty())
  1090. {
  1091. passDesc.vertexProgram = GpuProgram::create(passData.commonCode + passData.vertexCode, "main",
  1092. techniqueData.language, GPT_VERTEX_PROGRAM, getProfile(techniqueData.renderAPI, GPT_VERTEX_PROGRAM));
  1093. }
  1094. if (!passData.fragmentCode.empty())
  1095. {
  1096. passDesc.fragmentProgram = GpuProgram::create(passData.commonCode + passData.fragmentCode, "main",
  1097. techniqueData.language, GPT_FRAGMENT_PROGRAM, getProfile(techniqueData.renderAPI, GPT_FRAGMENT_PROGRAM));
  1098. }
  1099. if (!passData.geometryCode.empty())
  1100. {
  1101. passDesc.geometryProgram = GpuProgram::create(passData.commonCode + passData.geometryCode, "main",
  1102. techniqueData.language, GPT_GEOMETRY_PROGRAM, getProfile(techniqueData.renderAPI, GPT_GEOMETRY_PROGRAM));
  1103. }
  1104. if (!passData.hullCode.empty())
  1105. {
  1106. passDesc.hullProgram = GpuProgram::create(passData.commonCode + passData.hullCode, "main",
  1107. techniqueData.language, GPT_HULL_PROGRAM, getProfile(techniqueData.renderAPI, GPT_HULL_PROGRAM));
  1108. }
  1109. if (!passData.domainCode.empty())
  1110. {
  1111. passDesc.domainProgram = GpuProgram::create(passData.commonCode + passData.domainCode, "main",
  1112. techniqueData.language, GPT_DOMAIN_PROGRAM, getProfile(techniqueData.renderAPI, GPT_DOMAIN_PROGRAM));
  1113. }
  1114. if (!passData.computeCode.empty())
  1115. {
  1116. passDesc.computeProgram = GpuProgram::create(passData.commonCode + passData.computeCode, "main",
  1117. techniqueData.language, GPT_COMPUTE_PROGRAM, getProfile(techniqueData.renderAPI, GPT_COMPUTE_PROGRAM));
  1118. }
  1119. PassPtr pass = Pass::create(passDesc);
  1120. if (pass != nullptr)
  1121. passes[passData.seqIdx] = pass;
  1122. }
  1123. Vector<PassPtr> orderedPasses;
  1124. for (auto& KVP : passes)
  1125. orderedPasses.push_back(KVP.second);
  1126. if (orderedPasses.size() > 0)
  1127. {
  1128. TechniquePtr technique = Technique::create(techniqueData.renderAPI, techniqueData.renderer, orderedPasses);
  1129. techniques.push_back(technique);
  1130. }
  1131. }
  1132. Vector<String> includes;
  1133. IncludeLink* includeLink = parseState->includes;
  1134. while(includeLink != nullptr)
  1135. {
  1136. String includeFilename = includeLink->data->filename;
  1137. auto iterFind = std::find(includes.begin(), includes.end(), includeFilename);
  1138. if (iterFind == includes.end())
  1139. includes.push_back(includeFilename);
  1140. includeLink = includeLink->next;
  1141. }
  1142. parseStateDelete(parseState);
  1143. output.shader = Shader::_createPtr(name, shaderDesc, techniques);
  1144. output.shader->setIncludeFiles(includes);
  1145. return output;
  1146. }
  1147. String BSLFXCompiler::removeQuotes(const char* input)
  1148. {
  1149. UINT32 len = (UINT32)strlen(input);
  1150. String output(len - 2, ' ');
  1151. for (UINT32 i = 0; i < (len - 2); i++)
  1152. output[i] = input[i + 1];
  1153. return output;
  1154. }
  1155. GpuProgramProfile BSLFXCompiler::getProfile(const StringID& renderAPI, GpuProgramType type)
  1156. {
  1157. StringID target = renderAPI;
  1158. if (target == RenderAPIAny)
  1159. target = RenderAPICore::instance().getName();
  1160. if (target == RenderAPIDX11 || target == RenderAPIOpenGL)
  1161. {
  1162. switch (type)
  1163. {
  1164. case GPT_VERTEX_PROGRAM:
  1165. return GPP_VS_5_0;
  1166. case GPT_FRAGMENT_PROGRAM:
  1167. return GPP_FS_5_0;
  1168. case GPT_GEOMETRY_PROGRAM:
  1169. return GPP_GS_5_0;
  1170. case GPT_HULL_PROGRAM:
  1171. return GPP_HS_5_0;
  1172. case GPT_DOMAIN_PROGRAM:
  1173. return GPP_DS_5_0;
  1174. case GPT_COMPUTE_PROGRAM:
  1175. return GPP_CS_5_0;
  1176. }
  1177. }
  1178. else if (target == RenderAPIDX9)
  1179. {
  1180. switch (type)
  1181. {
  1182. case GPT_VERTEX_PROGRAM:
  1183. return GPP_VS_3_0;
  1184. case GPT_FRAGMENT_PROGRAM:
  1185. return GPP_FS_3_0;
  1186. }
  1187. }
  1188. return GPP_NONE;
  1189. }
  1190. HTexture BSLFXCompiler::getBuiltinTexture(const String& name)
  1191. {
  1192. if (StringUtil::compare(name, String("white"), false) == 0)
  1193. return BuiltinResources::getTexture(BuiltinTexture::White);
  1194. else if (StringUtil::compare(name, String("black"), false) == 0)
  1195. return BuiltinResources::getTexture(BuiltinTexture::Black);
  1196. else if (StringUtil::compare(name, String("normal"), false) == 0)
  1197. return BuiltinResources::getTexture(BuiltinTexture::Normal);
  1198. return HTexture();
  1199. }
  1200. }