EffectLoad.cpp 167 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002
  1. //--------------------------------------------------------------------------------------
  2. // File: EffectLoad.cpp
  3. //
  4. // Direct3D Effects file loading code
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //
  11. // Copyright (c) Microsoft Corporation. All rights reserved.
  12. //
  13. // http://go.microsoft.com/fwlink/p/?LinkId=271568
  14. //--------------------------------------------------------------------------------------
  15. #include "pchfx.h"
  16. #include "EffectStates11.h"
  17. #define PRIVATENEW new(m_BulkHeap)
  18. namespace D3DX11Effects
  19. {
  20. static LPCSTR g_szEffectLoadArea = "D3D11EffectLoader";
  21. SRasterizerBlock g_NullRasterizer;
  22. SDepthStencilBlock g_NullDepthStencil;
  23. SBlendBlock g_NullBlend;
  24. SShaderResource g_NullTexture;
  25. SInterface g_NullInterface;
  26. SUnorderedAccessView g_NullUnorderedAccessView;
  27. SRenderTargetView g_NullRenderTargetView;
  28. SDepthStencilView g_NullDepthStencilView;
  29. // these VTables must be setup in the proper order:
  30. // 1) SetShader
  31. // 2) SetConstantBuffers
  32. // 3) SetSamplers
  33. // 4) SetShaderResources
  34. // 5) CreateShader
  35. SD3DShaderVTable g_vtPS = {
  36. (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::PSSetShader,
  37. &ID3D11DeviceContext::PSSetConstantBuffers,
  38. &ID3D11DeviceContext::PSSetSamplers,
  39. &ID3D11DeviceContext::PSSetShaderResources,
  40. (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreatePixelShader
  41. };
  42. SD3DShaderVTable g_vtVS = {
  43. (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::VSSetShader,
  44. &ID3D11DeviceContext::VSSetConstantBuffers,
  45. &ID3D11DeviceContext::VSSetSamplers,
  46. &ID3D11DeviceContext::VSSetShaderResources,
  47. (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateVertexShader
  48. };
  49. SD3DShaderVTable g_vtGS = {
  50. (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::GSSetShader,
  51. &ID3D11DeviceContext::GSSetConstantBuffers,
  52. &ID3D11DeviceContext::GSSetSamplers,
  53. &ID3D11DeviceContext::GSSetShaderResources,
  54. (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateGeometryShader
  55. };
  56. SD3DShaderVTable g_vtHS = {
  57. (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::HSSetShader,
  58. &ID3D11DeviceContext::HSSetConstantBuffers,
  59. &ID3D11DeviceContext::HSSetSamplers,
  60. &ID3D11DeviceContext::HSSetShaderResources,
  61. (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateHullShader
  62. };
  63. SD3DShaderVTable g_vtDS = {
  64. (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::DSSetShader,
  65. &ID3D11DeviceContext::DSSetConstantBuffers,
  66. &ID3D11DeviceContext::DSSetSamplers,
  67. &ID3D11DeviceContext::DSSetShaderResources,
  68. (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateDomainShader
  69. };
  70. SD3DShaderVTable g_vtCS = {
  71. (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::CSSetShader,
  72. &ID3D11DeviceContext::CSSetConstantBuffers,
  73. &ID3D11DeviceContext::CSSetSamplers,
  74. &ID3D11DeviceContext::CSSetShaderResources,
  75. (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateComputeShader
  76. };
  77. SShaderBlock g_NullVS(&g_vtVS);
  78. SShaderBlock g_NullGS(&g_vtGS);
  79. SShaderBlock g_NullPS(&g_vtPS);
  80. SShaderBlock g_NullHS(&g_vtHS);
  81. SShaderBlock g_NullDS(&g_vtDS);
  82. SShaderBlock g_NullCS(&g_vtCS);
  83. D3D_SHADER_VARIABLE_TYPE GetSimpleParameterTypeFromObjectType(EObjectType ObjectType)
  84. {
  85. switch (ObjectType)
  86. {
  87. case EOT_String:
  88. return D3D_SVT_STRING;
  89. case EOT_Blend:
  90. return D3D_SVT_BLEND;
  91. case EOT_DepthStencil:
  92. return D3D_SVT_DEPTHSTENCIL;
  93. case EOT_Rasterizer:
  94. return D3D_SVT_RASTERIZER;
  95. case EOT_PixelShader:
  96. case EOT_PixelShader5:
  97. return D3D_SVT_PIXELSHADER;
  98. case EOT_VertexShader:
  99. case EOT_VertexShader5:
  100. return D3D_SVT_VERTEXSHADER;
  101. case EOT_GeometryShader:
  102. case EOT_GeometryShaderSO:
  103. case EOT_GeometryShader5:
  104. return D3D_SVT_GEOMETRYSHADER;
  105. case EOT_HullShader5:
  106. return D3D_SVT_HULLSHADER;
  107. case EOT_DomainShader5:
  108. return D3D_SVT_DOMAINSHADER;
  109. case EOT_ComputeShader5:
  110. return D3D_SVT_COMPUTESHADER;
  111. case EOT_RenderTargetView:
  112. return D3D_SVT_RENDERTARGETVIEW;
  113. case EOT_DepthStencilView:
  114. return D3D_SVT_DEPTHSTENCILVIEW;
  115. case EOT_Texture:
  116. case EOT_Texture1D:
  117. case EOT_Texture1DArray:
  118. case EOT_Texture2D:
  119. case EOT_Texture2DArray:
  120. case EOT_Texture2DMS:
  121. case EOT_Texture2DMSArray:
  122. case EOT_Texture3D:
  123. case EOT_TextureCube:
  124. case EOT_TextureCubeArray:
  125. return D3D_SVT_TEXTURE;
  126. case EOT_Buffer:
  127. return D3D_SVT_BUFFER;
  128. case EOT_Sampler:
  129. return D3D_SVT_SAMPLER;
  130. case EOT_ByteAddressBuffer:
  131. return D3D_SVT_BYTEADDRESS_BUFFER;
  132. case EOT_StructuredBuffer:
  133. return D3D_SVT_STRUCTURED_BUFFER;
  134. case EOT_RWTexture1D:
  135. return D3D_SVT_RWTEXTURE1D;
  136. case EOT_RWTexture1DArray:
  137. return D3D_SVT_RWTEXTURE1DARRAY;
  138. case EOT_RWTexture2D:
  139. return D3D_SVT_RWTEXTURE2D;
  140. case EOT_RWTexture2DArray:
  141. return D3D_SVT_RWTEXTURE2DARRAY;
  142. case EOT_RWTexture3D:
  143. return D3D_SVT_RWTEXTURE3D;
  144. case EOT_RWBuffer:
  145. return D3D_SVT_RWBUFFER;
  146. case EOT_RWByteAddressBuffer:
  147. return D3D_SVT_RWBYTEADDRESS_BUFFER;
  148. case EOT_RWStructuredBuffer:
  149. case EOT_RWStructuredBufferAlloc:
  150. case EOT_RWStructuredBufferConsume:
  151. return D3D_SVT_RWSTRUCTURED_BUFFER;
  152. case EOT_AppendStructuredBuffer:
  153. return D3D_SVT_APPEND_STRUCTURED_BUFFER;
  154. case EOT_ConsumeStructuredBuffer:
  155. return D3D_SVT_CONSUME_STRUCTURED_BUFFER;
  156. default:
  157. assert(0);
  158. }
  159. return D3D_SVT_VOID;
  160. }
  161. inline HRESULT VerifyPointer(uint32_t oBase, uint32_t dwSize, uint32_t dwMaxSize)
  162. {
  163. uint32_t dwAdd = oBase + dwSize;
  164. if (dwAdd < oBase || dwAdd > dwMaxSize)
  165. return E_FAIL;
  166. return S_OK;
  167. }
  168. //////////////////////////////////////////////////////////////////////////
  169. // EffectHeap
  170. // A simple class which assists in adding data to a block of memory
  171. //////////////////////////////////////////////////////////////////////////
  172. CEffectHeap::CEffectHeap() : m_pData(nullptr), m_dwSize(0), m_dwBufferSize(0)
  173. {
  174. }
  175. CEffectHeap::~CEffectHeap()
  176. {
  177. SAFE_DELETE_ARRAY(m_pData);
  178. }
  179. uint32_t CEffectHeap::GetSize()
  180. {
  181. return m_dwSize;
  182. }
  183. HRESULT CEffectHeap::ReserveMemory(uint32_t dwSize)
  184. {
  185. HRESULT hr = S_OK;
  186. assert(!m_pData);
  187. assert(dwSize == AlignToPowerOf2(dwSize, c_DataAlignment));
  188. m_dwBufferSize = dwSize;
  189. VN( m_pData = new uint8_t[m_dwBufferSize] );
  190. // make sure that we have machine word alignment
  191. assert(m_pData == AlignToPowerOf2(m_pData, c_DataAlignment));
  192. lExit:
  193. return hr;
  194. }
  195. _Use_decl_annotations_
  196. HRESULT CEffectHeap::AddString(const char *pString, char **ppPointer)
  197. {
  198. size_t size = strlen(pString) + 1;
  199. assert( size <= 0xffffffff );
  200. return AddData(pString, (uint32_t)size, (void**) ppPointer);
  201. }
  202. // This data is forcibly aligned, so make sure you account for that in calculating heap size
  203. template <bool bCopyData>
  204. HRESULT CEffectHeap::AddDataInternal(_In_reads_bytes_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer)
  205. {
  206. CCheckedDword chkFinalSize( m_dwSize );
  207. uint32_t finalSize;
  208. HRESULT hr = S_OK;
  209. chkFinalSize += dwSize;
  210. chkFinalSize += c_DataAlignment; // account for alignment
  211. VHD( chkFinalSize.GetValue(&finalSize), "Overflow while adding data to Effect heap." );
  212. // align original value
  213. finalSize = AlignToPowerOf2(finalSize - c_DataAlignment, c_DataAlignment);
  214. VBD( finalSize <= m_dwBufferSize, "Overflow adding data to Effect heap." );
  215. *ppPointer = m_pData + m_dwSize;
  216. assert(*ppPointer == AlignToPowerOf2(*ppPointer, c_DataAlignment));
  217. if( bCopyData )
  218. {
  219. memcpy(*ppPointer, pData, dwSize);
  220. }
  221. m_dwSize = finalSize;
  222. lExit:
  223. if (FAILED(hr))
  224. *ppPointer = nullptr;
  225. return hr;
  226. }
  227. _Use_decl_annotations_
  228. HRESULT CEffectHeap::AddData(const void *pData, uint32_t dwSize, void **ppPointer)
  229. {
  230. return AddDataInternal<true>( pData, dwSize, ppPointer );
  231. }
  232. // Moves a string from the general heap to the private heap and modifies the pointer to
  233. // point to the new memory block.
  234. // The general heap is freed as a whole, so we don't worry about leaking the given string pointer.
  235. // This data is forcibly aligned, so make sure you account for that in calculating heap size
  236. _Use_decl_annotations_
  237. HRESULT CEffectHeap::MoveString(char **ppString)
  238. {
  239. HRESULT hr;
  240. char *pNewPointer;
  241. if (*ppString == nullptr)
  242. return S_OK;
  243. hr = AddString(*ppString, &pNewPointer);
  244. if ( SUCCEEDED(hr) )
  245. *ppString = pNewPointer;
  246. return hr;
  247. }
  248. // Allocates space but does not move data
  249. // The general heap is freed as a whole, so we don't worry about leaking the given string pointer.
  250. // This data is forcibly aligned, so make sure you account for that in calculating heap size
  251. _Use_decl_annotations_
  252. HRESULT CEffectHeap::MoveEmptyDataBlock(void **ppData, uint32_t size)
  253. {
  254. HRESULT hr;
  255. void *pNewPointer;
  256. hr = AddDataInternal<false>(*ppData, size, &pNewPointer);
  257. if (SUCCEEDED(hr))
  258. {
  259. *ppData = pNewPointer;
  260. if (size == 0)
  261. {
  262. // To help catch bugs, set zero-byte blocks to null. There's no real reason to do this
  263. *ppData = nullptr;
  264. }
  265. }
  266. return hr;
  267. }
  268. // Moves an array of SInterfaceParameters from the general heap to the private heap and modifies the pointer to
  269. // point to the new memory block.
  270. // The general heap is freed as a whole, so we don't worry about leaking the given string pointer.
  271. // This data is forcibly aligned, so make sure you account for that in calculating heap size
  272. _Use_decl_annotations_
  273. HRESULT CEffectHeap::MoveInterfaceParameters(uint32_t InterfaceCount, SShaderBlock::SInterfaceParameter **ppInterfaces)
  274. {
  275. HRESULT hr;
  276. SShaderBlock::SInterfaceParameter *pNewPointer;
  277. if (*ppInterfaces == nullptr)
  278. return S_OK;
  279. VBD( InterfaceCount <= D3D11_SHADER_MAX_INTERFACES, "Internal loading error: InterfaceCount > D3D11_SHADER_MAX_INTERFACES." );
  280. VH( AddData(*ppInterfaces, InterfaceCount * sizeof(SShaderBlock::SInterfaceParameter), (void**)&pNewPointer) );
  281. for( size_t i=0; i < InterfaceCount; i++ )
  282. {
  283. VH( MoveString( &pNewPointer[i].pName ) );
  284. }
  285. *ppInterfaces = pNewPointer;
  286. lExit:
  287. return hr;
  288. }
  289. // Moves data from the general heap to the private heap and modifies the pointer to
  290. // point to the new memory block
  291. // The general heap is freed as a whole, so we don't worry about leaking the given pointer.
  292. // This data is forcibly aligned, so make sure you account for that in calculating heap size
  293. _Use_decl_annotations_
  294. HRESULT CEffectHeap::MoveData(void **ppData, uint32_t size)
  295. {
  296. HRESULT hr;
  297. void *pNewPointer;
  298. hr = AddData(*ppData, size, &pNewPointer);
  299. if ( SUCCEEDED(hr) )
  300. {
  301. *ppData = pNewPointer;
  302. if (size == 0)
  303. {
  304. // To help catch bugs, set zero-byte blocks to null. There's no real reason to do this
  305. *ppData = nullptr;
  306. }
  307. }
  308. return hr;
  309. }
  310. //////////////////////////////////////////////////////////////////////////
  311. // Load API
  312. //////////////////////////////////////////////////////////////////////////
  313. _Use_decl_annotations_
  314. HRESULT CEffect::LoadEffect(const void *pEffectBuffer, uint32_t cbEffectBuffer)
  315. {
  316. HRESULT hr = S_OK;
  317. CEffectLoader loader;
  318. if (!pEffectBuffer)
  319. {
  320. DPF(0, "%s: pEffectBuffer is nullptr.", g_szEffectLoadArea);
  321. VH( E_INVALIDARG );
  322. }
  323. VH( loader.LoadEffect(this, pEffectBuffer, cbEffectBuffer) );
  324. lExit:
  325. if( FAILED( hr ) )
  326. {
  327. // Release here because m_pShaderBlocks may still be in loader.m_BulkHeap if loading failed before we reallocated the memory
  328. ReleaseShaderRefection();
  329. }
  330. return hr;
  331. }
  332. //////////////////////////////////////////////////////////////////////////
  333. // CEffectLoader
  334. // A helper class which loads an effect
  335. //////////////////////////////////////////////////////////////////////////
  336. _Use_decl_annotations_
  337. HRESULT CEffectLoader::GetUnstructuredDataBlock(uint32_t offset, uint32_t *pdwSize, void **ppData)
  338. {
  339. HRESULT hr = S_OK;
  340. uint32_t *pBlockSize;
  341. VH( m_msUnstructured.ReadAtOffset(offset, sizeof(*pBlockSize), (void**) &pBlockSize ) );
  342. *pdwSize = *pBlockSize;
  343. VH( m_msUnstructured.Read(ppData, *pdwSize) );
  344. lExit:
  345. return hr;
  346. }
  347. // position in buffer is lost on error
  348. //
  349. // This function should be used in 1:1 conjunction with CEffectHeap::MoveString;
  350. // that is, any string added to the reflection heap with this function
  351. // must be relocated with MoveString at some point later on.
  352. _Use_decl_annotations_
  353. HRESULT CEffectLoader::GetStringAndAddToReflection(uint32_t offset, char **ppString)
  354. {
  355. HRESULT hr = S_OK;
  356. LPCSTR pName;
  357. size_t oldPos;
  358. if (offset == 0)
  359. {
  360. *ppString = nullptr;
  361. goto lExit;
  362. }
  363. oldPos = m_msUnstructured.GetPosition();
  364. VH( m_msUnstructured.ReadAtOffset(offset, &pName) );
  365. m_ReflectionMemory += AlignToPowerOf2( (uint32_t)strlen(pName) + 1, c_DataAlignment);
  366. *ppString = const_cast<char*>(pName);
  367. m_msUnstructured.Seek(oldPos);
  368. lExit:
  369. return hr;
  370. }
  371. // position in buffer is lost on error
  372. //
  373. // This function should be used in 1:1 conjunction with CEffectHeap::MoveInterfaceParameters;
  374. // that is, any array of parameters added to the reflection heap with this function
  375. // must be relocated with MoveInterfaceParameters at some point later on.
  376. _Use_decl_annotations_
  377. HRESULT CEffectLoader::GetInterfaceParametersAndAddToReflection( uint32_t InterfaceCount, uint32_t offset, SShaderBlock::SInterfaceParameter **ppInterfaces )
  378. {
  379. HRESULT hr = S_OK;
  380. SBinaryInterfaceInitializer* pInterfaceInitializer;
  381. size_t oldPos;
  382. if (offset == 0)
  383. {
  384. *ppInterfaces = nullptr;
  385. goto lExit;
  386. }
  387. oldPos = m_msUnstructured.GetPosition();
  388. VBD( InterfaceCount <= D3D11_SHADER_MAX_INTERFACES, "Internal loading error: InterfaceCount > D3D11_SHADER_MAX_INTERFACES." );
  389. m_ReflectionMemory += AlignToPowerOf2(InterfaceCount * sizeof(SShaderBlock::SInterfaceParameter), c_DataAlignment);
  390. assert( ppInterfaces != 0 );
  391. _Analysis_assume_( ppInterfaces != 0 );
  392. (*ppInterfaces) = PRIVATENEW SShaderBlock::SInterfaceParameter[InterfaceCount];
  393. VN( *ppInterfaces );
  394. VHD( m_msUnstructured.ReadAtOffset(offset, sizeof(SBinaryInterfaceInitializer) * InterfaceCount, (void**)&pInterfaceInitializer),
  395. "Invalid pEffectBuffer: cannot read interface initializer." );
  396. for( size_t i=0; i < InterfaceCount; i++ )
  397. {
  398. (*ppInterfaces)[i].Index = pInterfaceInitializer[i].ArrayIndex;
  399. VHD( m_msUnstructured.ReadAtOffset(pInterfaceInitializer[i].oInstanceName, const_cast<LPCSTR*>(&(*ppInterfaces)[i].pName)),
  400. "Invalid pEffectBuffer: cannot read interface initializer." );
  401. m_ReflectionMemory += AlignToPowerOf2( (uint32_t)strlen((*ppInterfaces)[i].pName) + 1, c_DataAlignment);
  402. }
  403. m_msUnstructured.Seek(oldPos);
  404. lExit:
  405. return hr;
  406. }
  407. HRESULT CEffectLoader::FixupCBPointer(_Inout_ SConstantBuffer **ppCB)
  408. {
  409. HRESULT hr = S_OK;
  410. size_t index = (SConstantBuffer*)*ppCB - m_pOldCBs;
  411. assert( index * sizeof(SConstantBuffer) == ((size_t)(SConstantBuffer*)*ppCB - (size_t)m_pOldCBs) );
  412. VBD( index < m_pEffect->m_CBCount, "Internal loading error: invalid constant buffer index." );
  413. *ppCB = (SConstantBuffer*)(m_pEffect->m_pCBs + index);
  414. lExit:
  415. return hr;
  416. }
  417. HRESULT CEffectLoader::FixupShaderPointer(_Inout_ SShaderBlock **ppShaderBlock)
  418. {
  419. HRESULT hr = S_OK;
  420. if (*ppShaderBlock != &g_NullVS && *ppShaderBlock != &g_NullGS && *ppShaderBlock != &g_NullPS &&
  421. *ppShaderBlock != &g_NullHS && *ppShaderBlock != &g_NullDS && *ppShaderBlock != &g_NullCS &&
  422. *ppShaderBlock != nullptr)
  423. {
  424. size_t index = *ppShaderBlock - m_pOldShaders;
  425. assert( index * sizeof(SShaderBlock) == ((size_t)*ppShaderBlock - (size_t)m_pOldShaders) );
  426. VBD( index < m_pEffect->m_ShaderBlockCount, "Internal loading error: invalid shader index." );
  427. *ppShaderBlock = m_pEffect->m_pShaderBlocks + index;
  428. }
  429. lExit:
  430. return hr;
  431. }
  432. HRESULT CEffectLoader::FixupDSPointer(_Inout_ SDepthStencilBlock **ppDSBlock)
  433. {
  434. HRESULT hr = S_OK;
  435. if (*ppDSBlock != &g_NullDepthStencil && *ppDSBlock != nullptr)
  436. {
  437. size_t index = *ppDSBlock - m_pOldDS;
  438. assert( index * sizeof(SDepthStencilBlock) == ((size_t)*ppDSBlock - (size_t)m_pOldDS) );
  439. VBD( index < m_pEffect->m_DepthStencilBlockCount, "Internal loading error: invalid depth-stencil state index." );
  440. *ppDSBlock = m_pEffect->m_pDepthStencilBlocks + index;
  441. }
  442. lExit:
  443. return hr;
  444. }
  445. HRESULT CEffectLoader::FixupABPointer(_Inout_ SBlendBlock **ppABBlock)
  446. {
  447. HRESULT hr = S_OK;
  448. if (*ppABBlock != &g_NullBlend && *ppABBlock != nullptr)
  449. {
  450. size_t index = *ppABBlock - m_pOldAB;
  451. assert( index * sizeof(SBlendBlock) == ((size_t)*ppABBlock - (size_t)m_pOldAB) );
  452. VBD( index < m_pEffect->m_BlendBlockCount, "Internal loading error: invalid blend state index." );
  453. *ppABBlock = m_pEffect->m_pBlendBlocks + index;
  454. }
  455. lExit:
  456. return hr;
  457. }
  458. HRESULT CEffectLoader::FixupRSPointer(_Inout_ SRasterizerBlock **ppRSBlock)
  459. {
  460. HRESULT hr = S_OK;
  461. if (*ppRSBlock != &g_NullRasterizer && *ppRSBlock != nullptr)
  462. {
  463. size_t index = *ppRSBlock - m_pOldRS;
  464. assert( index * sizeof(SRasterizerBlock) == ((size_t)*ppRSBlock - (size_t)m_pOldRS) );
  465. VBD( index < m_pEffect->m_RasterizerBlockCount, "Internal loading error: invalid rasterizer state index." );
  466. *ppRSBlock = m_pEffect->m_pRasterizerBlocks + index;
  467. }
  468. lExit:
  469. return hr;
  470. }
  471. HRESULT CEffectLoader::FixupSamplerPointer(_Inout_ SSamplerBlock **ppSampler)
  472. {
  473. HRESULT hr = S_OK;
  474. size_t index = *ppSampler - m_pOldSamplers;
  475. assert( index * sizeof(SSamplerBlock) == ((size_t)*ppSampler - (size_t)m_pOldSamplers) );
  476. VBD( index < m_pEffect->m_SamplerBlockCount, "Internal loading error: invalid sampler index." );
  477. *ppSampler = m_pEffect->m_pSamplerBlocks + index;
  478. lExit:
  479. return hr;
  480. }
  481. HRESULT CEffectLoader::FixupInterfacePointer(_Inout_ SInterface **ppInterface, _In_ bool CheckBackgroundInterfaces)
  482. {
  483. HRESULT hr = S_OK;
  484. if (*ppInterface != &g_NullInterface && *ppInterface != nullptr)
  485. {
  486. size_t index = *ppInterface - m_pOldInterfaces;
  487. if(index < m_OldInterfaceCount)
  488. {
  489. assert( index * sizeof(SInterface) == ((size_t)*ppInterface - (size_t)m_pOldInterfaces) );
  490. *ppInterface = m_pEffect->m_pInterfaces + index;
  491. }
  492. else
  493. {
  494. VBD( CheckBackgroundInterfaces, "Internal loading error: invalid interface pointer." );
  495. for( index=0; index < m_BackgroundInterfaces.GetSize(); index++ )
  496. {
  497. if( *ppInterface == m_BackgroundInterfaces[ (uint32_t)index ] )
  498. {
  499. // The interfaces m_BackgroundInterfaces were concatenated to the original ones in m_pEffect->m_pInterfaces
  500. *ppInterface = m_pEffect->m_pInterfaces + (m_OldInterfaceCount + index);
  501. break;
  502. }
  503. }
  504. VBD( index < m_BackgroundInterfaces.GetSize(), "Internal loading error: invalid interface pointer." );
  505. }
  506. }
  507. lExit:
  508. return hr;
  509. }
  510. HRESULT CEffectLoader::FixupShaderResourcePointer(_Inout_ SShaderResource **ppResource)
  511. {
  512. HRESULT hr = S_OK;
  513. if (*ppResource != &g_NullTexture && *ppResource != nullptr)
  514. {
  515. size_t index = *ppResource - m_pOldShaderResources;
  516. assert( index * sizeof(SShaderResource) == ((size_t)*ppResource - (size_t)m_pOldShaderResources) );
  517. // could be a TBuffer or a texture; better check first
  518. if (index < m_pEffect->m_ShaderResourceCount)
  519. {
  520. *ppResource = m_pEffect->m_pShaderResources + index;
  521. }
  522. else
  523. {
  524. // if this is a TBuffer, then the shader resource pointer
  525. // actually points into a SConstantBuffer's TBuffer field
  526. index = (SConstantBuffer*)*ppResource - (SConstantBuffer*)&m_pOldCBs->TBuffer;
  527. assert( index * sizeof(SConstantBuffer) == ((size_t)(SConstantBuffer*)*ppResource - (size_t)(SConstantBuffer*)&m_pOldCBs->TBuffer) );
  528. VBD( index < m_pEffect->m_CBCount, "Internal loading error: invalid SRV index." );
  529. *ppResource = &m_pEffect->m_pCBs[index].TBuffer;
  530. }
  531. }
  532. lExit:
  533. return hr;
  534. }
  535. HRESULT CEffectLoader::FixupUnorderedAccessViewPointer(_Inout_ SUnorderedAccessView **ppUnorderedAccessView)
  536. {
  537. HRESULT hr = S_OK;
  538. if (*ppUnorderedAccessView != &g_NullUnorderedAccessView && *ppUnorderedAccessView != nullptr)
  539. {
  540. size_t index = *ppUnorderedAccessView - m_pOldUnorderedAccessViews;
  541. assert( index * sizeof(SUnorderedAccessView) == ((size_t)*ppUnorderedAccessView - (size_t)m_pOldUnorderedAccessViews) );
  542. VBD( index < m_pEffect->m_UnorderedAccessViewCount, "Internal loading error: invalid UAV index." );
  543. *ppUnorderedAccessView = m_pEffect->m_pUnorderedAccessViews + index;
  544. }
  545. lExit:
  546. return hr;
  547. }
  548. HRESULT CEffectLoader::FixupRenderTargetViewPointer(_Inout_ SRenderTargetView **ppRenderTargetView)
  549. {
  550. HRESULT hr = S_OK;
  551. if (*ppRenderTargetView != &g_NullRenderTargetView && *ppRenderTargetView != nullptr)
  552. {
  553. size_t index = *ppRenderTargetView - m_pOldRenderTargetViews;
  554. assert( index * sizeof(SRenderTargetView) == ((size_t)*ppRenderTargetView - (size_t)m_pOldRenderTargetViews) );
  555. VBD( index < m_pEffect->m_RenderTargetViewCount, "Internal loading error: invalid RTV index." );
  556. *ppRenderTargetView = m_pEffect->m_pRenderTargetViews + index;
  557. }
  558. lExit:
  559. return hr;
  560. }
  561. HRESULT CEffectLoader::FixupDepthStencilViewPointer(_Inout_ SDepthStencilView **ppDepthStencilView)
  562. {
  563. HRESULT hr = S_OK;
  564. if (*ppDepthStencilView != &g_NullDepthStencilView && *ppDepthStencilView != nullptr)
  565. {
  566. size_t index = *ppDepthStencilView - m_pOldDepthStencilViews;
  567. assert( index * sizeof(SDepthStencilView) == ((size_t)*ppDepthStencilView - (size_t)m_pOldDepthStencilViews) );
  568. VBD( index < m_pEffect->m_DepthStencilViewCount, "Internal loading error: invalid DSV index." );
  569. *ppDepthStencilView = m_pEffect->m_pDepthStencilViews + index;
  570. }
  571. lExit:
  572. return hr;
  573. }
  574. HRESULT CEffectLoader::FixupStringPointer(_Inout_ SString **ppString)
  575. {
  576. HRESULT hr = S_OK;
  577. size_t index = *ppString - m_pOldStrings;
  578. assert( index * sizeof(SString) == ((size_t)*ppString - (size_t)m_pOldStrings) );
  579. VBD(index < m_pEffect->m_StringCount, "Internal loading error: invalid string index." );
  580. *ppString = m_pEffect->m_pStrings + index;
  581. lExit:
  582. return hr;
  583. }
  584. HRESULT CEffectLoader::FixupMemberDataPointer(_Inout_ SMemberDataPointer **ppMemberData)
  585. {
  586. HRESULT hr = S_OK;
  587. size_t index = *ppMemberData - m_pOldMemberDataBlocks;
  588. assert( index * sizeof(SMemberDataPointer) == ((size_t)*ppMemberData - (size_t)m_pOldMemberDataBlocks) );
  589. VBD( index < m_pEffect->m_MemberDataCount, "Internal loading error: invalid member block index." );
  590. *ppMemberData = m_pEffect->m_pMemberDataBlocks + index;
  591. lExit:
  592. return hr;
  593. }
  594. HRESULT CEffectLoader::FixupVariablePointer(_Inout_ SGlobalVariable **ppVar)
  595. {
  596. HRESULT hr = S_OK;
  597. size_t index = *ppVar - m_pOldVars;
  598. if( index < m_pEffect->m_VariableCount )
  599. {
  600. assert( index * sizeof(SGlobalVariable) == ((size_t)*ppVar - (size_t)m_pOldVars) );
  601. *ppVar = m_pEffect->m_pVariables + index;
  602. }
  603. else if( m_pvOldMemberInterfaces )
  604. {
  605. // When cloning, m_pvOldMemberInterfaces may be non-nullptr, and *ppVar may point to a variable in it.
  606. const size_t Members = m_pvOldMemberInterfaces->GetSize();
  607. for( index=0; index < Members; index++ )
  608. {
  609. if( (ID3DX11EffectVariable*)(*m_pvOldMemberInterfaces)[ (uint32_t)index] == (ID3DX11EffectVariable*)*ppVar )
  610. {
  611. break;
  612. }
  613. }
  614. VBD( index < Members, "Internal loading error: invalid member pointer." );
  615. *ppVar = (SGlobalVariable*)m_pEffect->m_pMemberInterfaces[ (uint32_t)index];
  616. }
  617. lExit:
  618. return hr;
  619. }
  620. HRESULT CEffectLoader::FixupGroupPointer(_Inout_ SGroup **ppGroup)
  621. {
  622. HRESULT hr = S_OK;
  623. if( *ppGroup != nullptr )
  624. {
  625. size_t index = *ppGroup - m_pOldGroups;
  626. assert( index * sizeof(SGroup) == ((size_t)*ppGroup - (size_t)m_pOldGroups) );
  627. VBD( index < m_pEffect->m_GroupCount, "Internal loading error: invalid group index." );
  628. *ppGroup = m_pEffect->m_pGroups + index;
  629. }
  630. lExit:
  631. return hr;
  632. }
  633. static HRESULT GetEffectVersion( _In_ uint32_t effectFileTag, _Out_ DWORD* pVersion )
  634. {
  635. assert( pVersion != nullptr );
  636. if( !pVersion )
  637. return E_FAIL;
  638. for( size_t i = 0; i < _countof(g_EffectVersions); i++ )
  639. {
  640. if( g_EffectVersions[i].m_Tag == effectFileTag )
  641. {
  642. *pVersion = g_EffectVersions[i].m_Version;
  643. return S_OK;
  644. }
  645. }
  646. return E_FAIL;
  647. }
  648. _Use_decl_annotations_
  649. HRESULT CEffectLoader::LoadEffect(CEffect *pEffect, const void *pEffectBuffer, uint32_t cbEffectBuffer)
  650. {
  651. HRESULT hr = S_OK;
  652. uint32_t i, varSize, cMemberDataBlocks;
  653. CCheckedDword chkVariables = 0;
  654. // Used for cloning
  655. m_pvOldMemberInterfaces = nullptr;
  656. m_BulkHeap.EnableAlignment();
  657. assert(pEffect && pEffectBuffer);
  658. m_pEffect = pEffect;
  659. m_EffectMemory = m_ReflectionMemory = 0;
  660. VN( m_pEffect->m_pReflection = new CEffectReflection() );
  661. m_pReflection = m_pEffect->m_pReflection;
  662. // Begin effect load
  663. VN( m_pEffect->m_pTypePool = new CEffect::CTypeHashTable );
  664. VN( m_pEffect->m_pStringPool = new CEffect::CStringHashTable );
  665. VN( m_pEffect->m_pPooledHeap = new CDataBlockStore );
  666. m_pEffect->m_pPooledHeap->EnableAlignment();
  667. m_pEffect->m_pTypePool->SetPrivateHeap(m_pEffect->m_pPooledHeap);
  668. m_pEffect->m_pStringPool->SetPrivateHeap(m_pEffect->m_pPooledHeap);
  669. VH( m_pEffect->m_pTypePool->AutoGrow() );
  670. VH( m_pEffect->m_pStringPool->AutoGrow() );
  671. // Load from blob
  672. m_pData = (uint8_t*)pEffectBuffer;
  673. m_dwBufferSize = cbEffectBuffer;
  674. VH( m_msStructured.SetData(m_pData, m_dwBufferSize) );
  675. // At this point, we assume that the blob is valid
  676. VHD( m_msStructured.Read((void**) &m_pHeader, sizeof(*m_pHeader)), "pEffectBuffer is too small." );
  677. // Verify the version
  678. if( FAILED( hr = GetEffectVersion( m_pHeader->Tag, &m_Version ) ) )
  679. {
  680. DPF(0, "Effect version is unrecognized. This runtime supports fx_5_0 to %s.", g_EffectVersions[_countof(g_EffectVersions)-1].m_pName );
  681. VH( hr );
  682. }
  683. if( m_pHeader->RequiresPool() || m_pHeader->Pool.cObjectVariables > 0 || m_pHeader->Pool.cNumericVariables > 0 )
  684. {
  685. DPF(0, "Effect11 does not support EffectPools." );
  686. VH( E_FAIL );
  687. }
  688. // Get shader block count
  689. VBD( m_pHeader->cInlineShaders <= m_pHeader->cTotalShaders, "Invalid Effect header: cInlineShaders > cTotalShaders." );
  690. // Make sure the counts for the Effect don't overflow
  691. chkVariables = m_pHeader->Effect.cObjectVariables;
  692. chkVariables += m_pHeader->Effect.cNumericVariables;
  693. chkVariables += m_pHeader->cInterfaceVariables;
  694. chkVariables *= sizeof(SGlobalVariable);
  695. VH( chkVariables.GetValue(&varSize) );
  696. // Make sure the counts for the SMemberDataPointers don't overflow
  697. chkVariables = m_pHeader->cClassInstanceElements;
  698. chkVariables += m_pHeader->cBlendStateBlocks;
  699. chkVariables += m_pHeader->cRasterizerStateBlocks;
  700. chkVariables += m_pHeader->cDepthStencilBlocks;
  701. chkVariables += m_pHeader->cSamplers;
  702. chkVariables += m_pHeader->Effect.cCBs; // Buffer (for CBuffers and TBuffers)
  703. chkVariables += m_pHeader->Effect.cCBs; // SRV (for TBuffers)
  704. VHD( chkVariables.GetValue(&cMemberDataBlocks), "Overflow: too many Effect variables." );
  705. // Allocate effect resources
  706. VN( m_pEffect->m_pCBs = PRIVATENEW SConstantBuffer[m_pHeader->Effect.cCBs] );
  707. VN( m_pEffect->m_pDepthStencilBlocks = PRIVATENEW SDepthStencilBlock[m_pHeader->cDepthStencilBlocks] );
  708. VN( m_pEffect->m_pRasterizerBlocks = PRIVATENEW SRasterizerBlock[m_pHeader->cRasterizerStateBlocks] );
  709. VN( m_pEffect->m_pBlendBlocks = PRIVATENEW SBlendBlock[m_pHeader->cBlendStateBlocks] );
  710. VN( m_pEffect->m_pSamplerBlocks = PRIVATENEW SSamplerBlock[m_pHeader->cSamplers] );
  711. // we allocate raw bytes for variables because they are polymorphic types that need to be placement new'ed
  712. VN( m_pEffect->m_pVariables = (SGlobalVariable *)PRIVATENEW uint8_t[varSize] );
  713. VN( m_pEffect->m_pAnonymousShaders = PRIVATENEW SAnonymousShader[m_pHeader->cInlineShaders] );
  714. VN( m_pEffect->m_pGroups = PRIVATENEW SGroup[m_pHeader->cGroups] );
  715. VN( m_pEffect->m_pShaderBlocks = PRIVATENEW SShaderBlock[m_pHeader->cTotalShaders] );
  716. VN( m_pEffect->m_pStrings = PRIVATENEW SString[m_pHeader->cStrings] );
  717. VN( m_pEffect->m_pShaderResources = PRIVATENEW SShaderResource[m_pHeader->cShaderResources] );
  718. VN( m_pEffect->m_pUnorderedAccessViews = PRIVATENEW SUnorderedAccessView[m_pHeader->cUnorderedAccessViews] );
  719. VN( m_pEffect->m_pInterfaces = PRIVATENEW SInterface[m_pHeader->cInterfaceVariableElements] );
  720. VN( m_pEffect->m_pMemberDataBlocks = PRIVATENEW SMemberDataPointer[cMemberDataBlocks] );
  721. VN( m_pEffect->m_pRenderTargetViews = PRIVATENEW SRenderTargetView[m_pHeader->cRenderTargetViews] );
  722. VN( m_pEffect->m_pDepthStencilViews = PRIVATENEW SDepthStencilView[m_pHeader->cDepthStencilViews] );
  723. uint32_t oStructured = m_pHeader->cbUnstructured + sizeof(SBinaryHeader5);
  724. VHD( m_msStructured.Seek(oStructured), "Invalid pEffectBuffer: Missing structured data block." );
  725. VH( m_msUnstructured.SetData(m_pData + sizeof(SBinaryHeader5), oStructured - sizeof(SBinaryHeader5)) );
  726. VH( LoadCBs() );
  727. VH( LoadObjectVariables() );
  728. VH( LoadInterfaceVariables() );
  729. VH( LoadGroups() );
  730. // Build shader dependencies
  731. for (i=0; i<m_pEffect->m_ShaderBlockCount; i++)
  732. {
  733. VH( BuildShaderBlock(&m_pEffect->m_pShaderBlocks[i]) );
  734. }
  735. for( size_t iGroup=0; iGroup<m_pHeader->cGroups; iGroup++ )
  736. {
  737. SGroup *pGroup = &m_pEffect->m_pGroups[iGroup];
  738. pGroup->HasDependencies = false;
  739. for( size_t iTechnique=0; iTechnique < pGroup->TechniqueCount; iTechnique++ )
  740. {
  741. STechnique* pTech = &pGroup->pTechniques[iTechnique];
  742. pTech->HasDependencies = false;
  743. for( size_t iPass=0; iPass < pTech->PassCount; iPass++ )
  744. {
  745. SPassBlock *pPass = &pTech->pPasses[iPass];
  746. pTech->HasDependencies |= pPass->CheckDependencies();
  747. }
  748. pGroup->HasDependencies |= pTech->HasDependencies;
  749. }
  750. }
  751. VH( InitializeReflectionDataAndMoveStrings() );
  752. VH( ReallocateReflectionData() );
  753. VH( ReallocateEffectData() );
  754. VB( m_pReflection->m_Heap.GetSize() == m_ReflectionMemory );
  755. // Verify that all of the various block/variable types were loaded
  756. VBD( m_pEffect->m_VariableCount == (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables), "Internal loading error: mismatched variable count." );
  757. VBD( m_pEffect->m_ShaderBlockCount == m_pHeader->cTotalShaders, "Internal loading error: mismatched shader block count." );
  758. VBD( m_pEffect->m_AnonymousShaderCount == m_pHeader->cInlineShaders, "Internal loading error: mismatched anonymous variable count." );
  759. VBD( m_pEffect->m_ShaderResourceCount == m_pHeader->cShaderResources, "Internal loading error: mismatched SRV count." );
  760. VBD( m_pEffect->m_InterfaceCount == m_pHeader->cInterfaceVariableElements + m_BackgroundInterfaces.GetSize(), "Internal loading error: mismatched interface count." );
  761. VBD( m_pEffect->m_UnorderedAccessViewCount == m_pHeader->cUnorderedAccessViews, "Internal loading error: mismatched UAV count." );
  762. VBD( m_pEffect->m_MemberDataCount == cMemberDataBlocks, "Internal loading error: mismatched member data block count." );
  763. VBD( m_pEffect->m_RenderTargetViewCount == m_pHeader->cRenderTargetViews, "Internal loading error: mismatched RTV count." );
  764. VBD( m_pEffect->m_DepthStencilViewCount == m_pHeader->cDepthStencilViews, "Internal loading error: mismatched DSV count." );
  765. VBD( m_pEffect->m_DepthStencilBlockCount == m_pHeader->cDepthStencilBlocks, "Internal loading error: mismatched depth-stencil state count." );
  766. VBD( m_pEffect->m_BlendBlockCount == m_pHeader->cBlendStateBlocks, "Internal loading error: mismatched blend state count." );
  767. VBD( m_pEffect->m_RasterizerBlockCount == m_pHeader->cRasterizerStateBlocks, "Internal loading error: mismatched rasterizer state count." );
  768. VBD( m_pEffect->m_SamplerBlockCount == m_pHeader->cSamplers, "Internal loading error: mismatched sampler count." );
  769. VBD( m_pEffect->m_StringCount == m_pHeader->cStrings, "Internal loading error: mismatched string count." );
  770. // Uncomment if you really need this information
  771. // DPF(0, "Effect heap size: %d, reflection heap size: %d, allocations avoided: %d", m_EffectMemory, m_ReflectionMemory, m_BulkHeap.m_cAllocations);
  772. lExit:
  773. return hr;
  774. }
  775. // position in buffer is lost on error
  776. _Use_decl_annotations_
  777. HRESULT CEffectLoader::LoadStringAndAddToPool(char **ppString, uint32_t dwOffset)
  778. {
  779. HRESULT hr = S_OK;
  780. char *pName;
  781. uint32_t hash;
  782. size_t oldPos;
  783. CEffect::CStringHashTable::CIterator iter;
  784. uint32_t len;
  785. if (dwOffset == 0)
  786. {
  787. *ppString = nullptr;
  788. goto lExit;
  789. }
  790. oldPos = m_msUnstructured.GetPosition();
  791. VHD( m_msUnstructured.ReadAtOffset(dwOffset, (LPCSTR *) &pName), "Invalid pEffectBuffer: cannot read string." );
  792. len = (uint32_t)strlen(pName);
  793. hash = ComputeHash((uint8_t *)pName, len);
  794. if (FAILED(m_pEffect->m_pStringPool->FindValueWithHash(pName, hash, &iter)))
  795. {
  796. assert( m_pEffect->m_pPooledHeap != 0 );
  797. _Analysis_assume_( m_pEffect->m_pPooledHeap != 0 );
  798. VN( (*ppString) = new(*m_pEffect->m_pPooledHeap) char[len + 1] );
  799. memcpy(*ppString, pName, len + 1);
  800. VHD( m_pEffect->m_pStringPool->AddValueWithHash(*ppString, hash), "Internal loading error: failed to add string to pool." );
  801. }
  802. else
  803. {
  804. *ppString = const_cast<LPSTR>(iter.GetData());
  805. }
  806. m_msUnstructured.Seek(oldPos);
  807. lExit:
  808. return hr;
  809. }
  810. _Use_decl_annotations_
  811. HRESULT CEffectLoader::LoadTypeAndAddToPool(SType **ppType, uint32_t dwOffset)
  812. {
  813. HRESULT hr = S_OK;
  814. SBinaryType *psType;
  815. SBinaryNumericType *pNumericType;
  816. EObjectType *pObjectType;
  817. uint32_t cMembers, iMember, cInterfaces;
  818. uint32_t oBaseClassType;
  819. SType temporaryType;
  820. CEffect::CTypeHashTable::CIterator iter;
  821. uint8_t *pHashBuffer;
  822. uint32_t hash;
  823. SVariable *pTempMembers = nullptr;
  824. m_HashBuffer.Empty();
  825. VHD( m_msUnstructured.ReadAtOffset(dwOffset, sizeof(SBinaryType), (void**) &psType), "Invalid pEffectBuffer: cannot read type." );
  826. VHD( LoadStringAndAddToPool(&temporaryType.pTypeName, psType->oTypeName), "Invalid pEffectBuffer: cannot read type name." );
  827. temporaryType.VarType = psType->VarType;
  828. temporaryType.Elements = psType->Elements;
  829. temporaryType.TotalSize = psType->TotalSize;
  830. temporaryType.Stride = psType->Stride;
  831. temporaryType.PackedSize = psType->PackedSize;
  832. // sanity check elements, size, stride, etc.
  833. uint32_t cElements = std::max<uint32_t>(1, temporaryType.Elements);
  834. VBD( cElements * temporaryType.Stride == AlignToPowerOf2(temporaryType.TotalSize, SType::c_RegisterSize), "Invalid pEffectBuffer: invalid type size." );
  835. VBD( temporaryType.Stride % SType::c_RegisterSize == 0, "Invalid pEffectBuffer: invalid type stride." );
  836. VBD( temporaryType.PackedSize <= temporaryType.TotalSize && temporaryType.PackedSize % cElements == 0, "Invalid pEffectBuffer: invalid type packed size." );
  837. switch(temporaryType.VarType)
  838. {
  839. case EVT_Object:
  840. VHD( m_msUnstructured.Read((void**) &pObjectType, sizeof(uint32_t)), "Invalid pEffectBuffer: cannot read object type." );
  841. temporaryType.ObjectType = *pObjectType;
  842. VBD( temporaryType.VarType > EOT_Invalid && temporaryType.VarType < EOT_Count, "Invalid pEffectBuffer: invalid object type." );
  843. VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
  844. sizeof(temporaryType.pTypeName) + sizeof(temporaryType.ObjectType)) );
  845. memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
  846. pHashBuffer += sizeof(temporaryType.VarType);
  847. memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
  848. pHashBuffer += sizeof(temporaryType.Elements);
  849. memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
  850. pHashBuffer += sizeof(temporaryType.pTypeName);
  851. memcpy(pHashBuffer, &temporaryType.ObjectType, sizeof(temporaryType.ObjectType));
  852. break;
  853. case EVT_Interface:
  854. temporaryType.InterfaceType = nullptr;
  855. VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
  856. sizeof(temporaryType.pTypeName) + sizeof(temporaryType.ObjectType)) );
  857. memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
  858. pHashBuffer += sizeof(temporaryType.VarType);
  859. memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
  860. pHashBuffer += sizeof(temporaryType.Elements);
  861. memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
  862. pHashBuffer += sizeof(temporaryType.pTypeName);
  863. memcpy(pHashBuffer, &temporaryType.ObjectType, sizeof(temporaryType.ObjectType));
  864. break;
  865. case EVT_Numeric:
  866. VHD( m_msUnstructured.Read((void**) &pNumericType, sizeof(SBinaryNumericType)), "Invalid pEffectBuffer: cannot read numeric type." );
  867. temporaryType.NumericType = *pNumericType;
  868. VBD( temporaryType.NumericType.Rows >= 1 && temporaryType.NumericType.Rows <= 4 &&
  869. temporaryType.NumericType.Columns >= 1 && temporaryType.NumericType.Columns <= 4 &&
  870. temporaryType.NumericType.NumericLayout != ENL_Invalid && temporaryType.NumericType.NumericLayout < ENL_Count &&
  871. temporaryType.NumericType.ScalarType > EST_Invalid && temporaryType.NumericType.ScalarType < EST_Count,
  872. "Invalid pEffectBuffer: invalid numeric type.");
  873. if (temporaryType.NumericType.NumericLayout != ENL_Matrix)
  874. {
  875. VBD( temporaryType.NumericType.IsColumnMajor == false, "Invalid pEffectBuffer: only matricies can be column major." );
  876. }
  877. VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
  878. sizeof(temporaryType.pTypeName) + sizeof(temporaryType.NumericType)) );
  879. memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
  880. pHashBuffer += sizeof(temporaryType.VarType);
  881. memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
  882. pHashBuffer += sizeof(temporaryType.Elements);
  883. memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
  884. pHashBuffer += sizeof(temporaryType.pTypeName);
  885. memcpy(pHashBuffer, &temporaryType.NumericType, sizeof(temporaryType.NumericType));
  886. break;
  887. case EVT_Struct:
  888. VHD( m_msUnstructured.Read(&cMembers), "Invalid pEffectBuffer: cannot read struct." );
  889. temporaryType.StructType.Members = cMembers;
  890. VN( pTempMembers = new SVariable[cMembers] );
  891. temporaryType.StructType.pMembers = pTempMembers;
  892. // read up all of the member descriptors at once
  893. SBinaryType::SBinaryMember *psMember;
  894. VHD( m_msUnstructured.Read((void**) &psMember, cMembers * sizeof(*psMember)), "Invalid pEffectBuffer: cannot read struct members." );
  895. {
  896. // Determine if this type implements an interface
  897. VHD( m_msUnstructured.Read(&oBaseClassType), "Invalid pEffectBuffer: cannot read base class type." );
  898. VHD( m_msUnstructured.Read(&cInterfaces), "Invalid pEffectBuffer: cannot read interfaces." );
  899. if( cInterfaces > 0 )
  900. {
  901. temporaryType.StructType.ImplementsInterface = 1;
  902. temporaryType.StructType.HasSuperClass = ( oBaseClassType > 0 ) ? 1 : 0;
  903. }
  904. else if( oBaseClassType > 0 )
  905. {
  906. // Get parent type and copy its ImplementsInterface
  907. SType* pBaseClassType;
  908. VH( LoadTypeAndAddToPool(&pBaseClassType, oBaseClassType) );
  909. temporaryType.StructType.ImplementsInterface = pBaseClassType->StructType.ImplementsInterface;
  910. temporaryType.StructType.HasSuperClass = 1;
  911. }
  912. // Read (and ignore) the interface types
  913. uint32_t *poInterface;
  914. VHD( m_msUnstructured.Read((void**) &poInterface, cInterfaces * sizeof(poInterface)), "Invalid pEffectBuffer: cannot read interface types." );
  915. }
  916. uint32_t totalSize;
  917. totalSize = 0;
  918. for (iMember=0; iMember<cMembers; iMember++)
  919. {
  920. SVariable *pMember;
  921. pMember = temporaryType.StructType.pMembers + iMember;
  922. VBD( psMember[iMember].Offset == totalSize ||
  923. psMember[iMember].Offset == AlignToPowerOf2(totalSize, SType::c_RegisterSize),
  924. "Internal loading error: invalid member offset." );
  925. pMember->Data.Offset = psMember[iMember].Offset;
  926. VH( LoadTypeAndAddToPool(&pMember->pType, psMember[iMember].oType) );
  927. VH( LoadStringAndAddToPool(&pMember->pName, psMember[iMember].oName) );
  928. VH( LoadStringAndAddToPool(&pMember->pSemantic, psMember[iMember].oSemantic) );
  929. totalSize = psMember[iMember].Offset + pMember->pType->TotalSize;
  930. }
  931. VBD( AlignToPowerOf2(totalSize, SType::c_RegisterSize) == temporaryType.Stride, "Internal loading error: invlid type size." );
  932. VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
  933. sizeof(temporaryType.pTypeName) + sizeof(temporaryType.StructType.Members) + cMembers * sizeof(SVariable)) );
  934. memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
  935. pHashBuffer += sizeof(temporaryType.VarType);
  936. memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
  937. pHashBuffer += sizeof(temporaryType.Elements);
  938. memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
  939. pHashBuffer += sizeof(temporaryType.pTypeName);
  940. memcpy(pHashBuffer, &temporaryType.StructType.Members, sizeof(temporaryType.StructType.Members));
  941. pHashBuffer += sizeof(temporaryType.StructType.Members);
  942. memcpy(pHashBuffer, temporaryType.StructType.pMembers, cMembers * sizeof(SVariable));
  943. break;
  944. default:
  945. assert(0);
  946. VHD( E_FAIL, "Internal loading error: invalid variable type." );
  947. }
  948. hash = ComputeHash(&m_HashBuffer[0], m_HashBuffer.GetSize());
  949. if (FAILED(m_pEffect->m_pTypePool->FindValueWithHash(&temporaryType, hash, &iter)))
  950. {
  951. assert( m_pEffect->m_pPooledHeap != nullptr );
  952. // allocate real member array, if necessary
  953. if (temporaryType.VarType == EVT_Struct)
  954. {
  955. VN( temporaryType.StructType.pMembers = new(*m_pEffect->m_pPooledHeap) SVariable[temporaryType.StructType.Members] );
  956. memcpy(temporaryType.StructType.pMembers, pTempMembers, temporaryType.StructType.Members * sizeof(SVariable));
  957. }
  958. // allocate real type
  959. VN( (*ppType) = new(*m_pEffect->m_pPooledHeap) SType );
  960. memcpy(*ppType, &temporaryType, sizeof(temporaryType));
  961. ZeroMemory(&temporaryType, sizeof(temporaryType));
  962. VH( m_pEffect->m_pTypePool->AddValueWithHash(*ppType, hash) );
  963. }
  964. else
  965. {
  966. *ppType = iter.GetData();
  967. }
  968. lExit:
  969. SAFE_DELETE_ARRAY(pTempMembers);
  970. return hr;
  971. }
  972. // Numeric data in annotations are tightly packed (unlike in CBs which follow D3D11 packing rules). This unpacks them.
  973. uint32_t CEffectLoader::UnpackData(uint8_t *pDestData, uint8_t *pSrcData, uint32_t PackedDataSize, SType *pType, uint32_t *pBytesRead)
  974. {
  975. uint32_t bytesRead = 0;
  976. HRESULT hr = S_OK;
  977. uint32_t elementsToCopy = std::max<uint32_t>(pType->Elements, 1);
  978. switch (pType->VarType)
  979. {
  980. case EVT_Struct:
  981. for (size_t i = 0; i < elementsToCopy; ++ i)
  982. {
  983. for (size_t j = 0; j < pType->StructType.Members; ++ j)
  984. {
  985. uint32_t br;
  986. assert(PackedDataSize > bytesRead);
  987. VH( UnpackData(pDestData + pType->StructType.pMembers[j].Data.Offset,
  988. pSrcData + bytesRead, PackedDataSize - bytesRead,
  989. pType->StructType.pMembers[j].pType, &br) );
  990. bytesRead += br;
  991. }
  992. pDestData += pType->Stride;
  993. }
  994. break;
  995. case EVT_Numeric:
  996. if (pType->NumericType.IsPackedArray)
  997. {
  998. // No support for packed arrays
  999. assert(0);
  1000. VHD(E_FAIL, "Internal loading error: packed arrays are not supported." );
  1001. }
  1002. else
  1003. {
  1004. uint32_t bytesToCopy;
  1005. if (pType->NumericType.IsColumnMajor)
  1006. {
  1007. uint32_t registers = pType->NumericType.Columns;
  1008. uint32_t entries = pType->NumericType.Rows;
  1009. bytesToCopy = entries * registers * SType::c_ScalarSize;
  1010. for (size_t i = 0; i < elementsToCopy; ++ i)
  1011. {
  1012. for (size_t j = 0; j < registers; ++ j)
  1013. {
  1014. for (size_t k = 0; k < entries; ++ k)
  1015. {
  1016. // type cast to an arbitrary scalar
  1017. ((uint32_t*)pDestData)[k] = ((uint32_t*)pSrcData)[k * registers + j];
  1018. }
  1019. pDestData += SType::c_RegisterSize; // advance to next register
  1020. }
  1021. pSrcData += bytesToCopy;
  1022. bytesRead += bytesToCopy;
  1023. }
  1024. }
  1025. else
  1026. {
  1027. uint32_t registers = pType->NumericType.Rows;
  1028. uint32_t entries = pType->NumericType.Columns;
  1029. bytesToCopy = entries * SType::c_ScalarSize;
  1030. for (size_t i = 0; i < elementsToCopy; ++ i)
  1031. {
  1032. for (size_t j = 0; j < registers; ++ j)
  1033. {
  1034. memcpy(pDestData, pSrcData, bytesToCopy);
  1035. pDestData += SType::c_RegisterSize; // advance to next register
  1036. pSrcData += bytesToCopy;
  1037. bytesRead += bytesToCopy;
  1038. }
  1039. }
  1040. }
  1041. }
  1042. break;
  1043. default:
  1044. // shouldn't be called on non-struct/numeric types
  1045. assert(0);
  1046. VHD(E_FAIL, "Internal loading error: UnpackData should not be called on non-struct, non-numeric types." );
  1047. }
  1048. lExit:
  1049. *pBytesRead = bytesRead;
  1050. return hr;
  1051. }
  1052. // Read info from the compiled blob and initialize a numeric variable
  1053. HRESULT CEffectLoader::LoadNumericVariable(_In_ SConstantBuffer *pParentCB)
  1054. {
  1055. HRESULT hr = S_OK;
  1056. SBinaryNumericVariable *psVar;
  1057. SGlobalVariable *pVar;
  1058. SType *pType;
  1059. void *pDefaultValue;
  1060. // Read variable info
  1061. VHD( m_msStructured.Read((void**) &psVar, sizeof(*psVar)), "Invalid pEffectBuffer: cannot read numeric variable." );
  1062. VBD( m_pEffect->m_VariableCount < (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables),
  1063. "Internal loading error: invalid variable counts.");
  1064. pVar = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
  1065. // Get type
  1066. VH( LoadTypeAndAddToPool(&pType, psVar->oType) );
  1067. // Make sure the right polymorphic type is created
  1068. VH( PlacementNewVariable(pVar, pType, false) );
  1069. if (psVar->Flags & D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT)
  1070. {
  1071. pVar->ExplicitBindPoint = psVar->Offset;
  1072. }
  1073. else
  1074. {
  1075. pVar->ExplicitBindPoint = uint32_t(-1);
  1076. }
  1077. pVar->pEffect = m_pEffect;
  1078. pVar->pType = pType;
  1079. pVar->pCB = pParentCB;
  1080. pVar->Data.pGeneric = pParentCB->pBackingStore + psVar->Offset;
  1081. VBD( psVar->Offset + pVar->pType->TotalSize <= pVar->pCB->Size, "Invalid pEffectBuffer: invalid variable offset." );
  1082. if (pType->VarType == EVT_Struct && pType->StructType.ImplementsInterface && !pParentCB->IsTBuffer)
  1083. {
  1084. pVar->MemberDataOffsetPlus4 = m_pEffect->m_MemberDataCount * sizeof(SMemberDataPointer) + 4;
  1085. m_pEffect->m_MemberDataCount += std::max<uint32_t>(pType->Elements,1);
  1086. }
  1087. // Get name & semantic
  1088. VHD( GetStringAndAddToReflection(psVar->oName, &pVar->pName), "Invalid pEffectBuffer: cannot read variable name." );
  1089. VHD( GetStringAndAddToReflection(psVar->oSemantic, &pVar->pSemantic), "Invalid pEffectBuffer: cannot read variable semantic." );
  1090. // Ensure the variable fits in the CBuffer and doesn't overflow
  1091. VBD( pType->TotalSize + psVar->Offset <= pParentCB->Size &&
  1092. pType->TotalSize + psVar->Offset >= pType->TotalSize, "Invalid pEffectBuffer: variable does not fit in CB." );
  1093. ZeroMemory(pVar->Data.pGeneric, pType->TotalSize);
  1094. // Get default value
  1095. if (0 != psVar->oDefaultValue)
  1096. {
  1097. uint32_t bytesUnpacked;
  1098. VHD( m_msUnstructured.ReadAtOffset(psVar->oDefaultValue, pType->PackedSize, &pDefaultValue), "Invalid pEffectBuffer: cannot read default value." );
  1099. VH( UnpackData((uint8_t*) pVar->Data.pGeneric, (uint8_t*) pDefaultValue, pType->PackedSize, pType, &bytesUnpacked) );
  1100. VBD( bytesUnpacked == pType->PackedSize, "Invalid pEffectBuffer: invalid type packed size.");
  1101. }
  1102. // We need to use offsets until we fixup
  1103. pVar->Data.Offset = psVar->Offset;
  1104. // Read annotations
  1105. VH( LoadAnnotations(&pVar->AnnotationCount, &pVar->pAnnotations) );
  1106. m_pEffect->m_VariableCount++;
  1107. lExit:
  1108. return hr;
  1109. }
  1110. // Read info from the compiled blob and initialize a constant buffer
  1111. HRESULT CEffectLoader::LoadCBs()
  1112. {
  1113. HRESULT hr = S_OK;
  1114. uint32_t iCB, iVar;
  1115. for (iCB=0; iCB<m_pHeader->Effect.cCBs; iCB++)
  1116. {
  1117. SBinaryConstantBuffer *psCB;
  1118. SConstantBuffer *pCB;
  1119. VHD( m_msStructured.Read((void**) &psCB, sizeof(*psCB)), "Invalid pEffectBuffer: cannot read CB." );
  1120. pCB = &m_pEffect->m_pCBs[iCB];
  1121. VHD( GetStringAndAddToReflection(psCB->oName, &pCB->pName), "Invalid pEffectBuffer: cannot read CB name." );
  1122. pCB->IsTBuffer = (psCB->Flags & SBinaryConstantBuffer::c_IsTBuffer) != 0 ? true : false;
  1123. pCB->IsSingle = (psCB->Flags & SBinaryConstantBuffer::c_IsSingle) != 0 ? true : false;
  1124. pCB->Size = psCB->Size;
  1125. pCB->ExplicitBindPoint = psCB->ExplicitBindPoint;
  1126. VBD( pCB->Size == AlignToPowerOf2(pCB->Size, SType::c_RegisterSize), "Invalid pEffectBuffer: CB size not a power of 2." );
  1127. VN( pCB->pBackingStore = PRIVATENEW uint8_t[pCB->Size] );
  1128. pCB->MemberDataOffsetPlus4 = m_pEffect->m_MemberDataCount * sizeof(SMemberDataPointer) + 4;
  1129. m_pEffect->m_MemberDataCount += 2;
  1130. // point this CB to variables that it owns
  1131. pCB->VariableCount = psCB->cVariables;
  1132. if (pCB->VariableCount > 0)
  1133. {
  1134. pCB->pVariables = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
  1135. }
  1136. else
  1137. {
  1138. pCB->pVariables = nullptr;
  1139. }
  1140. // Read annotations
  1141. VH( LoadAnnotations(&pCB->AnnotationCount, &pCB->pAnnotations) );
  1142. for (iVar=0; iVar<psCB->cVariables; iVar++)
  1143. {
  1144. VH( LoadNumericVariable(pCB) );
  1145. }
  1146. }
  1147. m_pEffect->m_CBCount = m_pHeader->Effect.cCBs;
  1148. lExit:
  1149. return hr;
  1150. }
  1151. // Used by LoadAssignment to initialize members on load
  1152. _Use_decl_annotations_
  1153. HRESULT CEffectLoader::ExecuteConstantAssignment(const SBinaryConstant *pConstant, void *pLHS, D3D_SHADER_VARIABLE_TYPE lhsType)
  1154. {
  1155. HRESULT hr = S_OK;
  1156. switch(pConstant->Type)
  1157. {
  1158. case EST_UInt:
  1159. case EST_Int:
  1160. case EST_Bool:
  1161. switch(lhsType)
  1162. {
  1163. case D3D_SVT_BOOL:
  1164. case D3D_SVT_INT:
  1165. case D3D_SVT_UINT:
  1166. *(uint32_t*) pLHS = pConstant->iValue;
  1167. break;
  1168. case D3D_SVT_UINT8:
  1169. *(uint8_t*) pLHS = (uint8_t) pConstant->iValue;
  1170. break;
  1171. case D3D_SVT_FLOAT:
  1172. *(float*) pLHS = (float) pConstant->iValue;
  1173. break;
  1174. default:
  1175. VHD( E_FAIL, "Internal loading error: invalid left-hand assignment type." );
  1176. }
  1177. break;
  1178. case EST_Float:
  1179. switch(lhsType)
  1180. {
  1181. case D3D_SVT_BOOL:
  1182. case D3D_SVT_INT:
  1183. case D3D_SVT_UINT:
  1184. *(uint32_t*) pLHS = (uint32_t) pConstant->fValue;
  1185. break;
  1186. case D3D_SVT_UINT8:
  1187. *(uint8_t*) pLHS = (uint8_t) pConstant->fValue;
  1188. break;
  1189. case D3D_SVT_FLOAT:
  1190. *(float*) pLHS = pConstant->fValue;
  1191. break;
  1192. default:
  1193. VHD( E_FAIL, "Internal loading error: invalid left-hand assignment type." );
  1194. }
  1195. break;
  1196. default:
  1197. VHD( E_FAIL, "Internal loading error: invalid left-hand assignment type." );
  1198. }
  1199. lExit:
  1200. return hr;
  1201. }
  1202. // Read info from the compiled blob and initialize a set of assignments
  1203. _Use_decl_annotations_
  1204. HRESULT CEffectLoader::LoadAssignments( uint32_t Assignments, SAssignment **ppAssignments,
  1205. uint8_t *pBackingStore, uint32_t *pRTVAssignments, uint32_t *pFinalAssignments )
  1206. {
  1207. HRESULT hr = S_OK;
  1208. uint32_t i, j;
  1209. SBinaryAssignment *psAssignments;
  1210. uint32_t finalAssignments = 0; // the number of assignments worth keeping
  1211. uint32_t renderTargetViewAssns = 0; // Number of render target view assns, used by passes since SetRTV is a vararg call
  1212. *pFinalAssignments = 0;
  1213. if (pRTVAssignments)
  1214. *pRTVAssignments = 0;
  1215. VHD( m_msStructured.Read((void**) &psAssignments, sizeof(*psAssignments) * Assignments), "Invalid pEffectBuffer: cannot read assignments." );
  1216. // allocate enough room to store all of the assignments (even though some may go unused)
  1217. VN( (*ppAssignments) = PRIVATENEW SAssignment[Assignments] )
  1218. //
  1219. // In this loop, we read assignments 1-by-1, keeping some and discarding others.
  1220. // We write to the "next" assignment which is given by &(*ppAssignments)[finalAssignments];
  1221. // if an assignment is worth keeping, we increment finalAssignments.
  1222. // This means that if you want to keep an assignment, you must be careful to initialize
  1223. // all members of SAssignment because old values from preceding discarded assignments might remain.
  1224. //
  1225. for (i = 0; i < Assignments; ++ i)
  1226. {
  1227. SGlobalVariable *pVarArray, *pVarIndex, *pVar;
  1228. const char *pGlobalVarName;
  1229. SAssignment *pAssignment = &(*ppAssignments)[finalAssignments];
  1230. uint8_t *pLHS;
  1231. VBD( psAssignments[i].iState < NUM_STATES, "Invalid pEffectBuffer: invalid assignment state." );
  1232. VBD( psAssignments[i].Index < g_lvGeneral[psAssignments[i].iState].m_Indices, "Invalid pEffectBuffer: invalid assignment index." );
  1233. pAssignment->LhsType = g_lvGeneral[psAssignments[i].iState].m_LhsType;
  1234. // Count RenderTargetView assignments
  1235. if (pAssignment->LhsType == ELHS_RenderTargetView)
  1236. renderTargetViewAssns++;
  1237. switch (g_lvGeneral[psAssignments[i].iState].m_Type)
  1238. {
  1239. case D3D_SVT_UINT8:
  1240. assert(g_lvGeneral[psAssignments[i].iState].m_Cols == 1); // uint8_t arrays not supported
  1241. pAssignment->DataSize = sizeof(uint8_t);
  1242. // Store an offset for destination instead of a pointer so that it's easy to relocate it later
  1243. break;
  1244. case D3D_SVT_BOOL:
  1245. case D3D_SVT_INT:
  1246. case D3D_SVT_UINT:
  1247. case D3D_SVT_FLOAT:
  1248. pAssignment->DataSize = SType::c_ScalarSize * g_lvGeneral[psAssignments[i].iState].m_Cols;
  1249. break;
  1250. case D3D_SVT_RASTERIZER:
  1251. pAssignment->DataSize = sizeof(SRasterizerBlock);
  1252. break;
  1253. case D3D_SVT_DEPTHSTENCIL:
  1254. pAssignment->DataSize = sizeof(SDepthStencilBlock);
  1255. break;
  1256. case D3D_SVT_BLEND:
  1257. pAssignment->DataSize = sizeof(SBlendBlock);
  1258. break;
  1259. case D3D_SVT_VERTEXSHADER:
  1260. case D3D_SVT_GEOMETRYSHADER:
  1261. case D3D_SVT_PIXELSHADER:
  1262. case D3D_SVT_HULLSHADER:
  1263. case D3D_SVT_DOMAINSHADER:
  1264. case D3D_SVT_COMPUTESHADER:
  1265. pAssignment->DataSize = sizeof(SShaderBlock);
  1266. break;
  1267. case D3D_SVT_TEXTURE:
  1268. case D3D_SVT_TEXTURE1D:
  1269. case D3D_SVT_TEXTURE2D:
  1270. case D3D_SVT_TEXTURE2DMS:
  1271. case D3D_SVT_TEXTURE3D:
  1272. case D3D_SVT_TEXTURECUBE:
  1273. case D3D_SVT_TEXTURECUBEARRAY:
  1274. case D3D_SVT_BYTEADDRESS_BUFFER:
  1275. case D3D_SVT_STRUCTURED_BUFFER:
  1276. pAssignment->DataSize = sizeof(SShaderResource);
  1277. break;
  1278. case D3D_SVT_RENDERTARGETVIEW:
  1279. pAssignment->DataSize = sizeof(SRenderTargetView);
  1280. break;
  1281. case D3D_SVT_DEPTHSTENCILVIEW:
  1282. pAssignment->DataSize = sizeof(SDepthStencilView);
  1283. break;
  1284. case D3D_SVT_RWTEXTURE1D:
  1285. case D3D_SVT_RWTEXTURE1DARRAY:
  1286. case D3D_SVT_RWTEXTURE2D:
  1287. case D3D_SVT_RWTEXTURE2DARRAY:
  1288. case D3D_SVT_RWTEXTURE3D:
  1289. case D3D_SVT_RWBUFFER:
  1290. case D3D_SVT_RWBYTEADDRESS_BUFFER:
  1291. case D3D_SVT_RWSTRUCTURED_BUFFER:
  1292. case D3D_SVT_APPEND_STRUCTURED_BUFFER:
  1293. case D3D_SVT_CONSUME_STRUCTURED_BUFFER:
  1294. pAssignment->DataSize = sizeof(SUnorderedAccessView);
  1295. break;
  1296. case D3D_SVT_INTERFACE_POINTER:
  1297. pAssignment->DataSize = sizeof(SInterface);
  1298. break;
  1299. default:
  1300. assert(0);
  1301. VHD( E_FAIL, "Internal loading error: invalid assignment type.");
  1302. }
  1303. uint32_t lhsStride;
  1304. if( g_lvGeneral[psAssignments[i].iState].m_Stride > 0 )
  1305. lhsStride = g_lvGeneral[psAssignments[i].iState].m_Stride;
  1306. else
  1307. lhsStride = pAssignment->DataSize;
  1308. // Store only the destination offset so that the backing store pointers can be easily fixed up later
  1309. pAssignment->Destination.Offset = g_lvGeneral[psAssignments[i].iState].m_Offset + lhsStride * psAssignments[i].Index;
  1310. // As a result, you should use pLHS in this function instead of the destination pointer
  1311. pLHS = pBackingStore + pAssignment->Destination.Offset;
  1312. switch (psAssignments[i].AssignmentType)
  1313. {
  1314. case ECAT_Constant: // e.g. LHS = 1; or LHS = nullptr;
  1315. uint32_t *pNumConstants;
  1316. SBinaryConstant *pConstants;
  1317. VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(uint32_t), (void**) &pNumConstants), "Invalid pEffectBuffer: cannot read NumConstants." );
  1318. VHD( m_msUnstructured.Read((void **)&pConstants, sizeof(SBinaryConstant) * (*pNumConstants)), "Invalid pEffectBuffer: cannot read constants." );
  1319. if(pAssignment->IsObjectAssignment())
  1320. {
  1321. // make sure this is a nullptr assignment
  1322. VBD( *pNumConstants == 1 && (pConstants[0].Type == EST_Int || pConstants[0].Type == EST_UInt) && pConstants[0].iValue == 0,
  1323. "Invalid pEffectBuffer: non-nullptr constant assignment to object.");
  1324. switch (pAssignment->LhsType)
  1325. {
  1326. case ELHS_DepthStencilBlock:
  1327. *((void **)pLHS) = &g_NullDepthStencil;
  1328. break;
  1329. case ELHS_BlendBlock:
  1330. *((void **)pLHS) = &g_NullBlend;
  1331. break;
  1332. case ELHS_RasterizerBlock:
  1333. *((void **)pLHS) = &g_NullRasterizer;
  1334. break;
  1335. case ELHS_VertexShaderBlock:
  1336. *((void **)pLHS) = &g_NullVS;
  1337. break;
  1338. case ELHS_PixelShaderBlock:
  1339. *((void **)pLHS) = &g_NullPS;
  1340. break;
  1341. case ELHS_GeometryShaderBlock:
  1342. *((void **)pLHS) = &g_NullGS;
  1343. break;
  1344. case ELHS_HullShaderBlock:
  1345. *((void **)pLHS) = &g_NullHS;
  1346. break;
  1347. case ELHS_DomainShaderBlock:
  1348. *((void **)pLHS) = &g_NullDS;
  1349. break;
  1350. case ELHS_ComputeShaderBlock:
  1351. *((void **)pLHS) = &g_NullCS;
  1352. break;
  1353. case ELHS_Texture:
  1354. *((void **)pLHS) = &g_NullTexture;
  1355. break;
  1356. case ELHS_DepthStencilView:
  1357. *((void **)pLHS) = &g_NullDepthStencilView;
  1358. break;
  1359. case ELHS_RenderTargetView:
  1360. *((void **)pLHS) = &g_NullRenderTargetView;
  1361. break;
  1362. default:
  1363. assert(0);
  1364. }
  1365. }
  1366. else
  1367. {
  1368. VBD( *pNumConstants == g_lvGeneral[psAssignments[i].iState].m_Cols, "Internal loading error: mismatch constant count." );
  1369. for (j = 0; j < *pNumConstants; ++ j)
  1370. {
  1371. VH( ExecuteConstantAssignment(pConstants + j, pLHS, g_lvGeneral[psAssignments[i].iState].m_Type) );
  1372. pLHS += SType::c_ScalarSize; // arrays of constants will always be regular scalar sized, never byte-sized
  1373. }
  1374. }
  1375. // Can get rid of this assignment
  1376. break;
  1377. case ECAT_Variable: // e.g. LHS = myVar;
  1378. VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, &pGlobalVarName), "Invalid pEffectBuffer: cannot read variable name." );
  1379. VBD( pVar = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find variable name." );
  1380. if (pAssignment->IsObjectAssignment())
  1381. {
  1382. VBD( pVar->pType->VarType == EVT_Object &&
  1383. GetSimpleParameterTypeFromObjectType(pVar->pType->ObjectType) == g_lvGeneral[psAssignments[i].iState].m_Type,
  1384. "Loading error: invalid variable type or object type." );
  1385. // Write directly into the state block's backing store
  1386. *((void **)pLHS) = pVar->Data.pGeneric;
  1387. // Now we can get rid of this assignment
  1388. }
  1389. else
  1390. {
  1391. VBD( pVar->pType->BelongsInConstantBuffer(), "Invalid pEffectBuffer: assignment type mismatch." );
  1392. pAssignment->DependencyCount = 1;
  1393. VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
  1394. pAssignment->pDependencies->pVariable = pVar;
  1395. // Store an offset for numeric values instead of a pointer so that it's easy to relocate it later
  1396. pAssignment->Source.Offset = pVar->Data.Offset;
  1397. pAssignment->AssignmentType = ERAT_NumericVariable;
  1398. // Can't get rid of this assignment
  1399. ++ finalAssignments;
  1400. }
  1401. break;
  1402. case ECAT_ConstIndex: // e.g. LHS = myGS[1]
  1403. SBinaryAssignment::SConstantIndex *psConstIndex;
  1404. VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psConstIndex), (void**) &psConstIndex),
  1405. "Invalid pEffectBuffer: cannot read assignment initializer." );
  1406. VHD( m_msUnstructured.ReadAtOffset(psConstIndex->oArrayName, &pGlobalVarName), "Invalid pEffectBuffer: cannot read array name." );
  1407. VBD( pVarArray = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find array name." );
  1408. if (pAssignment->IsObjectAssignment())
  1409. {
  1410. VBD( psConstIndex->Index < pVarArray->pType->Elements, "Invalid pEffectBuffer: out of bounds array index." );
  1411. VBD( pVarArray->pType->VarType == EVT_Object &&
  1412. GetSimpleParameterTypeFromObjectType(pVarArray->pType->ObjectType) == g_lvGeneral[psAssignments[i].iState].m_Type,
  1413. "Loading error: invalid variable type or object type." );
  1414. // Write directly into the state block's backing store
  1415. *((void **)pLHS) = GetBlockByIndex(pVarArray->pType->VarType, pVarArray->pType->ObjectType, pVarArray->Data.pGeneric, psConstIndex->Index);
  1416. VBD( nullptr != *((void **)pLHS), "Internal loading error: invalid block." );
  1417. // Now we can get rid of this assignment
  1418. }
  1419. else
  1420. {
  1421. VBD( pVarArray->pType->BelongsInConstantBuffer(), "Invalid pEffectBuffer: assignment type mismatch." );
  1422. pAssignment->DependencyCount = 1;
  1423. VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
  1424. pAssignment->pDependencies->pVariable = pVarArray;
  1425. CCheckedDword chkDataLen = psConstIndex->Index;
  1426. uint32_t dataLen;
  1427. chkDataLen *= SType::c_ScalarSize;
  1428. chkDataLen += pAssignment->DataSize;
  1429. VHD( chkDataLen.GetValue(&dataLen), "Overflow: assignment size." );
  1430. VBD( dataLen <= pVarArray->pType->TotalSize, "Internal loading error: assignment size mismatch" );
  1431. pAssignment->Source.Offset = pVarArray->Data.Offset + psConstIndex->Index * SType::c_ScalarSize;
  1432. // _NumericConstIndex is not used here because _NumericVariable
  1433. // does the same stuff in a more general fashion with no perf hit.
  1434. pAssignment->AssignmentType = ERAT_NumericVariable;
  1435. // Can't get rid of this assignment
  1436. ++ finalAssignments;
  1437. }
  1438. break;
  1439. case ECAT_VariableIndex: // e.g. LHS = myVar[numLights];
  1440. SBinaryAssignment::SVariableIndex *psVarIndex;
  1441. VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psVarIndex), (void**) &psVarIndex),
  1442. "Invalid pEffectBuffer: cannot read assignment initializer." );
  1443. VHD( m_msUnstructured.ReadAtOffset(psVarIndex->oArrayName, &pGlobalVarName), "Invalid pEffectBuffer: cannot read variable name." );
  1444. VBD( pVarArray = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find variable name." );
  1445. VHD( m_msUnstructured.ReadAtOffset(psVarIndex->oIndexVarName, &pGlobalVarName), "Invalid pEffectBuffer: cannot read index variable name." );
  1446. VBD( pVarIndex = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find index variable name." );
  1447. // Only support integer indices
  1448. VBD( pVarIndex->pType->VarType == EVT_Numeric && (pVarIndex->pType->NumericType.ScalarType == EST_Int || pVarIndex->pType->NumericType.ScalarType == EST_UInt),
  1449. "Invalid pEffectBuffer: invalid index variable type.");
  1450. VBD( pVarArray->pType->Elements > 0, "Invalid pEffectBuffer: array variable is not an array." );
  1451. pVarIndex->pCB->IsUsedByExpression = true;
  1452. if (pAssignment->IsObjectAssignment())
  1453. {
  1454. VBD( pVarArray->pType->VarType == EVT_Object &&
  1455. GetSimpleParameterTypeFromObjectType(pVarArray->pType->ObjectType) == g_lvGeneral[psAssignments[i].iState].m_Type,
  1456. "Loading error: invalid variable type or object type." );
  1457. // MaxElements is only 16-bits wide
  1458. VBD( pVarArray->pType->Elements <= 0xFFFF, "Internal error: array size is too large." );
  1459. pAssignment->MaxElements = pVarArray->pType->Elements;
  1460. pAssignment->DependencyCount = 1;
  1461. VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
  1462. pAssignment->pDependencies[0].pVariable = pVarIndex;
  1463. // Point this assignment to the start of the variable's object array.
  1464. // When this assignment is dirty, we write the value of this pointer plus
  1465. // the index given by its one dependency directly into the destination
  1466. pAssignment->Source = pVarArray->Data;
  1467. pAssignment->AssignmentType = ERAT_ObjectVariableIndex;
  1468. }
  1469. else
  1470. {
  1471. VBD( pVarArray->pType->BelongsInConstantBuffer(), "Invalid pEffectBuffer: assignment type mismatch." );
  1472. pAssignment->DependencyCount = 2;
  1473. VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
  1474. pAssignment->pDependencies[0].pVariable = pVarIndex;
  1475. pAssignment->pDependencies[1].pVariable = pVarArray;
  1476. // When pVarIndex is updated, we update the source pointer.
  1477. // When pVarArray is updated, we copy data from the source to the destination.
  1478. pAssignment->Source.pGeneric = nullptr;
  1479. pAssignment->AssignmentType = ERAT_NumericVariableIndex;
  1480. }
  1481. // Can't get rid of this assignment
  1482. ++ finalAssignments;
  1483. break;
  1484. case ECAT_ExpressionIndex:// e.g. LHS = myVar[a + b * c];
  1485. case ECAT_Expression: // e.g. LHS = a + b * c;
  1486. // we do not support FXLVM
  1487. VHD( E_NOTIMPL, "FXLVM Expressions (complex assignments like myVar[i*2]) are not supported in Effects11." );
  1488. break;
  1489. case ECAT_InlineShader:
  1490. case ECAT_InlineShader5:
  1491. uint32_t cbShaderBin;
  1492. uint8_t *pShaderBin;
  1493. SShaderBlock *pShaderBlock;
  1494. SAnonymousShader *pAnonShader;
  1495. union
  1496. {
  1497. SBinaryAssignment::SInlineShader *psInlineShader;
  1498. SBinaryShaderData5 *psInlineShader5;
  1499. };
  1500. // Inline shader assignments must be object types
  1501. assert(pAssignment->IsObjectAssignment());
  1502. C_ASSERT( offsetof(SBinaryAssignment::SInlineShader,oShader) == offsetof(SBinaryShaderData5,oShader) );
  1503. C_ASSERT( offsetof(SBinaryAssignment::SInlineShader,oSODecl) == offsetof(SBinaryShaderData5,oSODecls) );
  1504. if( psAssignments[i].AssignmentType == ECAT_InlineShader )
  1505. {
  1506. VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psInlineShader), (void**) &psInlineShader),
  1507. "Invalid pEffectBuffer: cannot read inline shader." );
  1508. }
  1509. else
  1510. {
  1511. VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psInlineShader5), (void**) &psInlineShader5),
  1512. "Invalid pEffectBuffer: cannot read inline shader." );
  1513. }
  1514. VBD( m_pEffect->m_ShaderBlockCount < m_pHeader->cTotalShaders, "Internal loading error: shader count is out incorrect." );
  1515. VBD( m_pEffect->m_AnonymousShaderCount < m_pHeader->cInlineShaders, "Internal loading error: anonymous shader count is out incorrect." );
  1516. pShaderBlock = &m_pEffect->m_pShaderBlocks[m_pEffect->m_ShaderBlockCount];
  1517. pAnonShader = &m_pEffect->m_pAnonymousShaders[m_pEffect->m_AnonymousShaderCount];
  1518. pAnonShader->pShaderBlock = pShaderBlock;
  1519. ++ m_pEffect->m_ShaderBlockCount;
  1520. ++ m_pEffect->m_AnonymousShaderCount;
  1521. // Write directly into the state block's backing store
  1522. *((void **)pLHS) = pShaderBlock;
  1523. VHD( GetUnstructuredDataBlock(psInlineShader->oShader, &cbShaderBin, (void **) &pShaderBin), "Invalid pEffectBuffer: cannot read inline shader block." );
  1524. if (cbShaderBin > 0)
  1525. {
  1526. VN( pShaderBlock->pReflectionData = PRIVATENEW SShaderBlock::SReflectionData );
  1527. pShaderBlock->pReflectionData->BytecodeLength = cbShaderBin;
  1528. pShaderBlock->pReflectionData->pBytecode = (uint8_t*) pShaderBin;
  1529. pShaderBlock->pReflectionData->pStreamOutDecls[0] =
  1530. pShaderBlock->pReflectionData->pStreamOutDecls[1] =
  1531. pShaderBlock->pReflectionData->pStreamOutDecls[2] =
  1532. pShaderBlock->pReflectionData->pStreamOutDecls[3] = nullptr;
  1533. pShaderBlock->pReflectionData->RasterizedStream = 0;
  1534. pShaderBlock->pReflectionData->IsNullGS = FALSE;
  1535. pShaderBlock->pReflectionData->pReflection = nullptr;
  1536. pShaderBlock->pReflectionData->InterfaceParameterCount = 0;
  1537. pShaderBlock->pReflectionData->pInterfaceParameters = nullptr;
  1538. }
  1539. switch (pAssignment->LhsType)
  1540. {
  1541. case ELHS_PixelShaderBlock:
  1542. pShaderBlock->pVT = &g_vtPS;
  1543. VBD( psInlineShader->oSODecl == 0, "Internal loading error: pixel shaders cannot have stream out decls." );
  1544. break;
  1545. case ELHS_GeometryShaderBlock:
  1546. pShaderBlock->pVT = &g_vtGS;
  1547. if( psAssignments[i].AssignmentType == ECAT_InlineShader )
  1548. {
  1549. if (psInlineShader->oSODecl)
  1550. {
  1551. // This is a GS with SO
  1552. VHD( GetStringAndAddToReflection(psInlineShader->oSODecl, &pShaderBlock->pReflectionData->pStreamOutDecls[0]),
  1553. "Invalid pEffectBuffer: cannot read SO decl." );
  1554. }
  1555. }
  1556. else
  1557. {
  1558. // This is a GS with addressable stream out
  1559. for( size_t iDecl=0; iDecl < psInlineShader5->cSODecls; ++iDecl )
  1560. {
  1561. if (psInlineShader5->oSODecls[iDecl])
  1562. {
  1563. VHD( GetStringAndAddToReflection(psInlineShader5->oSODecls[iDecl], &pShaderBlock->pReflectionData->pStreamOutDecls[iDecl]),
  1564. "Invalid pEffectBuffer: cannot read SO decl." );
  1565. }
  1566. }
  1567. pShaderBlock->pReflectionData->RasterizedStream = psInlineShader5->RasterizedStream;
  1568. }
  1569. break;
  1570. case ELHS_VertexShaderBlock:
  1571. pShaderBlock->pVT = &g_vtVS;
  1572. VBD( psInlineShader->oSODecl == 0, "Internal loading error: vertex shaders cannot have stream out decls." );
  1573. break;
  1574. case ELHS_HullShaderBlock:
  1575. pShaderBlock->pVT = &g_vtHS;
  1576. VBD( psInlineShader->oSODecl == 0, "Internal loading error: hull shaders cannot have stream out decls." );
  1577. break;
  1578. case ELHS_DomainShaderBlock:
  1579. pShaderBlock->pVT = &g_vtDS;
  1580. VBD( psInlineShader->oSODecl == 0, "Internal loading error: domain shaders cannot have stream out decls." );
  1581. break;
  1582. case ELHS_ComputeShaderBlock:
  1583. pShaderBlock->pVT = &g_vtCS;
  1584. VBD( psInlineShader->oSODecl == 0, "Internal loading error: compute shaders cannot have stream out decls." );
  1585. break;
  1586. case ELHS_GeometryShaderSO:
  1587. assert(0); // Should never happen
  1588. default:
  1589. VHD( E_FAIL, "Internal loading error: invalid shader type." );
  1590. }
  1591. if( psAssignments[i].AssignmentType == ECAT_InlineShader5 )
  1592. {
  1593. pShaderBlock->pReflectionData->InterfaceParameterCount = psInlineShader5->cInterfaceBindings;
  1594. VH( GetInterfaceParametersAndAddToReflection( psInlineShader5->cInterfaceBindings, psInlineShader5->oInterfaceBindings, &pShaderBlock->pReflectionData->pInterfaceParameters ) );
  1595. }
  1596. // Now we can get rid of this assignment
  1597. break;
  1598. default:
  1599. assert(0);
  1600. }
  1601. }
  1602. *pFinalAssignments = finalAssignments;
  1603. if (pRTVAssignments)
  1604. *pRTVAssignments = renderTargetViewAssns;
  1605. lExit:
  1606. return hr;
  1607. }
  1608. // Read info from the compiled blob and initialize an object variable
  1609. HRESULT CEffectLoader::LoadObjectVariables()
  1610. {
  1611. HRESULT hr = S_OK;
  1612. size_t cBlocks = m_pHeader->Effect.cObjectVariables;
  1613. for (size_t iBlock=0; iBlock<cBlocks; iBlock++)
  1614. {
  1615. SBinaryObjectVariable *psBlock;
  1616. SGlobalVariable *pVar;
  1617. SType *pType;
  1618. uint32_t elementsToRead;
  1619. CCheckedDword chkElementsTotal;
  1620. uint32_t elementsTotal;
  1621. // Read variable info
  1622. VHD( m_msStructured.Read((void**) &psBlock, sizeof(*psBlock)), "Invalid pEffectBuffer: cannot read object variable." );
  1623. VBD( m_pEffect->m_VariableCount < (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables),
  1624. "Internal loading error: variable count mismatch." );
  1625. pVar = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
  1626. // Get type
  1627. VH( LoadTypeAndAddToPool(&pType, psBlock->oType) );
  1628. // Make sure the right polymorphic type is created
  1629. VH( PlacementNewVariable(pVar, pType, false) );
  1630. pVar->pEffect = m_pEffect;
  1631. pVar->pType = pType;
  1632. pVar->pCB = nullptr;
  1633. pVar->ExplicitBindPoint = psBlock->ExplicitBindPoint;
  1634. if( pType->IsStateBlockObject() )
  1635. {
  1636. pVar->MemberDataOffsetPlus4 = m_pEffect->m_MemberDataCount * sizeof(SMemberDataPointer) + 4;
  1637. m_pEffect->m_MemberDataCount += std::max<uint32_t>(pType->Elements,1);
  1638. }
  1639. // Get name
  1640. VHD( GetStringAndAddToReflection(psBlock->oName, &pVar->pName), "Invalid pEffectBuffer: cannot read object variable name." );
  1641. VHD( GetStringAndAddToReflection(psBlock->oSemantic, &pVar->pSemantic), "Invalid pEffectBuffer: cannot read object variable semantic." );
  1642. m_pEffect->m_VariableCount++;
  1643. elementsToRead = std::max<uint32_t>(1, pType->Elements);
  1644. chkElementsTotal = elementsToRead;
  1645. if (pType->IsStateBlockObject())
  1646. {
  1647. // State blocks
  1648. EBlockType blockType;
  1649. uint32_t *maxBlockCount;
  1650. uint32_t *currentBlockCount;
  1651. switch (pType->ObjectType)
  1652. {
  1653. case EOT_Blend:
  1654. pVar->Data.pBlock = &m_pEffect->m_pBlendBlocks[m_pEffect->m_BlendBlockCount];
  1655. maxBlockCount = &m_pHeader->cBlendStateBlocks;
  1656. currentBlockCount = &m_pEffect->m_BlendBlockCount;
  1657. blockType = EBT_Blend;
  1658. break;
  1659. case EOT_DepthStencil:
  1660. pVar->Data.pBlock = &m_pEffect->m_pDepthStencilBlocks[m_pEffect->m_DepthStencilBlockCount];
  1661. maxBlockCount = &m_pHeader->cDepthStencilBlocks;
  1662. currentBlockCount = &m_pEffect->m_DepthStencilBlockCount;
  1663. blockType = EBT_DepthStencil;
  1664. break;
  1665. case EOT_Rasterizer:
  1666. pVar->Data.pBlock = &m_pEffect->m_pRasterizerBlocks[m_pEffect->m_RasterizerBlockCount];
  1667. maxBlockCount = &m_pHeader->cRasterizerStateBlocks;
  1668. currentBlockCount = &m_pEffect->m_RasterizerBlockCount;
  1669. blockType = EBT_Rasterizer;
  1670. break;
  1671. default:
  1672. VB(pType->IsSampler());
  1673. pVar->Data.pBlock = &m_pEffect->m_pSamplerBlocks[m_pEffect->m_SamplerBlockCount];
  1674. maxBlockCount = &m_pHeader->cSamplers;
  1675. currentBlockCount = &m_pEffect->m_SamplerBlockCount;
  1676. blockType = EBT_Sampler;
  1677. }
  1678. chkElementsTotal += *currentBlockCount;
  1679. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: vaiable elements." );
  1680. VBD( elementsTotal <= *maxBlockCount, "Internal loading error: element count overflow." );
  1681. *currentBlockCount += elementsToRead;
  1682. for (uint32_t iElement = 0; iElement < elementsToRead; ++ iElement)
  1683. {
  1684. SBaseBlock *pCurrentBlock;
  1685. uint32_t cAssignments;
  1686. pCurrentBlock = (SBaseBlock *) GetBlockByIndex(pVar->pType->VarType, pVar->pType->ObjectType, pVar->Data.pGeneric, iElement);
  1687. VBD( nullptr != pCurrentBlock, "Internal loading error: find state block." );
  1688. pCurrentBlock->BlockType = blockType;
  1689. VHD( m_msStructured.Read(&cAssignments), "Invalid pEffectBuffer: cannot read state block assignments." );
  1690. VH( LoadAssignments( cAssignments, &pCurrentBlock->pAssignments, (uint8_t*)pCurrentBlock, nullptr, &pCurrentBlock->AssignmentCount ) );
  1691. }
  1692. }
  1693. else if (pType->IsShader())
  1694. {
  1695. // Shaders
  1696. chkElementsTotal += m_pEffect->m_ShaderBlockCount;
  1697. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: shader block count." );
  1698. VBD( elementsTotal <= m_pHeader->cTotalShaders, "Invalid pEffectBuffer: shader count mismatch." );
  1699. pVar->Data.pShader = &m_pEffect->m_pShaderBlocks[m_pEffect->m_ShaderBlockCount];
  1700. for (size_t iElement=0; iElement<elementsToRead; iElement++)
  1701. {
  1702. uint32_t cbShaderBin;
  1703. void *pShaderBin;
  1704. SShaderBlock *pShaderBlock;
  1705. union
  1706. {
  1707. uint32_t *pOffset;
  1708. SBinaryGSSOInitializer *psInlineGSSO4;
  1709. SBinaryShaderData5 *psInlineShader5;
  1710. };
  1711. C_ASSERT( offsetof(SBinaryGSSOInitializer,oShader) == 0 );
  1712. C_ASSERT( offsetof(SBinaryShaderData5,oShader) == 0 );
  1713. pShaderBlock = &m_pEffect->m_pShaderBlocks[m_pEffect->m_ShaderBlockCount];
  1714. m_pEffect->m_ShaderBlockCount++;
  1715. // Get shader binary
  1716. switch (pType->ObjectType)
  1717. {
  1718. case EOT_VertexShader:
  1719. case EOT_GeometryShader:
  1720. case EOT_PixelShader:
  1721. VHD( m_msStructured.Read((void**)&pOffset, sizeof(*pOffset)), "Invalid pEffectBuffer: cannot read shader block." );
  1722. break;
  1723. case EOT_GeometryShaderSO:
  1724. VHD( m_msStructured.Read((void**)&psInlineGSSO4, sizeof(*psInlineGSSO4)), "Invalid pEffectBuffer: cannot read inline GS with SO." );
  1725. break;
  1726. case EOT_VertexShader5:
  1727. case EOT_GeometryShader5:
  1728. case EOT_HullShader5:
  1729. case EOT_DomainShader5:
  1730. case EOT_PixelShader5:
  1731. case EOT_ComputeShader5:
  1732. VHD( m_msStructured.Read((void**)&psInlineShader5, sizeof(*psInlineShader5)), "Invalid pEffectBuffer: cannot read inline shader." );
  1733. break;
  1734. default:
  1735. VH( E_FAIL );
  1736. }
  1737. VHD( GetUnstructuredDataBlock(*pOffset, &cbShaderBin, &pShaderBin), "Invalid pEffectBuffer: cannot read shader byte code." );
  1738. if (cbShaderBin > 0)
  1739. {
  1740. VN( pShaderBlock->pReflectionData = PRIVATENEW SShaderBlock::SReflectionData );
  1741. pShaderBlock->pReflectionData->BytecodeLength = cbShaderBin;
  1742. pShaderBlock->pReflectionData->pBytecode = (uint8_t*) pShaderBin;
  1743. pShaderBlock->pReflectionData->pStreamOutDecls[0] =
  1744. pShaderBlock->pReflectionData->pStreamOutDecls[1] =
  1745. pShaderBlock->pReflectionData->pStreamOutDecls[2] =
  1746. pShaderBlock->pReflectionData->pStreamOutDecls[3] = nullptr;
  1747. pShaderBlock->pReflectionData->RasterizedStream = 0;
  1748. pShaderBlock->pReflectionData->IsNullGS = FALSE;
  1749. pShaderBlock->pReflectionData->pReflection = nullptr;
  1750. pShaderBlock->pReflectionData->InterfaceParameterCount = 0;
  1751. pShaderBlock->pReflectionData->pInterfaceParameters = nullptr;
  1752. }
  1753. switch (pType->ObjectType)
  1754. {
  1755. case EOT_PixelShader:
  1756. pShaderBlock->pVT = &g_vtPS;
  1757. break;
  1758. case EOT_GeometryShaderSO:
  1759. // Get StreamOut decl
  1760. //VH( m_msStructured.Read(&dwOffset) );
  1761. if (cbShaderBin > 0)
  1762. {
  1763. VHD( GetStringAndAddToReflection(psInlineGSSO4->oSODecl, &pShaderBlock->pReflectionData->pStreamOutDecls[0]),
  1764. "Invalid pEffectBuffer: cannot read stream out decl." );
  1765. }
  1766. pShaderBlock->pVT = &g_vtGS;
  1767. break;
  1768. case EOT_VertexShader5:
  1769. case EOT_GeometryShader5:
  1770. case EOT_HullShader5:
  1771. case EOT_DomainShader5:
  1772. case EOT_PixelShader5:
  1773. case EOT_ComputeShader5:
  1774. // Get StreamOut decls
  1775. if (cbShaderBin > 0)
  1776. {
  1777. for( size_t iDecl=0; iDecl < psInlineShader5->cSODecls; ++iDecl )
  1778. {
  1779. VHD( GetStringAndAddToReflection(psInlineShader5->oSODecls[iDecl], &pShaderBlock->pReflectionData->pStreamOutDecls[iDecl]),
  1780. "Invalid pEffectBuffer: cannot read stream out decls." );
  1781. }
  1782. pShaderBlock->pReflectionData->RasterizedStream = psInlineShader5->RasterizedStream;
  1783. pShaderBlock->pReflectionData->InterfaceParameterCount = psInlineShader5->cInterfaceBindings;
  1784. VH( GetInterfaceParametersAndAddToReflection( psInlineShader5->cInterfaceBindings, psInlineShader5->oInterfaceBindings, &pShaderBlock->pReflectionData->pInterfaceParameters ) );
  1785. }
  1786. switch (pType->ObjectType)
  1787. {
  1788. case EOT_VertexShader5:
  1789. pShaderBlock->pVT = &g_vtVS;
  1790. break;
  1791. case EOT_GeometryShader5:
  1792. pShaderBlock->pVT = &g_vtGS;
  1793. break;
  1794. case EOT_HullShader5:
  1795. pShaderBlock->pVT = &g_vtHS;
  1796. break;
  1797. case EOT_DomainShader5:
  1798. pShaderBlock->pVT = &g_vtDS;
  1799. break;
  1800. case EOT_PixelShader5:
  1801. pShaderBlock->pVT = &g_vtPS;
  1802. break;
  1803. case EOT_ComputeShader5:
  1804. pShaderBlock->pVT = &g_vtCS;
  1805. break;
  1806. default:
  1807. VH( E_FAIL );
  1808. }
  1809. break;
  1810. case EOT_GeometryShader:
  1811. pShaderBlock->pVT = &g_vtGS;
  1812. break;
  1813. case EOT_VertexShader:
  1814. pShaderBlock->pVT = &g_vtVS;
  1815. break;
  1816. default:
  1817. VHD( E_FAIL, "Invalid pEffectBuffer: invalid shader type." );
  1818. }
  1819. }
  1820. }
  1821. else if (pType->IsObjectType(EOT_String))
  1822. {
  1823. // Strings
  1824. chkElementsTotal += m_pEffect->m_StringCount;
  1825. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: string object count." );
  1826. VBD( elementsTotal <= m_pHeader->cStrings, "Invalid pEffectBuffer: string count mismatch." );
  1827. pVar->Data.pString = &m_pEffect->m_pStrings[m_pEffect->m_StringCount];
  1828. for (size_t iElement=0; iElement<elementsToRead; iElement++)
  1829. {
  1830. uint32_t dwOffset;
  1831. SString *pString;
  1832. pString = &m_pEffect->m_pStrings[m_pEffect->m_StringCount];
  1833. m_pEffect->m_StringCount++;
  1834. // Get string
  1835. VHD( m_msStructured.Read(&dwOffset), "Invalid pEffectBuffer: cannot read string offset." );
  1836. VHD( GetStringAndAddToReflection(dwOffset, &pString->pString), "Invalid pEffectBuffer: cannot read string." );
  1837. }
  1838. }
  1839. else if (pType->IsShaderResource())
  1840. {
  1841. // Textures/buffers
  1842. chkElementsTotal += m_pEffect->m_ShaderResourceCount;
  1843. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: SRV object count." );
  1844. VBD( elementsTotal <= m_pHeader->cShaderResources, "Invalid pEffectBuffer: SRV count mismatch." );
  1845. pVar->Data.pShaderResource = &m_pEffect->m_pShaderResources[m_pEffect->m_ShaderResourceCount];
  1846. m_pEffect->m_ShaderResourceCount += elementsToRead;
  1847. }
  1848. else if (pType->IsUnorderedAccessView())
  1849. {
  1850. // UnorderedAccessViews
  1851. chkElementsTotal += m_pEffect->m_UnorderedAccessViewCount;
  1852. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: UAV object count." );
  1853. VBD( elementsTotal <= m_pHeader->cUnorderedAccessViews, "Invalid pEffectBuffer: UAV count mismatch." );
  1854. pVar->Data.pUnorderedAccessView = &m_pEffect->m_pUnorderedAccessViews[m_pEffect->m_UnorderedAccessViewCount];
  1855. m_pEffect->m_UnorderedAccessViewCount += elementsToRead;
  1856. }
  1857. else if (pType->IsRenderTargetView())
  1858. {
  1859. // RenderTargets
  1860. chkElementsTotal += m_pEffect->m_RenderTargetViewCount;
  1861. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: RTV object count." );
  1862. VBD( elementsTotal <= m_pHeader->cRenderTargetViews, "Invalid pEffectBuffer: RTV count mismatch." );
  1863. pVar->Data.pRenderTargetView = &m_pEffect->m_pRenderTargetViews[m_pEffect->m_RenderTargetViewCount];
  1864. m_pEffect->m_RenderTargetViewCount += elementsToRead;
  1865. }
  1866. else if (pType->IsDepthStencilView())
  1867. {
  1868. // DepthStencilViews
  1869. chkElementsTotal += m_pEffect->m_DepthStencilViewCount;
  1870. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: DSV object count." );
  1871. VBD( elementsTotal <= m_pHeader->cDepthStencilViews, "Invalid pEffectBuffer: DSV count mismatch." );
  1872. pVar->Data.pDepthStencilView = &m_pEffect->m_pDepthStencilViews[m_pEffect->m_DepthStencilViewCount];
  1873. m_pEffect->m_DepthStencilViewCount += elementsToRead;
  1874. }
  1875. else
  1876. {
  1877. VHD( E_FAIL, "Invalid pEffectBuffer: DSV count mismatch." );
  1878. }
  1879. // Read annotations
  1880. VH( LoadAnnotations(&pVar->AnnotationCount, &pVar->pAnnotations) );
  1881. }
  1882. lExit:
  1883. return hr;
  1884. }
  1885. // Read info from the compiled blob and initialize an interface variable
  1886. HRESULT CEffectLoader::LoadInterfaceVariables()
  1887. {
  1888. HRESULT hr = S_OK;
  1889. uint32_t iBlock;
  1890. uint32_t cBlocks;
  1891. cBlocks = m_pHeader->cInterfaceVariables;
  1892. for (iBlock=0; iBlock<cBlocks; iBlock++)
  1893. {
  1894. SBinaryInterfaceVariable *psBlock;
  1895. SGlobalVariable *pVar;
  1896. SType *pType;
  1897. uint32_t elementsToRead;
  1898. CCheckedDword chkElementsTotal;
  1899. uint32_t elementsTotal;
  1900. void *pDefaultValue;
  1901. // Read variable info
  1902. VHD( m_msStructured.Read((void**) &psBlock, sizeof(*psBlock)), "Invalid pEffectBuffer: cannot read interface block." );
  1903. VBD( m_pEffect->m_VariableCount < (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables),
  1904. "Internal loading error: variable count mismatch." );
  1905. pVar = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
  1906. // Get type
  1907. VH( LoadTypeAndAddToPool(&pType, psBlock->oType) );
  1908. // Make sure the right polymorphic type is created
  1909. VH( PlacementNewVariable(pVar, pType, false) );
  1910. pVar->pEffect = m_pEffect;
  1911. pVar->pType = pType;
  1912. pVar->pCB = nullptr;
  1913. pVar->ExplicitBindPoint = (uint32_t)-1;
  1914. pVar->pSemantic = nullptr;
  1915. // Get name
  1916. VHD( GetStringAndAddToReflection(psBlock->oName, &pVar->pName), "Invalid pEffectBuffer: cannot read interface name." );
  1917. m_pEffect->m_VariableCount++;
  1918. elementsToRead = std::max<uint32_t>(1, pType->Elements);
  1919. chkElementsTotal = elementsToRead;
  1920. VBD( pType->IsInterface(), "Internal loading error: invlaid type for interface." );
  1921. chkElementsTotal += m_pEffect->m_InterfaceCount;
  1922. VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: interface count." );
  1923. VBD( elementsTotal <= m_pHeader->cInterfaceVariableElements, "Invalid pEffectBuffer: interface count mismatch." );
  1924. pVar->Data.pInterface = &m_pEffect->m_pInterfaces[m_pEffect->m_InterfaceCount];
  1925. m_pEffect->m_InterfaceCount += elementsToRead;
  1926. // Get default value
  1927. if (0 != psBlock->oDefaultValue)
  1928. {
  1929. VHD( m_msUnstructured.ReadAtOffset(psBlock->oDefaultValue, elementsToRead * sizeof(SBinaryInterfaceInitializer), &pDefaultValue),
  1930. "Invalid pEffectBuffer: cannot read interface initializer offset." );
  1931. for( size_t i=0; i < elementsToRead; i++ )
  1932. {
  1933. SBinaryInterfaceInitializer* pInterfaceInit = &((SBinaryInterfaceInitializer*)pDefaultValue)[i];
  1934. LPCSTR pClassInstanceName;
  1935. VHD( m_msUnstructured.ReadAtOffset(pInterfaceInit->oInstanceName, &pClassInstanceName), "Invalid pEffectBuffer: cannot read interface initializer." );
  1936. SGlobalVariable *pCIVariable = m_pEffect->FindVariableByName(pClassInstanceName);
  1937. VBD( pCIVariable != nullptr, "Loading error: cannot find class instance for interface initializer." );
  1938. VBD( pCIVariable->pType->IsClassInstance(), "Loading error: variable type mismatch for interface initializer." );
  1939. if( pInterfaceInit->ArrayIndex == (uint32_t)-1 )
  1940. {
  1941. VBD( pCIVariable->pType->Elements == 0, "Loading error: array mismatch for interface initializer." );
  1942. pVar->Data.pInterface[i].pClassInstance = (SClassInstanceGlobalVariable*)pCIVariable;
  1943. }
  1944. else
  1945. {
  1946. VBD( pCIVariable->pType->Elements > 0, "Loading error: array mismatch for interface initializer." );
  1947. VBD( pInterfaceInit->ArrayIndex < pCIVariable->pType->Elements, "Loading error: array index out of range." );
  1948. SMember* pMember = (SMember*)pCIVariable->GetElement( pInterfaceInit->ArrayIndex );
  1949. VBD( pMember->IsValid(), "Loading error: cannot find member by name." );
  1950. VBD( pMember->pType->IsClassInstance(), "Loading error: member type mismatch for interface initializer." );
  1951. pVar->Data.pInterface[i].pClassInstance = (SClassInstanceGlobalVariable*)pMember;
  1952. }
  1953. }
  1954. }
  1955. // Read annotations
  1956. VH( LoadAnnotations(&pVar->AnnotationCount, &pVar->pAnnotations) );
  1957. }
  1958. lExit:
  1959. return hr;
  1960. }
  1961. // Read info from the compiled blob and initialize a group (and contained techniques and passes)
  1962. HRESULT CEffectLoader::LoadGroups()
  1963. {
  1964. HRESULT hr = S_OK;
  1965. uint32_t TechniquesInEffect = 0;
  1966. for( size_t iGroup=0; iGroup<m_pHeader->cGroups; iGroup++ )
  1967. {
  1968. SGroup *pGroup = &m_pEffect->m_pGroups[iGroup];
  1969. SBinaryGroup *psGroup;
  1970. // Read group info
  1971. VHD( m_msStructured.Read((void**) &psGroup, sizeof(*psGroup)), "Invalid pEffectBuffer: cannot read group." );
  1972. pGroup->TechniqueCount = psGroup->cTechniques;
  1973. VN( pGroup->pTechniques = PRIVATENEW STechnique[pGroup->TechniqueCount] );
  1974. VHD( GetStringAndAddToReflection(psGroup->oName, &pGroup->pName), "Invalid pEffectBuffer: cannot read group name." );
  1975. if( pGroup->pName == nullptr )
  1976. {
  1977. VBD( m_pEffect->m_pNullGroup == nullptr, "Internal loading error: multiple nullptr groups." );
  1978. m_pEffect->m_pNullGroup = pGroup;
  1979. }
  1980. // Read annotations
  1981. VH( LoadAnnotations(&pGroup->AnnotationCount, &pGroup->pAnnotations) );
  1982. for( size_t iTechnique=0; iTechnique < psGroup->cTechniques; iTechnique++ )
  1983. {
  1984. VH( LoadTechnique( &pGroup->pTechniques[iTechnique] ) );
  1985. }
  1986. TechniquesInEffect += psGroup->cTechniques;
  1987. }
  1988. VBD( TechniquesInEffect == m_pHeader->cTechniques, "Loading error: technique count mismatch." );
  1989. m_pEffect->m_TechniqueCount = m_pHeader->cTechniques;
  1990. m_pEffect->m_GroupCount = m_pHeader->cGroups;
  1991. lExit:
  1992. return hr;
  1993. }
  1994. // Read info from the compiled blob and initialize a technique (and contained passes)
  1995. HRESULT CEffectLoader::LoadTechnique( STechnique* pTech )
  1996. {
  1997. HRESULT hr = S_OK;
  1998. uint32_t iPass;
  1999. SBinaryTechnique *psTech;
  2000. // Read technique info
  2001. VHD( m_msStructured.Read((void**) &psTech, sizeof(*psTech)), "Invalid pEffectBuffer: cannot read technique." );
  2002. pTech->PassCount = psTech->cPasses;
  2003. VN( pTech->pPasses = PRIVATENEW SPassBlock[pTech->PassCount] );
  2004. VHD( GetStringAndAddToReflection(psTech->oName, &pTech->pName), "Invalid pEffectBuffer: cannot read technique name." );
  2005. // Read annotations
  2006. VH( LoadAnnotations(&pTech->AnnotationCount, &pTech->pAnnotations) );
  2007. for (iPass=0; iPass<psTech->cPasses; iPass++)
  2008. {
  2009. SBinaryPass *psPass;
  2010. SPassBlock *pPass = &pTech->pPasses[iPass];
  2011. // Read pass info
  2012. VHD( m_msStructured.Read((void**) &psPass, sizeof(SBinaryPass)), "Invalid pEffectBuffer: cannot read pass." );
  2013. VHD( GetStringAndAddToReflection(psPass->oName, &pPass->pName), "Invalid pEffectBuffer: cannot read pass name." );
  2014. // Read annotations
  2015. VH( LoadAnnotations(&pPass->AnnotationCount, &pPass->pAnnotations) );
  2016. VH( LoadAssignments( psPass->cAssignments, &pPass->pAssignments, (uint8_t*)pPass, &pPass->BackingStore.RenderTargetViewCount, &pPass->AssignmentCount ) );
  2017. VBD( pPass->BackingStore.RenderTargetViewCount <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, "Invalid pEffectBuffer: too many RTVs in pass." );
  2018. // Initialize other pass information
  2019. pPass->pEffect = m_pEffect;
  2020. pPass->BlockType = EBT_Pass;
  2021. }
  2022. lExit:
  2023. return hr;
  2024. }
  2025. // Read info from the compiled blob and initialize a set of annotations
  2026. HRESULT CEffectLoader::LoadAnnotations(uint32_t *pcAnnotations, SAnnotation **ppAnnotations)
  2027. {
  2028. HRESULT hr = S_OK;
  2029. uint32_t cAnnotations, i, oData;
  2030. SAnnotation *pAnnotations = nullptr;
  2031. VHD( m_msStructured.Read(&cAnnotations), "Invalid pEffectBuffer: cannot read anootation count." );
  2032. if (cAnnotations)
  2033. {
  2034. uint32_t annotationsSize;
  2035. CCheckedDword chkAnnotationsSize;
  2036. chkAnnotationsSize = cAnnotations;
  2037. chkAnnotationsSize *= sizeof(SAnnotation);
  2038. VHD( chkAnnotationsSize.GetValue(&annotationsSize), "Overflow in annotations." );
  2039. // we allocate raw bytes for annotations because they are polymorphic types that need to be placement new'ed
  2040. VN( pAnnotations = (SAnnotation *) PRIVATENEW uint8_t[annotationsSize] );
  2041. for (i=0; i<cAnnotations; i++)
  2042. {
  2043. SBinaryAnnotation *psAnnotation;
  2044. SAnnotation *pAn = &pAnnotations[i];
  2045. SType *pType;
  2046. VHD( m_msStructured.Read((void**) &psAnnotation, sizeof(SBinaryAnnotation)), "Invalid pEffectBuffer: cannot read annotation." );
  2047. VH( LoadTypeAndAddToPool(&pType, psAnnotation->oType) );
  2048. // Make sure the right polymorphic type is created
  2049. VH( PlacementNewVariable(pAn, pType, true) );
  2050. pAn->pEffect = m_pEffect;
  2051. pAn->pType = pType;
  2052. VHD( GetStringAndAddToReflection(psAnnotation->oName, &pAn->pName), "Invalid pEffectBuffer: cannot read annotation name." );
  2053. if (pType->IsObjectType(EOT_String))
  2054. {
  2055. uint32_t cElements = std::max<uint32_t>(1, pType->Elements);
  2056. uint32_t j;
  2057. VN( pAn->Data.pString = PRIVATENEW SString[cElements] );
  2058. for (j = 0; j < cElements; ++ j)
  2059. {
  2060. // Read initializer offset
  2061. VHD( m_msStructured.Read(&oData), "Invalid pEffectBuffer: cannot read string." );
  2062. #pragma warning( disable : 6011 )
  2063. VHD( GetStringAndAddToReflection(oData, &pAn->Data.pString[j].pString), "Invalid pEffectBuffer: cannot read string initializer." );
  2064. }
  2065. }
  2066. else if (pType->BelongsInConstantBuffer())
  2067. {
  2068. void *pDefaultValue;
  2069. uint32_t bytesUnpacked;
  2070. // Read initializer offset
  2071. VHD( m_msStructured.Read(&oData), "Invalid pEffectBuffer: cannot read annotation." );
  2072. VBD( oData != 0, "Invalid pEffectBuffer: invalid anotation offset." );
  2073. VN( pAn->Data.pGeneric = PRIVATENEW uint8_t[pType->TotalSize] );
  2074. ZeroMemory(pAn->Data.pGeneric, pType->TotalSize);
  2075. VHD( m_msUnstructured.ReadAtOffset(oData, pType->PackedSize, &pDefaultValue), "Invalid pEffectBuffer: cannot read variable default value." );
  2076. VH( UnpackData((uint8_t*) pAn->Data.pGeneric, (uint8_t*) pDefaultValue, pType->PackedSize, pType, &bytesUnpacked) );
  2077. VBD( bytesUnpacked == pType->PackedSize, "Invalid pEffectBuffer: packed sizes to not match." );
  2078. }
  2079. else
  2080. {
  2081. VHD( E_FAIL, "Invalid pEffectBuffer: invalid annotation type." );
  2082. }
  2083. }
  2084. }
  2085. *pcAnnotations = cAnnotations;
  2086. *ppAnnotations = pAnnotations;
  2087. lExit:
  2088. return hr;
  2089. }
  2090. //////////////////////////////////////////////////////////////////////////
  2091. // Build shader block dependencies from shader metadata
  2092. //////////////////////////////////////////////////////////////////////////
  2093. //
  2094. // Grabs shader resource dependency information from the bytecode of the shader
  2095. // (cbuffer, tbuffer, texture, buffer, sampler, and UAV dependencies),
  2096. // and sets up the given SShaderBlock to point to the dependencies within the effect
  2097. //
  2098. HRESULT CEffectLoader::GrabShaderData(SShaderBlock *pShaderBlock)
  2099. {
  2100. HRESULT hr = S_OK;
  2101. CEffectVector<SRange> vRanges[ER_Count], *pvRange;
  2102. SRange *pRange = nullptr;
  2103. CEffectVector<SConstantBuffer*> vTBuffers;
  2104. //////////////////////////////////////////////////////////////////////////
  2105. // Step 1: iterate through the resource binding structures and build
  2106. // an "optimized" list of all of the dependencies
  2107. D3D11_SHADER_DESC ShaderDesc;
  2108. hr = pShaderBlock->pReflectionData->pReflection->GetDesc( &ShaderDesc );
  2109. if ( FAILED(hr) )
  2110. return hr;
  2111. // Since we have the shader desc, let's find out if this is a nullptr GS
  2112. if( D3D11_SHVER_GET_TYPE( ShaderDesc.Version ) == D3D11_SHVER_VERTEX_SHADER && pShaderBlock->GetShaderType() == EOT_GeometryShader )
  2113. {
  2114. pShaderBlock->pReflectionData->IsNullGS = true;
  2115. }
  2116. pShaderBlock->CBDepCount = pShaderBlock->ResourceDepCount = pShaderBlock->TBufferDepCount = pShaderBlock->SampDepCount = 0;
  2117. pShaderBlock->UAVDepCount = pShaderBlock->InterfaceDepCount = 0;
  2118. for(uint32_t i = 0; i < ShaderDesc.BoundResources; i++)
  2119. {
  2120. LPCSTR pName;
  2121. uint32_t bindPoint, size;
  2122. ERanges eRange = ER_CBuffer;
  2123. SShaderResource *pShaderResource = nullptr;
  2124. SUnorderedAccessView *pUnorderedAccessView = nullptr;
  2125. SSamplerBlock *pSampler = nullptr;
  2126. SConstantBuffer *pCB = nullptr;
  2127. SVariable *pVariable = nullptr;
  2128. bool isFX9TextureLoad = false;
  2129. D3D11_SHADER_INPUT_BIND_DESC ResourceDesc;
  2130. pShaderBlock->pReflectionData->pReflection->GetResourceBindingDesc( i, &ResourceDesc );
  2131. // HUGE ASSUMPTION: the bindpoints we read in the shader metadata are sorted;
  2132. // i.e. bindpoints are steadily increasing
  2133. // If this assumption is not met, then we will hit an assert below
  2134. pName = ResourceDesc.Name;
  2135. bindPoint = ResourceDesc.BindPoint;
  2136. size = ResourceDesc.BindCount;
  2137. switch( ResourceDesc.Type )
  2138. {
  2139. case D3D_SIT_CBUFFER:
  2140. eRange = ER_CBuffer;
  2141. pCB = m_pEffect->FindCB(pName);
  2142. VBD( nullptr != pCB, "Loading error: cannot find cbuffer." );
  2143. VBD( size == 1, "Loading error: cbuffer arrays are not supported." );
  2144. break;
  2145. case D3D_SIT_TBUFFER:
  2146. eRange = ER_Texture;
  2147. pCB = m_pEffect->FindCB(pName);
  2148. VBD( nullptr != pCB, "Loading error: cannot find tbuffer." );
  2149. VBD( false != pCB->IsTBuffer, "Loading error: cbuffer found where tbuffer is expected." );
  2150. VBD( size == 1, "Loading error: tbuffer arrays are not supported." );
  2151. pShaderResource = &pCB->TBuffer;
  2152. break;
  2153. case D3D_SIT_TEXTURE:
  2154. case D3D_SIT_STRUCTURED:
  2155. case D3D_SIT_BYTEADDRESS:
  2156. {
  2157. eRange = ER_Texture;
  2158. pVariable = m_pEffect->FindVariableByNameWithParsing(pName);
  2159. VBD( pVariable != nullptr, "Loading error: cannot find SRV variable." );
  2160. uint32_t elements = std::max<uint32_t>(1, pVariable->pType->Elements);
  2161. VBD( size <= elements, "Loading error: SRV array size mismatch." );
  2162. if (pVariable->pType->IsShaderResource())
  2163. {
  2164. // this is just a straight texture assignment
  2165. pShaderResource = pVariable->Data.pShaderResource;
  2166. }
  2167. else
  2168. {
  2169. // This is a FX9/HLSL9-style texture load instruction that specifies only a sampler
  2170. VBD( pVariable->pType->IsSampler(), "Loading error: shader dependency is neither an SRV nor sampler.");
  2171. isFX9TextureLoad = true;
  2172. pSampler = pVariable->Data.pSampler;
  2173. // validate that all samplers actually used (i.e. based on size, not elements) in this variable have a valid TEXTURE assignment
  2174. for (size_t j = 0; j < size; ++ j)
  2175. {
  2176. if (nullptr == pSampler[j].BackingStore.pTexture)
  2177. {
  2178. // print spew appropriately for samplers vs sampler arrays
  2179. if (0 == pVariable->pType->Elements)
  2180. {
  2181. DPF(0, "%s: Sampler %s does not have a texture bound to it, even though the sampler is used in a DX9-style texture load instruction", g_szEffectLoadArea, pName);
  2182. }
  2183. else
  2184. {
  2185. DPF(0, "%s: Sampler %s[%u] does not have a texture bound to it, even though the sampler array is used in a DX9-style texture load instruction", g_szEffectLoadArea, pName, j);
  2186. }
  2187. VH( E_FAIL );
  2188. }
  2189. }
  2190. }
  2191. }
  2192. break;
  2193. case D3D_SIT_UAV_RWTYPED:
  2194. case D3D_SIT_UAV_RWSTRUCTURED:
  2195. case D3D_SIT_UAV_RWBYTEADDRESS:
  2196. case D3D_SIT_UAV_APPEND_STRUCTURED:
  2197. case D3D_SIT_UAV_CONSUME_STRUCTURED:
  2198. case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
  2199. eRange = ER_UnorderedAccessView;
  2200. pVariable = m_pEffect->FindVariableByNameWithParsing(pName);
  2201. VBD( pVariable != nullptr, "Loading error: cannot find UAV variable." );
  2202. VBD( size <= std::max<uint32_t>(1, pVariable->pType->Elements), "Loading error: UAV array index out of range." );
  2203. VBD( pVariable->pType->IsUnorderedAccessView(), "Loading error: UAV variable expected." );
  2204. pUnorderedAccessView = pVariable->Data.pUnorderedAccessView;
  2205. break;
  2206. case D3D_SIT_SAMPLER:
  2207. eRange = ER_Sampler;
  2208. pVariable = m_pEffect->FindVariableByNameWithParsing(pName);
  2209. VBD( pVariable != nullptr, "Loading error: cannot find sampler variable." );
  2210. VBD( size <= std::max<uint32_t>(1, pVariable->pType->Elements), "Loading error: sampler array index out of range." );
  2211. VBD( pVariable->pType->IsSampler(), "Loading error: sampler variable expected." );
  2212. pSampler = pVariable->Data.pSampler;
  2213. break;
  2214. default:
  2215. VHD( E_FAIL, "Internal loading error: unexpected shader dependency type." );
  2216. };
  2217. //
  2218. // Here's where the "optimized" part comes in; whenever there's
  2219. // a resource dependency, see if it's located contiguous to
  2220. // an existing resource dependency and merge them together
  2221. // if possible
  2222. //
  2223. uint32_t rangeCount;
  2224. pvRange = &vRanges[eRange];
  2225. rangeCount = pvRange->GetSize();
  2226. if ( rangeCount > 0 )
  2227. {
  2228. // Can we continue an existing range?
  2229. pRange = &( (*pvRange)[rangeCount - 1] );
  2230. // Make sure that bind points are strictly increasing,
  2231. // otherwise this algorithm breaks and we'd get worse runtime performance
  2232. assert(pRange->last <= bindPoint);
  2233. if ( pRange->last != bindPoint )
  2234. {
  2235. if( eRange != ER_UnorderedAccessView )
  2236. {
  2237. // No we can't. Begin a new range by setting rangeCount to 0 and triggering the next IF
  2238. rangeCount = 0;
  2239. }
  2240. else
  2241. {
  2242. // UAVs will always be located in one range, as they are more expensive to set
  2243. while(pRange->last < bindPoint)
  2244. {
  2245. VHD( pRange->vResources.Add(&g_NullUnorderedAccessView), "Internal loading error: cannot add UAV to range." );
  2246. pRange->last++;
  2247. }
  2248. }
  2249. }
  2250. }
  2251. if ( rangeCount == 0 )
  2252. {
  2253. VN( pRange = pvRange->Add() );
  2254. pRange->start = bindPoint;
  2255. }
  2256. pRange->last = bindPoint + size;
  2257. switch( ResourceDesc.Type )
  2258. {
  2259. case D3D_SIT_CBUFFER:
  2260. VHD( pRange->vResources.Add(pCB), "Internal loading error: cannot add cbuffer to range." );
  2261. break;
  2262. case D3D_SIT_TBUFFER:
  2263. VHD( pRange->vResources.Add(pShaderResource), "Internal loading error: cannot add tbuffer to range." );
  2264. VHD( vTBuffers.Add( (SConstantBuffer*)pCB ), "Internal loading error: cannot add tbuffer to vector." );
  2265. break;
  2266. case D3D_SIT_TEXTURE:
  2267. case D3D_SIT_STRUCTURED:
  2268. case D3D_SIT_BYTEADDRESS:
  2269. if (isFX9TextureLoad)
  2270. {
  2271. // grab all of the textures from each sampler
  2272. for (size_t j = 0; j < size; ++ j)
  2273. {
  2274. VHD( pRange->vResources.Add(pSampler[j].BackingStore.pTexture), "Internal loading error: cannot add SRV to range." );
  2275. }
  2276. }
  2277. else
  2278. {
  2279. // add the whole array
  2280. for (size_t j = 0; j < size; ++ j)
  2281. {
  2282. VHD( pRange->vResources.Add(pShaderResource + j), "Internal loading error: cannot add SRV to range." );
  2283. }
  2284. }
  2285. break;
  2286. case D3D_SIT_UAV_RWTYPED:
  2287. case D3D_SIT_UAV_RWSTRUCTURED:
  2288. case D3D_SIT_UAV_RWBYTEADDRESS:
  2289. case D3D_SIT_UAV_APPEND_STRUCTURED:
  2290. case D3D_SIT_UAV_CONSUME_STRUCTURED:
  2291. case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
  2292. // add the whole array
  2293. for (size_t j = 0; j < size; ++ j)
  2294. {
  2295. VHD( pRange->vResources.Add(pUnorderedAccessView + j), "Internal loading error: cannot add UAV to range." );
  2296. }
  2297. break;
  2298. case D3D_SIT_SAMPLER:
  2299. // add the whole array
  2300. for (size_t j = 0; j < size; ++ j)
  2301. {
  2302. VHD( pRange->vResources.Add(pSampler + j), "Internal loading error: cannot add sampler to range." );
  2303. }
  2304. break;
  2305. default:
  2306. VHD( E_FAIL, "Internal loading error: unexpected shader dependency type." );
  2307. }
  2308. }
  2309. //////////////////////////////////////////////////////////////////////////
  2310. // Step 2: iterate through the interfaces and build
  2311. // an "optimized" list of all of the dependencies
  2312. uint32_t NumInterfaces = pShaderBlock->pReflectionData->pReflection->GetNumInterfaceSlots();
  2313. uint32_t CurInterfaceParameter = 0;
  2314. if( NumInterfaces > 0 )
  2315. {
  2316. assert( ShaderDesc.ConstantBuffers > 0 );
  2317. for( uint32_t i=0; i < ShaderDesc.ConstantBuffers; i++ )
  2318. {
  2319. ID3D11ShaderReflectionConstantBuffer* pCB = pShaderBlock->pReflectionData->pReflection->GetConstantBufferByIndex(i);
  2320. VN( pCB );
  2321. D3D11_SHADER_BUFFER_DESC CBDesc;
  2322. VHD( pCB->GetDesc( &CBDesc ), "Internal loading error: cannot get CB desc." );
  2323. if( CBDesc.Type != D3D11_CT_INTERFACE_POINTERS )
  2324. {
  2325. continue;
  2326. }
  2327. for( uint32_t iVar=0; iVar < CBDesc.Variables; iVar++ )
  2328. {
  2329. ID3D11ShaderReflectionVariable* pInterfaceVar = pCB->GetVariableByIndex( iVar );
  2330. VN( pInterfaceVar );
  2331. D3D11_SHADER_VARIABLE_DESC InterfaceDesc;
  2332. VHD( pInterfaceVar->GetDesc(&InterfaceDesc), "Internal load error: cannot get IV desc.");
  2333. LPCSTR pName;
  2334. uint32_t bindPoint, size;
  2335. SGlobalVariable *pVariable = nullptr;
  2336. SInterface *pInterface = nullptr;
  2337. uint32_t VariableElements;
  2338. pName = InterfaceDesc.Name;
  2339. bindPoint = InterfaceDesc.StartOffset;
  2340. size = InterfaceDesc.Size;
  2341. if( bindPoint == (uint32_t)-1 )
  2342. {
  2343. continue;
  2344. }
  2345. assert( InterfaceDesc.uFlags & D3D11_SVF_INTERFACE_POINTER );
  2346. if( InterfaceDesc.uFlags & D3D11_SVF_INTERFACE_PARAMETER )
  2347. {
  2348. // This interface pointer is a parameter to the shader
  2349. if( pShaderBlock->pReflectionData->InterfaceParameterCount == 0 )
  2350. {
  2351. // There may be no interface parameters in this shader if it was compiled but had no interfaced bound to it.
  2352. // The shader cannot be set (correctly) in any pass.
  2353. continue;
  2354. }
  2355. else
  2356. {
  2357. VBD( CurInterfaceParameter < pShaderBlock->pReflectionData->InterfaceParameterCount,
  2358. "Internal loading error: interface count mismatch.");
  2359. SShaderBlock::SInterfaceParameter* pInterfaceInfo;
  2360. pInterfaceInfo = &pShaderBlock->pReflectionData->pInterfaceParameters[CurInterfaceParameter];
  2361. ++CurInterfaceParameter;
  2362. SGlobalVariable *pParent = m_pEffect->FindVariableByName(pInterfaceInfo->pName);
  2363. VBD( pParent != nullptr, "Loading error: cannot find parent type." );
  2364. if( pInterfaceInfo->Index == (uint32_t)-1 )
  2365. {
  2366. pVariable = pParent;
  2367. VariableElements = pVariable->pType->Elements;
  2368. }
  2369. else
  2370. {
  2371. // We want a specific index of the variable (ex. "MyVar[2]")
  2372. VBD( size == 1, "Loading error: interface array type mismatch." );
  2373. pVariable = (SGlobalVariable*)pParent->GetElement( pInterfaceInfo->Index );
  2374. VBD( pVariable->IsValid(), "Loading error: interface array index out of range." );
  2375. VariableElements = 0;
  2376. }
  2377. }
  2378. }
  2379. else
  2380. {
  2381. // This interface pointer is a global interface used in the shader
  2382. pVariable = m_pEffect->FindVariableByName(pName);
  2383. VBD( pVariable != nullptr, "Loading error: cannot find interface variable." );
  2384. VariableElements = pVariable->pType->Elements;
  2385. }
  2386. VBD( size <= std::max<uint32_t>(1, VariableElements), "Loading error: interface array size mismatch." );
  2387. if( pVariable->pType->IsInterface() )
  2388. {
  2389. pInterface = pVariable->Data.pInterface;
  2390. }
  2391. else if( pVariable->pType->IsClassInstance() )
  2392. {
  2393. // For class instances, we create background interfaces which point to the class instance. This is done so
  2394. // the shader can always expect SInterface dependencies, rather than a mix of SInterfaces and class instances
  2395. VN( pInterface = PRIVATENEW SInterface[size] );
  2396. if( VariableElements == 0 )
  2397. {
  2398. assert( size == 1 );
  2399. pInterface[0].pClassInstance = (SClassInstanceGlobalVariable*)pVariable;
  2400. m_BackgroundInterfaces.Add( &pInterface[0] );
  2401. }
  2402. else
  2403. {
  2404. // Fill each element of the SInstance array individually
  2405. VBD( size == VariableElements, "Loading error: class instance array size mismatch." );
  2406. for( uint32_t iElement=0; iElement < size; iElement++ )
  2407. {
  2408. SGlobalVariable *pElement = (SGlobalVariable*)pVariable->GetElement( iElement );
  2409. VBD( pElement->IsValid(), "Internal loading error: class instance array index out of range." );
  2410. pInterface[iElement].pClassInstance = (SClassInstanceGlobalVariable*)pElement;
  2411. m_BackgroundInterfaces.Add( &pInterface[iElement] );
  2412. }
  2413. }
  2414. }
  2415. else
  2416. {
  2417. VHD( E_FAIL, "Loading error: invalid interface initializer variable type.");
  2418. }
  2419. //
  2420. // Here's where the "optimized" part comes in; whenever there's
  2421. // a resource dependency, see if it's located contiguous to
  2422. // an existing resource dependency and merge them together
  2423. // if possible
  2424. //
  2425. uint32_t rangeCount;
  2426. pvRange = &vRanges[ER_Interfaces];
  2427. rangeCount = pvRange->GetSize();
  2428. VBD( rangeCount <= 1, "Internal loading error: invalid range count." );
  2429. if ( rangeCount == 0 )
  2430. {
  2431. VN( pRange = pvRange->Add() );
  2432. pRange->start = pRange->last = 0;
  2433. }
  2434. else
  2435. {
  2436. pRange = &( (*pvRange)[0] );
  2437. }
  2438. if( bindPoint < pRange->last )
  2439. {
  2440. // add interfaces into the range that already exists
  2441. VBD( bindPoint + size < pRange->last, "Internal loading error: range overlap." );
  2442. for( uint32_t j = 0; j < size; ++ j )
  2443. {
  2444. pRange->vResources[j + bindPoint] = pInterface + j;
  2445. }
  2446. }
  2447. else
  2448. {
  2449. // add interfaces to the end of the range
  2450. // add missing interface slots, if necessary
  2451. while(pRange->last < bindPoint)
  2452. {
  2453. VHD( pRange->vResources.Add(&g_NullInterface), "Internal loading error: cannot add nullptr interface to range." );
  2454. pRange->last++;
  2455. }
  2456. assert( bindPoint == pRange->last );
  2457. for( size_t j=0; j < size; ++ j )
  2458. {
  2459. VHD( pRange->vResources.Add(pInterface + j), "Internal loading error: cannot at interface to range." );
  2460. }
  2461. pRange->last = bindPoint + size;
  2462. }
  2463. }
  2464. // There is only one interface cbuffer
  2465. break;
  2466. }
  2467. }
  2468. //////////////////////////////////////////////////////////////////////////
  2469. // Step 3: allocate room in pShaderBlock for all of the dependency
  2470. // pointers and then hook them up
  2471. pShaderBlock->SampDepCount = vRanges[ ER_Sampler ].GetSize();
  2472. pShaderBlock->CBDepCount = vRanges[ ER_CBuffer ].GetSize();
  2473. pShaderBlock->InterfaceDepCount = vRanges[ ER_Interfaces ].GetSize();
  2474. pShaderBlock->ResourceDepCount = vRanges[ ER_Texture ].GetSize();
  2475. pShaderBlock->UAVDepCount = vRanges[ ER_UnorderedAccessView ].GetSize();
  2476. pShaderBlock->TBufferDepCount = vTBuffers.GetSize();
  2477. VN( pShaderBlock->pSampDeps = PRIVATENEW SShaderSamplerDependency[pShaderBlock->SampDepCount] );
  2478. VN( pShaderBlock->pCBDeps = PRIVATENEW SShaderCBDependency[pShaderBlock->CBDepCount] );
  2479. VN( pShaderBlock->pInterfaceDeps = PRIVATENEW SInterfaceDependency[pShaderBlock->InterfaceDepCount] );
  2480. VN( pShaderBlock->pResourceDeps = PRIVATENEW SShaderResourceDependency[pShaderBlock->ResourceDepCount] );
  2481. VN( pShaderBlock->pUAVDeps = PRIVATENEW SUnorderedAccessViewDependency[pShaderBlock->UAVDepCount] );
  2482. VN( pShaderBlock->ppTbufDeps = PRIVATENEW SConstantBuffer*[pShaderBlock->TBufferDepCount] );
  2483. for (size_t i=0; i<pShaderBlock->CBDepCount; ++i)
  2484. {
  2485. SShaderCBDependency *pDep = &pShaderBlock->pCBDeps[i];
  2486. pRange = &vRanges[ER_CBuffer][i];
  2487. pDep->StartIndex = pRange->start;
  2488. pDep->Count = pRange->last - pDep->StartIndex;
  2489. pDep->ppFXPointers = PRIVATENEW SConstantBuffer*[ pDep->Count ];
  2490. pDep->ppD3DObjects = PRIVATENEW ID3D11Buffer*[ pDep->Count ];
  2491. assert(pDep->Count == pRange->vResources.GetSize());
  2492. for (size_t j=0; j<pDep->Count; ++j)
  2493. {
  2494. pDep->ppFXPointers[j] = (SConstantBuffer *)pRange->vResources[j];
  2495. pDep->ppD3DObjects[j] = nullptr;
  2496. }
  2497. }
  2498. for (size_t i=0; i<pShaderBlock->SampDepCount; ++i)
  2499. {
  2500. SShaderSamplerDependency *pDep = &pShaderBlock->pSampDeps[i];
  2501. pRange = &vRanges[ER_Sampler][i];
  2502. pDep->StartIndex = pRange->start;
  2503. pDep->Count = pRange->last - pDep->StartIndex;
  2504. pDep->ppFXPointers = PRIVATENEW SSamplerBlock*[ pDep->Count ];
  2505. pDep->ppD3DObjects = PRIVATENEW ID3D11SamplerState*[ pDep->Count ];
  2506. assert(pDep->Count == pRange->vResources.GetSize());
  2507. for (size_t j=0; j<pDep->Count; ++j)
  2508. {
  2509. pDep->ppFXPointers[j] = (SSamplerBlock *) pRange->vResources[j];
  2510. pDep->ppD3DObjects[j] = nullptr;
  2511. }
  2512. }
  2513. for (size_t i=0; i<pShaderBlock->InterfaceDepCount; ++i)
  2514. {
  2515. SInterfaceDependency *pDep = &pShaderBlock->pInterfaceDeps[i];
  2516. pRange = &vRanges[ER_Interfaces][i];
  2517. pDep->StartIndex = pRange->start;
  2518. pDep->Count = pRange->last - pDep->StartIndex;
  2519. pDep->ppFXPointers = PRIVATENEW SInterface*[ pDep->Count ];
  2520. pDep->ppD3DObjects = PRIVATENEW ID3D11ClassInstance*[ pDep->Count ];
  2521. assert(pDep->Count == pRange->vResources.GetSize());
  2522. for (size_t j=0; j<pDep->Count; ++j)
  2523. {
  2524. pDep->ppFXPointers[j] = (SInterface *) pRange->vResources[j];
  2525. pDep->ppD3DObjects[j] = nullptr;
  2526. }
  2527. }
  2528. for (size_t i=0; i<pShaderBlock->ResourceDepCount; ++i)
  2529. {
  2530. SShaderResourceDependency *pDep = &pShaderBlock->pResourceDeps[i];
  2531. pRange = &vRanges[ER_Texture][i];
  2532. pDep->StartIndex = pRange->start;
  2533. pDep->Count = pRange->last - pDep->StartIndex;
  2534. pDep->ppFXPointers = PRIVATENEW SShaderResource*[ pDep->Count ];
  2535. pDep->ppD3DObjects = PRIVATENEW ID3D11ShaderResourceView*[ pDep->Count ];
  2536. assert(pDep->Count == pRange->vResources.GetSize());
  2537. for (size_t j=0; j<pDep->Count; ++j)
  2538. {
  2539. pDep->ppFXPointers[j] = (SShaderResource *) pRange->vResources[j];
  2540. pDep->ppD3DObjects[j] = nullptr;
  2541. }
  2542. }
  2543. for (size_t i=0; i<pShaderBlock->UAVDepCount; ++i)
  2544. {
  2545. SUnorderedAccessViewDependency *pDep = &pShaderBlock->pUAVDeps[i];
  2546. pRange = &vRanges[ER_UnorderedAccessView][i];
  2547. pDep->StartIndex = pRange->start;
  2548. pDep->Count = pRange->last - pDep->StartIndex;
  2549. pDep->ppFXPointers = PRIVATENEW SUnorderedAccessView*[ pDep->Count ];
  2550. pDep->ppD3DObjects = PRIVATENEW ID3D11UnorderedAccessView*[ pDep->Count ];
  2551. assert(pDep->Count == pRange->vResources.GetSize());
  2552. for (size_t j=0; j<pDep->Count; ++j)
  2553. {
  2554. pDep->ppFXPointers[j] = (SUnorderedAccessView *) pRange->vResources[j];
  2555. pDep->ppD3DObjects[j] = nullptr;
  2556. }
  2557. }
  2558. if (pShaderBlock->TBufferDepCount > 0)
  2559. {
  2560. memcpy(pShaderBlock->ppTbufDeps, &vTBuffers[0], pShaderBlock->TBufferDepCount * sizeof(SConstantBuffer*));
  2561. }
  2562. lExit:
  2563. return hr;
  2564. }
  2565. // Create shader reflection interface and grab dependency info
  2566. HRESULT CEffectLoader::BuildShaderBlock(SShaderBlock *pShaderBlock)
  2567. {
  2568. HRESULT hr = S_OK;
  2569. // unused shader block? that's not right
  2570. VBD( pShaderBlock->pVT != nullptr, "Internal loading error: nullptr shader vtable." );
  2571. assert(pShaderBlock->pD3DObject == nullptr);
  2572. if (nullptr == pShaderBlock->pReflectionData)
  2573. {
  2574. // File contains a shader variable without an assigned shader, or this is a null assignment.
  2575. // Usually, this is called by one of these guys:
  2576. // SetVertexShader( nullptr );
  2577. // or
  2578. // vertexshader g_VS = nullptr;
  2579. return S_OK;
  2580. }
  2581. // Initialize the reflection interface
  2582. VHD( D3DReflect( pShaderBlock->pReflectionData->pBytecode, pShaderBlock->pReflectionData->BytecodeLength, IID_ID3D11ShaderReflection, (void**)&pShaderBlock->pReflectionData->pReflection ),
  2583. "Internal loading error: cannot create shader reflection object." );
  2584. // Get dependencies
  2585. VH( GrabShaderData( pShaderBlock ) );
  2586. // Grab input signatures for VS
  2587. if( EOT_VertexShader == pShaderBlock->GetShaderType() )
  2588. {
  2589. assert( pShaderBlock->pInputSignatureBlob == nullptr );
  2590. VHD( D3DGetBlobPart( pShaderBlock->pReflectionData->pBytecode, pShaderBlock->pReflectionData->BytecodeLength,
  2591. D3D_BLOB_INPUT_SIGNATURE_BLOB, 0,
  2592. &pShaderBlock->pInputSignatureBlob ),
  2593. "Internal loading error: cannot get input signature." );
  2594. }
  2595. lExit:
  2596. return hr;
  2597. }
  2598. #undef PRIVATENEW
  2599. //////////////////////////////////////////////////////////////////////////
  2600. // Code to relocate data to private heaps (reflection & runtime effect)
  2601. //
  2602. // Important note about alignment: all reasonable chunks of data are
  2603. // machine word aligned (that is, any piece of data moved as a whole is
  2604. // aligned as a whole. This means that when computing m_ReflectionMemory
  2605. // or m_EffectMemory, each addition is aligned. This also means
  2606. // that, when later relocating that same memory, you must call MoveData
  2607. // or MoveString on the same chunks that were aligned. This is
  2608. // because: Align(a * b) != a * Align(b).
  2609. //////////////////////////////////////////////////////////////////////////
  2610. //////////////////////////////////////////////////////////////////////////
  2611. // Reflection reallocation code
  2612. //////////////////////////////////////////////////////////////////////////
  2613. HRESULT CEffectLoader::CalculateAnnotationSize(uint32_t cAnnotations, SAnnotation *pAnnotations)
  2614. {
  2615. HRESULT hr = S_OK;
  2616. uint32_t i;
  2617. m_ReflectionMemory += AlignToPowerOf2(cAnnotations * sizeof(SAnnotation), c_DataAlignment);
  2618. for (i=0; i<cAnnotations; i++)
  2619. {
  2620. if (pAnnotations[i].pType->BelongsInConstantBuffer())
  2621. {
  2622. m_ReflectionMemory += AlignToPowerOf2(pAnnotations[i].pType->TotalSize, c_DataAlignment);
  2623. }
  2624. else
  2625. {
  2626. VBD( pAnnotations[i].pType->IsObjectType(EOT_String), "Invalid pEffectBuffer: invalid annotation type." );
  2627. uint32_t cElements = std::max<uint32_t>(1, pAnnotations[i].pType->Elements);
  2628. m_ReflectionMemory += AlignToPowerOf2(cElements * sizeof(SString), c_DataAlignment);
  2629. }
  2630. }
  2631. lExit:
  2632. return hr;
  2633. }
  2634. HRESULT CEffectLoader::ReallocateAnnotationData(uint32_t cAnnotations, SAnnotation **ppAnnotations)
  2635. {
  2636. HRESULT hr = S_OK;
  2637. uint32_t i;
  2638. SAnnotation *pAnnotations;
  2639. VHD( m_pReflection->m_Heap.MoveData((void**) ppAnnotations, cAnnotations * sizeof(SAnnotation)),
  2640. "Internal loading error: cannot move annotation data." );
  2641. pAnnotations = *ppAnnotations;
  2642. for (i=0; i<cAnnotations; i++)
  2643. {
  2644. SAnnotation *pAn = &pAnnotations[i];
  2645. pAn->pEffect = m_pEffect;
  2646. VHD( m_pReflection->m_Heap.MoveString(&pAn->pName), "Internal loading error: cannot move annotation name." );
  2647. // Reallocate type later
  2648. if (pAn->pType->BelongsInConstantBuffer())
  2649. {
  2650. VHD( m_pReflection->m_Heap.MoveData( &pAn->Data.pGeneric, pAn->pType->TotalSize ), "Internal loading error: cannot move annotation data." );
  2651. }
  2652. else if (pAnnotations[i].pType->IsObjectType(EOT_String))
  2653. {
  2654. uint32_t cElements = std::max<uint32_t>(1, pAn->pType->Elements);
  2655. VHD( m_pReflection->m_Heap.MoveData((void**) &pAn->Data.pString, cElements * sizeof(SString)), "Internal loading error: cannot move annotation string." );
  2656. for (size_t j = 0; j < cElements; ++ j)
  2657. {
  2658. VHD( m_pReflection->m_Heap.MoveString(&pAn->Data.pString[j].pString), "Internal loading error: cannot move annotation string element." );
  2659. }
  2660. }
  2661. else
  2662. {
  2663. VHD( E_FAIL, "Invalid pEffectBuffer: invalid annotation type." );
  2664. }
  2665. }
  2666. lExit:
  2667. return hr;
  2668. }
  2669. HRESULT CEffectLoader::InitializeReflectionDataAndMoveStrings( uint32_t KnownSize )
  2670. {
  2671. HRESULT hr = S_OK;
  2672. uint32_t cbStrings;
  2673. CEffectHeap *pHeap = &m_pReflection->m_Heap;
  2674. // Get byte counts
  2675. cbStrings = m_pEffect->m_StringCount * sizeof( SString );
  2676. if( KnownSize )
  2677. {
  2678. m_ReflectionMemory = KnownSize;
  2679. }
  2680. else
  2681. {
  2682. m_ReflectionMemory += AlignToPowerOf2(cbStrings, c_DataAlignment);
  2683. for (size_t i=0; i<m_pEffect->m_CBCount; i++)
  2684. {
  2685. VH( CalculateAnnotationSize(m_pEffect->m_pCBs[i].AnnotationCount, m_pEffect->m_pCBs[i].pAnnotations) );
  2686. }
  2687. for (size_t i=0; i<m_pEffect->m_VariableCount; i++)
  2688. {
  2689. VH( CalculateAnnotationSize(m_pEffect->m_pVariables[i].AnnotationCount, m_pEffect->m_pVariables[i].pAnnotations) );
  2690. }
  2691. for (size_t i=0; i<m_pEffect->m_GroupCount; i++)
  2692. {
  2693. VH( CalculateAnnotationSize(m_pEffect->m_pGroups[i].AnnotationCount, m_pEffect->m_pGroups[i].pAnnotations) );
  2694. for (size_t j=0; j<m_pEffect->m_pGroups[i].TechniqueCount; j++)
  2695. {
  2696. VH( CalculateAnnotationSize(m_pEffect->m_pGroups[i].pTechniques[j].AnnotationCount, m_pEffect->m_pGroups[i].pTechniques[j].pAnnotations) );
  2697. for (size_t k=0; k<m_pEffect->m_pGroups[i].pTechniques[j].PassCount; k++)
  2698. {
  2699. VH( CalculateAnnotationSize(m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].AnnotationCount, m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].pAnnotations) );
  2700. }
  2701. }
  2702. }
  2703. // Calculate shader reflection data size
  2704. for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
  2705. {
  2706. if (nullptr != m_pEffect->m_pShaderBlocks[i].pReflectionData)
  2707. {
  2708. m_ReflectionMemory += AlignToPowerOf2(sizeof(SShaderBlock::SReflectionData), c_DataAlignment);
  2709. m_ReflectionMemory += AlignToPowerOf2(m_pEffect->m_pShaderBlocks[i].pReflectionData->BytecodeLength, c_DataAlignment);
  2710. // stream out decl is handled as a string, and thus its size is already factored because of GetStringAndAddToReflection
  2711. }
  2712. }
  2713. }
  2714. VHD( pHeap->ReserveMemory(m_ReflectionMemory), "Internal loading error: failed to reserve reflection memory." );
  2715. // Strings are handled separately because we are moving them to reflection
  2716. m_pOldStrings = m_pEffect->m_pStrings;
  2717. VHD( pHeap->MoveData((void**) &m_pEffect->m_pStrings, cbStrings), "Internal loading error: cannot move string data." );
  2718. for(size_t i=0; i<m_pEffect->m_StringCount; i++)
  2719. {
  2720. VHD( pHeap->MoveString( &m_pEffect->m_pStrings[i].pString), "Internal loading error: cannot move string pointer." );
  2721. }
  2722. lExit:
  2723. return hr;
  2724. }
  2725. // Move all reflection data to private heap
  2726. HRESULT CEffectLoader::ReallocateReflectionData( bool Cloning )
  2727. {
  2728. HRESULT hr = S_OK;
  2729. CEffectHeap *pHeap = &m_pReflection->m_Heap;
  2730. for(size_t i=0; i<m_pEffect->m_CBCount; i++)
  2731. {
  2732. VHD( pHeap->MoveString( &m_pEffect->m_pCBs[i].pName ), "Internal loading error: cannot move CB name." );
  2733. VH( ReallocateAnnotationData(m_pEffect->m_pCBs[i].AnnotationCount, &m_pEffect->m_pCBs[i].pAnnotations) );
  2734. }
  2735. for(size_t i=0; i<m_pEffect->m_VariableCount; i++)
  2736. {
  2737. VHD( pHeap->MoveString( &m_pEffect->m_pVariables[i].pName ), "Internal loading error: cannot move variable name." );
  2738. VHD( pHeap->MoveString( &m_pEffect->m_pVariables[i].pSemantic ), "Internal loading error: cannot move variable semantic." );
  2739. VH( ReallocateAnnotationData(m_pEffect->m_pVariables[i].AnnotationCount, &m_pEffect->m_pVariables[i].pAnnotations) );
  2740. }
  2741. for(size_t i=0; i<m_pEffect->m_GroupCount; i++)
  2742. {
  2743. VHD( pHeap->MoveString( &m_pEffect->m_pGroups[i].pName ), "Internal loading error: cannot move group name." );
  2744. VH( ReallocateAnnotationData(m_pEffect->m_pGroups[i].AnnotationCount, &m_pEffect->m_pGroups[i].pAnnotations) );
  2745. for(size_t j=0; j<m_pEffect->m_pGroups[i].TechniqueCount; j++)
  2746. {
  2747. VHD( pHeap->MoveString( &m_pEffect->m_pGroups[i].pTechniques[j].pName ), "Internal loading error: cannot move technique name." );
  2748. VH( ReallocateAnnotationData(m_pEffect->m_pGroups[i].pTechniques[j].AnnotationCount, &m_pEffect->m_pGroups[i].pTechniques[j].pAnnotations) );
  2749. for(size_t k=0; k<m_pEffect->m_pGroups[i].pTechniques[j].PassCount; k++)
  2750. {
  2751. VHD( pHeap->MoveString( &m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].pName ), "Internal loading error: cannot move pass name." );
  2752. VH( ReallocateAnnotationData(m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].AnnotationCount, &m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].pAnnotations) );
  2753. }
  2754. }
  2755. }
  2756. if( !Cloning )
  2757. {
  2758. // When not cloning, every member in m_pMemberInterfaces is from a global variable, so we can take pName and pSemantic
  2759. // from the parent variable, which were updated above
  2760. for (size_t i = 0; i < m_pEffect->m_pMemberInterfaces.GetSize(); ++ i)
  2761. {
  2762. SMember* pMember = m_pEffect->m_pMemberInterfaces[i];
  2763. SGlobalVariable* pTopLevelEntity = (SGlobalVariable*)pMember->pTopLevelEntity;
  2764. VH( FixupVariablePointer( &pTopLevelEntity ) );
  2765. pMember->pName = pTopLevelEntity->pName;
  2766. pMember->pSemantic = pTopLevelEntity->pSemantic;
  2767. }
  2768. }
  2769. // Move shader bytecode
  2770. for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
  2771. {
  2772. if (nullptr != m_pEffect->m_pShaderBlocks[i].pReflectionData)
  2773. {
  2774. VHD( pHeap->MoveData((void**)&m_pEffect->m_pShaderBlocks[i].pReflectionData, sizeof(SShaderBlock::SReflectionData)),
  2775. "Internal loading error: cannot move shader reflection block." );
  2776. VHD( pHeap->MoveData((void**)&m_pEffect->m_pShaderBlocks[i].pReflectionData->pBytecode, m_pEffect->m_pShaderBlocks[i].pReflectionData->BytecodeLength),
  2777. "Internal loading error: cannot move shader bytecode.");
  2778. for( size_t iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )
  2779. {
  2780. VHD( pHeap->MoveString(&m_pEffect->m_pShaderBlocks[i].pReflectionData->pStreamOutDecls[iDecl]), "Internal loading error: cannot move SO decl." );
  2781. }
  2782. VH( pHeap->MoveInterfaceParameters(m_pEffect->m_pShaderBlocks[i].pReflectionData->InterfaceParameterCount, &m_pEffect->m_pShaderBlocks[i].pReflectionData->pInterfaceParameters ) );
  2783. }
  2784. }
  2785. lExit:
  2786. return hr;
  2787. }
  2788. //////////////////////////////////////////////////////////////////////////
  2789. // Runtime effect reallocation code
  2790. //////////////////////////////////////////////////////////////////////////
  2791. template<class T> HRESULT CEffectLoader::ReallocateBlockAssignments(T* &pBlocks, uint32_t cBlocks, T* pOldBlocks)
  2792. {
  2793. HRESULT hr = S_OK;
  2794. CEffectHeap *pHeap = &m_pEffect->m_Heap;
  2795. for(size_t i=0; i<cBlocks; i++)
  2796. {
  2797. T *pBlock = &pBlocks[i];
  2798. VHD( pHeap->MoveData((void**) &pBlock->pAssignments, sizeof(SAssignment)*pBlock->AssignmentCount), "Internal loading error: cannot move assignment count." );
  2799. for (size_t j=0; j<pBlock->AssignmentCount; j++)
  2800. {
  2801. SAssignment *pAssignment = &pBlock->pAssignments[j];
  2802. uint32_t cbDeps;
  2803. // When cloning, convert pointers back into offsets
  2804. if( pOldBlocks )
  2805. {
  2806. T *pOldBlock = &pOldBlocks[i];
  2807. pAssignment->Destination.Offset = (uint32_t)( (UINT_PTR)pAssignment->Destination.pGeneric - (UINT_PTR)pOldBlock ) ;
  2808. }
  2809. // Convert destination pointers from offset to real pointer
  2810. pAssignment->Destination.pGeneric = (uint8_t*) pBlock + pAssignment->Destination.Offset;
  2811. // Make sure the data pointer points into the backing store
  2812. VBD( pAssignment->Destination.pGeneric >= &pBlock->BackingStore &&
  2813. pAssignment->Destination.pGeneric < (uint8_t*) &pBlock->BackingStore + sizeof(pBlock->BackingStore),
  2814. "Internal loading error: assignment destination out of range." );
  2815. // Fixup dependencies
  2816. cbDeps = pAssignment->DependencyCount * sizeof(SAssignment::SDependency);
  2817. VHD( pHeap->MoveData((void**) &pAssignment->pDependencies, cbDeps), "Internal loading error: cannot move assignment dependencies." );
  2818. SGlobalVariable *pOldVariable = nullptr;
  2819. for(size_t iDep=0; iDep<pAssignment->DependencyCount; iDep++)
  2820. {
  2821. SAssignment::SDependency *pDep = &pAssignment->pDependencies[iDep];
  2822. // We ignore all but the last variable because below, we only use the last dependency
  2823. pOldVariable = pDep->pVariable;
  2824. VH( FixupVariablePointer(&pDep->pVariable) );
  2825. }
  2826. // Fixup source pointers
  2827. switch(pAssignment->LhsType)
  2828. {
  2829. case ELHS_VertexShaderBlock:
  2830. case ELHS_PixelShaderBlock:
  2831. case ELHS_GeometryShaderBlock:
  2832. case ELHS_HullShaderBlock:
  2833. case ELHS_DomainShaderBlock:
  2834. case ELHS_ComputeShaderBlock:
  2835. VH( FixupShaderPointer(&pAssignment->Source.pShader) );
  2836. break;
  2837. case ELHS_DepthStencilBlock:
  2838. VH( FixupDSPointer((SDepthStencilBlock**)&pAssignment->Source.pBlock) );
  2839. break;
  2840. case ELHS_BlendBlock:
  2841. VH( FixupABPointer((SBlendBlock**) &pAssignment->Source.pBlock) );
  2842. break;
  2843. case ELHS_RasterizerBlock:
  2844. VH( FixupRSPointer((SRasterizerBlock**) &pAssignment->Source.pBlock) );
  2845. break;
  2846. case ELHS_Texture:
  2847. VH( FixupShaderResourcePointer((SShaderResource**) &pAssignment->Source.pShaderResource) );
  2848. break;
  2849. default:
  2850. // Non-object assignment (must have at least one dependency or it would have been pruned by now)
  2851. assert( !pAssignment->IsObjectAssignment() && pAssignment->DependencyCount > 0 );
  2852. // Numeric variables must be relocated before this function is called
  2853. switch (pAssignment->AssignmentType)
  2854. {
  2855. case ERAT_NumericVariable:
  2856. case ERAT_NumericVariableIndex:
  2857. // the variable or variable array is always the last dependency in the chain
  2858. SGlobalVariable *pVariable;
  2859. pVariable = pAssignment->pDependencies[pAssignment->DependencyCount - 1].pVariable;
  2860. assert( pVariable->pType->BelongsInConstantBuffer() && nullptr != pVariable->pCB );
  2861. // When cloning, convert pointers back into offsets
  2862. if( pOldBlocks )
  2863. {
  2864. VBD( pOldVariable != nullptr, "Internal loading error: pOldVariable is nullptr." );
  2865. pAssignment->Source.Offset = pAssignment->Source.pNumeric - pOldVariable->pCB->pBackingStore;
  2866. }
  2867. // Convert from offset to pointer
  2868. pAssignment->Source.pNumeric = pVariable->pCB->pBackingStore + pAssignment->Source.Offset;
  2869. break;
  2870. default:
  2871. // Shouldn't be able to get here
  2872. assert(0);
  2873. VHD( E_FAIL, "Loading error: invalid assignment type." );
  2874. }
  2875. break;
  2876. case ELHS_Invalid:
  2877. VHD( E_FAIL, "Loading error: invalid assignment type." );
  2878. }
  2879. assert(m_pEffect->m_LocalTimer > 0);
  2880. m_pEffect->EvaluateAssignment(pAssignment);
  2881. }
  2882. }
  2883. lExit:
  2884. return hr;
  2885. }
  2886. template<class T> uint32_t CEffectLoader::CalculateBlockAssignmentSize(T* &pBlocks, uint32_t cBlocks)
  2887. {
  2888. uint32_t dwSize = 0;
  2889. for(size_t i=0; i<cBlocks; i++)
  2890. {
  2891. SBaseBlock *pBlock = &pBlocks[i];
  2892. dwSize += AlignToPowerOf2(pBlock->AssignmentCount * sizeof(SAssignment), c_DataAlignment);
  2893. for (size_t j=0; j<pBlock->AssignmentCount; j++)
  2894. {
  2895. SAssignment *pAssignment = &pBlock->pAssignments[j];
  2896. dwSize += AlignToPowerOf2(pAssignment->DependencyCount * sizeof(SAssignment::SDependency), c_DataAlignment);
  2897. }
  2898. }
  2899. return dwSize;
  2900. }
  2901. HRESULT CEffectLoader::ReallocateShaderBlocks()
  2902. {
  2903. HRESULT hr = S_OK;
  2904. CEffectHeap *pHeap = &m_pEffect->m_Heap;
  2905. const char* pError = "Internal loading error: cannot move shader data.";
  2906. for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
  2907. {
  2908. SShaderBlock *pShader = &m_pEffect->m_pShaderBlocks[i];
  2909. // pShader->pReflection data and all of its members (bytecode, SO decl, etc.) are handled by ReallocateReflectionData()
  2910. VHD( pHeap->MoveData((void**) &pShader->pCBDeps, pShader->CBDepCount * sizeof(SShaderCBDependency)), pError );
  2911. VHD( pHeap->MoveData((void**) &pShader->pSampDeps, pShader->SampDepCount * sizeof(SShaderSamplerDependency)), pError );
  2912. VHD( pHeap->MoveData((void**) &pShader->pInterfaceDeps, pShader->InterfaceDepCount * sizeof(SInterfaceDependency)), pError );
  2913. VHD( pHeap->MoveData((void**) &pShader->pResourceDeps, pShader->ResourceDepCount * sizeof(SShaderResourceDependency)), pError );
  2914. VHD( pHeap->MoveData((void**) &pShader->pUAVDeps, pShader->UAVDepCount * sizeof(SUnorderedAccessViewDependency)), pError );
  2915. VHD( pHeap->MoveData((void**) &pShader->ppTbufDeps, pShader->TBufferDepCount * sizeof(SConstantBuffer*)), pError );
  2916. for (size_t j=0; j<pShader->CBDepCount; j++)
  2917. {
  2918. SShaderCBDependency *pCBDeps = &pShader->pCBDeps[j];
  2919. VHD( pHeap->MoveData((void**) &pCBDeps->ppD3DObjects, pCBDeps->Count * sizeof(ID3D11Buffer*)), pError );
  2920. VHD( pHeap->MoveData((void**) &pCBDeps->ppFXPointers, pCBDeps->Count * sizeof(SConstantBuffer*)), pError );
  2921. for (size_t k=0; k<pCBDeps->Count; k++)
  2922. {
  2923. VH( FixupCBPointer( &pCBDeps->ppFXPointers[k] ) );
  2924. }
  2925. }
  2926. for (size_t j=0; j<pShader->SampDepCount; j++)
  2927. {
  2928. SShaderSamplerDependency *pSampDeps = &pShader->pSampDeps[j];
  2929. VHD( pHeap->MoveData((void**) &pSampDeps->ppD3DObjects, pSampDeps->Count * sizeof(ID3D11SamplerState*)), pError );
  2930. VHD( pHeap->MoveData((void**) &pSampDeps->ppFXPointers, pSampDeps->Count * sizeof(SSamplerBlock*)), pError );
  2931. for (size_t k=0; k<pSampDeps->Count; k++)
  2932. {
  2933. VH( FixupSamplerPointer(&pSampDeps->ppFXPointers[k]) );
  2934. }
  2935. }
  2936. for (size_t j=0; j<pShader->InterfaceDepCount; j++)
  2937. {
  2938. SInterfaceDependency *pInterfaceDeps = &pShader->pInterfaceDeps[j];
  2939. VHD( pHeap->MoveData((void**) &pInterfaceDeps->ppD3DObjects, pInterfaceDeps->Count * sizeof(ID3D11ClassInstance*)), pError );
  2940. VHD( pHeap->MoveData((void**) &pInterfaceDeps->ppFXPointers, pInterfaceDeps->Count * sizeof(SInterface*)), pError );
  2941. for (size_t k=0; k<pInterfaceDeps->Count; k++)
  2942. {
  2943. VH( FixupInterfacePointer(&pInterfaceDeps->ppFXPointers[k], true) );
  2944. }
  2945. }
  2946. for (size_t j=0; j<pShader->ResourceDepCount; j++)
  2947. {
  2948. SShaderResourceDependency *pResourceDeps = &pShader->pResourceDeps[j];
  2949. VHD( pHeap->MoveData((void**) &pResourceDeps->ppD3DObjects, pResourceDeps->Count * sizeof(ID3D11ShaderResourceView*)), pError );
  2950. VHD( pHeap->MoveData((void**) &pResourceDeps->ppFXPointers, pResourceDeps->Count * sizeof(SShaderResource*)), pError );
  2951. for (size_t k=0; k<pResourceDeps->Count; k++)
  2952. {
  2953. VH( FixupShaderResourcePointer(&pResourceDeps->ppFXPointers[k]) );
  2954. }
  2955. }
  2956. for (size_t j=0; j<pShader->UAVDepCount; j++)
  2957. {
  2958. SUnorderedAccessViewDependency *pUAVDeps = &pShader->pUAVDeps[j];
  2959. VHD( pHeap->MoveData((void**) &pUAVDeps->ppD3DObjects, pUAVDeps->Count * sizeof(ID3D11UnorderedAccessView*)), pError );
  2960. VHD( pHeap->MoveData((void**) &pUAVDeps->ppFXPointers, pUAVDeps->Count * sizeof(SUnorderedAccessView*)), pError );
  2961. for (size_t k=0; k<pUAVDeps->Count; k++)
  2962. {
  2963. VH( FixupUnorderedAccessViewPointer(&pUAVDeps->ppFXPointers[k]) );
  2964. }
  2965. }
  2966. for (size_t j=0; j<pShader->TBufferDepCount; j++)
  2967. {
  2968. VH( FixupCBPointer( &pShader->ppTbufDeps[j] ) );
  2969. }
  2970. }
  2971. lExit:
  2972. return hr;
  2973. }
  2974. uint32_t CEffectLoader::CalculateShaderBlockSize()
  2975. {
  2976. uint32_t dwSize = 0;
  2977. for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
  2978. {
  2979. SShaderBlock *pShader = &m_pEffect->m_pShaderBlocks[i];
  2980. dwSize += AlignToPowerOf2(pShader->CBDepCount * sizeof(SShaderCBDependency), c_DataAlignment);
  2981. dwSize += AlignToPowerOf2(pShader->SampDepCount * sizeof(SShaderSamplerDependency), c_DataAlignment);
  2982. dwSize += AlignToPowerOf2(pShader->InterfaceDepCount * sizeof(SInterfaceDependency), c_DataAlignment);
  2983. dwSize += AlignToPowerOf2(pShader->ResourceDepCount * sizeof(SShaderResourceDependency), c_DataAlignment);
  2984. dwSize += AlignToPowerOf2(pShader->UAVDepCount * sizeof(SUnorderedAccessViewDependency), c_DataAlignment);
  2985. dwSize += AlignToPowerOf2(pShader->TBufferDepCount * sizeof(SConstantBuffer*), c_DataAlignment);
  2986. for (size_t j=0; j<pShader->CBDepCount; j++)
  2987. {
  2988. SShaderCBDependency *pCBDeps = &pShader->pCBDeps[j];
  2989. dwSize += AlignToPowerOf2(pCBDeps->Count * sizeof(ID3D11Buffer*), c_DataAlignment);
  2990. dwSize += AlignToPowerOf2(pCBDeps->Count * sizeof(SConstantBuffer*), c_DataAlignment);
  2991. }
  2992. for (size_t j=0; j<pShader->SampDepCount; j++)
  2993. {
  2994. SShaderSamplerDependency *pSampDeps = &pShader->pSampDeps[j];
  2995. dwSize += AlignToPowerOf2(pSampDeps->Count * sizeof(ID3D11SamplerState*), c_DataAlignment);
  2996. dwSize += AlignToPowerOf2(pSampDeps->Count * sizeof(SSamplerBlock*), c_DataAlignment);
  2997. }
  2998. for (size_t j=0; j<pShader->InterfaceDepCount; j++)
  2999. {
  3000. SInterfaceDependency *pInterfaceDeps = &pShader->pInterfaceDeps[j];
  3001. dwSize += AlignToPowerOf2(pInterfaceDeps->Count * sizeof(ID3D11ClassInstance*), c_DataAlignment);
  3002. dwSize += AlignToPowerOf2(pInterfaceDeps->Count * sizeof(SInterface*), c_DataAlignment);
  3003. }
  3004. for (size_t j=0; j<pShader->ResourceDepCount; j++)
  3005. {
  3006. SShaderResourceDependency *pResourceDeps = &pShader->pResourceDeps[j];
  3007. dwSize += AlignToPowerOf2(pResourceDeps->Count * sizeof(ID3D11ShaderResourceView*), c_DataAlignment);
  3008. dwSize += AlignToPowerOf2(pResourceDeps->Count * sizeof(SShaderResource*), c_DataAlignment);
  3009. }
  3010. for (size_t j=0; j<pShader->UAVDepCount; j++)
  3011. {
  3012. SUnorderedAccessViewDependency *pUAVDeps = &pShader->pUAVDeps[j];
  3013. dwSize += AlignToPowerOf2(pUAVDeps->Count * sizeof(ID3D11UnorderedAccessView*), c_DataAlignment);
  3014. dwSize += AlignToPowerOf2(pUAVDeps->Count * sizeof(SUnorderedAccessView*), c_DataAlignment);
  3015. }
  3016. }
  3017. return dwSize;
  3018. }
  3019. // Move all (non-reflection) effect data to private heap
  3020. #pragma warning(push)
  3021. #pragma warning(disable: 4616 6239 )
  3022. HRESULT CEffectLoader::ReallocateEffectData( bool Cloning )
  3023. {
  3024. HRESULT hr = S_OK;
  3025. CEffectHeap *pHeap = &m_pEffect->m_Heap;
  3026. uint32_t cbCBs = sizeof(SConstantBuffer) * m_pEffect->m_CBCount;
  3027. uint32_t cbVariables = sizeof(SGlobalVariable) * m_pEffect->m_VariableCount;
  3028. uint32_t cbGroups = sizeof(STechnique) * m_pEffect->m_GroupCount;
  3029. uint32_t cbShaders = sizeof(SShaderBlock) * m_pEffect->m_ShaderBlockCount;
  3030. uint32_t cbDS = sizeof(SDepthStencilBlock) * m_pEffect->m_DepthStencilBlockCount;
  3031. uint32_t cbAB = sizeof(SBlendBlock) * m_pEffect->m_BlendBlockCount;
  3032. uint32_t cbRS = sizeof(SRasterizerBlock) * m_pEffect->m_RasterizerBlockCount;
  3033. uint32_t cbSamplers = sizeof(SSamplerBlock) * m_pEffect->m_SamplerBlockCount;
  3034. uint32_t cbMemberDatas = sizeof(SMemberDataPointer) * m_pEffect->m_MemberDataCount;
  3035. uint32_t cbInterfaces = sizeof(SInterface) * m_pEffect->m_InterfaceCount;
  3036. uint32_t cbBackgroundInterfaces = sizeof(SInterface) * m_BackgroundInterfaces.GetSize();
  3037. uint32_t cbShaderResources = sizeof(SShaderResource) * m_pEffect->m_ShaderResourceCount;
  3038. uint32_t cbUnorderedAccessViews = sizeof(SUnorderedAccessView) * m_pEffect->m_UnorderedAccessViewCount;
  3039. uint32_t cbRenderTargetViews = sizeof(SRenderTargetView) * m_pEffect->m_RenderTargetViewCount;
  3040. uint32_t cbDepthStencilViews = sizeof(SDepthStencilView) * m_pEffect->m_DepthStencilViewCount;
  3041. uint32_t cbAnonymousShaders = sizeof(SAnonymousShader) * m_pEffect->m_AnonymousShaderCount;
  3042. // Calculate memory needed
  3043. m_EffectMemory += AlignToPowerOf2(cbCBs, c_DataAlignment);
  3044. m_EffectMemory += AlignToPowerOf2(cbVariables, c_DataAlignment);
  3045. m_EffectMemory += AlignToPowerOf2(cbGroups, c_DataAlignment);
  3046. m_EffectMemory += AlignToPowerOf2(cbShaders, c_DataAlignment);
  3047. m_EffectMemory += AlignToPowerOf2(cbMemberDatas, c_DataAlignment);
  3048. m_EffectMemory += AlignToPowerOf2(cbInterfaces + cbBackgroundInterfaces, c_DataAlignment);
  3049. m_EffectMemory += AlignToPowerOf2(cbShaderResources, c_DataAlignment);
  3050. m_EffectMemory += AlignToPowerOf2(cbUnorderedAccessViews, c_DataAlignment);
  3051. m_EffectMemory += AlignToPowerOf2(cbRenderTargetViews, c_DataAlignment);
  3052. m_EffectMemory += AlignToPowerOf2(cbDepthStencilViews, c_DataAlignment);
  3053. m_EffectMemory += AlignToPowerOf2(cbDS, c_DataAlignment);
  3054. m_EffectMemory += AlignToPowerOf2(cbAB, c_DataAlignment);
  3055. m_EffectMemory += AlignToPowerOf2(cbRS, c_DataAlignment);
  3056. m_EffectMemory += AlignToPowerOf2(cbSamplers, c_DataAlignment);
  3057. m_EffectMemory += AlignToPowerOf2(cbAnonymousShaders, c_DataAlignment);
  3058. m_EffectMemory += CalculateShaderBlockSize();
  3059. for (size_t i=0; i<m_pEffect->m_CBCount; i++)
  3060. {
  3061. SConstantBuffer *pCB = &m_pEffect->m_pCBs[i];
  3062. m_EffectMemory += AlignToPowerOf2(pCB->Size, c_DataAlignment);
  3063. }
  3064. for (size_t i=0; i<m_pEffect->m_GroupCount; i++)
  3065. {
  3066. SGroup *pGroup = &m_pEffect->m_pGroups[i];
  3067. m_EffectMemory += AlignToPowerOf2(pGroup->TechniqueCount * sizeof(STechnique), c_DataAlignment);
  3068. for (size_t j=0; j<pGroup->TechniqueCount; j++)
  3069. {
  3070. STechnique *pTech = &pGroup->pTechniques[j];
  3071. m_EffectMemory += AlignToPowerOf2(pTech->PassCount * sizeof(SPassBlock), c_DataAlignment);
  3072. m_EffectMemory += CalculateBlockAssignmentSize(pTech->pPasses, pTech->PassCount);
  3073. }
  3074. };
  3075. m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pBlendBlocks, m_pEffect->m_BlendBlockCount);
  3076. m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pDepthStencilBlocks, m_pEffect->m_DepthStencilBlockCount);
  3077. m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pRasterizerBlocks, m_pEffect->m_RasterizerBlockCount);
  3078. m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pSamplerBlocks, m_pEffect->m_SamplerBlockCount);
  3079. // Reserve memory
  3080. VHD( pHeap->ReserveMemory(m_EffectMemory), "Internal loading error: cannot reserve effect memory." );
  3081. // Move DataMemberPointer blocks
  3082. m_pOldMemberDataBlocks = m_pEffect->m_pMemberDataBlocks;
  3083. VHD( pHeap->MoveData((void**) &m_pEffect->m_pMemberDataBlocks, cbMemberDatas), "Internal loading error: cannot move member data blocks." );
  3084. // Move CBs
  3085. m_pOldCBs = m_pEffect->m_pCBs;
  3086. VHD( pHeap->MoveData((void**) &m_pEffect->m_pCBs, cbCBs), "Internal loading error: cannot move CB count." );
  3087. for (size_t i=0; i<m_pEffect->m_CBCount; i++)
  3088. {
  3089. SConstantBuffer *pCB = &m_pEffect->m_pCBs[i];
  3090. VHD( pHeap->MoveData((void**) &pCB->pBackingStore, pCB->Size), "Internal loading error: cannot move CB backing store." );
  3091. if( !Cloning )
  3092. {
  3093. // When creating the effect, MemberDataOffsetPlus4 is used, not pMemberData
  3094. if( pCB->MemberDataOffsetPlus4 )
  3095. {
  3096. pCB->pMemberData = (SMemberDataPointer*)( (uint8_t*)m_pEffect->m_pMemberDataBlocks + ( pCB->MemberDataOffsetPlus4 - 4 ) );
  3097. }
  3098. }
  3099. else if (pCB->pMemberData)
  3100. {
  3101. // When cloning an effect, pMemberData points to valid data in the original effect
  3102. VH( FixupMemberDataPointer( &pCB->pMemberData ) );
  3103. }
  3104. }
  3105. // Move numeric variables; move all variable types
  3106. m_pOldVars = m_pEffect->m_pVariables;
  3107. VHD( pHeap->MoveData((void**) &m_pEffect->m_pVariables, cbVariables), "Internal loading error: cannot move variable count." );
  3108. for (size_t i=0; i<m_pEffect->m_VariableCount; i++)
  3109. {
  3110. SGlobalVariable *pVar = &m_pEffect->m_pVariables[i];
  3111. pVar->pEffect = m_pEffect;
  3112. if( Cloning && pVar->pType->BelongsInConstantBuffer())
  3113. {
  3114. // Convert pointer back to offset
  3115. // pVar->pCB refers to the old CB
  3116. pVar->Data.Offset = (UINT_PTR)pVar->Data.pGeneric - (UINT_PTR)pVar->pCB->pBackingStore;
  3117. }
  3118. if (pVar->pCB)
  3119. {
  3120. VH( FixupCBPointer( &pVar->pCB ) );
  3121. }
  3122. if( !Cloning )
  3123. {
  3124. // When creating the effect, MemberDataOffsetPlus4 is used, not pMemberData
  3125. if( pVar->MemberDataOffsetPlus4 )
  3126. {
  3127. pVar->pMemberData = (SMemberDataPointer*)( (uint8_t*)m_pEffect->m_pMemberDataBlocks + ( pVar->MemberDataOffsetPlus4 - 4 ) );
  3128. }
  3129. }
  3130. else if (pVar->pMemberData)
  3131. {
  3132. // When cloning an effect, pMemberData points to valid data in the original effect
  3133. VH( FixupMemberDataPointer( &pVar->pMemberData ) );
  3134. }
  3135. if (pVar->pType->BelongsInConstantBuffer())
  3136. {
  3137. // Convert from offsets to pointers
  3138. pVar->Data.pGeneric = pVar->pCB->pBackingStore + pVar->Data.Offset;
  3139. }
  3140. }
  3141. // Fixup each CB's array of child variable pointers
  3142. for (size_t i=0; i<m_pEffect->m_CBCount; i++)
  3143. {
  3144. SConstantBuffer *pCB = &m_pEffect->m_pCBs[i];
  3145. pCB->pEffect = m_pEffect;
  3146. if (pCB->pVariables != nullptr)
  3147. {
  3148. VH( FixupVariablePointer(&pCB->pVariables) );
  3149. }
  3150. }
  3151. // Move shaders
  3152. m_pOldShaders = m_pEffect->m_pShaderBlocks;
  3153. VHD( pHeap->MoveData((void**) &m_pEffect->m_pShaderBlocks, cbShaders), "Internal loading error: cannot move shader count." );
  3154. // Move interfaces, combining global interfaces and those that were created during shader initialization
  3155. m_pOldInterfaces = m_pEffect->m_pInterfaces;
  3156. m_OldInterfaceCount = m_pEffect->m_InterfaceCount;
  3157. VHD( pHeap->MoveEmptyDataBlock((void**) &m_pEffect->m_pInterfaces, cbInterfaces + cbBackgroundInterfaces), "Internal loading error: cannot move shader." );
  3158. memcpy( m_pEffect->m_pInterfaces, m_pOldInterfaces, cbInterfaces );
  3159. for( size_t i=0; i < m_BackgroundInterfaces.GetSize(); i++ )
  3160. {
  3161. assert( m_BackgroundInterfaces[i] != nullptr );
  3162. uint8_t* pDst = (uint8_t*)m_pEffect->m_pInterfaces + ( m_pEffect->m_InterfaceCount * sizeof(SInterface) );
  3163. memcpy( pDst, m_BackgroundInterfaces[i], sizeof(SInterface) );
  3164. m_pEffect->m_InterfaceCount++;
  3165. }
  3166. m_pOldShaderResources = m_pEffect->m_pShaderResources;
  3167. VHD( pHeap->MoveData((void**) &m_pEffect->m_pShaderResources, cbShaderResources), "Internal loading error: cannot move SRVs." );
  3168. m_pOldUnorderedAccessViews = m_pEffect->m_pUnorderedAccessViews;
  3169. VHD( pHeap->MoveData((void**) &m_pEffect->m_pUnorderedAccessViews, cbUnorderedAccessViews), "Internal loading error: cannot move UAVS." );
  3170. m_pOldRenderTargetViews = m_pEffect->m_pRenderTargetViews;
  3171. VHD( pHeap->MoveData((void**) &m_pEffect->m_pRenderTargetViews, cbRenderTargetViews), "Internal loading error: cannot move RTVs." );
  3172. m_pOldDepthStencilViews = m_pEffect->m_pDepthStencilViews;
  3173. VHD( pHeap->MoveData((void**) &m_pEffect->m_pDepthStencilViews, cbDepthStencilViews), "Internal loading error: cannot move DSVs." );
  3174. m_pOldDS = m_pEffect->m_pDepthStencilBlocks;
  3175. VHD( pHeap->MoveData((void**) &m_pEffect->m_pDepthStencilBlocks, cbDS), "Internal loading error: cannot move depth-stencil state blocks." );
  3176. VH( ReallocateBlockAssignments(m_pEffect->m_pDepthStencilBlocks, m_pEffect->m_DepthStencilBlockCount, Cloning ? m_pOldDS : nullptr) );
  3177. m_pOldAB = m_pEffect->m_pBlendBlocks;
  3178. VHD( pHeap->MoveData((void**) &m_pEffect->m_pBlendBlocks, cbAB), "Internal loading error: cannot move blend state blocks." );
  3179. VH( ReallocateBlockAssignments(m_pEffect->m_pBlendBlocks, m_pEffect->m_BlendBlockCount, Cloning ? m_pOldAB : nullptr) );
  3180. m_pOldRS = m_pEffect->m_pRasterizerBlocks;
  3181. VHD( pHeap->MoveData((void**) &m_pEffect->m_pRasterizerBlocks, cbRS), "Internal loading error: cannot move rasterizer state blocks." );
  3182. VH( ReallocateBlockAssignments(m_pEffect->m_pRasterizerBlocks, m_pEffect->m_RasterizerBlockCount, Cloning ? m_pOldRS : nullptr) );
  3183. m_pOldSamplers = m_pEffect->m_pSamplerBlocks;
  3184. VHD( pHeap->MoveData((void**) &m_pEffect->m_pSamplerBlocks, cbSamplers), "Internal loading error: cannot move samplers." );
  3185. VH( ReallocateBlockAssignments(m_pEffect->m_pSamplerBlocks, m_pEffect->m_SamplerBlockCount, Cloning ? m_pOldSamplers : nullptr) );
  3186. // Fixup sampler backing stores
  3187. for (size_t i=0; i<m_pEffect->m_SamplerBlockCount; ++i)
  3188. {
  3189. VH( FixupShaderResourcePointer(&m_pEffect->m_pSamplerBlocks[i].BackingStore.pTexture) );
  3190. }
  3191. // Fixup each interface's class instance variable pointer
  3192. for (size_t i=0; i<m_pEffect->m_InterfaceCount; i++)
  3193. {
  3194. SInterface *pInterface = &m_pEffect->m_pInterfaces[i];
  3195. if (pInterface->pClassInstance != nullptr)
  3196. {
  3197. VH( FixupVariablePointer( (SGlobalVariable**)&pInterface->pClassInstance ) );
  3198. }
  3199. }
  3200. // Fixup pointers for non-numeric variables
  3201. for (size_t i=0; i<m_pEffect->m_VariableCount; i++)
  3202. {
  3203. SGlobalVariable *pVar = &m_pEffect->m_pVariables[i];
  3204. if (pVar->pType->IsShader())
  3205. {
  3206. VH( FixupShaderPointer(&pVar->Data.pShader) );
  3207. }
  3208. else if (pVar->pType->IsShaderResource())
  3209. {
  3210. VH( FixupShaderResourcePointer(&pVar->Data.pShaderResource) );
  3211. }
  3212. else if (pVar->pType->IsUnorderedAccessView())
  3213. {
  3214. VH( FixupUnorderedAccessViewPointer(&pVar->Data.pUnorderedAccessView) );
  3215. }
  3216. else if (pVar->pType->IsInterface())
  3217. {
  3218. VH( FixupInterfacePointer(&pVar->Data.pInterface, false) );
  3219. }
  3220. else if (pVar->pType->IsObjectType(EOT_String))
  3221. {
  3222. if( !m_pEffect->IsOptimized() )
  3223. {
  3224. VH( FixupStringPointer(&pVar->Data.pString) );
  3225. }
  3226. }
  3227. else if (pVar->pType->IsStateBlockObject())
  3228. {
  3229. switch(pVar->pType->ObjectType)
  3230. {
  3231. case EOT_DepthStencil:
  3232. VH( FixupDSPointer((SDepthStencilBlock**) &pVar->Data.pBlock) );
  3233. break;
  3234. case EOT_Blend:
  3235. VH( FixupABPointer((SBlendBlock**) &pVar->Data.pBlock) );
  3236. break;
  3237. case EOT_Rasterizer:
  3238. VH( FixupRSPointer((SRasterizerBlock**) &pVar->Data.pBlock) );
  3239. break;
  3240. case EOT_Sampler:
  3241. VB(pVar->pType->IsSampler());
  3242. VH( FixupSamplerPointer((SSamplerBlock**) &pVar->Data.pBlock) );
  3243. break;
  3244. default:
  3245. VH( E_FAIL );
  3246. }
  3247. }
  3248. else if (pVar->pType->VarType == EVT_Struct || pVar->pType->VarType == EVT_Numeric)
  3249. {
  3250. if( pVar->pType->IsClassInstance() )
  3251. {
  3252. // do nothing
  3253. }
  3254. else
  3255. {
  3256. // do nothing
  3257. }
  3258. }
  3259. else if (pVar->pType->IsRenderTargetView())
  3260. {
  3261. VH( FixupRenderTargetViewPointer(&pVar->Data.pRenderTargetView) );
  3262. }
  3263. else if (pVar->pType->IsDepthStencilView())
  3264. {
  3265. VH( FixupDepthStencilViewPointer(&pVar->Data.pDepthStencilView) );
  3266. }
  3267. else
  3268. {
  3269. VHD( E_FAIL, "Internal loading error: Invalid variable type." );
  3270. }
  3271. }
  3272. // Fixup created members
  3273. for (size_t i = 0; i < m_pEffect->m_pMemberInterfaces.GetSize(); ++ i)
  3274. {
  3275. SMember* pMember = m_pEffect->m_pMemberInterfaces[i];
  3276. SGlobalVariable** ppTopLevelEntity = (SGlobalVariable**)&pMember->pTopLevelEntity;
  3277. VN( *ppTopLevelEntity );
  3278. // This might be set to false later, for supporting textures inside classes
  3279. const bool bGlobalMemberDataBlock = true;
  3280. if( Cloning )
  3281. {
  3282. if( pMember->pType->BelongsInConstantBuffer() )
  3283. {
  3284. assert( pMember->Data.pGeneric == nullptr || (*ppTopLevelEntity)->pEffect->m_Heap.IsInHeap(pMember->Data.pGeneric) );
  3285. pMember->Data.Offset = (uint32_t)( (uint8_t*)pMember->Data.pGeneric - (uint8_t*)(*ppTopLevelEntity)->pCB->pBackingStore );
  3286. }
  3287. if( bGlobalMemberDataBlock && pMember->pMemberData )
  3288. {
  3289. pMember->MemberDataOffsetPlus4 = (uint32_t)( (uint8_t*)pMember->pMemberData - (uint8_t*)(*ppTopLevelEntity)->pEffect->m_pMemberDataBlocks ) + 4;
  3290. }
  3291. }
  3292. VH( FixupVariablePointer( ppTopLevelEntity ) );
  3293. if (pMember->pType->BelongsInConstantBuffer())
  3294. {
  3295. // Convert from offsets to pointers
  3296. pMember->Data.pGeneric = (*ppTopLevelEntity)->pCB->pBackingStore + pMember->Data.Offset;
  3297. }
  3298. if( bGlobalMemberDataBlock && pMember->MemberDataOffsetPlus4 )
  3299. {
  3300. pMember->pMemberData = (SMemberDataPointer*)( (uint8_t*)m_pEffect->m_pMemberDataBlocks + ( pMember->MemberDataOffsetPlus4 - 4 ) );
  3301. }
  3302. }
  3303. // Fixup shader data
  3304. VH( ReallocateShaderBlocks() );
  3305. // Move groups, techniques, and passes
  3306. m_pOldGroups = m_pEffect->m_pGroups;
  3307. VHD( pHeap->MoveData((void**) &m_pEffect->m_pGroups, cbGroups), "Internal loading error: cannot move groups." );
  3308. for (size_t i=0; i<m_pEffect->m_GroupCount; i++)
  3309. {
  3310. SGroup *pGroup = &m_pEffect->m_pGroups[i];
  3311. uint32_t cbTechniques;
  3312. cbTechniques = pGroup->TechniqueCount * sizeof(STechnique);
  3313. VHD( pHeap->MoveData((void**) &pGroup->pTechniques, cbTechniques), "Internal loading error: cannot move techniques." );
  3314. for (size_t j=0; j<pGroup->TechniqueCount; j++)
  3315. {
  3316. STechnique *pTech = &pGroup->pTechniques[j];
  3317. uint32_t cbPass;
  3318. cbPass = pTech->PassCount * sizeof(SPassBlock);
  3319. SPassBlock* pOldPasses = Cloning ? pTech->pPasses : nullptr;
  3320. VHD( pHeap->MoveData((void**) &pTech->pPasses, cbPass), "Internal loading error: cannot move passes." );
  3321. for (size_t iPass = 0; iPass < pTech->PassCount; ++ iPass)
  3322. {
  3323. pTech->pPasses[iPass].pEffect = m_pEffect;
  3324. // Fixup backing store pointers in passes
  3325. VH( FixupABPointer((SBlendBlock**) &pTech->pPasses[iPass].BackingStore.pBlendBlock) );
  3326. VH( FixupDSPointer((SDepthStencilBlock**) &pTech->pPasses[iPass].BackingStore.pDepthStencilBlock) );
  3327. VH( FixupRSPointer((SRasterizerBlock**) &pTech->pPasses[iPass].BackingStore.pRasterizerBlock) );
  3328. VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pVertexShaderBlock) );
  3329. VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pPixelShaderBlock) );
  3330. VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pGeometryShaderBlock) );
  3331. VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pHullShaderBlock) );
  3332. VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pDomainShaderBlock) );
  3333. VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pComputeShaderBlock) );
  3334. VH( FixupDepthStencilViewPointer( &pTech->pPasses[iPass].BackingStore.pDepthStencilView) );
  3335. for (size_t iRT = 0; iRT < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; iRT++)
  3336. {
  3337. VH( FixupRenderTargetViewPointer( &pTech->pPasses[iPass].BackingStore.pRenderTargetViews[iRT] ) );
  3338. }
  3339. }
  3340. VH( ReallocateBlockAssignments( pTech->pPasses, pTech->PassCount, pOldPasses ) );
  3341. }
  3342. }
  3343. VH( FixupGroupPointer( &m_pEffect->m_pNullGroup ) );
  3344. // Move anonymous shader variables
  3345. VHD( pHeap->MoveData((void **) &m_pEffect->m_pAnonymousShaders, cbAnonymousShaders), "Internal loading error: cannot move anonymous shaders." );
  3346. for (size_t i=0; i<m_pEffect->m_AnonymousShaderCount; ++i)
  3347. {
  3348. SAnonymousShader *pAnonymousShader = m_pEffect->m_pAnonymousShaders + i;
  3349. VH( FixupShaderPointer((SShaderBlock**) &pAnonymousShader->pShaderBlock) );
  3350. }
  3351. VBD( pHeap->GetSize() == m_EffectMemory, "Loading error: effect size mismatch." );
  3352. lExit:
  3353. return hr;
  3354. }
  3355. #pragma warning(pop)
  3356. }