1 | /*
|
2 | * Xsc.h
|
3 | *
|
4 | * This file is part of the XShaderCompiler project (Copyright (c) 2014-2017 by Lukas Hermanns)
|
5 | * See "LICENSE.txt" for license information.
|
6 | */
|
7 |
|
8 | #ifndef XSC_XSC_H
|
9 | #define XSC_XSC_H
|
10 |
|
11 |
|
12 | #include "Export.h"
|
13 | #include "Log.h"
|
14 | #include "IncludeHandler.h"
|
15 | #include "Targets.h"
|
16 | #include "Version.h"
|
17 | #include "Reflection.h"
|
18 |
|
19 | #include <string>
|
20 | #include <vector>
|
21 | #include <map>
|
22 | #include <istream>
|
23 | #include <ostream>
|
24 | #include <memory>
|
25 |
|
26 |
|
27 | /**
|
28 | \mainpage
|
29 | Welcome to the XShaderCompiler, Version 0.10 Alpha
|
30 |
|
31 | Here is a quick start example:
|
32 | \code
|
33 | #include <Xsc/Xsc.h>
|
34 | #include <fstream>
|
35 |
|
36 | int main()
|
37 | {
|
38 | // Open input and output streams
|
39 | auto inputStream = std::make_shared<std::ifstream>("Example.hlsl");
|
40 | std::ofstream outputStream("Example.VS.vert");
|
41 |
|
42 | // Initialize shader input descriptor structure
|
43 | Xsc::ShaderInput inputDesc;
|
44 | {
|
45 | inputDesc.sourceCode = inputStream;
|
46 | inputDesc.shaderVersion = Xsc::InputShaderVersion::HLSL5;
|
47 | inputDesc.entryPoint = "VS";
|
48 | inputDesc.shaderTarget = Xsc::ShaderTarget::VertexShader;
|
49 | }
|
50 |
|
51 | // Initialize shader output descriptor structure
|
52 | Xsc::ShaderOutput outputDesc;
|
53 | {
|
54 | outputDesc.sourceCode = &outputStream;
|
55 | outputDesc.shaderVersion = Xsc::OutputShaderVersion::GLSL330;
|
56 | }
|
57 |
|
58 | // Compile HLSL code into GLSL
|
59 | Xsc::StdLog log;
|
60 | bool result = Xsc::CompileShader(inputDesc, outputDesc, &log);
|
61 |
|
62 | // Show compilation status
|
63 | if (result)
|
64 | std::cout << "Compilation successful" << std::endl;
|
65 | else
|
66 | std::cerr << "Compilation failed" << std::endl;
|
67 |
|
68 | return 0;
|
69 | }
|
70 | \endcode
|
71 | */
|
72 |
|
73 |
|
74 | //! Main XShaderCompiler namespace
|
75 | namespace Xsc
|
76 | {
|
77 |
|
78 |
|
79 | /* ===== Public structures ===== */
|
80 |
|
81 | //! Compiler warning flags.
|
82 | struct Warnings
|
83 | {
|
84 | enum : unsigned int
|
85 | {
|
86 | Basic = (1 << 0), //!< Warning for basic issues (control path, disabled code etc.).
|
87 | Syntax = (1 << 1), //!< Warning for syntactic issues.
|
88 | PreProcessor = (1 << 2), //!< Warning for pre-processor issues.
|
89 | UnusedVariables = (1 << 3), //!< Warning for unused variables.
|
90 | EmptyStatementBody = (1 << 4), //!< Warning for statements with empty body.
|
91 | ImplicitTypeConversions = (1 << 5), //!< Warning for specific implicit type conversions.
|
92 | DeclarationShadowing = (1 << 6), //!< Warning for declarations that shadow a previous local (e.g. for-loops or variables in class hierarchy).
|
93 | UnlocatedObjects = (1 << 7), //!< Warning for optional objects that where not found.
|
94 | RequiredExtensions = (1 << 8), //!< Warning for required extensions in the output code.
|
95 | CodeReflection = (1 << 9), //!< Warning for issues during code reflection.
|
96 | IndexBoundary = (1 << 10), //!< Warning for index boundary violations.
|
97 |
|
98 | All = (~0u), //!< All warnings.
|
99 | };
|
100 | };
|
101 |
|
102 | /**
|
103 | \brief Language extension flags.
|
104 | \remakrs This is only supported, if the compiler was build with the 'XSC_ENABLE_LANGUAGE_EXT' macro.
|
105 | */
|
106 | struct Extensions
|
107 | {
|
108 | enum : unsigned int
|
109 | {
|
110 | LayoutAttribute = (1 << 0), //!< Enables the 'layout' attribute extension (e.g. "[layout(rgba8)]").
|
111 | SpaceAttribute = (1 << 1), //!< Enables the 'space' attribute extension for a stronger type system (e.g. "[space(OBJECT, MODEL)]").
|
112 |
|
113 | All = (~0u) //!< All extensions.
|
114 | };
|
115 | };
|
116 |
|
117 | //! Formatting descriptor structure for the output shader.
|
118 | struct Formatting
|
119 | {
|
120 | //! If true, scopes are always written in braces. By default false.
|
121 | bool alwaysBracedScopes = false;
|
122 |
|
123 | //! If true, blank lines are allowed. By default true.
|
124 | bool blanks = true;
|
125 |
|
126 | //! If true, wrapper functions for special intrinsics are written in a compact formatting (i.e. all in one line). By default false.
|
127 | bool compactWrappers = false;
|
128 |
|
129 | //! Indentation string for code generation. By default std::string(4, ' ').
|
130 | std::string indent = " " ;
|
131 |
|
132 | //! If true, line marks are allowed. By default false.
|
133 | bool lineMarks = false;
|
134 |
|
135 | //! If true, auto-formatting of line separation is allowed. By default true.
|
136 | bool lineSeparation = true;
|
137 |
|
138 | //! If true, the '{'-braces for an open scope gets its own line. If false, braces are written like in Java coding conventions. By default true.
|
139 | bool newLineOpenScope = true;
|
140 | };
|
141 |
|
142 | //! Structure for additional translation options.
|
143 | struct Options
|
144 | {
|
145 | //! If true, the shader output may contain GLSL extensions, if the target shader version is too low. By default false.
|
146 | bool allowExtensions = false;
|
147 |
|
148 | /**
|
149 | \brief If true, binding slots for all buffer types will be generated sequentially, starting with index at 'autoBindingStartSlot'. By default false.
|
150 | \remarks This will also enable 'explicitBinding'.
|
151 | */
|
152 | bool autoBinding = false;
|
153 |
|
154 | //! Index to start generating binding slots from. Only relevant if 'autoBinding' is enabled. By default 0.
|
155 | int autoBindingStartSlot = 0;
|
156 |
|
157 | //! If true, explicit binding slots are enabled. By default false.
|
158 | bool explicitBinding = false;
|
159 |
|
160 | //! If true, generate 'location' layout qualifiers for fragment program outputs. This can also be enabled by setting
|
161 | //! 'explicitBinding' to true.
|
162 | bool fragmentLocations = false;
|
163 |
|
164 | //! If true, code obfuscation is performed. By default false.
|
165 | bool obfuscate = false;
|
166 |
|
167 | //! If true, little code optimizations are performed. By default false.
|
168 | bool optimize = false;
|
169 |
|
170 | //TODO: maybe merge this option with "optimize" (preferWrappers == !optimize)
|
171 | //! If true, intrinsics are prefered to be implemented as wrappers (instead of inlining). By default false.
|
172 | bool preferWrappers = false;
|
173 |
|
174 | //! If true, only the preprocessed source code will be written out. By default false.
|
175 | bool preprocessOnly = false;
|
176 |
|
177 | //! If true, commentaries are preserved for each statement. By default false.
|
178 | bool = false;
|
179 |
|
180 | //! If true, matrices have row-major alignment. Otherwise the matrices have column-major alignment. By default false.
|
181 | bool rowMajorAlignment = false;
|
182 |
|
183 | //! If true, generated GLSL code will contain separate sampler and texture objects when supported. By default true.
|
184 | bool separateSamplers = true;
|
185 |
|
186 | //! If true, generated GLSL code will support the 'ARB_separate_shader_objects' extension. By default false.
|
187 | bool separateShaders = false;
|
188 |
|
189 | //! If true, the AST (Abstract Syntax Tree) will be written to the log output. By default false.
|
190 | bool showAST = false;
|
191 |
|
192 | //! If true, the timings of the different compilation processes are written to the log output. By default false.
|
193 | bool showTimes = false;
|
194 |
|
195 | //TODO: remove this option, and determine automatically when unrolling initializers are required!
|
196 | //! If true, array initializations will be unrolled. By default false.
|
197 | bool unrollArrayInitializers = false;
|
198 |
|
199 | //! If true, the source code is only validated, but no output code will be generated. By default false.
|
200 | bool validateOnly = false;
|
201 | };
|
202 |
|
203 | //! Name mangling descriptor structure for shader input/output variables (also referred to as "varyings"), temporary variables, and reserved keywords.
|
204 | struct NameMangling
|
205 | {
|
206 | /**
|
207 | \brief Name mangling prefix for shader input variables. By default "xsv_".
|
208 | \remarks This can also be empty or equal to "outputPrefix".
|
209 | */
|
210 | std::string inputPrefix = "xsv_" ;
|
211 |
|
212 | /**
|
213 | \brief Name mangling prefix for shader output variables. By default "xsv_".
|
214 | \remarks This can also be empty or equal to "inputPrefix".
|
215 | */
|
216 | std::string outputPrefix = "xsv_" ;
|
217 |
|
218 | /**
|
219 | \brief Name mangling prefix for reserved words (such as "texture", "main", "sin" etc.). By default "xsr_".
|
220 | \remarks This must not be equal to any of the other prefixes and it must not be empty.
|
221 | */
|
222 | std::string reservedWordPrefix = "xsr_" ;
|
223 |
|
224 | /**
|
225 | \brief Name mangling prefix for temporary variables. By default "xst_".
|
226 | \remarks This must not be equal to any of the other prefixes and it must not be empty.
|
227 | */
|
228 | std::string temporaryPrefix = "xst_" ;
|
229 |
|
230 | /**
|
231 | \brief Name mangling prefix for namespaces like structures or classes. By default "xsn_".
|
232 | \remarks This can also be empty, but if it's not empty it must not be equal to any of the other prefixes.
|
233 | */
|
234 | std::string namespacePrefix = "xsn_" ;
|
235 |
|
236 | /**
|
237 | If true, shader input/output variables are always renamed to their semantics,
|
238 | even for vertex input and fragment output. Otherwise, their original identifiers are used. By default false.
|
239 | */
|
240 | bool useAlwaysSemantics = false;
|
241 |
|
242 | /**
|
243 | \brief If true, the data fields of a 'buffer'-objects is renamed rather than the outer identifier. By default false.
|
244 | \remarks This can be useful for external diagnostic tools, to access the original identifier.
|
245 | */
|
246 | bool renameBufferFields = false;
|
247 | };
|
248 |
|
249 | //! Shader input descriptor structure.
|
250 | struct ShaderInput
|
251 | {
|
252 | //! Specifies the filename of the input shader code. This is an optional attribute, and only a hint to the compiler.
|
253 | std::string filename;
|
254 |
|
255 | //! Specifies the input source code stream.
|
256 | std::shared_ptr<std::istream> sourceCode;
|
257 |
|
258 | //! Specifies the input shader version (e.g. InputShaderVersion::HLSL5 for "HLSL 5"). By default InputShaderVersion::HLSL5.
|
259 | InputShaderVersion shaderVersion = InputShaderVersion::HLSL5;
|
260 |
|
261 | //! Specifies the target shader (Vertex, Fragment etc.). By default ShaderTarget::Undefined.
|
262 | ShaderTarget shaderTarget = ShaderTarget::Undefined;
|
263 |
|
264 | //! Specifies the HLSL shader entry point. By default "main".
|
265 | std::string entryPoint = "main" ;
|
266 |
|
267 | /**
|
268 | \brief Specifies the secondary HLSL shader entry point.
|
269 | \remarks This is only used for a Tessellation-Control Shader (alias Hull Shader) entry point,
|
270 | when a Tessellation-Control Shader (alias Domain Shader) is the output target.
|
271 | This is required to translate all Tessellation-Control attributes (i.e. "partitioning" and "outputtopology")
|
272 | to the Tessellation-Evaluation output shader. If this is empty, the default values for these attributes are used.
|
273 | */
|
274 | std::string secondaryEntryPoint;
|
275 |
|
276 | /**
|
277 | \brief Compiler warning flags. This can be a bitwise OR combination of the "Warnings" enumeration entries. By default 0.
|
278 | \see Warnings
|
279 | */
|
280 | unsigned int warnings = 0;
|
281 |
|
282 | /**
|
283 | \brief Language extension flags. This can be a bitwise OR combination of the "Extensions" enumeration entries. By default 0.
|
284 | \remarks This is ignored, if the compiler was not build with the 'XSC_ENABLE_LANGUAGE_EXT' macro.
|
285 | \see Extensions
|
286 | */
|
287 | unsigned int extensions = 0;
|
288 |
|
289 | /**
|
290 | \brief Optional pointer to the implementation of the "IncludeHandler" interface. By default null.
|
291 | \remarks If this is null, the default include handler will be used, which will include files with the STL input file streams.
|
292 | */
|
293 | IncludeHandler* includeHandler = nullptr;
|
294 | };
|
295 |
|
296 | //! Vertex shader semantic (or rather attribute) layout structure.
|
297 | struct VertexSemantic
|
298 | {
|
299 | //! Specifies the shader semantic (or rather attribute).
|
300 | std::string semantic;
|
301 |
|
302 | //! Specifies the binding location.
|
303 | int location;
|
304 | };
|
305 |
|
306 | //! Shader output descriptor structure.
|
307 | struct ShaderOutput
|
308 | {
|
309 | //! Specifies the filename of the output shader code. This is an optional attribute, and only a hint to the compiler.
|
310 | std::string filename;
|
311 |
|
312 | //! Specifies the output source code stream. This will contain the output code. This must not be null when passed to the "CompileShader" function!
|
313 | std::ostream* sourceCode = nullptr;
|
314 |
|
315 | //! Specifies the output shader version. By default OutputShaderVersion::GLSL (to auto-detect minimum required version).
|
316 | OutputShaderVersion shaderVersion = OutputShaderVersion::GLSL;
|
317 |
|
318 | //! Optional list of vertex semantic layouts, to bind a vertex attribute (semantic name) to a location index (only used when 'explicitBinding' is true).
|
319 | std::vector<VertexSemantic> vertexSemantics;
|
320 |
|
321 | //! Additional options to configure the code generation.
|
322 | Options options;
|
323 |
|
324 | //! Output code formatting descriptor.
|
325 | Formatting formatting;
|
326 |
|
327 | //! Specifies the options for name mangling.
|
328 | NameMangling nameMangling;
|
329 | };
|
330 |
|
331 | //! Descriptor structure for the shader disassembler.
|
332 | struct AssemblyDescriptor
|
333 | {
|
334 | //! Specifies the intermediate language of the assembly input code. Currently only SPIR-V is supported. By default IntermediateLanguage::SPIRV.
|
335 | IntermediateLanguage intermediateLanguage = IntermediateLanguage::SPIRV;
|
336 |
|
337 | //! Specifies the prefix character to be used for ID numbers in the SPIR-V instructions.
|
338 | char idPrefixChar = '%';
|
339 |
|
340 | //! Specifies whether to show the module header or not. By default true.
|
341 | bool = true;
|
342 |
|
343 | //! Specifies whether to show the instruction byte offsets in the disassembly or not. By default true.
|
344 | bool showOffsets = true;
|
345 |
|
346 | //! Specifies whether to indent the instruction operands or not. By default true.
|
347 | bool indentOperands = true;
|
348 | };
|
349 |
|
350 |
|
351 | /* ===== Public functions ===== */
|
352 |
|
353 | /**
|
354 | \brief Cross compiles the shader code from the specified input stream into the specified output shader code.
|
355 | \param[in] inputDesc Input shader code descriptor.
|
356 | \param[in] outputDesc Output shader code descriptor.
|
357 | \param[in] log Optional pointer to an output log. Inherit from the "Log" class interface. By default null.
|
358 | \param[out] reflectionData Optional pointer to a code reflection data structure. By default null.
|
359 | \return True if the code has been translated successfully.
|
360 | \throw std::invalid_argument If either the input or output streams are null.
|
361 | \see ShaderInput
|
362 | \see ShaderOutput
|
363 | \see Log
|
364 | \see ReflectionData
|
365 | */
|
366 | XSC_EXPORT bool CompileShader(
|
367 | const ShaderInput& inputDesc,
|
368 | const ShaderOutput& outputDesc,
|
369 | Log* log = nullptr,
|
370 | Reflection::ReflectionData* reflectionData = nullptr
|
371 | );
|
372 |
|
373 | /**
|
374 | \brief Disassembles the SPIR-V binary code into a human readable code.
|
375 | \param[in,out] streamIn Specifies the input stream of the SPIR-V binary code.
|
376 | \param[in,out] streamOut Specifies the output stream of the human readable code.
|
377 | \param[in] formatting Specifies the output formatting.
|
378 | \throws std::runtime_error If the disassembling failed.
|
379 | \throws std::invalid_argument If 'desc.intermediateLanguage' has an invalid value.
|
380 | */
|
381 | XSC_EXPORT void DisassembleShader(
|
382 | std::istream& streamIn,
|
383 | std::ostream& streamOut,
|
384 | const AssemblyDescriptor& desc = {}
|
385 | );
|
386 |
|
387 |
|
388 | } // /namespace Xsc
|
389 |
|
390 |
|
391 | #endif
|
392 |
|
393 |
|
394 |
|
395 | // ================================================================================ |