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 Parametersw::Shader::Parameter425 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 DestinationParametersw::Shader::DestinationParameter456 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 { SourceParametersw::Shader::SourceParameter473 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 { Semanticsw::Shader::Semantic583 Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF, bool flat = false) : usage(usage), index(index), centroid(false), flat(flat) 584 { 585 } 586 operator ==sw::Shader::Semantic587 bool operator==(const Semantic &semantic) const 588 { 589 return usage == semantic.usage && index == semantic.index; 590 } 591 activesw::Shader::Semantic592 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 658