blob: 03b95dc06534da55b28208a1e4934405823fe4a5 [file] [log] [blame]
John Bauman19bac1e2014-05-06 15:23:49 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2012 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#ifndef sw_Shader_hpp
13#define sw_Shader_hpp
14
15#include "Common/Types.hpp"
16
17#include <string>
18#include <vector>
19
20namespace sw
21{
22 class Shader
23 {
24 public:
25 enum ShaderType
26 {
27 SHADER_PIXEL = 0xFFFF,
28 SHADER_VERTEX = 0xFFFE,
29 SHADER_GEOMETRY = 0xFFFD
30 };
31
32 enum Opcode
33 {
34 // Matches order in d3d9types.h
35 OPCODE_NOP = 0,
36 OPCODE_MOV,
37 OPCODE_ADD,
38 OPCODE_SUB,
39 OPCODE_MAD,
40 OPCODE_MUL,
41 OPCODE_RCPX,
42 OPCODE_RSQX,
43 OPCODE_DP3,
44 OPCODE_DP4,
45 OPCODE_MIN,
46 OPCODE_MAX,
47 OPCODE_SLT,
48 OPCODE_SGE,
49 OPCODE_EXP2X, // D3DSIO_EXP
50 OPCODE_LOG2X, // D3DSIO_LOG
51 OPCODE_LIT,
52 OPCODE_ATT, // D3DSIO_DST
53 OPCODE_LRP,
54 OPCODE_FRC,
55 OPCODE_M4X4,
56 OPCODE_M4X3,
57 OPCODE_M3X4,
58 OPCODE_M3X3,
59 OPCODE_M3X2,
60 OPCODE_CALL,
61 OPCODE_CALLNZ,
62 OPCODE_LOOP,
63 OPCODE_RET,
64 OPCODE_ENDLOOP,
65 OPCODE_LABEL,
66 OPCODE_DCL,
67 OPCODE_POWX,
68 OPCODE_CRS,
69 OPCODE_SGN,
70 OPCODE_ABS,
71 OPCODE_NRM3, // D3DSIO_NRM
72 OPCODE_SINCOS,
73 OPCODE_REP,
74 OPCODE_ENDREP,
75 OPCODE_IF,
76 OPCODE_IFC,
77 OPCODE_ELSE,
78 OPCODE_ENDIF,
79 OPCODE_BREAK,
80 OPCODE_BREAKC,
81 OPCODE_MOVA,
82 OPCODE_DEFB,
83 OPCODE_DEFI,
84
85 OPCODE_TEXCOORD = 64,
86 OPCODE_TEXKILL,
87 OPCODE_TEX,
88 OPCODE_TEXBEM,
89 OPCODE_TEXBEML,
90 OPCODE_TEXREG2AR,
91 OPCODE_TEXREG2GB,
92 OPCODE_TEXM3X2PAD,
93 OPCODE_TEXM3X2TEX,
94 OPCODE_TEXM3X3PAD,
95 OPCODE_TEXM3X3TEX,
96 OPCODE_RESERVED0,
97 OPCODE_TEXM3X3SPEC,
98 OPCODE_TEXM3X3VSPEC,
99 OPCODE_EXPP,
100 OPCODE_LOGP,
101 OPCODE_CND,
102 OPCODE_DEF,
103 OPCODE_TEXREG2RGB,
104 OPCODE_TEXDP3TEX,
105 OPCODE_TEXM3X2DEPTH,
106 OPCODE_TEXDP3,
107 OPCODE_TEXM3X3,
108 OPCODE_TEXDEPTH,
109 OPCODE_CMP0, // D3DSIO_CMP
110 OPCODE_BEM,
111 OPCODE_DP2ADD,
112 OPCODE_DFDX, // D3DSIO_DSX
113 OPCODE_DFDY, // D3DSIO_DSY
114 OPCODE_TEXLDD,
115 OPCODE_CMP, // D3DSIO_SETP
116 OPCODE_TEXLDL,
117 OPCODE_BREAKP,
Alexis Hetu9bcb31d2015-07-22 17:03:26 -0400118 OPCODE_TEXSIZE,
John Bauman19bac1e2014-05-06 15:23:49 -0400119
120 OPCODE_PHASE = 0xFFFD,
121 OPCODE_COMMENT = 0xFFFE,
122 OPCODE_END = 0xFFFF,
123
124 OPCODE_PS_1_0 = 0xFFFF0100,
125 OPCODE_PS_1_1 = 0xFFFF0101,
126 OPCODE_PS_1_2 = 0xFFFF0102,
127 OPCODE_PS_1_3 = 0xFFFF0103,
128 OPCODE_PS_1_4 = 0xFFFF0104,
129 OPCODE_PS_2_0 = 0xFFFF0200,
130 OPCODE_PS_2_x = 0xFFFF0201,
131 OPCODE_PS_3_0 = 0xFFFF0300,
Nicolas Capens70589082015-10-15 00:42:20 -0400132
John Bauman19bac1e2014-05-06 15:23:49 -0400133 OPCODE_VS_1_0 = 0xFFFE0100,
134 OPCODE_VS_1_1 = 0xFFFE0101,
135 OPCODE_VS_2_0 = 0xFFFE0200,
136 OPCODE_VS_2_x = 0xFFFE0201,
137 OPCODE_VS_2_sw = 0xFFFE02FF,
138 OPCODE_VS_3_0 = 0xFFFE0300,
139 OPCODE_VS_3_sw = 0xFFFE03FF,
140
John Baumand4ae8632014-05-06 16:18:33 -0400141 OPCODE_NULL = 0x10000000, // Dead instruction, to be eliminated
142 OPCODE_WHILE,
John Bauman19bac1e2014-05-06 15:23:49 -0400143 OPCODE_ENDWHILE,
144 OPCODE_COS,
145 OPCODE_SIN,
146 OPCODE_TAN,
147 OPCODE_ACOS,
148 OPCODE_ASIN,
149 OPCODE_ATAN,
150 OPCODE_ATAN2,
Alexis Hetuaf1970c2015-04-17 14:26:07 -0400151 OPCODE_COSH,
152 OPCODE_SINH,
153 OPCODE_TANH,
154 OPCODE_ACOSH,
155 OPCODE_ASINH,
156 OPCODE_ATANH,
John Bauman19bac1e2014-05-06 15:23:49 -0400157 OPCODE_DP1,
158 OPCODE_DP2,
159 OPCODE_TRUNC,
160 OPCODE_FLOOR,
Alexis Hetuaf1970c2015-04-17 14:26:07 -0400161 OPCODE_ROUND,
162 OPCODE_ROUNDEVEN,
John Bauman19bac1e2014-05-06 15:23:49 -0400163 OPCODE_CEIL,
164 OPCODE_SQRT,
165 OPCODE_RSQ,
166 OPCODE_LEN2,
167 OPCODE_LEN3,
168 OPCODE_LEN4,
169 OPCODE_DIST1,
170 OPCODE_DIST2,
171 OPCODE_DIST3,
172 OPCODE_DIST4,
173 OPCODE_NRM2,
174 OPCODE_NRM4,
175 OPCODE_DIV,
176 OPCODE_MOD,
177 OPCODE_EXP2,
178 OPCODE_LOG2,
179 OPCODE_EXP,
180 OPCODE_LOG,
181 OPCODE_POW,
182 OPCODE_F2B, // Float to bool
183 OPCODE_B2F, // Bool to float
Alexis Hetuc4b57f52015-08-18 15:54:07 -0400184 OPCODE_F2I, // Float to int
185 OPCODE_I2F, // Int to float
186 OPCODE_F2U, // Float to uint
187 OPCODE_U2F, // Uint to float
Alexis Hetu8d78cf72015-08-28 14:24:45 -0400188 OPCODE_I2B, // Int to bool
189 OPCODE_B2I, // Bool to int
Alexis Hetuc3d95f32015-09-23 12:27:32 -0400190 OPCODE_DET2,
191 OPCODE_DET3,
192 OPCODE_DET4,
John Bauman19bac1e2014-05-06 15:23:49 -0400193 OPCODE_ALL,
194 OPCODE_ANY,
Alexis Hetuc4b57f52015-08-18 15:54:07 -0400195 OPCODE_NEG,
John Bauman19bac1e2014-05-06 15:23:49 -0400196 OPCODE_NOT,
197 OPCODE_OR,
198 OPCODE_XOR,
199 OPCODE_AND,
Alexis Hetu8d78cf72015-08-28 14:24:45 -0400200 OPCODE_EQ,
201 OPCODE_NE,
John Bauman19bac1e2014-05-06 15:23:49 -0400202 OPCODE_STEP,
203 OPCODE_SMOOTH,
Nicolas Capens813f97d2015-07-17 11:47:57 -0400204 OPCODE_ISNAN,
205 OPCODE_ISINF,
Alexis Hetu25d47fc2015-10-22 13:58:32 -0400206 OPCODE_TEXOFFSET,
207 OPCODE_TEXLDLOFFSET,
208 OPCODE_TEXELFETCH,
209 OPCODE_TEXELFETCHOFFSET,
210 OPCODE_TEXGRAD,
211 OPCODE_TEXGRADOFFSET,
Alexis Hetuaf1970c2015-04-17 14:26:07 -0400212 OPCODE_FLOATBITSTOINT,
213 OPCODE_FLOATBITSTOUINT,
214 OPCODE_INTBITSTOFLOAT,
215 OPCODE_UINTBITSTOFLOAT,
216 OPCODE_PACKSNORM2x16,
217 OPCODE_PACKUNORM2x16,
218 OPCODE_PACKHALF2x16,
219 OPCODE_UNPACKSNORM2x16,
220 OPCODE_UNPACKUNORM2x16,
221 OPCODE_UNPACKHALF2x16,
John Bauman19bac1e2014-05-06 15:23:49 -0400222 OPCODE_FORWARD1,
223 OPCODE_FORWARD2,
224 OPCODE_FORWARD3,
225 OPCODE_FORWARD4,
226 OPCODE_REFLECT1,
227 OPCODE_REFLECT2,
228 OPCODE_REFLECT3,
229 OPCODE_REFLECT4,
230 OPCODE_REFRACT1,
231 OPCODE_REFRACT2,
232 OPCODE_REFRACT3,
233 OPCODE_REFRACT4,
234 OPCODE_ICMP,
Alexis Hetuc4b57f52015-08-18 15:54:07 -0400235 OPCODE_UCMP,
John Bauman19bac1e2014-05-06 15:23:49 -0400236 OPCODE_SELECT,
237 OPCODE_EXTRACT,
238 OPCODE_INSERT,
239 OPCODE_DISCARD,
240 OPCODE_FWIDTH,
241 OPCODE_LEAVE, // Return before the end of the function
242 OPCODE_CONTINUE,
243 OPCODE_TEST, // Marks the end of the code that can be skipped by 'continue'
Alexis Hetuc4b57f52015-08-18 15:54:07 -0400244
245 // Integer opcodes
246 OPCODE_INEG,
247 OPCODE_IADD,
248 OPCODE_ISUB,
249 OPCODE_IMUL,
250 OPCODE_IDIV,
Alexis Hetu8d78cf72015-08-28 14:24:45 -0400251 OPCODE_IMAD,
Alexis Hetuc4b57f52015-08-18 15:54:07 -0400252 OPCODE_IMOD,
253 OPCODE_SHL,
254 OPCODE_ISHR,
255 OPCODE_IMIN,
256 OPCODE_IMAX,
257
258 // Unsigned integer opcodes
259 OPCODE_UDIV,
260 OPCODE_UMOD,
261 OPCODE_USHR,
262 OPCODE_UMIN,
263 OPCODE_UMAX,
John Bauman19bac1e2014-05-06 15:23:49 -0400264 };
265
266 static Opcode OPCODE_DP(int);
267 static Opcode OPCODE_LEN(int);
268 static Opcode OPCODE_DIST(int);
269 static Opcode OPCODE_NRM(int);
270 static Opcode OPCODE_FORWARD(int);
271 static Opcode OPCODE_REFLECT(int);
272 static Opcode OPCODE_REFRACT(int);
273
274 enum Control
275 {
276 CONTROL_RESERVED0,
277 CONTROL_GT,
278 CONTROL_EQ,
279 CONTROL_GE,
280 CONTROL_LT,
281 CONTROL_NE,
282 CONTROL_LE,
283 CONTROL_RESERVED1
284 };
285
286 enum SamplerType
287 {
288 SAMPLER_UNKNOWN,
289 SAMPLER_1D,
290 SAMPLER_2D,
291 SAMPLER_CUBE,
292 SAMPLER_VOLUME
293 };
294
295 enum Usage // For vertex input/output declarations
296 {
297 USAGE_POSITION = 0,
298 USAGE_BLENDWEIGHT = 1,
299 USAGE_BLENDINDICES = 2,
300 USAGE_NORMAL = 3,
301 USAGE_PSIZE = 4,
302 USAGE_TEXCOORD = 5,
303 USAGE_TANGENT = 6,
304 USAGE_BINORMAL = 7,
305 USAGE_TESSFACTOR = 8,
306 USAGE_POSITIONT = 9,
307 USAGE_COLOR = 10,
308 USAGE_FOG = 11,
309 USAGE_DEPTH = 12,
310 USAGE_SAMPLE = 13
311 };
312
313 enum ParameterType
314 {
315 PARAMETER_TEMP = 0,
316 PARAMETER_INPUT = 1,
317 PARAMETER_CONST = 2,
318 PARAMETER_TEXTURE = 3,
319 PARAMETER_ADDR = 3,
320 PARAMETER_RASTOUT = 4,
321 PARAMETER_ATTROUT = 5,
322 PARAMETER_TEXCRDOUT = 6,
323 PARAMETER_OUTPUT = 6,
324 PARAMETER_CONSTINT = 7,
325 PARAMETER_COLOROUT = 8,
326 PARAMETER_DEPTHOUT = 9,
327 PARAMETER_SAMPLER = 10,
328 PARAMETER_CONST2 = 11,
329 PARAMETER_CONST3 = 12,
330 PARAMETER_CONST4 = 13,
331 PARAMETER_CONSTBOOL = 14,
332 PARAMETER_LOOP = 15,
333 PARAMETER_TEMPFLOAT16 = 16,
334 PARAMETER_MISCTYPE = 17,
335 PARAMETER_LABEL = 18,
336 PARAMETER_PREDICATE = 19,
337
338 // PARAMETER_FLOAT1LITERAL,
339 // PARAMETER_FLOAT2LITERAL,
340 // PARAMETER_FLOAT3LITERAL,
341 PARAMETER_FLOAT4LITERAL,
342 PARAMETER_BOOL1LITERAL,
343 // PARAMETER_BOOL2LITERAL,
344 // PARAMETER_BOOL3LITERAL,
345 // PARAMETER_BOOL4LITERAL,
346 // PARAMETER_INT1LITERAL,
347 // PARAMETER_INT2LITERAL,
348 // PARAMETER_INT3LITERAL,
349 PARAMETER_INT4LITERAL,
350
351 PARAMETER_VOID
352 };
353
354 enum Modifier
355 {
356 MODIFIER_NONE,
357 MODIFIER_NEGATE,
358 MODIFIER_BIAS,
359 MODIFIER_BIAS_NEGATE,
360 MODIFIER_SIGN,
361 MODIFIER_SIGN_NEGATE,
362 MODIFIER_COMPLEMENT,
363 MODIFIER_X2,
364 MODIFIER_X2_NEGATE,
365 MODIFIER_DZ,
366 MODIFIER_DW,
367 MODIFIER_ABS,
368 MODIFIER_ABS_NEGATE,
369 MODIFIER_NOT
370 };
371
372 enum Analysis
373 {
374 // Flags indicating whether an instruction is affected by an execution enable mask
375 ANALYSIS_BRANCH = 0x00000001,
376 ANALYSIS_BREAK = 0x00000002,
377 ANALYSIS_CONTINUE = 0x00000004,
378 ANALYSIS_LEAVE = 0x00000008,
379 };
380
John Bauman19bac1e2014-05-06 15:23:49 -0400381 struct Parameter
382 {
383 union
384 {
385 struct
386 {
387 unsigned int index; // For registers types
388
John Bauman66b8ab22014-05-06 15:57:45 -0400389 struct
390 {
391 ParameterType type : 8;
392 unsigned int index;
393 unsigned int swizzle : 8;
394 unsigned int scale;
395 bool deterministic; // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
396 } rel;
John Bauman19bac1e2014-05-06 15:23:49 -0400397 };
398
399 float value[4]; // For float constants
400 int integer[4]; // For integer constants
401 int boolean[4]; // For boolean constants
402
403 struct
404 {
405 unsigned int label; // Label index
406 unsigned int callSite; // Call index (per label)
407 };
408 };
409
Alexis Hetu0085c442015-06-12 15:19:20 -0400410 Parameter() : index(0), type(PARAMETER_VOID)
John Bauman19bac1e2014-05-06 15:23:49 -0400411 {
John Bauman66b8ab22014-05-06 15:57:45 -0400412 rel.type = PARAMETER_VOID;
413 rel.index = 0;
414 rel.swizzle = 0;
415 rel.scale = 1;
416 rel.deterministic = false;
John Bauman19bac1e2014-05-06 15:23:49 -0400417 }
418
419 std::string string(ShaderType shaderType, unsigned short version) const;
420 std::string typeString(ShaderType shaderType, unsigned short version) const;
421 std::string relativeString() const;
422
423 ParameterType type : 8;
424 };
425
426 struct DestinationParameter : Parameter
427 {
428 union
429 {
430 unsigned char mask;
431
432 struct
433 {
434 bool x : 1;
435 bool y : 1;
436 bool z : 1;
437 bool w : 1;
438 };
439 };
440
441 DestinationParameter() : mask(0xF), integer(false), saturate(false), partialPrecision(false), centroid(false), shift(0)
442 {
443 }
444
445 std::string modifierString() const;
446 std::string shiftString() const;
447 std::string maskString() const;
448
449 bool integer : 1;
450 bool saturate : 1;
451 bool partialPrecision : 1;
452 bool centroid : 1;
453 signed char shift : 4;
454 };
455
456 struct SourceParameter : Parameter
457 {
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400458 SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE), bufferIndex(-1)
John Bauman19bac1e2014-05-06 15:23:49 -0400459 {
460 }
461
462 std::string swizzleString() const;
463 std::string preModifierString() const;
464 std::string postModifierString() const;
465
466 unsigned int swizzle : 8;
467 Modifier modifier : 8;
Alexis Hetu2c2a7b22015-10-27 16:12:11 -0400468 int bufferIndex : 8;
John Bauman19bac1e2014-05-06 15:23:49 -0400469 };
470
471 struct Instruction
472 {
473 explicit Instruction(Opcode opcode);
474 Instruction(const unsigned long *token, int size, unsigned char majorVersion);
475
476 virtual ~Instruction();
477
478 void parseOperationToken(unsigned long token, unsigned char majorVersion);
479 void parseDeclarationToken(unsigned long token);
480 void parseDestinationToken(const unsigned long *token, unsigned char majorVersion);
481 void parseSourceToken(int i, const unsigned long *token, unsigned char majorVersion);
482
483 std::string string(ShaderType shaderType, unsigned short version) const;
484 static std::string swizzleString(ParameterType type, unsigned char swizzle);
485 std::string operationString(unsigned short version) const;
486 std::string controlString() const;
487
488 bool isBranch() const;
489 bool isCall() const;
490 bool isBreak() const;
491 bool isLoop() const;
492 bool isEndLoop() const;
493
Nicolas Capensc6e8ab12014-05-06 23:31:07 -0400494 bool isPredicated() const;
495
John Bauman19bac1e2014-05-06 15:23:49 -0400496 Opcode opcode;
Nicolas Capens70589082015-10-15 00:42:20 -0400497
John Bauman19bac1e2014-05-06 15:23:49 -0400498 union
499 {
500 Control control;
Nicolas Capens70589082015-10-15 00:42:20 -0400501
John Bauman19bac1e2014-05-06 15:23:49 -0400502 struct
503 {
504 unsigned char project : 1;
505 unsigned char bias : 1;
506 };
507 };
508
509 bool predicate;
510 bool predicateNot; // Negative predicate
511 unsigned char predicateSwizzle;
512
513 bool coissue;
514 SamplerType samplerType;
515 Usage usage;
516 unsigned char usageIndex;
517
518 DestinationParameter dst;
Alexis Hetu25d47fc2015-10-22 13:58:32 -0400519 SourceParameter src[5];
John Bauman19bac1e2014-05-06 15:23:49 -0400520
521 union
522 {
523 unsigned int analysis;
524
525 struct
526 {
527 // Keep in sync with Shader::Analysis flags
528 unsigned int analysisBranch : 1;
529 unsigned int analysisBreak : 1;
530 unsigned int analysisContinue : 1;
531 unsigned int analysisLeave : 1;
532 };
533 };
534 };
535
536 Shader();
537
Ping-Hao Wu6dbd5fe2015-03-20 13:21:28 -0700538 virtual ~Shader();
John Bauman19bac1e2014-05-06 15:23:49 -0400539
540 int getSerialID() const;
Alexis Hetu8dcce862014-11-13 16:43:44 -0500541 size_t getLength() const;
John Bauman19bac1e2014-05-06 15:23:49 -0400542 ShaderType getShaderType() const;
543 unsigned short getVersion() const;
544
545 void append(Instruction *instruction);
546 void declareSampler(int i);
547
548 const Instruction *getInstruction(unsigned int i) const;
549 int size(unsigned long opcode) const;
550 static int size(unsigned long opcode, unsigned short version);
551
552 void print(const char *fileName, ...) const;
553 void printInstruction(int index, const char *fileName) const;
554
555 static bool maskContainsComponent(int mask, int component);
556 static bool swizzleContainsComponent(int swizzle, int component);
557 static bool swizzleContainsComponentMasked(int swizzle, int component, int mask);
558
559 bool containsDynamicBranching() const;
560 bool containsBreakInstruction() const;
561 bool containsContinueInstruction() const;
562 bool containsLeaveInstruction() const;
Nicolas Capenseafdb222015-05-15 15:24:08 -0400563 bool containsDefineInstruction() const;
John Bauman19bac1e2014-05-06 15:23:49 -0400564 bool usesSampler(int i) const;
565
566 struct Semantic
567 {
568 Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF) : usage(usage), index(index), centroid(false)
569 {
570 }
571
572 bool operator==(const Semantic &semantic) const
573 {
574 return usage == semantic.usage && index == semantic.index;
575 }
576
577 bool active() const
578 {
579 return usage != 0xFF;
580 }
581
582 unsigned char usage;
583 unsigned char index;
584 bool centroid;
585 };
586
John Baumand4ae8632014-05-06 16:18:33 -0400587 void optimize();
John Bauman19bac1e2014-05-06 15:23:49 -0400588 virtual void analyze() = 0;
589
590 // FIXME: Private
591 unsigned int dirtyConstantsF;
592 unsigned int dirtyConstantsI;
593 unsigned int dirtyConstantsB;
594
595 bool dynamicallyIndexedTemporaries;
596 bool dynamicallyIndexedInput;
597 bool dynamicallyIndexedOutput;
598
599 protected:
600 void parse(const unsigned long *token);
601
John Baumand4ae8632014-05-06 16:18:33 -0400602 void optimizeLeave();
603 void optimizeCall();
604 void removeNull();
605
John Bauman19bac1e2014-05-06 15:23:49 -0400606 void analyzeDirtyConstants();
607 void analyzeDynamicBranching();
608 void analyzeSamplers();
609 void analyzeCallSites();
610 void analyzeDynamicIndexing();
Nicolas Capens5d961882016-01-01 23:18:14 -0500611 void markFunctionAnalysis(unsigned int functionLabel, Analysis flag);
John Bauman19bac1e2014-05-06 15:23:49 -0400612
613 ShaderType shaderType;
614
615 union
616 {
617 unsigned short version;
618
619 struct
620 {
621 unsigned char minorVersion;
622 unsigned char majorVersion;
623 };
624 };
625
626 std::vector<Instruction*> instruction;
627
628 unsigned short usedSamplers; // Bit flags
629
630 private:
631 const int serialID;
632 static volatile int serialCounter;
633
634 bool dynamicBranching;
635 bool containsBreak;
636 bool containsContinue;
637 bool containsLeave;
Nicolas Capenseafdb222015-05-15 15:24:08 -0400638 bool containsDefine;
John Bauman19bac1e2014-05-06 15:23:49 -0400639 };
640}
641
642#endif // sw_Shader_hpp