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
29Welcome to the XShaderCompiler, Version 0.10 Alpha
30
31Here is a quick start example:
32\code
33#include <Xsc/Xsc.h>
34#include <fstream>
35
36int 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
75namespace Xsc
76{
77
78
79/* ===== Public structures ===== */
80
81//! Compiler warning flags.
82struct 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*/
106struct 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.
118struct 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.
143struct 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 preserveComments = 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.
204struct 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.
250struct 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.
297struct 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.
307struct 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.
332struct 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 showHeader = 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*/
366XSC_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*/
381XSC_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// ================================================================================