BsSLFXCompiler.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #pragma once
  2. #include "BsSLPrerequisites.h"
  3. #include "BsShader.h"
  4. #include "BsGpuProgram.h"
  5. extern "C" {
  6. #include "BsASTFX.h"
  7. }
  8. namespace BansheeEngine
  9. {
  10. /**
  11. * @brief Transforms a source file written in BSL FX syntax into a Shader object.
  12. */
  13. class BSLFXCompiler
  14. {
  15. /**
  16. * @brief Represents a block of code written in a GPU program language for
  17. * a specific GPU program type. (i.e. non-FX code)
  18. */
  19. struct CodeBlock
  20. {
  21. GpuProgramType type;
  22. String code;
  23. };
  24. public:
  25. /**
  26. * @brief Transforms a source file written in BSL FX syntax into a Shader object.
  27. *
  28. * @note If error occurs a nullptr will be returned and the error will be logged.
  29. */
  30. static ShaderPtr compile(const String& source);
  31. private:
  32. /**
  33. * @brief Converts the provided source into an abstract syntax tree using the
  34. * lexer & parser for BSL FX syntax.
  35. */
  36. static void parseFX(ParseState* parseState, const char* source);
  37. /**
  38. * @brief Retrieves non-FX code blocks (i.e. actual shader code) from the source code and
  39. * removes them from the input so all that remains is a pure FX code. Found blocks
  40. * are returned so they may be compiled using their appropriate compiler.
  41. */
  42. static Vector<CodeBlock> parseCodeBlocks(String& source);
  43. /**
  44. * @brief Converts FX renderer name into an in-engine renderer identifier.
  45. */
  46. static StringID parseRenderer(const String& name);
  47. /**
  48. * @brief Converts FX language into an in-engine shader language (e.g. hlsl, glsl) and
  49. * a rendering API that supports the provided language.
  50. */
  51. static void parseLanguage(const String& name, StringID& renderAPI, String& language);
  52. /**
  53. * @brief Maps FX buffer usage enum into in-engine param block usage.
  54. */
  55. static GpuParamBlockUsage parseBlockUsage(BufferUsageValue usage);
  56. /**
  57. * @brief Maps FX filter mode enum into in-engine filter mode.
  58. */
  59. static UINT32 parseFilterMode(FilterValue filter);
  60. /**
  61. * @brief Maps FX comparison function enum into in-engine compare function.
  62. */
  63. static CompareFunction parseCompFunc(CompFuncValue compFunc);
  64. /**
  65. * @brief Maps FX addressing mode enum into in-engine addressing mode.
  66. */
  67. static TextureAddressingMode parseAddrMode(AddrModeValue addrMode);
  68. /**
  69. * @brief Maps FX operation to in-engine blend factor.
  70. */
  71. static BlendFactor parseBlendFactor(OpValue factor);
  72. /**
  73. * @brief Maps FX blend operation to in-engine blend operation.
  74. */
  75. static BlendOperation parseBlendOp(BlendOpValue op);
  76. /**
  77. * @brief Maps FX parameter type to in-engine shader parameter.
  78. *
  79. * @param type Input FX parameter type.
  80. * @param isObjType Output parameter signaling whether the in-engine parameter is
  81. * a data or an object type.
  82. * @param typeId Type ID corresponding to a value of in-game GpuParamDataType or GpuParamObjectType
  83. * enum (depending on "isObjType").
  84. */
  85. static void parseParamType(ParamType type, bool& isObjType, UINT32& typeId);
  86. /**
  87. * @brief Maps FX operation to in-engine stencil operation.
  88. */
  89. static StencilOperation parseStencilOp(OpValue op);
  90. /**
  91. * @brief Maps FX cull mode enum to in-engine cull mode.
  92. */
  93. static CullingMode parseCullMode(CullModeValue cm);
  94. /**
  95. * @brief Maps FX fill mode enum to in-engine fill mode.
  96. */
  97. static PolygonMode parseFillMode(FillModeValue fm);
  98. /**
  99. * @brief Populates the front facing operation portion of the depth-stencil state descriptor
  100. * from the provided stencil-op AST node.
  101. */
  102. static void parseStencilFront(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode);
  103. /**
  104. * @brief Populates the back backing operation portion of the depth-stencil state descriptor
  105. * from the provided stencil-op AST node.
  106. */
  107. static void parseStencilBack(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* stencilOpNode);
  108. /**
  109. * @brief Populates the addressing mode portion of the sampler state descriptor for U/V/W axes from
  110. * the provided addressing mode AST node.
  111. */
  112. static void parseAddrMode(SAMPLER_STATE_DESC& desc, ASTFXNode* addrModeNode);
  113. /**
  114. * @brief Populates the color (RGB) portion of the blend state descriptor from the provided
  115. * blend definition AST node.
  116. */
  117. static void parseColorBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode);
  118. /**
  119. * @brief Populates the alpha portion of the blend state descriptor from the provided
  120. * blend definition AST node.
  121. */
  122. static void parseAlphaBlendDef(RENDER_TARGET_BLEND_STATE_DESC& desc, ASTFXNode* blendDefNode);
  123. /**
  124. * @brief Populates blend state descriptor for a single render target from the provided
  125. * AST node. Which target gets updated depends on the index set in the AST node.
  126. */
  127. static void parseRenderTargetBlendState(BLEND_STATE_DESC& desc, ASTFXNode* targetNode);
  128. /**
  129. * @brief Parses the blend state AST node and outputs a blend state object, or a nullptr
  130. * in case AST node is empty.
  131. */
  132. static BlendStatePtr parseBlendState(ASTFXNode* passNode);
  133. /**
  134. * @brief Parses the rasterizer state AST node and outputs a rasterizer state object, or a nullptr
  135. * in case AST node is empty.
  136. */
  137. static RasterizerStatePtr parseRasterizerState(ASTFXNode* passNode);
  138. /**
  139. * @brief Parses the depth-stencil state AST node and outputs a depth-stencil state object, or a nullptr
  140. * in case AST node is empty.
  141. */
  142. static DepthStencilStatePtr parseDepthStencilState(ASTFXNode* passNode);
  143. /**
  144. * @brief Parses the sampler state AST node and outputs a sampler state object, or a nullptr
  145. * in case AST node is empty.
  146. */
  147. static SamplerStatePtr parseSamplerState(ASTFXNode* samplerStateNode);
  148. /**
  149. * @brief Parses the pass AST node and generates a single pass object. Returns null
  150. * if no pass can be parsed. This method will generate any child state objects and
  151. * compile any child GPU programs.
  152. *
  153. * @param passNode Node to parse.
  154. * @param codeBlocks GPU program source code retrieved from "parseCodeBlocks".
  155. * @param includes Files paths relative to the current executable that will be injected
  156. * into GPU program code before compilation.
  157. * @param renderAPI API to use for compiling the GPU programs.
  158. * @param language GPU program language to use for parsing the provided code blocks.
  159. */
  160. static PassPtr parsePass(ASTFXNode* passNode, const Vector<CodeBlock>& codeBlocks, const Vector<String>& includes, const StringID& renderAPI, const String& language);
  161. /**
  162. * @brief Parses the technique AST node and generates a single technique object. Returns null
  163. * if no technique can be parsed.
  164. *
  165. * @param techniqueNode Node to parse.
  166. * @param codeBlocks GPU program source code retrieved from "parseCodeBlocks".
  167. */
  168. static TechniquePtr parseTechnique(ASTFXNode* techniqueNode, const Vector<CodeBlock>& codeBlocks);
  169. /**
  170. * @brief Parses the parameters AST node and populates the shader descriptor with information
  171. * about GPU program parameters and their default values.
  172. */
  173. static void parseParameters(SHADER_DESC& desc, ASTFXNode* parametersNode);
  174. /**
  175. * @brief Parses the blocks AST node and populates the shader descriptor with information
  176. * about GPU program parameter blocks.
  177. */
  178. static void parseBlocks(SHADER_DESC& desc, ASTFXNode* blocksNode);
  179. /**
  180. * @brief Parses the AST node hierarchy and generates a shader object.
  181. *
  182. * @param name Optional name for the shader.
  183. * @param rootNode Root node of the AST hierarchy retrieved from "parseFX".
  184. * @param codeBlocks GPU program source code retrieved from "parseCodeBlocks".
  185. *
  186. * @return A generated shader object, or a nullptr if shader was invalid.
  187. */
  188. static ShaderPtr parseShader(const String& name, ASTFXNode* rootNode, const Vector<CodeBlock>& codeBlocks);
  189. /**
  190. * @brief Converts a null-terminated string into a standard string, and eliminates quotes that are assumed
  191. * to be at the first and last index.
  192. */
  193. static String removeQuotes(const char* input);
  194. /**
  195. * @brief Retrieves a GPU program profile to use with the specified API and GPU program type.
  196. */
  197. static GpuProgramProfile getProfile(const StringID& renderAPI, GpuProgramType type);
  198. };
  199. }