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