BsSLFXCompiler.cpp 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139
  1. #include "BsSLFXCompiler.h"
  2. #include "BsGpuProgram.h"
  3. #include <regex>
  4. #include "BsShader.h"
  5. #include "BsTechnique.h"
  6. #include "BsPass.h"
  7. #include "BsSamplerState.h"
  8. #include "BsRasterizerState.h"
  9. #include "BsDepthStencilState.h"
  10. #include "BsBlendState.h"
  11. #include "BsRenderAPI.h"
  12. #include "BsDebug.h"
  13. extern "C" {
  14. #include "BsMMAlloc.h"
  15. #include "BsParserFX.h"
  16. #include "BsLexerFX.h"
  17. }
  18. namespace BansheeEngine
  19. {
  20. // Print out the FX AST, only for debug purposes
  21. void SLFXDebugPrint(ASTFXNode* node, String indent)
  22. {
  23. LOGWRN(indent + "NODE " + toString(node->type));
  24. for (int i = 0; i < node->options->count; i++)
  25. {
  26. OptionDataType odt = OPTION_LOOKUP[(int)node->options->entries[i].type].dataType;
  27. if (odt == ODT_Complex)
  28. {
  29. LOGWRN(indent + toString(i) + ". " + toString(node->options->entries[i].type));
  30. SLFXDebugPrint(node->options->entries[i].value.nodePtr, indent + "\t");
  31. continue;
  32. }
  33. String value;
  34. switch (odt)
  35. {
  36. case ODT_Bool:
  37. value = toString(node->options->entries[i].value.intValue != 0);
  38. break;
  39. case ODT_Int:
  40. value = toString(node->options->entries[i].value.intValue);
  41. break;
  42. case ODT_Float:
  43. value = toString(node->options->entries[i].value.floatValue);
  44. break;
  45. case ODT_String:
  46. value = node->options->entries[i].value.strValue;
  47. break;
  48. case ODT_Matrix:
  49. {
  50. Matrix4 mat4 = *(Matrix4*)(node->options->entries[i].value.matrixValue);
  51. value = toString(mat4);
  52. }
  53. break;
  54. }
  55. LOGWRN(indent + toString(i) + ". " + toString(node->options->entries[i].type) + " = " + value);
  56. }
  57. }
  58. ShaderPtr BSLFXCompiler::compile(const String& source)
  59. {
  60. String parsedSource = source;
  61. ParseState* parseState = parseStateCreate();
  62. Vector<CodeBlock> codeBlocks = parseCodeBlocks(parsedSource);
  63. parseFX(parseState, parsedSource.c_str());
  64. ShaderPtr output;
  65. if (parseState->hasError > 0)
  66. {
  67. LOGERR("Error while parsing a Shader: " + String(parseState->errorMessage) + ". Location: " +
  68. toString(parseState->errorLine) + " (" + toString(parseState->errorColumn) + ")");
  69. }
  70. else
  71. {
  72. output = parseShader("Shader", parseState->rootNode, codeBlocks);
  73. // Only enable for debug purposes
  74. //SLFXDebugPrint(parseState->rootNode, "");
  75. }
  76. parseStateDelete(parseState);
  77. return output;
  78. }
  79. void BSLFXCompiler::parseFX(ParseState* parseState, const char* source)
  80. {
  81. yyscan_t scanner;
  82. YY_BUFFER_STATE state;
  83. if (yylex_init_extra(parseState, &scanner))
  84. return;
  85. state = yy_scan_string(source, scanner);
  86. if (yyparse(parseState, scanner))
  87. return;
  88. yy_delete_buffer(state, scanner);
  89. yylex_destroy(scanner);
  90. }
  91. Vector<BSLFXCompiler::CodeBlock> BSLFXCompiler::parseCodeBlocks(String& source)
  92. {
  93. std::regex pattern = std::regex(R"((Vertex|Fragment|Geometry|Hull|Domain|Compute)\s*=\s*\{)");
  94. std::smatch matches;
  95. Vector<CodeBlock> codeBlocks;
  96. UINT32 offset = 0;
  97. while (std::regex_search(source.cbegin() + offset, source.cend(), matches, pattern))
  98. {
  99. UINT32 idx = (UINT32)codeBlocks.size();
  100. codeBlocks.push_back(CodeBlock());
  101. CodeBlock& newBlock = codeBlocks.back();
  102. std::string type = matches[1].str();
  103. if (type == "Vertex")
  104. newBlock.type = GPT_VERTEX_PROGRAM;
  105. else if (type == "Fragment")
  106. newBlock.type = GPT_FRAGMENT_PROGRAM;
  107. else if (type == "Geometry")
  108. newBlock.type = GPT_GEOMETRY_PROGRAM;
  109. else if (type == "Hull")
  110. newBlock.type = GPT_HULL_PROGRAM;
  111. else if (type == "Domain")
  112. newBlock.type = GPT_DOMAIN_PROGRAM;
  113. else if (type == "Compute")
  114. newBlock.type = GPT_COMPUTE_PROGRAM;
  115. offset += (UINT32)matches.position() + (UINT32)matches.length();
  116. StringStream newDataStream;
  117. newDataStream << "Index = " + toString(idx) + ";";
  118. StringStream codeStream;
  119. UINT32 ummatchedBrackets = 1;
  120. for (UINT32 i = offset; i < (UINT32)source.length(); i++)
  121. {
  122. if (source[i] == '{')
  123. ummatchedBrackets++;
  124. if (source[i] == '}')
  125. ummatchedBrackets--;
  126. if (ummatchedBrackets == 0)
  127. break;
  128. if (source[i] == '\r' || source[i] == '\n')
  129. newDataStream << source[i];
  130. codeStream << source[i];
  131. }
  132. newBlock.code = codeStream.str();
  133. source.erase(source.cbegin() + offset, source.cbegin() + offset + (UINT32)newBlock.code.size());
  134. String newData = newDataStream.str();
  135. source.insert(offset, newData);
  136. offset += (UINT32)newData.size();
  137. }
  138. return codeBlocks;
  139. }
  140. StringID BSLFXCompiler::parseRenderer(const String& name)
  141. {
  142. if (name == "Any")
  143. return RendererAny;
  144. else if (name == "Default")
  145. return RendererDefault;
  146. return RendererAny;
  147. }
  148. void BSLFXCompiler::parseLanguage(const String& name, StringID& renderAPI, String& language)
  149. {
  150. if (name == "HLSL" || name == "HLSL11")
  151. {
  152. renderAPI = RenderAPIDX11;
  153. language = "hlsl";
  154. }
  155. else if (name == "HLSL9")
  156. {
  157. renderAPI = RenderAPIDX9;
  158. language = "hlsl";
  159. }
  160. else if (name == "GLSL")
  161. {
  162. renderAPI = RenderAPIOpenGL;
  163. language = "glsl";
  164. }
  165. else
  166. {
  167. renderAPI = RenderAPIAny;
  168. language = "";
  169. }
  170. }
  171. GpuParamBlockUsage BSLFXCompiler::parseBlockUsage(BufferUsageValue usage)
  172. {
  173. if (usage == BUV_Dynamic)
  174. return GPBU_DYNAMIC;
  175. return GPBU_STATIC;
  176. }
  177. UINT32 BSLFXCompiler::parseFilterMode(FilterValue filter)
  178. {
  179. switch (filter)
  180. {
  181. case FV_Point:
  182. return FO_POINT;
  183. case FV_Linear:
  184. return FO_LINEAR;
  185. case FV_Anisotropic:
  186. return FO_ANISOTROPIC;
  187. case FV_PointCmp:
  188. return FO_POINT | FO_USE_COMPARISON;
  189. case FV_LinearCmp:
  190. return FO_LINEAR | FO_USE_COMPARISON;
  191. case FV_AnisotropicCmp:
  192. return FO_ANISOTROPIC | FO_USE_COMPARISON;
  193. }
  194. return FO_NONE;
  195. }
  196. CompareFunction BSLFXCompiler::parseCompFunc(CompFuncValue compFunc)
  197. {
  198. switch (compFunc)
  199. {
  200. case CFV_Pass:
  201. return CMPF_ALWAYS_PASS;
  202. case CFV_Fail:
  203. return CMPF_ALWAYS_FAIL;
  204. case CFV_LT:
  205. return CMPF_LESS;
  206. case CFV_LTE:
  207. return CMPF_LESS_EQUAL;
  208. case CFV_EQ:
  209. return CMPF_EQUAL;
  210. case CFV_NEQ:
  211. return CMPF_NOT_EQUAL;
  212. case CFV_GT:
  213. return CMPF_GREATER;
  214. case CFV_GTE:
  215. return CMPF_GREATER_EQUAL;
  216. }
  217. return CMPF_ALWAYS_PASS;
  218. }
  219. TextureAddressingMode BSLFXCompiler::parseAddrMode(AddrModeValue addrMode)
  220. {
  221. switch (addrMode)
  222. {
  223. case AMV_Wrap:
  224. return TAM_WRAP;
  225. case AMV_Mirror:
  226. return TAM_MIRROR;
  227. case AMV_Clamp:
  228. return TAM_CLAMP;
  229. case AMV_Border:
  230. return TAM_BORDER;
  231. }
  232. return TAM_WRAP;
  233. }
  234. BlendFactor BSLFXCompiler::parseBlendFactor(OpValue factor)
  235. {
  236. switch (factor)
  237. {
  238. case OV_One:
  239. return BF_ONE;
  240. case OV_Zero:
  241. return BF_ZERO;
  242. case OV_DestColor:
  243. return BF_DEST_COLOR;
  244. case OV_SrcColor:
  245. return BF_SOURCE_COLOR;
  246. case OV_InvDestColor:
  247. return BF_INV_DEST_COLOR;
  248. case OV_InvSrcColor:
  249. return BF_INV_SOURCE_COLOR;
  250. case OV_DestAlpha:
  251. return BF_DEST_ALPHA;
  252. case OV_SrcAlpha:
  253. return BF_SOURCE_ALPHA;
  254. case OV_InvDestAlpha:
  255. return BF_INV_DEST_ALPHA;
  256. case OV_InvSrcAlpha:
  257. return BF_INV_SOURCE_ALPHA;
  258. }
  259. return BF_ONE;
  260. }
  261. BlendOperation BSLFXCompiler::parseBlendOp(BlendOpValue op)
  262. {
  263. switch (op)
  264. {
  265. case BOV_Add:
  266. return BO_ADD;
  267. case BOV_Max:
  268. return BO_MAX;
  269. case BOV_Min:
  270. return BO_MIN;
  271. case BOV_Subtract:
  272. return BO_SUBTRACT;
  273. case BOV_RevSubtract:
  274. return BO_REVERSE_SUBTRACT;
  275. }
  276. return BO_ADD;
  277. }
  278. void BSLFXCompiler::parseParamType(ParamType type, bool& isObjType, UINT32& typeId)
  279. {
  280. struct ParamData
  281. {
  282. UINT32 type;
  283. bool isObjType;
  284. };
  285. static bool initialized = false;
  286. static ParamData lookup[PT_Count];
  287. if (!initialized)
  288. {
  289. lookup[PT_Float] = { { GPDT_FLOAT1 }, false };
  290. lookup[PT_Float2] = { { GPDT_FLOAT2 }, false };
  291. lookup[PT_Float3] = { { GPDT_FLOAT3 }, false };
  292. lookup[PT_Float4] = { { GPDT_FLOAT4 }, false };
  293. lookup[PT_Mat2x2] = { { GPDT_MATRIX_2X2 }, false };
  294. lookup[PT_Mat2x3] = { { GPDT_MATRIX_2X3 }, false };
  295. lookup[PT_Mat2x4] = { { GPDT_MATRIX_2X4 }, false };
  296. lookup[PT_Mat3x2] = { { GPDT_MATRIX_3X2 }, false };
  297. lookup[PT_Mat3x3] = { { GPDT_MATRIX_3X3 }, false };
  298. lookup[PT_Mat3x4] = { { GPDT_MATRIX_3X4 }, false };
  299. lookup[PT_Mat4x2] = { { GPDT_MATRIX_4X2 }, false };
  300. lookup[PT_Mat4x3] = { { GPDT_MATRIX_4X3 }, false };
  301. lookup[PT_Mat4x4] = { { GPDT_MATRIX_4X4 }, false };
  302. lookup[PT_Sampler1D] = { { GPOT_SAMPLER1D }, true };
  303. lookup[PT_Sampler2D] = { { GPOT_SAMPLER2D }, true };
  304. lookup[PT_Sampler3D] = { { GPOT_SAMPLER3D }, true };
  305. lookup[PT_SamplerCUBE] = { { GPOT_SAMPLERCUBE }, true };
  306. lookup[PT_Sampler2DMS] = { { GPOT_SAMPLER2DMS }, true };
  307. lookup[PT_Texture1D] = { { GPOT_TEXTURE1D }, true };
  308. lookup[PT_Texture2D] = { { GPOT_TEXTURE2D }, true };
  309. lookup[PT_Texture3D] = { { GPOT_TEXTURE3D }, true };
  310. lookup[PT_TextureCUBE] = { { GPOT_TEXTURECUBE }, true };
  311. lookup[PT_Texture2DMS] = { { GPOT_TEXTURE2DMS }, true };
  312. lookup[PT_ByteBuffer] = { { GPOT_BYTE_BUFFER }, true };
  313. lookup[PT_StructBuffer] = { { GPOT_STRUCTURED_BUFFER }, true };
  314. lookup[PT_TypedBufferRW] = { { GPOT_RWTYPED_BUFFER }, true };
  315. lookup[PT_ByteBufferRW] = { { GPOT_RWBYTE_BUFFER }, true };
  316. lookup[PT_StructBufferRW] = { { GPOT_RWSTRUCTURED_BUFFER }, true };
  317. lookup[PT_AppendBuffer] = { { GPOT_RWAPPEND_BUFFER }, true };
  318. lookup[PT_ConsumeBuffer] = { { GPOT_RWCONSUME_BUFFER }, true };
  319. initialized = true;
  320. }
  321. isObjType = lookup[type].isObjType;
  322. typeId = lookup[type].type;
  323. }
  324. StencilOperation BSLFXCompiler::parseStencilOp(OpValue op)
  325. {
  326. switch (op)
  327. {
  328. case OV_Keep:
  329. return SOP_KEEP;
  330. case OV_Zero:
  331. return SOP_ZERO;
  332. case OV_Replace:
  333. return SOP_REPLACE;
  334. case OV_Incr:
  335. return SOP_INCREMENT;
  336. case OV_Decr:
  337. return SOP_DECREMENT;
  338. case OV_IncrWrap:
  339. return SOP_INCREMENT_WRAP;
  340. case OV_DecrWrap:
  341. return SOP_DECREMENT_WRAP;
  342. case OV_Invert:
  343. return SOP_INVERT;
  344. }
  345. return SOP_KEEP;
  346. }
  347. CullingMode BSLFXCompiler::parseCullMode(CullModeValue cm)
  348. {
  349. switch (cm)
  350. {
  351. case CMV_None:
  352. return CULL_NONE;
  353. case CMV_CW:
  354. return CULL_CLOCKWISE;
  355. case CMV_CCW:
  356. return CULL_COUNTERCLOCKWISE;
  357. }
  358. return CULL_COUNTERCLOCKWISE;
  359. }
  360. PolygonMode BSLFXCompiler::parseFillMode(FillModeValue fm)
  361. {
  362. if (fm == FMV_Wire)
  363. return PM_WIREFRAME;
  364. return PM_SOLID;
  365. }
  366. void BSLFXCompiler::parseStencilFront(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode)
  367. {
  368. if (stencilOpNode == nullptr || stencilOpNode->type != NT_StencilOp)
  369. return;
  370. for (int i = 0; i < stencilOpNode->options->count; i++)
  371. {
  372. NodeOption* option = &stencilOpNode->options->entries[i];
  373. switch (option->type)
  374. {
  375. case OT_Fail:
  376. desc.frontStencilFailOp = parseStencilOp((OpValue)option->value.intValue);
  377. break;
  378. case OT_ZFail:
  379. desc.frontStencilZFailOp = parseStencilOp((OpValue)option->value.intValue);
  380. break;
  381. case OT_PassOp:
  382. desc.frontStencilPassOp = parseStencilOp((OpValue)option->value.intValue);
  383. break;
  384. case OT_CompareFunc:
  385. desc.frontStencilComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  386. break;
  387. }
  388. }
  389. }
  390. void BSLFXCompiler::parseStencilBack(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode)
  391. {
  392. if (stencilOpNode == nullptr || stencilOpNode->type != NT_StencilOp)
  393. return;
  394. for (int i = 0; i < stencilOpNode->options->count; i++)
  395. {
  396. NodeOption* option = &stencilOpNode->options->entries[i];
  397. switch (option->type)
  398. {
  399. case OT_Fail:
  400. desc.backStencilFailOp = parseStencilOp((OpValue)option->value.intValue);
  401. break;
  402. case OT_ZFail:
  403. desc.backStencilZFailOp = parseStencilOp((OpValue)option->value.intValue);
  404. break;
  405. case OT_PassOp:
  406. desc.backStencilPassOp = parseStencilOp((OpValue)option->value.intValue);
  407. break;
  408. case OT_CompareFunc:
  409. desc.backStencilComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  410. break;
  411. }
  412. }
  413. }
  414. void BSLFXCompiler::parseAddrMode(SAMPLER_STATE_DESC& desc, ASTFXNode* addrModeNode)
  415. {
  416. if (addrModeNode == nullptr || addrModeNode->type != NT_AddrMode)
  417. return;
  418. for (int i = 0; i < addrModeNode->options->count; i++)
  419. {
  420. NodeOption* option = &addrModeNode->options->entries[i];
  421. switch (option->type)
  422. {
  423. case OT_U:
  424. desc.addressMode.u = parseAddrMode((AddrModeValue)option->value.intValue);
  425. break;
  426. case OT_V:
  427. desc.addressMode.v = parseAddrMode((AddrModeValue)option->value.intValue);
  428. break;
  429. case OT_W:
  430. desc.addressMode.w = parseAddrMode((AddrModeValue)option->value.intValue);
  431. break;
  432. }
  433. }
  434. }
  435. void BSLFXCompiler::parseColorBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode)
  436. {
  437. if (blendDefNode == nullptr || blendDefNode->type != NT_BlendDef)
  438. return;
  439. for (int i = 0; i < blendDefNode->options->count; i++)
  440. {
  441. NodeOption* option = &blendDefNode->options->entries[i];
  442. switch (option->type)
  443. {
  444. case OT_Source:
  445. desc.srcBlend = parseBlendFactor((OpValue)option->value.intValue);
  446. break;
  447. case OT_Dest:
  448. desc.dstBlend = parseBlendFactor((OpValue)option->value.intValue);
  449. break;
  450. case OT_Op:
  451. desc.blendOp = parseBlendOp((BlendOpValue)option->value.intValue);
  452. break;
  453. }
  454. }
  455. }
  456. void BSLFXCompiler::parseAlphaBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode)
  457. {
  458. if (blendDefNode == nullptr || blendDefNode->type != NT_BlendDef)
  459. return;
  460. for (int i = 0; i < blendDefNode->options->count; i++)
  461. {
  462. NodeOption* option = &blendDefNode->options->entries[i];
  463. switch (option->type)
  464. {
  465. case OT_Source:
  466. desc.srcBlendAlpha = parseBlendFactor((OpValue)option->value.intValue);
  467. break;
  468. case OT_Dest:
  469. desc.dstBlendAlpha = parseBlendFactor((OpValue)option->value.intValue);
  470. break;
  471. case OT_Op:
  472. desc.blendOpAlpha = parseBlendOp((BlendOpValue)option->value.intValue);
  473. break;
  474. }
  475. }
  476. }
  477. void BSLFXCompiler::parseRenderTargetBlendState(BLEND_STATE_DESC& desc, ASTFXNode* targetNode)
  478. {
  479. if (targetNode == nullptr || targetNode->type != NT_Target)
  480. return;
  481. UINT32 index = 0;
  482. for (int i = 0; i < targetNode->options->count; i++)
  483. {
  484. NodeOption* option = &targetNode->options->entries[i];
  485. switch (option->type)
  486. {
  487. case OT_Index:
  488. index = option->value.intValue;
  489. break;
  490. }
  491. }
  492. if (index >= BS_MAX_MULTIPLE_RENDER_TARGETS)
  493. return;
  494. RENDER_TARGET_BLEND_STATE_DESC& rtDesc = desc.renderTargetDesc[index];
  495. for (int i = 0; i < targetNode->options->count; i++)
  496. {
  497. NodeOption* option = &targetNode->options->entries[i];
  498. switch (option->type)
  499. {
  500. case OT_Blend:
  501. rtDesc.blendEnable = option->value.intValue > 0;
  502. break;
  503. case OT_Color:
  504. parseColorBlendDef(rtDesc, option->value.nodePtr);
  505. break;
  506. case OT_Alpha:
  507. parseAlphaBlendDef(rtDesc, option->value.nodePtr);
  508. break;
  509. case OT_WriteMask:
  510. rtDesc.renderTargetWriteMask = option->value.intValue;
  511. break;
  512. }
  513. }
  514. }
  515. HBlendState BSLFXCompiler::parseBlendState(ASTFXNode* passNode)
  516. {
  517. if (passNode == nullptr || passNode->type != NT_Pass)
  518. return HBlendState();
  519. BLEND_STATE_DESC desc;
  520. bool default = true;
  521. for (int i = 0; i < passNode->options->count; i++)
  522. {
  523. NodeOption* option = &passNode->options->entries[i];
  524. switch (option->type)
  525. {
  526. case OT_AlphaToCoverage:
  527. desc.alphaToCoverageEnable = option->value.intValue > 0;
  528. default = false;
  529. break;
  530. case OT_IndependantBlend:
  531. desc.independantBlendEnable = option->value.intValue > 0;
  532. default = false;
  533. break;
  534. case OT_Target:
  535. parseRenderTargetBlendState(desc, option->value.nodePtr);
  536. default = false;
  537. break;
  538. }
  539. }
  540. if (default)
  541. return HBlendState();
  542. return BlendState::create(desc);
  543. }
  544. HRasterizerState BSLFXCompiler::parseRasterizerState(ASTFXNode* passNode)
  545. {
  546. if (passNode == nullptr || passNode->type != NT_Pass)
  547. return HRasterizerState();
  548. RASTERIZER_STATE_DESC desc;
  549. bool default = true;
  550. for (int i = 0; i < passNode->options->count; i++)
  551. {
  552. NodeOption* option = &passNode->options->entries[i];
  553. switch (option->type)
  554. {
  555. case OT_FillMode:
  556. desc.polygonMode = parseFillMode((FillModeValue)option->value.intValue);
  557. default = false;
  558. break;
  559. case OT_CullMode:
  560. desc.cullMode = parseCullMode((CullModeValue)option->value.intValue);
  561. default = false;
  562. break;
  563. case OT_DepthBias:
  564. desc.depthBias = option->value.floatValue;
  565. default = false;
  566. break;
  567. case OT_SDepthBias:
  568. desc.slopeScaledDepthBias = option->value.floatValue;
  569. default = false;
  570. break;
  571. case OT_DepthClip:
  572. desc.depthClipEnable = option->value.intValue > 0;
  573. default = false;
  574. break;
  575. case OT_Scissor:
  576. desc.scissorEnable = option->value.intValue > 0;
  577. default = false;
  578. break;
  579. case OT_Multisample:
  580. desc.multisampleEnable = option->value.intValue > 0;
  581. default = false;
  582. break;
  583. case OT_AALine:
  584. desc.antialiasedLineEnable = option->value.intValue > 0;
  585. default = false;
  586. break;
  587. }
  588. }
  589. if (default)
  590. return HRasterizerState();
  591. return RasterizerState::create(desc);
  592. }
  593. HDepthStencilState BSLFXCompiler::parseDepthStencilState(ASTFXNode* passNode)
  594. {
  595. if (passNode == nullptr || passNode->type != NT_Pass)
  596. return HDepthStencilState();
  597. DEPTH_STENCIL_STATE_DESC desc;
  598. bool default = true;
  599. for (int i = 0; i < passNode->options->count; i++)
  600. {
  601. NodeOption* option = &passNode->options->entries[i];
  602. switch (option->type)
  603. {
  604. case OT_DepthRead:
  605. desc.depthReadEnable = option->value.intValue > 0;
  606. default = false;
  607. break;
  608. case OT_DepthWrite:
  609. desc.depthWriteEnable = option->value.intValue > 0;
  610. default = false;
  611. break;
  612. case OT_CompareFunc:
  613. desc.depthComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  614. default = false;
  615. break;
  616. case OT_Stencil:
  617. desc.stencilEnable = option->value.intValue > 0;
  618. default = false;
  619. break;
  620. case OT_StencilReadMask:
  621. desc.stencilReadMask = (UINT8)option->value.intValue;
  622. default = false;
  623. break;
  624. case OT_StencilWriteMask:
  625. desc.stencilWriteMask = (UINT8)option->value.intValue;
  626. default = false;
  627. break;
  628. case OT_StencilOpFront:
  629. parseStencilFront(desc, option->value.nodePtr);
  630. default = false;
  631. break;
  632. case OT_StencilOpBack:
  633. parseStencilBack(desc, option->value.nodePtr);
  634. default = false;
  635. break;
  636. }
  637. }
  638. if (default)
  639. return HDepthStencilState();
  640. return DepthStencilState::create(desc);
  641. }
  642. HSamplerState BSLFXCompiler::parseSamplerState(ASTFXNode* samplerStateNode)
  643. {
  644. if (samplerStateNode == nullptr || samplerStateNode->type != NT_SamplerState)
  645. return HSamplerState();
  646. SAMPLER_STATE_DESC desc;
  647. bool default = true;
  648. for (int i = 0; i < samplerStateNode->options->count; i++)
  649. {
  650. NodeOption* option = &samplerStateNode->options->entries[i];
  651. switch (option->type)
  652. {
  653. case OT_AddrMode:
  654. parseAddrMode(desc, option->value.nodePtr);
  655. default = false;
  656. break;
  657. case OT_MinFilter:
  658. desc.minFilter = (FilterOptions)parseFilterMode((FilterValue)option->value.intValue);
  659. default = false;
  660. break;
  661. case OT_MagFilter:
  662. desc.magFilter = (FilterOptions)parseFilterMode((FilterValue)option->value.intValue);
  663. default = false;
  664. break;
  665. case OT_MipFilter:
  666. desc.mipFilter = (FilterOptions)parseFilterMode((FilterValue)option->value.intValue);
  667. default = false;
  668. break;
  669. case OT_MaxAniso:
  670. desc.maxAniso = option->value.intValue;
  671. default = false;
  672. break;
  673. case OT_MipBias:
  674. desc.mipmapBias = option->value.floatValue;
  675. default = false;
  676. break;
  677. case OT_MipMin:
  678. desc.mipMin = option->value.floatValue;
  679. default = false;
  680. break;
  681. case OT_MipMax:
  682. desc.mipMax = option->value.floatValue;
  683. default = false;
  684. break;
  685. case OT_BorderColor:
  686. desc.borderColor = Color(option->value.matrixValue[0], option->value.matrixValue[1],
  687. option->value.matrixValue[2], option->value.matrixValue[3]);
  688. default = false;
  689. break;
  690. case OT_CompareFunc:
  691. desc.comparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
  692. default = false;
  693. break;
  694. }
  695. }
  696. if (default)
  697. return HSamplerState();
  698. return SamplerState::create(desc);
  699. }
  700. PassPtr BSLFXCompiler::parsePass(ASTFXNode* passNode, const Vector<CodeBlock>& codeBlocks, const Vector<String>& includes, const StringID& renderAPI, const String& language)
  701. {
  702. if (passNode == nullptr || passNode->type != NT_Pass)
  703. return nullptr;
  704. PASS_DESC passDesc;
  705. passDesc.blendState = parseBlendState(passNode);
  706. passDesc.rasterizerState = parseRasterizerState(passNode);
  707. passDesc.depthStencilState = parseDepthStencilState(passNode);
  708. for (int i = 0; i < passNode->options->count; i++)
  709. {
  710. NodeOption* option = &passNode->options->entries[i];
  711. switch (option->type)
  712. {
  713. case OT_StencilRef:
  714. passDesc.stencilRefValue = option->value.intValue;
  715. break;
  716. case OT_Code:
  717. {
  718. ASTFXNode* codeNode = option->value.nodePtr;
  719. if (codeNode != nullptr && codeNode->type == NT_Code)
  720. {
  721. UINT32 index = (UINT32)-1;
  722. for (int j = 0; j < codeNode->options->count; j++)
  723. {
  724. if (codeNode->options->entries[j].type == OT_Index)
  725. index = codeNode->options->entries[j].value.intValue;
  726. }
  727. if (index != (UINT32)-1 && index < (UINT32)codeBlocks.size())
  728. {
  729. const CodeBlock& codeBlock = codeBlocks[index];
  730. switch (codeBlock.type)
  731. {
  732. case GPT_VERTEX_PROGRAM:
  733. passDesc.vertexProgram = GpuProgram::create(codeBlock.code, "main", language,
  734. codeBlock.type, getProfile(renderAPI, codeBlock.type));
  735. break;
  736. case GPT_FRAGMENT_PROGRAM:
  737. passDesc.fragmentProgram = GpuProgram::create(codeBlock.code, "main", language,
  738. codeBlock.type, getProfile(renderAPI, codeBlock.type));
  739. break;
  740. case GPT_GEOMETRY_PROGRAM:
  741. passDesc.geometryProgram = GpuProgram::create(codeBlock.code, "main", language,
  742. codeBlock.type, getProfile(renderAPI, codeBlock.type));
  743. break;
  744. case GPT_HULL_PROGRAM:
  745. passDesc.hullProgram = GpuProgram::create(codeBlock.code, "main", language,
  746. codeBlock.type, getProfile(renderAPI, codeBlock.type));
  747. break;
  748. case GPT_DOMAIN_PROGRAM:
  749. passDesc.domainProgram = GpuProgram::create(codeBlock.code, "main", language,
  750. codeBlock.type, getProfile(renderAPI, codeBlock.type));
  751. break;
  752. case GPT_COMPUTE_PROGRAM:
  753. passDesc.computeProgram = GpuProgram::create(codeBlock.code, "main", language,
  754. codeBlock.type, getProfile(renderAPI, codeBlock.type));
  755. break;
  756. }
  757. }
  758. }
  759. }
  760. break;
  761. }
  762. }
  763. return Pass::create(passDesc);
  764. }
  765. TechniquePtr BSLFXCompiler::parseTechnique(ASTFXNode* techniqueNode, const Vector<CodeBlock>& codeBlocks)
  766. {
  767. if (techniqueNode == nullptr || techniqueNode->type != NT_Technique)
  768. return nullptr;
  769. Vector<ASTFXNode*> passNodes;
  770. StringID renderer = RendererAny;
  771. StringID renderAPI = RenderAPIAny;
  772. String language;
  773. Vector<String> includes; // TODO - Need to figure out what to do with these
  774. for (int i = 0; i < techniqueNode->options->count; i++)
  775. {
  776. NodeOption* option = &techniqueNode->options->entries[i];
  777. switch (option->type)
  778. {
  779. case OT_Pass:
  780. passNodes.push_back(option->value.nodePtr);
  781. break;
  782. case OT_Include:
  783. {
  784. String include = removeQuotes(option->value.strValue);
  785. includes.push_back(include);
  786. }
  787. break;
  788. case OT_Renderer:
  789. renderer = parseRenderer(removeQuotes(option->value.strValue));
  790. break;
  791. case OT_Language:
  792. parseLanguage(removeQuotes(option->value.strValue), renderAPI, language);
  793. break;
  794. }
  795. }
  796. Vector<PassPtr> passes;
  797. for (auto& passNode : passNodes)
  798. {
  799. PassPtr pass = parsePass(passNode, codeBlocks, includes, renderAPI, language);
  800. if (pass != nullptr)
  801. passes.push_back(pass);
  802. }
  803. if (passes.size() > 0)
  804. return Technique::create(renderAPI, renderer, passes);
  805. return nullptr;
  806. }
  807. void BSLFXCompiler::parseParameters(SHADER_DESC& desc, ASTFXNode* parametersNode)
  808. {
  809. if (parametersNode == nullptr || parametersNode->type != NT_Parameters)
  810. return;
  811. for (int i = 0; i < parametersNode->options->count; i++)
  812. {
  813. NodeOption* option = &parametersNode->options->entries[i];
  814. if (option->type != OT_Parameter)
  815. continue;
  816. ASTFXNode* parameter = option->value.nodePtr;
  817. String name;
  818. String alias;
  819. float defaultValue[16];
  820. UINT32 typeId;
  821. bool isObjType = false;
  822. StringID semantic;
  823. for (int j = 0; j < parameter->options->count; j++)
  824. {
  825. NodeOption* paramOption = &parameter->options->entries[j];
  826. switch (paramOption->type)
  827. {
  828. case OT_Identifier:
  829. name = paramOption->value.strValue;
  830. break;
  831. case OT_Alias:
  832. alias = removeQuotes(paramOption->value.strValue);
  833. break;
  834. case OT_ParamValue:
  835. memcpy(defaultValue, paramOption->value.matrixValue, sizeof(defaultValue));
  836. break;
  837. case OT_ParamType:
  838. parseParamType((ParamType)paramOption->value.intValue, isObjType, typeId);
  839. break;
  840. case OT_Auto:
  841. semantic = removeQuotes(paramOption->value.strValue);
  842. break;
  843. case OT_SamplerState:
  844. HSamplerState samplerState = parseSamplerState(paramOption->value.nodePtr);
  845. // TODO - How to deal with sampler-state default value?
  846. break;
  847. }
  848. }
  849. if (name.empty())
  850. continue;
  851. if (isObjType)
  852. desc.addParameter(name, name, (GpuParamObjectType)typeId, semantic);
  853. else
  854. desc.addParameter(name, name, (GpuParamDataType)typeId, semantic); // TODO - Add default value
  855. if (!alias.empty())
  856. {
  857. if (isObjType)
  858. desc.addParameter(name, alias, (GpuParamObjectType)typeId, semantic);
  859. else
  860. desc.addParameter(name, alias, (GpuParamDataType)typeId, semantic); // TODO - Add default value
  861. }
  862. }
  863. }
  864. void BSLFXCompiler::parseBlocks(SHADER_DESC& desc, ASTFXNode* blocksNode)
  865. {
  866. if (blocksNode == nullptr || blocksNode->type != NT_Blocks)
  867. return;
  868. for (int i = 0; i < blocksNode->options->count; i++)
  869. {
  870. NodeOption* option = &blocksNode->options->entries[i];
  871. if (option->type != OT_Block)
  872. continue;
  873. ASTFXNode* parameter = option->value.nodePtr;
  874. String name;
  875. bool shared;
  876. GpuParamBlockUsage usage;
  877. StringID semantic;
  878. for (int j = 0; j < parameter->options->count; j++)
  879. {
  880. NodeOption* paramOption = &parameter->options->entries[j];
  881. switch (paramOption->type)
  882. {
  883. case OT_Identifier:
  884. name = paramOption->value.strValue;
  885. break;
  886. case OT_Shared:
  887. shared = paramOption->value.intValue > 0;
  888. break;
  889. case OT_Usage:
  890. usage = parseBlockUsage((BufferUsageValue)paramOption->value.intValue);
  891. break;
  892. case OT_Auto:
  893. semantic = removeQuotes(paramOption->value.strValue);
  894. break;
  895. }
  896. }
  897. if (name.empty())
  898. continue;
  899. desc.setParamBlockAttribs(name, shared, usage, semantic);
  900. }
  901. }
  902. ShaderPtr BSLFXCompiler::parseShader(const String& name, ASTFXNode* rootNode, const Vector<CodeBlock>& codeBlocks)
  903. {
  904. SHADER_DESC shaderDesc;
  905. Vector<TechniquePtr> techniques;
  906. if (rootNode->type == NT_Shader)
  907. {
  908. for (int i = 0; i < rootNode->options->count; i++)
  909. {
  910. NodeOption* option = &rootNode->options->entries[i];
  911. switch (option->type)
  912. {
  913. case OT_Separable:
  914. shaderDesc.separablePasses = option->value.intValue > 1;
  915. break;
  916. case OT_Queue:
  917. shaderDesc.queuePriority = option->value.intValue;
  918. break;
  919. case OT_Priority:
  920. shaderDesc.queuePriority = option->value.intValue;
  921. break;
  922. case OT_Technique:
  923. {
  924. TechniquePtr technique = parseTechnique(option->value.nodePtr, codeBlocks);
  925. if (technique != nullptr)
  926. techniques.push_back(technique);
  927. break;
  928. }
  929. case OT_Parameters:
  930. parseParameters(shaderDesc, option->value.nodePtr);
  931. break;
  932. case OT_Blocks:
  933. parseBlocks(shaderDesc, option->value.nodePtr);
  934. break;
  935. }
  936. }
  937. }
  938. return Shader::_createPtr(name, shaderDesc, techniques);
  939. }
  940. String BSLFXCompiler::removeQuotes(const char* input)
  941. {
  942. UINT32 len = (UINT32)strlen(input);
  943. String output(len - 2, ' ');
  944. for (UINT32 i = 0; i < (len - 2); i++)
  945. output[i] = input[i + 1];
  946. return output;
  947. }
  948. GpuProgramProfile BSLFXCompiler::getProfile(const StringID& renderAPI, GpuProgramType type)
  949. {
  950. StringID target = renderAPI;
  951. if (target == RenderAPIAny)
  952. target = RenderAPICore::instance().getName();
  953. if (target == RenderAPIDX11 || target == RenderAPIOpenGL)
  954. {
  955. switch (type)
  956. {
  957. case GPT_VERTEX_PROGRAM:
  958. return GPP_VS_5_0;
  959. case GPT_FRAGMENT_PROGRAM:
  960. return GPP_FS_5_0;
  961. case GPT_GEOMETRY_PROGRAM:
  962. return GPP_GS_5_0;
  963. case GPT_HULL_PROGRAM:
  964. return GPP_HS_5_0;
  965. case GPT_DOMAIN_PROGRAM:
  966. return GPP_DS_5_0;
  967. case GPT_COMPUTE_PROGRAM:
  968. return GPP_CS_5_0;
  969. }
  970. }
  971. else if (target == RenderAPIDX9)
  972. {
  973. switch (type)
  974. {
  975. case GPT_VERTEX_PROGRAM:
  976. return GPP_VS_3_0;
  977. case GPT_FRAGMENT_PROGRAM:
  978. return GPP_FS_3_0;
  979. }
  980. }
  981. return GPP_NONE;
  982. }
  983. }