1 // 2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 // Copyright (C) 2012-2016 LunarG, Inc. 4 // 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions 9 // are met: 10 // 11 // Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 14 // Redistributions in binary form must reproduce the above 15 // copyright notice, this list of conditions and the following 16 // disclaimer in the documentation and/or other materials provided 17 // with the distribution. 18 // 19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20 // contributors may be used to endorse or promote products derived 21 // from this software without specific prior written permission. 22 // 23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 // POSSIBILITY OF SUCH DAMAGE. 35 // 36 37 #include "localintermediate.h" 38 #include "../Include/InfoSink.h" 39 40 #ifdef _MSC_VER 41 #include <cfloat> 42 #else 43 #include <cmath> 44 #endif 45 46 namespace { 47 48 bool IsInfinity(double x) { 49 #ifdef _MSC_VER 50 switch (_fpclass(x)) { 51 case _FPCLASS_NINF: 52 case _FPCLASS_PINF: 53 return true; 54 default: 55 return false; 56 } 57 #else 58 return std::isinf(x); 59 #endif 60 } 61 62 bool IsNan(double x) { 63 #ifdef _MSC_VER 64 switch (_fpclass(x)) { 65 case _FPCLASS_SNAN: 66 case _FPCLASS_QNAN: 67 return true; 68 default: 69 return false; 70 } 71 #else 72 return std::isnan(x); 73 #endif 74 } 75 76 } 77 78 namespace glslang { 79 80 // 81 // Two purposes: 82 // 1. Show an example of how to iterate tree. Functions can 83 // also directly call Traverse() on children themselves to 84 // have finer grained control over the process than shown here. 85 // See the last function for how to get started. 86 // 2. Print out a text based description of the tree. 87 // 88 89 // 90 // Use this class to carry along data from node to node in 91 // the traversal 92 // 93 class TOutputTraverser : public TIntermTraverser { 94 public: 95 TOutputTraverser(TInfoSink& i) : infoSink(i) { } 96 97 virtual bool visitBinary(TVisit, TIntermBinary* node); 98 virtual bool visitUnary(TVisit, TIntermUnary* node); 99 virtual bool visitAggregate(TVisit, TIntermAggregate* node); 100 virtual bool visitSelection(TVisit, TIntermSelection* node); 101 virtual void visitConstantUnion(TIntermConstantUnion* node); 102 virtual void visitSymbol(TIntermSymbol* node); 103 virtual bool visitLoop(TVisit, TIntermLoop* node); 104 virtual bool visitBranch(TVisit, TIntermBranch* node); 105 virtual bool visitSwitch(TVisit, TIntermSwitch* node); 106 107 TInfoSink& infoSink; 108 protected: 109 TOutputTraverser(TOutputTraverser&); 110 TOutputTraverser& operator=(TOutputTraverser&); 111 }; 112 113 // 114 // Helper functions for printing, not part of traversing. 115 // 116 117 static void OutputTreeText(TInfoSink& infoSink, const TIntermNode* node, const int depth) 118 { 119 int i; 120 121 infoSink.debug << node->getLoc().string << ":"; 122 if (node->getLoc().line) 123 infoSink.debug << node->getLoc().line; 124 else 125 infoSink.debug << "? "; 126 127 for (i = 0; i < depth; ++i) 128 infoSink.debug << " "; 129 } 130 131 // 132 // The rest of the file are the traversal functions. The last one 133 // is the one that starts the traversal. 134 // 135 // Return true from interior nodes to have the external traversal 136 // continue on to children. If you process children yourself, 137 // return false. 138 // 139 140 bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) 141 { 142 TInfoSink& out = infoSink; 143 144 OutputTreeText(out, node, depth); 145 146 switch (node->getOp()) { 147 case EOpAssign: out.debug << "move second child to first child"; break; 148 case EOpAddAssign: out.debug << "add second child into first child"; break; 149 case EOpSubAssign: out.debug << "subtract second child into first child"; break; 150 case EOpMulAssign: out.debug << "multiply second child into first child"; break; 151 case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break; 152 case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break; 153 case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break; 154 case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break; 155 case EOpDivAssign: out.debug << "divide second child into first child"; break; 156 case EOpModAssign: out.debug << "mod second child into first child"; break; 157 case EOpAndAssign: out.debug << "and second child into first child"; break; 158 case EOpInclusiveOrAssign: out.debug << "or second child into first child"; break; 159 case EOpExclusiveOrAssign: out.debug << "exclusive or second child into first child"; break; 160 case EOpLeftShiftAssign: out.debug << "left shift second child into first child"; break; 161 case EOpRightShiftAssign: out.debug << "right shift second child into first child"; break; 162 163 case EOpIndexDirect: out.debug << "direct index"; break; 164 case EOpIndexIndirect: out.debug << "indirect index"; break; 165 case EOpIndexDirectStruct: 166 out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName(); 167 out.debug << ": direct index for structure"; break; 168 case EOpVectorSwizzle: out.debug << "vector swizzle"; break; 169 case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break; 170 171 case EOpAdd: out.debug << "add"; break; 172 case EOpSub: out.debug << "subtract"; break; 173 case EOpMul: out.debug << "component-wise multiply"; break; 174 case EOpDiv: out.debug << "divide"; break; 175 case EOpMod: out.debug << "mod"; break; 176 case EOpRightShift: out.debug << "right-shift"; break; 177 case EOpLeftShift: out.debug << "left-shift"; break; 178 case EOpAnd: out.debug << "bitwise and"; break; 179 case EOpInclusiveOr: out.debug << "inclusive-or"; break; 180 case EOpExclusiveOr: out.debug << "exclusive-or"; break; 181 case EOpEqual: out.debug << "Compare Equal"; break; 182 case EOpNotEqual: out.debug << "Compare Not Equal"; break; 183 case EOpLessThan: out.debug << "Compare Less Than"; break; 184 case EOpGreaterThan: out.debug << "Compare Greater Than"; break; 185 case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break; 186 case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break; 187 case EOpVectorEqual: out.debug << "Equal"; break; 188 case EOpVectorNotEqual: out.debug << "NotEqual"; break; 189 190 case EOpVectorTimesScalar: out.debug << "vector-scale"; break; 191 case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break; 192 case EOpMatrixTimesVector: out.debug << "matrix-times-vector"; break; 193 case EOpMatrixTimesScalar: out.debug << "matrix-scale"; break; 194 case EOpMatrixTimesMatrix: out.debug << "matrix-multiply"; break; 195 196 case EOpLogicalOr: out.debug << "logical-or"; break; 197 case EOpLogicalXor: out.debug << "logical-xor"; break; 198 case EOpLogicalAnd: out.debug << "logical-and"; break; 199 default: out.debug << "<unknown op>"; 200 } 201 202 out.debug << " (" << node->getCompleteString() << ")"; 203 204 out.debug << "\n"; 205 206 return true; 207 } 208 209 bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) 210 { 211 TInfoSink& out = infoSink; 212 213 OutputTreeText(out, node, depth); 214 215 switch (node->getOp()) { 216 case EOpNegative: out.debug << "Negate value"; break; 217 case EOpVectorLogicalNot: 218 case EOpLogicalNot: out.debug << "Negate conditional"; break; 219 case EOpBitwiseNot: out.debug << "Bitwise not"; break; 220 221 case EOpPostIncrement: out.debug << "Post-Increment"; break; 222 case EOpPostDecrement: out.debug << "Post-Decrement"; break; 223 case EOpPreIncrement: out.debug << "Pre-Increment"; break; 224 case EOpPreDecrement: out.debug << "Pre-Decrement"; break; 225 226 case EOpConvIntToBool: out.debug << "Convert int to bool"; break; 227 case EOpConvUintToBool: out.debug << "Convert uint to bool"; break; 228 case EOpConvFloatToBool: out.debug << "Convert float to bool"; break; 229 case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break; 230 case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break; 231 case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break; 232 case EOpConvIntToFloat: out.debug << "Convert int to float"; break; 233 case EOpConvUintToFloat: out.debug << "Convert uint to float"; break; 234 case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break; 235 case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break; 236 case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break; 237 case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break; 238 case EOpConvUintToInt: out.debug << "Convert uint to int"; break; 239 case EOpConvFloatToInt: out.debug << "Convert float to int"; break; 240 case EOpConvDoubleToInt: out.debug << "Convert double to int"; break; 241 case EOpConvBoolToInt: out.debug << "Convert bool to int"; break; 242 case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break; 243 case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break; 244 case EOpConvIntToUint: out.debug << "Convert int to uint"; break; 245 case EOpConvFloatToUint: out.debug << "Convert float to uint"; break; 246 case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break; 247 case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break; 248 case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break; 249 case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break; 250 case EOpConvIntToDouble: out.debug << "Convert int to double"; break; 251 case EOpConvUintToDouble: out.debug << "Convert uint to double"; break; 252 case EOpConvFloatToDouble: out.debug << "Convert float to double"; break; 253 case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break; 254 case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break; 255 case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break; 256 case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break; 257 case EOpConvIntToInt64: out.debug << "Convert int to int64"; break; 258 case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break; 259 case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break; 260 case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break; 261 case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break; 262 case EOpConvBoolToUint64: out.debug << "Convert bool to uint64"; break; 263 case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break; 264 case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break; 265 case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break; 266 case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break; 267 case EOpConvInt64ToUint64: out.debug << "Convert uint64 to uint64"; break; 268 269 case EOpRadians: out.debug << "radians"; break; 270 case EOpDegrees: out.debug << "degrees"; break; 271 case EOpSin: out.debug << "sine"; break; 272 case EOpCos: out.debug << "cosine"; break; 273 case EOpTan: out.debug << "tangent"; break; 274 case EOpAsin: out.debug << "arc sine"; break; 275 case EOpAcos: out.debug << "arc cosine"; break; 276 case EOpAtan: out.debug << "arc tangent"; break; 277 case EOpSinh: out.debug << "hyp. sine"; break; 278 case EOpCosh: out.debug << "hyp. cosine"; break; 279 case EOpTanh: out.debug << "hyp. tangent"; break; 280 case EOpAsinh: out.debug << "arc hyp. sine"; break; 281 case EOpAcosh: out.debug << "arc hyp. cosine"; break; 282 case EOpAtanh: out.debug << "arc hyp. tangent"; break; 283 284 case EOpExp: out.debug << "exp"; break; 285 case EOpLog: out.debug << "log"; break; 286 case EOpExp2: out.debug << "exp2"; break; 287 case EOpLog2: out.debug << "log2"; break; 288 case EOpSqrt: out.debug << "sqrt"; break; 289 case EOpInverseSqrt: out.debug << "inverse sqrt"; break; 290 291 case EOpAbs: out.debug << "Absolute value"; break; 292 case EOpSign: out.debug << "Sign"; break; 293 case EOpFloor: out.debug << "Floor"; break; 294 case EOpTrunc: out.debug << "trunc"; break; 295 case EOpRound: out.debug << "round"; break; 296 case EOpRoundEven: out.debug << "roundEven"; break; 297 case EOpCeil: out.debug << "Ceiling"; break; 298 case EOpFract: out.debug << "Fraction"; break; 299 300 case EOpIsNan: out.debug << "isnan"; break; 301 case EOpIsInf: out.debug << "isinf"; break; 302 303 case EOpFloatBitsToInt: out.debug << "floatBitsToInt"; break; 304 case EOpFloatBitsToUint:out.debug << "floatBitsToUint"; break; 305 case EOpIntBitsToFloat: out.debug << "intBitsToFloat"; break; 306 case EOpUintBitsToFloat:out.debug << "uintBitsToFloat"; break; 307 case EOpDoubleBitsToInt64: out.debug << "doubleBitsToInt64"; break; 308 case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break; 309 case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break; 310 case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break; 311 #ifdef AMD_EXTENSIONS 312 case EOpFloat16BitsToInt16: out.debug << "float16BitsToInt16"; break; 313 case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break; 314 case EOpInt16BitsToFloat16: out.debug << "int16BitsToFloat16"; break; 315 case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break; 316 #endif 317 318 case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break; 319 case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break; 320 case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break; 321 case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16"; break; 322 case EOpPackHalf2x16: out.debug << "packHalf2x16"; break; 323 case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16"; break; 324 325 case EOpPackSnorm4x8: out.debug << "PackSnorm4x8"; break; 326 case EOpUnpackSnorm4x8: out.debug << "UnpackSnorm4x8"; break; 327 case EOpPackUnorm4x8: out.debug << "PackUnorm4x8"; break; 328 case EOpUnpackUnorm4x8: out.debug << "UnpackUnorm4x8"; break; 329 case EOpPackDouble2x32: out.debug << "PackDouble2x32"; break; 330 case EOpUnpackDouble2x32: out.debug << "UnpackDouble2x32"; break; 331 332 case EOpPackInt2x32: out.debug << "packInt2x32"; break; 333 case EOpUnpackInt2x32: out.debug << "unpackInt2x32"; break; 334 case EOpPackUint2x32: out.debug << "packUint2x32"; break; 335 case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break; 336 337 #ifdef AMD_EXTENSIONS 338 case EOpPackInt2x16: out.debug << "packInt2x16"; break; 339 case EOpUnpackInt2x16: out.debug << "unpackInt2x16"; break; 340 case EOpPackUint2x16: out.debug << "packUint2x16"; break; 341 case EOpUnpackUint2x16: out.debug << "unpackUint2x16"; break; 342 343 case EOpPackInt4x16: out.debug << "packInt4x16"; break; 344 case EOpUnpackInt4x16: out.debug << "unpackInt4x16"; break; 345 case EOpPackUint4x16: out.debug << "packUint4x16"; break; 346 case EOpUnpackUint4x16: out.debug << "unpackUint4x16"; break; 347 348 case EOpPackFloat2x16: out.debug << "packFloat2x16"; break; 349 case EOpUnpackFloat2x16: out.debug << "unpackFloat2x16"; break; 350 #endif 351 352 case EOpLength: out.debug << "length"; break; 353 case EOpNormalize: out.debug << "normalize"; break; 354 case EOpDPdx: out.debug << "dPdx"; break; 355 case EOpDPdy: out.debug << "dPdy"; break; 356 case EOpFwidth: out.debug << "fwidth"; break; 357 case EOpDPdxFine: out.debug << "dPdxFine"; break; 358 case EOpDPdyFine: out.debug << "dPdyFine"; break; 359 case EOpFwidthFine: out.debug << "fwidthFine"; break; 360 case EOpDPdxCoarse: out.debug << "dPdxCoarse"; break; 361 case EOpDPdyCoarse: out.debug << "dPdyCoarse"; break; 362 case EOpFwidthCoarse: out.debug << "fwidthCoarse"; break; 363 364 case EOpInterpolateAtCentroid: out.debug << "interpolateAtCentroid"; break; 365 366 case EOpDeterminant: out.debug << "determinant"; break; 367 case EOpMatrixInverse: out.debug << "inverse"; break; 368 case EOpTranspose: out.debug << "transpose"; break; 369 370 case EOpAny: out.debug << "any"; break; 371 case EOpAll: out.debug << "all"; break; 372 373 case EOpArrayLength: out.debug << "array length"; break; 374 375 case EOpEmitStreamVertex: out.debug << "EmitStreamVertex"; break; 376 case EOpEndStreamPrimitive: out.debug << "EndStreamPrimitive"; break; 377 378 case EOpAtomicCounterIncrement: out.debug << "AtomicCounterIncrement";break; 379 case EOpAtomicCounterDecrement: out.debug << "AtomicCounterDecrement";break; 380 case EOpAtomicCounter: out.debug << "AtomicCounter"; break; 381 382 case EOpTextureQuerySize: out.debug << "textureSize"; break; 383 case EOpTextureQueryLod: out.debug << "textureQueryLod"; break; 384 case EOpTextureQueryLevels: out.debug << "textureQueryLevels"; break; 385 case EOpTextureQuerySamples: out.debug << "textureSamples"; break; 386 case EOpImageQuerySize: out.debug << "imageQuerySize"; break; 387 case EOpImageQuerySamples: out.debug << "imageQuerySamples"; break; 388 case EOpImageLoad: out.debug << "imageLoad"; break; 389 390 case EOpBitFieldReverse: out.debug << "bitFieldReverse"; break; 391 case EOpBitCount: out.debug << "bitCount"; break; 392 case EOpFindLSB: out.debug << "findLSB"; break; 393 case EOpFindMSB: out.debug << "findMSB"; break; 394 395 case EOpNoise: out.debug << "noise"; break; 396 397 case EOpBallot: out.debug << "ballot"; break; 398 case EOpReadFirstInvocation: out.debug << "readFirstInvocation"; break; 399 400 case EOpAnyInvocation: out.debug << "anyInvocation"; break; 401 case EOpAllInvocations: out.debug << "allInvocations"; break; 402 case EOpAllInvocationsEqual: out.debug << "allInvocationsEqual"; break; 403 404 case EOpClip: out.debug << "clip"; break; 405 case EOpIsFinite: out.debug << "isfinite"; break; 406 case EOpLog10: out.debug << "log10"; break; 407 case EOpRcp: out.debug << "rcp"; break; 408 case EOpSaturate: out.debug << "saturate"; break; 409 410 case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break; 411 412 #ifdef AMD_EXTENSIONS 413 case EOpMinInvocations: out.debug << "minInvocations"; break; 414 case EOpMaxInvocations: out.debug << "maxInvocations"; break; 415 case EOpAddInvocations: out.debug << "addInvocations"; break; 416 case EOpMinInvocationsNonUniform: out.debug << "minInvocationsNonUniform"; break; 417 case EOpMaxInvocationsNonUniform: out.debug << "maxInvocationsNonUniform"; break; 418 case EOpAddInvocationsNonUniform: out.debug << "addInvocationsNonUniform"; break; 419 420 case EOpMinInvocationsInclusiveScan: out.debug << "minInvocationsInclusiveScan"; break; 421 case EOpMaxInvocationsInclusiveScan: out.debug << "maxInvocationsInclusiveScan"; break; 422 case EOpAddInvocationsInclusiveScan: out.debug << "addInvocationsInclusiveScan"; break; 423 case EOpMinInvocationsInclusiveScanNonUniform: out.debug << "minInvocationsInclusiveScanNonUniform"; break; 424 case EOpMaxInvocationsInclusiveScanNonUniform: out.debug << "maxInvocationsInclusiveScanNonUniform"; break; 425 case EOpAddInvocationsInclusiveScanNonUniform: out.debug << "addInvocationsInclusiveScanNonUniform"; break; 426 427 case EOpMinInvocationsExclusiveScan: out.debug << "minInvocationsExclusiveScan"; break; 428 case EOpMaxInvocationsExclusiveScan: out.debug << "maxInvocationsExclusiveScan"; break; 429 case EOpAddInvocationsExclusiveScan: out.debug << "addInvocationsExclusiveScan"; break; 430 case EOpMinInvocationsExclusiveScanNonUniform: out.debug << "minInvocationsExclusiveScanNonUniform"; break; 431 case EOpMaxInvocationsExclusiveScanNonUniform: out.debug << "maxInvocationsExclusiveScanNonUniform"; break; 432 case EOpAddInvocationsExclusiveScanNonUniform: out.debug << "addInvocationsExclusiveScanNonUniform"; break; 433 434 case EOpMbcnt: out.debug << "mbcnt"; break; 435 436 case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break; 437 case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break; 438 439 case EOpConvBoolToFloat16: out.debug << "Convert bool to float16"; break; 440 case EOpConvIntToFloat16: out.debug << "Convert int to float16"; break; 441 case EOpConvUintToFloat16: out.debug << "Convert uint to float16"; break; 442 case EOpConvFloatToFloat16: out.debug << "Convert float to float16"; break; 443 case EOpConvDoubleToFloat16: out.debug << "Convert double to float16"; break; 444 case EOpConvInt64ToFloat16: out.debug << "Convert int64 to float16"; break; 445 case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16"; break; 446 case EOpConvFloat16ToBool: out.debug << "Convert float16 to bool"; break; 447 case EOpConvFloat16ToInt: out.debug << "Convert float16 to int"; break; 448 case EOpConvFloat16ToUint: out.debug << "Convert float16 to uint"; break; 449 case EOpConvFloat16ToFloat: out.debug << "Convert float16 to float"; break; 450 case EOpConvFloat16ToDouble: out.debug << "Convert float16 to double"; break; 451 case EOpConvFloat16ToInt64: out.debug << "Convert float16 to int64"; break; 452 case EOpConvFloat16ToUint64: out.debug << "Convert float16 to uint64"; break; 453 454 case EOpConvBoolToInt16: out.debug << "Convert bool to int16"; break; 455 case EOpConvIntToInt16: out.debug << "Convert int to int16"; break; 456 case EOpConvUintToInt16: out.debug << "Convert uint to int16"; break; 457 case EOpConvFloatToInt16: out.debug << "Convert float to int16"; break; 458 case EOpConvDoubleToInt16: out.debug << "Convert double to int16"; break; 459 case EOpConvFloat16ToInt16: out.debug << "Convert float16 to int16"; break; 460 case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16"; break; 461 case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16"; break; 462 case EOpConvUint16ToInt16: out.debug << "Convert uint16 to int16"; break; 463 case EOpConvInt16ToBool: out.debug << "Convert int16 to bool"; break; 464 case EOpConvInt16ToInt: out.debug << "Convert int16 to int"; break; 465 case EOpConvInt16ToUint: out.debug << "Convert int16 to uint"; break; 466 case EOpConvInt16ToFloat: out.debug << "Convert int16 to float"; break; 467 case EOpConvInt16ToDouble: out.debug << "Convert int16 to double"; break; 468 case EOpConvInt16ToFloat16: out.debug << "Convert int16 to float16"; break; 469 case EOpConvInt16ToInt64: out.debug << "Convert int16 to int64"; break; 470 case EOpConvInt16ToUint64: out.debug << "Convert int16 to uint64"; break; 471 472 case EOpConvBoolToUint16: out.debug << "Convert bool to uint16"; break; 473 case EOpConvIntToUint16: out.debug << "Convert int to uint16"; break; 474 case EOpConvUintToUint16: out.debug << "Convert uint to uint16"; break; 475 case EOpConvFloatToUint16: out.debug << "Convert float to uint16"; break; 476 case EOpConvDoubleToUint16: out.debug << "Convert double to uint16"; break; 477 case EOpConvFloat16ToUint16: out.debug << "Convert float16 to uint16"; break; 478 case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16"; break; 479 case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break; 480 case EOpConvInt16ToUint16: out.debug << "Convert int16 to uint16"; break; 481 case EOpConvUint16ToBool: out.debug << "Convert uint16 to bool"; break; 482 case EOpConvUint16ToInt: out.debug << "Convert uint16 to int"; break; 483 case EOpConvUint16ToUint: out.debug << "Convert uint16 to uint"; break; 484 case EOpConvUint16ToFloat: out.debug << "Convert uint16 to float"; break; 485 case EOpConvUint16ToDouble: out.debug << "Convert uint16 to double"; break; 486 case EOpConvUint16ToFloat16: out.debug << "Convert uint16 to float16"; break; 487 case EOpConvUint16ToInt64: out.debug << "Convert uint16 to int64"; break; 488 case EOpConvUint16ToUint64: out.debug << "Convert uint16 to uint64"; break; 489 #endif 490 491 default: out.debug.message(EPrefixError, "Bad unary op"); 492 } 493 494 out.debug << " (" << node->getCompleteString() << ")"; 495 496 out.debug << "\n"; 497 498 return true; 499 } 500 501 bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) 502 { 503 TInfoSink& out = infoSink; 504 505 if (node->getOp() == EOpNull) { 506 out.debug.message(EPrefixError, "node is still EOpNull!"); 507 return true; 508 } 509 510 OutputTreeText(out, node, depth); 511 512 switch (node->getOp()) { 513 case EOpSequence: out.debug << "Sequence\n"; return true; 514 case EOpLinkerObjects: out.debug << "Linker Objects\n"; return true; 515 case EOpComma: out.debug << "Comma"; break; 516 case EOpFunction: out.debug << "Function Definition: " << node->getName(); break; 517 case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break; 518 case EOpParameters: out.debug << "Function Parameters: "; break; 519 520 case EOpConstructFloat: out.debug << "Construct float"; break; 521 case EOpConstructDouble:out.debug << "Construct double"; break; 522 523 case EOpConstructVec2: out.debug << "Construct vec2"; break; 524 case EOpConstructVec3: out.debug << "Construct vec3"; break; 525 case EOpConstructVec4: out.debug << "Construct vec4"; break; 526 case EOpConstructDVec2: out.debug << "Construct dvec2"; break; 527 case EOpConstructDVec3: out.debug << "Construct dvec3"; break; 528 case EOpConstructDVec4: out.debug << "Construct dvec4"; break; 529 case EOpConstructBool: out.debug << "Construct bool"; break; 530 case EOpConstructBVec2: out.debug << "Construct bvec2"; break; 531 case EOpConstructBVec3: out.debug << "Construct bvec3"; break; 532 case EOpConstructBVec4: out.debug << "Construct bvec4"; break; 533 case EOpConstructInt: out.debug << "Construct int"; break; 534 case EOpConstructIVec2: out.debug << "Construct ivec2"; break; 535 case EOpConstructIVec3: out.debug << "Construct ivec3"; break; 536 case EOpConstructIVec4: out.debug << "Construct ivec4"; break; 537 case EOpConstructUint: out.debug << "Construct uint"; break; 538 case EOpConstructUVec2: out.debug << "Construct uvec2"; break; 539 case EOpConstructUVec3: out.debug << "Construct uvec3"; break; 540 case EOpConstructUVec4: out.debug << "Construct uvec4"; break; 541 case EOpConstructInt64: out.debug << "Construct int64_t"; break; 542 case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break; 543 case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break; 544 case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break; 545 case EOpConstructUint64: out.debug << "Construct uint64_t"; break; 546 case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break; 547 case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break; 548 case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break; 549 #ifdef AMD_EXTENSIONS 550 case EOpConstructInt16: out.debug << "Construct int16_t"; break; 551 case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break; 552 case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break; 553 case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break; 554 case EOpConstructUint16: out.debug << "Construct uint16_t"; break; 555 case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break; 556 case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break; 557 case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break; 558 #endif 559 case EOpConstructMat2x2: out.debug << "Construct mat2"; break; 560 case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break; 561 case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break; 562 case EOpConstructMat3x2: out.debug << "Construct mat3x2"; break; 563 case EOpConstructMat3x3: out.debug << "Construct mat3"; break; 564 case EOpConstructMat3x4: out.debug << "Construct mat3x4"; break; 565 case EOpConstructMat4x2: out.debug << "Construct mat4x2"; break; 566 case EOpConstructMat4x3: out.debug << "Construct mat4x3"; break; 567 case EOpConstructMat4x4: out.debug << "Construct mat4"; break; 568 case EOpConstructDMat2x2: out.debug << "Construct dmat2"; break; 569 case EOpConstructDMat2x3: out.debug << "Construct dmat2x3"; break; 570 case EOpConstructDMat2x4: out.debug << "Construct dmat2x4"; break; 571 case EOpConstructDMat3x2: out.debug << "Construct dmat3x2"; break; 572 case EOpConstructDMat3x3: out.debug << "Construct dmat3"; break; 573 case EOpConstructDMat3x4: out.debug << "Construct dmat3x4"; break; 574 case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break; 575 case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break; 576 case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break; 577 case EOpConstructIMat2x2: out.debug << "Construct imat2"; break; 578 case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break; 579 case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break; 580 case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break; 581 case EOpConstructIMat3x3: out.debug << "Construct imat3"; break; 582 case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break; 583 case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break; 584 case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break; 585 case EOpConstructIMat4x4: out.debug << "Construct imat4"; break; 586 case EOpConstructUMat2x2: out.debug << "Construct umat2"; break; 587 case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break; 588 case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break; 589 case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break; 590 case EOpConstructUMat3x3: out.debug << "Construct umat3"; break; 591 case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break; 592 case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break; 593 case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break; 594 case EOpConstructUMat4x4: out.debug << "Construct umat4"; break; 595 case EOpConstructBMat2x2: out.debug << "Construct bmat2"; break; 596 case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break; 597 case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break; 598 case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break; 599 case EOpConstructBMat3x3: out.debug << "Construct bmat3"; break; 600 case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break; 601 case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break; 602 case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break; 603 case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break; 604 #ifdef AMD_EXTENSIONS 605 case EOpConstructFloat16: out.debug << "Construct float16_t"; break; 606 case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break; 607 case EOpConstructF16Vec3: out.debug << "Construct f16vec3"; break; 608 case EOpConstructF16Vec4: out.debug << "Construct f16vec4"; break; 609 case EOpConstructF16Mat2x2: out.debug << "Construct f16mat2"; break; 610 case EOpConstructF16Mat2x3: out.debug << "Construct f16mat2x3"; break; 611 case EOpConstructF16Mat2x4: out.debug << "Construct f16mat2x4"; break; 612 case EOpConstructF16Mat3x2: out.debug << "Construct f16mat3x2"; break; 613 case EOpConstructF16Mat3x3: out.debug << "Construct f16mat3"; break; 614 case EOpConstructF16Mat3x4: out.debug << "Construct f16mat3x4"; break; 615 case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break; 616 case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break; 617 case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break; 618 #endif 619 case EOpConstructStruct: out.debug << "Construct structure"; break; 620 case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break; 621 622 case EOpLessThan: out.debug << "Compare Less Than"; break; 623 case EOpGreaterThan: out.debug << "Compare Greater Than"; break; 624 case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break; 625 case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break; 626 case EOpVectorEqual: out.debug << "Equal"; break; 627 case EOpVectorNotEqual: out.debug << "NotEqual"; break; 628 629 case EOpMod: out.debug << "mod"; break; 630 case EOpModf: out.debug << "modf"; break; 631 case EOpPow: out.debug << "pow"; break; 632 633 case EOpAtan: out.debug << "arc tangent"; break; 634 635 case EOpMin: out.debug << "min"; break; 636 case EOpMax: out.debug << "max"; break; 637 case EOpClamp: out.debug << "clamp"; break; 638 case EOpMix: out.debug << "mix"; break; 639 case EOpStep: out.debug << "step"; break; 640 case EOpSmoothStep: out.debug << "smoothstep"; break; 641 642 case EOpDistance: out.debug << "distance"; break; 643 case EOpDot: out.debug << "dot-product"; break; 644 case EOpCross: out.debug << "cross-product"; break; 645 case EOpFaceForward: out.debug << "face-forward"; break; 646 case EOpReflect: out.debug << "reflect"; break; 647 case EOpRefract: out.debug << "refract"; break; 648 case EOpMul: out.debug << "component-wise multiply"; break; 649 case EOpOuterProduct: out.debug << "outer product"; break; 650 651 case EOpEmitVertex: out.debug << "EmitVertex"; break; 652 case EOpEndPrimitive: out.debug << "EndPrimitive"; break; 653 654 case EOpBarrier: out.debug << "Barrier"; break; 655 case EOpMemoryBarrier: out.debug << "MemoryBarrier"; break; 656 case EOpMemoryBarrierAtomicCounter: out.debug << "MemoryBarrierAtomicCounter"; break; 657 case EOpMemoryBarrierBuffer: out.debug << "MemoryBarrierBuffer"; break; 658 case EOpMemoryBarrierImage: out.debug << "MemoryBarrierImage"; break; 659 case EOpMemoryBarrierShared: out.debug << "MemoryBarrierShared"; break; 660 case EOpGroupMemoryBarrier: out.debug << "GroupMemoryBarrier"; break; 661 662 case EOpReadInvocation: out.debug << "readInvocation"; break; 663 664 #ifdef AMD_EXTENSIONS 665 case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break; 666 case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break; 667 case EOpWriteInvocation: out.debug << "writeInvocation"; break; 668 669 case EOpMin3: out.debug << "min3"; break; 670 case EOpMax3: out.debug << "max3"; break; 671 case EOpMid3: out.debug << "mid3"; break; 672 673 case EOpTime: out.debug << "time"; break; 674 #endif 675 676 case EOpAtomicAdd: out.debug << "AtomicAdd"; break; 677 case EOpAtomicMin: out.debug << "AtomicMin"; break; 678 case EOpAtomicMax: out.debug << "AtomicMax"; break; 679 case EOpAtomicAnd: out.debug << "AtomicAnd"; break; 680 case EOpAtomicOr: out.debug << "AtomicOr"; break; 681 case EOpAtomicXor: out.debug << "AtomicXor"; break; 682 case EOpAtomicExchange: out.debug << "AtomicExchange"; break; 683 case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break; 684 685 case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break; 686 case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break; 687 case EOpAtomicCounterMin: out.debug << "AtomicCounterMin"; break; 688 case EOpAtomicCounterMax: out.debug << "AtomicCounterMax"; break; 689 case EOpAtomicCounterAnd: out.debug << "AtomicCounterAnd"; break; 690 case EOpAtomicCounterOr: out.debug << "AtomicCounterOr"; break; 691 case EOpAtomicCounterXor: out.debug << "AtomicCounterXor"; break; 692 case EOpAtomicCounterExchange: out.debug << "AtomicCounterExchange"; break; 693 case EOpAtomicCounterCompSwap: out.debug << "AtomicCounterCompSwap"; break; 694 695 case EOpImageQuerySize: out.debug << "imageQuerySize"; break; 696 case EOpImageQuerySamples: out.debug << "imageQuerySamples"; break; 697 case EOpImageLoad: out.debug << "imageLoad"; break; 698 case EOpImageStore: out.debug << "imageStore"; break; 699 case EOpImageAtomicAdd: out.debug << "imageAtomicAdd"; break; 700 case EOpImageAtomicMin: out.debug << "imageAtomicMin"; break; 701 case EOpImageAtomicMax: out.debug << "imageAtomicMax"; break; 702 case EOpImageAtomicAnd: out.debug << "imageAtomicAnd"; break; 703 case EOpImageAtomicOr: out.debug << "imageAtomicOr"; break; 704 case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break; 705 case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break; 706 case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break; 707 #ifdef AMD_EXTENSIONS 708 case EOpImageLoadLod: out.debug << "imageLoadLod"; break; 709 case EOpImageStoreLod: out.debug << "imageStoreLod"; break; 710 #endif 711 712 case EOpTextureQuerySize: out.debug << "textureSize"; break; 713 case EOpTextureQueryLod: out.debug << "textureQueryLod"; break; 714 case EOpTextureQueryLevels: out.debug << "textureQueryLevels"; break; 715 case EOpTextureQuerySamples: out.debug << "textureSamples"; break; 716 case EOpTexture: out.debug << "texture"; break; 717 case EOpTextureProj: out.debug << "textureProj"; break; 718 case EOpTextureLod: out.debug << "textureLod"; break; 719 case EOpTextureOffset: out.debug << "textureOffset"; break; 720 case EOpTextureFetch: out.debug << "textureFetch"; break; 721 case EOpTextureFetchOffset: out.debug << "textureFetchOffset"; break; 722 case EOpTextureProjOffset: out.debug << "textureProjOffset"; break; 723 case EOpTextureLodOffset: out.debug << "textureLodOffset"; break; 724 case EOpTextureProjLod: out.debug << "textureProjLod"; break; 725 case EOpTextureProjLodOffset: out.debug << "textureProjLodOffset"; break; 726 case EOpTextureGrad: out.debug << "textureGrad"; break; 727 case EOpTextureGradOffset: out.debug << "textureGradOffset"; break; 728 case EOpTextureProjGrad: out.debug << "textureProjGrad"; break; 729 case EOpTextureProjGradOffset: out.debug << "textureProjGradOffset"; break; 730 case EOpTextureGather: out.debug << "textureGather"; break; 731 case EOpTextureGatherOffset: out.debug << "textureGatherOffset"; break; 732 case EOpTextureGatherOffsets: out.debug << "textureGatherOffsets"; break; 733 case EOpTextureClamp: out.debug << "textureClamp"; break; 734 case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break; 735 case EOpTextureGradClamp: out.debug << "textureGradClamp"; break; 736 case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break; 737 #ifdef AMD_EXTENSIONS 738 case EOpTextureGatherLod: out.debug << "textureGatherLod"; break; 739 case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break; 740 case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break; 741 #endif 742 743 case EOpSparseTexture: out.debug << "sparseTexture"; break; 744 case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break; 745 case EOpSparseTextureLod: out.debug << "sparseTextureLod"; break; 746 case EOpSparseTextureLodOffset: out.debug << "sparseTextureLodOffset"; break; 747 case EOpSparseTextureFetch: out.debug << "sparseTexelFetch"; break; 748 case EOpSparseTextureFetchOffset: out.debug << "sparseTexelFetchOffset"; break; 749 case EOpSparseTextureGrad: out.debug << "sparseTextureGrad"; break; 750 case EOpSparseTextureGradOffset: out.debug << "sparseTextureGradOffset"; break; 751 case EOpSparseTextureGather: out.debug << "sparseTextureGather"; break; 752 case EOpSparseTextureGatherOffset: out.debug << "sparseTextureGatherOffset"; break; 753 case EOpSparseTextureGatherOffsets: out.debug << "sparseTextureGatherOffsets"; break; 754 case EOpSparseImageLoad: out.debug << "sparseImageLoad"; break; 755 case EOpSparseTextureClamp: out.debug << "sparseTextureClamp"; break; 756 case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break; 757 case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break; 758 case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break; 759 #ifdef AMD_EXTENSIONS 760 case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break; 761 case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break; 762 case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break; 763 case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break; 764 #endif 765 766 case EOpAddCarry: out.debug << "addCarry"; break; 767 case EOpSubBorrow: out.debug << "subBorrow"; break; 768 case EOpUMulExtended: out.debug << "uMulExtended"; break; 769 case EOpIMulExtended: out.debug << "iMulExtended"; break; 770 case EOpBitfieldExtract: out.debug << "bitfieldExtract"; break; 771 case EOpBitfieldInsert: out.debug << "bitfieldInsert"; break; 772 773 case EOpFma: out.debug << "fma"; break; 774 case EOpFrexp: out.debug << "frexp"; break; 775 case EOpLdexp: out.debug << "ldexp"; break; 776 777 case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break; 778 case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break; 779 #ifdef AMD_EXTENSIONS 780 case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break; 781 #endif 782 783 case EOpSinCos: out.debug << "sincos"; break; 784 case EOpGenMul: out.debug << "mul"; break; 785 786 case EOpAllMemoryBarrierWithGroupSync: out.debug << "AllMemoryBarrierWithGroupSync"; break; 787 case EOpGroupMemoryBarrierWithGroupSync: out.debug << "GroupMemoryBarrierWithGroupSync"; break; 788 case EOpWorkgroupMemoryBarrier: out.debug << "WorkgroupMemoryBarrier"; break; 789 case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break; 790 791 default: out.debug.message(EPrefixError, "Bad aggregation op"); 792 } 793 794 if (node->getOp() != EOpSequence && node->getOp() != EOpParameters) 795 out.debug << " (" << node->getCompleteString() << ")"; 796 797 out.debug << "\n"; 798 799 return true; 800 } 801 802 bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node) 803 { 804 TInfoSink& out = infoSink; 805 806 OutputTreeText(out, node, depth); 807 808 out.debug << "Test condition and select"; 809 out.debug << " (" << node->getCompleteString() << ")\n"; 810 811 ++depth; 812 813 OutputTreeText(out, node, depth); 814 out.debug << "Condition\n"; 815 node->getCondition()->traverse(this); 816 817 OutputTreeText(out, node, depth); 818 if (node->getTrueBlock()) { 819 out.debug << "true case\n"; 820 node->getTrueBlock()->traverse(this); 821 } else 822 out.debug << "true case is null\n"; 823 824 if (node->getFalseBlock()) { 825 OutputTreeText(out, node, depth); 826 out.debug << "false case\n"; 827 node->getFalseBlock()->traverse(this); 828 } 829 830 --depth; 831 832 return false; 833 } 834 835 static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth) 836 { 837 int size = node->getType().computeNumComponents(); 838 839 for (int i = 0; i < size; i++) { 840 OutputTreeText(out, node, depth); 841 switch (constUnion[i].getType()) { 842 case EbtBool: 843 if (constUnion[i].getBConst()) 844 out.debug << "true"; 845 else 846 out.debug << "false"; 847 848 out.debug << " (" << "const bool" << ")"; 849 850 out.debug << "\n"; 851 break; 852 case EbtFloat: 853 case EbtDouble: 854 #ifdef AMD_EXTENSIONS 855 case EbtFloat16: 856 #endif 857 { 858 const double value = constUnion[i].getDConst(); 859 // Print infinities and NaNs in a portable way. 860 if (IsInfinity(value)) { 861 if (value < 0) 862 out.debug << "-1.#INF\n"; 863 else 864 out.debug << "+1.#INF\n"; 865 } else if (IsNan(value)) 866 out.debug << "1.#IND\n"; 867 else { 868 const int maxSize = 300; 869 char buf[maxSize]; 870 snprintf(buf, maxSize, "%f", value); 871 872 out.debug << buf << "\n"; 873 } 874 } 875 break; 876 case EbtInt: 877 { 878 const int maxSize = 300; 879 char buf[maxSize]; 880 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int"); 881 882 out.debug << buf << "\n"; 883 } 884 break; 885 case EbtUint: 886 { 887 const int maxSize = 300; 888 char buf[maxSize]; 889 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint"); 890 891 out.debug << buf << "\n"; 892 } 893 break; 894 case EbtInt64: 895 { 896 const int maxSize = 300; 897 char buf[maxSize]; 898 snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t"); 899 900 out.debug << buf << "\n"; 901 } 902 break; 903 case EbtUint64: 904 { 905 const int maxSize = 300; 906 char buf[maxSize]; 907 snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t"); 908 909 out.debug << buf << "\n"; 910 } 911 break; 912 #ifdef AMD_EXTENSIONS 913 case EbtInt16: 914 { 915 const int maxSize = 300; 916 char buf[maxSize]; 917 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t"); 918 919 out.debug << buf << "\n"; 920 } 921 break; 922 case EbtUint16: 923 { 924 const int maxSize = 300; 925 char buf[maxSize]; 926 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t"); 927 928 out.debug << buf << "\n"; 929 } 930 break; 931 #endif 932 default: 933 out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc()); 934 break; 935 } 936 } 937 } 938 939 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node) 940 { 941 OutputTreeText(infoSink, node, depth); 942 infoSink.debug << "Constant:\n"; 943 944 OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); 945 } 946 947 void TOutputTraverser::visitSymbol(TIntermSymbol* node) 948 { 949 OutputTreeText(infoSink, node, depth); 950 951 infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n"; 952 953 if (! node->getConstArray().empty()) 954 OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); 955 else if (node->getConstSubtree()) { 956 incrementDepth(node); 957 node->getConstSubtree()->traverse(this); 958 decrementDepth(); 959 } 960 } 961 962 bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node) 963 { 964 TInfoSink& out = infoSink; 965 966 OutputTreeText(out, node, depth); 967 968 out.debug << "Loop with condition "; 969 if (! node->testFirst()) 970 out.debug << "not "; 971 out.debug << "tested first\n"; 972 973 ++depth; 974 975 OutputTreeText(infoSink, node, depth); 976 if (node->getTest()) { 977 out.debug << "Loop Condition\n"; 978 node->getTest()->traverse(this); 979 } else 980 out.debug << "No loop condition\n"; 981 982 OutputTreeText(infoSink, node, depth); 983 if (node->getBody()) { 984 out.debug << "Loop Body\n"; 985 node->getBody()->traverse(this); 986 } else 987 out.debug << "No loop body\n"; 988 989 if (node->getTerminal()) { 990 OutputTreeText(infoSink, node, depth); 991 out.debug << "Loop Terminal Expression\n"; 992 node->getTerminal()->traverse(this); 993 } 994 995 --depth; 996 997 return false; 998 } 999 1000 bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node) 1001 { 1002 TInfoSink& out = infoSink; 1003 1004 OutputTreeText(out, node, depth); 1005 1006 switch (node->getFlowOp()) { 1007 case EOpKill: out.debug << "Branch: Kill"; break; 1008 case EOpBreak: out.debug << "Branch: Break"; break; 1009 case EOpContinue: out.debug << "Branch: Continue"; break; 1010 case EOpReturn: out.debug << "Branch: Return"; break; 1011 case EOpCase: out.debug << "case: "; break; 1012 case EOpDefault: out.debug << "default: "; break; 1013 default: out.debug << "Branch: Unknown Branch"; break; 1014 } 1015 1016 if (node->getExpression()) { 1017 out.debug << " with expression\n"; 1018 ++depth; 1019 node->getExpression()->traverse(this); 1020 --depth; 1021 } else 1022 out.debug << "\n"; 1023 1024 return false; 1025 } 1026 1027 bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node) 1028 { 1029 TInfoSink& out = infoSink; 1030 1031 OutputTreeText(out, node, depth); 1032 out.debug << "switch\n"; 1033 1034 OutputTreeText(out, node, depth); 1035 out.debug << "condition\n"; 1036 ++depth; 1037 node->getCondition()->traverse(this); 1038 1039 --depth; 1040 OutputTreeText(out, node, depth); 1041 out.debug << "body\n"; 1042 ++depth; 1043 node->getBody()->traverse(this); 1044 1045 --depth; 1046 1047 return false; 1048 } 1049 1050 // 1051 // This function is the one to call externally to start the traversal. 1052 // Individual functions can be initialized to 0 to skip processing of that 1053 // type of node. It's children will still be processed. 1054 // 1055 void TIntermediate::output(TInfoSink& infoSink, bool tree) 1056 { 1057 infoSink.debug << "Shader version: " << version << "\n"; 1058 if (requestedExtensions.size() > 0) { 1059 for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) 1060 infoSink.debug << "Requested " << *extIt << "\n"; 1061 } 1062 1063 if (xfbMode) 1064 infoSink.debug << "in xfb mode\n"; 1065 1066 switch (language) { 1067 case EShLangVertex: 1068 break; 1069 1070 case EShLangTessControl: 1071 infoSink.debug << "vertices = " << vertices << "\n"; 1072 1073 if (inputPrimitive != ElgNone) 1074 infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; 1075 if (vertexSpacing != EvsNone) 1076 infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n"; 1077 if (vertexOrder != EvoNone) 1078 infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n"; 1079 break; 1080 1081 case EShLangTessEvaluation: 1082 infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; 1083 infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n"; 1084 infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n"; 1085 if (pointMode) 1086 infoSink.debug << "using point mode\n"; 1087 break; 1088 1089 case EShLangGeometry: 1090 infoSink.debug << "invocations = " << invocations << "\n"; 1091 infoSink.debug << "max_vertices = " << vertices << "\n"; 1092 infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; 1093 infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n"; 1094 break; 1095 1096 case EShLangFragment: 1097 if (pixelCenterInteger) 1098 infoSink.debug << "gl_FragCoord pixel center is integer\n"; 1099 if (originUpperLeft) 1100 infoSink.debug << "gl_FragCoord origin is upper left\n"; 1101 if (earlyFragmentTests) 1102 infoSink.debug << "using early_fragment_tests\n"; 1103 if (postDepthCoverage) 1104 infoSink.debug << "using post_depth_coverage\n"; 1105 if (depthLayout != EldNone) 1106 infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n"; 1107 if (blendEquations != 0) { 1108 infoSink.debug << "using"; 1109 // blendEquations is a mask, decode it 1110 for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) { 1111 if (blendEquations & (1 << be)) 1112 infoSink.debug << " " << TQualifier::getBlendEquationString(be); 1113 } 1114 infoSink.debug << "\n"; 1115 } 1116 break; 1117 1118 case EShLangCompute: 1119 infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; 1120 { 1121 if (localSizeSpecId[0] != TQualifier::layoutNotSet || 1122 localSizeSpecId[1] != TQualifier::layoutNotSet || 1123 localSizeSpecId[2] != TQualifier::layoutNotSet) { 1124 infoSink.debug << "local_size ids = (" << 1125 localSizeSpecId[0] << ", " << 1126 localSizeSpecId[1] << ", " << 1127 localSizeSpecId[2] << ")\n"; 1128 } 1129 } 1130 break; 1131 1132 default: 1133 break; 1134 } 1135 1136 if (treeRoot == 0 || ! tree) 1137 return; 1138 1139 TOutputTraverser it(infoSink); 1140 1141 treeRoot->traverse(&it); 1142 } 1143 1144 } // end namespace glslang 1145