Shader.hpp revision c3d95f36258143af6cca041ede521995d8f890ea
1// 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, 118 119 OPCODE_PHASE = 0xFFFD, 120 OPCODE_COMMENT = 0xFFFE, 121 OPCODE_END = 0xFFFF, 122 123 OPCODE_PS_1_0 = 0xFFFF0100, 124 OPCODE_PS_1_1 = 0xFFFF0101, 125 OPCODE_PS_1_2 = 0xFFFF0102, 126 OPCODE_PS_1_3 = 0xFFFF0103, 127 OPCODE_PS_1_4 = 0xFFFF0104, 128 OPCODE_PS_2_0 = 0xFFFF0200, 129 OPCODE_PS_2_x = 0xFFFF0201, 130 OPCODE_PS_3_0 = 0xFFFF0300, 131 132 OPCODE_VS_1_0 = 0xFFFE0100, 133 OPCODE_VS_1_1 = 0xFFFE0101, 134 OPCODE_VS_2_0 = 0xFFFE0200, 135 OPCODE_VS_2_x = 0xFFFE0201, 136 OPCODE_VS_2_sw = 0xFFFE02FF, 137 OPCODE_VS_3_0 = 0xFFFE0300, 138 OPCODE_VS_3_sw = 0xFFFE03FF, 139 140 OPCODE_NULL = 0x10000000, // Dead instruction, to be eliminated 141 OPCODE_WHILE, 142 OPCODE_ENDWHILE, 143 OPCODE_COS, 144 OPCODE_SIN, 145 OPCODE_TAN, 146 OPCODE_ACOS, 147 OPCODE_ASIN, 148 OPCODE_ATAN, 149 OPCODE_ATAN2, 150 OPCODE_COSH, 151 OPCODE_SINH, 152 OPCODE_TANH, 153 OPCODE_ACOSH, 154 OPCODE_ASINH, 155 OPCODE_ATANH, 156 OPCODE_DP1, 157 OPCODE_DP2, 158 OPCODE_TRUNC, 159 OPCODE_FLOOR, 160 OPCODE_ROUND, 161 OPCODE_ROUNDEVEN, 162 OPCODE_CEIL, 163 OPCODE_SQRT, 164 OPCODE_RSQ, 165 OPCODE_LEN2, 166 OPCODE_LEN3, 167 OPCODE_LEN4, 168 OPCODE_DIST1, 169 OPCODE_DIST2, 170 OPCODE_DIST3, 171 OPCODE_DIST4, 172 OPCODE_NRM2, 173 OPCODE_NRM4, 174 OPCODE_DIV, 175 OPCODE_MOD, 176 OPCODE_EXP2, 177 OPCODE_LOG2, 178 OPCODE_EXP, 179 OPCODE_LOG, 180 OPCODE_POW, 181 OPCODE_F2B, // Float to bool 182 OPCODE_B2F, // Bool to float 183 OPCODE_F2I, // Float to int 184 OPCODE_I2F, // Int to float 185 OPCODE_F2U, // Float to uint 186 OPCODE_U2F, // Uint to float 187 OPCODE_I2B, // Int to bool 188 OPCODE_B2I, // Bool to int 189 OPCODE_U2B, // Uint to bool 190 OPCODE_B2U, // Bool to uint 191 OPCODE_DET2, 192 OPCODE_DET3, 193 OPCODE_DET4, 194 OPCODE_ALL, 195 OPCODE_ANY, 196 OPCODE_NEG, 197 OPCODE_NOT, 198 OPCODE_OR, 199 OPCODE_XOR, 200 OPCODE_AND, 201 OPCODE_EQ, 202 OPCODE_NE, 203 OPCODE_STEP, 204 OPCODE_SMOOTH, 205 OPCODE_ISNAN, 206 OPCODE_ISINF, 207 OPCODE_FLOATBITSTOINT, 208 OPCODE_FLOATBITSTOUINT, 209 OPCODE_INTBITSTOFLOAT, 210 OPCODE_UINTBITSTOFLOAT, 211 OPCODE_PACKSNORM2x16, 212 OPCODE_PACKUNORM2x16, 213 OPCODE_PACKHALF2x16, 214 OPCODE_UNPACKSNORM2x16, 215 OPCODE_UNPACKUNORM2x16, 216 OPCODE_UNPACKHALF2x16, 217 OPCODE_FORWARD1, 218 OPCODE_FORWARD2, 219 OPCODE_FORWARD3, 220 OPCODE_FORWARD4, 221 OPCODE_REFLECT1, 222 OPCODE_REFLECT2, 223 OPCODE_REFLECT3, 224 OPCODE_REFLECT4, 225 OPCODE_REFRACT1, 226 OPCODE_REFRACT2, 227 OPCODE_REFRACT3, 228 OPCODE_REFRACT4, 229 OPCODE_ICMP, 230 OPCODE_UCMP, 231 OPCODE_SELECT, 232 OPCODE_EXTRACT, 233 OPCODE_INSERT, 234 OPCODE_DISCARD, 235 OPCODE_FWIDTH, 236 OPCODE_LEAVE, // Return before the end of the function 237 OPCODE_CONTINUE, 238 OPCODE_TEST, // Marks the end of the code that can be skipped by 'continue' 239 240 // Integer opcodes 241 OPCODE_INEG, 242 OPCODE_IADD, 243 OPCODE_ISUB, 244 OPCODE_IMUL, 245 OPCODE_IDIV, 246 OPCODE_IMAD, 247 OPCODE_IMOD, 248 OPCODE_SHL, 249 OPCODE_ISHR, 250 OPCODE_IMIN, 251 OPCODE_IMAX, 252 253 // Unsigned integer opcodes 254 OPCODE_UDIV, 255 OPCODE_UMOD, 256 OPCODE_USHR, 257 OPCODE_UMIN, 258 OPCODE_UMAX, 259 }; 260 261 static Opcode OPCODE_DP(int); 262 static Opcode OPCODE_LEN(int); 263 static Opcode OPCODE_DIST(int); 264 static Opcode OPCODE_NRM(int); 265 static Opcode OPCODE_FORWARD(int); 266 static Opcode OPCODE_REFLECT(int); 267 static Opcode OPCODE_REFRACT(int); 268 269 enum Control 270 { 271 CONTROL_RESERVED0, 272 CONTROL_GT, 273 CONTROL_EQ, 274 CONTROL_GE, 275 CONTROL_LT, 276 CONTROL_NE, 277 CONTROL_LE, 278 CONTROL_RESERVED1 279 }; 280 281 enum SamplerType 282 { 283 SAMPLER_UNKNOWN, 284 SAMPLER_1D, 285 SAMPLER_2D, 286 SAMPLER_CUBE, 287 SAMPLER_VOLUME 288 }; 289 290 enum Usage // For vertex input/output declarations 291 { 292 USAGE_POSITION = 0, 293 USAGE_BLENDWEIGHT = 1, 294 USAGE_BLENDINDICES = 2, 295 USAGE_NORMAL = 3, 296 USAGE_PSIZE = 4, 297 USAGE_TEXCOORD = 5, 298 USAGE_TANGENT = 6, 299 USAGE_BINORMAL = 7, 300 USAGE_TESSFACTOR = 8, 301 USAGE_POSITIONT = 9, 302 USAGE_COLOR = 10, 303 USAGE_FOG = 11, 304 USAGE_DEPTH = 12, 305 USAGE_SAMPLE = 13 306 }; 307 308 enum ParameterType 309 { 310 PARAMETER_TEMP = 0, 311 PARAMETER_INPUT = 1, 312 PARAMETER_CONST = 2, 313 PARAMETER_TEXTURE = 3, 314 PARAMETER_ADDR = 3, 315 PARAMETER_RASTOUT = 4, 316 PARAMETER_ATTROUT = 5, 317 PARAMETER_TEXCRDOUT = 6, 318 PARAMETER_OUTPUT = 6, 319 PARAMETER_CONSTINT = 7, 320 PARAMETER_COLOROUT = 8, 321 PARAMETER_DEPTHOUT = 9, 322 PARAMETER_SAMPLER = 10, 323 PARAMETER_CONST2 = 11, 324 PARAMETER_CONST3 = 12, 325 PARAMETER_CONST4 = 13, 326 PARAMETER_CONSTBOOL = 14, 327 PARAMETER_LOOP = 15, 328 PARAMETER_TEMPFLOAT16 = 16, 329 PARAMETER_MISCTYPE = 17, 330 PARAMETER_LABEL = 18, 331 PARAMETER_PREDICATE = 19, 332 333 // PARAMETER_FLOAT1LITERAL, 334 // PARAMETER_FLOAT2LITERAL, 335 // PARAMETER_FLOAT3LITERAL, 336 PARAMETER_FLOAT4LITERAL, 337 PARAMETER_BOOL1LITERAL, 338 // PARAMETER_BOOL2LITERAL, 339 // PARAMETER_BOOL3LITERAL, 340 // PARAMETER_BOOL4LITERAL, 341 // PARAMETER_INT1LITERAL, 342 // PARAMETER_INT2LITERAL, 343 // PARAMETER_INT3LITERAL, 344 PARAMETER_INT4LITERAL, 345 346 PARAMETER_VOID 347 }; 348 349 enum Modifier 350 { 351 MODIFIER_NONE, 352 MODIFIER_NEGATE, 353 MODIFIER_BIAS, 354 MODIFIER_BIAS_NEGATE, 355 MODIFIER_SIGN, 356 MODIFIER_SIGN_NEGATE, 357 MODIFIER_COMPLEMENT, 358 MODIFIER_X2, 359 MODIFIER_X2_NEGATE, 360 MODIFIER_DZ, 361 MODIFIER_DW, 362 MODIFIER_ABS, 363 MODIFIER_ABS_NEGATE, 364 MODIFIER_NOT 365 }; 366 367 enum Analysis 368 { 369 // Flags indicating whether an instruction is affected by an execution enable mask 370 ANALYSIS_BRANCH = 0x00000001, 371 ANALYSIS_BREAK = 0x00000002, 372 ANALYSIS_CONTINUE = 0x00000004, 373 ANALYSIS_LEAVE = 0x00000008, 374 }; 375 376 struct Parameter 377 { 378 union 379 { 380 struct 381 { 382 unsigned int index; // For registers types 383 384 struct 385 { 386 ParameterType type : 8; 387 unsigned int index; 388 unsigned int swizzle : 8; 389 unsigned int scale; 390 bool deterministic; // Equal accross shader instances run in lockstep (e.g. unrollable loop couters) 391 } rel; 392 }; 393 394 float value[4]; // For float constants 395 int integer[4]; // For integer constants 396 int boolean[4]; // For boolean constants 397 398 struct 399 { 400 unsigned int label; // Label index 401 unsigned int callSite; // Call index (per label) 402 }; 403 }; 404 405 Parameter() : index(0), type(PARAMETER_VOID) 406 { 407 rel.type = PARAMETER_VOID; 408 rel.index = 0; 409 rel.swizzle = 0; 410 rel.scale = 1; 411 rel.deterministic = false; 412 } 413 414 std::string string(ShaderType shaderType, unsigned short version) const; 415 std::string typeString(ShaderType shaderType, unsigned short version) const; 416 std::string relativeString() const; 417 418 ParameterType type : 8; 419 }; 420 421 struct DestinationParameter : Parameter 422 { 423 union 424 { 425 unsigned char mask; 426 427 struct 428 { 429 bool x : 1; 430 bool y : 1; 431 bool z : 1; 432 bool w : 1; 433 }; 434 }; 435 436 DestinationParameter() : mask(0xF), integer(false), saturate(false), partialPrecision(false), centroid(false), shift(0) 437 { 438 } 439 440 std::string modifierString() const; 441 std::string shiftString() const; 442 std::string maskString() const; 443 444 bool integer : 1; 445 bool saturate : 1; 446 bool partialPrecision : 1; 447 bool centroid : 1; 448 signed char shift : 4; 449 }; 450 451 struct SourceParameter : Parameter 452 { 453 SourceParameter() : swizzle(0xE4), modifier(MODIFIER_NONE) 454 { 455 } 456 457 std::string swizzleString() const; 458 std::string preModifierString() const; 459 std::string postModifierString() const; 460 461 unsigned int swizzle : 8; 462 Modifier modifier : 8; 463 }; 464 465 struct Instruction 466 { 467 explicit Instruction(Opcode opcode); 468 Instruction(const unsigned long *token, int size, unsigned char majorVersion); 469 470 virtual ~Instruction(); 471 472 void parseOperationToken(unsigned long token, unsigned char majorVersion); 473 void parseDeclarationToken(unsigned long token); 474 void parseDestinationToken(const unsigned long *token, unsigned char majorVersion); 475 void parseSourceToken(int i, const unsigned long *token, unsigned char majorVersion); 476 477 std::string string(ShaderType shaderType, unsigned short version) const; 478 static std::string swizzleString(ParameterType type, unsigned char swizzle); 479 std::string operationString(unsigned short version) const; 480 std::string controlString() const; 481 482 bool isBranch() const; 483 bool isCall() const; 484 bool isBreak() const; 485 bool isLoop() const; 486 bool isEndLoop() const; 487 488 bool isPredicated() const; 489 490 Opcode opcode; 491 492 union 493 { 494 Control control; 495 496 struct 497 { 498 unsigned char project : 1; 499 unsigned char bias : 1; 500 }; 501 }; 502 503 bool predicate; 504 bool predicateNot; // Negative predicate 505 unsigned char predicateSwizzle; 506 507 bool coissue; 508 SamplerType samplerType; 509 Usage usage; 510 unsigned char usageIndex; 511 512 DestinationParameter dst; 513 SourceParameter src[4]; 514 515 union 516 { 517 unsigned int analysis; 518 519 struct 520 { 521 // Keep in sync with Shader::Analysis flags 522 unsigned int analysisBranch : 1; 523 unsigned int analysisBreak : 1; 524 unsigned int analysisContinue : 1; 525 unsigned int analysisLeave : 1; 526 }; 527 }; 528 }; 529 530 Shader(); 531 532 virtual ~Shader(); 533 534 int getSerialID() const; 535 size_t getLength() const; 536 ShaderType getShaderType() const; 537 unsigned short getVersion() const; 538 539 void append(Instruction *instruction); 540 void declareSampler(int i); 541 542 const Instruction *getInstruction(unsigned int i) const; 543 int size(unsigned long opcode) const; 544 static int size(unsigned long opcode, unsigned short version); 545 546 void print(const char *fileName, ...) const; 547 void printInstruction(int index, const char *fileName) const; 548 549 static bool maskContainsComponent(int mask, int component); 550 static bool swizzleContainsComponent(int swizzle, int component); 551 static bool swizzleContainsComponentMasked(int swizzle, int component, int mask); 552 553 bool containsDynamicBranching() const; 554 bool containsBreakInstruction() const; 555 bool containsContinueInstruction() const; 556 bool containsLeaveInstruction() const; 557 bool containsDefineInstruction() const; 558 bool usesSampler(int i) const; 559 560 struct Semantic 561 { 562 Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF) : usage(usage), index(index), centroid(false) 563 { 564 } 565 566 bool operator==(const Semantic &semantic) const 567 { 568 return usage == semantic.usage && index == semantic.index; 569 } 570 571 bool active() const 572 { 573 return usage != 0xFF; 574 } 575 576 unsigned char usage; 577 unsigned char index; 578 bool centroid; 579 }; 580 581 void optimize(); 582 virtual void analyze() = 0; 583 584 // FIXME: Private 585 unsigned int dirtyConstantsF; 586 unsigned int dirtyConstantsI; 587 unsigned int dirtyConstantsB; 588 589 bool dynamicallyIndexedTemporaries; 590 bool dynamicallyIndexedInput; 591 bool dynamicallyIndexedOutput; 592 593 protected: 594 void parse(const unsigned long *token); 595 596 void optimizeLeave(); 597 void optimizeCall(); 598 void removeNull(); 599 600 void analyzeDirtyConstants(); 601 void analyzeDynamicBranching(); 602 void analyzeSamplers(); 603 void analyzeCallSites(); 604 void analyzeDynamicIndexing(); 605 void markFunctionAnalysis(int functionLabel, Analysis flag); 606 607 ShaderType shaderType; 608 609 union 610 { 611 unsigned short version; 612 613 struct 614 { 615 unsigned char minorVersion; 616 unsigned char majorVersion; 617 }; 618 }; 619 620 std::vector<Instruction*> instruction; 621 622 unsigned short usedSamplers; // Bit flags 623 624 private: 625 const int serialID; 626 static volatile int serialCounter; 627 628 bool dynamicBranching; 629 bool containsBreak; 630 bool containsContinue; 631 bool containsLeave; 632 bool containsDefine; 633 }; 634} 635 636#endif // sw_Shader_hpp 637