OSDN Git Service

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