spirv_reflect.c 191 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546
  1. /*
  2. Copyright 2017-2022 Google Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #include "spirv_reflect.h"
  14. #include <assert.h>
  15. #include <stdbool.h>
  16. #include <string.h>
  17. #if defined(WIN32)
  18. #define _CRTDBG_MAP_ALLOC
  19. #include <stdlib.h>
  20. #include <crtdbg.h>
  21. #else
  22. #include <stdlib.h>
  23. #endif
  24. #if defined(__clang__) || defined(__GNUC__) || defined(__APPLE_CC__)
  25. #define FALLTHROUGH __attribute__((fallthrough))
  26. #else
  27. #define FALLTHROUGH
  28. #endif
  29. #if defined(SPIRV_REFLECT_ENABLE_ASSERTS)
  30. #define SPV_REFLECT_ASSERT(COND) \
  31. assert(COND);
  32. #else
  33. #define SPV_REFLECT_ASSERT(COND)
  34. #endif
  35. // Temporary enums until these make it into SPIR-V/Vulkan
  36. // clang-format off
  37. enum {
  38. SpvReflectOpDecorateId = 332,
  39. SpvReflectOpDecorateStringGOOGLE = 5632,
  40. SpvReflectOpMemberDecorateStringGOOGLE = 5633,
  41. SpvReflectDecorationHlslCounterBufferGOOGLE = 5634,
  42. SpvReflectDecorationHlslSemanticGOOGLE = 5635,
  43. };
  44. // clang-format on
  45. // clang-format off
  46. enum {
  47. SPIRV_STARTING_WORD_INDEX = 5,
  48. SPIRV_WORD_SIZE = sizeof(uint32_t),
  49. SPIRV_BYTE_WIDTH = 8,
  50. SPIRV_MINIMUM_FILE_SIZE = SPIRV_STARTING_WORD_INDEX * SPIRV_WORD_SIZE,
  51. SPIRV_DATA_ALIGNMENT = 4 * SPIRV_WORD_SIZE, // 16
  52. SPIRV_ACCESS_CHAIN_INDEX_OFFSET = 4,
  53. };
  54. // clang-format on
  55. // clang-format off
  56. enum {
  57. INVALID_VALUE = 0xFFFFFFFF,
  58. };
  59. // clang-format on
  60. // clang-format off
  61. enum {
  62. MAX_NODE_NAME_LENGTH = 1024,
  63. // Number of unique PhysicalStorageBuffer structs tracked to detect recursion
  64. MAX_RECURSIVE_PHYSICAL_POINTER_CHECK = 128,
  65. };
  66. // clang-format on
  67. // clang-format off
  68. enum {
  69. IMAGE_SAMPLED = 1,
  70. IMAGE_STORAGE = 2,
  71. };
  72. // clang-format on
  73. // clang-format off
  74. typedef struct SpvReflectPrvArrayTraits {
  75. uint32_t element_type_id;
  76. uint32_t length_id;
  77. } SpvReflectPrvArrayTraits;
  78. // clang-format on
  79. // clang-format off
  80. typedef struct SpvReflectPrvImageTraits {
  81. uint32_t sampled_type_id;
  82. SpvDim dim;
  83. uint32_t depth;
  84. uint32_t arrayed;
  85. uint32_t ms;
  86. uint32_t sampled;
  87. SpvImageFormat image_format;
  88. } SpvReflectPrvImageTraits;
  89. // clang-format on
  90. // clang-format off
  91. typedef struct SpvReflectPrvNumberDecoration {
  92. uint32_t word_offset;
  93. uint32_t value;
  94. } SpvReflectPrvNumberDecoration;
  95. // clang-format on
  96. // clang-format off
  97. typedef struct SpvReflectPrvStringDecoration {
  98. uint32_t word_offset;
  99. const char* value;
  100. } SpvReflectPrvStringDecoration;
  101. // clang-format on
  102. // clang-format off
  103. typedef struct SpvReflectPrvDecorations {
  104. bool is_relaxed_precision;
  105. bool is_block;
  106. bool is_buffer_block;
  107. bool is_row_major;
  108. bool is_column_major;
  109. bool is_built_in;
  110. bool is_noperspective;
  111. bool is_flat;
  112. bool is_non_writable;
  113. bool is_non_readable;
  114. SpvReflectPrvNumberDecoration set;
  115. SpvReflectPrvNumberDecoration binding;
  116. SpvReflectPrvNumberDecoration input_attachment_index;
  117. SpvReflectPrvNumberDecoration location;
  118. SpvReflectPrvNumberDecoration component;
  119. SpvReflectPrvNumberDecoration offset;
  120. SpvReflectPrvNumberDecoration uav_counter_buffer;
  121. // -- GODOT begin --
  122. SpvReflectPrvNumberDecoration specialization_constant;
  123. // -- GODOT end --
  124. SpvReflectPrvStringDecoration semantic;
  125. uint32_t array_stride;
  126. uint32_t matrix_stride;
  127. SpvBuiltIn built_in;
  128. } SpvReflectPrvDecorations;
  129. // clang-format on
  130. // clang-format off
  131. typedef struct SpvReflectPrvNode {
  132. uint32_t result_id;
  133. SpvOp op;
  134. uint32_t result_type_id;
  135. uint32_t type_id;
  136. SpvCapability capability;
  137. SpvStorageClass storage_class;
  138. uint32_t word_offset;
  139. uint32_t word_count;
  140. bool is_type;
  141. SpvReflectPrvArrayTraits array_traits;
  142. SpvReflectPrvImageTraits image_traits;
  143. uint32_t image_type_id;
  144. const char* name;
  145. SpvReflectPrvDecorations decorations;
  146. uint32_t member_count;
  147. const char** member_names;
  148. SpvReflectPrvDecorations* member_decorations;
  149. } SpvReflectPrvNode;
  150. // clang-format on
  151. // clang-format off
  152. typedef struct SpvReflectPrvString {
  153. uint32_t result_id;
  154. const char* string;
  155. } SpvReflectPrvString;
  156. // clang-format on
  157. // clang-format off
  158. typedef struct SpvReflectPrvFunction {
  159. uint32_t id;
  160. uint32_t callee_count;
  161. uint32_t* callees;
  162. struct SpvReflectPrvFunction** callee_ptrs;
  163. uint32_t accessed_ptr_count;
  164. uint32_t* accessed_ptrs;
  165. } SpvReflectPrvFunction;
  166. // clang-format on
  167. // clang-format off
  168. typedef struct SpvReflectPrvAccessChain {
  169. uint32_t result_id;
  170. uint32_t result_type_id;
  171. //
  172. // Pointing to the base of a composite object.
  173. // Generally the id of descriptor block variable
  174. uint32_t base_id;
  175. //
  176. // From spec:
  177. // The first index in Indexes will select the
  178. // top-level member/element/component/element
  179. // of the base composite
  180. uint32_t index_count;
  181. uint32_t* indexes;
  182. //
  183. // Block variable ac is pointing to (for block references)
  184. SpvReflectBlockVariable* block_var;
  185. } SpvReflectPrvAccessChain;
  186. // clang-format on
  187. // clang-format off
  188. typedef struct SpvReflectPrvParser {
  189. size_t spirv_word_count;
  190. uint32_t* spirv_code;
  191. uint32_t string_count;
  192. SpvReflectPrvString* strings;
  193. SpvSourceLanguage source_language;
  194. uint32_t source_language_version;
  195. uint32_t source_file_id;
  196. const char* source_embedded;
  197. size_t node_count;
  198. SpvReflectPrvNode* nodes;
  199. uint32_t entry_point_count;
  200. uint32_t capability_count;
  201. uint32_t function_count;
  202. SpvReflectPrvFunction* functions;
  203. uint32_t access_chain_count;
  204. SpvReflectPrvAccessChain* access_chains;
  205. uint32_t type_count;
  206. uint32_t descriptor_count;
  207. uint32_t push_constant_count;
  208. uint32_t physical_pointer_check[MAX_RECURSIVE_PHYSICAL_POINTER_CHECK];
  209. uint32_t physical_pointer_count;
  210. } SpvReflectPrvParser;
  211. // clang-format on
  212. static uint32_t Max(uint32_t a, uint32_t b) { return a > b ? a : b; }
  213. static uint32_t Min(uint32_t a, uint32_t b) { return a < b ? a : b; }
  214. static uint32_t RoundUp(
  215. uint32_t value,
  216. uint32_t multiple)
  217. {
  218. assert(multiple && ((multiple & (multiple - 1)) == 0));
  219. return (value + multiple - 1) & ~(multiple - 1);
  220. }
  221. #define IsNull(ptr) \
  222. (ptr == NULL)
  223. #define IsNotNull(ptr) \
  224. (ptr != NULL)
  225. #define SafeFree(ptr) \
  226. { \
  227. free((void*)ptr); \
  228. ptr = NULL; \
  229. }
  230. static int SortCompareUint32(
  231. const void* a,
  232. const void* b)
  233. {
  234. const uint32_t* p_a = (const uint32_t*)a;
  235. const uint32_t* p_b = (const uint32_t*)b;
  236. return (int)*p_a - (int)*p_b;
  237. }
  238. //
  239. // De-duplicates a sorted array and returns the new size.
  240. //
  241. // Note: The array doesn't actually need to be sorted, just
  242. // arranged into "runs" so that all the entries with one
  243. // value are adjacent.
  244. //
  245. static size_t DedupSortedUint32(uint32_t* arr, size_t size)
  246. {
  247. if (size == 0) {
  248. return 0;
  249. }
  250. size_t dedup_idx = 0;
  251. for (size_t i = 0; i < size; ++i) {
  252. if (arr[dedup_idx] != arr[i]) {
  253. ++dedup_idx;
  254. arr[dedup_idx] = arr[i];
  255. }
  256. }
  257. return dedup_idx+1;
  258. }
  259. static bool SearchSortedUint32(
  260. const uint32_t* arr,
  261. size_t size,
  262. uint32_t target)
  263. {
  264. size_t lo = 0;
  265. size_t hi = size;
  266. while (lo < hi) {
  267. size_t mid = (hi - lo) / 2 + lo;
  268. if (arr[mid] == target) {
  269. return true;
  270. } else if (arr[mid] < target) {
  271. lo = mid+1;
  272. } else {
  273. hi = mid;
  274. }
  275. }
  276. return false;
  277. }
  278. static SpvReflectResult IntersectSortedUint32(
  279. const uint32_t* p_arr0,
  280. size_t arr0_size,
  281. const uint32_t* p_arr1,
  282. size_t arr1_size,
  283. uint32_t** pp_res,
  284. size_t* res_size
  285. )
  286. {
  287. *pp_res = NULL;
  288. *res_size = 0;
  289. if (IsNull(p_arr0) || IsNull(p_arr1)) {
  290. return SPV_REFLECT_RESULT_SUCCESS;
  291. }
  292. const uint32_t* arr0_end = p_arr0 + arr0_size;
  293. const uint32_t* arr1_end = p_arr1 + arr1_size;
  294. const uint32_t* idx0 = p_arr0;
  295. const uint32_t* idx1 = p_arr1;
  296. while (idx0 != arr0_end && idx1 != arr1_end) {
  297. if (*idx0 < *idx1) {
  298. ++idx0;
  299. } else if (*idx0 > *idx1) {
  300. ++idx1;
  301. } else {
  302. ++*res_size;
  303. ++idx0;
  304. ++idx1;
  305. }
  306. }
  307. if (*res_size > 0) {
  308. *pp_res = (uint32_t*)calloc(*res_size, sizeof(**pp_res));
  309. if (IsNull(*pp_res)) {
  310. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  311. }
  312. uint32_t* idxr = *pp_res;
  313. idx0 = p_arr0;
  314. idx1 = p_arr1;
  315. while (idx0 != arr0_end && idx1 != arr1_end) {
  316. if (*idx0 < *idx1) {
  317. ++idx0;
  318. } else if (*idx0 > *idx1) {
  319. ++idx1;
  320. } else {
  321. *(idxr++) = *idx0;
  322. ++idx0;
  323. ++idx1;
  324. }
  325. }
  326. }
  327. return SPV_REFLECT_RESULT_SUCCESS;
  328. }
  329. static bool InRange(
  330. const SpvReflectPrvParser* p_parser,
  331. uint32_t index)
  332. {
  333. bool in_range = false;
  334. if (IsNotNull(p_parser)) {
  335. in_range = (index < p_parser->spirv_word_count);
  336. }
  337. return in_range;
  338. }
  339. static SpvReflectResult ReadU32(
  340. SpvReflectPrvParser* p_parser,
  341. uint32_t word_offset,
  342. uint32_t* p_value)
  343. {
  344. assert(IsNotNull(p_parser));
  345. assert(IsNotNull(p_parser->spirv_code));
  346. assert(InRange(p_parser, word_offset));
  347. SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF;
  348. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && InRange(p_parser, word_offset)) {
  349. *p_value = *(p_parser->spirv_code + word_offset);
  350. result = SPV_REFLECT_RESULT_SUCCESS;
  351. }
  352. return result;
  353. }
  354. #define UNCHECKED_READU32(parser, word_offset, value) \
  355. { \
  356. (void) ReadU32(parser, word_offset, (uint32_t*)&(value)); \
  357. }
  358. #define CHECKED_READU32(parser, word_offset, value) \
  359. { \
  360. SpvReflectResult checked_readu32_result = ReadU32(parser, \
  361. word_offset, (uint32_t*)&(value)); \
  362. if (checked_readu32_result != SPV_REFLECT_RESULT_SUCCESS) { \
  363. return checked_readu32_result; \
  364. } \
  365. }
  366. #define CHECKED_READU32_CAST(parser, word_offset, cast_to_type, value) \
  367. { \
  368. uint32_t checked_readu32_cast_u32 = UINT32_MAX; \
  369. SpvReflectResult checked_readu32_cast_result = ReadU32(parser, \
  370. word_offset, \
  371. (uint32_t*)&(checked_readu32_cast_u32)); \
  372. if (checked_readu32_cast_result != SPV_REFLECT_RESULT_SUCCESS) { \
  373. return checked_readu32_cast_result; \
  374. } \
  375. value = (cast_to_type)checked_readu32_cast_u32; \
  376. }
  377. #define IF_READU32(result, parser, word_offset, value) \
  378. if ((result) == SPV_REFLECT_RESULT_SUCCESS) { \
  379. result = ReadU32(parser, word_offset, (uint32_t*)&(value)); \
  380. }
  381. #define IF_READU32_CAST(result, parser, word_offset, cast_to_type, value) \
  382. if ((result) == SPV_REFLECT_RESULT_SUCCESS) { \
  383. uint32_t if_readu32_cast_u32 = UINT32_MAX; \
  384. result = ReadU32(parser, word_offset, &if_readu32_cast_u32); \
  385. if ((result) == SPV_REFLECT_RESULT_SUCCESS) { \
  386. value = (cast_to_type)if_readu32_cast_u32; \
  387. } \
  388. }
  389. static SpvReflectResult ReadStr(
  390. SpvReflectPrvParser* p_parser,
  391. uint32_t word_offset,
  392. uint32_t word_index,
  393. uint32_t word_count,
  394. uint32_t* p_buf_size,
  395. char* p_buf
  396. )
  397. {
  398. uint32_t limit = (word_offset + word_count);
  399. assert(IsNotNull(p_parser));
  400. assert(IsNotNull(p_parser->spirv_code));
  401. assert(InRange(p_parser, limit));
  402. SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF;
  403. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && InRange(p_parser, limit)) {
  404. const char* c_str = (const char*)(p_parser->spirv_code + word_offset + word_index);
  405. uint32_t n = word_count * SPIRV_WORD_SIZE;
  406. uint32_t length_with_terminator = 0;
  407. for (uint32_t i = 0; i < n; ++i) {
  408. char c = *(c_str + i);
  409. if (c == 0) {
  410. length_with_terminator = i + 1;
  411. break;
  412. }
  413. }
  414. if (length_with_terminator > 0) {
  415. result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  416. if (IsNotNull(p_buf_size) && IsNotNull(p_buf)) {
  417. result = SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;
  418. if (length_with_terminator <= *p_buf_size) {
  419. memset(p_buf, 0, *p_buf_size);
  420. memcpy(p_buf, c_str, length_with_terminator);
  421. result = SPV_REFLECT_RESULT_SUCCESS;
  422. }
  423. }
  424. else {
  425. if (IsNotNull(p_buf_size)) {
  426. *p_buf_size = length_with_terminator;
  427. result = SPV_REFLECT_RESULT_SUCCESS;
  428. }
  429. }
  430. }
  431. }
  432. return result;
  433. }
  434. static SpvReflectDecorationFlags ApplyDecorations(const SpvReflectPrvDecorations* p_decoration_fields)
  435. {
  436. SpvReflectDecorationFlags decorations = SPV_REFLECT_DECORATION_NONE;
  437. if (p_decoration_fields->is_relaxed_precision) {
  438. decorations |= SPV_REFLECT_DECORATION_RELAXED_PRECISION;
  439. }
  440. if (p_decoration_fields->is_block) {
  441. decorations |= SPV_REFLECT_DECORATION_BLOCK;
  442. }
  443. if (p_decoration_fields->is_buffer_block) {
  444. decorations |= SPV_REFLECT_DECORATION_BUFFER_BLOCK;
  445. }
  446. if (p_decoration_fields->is_row_major) {
  447. decorations |= SPV_REFLECT_DECORATION_ROW_MAJOR;
  448. }
  449. if (p_decoration_fields->is_column_major) {
  450. decorations |= SPV_REFLECT_DECORATION_COLUMN_MAJOR;
  451. }
  452. if (p_decoration_fields->is_built_in) {
  453. decorations |= SPV_REFLECT_DECORATION_BUILT_IN;
  454. }
  455. if (p_decoration_fields->is_noperspective) {
  456. decorations |= SPV_REFLECT_DECORATION_NOPERSPECTIVE;
  457. }
  458. if (p_decoration_fields->is_flat) {
  459. decorations |= SPV_REFLECT_DECORATION_FLAT;
  460. }
  461. if (p_decoration_fields->is_non_writable) {
  462. decorations |= SPV_REFLECT_DECORATION_NON_WRITABLE;
  463. }
  464. if (p_decoration_fields->is_non_readable) {
  465. decorations |= SPV_REFLECT_DECORATION_NON_READABLE;
  466. }
  467. return decorations;
  468. }
  469. static void ApplyNumericTraits(const SpvReflectTypeDescription* p_type, SpvReflectNumericTraits* p_numeric_traits)
  470. {
  471. memcpy(p_numeric_traits, &p_type->traits.numeric, sizeof(p_type->traits.numeric));
  472. }
  473. static void ApplyArrayTraits(const SpvReflectTypeDescription* p_type, SpvReflectArrayTraits* p_array_traits)
  474. {
  475. memcpy(p_array_traits, &p_type->traits.array, sizeof(p_type->traits.array));
  476. }
  477. static SpvReflectPrvNode* FindNode(
  478. SpvReflectPrvParser* p_parser,
  479. uint32_t result_id)
  480. {
  481. SpvReflectPrvNode* p_node = NULL;
  482. for (size_t i = 0; i < p_parser->node_count; ++i) {
  483. SpvReflectPrvNode* p_elem = &(p_parser->nodes[i]);
  484. if (p_elem->result_id == result_id) {
  485. p_node = p_elem;
  486. break;
  487. }
  488. }
  489. return p_node;
  490. }
  491. static SpvReflectTypeDescription* FindType(SpvReflectShaderModule* p_module, uint32_t type_id)
  492. {
  493. SpvReflectTypeDescription* p_type = NULL;
  494. for (size_t i = 0; i < p_module->_internal->type_description_count; ++i) {
  495. SpvReflectTypeDescription* p_elem = &(p_module->_internal->type_descriptions[i]);
  496. if (p_elem->id == type_id) {
  497. p_type = p_elem;
  498. break;
  499. }
  500. }
  501. return p_type;
  502. }
  503. static SpvReflectPrvAccessChain* FindAccessChain(SpvReflectPrvParser* p_parser,
  504. uint32_t id) {
  505. uint32_t ac_cnt = p_parser->access_chain_count;
  506. for (uint32_t i = 0; i < ac_cnt; i++) {
  507. if (p_parser->access_chains[i].result_id == id) {
  508. return &p_parser->access_chains[i];
  509. }
  510. }
  511. return 0;
  512. }
  513. static uint32_t FindBaseId(SpvReflectPrvParser* p_parser,
  514. SpvReflectPrvAccessChain* ac) {
  515. uint32_t base_id = ac->base_id;
  516. SpvReflectPrvNode* base_node = FindNode(p_parser, base_id);
  517. // TODO - This is just a band-aid to fix crashes.
  518. // Need to understand why here and hopefully remove
  519. // https://github.com/KhronosGroup/SPIRV-Reflect/pull/206
  520. if (IsNull(base_node)) {
  521. return 0;
  522. }
  523. while (base_node->op != SpvOpVariable) {
  524. switch (base_node->op) {
  525. case SpvOpLoad: {
  526. UNCHECKED_READU32(p_parser, base_node->word_offset + 3, base_id);
  527. }
  528. break;
  529. case SpvOpFunctionParameter: {
  530. UNCHECKED_READU32(p_parser, base_node->word_offset + 2, base_id);
  531. }
  532. break;
  533. default: {
  534. assert(false);
  535. }
  536. break;
  537. }
  538. SpvReflectPrvAccessChain* base_ac = FindAccessChain(p_parser, base_id);
  539. if (base_ac == 0) {
  540. return 0;
  541. }
  542. base_id = base_ac->base_id;
  543. base_node = FindNode(p_parser, base_id);
  544. }
  545. return base_id;
  546. }
  547. static SpvReflectBlockVariable* GetRefBlkVar(SpvReflectPrvParser* p_parser,
  548. SpvReflectPrvAccessChain* ac) {
  549. uint32_t base_id = ac->base_id;
  550. SpvReflectPrvNode* base_node = FindNode(p_parser, base_id);
  551. assert(base_node->op == SpvOpLoad);
  552. UNCHECKED_READU32(p_parser, base_node->word_offset + 3, base_id);
  553. SpvReflectPrvAccessChain* base_ac = FindAccessChain(p_parser, base_id);
  554. assert(base_ac != 0);
  555. SpvReflectBlockVariable* base_var = base_ac->block_var;
  556. assert(base_var != 0);
  557. return base_var;
  558. }
  559. bool IsPointerToPointer(SpvReflectPrvParser* p_parser, uint32_t type_id) {
  560. SpvReflectPrvNode* ptr_node = FindNode(p_parser, type_id);
  561. if (ptr_node->op != SpvOpTypePointer) {
  562. return false;
  563. }
  564. uint32_t pte_id = 0;
  565. UNCHECKED_READU32(p_parser, ptr_node->word_offset + 3, pte_id);
  566. SpvReflectPrvNode* pte_node = FindNode(p_parser, pte_id);
  567. return pte_node->op == SpvOpTypePointer;
  568. }
  569. static SpvReflectResult CreateParser(
  570. size_t size,
  571. void* p_code,
  572. SpvReflectPrvParser* p_parser)
  573. {
  574. if (p_code == NULL) {
  575. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  576. }
  577. if (size < SPIRV_MINIMUM_FILE_SIZE) {
  578. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE;
  579. }
  580. if ((size % 4) != 0) {
  581. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE;
  582. }
  583. p_parser->spirv_word_count = size / SPIRV_WORD_SIZE;
  584. p_parser->spirv_code = (uint32_t*)p_code;
  585. if (p_parser->spirv_code[0] != SpvMagicNumber) {
  586. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_MAGIC_NUMBER;
  587. }
  588. return SPV_REFLECT_RESULT_SUCCESS;
  589. }
  590. static void DestroyParser(SpvReflectPrvParser* p_parser)
  591. {
  592. if (!IsNull(p_parser->nodes)) {
  593. // Free nodes
  594. for (size_t i = 0; i < p_parser->node_count; ++i) {
  595. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  596. if (IsNotNull(p_node->member_names)) {
  597. SafeFree(p_node->member_names);
  598. }
  599. if (IsNotNull(p_node->member_decorations)) {
  600. SafeFree(p_node->member_decorations);
  601. }
  602. }
  603. // Free functions
  604. for (size_t i = 0; i < p_parser->function_count; ++i) {
  605. SafeFree(p_parser->functions[i].callees);
  606. SafeFree(p_parser->functions[i].callee_ptrs);
  607. SafeFree(p_parser->functions[i].accessed_ptrs);
  608. }
  609. // Free access chains
  610. for (uint32_t i = 0; i < p_parser->access_chain_count; ++i) {
  611. SafeFree(p_parser->access_chains[i].indexes);
  612. }
  613. SafeFree(p_parser->nodes);
  614. SafeFree(p_parser->strings);
  615. SafeFree(p_parser->source_embedded);
  616. SafeFree(p_parser->functions);
  617. SafeFree(p_parser->access_chains);
  618. p_parser->node_count = 0;
  619. }
  620. }
  621. static SpvReflectResult ParseNodes(SpvReflectPrvParser* p_parser)
  622. {
  623. assert(IsNotNull(p_parser));
  624. assert(IsNotNull(p_parser->spirv_code));
  625. uint32_t* p_spirv = p_parser->spirv_code;
  626. uint32_t spirv_word_index = SPIRV_STARTING_WORD_INDEX;
  627. // Count nodes
  628. uint32_t node_count = 0;
  629. while (spirv_word_index < p_parser->spirv_word_count) {
  630. uint32_t word = p_spirv[spirv_word_index];
  631. SpvOp op = (SpvOp)(word & 0xFFFF);
  632. uint32_t node_word_count = (word >> 16) & 0xFFFF;
  633. if (node_word_count == 0) {
  634. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION;
  635. }
  636. if (op == SpvOpAccessChain) {
  637. ++(p_parser->access_chain_count);
  638. }
  639. spirv_word_index += node_word_count;
  640. ++node_count;
  641. }
  642. if (node_count == 0) {
  643. return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF;
  644. }
  645. // Allocate nodes
  646. p_parser->node_count = node_count;
  647. p_parser->nodes = (SpvReflectPrvNode*)calloc(p_parser->node_count, sizeof(*(p_parser->nodes)));
  648. if (IsNull(p_parser->nodes)) {
  649. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  650. }
  651. // Mark all nodes with an invalid state
  652. for (uint32_t i = 0; i < node_count; ++i) {
  653. p_parser->nodes[i].op = (SpvOp)INVALID_VALUE;
  654. p_parser->nodes[i].storage_class = (SpvStorageClass)INVALID_VALUE;
  655. p_parser->nodes[i].decorations.set.value = (uint32_t)INVALID_VALUE;
  656. p_parser->nodes[i].decorations.binding.value = (uint32_t)INVALID_VALUE;
  657. p_parser->nodes[i].decorations.location.value = (uint32_t)INVALID_VALUE;
  658. p_parser->nodes[i].decorations.component.value = (uint32_t)INVALID_VALUE;
  659. p_parser->nodes[i].decorations.offset.value = (uint32_t)INVALID_VALUE;
  660. p_parser->nodes[i].decorations.uav_counter_buffer.value = (uint32_t)INVALID_VALUE;
  661. p_parser->nodes[i].decorations.built_in = (SpvBuiltIn)INVALID_VALUE;
  662. // -- GODOT begin --
  663. p_parser->nodes[i].decorations.specialization_constant.value = (SpvBuiltIn)INVALID_VALUE;
  664. // -- GODOT end --
  665. }
  666. // Mark source file id node
  667. p_parser->source_file_id = (uint32_t)INVALID_VALUE;
  668. p_parser->source_embedded = NULL;
  669. // Function node
  670. uint32_t function_node = (uint32_t)INVALID_VALUE;
  671. // Allocate access chain
  672. if (p_parser->access_chain_count > 0) {
  673. p_parser->access_chains = (SpvReflectPrvAccessChain*)calloc(p_parser->access_chain_count, sizeof(*(p_parser->access_chains)));
  674. if (IsNull(p_parser->access_chains)) {
  675. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  676. }
  677. }
  678. // Parse nodes
  679. uint32_t node_index = 0;
  680. uint32_t access_chain_index = 0;
  681. spirv_word_index = SPIRV_STARTING_WORD_INDEX;
  682. while (spirv_word_index < p_parser->spirv_word_count) {
  683. uint32_t word = p_spirv[spirv_word_index];
  684. SpvOp op = (SpvOp)(word & 0xFFFF);
  685. uint32_t node_word_count = (word >> 16) & 0xFFFF;
  686. SpvReflectPrvNode* p_node = &(p_parser->nodes[node_index]);
  687. p_node->op = op;
  688. p_node->word_offset = spirv_word_index;
  689. p_node->word_count = node_word_count;
  690. switch (p_node->op) {
  691. default: break;
  692. case SpvOpString: {
  693. ++(p_parser->string_count);
  694. }
  695. break;
  696. case SpvOpSource: {
  697. CHECKED_READU32_CAST(p_parser, p_node->word_offset + 1, SpvSourceLanguage, p_parser->source_language);
  698. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_parser->source_language_version);
  699. if (p_node->word_count >= 4) {
  700. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_parser->source_file_id);
  701. }
  702. if (p_node->word_count >= 5) {
  703. const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 4);
  704. const size_t source_len = strlen(p_source);
  705. char* p_source_temp = (char*)calloc(source_len + 1, sizeof(char));
  706. if (IsNull(p_source_temp)) {
  707. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  708. }
  709. #ifdef _WIN32
  710. strcpy_s(p_source_temp, source_len + 1, p_source);
  711. #else
  712. strcpy(p_source_temp, p_source);
  713. #endif
  714. SafeFree(p_parser->source_embedded);
  715. p_parser->source_embedded = p_source_temp;
  716. }
  717. }
  718. break;
  719. case SpvOpSourceContinued: {
  720. const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 1);
  721. const size_t source_len = strlen(p_source);
  722. const size_t embedded_source_len = strlen(p_parser->source_embedded);
  723. char* p_continued_source = (char*)calloc(source_len + embedded_source_len + 1, sizeof(char));
  724. if (IsNull(p_continued_source)) {
  725. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  726. }
  727. #ifdef _WIN32
  728. strcpy_s(p_continued_source, embedded_source_len + 1, p_parser->source_embedded);
  729. strcat_s(p_continued_source, embedded_source_len + source_len + 1, p_source);
  730. #else
  731. strcpy(p_continued_source, p_parser->source_embedded);
  732. strcat(p_continued_source, p_source);
  733. #endif
  734. SafeFree(p_parser->source_embedded);
  735. p_parser->source_embedded = p_continued_source;
  736. }
  737. break;
  738. case SpvOpEntryPoint: {
  739. ++(p_parser->entry_point_count);
  740. }
  741. break;
  742. case SpvOpCapability: {
  743. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->capability);
  744. ++(p_parser->capability_count);
  745. }
  746. break;
  747. case SpvOpName:
  748. case SpvOpMemberName:
  749. {
  750. uint32_t member_offset = (p_node->op == SpvOpMemberName) ? 1 : 0;
  751. uint32_t name_start = p_node->word_offset + member_offset + 2;
  752. p_node->name = (const char*)(p_parser->spirv_code + name_start);
  753. }
  754. break;
  755. case SpvOpTypeStruct:
  756. {
  757. p_node->member_count = p_node->word_count - 2;
  758. FALLTHROUGH;
  759. } // Fall through
  760. // This is all the rest of OpType* that need to be tracked
  761. // Possible new extensions might expose new type, will need to be added
  762. // here
  763. case SpvOpTypeVoid:
  764. case SpvOpTypeBool:
  765. case SpvOpTypeInt:
  766. case SpvOpTypeFloat:
  767. case SpvOpTypeVector:
  768. case SpvOpTypeMatrix:
  769. case SpvOpTypeSampler:
  770. case SpvOpTypeOpaque:
  771. case SpvOpTypeFunction:
  772. case SpvOpTypeEvent:
  773. case SpvOpTypeDeviceEvent:
  774. case SpvOpTypeReserveId:
  775. case SpvOpTypeQueue:
  776. case SpvOpTypePipe:
  777. case SpvOpTypeAccelerationStructureKHR:
  778. case SpvOpTypeRayQueryKHR:
  779. case SpvOpTypeHitObjectNV:
  780. case SpvOpTypeCooperativeMatrixNV:
  781. case SpvOpTypeCooperativeMatrixKHR: {
  782. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
  783. p_node->is_type = true;
  784. } break;
  785. case SpvOpTypeImage: {
  786. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
  787. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->image_traits.sampled_type_id);
  788. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->image_traits.dim);
  789. CHECKED_READU32(p_parser, p_node->word_offset + 4, p_node->image_traits.depth);
  790. CHECKED_READU32(p_parser, p_node->word_offset + 5, p_node->image_traits.arrayed);
  791. CHECKED_READU32(p_parser, p_node->word_offset + 6, p_node->image_traits.ms);
  792. CHECKED_READU32(p_parser, p_node->word_offset + 7, p_node->image_traits.sampled);
  793. CHECKED_READU32(p_parser, p_node->word_offset + 8, p_node->image_traits.image_format);
  794. p_node->is_type = true;
  795. }
  796. break;
  797. case SpvOpTypeSampledImage: {
  798. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
  799. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->image_type_id);
  800. p_node->is_type = true;
  801. }
  802. break;
  803. case SpvOpTypeArray: {
  804. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
  805. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->array_traits.element_type_id);
  806. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->array_traits.length_id);
  807. p_node->is_type = true;
  808. }
  809. break;
  810. case SpvOpTypeRuntimeArray: {
  811. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
  812. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->array_traits.element_type_id);
  813. p_node->is_type = true;
  814. }
  815. break;
  816. case SpvOpTypePointer: {
  817. uint32_t result_id;
  818. CHECKED_READU32(p_parser, p_node->word_offset + 1, result_id);
  819. // Look for forward pointer. Clear result id if found
  820. SpvReflectPrvNode* p_fwd_node = FindNode(p_parser, result_id);
  821. if (p_fwd_node) {
  822. p_fwd_node->result_id = 0;
  823. }
  824. // Register pointer type
  825. p_node->result_id = result_id;
  826. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->storage_class);
  827. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->type_id);
  828. p_node->is_type = true;
  829. }
  830. break;
  831. case SpvOpTypeForwardPointer:
  832. {
  833. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
  834. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->storage_class);
  835. p_node->is_type = true;
  836. }
  837. break;
  838. case SpvOpConstantTrue:
  839. case SpvOpConstantFalse:
  840. case SpvOpConstant:
  841. case SpvOpConstantComposite:
  842. case SpvOpConstantSampler:
  843. case SpvOpConstantNull: {
  844. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
  845. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  846. }
  847. break;
  848. case SpvOpSpecConstantTrue:
  849. case SpvOpSpecConstantFalse:
  850. // -- GODOT begin --
  851. case SpvOpSpecConstant: {
  852. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
  853. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  854. p_node->is_type = true;
  855. }
  856. break;
  857. // -- GODOT end --
  858. case SpvOpSpecConstantComposite:
  859. case SpvOpSpecConstantOp: {
  860. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
  861. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  862. }
  863. break;
  864. case SpvOpVariable:
  865. {
  866. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->type_id);
  867. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  868. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_node->storage_class);
  869. }
  870. break;
  871. case SpvOpLoad:
  872. {
  873. // Only load enough so OpDecorate can reference the node, skip the remaining operands.
  874. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
  875. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  876. }
  877. break;
  878. case SpvOpAccessChain:
  879. {
  880. SpvReflectPrvAccessChain* p_access_chain = &(p_parser->access_chains[access_chain_index]);
  881. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_access_chain->result_type_id);
  882. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_access_chain->result_id);
  883. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_access_chain->base_id);
  884. //
  885. // SPIRV_ACCESS_CHAIN_INDEX_OFFSET (4) is the number of words up until the first index:
  886. // [Node, Result Type Id, Result Id, Base Id, <Indexes>]
  887. //
  888. p_access_chain->index_count = (node_word_count - SPIRV_ACCESS_CHAIN_INDEX_OFFSET);
  889. if (p_access_chain->index_count > 0) {
  890. p_access_chain->indexes = (uint32_t*)calloc(p_access_chain->index_count, sizeof(*(p_access_chain->indexes)));
  891. if (IsNull( p_access_chain->indexes)) {
  892. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  893. }
  894. // Parse any index values for access chain
  895. for (uint32_t index_index = 0; index_index < p_access_chain->index_count; ++index_index) {
  896. // Read index id
  897. uint32_t index_id = 0;
  898. CHECKED_READU32(p_parser, p_node->word_offset + SPIRV_ACCESS_CHAIN_INDEX_OFFSET + index_index, index_id);
  899. // Find OpConstant node that contains index value
  900. SpvReflectPrvNode* p_index_value_node = FindNode(p_parser, index_id);
  901. if ((p_index_value_node != NULL) && (p_index_value_node->op == SpvOpConstant)) {
  902. // Read index value
  903. uint32_t index_value = UINT32_MAX;
  904. CHECKED_READU32(p_parser, p_index_value_node->word_offset + 3, index_value);
  905. assert(index_value != UINT32_MAX);
  906. // Write index value to array
  907. p_access_chain->indexes[index_index] = index_value;
  908. }
  909. }
  910. }
  911. ++access_chain_index;
  912. }
  913. break;
  914. case SpvOpFunction:
  915. {
  916. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  917. // Count function definitions, not function declarations. To determine
  918. // the difference, set an in-function variable, and then if an OpLabel
  919. // is reached before the end of the function increment the function
  920. // count.
  921. function_node = node_index;
  922. }
  923. break;
  924. case SpvOpLabel:
  925. {
  926. if (function_node != (uint32_t)INVALID_VALUE) {
  927. SpvReflectPrvNode* p_func_node = &(p_parser->nodes[function_node]);
  928. CHECKED_READU32(p_parser, p_func_node->word_offset + 2, p_func_node->result_id);
  929. ++(p_parser->function_count);
  930. }
  931. FALLTHROUGH;
  932. } // Fall through
  933. case SpvOpFunctionEnd:
  934. {
  935. function_node = (uint32_t)INVALID_VALUE;
  936. }
  937. break;
  938. case SpvOpFunctionParameter:
  939. {
  940. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
  941. }
  942. break;
  943. }
  944. if (p_node->is_type) {
  945. ++(p_parser->type_count);
  946. }
  947. spirv_word_index += node_word_count;
  948. ++node_index;
  949. }
  950. return SPV_REFLECT_RESULT_SUCCESS;
  951. }
  952. static SpvReflectResult ParseStrings(SpvReflectPrvParser* p_parser)
  953. {
  954. assert(IsNotNull(p_parser));
  955. assert(IsNotNull(p_parser->spirv_code));
  956. assert(IsNotNull(p_parser->nodes));
  957. // Early out
  958. if (p_parser->string_count == 0) {
  959. return SPV_REFLECT_RESULT_SUCCESS;
  960. }
  961. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {
  962. // Allocate string storage
  963. p_parser->strings = (SpvReflectPrvString*)calloc(p_parser->string_count, sizeof(*(p_parser->strings)));
  964. uint32_t string_index = 0;
  965. for (size_t i = 0; i < p_parser->node_count; ++i) {
  966. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  967. if (p_node->op != SpvOpString) {
  968. continue;
  969. }
  970. // Paranoid check against string count
  971. assert(string_index < p_parser->string_count);
  972. if (string_index >= p_parser->string_count) {
  973. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  974. }
  975. // Result id
  976. SpvReflectPrvString* p_string = &(p_parser->strings[string_index]);
  977. CHECKED_READU32(p_parser, p_node->word_offset + 1, p_string->result_id);
  978. // String
  979. uint32_t string_start = p_node->word_offset + 2;
  980. p_string->string = (const char*)(p_parser->spirv_code + string_start);
  981. // Increment string index
  982. ++string_index;
  983. }
  984. }
  985. return SPV_REFLECT_RESULT_SUCCESS;
  986. }
  987. static SpvReflectResult ParseSource(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module)
  988. {
  989. assert(IsNotNull(p_parser));
  990. assert(IsNotNull(p_parser->spirv_code));
  991. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code)) {
  992. // Source file
  993. if (IsNotNull(p_parser->strings)) {
  994. for (uint32_t i = 0; i < p_parser->string_count; ++i) {
  995. SpvReflectPrvString* p_string = &(p_parser->strings[i]);
  996. if (p_string->result_id == p_parser->source_file_id) {
  997. p_module->source_file = p_string->string;
  998. break;
  999. }
  1000. }
  1001. }
  1002. //Source code
  1003. if (IsNotNull(p_parser->source_embedded))
  1004. {
  1005. const size_t source_len = strlen(p_parser->source_embedded);
  1006. char* p_source = (char*)calloc(source_len + 1, sizeof(char));
  1007. if (IsNull(p_source)) {
  1008. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1009. }
  1010. #ifdef _WIN32
  1011. strcpy_s(p_source, source_len + 1, p_parser->source_embedded);
  1012. #else
  1013. strcpy(p_source, p_parser->source_embedded);
  1014. #endif
  1015. p_module->source_source = p_source;
  1016. }
  1017. }
  1018. return SPV_REFLECT_RESULT_SUCCESS;
  1019. }
  1020. static SpvReflectResult ParseFunction(
  1021. SpvReflectPrvParser* p_parser,
  1022. SpvReflectPrvNode* p_func_node,
  1023. SpvReflectPrvFunction* p_func,
  1024. size_t first_label_index)
  1025. {
  1026. p_func->id = p_func_node->result_id;
  1027. p_func->callee_count = 0;
  1028. p_func->accessed_ptr_count = 0;
  1029. for (size_t i = first_label_index; i < p_parser->node_count; ++i) {
  1030. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1031. if (p_node->op == SpvOpFunctionEnd) {
  1032. break;
  1033. }
  1034. switch (p_node->op) {
  1035. case SpvOpFunctionCall: {
  1036. ++(p_func->callee_count);
  1037. }
  1038. break;
  1039. case SpvOpLoad:
  1040. case SpvOpAccessChain:
  1041. case SpvOpInBoundsAccessChain:
  1042. case SpvOpPtrAccessChain:
  1043. case SpvOpArrayLength:
  1044. case SpvOpGenericPtrMemSemantics:
  1045. case SpvOpInBoundsPtrAccessChain:
  1046. case SpvOpStore:
  1047. case SpvOpImageTexelPointer:
  1048. {
  1049. ++(p_func->accessed_ptr_count);
  1050. }
  1051. break;
  1052. case SpvOpCopyMemory:
  1053. case SpvOpCopyMemorySized:
  1054. {
  1055. p_func->accessed_ptr_count += 2;
  1056. }
  1057. break;
  1058. default: break;
  1059. }
  1060. }
  1061. if (p_func->callee_count > 0) {
  1062. p_func->callees = (uint32_t*)calloc(p_func->callee_count,
  1063. sizeof(*(p_func->callees)));
  1064. if (IsNull(p_func->callees)) {
  1065. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1066. }
  1067. }
  1068. if (p_func->accessed_ptr_count > 0) {
  1069. p_func->accessed_ptrs = (uint32_t*)calloc(p_func->accessed_ptr_count,
  1070. sizeof(*(p_func->accessed_ptrs)));
  1071. if (IsNull(p_func->accessed_ptrs)) {
  1072. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1073. }
  1074. }
  1075. p_func->callee_count = 0;
  1076. p_func->accessed_ptr_count = 0;
  1077. for (size_t i = first_label_index; i < p_parser->node_count; ++i) {
  1078. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1079. if (p_node->op == SpvOpFunctionEnd) {
  1080. break;
  1081. }
  1082. switch (p_node->op) {
  1083. case SpvOpFunctionCall: {
  1084. CHECKED_READU32(p_parser, p_node->word_offset + 3,
  1085. p_func->callees[p_func->callee_count]);
  1086. (++p_func->callee_count);
  1087. }
  1088. break;
  1089. case SpvOpLoad:
  1090. case SpvOpAccessChain:
  1091. case SpvOpInBoundsAccessChain:
  1092. case SpvOpPtrAccessChain:
  1093. case SpvOpArrayLength:
  1094. case SpvOpGenericPtrMemSemantics:
  1095. case SpvOpInBoundsPtrAccessChain:
  1096. case SpvOpImageTexelPointer:
  1097. {
  1098. CHECKED_READU32(p_parser, p_node->word_offset + 3,
  1099. p_func->accessed_ptrs[p_func->accessed_ptr_count]);
  1100. (++p_func->accessed_ptr_count);
  1101. }
  1102. break;
  1103. case SpvOpStore:
  1104. {
  1105. CHECKED_READU32(p_parser, p_node->word_offset + 2,
  1106. p_func->accessed_ptrs[p_func->accessed_ptr_count]);
  1107. (++p_func->accessed_ptr_count);
  1108. }
  1109. break;
  1110. case SpvOpCopyMemory:
  1111. case SpvOpCopyMemorySized:
  1112. {
  1113. CHECKED_READU32(p_parser, p_node->word_offset + 2,
  1114. p_func->accessed_ptrs[p_func->accessed_ptr_count]);
  1115. (++p_func->accessed_ptr_count);
  1116. CHECKED_READU32(p_parser, p_node->word_offset + 3,
  1117. p_func->accessed_ptrs[p_func->accessed_ptr_count]);
  1118. (++p_func->accessed_ptr_count);
  1119. }
  1120. break;
  1121. default: break;
  1122. }
  1123. }
  1124. if (p_func->callee_count > 0) {
  1125. qsort(p_func->callees, p_func->callee_count,
  1126. sizeof(*(p_func->callees)), SortCompareUint32);
  1127. }
  1128. p_func->callee_count = (uint32_t)DedupSortedUint32(p_func->callees,
  1129. p_func->callee_count);
  1130. if (p_func->accessed_ptr_count > 0) {
  1131. qsort(p_func->accessed_ptrs, p_func->accessed_ptr_count,
  1132. sizeof(*(p_func->accessed_ptrs)), SortCompareUint32);
  1133. }
  1134. p_func->accessed_ptr_count = (uint32_t)DedupSortedUint32(p_func->accessed_ptrs,
  1135. p_func->accessed_ptr_count);
  1136. return SPV_REFLECT_RESULT_SUCCESS;
  1137. }
  1138. static int SortCompareFunctions(
  1139. const void* a,
  1140. const void* b)
  1141. {
  1142. const SpvReflectPrvFunction* af = (const SpvReflectPrvFunction*)a;
  1143. const SpvReflectPrvFunction* bf = (const SpvReflectPrvFunction*)b;
  1144. return (int)af->id - (int)bf->id;
  1145. }
  1146. static SpvReflectResult ParseFunctions(SpvReflectPrvParser* p_parser)
  1147. {
  1148. assert(IsNotNull(p_parser));
  1149. assert(IsNotNull(p_parser->spirv_code));
  1150. assert(IsNotNull(p_parser->nodes));
  1151. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {
  1152. if (p_parser->function_count == 0) {
  1153. return SPV_REFLECT_RESULT_SUCCESS;
  1154. }
  1155. p_parser->functions = (SpvReflectPrvFunction*)calloc(p_parser->function_count,
  1156. sizeof(*(p_parser->functions)));
  1157. if (IsNull(p_parser->functions)) {
  1158. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1159. }
  1160. size_t function_index = 0;
  1161. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1162. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1163. if (p_node->op != SpvOpFunction) {
  1164. continue;
  1165. }
  1166. // Skip over function declarations that aren't definitions
  1167. bool func_definition = false;
  1168. // Intentionally reuse i to avoid iterating over these nodes more than
  1169. // once
  1170. for (; i < p_parser->node_count; ++i) {
  1171. if (p_parser->nodes[i].op == SpvOpLabel) {
  1172. func_definition = true;
  1173. break;
  1174. }
  1175. if (p_parser->nodes[i].op == SpvOpFunctionEnd) {
  1176. break;
  1177. }
  1178. }
  1179. if (!func_definition) {
  1180. continue;
  1181. }
  1182. SpvReflectPrvFunction* p_function = &(p_parser->functions[function_index]);
  1183. SpvReflectResult result = ParseFunction(p_parser, p_node, p_function, i);
  1184. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  1185. return result;
  1186. }
  1187. ++function_index;
  1188. }
  1189. qsort(p_parser->functions, p_parser->function_count,
  1190. sizeof(*(p_parser->functions)), SortCompareFunctions);
  1191. // Once they're sorted, link the functions with pointers to improve graph
  1192. // traversal efficiency
  1193. for (size_t i = 0; i < p_parser->function_count; ++i) {
  1194. SpvReflectPrvFunction* p_func = &(p_parser->functions[i]);
  1195. if (p_func->callee_count == 0) {
  1196. continue;
  1197. }
  1198. p_func->callee_ptrs = (SpvReflectPrvFunction**)calloc(p_func->callee_count,
  1199. sizeof(*(p_func->callee_ptrs)));
  1200. for (size_t j = 0, k = 0; j < p_func->callee_count; ++j) {
  1201. while (p_parser->functions[k].id != p_func->callees[j]) {
  1202. ++k;
  1203. if (k >= p_parser->function_count) {
  1204. // Invalid called function ID somewhere
  1205. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1206. }
  1207. }
  1208. p_func->callee_ptrs[j] = &(p_parser->functions[k]);
  1209. }
  1210. }
  1211. }
  1212. return SPV_REFLECT_RESULT_SUCCESS;
  1213. }
  1214. static SpvReflectResult ParseMemberCounts(SpvReflectPrvParser* p_parser)
  1215. {
  1216. assert(IsNotNull(p_parser));
  1217. assert(IsNotNull(p_parser->spirv_code));
  1218. assert(IsNotNull(p_parser->nodes));
  1219. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {
  1220. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1221. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1222. if ((p_node->op != SpvOpMemberName) && (p_node->op != SpvOpMemberDecorate)) {
  1223. continue;
  1224. }
  1225. uint32_t target_id = 0;
  1226. uint32_t member_index = (uint32_t)INVALID_VALUE;
  1227. CHECKED_READU32(p_parser, p_node->word_offset + 1, target_id);
  1228. CHECKED_READU32(p_parser, p_node->word_offset + 2, member_index);
  1229. SpvReflectPrvNode* p_target_node = FindNode(p_parser, target_id);
  1230. // Not all nodes get parsed, so FindNode returning NULL is expected.
  1231. if (IsNull(p_target_node)) {
  1232. continue;
  1233. }
  1234. if (member_index == INVALID_VALUE) {
  1235. return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;
  1236. }
  1237. p_target_node->member_count = Max(p_target_node->member_count, member_index + 1);
  1238. }
  1239. for (uint32_t i = 0; i < p_parser->node_count; ++i) {
  1240. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1241. if (p_node->member_count == 0) {
  1242. continue;
  1243. }
  1244. p_node->member_names = (const char **)calloc(p_node->member_count, sizeof(*(p_node->member_names)));
  1245. if (IsNull(p_node->member_names)) {
  1246. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1247. }
  1248. p_node->member_decorations = (SpvReflectPrvDecorations*)calloc(p_node->member_count, sizeof(*(p_node->member_decorations)));
  1249. if (IsNull(p_node->member_decorations)) {
  1250. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1251. }
  1252. }
  1253. }
  1254. return SPV_REFLECT_RESULT_SUCCESS;
  1255. }
  1256. static SpvReflectResult ParseNames(SpvReflectPrvParser* p_parser)
  1257. {
  1258. assert(IsNotNull(p_parser));
  1259. assert(IsNotNull(p_parser->spirv_code));
  1260. assert(IsNotNull(p_parser->nodes));
  1261. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {
  1262. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1263. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1264. if ((p_node->op != SpvOpName) && (p_node->op != SpvOpMemberName)) {
  1265. continue;
  1266. }
  1267. uint32_t target_id = 0;
  1268. CHECKED_READU32(p_parser, p_node->word_offset + 1, target_id);
  1269. SpvReflectPrvNode* p_target_node = FindNode(p_parser, target_id);
  1270. // Not all nodes get parsed, so FindNode returning NULL is expected.
  1271. if (IsNull(p_target_node)) {
  1272. continue;
  1273. }
  1274. const char** pp_target_name = &(p_target_node->name);
  1275. if (p_node->op == SpvOpMemberName) {
  1276. uint32_t member_index = UINT32_MAX;
  1277. CHECKED_READU32(p_parser, p_node->word_offset + 2, member_index);
  1278. pp_target_name = &(p_target_node->member_names[member_index]);
  1279. }
  1280. *pp_target_name = p_node->name;
  1281. }
  1282. }
  1283. return SPV_REFLECT_RESULT_SUCCESS;
  1284. }
  1285. static SpvReflectResult ParseDecorations(SpvReflectPrvParser* p_parser)
  1286. {
  1287. for (uint32_t i = 0; i < p_parser->node_count; ++i) {
  1288. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1289. if (((uint32_t)p_node->op != (uint32_t)SpvOpDecorate) &&
  1290. ((uint32_t)p_node->op != (uint32_t)SpvOpMemberDecorate) &&
  1291. ((uint32_t)p_node->op != (uint32_t)SpvReflectOpDecorateId) &&
  1292. ((uint32_t)p_node->op != (uint32_t)SpvReflectOpDecorateStringGOOGLE) &&
  1293. ((uint32_t)p_node->op != (uint32_t)SpvReflectOpMemberDecorateStringGOOGLE))
  1294. {
  1295. continue;
  1296. }
  1297. // Need to adjust the read offset if this is a member decoration
  1298. uint32_t member_offset = 0;
  1299. if (p_node->op == SpvOpMemberDecorate) {
  1300. member_offset = 1;
  1301. }
  1302. // Get decoration
  1303. uint32_t decoration = (uint32_t)INVALID_VALUE;
  1304. CHECKED_READU32(p_parser, p_node->word_offset + member_offset + 2, decoration);
  1305. // Filter out the decoration that do not affect reflection, otherwise
  1306. // there will be random crashes because the nodes aren't found.
  1307. bool skip = false;
  1308. switch (decoration) {
  1309. default: {
  1310. skip = true;
  1311. }
  1312. break;
  1313. // -- GODOT begin --
  1314. case SpvDecorationSpecId:
  1315. // -- GODOT end --
  1316. case SpvDecorationRelaxedPrecision:
  1317. case SpvDecorationBlock:
  1318. case SpvDecorationBufferBlock:
  1319. case SpvDecorationColMajor:
  1320. case SpvDecorationRowMajor:
  1321. case SpvDecorationArrayStride:
  1322. case SpvDecorationMatrixStride:
  1323. case SpvDecorationBuiltIn:
  1324. case SpvDecorationNoPerspective:
  1325. case SpvDecorationFlat:
  1326. case SpvDecorationNonWritable:
  1327. case SpvDecorationNonReadable:
  1328. case SpvDecorationLocation:
  1329. case SpvDecorationComponent:
  1330. case SpvDecorationBinding:
  1331. case SpvDecorationDescriptorSet:
  1332. case SpvDecorationOffset:
  1333. case SpvDecorationInputAttachmentIndex:
  1334. case SpvReflectDecorationHlslCounterBufferGOOGLE:
  1335. case SpvReflectDecorationHlslSemanticGOOGLE: {
  1336. skip = false;
  1337. }
  1338. break;
  1339. }
  1340. if (skip) {
  1341. continue;
  1342. }
  1343. // Find target target node
  1344. uint32_t target_id = 0;
  1345. CHECKED_READU32(p_parser, p_node->word_offset + 1, target_id);
  1346. SpvReflectPrvNode* p_target_node = FindNode(p_parser, target_id);
  1347. if (IsNull(p_target_node)) {
  1348. if ((p_node->op == (uint32_t)SpvOpDecorate) && (decoration == SpvDecorationRelaxedPrecision)) {
  1349. // Many OPs can be decorated that we don't care about. Ignore those.
  1350. // See https://github.com/KhronosGroup/SPIRV-Reflect/issues/134
  1351. continue;
  1352. }
  1353. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1354. }
  1355. // Get decorations
  1356. SpvReflectPrvDecorations* p_target_decorations = &(p_target_node->decorations);
  1357. // Update pointer if this is a member member decoration
  1358. if (p_node->op == SpvOpMemberDecorate) {
  1359. uint32_t member_index = (uint32_t)INVALID_VALUE;
  1360. CHECKED_READU32(p_parser, p_node->word_offset + 2, member_index);
  1361. p_target_decorations = &(p_target_node->member_decorations[member_index]);
  1362. }
  1363. switch (decoration) {
  1364. default: break;
  1365. case SpvDecorationRelaxedPrecision: {
  1366. p_target_decorations->is_relaxed_precision = true;
  1367. }
  1368. break;
  1369. case SpvDecorationBlock: {
  1370. p_target_decorations->is_block = true;
  1371. }
  1372. break;
  1373. case SpvDecorationBufferBlock: {
  1374. p_target_decorations->is_buffer_block = true;
  1375. }
  1376. break;
  1377. case SpvDecorationColMajor: {
  1378. p_target_decorations->is_column_major = true;
  1379. }
  1380. break;
  1381. case SpvDecorationRowMajor: {
  1382. p_target_decorations->is_row_major = true;
  1383. }
  1384. break;
  1385. case SpvDecorationArrayStride: {
  1386. uint32_t word_offset = p_node->word_offset + member_offset + 3;
  1387. CHECKED_READU32(p_parser, word_offset, p_target_decorations->array_stride);
  1388. }
  1389. break;
  1390. case SpvDecorationMatrixStride: {
  1391. uint32_t word_offset = p_node->word_offset + member_offset + 3;
  1392. CHECKED_READU32(p_parser, word_offset, p_target_decorations->matrix_stride);
  1393. }
  1394. break;
  1395. case SpvDecorationBuiltIn: {
  1396. p_target_decorations->is_built_in = true;
  1397. uint32_t word_offset = p_node->word_offset + member_offset + 3;
  1398. CHECKED_READU32_CAST(p_parser, word_offset, SpvBuiltIn, p_target_decorations->built_in);
  1399. }
  1400. break;
  1401. case SpvDecorationNoPerspective: {
  1402. p_target_decorations->is_noperspective = true;
  1403. }
  1404. break;
  1405. case SpvDecorationFlat: {
  1406. p_target_decorations->is_flat = true;
  1407. }
  1408. break;
  1409. case SpvDecorationNonWritable: {
  1410. p_target_decorations->is_non_writable = true;
  1411. }
  1412. break;
  1413. case SpvDecorationNonReadable: {
  1414. p_target_decorations->is_non_readable = true;
  1415. }
  1416. break;
  1417. case SpvDecorationLocation: {
  1418. uint32_t word_offset = p_node->word_offset + member_offset + 3;
  1419. CHECKED_READU32(p_parser, word_offset, p_target_decorations->location.value);
  1420. p_target_decorations->location.word_offset = word_offset;
  1421. }
  1422. break;
  1423. case SpvDecorationComponent: {
  1424. uint32_t word_offset = p_node->word_offset + member_offset + 3;
  1425. CHECKED_READU32(p_parser, word_offset,
  1426. p_target_decorations->component.value);
  1427. p_target_decorations->component.word_offset = word_offset;
  1428. } break;
  1429. case SpvDecorationBinding: {
  1430. uint32_t word_offset = p_node->word_offset + member_offset+ 3;
  1431. CHECKED_READU32(p_parser, word_offset, p_target_decorations->binding.value);
  1432. p_target_decorations->binding.word_offset = word_offset;
  1433. }
  1434. break;
  1435. case SpvDecorationDescriptorSet: {
  1436. uint32_t word_offset = p_node->word_offset + member_offset+ 3;
  1437. CHECKED_READU32(p_parser, word_offset, p_target_decorations->set.value);
  1438. p_target_decorations->set.word_offset = word_offset;
  1439. }
  1440. break;
  1441. case SpvDecorationOffset: {
  1442. uint32_t word_offset = p_node->word_offset + member_offset+ 3;
  1443. CHECKED_READU32(p_parser, word_offset, p_target_decorations->offset.value);
  1444. p_target_decorations->offset.word_offset = word_offset;
  1445. }
  1446. break;
  1447. case SpvDecorationInputAttachmentIndex: {
  1448. uint32_t word_offset = p_node->word_offset + member_offset+ 3;
  1449. CHECKED_READU32(p_parser, word_offset, p_target_decorations->input_attachment_index.value);
  1450. p_target_decorations->input_attachment_index.word_offset = word_offset;
  1451. }
  1452. break;
  1453. // -- GODOT begin --
  1454. case SpvDecorationSpecId: {
  1455. uint32_t word_offset = p_node->word_offset + member_offset+ 3;
  1456. CHECKED_READU32(p_parser, word_offset, p_target_decorations->specialization_constant.value);
  1457. p_target_decorations->specialization_constant.word_offset = word_offset;
  1458. }
  1459. break;
  1460. // -- GODOT end --
  1461. case SpvReflectDecorationHlslCounterBufferGOOGLE: {
  1462. uint32_t word_offset = p_node->word_offset + member_offset+ 3;
  1463. CHECKED_READU32(p_parser, word_offset, p_target_decorations->uav_counter_buffer.value);
  1464. p_target_decorations->uav_counter_buffer.word_offset = word_offset;
  1465. }
  1466. break;
  1467. case SpvReflectDecorationHlslSemanticGOOGLE: {
  1468. uint32_t word_offset = p_node->word_offset + member_offset + 3;
  1469. p_target_decorations->semantic.value = (const char*)(p_parser->spirv_code + word_offset);
  1470. p_target_decorations->semantic.word_offset = word_offset;
  1471. }
  1472. break;
  1473. }
  1474. }
  1475. return SPV_REFLECT_RESULT_SUCCESS;
  1476. }
  1477. static SpvReflectResult EnumerateAllUniforms(
  1478. SpvReflectShaderModule* p_module,
  1479. size_t* p_uniform_count,
  1480. uint32_t** pp_uniforms
  1481. )
  1482. {
  1483. *p_uniform_count = p_module->descriptor_binding_count;
  1484. if (*p_uniform_count == 0) {
  1485. return SPV_REFLECT_RESULT_SUCCESS;
  1486. }
  1487. *pp_uniforms = (uint32_t*)calloc(*p_uniform_count, sizeof(**pp_uniforms));
  1488. if (IsNull(*pp_uniforms)) {
  1489. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1490. }
  1491. for (size_t i = 0; i < *p_uniform_count; ++i) {
  1492. (*pp_uniforms)[i] = p_module->descriptor_bindings[i].spirv_id;
  1493. }
  1494. qsort(*pp_uniforms, *p_uniform_count, sizeof(**pp_uniforms),
  1495. SortCompareUint32);
  1496. return SPV_REFLECT_RESULT_SUCCESS;
  1497. }
  1498. static SpvReflectResult ParseType(
  1499. SpvReflectPrvParser* p_parser,
  1500. SpvReflectPrvNode* p_node,
  1501. SpvReflectPrvDecorations* p_struct_member_decorations,
  1502. SpvReflectShaderModule* p_module,
  1503. SpvReflectTypeDescription* p_type
  1504. )
  1505. {
  1506. SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
  1507. if (p_node->member_count > 0) {
  1508. p_type->struct_type_description = FindType(p_module, p_node->result_id);
  1509. p_type->member_count = p_node->member_count;
  1510. p_type->members = (SpvReflectTypeDescription*)calloc(p_type->member_count, sizeof(*(p_type->members)));
  1511. if (IsNotNull(p_type->members)) {
  1512. // Mark all members types with an invalid state
  1513. for (size_t i = 0; i < p_type->members->member_count; ++i) {
  1514. SpvReflectTypeDescription* p_member_type = &(p_type->members[i]);
  1515. p_member_type->id = (uint32_t)INVALID_VALUE;
  1516. p_member_type->op = (SpvOp)INVALID_VALUE;
  1517. p_member_type->storage_class = (SpvStorageClass)INVALID_VALUE;
  1518. }
  1519. }
  1520. else {
  1521. result = SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1522. }
  1523. }
  1524. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  1525. // Since the parse descends on type information, these will get overwritten
  1526. // if not guarded against assignment. Only assign if the id is invalid.
  1527. if (p_type->id == INVALID_VALUE) {
  1528. p_type->id = p_node->result_id;
  1529. p_type->op = p_node->op;
  1530. p_type->decoration_flags = 0;
  1531. }
  1532. // Top level types need to pick up decorations from all types below it.
  1533. // Issue and fix here: https://github.com/chaoticbob/SPIRV-Reflect/issues/64
  1534. p_type->decoration_flags = ApplyDecorations(&p_node->decorations);
  1535. switch (p_node->op) {
  1536. default: break;
  1537. case SpvOpTypeVoid:
  1538. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_VOID;
  1539. break;
  1540. case SpvOpTypeBool:
  1541. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_BOOL;
  1542. break;
  1543. case SpvOpTypeInt: {
  1544. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_INT;
  1545. IF_READU32(result, p_parser, p_node->word_offset + 2, p_type->traits.numeric.scalar.width);
  1546. IF_READU32(result, p_parser, p_node->word_offset + 3, p_type->traits.numeric.scalar.signedness);
  1547. }
  1548. break;
  1549. case SpvOpTypeFloat: {
  1550. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_FLOAT;
  1551. IF_READU32(result, p_parser, p_node->word_offset + 2, p_type->traits.numeric.scalar.width);
  1552. }
  1553. break;
  1554. case SpvOpTypeVector: {
  1555. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_VECTOR;
  1556. uint32_t component_type_id = (uint32_t)INVALID_VALUE;
  1557. IF_READU32(result, p_parser, p_node->word_offset + 2, component_type_id);
  1558. IF_READU32(result, p_parser, p_node->word_offset + 3, p_type->traits.numeric.vector.component_count);
  1559. // Parse component type
  1560. SpvReflectPrvNode* p_next_node = FindNode(p_parser, component_type_id);
  1561. if (IsNotNull(p_next_node)) {
  1562. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1563. }
  1564. else {
  1565. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1566. SPV_REFLECT_ASSERT(false);
  1567. }
  1568. }
  1569. break;
  1570. case SpvOpTypeMatrix: {
  1571. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_MATRIX;
  1572. uint32_t column_type_id = (uint32_t)INVALID_VALUE;
  1573. IF_READU32(result, p_parser, p_node->word_offset + 2, column_type_id);
  1574. IF_READU32(result, p_parser, p_node->word_offset + 3, p_type->traits.numeric.matrix.column_count);
  1575. SpvReflectPrvNode* p_next_node = FindNode(p_parser, column_type_id);
  1576. if (IsNotNull(p_next_node)) {
  1577. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1578. }
  1579. else {
  1580. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1581. SPV_REFLECT_ASSERT(false);
  1582. }
  1583. p_type->traits.numeric.matrix.row_count = p_type->traits.numeric.vector.component_count;
  1584. p_type->traits.numeric.matrix.stride = p_node->decorations.matrix_stride;
  1585. // NOTE: Matrix stride is decorated using OpMemberDecoreate - not OpDecoreate.
  1586. if (IsNotNull(p_struct_member_decorations)) {
  1587. p_type->traits.numeric.matrix.stride = p_struct_member_decorations->matrix_stride;
  1588. }
  1589. }
  1590. break;
  1591. case SpvOpTypeImage: {
  1592. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE;
  1593. uint32_t sampled_type_id = (uint32_t)INVALID_VALUE;
  1594. IF_READU32(result, p_parser, p_node->word_offset + 2, sampled_type_id);
  1595. SpvReflectPrvNode* p_next_node = FindNode(p_parser, sampled_type_id);
  1596. if (IsNotNull(p_next_node)) {
  1597. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1598. }
  1599. else {
  1600. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1601. }
  1602. IF_READU32_CAST(result, p_parser, p_node->word_offset + 3, SpvDim, p_type->traits.image.dim);
  1603. IF_READU32(result, p_parser, p_node->word_offset + 4, p_type->traits.image.depth);
  1604. IF_READU32(result, p_parser, p_node->word_offset + 5, p_type->traits.image.arrayed);
  1605. IF_READU32(result, p_parser, p_node->word_offset + 6, p_type->traits.image.ms);
  1606. IF_READU32(result, p_parser, p_node->word_offset + 7, p_type->traits.image.sampled);
  1607. IF_READU32_CAST(result, p_parser, p_node->word_offset + 8, SpvImageFormat, p_type->traits.image.image_format);
  1608. }
  1609. break;
  1610. case SpvOpTypeSampler: {
  1611. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER;
  1612. }
  1613. break;
  1614. case SpvOpTypeSampledImage: {
  1615. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE;
  1616. uint32_t image_type_id = (uint32_t)INVALID_VALUE;
  1617. IF_READU32(result, p_parser, p_node->word_offset + 2, image_type_id);
  1618. SpvReflectPrvNode* p_next_node = FindNode(p_parser, image_type_id);
  1619. if (IsNotNull(p_next_node)) {
  1620. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1621. }
  1622. else {
  1623. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1624. SPV_REFLECT_ASSERT(false);
  1625. }
  1626. }
  1627. break;
  1628. case SpvOpTypeArray: {
  1629. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_ARRAY;
  1630. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  1631. uint32_t element_type_id = (uint32_t)INVALID_VALUE;
  1632. uint32_t length_id = (uint32_t)INVALID_VALUE;
  1633. IF_READU32(result, p_parser, p_node->word_offset + 2, element_type_id);
  1634. IF_READU32(result, p_parser, p_node->word_offset + 3, length_id);
  1635. // NOTE: Array stride is decorated using OpDecorate instead of
  1636. // OpMemberDecorate, even if the array is apart of a struct.
  1637. p_type->traits.array.stride = p_node->decorations.array_stride;
  1638. // Get length for current dimension
  1639. SpvReflectPrvNode* p_length_node = FindNode(p_parser, length_id);
  1640. if (IsNotNull(p_length_node)) {
  1641. uint32_t dim_index = p_type->traits.array.dims_count;
  1642. if (p_length_node->op == SpvOpSpecConstant ||
  1643. p_length_node->op == SpvOpSpecConstantOp) {
  1644. p_type->traits.array.dims[dim_index] =
  1645. (uint32_t)SPV_REFLECT_ARRAY_DIM_SPEC_CONSTANT;
  1646. p_type->traits.array.spec_constant_op_ids[dim_index] = length_id;
  1647. p_type->traits.array.dims_count += 1;
  1648. } else {
  1649. uint32_t length = 0;
  1650. IF_READU32(result, p_parser, p_length_node->word_offset + 3, length);
  1651. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  1652. // Write the array dim and increment the count and offset
  1653. p_type->traits.array.dims[dim_index] = length;
  1654. p_type->traits.array.spec_constant_op_ids[dim_index] =
  1655. (uint32_t)SPV_REFLECT_ARRAY_DIM_SPEC_CONSTANT;
  1656. p_type->traits.array.dims_count += 1;
  1657. } else {
  1658. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1659. SPV_REFLECT_ASSERT(false);
  1660. }
  1661. }
  1662. // Parse next dimension or element type
  1663. SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id);
  1664. if (IsNotNull(p_next_node)) {
  1665. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1666. }
  1667. }
  1668. else {
  1669. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1670. SPV_REFLECT_ASSERT(false);
  1671. }
  1672. }
  1673. }
  1674. break;
  1675. case SpvOpTypeRuntimeArray: {
  1676. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_ARRAY;
  1677. uint32_t element_type_id = (uint32_t)INVALID_VALUE;
  1678. IF_READU32(result, p_parser, p_node->word_offset + 2, element_type_id);
  1679. p_type->traits.array.stride = p_node->decorations.array_stride;
  1680. uint32_t dim_index = p_type->traits.array.dims_count;
  1681. p_type->traits.array.dims[dim_index] =
  1682. (uint32_t)SPV_REFLECT_ARRAY_DIM_RUNTIME;
  1683. p_type->traits.array.spec_constant_op_ids[dim_index] = 0;
  1684. p_type->traits.array.dims_count += 1;
  1685. // Parse next dimension or element type
  1686. SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id);
  1687. if (IsNotNull(p_next_node)) {
  1688. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1689. }
  1690. else {
  1691. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1692. SPV_REFLECT_ASSERT(false);
  1693. }
  1694. }
  1695. break;
  1696. case SpvOpTypeStruct: {
  1697. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_STRUCT;
  1698. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK;
  1699. uint32_t word_index = 2;
  1700. uint32_t member_index = 0;
  1701. for (; word_index < p_node->word_count; ++word_index, ++member_index) {
  1702. uint32_t member_id = (uint32_t)INVALID_VALUE;
  1703. IF_READU32(result, p_parser, p_node->word_offset + word_index, member_id);
  1704. // Find member node
  1705. SpvReflectPrvNode* p_member_node = FindNode(p_parser, member_id);
  1706. if (IsNull(p_member_node)) {
  1707. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1708. SPV_REFLECT_ASSERT(false);
  1709. break;
  1710. }
  1711. // Member decorations
  1712. SpvReflectPrvDecorations* p_member_decorations = &p_node->member_decorations[member_index];
  1713. assert(member_index < p_type->member_count);
  1714. // Parse member type
  1715. SpvReflectTypeDescription* p_member_type = &(p_type->members[member_index]);
  1716. p_member_type->id = member_id;
  1717. p_member_type->op = p_member_node->op;
  1718. result = ParseType(p_parser, p_member_node, p_member_decorations, p_module, p_member_type);
  1719. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  1720. break;
  1721. }
  1722. // This looks wrong
  1723. //p_member_type->type_name = p_member_node->name;
  1724. p_member_type->struct_member_name = p_node->member_names[member_index];
  1725. }
  1726. }
  1727. break;
  1728. case SpvOpTypeOpaque: break;
  1729. case SpvOpTypePointer: {
  1730. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_REF;
  1731. IF_READU32_CAST(result, p_parser, p_node->word_offset + 2, SpvStorageClass, p_type->storage_class);
  1732. bool found_recursion = false;
  1733. if (p_type->storage_class == SpvStorageClassPhysicalStorageBuffer) {
  1734. // Need to make sure we haven't started an infinite recursive loop
  1735. for (uint32_t i = 0; i < p_parser->physical_pointer_count; i++) {
  1736. if (p_type->id == p_parser->physical_pointer_check[i]) {
  1737. found_recursion = true;
  1738. break; // still need to fill in p_type values
  1739. }
  1740. }
  1741. if (!found_recursion) {
  1742. p_parser->physical_pointer_check[p_parser->physical_pointer_count] =
  1743. p_type->id;
  1744. p_parser->physical_pointer_count++;
  1745. if (p_parser->physical_pointer_count >=
  1746. MAX_RECURSIVE_PHYSICAL_POINTER_CHECK) {
  1747. return SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED;
  1748. }
  1749. }
  1750. }
  1751. uint32_t type_id = (uint32_t)INVALID_VALUE;
  1752. IF_READU32(result, p_parser, p_node->word_offset + 3, type_id);
  1753. // Parse type
  1754. SpvReflectPrvNode* p_next_node = FindNode(p_parser, type_id);
  1755. if (IsNull(p_next_node)) {
  1756. result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1757. SPV_REFLECT_ASSERT(false);
  1758. }
  1759. else if (!found_recursion) {
  1760. result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
  1761. }
  1762. }
  1763. break;
  1764. case SpvOpTypeAccelerationStructureKHR: {
  1765. p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE;
  1766. }
  1767. break;
  1768. // -- GODOT begin --
  1769. case SpvOpSpecConstantTrue:
  1770. case SpvOpSpecConstantFalse:
  1771. case SpvOpSpecConstant: {
  1772. }
  1773. break;
  1774. // -- GODOT end --
  1775. }
  1776. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  1777. // Names get assigned on the way down. Guard against names
  1778. // get overwritten on the way up.
  1779. if (IsNull(p_type->type_name)) {
  1780. p_type->type_name = p_node->name;
  1781. }
  1782. }
  1783. }
  1784. return result;
  1785. }
  1786. static SpvReflectResult ParseTypes(
  1787. SpvReflectPrvParser* p_parser,
  1788. SpvReflectShaderModule* p_module)
  1789. {
  1790. if (p_parser->type_count == 0) {
  1791. return SPV_REFLECT_RESULT_SUCCESS;
  1792. }
  1793. p_module->_internal->type_description_count = p_parser->type_count;
  1794. p_module->_internal->type_descriptions = (SpvReflectTypeDescription*)calloc(p_module->_internal->type_description_count,
  1795. sizeof(*(p_module->_internal->type_descriptions)));
  1796. if (IsNull(p_module->_internal->type_descriptions)) {
  1797. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1798. }
  1799. // Mark all types with an invalid state
  1800. for (size_t i = 0; i < p_module->_internal->type_description_count; ++i) {
  1801. SpvReflectTypeDescription* p_type = &(p_module->_internal->type_descriptions[i]);
  1802. p_type->id = (uint32_t)INVALID_VALUE;
  1803. p_type->op = (SpvOp)INVALID_VALUE;
  1804. p_type->storage_class = (SpvStorageClass)INVALID_VALUE;
  1805. }
  1806. size_t type_index = 0;
  1807. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1808. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1809. if (! p_node->is_type) {
  1810. continue;
  1811. }
  1812. SpvReflectTypeDescription* p_type = &(p_module->_internal->type_descriptions[type_index]);
  1813. p_parser->physical_pointer_count = 0;
  1814. SpvReflectResult result = ParseType(p_parser, p_node, NULL, p_module, p_type);
  1815. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  1816. return result;
  1817. }
  1818. ++type_index;
  1819. }
  1820. return SPV_REFLECT_RESULT_SUCCESS;
  1821. }
  1822. static SpvReflectResult ParseCapabilities(
  1823. SpvReflectPrvParser* p_parser,
  1824. SpvReflectShaderModule* p_module)
  1825. {
  1826. if (p_parser->capability_count == 0) {
  1827. return SPV_REFLECT_RESULT_SUCCESS;
  1828. }
  1829. p_module->capability_count = p_parser->capability_count;
  1830. p_module->capabilities = (SpvReflectCapability*)calloc(p_module->capability_count,
  1831. sizeof(*(p_module->capabilities)));
  1832. if (IsNull(p_module->capabilities)) {
  1833. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1834. }
  1835. // Mark all types with an invalid state
  1836. for (size_t i = 0; i < p_module->capability_count; ++i) {
  1837. SpvReflectCapability* p_cap = &(p_module->capabilities[i]);
  1838. p_cap->value = SpvCapabilityMax;
  1839. p_cap->word_offset = (uint32_t)INVALID_VALUE;
  1840. }
  1841. size_t capability_index = 0;
  1842. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1843. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1844. if (SpvOpCapability != p_node->op) {
  1845. continue;
  1846. }
  1847. SpvReflectCapability* p_cap = &(p_module->capabilities[capability_index]);
  1848. p_cap->value = p_node->capability;
  1849. p_cap->word_offset = p_node->word_offset + 1;
  1850. ++capability_index;
  1851. }
  1852. return SPV_REFLECT_RESULT_SUCCESS;
  1853. }
  1854. static int SortCompareDescriptorBinding(const void* a, const void* b)
  1855. {
  1856. const SpvReflectDescriptorBinding* p_elem_a = (const SpvReflectDescriptorBinding*)a;
  1857. const SpvReflectDescriptorBinding* p_elem_b = (const SpvReflectDescriptorBinding*)b;
  1858. int value = (int)(p_elem_a->binding) - (int)(p_elem_b->binding);
  1859. if (value == 0) {
  1860. // use spirv-id as a tiebreaker to ensure a stable ordering, as they're guaranteed
  1861. // unique.
  1862. assert(p_elem_a->spirv_id != p_elem_b->spirv_id);
  1863. value = (int)(p_elem_a->spirv_id) - (int)(p_elem_b->spirv_id);
  1864. }
  1865. return value;
  1866. }
  1867. static SpvReflectResult ParseDescriptorBindings(
  1868. SpvReflectPrvParser* p_parser,
  1869. SpvReflectShaderModule* p_module)
  1870. {
  1871. p_module->descriptor_binding_count = 0;
  1872. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1873. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1874. if ((p_node->op != SpvOpVariable) ||
  1875. ((p_node->storage_class != SpvStorageClassUniform) &&
  1876. (p_node->storage_class != SpvStorageClassStorageBuffer) &&
  1877. (p_node->storage_class != SpvStorageClassUniformConstant)))
  1878. {
  1879. continue;
  1880. }
  1881. if ((p_node->decorations.set.value == INVALID_VALUE) || (p_node->decorations.binding.value == INVALID_VALUE)) {
  1882. continue;
  1883. }
  1884. p_module->descriptor_binding_count += 1;
  1885. }
  1886. if (p_module->descriptor_binding_count == 0) {
  1887. return SPV_REFLECT_RESULT_SUCCESS;
  1888. }
  1889. p_module->descriptor_bindings = (SpvReflectDescriptorBinding*)calloc(p_module->descriptor_binding_count, sizeof(*(p_module->descriptor_bindings)));
  1890. if (IsNull(p_module->descriptor_bindings)) {
  1891. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  1892. }
  1893. // Mark all types with an invalid state
  1894. for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {
  1895. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);
  1896. p_descriptor->binding = (uint32_t)INVALID_VALUE;
  1897. p_descriptor->input_attachment_index = (uint32_t)INVALID_VALUE;
  1898. p_descriptor->set = (uint32_t)INVALID_VALUE;
  1899. p_descriptor->descriptor_type = (SpvReflectDescriptorType)INVALID_VALUE;
  1900. p_descriptor->uav_counter_id = (uint32_t)INVALID_VALUE;
  1901. }
  1902. size_t descriptor_index = 0;
  1903. for (size_t i = 0; i < p_parser->node_count; ++i) {
  1904. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  1905. if ((p_node->op != SpvOpVariable) ||
  1906. ((p_node->storage_class != SpvStorageClassUniform) &&
  1907. (p_node->storage_class != SpvStorageClassStorageBuffer) &&
  1908. (p_node->storage_class != SpvStorageClassUniformConstant)))
  1909. {
  1910. continue;
  1911. }
  1912. if ((p_node->decorations.set.value == INVALID_VALUE) || (p_node->decorations.binding.value == INVALID_VALUE)) {
  1913. continue;
  1914. }
  1915. SpvReflectTypeDescription* p_type = FindType(p_module, p_node->type_id);
  1916. if (IsNull(p_type)) {
  1917. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1918. }
  1919. // If the type is a pointer, resolve it. We need to retain the storage class
  1920. // from the pointer so that we can use it to deduce deescriptor types.
  1921. SpvStorageClass pointer_storage_class = SpvStorageClassMax;
  1922. if (p_type->op == SpvOpTypePointer) {
  1923. pointer_storage_class = p_type->storage_class;
  1924. // Find the type's node
  1925. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  1926. if (IsNull(p_type_node)) {
  1927. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1928. }
  1929. // Should be the resolved type
  1930. p_type = FindType(p_module, p_type_node->type_id);
  1931. if (IsNull(p_type)) {
  1932. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  1933. }
  1934. }
  1935. SpvReflectDescriptorBinding* p_descriptor = &p_module->descriptor_bindings[descriptor_index];
  1936. p_descriptor->spirv_id = p_node->result_id;
  1937. p_descriptor->name = p_node->name;
  1938. p_descriptor->binding = p_node->decorations.binding.value;
  1939. p_descriptor->input_attachment_index = p_node->decorations.input_attachment_index.value;
  1940. p_descriptor->set = p_node->decorations.set.value;
  1941. p_descriptor->count = 1;
  1942. p_descriptor->uav_counter_id = p_node->decorations.uav_counter_buffer.value;
  1943. p_descriptor->type_description = p_type;
  1944. p_descriptor->decoration_flags = ApplyDecorations(&p_node->decorations);
  1945. // If this is in the StorageBuffer storage class, it's for sure a storage
  1946. // buffer descriptor. We need to handle this case earlier because in SPIR-V
  1947. // there are two ways to indicate a storage buffer:
  1948. // 1) Uniform storage class + BufferBlock decoration, or
  1949. // 2) StorageBuffer storage class + Buffer decoration.
  1950. // The 1) way is deprecated since SPIR-V v1.3. But the Buffer decoration is
  1951. // also used together with Uniform storage class to mean uniform buffer..
  1952. // We'll handle the pre-v1.3 cases in ParseDescriptorType().
  1953. if (pointer_storage_class == SpvStorageClassStorageBuffer) {
  1954. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;
  1955. }
  1956. // Copy image traits
  1957. if ((p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) == SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE) {
  1958. memcpy(&p_descriptor->image, &p_type->traits.image, sizeof(p_descriptor->image));
  1959. }
  1960. // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096
  1961. {
  1962. const uint32_t resource_mask = SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE;
  1963. if ((p_type->type_flags & resource_mask) == resource_mask) {
  1964. memcpy(&p_descriptor->image, &p_type->traits.image, sizeof(p_descriptor->image));
  1965. }
  1966. }
  1967. // Copy array traits
  1968. if (p_type->traits.array.dims_count > 0) {
  1969. p_descriptor->array.dims_count = p_type->traits.array.dims_count;
  1970. for (uint32_t dim_index = 0; dim_index < p_type->traits.array.dims_count; ++dim_index) {
  1971. uint32_t dim_value = p_type->traits.array.dims[dim_index];
  1972. p_descriptor->array.dims[dim_index] = dim_value;
  1973. p_descriptor->count *= dim_value;
  1974. }
  1975. }
  1976. // Count
  1977. p_descriptor->word_offset.binding = p_node->decorations.binding.word_offset;
  1978. p_descriptor->word_offset.set = p_node->decorations.set.word_offset;
  1979. ++descriptor_index;
  1980. }
  1981. if (p_module->descriptor_binding_count > 0) {
  1982. qsort(p_module->descriptor_bindings,
  1983. p_module->descriptor_binding_count,
  1984. sizeof(*(p_module->descriptor_bindings)),
  1985. SortCompareDescriptorBinding);
  1986. }
  1987. return SPV_REFLECT_RESULT_SUCCESS;
  1988. }
  1989. static SpvReflectResult ParseDescriptorType(SpvReflectShaderModule* p_module)
  1990. {
  1991. if (p_module->descriptor_binding_count == 0) {
  1992. return SPV_REFLECT_RESULT_SUCCESS;
  1993. }
  1994. for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {
  1995. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);
  1996. SpvReflectTypeDescription* p_type = p_descriptor->type_description;
  1997. if ((int)p_descriptor->descriptor_type == (int)INVALID_VALUE) {
  1998. switch (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) {
  1999. default: assert(false && "unknown type flag"); break;
  2000. case SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE: {
  2001. if (p_descriptor->image.dim == SpvDimBuffer) {
  2002. switch (p_descriptor->image.sampled) {
  2003. default: assert(false && "unknown texel buffer sampled value"); break;
  2004. case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;
  2005. case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;
  2006. }
  2007. }
  2008. else if(p_descriptor->image.dim == SpvDimSubpassData) {
  2009. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
  2010. }
  2011. else {
  2012. switch (p_descriptor->image.sampled) {
  2013. default: assert(false && "unknown image sampled value"); break;
  2014. case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE; break;
  2015. case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE; break;
  2016. }
  2017. }
  2018. }
  2019. break;
  2020. case SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER: {
  2021. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER;
  2022. }
  2023. break;
  2024. case (SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE): {
  2025. // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096
  2026. if (p_descriptor->image.dim == SpvDimBuffer) {
  2027. switch (p_descriptor->image.sampled) {
  2028. default: assert(false && "unknown texel buffer sampled value"); break;
  2029. case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;
  2030. case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;
  2031. }
  2032. }
  2033. else {
  2034. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  2035. }
  2036. }
  2037. break;
  2038. case SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK: {
  2039. if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BLOCK) {
  2040. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  2041. }
  2042. else if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BUFFER_BLOCK) {
  2043. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;
  2044. }
  2045. else {
  2046. assert(false && "unknown struct");
  2047. }
  2048. }
  2049. break;
  2050. case SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE: {
  2051. p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
  2052. }
  2053. break;
  2054. }
  2055. }
  2056. switch (p_descriptor->descriptor_type) {
  2057. case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SAMPLER; break;
  2058. case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : p_descriptor->resource_type = (SpvReflectResourceType)(SPV_REFLECT_RESOURCE_FLAG_SAMPLER | SPV_REFLECT_RESOURCE_FLAG_SRV); break;
  2059. case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
  2060. case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
  2061. case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
  2062. case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
  2063. case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;
  2064. case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;
  2065. case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
  2066. case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
  2067. case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : break;
  2068. case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
  2069. }
  2070. }
  2071. return SPV_REFLECT_RESULT_SUCCESS;
  2072. }
  2073. static SpvReflectResult ParseUAVCounterBindings(SpvReflectShaderModule* p_module)
  2074. {
  2075. char name[MAX_NODE_NAME_LENGTH];
  2076. const char* k_count_tag = "@count";
  2077. for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {
  2078. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);
  2079. if (p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
  2080. continue;
  2081. }
  2082. SpvReflectDescriptorBinding* p_counter_descriptor = NULL;
  2083. // Use UAV counter buffer id if present...
  2084. if (p_descriptor->uav_counter_id != UINT32_MAX) {
  2085. for (uint32_t counter_descriptor_index = 0; counter_descriptor_index < p_module->descriptor_binding_count; ++counter_descriptor_index) {
  2086. SpvReflectDescriptorBinding* p_test_counter_descriptor = &(p_module->descriptor_bindings[counter_descriptor_index]);
  2087. if (p_test_counter_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
  2088. continue;
  2089. }
  2090. if (p_descriptor->uav_counter_id == p_test_counter_descriptor->spirv_id) {
  2091. p_counter_descriptor = p_test_counter_descriptor;
  2092. break;
  2093. }
  2094. }
  2095. }
  2096. // ...otherwise use old @count convention.
  2097. else {
  2098. const size_t descriptor_name_length = p_descriptor->name? strlen(p_descriptor->name): 0;
  2099. memset(name, 0, MAX_NODE_NAME_LENGTH);
  2100. memcpy(name, p_descriptor->name, descriptor_name_length);
  2101. #if defined(_WIN32)
  2102. strcat_s(name, MAX_NODE_NAME_LENGTH, k_count_tag);
  2103. #else
  2104. strcat(name, k_count_tag);
  2105. #endif
  2106. for (uint32_t counter_descriptor_index = 0; counter_descriptor_index < p_module->descriptor_binding_count; ++counter_descriptor_index) {
  2107. SpvReflectDescriptorBinding* p_test_counter_descriptor = &(p_module->descriptor_bindings[counter_descriptor_index]);
  2108. if (p_test_counter_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
  2109. continue;
  2110. }
  2111. if (p_test_counter_descriptor->name && strcmp(name, p_test_counter_descriptor->name) == 0) {
  2112. p_counter_descriptor = p_test_counter_descriptor;
  2113. break;
  2114. }
  2115. }
  2116. }
  2117. if (p_counter_descriptor != NULL) {
  2118. p_descriptor->uav_counter_binding = p_counter_descriptor;
  2119. }
  2120. }
  2121. return SPV_REFLECT_RESULT_SUCCESS;
  2122. }
  2123. static SpvReflectResult ParseDescriptorBlockVariable(
  2124. SpvReflectPrvParser* p_parser,
  2125. SpvReflectShaderModule* p_module,
  2126. SpvReflectTypeDescription* p_type,
  2127. SpvReflectBlockVariable* p_var
  2128. )
  2129. {
  2130. bool has_non_writable = false;
  2131. if (IsNotNull(p_type->members) && (p_type->member_count > 0)) {
  2132. p_var->member_count = p_type->member_count;
  2133. p_var->members = (SpvReflectBlockVariable*)calloc(p_var->member_count, sizeof(*p_var->members));
  2134. if (IsNull(p_var->members)) {
  2135. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2136. }
  2137. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  2138. if (IsNull(p_type_node)) {
  2139. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2140. }
  2141. // Resolve to element type if current type is array or run time array
  2142. while (p_type_node->op == SpvOpTypeArray || p_type_node->op == SpvOpTypeRuntimeArray) {
  2143. if (p_type_node->op == SpvOpTypeArray) {
  2144. p_type_node = FindNode(p_parser, p_type_node->array_traits.element_type_id);
  2145. }
  2146. else {
  2147. // Element type description
  2148. SpvReflectTypeDescription* p_type_temp = FindType(p_module, p_type_node->array_traits.element_type_id);
  2149. if (IsNull(p_type_temp)) {
  2150. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2151. }
  2152. // Element type node
  2153. p_type_node = FindNode(p_parser, p_type_temp->id);
  2154. }
  2155. if (IsNull(p_type_node)) {
  2156. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2157. }
  2158. }
  2159. // Parse members
  2160. for (uint32_t member_index = 0; member_index < p_type->member_count; ++member_index) {
  2161. SpvReflectTypeDescription* p_member_type = &p_type->members[member_index];
  2162. SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];
  2163. // If pointer type, treat like reference and resolve to pointee type
  2164. SpvReflectTypeDescription* p_member_ptr_type = 0;
  2165. bool found_recursion = false;
  2166. if (p_member_type->op == SpvOpTypePointer) {
  2167. if (p_member_type->storage_class ==
  2168. SpvStorageClassPhysicalStorageBuffer) {
  2169. // Need to make sure we haven't started an infinite recursive loop
  2170. for (uint32_t i = 0; i < p_parser->physical_pointer_count; i++) {
  2171. if (p_member_type->id == p_parser->physical_pointer_check[i]) {
  2172. found_recursion = true;
  2173. break; // still need to fill in p_member_type values
  2174. }
  2175. }
  2176. if (!found_recursion) {
  2177. p_parser->physical_pointer_check[p_parser->physical_pointer_count] =
  2178. p_member_type->id;
  2179. p_parser->physical_pointer_count++;
  2180. if (p_parser->physical_pointer_count >=
  2181. MAX_RECURSIVE_PHYSICAL_POINTER_CHECK) {
  2182. return SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED;
  2183. }
  2184. }
  2185. }
  2186. // Remember the original type
  2187. p_member_ptr_type = p_member_type;
  2188. SpvReflectPrvNode* p_member_type_node =
  2189. FindNode(p_parser, p_member_type->id);
  2190. if (IsNull(p_member_type_node)) {
  2191. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2192. }
  2193. // Should be the pointee type
  2194. p_member_type = FindType(p_module, p_member_type_node->type_id);
  2195. if (IsNull(p_member_type)) {
  2196. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2197. }
  2198. }
  2199. bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT;
  2200. if (is_struct && !found_recursion) {
  2201. SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_member_type, p_member_var);
  2202. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2203. return result;
  2204. }
  2205. }
  2206. if (p_type_node->storage_class == SpvStorageClassPhysicalStorageBuffer &&
  2207. !p_type_node->member_names) {
  2208. // TODO 212 - If a buffer ref has an array of itself, all members are null
  2209. continue;
  2210. }
  2211. p_member_var->name = p_type_node->member_names[member_index];
  2212. p_member_var->offset = p_type_node->member_decorations[member_index].offset.value;
  2213. p_member_var->decoration_flags = ApplyDecorations(&p_type_node->member_decorations[member_index]);
  2214. p_member_var->flags |= SPV_REFLECT_VARIABLE_FLAGS_UNUSED;
  2215. if (!has_non_writable && (p_member_var->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE)) {
  2216. has_non_writable = true;
  2217. }
  2218. ApplyNumericTraits(p_member_type, &p_member_var->numeric);
  2219. if (p_member_type->op == SpvOpTypeArray) {
  2220. ApplyArrayTraits(p_member_type, &p_member_var->array);
  2221. }
  2222. p_member_var->word_offset.offset = p_type_node->member_decorations[member_index].offset.word_offset;
  2223. p_member_var->type_description =
  2224. p_member_ptr_type ? p_member_ptr_type : p_member_type;
  2225. }
  2226. }
  2227. p_var->name = p_type->type_name;
  2228. p_var->type_description = p_type;
  2229. if (has_non_writable) {
  2230. p_var->decoration_flags |= SPV_REFLECT_DECORATION_NON_WRITABLE;
  2231. }
  2232. return SPV_REFLECT_RESULT_SUCCESS;
  2233. }
  2234. static SpvReflectResult ParseDescriptorBlockVariableSizes(
  2235. SpvReflectPrvParser* p_parser,
  2236. SpvReflectShaderModule* p_module,
  2237. bool is_parent_root,
  2238. bool is_parent_aos,
  2239. bool is_parent_rta,
  2240. SpvReflectBlockVariable* p_var
  2241. )
  2242. {
  2243. if (p_var->member_count == 0) {
  2244. return SPV_REFLECT_RESULT_SUCCESS;
  2245. }
  2246. bool is_parent_ref = p_var->type_description->op == SpvOpTypePointer;
  2247. // Absolute offsets
  2248. for (uint32_t member_index = 0; member_index < p_var->member_count; ++member_index) {
  2249. SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];
  2250. if (is_parent_root) {
  2251. p_member_var->absolute_offset = p_member_var->offset;
  2252. } else {
  2253. p_member_var->absolute_offset =
  2254. is_parent_aos
  2255. ? 0
  2256. : (is_parent_ref ? p_member_var->offset
  2257. : p_member_var->offset + p_var->absolute_offset);
  2258. }
  2259. }
  2260. // Size
  2261. for (uint32_t member_index = 0; member_index < p_var->member_count; ++member_index) {
  2262. SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];
  2263. SpvReflectTypeDescription* p_member_type = p_member_var->type_description;
  2264. if (!p_member_type) {
  2265. // TODO 212 - If a buffer ref has an array of itself, all members are null
  2266. continue;
  2267. }
  2268. switch (p_member_type->op) {
  2269. case SpvOpTypeBool: {
  2270. p_member_var->size = SPIRV_WORD_SIZE;
  2271. }
  2272. break;
  2273. case SpvOpTypeInt:
  2274. case SpvOpTypeFloat: {
  2275. p_member_var->size = p_member_type->traits.numeric.scalar.width / SPIRV_BYTE_WIDTH;
  2276. }
  2277. break;
  2278. case SpvOpTypeVector: {
  2279. uint32_t size = p_member_type->traits.numeric.vector.component_count *
  2280. (p_member_type->traits.numeric.scalar.width / SPIRV_BYTE_WIDTH);
  2281. p_member_var->size = size;
  2282. }
  2283. break;
  2284. case SpvOpTypeMatrix: {
  2285. if (p_member_var->decoration_flags & SPV_REFLECT_DECORATION_COLUMN_MAJOR) {
  2286. p_member_var->size = p_member_var->numeric.matrix.column_count * p_member_var->numeric.matrix.stride;
  2287. }
  2288. else if (p_member_var->decoration_flags & SPV_REFLECT_DECORATION_ROW_MAJOR) {
  2289. p_member_var->size = p_member_var->numeric.matrix.row_count * p_member_var->numeric.matrix.stride;
  2290. }
  2291. }
  2292. break;
  2293. case SpvOpTypeArray: {
  2294. // If array of structs, parse members first...
  2295. bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT;
  2296. if (is_struct) {
  2297. SpvReflectResult result = ParseDescriptorBlockVariableSizes(p_parser, p_module, false, true, is_parent_rta, p_member_var);
  2298. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2299. return result;
  2300. }
  2301. }
  2302. // ...then array
  2303. uint32_t element_count = (p_member_var->array.dims_count > 0 ? 1 : 0);
  2304. for (uint32_t i = 0; i < p_member_var->array.dims_count; ++i) {
  2305. element_count *= p_member_var->array.dims[i];
  2306. }
  2307. p_member_var->size = element_count * p_member_var->array.stride;
  2308. }
  2309. break;
  2310. case SpvOpTypeRuntimeArray: {
  2311. bool is_struct = (p_member_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) == SPV_REFLECT_TYPE_FLAG_STRUCT;
  2312. if (is_struct) {
  2313. SpvReflectResult result = ParseDescriptorBlockVariableSizes(p_parser, p_module, false, true, true, p_member_var);
  2314. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2315. return result;
  2316. }
  2317. }
  2318. }
  2319. break;
  2320. case SpvOpTypePointer: {
  2321. // Reference. Get to underlying struct type.
  2322. SpvReflectPrvNode* p_member_type_node = FindNode(p_parser, p_member_type->id);
  2323. if (IsNull(p_member_type_node)) {
  2324. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2325. }
  2326. // Get the pointee type
  2327. p_member_type = FindType(p_module, p_member_type_node->type_id);
  2328. if (IsNull(p_member_type)) {
  2329. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2330. }
  2331. assert(p_member_type->op == SpvOpTypeStruct);
  2332. FALLTHROUGH;
  2333. }
  2334. case SpvOpTypeStruct: {
  2335. SpvReflectResult result = ParseDescriptorBlockVariableSizes(p_parser, p_module, false, is_parent_aos, is_parent_rta, p_member_var);
  2336. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2337. return result;
  2338. }
  2339. }
  2340. break;
  2341. default:
  2342. break;
  2343. }
  2344. }
  2345. // Parse padded size using offset difference for all member except for the last entry...
  2346. for (uint32_t member_index = 0; member_index < (p_var->member_count - 1); ++member_index) {
  2347. SpvReflectBlockVariable* p_member_var = &p_var->members[member_index];
  2348. SpvReflectBlockVariable* p_next_member_var = &p_var->members[member_index + 1];
  2349. p_member_var->padded_size = p_next_member_var->offset - p_member_var->offset;
  2350. if (p_member_var->size > p_member_var->padded_size) {
  2351. p_member_var->size = p_member_var->padded_size;
  2352. }
  2353. if (is_parent_rta) {
  2354. p_member_var->padded_size = p_member_var->size;
  2355. }
  2356. }
  2357. // ...last entry just gets rounded up to near multiple of SPIRV_DATA_ALIGNMENT, which is 16 and
  2358. // subtract the offset.
  2359. if (p_var->member_count > 0) {
  2360. SpvReflectBlockVariable* p_member_var = &p_var->members[p_var->member_count - 1];
  2361. p_member_var->padded_size = RoundUp(p_member_var->offset + p_member_var->size, SPIRV_DATA_ALIGNMENT) - p_member_var->offset;
  2362. if (p_member_var->size > p_member_var->padded_size) {
  2363. p_member_var->size = p_member_var->padded_size;
  2364. }
  2365. if (is_parent_rta) {
  2366. p_member_var->padded_size = p_member_var->size;
  2367. }
  2368. }
  2369. // If buffer ref, sizes are same as uint64_t
  2370. if (is_parent_ref) {
  2371. p_var->size = p_var->padded_size = 8;
  2372. return SPV_REFLECT_RESULT_SUCCESS;
  2373. }
  2374. // @TODO validate this with assertion
  2375. p_var->size = p_var->members[p_var->member_count - 1].offset +
  2376. p_var->members[p_var->member_count - 1].padded_size;
  2377. p_var->padded_size = p_var->size;
  2378. return SPV_REFLECT_RESULT_SUCCESS;
  2379. }
  2380. static void MarkSelfAndAllMemberVarsAsUsed(SpvReflectBlockVariable* p_var)
  2381. {
  2382. // Clear the current variable's UNUSED flag
  2383. p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED;
  2384. SpvOp op_type = p_var->type_description->op;
  2385. switch (op_type) {
  2386. default: break;
  2387. case SpvOpTypeArray: {
  2388. }
  2389. break;
  2390. case SpvOpTypeStruct: {
  2391. for (uint32_t i = 0; i < p_var->member_count; ++i) {
  2392. SpvReflectBlockVariable* p_member_var = &p_var->members[i];
  2393. MarkSelfAndAllMemberVarsAsUsed(p_member_var);
  2394. }
  2395. }
  2396. break;
  2397. }
  2398. }
  2399. static SpvReflectResult ParseDescriptorBlockVariableUsage(
  2400. SpvReflectPrvParser* p_parser,
  2401. SpvReflectShaderModule* p_module,
  2402. SpvReflectPrvAccessChain* p_access_chain,
  2403. uint32_t index_index,
  2404. SpvOp override_op_type,
  2405. SpvReflectBlockVariable* p_var
  2406. )
  2407. {
  2408. // Clear the current variable's UNUSED flag
  2409. p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED;
  2410. // Parsing arrays requires overriding the op type for
  2411. // for the lowest dim's element type.
  2412. SpvReflectTypeDescription* p_type = p_var->type_description;
  2413. SpvOp op_type = p_type->op;
  2414. if (override_op_type != (SpvOp)INVALID_VALUE) {
  2415. op_type = override_op_type;
  2416. }
  2417. switch (op_type) {
  2418. default: break;
  2419. case SpvOpTypeArray: {
  2420. // Parse through array's type hierarchy to find the actual/non-array element type
  2421. while ((p_type->op == SpvOpTypeArray) && (index_index < p_access_chain->index_count)) {
  2422. // Find the array element type id
  2423. SpvReflectPrvNode* p_node = FindNode(p_parser, p_type->id);
  2424. if (p_node == NULL) {
  2425. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2426. }
  2427. uint32_t element_type_id = p_node->array_traits.element_type_id;
  2428. // Get the array element type
  2429. p_type = FindType(p_module, element_type_id);
  2430. if (p_type == NULL) {
  2431. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2432. }
  2433. // Next access chain index
  2434. index_index += 1;
  2435. }
  2436. // Only continue parsing if there's remaining indices in the access
  2437. // chain. If the end of the access chain has been reached then all
  2438. // remaining variables (including those in struct hierarchies)
  2439. // are considered USED.
  2440. //
  2441. // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78
  2442. //
  2443. if (index_index < p_access_chain->index_count) {
  2444. // Parse current var again with a type override and advanced index index
  2445. SpvReflectResult result = ParseDescriptorBlockVariableUsage(
  2446. p_parser,
  2447. p_module,
  2448. p_access_chain,
  2449. index_index,
  2450. p_type->op,
  2451. p_var);
  2452. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2453. return result;
  2454. }
  2455. } else {
  2456. // Clear UNUSED flag for remaining variables
  2457. MarkSelfAndAllMemberVarsAsUsed(p_var);
  2458. }
  2459. }
  2460. break;
  2461. case SpvOpTypePointer: {
  2462. // Reference. Get to underlying struct type.
  2463. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  2464. if (IsNull(p_type_node)) {
  2465. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2466. }
  2467. // Get the pointee type
  2468. p_type = FindType(p_module, p_type_node->type_id);
  2469. if (IsNull(p_type)) {
  2470. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2471. }
  2472. if (p_type->op != SpvOpTypeStruct) {
  2473. break;
  2474. }
  2475. FALLTHROUGH;
  2476. }
  2477. case SpvOpTypeStruct: {
  2478. assert(p_var->member_count > 0);
  2479. if (p_var->member_count == 0) {
  2480. return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA;
  2481. }
  2482. // The access chain can have zero indexes, if used for a runtime array
  2483. if (p_access_chain->index_count == 0) {
  2484. return SPV_REFLECT_RESULT_SUCCESS;
  2485. }
  2486. // Get member variable at the access's chain current index
  2487. uint32_t index = p_access_chain->indexes[index_index];
  2488. if (index >= p_var->member_count) {
  2489. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE;
  2490. }
  2491. SpvReflectBlockVariable* p_member_var = &p_var->members[index];
  2492. // Next access chain index
  2493. index_index += 1;
  2494. // Only continue parsing if there's remaining indices in the access
  2495. // chain. If the end of the access chain has been reach then all
  2496. // remaining variables (including those in struct hierarchies)
  2497. // are considered USED.
  2498. //
  2499. // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78
  2500. //
  2501. if (index_index < p_access_chain->index_count) {
  2502. SpvReflectResult result = ParseDescriptorBlockVariableUsage(
  2503. p_parser,
  2504. p_module,
  2505. p_access_chain,
  2506. index_index,
  2507. (SpvOp)INVALID_VALUE,
  2508. p_member_var);
  2509. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2510. return result;
  2511. }
  2512. }
  2513. else if (IsPointerToPointer(p_parser, p_access_chain->result_type_id)) {
  2514. // Remember block var for this access chain for downstream dereference
  2515. p_access_chain->block_var = p_member_var;
  2516. } else {
  2517. // Clear UNUSED flag for remaining variables
  2518. MarkSelfAndAllMemberVarsAsUsed(p_member_var);
  2519. }
  2520. }
  2521. break;
  2522. }
  2523. return SPV_REFLECT_RESULT_SUCCESS;
  2524. }
  2525. static SpvReflectResult ParseDescriptorBlocks(
  2526. SpvReflectPrvParser* p_parser,
  2527. SpvReflectShaderModule* p_module)
  2528. {
  2529. if (p_module->descriptor_binding_count == 0) {
  2530. return SPV_REFLECT_RESULT_SUCCESS;
  2531. }
  2532. for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {
  2533. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);
  2534. SpvReflectTypeDescription* p_type = p_descriptor->type_description;
  2535. if ((p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER) &&
  2536. (p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) )
  2537. {
  2538. continue;
  2539. }
  2540. // Mark UNUSED
  2541. p_descriptor->block.flags |= SPV_REFLECT_VARIABLE_FLAGS_UNUSED;
  2542. p_parser->physical_pointer_count = 0;
  2543. // Parse descriptor block
  2544. SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_type, &p_descriptor->block);
  2545. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2546. return result;
  2547. }
  2548. for (uint32_t access_chain_index = 0; access_chain_index < p_parser->access_chain_count; ++access_chain_index) {
  2549. SpvReflectPrvAccessChain* p_access_chain = &(p_parser->access_chains[access_chain_index]);
  2550. // Skip any access chains that aren't touching this descriptor block
  2551. if (p_descriptor->spirv_id != p_access_chain->base_id) {
  2552. continue;
  2553. }
  2554. result = ParseDescriptorBlockVariableUsage(
  2555. p_parser,
  2556. p_module,
  2557. p_access_chain,
  2558. 0,
  2559. (SpvOp)INVALID_VALUE,
  2560. &p_descriptor->block);
  2561. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2562. return result;
  2563. }
  2564. }
  2565. p_descriptor->block.name = p_descriptor->name;
  2566. bool is_parent_rta = (p_descriptor->descriptor_type == SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER);
  2567. result = ParseDescriptorBlockVariableSizes(p_parser, p_module, true, false, is_parent_rta, &p_descriptor->block);
  2568. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2569. return result;
  2570. }
  2571. if (is_parent_rta) {
  2572. p_descriptor->block.size = 0;
  2573. p_descriptor->block.padded_size = 0;
  2574. }
  2575. }
  2576. return SPV_REFLECT_RESULT_SUCCESS;
  2577. }
  2578. static SpvReflectResult ParseFormat(
  2579. const SpvReflectTypeDescription* p_type,
  2580. SpvReflectFormat* p_format
  2581. )
  2582. {
  2583. SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR;
  2584. bool signedness = (p_type->traits.numeric.scalar.signedness != 0);
  2585. uint32_t bit_width = p_type->traits.numeric.scalar.width;
  2586. if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_VECTOR) {
  2587. uint32_t component_count = p_type->traits.numeric.vector.component_count;
  2588. if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) {
  2589. switch (bit_width) {
  2590. case 16: {
  2591. switch (component_count) {
  2592. case 2: *p_format = SPV_REFLECT_FORMAT_R16G16_SFLOAT; break;
  2593. case 3: *p_format = SPV_REFLECT_FORMAT_R16G16B16_SFLOAT; break;
  2594. case 4: *p_format = SPV_REFLECT_FORMAT_R16G16B16A16_SFLOAT; break;
  2595. }
  2596. }
  2597. break;
  2598. case 32: {
  2599. switch (component_count) {
  2600. case 2: *p_format = SPV_REFLECT_FORMAT_R32G32_SFLOAT; break;
  2601. case 3: *p_format = SPV_REFLECT_FORMAT_R32G32B32_SFLOAT; break;
  2602. case 4: *p_format = SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT; break;
  2603. }
  2604. }
  2605. break;
  2606. case 64: {
  2607. switch (component_count) {
  2608. case 2: *p_format = SPV_REFLECT_FORMAT_R64G64_SFLOAT; break;
  2609. case 3: *p_format = SPV_REFLECT_FORMAT_R64G64B64_SFLOAT; break;
  2610. case 4: *p_format = SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT; break;
  2611. }
  2612. }
  2613. }
  2614. result = SPV_REFLECT_RESULT_SUCCESS;
  2615. }
  2616. else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) {
  2617. switch (bit_width) {
  2618. case 16: {
  2619. switch (component_count) {
  2620. case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R16G16_SINT : SPV_REFLECT_FORMAT_R16G16_UINT; break;
  2621. case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R16G16B16_SINT : SPV_REFLECT_FORMAT_R16G16B16_UINT; break;
  2622. case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R16G16B16A16_SINT : SPV_REFLECT_FORMAT_R16G16B16A16_UINT; break;
  2623. }
  2624. }
  2625. break;
  2626. case 32: {
  2627. switch (component_count) {
  2628. case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32_SINT : SPV_REFLECT_FORMAT_R32G32_UINT; break;
  2629. case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32_SINT : SPV_REFLECT_FORMAT_R32G32B32_UINT; break;
  2630. case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32A32_SINT : SPV_REFLECT_FORMAT_R32G32B32A32_UINT; break;
  2631. }
  2632. }
  2633. break;
  2634. case 64: {
  2635. switch (component_count) {
  2636. case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64_SINT : SPV_REFLECT_FORMAT_R64G64_UINT; break;
  2637. case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64_SINT : SPV_REFLECT_FORMAT_R64G64B64_UINT; break;
  2638. case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64A64_SINT : SPV_REFLECT_FORMAT_R64G64B64A64_UINT; break;
  2639. }
  2640. }
  2641. }
  2642. result = SPV_REFLECT_RESULT_SUCCESS;
  2643. }
  2644. }
  2645. else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) {
  2646. switch(bit_width) {
  2647. case 16:
  2648. *p_format = SPV_REFLECT_FORMAT_R16_SFLOAT;
  2649. break;
  2650. case 32:
  2651. *p_format = SPV_REFLECT_FORMAT_R32_SFLOAT;
  2652. break;
  2653. case 64:
  2654. *p_format = SPV_REFLECT_FORMAT_R64_SFLOAT;
  2655. break;
  2656. }
  2657. result = SPV_REFLECT_RESULT_SUCCESS;
  2658. }
  2659. else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) {
  2660. switch(bit_width) {
  2661. case 16:
  2662. *p_format = signedness ? SPV_REFLECT_FORMAT_R16_SINT : SPV_REFLECT_FORMAT_R16_UINT; break;
  2663. break;
  2664. case 32:
  2665. *p_format = signedness ? SPV_REFLECT_FORMAT_R32_SINT : SPV_REFLECT_FORMAT_R32_UINT; break;
  2666. break;
  2667. case 64:
  2668. *p_format = signedness ? SPV_REFLECT_FORMAT_R64_SINT : SPV_REFLECT_FORMAT_R64_UINT; break;
  2669. }
  2670. result = SPV_REFLECT_RESULT_SUCCESS;
  2671. }
  2672. else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) {
  2673. *p_format = SPV_REFLECT_FORMAT_UNDEFINED;
  2674. result = SPV_REFLECT_RESULT_SUCCESS;
  2675. }
  2676. return result;
  2677. }
  2678. static SpvReflectResult ParseInterfaceVariable(
  2679. SpvReflectPrvParser* p_parser,
  2680. const SpvReflectPrvDecorations* p_var_node_decorations,
  2681. const SpvReflectPrvDecorations* p_type_node_decorations,
  2682. SpvReflectShaderModule* p_module,
  2683. SpvReflectTypeDescription* p_type,
  2684. SpvReflectInterfaceVariable* p_var,
  2685. bool* p_has_built_in
  2686. )
  2687. {
  2688. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  2689. if (IsNull(p_type_node)) {
  2690. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2691. }
  2692. if (p_type->member_count > 0) {
  2693. p_var->member_count = p_type->member_count;
  2694. p_var->members = (SpvReflectInterfaceVariable*)calloc(p_var->member_count, sizeof(*p_var->members));
  2695. if (IsNull(p_var->members)) {
  2696. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2697. }
  2698. for (uint32_t member_index = 0; member_index < p_type_node->member_count; ++member_index) {
  2699. SpvReflectPrvDecorations* p_member_decorations = &p_type_node->member_decorations[member_index];
  2700. SpvReflectTypeDescription* p_member_type = &p_type->members[member_index];
  2701. SpvReflectInterfaceVariable* p_member_var = &p_var->members[member_index];
  2702. // Storage class is the same throughout the whole struct
  2703. p_member_var->storage_class = p_var->storage_class;
  2704. SpvReflectResult result = ParseInterfaceVariable(p_parser, NULL, p_member_decorations, p_module, p_member_type, p_member_var, p_has_built_in);
  2705. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2706. SPV_REFLECT_ASSERT(false);
  2707. return result;
  2708. }
  2709. }
  2710. }
  2711. p_var->name = p_type_node->name;
  2712. p_var->decoration_flags = ApplyDecorations(p_type_node_decorations);
  2713. if (p_var_node_decorations != NULL) {
  2714. p_var->decoration_flags |= ApplyDecorations(p_var_node_decorations);
  2715. } else {
  2716. // Apply member decoration values to struct members
  2717. p_var->location = p_type_node_decorations->location.value;
  2718. p_var->component = p_type_node_decorations->component.value;
  2719. }
  2720. p_var->built_in = p_type_node_decorations->built_in;
  2721. ApplyNumericTraits(p_type, &p_var->numeric);
  2722. if (p_type->op == SpvOpTypeArray) {
  2723. ApplyArrayTraits(p_type, &p_var->array);
  2724. }
  2725. p_var->type_description = p_type;
  2726. *p_has_built_in |= p_type_node_decorations->is_built_in;
  2727. // Only parse format for interface variables that are input or output
  2728. if ((p_var->storage_class == SpvStorageClassInput) || (p_var->storage_class == SpvStorageClassOutput)) {
  2729. SpvReflectResult result = ParseFormat(p_var->type_description, &p_var->format);
  2730. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2731. SPV_REFLECT_ASSERT(false);
  2732. return result;
  2733. }
  2734. }
  2735. return SPV_REFLECT_RESULT_SUCCESS;
  2736. }
  2737. static SpvReflectResult ParseInterfaceVariables(
  2738. SpvReflectPrvParser* p_parser,
  2739. SpvReflectShaderModule* p_module,
  2740. SpvReflectEntryPoint* p_entry,
  2741. uint32_t interface_variable_count,
  2742. uint32_t* p_interface_variable_ids
  2743. )
  2744. {
  2745. if (interface_variable_count == 0) {
  2746. return SPV_REFLECT_RESULT_SUCCESS;
  2747. }
  2748. p_entry->interface_variable_count = interface_variable_count;
  2749. p_entry->input_variable_count = 0;
  2750. p_entry->output_variable_count = 0;
  2751. for (size_t i = 0; i < interface_variable_count; ++i) {
  2752. uint32_t var_result_id = *(p_interface_variable_ids + i);
  2753. SpvReflectPrvNode* p_node = FindNode(p_parser, var_result_id);
  2754. if (IsNull(p_node)) {
  2755. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2756. }
  2757. if (p_node->storage_class == SpvStorageClassInput) {
  2758. p_entry->input_variable_count += 1;
  2759. }
  2760. else if (p_node->storage_class == SpvStorageClassOutput) {
  2761. p_entry->output_variable_count += 1;
  2762. }
  2763. }
  2764. if (p_entry->input_variable_count > 0) {
  2765. p_entry->input_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->input_variable_count, sizeof(*(p_entry->input_variables)));
  2766. if (IsNull(p_entry->input_variables)) {
  2767. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2768. }
  2769. }
  2770. if (p_entry->output_variable_count > 0) {
  2771. p_entry->output_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->output_variable_count, sizeof(*(p_entry->output_variables)));
  2772. if (IsNull(p_entry->output_variables)) {
  2773. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2774. }
  2775. }
  2776. if (p_entry->interface_variable_count > 0) {
  2777. p_entry->interface_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->interface_variable_count, sizeof(*(p_entry->interface_variables)));
  2778. if (IsNull(p_entry->interface_variables)) {
  2779. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2780. }
  2781. }
  2782. size_t input_index = 0;
  2783. size_t output_index = 0;
  2784. for (size_t i = 0; i < interface_variable_count; ++i) {
  2785. uint32_t var_result_id = *(p_interface_variable_ids + i);
  2786. SpvReflectPrvNode* p_node = FindNode(p_parser, var_result_id);
  2787. if (IsNull(p_node)) {
  2788. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2789. }
  2790. SpvReflectTypeDescription* p_type = FindType(p_module, p_node->type_id);
  2791. if (IsNull(p_node)) {
  2792. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2793. }
  2794. // If the type is a pointer, resolve it
  2795. if (p_type->op == SpvOpTypePointer) {
  2796. // Find the type's node
  2797. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  2798. if (IsNull(p_type_node)) {
  2799. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2800. }
  2801. // Should be the resolved type
  2802. p_type = FindType(p_module, p_type_node->type_id);
  2803. if (IsNull(p_type)) {
  2804. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2805. }
  2806. }
  2807. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  2808. if (IsNull(p_type_node)) {
  2809. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2810. }
  2811. SpvReflectInterfaceVariable* p_var = &(p_entry->interface_variables[i]);
  2812. p_var->storage_class = p_node->storage_class;
  2813. bool has_built_in = p_node->decorations.is_built_in;
  2814. SpvReflectResult result = ParseInterfaceVariable(
  2815. p_parser,
  2816. &p_node->decorations,
  2817. &p_type_node->decorations,
  2818. p_module,
  2819. p_type,
  2820. p_var,
  2821. &has_built_in);
  2822. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2823. SPV_REFLECT_ASSERT(false);
  2824. return result;
  2825. }
  2826. // Input and output variables
  2827. if (p_var->storage_class == SpvStorageClassInput) {
  2828. p_entry->input_variables[input_index] = p_var;
  2829. ++input_index;
  2830. }
  2831. else if (p_node->storage_class == SpvStorageClassOutput) {
  2832. p_entry->output_variables[output_index] = p_var;
  2833. ++output_index;
  2834. }
  2835. // SPIR-V result id
  2836. p_var->spirv_id = p_node->result_id;
  2837. // Name
  2838. p_var->name = p_node->name;
  2839. // Semantic
  2840. p_var->semantic = p_node->decorations.semantic.value;
  2841. // Decorate with built-in if any member is built-in
  2842. if (has_built_in) {
  2843. p_var->decoration_flags |= SPV_REFLECT_DECORATION_BUILT_IN;
  2844. }
  2845. // Location is decorated on OpVariable node, not the type node.
  2846. p_var->location = p_node->decorations.location.value;
  2847. p_var->component = p_node->decorations.component.value;
  2848. p_var->word_offset.location = p_node->decorations.location.word_offset;
  2849. // Built in
  2850. if (p_node->decorations.is_built_in) {
  2851. p_var->built_in = p_node->decorations.built_in;
  2852. }
  2853. }
  2854. return SPV_REFLECT_RESULT_SUCCESS;
  2855. }
  2856. static SpvReflectResult EnumerateAllPushConstants(
  2857. SpvReflectShaderModule* p_module,
  2858. size_t* p_push_constant_count,
  2859. uint32_t** p_push_constants
  2860. )
  2861. {
  2862. *p_push_constant_count = p_module->push_constant_block_count;
  2863. if (*p_push_constant_count == 0) {
  2864. return SPV_REFLECT_RESULT_SUCCESS;
  2865. }
  2866. *p_push_constants = (uint32_t*)calloc(*p_push_constant_count, sizeof(**p_push_constants));
  2867. if (IsNull(*p_push_constants)) {
  2868. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2869. }
  2870. for (size_t i = 0; i < *p_push_constant_count; ++i) {
  2871. (*p_push_constants)[i] = p_module->push_constant_blocks[i].spirv_id;
  2872. }
  2873. qsort(*p_push_constants, *p_push_constant_count, sizeof(**p_push_constants),
  2874. SortCompareUint32);
  2875. return SPV_REFLECT_RESULT_SUCCESS;
  2876. }
  2877. static SpvReflectResult TraverseCallGraph(
  2878. SpvReflectPrvParser* p_parser,
  2879. SpvReflectPrvFunction* p_func,
  2880. size_t* p_func_count,
  2881. uint32_t* p_func_ids,
  2882. uint32_t depth
  2883. )
  2884. {
  2885. if (depth > p_parser->function_count) {
  2886. // Vulkan does not permit recursion (Vulkan spec Appendix A):
  2887. // "Recursion: The static function-call graph for an entry point must not
  2888. // contain cycles."
  2889. return SPV_REFLECT_RESULT_ERROR_SPIRV_RECURSION;
  2890. }
  2891. if (IsNotNull(p_func_ids)) {
  2892. p_func_ids[(*p_func_count)++] = p_func->id;
  2893. } else {
  2894. ++*p_func_count;
  2895. }
  2896. for (size_t i = 0; i < p_func->callee_count; ++i) {
  2897. SpvReflectResult result = TraverseCallGraph(
  2898. p_parser, p_func->callee_ptrs[i], p_func_count, p_func_ids, depth + 1);
  2899. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2900. return result;
  2901. }
  2902. }
  2903. return SPV_REFLECT_RESULT_SUCCESS;
  2904. }
  2905. static SpvReflectResult ParseStaticallyUsedResources(
  2906. SpvReflectPrvParser* p_parser,
  2907. SpvReflectShaderModule* p_module,
  2908. SpvReflectEntryPoint* p_entry,
  2909. size_t uniform_count,
  2910. uint32_t* uniforms,
  2911. size_t push_constant_count,
  2912. uint32_t* push_constants
  2913. )
  2914. {
  2915. // Find function with the right id
  2916. SpvReflectPrvFunction* p_func = NULL;
  2917. for (size_t i = 0; i < p_parser->function_count; ++i) {
  2918. if (p_parser->functions[i].id == p_entry->id) {
  2919. p_func = &(p_parser->functions[i]);
  2920. break;
  2921. }
  2922. }
  2923. if (p_func == NULL) {
  2924. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  2925. }
  2926. size_t called_function_count = 0;
  2927. SpvReflectResult result = TraverseCallGraph(
  2928. p_parser,
  2929. p_func,
  2930. &called_function_count,
  2931. NULL,
  2932. 0);
  2933. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2934. return result;
  2935. }
  2936. uint32_t* p_called_functions = NULL;
  2937. if (called_function_count > 0) {
  2938. p_called_functions = (uint32_t*)calloc(called_function_count, sizeof(*p_called_functions));
  2939. if (IsNull(p_called_functions)) {
  2940. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2941. }
  2942. }
  2943. called_function_count = 0;
  2944. result = TraverseCallGraph(
  2945. p_parser,
  2946. p_func,
  2947. &called_function_count,
  2948. p_called_functions,
  2949. 0);
  2950. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  2951. return result;
  2952. }
  2953. if (called_function_count > 0) {
  2954. qsort(
  2955. p_called_functions,
  2956. called_function_count,
  2957. sizeof(*p_called_functions),
  2958. SortCompareUint32);
  2959. }
  2960. called_function_count = DedupSortedUint32(p_called_functions, called_function_count);
  2961. uint32_t used_variable_count = 0;
  2962. for (size_t i = 0, j = 0; i < called_function_count; ++i) {
  2963. // No need to bounds check j because a missing ID issue would have been
  2964. // found during TraverseCallGraph
  2965. while (p_parser->functions[j].id != p_called_functions[i]) {
  2966. ++j;
  2967. }
  2968. used_variable_count += p_parser->functions[j].accessed_ptr_count;
  2969. }
  2970. uint32_t* used_variables = NULL;
  2971. if (used_variable_count > 0) {
  2972. used_variables = (uint32_t*)calloc(used_variable_count,
  2973. sizeof(*used_variables));
  2974. if (IsNull(used_variables)) {
  2975. SafeFree(p_called_functions);
  2976. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  2977. }
  2978. }
  2979. used_variable_count = 0;
  2980. for (size_t i = 0, j = 0; i < called_function_count; ++i) {
  2981. while (p_parser->functions[j].id != p_called_functions[i]) {
  2982. ++j;
  2983. }
  2984. memcpy(&used_variables[used_variable_count],
  2985. p_parser->functions[j].accessed_ptrs,
  2986. p_parser->functions[j].accessed_ptr_count * sizeof(*used_variables));
  2987. used_variable_count += p_parser->functions[j].accessed_ptr_count;
  2988. }
  2989. SafeFree(p_called_functions);
  2990. if (used_variable_count > 0) {
  2991. qsort(used_variables, used_variable_count, sizeof(*used_variables),
  2992. SortCompareUint32);
  2993. }
  2994. used_variable_count = (uint32_t)DedupSortedUint32(used_variables,
  2995. used_variable_count);
  2996. // Do set intersection to find the used uniform and push constants
  2997. size_t used_uniform_count = 0;
  2998. //
  2999. SpvReflectResult result0 = IntersectSortedUint32(
  3000. used_variables,
  3001. used_variable_count,
  3002. uniforms,
  3003. uniform_count,
  3004. &p_entry->used_uniforms,
  3005. &used_uniform_count);
  3006. size_t used_push_constant_count = 0;
  3007. //
  3008. SpvReflectResult result1 = IntersectSortedUint32(
  3009. used_variables,
  3010. used_variable_count,
  3011. push_constants,
  3012. push_constant_count,
  3013. &p_entry->used_push_constants,
  3014. &used_push_constant_count);
  3015. for (uint32_t j = 0; j < p_module->descriptor_binding_count; ++j) {
  3016. SpvReflectDescriptorBinding* p_binding = &p_module->descriptor_bindings[j];
  3017. bool found = SearchSortedUint32(
  3018. used_variables,
  3019. used_variable_count,
  3020. p_binding->spirv_id);
  3021. if (found) {
  3022. p_binding->accessed = 1;
  3023. }
  3024. }
  3025. SafeFree(used_variables);
  3026. if (result0 != SPV_REFLECT_RESULT_SUCCESS) {
  3027. return result0;
  3028. }
  3029. if (result1 != SPV_REFLECT_RESULT_SUCCESS) {
  3030. return result1;
  3031. }
  3032. p_entry->used_uniform_count = (uint32_t)used_uniform_count;
  3033. p_entry->used_push_constant_count = (uint32_t)used_push_constant_count;
  3034. return SPV_REFLECT_RESULT_SUCCESS;
  3035. }
  3036. static SpvReflectResult ParseEntryPoints(
  3037. SpvReflectPrvParser* p_parser,
  3038. SpvReflectShaderModule* p_module)
  3039. {
  3040. if (p_parser->entry_point_count == 0) {
  3041. return SPV_REFLECT_RESULT_SUCCESS;
  3042. }
  3043. p_module->entry_point_count = p_parser->entry_point_count;
  3044. p_module->entry_points = (SpvReflectEntryPoint*)calloc(p_module->entry_point_count,
  3045. sizeof(*(p_module->entry_points)));
  3046. if (IsNull(p_module->entry_points)) {
  3047. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3048. }
  3049. SpvReflectResult result;
  3050. size_t uniform_count = 0;
  3051. uint32_t* uniforms = NULL;
  3052. if ((result = EnumerateAllUniforms(p_module, &uniform_count, &uniforms)) !=
  3053. SPV_REFLECT_RESULT_SUCCESS) {
  3054. return result;
  3055. }
  3056. size_t push_constant_count = 0;
  3057. uint32_t* push_constants = NULL;
  3058. if ((result = EnumerateAllPushConstants(p_module, &push_constant_count, &push_constants)) !=
  3059. SPV_REFLECT_RESULT_SUCCESS) {
  3060. return result;
  3061. }
  3062. size_t entry_point_index = 0;
  3063. for (size_t i = 0; entry_point_index < p_parser->entry_point_count && i < p_parser->node_count; ++i) {
  3064. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  3065. if (p_node->op != SpvOpEntryPoint) {
  3066. continue;
  3067. }
  3068. SpvReflectEntryPoint* p_entry_point = &(p_module->entry_points[entry_point_index]);
  3069. CHECKED_READU32_CAST(p_parser, p_node->word_offset + 1, SpvExecutionModel, p_entry_point->spirv_execution_model);
  3070. CHECKED_READU32(p_parser, p_node->word_offset + 2, p_entry_point->id);
  3071. switch (p_entry_point->spirv_execution_model) {
  3072. default: break;
  3073. case SpvExecutionModelVertex : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_VERTEX_BIT; break;
  3074. case SpvExecutionModelTessellationControl : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TESSELLATION_CONTROL_BIT; break;
  3075. case SpvExecutionModelTessellationEvaluation : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; break;
  3076. case SpvExecutionModelGeometry : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT; break;
  3077. case SpvExecutionModelFragment : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT; break;
  3078. case SpvExecutionModelGLCompute : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT; break;
  3079. case SpvExecutionModelTaskNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV; break;
  3080. case SpvExecutionModelTaskEXT : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TASK_BIT_EXT; break;
  3081. case SpvExecutionModelMeshNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV; break;
  3082. case SpvExecutionModelMeshEXT : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_EXT; break;
  3083. case SpvExecutionModelRayGenerationKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR; break;
  3084. case SpvExecutionModelIntersectionKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR; break;
  3085. case SpvExecutionModelAnyHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR; break;
  3086. case SpvExecutionModelClosestHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break;
  3087. case SpvExecutionModelMissKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR; break;
  3088. case SpvExecutionModelCallableKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR; break;
  3089. }
  3090. ++entry_point_index;
  3091. // Name length is required to calculate next operand
  3092. uint32_t name_start_word_offset = 3;
  3093. uint32_t name_length_with_terminator = 0;
  3094. result = ReadStr(p_parser, p_node->word_offset + name_start_word_offset, 0, p_node->word_count, &name_length_with_terminator, NULL);
  3095. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3096. return result;
  3097. }
  3098. p_entry_point->name = (const char*)(p_parser->spirv_code + p_node->word_offset + name_start_word_offset);
  3099. uint32_t name_word_count = RoundUp(name_length_with_terminator, SPIRV_WORD_SIZE) / SPIRV_WORD_SIZE;
  3100. uint32_t interface_variable_count = (p_node->word_count - (name_start_word_offset + name_word_count));
  3101. uint32_t* p_interface_variables = NULL;
  3102. if (interface_variable_count > 0) {
  3103. p_interface_variables = (uint32_t*)calloc(interface_variable_count, sizeof(*(p_interface_variables)));
  3104. if (IsNull(p_interface_variables)) {
  3105. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3106. }
  3107. }
  3108. for (uint32_t var_index = 0; var_index < interface_variable_count; ++var_index) {
  3109. uint32_t var_result_id = (uint32_t)INVALID_VALUE;
  3110. uint32_t offset = name_start_word_offset + name_word_count + var_index;
  3111. CHECKED_READU32(p_parser, p_node->word_offset + offset, var_result_id);
  3112. p_interface_variables[var_index] = var_result_id;
  3113. }
  3114. result = ParseInterfaceVariables(
  3115. p_parser,
  3116. p_module,
  3117. p_entry_point,
  3118. interface_variable_count,
  3119. p_interface_variables);
  3120. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3121. return result;
  3122. }
  3123. SafeFree(p_interface_variables);
  3124. result = ParseStaticallyUsedResources(
  3125. p_parser,
  3126. p_module,
  3127. p_entry_point,
  3128. uniform_count,
  3129. uniforms,
  3130. push_constant_count,
  3131. push_constants);
  3132. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3133. return result;
  3134. }
  3135. }
  3136. SafeFree(uniforms);
  3137. SafeFree(push_constants);
  3138. return SPV_REFLECT_RESULT_SUCCESS;
  3139. }
  3140. static SpvReflectResult ParseExecutionModes(
  3141. SpvReflectPrvParser* p_parser,
  3142. SpvReflectShaderModule* p_module)
  3143. {
  3144. assert(IsNotNull(p_parser));
  3145. assert(IsNotNull(p_parser->nodes));
  3146. assert(IsNotNull(p_module));
  3147. if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {
  3148. for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) {
  3149. SpvReflectPrvNode* p_node = &(p_parser->nodes[node_idx]);
  3150. if (p_node->op != SpvOpExecutionMode) {
  3151. continue;
  3152. }
  3153. // Read entry point id
  3154. uint32_t entry_point_id = 0;
  3155. CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id);
  3156. // Find entry point
  3157. SpvReflectEntryPoint* p_entry_point = NULL;
  3158. for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {
  3159. if (p_module->entry_points[entry_point_idx].id == entry_point_id) {
  3160. p_entry_point = &p_module->entry_points[entry_point_idx];
  3161. break;
  3162. }
  3163. }
  3164. // Bail if entry point is null
  3165. if (IsNull(p_entry_point)) {
  3166. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT;
  3167. }
  3168. // Read execution mode
  3169. uint32_t execution_mode = (uint32_t)INVALID_VALUE;
  3170. CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode);
  3171. // Parse execution mode
  3172. switch (execution_mode) {
  3173. default: {
  3174. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE;
  3175. }
  3176. break;
  3177. case SpvExecutionModeInvocations: {
  3178. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->invocations);
  3179. }
  3180. break;
  3181. case SpvExecutionModeSpacingEqual:
  3182. case SpvExecutionModeSpacingFractionalEven:
  3183. case SpvExecutionModeSpacingFractionalOdd:
  3184. case SpvExecutionModeVertexOrderCw:
  3185. case SpvExecutionModeVertexOrderCcw:
  3186. case SpvExecutionModePixelCenterInteger:
  3187. case SpvExecutionModeOriginUpperLeft:
  3188. case SpvExecutionModeOriginLowerLeft:
  3189. case SpvExecutionModeEarlyFragmentTests:
  3190. case SpvExecutionModePointMode:
  3191. case SpvExecutionModeXfb:
  3192. case SpvExecutionModeDepthReplacing:
  3193. case SpvExecutionModeDepthGreater:
  3194. case SpvExecutionModeDepthLess:
  3195. case SpvExecutionModeDepthUnchanged:
  3196. break;
  3197. case SpvExecutionModeLocalSize: {
  3198. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->local_size.x);
  3199. CHECKED_READU32(p_parser, p_node->word_offset + 4, p_entry_point->local_size.y);
  3200. CHECKED_READU32(p_parser, p_node->word_offset + 5, p_entry_point->local_size.z);
  3201. }
  3202. break;
  3203. case SpvExecutionModeLocalSizeHint:
  3204. case SpvExecutionModeInputPoints:
  3205. case SpvExecutionModeInputLines:
  3206. case SpvExecutionModeInputLinesAdjacency:
  3207. case SpvExecutionModeTriangles:
  3208. case SpvExecutionModeInputTrianglesAdjacency:
  3209. case SpvExecutionModeQuads:
  3210. case SpvExecutionModeIsolines:
  3211. case SpvExecutionModeOutputVertices: {
  3212. CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->output_vertices);
  3213. }
  3214. break;
  3215. case SpvExecutionModeOutputPoints:
  3216. case SpvExecutionModeOutputLineStrip:
  3217. case SpvExecutionModeOutputTriangleStrip:
  3218. case SpvExecutionModeVecTypeHint:
  3219. case SpvExecutionModeContractionOff:
  3220. case SpvExecutionModeInitializer:
  3221. case SpvExecutionModeFinalizer:
  3222. case SpvExecutionModeSubgroupSize:
  3223. case SpvExecutionModeSubgroupsPerWorkgroup:
  3224. case SpvExecutionModeSubgroupsPerWorkgroupId:
  3225. case SpvExecutionModeLocalSizeId:
  3226. case SpvExecutionModeLocalSizeHintId:
  3227. case SpvExecutionModePostDepthCoverage:
  3228. case SpvExecutionModeDenormPreserve:
  3229. case SpvExecutionModeDenormFlushToZero:
  3230. case SpvExecutionModeSignedZeroInfNanPreserve:
  3231. case SpvExecutionModeRoundingModeRTE:
  3232. case SpvExecutionModeRoundingModeRTZ:
  3233. case SpvExecutionModeStencilRefReplacingEXT:
  3234. case SpvExecutionModeOutputLinesNV:
  3235. case SpvExecutionModeOutputPrimitivesNV:
  3236. case SpvExecutionModeOutputTrianglesNV:
  3237. case SpvExecutionModePixelInterlockOrderedEXT:
  3238. case SpvExecutionModePixelInterlockUnorderedEXT:
  3239. case SpvExecutionModeSampleInterlockOrderedEXT:
  3240. case SpvExecutionModeSampleInterlockUnorderedEXT:
  3241. break;
  3242. }
  3243. p_entry_point->execution_mode_count++;
  3244. }
  3245. uint32_t* indices = (uint32_t*)calloc(p_module->entry_point_count, sizeof(indices));
  3246. if (IsNull(indices)) {
  3247. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3248. }
  3249. for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {
  3250. SpvReflectEntryPoint* p_entry_point = &p_module->entry_points[entry_point_idx];
  3251. if (p_entry_point->execution_mode_count > 0) {
  3252. p_entry_point->execution_modes =
  3253. (SpvExecutionMode*)calloc(p_entry_point->execution_mode_count, sizeof(*p_entry_point->execution_modes));
  3254. if (IsNull(p_entry_point->execution_modes)) {
  3255. SafeFree(indices);
  3256. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3257. }
  3258. }
  3259. }
  3260. for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) {
  3261. SpvReflectPrvNode* p_node = &(p_parser->nodes[node_idx]);
  3262. if (p_node->op != SpvOpExecutionMode) {
  3263. continue;
  3264. }
  3265. // Read entry point id
  3266. uint32_t entry_point_id = 0;
  3267. CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id);
  3268. // Find entry point
  3269. SpvReflectEntryPoint* p_entry_point = NULL;
  3270. uint32_t* idx = NULL;
  3271. for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {
  3272. if (p_module->entry_points[entry_point_idx].id == entry_point_id) {
  3273. p_entry_point = &p_module->entry_points[entry_point_idx];
  3274. idx = &indices[entry_point_idx];
  3275. break;
  3276. }
  3277. }
  3278. // Read execution mode
  3279. uint32_t execution_mode = (uint32_t)INVALID_VALUE;
  3280. CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode);
  3281. p_entry_point->execution_modes[(*idx)++] = (SpvExecutionMode)execution_mode;
  3282. }
  3283. SafeFree(indices);
  3284. }
  3285. return SPV_REFLECT_RESULT_SUCCESS;
  3286. }
  3287. // -- GODOT begin --
  3288. static SpvReflectResult ParseSpecializationConstants(SpvReflectPrvParser* p_parser, SpvReflectShaderModule* p_module)
  3289. {
  3290. p_module->specialization_constant_count = 0;
  3291. p_module->specialization_constants = NULL;
  3292. for (size_t i = 0; i < p_parser->node_count; ++i) {
  3293. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  3294. if (p_node->op == SpvOpSpecConstantTrue || p_node->op == SpvOpSpecConstantFalse || p_node->op == SpvOpSpecConstant) {
  3295. p_module->specialization_constant_count++;
  3296. }
  3297. }
  3298. if (p_module->specialization_constant_count == 0) {
  3299. return SPV_REFLECT_RESULT_SUCCESS;
  3300. }
  3301. p_module->specialization_constants = (SpvReflectSpecializationConstant*)calloc(p_module->specialization_constant_count, sizeof(SpvReflectSpecializationConstant));
  3302. uint32_t index = 0;
  3303. for (size_t i = 0; i < p_parser->node_count; ++i) {
  3304. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  3305. switch(p_node->op) {
  3306. default: continue;
  3307. case SpvOpSpecConstantTrue: {
  3308. p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL;
  3309. p_module->specialization_constants[index].default_value.int_bool_value = 1;
  3310. } break;
  3311. case SpvOpSpecConstantFalse: {
  3312. p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL;
  3313. p_module->specialization_constants[index].default_value.int_bool_value = 0;
  3314. } break;
  3315. case SpvOpSpecConstant: {
  3316. SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
  3317. uint32_t element_type_id = (uint32_t)INVALID_VALUE;
  3318. uint32_t default_value = 0;
  3319. IF_READU32(result, p_parser, p_node->word_offset + 1, element_type_id);
  3320. IF_READU32(result, p_parser, p_node->word_offset + 3, default_value);
  3321. SpvReflectPrvNode* p_next_node = FindNode(p_parser, element_type_id);
  3322. if (p_next_node->op == SpvOpTypeInt) {
  3323. p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_INT;
  3324. } else if (p_next_node->op == SpvOpTypeFloat) {
  3325. p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT;
  3326. } else {
  3327. return SPV_REFLECT_RESULT_ERROR_PARSE_FAILED;
  3328. }
  3329. p_module->specialization_constants[index].default_value.int_bool_value = default_value; //bits are the same for int and float
  3330. } break;
  3331. }
  3332. p_module->specialization_constants[index].name = p_node->name;
  3333. p_module->specialization_constants[index].constant_id = p_node->decorations.specialization_constant.value;
  3334. p_module->specialization_constants[index].spirv_id = p_node->result_id;
  3335. index++;
  3336. }
  3337. return SPV_REFLECT_RESULT_SUCCESS;
  3338. }
  3339. // -- GODOT end --
  3340. static SpvReflectResult ParsePushConstantBlocks(
  3341. SpvReflectPrvParser* p_parser,
  3342. SpvReflectShaderModule* p_module)
  3343. {
  3344. for (size_t i = 0; i < p_parser->node_count; ++i) {
  3345. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  3346. if ((p_node->op != SpvOpVariable) || (p_node->storage_class != SpvStorageClassPushConstant)) {
  3347. continue;
  3348. }
  3349. p_module->push_constant_block_count += 1;
  3350. }
  3351. if (p_module->push_constant_block_count == 0) {
  3352. return SPV_REFLECT_RESULT_SUCCESS;
  3353. }
  3354. p_module->push_constant_blocks = (SpvReflectBlockVariable*)calloc(p_module->push_constant_block_count, sizeof(*p_module->push_constant_blocks));
  3355. if (IsNull(p_module->push_constant_blocks)) {
  3356. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3357. }
  3358. uint32_t push_constant_index = 0;
  3359. for (size_t i = 0; i < p_parser->node_count; ++i) {
  3360. SpvReflectPrvNode* p_node = &(p_parser->nodes[i]);
  3361. if ((p_node->op != SpvOpVariable) || (p_node->storage_class != SpvStorageClassPushConstant)) {
  3362. continue;
  3363. }
  3364. SpvReflectTypeDescription* p_type = FindType(p_module, p_node->type_id);
  3365. if (IsNull(p_node)) {
  3366. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  3367. }
  3368. // If the type is a pointer, resolve it
  3369. if (p_type->op == SpvOpTypePointer) {
  3370. // Find the type's node
  3371. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  3372. if (IsNull(p_type_node)) {
  3373. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  3374. }
  3375. // Should be the resolved type
  3376. p_type = FindType(p_module, p_type_node->type_id);
  3377. if (IsNull(p_type)) {
  3378. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  3379. }
  3380. }
  3381. SpvReflectPrvNode* p_type_node = FindNode(p_parser, p_type->id);
  3382. if (IsNull(p_type_node)) {
  3383. return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
  3384. }
  3385. SpvReflectBlockVariable* p_push_constant = &p_module->push_constant_blocks[push_constant_index];
  3386. p_push_constant->spirv_id = p_node->result_id;
  3387. p_parser->physical_pointer_count = 0;
  3388. SpvReflectResult result = ParseDescriptorBlockVariable(p_parser, p_module, p_type, p_push_constant);
  3389. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3390. return result;
  3391. }
  3392. for (uint32_t access_chain_index = 0;
  3393. access_chain_index < p_parser->access_chain_count;
  3394. ++access_chain_index) {
  3395. SpvReflectPrvAccessChain* p_access_chain =
  3396. &(p_parser->access_chains[access_chain_index]);
  3397. // Skip any access chains that aren't touching this push constant block
  3398. if (p_push_constant->spirv_id != FindBaseId(p_parser, p_access_chain)) {
  3399. continue;
  3400. }
  3401. SpvReflectBlockVariable* p_var =
  3402. (p_access_chain->base_id == p_push_constant->spirv_id)
  3403. ? p_push_constant
  3404. : GetRefBlkVar(p_parser, p_access_chain);
  3405. result = ParseDescriptorBlockVariableUsage(
  3406. p_parser, p_module, p_access_chain, 0, (SpvOp)INVALID_VALUE, p_var);
  3407. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3408. return result;
  3409. }
  3410. }
  3411. p_push_constant->name = p_node->name;
  3412. result = ParseDescriptorBlockVariableSizes(p_parser, p_module, true, false, false, p_push_constant);
  3413. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3414. return result;
  3415. }
  3416. // Get minimum offset for whole Push Constant block
  3417. // It is not valid SPIR-V to have an empty Push Constant Block
  3418. p_push_constant->offset = UINT32_MAX;
  3419. for (uint32_t k = 0; k < p_push_constant->member_count; ++k) {
  3420. const uint32_t member_offset = p_push_constant->members[k].offset;
  3421. p_push_constant->offset = Min(p_push_constant->offset, member_offset);
  3422. }
  3423. ++push_constant_index;
  3424. }
  3425. return SPV_REFLECT_RESULT_SUCCESS;
  3426. }
  3427. static int SortCompareDescriptorSet(const void* a, const void* b)
  3428. {
  3429. const SpvReflectDescriptorSet* p_elem_a = (const SpvReflectDescriptorSet*)a;
  3430. const SpvReflectDescriptorSet* p_elem_b = (const SpvReflectDescriptorSet*)b;
  3431. int value = (int)(p_elem_a->set) - (int)(p_elem_b->set);
  3432. // We should never see duplicate descriptor set numbers in a shader; if so, a tiebreaker
  3433. // would be needed here.
  3434. assert(value != 0);
  3435. return value;
  3436. }
  3437. static SpvReflectResult ParseEntrypointDescriptorSets(SpvReflectShaderModule* p_module) {
  3438. // Update the entry point's sets
  3439. for (uint32_t i = 0; i < p_module->entry_point_count; ++i) {
  3440. SpvReflectEntryPoint* p_entry = &p_module->entry_points[i];
  3441. for (uint32_t j = 0; j < p_entry->descriptor_set_count; ++j) {
  3442. SafeFree(p_entry->descriptor_sets[j].bindings);
  3443. }
  3444. SafeFree(p_entry->descriptor_sets);
  3445. p_entry->descriptor_set_count = 0;
  3446. for (uint32_t j = 0; j < p_module->descriptor_set_count; ++j) {
  3447. const SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];
  3448. for (uint32_t k = 0; k < p_set->binding_count; ++k) {
  3449. bool found = SearchSortedUint32(
  3450. p_entry->used_uniforms,
  3451. p_entry->used_uniform_count,
  3452. p_set->bindings[k]->spirv_id);
  3453. if (found) {
  3454. ++p_entry->descriptor_set_count;
  3455. break;
  3456. }
  3457. }
  3458. }
  3459. p_entry->descriptor_sets = NULL;
  3460. if (p_entry->descriptor_set_count > 0) {
  3461. p_entry->descriptor_sets = (SpvReflectDescriptorSet*)calloc(p_entry->descriptor_set_count,
  3462. sizeof(*p_entry->descriptor_sets));
  3463. if (IsNull(p_entry->descriptor_sets)) {
  3464. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3465. }
  3466. }
  3467. p_entry->descriptor_set_count = 0;
  3468. for (uint32_t j = 0; j < p_module->descriptor_set_count; ++j) {
  3469. const SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];
  3470. uint32_t count = 0;
  3471. for (uint32_t k = 0; k < p_set->binding_count; ++k) {
  3472. bool found = SearchSortedUint32(
  3473. p_entry->used_uniforms,
  3474. p_entry->used_uniform_count,
  3475. p_set->bindings[k]->spirv_id);
  3476. if (found) {
  3477. ++count;
  3478. }
  3479. }
  3480. if (count == 0) {
  3481. continue;
  3482. }
  3483. SpvReflectDescriptorSet* p_entry_set = &p_entry->descriptor_sets[
  3484. p_entry->descriptor_set_count++];
  3485. p_entry_set->set = p_set->set;
  3486. p_entry_set->bindings = (SpvReflectDescriptorBinding**)calloc(count,
  3487. sizeof(*p_entry_set->bindings));
  3488. if (IsNull(p_entry_set->bindings)) {
  3489. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3490. }
  3491. for (uint32_t k = 0; k < p_set->binding_count; ++k) {
  3492. bool found = SearchSortedUint32(
  3493. p_entry->used_uniforms,
  3494. p_entry->used_uniform_count,
  3495. p_set->bindings[k]->spirv_id);
  3496. if (found) {
  3497. p_entry_set->bindings[p_entry_set->binding_count++] = p_set->bindings[k];
  3498. }
  3499. }
  3500. }
  3501. }
  3502. return SPV_REFLECT_RESULT_SUCCESS;
  3503. }
  3504. static SpvReflectResult ParseDescriptorSets(SpvReflectShaderModule* p_module)
  3505. {
  3506. // Count the descriptors in each set
  3507. for (uint32_t i = 0; i < p_module->descriptor_binding_count; ++i) {
  3508. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[i]);
  3509. // Look for a target set using the descriptor's set number
  3510. SpvReflectDescriptorSet* p_target_set = NULL;
  3511. for (uint32_t j = 0; j < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++j) {
  3512. SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];
  3513. if (p_set->set == p_descriptor->set) {
  3514. p_target_set = p_set;
  3515. break;
  3516. }
  3517. }
  3518. // If a target set isn't found, find the first available one.
  3519. if (IsNull(p_target_set)) {
  3520. for (uint32_t j = 0; j < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++j) {
  3521. SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[j];
  3522. if (p_set->set == (uint32_t)INVALID_VALUE) {
  3523. p_target_set = p_set;
  3524. p_target_set->set = p_descriptor->set;
  3525. break;
  3526. }
  3527. }
  3528. }
  3529. if (IsNull(p_target_set)) {
  3530. return SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR;
  3531. }
  3532. p_target_set->binding_count += 1;
  3533. }
  3534. // Count the descriptor sets
  3535. for (uint32_t i = 0; i < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++i) {
  3536. const SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];
  3537. if (p_set->set != (uint32_t)INVALID_VALUE) {
  3538. p_module->descriptor_set_count += 1;
  3539. }
  3540. }
  3541. // Sort the descriptor sets based on numbers
  3542. if (p_module->descriptor_set_count > 0) {
  3543. qsort(p_module->descriptor_sets,
  3544. p_module->descriptor_set_count,
  3545. sizeof(*(p_module->descriptor_sets)),
  3546. SortCompareDescriptorSet);
  3547. }
  3548. // Build descriptor pointer array
  3549. for (uint32_t i = 0; i <p_module->descriptor_set_count; ++i) {
  3550. SpvReflectDescriptorSet* p_set = &(p_module->descriptor_sets[i]);
  3551. p_set->bindings = (SpvReflectDescriptorBinding **)calloc(p_set->binding_count, sizeof(*(p_set->bindings)));
  3552. uint32_t descriptor_index = 0;
  3553. for (uint32_t j = 0; j < p_module->descriptor_binding_count; ++j) {
  3554. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[j]);
  3555. if (p_descriptor->set == p_set->set) {
  3556. assert(descriptor_index < p_set->binding_count);
  3557. p_set->bindings[descriptor_index] = p_descriptor;
  3558. ++descriptor_index;
  3559. }
  3560. }
  3561. }
  3562. return ParseEntrypointDescriptorSets(p_module);
  3563. }
  3564. static SpvReflectResult DisambiguateStorageBufferSrvUav(SpvReflectShaderModule* p_module)
  3565. {
  3566. if (p_module->descriptor_binding_count == 0) {
  3567. return SPV_REFLECT_RESULT_SUCCESS;
  3568. }
  3569. for (uint32_t descriptor_index = 0; descriptor_index < p_module->descriptor_binding_count; ++descriptor_index) {
  3570. SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);
  3571. // Skip everything that isn't a STORAGE_BUFFER descriptor
  3572. if (p_descriptor->descriptor_type != SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
  3573. continue;
  3574. }
  3575. //
  3576. // Vulkan doesn't disambiguate between SRVs and UAVs so they
  3577. // come back as STORAGE_BUFFER. The block parsing process will
  3578. // mark a block as non-writable should any member of the block
  3579. // or its descendants are non-writable.
  3580. //
  3581. if (p_descriptor->block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) {
  3582. p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV;
  3583. }
  3584. }
  3585. return SPV_REFLECT_RESULT_SUCCESS;
  3586. }
  3587. static SpvReflectResult SynchronizeDescriptorSets(SpvReflectShaderModule* p_module)
  3588. {
  3589. // Free and reset all descriptor set numbers
  3590. for (uint32_t i = 0; i < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++i) {
  3591. SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];
  3592. SafeFree(p_set->bindings);
  3593. p_set->binding_count = 0;
  3594. p_set->set = (uint32_t)INVALID_VALUE;
  3595. }
  3596. // Set descriptor set count to zero
  3597. p_module->descriptor_set_count = 0;
  3598. SpvReflectResult result = ParseDescriptorSets(p_module);
  3599. return result;
  3600. }
  3601. static SpvReflectResult CreateShaderModule(
  3602. uint32_t flags,
  3603. size_t size,
  3604. const void* p_code,
  3605. SpvReflectShaderModule* p_module
  3606. )
  3607. {
  3608. // Initialize all module fields to zero
  3609. memset(p_module, 0, sizeof(*p_module));
  3610. // Allocate module internals
  3611. #ifdef __cplusplus
  3612. p_module->_internal = (SpvReflectShaderModule::Internal*)calloc(1, sizeof(*(p_module->_internal)));
  3613. #else
  3614. p_module->_internal = calloc(1, sizeof(*(p_module->_internal)));
  3615. #endif
  3616. if (IsNull(p_module->_internal)) {
  3617. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3618. }
  3619. // Copy flags
  3620. p_module->_internal->module_flags = flags;
  3621. // Figure out if we need to copy the SPIR-V code or not
  3622. if (flags & SPV_REFLECT_MODULE_FLAG_NO_COPY) {
  3623. // Set internal size and pointer to args passed in
  3624. p_module->_internal->spirv_size = size;
  3625. #if defined(__cplusplus)
  3626. p_module->_internal->spirv_code = const_cast<uint32_t*>(static_cast<const uint32_t*>(p_code)); // cast that const away
  3627. #else
  3628. p_module->_internal->spirv_code = (void*)p_code; // cast that const away
  3629. #endif
  3630. p_module->_internal->spirv_word_count = (uint32_t)(size / SPIRV_WORD_SIZE);
  3631. }
  3632. else {
  3633. // Allocate SPIR-V code storage
  3634. p_module->_internal->spirv_size = size;
  3635. p_module->_internal->spirv_code = (uint32_t*)calloc(1, p_module->_internal->spirv_size);
  3636. p_module->_internal->spirv_word_count = (uint32_t)(size / SPIRV_WORD_SIZE);
  3637. if (IsNull(p_module->_internal->spirv_code)) {
  3638. SafeFree(p_module->_internal);
  3639. return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
  3640. }
  3641. // Copy SPIR-V to code storage
  3642. memcpy(p_module->_internal->spirv_code, p_code, size);
  3643. }
  3644. // Initialize everything to zero
  3645. SpvReflectPrvParser parser;
  3646. memset(&parser, 0, sizeof(SpvReflectPrvParser));
  3647. // Create parser
  3648. SpvReflectResult result = CreateParser(p_module->_internal->spirv_size,
  3649. p_module->_internal->spirv_code,
  3650. &parser);
  3651. // Generator
  3652. {
  3653. const uint32_t* p_ptr = (const uint32_t*)p_module->_internal->spirv_code;
  3654. p_module->generator = (SpvReflectGenerator)((*(p_ptr + 2) & 0xFFFF0000) >> 16);
  3655. }
  3656. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3657. result = ParseNodes(&parser);
  3658. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3659. }
  3660. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3661. result = ParseStrings(&parser);
  3662. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3663. }
  3664. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3665. result = ParseSource(&parser, p_module);
  3666. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3667. }
  3668. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3669. result = ParseFunctions(&parser);
  3670. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3671. }
  3672. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3673. result = ParseMemberCounts(&parser);
  3674. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3675. }
  3676. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3677. result = ParseNames(&parser);
  3678. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3679. }
  3680. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3681. result = ParseDecorations(&parser);
  3682. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3683. }
  3684. // Start of reflection data parsing
  3685. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3686. p_module->source_language = parser.source_language;
  3687. p_module->source_language_version = parser.source_language_version;
  3688. // Zero out descriptor set data
  3689. p_module->descriptor_set_count = 0;
  3690. memset(p_module->descriptor_sets, 0, SPV_REFLECT_MAX_DESCRIPTOR_SETS * sizeof(*p_module->descriptor_sets));
  3691. // Initialize descriptor set numbers
  3692. for (uint32_t set_number = 0; set_number < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++set_number) {
  3693. p_module->descriptor_sets[set_number].set = (uint32_t)INVALID_VALUE;
  3694. }
  3695. }
  3696. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3697. result = ParseTypes(&parser, p_module);
  3698. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3699. }
  3700. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3701. result = ParseDescriptorBindings(&parser, p_module);
  3702. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3703. }
  3704. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3705. result = ParseDescriptorType(p_module);
  3706. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3707. }
  3708. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3709. result = ParseUAVCounterBindings(p_module);
  3710. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3711. }
  3712. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3713. result = ParseDescriptorBlocks(&parser, p_module);
  3714. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3715. }
  3716. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3717. result = ParsePushConstantBlocks(&parser, p_module);
  3718. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3719. }
  3720. // -- GODOT begin --
  3721. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3722. result = ParseSpecializationConstants(&parser, p_module);
  3723. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3724. }
  3725. // -- GODOT end --
  3726. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3727. result = ParseEntryPoints(&parser, p_module);
  3728. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3729. }
  3730. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3731. result = ParseCapabilities(&parser, p_module);
  3732. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3733. }
  3734. if (result == SPV_REFLECT_RESULT_SUCCESS && p_module->entry_point_count > 0) {
  3735. SpvReflectEntryPoint* p_entry = &(p_module->entry_points[0]);
  3736. p_module->entry_point_name = p_entry->name;
  3737. p_module->entry_point_id = p_entry->id;
  3738. p_module->spirv_execution_model = p_entry->spirv_execution_model;
  3739. p_module->shader_stage = p_entry->shader_stage;
  3740. p_module->input_variable_count = p_entry->input_variable_count;
  3741. p_module->input_variables = p_entry->input_variables;
  3742. p_module->output_variable_count = p_entry->output_variable_count;
  3743. p_module->output_variables = p_entry->output_variables;
  3744. p_module->interface_variable_count = p_entry->interface_variable_count;
  3745. p_module->interface_variables = p_entry->interface_variables;
  3746. }
  3747. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3748. result = DisambiguateStorageBufferSrvUav(p_module);
  3749. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3750. }
  3751. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3752. result = SynchronizeDescriptorSets(p_module);
  3753. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3754. }
  3755. if (result == SPV_REFLECT_RESULT_SUCCESS) {
  3756. result = ParseExecutionModes(&parser, p_module);
  3757. SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
  3758. }
  3759. // Destroy module if parse was not successful
  3760. if (result != SPV_REFLECT_RESULT_SUCCESS) {
  3761. spvReflectDestroyShaderModule(p_module);
  3762. }
  3763. DestroyParser(&parser);
  3764. return result;
  3765. }
  3766. SpvReflectResult spvReflectCreateShaderModule(
  3767. size_t size,
  3768. const void* p_code,
  3769. SpvReflectShaderModule* p_module
  3770. )
  3771. {
  3772. return CreateShaderModule(0, size, p_code, p_module);
  3773. }
  3774. SpvReflectResult spvReflectCreateShaderModule2(
  3775. uint32_t flags,
  3776. size_t size,
  3777. const void* p_code,
  3778. SpvReflectShaderModule* p_module
  3779. )
  3780. {
  3781. return CreateShaderModule(flags, size, p_code, p_module);
  3782. }
  3783. SpvReflectResult spvReflectGetShaderModule(
  3784. size_t size,
  3785. const void* p_code,
  3786. SpvReflectShaderModule* p_module
  3787. )
  3788. {
  3789. return spvReflectCreateShaderModule(size, p_code, p_module);
  3790. }
  3791. static void SafeFreeTypes(SpvReflectTypeDescription* p_type)
  3792. {
  3793. if (IsNull(p_type)) {
  3794. return;
  3795. }
  3796. if (IsNotNull(p_type->members)) {
  3797. for (size_t i = 0; i < p_type->member_count; ++i) {
  3798. SpvReflectTypeDescription* p_member = &p_type->members[i];
  3799. SafeFreeTypes(p_member);
  3800. }
  3801. SafeFree(p_type->members);
  3802. p_type->members = NULL;
  3803. }
  3804. }
  3805. static void SafeFreeBlockVariables(SpvReflectBlockVariable* p_block)
  3806. {
  3807. if (IsNull(p_block)) {
  3808. return;
  3809. }
  3810. if (IsNotNull(p_block->members)) {
  3811. for (size_t i = 0; i < p_block->member_count; ++i) {
  3812. SpvReflectBlockVariable* p_member = &p_block->members[i];
  3813. SafeFreeBlockVariables(p_member);
  3814. }
  3815. SafeFree(p_block->members);
  3816. p_block->members = NULL;
  3817. }
  3818. }
  3819. static void SafeFreeInterfaceVariable(SpvReflectInterfaceVariable* p_interface)
  3820. {
  3821. if (IsNull(p_interface)) {
  3822. return;
  3823. }
  3824. if (IsNotNull(p_interface->members)) {
  3825. for (size_t i = 0; i < p_interface->member_count; ++i) {
  3826. SpvReflectInterfaceVariable* p_member = &p_interface->members[i];
  3827. SafeFreeInterfaceVariable(p_member);
  3828. }
  3829. SafeFree(p_interface->members);
  3830. p_interface->members = NULL;
  3831. }
  3832. }
  3833. void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)
  3834. {
  3835. if (IsNull(p_module->_internal)) {
  3836. return;
  3837. }
  3838. SafeFree(p_module->source_source);
  3839. // Descriptor set bindings
  3840. for (size_t i = 0; i < p_module->descriptor_set_count; ++i) {
  3841. SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];
  3842. free(p_set->bindings);
  3843. }
  3844. // Descriptor binding blocks
  3845. for (size_t i = 0; i < p_module->descriptor_binding_count; ++i) {
  3846. SpvReflectDescriptorBinding* p_descriptor = &p_module->descriptor_bindings[i];
  3847. SafeFreeBlockVariables(&p_descriptor->block);
  3848. }
  3849. SafeFree(p_module->descriptor_bindings);
  3850. // Entry points
  3851. for (size_t i = 0; i < p_module->entry_point_count; ++i) {
  3852. SpvReflectEntryPoint* p_entry = &p_module->entry_points[i];
  3853. for (size_t j = 0; j < p_entry->interface_variable_count; j++) {
  3854. SafeFreeInterfaceVariable(&p_entry->interface_variables[j]);
  3855. }
  3856. for (uint32_t j = 0; j < p_entry->descriptor_set_count; ++j) {
  3857. SafeFree(p_entry->descriptor_sets[j].bindings);
  3858. }
  3859. SafeFree(p_entry->descriptor_sets);
  3860. SafeFree(p_entry->input_variables);
  3861. SafeFree(p_entry->output_variables);
  3862. SafeFree(p_entry->interface_variables);
  3863. SafeFree(p_entry->used_uniforms);
  3864. SafeFree(p_entry->used_push_constants);
  3865. SafeFree(p_entry->execution_modes);
  3866. }
  3867. SafeFree(p_module->capabilities);
  3868. SafeFree(p_module->entry_points);
  3869. // -- GODOT begin --
  3870. SafeFree(p_module->specialization_constants);
  3871. // -- GODOT end --
  3872. // Push constants
  3873. for (size_t i = 0; i < p_module->push_constant_block_count; ++i) {
  3874. SafeFreeBlockVariables(&p_module->push_constant_blocks[i]);
  3875. }
  3876. SafeFree(p_module->push_constant_blocks);
  3877. // Type infos
  3878. for (size_t i = 0; i < p_module->_internal->type_description_count; ++i) {
  3879. SpvReflectTypeDescription* p_type = &p_module->_internal->type_descriptions[i];
  3880. if (IsNotNull(p_type->members)) {
  3881. SafeFreeTypes(p_type);
  3882. }
  3883. SafeFree(p_type->members);
  3884. }
  3885. SafeFree(p_module->_internal->type_descriptions);
  3886. // Free SPIR-V code if there was a copy
  3887. if ((p_module->_internal->module_flags & SPV_REFLECT_MODULE_FLAG_NO_COPY) == 0) {
  3888. SafeFree(p_module->_internal->spirv_code);
  3889. }
  3890. // Free internal
  3891. SafeFree(p_module->_internal);
  3892. }
  3893. uint32_t spvReflectGetCodeSize(const SpvReflectShaderModule* p_module)
  3894. {
  3895. if (IsNull(p_module)) {
  3896. return 0;
  3897. }
  3898. return (uint32_t)(p_module->_internal->spirv_size);
  3899. }
  3900. const uint32_t* spvReflectGetCode(const SpvReflectShaderModule* p_module)
  3901. {
  3902. if (IsNull(p_module)) {
  3903. return NULL;
  3904. }
  3905. return p_module->_internal->spirv_code;
  3906. }
  3907. const SpvReflectEntryPoint* spvReflectGetEntryPoint(
  3908. const SpvReflectShaderModule* p_module,
  3909. const char* entry_point
  3910. ) {
  3911. if (IsNull(p_module) || IsNull(entry_point)) {
  3912. return NULL;
  3913. }
  3914. for (uint32_t i = 0; i < p_module->entry_point_count; ++i) {
  3915. if (strcmp(p_module->entry_points[i].name, entry_point) == 0) {
  3916. return &p_module->entry_points[i];
  3917. }
  3918. }
  3919. return NULL;
  3920. }
  3921. SpvReflectResult spvReflectEnumerateDescriptorBindings(
  3922. const SpvReflectShaderModule* p_module,
  3923. uint32_t* p_count,
  3924. SpvReflectDescriptorBinding** pp_bindings
  3925. )
  3926. {
  3927. if (IsNull(p_module)) {
  3928. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  3929. }
  3930. if (IsNull(p_count)) {
  3931. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  3932. }
  3933. if (IsNotNull(pp_bindings)) {
  3934. if (*p_count != p_module->descriptor_binding_count) {
  3935. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  3936. }
  3937. for (uint32_t index = 0; index < *p_count; ++index) {
  3938. SpvReflectDescriptorBinding* p_bindings = (SpvReflectDescriptorBinding*)&p_module->descriptor_bindings[index];
  3939. pp_bindings[index] = p_bindings;
  3940. }
  3941. }
  3942. else {
  3943. *p_count = p_module->descriptor_binding_count;
  3944. }
  3945. return SPV_REFLECT_RESULT_SUCCESS;
  3946. }
  3947. SpvReflectResult spvReflectEnumerateEntryPointDescriptorBindings(
  3948. const SpvReflectShaderModule* p_module,
  3949. const char* entry_point,
  3950. uint32_t* p_count,
  3951. SpvReflectDescriptorBinding** pp_bindings
  3952. )
  3953. {
  3954. if (IsNull(p_module)) {
  3955. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  3956. }
  3957. if (IsNull(p_count)) {
  3958. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  3959. }
  3960. const SpvReflectEntryPoint* p_entry =
  3961. spvReflectGetEntryPoint(p_module, entry_point);
  3962. if (IsNull(p_entry)) {
  3963. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  3964. }
  3965. uint32_t count = 0;
  3966. for (uint32_t i = 0; i < p_module->descriptor_binding_count; ++i) {
  3967. bool found = SearchSortedUint32(
  3968. p_entry->used_uniforms,
  3969. p_entry->used_uniform_count,
  3970. p_module->descriptor_bindings[i].spirv_id);
  3971. if (found) {
  3972. if (IsNotNull(pp_bindings)) {
  3973. if (count >= *p_count) {
  3974. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  3975. }
  3976. pp_bindings[count++] = (SpvReflectDescriptorBinding*)&p_module->descriptor_bindings[i];
  3977. } else {
  3978. ++count;
  3979. }
  3980. }
  3981. }
  3982. if (IsNotNull(pp_bindings)) {
  3983. if (count != *p_count) {
  3984. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  3985. }
  3986. } else {
  3987. *p_count = count;
  3988. }
  3989. return SPV_REFLECT_RESULT_SUCCESS;
  3990. }
  3991. SpvReflectResult spvReflectEnumerateDescriptorSets(
  3992. const SpvReflectShaderModule* p_module,
  3993. uint32_t* p_count,
  3994. SpvReflectDescriptorSet** pp_sets
  3995. )
  3996. {
  3997. if (IsNull(p_module)) {
  3998. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  3999. }
  4000. if (IsNull(p_count)) {
  4001. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4002. }
  4003. if (IsNotNull(pp_sets)) {
  4004. if (*p_count != p_module->descriptor_set_count) {
  4005. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4006. }
  4007. for (uint32_t index = 0; index < *p_count; ++index) {
  4008. SpvReflectDescriptorSet* p_set = (SpvReflectDescriptorSet*)&p_module->descriptor_sets[index];
  4009. pp_sets[index] = p_set;
  4010. }
  4011. }
  4012. else {
  4013. *p_count = p_module->descriptor_set_count;
  4014. }
  4015. return SPV_REFLECT_RESULT_SUCCESS;
  4016. }
  4017. SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets(
  4018. const SpvReflectShaderModule* p_module,
  4019. const char* entry_point,
  4020. uint32_t* p_count,
  4021. SpvReflectDescriptorSet** pp_sets
  4022. )
  4023. {
  4024. if (IsNull(p_module)) {
  4025. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4026. }
  4027. if (IsNull(p_count)) {
  4028. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4029. }
  4030. const SpvReflectEntryPoint* p_entry =
  4031. spvReflectGetEntryPoint(p_module, entry_point);
  4032. if (IsNull(p_entry)) {
  4033. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4034. }
  4035. if (IsNotNull(pp_sets)) {
  4036. if (*p_count != p_entry->descriptor_set_count) {
  4037. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4038. }
  4039. for (uint32_t index = 0; index < *p_count; ++index) {
  4040. SpvReflectDescriptorSet* p_set = (SpvReflectDescriptorSet*)&p_entry->descriptor_sets[index];
  4041. pp_sets[index] = p_set;
  4042. }
  4043. }
  4044. else {
  4045. *p_count = p_entry->descriptor_set_count;
  4046. }
  4047. return SPV_REFLECT_RESULT_SUCCESS;
  4048. }
  4049. SpvReflectResult spvReflectEnumerateInterfaceVariables(
  4050. const SpvReflectShaderModule* p_module,
  4051. uint32_t* p_count,
  4052. SpvReflectInterfaceVariable** pp_variables
  4053. )
  4054. {
  4055. if (IsNull(p_module)) {
  4056. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4057. }
  4058. if (IsNull(p_count)) {
  4059. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4060. }
  4061. if (IsNotNull(pp_variables)) {
  4062. if (*p_count != p_module->interface_variable_count) {
  4063. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4064. }
  4065. for (uint32_t index = 0; index < *p_count; ++index) {
  4066. SpvReflectInterfaceVariable* p_var = &p_module->interface_variables[index];
  4067. pp_variables[index] = p_var;
  4068. }
  4069. }
  4070. else {
  4071. *p_count = p_module->interface_variable_count;
  4072. }
  4073. return SPV_REFLECT_RESULT_SUCCESS;
  4074. }
  4075. SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(
  4076. const SpvReflectShaderModule* p_module,
  4077. const char* entry_point,
  4078. uint32_t* p_count,
  4079. SpvReflectInterfaceVariable** pp_variables
  4080. )
  4081. {
  4082. if (IsNull(p_module)) {
  4083. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4084. }
  4085. if (IsNull(p_count)) {
  4086. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4087. }
  4088. const SpvReflectEntryPoint* p_entry =
  4089. spvReflectGetEntryPoint(p_module, entry_point);
  4090. if (IsNull(p_entry)) {
  4091. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4092. }
  4093. if (IsNotNull(pp_variables)) {
  4094. if (*p_count != p_entry->interface_variable_count) {
  4095. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4096. }
  4097. for (uint32_t index = 0; index < *p_count; ++index) {
  4098. SpvReflectInterfaceVariable* p_var = &p_entry->interface_variables[index];
  4099. pp_variables[index] = p_var;
  4100. }
  4101. }
  4102. else {
  4103. *p_count = p_entry->interface_variable_count;
  4104. }
  4105. return SPV_REFLECT_RESULT_SUCCESS;
  4106. }
  4107. // -- GODOT begin --
  4108. SpvReflectResult spvReflectEnumerateSpecializationConstants(
  4109. const SpvReflectShaderModule* p_module,
  4110. uint32_t* p_count,
  4111. SpvReflectSpecializationConstant** pp_constants
  4112. )
  4113. {
  4114. if (IsNull(p_module)) {
  4115. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4116. }
  4117. if (IsNull(p_count)) {
  4118. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4119. }
  4120. if (IsNotNull(pp_constants)) {
  4121. if (*p_count != p_module->specialization_constant_count) {
  4122. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4123. }
  4124. for (uint32_t index = 0; index < *p_count; ++index) {
  4125. SpvReflectSpecializationConstant *p_const = &p_module->specialization_constants[index];
  4126. pp_constants[index] = p_const;
  4127. }
  4128. }
  4129. else {
  4130. *p_count = p_module->specialization_constant_count;
  4131. }
  4132. return SPV_REFLECT_RESULT_SUCCESS;
  4133. }
  4134. // -- GODOT end --
  4135. SpvReflectResult spvReflectEnumerateInputVariables(
  4136. const SpvReflectShaderModule* p_module,
  4137. uint32_t* p_count,
  4138. SpvReflectInterfaceVariable** pp_variables
  4139. )
  4140. {
  4141. if (IsNull(p_module)) {
  4142. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4143. }
  4144. if (IsNull(p_count)) {
  4145. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4146. }
  4147. if (IsNotNull(pp_variables)) {
  4148. if (*p_count != p_module->input_variable_count) {
  4149. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4150. }
  4151. for (uint32_t index = 0; index < *p_count; ++index) {
  4152. SpvReflectInterfaceVariable* p_var = p_module->input_variables[index];
  4153. pp_variables[index] = p_var;
  4154. }
  4155. }
  4156. else {
  4157. *p_count = p_module->input_variable_count;
  4158. }
  4159. return SPV_REFLECT_RESULT_SUCCESS;
  4160. }
  4161. SpvReflectResult spvReflectEnumerateEntryPointInputVariables(
  4162. const SpvReflectShaderModule* p_module,
  4163. const char* entry_point,
  4164. uint32_t* p_count,
  4165. SpvReflectInterfaceVariable** pp_variables
  4166. )
  4167. {
  4168. if (IsNull(p_module)) {
  4169. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4170. }
  4171. if (IsNull(p_count)) {
  4172. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4173. }
  4174. const SpvReflectEntryPoint* p_entry =
  4175. spvReflectGetEntryPoint(p_module, entry_point);
  4176. if (IsNull(p_entry)) {
  4177. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4178. }
  4179. if (IsNotNull(pp_variables)) {
  4180. if (*p_count != p_entry->input_variable_count) {
  4181. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4182. }
  4183. for (uint32_t index = 0; index < *p_count; ++index) {
  4184. SpvReflectInterfaceVariable* p_var = p_entry->input_variables[index];
  4185. pp_variables[index] = p_var;
  4186. }
  4187. }
  4188. else {
  4189. *p_count = p_entry->input_variable_count;
  4190. }
  4191. return SPV_REFLECT_RESULT_SUCCESS;
  4192. }
  4193. SpvReflectResult spvReflectEnumerateOutputVariables(
  4194. const SpvReflectShaderModule* p_module,
  4195. uint32_t* p_count,
  4196. SpvReflectInterfaceVariable** pp_variables
  4197. )
  4198. {
  4199. if (IsNull(p_module)) {
  4200. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4201. }
  4202. if (IsNull(p_count)) {
  4203. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4204. }
  4205. if (IsNotNull(pp_variables)) {
  4206. if (*p_count != p_module->output_variable_count) {
  4207. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4208. }
  4209. for (uint32_t index = 0; index < *p_count; ++index) {
  4210. SpvReflectInterfaceVariable* p_var = p_module->output_variables[index];
  4211. pp_variables[index] = p_var;
  4212. }
  4213. }
  4214. else {
  4215. *p_count = p_module->output_variable_count;
  4216. }
  4217. return SPV_REFLECT_RESULT_SUCCESS;
  4218. }
  4219. SpvReflectResult spvReflectEnumerateEntryPointOutputVariables(
  4220. const SpvReflectShaderModule* p_module,
  4221. const char* entry_point,
  4222. uint32_t* p_count,
  4223. SpvReflectInterfaceVariable** pp_variables
  4224. )
  4225. {
  4226. if (IsNull(p_module)) {
  4227. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4228. }
  4229. if (IsNull(p_count)) {
  4230. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4231. }
  4232. const SpvReflectEntryPoint* p_entry =
  4233. spvReflectGetEntryPoint(p_module, entry_point);
  4234. if (IsNull(p_entry)) {
  4235. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4236. }
  4237. if (IsNotNull(pp_variables)) {
  4238. if (*p_count != p_entry->output_variable_count) {
  4239. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4240. }
  4241. for (uint32_t index = 0; index < *p_count; ++index) {
  4242. SpvReflectInterfaceVariable* p_var = p_entry->output_variables[index];
  4243. pp_variables[index] = p_var;
  4244. }
  4245. }
  4246. else {
  4247. *p_count = p_entry->output_variable_count;
  4248. }
  4249. return SPV_REFLECT_RESULT_SUCCESS;
  4250. }
  4251. SpvReflectResult spvReflectEnumeratePushConstantBlocks(
  4252. const SpvReflectShaderModule* p_module,
  4253. uint32_t* p_count,
  4254. SpvReflectBlockVariable** pp_blocks
  4255. )
  4256. {
  4257. if (IsNull(p_module)) {
  4258. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4259. }
  4260. if (IsNull(p_count)) {
  4261. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4262. }
  4263. if (pp_blocks != NULL) {
  4264. if (*p_count != p_module->push_constant_block_count) {
  4265. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4266. }
  4267. for (uint32_t index = 0; index < *p_count; ++index) {
  4268. SpvReflectBlockVariable* p_push_constant_blocks = (SpvReflectBlockVariable*)&p_module->push_constant_blocks[index];
  4269. pp_blocks[index] = p_push_constant_blocks;
  4270. }
  4271. }
  4272. else {
  4273. *p_count = p_module->push_constant_block_count;
  4274. }
  4275. return SPV_REFLECT_RESULT_SUCCESS;
  4276. }
  4277. SpvReflectResult spvReflectEnumeratePushConstants(
  4278. const SpvReflectShaderModule* p_module,
  4279. uint32_t* p_count,
  4280. SpvReflectBlockVariable** pp_blocks
  4281. )
  4282. {
  4283. return spvReflectEnumeratePushConstantBlocks(p_module, p_count, pp_blocks);
  4284. }
  4285. SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks(
  4286. const SpvReflectShaderModule* p_module,
  4287. const char* entry_point,
  4288. uint32_t* p_count,
  4289. SpvReflectBlockVariable** pp_blocks
  4290. )
  4291. {
  4292. if (IsNull(p_module)) {
  4293. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4294. }
  4295. if (IsNull(p_count)) {
  4296. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4297. }
  4298. const SpvReflectEntryPoint* p_entry =
  4299. spvReflectGetEntryPoint(p_module, entry_point);
  4300. if (IsNull(p_entry)) {
  4301. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4302. }
  4303. uint32_t count = 0;
  4304. for (uint32_t i = 0; i < p_module->push_constant_block_count; ++i) {
  4305. bool found = SearchSortedUint32(p_entry->used_push_constants,
  4306. p_entry->used_push_constant_count,
  4307. p_module->push_constant_blocks[i].spirv_id);
  4308. if (found) {
  4309. if (IsNotNull(pp_blocks)) {
  4310. if (count >= *p_count) {
  4311. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4312. }
  4313. pp_blocks[count++] = (SpvReflectBlockVariable*)&p_module->push_constant_blocks[i];
  4314. } else {
  4315. ++count;
  4316. }
  4317. }
  4318. }
  4319. if (IsNotNull(pp_blocks)) {
  4320. if (count != *p_count) {
  4321. return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
  4322. }
  4323. } else {
  4324. *p_count = count;
  4325. }
  4326. return SPV_REFLECT_RESULT_SUCCESS;
  4327. }
  4328. const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding(
  4329. const SpvReflectShaderModule* p_module,
  4330. uint32_t binding_number,
  4331. uint32_t set_number,
  4332. SpvReflectResult* p_result
  4333. )
  4334. {
  4335. const SpvReflectDescriptorBinding* p_descriptor = NULL;
  4336. if (IsNotNull(p_module)) {
  4337. for (uint32_t index = 0; index < p_module->descriptor_binding_count; ++index) {
  4338. const SpvReflectDescriptorBinding* p_potential = &p_module->descriptor_bindings[index];
  4339. if ((p_potential->binding == binding_number) && (p_potential->set == set_number)) {
  4340. p_descriptor = p_potential;
  4341. break;
  4342. }
  4343. }
  4344. }
  4345. if (IsNotNull(p_result)) {
  4346. *p_result = IsNotNull(p_descriptor)
  4347. ? SPV_REFLECT_RESULT_SUCCESS
  4348. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4349. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4350. }
  4351. return p_descriptor;
  4352. }
  4353. const SpvReflectDescriptorBinding* spvReflectGetEntryPointDescriptorBinding(
  4354. const SpvReflectShaderModule* p_module,
  4355. const char* entry_point,
  4356. uint32_t binding_number,
  4357. uint32_t set_number,
  4358. SpvReflectResult* p_result
  4359. )
  4360. {
  4361. const SpvReflectEntryPoint* p_entry =
  4362. spvReflectGetEntryPoint(p_module, entry_point);
  4363. if (IsNull(p_entry)) {
  4364. if (IsNotNull(p_result)) {
  4365. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4366. }
  4367. return NULL;
  4368. }
  4369. const SpvReflectDescriptorBinding* p_descriptor = NULL;
  4370. if (IsNotNull(p_module)) {
  4371. for (uint32_t index = 0; index < p_module->descriptor_binding_count; ++index) {
  4372. const SpvReflectDescriptorBinding* p_potential = &p_module->descriptor_bindings[index];
  4373. bool found = SearchSortedUint32(
  4374. p_entry->used_uniforms,
  4375. p_entry->used_uniform_count,
  4376. p_potential->spirv_id);
  4377. if ((p_potential->binding == binding_number) && (p_potential->set == set_number) && found) {
  4378. p_descriptor = p_potential;
  4379. break;
  4380. }
  4381. }
  4382. }
  4383. if (IsNotNull(p_result)) {
  4384. *p_result = IsNotNull(p_descriptor)
  4385. ? SPV_REFLECT_RESULT_SUCCESS
  4386. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4387. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4388. }
  4389. return p_descriptor;
  4390. }
  4391. const SpvReflectDescriptorSet* spvReflectGetDescriptorSet(
  4392. const SpvReflectShaderModule* p_module,
  4393. uint32_t set_number,
  4394. SpvReflectResult* p_result
  4395. )
  4396. {
  4397. const SpvReflectDescriptorSet* p_set = NULL;
  4398. if (IsNotNull(p_module)) {
  4399. for (uint32_t index = 0; index < p_module->descriptor_set_count; ++index) {
  4400. const SpvReflectDescriptorSet* p_potential = &p_module->descriptor_sets[index];
  4401. if (p_potential->set == set_number) {
  4402. p_set = p_potential;
  4403. }
  4404. }
  4405. }
  4406. if (IsNotNull(p_result)) {
  4407. *p_result = IsNotNull(p_set)
  4408. ? SPV_REFLECT_RESULT_SUCCESS
  4409. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4410. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4411. }
  4412. return p_set;
  4413. }
  4414. const SpvReflectDescriptorSet* spvReflectGetEntryPointDescriptorSet(
  4415. const SpvReflectShaderModule* p_module,
  4416. const char* entry_point,
  4417. uint32_t set_number,
  4418. SpvReflectResult* p_result)
  4419. {
  4420. const SpvReflectDescriptorSet* p_set = NULL;
  4421. if (IsNotNull(p_module)) {
  4422. const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);
  4423. if (IsNull(p_entry)) {
  4424. if (IsNotNull(p_result)) {
  4425. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4426. }
  4427. return NULL;
  4428. }
  4429. for (uint32_t index = 0; index < p_entry->descriptor_set_count; ++index) {
  4430. const SpvReflectDescriptorSet* p_potential = &p_entry->descriptor_sets[index];
  4431. if (p_potential->set == set_number) {
  4432. p_set = p_potential;
  4433. }
  4434. }
  4435. }
  4436. if (IsNotNull(p_result)) {
  4437. *p_result = IsNotNull(p_set)
  4438. ? SPV_REFLECT_RESULT_SUCCESS
  4439. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4440. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4441. }
  4442. return p_set;
  4443. }
  4444. const SpvReflectInterfaceVariable* spvReflectGetInputVariableByLocation(
  4445. const SpvReflectShaderModule* p_module,
  4446. uint32_t location,
  4447. SpvReflectResult* p_result
  4448. )
  4449. {
  4450. if (location == INVALID_VALUE) {
  4451. if (IsNotNull(p_result)) {
  4452. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4453. }
  4454. return NULL;
  4455. }
  4456. const SpvReflectInterfaceVariable* p_var = NULL;
  4457. if (IsNotNull(p_module)) {
  4458. for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {
  4459. const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index];
  4460. if (p_potential->location == location) {
  4461. p_var = p_potential;
  4462. }
  4463. }
  4464. }
  4465. if (IsNotNull(p_result)) {
  4466. *p_result = IsNotNull(p_var)
  4467. ? SPV_REFLECT_RESULT_SUCCESS
  4468. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4469. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4470. }
  4471. return p_var;
  4472. }
  4473. const SpvReflectInterfaceVariable* spvReflectGetInputVariable(
  4474. const SpvReflectShaderModule* p_module,
  4475. uint32_t location,
  4476. SpvReflectResult* p_result
  4477. )
  4478. {
  4479. return spvReflectGetInputVariableByLocation(p_module, location, p_result);
  4480. }
  4481. const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocation(
  4482. const SpvReflectShaderModule* p_module,
  4483. const char* entry_point,
  4484. uint32_t location,
  4485. SpvReflectResult* p_result
  4486. )
  4487. {
  4488. if (location == INVALID_VALUE) {
  4489. if (IsNotNull(p_result)) {
  4490. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4491. }
  4492. return NULL;
  4493. }
  4494. const SpvReflectInterfaceVariable* p_var = NULL;
  4495. if (IsNotNull(p_module)) {
  4496. const SpvReflectEntryPoint* p_entry =
  4497. spvReflectGetEntryPoint(p_module, entry_point);
  4498. if (IsNull(p_entry)) {
  4499. if (IsNotNull(p_result)) {
  4500. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4501. }
  4502. return NULL;
  4503. }
  4504. for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) {
  4505. const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index];
  4506. if (p_potential->location == location) {
  4507. p_var = p_potential;
  4508. }
  4509. }
  4510. }
  4511. if (IsNotNull(p_result)) {
  4512. *p_result = IsNotNull(p_var)
  4513. ? SPV_REFLECT_RESULT_SUCCESS
  4514. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4515. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4516. }
  4517. return p_var;
  4518. }
  4519. const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic(
  4520. const SpvReflectShaderModule* p_module,
  4521. const char* semantic,
  4522. SpvReflectResult* p_result
  4523. )
  4524. {
  4525. if (IsNull(semantic)) {
  4526. if (IsNotNull(p_result)) {
  4527. *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4528. }
  4529. return NULL;
  4530. }
  4531. if (semantic[0] == '\0') {
  4532. if (IsNotNull(p_result)) {
  4533. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4534. }
  4535. return NULL;
  4536. }
  4537. const SpvReflectInterfaceVariable* p_var = NULL;
  4538. if (IsNotNull(p_module)) {
  4539. for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {
  4540. const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index];
  4541. if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
  4542. p_var = p_potential;
  4543. }
  4544. }
  4545. }
  4546. if (IsNotNull(p_result)) {
  4547. *p_result = IsNotNull(p_var)
  4548. ? SPV_REFLECT_RESULT_SUCCESS
  4549. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4550. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4551. }
  4552. return p_var;
  4553. }
  4554. const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemantic(
  4555. const SpvReflectShaderModule* p_module,
  4556. const char* entry_point,
  4557. const char* semantic,
  4558. SpvReflectResult* p_result
  4559. )
  4560. {
  4561. if (IsNull(semantic)) {
  4562. if (IsNotNull(p_result)) {
  4563. *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4564. }
  4565. return NULL;
  4566. }
  4567. if (semantic[0] == '\0') {
  4568. if (IsNotNull(p_result)) {
  4569. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4570. }
  4571. return NULL;
  4572. }
  4573. const SpvReflectInterfaceVariable* p_var = NULL;
  4574. if (IsNotNull(p_module)) {
  4575. const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);
  4576. if (IsNull(p_entry)) {
  4577. if (IsNotNull(p_result)) {
  4578. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4579. }
  4580. return NULL;
  4581. }
  4582. for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) {
  4583. const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index];
  4584. if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
  4585. p_var = p_potential;
  4586. }
  4587. }
  4588. }
  4589. if (IsNotNull(p_result)) {
  4590. *p_result = IsNotNull(p_var)
  4591. ? SPV_REFLECT_RESULT_SUCCESS
  4592. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4593. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4594. }
  4595. return p_var;
  4596. }
  4597. const SpvReflectInterfaceVariable* spvReflectGetOutputVariableByLocation(
  4598. const SpvReflectShaderModule* p_module,
  4599. uint32_t location,
  4600. SpvReflectResult* p_result
  4601. )
  4602. {
  4603. if (location == INVALID_VALUE) {
  4604. if (IsNotNull(p_result)) {
  4605. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4606. }
  4607. return NULL;
  4608. }
  4609. const SpvReflectInterfaceVariable* p_var = NULL;
  4610. if (IsNotNull(p_module)) {
  4611. for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {
  4612. const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index];
  4613. if (p_potential->location == location) {
  4614. p_var = p_potential;
  4615. }
  4616. }
  4617. }
  4618. if (IsNotNull(p_result)) {
  4619. *p_result = IsNotNull(p_var)
  4620. ? SPV_REFLECT_RESULT_SUCCESS
  4621. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4622. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4623. }
  4624. return p_var;
  4625. }
  4626. const SpvReflectInterfaceVariable* spvReflectGetOutputVariable(
  4627. const SpvReflectShaderModule* p_module,
  4628. uint32_t location,
  4629. SpvReflectResult* p_result
  4630. )
  4631. {
  4632. return spvReflectGetOutputVariableByLocation(p_module, location, p_result);
  4633. }
  4634. const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocation(
  4635. const SpvReflectShaderModule* p_module,
  4636. const char* entry_point,
  4637. uint32_t location,
  4638. SpvReflectResult* p_result
  4639. )
  4640. {
  4641. if (location == INVALID_VALUE) {
  4642. if (IsNotNull(p_result)) {
  4643. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4644. }
  4645. return NULL;
  4646. }
  4647. const SpvReflectInterfaceVariable* p_var = NULL;
  4648. if (IsNotNull(p_module)) {
  4649. const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);
  4650. if (IsNull(p_entry)) {
  4651. if (IsNotNull(p_result)) {
  4652. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4653. }
  4654. return NULL;
  4655. }
  4656. for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) {
  4657. const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index];
  4658. if (p_potential->location == location) {
  4659. p_var = p_potential;
  4660. }
  4661. }
  4662. }
  4663. if (IsNotNull(p_result)) {
  4664. *p_result = IsNotNull(p_var)
  4665. ? SPV_REFLECT_RESULT_SUCCESS
  4666. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4667. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4668. }
  4669. return p_var;
  4670. }
  4671. const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic(
  4672. const SpvReflectShaderModule* p_module,
  4673. const char* semantic,
  4674. SpvReflectResult* p_result
  4675. )
  4676. {
  4677. if (IsNull(semantic)) {
  4678. if (IsNotNull(p_result)) {
  4679. *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4680. }
  4681. return NULL;
  4682. }
  4683. if (semantic[0] == '\0') {
  4684. if (IsNotNull(p_result)) {
  4685. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4686. }
  4687. return NULL;
  4688. }
  4689. const SpvReflectInterfaceVariable* p_var = NULL;
  4690. if (IsNotNull(p_module)) {
  4691. for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {
  4692. const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index];
  4693. if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
  4694. p_var = p_potential;
  4695. }
  4696. }
  4697. }
  4698. if (IsNotNull(p_result)) {
  4699. *p_result = IsNotNull(p_var)
  4700. ? SPV_REFLECT_RESULT_SUCCESS
  4701. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4702. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4703. }
  4704. return p_var;
  4705. }
  4706. const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemantic(
  4707. const SpvReflectShaderModule* p_module,
  4708. const char* entry_point,
  4709. const char* semantic,
  4710. SpvReflectResult* p_result)
  4711. {
  4712. if (IsNull(semantic)) {
  4713. if (IsNotNull(p_result)) {
  4714. *p_result = SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4715. }
  4716. return NULL;
  4717. }
  4718. if (semantic[0] == '\0') {
  4719. if (IsNotNull(p_result)) {
  4720. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4721. }
  4722. return NULL;
  4723. }
  4724. const SpvReflectInterfaceVariable* p_var = NULL;
  4725. if (IsNotNull(p_module)) {
  4726. const SpvReflectEntryPoint* p_entry = spvReflectGetEntryPoint(p_module, entry_point);
  4727. if (IsNull(p_entry)) {
  4728. if (IsNotNull(p_result)) {
  4729. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4730. }
  4731. return NULL;
  4732. }
  4733. for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) {
  4734. const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index];
  4735. if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
  4736. p_var = p_potential;
  4737. }
  4738. }
  4739. }
  4740. if (IsNotNull(p_result)) {
  4741. *p_result = IsNotNull(p_var)
  4742. ? SPV_REFLECT_RESULT_SUCCESS
  4743. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4744. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4745. }
  4746. return p_var;
  4747. }
  4748. const SpvReflectBlockVariable* spvReflectGetPushConstantBlock(
  4749. const SpvReflectShaderModule* p_module,
  4750. uint32_t index,
  4751. SpvReflectResult* p_result
  4752. )
  4753. {
  4754. const SpvReflectBlockVariable* p_push_constant = NULL;
  4755. if (IsNotNull(p_module)) {
  4756. if (index < p_module->push_constant_block_count) {
  4757. p_push_constant = &p_module->push_constant_blocks[index];
  4758. }
  4759. }
  4760. if (IsNotNull(p_result)) {
  4761. *p_result = IsNotNull(p_push_constant)
  4762. ? SPV_REFLECT_RESULT_SUCCESS
  4763. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4764. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4765. }
  4766. return p_push_constant;
  4767. }
  4768. const SpvReflectBlockVariable* spvReflectGetPushConstant(
  4769. const SpvReflectShaderModule* p_module,
  4770. uint32_t index,
  4771. SpvReflectResult* p_result
  4772. )
  4773. {
  4774. return spvReflectGetPushConstantBlock(p_module, index, p_result);
  4775. }
  4776. const SpvReflectBlockVariable* spvReflectGetEntryPointPushConstantBlock(
  4777. const SpvReflectShaderModule* p_module,
  4778. const char* entry_point,
  4779. SpvReflectResult* p_result)
  4780. {
  4781. const SpvReflectBlockVariable* p_push_constant = NULL;
  4782. if (IsNotNull(p_module)) {
  4783. const SpvReflectEntryPoint* p_entry =
  4784. spvReflectGetEntryPoint(p_module, entry_point);
  4785. if (IsNull(p_entry)) {
  4786. if (IsNotNull(p_result)) {
  4787. *p_result = SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4788. }
  4789. return NULL;
  4790. }
  4791. for (uint32_t i = 0; i < p_module->push_constant_block_count; ++i) {
  4792. bool found = SearchSortedUint32(
  4793. p_entry->used_push_constants,
  4794. p_entry->used_push_constant_count,
  4795. p_module->push_constant_blocks[i].spirv_id);
  4796. if (found) {
  4797. p_push_constant = &p_module->push_constant_blocks[i];
  4798. break;
  4799. }
  4800. }
  4801. }
  4802. if (IsNotNull(p_result)) {
  4803. *p_result = IsNotNull(p_push_constant)
  4804. ? SPV_REFLECT_RESULT_SUCCESS
  4805. : (IsNull(p_module) ? SPV_REFLECT_RESULT_ERROR_NULL_POINTER
  4806. : SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND);
  4807. }
  4808. return p_push_constant;
  4809. }
  4810. SpvReflectResult spvReflectChangeDescriptorBindingNumbers(
  4811. SpvReflectShaderModule* p_module,
  4812. const SpvReflectDescriptorBinding* p_binding,
  4813. uint32_t new_binding_number,
  4814. uint32_t new_set_binding
  4815. )
  4816. {
  4817. if (IsNull(p_module)) {
  4818. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4819. }
  4820. if (IsNull(p_binding)) {
  4821. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4822. }
  4823. SpvReflectDescriptorBinding* p_target_descriptor = NULL;
  4824. for (uint32_t index = 0; index < p_module->descriptor_binding_count; ++index) {
  4825. if(&p_module->descriptor_bindings[index] == p_binding) {
  4826. p_target_descriptor = &p_module->descriptor_bindings[index];
  4827. break;
  4828. }
  4829. }
  4830. if (IsNotNull(p_target_descriptor)) {
  4831. if (p_target_descriptor->word_offset.binding > (p_module->_internal->spirv_word_count - 1)) {
  4832. return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;
  4833. }
  4834. // Binding number
  4835. if (new_binding_number != (uint32_t)SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE) {
  4836. uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.binding;
  4837. *p_code = new_binding_number;
  4838. p_target_descriptor->binding = new_binding_number;
  4839. }
  4840. // Set number
  4841. if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
  4842. uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.set;
  4843. *p_code = new_set_binding;
  4844. p_target_descriptor->set = new_set_binding;
  4845. }
  4846. }
  4847. SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
  4848. if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
  4849. result = SynchronizeDescriptorSets(p_module);
  4850. }
  4851. return result;
  4852. }
  4853. SpvReflectResult spvReflectChangeDescriptorBindingNumber(
  4854. SpvReflectShaderModule* p_module,
  4855. const SpvReflectDescriptorBinding* p_descriptor_binding,
  4856. uint32_t new_binding_number,
  4857. uint32_t optional_new_set_number
  4858. )
  4859. {
  4860. return spvReflectChangeDescriptorBindingNumbers(
  4861. p_module,p_descriptor_binding,
  4862. new_binding_number,
  4863. optional_new_set_number);
  4864. }
  4865. SpvReflectResult spvReflectChangeDescriptorSetNumber(
  4866. SpvReflectShaderModule* p_module,
  4867. const SpvReflectDescriptorSet* p_set,
  4868. uint32_t new_set_number
  4869. )
  4870. {
  4871. if (IsNull(p_module)) {
  4872. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4873. }
  4874. if (IsNull(p_set)) {
  4875. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4876. }
  4877. SpvReflectDescriptorSet* p_target_set = NULL;
  4878. for (uint32_t index = 0; index < SPV_REFLECT_MAX_DESCRIPTOR_SETS; ++index) {
  4879. // The descriptor sets for specific entry points might not be in this set,
  4880. // so just match on set index.
  4881. if (p_module->descriptor_sets[index].set == p_set->set) {
  4882. p_target_set = (SpvReflectDescriptorSet*)p_set;
  4883. break;
  4884. }
  4885. }
  4886. SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
  4887. if (IsNotNull(p_target_set) && new_set_number != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
  4888. for (uint32_t index = 0; index < p_target_set->binding_count; ++index) {
  4889. SpvReflectDescriptorBinding* p_descriptor = p_target_set->bindings[index];
  4890. if (p_descriptor->word_offset.set > (p_module->_internal->spirv_word_count - 1)) {
  4891. return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;
  4892. }
  4893. uint32_t* p_code = p_module->_internal->spirv_code + p_descriptor->word_offset.set;
  4894. *p_code = new_set_number;
  4895. p_descriptor->set = new_set_number;
  4896. }
  4897. result = SynchronizeDescriptorSets(p_module);
  4898. }
  4899. return result;
  4900. }
  4901. static SpvReflectResult ChangeVariableLocation(
  4902. SpvReflectShaderModule* p_module,
  4903. SpvReflectInterfaceVariable* p_variable,
  4904. uint32_t new_location
  4905. )
  4906. {
  4907. if (p_variable->word_offset.location > (p_module->_internal->spirv_word_count - 1)) {
  4908. return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;
  4909. }
  4910. uint32_t* p_code = p_module->_internal->spirv_code + p_variable->word_offset.location;
  4911. *p_code = new_location;
  4912. p_variable->location = new_location;
  4913. return SPV_REFLECT_RESULT_SUCCESS;
  4914. }
  4915. SpvReflectResult spvReflectChangeInputVariableLocation(
  4916. SpvReflectShaderModule* p_module,
  4917. const SpvReflectInterfaceVariable* p_input_variable,
  4918. uint32_t new_location
  4919. )
  4920. {
  4921. if (IsNull(p_module)) {
  4922. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4923. }
  4924. if (IsNull(p_input_variable)) {
  4925. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4926. }
  4927. for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {
  4928. if(p_module->input_variables[index] == p_input_variable) {
  4929. return ChangeVariableLocation(p_module, p_module->input_variables[index], new_location);
  4930. }
  4931. }
  4932. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4933. }
  4934. SpvReflectResult spvReflectChangeOutputVariableLocation(
  4935. SpvReflectShaderModule* p_module,
  4936. const SpvReflectInterfaceVariable* p_output_variable,
  4937. uint32_t new_location
  4938. )
  4939. {
  4940. if (IsNull(p_module)) {
  4941. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4942. }
  4943. if (IsNull(p_output_variable)) {
  4944. return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
  4945. }
  4946. for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {
  4947. if(p_module->output_variables[index] == p_output_variable) {
  4948. return ChangeVariableLocation(p_module, p_module->output_variables[index], new_location);
  4949. }
  4950. }
  4951. return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
  4952. }
  4953. const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang)
  4954. {
  4955. switch (source_lang) {
  4956. case SpvSourceLanguageESSL : return "ESSL";
  4957. case SpvSourceLanguageGLSL : return "GLSL";
  4958. case SpvSourceLanguageOpenCL_C : return "OpenCL_C";
  4959. case SpvSourceLanguageOpenCL_CPP : return "OpenCL_CPP";
  4960. case SpvSourceLanguageHLSL : return "HLSL";
  4961. case SpvSourceLanguageCPP_for_OpenCL : return "CPP_for_OpenCL";
  4962. case SpvSourceLanguageSYCL : return "SYCL";
  4963. case SpvSourceLanguageHERO_C : return "Hero C";
  4964. case SpvSourceLanguageNZSL : return "NZSL";
  4965. default:
  4966. break;
  4967. }
  4968. // The source language is SpvSourceLanguageUnknown, SpvSourceLanguageMax, or
  4969. // some other value that does not correspond to a knonwn language.
  4970. return "Unknown";
  4971. }
  4972. const char* spvReflectBlockVariableTypeName(
  4973. const SpvReflectBlockVariable* p_var
  4974. )
  4975. {
  4976. if (p_var == NULL) {
  4977. return NULL;
  4978. }
  4979. return p_var->type_description->type_name;
  4980. }