BsSLFXCompiler.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466
  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. #define XSC_ENABLE_LANGUAGE_EXT 1
  17. #include "Xsc/Xsc.h"
  18. //DEBUG ONLY
  19. #include "BsFileSystem.h"
  20. #include "BsDataStream.h"
  21. extern "C" {
  22. #include "BsMMAlloc.h"
  23. #include "BsParserFX.h"
  24. #include "BsLexerFX.h"
  25. }
  26. using namespace std;
  27. namespace bs
  28. {
  29. // Print out the FX AST, only for debug purposes
  30. void SLFXDebugPrint(ASTFXNode* node, String indent)
  31. {
  32. LOGDBG(indent + "NODE " + toString(node->type));
  33. for (int i = 0; i < node->options->count; i++)
  34. {
  35. OptionDataType odt = OPTION_LOOKUP[(int)node->options->entries[i].type].dataType;
  36. if (odt == ODT_Complex)
  37. {
  38. LOGDBG(indent + toString(i) + ". " + toString(node->options->entries[i].type));
  39. SLFXDebugPrint(node->options->entries[i].value.nodePtr, indent + "\t");
  40. continue;
  41. }
  42. String value;
  43. switch (odt)
  44. {
  45. case ODT_Bool:
  46. value = toString(node->options->entries[i].value.intValue != 0);
  47. break;
  48. case ODT_Int:
  49. value = toString(node->options->entries[i].value.intValue);
  50. break;
  51. case ODT_Float:
  52. value = toString(node->options->entries[i].value.floatValue);
  53. break;
  54. case ODT_String:
  55. value = node->options->entries[i].value.strValue;
  56. break;
  57. case ODT_Matrix:
  58. {
  59. Matrix4 mat4 = *(Matrix4*)(node->options->entries[i].value.matrixValue);
  60. value = toString(mat4);
  61. }
  62. break;
  63. default:
  64. break;
  65. }
  66. LOGDBG(indent + toString(i) + ". " + toString(node->options->entries[i].type) + " = " + value);
  67. }
  68. }
  69. class XscLog : public Xsc::Log
  70. {
  71. public:
  72. void SumitReport(const Xsc::Report& report) override
  73. {
  74. switch (report.Type())
  75. {
  76. case Xsc::ReportTypes::Info:
  77. mInfos.push_back({ FullIndent(), report });
  78. break;
  79. case Xsc::ReportTypes::Warning:
  80. mWarnings.push_back({ FullIndent(), report });
  81. break;
  82. case Xsc::ReportTypes::Error:
  83. mErrors.push_back({ FullIndent(), report });
  84. break;
  85. }
  86. }
  87. void getMessages(StringStream& output)
  88. {
  89. printAndClearReports(output, mInfos);
  90. printAndClearReports(output, mWarnings, (mWarnings.size() == 1 ? "WARNING" : "WARNINGS"));
  91. printAndClearReports(output, mErrors, (mErrors.size() == 1 ? "ERROR" : "ERRORS"));
  92. }
  93. private:
  94. struct IndentReport
  95. {
  96. std::string indent;
  97. Xsc::Report report;
  98. };
  99. static void printMultiLineString(StringStream& output, const std::string& str, const std::string& indent)
  100. {
  101. // Determine at which position the actual text begins (excluding the "error (X:Y) : " or the like)
  102. auto textStartPos = str.find(" : ");
  103. if (textStartPos != std::string::npos)
  104. textStartPos += 3;
  105. else
  106. textStartPos = 0;
  107. std::string newLineIndent(textStartPos, ' ');
  108. size_t start = 0;
  109. bool useNewLineIndent = false;
  110. while (start < str.size())
  111. {
  112. output << indent;
  113. if (useNewLineIndent)
  114. output << newLineIndent;
  115. // Print next line
  116. auto end = str.find('\n', start);
  117. if (end != std::string::npos)
  118. {
  119. output << str.substr(start, end - start);
  120. start = end + 1;
  121. }
  122. else
  123. {
  124. output << str.substr(start);
  125. start = end;
  126. }
  127. output << std::endl;
  128. useNewLineIndent = true;
  129. }
  130. }
  131. void printReport(StringStream& output, const IndentReport& r)
  132. {
  133. // Print optional context description
  134. if (!r.report.Context().empty())
  135. printMultiLineString(output, r.report.Context(), r.indent);
  136. // Print report message
  137. const auto& msg = r.report.Message();
  138. printMultiLineString(output, msg, r.indent);
  139. // Print optional line and line-marker
  140. if (r.report.HasLine())
  141. {
  142. const auto& line = r.report.Line();
  143. const auto& marker = r.report.Marker();
  144. // Print line
  145. output << r.indent << line << std::endl;
  146. // Print line marker
  147. output << r.indent << marker << std::endl;
  148. }
  149. // Print optional hints
  150. for (const auto& hint : r.report.GetHints())
  151. output << r.indent << hint << std::endl;
  152. }
  153. void printAndClearReports(StringStream& output, Vector<IndentReport>& reports, const String& headline = "")
  154. {
  155. if (!reports.empty())
  156. {
  157. if (!headline.empty())
  158. {
  159. String s = toString(reports.size()) + " " + headline;
  160. output << s << std::endl;
  161. output << String(s.size(), '-') << std::endl;
  162. }
  163. for (const auto& r : reports)
  164. printReport(output, r);
  165. reports.clear();
  166. }
  167. }
  168. Vector<IndentReport> mInfos;
  169. Vector<IndentReport> mWarnings;
  170. Vector<IndentReport> mErrors;
  171. };
  172. // Convert HLSL code to GLSL
  173. String HLSLtoGLSL(const String& hlsl, GpuProgramType type, bool vulkan, UINT32& startBindingSlot)
  174. {
  175. SPtr<StringStream> input = bs_shared_ptr_new<StringStream>();
  176. if (vulkan)
  177. *input << "#define VULKAN 1" << std::endl;
  178. else
  179. *input << "#define OPENGL 1" << std::endl;
  180. *input << hlsl;
  181. Xsc::ShaderInput inputDesc;
  182. inputDesc.entryPoint = "main";
  183. inputDesc.shaderVersion = Xsc::InputShaderVersion::HLSL5;
  184. inputDesc.sourceCode = input;
  185. inputDesc.extensions = Xsc::Extensions::LayoutAttribute;
  186. switch (type)
  187. {
  188. case GPT_VERTEX_PROGRAM:
  189. inputDesc.shaderTarget = Xsc::ShaderTarget::VertexShader;
  190. break;
  191. case GPT_GEOMETRY_PROGRAM:
  192. inputDesc.shaderTarget = Xsc::ShaderTarget::GeometryShader;
  193. break;
  194. case GPT_HULL_PROGRAM:
  195. inputDesc.shaderTarget = Xsc::ShaderTarget::TessellationControlShader;
  196. break;
  197. case GPT_DOMAIN_PROGRAM:
  198. inputDesc.shaderTarget = Xsc::ShaderTarget::TessellationEvaluationShader;
  199. break;
  200. case GPT_FRAGMENT_PROGRAM:
  201. inputDesc.shaderTarget = Xsc::ShaderTarget::FragmentShader;
  202. break;
  203. case GPT_COMPUTE_PROGRAM:
  204. inputDesc.shaderTarget = Xsc::ShaderTarget::ComputeShader;
  205. break;
  206. }
  207. StringStream output;
  208. Xsc::ShaderOutput outputDesc;
  209. outputDesc.sourceCode = &output;
  210. outputDesc.options.autoBinding = vulkan;
  211. outputDesc.options.autoBindingStartSlot = startBindingSlot;
  212. outputDesc.options.separateShaders = true;
  213. outputDesc.options.separateSamplers = false;
  214. outputDesc.nameMangling.inputPrefix = "bs_";
  215. outputDesc.nameMangling.useAlwaysSemantics = true;
  216. outputDesc.nameMangling.renameBufferFields = true;
  217. if (vulkan)
  218. outputDesc.shaderVersion = Xsc::OutputShaderVersion::VKSL450;
  219. else
  220. outputDesc.shaderVersion = Xsc::OutputShaderVersion::GLSL450;
  221. XscLog log;
  222. Xsc::Reflection::ReflectionData reflectionData;
  223. if (!Xsc::CompileShader(inputDesc, outputDesc, &log, &reflectionData))
  224. {
  225. StringStream logOutput;
  226. log.getMessages(logOutput);
  227. LOGERR("Shader cross compilation failed. Log: \n\n" + logOutput.str());
  228. return "";
  229. }
  230. for (auto& entry : reflectionData.constantBuffers)
  231. startBindingSlot = std::max(startBindingSlot, entry.location + 1u);
  232. for (auto& entry : reflectionData.textures)
  233. startBindingSlot = std::max(startBindingSlot, entry.location + 1u);
  234. for (auto& entry : reflectionData.storageBuffers)
  235. startBindingSlot = std::max(startBindingSlot, entry.location + 1u);
  236. return output.str();
  237. }
  238. /* Remove non-standard HLSL attributes. */
  239. void cleanNonStandardHLSL(GPU_PROGRAM_DESC& progDesc)
  240. {
  241. static std::regex regex("\\[.*layout.*\\(.*\\).*\\]");
  242. if (progDesc.language != "hlsl")
  243. return;
  244. progDesc.source = regex_replace(progDesc.source, regex, "");
  245. }
  246. BSLFXCompileResult BSLFXCompiler::compile(const String& name, const String& source,
  247. const UnorderedMap<String, String>& defines)
  248. {
  249. BSLFXCompileResult output;
  250. String parsedSource = source;
  251. ParseState* parseState = parseStateCreate();
  252. for(auto& define : defines)
  253. {
  254. if (define.first.size() == 0)
  255. continue;
  256. addDefine(parseState, define.first.c_str());
  257. if(define.second.size() > 0)
  258. addDefineExpr(parseState, define.second.c_str());
  259. }
  260. parseFX(parseState, parsedSource.c_str());
  261. if (parseState->hasError > 0)
  262. {
  263. output.errorMessage = parseState->errorMessage;
  264. output.errorLine = parseState->errorLine;
  265. output.errorColumn = parseState->errorColumn;
  266. if(parseState->errorFile != nullptr)
  267. output.errorFile = parseState->errorFile;
  268. parseStateDelete(parseState);
  269. }
  270. else
  271. {
  272. // Only enable for debug purposes
  273. //SLFXDebugPrint(parseState->rootNode, "");
  274. Vector<String> codeBlocks;
  275. CodeString* codeString = parseState->codeStrings;
  276. while(codeString != nullptr)
  277. {
  278. while ((INT32)codeBlocks.size() <= codeString->index)
  279. codeBlocks.push_back(String());
  280. codeBlocks[codeString->index] = String(codeString->code, codeString->size);
  281. codeString = codeString->next;
  282. }
  283. output = parseShader(name, parseState, codeBlocks);
  284. StringStream gpuProgError;
  285. bool hasError = false;
  286. if (output.shader != nullptr)
  287. {
  288. Vector<SPtr<Technique>> techniques = output.shader->getCompatibleTechniques();
  289. for (auto& technique : techniques)
  290. {
  291. UINT32 numPasses = technique->getNumPasses();
  292. for (UINT32 i = 0; i < numPasses; i++)
  293. {
  294. SPtr<Pass> pass = technique->getPass(i);
  295. auto checkCompileStatus = [&](const String& prefix, const SPtr<GpuProgram>& prog)
  296. {
  297. if (prog != nullptr)
  298. {
  299. prog->blockUntilCoreInitialized();
  300. if (!prog->isCompiled())
  301. {
  302. hasError = true;
  303. gpuProgError << prefix << ": " << prog->getCompileErrorMessage() << std::endl;
  304. }
  305. }
  306. };
  307. checkCompileStatus("Vertex program", pass->getVertexProgram());
  308. checkCompileStatus("Fragment program", pass->getFragmentProgram());
  309. checkCompileStatus("Geometry program", pass->getGeometryProgram());
  310. checkCompileStatus("Hull program", pass->getHullProgram());
  311. checkCompileStatus("Domain program", pass->getDomainProgram());
  312. checkCompileStatus("Compute program", pass->getComputeProgram());
  313. }
  314. }
  315. }
  316. if (hasError)
  317. {
  318. output.errorMessage = "Failed compiling GPU program(s): " + gpuProgError.str();
  319. output.errorLine = 0;
  320. output.errorColumn = 0;
  321. }
  322. }
  323. return output;
  324. }
  325. void BSLFXCompiler::parseFX(ParseState* parseState, const char* source)
  326. {
  327. yyscan_t scanner;
  328. YY_BUFFER_STATE state;
  329. if (yylex_init_extra(parseState, &scanner))
  330. return;
  331. // If debug output from lexer is needed uncomment this and add %debug option to lexer file
  332. //yyset_debug(true, scanner);
  333. // If debug output from parser is needed uncomment this and add %debug option to parser file
  334. //yydebug = true;
  335. state = yy_scan_string(source, scanner);
  336. if (yyparse(parseState, scanner))
  337. return;
  338. yy_delete_buffer(state, scanner);
  339. yylex_destroy(scanner);
  340. }
  341. BSLFXCompiler::TechniqueMetaData BSLFXCompiler::parseTechniqueMetaData(ASTFXNode* technique)
  342. {
  343. TechniqueMetaData metaData;
  344. metaData.renderer = RendererAny;
  345. metaData.language = "hlsl";
  346. for (int i = 0; i < technique->options->count; i++)
  347. {
  348. NodeOption* option = &technique->options->entries[i];
  349. switch (option->type)
  350. {
  351. case OT_Renderer:
  352. metaData.renderer = parseRenderer(removeQuotes(option->value.strValue));
  353. break;
  354. case OT_Tags:
  355. {
  356. ASTFXNode* tagsNode = option->value.nodePtr;
  357. for (int j = 0; j < tagsNode->options->count; j++)
  358. {
  359. NodeOption* tagOption = &tagsNode->options->entries[j];
  360. if (tagOption->type == OT_TagValue)
  361. metaData.tags.push_back(removeQuotes(tagOption->value.strValue));
  362. }
  363. }
  364. break;
  365. case OT_Base:
  366. metaData.baseName = removeQuotes(option->value.strValue);
  367. break;
  368. case OT_Inherits:
  369. metaData.inherits.push_back(removeQuotes(option->value.strValue));
  370. break;
  371. default:
  372. break;
  373. }
  374. }
  375. return metaData;
  376. }
  377. StringID BSLFXCompiler::parseRenderer(const String& name)
  378. {
  379. if (name == "Any")
  380. return RendererAny;
  381. else if (name == "Default")
  382. return RendererDefault;
  383. return RendererAny;
  384. }
  385. QueueSortType BSLFXCompiler::parseSortType(CullAndSortModeValue sortType)
  386. {
  387. switch (sortType)
  388. {
  389. case CASV_BackToFront:
  390. return QueueSortType::BackToFront;
  391. case CASV_FrontToBack:
  392. return QueueSortType::FrontToBack;
  393. case CASV_None:
  394. return QueueSortType::None;
  395. }
  396. return QueueSortType::None;
  397. }
  398. CompareFunction BSLFXCompiler::parseCompFunc(CompFuncValue compFunc)
  399. {
  400. switch (compFunc)
  401. {
  402. case CFV_Pass:
  403. return CMPF_ALWAYS_PASS;
  404. case CFV_Fail:
  405. return CMPF_ALWAYS_FAIL;
  406. case CFV_LT:
  407. return CMPF_LESS;
  408. case CFV_LTE:
  409. return CMPF_LESS_EQUAL;
  410. case CFV_EQ:
  411. return CMPF_EQUAL;
  412. case CFV_NEQ:
  413. return CMPF_NOT_EQUAL;
  414. case CFV_GT:
  415. return CMPF_GREATER;
  416. case CFV_GTE:
  417. return CMPF_GREATER_EQUAL;
  418. }
  419. return CMPF_ALWAYS_PASS;
  420. }
  421. BlendFactor BSLFXCompiler::parseBlendFactor(OpValue factor)
  422. {
  423. switch (factor)
  424. {
  425. case OV_One:
  426. return BF_ONE;
  427. case OV_Zero:
  428. return BF_ZERO;
  429. case OV_DestColor:
  430. return BF_DEST_COLOR;
  431. case OV_SrcColor:
  432. return BF_SOURCE_COLOR;
  433. case OV_InvDestColor:
  434. return BF_INV_DEST_COLOR;
  435. case OV_InvSrcColor:
  436. return BF_INV_SOURCE_COLOR;
  437. case OV_DestAlpha:
  438. return BF_DEST_ALPHA;
  439. case OV_SrcAlpha:
  440. return BF_SOURCE_ALPHA;
  441. case OV_InvDestAlpha:
  442. return BF_INV_DEST_ALPHA;
  443. case OV_InvSrcAlpha:
  444. return BF_INV_SOURCE_ALPHA;
  445. default:
  446. break;
  447. }
  448. return BF_ONE;
  449. }
  450. BlendOperation BSLFXCompiler::parseBlendOp(BlendOpValue op)
  451. {
  452. switch (op)
  453. {
  454. case BOV_Add:
  455. return BO_ADD;
  456. case BOV_Max:
  457. return BO_MAX;
  458. case BOV_Min:
  459. return BO_MIN;
  460. case BOV_Subtract:
  461. return BO_SUBTRACT;
  462. case BOV_RevSubtract:
  463. return BO_REVERSE_SUBTRACT;
  464. }
  465. return BO_ADD;
  466. }
  467. StencilOperation BSLFXCompiler::parseStencilOp(OpValue op)
  468. {
  469. switch (op)
  470. {
  471. case OV_Keep:
  472. return SOP_KEEP;
  473. case OV_Zero:
  474. return SOP_ZERO;
  475. case OV_Replace:
  476. return SOP_REPLACE;
  477. case OV_Incr:
  478. return SOP_INCREMENT;
  479. case OV_Decr:
  480. return SOP_DECREMENT;
  481. case OV_IncrWrap:
  482. return SOP_INCREMENT_WRAP;
  483. case OV_DecrWrap:
  484. return SOP_DECREMENT_WRAP;
  485. case OV_Invert:
  486. return SOP_INVERT;
  487. default:
  488. break;
  489. }
  490. return SOP_KEEP;
  491. }
  492. CullingMode BSLFXCompiler::parseCullMode(CullAndSortModeValue cm)
  493. {
  494. switch (cm)
  495. {
  496. case CASV_None:
  497. return CULL_NONE;
  498. case CASV_CW:
  499. return CULL_CLOCKWISE;
  500. case CASV_CCW:
  501. return CULL_COUNTERCLOCKWISE;
  502. }
  503. return CULL_COUNTERCLOCKWISE;
  504. }
  505. PolygonMode BSLFXCompiler::parseFillMode(FillModeValue fm)
  506. {
  507. if (fm == FMV_Wire)
  508. return PM_WIREFRAME;
  509. return PM_SOLID;
  510. }
  511. void BSLFXCompiler::parseStencilFront(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode)
  512. {
  513. if (stencilOpNode == nullptr || stencilOpNode->type != NT_StencilOp)
  514. return;
  515. for (int i = 0; i < stencilOpNode->options->count; i++)
  516. {
  517. NodeOption* option = &stencilOpNode->options->entries[i];
  518. switch (option->type)
  519. {
  520. case OT_Fail:
  521. desc.frontStencilFailOp = parseStencilOp((OpValue)option->value.intValue);
  522. break;
  523. case OT_ZFail:
  524. desc.frontStencilZFailOp = parseStencilOp((OpValue)option->value.intValue);
  525. break;
  526. case OT_PassOp:
  527. desc.frontStencilPassOp = parseStencilOp((OpValue)option->value.intValue);
  528. break;
  529. case OT_CompareFunc:
  530. desc.frontStencilComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  531. break;
  532. default:
  533. break;
  534. }
  535. }
  536. }
  537. void BSLFXCompiler::parseStencilBack(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode)
  538. {
  539. if (stencilOpNode == nullptr || stencilOpNode->type != NT_StencilOp)
  540. return;
  541. for (int i = 0; i < stencilOpNode->options->count; i++)
  542. {
  543. NodeOption* option = &stencilOpNode->options->entries[i];
  544. switch (option->type)
  545. {
  546. case OT_Fail:
  547. desc.backStencilFailOp = parseStencilOp((OpValue)option->value.intValue);
  548. break;
  549. case OT_ZFail:
  550. desc.backStencilZFailOp = parseStencilOp((OpValue)option->value.intValue);
  551. break;
  552. case OT_PassOp:
  553. desc.backStencilPassOp = parseStencilOp((OpValue)option->value.intValue);
  554. break;
  555. case OT_CompareFunc:
  556. desc.backStencilComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  557. break;
  558. default:
  559. break;
  560. }
  561. }
  562. }
  563. void BSLFXCompiler::parseColorBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode)
  564. {
  565. if (blendDefNode == nullptr || blendDefNode->type != NT_BlendDef)
  566. return;
  567. for (int i = 0; i < blendDefNode->options->count; i++)
  568. {
  569. NodeOption* option = &blendDefNode->options->entries[i];
  570. switch (option->type)
  571. {
  572. case OT_Source:
  573. desc.srcBlend = parseBlendFactor((OpValue)option->value.intValue);
  574. break;
  575. case OT_Dest:
  576. desc.dstBlend = parseBlendFactor((OpValue)option->value.intValue);
  577. break;
  578. case OT_Op:
  579. desc.blendOp = parseBlendOp((BlendOpValue)option->value.intValue);
  580. break;
  581. default:
  582. break;
  583. }
  584. }
  585. }
  586. void BSLFXCompiler::parseAlphaBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode)
  587. {
  588. if (blendDefNode == nullptr || blendDefNode->type != NT_BlendDef)
  589. return;
  590. for (int i = 0; i < blendDefNode->options->count; i++)
  591. {
  592. NodeOption* option = &blendDefNode->options->entries[i];
  593. switch (option->type)
  594. {
  595. case OT_Source:
  596. desc.srcBlendAlpha = parseBlendFactor((OpValue)option->value.intValue);
  597. break;
  598. case OT_Dest:
  599. desc.dstBlendAlpha = parseBlendFactor((OpValue)option->value.intValue);
  600. break;
  601. case OT_Op:
  602. desc.blendOpAlpha = parseBlendOp((BlendOpValue)option->value.intValue);
  603. break;
  604. default:
  605. break;
  606. }
  607. }
  608. }
  609. void BSLFXCompiler::parseRenderTargetBlendState(BLEND_STATE_DESC& desc, ASTFXNode* targetNode)
  610. {
  611. if (targetNode == nullptr || targetNode->type != NT_Target)
  612. return;
  613. UINT32 index = 0;
  614. for (int i = 0; i < targetNode->options->count; i++)
  615. {
  616. NodeOption* option = &targetNode->options->entries[i];
  617. switch (option->type)
  618. {
  619. case OT_Index:
  620. index = option->value.intValue;
  621. break;
  622. default:
  623. break;
  624. }
  625. }
  626. if (index >= BS_MAX_MULTIPLE_RENDER_TARGETS)
  627. return;
  628. RENDER_TARGET_BLEND_STATE_DESC& rtDesc = desc.renderTargetDesc[index];
  629. for (int i = 0; i < targetNode->options->count; i++)
  630. {
  631. NodeOption* option = &targetNode->options->entries[i];
  632. switch (option->type)
  633. {
  634. case OT_Enabled:
  635. rtDesc.blendEnable = option->value.intValue > 0;
  636. break;
  637. case OT_Color:
  638. parseColorBlendDef(rtDesc, option->value.nodePtr);
  639. break;
  640. case OT_Alpha:
  641. parseAlphaBlendDef(rtDesc, option->value.nodePtr);
  642. break;
  643. case OT_WriteMask:
  644. rtDesc.renderTargetWriteMask = option->value.intValue;
  645. break;
  646. default:
  647. break;
  648. }
  649. }
  650. }
  651. bool BSLFXCompiler::parseBlendState(PassData& desc, ASTFXNode* blendNode)
  652. {
  653. if (blendNode == nullptr || blendNode->type != NT_Blend)
  654. return false;
  655. bool isDefault = true;
  656. for (int i = 0; i < blendNode->options->count; i++)
  657. {
  658. NodeOption* option = &blendNode->options->entries[i];
  659. switch (option->type)
  660. {
  661. case OT_AlphaToCoverage:
  662. desc.blendDesc.alphaToCoverageEnable = option->value.intValue > 0;
  663. isDefault = false;
  664. break;
  665. case OT_IndependantBlend:
  666. desc.blendDesc.independantBlendEnable = option->value.intValue > 0;
  667. isDefault = false;
  668. break;
  669. case OT_Target:
  670. parseRenderTargetBlendState(desc.blendDesc, option->value.nodePtr);
  671. isDefault = false;
  672. break;
  673. default:
  674. break;
  675. }
  676. }
  677. return !isDefault;
  678. }
  679. bool BSLFXCompiler::parseRasterizerState(PassData& desc, ASTFXNode* rasterNode)
  680. {
  681. if (rasterNode == nullptr || rasterNode->type != NT_Raster)
  682. return false;
  683. bool isDefault = true;
  684. for (int i = 0; i < rasterNode->options->count; i++)
  685. {
  686. NodeOption* option = &rasterNode->options->entries[i];
  687. switch (option->type)
  688. {
  689. case OT_FillMode:
  690. desc.rasterizerDesc.polygonMode = parseFillMode((FillModeValue)option->value.intValue);
  691. isDefault = false;
  692. break;
  693. case OT_CullMode:
  694. desc.rasterizerDesc.cullMode = parseCullMode((CullAndSortModeValue)option->value.intValue);
  695. isDefault = false;
  696. break;
  697. case OT_DepthBias:
  698. desc.rasterizerDesc.depthBias = option->value.floatValue;
  699. isDefault = false;
  700. break;
  701. case OT_SDepthBias:
  702. desc.rasterizerDesc.slopeScaledDepthBias = option->value.floatValue;
  703. isDefault = false;
  704. break;
  705. case OT_DepthClip:
  706. desc.rasterizerDesc.depthClipEnable = option->value.intValue > 0;
  707. isDefault = false;
  708. break;
  709. case OT_Scissor:
  710. desc.rasterizerDesc.scissorEnable = option->value.intValue > 0;
  711. isDefault = false;
  712. break;
  713. case OT_Multisample:
  714. desc.rasterizerDesc.multisampleEnable = option->value.intValue > 0;
  715. isDefault = false;
  716. break;
  717. case OT_AALine:
  718. desc.rasterizerDesc.antialiasedLineEnable = option->value.intValue > 0;
  719. isDefault = false;
  720. break;
  721. default:
  722. break;
  723. }
  724. }
  725. return !isDefault;
  726. }
  727. bool BSLFXCompiler::parseDepthState(PassData& passData, ASTFXNode* depthNode)
  728. {
  729. if (depthNode == nullptr || depthNode->type != NT_Depth)
  730. return false;
  731. bool isDefault = true;
  732. for (int i = 0; i < depthNode->options->count; i++)
  733. {
  734. NodeOption* option = &depthNode->options->entries[i];
  735. switch (option->type)
  736. {
  737. case OT_DepthRead:
  738. passData.depthStencilDesc.depthReadEnable = option->value.intValue > 0;
  739. isDefault = false;
  740. break;
  741. case OT_DepthWrite:
  742. passData.depthStencilDesc.depthWriteEnable = option->value.intValue > 0;
  743. isDefault = false;
  744. break;
  745. case OT_CompareFunc:
  746. passData.depthStencilDesc.depthComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  747. isDefault = false;
  748. break;
  749. default:
  750. break;
  751. }
  752. }
  753. return !isDefault;
  754. }
  755. bool BSLFXCompiler::parseStencilState(PassData& passData, ASTFXNode* stencilNode)
  756. {
  757. if (stencilNode == nullptr || stencilNode->type != NT_Stencil)
  758. return false;
  759. bool isDefault = true;
  760. for (int i = 0; i < stencilNode->options->count; i++)
  761. {
  762. NodeOption* option = &stencilNode->options->entries[i];
  763. switch (option->type)
  764. {
  765. case OT_Enabled:
  766. passData.depthStencilDesc.stencilEnable = option->value.intValue > 0;
  767. isDefault = false;
  768. break;
  769. case OT_StencilReadMask:
  770. passData.depthStencilDesc.stencilReadMask = (UINT8)option->value.intValue;
  771. isDefault = false;
  772. break;
  773. case OT_StencilWriteMask:
  774. passData.depthStencilDesc.stencilWriteMask = (UINT8)option->value.intValue;
  775. isDefault = false;
  776. break;
  777. case OT_StencilOpFront:
  778. parseStencilFront(passData.depthStencilDesc, option->value.nodePtr);
  779. isDefault = false;
  780. break;
  781. case OT_StencilOpBack:
  782. parseStencilBack(passData.depthStencilDesc, option->value.nodePtr);
  783. isDefault = false;
  784. break;
  785. case OT_StencilRef:
  786. passData.stencilRefValue = option->value.intValue;
  787. break;
  788. default:
  789. break;
  790. }
  791. }
  792. return !isDefault;
  793. }
  794. void BSLFXCompiler::parseCodeBlock(ASTFXNode* codeNode, const Vector<String>& codeBlocks, PassData& passData)
  795. {
  796. if (codeNode == nullptr || (codeNode->type != NT_CodeCommon && codeNode->type != NT_CodeVertex &&
  797. codeNode->type != NT_CodeFragment && codeNode->type != NT_CodeGeometry && codeNode->type != NT_CodeHull &&
  798. codeNode->type != NT_CodeDomain && codeNode->type != NT_CodeCompute))
  799. {
  800. return;
  801. }
  802. UINT32 index = (UINT32)-1;
  803. for (int j = 0; j < codeNode->options->count; j++)
  804. {
  805. if (codeNode->options->entries[j].type == OT_Index)
  806. index = codeNode->options->entries[j].value.intValue;
  807. }
  808. if (index != (UINT32)-1 && index < (UINT32)codeBlocks.size())
  809. {
  810. switch (codeNode->type)
  811. {
  812. case NT_CodeVertex:
  813. passData.vertexCode += codeBlocks[index];
  814. break;
  815. case NT_CodeFragment:
  816. passData.fragmentCode += codeBlocks[index];
  817. break;
  818. case NT_CodeGeometry:
  819. passData.geometryCode += codeBlocks[index];
  820. break;
  821. case NT_CodeHull:
  822. passData.hullCode += codeBlocks[index];
  823. break;
  824. case NT_CodeDomain:
  825. passData.domainCode += codeBlocks[index];
  826. break;
  827. case NT_CodeCompute:
  828. passData.computeCode += codeBlocks[index];
  829. break;
  830. case NT_CodeCommon:
  831. passData.commonCode += codeBlocks[index];
  832. break;
  833. default:
  834. break;
  835. }
  836. }
  837. }
  838. void BSLFXCompiler::parsePass(ASTFXNode* passNode, const Vector<String>& codeBlocks, PassData& passData)
  839. {
  840. if (passNode == nullptr || passNode->type != NT_Pass)
  841. return;
  842. for (int i = 0; i < passNode->options->count; i++)
  843. {
  844. NodeOption* option = &passNode->options->entries[i];
  845. switch (option->type)
  846. {
  847. case OT_Blend:
  848. passData.blendIsDefault &= !parseBlendState(passData, option->value.nodePtr);
  849. break;
  850. case OT_Raster:
  851. passData.rasterizerIsDefault &= !parseRasterizerState(passData, option->value.nodePtr);
  852. break;
  853. case OT_Depth:
  854. passData.depthStencilIsDefault &= !parseDepthState(passData, option->value.nodePtr);
  855. break;
  856. case OT_Stencil:
  857. passData.depthStencilIsDefault &= !parseStencilState(passData, option->value.nodePtr);
  858. break;
  859. case OT_Code:
  860. parseCodeBlock(option->value.nodePtr, codeBlocks, passData);
  861. break;
  862. default:
  863. break;
  864. }
  865. }
  866. }
  867. void BSLFXCompiler::parseTechnique(ASTFXNode* techniqueNode, const Vector<String>& codeBlocks, TechniqueData& techniqueData)
  868. {
  869. if (techniqueNode == nullptr || techniqueNode->type != NT_Technique)
  870. return;
  871. // There must always be at least one pass
  872. if(techniqueData.passes.empty())
  873. {
  874. techniqueData.passes.push_back(PassData());
  875. techniqueData.passes.back().seqIdx = 0;
  876. }
  877. PassData combinedCommonPassData;
  878. UINT32 nextPassIdx = 0;
  879. // Go in reverse because options are added in reverse order during parsing
  880. for (int i = techniqueNode->options->count - 1; i >= 0; i--)
  881. {
  882. NodeOption* option = &techniqueNode->options->entries[i];
  883. switch (option->type)
  884. {
  885. case OT_Pass:
  886. {
  887. UINT32 passIdx = nextPassIdx;
  888. PassData* passData = nullptr;
  889. for (auto& entry : techniqueData.passes)
  890. {
  891. if (entry.seqIdx == passIdx)
  892. passData = &entry;
  893. }
  894. if (passData == nullptr)
  895. {
  896. techniqueData.passes.push_back(PassData());
  897. passData = &techniqueData.passes.back();
  898. passData->seqIdx = passIdx;
  899. }
  900. nextPassIdx = std::max(nextPassIdx, passIdx) + 1;
  901. passData->vertexCode = combinedCommonPassData.vertexCode + passData->vertexCode;
  902. passData->fragmentCode = combinedCommonPassData.fragmentCode + passData->fragmentCode;
  903. passData->geometryCode = combinedCommonPassData.geometryCode + passData->geometryCode;
  904. passData->hullCode = combinedCommonPassData.hullCode + passData->hullCode;
  905. passData->domainCode = combinedCommonPassData.domainCode + passData->domainCode;
  906. passData->computeCode = combinedCommonPassData.computeCode + passData->computeCode;
  907. passData->commonCode = combinedCommonPassData.commonCode + passData->commonCode;
  908. ASTFXNode* passNode = option->value.nodePtr;
  909. parsePass(passNode, codeBlocks, *passData);
  910. }
  911. break;
  912. case OT_Code:
  913. {
  914. PassData commonPassData;
  915. parseCodeBlock(option->value.nodePtr, codeBlocks, commonPassData);
  916. for (auto& passData : techniqueData.passes)
  917. {
  918. passData.vertexCode += commonPassData.vertexCode;
  919. passData.fragmentCode += commonPassData.fragmentCode;
  920. passData.geometryCode += commonPassData.geometryCode;
  921. passData.hullCode += commonPassData.hullCode;
  922. passData.domainCode += commonPassData.domainCode;
  923. passData.computeCode += commonPassData.computeCode;
  924. passData.commonCode += commonPassData.commonCode;
  925. }
  926. combinedCommonPassData.vertexCode += commonPassData.vertexCode;
  927. combinedCommonPassData.fragmentCode += commonPassData.fragmentCode;
  928. combinedCommonPassData.geometryCode += commonPassData.geometryCode;
  929. combinedCommonPassData.hullCode += commonPassData.hullCode;
  930. combinedCommonPassData.domainCode += commonPassData.domainCode;
  931. combinedCommonPassData.computeCode += commonPassData.computeCode;
  932. combinedCommonPassData.commonCode += commonPassData.commonCode;
  933. }
  934. break;
  935. default:
  936. break;
  937. }
  938. }
  939. // Parse common pass states
  940. for (int i = 0; i < techniqueNode->options->count; i++)
  941. {
  942. NodeOption* option = &techniqueNode->options->entries[i];
  943. switch (option->type)
  944. {
  945. case OT_Blend:
  946. for (auto& passData : techniqueData.passes)
  947. passData.blendIsDefault &= !parseBlendState(passData, option->value.nodePtr);
  948. break;
  949. case OT_Raster:
  950. for (auto& passData : techniqueData.passes)
  951. passData.rasterizerIsDefault &= !parseRasterizerState(passData, option->value.nodePtr);
  952. break;
  953. case OT_Depth:
  954. for (auto& passData : techniqueData.passes)
  955. passData.depthStencilIsDefault &= !parseDepthState(passData, option->value.nodePtr);
  956. break;
  957. case OT_Stencil:
  958. for (auto& passData : techniqueData.passes)
  959. passData.depthStencilIsDefault &= !parseStencilState(passData, option->value.nodePtr);
  960. break;
  961. default:
  962. break;
  963. }
  964. }
  965. }
  966. void BSLFXCompiler::parseOptions(ASTFXNode* optionsNode, SHADER_DESC& shaderDesc)
  967. {
  968. if (optionsNode == nullptr || optionsNode->type != NT_Options)
  969. return;
  970. for (int i = optionsNode->options->count - 1; i >= 0; i--)
  971. {
  972. NodeOption* option = &optionsNode->options->entries[i];
  973. switch (option->type)
  974. {
  975. case OT_Separable:
  976. shaderDesc.separablePasses = option->value.intValue > 1;
  977. break;
  978. case OT_Sort:
  979. shaderDesc.queueSortType = parseSortType((CullAndSortModeValue)option->value.intValue);
  980. break;
  981. case OT_Priority:
  982. shaderDesc.queuePriority = option->value.intValue;
  983. break;
  984. case OT_Transparent:
  985. shaderDesc.flags |= (UINT32)ShaderFlags::Transparent;
  986. break;
  987. default:
  988. break;
  989. }
  990. }
  991. }
  992. BSLFXCompileResult BSLFXCompiler::parseShader(const String& name, ParseState* parseState, Vector<String>& codeBlocks)
  993. {
  994. BSLFXCompileResult output;
  995. if (parseState->rootNode == nullptr || parseState->rootNode->type != NT_Shader)
  996. {
  997. parseStateDelete(parseState);
  998. output.errorMessage = "Root not is null or not a shader.";
  999. return output;
  1000. }
  1001. SHADER_DESC shaderDesc;
  1002. Vector<pair<ASTFXNode*, TechniqueData>> techniqueData;
  1003. // Go in reverse because options are added in reverse order during parsing
  1004. for (int i = parseState->rootNode->options->count - 1; i >= 0; i--)
  1005. {
  1006. NodeOption* option = &parseState->rootNode->options->entries[i];
  1007. switch (option->type)
  1008. {
  1009. case OT_Options:
  1010. parseOptions(option->value.nodePtr, shaderDesc);
  1011. break;
  1012. case OT_Technique:
  1013. {
  1014. // We initially parse only meta-data, so we can handle out-of-order technique definitions
  1015. TechniqueMetaData metaData = parseTechniqueMetaData(option->value.nodePtr);
  1016. techniqueData.push_back(std::make_pair(option->value.nodePtr, TechniqueData()));
  1017. TechniqueData& data = techniqueData.back().second;
  1018. data.metaData = metaData;
  1019. break;
  1020. }
  1021. default:
  1022. break;
  1023. }
  1024. }
  1025. bool* techniqueWasParsed = bs_stack_alloc<bool>((UINT32)techniqueData.size());
  1026. std::function<bool(const TechniqueMetaData&, TechniqueData&)> parseInherited =
  1027. [&](const TechniqueMetaData& metaData, TechniqueData& outTechnique)
  1028. {
  1029. for (auto riter = metaData.inherits.rbegin(); riter != metaData.inherits.rend(); ++riter)
  1030. {
  1031. const String& inherits = *riter;
  1032. UINT32 baseIdx = -1;
  1033. for(UINT32 i = 0; i < (UINT32)techniqueData.size(); i++)
  1034. {
  1035. auto& entry = techniqueData[i];
  1036. if (entry.second.metaData.baseName == inherits)
  1037. {
  1038. bool matches = entry.second.metaData.language == metaData.language || entry.second.metaData.language == "Any";
  1039. matches &= entry.second.metaData.renderer == metaData.renderer || entry.second.metaData.renderer == RendererAny;
  1040. // We want the last matching technique, in order to allow techniques to override each other
  1041. if (matches)
  1042. baseIdx = i;
  1043. }
  1044. }
  1045. if (baseIdx != -1)
  1046. {
  1047. auto& entry = techniqueData[baseIdx];
  1048. // Was already parsed previously, don't parse it multiple times (happens when multiple techniques
  1049. // include the same base)
  1050. if (techniqueWasParsed[baseIdx])
  1051. continue;
  1052. if (!parseInherited(entry.second.metaData, outTechnique))
  1053. return false;
  1054. parseTechnique(entry.first, codeBlocks, outTechnique);
  1055. techniqueWasParsed[baseIdx] = true;
  1056. }
  1057. else
  1058. {
  1059. output.errorMessage = "Base technique \"" + inherits + "\" cannot be found.";
  1060. return false;
  1061. }
  1062. }
  1063. return true;
  1064. };
  1065. // Actually parse techniques
  1066. for (auto& entry : techniqueData)
  1067. {
  1068. const TechniqueMetaData& metaData = entry.second.metaData;
  1069. if (!metaData.baseName.empty())
  1070. continue;
  1071. bs_zero_out(techniqueWasParsed, techniqueData.size());
  1072. if (!parseInherited(metaData, entry.second))
  1073. {
  1074. parseStateDelete(parseState);
  1075. return output;
  1076. }
  1077. parseTechnique(entry.first, codeBlocks, entry.second);
  1078. }
  1079. bs_stack_free(techniqueWasParsed);
  1080. // Auto-generate GLSL techniques
  1081. UINT32 end = (UINT32)techniqueData.size();
  1082. for(UINT32 i = 0; i < end; i++)
  1083. {
  1084. const TechniqueMetaData& metaData = techniqueData[i].second.metaData;
  1085. if (!metaData.baseName.empty())
  1086. continue;
  1087. auto createTechniqueForLanguage = [](const String& name, const TechniqueData& orig, bool vulkan)
  1088. {
  1089. TechniqueData copy = orig;
  1090. copy.metaData.language = vulkan ? "vksl" : "glsl";
  1091. for (auto& passData : copy.passes)
  1092. {
  1093. UINT32 nextFreeBindingSlot = 0;
  1094. if (!passData.vertexCode.empty())
  1095. {
  1096. String hlslCode = passData.commonCode + passData.vertexCode;
  1097. passData.vertexCode = HLSLtoGLSL(hlslCode, GPT_VERTEX_PROGRAM, vulkan, nextFreeBindingSlot);
  1098. }
  1099. if (!passData.fragmentCode.empty())
  1100. {
  1101. String hlslCode = passData.commonCode + passData.fragmentCode;
  1102. passData.fragmentCode = HLSLtoGLSL(hlslCode, GPT_FRAGMENT_PROGRAM, vulkan, nextFreeBindingSlot);
  1103. }
  1104. if (!passData.geometryCode.empty())
  1105. {
  1106. String hlslCode = passData.commonCode + passData.geometryCode;
  1107. passData.geometryCode = HLSLtoGLSL(hlslCode, GPT_GEOMETRY_PROGRAM, vulkan, nextFreeBindingSlot);
  1108. }
  1109. if (!passData.hullCode.empty())
  1110. {
  1111. String hlslCode = passData.commonCode + passData.hullCode;
  1112. passData.hullCode = HLSLtoGLSL(hlslCode, GPT_HULL_PROGRAM, vulkan, nextFreeBindingSlot);
  1113. }
  1114. if (!passData.domainCode.empty())
  1115. {
  1116. String hlslCode = passData.commonCode + passData.domainCode;
  1117. passData.domainCode = HLSLtoGLSL(hlslCode, GPT_DOMAIN_PROGRAM, vulkan, nextFreeBindingSlot);
  1118. }
  1119. if (!passData.computeCode.empty())
  1120. {
  1121. String hlslCode = passData.commonCode + passData.computeCode;
  1122. passData.computeCode = HLSLtoGLSL(hlslCode, GPT_COMPUTE_PROGRAM, vulkan, nextFreeBindingSlot);
  1123. }
  1124. passData.commonCode = "";
  1125. }
  1126. return copy;
  1127. };
  1128. TechniqueData glslTechnique = createTechniqueForLanguage(name, techniqueData[i].second, false);
  1129. techniqueData.push_back(std::make_pair(techniqueData[i].first, glslTechnique));
  1130. TechniqueData vkslTechnique = createTechniqueForLanguage(name, techniqueData[i].second, true);
  1131. techniqueData.push_back(std::make_pair(techniqueData[i].first, vkslTechnique));
  1132. }
  1133. Vector<SPtr<Technique>> techniques;
  1134. for(auto& entry : techniqueData)
  1135. {
  1136. const TechniqueMetaData& metaData = entry.second.metaData;
  1137. if (!metaData.baseName.empty())
  1138. continue;
  1139. Map<UINT32, SPtr<Pass>, std::greater<UINT32>> passes;
  1140. for (auto& passData : entry.second.passes)
  1141. {
  1142. PASS_DESC passDesc;
  1143. if (!passData.blendIsDefault)
  1144. passDesc.blendState = BlendState::create(passData.blendDesc);
  1145. if (!passData.rasterizerIsDefault)
  1146. passDesc.rasterizerState = RasterizerState::create(passData.rasterizerDesc);
  1147. if (!passData.depthStencilIsDefault)
  1148. passDesc.depthStencilState = DepthStencilState::create(passData.depthStencilDesc);
  1149. GPU_PROGRAM_DESC desc;
  1150. desc.entryPoint = "main";
  1151. desc.language = metaData.language;
  1152. if (!passData.vertexCode.empty())
  1153. {
  1154. desc.source = passData.commonCode + passData.vertexCode;
  1155. desc.type = GPT_VERTEX_PROGRAM;
  1156. cleanNonStandardHLSL(desc);
  1157. passDesc.vertexProgram = GpuProgram::create(desc);
  1158. }
  1159. if (!passData.fragmentCode.empty())
  1160. {
  1161. desc.source = passData.commonCode + passData.fragmentCode;
  1162. desc.type = GPT_FRAGMENT_PROGRAM;
  1163. cleanNonStandardHLSL(desc);
  1164. passDesc.fragmentProgram = GpuProgram::create(desc);
  1165. }
  1166. if (!passData.geometryCode.empty())
  1167. {
  1168. desc.source = passData.commonCode + passData.geometryCode;
  1169. desc.type = GPT_GEOMETRY_PROGRAM;
  1170. cleanNonStandardHLSL(desc);
  1171. passDesc.geometryProgram = GpuProgram::create(desc);
  1172. }
  1173. if (!passData.hullCode.empty())
  1174. {
  1175. desc.source = passData.commonCode + passData.hullCode;
  1176. desc.type = GPT_HULL_PROGRAM;
  1177. cleanNonStandardHLSL(desc);
  1178. passDesc.hullProgram = GpuProgram::create(desc);
  1179. }
  1180. if (!passData.domainCode.empty())
  1181. {
  1182. desc.source = passData.commonCode + passData.domainCode;
  1183. desc.type = GPT_DOMAIN_PROGRAM;
  1184. cleanNonStandardHLSL(desc);
  1185. passDesc.domainProgram = GpuProgram::create(desc);
  1186. }
  1187. if (!passData.computeCode.empty())
  1188. {
  1189. desc.source = passData.commonCode + passData.computeCode;
  1190. desc.type = GPT_COMPUTE_PROGRAM;
  1191. cleanNonStandardHLSL(desc);
  1192. passDesc.computeProgram = GpuProgram::create(desc);
  1193. }
  1194. passDesc.stencilRefValue = passData.stencilRefValue;
  1195. SPtr<Pass> pass = Pass::create(passDesc);
  1196. if (pass != nullptr)
  1197. passes[passData.seqIdx] = pass;
  1198. }
  1199. Vector<SPtr<Pass>> orderedPasses;
  1200. for (auto& KVP : passes)
  1201. orderedPasses.push_back(KVP.second);
  1202. if (orderedPasses.size() > 0)
  1203. {
  1204. SPtr<Technique> technique = Technique::create(metaData.language, metaData.renderer, metaData.tags,
  1205. orderedPasses);
  1206. techniques.push_back(technique);
  1207. }
  1208. }
  1209. Vector<String> includes;
  1210. IncludeLink* includeLink = parseState->includes;
  1211. while(includeLink != nullptr)
  1212. {
  1213. String includeFilename = includeLink->data->filename;
  1214. auto iterFind = std::find(includes.begin(), includes.end(), includeFilename);
  1215. if (iterFind == includes.end())
  1216. includes.push_back(includeFilename);
  1217. includeLink = includeLink->next;
  1218. }
  1219. parseStateDelete(parseState);
  1220. output.shader = Shader::_createPtr(name, shaderDesc, techniques);
  1221. output.shader->setIncludeFiles(includes);
  1222. return output;
  1223. }
  1224. String BSLFXCompiler::removeQuotes(const char* input)
  1225. {
  1226. UINT32 len = (UINT32)strlen(input);
  1227. String output(len - 2, ' ');
  1228. for (UINT32 i = 0; i < (len - 2); i++)
  1229. output[i] = input[i + 1];
  1230. return output;
  1231. }
  1232. HTexture BSLFXCompiler::getBuiltinTexture(const String& name)
  1233. {
  1234. if (StringUtil::compare(name, String("white"), false) == 0)
  1235. return BuiltinResources::getTexture(BuiltinTexture::White);
  1236. else if (StringUtil::compare(name, String("black"), false) == 0)
  1237. return BuiltinResources::getTexture(BuiltinTexture::Black);
  1238. else if (StringUtil::compare(name, String("normal"), false) == 0)
  1239. return BuiltinResources::getTexture(BuiltinTexture::Normal);
  1240. return HTexture();
  1241. }
  1242. }