Intermediate.cpp 133 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2012-2015 LunarG, Inc.
  4. // Copyright (C) 2015-2020 Google, Inc.
  5. // Copyright (C) 2017 ARM Limited.
  6. //
  7. // All rights reserved.
  8. //
  9. // Redistribution and use in source and binary forms, with or without
  10. // modification, are permitted provided that the following conditions
  11. // are met:
  12. //
  13. // Redistributions of source code must retain the above copyright
  14. // notice, this list of conditions and the following disclaimer.
  15. //
  16. // Redistributions in binary form must reproduce the above
  17. // copyright notice, this list of conditions and the following
  18. // disclaimer in the documentation and/or other materials provided
  19. // with the distribution.
  20. //
  21. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  22. // contributors may be used to endorse or promote products derived
  23. // from this software without specific prior written permission.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  28. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  29. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  30. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  31. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  32. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  33. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  35. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. // POSSIBILITY OF SUCH DAMAGE.
  37. //
  38. //
  39. // Build the intermediate representation.
  40. //
  41. #include "localintermediate.h"
  42. #include "RemoveTree.h"
  43. #include "SymbolTable.h"
  44. #include "propagateNoContraction.h"
  45. #include <cfloat>
  46. #include <utility>
  47. #include <tuple>
  48. namespace glslang {
  49. ////////////////////////////////////////////////////////////////////////////
  50. //
  51. // First set of functions are to help build the intermediate representation.
  52. // These functions are not member functions of the nodes.
  53. // They are called from parser productions.
  54. //
  55. /////////////////////////////////////////////////////////////////////////////
  56. //
  57. // Add a terminal node for an identifier in an expression.
  58. //
  59. // Returns the added node.
  60. //
  61. TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray,
  62. TIntermTyped* constSubtree, const TSourceLoc& loc)
  63. {
  64. TIntermSymbol* node = new TIntermSymbol(id, name, type);
  65. node->setLoc(loc);
  66. node->setConstArray(constArray);
  67. node->setConstSubtree(constSubtree);
  68. return node;
  69. }
  70. TIntermSymbol* TIntermediate::addSymbol(const TIntermSymbol& intermSymbol)
  71. {
  72. return addSymbol(intermSymbol.getId(),
  73. intermSymbol.getName(),
  74. intermSymbol.getType(),
  75. intermSymbol.getConstArray(),
  76. intermSymbol.getConstSubtree(),
  77. intermSymbol.getLoc());
  78. }
  79. TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable)
  80. {
  81. glslang::TSourceLoc loc; // just a null location
  82. loc.init();
  83. return addSymbol(variable, loc);
  84. }
  85. TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
  86. {
  87. return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc);
  88. }
  89. TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc)
  90. {
  91. TConstUnionArray unionArray; // just a null constant
  92. return addSymbol(0, "", type, unionArray, nullptr, loc);
  93. }
  94. //
  95. // Connect two nodes with a new parent that does a binary operation on the nodes.
  96. //
  97. // Returns the added node.
  98. //
  99. // Returns nullptr if the working conversions and promotions could not be found.
  100. //
  101. TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
  102. {
  103. // No operations work on blocks
  104. if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
  105. return nullptr;
  106. // Convert "reference +/- int" and "reference - reference" to integer math
  107. if (op == EOpAdd || op == EOpSub) {
  108. // No addressing math on struct with unsized array.
  109. if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) ||
  110. (right->isReference() && right->getType().getReferentType()->containsUnsizedArray())) {
  111. return nullptr;
  112. }
  113. if (left->isReference() && isTypeInt(right->getBasicType())) {
  114. const TType& referenceType = left->getType();
  115. TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
  116. left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));
  117. right = createConversion(EbtInt64, right);
  118. right = addBinaryMath(EOpMul, right, size, loc);
  119. TIntermTyped *node = addBinaryMath(op, left, right, loc);
  120. node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
  121. return node;
  122. }
  123. }
  124. if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) {
  125. const TType& referenceType = right->getType();
  126. TIntermConstantUnion* size =
  127. addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true);
  128. right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
  129. left = createConversion(EbtInt64, left);
  130. left = addBinaryMath(EOpMul, left, size, loc);
  131. TIntermTyped *node = addBinaryMath(op, left, right, loc);
  132. node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
  133. return node;
  134. }
  135. if (op == EOpSub && left->isReference() && right->isReference()) {
  136. TIntermConstantUnion* size =
  137. addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
  138. left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));
  139. right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
  140. left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64));
  141. right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64));
  142. left = addBinaryMath(EOpSub, left, right, loc);
  143. TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc);
  144. return node;
  145. }
  146. // No other math operators supported on references
  147. if (left->isReference() || right->isReference())
  148. return nullptr;
  149. // Try converting the children's base types to compatible types.
  150. auto children = addPairConversion(op, left, right);
  151. left = std::get<0>(children);
  152. right = std::get<1>(children);
  153. if (left == nullptr || right == nullptr)
  154. return nullptr;
  155. // Convert the children's type shape to be compatible.
  156. addBiShapeConversion(op, left, right);
  157. if (left == nullptr || right == nullptr)
  158. return nullptr;
  159. //
  160. // Need a new node holding things together. Make
  161. // one and promote it to the right type.
  162. //
  163. TIntermBinary* node = addBinaryNode(op, left, right, loc);
  164. if (! promote(node))
  165. return nullptr;
  166. node->updatePrecision();
  167. //
  168. // If they are both (non-specialization) constants, they must be folded.
  169. // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
  170. //
  171. TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion();
  172. TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion();
  173. if (leftTempConstant && rightTempConstant) {
  174. TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
  175. if (folded)
  176. return folded;
  177. }
  178. // If can propagate spec-constantness and if the operation is an allowed
  179. // specialization-constant operation, make a spec-constant.
  180. if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node))
  181. node->getWritableType().getQualifier().makeSpecConstant();
  182. // If must propagate nonuniform, make a nonuniform.
  183. if ((node->getLeft()->getQualifier().isNonUniform() || node->getRight()->getQualifier().isNonUniform()) &&
  184. isNonuniformPropagating(node->getOp()))
  185. node->getWritableType().getQualifier().nonUniform = true;
  186. return node;
  187. }
  188. //
  189. // Low level: add binary node (no promotions or other argument modifications)
  190. //
  191. TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right,
  192. const TSourceLoc& loc) const
  193. {
  194. // build the node
  195. TIntermBinary* node = new TIntermBinary(op);
  196. node->setLoc(loc.line != 0 ? loc : left->getLoc());
  197. node->setLeft(left);
  198. node->setRight(right);
  199. return node;
  200. }
  201. //
  202. // like non-type form, but sets node's type.
  203. //
  204. TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right,
  205. const TSourceLoc& loc, const TType& type) const
  206. {
  207. TIntermBinary* node = addBinaryNode(op, left, right, loc);
  208. node->setType(type);
  209. return node;
  210. }
  211. //
  212. // Low level: add unary node (no promotions or other argument modifications)
  213. //
  214. TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc) const
  215. {
  216. TIntermUnary* node = new TIntermUnary(op);
  217. node->setLoc(loc.line != 0 ? loc : child->getLoc());
  218. node->setOperand(child);
  219. return node;
  220. }
  221. //
  222. // like non-type form, but sets node's type.
  223. //
  224. TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc, const TType& type)
  225. const
  226. {
  227. TIntermUnary* node = addUnaryNode(op, child, loc);
  228. node->setType(type);
  229. return node;
  230. }
  231. //
  232. // Connect two nodes through an assignment.
  233. //
  234. // Returns the added node.
  235. //
  236. // Returns nullptr if the 'right' type could not be converted to match the 'left' type,
  237. // or the resulting operation cannot be properly promoted.
  238. //
  239. TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right,
  240. const TSourceLoc& loc)
  241. {
  242. // No block assignment
  243. if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
  244. return nullptr;
  245. // Convert "reference += int" to "reference = reference + int". We need this because the
  246. // "reference + int" calculation involves a cast back to the original type, which makes it
  247. // not an lvalue.
  248. if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) {
  249. if (!(right->getType().isScalar() && right->getType().isIntegerDomain()))
  250. return nullptr;
  251. TIntermTyped* node = addBinaryMath(op == EOpAddAssign ? EOpAdd : EOpSub, left, right, loc);
  252. if (!node)
  253. return nullptr;
  254. TIntermSymbol* symbol = left->getAsSymbolNode();
  255. left = addSymbol(*symbol);
  256. node = addAssign(EOpAssign, left, node, loc);
  257. return node;
  258. }
  259. //
  260. // Like adding binary math, except the conversion can only go
  261. // from right to left.
  262. //
  263. // convert base types, nullptr return means not possible
  264. right = addConversion(op, left->getType(), right);
  265. if (right == nullptr)
  266. return nullptr;
  267. // convert shape
  268. right = addUniShapeConversion(op, left->getType(), right);
  269. // build the node
  270. TIntermBinary* node = addBinaryNode(op, left, right, loc);
  271. if (! promote(node))
  272. return nullptr;
  273. node->updatePrecision();
  274. return node;
  275. }
  276. //
  277. // Connect two nodes through an index operator, where the left node is the base
  278. // of an array or struct, and the right node is a direct or indirect offset.
  279. //
  280. // Returns the added node.
  281. // The caller should set the type of the returned node.
  282. //
  283. TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index,
  284. const TSourceLoc& loc)
  285. {
  286. // caller should set the type
  287. return addBinaryNode(op, base, index, loc);
  288. }
  289. //
  290. // Add one node as the parent of another that it operates on.
  291. //
  292. // Returns the added node.
  293. //
  294. TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
  295. const TSourceLoc& loc)
  296. {
  297. if (child == 0)
  298. return nullptr;
  299. if (child->getType().getBasicType() == EbtBlock)
  300. return nullptr;
  301. switch (op) {
  302. case EOpLogicalNot:
  303. if (getSource() == EShSourceHlsl) {
  304. break; // HLSL can promote logical not
  305. }
  306. if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
  307. return nullptr;
  308. }
  309. break;
  310. case EOpPostIncrement:
  311. case EOpPreIncrement:
  312. case EOpPostDecrement:
  313. case EOpPreDecrement:
  314. case EOpNegative:
  315. if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
  316. return nullptr;
  317. default: break; // some compilers want this
  318. }
  319. //
  320. // Do we need to promote the operand?
  321. //
  322. TBasicType newType = EbtVoid;
  323. switch (op) {
  324. case EOpConstructBool: newType = EbtBool; break;
  325. case EOpConstructFloat: newType = EbtFloat; break;
  326. case EOpConstructInt: newType = EbtInt; break;
  327. case EOpConstructUint: newType = EbtUint; break;
  328. #ifndef GLSLANG_WEB
  329. case EOpConstructInt8: newType = EbtInt8; break;
  330. case EOpConstructUint8: newType = EbtUint8; break;
  331. case EOpConstructInt16: newType = EbtInt16; break;
  332. case EOpConstructUint16: newType = EbtUint16; break;
  333. case EOpConstructInt64: newType = EbtInt64; break;
  334. case EOpConstructUint64: newType = EbtUint64; break;
  335. case EOpConstructDouble: newType = EbtDouble; break;
  336. case EOpConstructFloat16: newType = EbtFloat16; break;
  337. #endif
  338. default: break; // some compilers want this
  339. }
  340. if (newType != EbtVoid) {
  341. child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
  342. child->getMatrixCols(),
  343. child->getMatrixRows(),
  344. child->isVector()),
  345. child);
  346. if (child == nullptr)
  347. return nullptr;
  348. }
  349. //
  350. // For constructors, we are now done, it was all in the conversion.
  351. // TODO: but, did this bypass constant folding?
  352. //
  353. switch (op) {
  354. case EOpConstructInt8:
  355. case EOpConstructUint8:
  356. case EOpConstructInt16:
  357. case EOpConstructUint16:
  358. case EOpConstructInt:
  359. case EOpConstructUint:
  360. case EOpConstructInt64:
  361. case EOpConstructUint64:
  362. case EOpConstructBool:
  363. case EOpConstructFloat:
  364. case EOpConstructDouble:
  365. case EOpConstructFloat16:
  366. return child;
  367. default: break; // some compilers want this
  368. }
  369. //
  370. // Make a new node for the operator.
  371. //
  372. TIntermUnary* node = addUnaryNode(op, child, loc);
  373. if (! promote(node))
  374. return nullptr;
  375. node->updatePrecision();
  376. // If it's a (non-specialization) constant, it must be folded.
  377. if (node->getOperand()->getAsConstantUnion())
  378. return node->getOperand()->getAsConstantUnion()->fold(op, node->getType());
  379. // If it's a specialization constant, the result is too,
  380. // if the operation is allowed for specialization constants.
  381. if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
  382. node->getWritableType().getQualifier().makeSpecConstant();
  383. // If must propagate nonuniform, make a nonuniform.
  384. if (node->getOperand()->getQualifier().isNonUniform() && isNonuniformPropagating(node->getOp()))
  385. node->getWritableType().getQualifier().nonUniform = true;
  386. return node;
  387. }
  388. TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary,
  389. TIntermNode* childNode, const TType& returnType)
  390. {
  391. if (unary) {
  392. //
  393. // Treat it like a unary operator.
  394. // addUnaryMath() should get the type correct on its own;
  395. // including constness (which would differ from the prototype).
  396. //
  397. TIntermTyped* child = childNode->getAsTyped();
  398. if (child == nullptr)
  399. return nullptr;
  400. if (child->getAsConstantUnion()) {
  401. TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType);
  402. if (folded)
  403. return folded;
  404. }
  405. return addUnaryNode(op, child, child->getLoc(), returnType);
  406. } else {
  407. // setAggregateOperater() calls fold() for constant folding
  408. TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc);
  409. return node;
  410. }
  411. }
  412. //
  413. // This is the safe way to change the operator on an aggregate, as it
  414. // does lots of error checking and fixing. Especially for establishing
  415. // a function call's operation on its set of parameters. Sequences
  416. // of instructions are also aggregates, but they just directly set
  417. // their operator to EOpSequence.
  418. //
  419. // Returns an aggregate node, which could be the one passed in if
  420. // it was already an aggregate.
  421. //
  422. TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type,
  423. const TSourceLoc& loc)
  424. {
  425. TIntermAggregate* aggNode;
  426. //
  427. // Make sure we have an aggregate. If not turn it into one.
  428. //
  429. if (node != nullptr) {
  430. aggNode = node->getAsAggregate();
  431. if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
  432. //
  433. // Make an aggregate containing this node.
  434. //
  435. aggNode = new TIntermAggregate();
  436. aggNode->getSequence().push_back(node);
  437. }
  438. } else
  439. aggNode = new TIntermAggregate();
  440. //
  441. // Set the operator.
  442. //
  443. aggNode->setOperator(op);
  444. if (loc.line != 0 || node != nullptr)
  445. aggNode->setLoc(loc.line != 0 ? loc : node->getLoc());
  446. aggNode->setType(type);
  447. return fold(aggNode);
  448. }
  449. bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
  450. {
  451. //
  452. // Does the base type even allow the operation?
  453. //
  454. switch (node->getBasicType()) {
  455. case EbtVoid:
  456. return false;
  457. case EbtAtomicUint:
  458. case EbtSampler:
  459. case EbtAccStruct:
  460. // opaque types can be passed to functions
  461. if (op == EOpFunction)
  462. break;
  463. // HLSL can assign samplers directly (no constructor)
  464. if (getSource() == EShSourceHlsl && node->getBasicType() == EbtSampler)
  465. break;
  466. // samplers can get assigned via a sampler constructor
  467. // (well, not yet, but code in the rest of this function is ready for it)
  468. if (node->getBasicType() == EbtSampler && op == EOpAssign &&
  469. node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
  470. break;
  471. // otherwise, opaque types can't even be operated on, let alone converted
  472. return false;
  473. default:
  474. break;
  475. }
  476. return true;
  477. }
  478. bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const
  479. {
  480. switch (dst) {
  481. #ifndef GLSLANG_WEB
  482. case EbtDouble:
  483. switch (src) {
  484. case EbtUint: newOp = EOpConvUintToDouble; break;
  485. case EbtBool: newOp = EOpConvBoolToDouble; break;
  486. case EbtFloat: newOp = EOpConvFloatToDouble; break;
  487. case EbtInt: newOp = EOpConvIntToDouble; break;
  488. case EbtInt8: newOp = EOpConvInt8ToDouble; break;
  489. case EbtUint8: newOp = EOpConvUint8ToDouble; break;
  490. case EbtInt16: newOp = EOpConvInt16ToDouble; break;
  491. case EbtUint16: newOp = EOpConvUint16ToDouble; break;
  492. case EbtFloat16: newOp = EOpConvFloat16ToDouble; break;
  493. case EbtInt64: newOp = EOpConvInt64ToDouble; break;
  494. case EbtUint64: newOp = EOpConvUint64ToDouble; break;
  495. default:
  496. return false;
  497. }
  498. break;
  499. #endif
  500. case EbtFloat:
  501. switch (src) {
  502. case EbtInt: newOp = EOpConvIntToFloat; break;
  503. case EbtUint: newOp = EOpConvUintToFloat; break;
  504. case EbtBool: newOp = EOpConvBoolToFloat; break;
  505. #ifndef GLSLANG_WEB
  506. case EbtDouble: newOp = EOpConvDoubleToFloat; break;
  507. case EbtInt8: newOp = EOpConvInt8ToFloat; break;
  508. case EbtUint8: newOp = EOpConvUint8ToFloat; break;
  509. case EbtInt16: newOp = EOpConvInt16ToFloat; break;
  510. case EbtUint16: newOp = EOpConvUint16ToFloat; break;
  511. case EbtFloat16: newOp = EOpConvFloat16ToFloat; break;
  512. case EbtInt64: newOp = EOpConvInt64ToFloat; break;
  513. case EbtUint64: newOp = EOpConvUint64ToFloat; break;
  514. #endif
  515. default:
  516. return false;
  517. }
  518. break;
  519. #ifndef GLSLANG_WEB
  520. case EbtFloat16:
  521. switch (src) {
  522. case EbtInt8: newOp = EOpConvInt8ToFloat16; break;
  523. case EbtUint8: newOp = EOpConvUint8ToFloat16; break;
  524. case EbtInt16: newOp = EOpConvInt16ToFloat16; break;
  525. case EbtUint16: newOp = EOpConvUint16ToFloat16; break;
  526. case EbtInt: newOp = EOpConvIntToFloat16; break;
  527. case EbtUint: newOp = EOpConvUintToFloat16; break;
  528. case EbtBool: newOp = EOpConvBoolToFloat16; break;
  529. case EbtFloat: newOp = EOpConvFloatToFloat16; break;
  530. case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
  531. case EbtInt64: newOp = EOpConvInt64ToFloat16; break;
  532. case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
  533. default:
  534. return false;
  535. }
  536. break;
  537. #endif
  538. case EbtBool:
  539. switch (src) {
  540. case EbtInt: newOp = EOpConvIntToBool; break;
  541. case EbtUint: newOp = EOpConvUintToBool; break;
  542. case EbtFloat: newOp = EOpConvFloatToBool; break;
  543. #ifndef GLSLANG_WEB
  544. case EbtDouble: newOp = EOpConvDoubleToBool; break;
  545. case EbtInt8: newOp = EOpConvInt8ToBool; break;
  546. case EbtUint8: newOp = EOpConvUint8ToBool; break;
  547. case EbtInt16: newOp = EOpConvInt16ToBool; break;
  548. case EbtUint16: newOp = EOpConvUint16ToBool; break;
  549. case EbtFloat16: newOp = EOpConvFloat16ToBool; break;
  550. case EbtInt64: newOp = EOpConvInt64ToBool; break;
  551. case EbtUint64: newOp = EOpConvUint64ToBool; break;
  552. #endif
  553. default:
  554. return false;
  555. }
  556. break;
  557. #ifndef GLSLANG_WEB
  558. case EbtInt8:
  559. switch (src) {
  560. case EbtUint8: newOp = EOpConvUint8ToInt8; break;
  561. case EbtInt16: newOp = EOpConvInt16ToInt8; break;
  562. case EbtUint16: newOp = EOpConvUint16ToInt8; break;
  563. case EbtInt: newOp = EOpConvIntToInt8; break;
  564. case EbtUint: newOp = EOpConvUintToInt8; break;
  565. case EbtInt64: newOp = EOpConvInt64ToInt8; break;
  566. case EbtUint64: newOp = EOpConvUint64ToInt8; break;
  567. case EbtBool: newOp = EOpConvBoolToInt8; break;
  568. case EbtFloat: newOp = EOpConvFloatToInt8; break;
  569. case EbtDouble: newOp = EOpConvDoubleToInt8; break;
  570. case EbtFloat16: newOp = EOpConvFloat16ToInt8; break;
  571. default:
  572. return false;
  573. }
  574. break;
  575. case EbtUint8:
  576. switch (src) {
  577. case EbtInt8: newOp = EOpConvInt8ToUint8; break;
  578. case EbtInt16: newOp = EOpConvInt16ToUint8; break;
  579. case EbtUint16: newOp = EOpConvUint16ToUint8; break;
  580. case EbtInt: newOp = EOpConvIntToUint8; break;
  581. case EbtUint: newOp = EOpConvUintToUint8; break;
  582. case EbtInt64: newOp = EOpConvInt64ToUint8; break;
  583. case EbtUint64: newOp = EOpConvUint64ToUint8; break;
  584. case EbtBool: newOp = EOpConvBoolToUint8; break;
  585. case EbtFloat: newOp = EOpConvFloatToUint8; break;
  586. case EbtDouble: newOp = EOpConvDoubleToUint8; break;
  587. case EbtFloat16: newOp = EOpConvFloat16ToUint8; break;
  588. default:
  589. return false;
  590. }
  591. break;
  592. case EbtInt16:
  593. switch (src) {
  594. case EbtUint8: newOp = EOpConvUint8ToInt16; break;
  595. case EbtInt8: newOp = EOpConvInt8ToInt16; break;
  596. case EbtUint16: newOp = EOpConvUint16ToInt16; break;
  597. case EbtInt: newOp = EOpConvIntToInt16; break;
  598. case EbtUint: newOp = EOpConvUintToInt16; break;
  599. case EbtInt64: newOp = EOpConvInt64ToInt16; break;
  600. case EbtUint64: newOp = EOpConvUint64ToInt16; break;
  601. case EbtBool: newOp = EOpConvBoolToInt16; break;
  602. case EbtFloat: newOp = EOpConvFloatToInt16; break;
  603. case EbtDouble: newOp = EOpConvDoubleToInt16; break;
  604. case EbtFloat16: newOp = EOpConvFloat16ToInt16; break;
  605. default:
  606. return false;
  607. }
  608. break;
  609. case EbtUint16:
  610. switch (src) {
  611. case EbtInt8: newOp = EOpConvInt8ToUint16; break;
  612. case EbtUint8: newOp = EOpConvUint8ToUint16; break;
  613. case EbtInt16: newOp = EOpConvInt16ToUint16; break;
  614. case EbtInt: newOp = EOpConvIntToUint16; break;
  615. case EbtUint: newOp = EOpConvUintToUint16; break;
  616. case EbtInt64: newOp = EOpConvInt64ToUint16; break;
  617. case EbtUint64: newOp = EOpConvUint64ToUint16; break;
  618. case EbtBool: newOp = EOpConvBoolToUint16; break;
  619. case EbtFloat: newOp = EOpConvFloatToUint16; break;
  620. case EbtDouble: newOp = EOpConvDoubleToUint16; break;
  621. case EbtFloat16: newOp = EOpConvFloat16ToUint16; break;
  622. default:
  623. return false;
  624. }
  625. break;
  626. #endif
  627. case EbtInt:
  628. switch (src) {
  629. case EbtUint: newOp = EOpConvUintToInt; break;
  630. case EbtBool: newOp = EOpConvBoolToInt; break;
  631. case EbtFloat: newOp = EOpConvFloatToInt; break;
  632. #ifndef GLSLANG_WEB
  633. case EbtInt8: newOp = EOpConvInt8ToInt; break;
  634. case EbtUint8: newOp = EOpConvUint8ToInt; break;
  635. case EbtInt16: newOp = EOpConvInt16ToInt; break;
  636. case EbtUint16: newOp = EOpConvUint16ToInt; break;
  637. case EbtDouble: newOp = EOpConvDoubleToInt; break;
  638. case EbtFloat16: newOp = EOpConvFloat16ToInt; break;
  639. case EbtInt64: newOp = EOpConvInt64ToInt; break;
  640. case EbtUint64: newOp = EOpConvUint64ToInt; break;
  641. #endif
  642. default:
  643. return false;
  644. }
  645. break;
  646. case EbtUint:
  647. switch (src) {
  648. case EbtInt: newOp = EOpConvIntToUint; break;
  649. case EbtBool: newOp = EOpConvBoolToUint; break;
  650. case EbtFloat: newOp = EOpConvFloatToUint; break;
  651. #ifndef GLSLANG_WEB
  652. case EbtInt8: newOp = EOpConvInt8ToUint; break;
  653. case EbtUint8: newOp = EOpConvUint8ToUint; break;
  654. case EbtInt16: newOp = EOpConvInt16ToUint; break;
  655. case EbtUint16: newOp = EOpConvUint16ToUint; break;
  656. case EbtDouble: newOp = EOpConvDoubleToUint; break;
  657. case EbtFloat16: newOp = EOpConvFloat16ToUint; break;
  658. case EbtInt64: newOp = EOpConvInt64ToUint; break;
  659. case EbtUint64: newOp = EOpConvUint64ToUint; break;
  660. #endif
  661. default:
  662. return false;
  663. }
  664. break;
  665. #ifndef GLSLANG_WEB
  666. case EbtInt64:
  667. switch (src) {
  668. case EbtInt8: newOp = EOpConvInt8ToInt64; break;
  669. case EbtUint8: newOp = EOpConvUint8ToInt64; break;
  670. case EbtInt16: newOp = EOpConvInt16ToInt64; break;
  671. case EbtUint16: newOp = EOpConvUint16ToInt64; break;
  672. case EbtInt: newOp = EOpConvIntToInt64; break;
  673. case EbtUint: newOp = EOpConvUintToInt64; break;
  674. case EbtBool: newOp = EOpConvBoolToInt64; break;
  675. case EbtFloat: newOp = EOpConvFloatToInt64; break;
  676. case EbtDouble: newOp = EOpConvDoubleToInt64; break;
  677. case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
  678. case EbtUint64: newOp = EOpConvUint64ToInt64; break;
  679. default:
  680. return false;
  681. }
  682. break;
  683. case EbtUint64:
  684. switch (src) {
  685. case EbtInt8: newOp = EOpConvInt8ToUint64; break;
  686. case EbtUint8: newOp = EOpConvUint8ToUint64; break;
  687. case EbtInt16: newOp = EOpConvInt16ToUint64; break;
  688. case EbtUint16: newOp = EOpConvUint16ToUint64; break;
  689. case EbtInt: newOp = EOpConvIntToUint64; break;
  690. case EbtUint: newOp = EOpConvUintToUint64; break;
  691. case EbtBool: newOp = EOpConvBoolToUint64; break;
  692. case EbtFloat: newOp = EOpConvFloatToUint64; break;
  693. case EbtDouble: newOp = EOpConvDoubleToUint64; break;
  694. case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
  695. case EbtInt64: newOp = EOpConvInt64ToUint64; break;
  696. default:
  697. return false;
  698. }
  699. break;
  700. #endif
  701. default:
  702. return false;
  703. }
  704. return true;
  705. }
  706. // This is 'mechanism' here, it does any conversion told.
  707. // It is about basic type, not about shape.
  708. // The policy comes from the shader or the calling code.
  709. TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const
  710. {
  711. //
  712. // Add a new newNode for the conversion.
  713. //
  714. #ifndef GLSLANG_WEB
  715. bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 ||
  716. convertTo == EbtInt16 || convertTo == EbtUint16 ||
  717. convertTo == EbtInt || convertTo == EbtUint ||
  718. convertTo == EbtInt64 || convertTo == EbtUint64);
  719. bool convertFromIntTypes = (node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8 ||
  720. node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16 ||
  721. node->getBasicType() == EbtInt || node->getBasicType() == EbtUint ||
  722. node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64);
  723. bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble);
  724. bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 ||
  725. node->getBasicType() == EbtFloat ||
  726. node->getBasicType() == EbtDouble);
  727. if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) ||
  728. ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) {
  729. if (! getArithemeticInt8Enabled()) {
  730. return nullptr;
  731. }
  732. }
  733. if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) ||
  734. ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) {
  735. if (! getArithemeticInt16Enabled()) {
  736. return nullptr;
  737. }
  738. }
  739. if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) ||
  740. (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) {
  741. if (! getArithemeticFloat16Enabled()) {
  742. return nullptr;
  743. }
  744. }
  745. #endif
  746. TIntermUnary* newNode = nullptr;
  747. TOperator newOp = EOpNull;
  748. if (!buildConvertOp(convertTo, node->getBasicType(), newOp)) {
  749. return nullptr;
  750. }
  751. TType newType(convertTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
  752. newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
  753. if (node->getAsConstantUnion()) {
  754. #ifndef GLSLANG_WEB
  755. // 8/16-bit storage extensions don't support 8/16-bit constants, so don't fold conversions
  756. // to those types
  757. if ((getArithemeticInt8Enabled() || !(convertTo == EbtInt8 || convertTo == EbtUint8)) &&
  758. (getArithemeticInt16Enabled() || !(convertTo == EbtInt16 || convertTo == EbtUint16)) &&
  759. (getArithemeticFloat16Enabled() || !(convertTo == EbtFloat16)))
  760. #endif
  761. {
  762. TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType);
  763. if (folded)
  764. return folded;
  765. }
  766. }
  767. // Propagate specialization-constant-ness, if allowed
  768. if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode))
  769. newNode->getWritableType().getQualifier().makeSpecConstant();
  770. return newNode;
  771. }
  772. TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const
  773. {
  774. return createConversion(convertTo, node);
  775. }
  776. // For converting a pair of operands to a binary operation to compatible
  777. // types with each other, relative to the operation in 'op'.
  778. // This does not cover assignment operations, which is asymmetric in that the
  779. // left type is not changeable.
  780. // See addConversion(op, type, node) for assignments and unary operation
  781. // conversions.
  782. //
  783. // Generally, this is focused on basic type conversion, not shape conversion.
  784. // See addShapeConversion() for shape conversions.
  785. //
  786. // Returns the converted pair of nodes.
  787. // Returns <nullptr, nullptr> when there is no conversion.
  788. std::tuple<TIntermTyped*, TIntermTyped*>
  789. TIntermediate::addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1)
  790. {
  791. if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1))
  792. return std::make_tuple(nullptr, nullptr);
  793. if (node0->getType() != node1->getType()) {
  794. // If differing structure, then no conversions.
  795. if (node0->isStruct() || node1->isStruct())
  796. return std::make_tuple(nullptr, nullptr);
  797. // If differing arrays, then no conversions.
  798. if (node0->getType().isArray() || node1->getType().isArray())
  799. return std::make_tuple(nullptr, nullptr);
  800. // No implicit conversions for operations involving cooperative matrices
  801. if (node0->getType().isCoopMat() || node1->getType().isCoopMat())
  802. return std::make_tuple(node0, node1);
  803. }
  804. auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes);
  805. switch (op) {
  806. //
  807. // List all the binary ops that can implicitly convert one operand to the other's type;
  808. // This implements the 'policy' for implicit type conversion.
  809. //
  810. case EOpLessThan:
  811. case EOpGreaterThan:
  812. case EOpLessThanEqual:
  813. case EOpGreaterThanEqual:
  814. case EOpEqual:
  815. case EOpNotEqual:
  816. case EOpAdd:
  817. case EOpSub:
  818. case EOpMul:
  819. case EOpDiv:
  820. case EOpMod:
  821. case EOpVectorTimesScalar:
  822. case EOpVectorTimesMatrix:
  823. case EOpMatrixTimesVector:
  824. case EOpMatrixTimesScalar:
  825. case EOpAnd:
  826. case EOpInclusiveOr:
  827. case EOpExclusiveOr:
  828. case EOpSequence: // used by ?:
  829. if (node0->getBasicType() == node1->getBasicType())
  830. return std::make_tuple(node0, node1);
  831. promoteTo = getConversionDestinationType(node0->getBasicType(), node1->getBasicType(), op);
  832. if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes)
  833. return std::make_tuple(nullptr, nullptr);
  834. break;
  835. case EOpLogicalAnd:
  836. case EOpLogicalOr:
  837. case EOpLogicalXor:
  838. if (getSource() == EShSourceHlsl)
  839. promoteTo = std::make_tuple(EbtBool, EbtBool);
  840. else
  841. return std::make_tuple(node0, node1);
  842. break;
  843. // There are no conversions needed for GLSL; the shift amount just needs to be an
  844. // integer type, as does the base.
  845. // HLSL can promote bools to ints to make this work.
  846. case EOpLeftShift:
  847. case EOpRightShift:
  848. if (getSource() == EShSourceHlsl) {
  849. TBasicType node0BasicType = node0->getBasicType();
  850. if (node0BasicType == EbtBool)
  851. node0BasicType = EbtInt;
  852. if (node1->getBasicType() == EbtBool)
  853. promoteTo = std::make_tuple(node0BasicType, EbtInt);
  854. else
  855. promoteTo = std::make_tuple(node0BasicType, node1->getBasicType());
  856. } else {
  857. if (isTypeInt(node0->getBasicType()) && isTypeInt(node1->getBasicType()))
  858. return std::make_tuple(node0, node1);
  859. else
  860. return std::make_tuple(nullptr, nullptr);
  861. }
  862. break;
  863. default:
  864. if (node0->getType() == node1->getType())
  865. return std::make_tuple(node0, node1);
  866. return std::make_tuple(nullptr, nullptr);
  867. }
  868. TIntermTyped* newNode0;
  869. TIntermTyped* newNode1;
  870. if (std::get<0>(promoteTo) != node0->getType().getBasicType()) {
  871. if (node0->getAsConstantUnion())
  872. newNode0 = promoteConstantUnion(std::get<0>(promoteTo), node0->getAsConstantUnion());
  873. else
  874. newNode0 = createConversion(std::get<0>(promoteTo), node0);
  875. } else
  876. newNode0 = node0;
  877. if (std::get<1>(promoteTo) != node1->getType().getBasicType()) {
  878. if (node1->getAsConstantUnion())
  879. newNode1 = promoteConstantUnion(std::get<1>(promoteTo), node1->getAsConstantUnion());
  880. else
  881. newNode1 = createConversion(std::get<1>(promoteTo), node1);
  882. } else
  883. newNode1 = node1;
  884. return std::make_tuple(newNode0, newNode1);
  885. }
  886. //
  887. // Convert the node's type to the given type, as allowed by the operation involved: 'op'.
  888. // For implicit conversions, 'op' is not the requested conversion, it is the explicit
  889. // operation requiring the implicit conversion.
  890. //
  891. // Binary operation conversions should be handled by addConversion(op, node, node), not here.
  892. //
  893. // Returns a node representing the conversion, which could be the same
  894. // node passed in if no conversion was needed.
  895. //
  896. // Generally, this is focused on basic type conversion, not shape conversion.
  897. // See addShapeConversion() for shape conversions.
  898. //
  899. // Return nullptr if a conversion can't be done.
  900. //
  901. TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
  902. {
  903. if (!isConversionAllowed(op, node))
  904. return nullptr;
  905. // Otherwise, if types are identical, no problem
  906. if (type == node->getType())
  907. return node;
  908. // If one's a structure, then no conversions.
  909. if (type.isStruct() || node->isStruct())
  910. return nullptr;
  911. // If one's an array, then no conversions.
  912. if (type.isArray() || node->getType().isArray())
  913. return nullptr;
  914. // Note: callers are responsible for other aspects of shape,
  915. // like vector and matrix sizes.
  916. switch (op) {
  917. //
  918. // Explicit conversions (unary operations)
  919. //
  920. case EOpConstructBool:
  921. case EOpConstructFloat:
  922. case EOpConstructInt:
  923. case EOpConstructUint:
  924. #ifndef GLSLANG_WEB
  925. case EOpConstructDouble:
  926. case EOpConstructFloat16:
  927. case EOpConstructInt8:
  928. case EOpConstructUint8:
  929. case EOpConstructInt16:
  930. case EOpConstructUint16:
  931. case EOpConstructInt64:
  932. case EOpConstructUint64:
  933. break;
  934. #endif
  935. //
  936. // Implicit conversions
  937. //
  938. case EOpLogicalNot:
  939. case EOpFunctionCall:
  940. case EOpReturn:
  941. case EOpAssign:
  942. case EOpAddAssign:
  943. case EOpSubAssign:
  944. case EOpMulAssign:
  945. case EOpVectorTimesScalarAssign:
  946. case EOpMatrixTimesScalarAssign:
  947. case EOpDivAssign:
  948. case EOpModAssign:
  949. case EOpAndAssign:
  950. case EOpInclusiveOrAssign:
  951. case EOpExclusiveOrAssign:
  952. case EOpAtan:
  953. case EOpClamp:
  954. case EOpCross:
  955. case EOpDistance:
  956. case EOpDot:
  957. case EOpDst:
  958. case EOpFaceForward:
  959. case EOpFma:
  960. case EOpFrexp:
  961. case EOpLdexp:
  962. case EOpMix:
  963. case EOpLit:
  964. case EOpMax:
  965. case EOpMin:
  966. case EOpMod:
  967. case EOpModf:
  968. case EOpPow:
  969. case EOpReflect:
  970. case EOpRefract:
  971. case EOpSmoothStep:
  972. case EOpStep:
  973. case EOpSequence:
  974. case EOpConstructStruct:
  975. case EOpConstructCooperativeMatrix:
  976. if (type.isReference() || node->getType().isReference()) {
  977. // types must match to assign a reference
  978. if (type == node->getType())
  979. return node;
  980. else
  981. return nullptr;
  982. }
  983. if (type.getBasicType() == node->getType().getBasicType())
  984. return node;
  985. if (! canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op))
  986. return nullptr;
  987. break;
  988. // For GLSL, there are no conversions needed; the shift amount just needs to be an
  989. // integer type, as do the base/result.
  990. // HLSL can convert the shift from a bool to an int.
  991. case EOpLeftShiftAssign:
  992. case EOpRightShiftAssign:
  993. {
  994. if (!(getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)) {
  995. if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType()))
  996. return node;
  997. else
  998. return nullptr;
  999. }
  1000. break;
  1001. }
  1002. default:
  1003. // default is to require a match; all exceptions should have case statements above
  1004. if (type.getBasicType() == node->getType().getBasicType())
  1005. return node;
  1006. else
  1007. return nullptr;
  1008. }
  1009. bool canPromoteConstant = true;
  1010. #ifndef GLSLANG_WEB
  1011. // GL_EXT_shader_16bit_storage can't do OpConstantComposite with
  1012. // 16-bit types, so disable promotion for those types.
  1013. // Many issues with this, from JohnK:
  1014. // - this isn't really right to discuss SPIR-V here
  1015. // - this could easily be entirely about scalars, so is overstepping
  1016. // - we should be looking at what the shader asked for, and saying whether or
  1017. // not it can be done, in the parser, by calling requireExtensions(), not
  1018. // changing language sementics on the fly by asking what extensions are in use
  1019. // - at the time of this writing (14-Aug-2020), no test results are changed by this.
  1020. switch (op) {
  1021. case EOpConstructFloat16:
  1022. canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
  1023. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
  1024. break;
  1025. case EOpConstructInt8:
  1026. case EOpConstructUint8:
  1027. canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
  1028. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8);
  1029. break;
  1030. case EOpConstructInt16:
  1031. case EOpConstructUint16:
  1032. canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
  1033. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16);
  1034. break;
  1035. default:
  1036. break;
  1037. }
  1038. #endif
  1039. if (canPromoteConstant && node->getAsConstantUnion())
  1040. return promoteConstantUnion(type.getBasicType(), node->getAsConstantUnion());
  1041. //
  1042. // Add a new newNode for the conversion.
  1043. //
  1044. TIntermTyped* newNode = createConversion(type.getBasicType(), node);
  1045. return newNode;
  1046. }
  1047. // Convert the node's shape of type for the given type, as allowed by the
  1048. // operation involved: 'op'. This is for situations where there is only one
  1049. // direction to consider doing the shape conversion.
  1050. //
  1051. // This implements policy, it call addShapeConversion() for the mechanism.
  1052. //
  1053. // Generally, the AST represents allowed GLSL shapes, so this isn't needed
  1054. // for GLSL. Bad shapes are caught in conversion or promotion.
  1055. //
  1056. // Return 'node' if no conversion was done. Promotion handles final shape
  1057. // checking.
  1058. //
  1059. TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
  1060. {
  1061. // some source languages don't do this
  1062. switch (getSource()) {
  1063. case EShSourceHlsl:
  1064. break;
  1065. case EShSourceGlsl:
  1066. default:
  1067. return node;
  1068. }
  1069. // some operations don't do this
  1070. switch (op) {
  1071. case EOpFunctionCall:
  1072. case EOpReturn:
  1073. break;
  1074. case EOpMulAssign:
  1075. // want to support vector *= scalar native ops in AST and lower, not smear, similarly for
  1076. // matrix *= scalar, etc.
  1077. case EOpAddAssign:
  1078. case EOpSubAssign:
  1079. case EOpDivAssign:
  1080. case EOpAndAssign:
  1081. case EOpInclusiveOrAssign:
  1082. case EOpExclusiveOrAssign:
  1083. case EOpRightShiftAssign:
  1084. case EOpLeftShiftAssign:
  1085. if (node->getVectorSize() == 1)
  1086. return node;
  1087. break;
  1088. case EOpAssign:
  1089. break;
  1090. case EOpMix:
  1091. break;
  1092. default:
  1093. return node;
  1094. }
  1095. return addShapeConversion(type, node);
  1096. }
  1097. // Convert the nodes' shapes to be compatible for the operation 'op'.
  1098. //
  1099. // This implements policy, it call addShapeConversion() for the mechanism.
  1100. //
  1101. // Generally, the AST represents allowed GLSL shapes, so this isn't needed
  1102. // for GLSL. Bad shapes are caught in conversion or promotion.
  1103. //
  1104. void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
  1105. {
  1106. // some source languages don't do this
  1107. switch (getSource()) {
  1108. case EShSourceHlsl:
  1109. break;
  1110. case EShSourceGlsl:
  1111. default:
  1112. return;
  1113. }
  1114. // some operations don't do this
  1115. // 'break' will mean attempt bidirectional conversion
  1116. switch (op) {
  1117. case EOpMulAssign:
  1118. case EOpAssign:
  1119. case EOpAddAssign:
  1120. case EOpSubAssign:
  1121. case EOpDivAssign:
  1122. case EOpAndAssign:
  1123. case EOpInclusiveOrAssign:
  1124. case EOpExclusiveOrAssign:
  1125. case EOpRightShiftAssign:
  1126. case EOpLeftShiftAssign:
  1127. // switch to unidirectional conversion (the lhs can't change)
  1128. rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
  1129. return;
  1130. case EOpMul:
  1131. // matrix multiply does not change shapes
  1132. if (lhsNode->isMatrix() && rhsNode->isMatrix())
  1133. return;
  1134. case EOpAdd:
  1135. case EOpSub:
  1136. case EOpDiv:
  1137. // want to support vector * scalar native ops in AST and lower, not smear, similarly for
  1138. // matrix * vector, etc.
  1139. if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1)
  1140. return;
  1141. break;
  1142. case EOpRightShift:
  1143. case EOpLeftShift:
  1144. // can natively support the right operand being a scalar and the left a vector,
  1145. // but not the reverse
  1146. if (rhsNode->getVectorSize() == 1)
  1147. return;
  1148. break;
  1149. case EOpLessThan:
  1150. case EOpGreaterThan:
  1151. case EOpLessThanEqual:
  1152. case EOpGreaterThanEqual:
  1153. case EOpEqual:
  1154. case EOpNotEqual:
  1155. case EOpLogicalAnd:
  1156. case EOpLogicalOr:
  1157. case EOpLogicalXor:
  1158. case EOpAnd:
  1159. case EOpInclusiveOr:
  1160. case EOpExclusiveOr:
  1161. case EOpMix:
  1162. break;
  1163. default:
  1164. return;
  1165. }
  1166. // Do bidirectional conversions
  1167. if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) {
  1168. if (lhsNode->getType().isScalarOrVec1())
  1169. lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
  1170. else
  1171. rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
  1172. }
  1173. lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
  1174. rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
  1175. }
  1176. // Convert the node's shape of type for the given type, as allowed by the
  1177. // operation involved: 'op'.
  1178. //
  1179. // Generally, the AST represents allowed GLSL shapes, so this isn't needed
  1180. // for GLSL. Bad shapes are caught in conversion or promotion.
  1181. //
  1182. // Return 'node' if no conversion was done. Promotion handles final shape
  1183. // checking.
  1184. //
  1185. TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
  1186. {
  1187. // no conversion needed
  1188. if (node->getType() == type)
  1189. return node;
  1190. // structures and arrays don't change shape, either to or from
  1191. if (node->getType().isStruct() || node->getType().isArray() ||
  1192. type.isStruct() || type.isArray())
  1193. return node;
  1194. // The new node that handles the conversion
  1195. TOperator constructorOp = mapTypeToConstructorOp(type);
  1196. if (getSource() == EShSourceHlsl) {
  1197. // HLSL rules for scalar, vector and matrix conversions:
  1198. // 1) scalar can become anything, initializing every component with its value
  1199. // 2) vector and matrix can become scalar, first element is used (warning: truncation)
  1200. // 3) matrix can become matrix with less rows and/or columns (warning: truncation)
  1201. // 4) vector can become vector with less rows size (warning: truncation)
  1202. // 5a) vector 4 can become 2x2 matrix (special case) (same packing layout, its a reinterpret)
  1203. // 5b) 2x2 matrix can become vector 4 (special case) (same packing layout, its a reinterpret)
  1204. const TType &sourceType = node->getType();
  1205. // rule 1 for scalar to matrix is special
  1206. if (sourceType.isScalarOrVec1() && type.isMatrix()) {
  1207. // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its
  1208. // own devices, the constructor from a scalar would populate the diagonal. This forces replication
  1209. // to every matrix element.
  1210. // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here
  1211. // repeatedly, so we copy it to a temp, then use the temp.
  1212. const int matSize = type.computeNumComponents();
  1213. TIntermAggregate* rhsAggregate = new TIntermAggregate();
  1214. const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr);
  1215. if (!isSimple) {
  1216. assert(0); // TODO: use node replicator service when available.
  1217. }
  1218. for (int x = 0; x < matSize; ++x)
  1219. rhsAggregate->getSequence().push_back(node);
  1220. return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc());
  1221. }
  1222. // rule 1 and 2
  1223. if ((sourceType.isScalar() && !type.isScalar()) || (!sourceType.isScalar() && type.isScalar()))
  1224. return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
  1225. // rule 3 and 5b
  1226. if (sourceType.isMatrix()) {
  1227. // rule 3
  1228. if (type.isMatrix()) {
  1229. if ((sourceType.getMatrixCols() != type.getMatrixCols() || sourceType.getMatrixRows() != type.getMatrixRows()) &&
  1230. sourceType.getMatrixCols() >= type.getMatrixCols() && sourceType.getMatrixRows() >= type.getMatrixRows())
  1231. return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
  1232. // rule 5b
  1233. } else if (type.isVector()) {
  1234. if (type.getVectorSize() == 4 && sourceType.getMatrixCols() == 2 && sourceType.getMatrixRows() == 2)
  1235. return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
  1236. }
  1237. }
  1238. // rule 4 and 5a
  1239. if (sourceType.isVector()) {
  1240. // rule 4
  1241. if (type.isVector())
  1242. {
  1243. if (sourceType.getVectorSize() > type.getVectorSize())
  1244. return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
  1245. // rule 5a
  1246. } else if (type.isMatrix()) {
  1247. if (sourceType.getVectorSize() == 4 && type.getMatrixCols() == 2 && type.getMatrixRows() == 2)
  1248. return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
  1249. }
  1250. }
  1251. }
  1252. // scalar -> vector or vec1 -> vector or
  1253. // vector -> scalar or
  1254. // bigger vector -> smaller vector
  1255. if ((node->getType().isScalarOrVec1() && type.isVector()) ||
  1256. (node->getType().isVector() && type.isScalar()) ||
  1257. (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize()))
  1258. return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
  1259. return node;
  1260. }
  1261. bool TIntermediate::isIntegralPromotion(TBasicType from, TBasicType to) const
  1262. {
  1263. // integral promotions
  1264. if (to == EbtInt) {
  1265. switch(from) {
  1266. case EbtInt8:
  1267. case EbtInt16:
  1268. case EbtUint8:
  1269. case EbtUint16:
  1270. return true;
  1271. default:
  1272. break;
  1273. }
  1274. }
  1275. return false;
  1276. }
  1277. bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const
  1278. {
  1279. // floating-point promotions
  1280. if (to == EbtDouble) {
  1281. switch(from) {
  1282. case EbtFloat16:
  1283. case EbtFloat:
  1284. return true;
  1285. default:
  1286. break;
  1287. }
  1288. }
  1289. return false;
  1290. }
  1291. bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const
  1292. {
  1293. #ifdef GLSLANG_WEB
  1294. return false;
  1295. #endif
  1296. switch (from) {
  1297. case EbtInt:
  1298. switch(to) {
  1299. case EbtUint:
  1300. return version >= 400 || getSource() == EShSourceHlsl;
  1301. case EbtInt64:
  1302. case EbtUint64:
  1303. return true;
  1304. default:
  1305. break;
  1306. }
  1307. break;
  1308. case EbtUint:
  1309. switch(to) {
  1310. case EbtInt64:
  1311. case EbtUint64:
  1312. return true;
  1313. default:
  1314. break;
  1315. }
  1316. break;
  1317. case EbtInt8:
  1318. switch (to) {
  1319. case EbtUint8:
  1320. case EbtInt16:
  1321. case EbtUint16:
  1322. case EbtUint:
  1323. case EbtInt64:
  1324. case EbtUint64:
  1325. return true;
  1326. default:
  1327. break;
  1328. }
  1329. break;
  1330. case EbtUint8:
  1331. switch (to) {
  1332. case EbtInt16:
  1333. case EbtUint16:
  1334. case EbtUint:
  1335. case EbtInt64:
  1336. case EbtUint64:
  1337. return true;
  1338. default:
  1339. break;
  1340. }
  1341. break;
  1342. case EbtInt16:
  1343. switch(to) {
  1344. case EbtUint16:
  1345. case EbtUint:
  1346. case EbtInt64:
  1347. case EbtUint64:
  1348. return true;
  1349. default:
  1350. break;
  1351. }
  1352. break;
  1353. case EbtUint16:
  1354. switch(to) {
  1355. case EbtUint:
  1356. case EbtInt64:
  1357. case EbtUint64:
  1358. return true;
  1359. default:
  1360. break;
  1361. }
  1362. break;
  1363. case EbtInt64:
  1364. if (to == EbtUint64) {
  1365. return true;
  1366. }
  1367. break;
  1368. default:
  1369. break;
  1370. }
  1371. return false;
  1372. }
  1373. bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const
  1374. {
  1375. #ifdef GLSLANG_WEB
  1376. return false;
  1377. #endif
  1378. if (to == EbtFloat && from == EbtFloat16) {
  1379. return true;
  1380. } else {
  1381. return false;
  1382. }
  1383. }
  1384. bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const
  1385. {
  1386. switch (from) {
  1387. case EbtInt:
  1388. case EbtUint:
  1389. switch(to) {
  1390. case EbtFloat:
  1391. case EbtDouble:
  1392. return true;
  1393. default:
  1394. break;
  1395. }
  1396. break;
  1397. #ifndef GLSLANG_WEB
  1398. case EbtInt8:
  1399. case EbtUint8:
  1400. case EbtInt16:
  1401. case EbtUint16:
  1402. switch (to) {
  1403. case EbtFloat16:
  1404. case EbtFloat:
  1405. case EbtDouble:
  1406. return true;
  1407. default:
  1408. break;
  1409. }
  1410. break;
  1411. case EbtInt64:
  1412. case EbtUint64:
  1413. if (to == EbtDouble) {
  1414. return true;
  1415. }
  1416. break;
  1417. #endif
  1418. default:
  1419. break;
  1420. }
  1421. return false;
  1422. }
  1423. //
  1424. // See if the 'from' type is allowed to be implicitly converted to the
  1425. // 'to' type. This is not about vector/array/struct, only about basic type.
  1426. //
  1427. bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const
  1428. {
  1429. return (from == to); // godlike: Because I like explicitness
  1430. if ((isEsProfile() && version < 310 ) || version == 110)
  1431. return false;
  1432. if (from == to)
  1433. return true;
  1434. // TODO: Move more policies into language-specific handlers.
  1435. // Some languages allow more general (or potentially, more specific) conversions under some conditions.
  1436. if (getSource() == EShSourceHlsl) {
  1437. const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool);
  1438. const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool);
  1439. if (fromConvertable && toConvertable) {
  1440. switch (op) {
  1441. case EOpAndAssign: // assignments can perform arbitrary conversions
  1442. case EOpInclusiveOrAssign: // ...
  1443. case EOpExclusiveOrAssign: // ...
  1444. case EOpAssign: // ...
  1445. case EOpAddAssign: // ...
  1446. case EOpSubAssign: // ...
  1447. case EOpMulAssign: // ...
  1448. case EOpVectorTimesScalarAssign: // ...
  1449. case EOpMatrixTimesScalarAssign: // ...
  1450. case EOpDivAssign: // ...
  1451. case EOpModAssign: // ...
  1452. case EOpReturn: // function returns can also perform arbitrary conversions
  1453. case EOpFunctionCall: // conversion of a calling parameter
  1454. case EOpLogicalNot:
  1455. case EOpLogicalAnd:
  1456. case EOpLogicalOr:
  1457. case EOpLogicalXor:
  1458. case EOpConstructStruct:
  1459. return true;
  1460. default:
  1461. break;
  1462. }
  1463. }
  1464. }
  1465. if (getSource() == EShSourceHlsl) {
  1466. // HLSL
  1467. if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat))
  1468. return true;
  1469. } else {
  1470. // GLSL
  1471. if (isIntegralPromotion(from, to) ||
  1472. isFPPromotion(from, to) ||
  1473. isIntegralConversion(from, to) ||
  1474. isFPConversion(from, to) ||
  1475. isFPIntegralConversion(from, to)) {
  1476. if (numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
  1477. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8) ||
  1478. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16) ||
  1479. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int32) ||
  1480. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int64) ||
  1481. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16) ||
  1482. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float32) ||
  1483. numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float64)) {
  1484. return true;
  1485. }
  1486. }
  1487. }
  1488. if (isEsProfile()) {
  1489. switch (to) {
  1490. case EbtFloat:
  1491. switch (from) {
  1492. case EbtInt:
  1493. case EbtUint:
  1494. return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions);
  1495. default:
  1496. return false;
  1497. }
  1498. case EbtUint:
  1499. switch (from) {
  1500. case EbtInt:
  1501. return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions);
  1502. default:
  1503. return false;
  1504. }
  1505. default:
  1506. return false;
  1507. }
  1508. } else {
  1509. switch (to) {
  1510. case EbtDouble:
  1511. switch (from) {
  1512. case EbtInt:
  1513. case EbtUint:
  1514. case EbtInt64:
  1515. case EbtUint64:
  1516. case EbtFloat:
  1517. return version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64);
  1518. case EbtInt16:
  1519. case EbtUint16:
  1520. return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
  1521. numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1522. case EbtFloat16:
  1523. return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
  1524. numericFeatures.contains(TNumericFeatures::gpu_shader_half_float);
  1525. default:
  1526. return false;
  1527. }
  1528. case EbtFloat:
  1529. switch (from) {
  1530. case EbtInt:
  1531. case EbtUint:
  1532. return true;
  1533. case EbtBool:
  1534. return getSource() == EShSourceHlsl;
  1535. case EbtInt16:
  1536. case EbtUint16:
  1537. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1538. case EbtFloat16:
  1539. return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
  1540. getSource() == EShSourceHlsl;
  1541. default:
  1542. return false;
  1543. }
  1544. case EbtUint:
  1545. switch (from) {
  1546. case EbtInt:
  1547. return version >= 400 || getSource() == EShSourceHlsl;
  1548. case EbtBool:
  1549. return getSource() == EShSourceHlsl;
  1550. case EbtInt16:
  1551. case EbtUint16:
  1552. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1553. default:
  1554. return false;
  1555. }
  1556. case EbtInt:
  1557. switch (from) {
  1558. case EbtBool:
  1559. return getSource() == EShSourceHlsl;
  1560. case EbtInt16:
  1561. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1562. default:
  1563. return false;
  1564. }
  1565. case EbtUint64:
  1566. switch (from) {
  1567. case EbtInt:
  1568. case EbtUint:
  1569. case EbtInt64:
  1570. return true;
  1571. case EbtInt16:
  1572. case EbtUint16:
  1573. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1574. default:
  1575. return false;
  1576. }
  1577. case EbtInt64:
  1578. switch (from) {
  1579. case EbtInt:
  1580. return true;
  1581. case EbtInt16:
  1582. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1583. default:
  1584. return false;
  1585. }
  1586. case EbtFloat16:
  1587. switch (from) {
  1588. case EbtInt16:
  1589. case EbtUint16:
  1590. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1591. default:
  1592. break;
  1593. }
  1594. return false;
  1595. case EbtUint16:
  1596. switch (from) {
  1597. case EbtInt16:
  1598. return numericFeatures.contains(TNumericFeatures::gpu_shader_int16);
  1599. default:
  1600. break;
  1601. }
  1602. return false;
  1603. default:
  1604. return false;
  1605. }
  1606. }
  1607. return false;
  1608. }
  1609. static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType)
  1610. {
  1611. #ifdef GLSLANG_WEB
  1612. return false;
  1613. #endif
  1614. switch(sintType) {
  1615. case EbtInt8:
  1616. switch(uintType) {
  1617. case EbtUint8:
  1618. case EbtUint16:
  1619. case EbtUint:
  1620. case EbtUint64:
  1621. return false;
  1622. default:
  1623. assert(false);
  1624. return false;
  1625. }
  1626. break;
  1627. case EbtInt16:
  1628. switch(uintType) {
  1629. case EbtUint8:
  1630. return true;
  1631. case EbtUint16:
  1632. case EbtUint:
  1633. case EbtUint64:
  1634. return false;
  1635. default:
  1636. assert(false);
  1637. return false;
  1638. }
  1639. break;
  1640. case EbtInt:
  1641. switch(uintType) {
  1642. case EbtUint8:
  1643. case EbtUint16:
  1644. return true;
  1645. case EbtUint:
  1646. return false;
  1647. default:
  1648. assert(false);
  1649. return false;
  1650. }
  1651. break;
  1652. case EbtInt64:
  1653. switch(uintType) {
  1654. case EbtUint8:
  1655. case EbtUint16:
  1656. case EbtUint:
  1657. return true;
  1658. case EbtUint64:
  1659. return false;
  1660. default:
  1661. assert(false);
  1662. return false;
  1663. }
  1664. break;
  1665. default:
  1666. assert(false);
  1667. return false;
  1668. }
  1669. }
  1670. static TBasicType getCorrespondingUnsignedType(TBasicType type)
  1671. {
  1672. #ifdef GLSLANG_WEB
  1673. assert(type == EbtInt);
  1674. return EbtUint;
  1675. #endif
  1676. switch(type) {
  1677. case EbtInt8:
  1678. return EbtUint8;
  1679. case EbtInt16:
  1680. return EbtUint16;
  1681. case EbtInt:
  1682. return EbtUint;
  1683. case EbtInt64:
  1684. return EbtUint64;
  1685. default:
  1686. assert(false);
  1687. return EbtNumTypes;
  1688. }
  1689. }
  1690. // Implements the following rules
  1691. // - If either operand has type float64_t or derived from float64_t,
  1692. // the other shall be converted to float64_t or derived type.
  1693. // - Otherwise, if either operand has type float32_t or derived from
  1694. // float32_t, the other shall be converted to float32_t or derived type.
  1695. // - Otherwise, if either operand has type float16_t or derived from
  1696. // float16_t, the other shall be converted to float16_t or derived type.
  1697. // - Otherwise, if both operands have integer types the following rules
  1698. // shall be applied to the operands:
  1699. // - If both operands have the same type, no further conversion
  1700. // is needed.
  1701. // - Otherwise, if both operands have signed integer types or both
  1702. // have unsigned integer types, the operand with the type of lesser
  1703. // integer conversion rank shall be converted to the type of the
  1704. // operand with greater rank.
  1705. // - Otherwise, if the operand that has unsigned integer type has rank
  1706. // greater than or equal to the rank of the type of the other
  1707. // operand, the operand with signed integer type shall be converted
  1708. // to the type of the operand with unsigned integer type.
  1709. // - Otherwise, if the type of the operand with signed integer type can
  1710. // represent all of the values of the type of the operand with
  1711. // unsigned integer type, the operand with unsigned integer type
  1712. // shall be converted to the type of the operand with signed
  1713. // integer type.
  1714. // - Otherwise, both operands shall be converted to the unsigned
  1715. // integer type corresponding to the type of the operand with signed
  1716. // integer type.
  1717. std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const
  1718. {
  1719. TBasicType res0 = EbtNumTypes;
  1720. TBasicType res1 = EbtNumTypes;
  1721. if ((isEsProfile() &&
  1722. (version < 310 || !numericFeatures.contains(TNumericFeatures::shader_implicit_conversions))) ||
  1723. version == 110)
  1724. return std::make_tuple(res0, res1);
  1725. if (getSource() == EShSourceHlsl) {
  1726. if (canImplicitlyPromote(type1, type0, op)) {
  1727. res0 = type0;
  1728. res1 = type0;
  1729. } else if (canImplicitlyPromote(type0, type1, op)) {
  1730. res0 = type1;
  1731. res1 = type1;
  1732. }
  1733. return std::make_tuple(res0, res1);
  1734. }
  1735. if ((type0 == EbtDouble && canImplicitlyPromote(type1, EbtDouble, op)) ||
  1736. (type1 == EbtDouble && canImplicitlyPromote(type0, EbtDouble, op)) ) {
  1737. res0 = EbtDouble;
  1738. res1 = EbtDouble;
  1739. } else if ((type0 == EbtFloat && canImplicitlyPromote(type1, EbtFloat, op)) ||
  1740. (type1 == EbtFloat && canImplicitlyPromote(type0, EbtFloat, op)) ) {
  1741. res0 = EbtFloat;
  1742. res1 = EbtFloat;
  1743. } else if ((type0 == EbtFloat16 && canImplicitlyPromote(type1, EbtFloat16, op)) ||
  1744. (type1 == EbtFloat16 && canImplicitlyPromote(type0, EbtFloat16, op)) ) {
  1745. res0 = EbtFloat16;
  1746. res1 = EbtFloat16;
  1747. } else if (isTypeInt(type0) && isTypeInt(type1) &&
  1748. (canImplicitlyPromote(type0, type1, op) || canImplicitlyPromote(type1, type0, op))) {
  1749. if ((isTypeSignedInt(type0) && isTypeSignedInt(type1)) ||
  1750. (isTypeUnsignedInt(type0) && isTypeUnsignedInt(type1))) {
  1751. if (getTypeRank(type0) < getTypeRank(type1)) {
  1752. res0 = type1;
  1753. res1 = type1;
  1754. } else {
  1755. res0 = type0;
  1756. res1 = type0;
  1757. }
  1758. } else if (isTypeUnsignedInt(type0) && (getTypeRank(type0) > getTypeRank(type1))) {
  1759. res0 = type0;
  1760. res1 = type0;
  1761. } else if (isTypeUnsignedInt(type1) && (getTypeRank(type1) > getTypeRank(type0))) {
  1762. res0 = type1;
  1763. res1 = type1;
  1764. } else if (isTypeSignedInt(type0)) {
  1765. if (canSignedIntTypeRepresentAllUnsignedValues(type0, type1)) {
  1766. res0 = type0;
  1767. res1 = type0;
  1768. } else {
  1769. res0 = getCorrespondingUnsignedType(type0);
  1770. res1 = getCorrespondingUnsignedType(type0);
  1771. }
  1772. } else if (isTypeSignedInt(type1)) {
  1773. if (canSignedIntTypeRepresentAllUnsignedValues(type1, type0)) {
  1774. res0 = type1;
  1775. res1 = type1;
  1776. } else {
  1777. res0 = getCorrespondingUnsignedType(type1);
  1778. res1 = getCorrespondingUnsignedType(type1);
  1779. }
  1780. }
  1781. }
  1782. return std::make_tuple(res0, res1);
  1783. }
  1784. //
  1785. // Given a type, find what operation would fully construct it.
  1786. //
  1787. TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
  1788. {
  1789. TOperator op = EOpNull;
  1790. if (type.getQualifier().isNonUniform())
  1791. return EOpConstructNonuniform;
  1792. if (type.isCoopMat())
  1793. return EOpConstructCooperativeMatrix;
  1794. switch (type.getBasicType()) {
  1795. case EbtStruct:
  1796. op = EOpConstructStruct;
  1797. break;
  1798. case EbtSampler:
  1799. if (type.getSampler().isCombined())
  1800. op = EOpConstructTextureSampler;
  1801. break;
  1802. case EbtFloat:
  1803. if (type.isMatrix()) {
  1804. switch (type.getMatrixCols()) {
  1805. case 2:
  1806. switch (type.getMatrixRows()) {
  1807. case 2: op = EOpConstructMat2x2; break;
  1808. case 3: op = EOpConstructMat2x3; break;
  1809. case 4: op = EOpConstructMat2x4; break;
  1810. default: break; // some compilers want this
  1811. }
  1812. break;
  1813. case 3:
  1814. switch (type.getMatrixRows()) {
  1815. case 2: op = EOpConstructMat3x2; break;
  1816. case 3: op = EOpConstructMat3x3; break;
  1817. case 4: op = EOpConstructMat3x4; break;
  1818. default: break; // some compilers want this
  1819. }
  1820. break;
  1821. case 4:
  1822. switch (type.getMatrixRows()) {
  1823. case 2: op = EOpConstructMat4x2; break;
  1824. case 3: op = EOpConstructMat4x3; break;
  1825. case 4: op = EOpConstructMat4x4; break;
  1826. default: break; // some compilers want this
  1827. }
  1828. break;
  1829. default: break; // some compilers want this
  1830. }
  1831. } else {
  1832. switch(type.getVectorSize()) {
  1833. case 1: op = EOpConstructFloat; break;
  1834. case 2: op = EOpConstructVec2; break;
  1835. case 3: op = EOpConstructVec3; break;
  1836. case 4: op = EOpConstructVec4; break;
  1837. default: break; // some compilers want this
  1838. }
  1839. }
  1840. break;
  1841. case EbtInt:
  1842. if (type.getMatrixCols()) {
  1843. switch (type.getMatrixCols()) {
  1844. case 2:
  1845. switch (type.getMatrixRows()) {
  1846. case 2: op = EOpConstructIMat2x2; break;
  1847. case 3: op = EOpConstructIMat2x3; break;
  1848. case 4: op = EOpConstructIMat2x4; break;
  1849. default: break; // some compilers want this
  1850. }
  1851. break;
  1852. case 3:
  1853. switch (type.getMatrixRows()) {
  1854. case 2: op = EOpConstructIMat3x2; break;
  1855. case 3: op = EOpConstructIMat3x3; break;
  1856. case 4: op = EOpConstructIMat3x4; break;
  1857. default: break; // some compilers want this
  1858. }
  1859. break;
  1860. case 4:
  1861. switch (type.getMatrixRows()) {
  1862. case 2: op = EOpConstructIMat4x2; break;
  1863. case 3: op = EOpConstructIMat4x3; break;
  1864. case 4: op = EOpConstructIMat4x4; break;
  1865. default: break; // some compilers want this
  1866. }
  1867. break;
  1868. }
  1869. } else {
  1870. switch(type.getVectorSize()) {
  1871. case 1: op = EOpConstructInt; break;
  1872. case 2: op = EOpConstructIVec2; break;
  1873. case 3: op = EOpConstructIVec3; break;
  1874. case 4: op = EOpConstructIVec4; break;
  1875. default: break; // some compilers want this
  1876. }
  1877. }
  1878. break;
  1879. case EbtUint:
  1880. if (type.getMatrixCols()) {
  1881. switch (type.getMatrixCols()) {
  1882. case 2:
  1883. switch (type.getMatrixRows()) {
  1884. case 2: op = EOpConstructUMat2x2; break;
  1885. case 3: op = EOpConstructUMat2x3; break;
  1886. case 4: op = EOpConstructUMat2x4; break;
  1887. default: break; // some compilers want this
  1888. }
  1889. break;
  1890. case 3:
  1891. switch (type.getMatrixRows()) {
  1892. case 2: op = EOpConstructUMat3x2; break;
  1893. case 3: op = EOpConstructUMat3x3; break;
  1894. case 4: op = EOpConstructUMat3x4; break;
  1895. default: break; // some compilers want this
  1896. }
  1897. break;
  1898. case 4:
  1899. switch (type.getMatrixRows()) {
  1900. case 2: op = EOpConstructUMat4x2; break;
  1901. case 3: op = EOpConstructUMat4x3; break;
  1902. case 4: op = EOpConstructUMat4x4; break;
  1903. default: break; // some compilers want this
  1904. }
  1905. break;
  1906. }
  1907. } else {
  1908. switch(type.getVectorSize()) {
  1909. case 1: op = EOpConstructUint; break;
  1910. case 2: op = EOpConstructUVec2; break;
  1911. case 3: op = EOpConstructUVec3; break;
  1912. case 4: op = EOpConstructUVec4; break;
  1913. default: break; // some compilers want this
  1914. }
  1915. }
  1916. break;
  1917. case EbtBool:
  1918. if (type.getMatrixCols()) {
  1919. switch (type.getMatrixCols()) {
  1920. case 2:
  1921. switch (type.getMatrixRows()) {
  1922. case 2: op = EOpConstructBMat2x2; break;
  1923. case 3: op = EOpConstructBMat2x3; break;
  1924. case 4: op = EOpConstructBMat2x4; break;
  1925. default: break; // some compilers want this
  1926. }
  1927. break;
  1928. case 3:
  1929. switch (type.getMatrixRows()) {
  1930. case 2: op = EOpConstructBMat3x2; break;
  1931. case 3: op = EOpConstructBMat3x3; break;
  1932. case 4: op = EOpConstructBMat3x4; break;
  1933. default: break; // some compilers want this
  1934. }
  1935. break;
  1936. case 4:
  1937. switch (type.getMatrixRows()) {
  1938. case 2: op = EOpConstructBMat4x2; break;
  1939. case 3: op = EOpConstructBMat4x3; break;
  1940. case 4: op = EOpConstructBMat4x4; break;
  1941. default: break; // some compilers want this
  1942. }
  1943. break;
  1944. }
  1945. } else {
  1946. switch(type.getVectorSize()) {
  1947. case 1: op = EOpConstructBool; break;
  1948. case 2: op = EOpConstructBVec2; break;
  1949. case 3: op = EOpConstructBVec3; break;
  1950. case 4: op = EOpConstructBVec4; break;
  1951. default: break; // some compilers want this
  1952. }
  1953. }
  1954. break;
  1955. #ifndef GLSLANG_WEB
  1956. case EbtDouble:
  1957. if (type.getMatrixCols()) {
  1958. switch (type.getMatrixCols()) {
  1959. case 2:
  1960. switch (type.getMatrixRows()) {
  1961. case 2: op = EOpConstructDMat2x2; break;
  1962. case 3: op = EOpConstructDMat2x3; break;
  1963. case 4: op = EOpConstructDMat2x4; break;
  1964. default: break; // some compilers want this
  1965. }
  1966. break;
  1967. case 3:
  1968. switch (type.getMatrixRows()) {
  1969. case 2: op = EOpConstructDMat3x2; break;
  1970. case 3: op = EOpConstructDMat3x3; break;
  1971. case 4: op = EOpConstructDMat3x4; break;
  1972. default: break; // some compilers want this
  1973. }
  1974. break;
  1975. case 4:
  1976. switch (type.getMatrixRows()) {
  1977. case 2: op = EOpConstructDMat4x2; break;
  1978. case 3: op = EOpConstructDMat4x3; break;
  1979. case 4: op = EOpConstructDMat4x4; break;
  1980. default: break; // some compilers want this
  1981. }
  1982. break;
  1983. }
  1984. } else {
  1985. switch(type.getVectorSize()) {
  1986. case 1: op = EOpConstructDouble; break;
  1987. case 2: op = EOpConstructDVec2; break;
  1988. case 3: op = EOpConstructDVec3; break;
  1989. case 4: op = EOpConstructDVec4; break;
  1990. default: break; // some compilers want this
  1991. }
  1992. }
  1993. break;
  1994. case EbtFloat16:
  1995. if (type.getMatrixCols()) {
  1996. switch (type.getMatrixCols()) {
  1997. case 2:
  1998. switch (type.getMatrixRows()) {
  1999. case 2: op = EOpConstructF16Mat2x2; break;
  2000. case 3: op = EOpConstructF16Mat2x3; break;
  2001. case 4: op = EOpConstructF16Mat2x4; break;
  2002. default: break; // some compilers want this
  2003. }
  2004. break;
  2005. case 3:
  2006. switch (type.getMatrixRows()) {
  2007. case 2: op = EOpConstructF16Mat3x2; break;
  2008. case 3: op = EOpConstructF16Mat3x3; break;
  2009. case 4: op = EOpConstructF16Mat3x4; break;
  2010. default: break; // some compilers want this
  2011. }
  2012. break;
  2013. case 4:
  2014. switch (type.getMatrixRows()) {
  2015. case 2: op = EOpConstructF16Mat4x2; break;
  2016. case 3: op = EOpConstructF16Mat4x3; break;
  2017. case 4: op = EOpConstructF16Mat4x4; break;
  2018. default: break; // some compilers want this
  2019. }
  2020. break;
  2021. }
  2022. }
  2023. else {
  2024. switch (type.getVectorSize()) {
  2025. case 1: op = EOpConstructFloat16; break;
  2026. case 2: op = EOpConstructF16Vec2; break;
  2027. case 3: op = EOpConstructF16Vec3; break;
  2028. case 4: op = EOpConstructF16Vec4; break;
  2029. default: break; // some compilers want this
  2030. }
  2031. }
  2032. break;
  2033. case EbtInt8:
  2034. switch(type.getVectorSize()) {
  2035. case 1: op = EOpConstructInt8; break;
  2036. case 2: op = EOpConstructI8Vec2; break;
  2037. case 3: op = EOpConstructI8Vec3; break;
  2038. case 4: op = EOpConstructI8Vec4; break;
  2039. default: break; // some compilers want this
  2040. }
  2041. break;
  2042. case EbtUint8:
  2043. switch(type.getVectorSize()) {
  2044. case 1: op = EOpConstructUint8; break;
  2045. case 2: op = EOpConstructU8Vec2; break;
  2046. case 3: op = EOpConstructU8Vec3; break;
  2047. case 4: op = EOpConstructU8Vec4; break;
  2048. default: break; // some compilers want this
  2049. }
  2050. break;
  2051. case EbtInt16:
  2052. switch(type.getVectorSize()) {
  2053. case 1: op = EOpConstructInt16; break;
  2054. case 2: op = EOpConstructI16Vec2; break;
  2055. case 3: op = EOpConstructI16Vec3; break;
  2056. case 4: op = EOpConstructI16Vec4; break;
  2057. default: break; // some compilers want this
  2058. }
  2059. break;
  2060. case EbtUint16:
  2061. switch(type.getVectorSize()) {
  2062. case 1: op = EOpConstructUint16; break;
  2063. case 2: op = EOpConstructU16Vec2; break;
  2064. case 3: op = EOpConstructU16Vec3; break;
  2065. case 4: op = EOpConstructU16Vec4; break;
  2066. default: break; // some compilers want this
  2067. }
  2068. break;
  2069. case EbtInt64:
  2070. switch(type.getVectorSize()) {
  2071. case 1: op = EOpConstructInt64; break;
  2072. case 2: op = EOpConstructI64Vec2; break;
  2073. case 3: op = EOpConstructI64Vec3; break;
  2074. case 4: op = EOpConstructI64Vec4; break;
  2075. default: break; // some compilers want this
  2076. }
  2077. break;
  2078. case EbtUint64:
  2079. switch(type.getVectorSize()) {
  2080. case 1: op = EOpConstructUint64; break;
  2081. case 2: op = EOpConstructU64Vec2; break;
  2082. case 3: op = EOpConstructU64Vec3; break;
  2083. case 4: op = EOpConstructU64Vec4; break;
  2084. default: break; // some compilers want this
  2085. }
  2086. break;
  2087. case EbtReference:
  2088. op = EOpConstructReference;
  2089. break;
  2090. case EbtAccStruct:
  2091. op = EOpConstructAccStruct;
  2092. break;
  2093. #endif
  2094. default:
  2095. break;
  2096. }
  2097. return op;
  2098. }
  2099. //
  2100. // Safe way to combine two nodes into an aggregate. Works with null pointers,
  2101. // a node that's not a aggregate yet, etc.
  2102. //
  2103. // Returns the resulting aggregate, unless nullptr was passed in for
  2104. // both existing nodes.
  2105. //
  2106. TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
  2107. {
  2108. if (left == nullptr && right == nullptr)
  2109. return nullptr;
  2110. TIntermAggregate* aggNode = nullptr;
  2111. if (left != nullptr)
  2112. aggNode = left->getAsAggregate();
  2113. if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
  2114. aggNode = new TIntermAggregate;
  2115. if (left != nullptr)
  2116. aggNode->getSequence().push_back(left);
  2117. }
  2118. if (right != nullptr)
  2119. aggNode->getSequence().push_back(right);
  2120. return aggNode;
  2121. }
  2122. TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
  2123. {
  2124. TIntermAggregate* aggNode = growAggregate(left, right);
  2125. if (aggNode)
  2126. aggNode->setLoc(loc);
  2127. return aggNode;
  2128. }
  2129. //
  2130. // Turn an existing node into an aggregate.
  2131. //
  2132. // Returns an aggregate, unless nullptr was passed in for the existing node.
  2133. //
  2134. TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
  2135. {
  2136. if (node == nullptr)
  2137. return nullptr;
  2138. TIntermAggregate* aggNode = new TIntermAggregate;
  2139. aggNode->getSequence().push_back(node);
  2140. aggNode->setLoc(node->getLoc());
  2141. return aggNode;
  2142. }
  2143. TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
  2144. {
  2145. if (node == nullptr)
  2146. return nullptr;
  2147. TIntermAggregate* aggNode = new TIntermAggregate;
  2148. aggNode->getSequence().push_back(node);
  2149. aggNode->setLoc(loc);
  2150. return aggNode;
  2151. }
  2152. //
  2153. // Make an aggregate with an empty sequence.
  2154. //
  2155. TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
  2156. {
  2157. TIntermAggregate* aggNode = new TIntermAggregate;
  2158. aggNode->setLoc(loc);
  2159. return aggNode;
  2160. }
  2161. //
  2162. // For "if" test nodes. There are three children; a condition,
  2163. // a true path, and a false path. The two paths are in the
  2164. // nodePair.
  2165. //
  2166. // Returns the selection node created.
  2167. //
  2168. TIntermSelection* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
  2169. {
  2170. //
  2171. // Don't prune the false path for compile-time constants; it's needed
  2172. // for static access analysis.
  2173. //
  2174. TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
  2175. node->setLoc(loc);
  2176. return node;
  2177. }
  2178. TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
  2179. {
  2180. // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators
  2181. // ... are not included in the operators that can create a constant expression.
  2182. //
  2183. // if (left->getType().getQualifier().storage == EvqConst &&
  2184. // right->getType().getQualifier().storage == EvqConst) {
  2185. // return right;
  2186. //}
  2187. TIntermTyped *commaAggregate = growAggregate(left, right, loc);
  2188. commaAggregate->getAsAggregate()->setOperator(EOpComma);
  2189. commaAggregate->setType(right->getType());
  2190. commaAggregate->getWritableType().getQualifier().makeTemporary();
  2191. return commaAggregate;
  2192. }
  2193. TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc)
  2194. {
  2195. TIntermMethod* method = new TIntermMethod(object, type, *name);
  2196. method->setLoc(loc);
  2197. return method;
  2198. }
  2199. //
  2200. // For "?:" test nodes. There are three children; a condition,
  2201. // a true path, and a false path. The two paths are specified
  2202. // as separate parameters. For vector 'cond', the true and false
  2203. // are not paths, but vectors to mix.
  2204. //
  2205. // Specialization constant operations include
  2206. // - The ternary operator ( ? : )
  2207. //
  2208. // Returns the selection node created, or nullptr if one could not be.
  2209. //
  2210. TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock,
  2211. const TSourceLoc& loc)
  2212. {
  2213. // If it's void, go to the if-then-else selection()
  2214. if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
  2215. TIntermNodePair pair = { trueBlock, falseBlock };
  2216. TIntermSelection* selection = addSelection(cond, pair, loc);
  2217. if (getSource() == EShSourceHlsl)
  2218. selection->setNoShortCircuit();
  2219. return selection;
  2220. }
  2221. //
  2222. // Get compatible types.
  2223. //
  2224. auto children = addPairConversion(EOpSequence, trueBlock, falseBlock);
  2225. trueBlock = std::get<0>(children);
  2226. falseBlock = std::get<1>(children);
  2227. if (trueBlock == nullptr || falseBlock == nullptr)
  2228. return nullptr;
  2229. // Handle a vector condition as a mix
  2230. if (!cond->getType().isScalarOrVec1()) {
  2231. TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
  2232. cond->getType().getVectorSize());
  2233. // smear true/false operands as needed
  2234. trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock);
  2235. falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock);
  2236. // After conversion, types have to match.
  2237. if (falseBlock->getType() != trueBlock->getType())
  2238. return nullptr;
  2239. // make the mix operation
  2240. TIntermAggregate* mix = makeAggregate(loc);
  2241. mix = growAggregate(mix, falseBlock);
  2242. mix = growAggregate(mix, trueBlock);
  2243. mix = growAggregate(mix, cond);
  2244. mix->setType(targetVectorType);
  2245. mix->setOp(EOpMix);
  2246. return mix;
  2247. }
  2248. // Now have a scalar condition...
  2249. // Convert true and false expressions to matching types
  2250. addBiShapeConversion(EOpMix, trueBlock, falseBlock);
  2251. // After conversion, types have to match.
  2252. if (falseBlock->getType() != trueBlock->getType())
  2253. return nullptr;
  2254. // Eliminate the selection when the condition is a scalar and all operands are constant.
  2255. if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
  2256. if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
  2257. return trueBlock;
  2258. else
  2259. return falseBlock;
  2260. }
  2261. //
  2262. // Make a selection node.
  2263. //
  2264. TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
  2265. node->setLoc(loc);
  2266. node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
  2267. if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) ||
  2268. (cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() &&
  2269. falseBlock->getQualifier().isConstant()))
  2270. node->getQualifier().makeSpecConstant();
  2271. else
  2272. node->getQualifier().makeTemporary();
  2273. if (getSource() == EShSourceHlsl)
  2274. node->setNoShortCircuit();
  2275. return node;
  2276. }
  2277. //
  2278. // Constant terminal nodes. Has a union that contains bool, float or int constants
  2279. //
  2280. // Returns the constant union node created.
  2281. //
  2282. TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const
  2283. {
  2284. TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
  2285. node->getQualifier().storage = EvqConst;
  2286. node->setLoc(loc);
  2287. if (literal)
  2288. node->setLiteral();
  2289. return node;
  2290. }
  2291. TIntermConstantUnion* TIntermediate::addConstantUnion(signed char i8, const TSourceLoc& loc, bool literal) const
  2292. {
  2293. TConstUnionArray unionArray(1);
  2294. unionArray[0].setI8Const(i8);
  2295. return addConstantUnion(unionArray, TType(EbtInt8, EvqConst), loc, literal);
  2296. }
  2297. TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned char u8, const TSourceLoc& loc, bool literal) const
  2298. {
  2299. TConstUnionArray unionArray(1);
  2300. unionArray[0].setUConst(u8);
  2301. return addConstantUnion(unionArray, TType(EbtUint8, EvqConst), loc, literal);
  2302. }
  2303. TIntermConstantUnion* TIntermediate::addConstantUnion(signed short i16, const TSourceLoc& loc, bool literal) const
  2304. {
  2305. TConstUnionArray unionArray(1);
  2306. unionArray[0].setI16Const(i16);
  2307. return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal);
  2308. }
  2309. TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const
  2310. {
  2311. TConstUnionArray unionArray(1);
  2312. unionArray[0].setU16Const(u16);
  2313. return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal);
  2314. }
  2315. TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const
  2316. {
  2317. TConstUnionArray unionArray(1);
  2318. unionArray[0].setIConst(i);
  2319. return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal);
  2320. }
  2321. TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const
  2322. {
  2323. TConstUnionArray unionArray(1);
  2324. unionArray[0].setUConst(u);
  2325. return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal);
  2326. }
  2327. TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const
  2328. {
  2329. TConstUnionArray unionArray(1);
  2330. unionArray[0].setI64Const(i64);
  2331. return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal);
  2332. }
  2333. TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const
  2334. {
  2335. TConstUnionArray unionArray(1);
  2336. unionArray[0].setU64Const(u64);
  2337. return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
  2338. }
  2339. TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
  2340. {
  2341. TConstUnionArray unionArray(1);
  2342. unionArray[0].setBConst(b);
  2343. return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal);
  2344. }
  2345. TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
  2346. {
  2347. assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
  2348. TConstUnionArray unionArray(1);
  2349. unionArray[0].setDConst(d);
  2350. return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
  2351. }
  2352. TIntermConstantUnion* TIntermediate::addConstantUnion(const TString* s, const TSourceLoc& loc, bool literal) const
  2353. {
  2354. TConstUnionArray unionArray(1);
  2355. unionArray[0].setSConst(s);
  2356. return addConstantUnion(unionArray, TType(EbtString, EvqConst), loc, literal);
  2357. }
  2358. // Put vector swizzle selectors onto the given sequence
  2359. void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc)
  2360. {
  2361. TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc);
  2362. sequence.push_back(constIntNode);
  2363. }
  2364. // Put matrix swizzle selectors onto the given sequence
  2365. void TIntermediate::pushSelector(TIntermSequence& sequence, const TMatrixSelector& selector, const TSourceLoc& loc)
  2366. {
  2367. TIntermConstantUnion* constIntNode = addConstantUnion(selector.coord1, loc);
  2368. sequence.push_back(constIntNode);
  2369. constIntNode = addConstantUnion(selector.coord2, loc);
  2370. sequence.push_back(constIntNode);
  2371. }
  2372. // Make an aggregate node that has a sequence of all selectors.
  2373. template TIntermTyped* TIntermediate::addSwizzle<TVectorSelector>(TSwizzleSelectors<TVectorSelector>& selector, const TSourceLoc& loc);
  2374. template TIntermTyped* TIntermediate::addSwizzle<TMatrixSelector>(TSwizzleSelectors<TMatrixSelector>& selector, const TSourceLoc& loc);
  2375. template<typename selectorType>
  2376. TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selector, const TSourceLoc& loc)
  2377. {
  2378. TIntermAggregate* node = new TIntermAggregate(EOpSequence);
  2379. node->setLoc(loc);
  2380. TIntermSequence &sequenceVector = node->getSequence();
  2381. for (int i = 0; i < selector.size(); i++)
  2382. pushSelector(sequenceVector, selector[i], loc);
  2383. return node;
  2384. }
  2385. //
  2386. // Follow the left branches down to the root of an l-value
  2387. // expression (just "." and []).
  2388. //
  2389. // Return the base of the l-value (where following indexing quits working).
  2390. // Return nullptr if a chain following dereferences cannot be followed.
  2391. //
  2392. // 'swizzleOkay' says whether or not it is okay to consider a swizzle
  2393. // a valid part of the dereference chain.
  2394. //
  2395. const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
  2396. {
  2397. do {
  2398. const TIntermBinary* binary = node->getAsBinaryNode();
  2399. if (binary == nullptr)
  2400. return node;
  2401. TOperator op = binary->getOp();
  2402. if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
  2403. return nullptr;
  2404. if (! swizzleOkay) {
  2405. if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
  2406. return nullptr;
  2407. if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
  2408. (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
  2409. ! binary->getLeft()->getType().isArray())
  2410. return nullptr;
  2411. }
  2412. node = node->getAsBinaryNode()->getLeft();
  2413. } while (true);
  2414. }
  2415. //
  2416. // Create while and do-while loop nodes.
  2417. //
  2418. TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst,
  2419. const TSourceLoc& loc)
  2420. {
  2421. TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
  2422. node->setLoc(loc);
  2423. return node;
  2424. }
  2425. //
  2426. // Create a for-loop sequence.
  2427. //
  2428. TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test,
  2429. TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TIntermLoop*& node)
  2430. {
  2431. node = new TIntermLoop(body, test, terminal, testFirst);
  2432. node->setLoc(loc);
  2433. // make a sequence of the initializer and statement, but try to reuse the
  2434. // aggregate already created for whatever is in the initializer, if there is one
  2435. TIntermAggregate* loopSequence = (initializer == nullptr ||
  2436. initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc)
  2437. : initializer->getAsAggregate();
  2438. if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence)
  2439. loopSequence->setOp(EOpNull);
  2440. loopSequence = growAggregate(loopSequence, node);
  2441. loopSequence->setOperator(EOpSequence);
  2442. return loopSequence;
  2443. }
  2444. //
  2445. // Add branches.
  2446. //
  2447. TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
  2448. {
  2449. return addBranch(branchOp, nullptr, loc);
  2450. }
  2451. TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
  2452. {
  2453. TIntermBranch* node = new TIntermBranch(branchOp, expression);
  2454. node->setLoc(loc);
  2455. return node;
  2456. }
  2457. // Propagate precision from formal function return type to actual return type,
  2458. // and on to its subtree.
  2459. void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision)
  2460. {
  2461. TIntermTyped* exp = getExpression();
  2462. if (exp == nullptr)
  2463. return;
  2464. if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
  2465. exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) {
  2466. if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
  2467. exp->propagatePrecision(parentPrecision);
  2468. }
  2469. }
  2470. }
  2471. //
  2472. // This is to be executed after the final root is put on top by the parsing
  2473. // process.
  2474. //
  2475. bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
  2476. {
  2477. if (root == nullptr)
  2478. return true;
  2479. // Finish off the top-level sequence
  2480. TIntermAggregate* aggRoot = root->getAsAggregate();
  2481. if (aggRoot && aggRoot->getOp() == EOpNull)
  2482. aggRoot->setOperator(EOpSequence);
  2483. #ifndef GLSLANG_WEB
  2484. // Propagate 'noContraction' label in backward from 'precise' variables.
  2485. glslang::PropagateNoContraction(*this);
  2486. switch (textureSamplerTransformMode) {
  2487. case EShTexSampTransKeep:
  2488. break;
  2489. case EShTexSampTransUpgradeTextureRemoveSampler:
  2490. performTextureUpgradeAndSamplerRemovalTransformation(root);
  2491. break;
  2492. case EShTexSampTransCount:
  2493. assert(0);
  2494. break;
  2495. }
  2496. #endif
  2497. return true;
  2498. }
  2499. void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
  2500. {
  2501. // Add top-level nodes for declarations that must be checked cross
  2502. // compilation unit by a linker, yet might not have been referenced
  2503. // by the AST.
  2504. //
  2505. // Almost entirely, translation of symbols is driven by what's present
  2506. // in the AST traversal, not by translating the symbol table.
  2507. //
  2508. // However, there are some special cases:
  2509. // - From the specification: "Special built-in inputs gl_VertexID and
  2510. // gl_InstanceID are also considered active vertex attributes."
  2511. // - Linker-based type mismatch error reporting needs to see all
  2512. // uniforms/ins/outs variables and blocks.
  2513. // - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active.
  2514. //
  2515. // if (ftransformUsed) {
  2516. // TODO: 1.1 lowering functionality: track ftransform() usage
  2517. // addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
  2518. // addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
  2519. //}
  2520. if (language == EShLangVertex) {
  2521. // the names won't be found in the symbol table unless the versions are right,
  2522. // so version logic does not need to be repeated here
  2523. addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
  2524. addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
  2525. }
  2526. // Add a child to the root node for the linker objects
  2527. linkage->setOperator(EOpLinkerObjects);
  2528. treeRoot = growAggregate(treeRoot, linkage);
  2529. }
  2530. //
  2531. // Add the given name or symbol to the list of nodes at the end of the tree used
  2532. // for link-time checking and external linkage.
  2533. //
  2534. void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
  2535. {
  2536. TSymbol* symbol = symbolTable.find(name);
  2537. if (symbol)
  2538. addSymbolLinkageNode(linkage, *symbol->getAsVariable());
  2539. }
  2540. void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol)
  2541. {
  2542. const TVariable* variable = symbol.getAsVariable();
  2543. if (! variable) {
  2544. // This must be a member of an anonymous block, and we need to add the whole block
  2545. const TAnonMember* anon = symbol.getAsAnonMember();
  2546. variable = &anon->getAnonContainer();
  2547. }
  2548. TIntermSymbol* node = addSymbol(*variable);
  2549. linkage = growAggregate(linkage, node);
  2550. }
  2551. //
  2552. // Add a caller->callee relationship to the call graph.
  2553. // Assumes the strings are unique per signature.
  2554. //
  2555. void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee)
  2556. {
  2557. // Duplicates are okay, but faster to not keep them, and they come grouped by caller,
  2558. // as long as new ones are push on the same end we check on for duplicates
  2559. for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
  2560. if (call->caller != caller)
  2561. break;
  2562. if (call->callee == callee)
  2563. return;
  2564. }
  2565. callGraph.emplace_front(caller, callee);
  2566. }
  2567. //
  2568. // This deletes the tree.
  2569. //
  2570. void TIntermediate::removeTree()
  2571. {
  2572. if (treeRoot)
  2573. RemoveAllTreeNodes(treeRoot);
  2574. }
  2575. //
  2576. // Implement the part of KHR_vulkan_glsl that lists the set of operations
  2577. // that can result in a specialization constant operation.
  2578. //
  2579. // "5.x Specialization Constant Operations"
  2580. //
  2581. // Only some operations discussed in this section may be applied to a
  2582. // specialization constant and still yield a result that is as
  2583. // specialization constant. The operations allowed are listed below.
  2584. // When a specialization constant is operated on with one of these
  2585. // operators and with another constant or specialization constant, the
  2586. // result is implicitly a specialization constant.
  2587. //
  2588. // - int(), uint(), and bool() constructors for type conversions
  2589. // from any of the following types to any of the following types:
  2590. // * int
  2591. // * uint
  2592. // * bool
  2593. // - vector versions of the above conversion constructors
  2594. // - allowed implicit conversions of the above
  2595. // - swizzles (e.g., foo.yx)
  2596. // - The following when applied to integer or unsigned integer types:
  2597. // * unary negative ( - )
  2598. // * binary operations ( + , - , * , / , % )
  2599. // * shift ( <<, >> )
  2600. // * bitwise operations ( & , | , ^ )
  2601. // - The following when applied to integer or unsigned integer scalar types:
  2602. // * comparison ( == , != , > , >= , < , <= )
  2603. // - The following when applied to the Boolean scalar type:
  2604. // * not ( ! )
  2605. // * logical operations ( && , || , ^^ )
  2606. // * comparison ( == , != )"
  2607. //
  2608. // This function just handles binary and unary nodes. Construction
  2609. // rules are handled in construction paths that are not covered by the unary
  2610. // and binary paths, while required conversions will still show up here
  2611. // as unary converters in the from a construction operator.
  2612. //
  2613. bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
  2614. {
  2615. // The operations resulting in floating point are quite limited
  2616. // (However, some floating-point operations result in bool, like ">",
  2617. // so are handled later.)
  2618. if (node.getType().isFloatingDomain()) {
  2619. switch (node.getOp()) {
  2620. case EOpIndexDirect:
  2621. case EOpIndexIndirect:
  2622. case EOpIndexDirectStruct:
  2623. case EOpVectorSwizzle:
  2624. case EOpConvFloatToDouble:
  2625. case EOpConvDoubleToFloat:
  2626. case EOpConvFloat16ToFloat:
  2627. case EOpConvFloatToFloat16:
  2628. case EOpConvFloat16ToDouble:
  2629. case EOpConvDoubleToFloat16:
  2630. return true;
  2631. default:
  2632. return false;
  2633. }
  2634. }
  2635. // Check for floating-point arguments
  2636. if (const TIntermBinary* bin = node.getAsBinaryNode())
  2637. if (bin->getLeft() ->getType().isFloatingDomain() ||
  2638. bin->getRight()->getType().isFloatingDomain())
  2639. return false;
  2640. // So, for now, we can assume everything left is non-floating-point...
  2641. // Now check for integer/bool-based operations
  2642. switch (node.getOp()) {
  2643. // dereference/swizzle
  2644. case EOpIndexDirect:
  2645. case EOpIndexIndirect:
  2646. case EOpIndexDirectStruct:
  2647. case EOpVectorSwizzle:
  2648. // (u)int* -> bool
  2649. case EOpConvInt8ToBool:
  2650. case EOpConvInt16ToBool:
  2651. case EOpConvIntToBool:
  2652. case EOpConvInt64ToBool:
  2653. case EOpConvUint8ToBool:
  2654. case EOpConvUint16ToBool:
  2655. case EOpConvUintToBool:
  2656. case EOpConvUint64ToBool:
  2657. // bool -> (u)int*
  2658. case EOpConvBoolToInt8:
  2659. case EOpConvBoolToInt16:
  2660. case EOpConvBoolToInt:
  2661. case EOpConvBoolToInt64:
  2662. case EOpConvBoolToUint8:
  2663. case EOpConvBoolToUint16:
  2664. case EOpConvBoolToUint:
  2665. case EOpConvBoolToUint64:
  2666. // int8_t -> (u)int*
  2667. case EOpConvInt8ToInt16:
  2668. case EOpConvInt8ToInt:
  2669. case EOpConvInt8ToInt64:
  2670. case EOpConvInt8ToUint8:
  2671. case EOpConvInt8ToUint16:
  2672. case EOpConvInt8ToUint:
  2673. case EOpConvInt8ToUint64:
  2674. // int16_t -> (u)int*
  2675. case EOpConvInt16ToInt8:
  2676. case EOpConvInt16ToInt:
  2677. case EOpConvInt16ToInt64:
  2678. case EOpConvInt16ToUint8:
  2679. case EOpConvInt16ToUint16:
  2680. case EOpConvInt16ToUint:
  2681. case EOpConvInt16ToUint64:
  2682. // int32_t -> (u)int*
  2683. case EOpConvIntToInt8:
  2684. case EOpConvIntToInt16:
  2685. case EOpConvIntToInt64:
  2686. case EOpConvIntToUint8:
  2687. case EOpConvIntToUint16:
  2688. case EOpConvIntToUint:
  2689. case EOpConvIntToUint64:
  2690. // int64_t -> (u)int*
  2691. case EOpConvInt64ToInt8:
  2692. case EOpConvInt64ToInt16:
  2693. case EOpConvInt64ToInt:
  2694. case EOpConvInt64ToUint8:
  2695. case EOpConvInt64ToUint16:
  2696. case EOpConvInt64ToUint:
  2697. case EOpConvInt64ToUint64:
  2698. // uint8_t -> (u)int*
  2699. case EOpConvUint8ToInt8:
  2700. case EOpConvUint8ToInt16:
  2701. case EOpConvUint8ToInt:
  2702. case EOpConvUint8ToInt64:
  2703. case EOpConvUint8ToUint16:
  2704. case EOpConvUint8ToUint:
  2705. case EOpConvUint8ToUint64:
  2706. // uint16_t -> (u)int*
  2707. case EOpConvUint16ToInt8:
  2708. case EOpConvUint16ToInt16:
  2709. case EOpConvUint16ToInt:
  2710. case EOpConvUint16ToInt64:
  2711. case EOpConvUint16ToUint8:
  2712. case EOpConvUint16ToUint:
  2713. case EOpConvUint16ToUint64:
  2714. // uint32_t -> (u)int*
  2715. case EOpConvUintToInt8:
  2716. case EOpConvUintToInt16:
  2717. case EOpConvUintToInt:
  2718. case EOpConvUintToInt64:
  2719. case EOpConvUintToUint8:
  2720. case EOpConvUintToUint16:
  2721. case EOpConvUintToUint64:
  2722. // uint64_t -> (u)int*
  2723. case EOpConvUint64ToInt8:
  2724. case EOpConvUint64ToInt16:
  2725. case EOpConvUint64ToInt:
  2726. case EOpConvUint64ToInt64:
  2727. case EOpConvUint64ToUint8:
  2728. case EOpConvUint64ToUint16:
  2729. case EOpConvUint64ToUint:
  2730. // unary operations
  2731. case EOpNegative:
  2732. case EOpLogicalNot:
  2733. case EOpBitwiseNot:
  2734. // binary operations
  2735. case EOpAdd:
  2736. case EOpSub:
  2737. case EOpMul:
  2738. case EOpVectorTimesScalar:
  2739. case EOpDiv:
  2740. case EOpMod:
  2741. case EOpRightShift:
  2742. case EOpLeftShift:
  2743. case EOpAnd:
  2744. case EOpInclusiveOr:
  2745. case EOpExclusiveOr:
  2746. case EOpLogicalOr:
  2747. case EOpLogicalXor:
  2748. case EOpLogicalAnd:
  2749. case EOpEqual:
  2750. case EOpNotEqual:
  2751. case EOpLessThan:
  2752. case EOpGreaterThan:
  2753. case EOpLessThanEqual:
  2754. case EOpGreaterThanEqual:
  2755. return true;
  2756. default:
  2757. return false;
  2758. }
  2759. }
  2760. // Is the operation one that must propagate nonuniform?
  2761. bool TIntermediate::isNonuniformPropagating(TOperator op) const
  2762. {
  2763. // "* All Operators in Section 5.1 (Operators), except for assignment,
  2764. // arithmetic assignment, and sequence
  2765. // * Component selection in Section 5.5
  2766. // * Matrix components in Section 5.6
  2767. // * Structure and Array Operations in Section 5.7, except for the length
  2768. // method."
  2769. switch (op) {
  2770. case EOpPostIncrement:
  2771. case EOpPostDecrement:
  2772. case EOpPreIncrement:
  2773. case EOpPreDecrement:
  2774. case EOpNegative:
  2775. case EOpLogicalNot:
  2776. case EOpVectorLogicalNot:
  2777. case EOpBitwiseNot:
  2778. case EOpAdd:
  2779. case EOpSub:
  2780. case EOpMul:
  2781. case EOpDiv:
  2782. case EOpMod:
  2783. case EOpRightShift:
  2784. case EOpLeftShift:
  2785. case EOpAnd:
  2786. case EOpInclusiveOr:
  2787. case EOpExclusiveOr:
  2788. case EOpEqual:
  2789. case EOpNotEqual:
  2790. case EOpLessThan:
  2791. case EOpGreaterThan:
  2792. case EOpLessThanEqual:
  2793. case EOpGreaterThanEqual:
  2794. case EOpVectorTimesScalar:
  2795. case EOpVectorTimesMatrix:
  2796. case EOpMatrixTimesVector:
  2797. case EOpMatrixTimesScalar:
  2798. case EOpLogicalOr:
  2799. case EOpLogicalXor:
  2800. case EOpLogicalAnd:
  2801. case EOpIndexDirect:
  2802. case EOpIndexIndirect:
  2803. case EOpIndexDirectStruct:
  2804. case EOpVectorSwizzle:
  2805. return true;
  2806. default:
  2807. break;
  2808. }
  2809. return false;
  2810. }
  2811. ////////////////////////////////////////////////////////////////
  2812. //
  2813. // Member functions of the nodes used for building the tree.
  2814. //
  2815. ////////////////////////////////////////////////////////////////
  2816. //
  2817. // Say whether or not an operation node changes the value of a variable.
  2818. //
  2819. // Returns true if state is modified.
  2820. //
  2821. bool TIntermOperator::modifiesState() const
  2822. {
  2823. switch (op) {
  2824. case EOpPostIncrement:
  2825. case EOpPostDecrement:
  2826. case EOpPreIncrement:
  2827. case EOpPreDecrement:
  2828. case EOpAssign:
  2829. case EOpAddAssign:
  2830. case EOpSubAssign:
  2831. case EOpMulAssign:
  2832. case EOpVectorTimesMatrixAssign:
  2833. case EOpVectorTimesScalarAssign:
  2834. case EOpMatrixTimesScalarAssign:
  2835. case EOpMatrixTimesMatrixAssign:
  2836. case EOpDivAssign:
  2837. case EOpModAssign:
  2838. case EOpAndAssign:
  2839. case EOpInclusiveOrAssign:
  2840. case EOpExclusiveOrAssign:
  2841. case EOpLeftShiftAssign:
  2842. case EOpRightShiftAssign:
  2843. return true;
  2844. default:
  2845. return false;
  2846. }
  2847. }
  2848. //
  2849. // returns true if the operator is for one of the constructors
  2850. //
  2851. bool TIntermOperator::isConstructor() const
  2852. {
  2853. return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
  2854. }
  2855. //
  2856. // Make sure the type of an operator is appropriate for its
  2857. // combination of operation and operand type. This will invoke
  2858. // promoteUnary, promoteBinary, etc as needed.
  2859. //
  2860. // Returns false if nothing makes sense.
  2861. //
  2862. bool TIntermediate::promote(TIntermOperator* node)
  2863. {
  2864. if (node == nullptr)
  2865. return false;
  2866. if (node->getAsUnaryNode())
  2867. return promoteUnary(*node->getAsUnaryNode());
  2868. if (node->getAsBinaryNode())
  2869. return promoteBinary(*node->getAsBinaryNode());
  2870. if (node->getAsAggregate())
  2871. return promoteAggregate(*node->getAsAggregate());
  2872. return false;
  2873. }
  2874. //
  2875. // See TIntermediate::promote
  2876. //
  2877. bool TIntermediate::promoteUnary(TIntermUnary& node)
  2878. {
  2879. const TOperator op = node.getOp();
  2880. TIntermTyped* operand = node.getOperand();
  2881. switch (op) {
  2882. case EOpLogicalNot:
  2883. // Convert operand to a boolean type
  2884. if (operand->getBasicType() != EbtBool) {
  2885. // Add constructor to boolean type. If that fails, we can't do it, so return false.
  2886. TIntermTyped* converted = addConversion(op, TType(EbtBool), operand);
  2887. if (converted == nullptr)
  2888. return false;
  2889. // Use the result of converting the node to a bool.
  2890. node.setOperand(operand = converted); // also updates stack variable
  2891. }
  2892. break;
  2893. case EOpBitwiseNot:
  2894. if (!isTypeInt(operand->getBasicType()))
  2895. return false;
  2896. break;
  2897. case EOpNegative:
  2898. case EOpPostIncrement:
  2899. case EOpPostDecrement:
  2900. case EOpPreIncrement:
  2901. case EOpPreDecrement:
  2902. if (!isTypeInt(operand->getBasicType()) &&
  2903. operand->getBasicType() != EbtFloat &&
  2904. operand->getBasicType() != EbtFloat16 &&
  2905. operand->getBasicType() != EbtDouble)
  2906. return false;
  2907. break;
  2908. default:
  2909. // HLSL uses this path for initial function signature finding for built-ins
  2910. // taking a single argument, which generally don't participate in
  2911. // operator-based type promotion (type conversion will occur later).
  2912. // For now, scalar argument cases are relying on the setType() call below.
  2913. if (getSource() == EShSourceHlsl)
  2914. break;
  2915. // GLSL only allows integer arguments for the cases identified above in the
  2916. // case statements.
  2917. if (operand->getBasicType() != EbtFloat)
  2918. return false;
  2919. }
  2920. node.setType(operand->getType());
  2921. node.getWritableType().getQualifier().makeTemporary();
  2922. return true;
  2923. }
  2924. // Propagate precision qualifiers *up* from children to parent.
  2925. void TIntermUnary::updatePrecision()
  2926. {
  2927. if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
  2928. getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
  2929. if (operand->getQualifier().precision > getQualifier().precision)
  2930. getQualifier().precision = operand->getQualifier().precision;
  2931. }
  2932. }
  2933. //
  2934. // See TIntermediate::promote
  2935. //
  2936. bool TIntermediate::promoteBinary(TIntermBinary& node)
  2937. {
  2938. TOperator op = node.getOp();
  2939. TIntermTyped* left = node.getLeft();
  2940. TIntermTyped* right = node.getRight();
  2941. // Arrays and structures have to be exact matches.
  2942. if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
  2943. && left->getType() != right->getType())
  2944. return false;
  2945. // Base assumption: just make the type the same as the left
  2946. // operand. Only deviations from this will be coded.
  2947. node.setType(left->getType());
  2948. node.getWritableType().getQualifier().clear();
  2949. // Composite and opaque types don't having pending operator changes, e.g.,
  2950. // array, structure, and samplers. Just establish final type and correctness.
  2951. if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) {
  2952. switch (op) {
  2953. case EOpEqual:
  2954. case EOpNotEqual:
  2955. if (left->getBasicType() == EbtSampler) {
  2956. // can't compare samplers
  2957. return false;
  2958. } else {
  2959. // Promote to conditional
  2960. node.setType(TType(EbtBool));
  2961. }
  2962. return true;
  2963. case EOpAssign:
  2964. // Keep type from above
  2965. return true;
  2966. default:
  2967. return false;
  2968. }
  2969. }
  2970. //
  2971. // We now have only scalars, vectors, and matrices to worry about.
  2972. //
  2973. // HLSL implicitly promotes bool -> int for numeric operations.
  2974. // (Implicit conversions to make the operands match each other's types were already done.)
  2975. if (getSource() == EShSourceHlsl &&
  2976. (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) {
  2977. switch (op) {
  2978. case EOpLessThan:
  2979. case EOpGreaterThan:
  2980. case EOpLessThanEqual:
  2981. case EOpGreaterThanEqual:
  2982. case EOpRightShift:
  2983. case EOpLeftShift:
  2984. case EOpMod:
  2985. case EOpAnd:
  2986. case EOpInclusiveOr:
  2987. case EOpExclusiveOr:
  2988. case EOpAdd:
  2989. case EOpSub:
  2990. case EOpDiv:
  2991. case EOpMul:
  2992. if (left->getBasicType() == EbtBool)
  2993. left = createConversion(EbtInt, left);
  2994. if (right->getBasicType() == EbtBool)
  2995. right = createConversion(EbtInt, right);
  2996. if (left == nullptr || right == nullptr)
  2997. return false;
  2998. node.setLeft(left);
  2999. node.setRight(right);
  3000. // Update the original base assumption on result type..
  3001. node.setType(left->getType());
  3002. node.getWritableType().getQualifier().clear();
  3003. break;
  3004. default:
  3005. break;
  3006. }
  3007. }
  3008. // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
  3009. switch (op) {
  3010. case EOpLessThan:
  3011. case EOpGreaterThan:
  3012. case EOpLessThanEqual:
  3013. case EOpGreaterThanEqual:
  3014. // Relational comparisons need numeric types and will promote to scalar Boolean.
  3015. if (left->getBasicType() == EbtBool)
  3016. return false;
  3017. node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
  3018. break;
  3019. case EOpEqual:
  3020. case EOpNotEqual:
  3021. if (getSource() == EShSourceHlsl) {
  3022. const int resultWidth = std::max(left->getVectorSize(), right->getVectorSize());
  3023. // In HLSL, == or != on vectors means component-wise comparison.
  3024. if (resultWidth > 1) {
  3025. op = (op == EOpEqual) ? EOpVectorEqual : EOpVectorNotEqual;
  3026. node.setOp(op);
  3027. }
  3028. node.setType(TType(EbtBool, EvqTemporary, resultWidth));
  3029. } else {
  3030. // All the above comparisons result in a bool (but not the vector compares)
  3031. node.setType(TType(EbtBool));
  3032. }
  3033. break;
  3034. case EOpLogicalAnd:
  3035. case EOpLogicalOr:
  3036. case EOpLogicalXor:
  3037. // logical ops operate only on Booleans or vectors of Booleans.
  3038. if (left->getBasicType() != EbtBool || left->isMatrix())
  3039. return false;
  3040. if (getSource() == EShSourceGlsl) {
  3041. // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
  3042. if (left->isVector())
  3043. return false;
  3044. }
  3045. node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
  3046. break;
  3047. case EOpRightShift:
  3048. case EOpLeftShift:
  3049. case EOpRightShiftAssign:
  3050. case EOpLeftShiftAssign:
  3051. case EOpMod:
  3052. case EOpModAssign:
  3053. case EOpAnd:
  3054. case EOpInclusiveOr:
  3055. case EOpExclusiveOr:
  3056. case EOpAndAssign:
  3057. case EOpInclusiveOrAssign:
  3058. case EOpExclusiveOrAssign:
  3059. if (getSource() == EShSourceHlsl)
  3060. break;
  3061. // Check for integer-only operands.
  3062. if (!isTypeInt(left->getBasicType()) && !isTypeInt(right->getBasicType()))
  3063. return false;
  3064. if (left->isMatrix() || right->isMatrix())
  3065. return false;
  3066. break;
  3067. case EOpAdd:
  3068. case EOpSub:
  3069. case EOpDiv:
  3070. case EOpMul:
  3071. case EOpAddAssign:
  3072. case EOpSubAssign:
  3073. case EOpMulAssign:
  3074. case EOpDivAssign:
  3075. // check for non-Boolean operands
  3076. if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
  3077. return false;
  3078. default:
  3079. break;
  3080. }
  3081. // Compare left and right, and finish with the cases where the operand types must match
  3082. switch (op) {
  3083. case EOpLessThan:
  3084. case EOpGreaterThan:
  3085. case EOpLessThanEqual:
  3086. case EOpGreaterThanEqual:
  3087. case EOpEqual:
  3088. case EOpNotEqual:
  3089. case EOpVectorEqual:
  3090. case EOpVectorNotEqual:
  3091. case EOpLogicalAnd:
  3092. case EOpLogicalOr:
  3093. case EOpLogicalXor:
  3094. return left->getType() == right->getType();
  3095. case EOpMod:
  3096. case EOpModAssign:
  3097. case EOpAnd:
  3098. case EOpInclusiveOr:
  3099. case EOpExclusiveOr:
  3100. case EOpAndAssign:
  3101. case EOpInclusiveOrAssign:
  3102. case EOpExclusiveOrAssign:
  3103. case EOpAdd:
  3104. case EOpSub:
  3105. case EOpDiv:
  3106. case EOpAddAssign:
  3107. case EOpSubAssign:
  3108. case EOpDivAssign:
  3109. // Quick out in case the types do match
  3110. if (left->getType() == right->getType())
  3111. return true;
  3112. // Fall through
  3113. case EOpMul:
  3114. case EOpMulAssign:
  3115. // At least the basic type has to match
  3116. if (left->getBasicType() != right->getBasicType())
  3117. return false;
  3118. default:
  3119. break;
  3120. }
  3121. if (left->getType().isCoopMat() || right->getType().isCoopMat()) {
  3122. if (left->getType().isCoopMat() && right->getType().isCoopMat() &&
  3123. *left->getType().getTypeParameters() != *right->getType().getTypeParameters()) {
  3124. return false;
  3125. }
  3126. switch (op) {
  3127. case EOpMul:
  3128. case EOpMulAssign:
  3129. if (left->getType().isCoopMat() && right->getType().isCoopMat()) {
  3130. return false;
  3131. }
  3132. if (op == EOpMulAssign && right->getType().isCoopMat()) {
  3133. return false;
  3134. }
  3135. node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar);
  3136. if (right->getType().isCoopMat()) {
  3137. node.setType(right->getType());
  3138. }
  3139. return true;
  3140. case EOpAdd:
  3141. case EOpSub:
  3142. case EOpDiv:
  3143. case EOpAssign:
  3144. // These require both to be cooperative matrices
  3145. if (!left->getType().isCoopMat() || !right->getType().isCoopMat()) {
  3146. return false;
  3147. }
  3148. return true;
  3149. default:
  3150. break;
  3151. }
  3152. return false;
  3153. }
  3154. // Finish handling the case, for all ops, where both operands are scalars.
  3155. if (left->isScalar() && right->isScalar())
  3156. return true;
  3157. // Finish handling the case, for all ops, where there are two vectors of different sizes
  3158. if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
  3159. return false;
  3160. //
  3161. // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
  3162. //
  3163. // Can these two operands be combined, what is the resulting type?
  3164. TBasicType basicType = left->getBasicType();
  3165. switch (op) {
  3166. case EOpMul:
  3167. if (!left->isMatrix() && right->isMatrix()) {
  3168. if (left->isVector()) {
  3169. if (left->getVectorSize() != right->getMatrixRows())
  3170. return false;
  3171. node.setOp(op = EOpVectorTimesMatrix);
  3172. node.setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
  3173. } else {
  3174. node.setOp(op = EOpMatrixTimesScalar);
  3175. node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
  3176. }
  3177. } else if (left->isMatrix() && !right->isMatrix()) {
  3178. if (right->isVector()) {
  3179. if (left->getMatrixCols() != right->getVectorSize())
  3180. return false;
  3181. node.setOp(op = EOpMatrixTimesVector);
  3182. node.setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
  3183. } else {
  3184. node.setOp(op = EOpMatrixTimesScalar);
  3185. }
  3186. } else if (left->isMatrix() && right->isMatrix()) {
  3187. if (left->getMatrixCols() != right->getMatrixRows())
  3188. return false;
  3189. node.setOp(op = EOpMatrixTimesMatrix);
  3190. node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows()));
  3191. } else if (! left->isMatrix() && ! right->isMatrix()) {
  3192. if (left->isVector() && right->isVector()) {
  3193. ; // leave as component product
  3194. } else if (left->isVector() || right->isVector()) {
  3195. node.setOp(op = EOpVectorTimesScalar);
  3196. if (right->isVector())
  3197. node.setType(TType(basicType, EvqTemporary, right->getVectorSize()));
  3198. }
  3199. } else {
  3200. return false;
  3201. }
  3202. break;
  3203. case EOpMulAssign:
  3204. if (! left->isMatrix() && right->isMatrix()) {
  3205. if (left->isVector()) {
  3206. if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
  3207. return false;
  3208. node.setOp(op = EOpVectorTimesMatrixAssign);
  3209. } else {
  3210. return false;
  3211. }
  3212. } else if (left->isMatrix() && !right->isMatrix()) {
  3213. if (right->isVector()) {
  3214. return false;
  3215. } else {
  3216. node.setOp(op = EOpMatrixTimesScalarAssign);
  3217. }
  3218. } else if (left->isMatrix() && right->isMatrix()) {
  3219. if (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
  3220. return false;
  3221. node.setOp(op = EOpMatrixTimesMatrixAssign);
  3222. } else if (!left->isMatrix() && !right->isMatrix()) {
  3223. if (left->isVector() && right->isVector()) {
  3224. // leave as component product
  3225. } else if (left->isVector() || right->isVector()) {
  3226. if (! left->isVector())
  3227. return false;
  3228. node.setOp(op = EOpVectorTimesScalarAssign);
  3229. }
  3230. } else {
  3231. return false;
  3232. }
  3233. break;
  3234. case EOpRightShift:
  3235. case EOpLeftShift:
  3236. case EOpRightShiftAssign:
  3237. case EOpLeftShiftAssign:
  3238. if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize()))
  3239. return false;
  3240. break;
  3241. case EOpAssign:
  3242. if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
  3243. return false;
  3244. // fall through
  3245. case EOpAdd:
  3246. case EOpSub:
  3247. case EOpDiv:
  3248. case EOpMod:
  3249. case EOpAnd:
  3250. case EOpInclusiveOr:
  3251. case EOpExclusiveOr:
  3252. case EOpAddAssign:
  3253. case EOpSubAssign:
  3254. case EOpDivAssign:
  3255. case EOpModAssign:
  3256. case EOpAndAssign:
  3257. case EOpInclusiveOrAssign:
  3258. case EOpExclusiveOrAssign:
  3259. if ((left->isMatrix() && right->isVector()) ||
  3260. (left->isVector() && right->isMatrix()) ||
  3261. left->getBasicType() != right->getBasicType())
  3262. return false;
  3263. if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
  3264. return false;
  3265. if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
  3266. return false;
  3267. if (right->isVector() || right->isMatrix()) {
  3268. node.getWritableType().shallowCopy(right->getType());
  3269. node.getWritableType().getQualifier().makeTemporary();
  3270. }
  3271. break;
  3272. default:
  3273. return false;
  3274. }
  3275. //
  3276. // One more check for assignment.
  3277. //
  3278. switch (op) {
  3279. // The resulting type has to match the left operand.
  3280. case EOpAssign:
  3281. case EOpAddAssign:
  3282. case EOpSubAssign:
  3283. case EOpMulAssign:
  3284. case EOpDivAssign:
  3285. case EOpModAssign:
  3286. case EOpAndAssign:
  3287. case EOpInclusiveOrAssign:
  3288. case EOpExclusiveOrAssign:
  3289. case EOpLeftShiftAssign:
  3290. case EOpRightShiftAssign:
  3291. if (node.getType() != left->getType())
  3292. return false;
  3293. break;
  3294. default:
  3295. break;
  3296. }
  3297. return true;
  3298. }
  3299. //
  3300. // See TIntermediate::promote
  3301. //
  3302. bool TIntermediate::promoteAggregate(TIntermAggregate& node)
  3303. {
  3304. TOperator op = node.getOp();
  3305. TIntermSequence& args = node.getSequence();
  3306. const int numArgs = static_cast<int>(args.size());
  3307. // Presently, only hlsl does intrinsic promotions.
  3308. if (getSource() != EShSourceHlsl)
  3309. return true;
  3310. // set of opcodes that can be promoted in this manner.
  3311. switch (op) {
  3312. case EOpAtan:
  3313. case EOpClamp:
  3314. case EOpCross:
  3315. case EOpDistance:
  3316. case EOpDot:
  3317. case EOpDst:
  3318. case EOpFaceForward:
  3319. // case EOpFindMSB: TODO:
  3320. // case EOpFindLSB: TODO:
  3321. case EOpFma:
  3322. case EOpMod:
  3323. case EOpFrexp:
  3324. case EOpLdexp:
  3325. case EOpMix:
  3326. case EOpLit:
  3327. case EOpMax:
  3328. case EOpMin:
  3329. case EOpModf:
  3330. // case EOpGenMul: TODO:
  3331. case EOpPow:
  3332. case EOpReflect:
  3333. case EOpRefract:
  3334. // case EOpSinCos: TODO:
  3335. case EOpSmoothStep:
  3336. case EOpStep:
  3337. break;
  3338. default:
  3339. return true;
  3340. }
  3341. // TODO: array and struct behavior
  3342. // Try converting all nodes to the given node's type
  3343. TIntermSequence convertedArgs(numArgs, nullptr);
  3344. // Try to convert all types to the nonConvArg type.
  3345. for (int nonConvArg = 0; nonConvArg < numArgs; ++nonConvArg) {
  3346. // Try converting all args to this arg's type
  3347. for (int convArg = 0; convArg < numArgs; ++convArg) {
  3348. convertedArgs[convArg] = addConversion(op, args[nonConvArg]->getAsTyped()->getType(),
  3349. args[convArg]->getAsTyped());
  3350. }
  3351. // If we successfully converted all the args, use the result.
  3352. if (std::all_of(convertedArgs.begin(), convertedArgs.end(),
  3353. [](const TIntermNode* node) { return node != nullptr; })) {
  3354. std::swap(args, convertedArgs);
  3355. return true;
  3356. }
  3357. }
  3358. return false;
  3359. }
  3360. // Propagate precision qualifiers *up* from children to parent, and then
  3361. // back *down* again to the children's subtrees.
  3362. void TIntermBinary::updatePrecision()
  3363. {
  3364. if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
  3365. getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
  3366. getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
  3367. if (getQualifier().precision != EpqNone) {
  3368. left->propagatePrecision(getQualifier().precision);
  3369. right->propagatePrecision(getQualifier().precision);
  3370. }
  3371. }
  3372. }
  3373. // Recursively propagate precision qualifiers *down* the subtree of the current node,
  3374. // until reaching a node that already has a precision qualifier or otherwise does
  3375. // not participate in precision propagation.
  3376. void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
  3377. {
  3378. if (getQualifier().precision != EpqNone ||
  3379. (getBasicType() != EbtInt && getBasicType() != EbtUint &&
  3380. getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
  3381. return;
  3382. getQualifier().precision = newPrecision;
  3383. TIntermBinary* binaryNode = getAsBinaryNode();
  3384. if (binaryNode) {
  3385. binaryNode->getLeft()->propagatePrecision(newPrecision);
  3386. binaryNode->getRight()->propagatePrecision(newPrecision);
  3387. return;
  3388. }
  3389. TIntermUnary* unaryNode = getAsUnaryNode();
  3390. if (unaryNode) {
  3391. unaryNode->getOperand()->propagatePrecision(newPrecision);
  3392. return;
  3393. }
  3394. TIntermAggregate* aggregateNode = getAsAggregate();
  3395. if (aggregateNode) {
  3396. TIntermSequence operands = aggregateNode->getSequence();
  3397. for (unsigned int i = 0; i < operands.size(); ++i) {
  3398. TIntermTyped* typedNode = operands[i]->getAsTyped();
  3399. if (! typedNode)
  3400. break;
  3401. typedNode->propagatePrecision(newPrecision);
  3402. }
  3403. return;
  3404. }
  3405. TIntermSelection* selectionNode = getAsSelectionNode();
  3406. if (selectionNode) {
  3407. TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
  3408. if (typedNode) {
  3409. typedNode->propagatePrecision(newPrecision);
  3410. typedNode = selectionNode->getFalseBlock()->getAsTyped();
  3411. if (typedNode)
  3412. typedNode->propagatePrecision(newPrecision);
  3413. }
  3414. return;
  3415. }
  3416. }
  3417. TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
  3418. {
  3419. const TConstUnionArray& rightUnionArray = node->getConstArray();
  3420. int size = node->getType().computeNumComponents();
  3421. TConstUnionArray leftUnionArray(size);
  3422. for (int i=0; i < size; i++) {
  3423. #define PROMOTE(Set, CType, Get) leftUnionArray[i].Set(static_cast<CType>(rightUnionArray[i].Get()))
  3424. #define PROMOTE_TO_BOOL(Get) leftUnionArray[i].setBConst(rightUnionArray[i].Get() != 0)
  3425. #ifdef GLSLANG_WEB
  3426. #define TO_ALL(Get) \
  3427. switch (promoteTo) { \
  3428. case EbtFloat: PROMOTE(setDConst, double, Get); break; \
  3429. case EbtInt: PROMOTE(setIConst, int, Get); break; \
  3430. case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
  3431. case EbtBool: PROMOTE_TO_BOOL(Get); break; \
  3432. default: return node; \
  3433. }
  3434. #else
  3435. #define TO_ALL(Get) \
  3436. switch (promoteTo) { \
  3437. case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
  3438. case EbtFloat: PROMOTE(setDConst, double, Get); break; \
  3439. case EbtDouble: PROMOTE(setDConst, double, Get); break; \
  3440. case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
  3441. case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
  3442. case EbtInt: PROMOTE(setIConst, int, Get); break; \
  3443. case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
  3444. case EbtUint8: PROMOTE(setU8Const, unsigned char, Get); break; \
  3445. case EbtUint16: PROMOTE(setU16Const, unsigned short, Get); break; \
  3446. case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
  3447. case EbtUint64: PROMOTE(setU64Const, unsigned long long, Get); break; \
  3448. case EbtBool: PROMOTE_TO_BOOL(Get); break; \
  3449. default: return node; \
  3450. }
  3451. #endif
  3452. switch (node->getType().getBasicType()) {
  3453. case EbtFloat: TO_ALL(getDConst); break;
  3454. case EbtInt: TO_ALL(getIConst); break;
  3455. case EbtUint: TO_ALL(getUConst); break;
  3456. case EbtBool: TO_ALL(getBConst); break;
  3457. #ifndef GLSLANG_WEB
  3458. case EbtFloat16: TO_ALL(getDConst); break;
  3459. case EbtDouble: TO_ALL(getDConst); break;
  3460. case EbtInt8: TO_ALL(getI8Const); break;
  3461. case EbtInt16: TO_ALL(getI16Const); break;
  3462. case EbtInt64: TO_ALL(getI64Const); break;
  3463. case EbtUint8: TO_ALL(getU8Const); break;
  3464. case EbtUint16: TO_ALL(getU16Const); break;
  3465. case EbtUint64: TO_ALL(getU64Const); break;
  3466. #endif
  3467. default: return node;
  3468. }
  3469. }
  3470. const TType& t = node->getType();
  3471. return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
  3472. node->getLoc());
  3473. }
  3474. void TIntermAggregate::setPragmaTable(const TPragmaTable& pTable)
  3475. {
  3476. assert(pragmaTable == nullptr);
  3477. pragmaTable = new TPragmaTable;
  3478. *pragmaTable = pTable;
  3479. }
  3480. // If either node is a specialization constant, while the other is
  3481. // a constant (or specialization constant), the result is still
  3482. // a specialization constant.
  3483. bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2)
  3484. {
  3485. return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) ||
  3486. (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
  3487. }
  3488. struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
  3489. void visitSymbol(TIntermSymbol* symbol) override {
  3490. if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
  3491. symbol->getWritableType().getSampler().setCombined(true);
  3492. }
  3493. }
  3494. bool visitAggregate(TVisit, TIntermAggregate* ag) override {
  3495. using namespace std;
  3496. TIntermSequence& seq = ag->getSequence();
  3497. TQualifierList& qual = ag->getQualifierList();
  3498. // qual and seq are indexed using the same indices, so we have to modify both in lock-step
  3499. assert(seq.size() == qual.size() || qual.empty());
  3500. size_t write = 0;
  3501. for (size_t i = 0; i < seq.size(); ++i) {
  3502. TIntermSymbol* symbol = seq[i]->getAsSymbolNode();
  3503. if (symbol && symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()) {
  3504. // remove pure sampler variables
  3505. continue;
  3506. }
  3507. TIntermNode* result = seq[i];
  3508. // replace constructors with sampler/textures
  3509. TIntermAggregate *constructor = seq[i]->getAsAggregate();
  3510. if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
  3511. if (!constructor->getSequence().empty())
  3512. result = constructor->getSequence()[0];
  3513. }
  3514. // write new node & qualifier
  3515. seq[write] = result;
  3516. if (!qual.empty())
  3517. qual[write] = qual[i];
  3518. write++;
  3519. }
  3520. seq.resize(write);
  3521. if (!qual.empty())
  3522. qual.resize(write);
  3523. return true;
  3524. }
  3525. };
  3526. void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
  3527. {
  3528. TextureUpgradeAndSamplerRemovalTransform transform;
  3529. root->traverse(&transform);
  3530. }
  3531. const char* TIntermediate::getResourceName(TResourceType res)
  3532. {
  3533. switch (res) {
  3534. case EResSampler: return "shift-sampler-binding";
  3535. case EResTexture: return "shift-texture-binding";
  3536. case EResImage: return "shift-image-binding";
  3537. case EResUbo: return "shift-UBO-binding";
  3538. case EResSsbo: return "shift-ssbo-binding";
  3539. case EResUav: return "shift-uav-binding";
  3540. default:
  3541. assert(0); // internal error: should only be called with valid resource types.
  3542. return nullptr;
  3543. }
  3544. }
  3545. } // end namespace glslang