ValidationTest.cpp 149 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // ValidationTest.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #define NOMINMAX
  11. #include <memory>
  12. #include <vector>
  13. #include <string>
  14. #include <algorithm>
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/Support/Regex.h"
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "dxc/DxilContainer/DxilContainer.h"
  19. #include "dxc/DxilContainer/DxilContainerAssembler.h"
  20. #ifdef _WIN32
  21. #include <atlbase.h>
  22. #endif
  23. #include "dxc/Support/Global.h"
  24. #include "dxc/Support/FileIOHelper.h"
  25. #include "DxcTestUtils.h"
  26. #include "HlslTestUtils.h"
  27. using namespace std;
  28. using namespace hlsl;
  29. #ifdef _WIN32
  30. class ValidationTest {
  31. #else
  32. class ValidationTest : public ::testing::Test {
  33. #endif
  34. public:
  35. BEGIN_TEST_CLASS(ValidationTest)
  36. TEST_CLASS_PROPERTY(L"Parallel", L"true")
  37. TEST_METHOD_PROPERTY(L"Priority", L"0")
  38. END_TEST_CLASS()
  39. TEST_CLASS_SETUP(InitSupport);
  40. TEST_METHOD(WhenCorrectThenOK)
  41. TEST_METHOD(WhenMisalignedThenFail)
  42. TEST_METHOD(WhenEmptyFileThenFail)
  43. TEST_METHOD(WhenIncorrectMagicThenFail)
  44. TEST_METHOD(WhenIncorrectTargetTripleThenFail)
  45. TEST_METHOD(WhenIncorrectModelThenFail)
  46. TEST_METHOD(WhenIncorrectPSThenFail)
  47. TEST_METHOD(WhenWaveAffectsGradientThenFail)
  48. TEST_METHOD(WhenMultipleModulesThenFail)
  49. TEST_METHOD(WhenUnexpectedEOFThenFail)
  50. TEST_METHOD(WhenUnknownBlocksThenFail)
  51. TEST_METHOD(WhenZeroInputPatchCountWithInputThenFail)
  52. TEST_METHOD(Float32DenormModeAttribute)
  53. TEST_METHOD(LoadOutputControlPointNotInPatchConstantFunction)
  54. TEST_METHOD(StorePatchControlNotInPatchConstantFunction)
  55. TEST_METHOD(OutputControlPointIDInPatchConstantFunction)
  56. TEST_METHOD(GsVertexIDOutOfBound)
  57. TEST_METHOD(StreamIDOutOfBound)
  58. TEST_METHOD(SignatureDataWidth)
  59. TEST_METHOD(SignatureStreamIDForNonGS)
  60. TEST_METHOD(TypedUAVStoreFullMask0)
  61. TEST_METHOD(TypedUAVStoreFullMask1)
  62. TEST_METHOD(Recursive)
  63. TEST_METHOD(Recursive2)
  64. TEST_METHOD(Recursive3)
  65. TEST_METHOD(ResourceRangeOverlap0)
  66. TEST_METHOD(ResourceRangeOverlap1)
  67. TEST_METHOD(ResourceRangeOverlap2)
  68. TEST_METHOD(ResourceRangeOverlap3)
  69. TEST_METHOD(CBufferOverlap0)
  70. TEST_METHOD(CBufferOverlap1)
  71. TEST_METHOD(ControlFlowHint)
  72. TEST_METHOD(ControlFlowHint1)
  73. TEST_METHOD(ControlFlowHint2)
  74. TEST_METHOD(SemanticLength1)
  75. TEST_METHOD(SemanticLength64)
  76. TEST_METHOD(PullModelPosition)
  77. TEST_METHOD(StructBufStrideAlign)
  78. TEST_METHOD(StructBufStrideOutOfBound)
  79. TEST_METHOD(StructBufGlobalCoherentAndCounter)
  80. TEST_METHOD(StructBufLoadCoordinates)
  81. TEST_METHOD(StructBufStoreCoordinates)
  82. TEST_METHOD(TypedBufRetType)
  83. TEST_METHOD(VsInputSemantic)
  84. TEST_METHOD(VsOutputSemantic)
  85. TEST_METHOD(HsInputSemantic)
  86. TEST_METHOD(HsOutputSemantic)
  87. TEST_METHOD(PatchConstSemantic)
  88. TEST_METHOD(DsInputSemantic)
  89. TEST_METHOD(DsOutputSemantic)
  90. TEST_METHOD(GsInputSemantic)
  91. TEST_METHOD(GsOutputSemantic)
  92. TEST_METHOD(PsInputSemantic)
  93. TEST_METHOD(PsOutputSemantic)
  94. TEST_METHOD(ArrayOfSVTarget)
  95. TEST_METHOD(InfiniteLog)
  96. TEST_METHOD(InfiniteAsin)
  97. TEST_METHOD(InfiniteAcos)
  98. TEST_METHOD(InfiniteDdxDdy)
  99. TEST_METHOD(IDivByZero)
  100. TEST_METHOD(UDivByZero)
  101. TEST_METHOD(UnusedMetadata)
  102. TEST_METHOD(MemoryOutOfBound)
  103. TEST_METHOD(LocalRes2)
  104. TEST_METHOD(LocalRes3)
  105. TEST_METHOD(LocalRes5)
  106. TEST_METHOD(LocalRes5Dbg)
  107. TEST_METHOD(LocalRes6)
  108. TEST_METHOD(LocalRes6Dbg)
  109. TEST_METHOD(AddrSpaceCast)
  110. TEST_METHOD(PtrBitCast)
  111. TEST_METHOD(MinPrecisionBitCast)
  112. TEST_METHOD(StructBitCast)
  113. TEST_METHOD(MultiDimArray)
  114. TEST_METHOD(SimpleGs8)
  115. TEST_METHOD(SimpleGs9)
  116. TEST_METHOD(SimpleGs10)
  117. TEST_METHOD(IllegalSampleOffset3)
  118. TEST_METHOD(IllegalSampleOffset4)
  119. TEST_METHOD(NoFunctionParam)
  120. TEST_METHOD(I8Type)
  121. TEST_METHOD(EmptyStructInBuffer)
  122. TEST_METHOD(BigStructInBuffer)
  123. TEST_METHOD(GloballyCoherent2)
  124. TEST_METHOD(GloballyCoherent3)
  125. // TODO: enable this.
  126. //TEST_METHOD(TGSMRaceCond)
  127. //TEST_METHOD(TGSMRaceCond2)
  128. TEST_METHOD(AddUint64Odd)
  129. TEST_METHOD(BarycentricFloat4Fail)
  130. TEST_METHOD(BarycentricMaxIndexFail)
  131. TEST_METHOD(BarycentricNoInterpolationFail)
  132. TEST_METHOD(BarycentricSamePerspectiveFail)
  133. TEST_METHOD(ClipCullMaxComponents)
  134. TEST_METHOD(ClipCullMaxRows)
  135. TEST_METHOD(DuplicateSysValue)
  136. TEST_METHOD(FunctionAttributes)
  137. TEST_METHOD(GSMainMissingAttributeFail)
  138. TEST_METHOD(GSOtherMissingAttributeFail)
  139. TEST_METHOD(GSMissingMaxVertexCountFail)
  140. TEST_METHOD(HSMissingPCFFail)
  141. TEST_METHOD(GetAttributeAtVertexInVSFail)
  142. TEST_METHOD(GetAttributeAtVertexIn60Fail)
  143. TEST_METHOD(GetAttributeAtVertexInterpFail)
  144. TEST_METHOD(SemTargetMax)
  145. TEST_METHOD(SemTargetIndexMatchesRow)
  146. TEST_METHOD(SemTargetCol0)
  147. TEST_METHOD(SemIndexMax)
  148. TEST_METHOD(SemTessFactorIndexMax)
  149. TEST_METHOD(SemInsideTessFactorIndexMax)
  150. TEST_METHOD(SemShouldBeAllocated)
  151. TEST_METHOD(SemShouldNotBeAllocated)
  152. TEST_METHOD(SemComponentOrder)
  153. TEST_METHOD(SemComponentOrder2)
  154. TEST_METHOD(SemComponentOrder3)
  155. TEST_METHOD(SemIndexConflictArbSV)
  156. TEST_METHOD(SemIndexConflictTessfactors)
  157. TEST_METHOD(SemIndexConflictTessfactors2)
  158. TEST_METHOD(SemRowOutOfRange)
  159. TEST_METHOD(SemPackOverlap)
  160. TEST_METHOD(SemPackOverlap2)
  161. TEST_METHOD(SemMultiDepth)
  162. TEST_METHOD(WhenInstrDisallowedThenFail)
  163. TEST_METHOD(WhenDepthNotFloatThenFail)
  164. TEST_METHOD(BarrierFail)
  165. TEST_METHOD(CBufferLegacyOutOfBoundFail)
  166. TEST_METHOD(CsThreadSizeFail)
  167. TEST_METHOD(DeadLoopFail)
  168. TEST_METHOD(EvalFail)
  169. TEST_METHOD(GetDimCalcLODFail)
  170. TEST_METHOD(HsAttributeFail)
  171. TEST_METHOD(InnerCoverageFail)
  172. TEST_METHOD(InterpChangeFail)
  173. TEST_METHOD(InterpOnIntFail)
  174. TEST_METHOD(InvalidSigCompTyFail)
  175. TEST_METHOD(MultiStream2Fail)
  176. TEST_METHOD(PhiTGSMFail)
  177. TEST_METHOD(QuadOpInVS)
  178. TEST_METHOD(ReducibleFail)
  179. TEST_METHOD(SampleBiasFail)
  180. TEST_METHOD(SamplerKindFail)
  181. TEST_METHOD(SemaOverlapFail)
  182. TEST_METHOD(SigOutOfRangeFail)
  183. TEST_METHOD(SigOverlapFail)
  184. TEST_METHOD(SimpleHs1Fail)
  185. TEST_METHOD(SimpleHs3Fail)
  186. TEST_METHOD(SimpleHs4Fail)
  187. TEST_METHOD(SimpleDs1Fail)
  188. TEST_METHOD(SimpleGs1Fail)
  189. TEST_METHOD(UavBarrierFail)
  190. TEST_METHOD(UndefValueFail)
  191. TEST_METHOD(UpdateCounterFail)
  192. TEST_METHOD(LocalResCopy)
  193. TEST_METHOD(ResCounter)
  194. TEST_METHOD(WhenSmUnknownThenFail)
  195. TEST_METHOD(WhenSmLegacyThenFail)
  196. TEST_METHOD(WhenMetaFlagsUsageDeclThenOK)
  197. TEST_METHOD(WhenMetaFlagsUsageThenFail)
  198. TEST_METHOD(WhenRootSigMismatchThenFail)
  199. TEST_METHOD(WhenRootSigCompatThenSucceed)
  200. TEST_METHOD(WhenRootSigMatchShaderSucceed_RootConstVis)
  201. TEST_METHOD(WhenRootSigMatchShaderFail_RootConstVis)
  202. TEST_METHOD(WhenRootSigMatchShaderSucceed_RootCBV)
  203. TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Range)
  204. TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Space)
  205. TEST_METHOD(WhenRootSigMatchShaderSucceed_RootSRV)
  206. TEST_METHOD(WhenRootSigMatchShaderFail_RootSRV_ResType)
  207. TEST_METHOD(WhenRootSigMatchShaderSucceed_RootUAV)
  208. TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable)
  209. TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_GoodRange)
  210. TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_Unbounded)
  211. TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range1)
  212. TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range2)
  213. TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range3)
  214. TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Space)
  215. TEST_METHOD(WhenRootSigMatchShaderSucceed_Unbounded)
  216. TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded1)
  217. TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded2)
  218. TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded3)
  219. TEST_METHOD(WhenProgramOutSigMissingThenFail)
  220. TEST_METHOD(WhenProgramOutSigUnexpectedThenFail)
  221. TEST_METHOD(WhenProgramSigMismatchThenFail)
  222. TEST_METHOD(WhenProgramInSigMissingThenFail)
  223. TEST_METHOD(WhenProgramSigMismatchThenFail2)
  224. TEST_METHOD(WhenProgramPCSigMissingThenFail)
  225. TEST_METHOD(WhenPSVMismatchThenFail)
  226. TEST_METHOD(WhenRDATMismatchThenFail)
  227. TEST_METHOD(WhenFeatureInfoMismatchThenFail)
  228. TEST_METHOD(RayShaderWithSignaturesFail)
  229. TEST_METHOD(ViewIDInCSFail)
  230. TEST_METHOD(ViewIDIn60Fail)
  231. TEST_METHOD(ViewIDNoSpaceFail)
  232. TEST_METHOD(LibFunctionResInSig)
  233. TEST_METHOD(RayPayloadIsStruct)
  234. TEST_METHOD(RayAttrIsStruct)
  235. TEST_METHOD(CallableParamIsStruct)
  236. TEST_METHOD(RayShaderExtraArg)
  237. TEST_METHOD(ResInShaderStruct)
  238. TEST_METHOD(WhenPayloadSizeTooSmallThenFail)
  239. TEST_METHOD(WhenMissingPayloadThenFail)
  240. TEST_METHOD(ShaderFunctionReturnTypeVoid)
  241. TEST_METHOD(WhenDisassembleInvalidBlobThenFail)
  242. TEST_METHOD(MeshMultipleSetMeshOutputCounts)
  243. TEST_METHOD(MeshMissingSetMeshOutputCounts)
  244. TEST_METHOD(MeshNonDominatingSetMeshOutputCounts)
  245. TEST_METHOD(MeshOversizePayload)
  246. TEST_METHOD(MeshOversizeOutput)
  247. TEST_METHOD(MeshOversizePayloadOutput)
  248. TEST_METHOD(MeshMultipleGetMeshPayload)
  249. TEST_METHOD(MeshOutofRangeMaxVertexCount)
  250. TEST_METHOD(MeshOutofRangeMaxPrimitiveCount)
  251. TEST_METHOD(MeshLessThanMinX)
  252. TEST_METHOD(MeshGreaterThanMaxX)
  253. TEST_METHOD(MeshLessThanMinY)
  254. TEST_METHOD(MeshGreaterThanMaxY)
  255. TEST_METHOD(MeshLessThanMinZ)
  256. TEST_METHOD(MeshGreaterThanMaxZ)
  257. TEST_METHOD(MeshGreaterThanMaxXYZ)
  258. TEST_METHOD(MeshGreaterThanMaxVSigRowCount)
  259. TEST_METHOD(MeshGreaterThanMaxPSigRowCount)
  260. TEST_METHOD(MeshGreaterThanMaxTotalSigRowCount)
  261. TEST_METHOD(MeshOversizeSM)
  262. TEST_METHOD(AmplificationMultipleDispatchMesh)
  263. TEST_METHOD(AmplificationMissingDispatchMesh)
  264. TEST_METHOD(AmplificationNonDominatingDispatchMesh)
  265. TEST_METHOD(AmplificationOversizePayload)
  266. TEST_METHOD(AmplificationLessThanMinX)
  267. TEST_METHOD(AmplificationGreaterThanMaxX)
  268. TEST_METHOD(AmplificationLessThanMinY)
  269. TEST_METHOD(AmplificationGreaterThanMaxY)
  270. TEST_METHOD(AmplificationLessThanMinZ)
  271. TEST_METHOD(AmplificationGreaterThanMaxZ)
  272. TEST_METHOD(AmplificationGreaterThanMaxXYZ)
  273. dxc::DxcDllSupport m_dllSupport;
  274. VersionSupportInfo m_ver;
  275. void TestCheck(LPCWSTR name) {
  276. std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(name);
  277. FileRunTestResult t = FileRunTestResult::RunFromFileCommands(fullPath.c_str());
  278. if (t.RunResult != 0) {
  279. CA2W commentWide(t.ErrorMessage.c_str(), CP_UTF8);
  280. WEX::Logging::Log::Comment(commentWide);
  281. WEX::Logging::Log::Error(L"Run result is not zero");
  282. }
  283. }
  284. void CheckValidationMsgs(IDxcBlob *pBlob, llvm::ArrayRef<LPCSTR> pErrorMsgs, bool bRegex = false) {
  285. CComPtr<IDxcValidator> pValidator;
  286. CComPtr<IDxcOperationResult> pResult;
  287. UINT32 Flags = DxcValidatorFlags_Default;
  288. if (!IsDxilContainerLike(pBlob->GetBufferPointer(), pBlob->GetBufferSize())) {
  289. // Validation of raw bitcode as opposed to DxilContainer is not supported through DXIL.dll
  290. if (!m_ver.m_InternalValidator) {
  291. WEX::Logging::Log::Comment(L"Test skipped due to validation of raw bitcode without container and use of external DXIL.dll validator.");
  292. return;
  293. }
  294. Flags |= DxcValidatorFlags_ModuleOnly;
  295. }
  296. VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcValidator, &pValidator));
  297. VERIFY_SUCCEEDED(pValidator->Validate(pBlob, Flags, &pResult));
  298. CheckOperationResultMsgs(pResult, pErrorMsgs, false, bRegex);
  299. }
  300. void CheckValidationMsgs(const char *pBlob, size_t blobSize, llvm::ArrayRef<LPCSTR> pErrorMsgs, bool bRegex = false) {
  301. CComPtr<IDxcLibrary> pLibrary;
  302. CComPtr<IDxcBlobEncoding> pBlobEncoding; // Encoding doesn't actually matter, it's binary.
  303. VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
  304. VERIFY_SUCCEEDED(pLibrary->CreateBlobWithEncodingFromPinned(pBlob, blobSize, CP_UTF8, &pBlobEncoding));
  305. CheckValidationMsgs(pBlobEncoding, pErrorMsgs, bRegex);
  306. }
  307. bool CompileSource(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
  308. LPCWSTR *pArguments, UINT32 argCount, const DxcDefine *pDefines,
  309. UINT32 defineCount, IDxcBlob **pResultBlob) {
  310. CComPtr<IDxcCompiler> pCompiler;
  311. CComPtr<IDxcOperationResult> pResult;
  312. CComPtr<IDxcBlob> pProgram;
  313. CA2W shWide(pShaderModel, CP_UTF8);
  314. wchar_t *pEntryName = L"main";
  315. llvm::StringRef stage;
  316. unsigned RequiredDxilMajor = 1, RequiredDxilMinor = 0;
  317. if (ParseTargetProfile(pShaderModel, stage, RequiredDxilMajor, RequiredDxilMinor)) {
  318. if (stage.compare("lib") == 0)
  319. pEntryName = L"";
  320. if (stage.compare("rootsig") != 0) {
  321. RequiredDxilMajor = std::max(RequiredDxilMajor, (unsigned)6) - 5;
  322. if (m_ver.SkipDxilVersion(RequiredDxilMajor, RequiredDxilMinor))
  323. return false;
  324. }
  325. }
  326. std::vector<LPCWSTR> args;
  327. args.reserve(argCount + 1);
  328. args.insert(args.begin(), pArguments, pArguments + argCount);
  329. args.emplace_back(L"-Qkeep_reflect_in_dxil");
  330. VERIFY_SUCCEEDED(
  331. m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
  332. VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", pEntryName, shWide,
  333. args.data(), (UINT32)args.size(), pDefines,
  334. defineCount, nullptr, &pResult));
  335. CheckOperationResultMsgs(pResult, nullptr, false, false);
  336. VERIFY_SUCCEEDED(pResult->GetResult(pResultBlob));
  337. return true;
  338. }
  339. bool CompileSource(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
  340. IDxcBlob **pResultBlob) {
  341. return CompileSource(pSource, pShaderModel, nullptr, 0, nullptr, 0, pResultBlob);
  342. }
  343. bool CompileSource(LPCSTR pSource, LPCSTR pShaderModel,
  344. IDxcBlob **pResultBlob) {
  345. CComPtr<IDxcBlobEncoding> pSourceBlob;
  346. Utf8ToBlob(m_dllSupport, pSource, &pSourceBlob);
  347. return CompileSource(pSourceBlob, pShaderModel, nullptr, 0, nullptr, 0, pResultBlob);
  348. }
  349. void DisassembleProgram(IDxcBlob *pProgram, std::string *text) {
  350. *text = ::DisassembleProgram(m_dllSupport, pProgram);
  351. }
  352. bool RewriteAssemblyCheckMsg(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
  353. LPCWSTR *pArguments, UINT32 argCount,
  354. const DxcDefine *pDefines, UINT32 defineCount,
  355. llvm::ArrayRef<LPCSTR> pLookFors,
  356. llvm::ArrayRef<LPCSTR> pReplacements,
  357. llvm::ArrayRef<LPCSTR> pErrorMsgs,
  358. bool bRegex = false) {
  359. CComPtr<IDxcBlob> pText;
  360. if (!RewriteAssemblyToText(pSource, pShaderModel, pArguments, argCount, pDefines, defineCount, pLookFors, pReplacements, &pText, bRegex))
  361. return false;
  362. CComPtr<IDxcAssembler> pAssembler;
  363. CComPtr<IDxcOperationResult> pAssembleResult;
  364. VERIFY_SUCCEEDED(
  365. m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
  366. VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pText, &pAssembleResult));
  367. if (!CheckOperationResultMsgs(pAssembleResult, pErrorMsgs, true, bRegex)) {
  368. // Assembly succeeded, try validation.
  369. CComPtr<IDxcBlob> pBlob;
  370. VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pBlob));
  371. CheckValidationMsgs(pBlob, pErrorMsgs, bRegex);
  372. }
  373. return true;
  374. }
  375. void RewriteAssemblyCheckMsg(LPCSTR pSource, LPCSTR pShaderModel,
  376. LPCWSTR *pArguments, UINT32 argCount,
  377. const DxcDefine *pDefines, UINT32 defineCount,
  378. llvm::ArrayRef<LPCSTR> pLookFors,
  379. llvm::ArrayRef<LPCSTR> pReplacements,
  380. llvm::ArrayRef<LPCSTR> pErrorMsgs,
  381. bool bRegex = false) {
  382. CComPtr<IDxcBlobEncoding> pSourceBlob;
  383. Utf8ToBlob(m_dllSupport, pSource, &pSourceBlob);
  384. RewriteAssemblyCheckMsg(pSourceBlob, pShaderModel, pArguments, argCount,
  385. pDefines, defineCount, pLookFors, pReplacements,
  386. pErrorMsgs, bRegex);
  387. }
  388. void RewriteAssemblyCheckMsg(LPCSTR pSource, LPCSTR pShaderModel,
  389. llvm::ArrayRef<LPCSTR> pLookFors, llvm::ArrayRef<LPCSTR> pReplacements,
  390. llvm::ArrayRef<LPCSTR> pErrorMsgs, bool bRegex = false) {
  391. RewriteAssemblyCheckMsg(pSource, pShaderModel, nullptr, 0, nullptr, 0, pLookFors, pReplacements, pErrorMsgs, bRegex);
  392. }
  393. void RewriteAssemblyCheckMsg(LPCWSTR name, LPCSTR pShaderModel,
  394. LPCWSTR *pArguments, UINT32 argCount,
  395. const DxcDefine *pDefines, UINT32 defCount,
  396. llvm::ArrayRef<LPCSTR> pLookFors,
  397. llvm::ArrayRef<LPCSTR> pReplacements,
  398. llvm::ArrayRef<LPCSTR> pErrorMsgs,
  399. bool bRegex = false) {
  400. std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(name);
  401. CComPtr<IDxcLibrary> pLibrary;
  402. CComPtr<IDxcBlobEncoding> pSource;
  403. VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
  404. VERIFY_SUCCEEDED(
  405. pLibrary->CreateBlobFromFile(fullPath.c_str(), nullptr, &pSource));
  406. RewriteAssemblyCheckMsg(pSource, pShaderModel,
  407. pArguments, argCount, pDefines, defCount, pLookFors,
  408. pReplacements, pErrorMsgs, bRegex);
  409. }
  410. void RewriteAssemblyCheckMsg(LPCWSTR name, LPCSTR pShaderModel,
  411. llvm::ArrayRef<LPCSTR> pLookFors,
  412. llvm::ArrayRef<LPCSTR> pReplacements,
  413. llvm::ArrayRef<LPCSTR> pErrorMsgs,
  414. bool bRegex = false) {
  415. RewriteAssemblyCheckMsg(name, pShaderModel, nullptr, 0, nullptr, 0,
  416. pLookFors, pReplacements, pErrorMsgs, bRegex);
  417. }
  418. bool RewriteAssemblyToText(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
  419. LPCWSTR *pArguments, UINT32 argCount,
  420. const DxcDefine *pDefines, UINT32 defineCount,
  421. llvm::ArrayRef<LPCSTR> pLookFors,
  422. llvm::ArrayRef<LPCSTR> pReplacements,
  423. IDxcBlob **pBlob, bool bRegex = false) {
  424. CComPtr<IDxcBlob> pProgram;
  425. std::string disassembly;
  426. if (!CompileSource(pSource, pShaderModel, pArguments, argCount, pDefines, defineCount, &pProgram))
  427. return false;
  428. DisassembleProgram(pProgram, &disassembly);
  429. for (unsigned i = 0; i < pLookFors.size(); ++i) {
  430. LPCSTR pLookFor = pLookFors[i];
  431. bool bOptional = false;
  432. if (pLookFor[0] == '?') {
  433. bOptional = true;
  434. pLookFor++;
  435. }
  436. LPCSTR pReplacement = pReplacements[i];
  437. if (pLookFor && *pLookFor) {
  438. if (bRegex) {
  439. llvm::Regex RE(pLookFor);
  440. std::string reErrors;
  441. VERIFY_IS_TRUE(RE.isValid(reErrors));
  442. std::string replaced = RE.sub(pReplacement, disassembly, &reErrors);
  443. if (!bOptional) {
  444. VERIFY_ARE_NOT_EQUAL(disassembly, replaced);
  445. VERIFY_IS_TRUE(reErrors.empty());
  446. }
  447. disassembly = std::move(replaced);
  448. } else {
  449. bool found = false;
  450. size_t pos = 0;
  451. size_t lookForLen = strlen(pLookFor);
  452. size_t replaceLen = strlen(pReplacement);
  453. for (;;) {
  454. pos = disassembly.find(pLookFor, pos);
  455. if (pos == std::string::npos)
  456. break;
  457. found = true; // at least once
  458. disassembly.replace(pos, lookForLen, pReplacement);
  459. pos += replaceLen;
  460. }
  461. if (!bOptional) {
  462. VERIFY_IS_TRUE(found);
  463. }
  464. }
  465. }
  466. }
  467. Utf8ToBlob(m_dllSupport, disassembly.c_str(), pBlob);
  468. return true;
  469. }
  470. // compile one or two sources, validate module from 1 with container parts from 2, check messages
  471. bool ReplaceContainerPartsCheckMsgs(LPCSTR pSource1, LPCSTR pSource2, LPCSTR pShaderModel,
  472. llvm::ArrayRef<DxilFourCC> PartsToReplace,
  473. llvm::ArrayRef<LPCSTR> pErrorMsgs) {
  474. CComPtr<IDxcBlob> pProgram1, pProgram2;
  475. if (!CompileSource(pSource1, pShaderModel, &pProgram1))
  476. return false;
  477. VERIFY_IS_NOT_NULL(pProgram1);
  478. if (pSource2) {
  479. if (!CompileSource(pSource2, pShaderModel, &pProgram2))
  480. return false;
  481. VERIFY_IS_NOT_NULL(pProgram2);
  482. } else {
  483. pProgram2 = pProgram1;
  484. }
  485. // construct container with module from pProgram1 with other parts from pProgram2:
  486. const DxilContainerHeader *pHeader1 = IsDxilContainerLike(pProgram1->GetBufferPointer(), pProgram1->GetBufferSize());
  487. VERIFY_IS_NOT_NULL(pHeader1);
  488. const DxilContainerHeader *pHeader2 = IsDxilContainerLike(pProgram2->GetBufferPointer(), pProgram2->GetBufferSize());
  489. VERIFY_IS_NOT_NULL(pHeader2);
  490. unique_ptr<DxilContainerWriter> pContainerWriter(NewDxilContainerWriter());
  491. // Add desired parts from first container
  492. for (auto pPart : pHeader1) {
  493. for (auto dfcc : PartsToReplace) {
  494. if (dfcc == pPart->PartFourCC) {
  495. pPart = nullptr;
  496. break;
  497. }
  498. }
  499. if (!pPart)
  500. continue;
  501. pContainerWriter->AddPart(pPart->PartFourCC, pPart->PartSize, [=](AbstractMemoryStream *pStream) {
  502. ULONG cbWritten = 0;
  503. pStream->Write(GetDxilPartData(pPart), pPart->PartSize, &cbWritten);
  504. });
  505. }
  506. // Add desired parts from second container
  507. for (auto pPart : pHeader2) {
  508. for (auto dfcc : PartsToReplace) {
  509. if (dfcc == pPart->PartFourCC) {
  510. pContainerWriter->AddPart(pPart->PartFourCC, pPart->PartSize, [=](AbstractMemoryStream *pStream) {
  511. ULONG cbWritten = 0;
  512. pStream->Write(GetDxilPartData(pPart), pPart->PartSize, &cbWritten);
  513. });
  514. break;
  515. }
  516. }
  517. }
  518. // Write the container
  519. CComPtr<IMalloc> pMalloc;
  520. VERIFY_SUCCEEDED(CoGetMalloc(1, &pMalloc));
  521. CComPtr<AbstractMemoryStream> pOutputStream;
  522. VERIFY_SUCCEEDED(CreateMemoryStream(pMalloc, &pOutputStream));
  523. pOutputStream->Reserve(pContainerWriter->size());
  524. pContainerWriter->write(pOutputStream);
  525. CheckValidationMsgs((const char *)pOutputStream->GetPtr(), pOutputStream->GetPtrSize(), pErrorMsgs, /*bRegex*/false);
  526. return true;
  527. }
  528. };
  529. bool ValidationTest::InitSupport() {
  530. if (!m_dllSupport.IsEnabled()) {
  531. VERIFY_SUCCEEDED(m_dllSupport.Initialize());
  532. m_ver.Initialize(m_dllSupport);
  533. }
  534. return true;
  535. }
  536. TEST_F(ValidationTest, WhenCorrectThenOK) {
  537. CComPtr<IDxcBlob> pProgram;
  538. CompileSource("float4 main() : SV_Target { return 1; }", "ps_6_0", &pProgram);
  539. CheckValidationMsgs(pProgram, nullptr);
  540. }
  541. // Lots of these going on below for simplicity in setting up payloads.
  542. //
  543. // warning C4838: conversion from 'int' to 'const char' requires a narrowing conversion
  544. // warning C4309: 'initializing': truncation of constant value
  545. #pragma warning(disable: 4838)
  546. #pragma warning(disable: 4309)
  547. TEST_F(ValidationTest, WhenMisalignedThenFail) {
  548. // Bitcode size must 4-byte aligned
  549. const char blob[] = {
  550. 'B', 'C',
  551. };
  552. CheckValidationMsgs(blob, _countof(blob), "Invalid bitcode size");
  553. }
  554. TEST_F(ValidationTest, WhenEmptyFileThenFail) {
  555. // No blocks after signature.
  556. const char blob[] = {
  557. 'B', 'C', (char)0xc0, (char)0xde
  558. };
  559. CheckValidationMsgs(blob, _countof(blob), "Malformed IR file");
  560. }
  561. TEST_F(ValidationTest, WhenIncorrectMagicThenFail) {
  562. // Signature isn't 'B', 'C', 0xC0 0xDE
  563. const char blob[] = {
  564. 'B', 'C', (char)0xc0, (char)0xdd
  565. };
  566. CheckValidationMsgs(blob, _countof(blob), "Invalid bitcode signature");
  567. }
  568. TEST_F(ValidationTest, WhenIncorrectTargetTripleThenFail) {
  569. const char blob[] = {
  570. 'B', 'C', (char)0xc0, (char)0xde
  571. };
  572. CheckValidationMsgs(blob, _countof(blob), "Malformed IR file");
  573. }
  574. TEST_F(ValidationTest, WhenMultipleModulesThenFail) {
  575. const char blob[] = {
  576. 'B', 'C', (char)0xc0, (char)0xde,
  577. 0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
  578. 0x00, 0x00, 0x00, 0x00, // NumWords = 0
  579. 0x08, 0x00, 0x00, 0x00, // End-of-block, padding
  580. // At this point, this is valid bitcode (but missing required DXIL metadata)
  581. // Trigger the case we're looking for now
  582. 0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
  583. };
  584. CheckValidationMsgs(blob, _countof(blob), "Unused bits in buffer");
  585. }
  586. TEST_F(ValidationTest, WhenUnexpectedEOFThenFail) {
  587. // Importantly, this is testing the usage of report_fatal_error during deserialization.
  588. const char blob[] = {
  589. 'B', 'C', (char)0xc0, (char)0xde,
  590. 0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
  591. 0x00, 0x00, 0x00, 0x00, // NumWords = 0
  592. };
  593. CheckValidationMsgs(blob, _countof(blob), "Invalid record");
  594. }
  595. TEST_F(ValidationTest, WhenUnknownBlocksThenFail) {
  596. const char blob[] = {
  597. 'B', 'C', (char)0xc0, (char)0xde, // Signature
  598. 0x31, 0x00, 0x00, 0x00 // Enter sub-block, BlockID != 8
  599. };
  600. CheckValidationMsgs(blob, _countof(blob), "Unrecognized block found");
  601. }
  602. TEST_F(ValidationTest, WhenZeroInputPatchCountWithInputThenFail) {
  603. RewriteAssemblyCheckMsg(
  604. L"..\\CodeGenHLSL\\validation\\SimpleHs1.hlsl", "hs_6_0",
  605. "void ()* @\"\\01?HSPerPatchFunc@@YA?AUHSPerPatchData@@V?$InputPatch@UPSSceneIn@@$02@@@Z\", i32 3, i32 3",
  606. "void ()* @\"\\01?HSPerPatchFunc@@YA?AUHSPerPatchData@@V?$InputPatch@UPSSceneIn@@$02@@@Z\", i32 0, i32 3",
  607. "When HS input control point count is 0, no input signature should exist");
  608. }
  609. TEST_F(ValidationTest, WhenInstrDisallowedThenFail) {
  610. RewriteAssemblyCheckMsg(
  611. L"..\\CodeGenHLSL\\validation\\abs2.hlsl", "ps_6_0",
  612. {
  613. "target triple = \"dxil-ms-dx\"",
  614. "ret void",
  615. "dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 3, i32 undef)",
  616. "!\"ps\", i32 6, i32 0",
  617. },
  618. {
  619. "target triple = \"dxil-ms-dx\"\n%dx.types.wave_t = type { i8* }",
  620. "unreachable",
  621. "dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 3, i32 undef)\n%wave_local = alloca %dx.types.wave_t",
  622. "!\"vs\", i32 6, i32 0",
  623. },
  624. {"Semantic 'SV_Target' is invalid as vs Output",
  625. "Declaration '%dx.types.wave_t = type { i8* }' uses a reserved prefix",
  626. "Instructions must be of an allowed type",
  627. }
  628. );
  629. }
  630. TEST_F(ValidationTest, WhenDepthNotFloatThenFail) {
  631. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\IntegerDepth2.hlsl", "ps_6_0",
  632. {
  633. "!\"SV_Depth\", i8 9",
  634. },
  635. {
  636. "!\"SV_Depth\", i8 4",
  637. },
  638. {
  639. "SV_Depth must be float",
  640. });
  641. }
  642. TEST_F(ValidationTest, BarrierFail) {
  643. if (m_ver.SkipIRSensitiveTest()) return;
  644. RewriteAssemblyCheckMsg(
  645. L"..\\CodeGenHLSL\\barrier.hlsl", "cs_6_0",
  646. {"dx.op.barrier(i32 80, i32 8)",
  647. "dx.op.barrier(i32 80, i32 9)",
  648. "dx.op.barrier(i32 80, i32 11)",
  649. "%\"class.RWStructuredBuffer<matrix<float, 2, 2> >\" = type { %class.matrix.float.2.2 }\n",
  650. "call i32 @dx.op.flattenedThreadIdInGroup.i32(i32 96)",
  651. },
  652. {"dx.op.barrier(i32 80, i32 15)",
  653. "dx.op.barrier(i32 80, i32 0)",
  654. "dx.op.barrier(i32 80, i32 %rem)",
  655. "%\"class.RWStructuredBuffer<matrix<float, 2, 2> >\" = type { %class.matrix.float.2.2 }\n"
  656. "@dx.typevar.8 = external addrspace(1) constant %\"class.RWStructuredBuffer<matrix<float, 2, 2> >\"\n"
  657. "@\"internalGV\" = internal global [64 x <4 x float>] undef\n",
  658. "call i32 @dx.op.flattenedThreadIdInGroup.i32(i32 96)\n"
  659. "%load = load %\"class.RWStructuredBuffer<matrix<float, 2, 2> >\", %\"class.RWStructuredBuffer<matrix<float, 2, 2> >\" addrspace(1)* @dx.typevar.8",
  660. },
  661. {"Internal declaration 'internalGV' is unused",
  662. "External declaration 'dx.typevar.8' is unused",
  663. "Vector type '<4 x float>' is not allowed",
  664. "Mode of Barrier must be an immediate constant",
  665. "sync must include some form of memory barrier - _u (UAV) and/or _g (Thread Group Shared Memory)",
  666. "sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal"
  667. });
  668. }
  669. TEST_F(ValidationTest, CBufferLegacyOutOfBoundFail) {
  670. RewriteAssemblyCheckMsg(
  671. L"..\\CodeGenHLSL\\validation\\cbuffer1.50.hlsl", "ps_6_0",
  672. "cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo2_cbuffer, i32 0)",
  673. "cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %Foo2_cbuffer, i32 6)",
  674. "Cbuffer access out of bound");
  675. }
  676. TEST_F(ValidationTest, CsThreadSizeFail) {
  677. RewriteAssemblyCheckMsg(
  678. L"..\\CodeGenHLSL\\validation\\share_mem1.hlsl", "cs_6_0",
  679. {"!{i32 8, i32 8, i32 1",
  680. "[256 x float]"},
  681. {"!{i32 1025, i32 1025, i32 1025",
  682. "[64000000 x float]"},
  683. {"Declared Thread Group X size 1025 outside valid range",
  684. "Declared Thread Group Y size 1025 outside valid range",
  685. "Declared Thread Group Z size 1025 outside valid range",
  686. "Declared Thread Group Count 1076890625 (X*Y*Z) is beyond the valid maximum",
  687. "Total Thread Group Shared Memory storage is 256000000, exceeded 32768",
  688. });
  689. }
  690. TEST_F(ValidationTest, DeadLoopFail) {
  691. if (m_ver.SkipIRSensitiveTest()) return;
  692. RewriteAssemblyCheckMsg(
  693. L"..\\CodeGenHLSL\\validation\\loop1.hlsl", "ps_6_0",
  694. {"br i1 %exitcond, label %for.end.loopexit, label %for.body, !llvm.loop !([0-9]+)",
  695. "?%add(\\.lcssa)? = phi float \\[ %add, %for.body \\]",
  696. "!dx.entryPoints = !\\{!([0-9]+)\\}",
  697. "\\[ %add(\\.lcssa)?, %for.end.loopexit \\]"
  698. },
  699. {"br label %for.body",
  700. "",
  701. "!dx.entryPoints = !\\{!\\1\\}\n!dx.unused = !\\{!\\1\\}",
  702. "[ 0.000000e+00, %for.end.loopexit ]"
  703. },
  704. {"Loop must have break",
  705. "Named metadata 'dx.unused' is unknown",
  706. },
  707. /*bRegex*/true);
  708. }
  709. TEST_F(ValidationTest, EvalFail) {
  710. RewriteAssemblyCheckMsg(
  711. L"..\\CodeGenHLSL\\validation\\eval.hlsl", "ps_6_0",
  712. "!\"A\", i8 9, i8 0, !([0-9]+), i8 2, i32 1, i8 4",
  713. "!\"A\", i8 9, i8 0, !\\1, i8 0, i32 1, i8 4",
  714. "Interpolation mode on A used with eval_\\* instruction must be ",
  715. /*bRegex*/true);
  716. }
  717. TEST_F(ValidationTest, GetDimCalcLODFail) {
  718. RewriteAssemblyCheckMsg(
  719. L"..\\CodeGenHLSL\\GetDimCalcLOD.hlsl", "ps_6_0",
  720. {"extractvalue %dx.types.Dimensions %([0-9]+), 1",
  721. "float 1.000000e\\+00, i1 true"
  722. },
  723. {"extractvalue %dx.types.Dimensions %\\1, 2",
  724. "float undef, i1 true"
  725. },
  726. {"GetDimensions used undef dimension z on TextureCube",
  727. "coord uninitialized"},
  728. /*bRegex*/true);
  729. }
  730. TEST_F(ValidationTest, HsAttributeFail) {
  731. RewriteAssemblyCheckMsg(
  732. L"..\\CodeGenHLSL\\hsAttribute.hlsl", "hs_6_0",
  733. {"i32 3, i32 3, i32 2, i32 3, i32 3, float 6.400000e+01"
  734. },
  735. {"i32 36, i32 36, i32 0, i32 0, i32 0, float 6.500000e+01"
  736. },
  737. {"HS input control point count must be [0..32]. 36 specified",
  738. "Invalid Tessellator Domain specified. Must be isoline, tri or quad",
  739. "Invalid Tessellator Partitioning specified",
  740. "Invalid Tessellator Output Primitive specified",
  741. "Hull Shader MaxTessFactor must be [1.000000..64.000000]. 65.000000 specified",
  742. "output control point count must be [0..32]. 36 specified"});
  743. }
  744. TEST_F(ValidationTest, InnerCoverageFail) {
  745. RewriteAssemblyCheckMsg(
  746. L"..\\CodeGenHLSL\\InnerCoverage2.hlsl", "ps_6_0",
  747. {"dx.op.coverage.i32(i32 91)",
  748. "declare i32 @dx.op.coverage.i32(i32)"
  749. },
  750. {"dx.op.coverage.i32(i32 91)\n %inner = call i32 @dx.op.innerCoverage.i32(i32 92)",
  751. "declare i32 @dx.op.coverage.i32(i32)\n"
  752. "declare i32 @dx.op.innerCoverage.i32(i32)"
  753. },
  754. "InnerCoverage and Coverage are mutually exclusive.");
  755. }
  756. TEST_F(ValidationTest, InterpChangeFail) {
  757. RewriteAssemblyCheckMsg(
  758. L"..\\CodeGenHLSL\\interpChange.hlsl", "ps_6_0",
  759. { "i32 1, i8 0, (.*)}",
  760. "?!dx.viewIdState ="},
  761. { "i32 0, i8 2, \\1}",
  762. "!1012 ="},
  763. "interpolation mode that differs from another element packed",
  764. /*bRegex*/true);
  765. }
  766. TEST_F(ValidationTest, InterpOnIntFail) {
  767. RewriteAssemblyCheckMsg(
  768. L"..\\CodeGenHLSL\\interpOnInt2.hlsl", "ps_6_0",
  769. "!\"A\", i8 5, i8 0, !([0-9]+), i8 1",
  770. "!\"A\", i8 5, i8 0, !\\1, i8 2",
  771. "signature element A specifies invalid interpolation mode for integer component type",
  772. /*bRegex*/true);
  773. }
  774. TEST_F(ValidationTest, InvalidSigCompTyFail) {
  775. RewriteAssemblyCheckMsg(
  776. L"..\\CodeGenHLSL\\validation\\abs2.hlsl", "ps_6_0",
  777. "!\"A\", i8 4",
  778. "!\"A\", i8 0",
  779. "A specifies unrecognized or invalid component type");
  780. }
  781. TEST_F(ValidationTest, MultiStream2Fail) {
  782. RewriteAssemblyCheckMsg(
  783. L"..\\CodeGenHLSL\\validation\\multiStreamGS.hlsl", "gs_6_0",
  784. "i32 1, i32 12, i32 7, i32 1, i32 1",
  785. "i32 1, i32 12, i32 7, i32 2, i32 1",
  786. "Multiple GS output streams are used but 'XXX' is not pointlist");
  787. }
  788. TEST_F(ValidationTest, PhiTGSMFail) {
  789. if (m_ver.SkipIRSensitiveTest()) return;
  790. RewriteAssemblyCheckMsg(
  791. L"..\\CodeGenHLSL\\phiTGSM.hlsl", "cs_6_0",
  792. "ret void",
  793. "%arrayPhi = phi i32 addrspace(3)* [ %arrayidx, %if.then ], [ %arrayidx2, %if.else ]\n"
  794. "%phiAtom = atomicrmw add i32 addrspace(3)* %arrayPhi, i32 1 seq_cst\n"
  795. "ret void",
  796. "TGSM pointers must originate from an unambiguous TGSM global variable");
  797. }
  798. TEST_F(ValidationTest, QuadOpInVS) {
  799. if (m_ver.SkipDxilVersion(1, 5)) return;
  800. RewriteAssemblyCheckMsg(
  801. "struct PerThreadData { int "
  802. "input; int output; }; RWStructuredBuffer<PerThreadData> g_sb; "
  803. "void main(uint vid : SV_VertexID)"
  804. "{ g_sb[vid].output = WaveActiveSum(g_sb[vid].input); }",
  805. "vs_6_0", {"@dx.op.waveActiveOp.i32(i32 119", "declare i32 @dx.op.waveActiveOp.i32(i32, i32, i8, i8)"},
  806. {"@dx.op.quadOp.i32(i32 123", "declare i32 @dx.op.quadOp.i32(i32, i32, i8, i8)"},
  807. "QuadOp not valid in shader model vs_6_0"
  808. );
  809. }
  810. TEST_F(ValidationTest, ReducibleFail) {
  811. if (m_ver.SkipIRSensitiveTest()) return;
  812. RewriteAssemblyCheckMsg(
  813. L"..\\CodeGenHLSL\\reducible.hlsl", "ps_6_0",
  814. {"%conv\n"
  815. " br label %if.end",
  816. "to float\n"
  817. " br label %if.end"
  818. },
  819. {"%conv\n"
  820. " br i1 %cmp, label %if.else, label %if.end",
  821. "to float\n"
  822. " br i1 %cmp, label %if.then, label %if.end"
  823. },
  824. "Execution flow must be reducible");
  825. }
  826. TEST_F(ValidationTest, SampleBiasFail) {
  827. RewriteAssemblyCheckMsg(
  828. L"..\\CodeGenHLSL\\validation\\sampleBias.hlsl", "ps_6_0",
  829. {"float -1.600000e+01"
  830. },
  831. {"float 1.800000e+01"
  832. },
  833. "bias amount for sample_b must be in the range [-16.000000,15.990000]");
  834. }
  835. TEST_F(ValidationTest, SamplerKindFail) {
  836. RewriteAssemblyCheckMsg(
  837. L"..\\CodeGenHLSL\\SamplerKind.hlsl", "ps_6_0",
  838. {"uav1_UAV_2d = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1",
  839. "g_txDiffuse_texture_2d = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0",
  840. "\"g_samLinear\", i32 0, i32 0, i32 1, i32 0",
  841. "\"g_samLinearC\", i32 0, i32 1, i32 1, i32 1",
  842. },
  843. {"uav1_UAV_2d = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0",
  844. "g_txDiffuse_texture_2d = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1",
  845. "\"g_samLinear\", i32 0, i32 0, i32 1, i32 3",
  846. "\"g_samLinearC\", i32 0, i32 1, i32 1, i32 3",
  847. },
  848. {"Invalid sampler mode",
  849. "require sampler declared in comparison mode",
  850. "requires sampler declared in default mode",
  851. // 1.4: "should", 1.5: "should be "
  852. "on srv resource"});
  853. }
  854. TEST_F(ValidationTest, SemaOverlapFail) {
  855. RewriteAssemblyCheckMsg(
  856. L"..\\CodeGenHLSL\\semaOverlap1.hlsl", "ps_6_0",
  857. {"!\\{i32 0, !\"A\", i8 9, i8 0, !([0-9]+), i8 2, i32 1, i8 4, i32 0, i8 0, (.*)"
  858. "!\\{i32 1, !\"A\", i8 9, i8 0, !([0-9]+)",
  859. },
  860. {"!\\{i32 0, !\"A\", i8 9, i8 0, !\\1, i8 2, i32 1, i8 4, i32 0, i8 0, \\2"
  861. "!\\{i32 1, !\"A\", i8 9, i8 0, !\\1",
  862. },
  863. {"Semantic 'A' overlap at 0"},
  864. /*bRegex*/true);
  865. }
  866. TEST_F(ValidationTest, SigOutOfRangeFail) {
  867. return; // Skip for now since this fails AssembleToContainer in PSV creation due to out of range start row
  868. RewriteAssemblyCheckMsg(
  869. L"..\\CodeGenHLSL\\semaOverlap1.hlsl", "ps_6_0",
  870. {"i32 1, i8 0, null}",
  871. },
  872. {"i32 8000, i8 0, null}",
  873. },
  874. {"signature element A at location (8000,0) size (1,4) is out of range"});
  875. }
  876. TEST_F(ValidationTest, SigOverlapFail) {
  877. RewriteAssemblyCheckMsg(
  878. L"..\\CodeGenHLSL\\semaOverlap1.hlsl", "ps_6_0",
  879. { "i8 2, i32 1, i8 4, i32 1, i8 0,",
  880. "?!dx.viewIdState =" },
  881. { "i8 2, i32 1, i8 4, i32 0, i8 0,",
  882. "!1012 =" },
  883. {"signature element A at location (0,0) size (1,4) overlaps another signature element"});
  884. }
  885. TEST_F(ValidationTest, SimpleHs1Fail) {
  886. RewriteAssemblyCheckMsg(
  887. L"..\\CodeGenHLSL\\validation\\SimpleHs1.hlsl", "hs_6_0",
  888. {"i32 3, i32 3, i32 2, i32 3, i32 3, float 6.400000e+01}",
  889. "\"SV_TessFactor\", i8 9, i8 25",
  890. "\"SV_InsideTessFactor\", i8 9, i8 26",
  891. },
  892. {"i32 3, i32 3000, i32 2, i32 3, i32 3, float 6.400000e+01}",
  893. "\"TessFactor\", i8 9, i8 0",
  894. "\"InsideTessFactor\", i8 9, i8 0",
  895. },
  896. {"output control point count must be [0..32]. 3000 specified",
  897. "Required TessFactor for domain not found declared anywhere in Patch Constant data",
  898. // TODO: enable this after support pass thru hull shader.
  899. //"For pass thru hull shader, input control point count must match output control point count",
  900. //"Total number of scalars across all HS output control points must not exceed",
  901. });
  902. }
  903. TEST_F(ValidationTest, SimpleHs3Fail) {
  904. RewriteAssemblyCheckMsg(
  905. L"..\\CodeGenHLSL\\validation\\SimpleHs3.hlsl", "hs_6_0",
  906. {
  907. "i32 3, i32 3, i32 2, i32 3, i32 3, float 6.400000e+01}",
  908. },
  909. {
  910. "i32 3, i32 3, i32 2, i32 3, i32 2, float 6.400000e+01}",
  911. },
  912. {"Hull Shader declared with Tri Domain must specify output primitive "
  913. "point, triangle_cw or triangle_ccw. Line output is not compatible with "
  914. "the Tri domain"});
  915. }
  916. TEST_F(ValidationTest, SimpleHs4Fail) {
  917. RewriteAssemblyCheckMsg(
  918. L"..\\CodeGenHLSL\\validation\\SimpleHs4.hlsl", "hs_6_0",
  919. {
  920. "i32 2, i32 2, i32 1, i32 3, i32 2, float 6.400000e+01}",
  921. },
  922. {
  923. "i32 2, i32 2, i32 1, i32 3, i32 3, float 6.400000e+01}",
  924. },
  925. {"Hull Shader declared with IsoLine Domain must specify output primitive "
  926. "point or line. Triangle_cw or triangle_ccw output are not compatible "
  927. "with the IsoLine Domain"});
  928. }
  929. TEST_F(ValidationTest, SimpleDs1Fail) {
  930. RewriteAssemblyCheckMsg(
  931. L"..\\CodeGenHLSL\\validation\\SimpleDs1.hlsl", "ds_6_0",
  932. {"!{i32 2, i32 3}"
  933. },
  934. {"!{i32 4, i32 36}"
  935. },
  936. {"DS input control point count must be [0..32]. 36 specified",
  937. "Invalid Tessellator Domain specified. Must be isoline, tri or quad",
  938. "DomainLocation component index out of bounds for the domain"});
  939. }
  940. TEST_F(ValidationTest, SimpleGs1Fail) {
  941. return; // Skip for now since this fails AssembleToContainer in PSV creation due to out of range stream index
  942. RewriteAssemblyCheckMsg(
  943. L"..\\CodeGenHLSL\\validation\\SimpleGS1.hlsl", "gs_6_0",
  944. {"!{i32 1, i32 3, i32 1, i32 5, i32 1}",
  945. "i8 4, i32 1, i8 4, i32 2, i8 0, null}"
  946. },
  947. {"!{i32 5, i32 1025, i32 1, i32 0, i32 33}",
  948. "i8 4, i32 1, i8 4, i32 2, i8 0, !100}\n"
  949. "!100 = !{i32 0, i32 5}"
  950. },
  951. {"GS output vertex count must be [0..1024]. 1025 specified",
  952. "GS instance count must be [1..32]. 33 specified",
  953. "GS output primitive topology unrecognized",
  954. "GS input primitive unrecognized",
  955. "Stream index (5) must between 0 and 3"});
  956. }
  957. TEST_F(ValidationTest, UavBarrierFail) {
  958. if (m_ver.SkipIRSensitiveTest()) return;
  959. RewriteAssemblyCheckMsg(
  960. L"..\\CodeGenHLSL\\uavBarrier.hlsl", "ps_6_0",
  961. {"dx.op.barrier(i32 80, i32 2)",
  962. "textureLoad.f32(i32 66, %dx.types.Handle %uav1_UAV_2d, i32 undef",
  963. "i32 undef, i32 undef, i32 undef, i32 undef)",
  964. "float %add9.i3, i8 15)",
  965. },
  966. {"dx.op.barrier(i32 80, i32 9)",
  967. "textureLoad.f32(i32 66, %dx.types.Handle %uav1_UAV_2d, i32 1",
  968. "i32 1, i32 2, i32 undef, i32 undef)",
  969. "float undef, i8 7)",
  970. },
  971. {"uav load don't support offset",
  972. "uav load don't support mipLevel/sampleIndex",
  973. "store on typed uav must write to all four components of the UAV",
  974. "sync in a non-", // 1.4: "Compute" 1.5: "Compute/Amplification/Mesh"
  975. " Shader must only sync UAV (sync_uglobal)"});
  976. }
  977. TEST_F(ValidationTest, UndefValueFail) {
  978. TestCheck(L"..\\CodeGenHLSL\\UndefValue.hlsl");
  979. }
  980. TEST_F(ValidationTest, UpdateCounterFail) {
  981. if (m_ver.SkipIRSensitiveTest()) return;
  982. RewriteAssemblyCheckMsg(
  983. L"..\\CodeGenHLSL\\updateCounter2.hlsl", "ps_6_0",
  984. {"%2 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i8 1)",
  985. "%3 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i8 1)"
  986. },
  987. {"%2 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i8 -1)",
  988. "%3 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i8 1)\n"
  989. "%srvUpdate = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %buf1_texture_buf, i8 undef)"
  990. },
  991. {"BufferUpdateCounter valid only on UAV",
  992. "BufferUpdateCounter valid only on structured buffers",
  993. "inc of BufferUpdateCounter must be an immediate constant",
  994. "RWStructuredBuffers may increment or decrement their counters, but not both"});
  995. }
  996. TEST_F(ValidationTest, LocalResCopy) {
  997. RewriteAssemblyCheckMsg(
  998. L"..\\CodeGenHLSL\\validation\\resCopy.hlsl", "cs_6_0", {"ret void"},
  999. {"%H = alloca %dx.types.ResRet.i32\n"
  1000. "ret void"},
  1001. {"Dxil struct types should only used by ExtractValue"});
  1002. }
  1003. TEST_F(ValidationTest, WhenIncorrectModelThenFail) {
  1004. TestCheck(L"..\\CodeGenHLSL\\val-failures.hlsl");
  1005. }
  1006. TEST_F(ValidationTest, WhenIncorrectPSThenFail) {
  1007. TestCheck(L"..\\CodeGenHLSL\\val-failures-ps.hlsl");
  1008. }
  1009. TEST_F(ValidationTest, WhenSmUnknownThenFail) {
  1010. RewriteAssemblyCheckMsg("float4 main() : SV_Target { return 1; }", "ps_6_0",
  1011. {"{!\"ps\", i32 6, i32 0}"},
  1012. {"{!\"ps\", i32 1, i32 2}"},
  1013. "Unknown shader model 'ps_1_2'");
  1014. }
  1015. TEST_F(ValidationTest, WhenSmLegacyThenFail) {
  1016. RewriteAssemblyCheckMsg("float4 main() : SV_Target { return 1; }", "ps_6_0",
  1017. "{!\"ps\", i32 6, i32 0}", "{!\"ps\", i32 5, i32 1}",
  1018. "Unknown shader model 'ps_5_1'");
  1019. }
  1020. TEST_F(ValidationTest, WhenMetaFlagsUsageDeclThenOK) {
  1021. RewriteAssemblyCheckMsg(
  1022. "uint u; float4 main() : SV_Target { uint64_t n = u; n *= u; return (uint)(n >> 32); }", "ps_6_0",
  1023. "1048576", "1048577", // inhibit optimization, which should work fine
  1024. nullptr);
  1025. }
  1026. TEST_F(ValidationTest, GsVertexIDOutOfBound) {
  1027. RewriteAssemblyCheckMsg(
  1028. L"..\\CodeGenHLSL\\validation\\SimpleGS1.hlsl", "gs_6_0",
  1029. "dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 2, i32 0)",
  1030. "dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 2, i32 1)",
  1031. "expect VertexID between 0~1, got 1");
  1032. }
  1033. TEST_F(ValidationTest, StreamIDOutOfBound) {
  1034. RewriteAssemblyCheckMsg(
  1035. L"..\\CodeGenHLSL\\validation\\SimpleGS1.hlsl", "gs_6_0",
  1036. "dx.op.emitStream(i32 97, i8 0)",
  1037. "dx.op.emitStream(i32 97, i8 1)",
  1038. "expect StreamID between 0 , got 1");
  1039. }
  1040. TEST_F(ValidationTest, SignatureDataWidth) {
  1041. if (m_ver.SkipDxilVersion(1, 2)) return;
  1042. std::vector<LPCWSTR> pArguments = { L"-enable-16bit-types", L"-HV", L"2018" };
  1043. RewriteAssemblyCheckMsg(
  1044. L"..\\CodeGenHLSL\\validation\\signature_packing_by_width.hlsl", "ps_6_2",
  1045. pArguments.data(), 3, nullptr, 0,
  1046. {"i8 8, i8 0, (![0-9]+), i8 2, i32 1, i8 2, i32 0, i8 0, null}"},
  1047. {"i8 9, i8 0, \\1, i8 2, i32 1, i8 2, i32 0, i8 0, null}"},
  1048. "signature element F at location \\(0, 2\\) size \\(1, 2\\) has data "
  1049. "width that differs from another element packed into the same row.",
  1050. true);
  1051. }
  1052. TEST_F(ValidationTest, SignatureStreamIDForNonGS) {
  1053. RewriteAssemblyCheckMsg(
  1054. L"..\\CodeGenHLSL\\validation\\abs1.hlsl", "ps_6_0",
  1055. { ", i8 0, i32 1, i8 4, i32 0, i8 0, [^,]+}",
  1056. "?!dx.viewIdState ="},
  1057. { ", i8 0, i32 1, i8 4, i32 0, i8 0, !1019}\n!1019 = !{i32 0, i32 1}",
  1058. "!1012 =" },
  1059. "Stream index \\(1\\) must between 0 and 0",
  1060. true);
  1061. }
  1062. TEST_F(ValidationTest, TypedUAVStoreFullMask0) {
  1063. RewriteAssemblyCheckMsg(
  1064. L"..\\CodeGenHLSL\\uav_typed_store.hlsl", "ps_6_0",
  1065. "float 2.000000e+00, i8 15)",
  1066. "float 2.000000e+00, i8 undef)",
  1067. "Mask of TextureStore must be an immediate constant");
  1068. }
  1069. TEST_F(ValidationTest, TypedUAVStoreFullMask1) {
  1070. RewriteAssemblyCheckMsg(
  1071. L"..\\CodeGenHLSL\\uav_typed_store.hlsl", "ps_6_0",
  1072. "float 3.000000e+00, i8 15)",
  1073. "float 3.000000e+00, i8 undef)",
  1074. "Mask of BufferStore must be an immediate constant");
  1075. }
  1076. TEST_F(ValidationTest, Recursive) {
  1077. // Includes coverage for user-defined functions.
  1078. TestCheck(L"..\\CodeGenHLSL\\recursive.ll");
  1079. }
  1080. TEST_F(ValidationTest, Recursive2) {
  1081. TestCheck(L"..\\CodeGenHLSL\\recursive2.hlsl");
  1082. }
  1083. TEST_F(ValidationTest, Recursive3) {
  1084. TestCheck(L"..\\CodeGenHLSL\\recursive3.hlsl");
  1085. }
  1086. TEST_F(ValidationTest, ResourceRangeOverlap0) {
  1087. RewriteAssemblyCheckMsg(
  1088. L"..\\CodeGenHLSL\\resource_overlap.hlsl", "ps_6_0",
  1089. "!\"B\", i32 0, i32 1",
  1090. "!\"B\", i32 0, i32 0",
  1091. "Resource B with base 0 size 1 overlap");
  1092. }
  1093. TEST_F(ValidationTest, ResourceRangeOverlap1) {
  1094. RewriteAssemblyCheckMsg(
  1095. L"..\\CodeGenHLSL\\resource_overlap.hlsl", "ps_6_0",
  1096. "!\"s1\", i32 0, i32 1",
  1097. "!\"s1\", i32 0, i32 0",
  1098. "Resource s1 with base 0 size 1 overlap");
  1099. }
  1100. TEST_F(ValidationTest, ResourceRangeOverlap2) {
  1101. RewriteAssemblyCheckMsg(
  1102. L"..\\CodeGenHLSL\\resource_overlap.hlsl", "ps_6_0",
  1103. "!\"uav2\", i32 0, i32 0",
  1104. "!\"uav2\", i32 0, i32 3",
  1105. "Resource uav2 with base 3 size 1 overlap");
  1106. }
  1107. TEST_F(ValidationTest, ResourceRangeOverlap3) {
  1108. RewriteAssemblyCheckMsg(
  1109. L"..\\CodeGenHLSL\\resource_overlap.hlsl", "ps_6_0",
  1110. "!\"srv2\", i32 0, i32 1",
  1111. "!\"srv2\", i32 0, i32 0",
  1112. "Resource srv2 with base 0 size 1 overlap");
  1113. }
  1114. TEST_F(ValidationTest, CBufferOverlap0) {
  1115. RewriteAssemblyCheckMsg(
  1116. L"..\\CodeGenHLSL\\cbufferOffset.hlsl", "ps_6_0",
  1117. "i32 6, !\"g2\", i32 3, i32 0",
  1118. "i32 6, !\"g2\", i32 3, i32 8",
  1119. "CBuffer Foo1 has offset overlaps at 16");
  1120. }
  1121. TEST_F(ValidationTest, CBufferOverlap1) {
  1122. RewriteAssemblyCheckMsg(
  1123. L"..\\CodeGenHLSL\\cbufferOffset.hlsl", "ps_6_0",
  1124. " = !{i32 32, !",
  1125. " = !{i32 16, !",
  1126. "CBuffer Foo1 size insufficient for element at offset 16");
  1127. }
  1128. TEST_F(ValidationTest, ControlFlowHint) {
  1129. RewriteAssemblyCheckMsg(
  1130. L"..\\CodeGenHLSL\\validation\\if1.hlsl", "ps_6_0",
  1131. "!\"dx.controlflow.hints\", i32 1",
  1132. "!\"dx.controlflow.hints\", i32 5",
  1133. "Attribute forcecase only works for switch");
  1134. }
  1135. TEST_F(ValidationTest, ControlFlowHint1) {
  1136. RewriteAssemblyCheckMsg(
  1137. L"..\\CodeGenHLSL\\validation\\if1.hlsl", "ps_6_0",
  1138. "!\"dx.controlflow.hints\", i32 1",
  1139. "!\"dx.controlflow.hints\", i32 1, i32 2",
  1140. "Can't use branch and flatten attributes together");
  1141. }
  1142. TEST_F(ValidationTest, ControlFlowHint2) {
  1143. RewriteAssemblyCheckMsg(
  1144. L"..\\CodeGenHLSL\\validation\\if1.hlsl", "ps_6_0",
  1145. "!\"dx.controlflow.hints\", i32 1",
  1146. "!\"dx.controlflow.hints\", i32 3",
  1147. "Invalid control flow hint");
  1148. }
  1149. TEST_F(ValidationTest, SemanticLength1) {
  1150. RewriteAssemblyCheckMsg(
  1151. L"..\\CodeGenHLSL\\validation\\binary1.hlsl", "ps_6_0",
  1152. "!\"C\"",
  1153. "!\"\"",
  1154. "Semantic length must be at least 1 and at most 64");
  1155. }
  1156. TEST_F(ValidationTest, SemanticLength64) {
  1157. RewriteAssemblyCheckMsg(
  1158. L"..\\CodeGenHLSL\\validation\\binary1.hlsl", "ps_6_0",
  1159. "!\"C\"",
  1160. "!\"CSESESESESESESESESESESESESESESESESESESESESESESESESESESESESESESESE\"",
  1161. "Semantic length must be at least 1 and at most 64");
  1162. }
  1163. TEST_F(ValidationTest, PullModelPosition) {
  1164. RewriteAssemblyCheckMsg(
  1165. L"..\\CodeGenHLSL\\validation\\eval.hlsl", "ps_6_0",
  1166. "!\"A\", i8 9, i8 0",
  1167. "!\"SV_Position\", i8 9, i8 3",
  1168. "does not support pull-model evaluation of position");
  1169. }
  1170. TEST_F(ValidationTest, StructBufGlobalCoherentAndCounter) {
  1171. RewriteAssemblyCheckMsg(
  1172. L"..\\CodeGenHLSL\\validation\\struct_buf1.hlsl", "ps_6_0",
  1173. "!\"buf2\", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false",
  1174. "!\"buf2\", i32 0, i32 0, i32 1, i32 12, i1 true, i1 true",
  1175. "globallycoherent cannot be used with append/consume buffers'buf2'");
  1176. }
  1177. TEST_F(ValidationTest, StructBufStrideAlign) {
  1178. RewriteAssemblyCheckMsg(
  1179. L"..\\CodeGenHLSL\\validation\\struct_buf1.hlsl", "ps_6_0",
  1180. "= !{i32 1, i32 52}",
  1181. "= !{i32 1, i32 50}",
  1182. "structured buffer element size must be a multiple of 4 bytes (actual size 50 bytes)");
  1183. }
  1184. TEST_F(ValidationTest, StructBufStrideOutOfBound) {
  1185. RewriteAssemblyCheckMsg(
  1186. L"..\\CodeGenHLSL\\validation\\struct_buf1.hlsl", "ps_6_0",
  1187. "= !{i32 1, i32 52}",
  1188. "= !{i32 1, i32 2052}",
  1189. "structured buffer elements cannot be larger than 2048 bytes (actual size 2052 bytes)");
  1190. }
  1191. TEST_F(ValidationTest, StructBufLoadCoordinates) {
  1192. RewriteAssemblyCheckMsg(
  1193. L"..\\CodeGenHLSL\\validation\\struct_buf1.hlsl", "ps_6_0",
  1194. "bufferLoad.f32(i32 68, %dx.types.Handle %buf1_texture_structbuf, i32 1, i32 8)",
  1195. "bufferLoad.f32(i32 68, %dx.types.Handle %buf1_texture_structbuf, i32 1, i32 undef)",
  1196. "structured buffer require 2 coordinates");
  1197. }
  1198. TEST_F(ValidationTest, StructBufStoreCoordinates) {
  1199. RewriteAssemblyCheckMsg(
  1200. L"..\\CodeGenHLSL\\validation\\struct_buf1.hlsl", "ps_6_0",
  1201. "bufferStore.f32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 0, i32 0",
  1202. "bufferStore.f32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 0, i32 undef",
  1203. "structured buffer require 2 coordinates");
  1204. }
  1205. TEST_F(ValidationTest, TypedBufRetType) {
  1206. RewriteAssemblyCheckMsg(
  1207. L"..\\CodeGenHLSL\\validation\\sample5.hlsl", "ps_6_0",
  1208. " = type { <4 x float>",
  1209. " = type { <4 x double>",
  1210. "elements of typed buffers and textures must fit in four 32-bit quantities");
  1211. }
  1212. TEST_F(ValidationTest, VsInputSemantic) {
  1213. RewriteAssemblyCheckMsg(
  1214. L"..\\CodeGenHLSL\\validation\\clip_planes.hlsl", "vs_6_0",
  1215. "!\"POSITION\", i8 9, i8 0",
  1216. "!\"SV_Target\", i8 9, i8 16",
  1217. "Semantic 'SV_Target' is invalid as vs Input");
  1218. }
  1219. TEST_F(ValidationTest, VsOutputSemantic) {
  1220. RewriteAssemblyCheckMsg(
  1221. L"..\\CodeGenHLSL\\validation\\clip_planes.hlsl", "vs_6_0",
  1222. "!\"NORMAL\", i8 9, i8 0",
  1223. "!\"SV_Target\", i8 9, i8 16",
  1224. "Semantic 'SV_Target' is invalid as vs Output");
  1225. }
  1226. TEST_F(ValidationTest, HsInputSemantic) {
  1227. RewriteAssemblyCheckMsg(
  1228. L"..\\CodeGenHLSL\\validation\\SimpleHs1.hlsl", "hs_6_0",
  1229. "!\"TEXCOORD\", i8 9, i8 0",
  1230. "!\"VertexID\", i8 4, i8 1",
  1231. "Semantic 'VertexID' is invalid as hs Input");
  1232. }
  1233. TEST_F(ValidationTest, HsOutputSemantic) {
  1234. RewriteAssemblyCheckMsg(
  1235. L"..\\CodeGenHLSL\\validation\\SimpleHs1.hlsl", "hs_6_0",
  1236. "!\"TEXCOORD\", i8 9, i8 0",
  1237. "!\"VertexID\", i8 4, i8 1",
  1238. "Semantic 'VertexID' is invalid as hs Output");
  1239. }
  1240. TEST_F(ValidationTest, PatchConstSemantic) {
  1241. RewriteAssemblyCheckMsg(
  1242. L"..\\CodeGenHLSL\\validation\\SimpleHs1.hlsl", "hs_6_0",
  1243. "!\"SV_TessFactor\", i8 9, i8 25",
  1244. "!\"VertexID\", i8 4, i8 1",
  1245. "Semantic 'VertexID' is invalid as hs PatchConstant");
  1246. }
  1247. TEST_F(ValidationTest, DsInputSemantic) {
  1248. RewriteAssemblyCheckMsg(
  1249. L"..\\CodeGenHLSL\\validation\\SimpleDs1.hlsl", "ds_6_0",
  1250. "!\"TEXCOORD\", i8 9, i8 0",
  1251. "!\"VertexID\", i8 4, i8 1",
  1252. "Semantic 'VertexID' is invalid as ds Input");
  1253. }
  1254. TEST_F(ValidationTest, DsOutputSemantic) {
  1255. RewriteAssemblyCheckMsg(
  1256. L"..\\CodeGenHLSL\\validation\\SimpleDs1.hlsl", "ds_6_0",
  1257. "!\"TEXCOORD\", i8 9, i8 0",
  1258. "!\"VertexID\", i8 4, i8 1",
  1259. "Semantic 'VertexID' is invalid as ds Output");
  1260. }
  1261. TEST_F(ValidationTest, GsInputSemantic) {
  1262. RewriteAssemblyCheckMsg(
  1263. L"..\\CodeGenHLSL\\validation\\SimpleGS1.hlsl", "gs_6_0",
  1264. "!\"POSSIZE\", i8 9, i8 0",
  1265. "!\"VertexID\", i8 4, i8 1",
  1266. "Semantic 'VertexID' is invalid as gs Input");
  1267. }
  1268. TEST_F(ValidationTest, GsOutputSemantic) {
  1269. RewriteAssemblyCheckMsg(
  1270. L"..\\CodeGenHLSL\\validation\\SimpleGS1.hlsl", "gs_6_0",
  1271. "!\"TEXCOORD\", i8 9, i8 0",
  1272. "!\"VertexID\", i8 4, i8 1",
  1273. "Semantic 'VertexID' is invalid as gs Output");
  1274. }
  1275. TEST_F(ValidationTest, PsInputSemantic) {
  1276. RewriteAssemblyCheckMsg(
  1277. L"..\\CodeGenHLSL\\validation\\abs2.hlsl", "ps_6_0",
  1278. "!\"A\", i8 4, i8 0",
  1279. "!\"VertexID\", i8 4, i8 1",
  1280. "Semantic 'VertexID' is invalid as ps Input");
  1281. }
  1282. TEST_F(ValidationTest, PsOutputSemantic) {
  1283. RewriteAssemblyCheckMsg(
  1284. L"..\\CodeGenHLSL\\validation\\abs2.hlsl", "ps_6_0",
  1285. "!\"SV_Target\", i8 9, i8 16",
  1286. "!\"VertexID\", i8 4, i8 1",
  1287. "Semantic 'VertexID' is invalid as ps Output");
  1288. }
  1289. TEST_F(ValidationTest, ArrayOfSVTarget) {
  1290. RewriteAssemblyCheckMsg(
  1291. L"..\\CodeGenHLSL\\targetArray.hlsl", "ps_6_0",
  1292. "i32 2, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 4, i32 0, i8 0, (.*)}",
  1293. "i32 2, !\"SV_Target\", i8 9, i8 16, !101, i8 0, i32 2, i8 4, i32 0, i8 0, \\2}\n!101 = !{i32 5, i32 6}",
  1294. "Pixel shader output registers are not indexable.",
  1295. /*bRegex*/true);
  1296. }
  1297. TEST_F(ValidationTest, InfiniteLog) {
  1298. RewriteAssemblyCheckMsg(
  1299. L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
  1300. "op.unary.f32\\(i32 23, float %[0-9+]\\)",
  1301. "op.unary.f32(i32 23, float 0x7FF0000000000000)",
  1302. "No indefinite logarithm",
  1303. /*bRegex*/true);
  1304. }
  1305. TEST_F(ValidationTest, InfiniteAsin) {
  1306. RewriteAssemblyCheckMsg(
  1307. L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
  1308. "op.unary.f32\\(i32 16, float %[0-9]+\\)",
  1309. "op.unary.f32(i32 16, float 0x7FF0000000000000)",
  1310. "No indefinite arcsine",
  1311. /*bRegex*/true);
  1312. }
  1313. TEST_F(ValidationTest, InfiniteAcos) {
  1314. RewriteAssemblyCheckMsg(
  1315. L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
  1316. "op.unary.f32\\(i32 15, float %[0-9]+\\)",
  1317. "op.unary.f32(i32 15, float 0x7FF0000000000000)",
  1318. "No indefinite arccosine",
  1319. /*bRegex*/true);
  1320. }
  1321. TEST_F(ValidationTest, InfiniteDdxDdy) {
  1322. RewriteAssemblyCheckMsg(
  1323. L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
  1324. "op.unary.f32\\(i32 85, float %[0-9]+\\)",
  1325. "op.unary.f32(i32 85, float 0x7FF0000000000000)",
  1326. "No indefinite derivative calculation",
  1327. /*bRegex*/true);
  1328. }
  1329. TEST_F(ValidationTest, IDivByZero) {
  1330. RewriteAssemblyCheckMsg(
  1331. L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
  1332. "sdiv i32 %([0-9]+), %[0-9]+",
  1333. "sdiv i32 %\\1, 0",
  1334. "No signed integer division by zero",
  1335. /*bRegex*/true);
  1336. }
  1337. TEST_F(ValidationTest, UDivByZero) {
  1338. RewriteAssemblyCheckMsg(
  1339. L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_6_0",
  1340. "udiv i32 %([0-9]+), %[0-9]+",
  1341. "udiv i32 %\\1, 0",
  1342. "No unsigned integer division by zero",
  1343. /*bRegex*/true);
  1344. }
  1345. TEST_F(ValidationTest, UnusedMetadata) {
  1346. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\loop2.hlsl", "ps_6_0",
  1347. ", !llvm.loop ",
  1348. ", !llvm.loop2 ",
  1349. "All metadata must be used by dxil");
  1350. }
  1351. TEST_F(ValidationTest, MemoryOutOfBound) {
  1352. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\targetArray.hlsl", "ps_6_0",
  1353. "getelementptr [4 x float], [4 x float]* %7, i32 0, i32 3",
  1354. "getelementptr [4 x float], [4 x float]* %7, i32 0, i32 10",
  1355. "Access to out-of-bounds memory is disallowed");
  1356. }
  1357. TEST_F(ValidationTest, LocalRes2) {
  1358. TestCheck(L"..\\CodeGenHLSL\\local_resource2.hlsl");
  1359. }
  1360. TEST_F(ValidationTest, LocalRes3) {
  1361. TestCheck(L"..\\CodeGenHLSL\\local_resource3.hlsl");
  1362. }
  1363. TEST_F(ValidationTest, LocalRes5) {
  1364. TestCheck(L"..\\CodeGenHLSL\\local_resource5.hlsl");
  1365. }
  1366. TEST_F(ValidationTest, LocalRes5Dbg) {
  1367. TestCheck(L"..\\CodeGenHLSL\\local_resource5_dbg.hlsl");
  1368. }
  1369. TEST_F(ValidationTest, LocalRes6) {
  1370. TestCheck(L"..\\CodeGenHLSL\\local_resource6.hlsl");
  1371. }
  1372. TEST_F(ValidationTest, LocalRes6Dbg) {
  1373. TestCheck(L"..\\CodeGenHLSL\\local_resource6_dbg.hlsl");
  1374. }
  1375. TEST_F(ValidationTest, AddrSpaceCast) {
  1376. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\staticGlobals.hlsl", "ps_6_0",
  1377. "%([0-9]+) = getelementptr \\[4 x i32\\], \\[4 x i32\\]\\* %([0-9]+), i32 0, i32 0\n"
  1378. " store i32 %([0-9]+), i32\\* %\\1, align 4",
  1379. "%\\1 = getelementptr [4 x i32], [4 x i32]* %\\2, i32 0, i32 0\n"
  1380. " %X = addrspacecast i32* %\\1 to i32 addrspace(1)* \n"
  1381. " store i32 %\\3, i32 addrspace(1)* %X, align 4",
  1382. "generic address space",
  1383. /*bRegex*/true);
  1384. }
  1385. TEST_F(ValidationTest, PtrBitCast) {
  1386. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\staticGlobals.hlsl", "ps_6_0",
  1387. "%([0-9]+) = getelementptr \\[4 x i32\\], \\[4 x i32\\]\\* %([0-9]+), i32 0, i32 0\n"
  1388. " store i32 %([0-9]+), i32\\* %\\1, align 4",
  1389. "%\\1 = getelementptr [4 x i32], [4 x i32]* %\\2, i32 0, i32 0\n"
  1390. " %X = bitcast i32* %\\1 to double* \n"
  1391. " store i32 %\\3, i32* %\\1, align 4",
  1392. "Pointer type bitcast must be have same size",
  1393. /*bRegex*/true);
  1394. }
  1395. TEST_F(ValidationTest, MinPrecisionBitCast) {
  1396. if (m_ver.SkipDxilVersion(1, 2)) return;
  1397. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\staticGlobals.hlsl", "ps_6_0",
  1398. "%([0-9]+) = getelementptr \\[4 x i32\\], \\[4 x i32\\]\\* %([0-9]+), i32 0, i32 0\n"
  1399. " store i32 %([0-9]+), i32\\* %\\1, align 4",
  1400. "%\\1 = getelementptr [4 x i32], [4 x i32]* %\\2, i32 0, i32 0\n"
  1401. " %X = bitcast i32* %\\1 to half* \n"
  1402. " store i32 %\\3, i32* %\\1, align 4",
  1403. "Bitcast on minprecison types is not allowed",
  1404. /*bRegex*/true);
  1405. }
  1406. TEST_F(ValidationTest, StructBitCast) {
  1407. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\staticGlobals.hlsl", "ps_6_0",
  1408. "%([0-9]+) = getelementptr \\[4 x i32\\], \\[4 x i32\\]\\* %([0-9]+), i32 0, i32 0\n"
  1409. " store i32 %([0-9]+), i32\\* %\\1, align 4",
  1410. "%\\1 = getelementptr [4 x i32], [4 x i32]* %\\2, i32 0, i32 0\n"
  1411. " %X = bitcast i32* %\\1 to %dx.types.Handle* \n"
  1412. " store i32 %\\3, i32* %\\1, align 4",
  1413. "Bitcast on struct types is not allowed",
  1414. /*bRegex*/true);
  1415. }
  1416. TEST_F(ValidationTest, MultiDimArray) {
  1417. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\staticGlobals.hlsl", "ps_6_0",
  1418. "= alloca [4 x i32]",
  1419. "= alloca [4 x i32]\n"
  1420. " %md = alloca [2 x [4 x float]]",
  1421. "Only one dimension allowed for array type");
  1422. }
  1423. TEST_F(ValidationTest, SimpleGs8) {
  1424. TestCheck(L"..\\CodeGenHLSL\\SimpleGS8.hlsl");
  1425. }
  1426. TEST_F(ValidationTest, SimpleGs9) {
  1427. TestCheck(L"..\\CodeGenHLSL\\SimpleGS9.hlsl");
  1428. }
  1429. TEST_F(ValidationTest, SimpleGs10) {
  1430. TestCheck(L"..\\CodeGenHLSL\\SimpleGS10.hlsl");
  1431. }
  1432. TEST_F(ValidationTest, IllegalSampleOffset3) {
  1433. TestCheck(L"..\\CodeGenHLSL\\optForNoOpt3.hlsl");
  1434. }
  1435. TEST_F(ValidationTest, IllegalSampleOffset4) {
  1436. TestCheck(L"..\\CodeGenHLSL\\optForNoOpt4.hlsl");
  1437. }
  1438. TEST_F(ValidationTest, NoFunctionParam) {
  1439. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\abs2.hlsl", "ps_6_0",
  1440. {"define void @main\\(\\)", "void \\(\\)\\* @main, !([0-9]+)\\}(.*)!\\1 = !\\{!([0-9]+)\\}", "void \\(\\)\\* @main"},
  1441. {"define void @main(<4 x i32> %mainArg)", "void (<4 x i32>)* @main, !\\1}\\2!\\1 = !{!\\3, !\\3}", "void (<4 x i32>)* @main"},
  1442. "with parameter is not permitted",
  1443. /*bRegex*/true);
  1444. }
  1445. TEST_F(ValidationTest, I8Type) {
  1446. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\validation\\staticGlobals.hlsl", "ps_6_0",
  1447. "%([0-9]+) = alloca \\[4 x i32\\]",
  1448. "%\\1 = alloca [4 x i32]\n"
  1449. " %m8 = alloca i8",
  1450. "I8 can only used as immediate value for intrinsic",
  1451. /*bRegex*/true);
  1452. }
  1453. TEST_F(ValidationTest, EmptyStructInBuffer) {
  1454. TestCheck(L"..\\CodeGenHLSL\\EmptyStructInBuffer.hlsl");
  1455. }
  1456. TEST_F(ValidationTest, BigStructInBuffer) {
  1457. TestCheck(L"..\\CodeGenHLSL\\BigStructInBuffer.hlsl");
  1458. }
  1459. TEST_F(ValidationTest, GloballyCoherent2) {
  1460. TestCheck(L"..\\CodeGenHLSL\\globallycoherent2.hlsl");
  1461. }
  1462. TEST_F(ValidationTest, GloballyCoherent3) {
  1463. TestCheck(L"..\\CodeGenHLSL\\globallycoherent3.hlsl");
  1464. }
  1465. // TODO: enable this.
  1466. //TEST_F(ValidationTest, TGSMRaceCond) {
  1467. // TestCheck(L"..\\CodeGenHLSL\\RaceCond.hlsl");
  1468. //}
  1469. //
  1470. //TEST_F(ValidationTest, TGSMRaceCond2) {
  1471. // RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\structInBuffer.hlsl", "cs_6_0",
  1472. // "ret void",
  1473. // "%TID = call i32 @dx.op.flattenedThreadIdInGroup.i32(i32 96)\n"
  1474. // "store i32 %TID, i32 addrspace(3)* @\"\\01?sharedData@@3UFoo@@A.3\", align 4\n"
  1475. // "ret void",
  1476. // "Race condition writing to shared memory detected, consider making this write conditional");
  1477. //}
  1478. TEST_F(ValidationTest, AddUint64Odd) {
  1479. TestCheck(L"..\\CodeGenHLSL\\AddUint64Odd.hlsl");
  1480. }
  1481. TEST_F(ValidationTest, WhenWaveAffectsGradientThenFail) {
  1482. TestCheck(L"..\\CodeGenHLSL\\val-wave-failures-ps.hlsl");
  1483. }
  1484. TEST_F(ValidationTest, WhenMetaFlagsUsageThenFail) {
  1485. RewriteAssemblyCheckMsg(
  1486. "uint u; float4 main() : SV_Target { uint64_t n = u; n *= u; return (uint)(n >> 32); }", "ps_6_0",
  1487. "1048576", "0", // remove the int64 flag
  1488. "Flags must match usage");
  1489. }
  1490. TEST_F(ValidationTest, StorePatchControlNotInPatchConstantFunction) {
  1491. if (m_ver.SkipDxilVersion(1, 3)) return;
  1492. RewriteAssemblyCheckMsg(
  1493. "struct PSSceneIn \
  1494. { \
  1495. float4 pos : SV_Position; \
  1496. float2 tex : TEXCOORD0; \
  1497. float3 norm : NORMAL; \
  1498. }; \
  1499. \
  1500. struct HSPerVertexData \
  1501. { \
  1502. PSSceneIn v; \
  1503. }; \
  1504. struct HSPerPatchData \
  1505. { \
  1506. float edges[ 3 ] : SV_TessFactor; \
  1507. float inside : SV_InsideTessFactor; \
  1508. }; \
  1509. HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 3 > points, \
  1510. OutputPatch<HSPerVertexData, 3> outpoints) \
  1511. { \
  1512. HSPerPatchData d; \
  1513. \
  1514. d.edges[ 0 ] = points[0].tex.x + outpoints[0].v.tex.x; \
  1515. d.edges[ 1 ] = 1; \
  1516. d.edges[ 2 ] = 1; \
  1517. d.inside = 1; \
  1518. \
  1519. return d; \
  1520. }\
  1521. [domain(\"tri\")]\
  1522. [partitioning(\"fractional_odd\")]\
  1523. [outputtopology(\"triangle_cw\")]\
  1524. [patchconstantfunc(\"HSPerPatchFunc\")]\
  1525. [outputcontrolpoints(3)]\
  1526. HSPerVertexData main( const uint id : SV_OutputControlPointID,\
  1527. const InputPatch< PSSceneIn, 3 > points )\
  1528. {\
  1529. HSPerVertexData v;\
  1530. \
  1531. v.v = points[ id ];\
  1532. \
  1533. return v;\
  1534. }\
  1535. ",
  1536. "hs_6_0",
  1537. "dx.op.storeOutput.f32(i32 5",
  1538. "dx.op.storePatchConstant.f32(i32 106",
  1539. "opcode 'StorePatchConstant' should only be used in 'PatchConstant function'");
  1540. }
  1541. TEST_F(ValidationTest, LoadOutputControlPointNotInPatchConstantFunction) {
  1542. if (m_ver.SkipDxilVersion(1, 3)) return;
  1543. RewriteAssemblyCheckMsg(
  1544. "struct PSSceneIn \
  1545. { \
  1546. float4 pos : SV_Position; \
  1547. float2 tex : TEXCOORD0; \
  1548. float3 norm : NORMAL; \
  1549. }; \
  1550. \
  1551. struct HSPerVertexData \
  1552. { \
  1553. PSSceneIn v; \
  1554. }; \
  1555. struct HSPerPatchData \
  1556. { \
  1557. float edges[ 3 ] : SV_TessFactor; \
  1558. float inside : SV_InsideTessFactor; \
  1559. }; \
  1560. HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 3 > points, \
  1561. OutputPatch<HSPerVertexData, 3> outpoints) \
  1562. { \
  1563. HSPerPatchData d; \
  1564. \
  1565. d.edges[ 0 ] = points[0].tex.x + outpoints[0].v.tex.x; \
  1566. d.edges[ 1 ] = 1; \
  1567. d.edges[ 2 ] = 1; \
  1568. d.inside = 1; \
  1569. \
  1570. return d; \
  1571. }\
  1572. [domain(\"tri\")]\
  1573. [partitioning(\"fractional_odd\")]\
  1574. [outputtopology(\"triangle_cw\")]\
  1575. [patchconstantfunc(\"HSPerPatchFunc\")]\
  1576. [outputcontrolpoints(3)]\
  1577. HSPerVertexData main( const uint id : SV_OutputControlPointID,\
  1578. const InputPatch< PSSceneIn, 3 > points )\
  1579. {\
  1580. HSPerVertexData v;\
  1581. \
  1582. v.v = points[ id ];\
  1583. \
  1584. return v;\
  1585. }\
  1586. ",
  1587. "hs_6_0",
  1588. "dx.op.loadInput.f32(i32 4",
  1589. "dx.op.loadOutputControlPoint.f32(i32 103",
  1590. "opcode 'LoadOutputControlPoint' should only be used in 'PatchConstant function'");
  1591. }
  1592. TEST_F(ValidationTest, OutputControlPointIDInPatchConstantFunction) {
  1593. if (m_ver.SkipDxilVersion(1, 3)) return;
  1594. RewriteAssemblyCheckMsg(
  1595. "struct PSSceneIn \
  1596. { \
  1597. float4 pos : SV_Position; \
  1598. float2 tex : TEXCOORD0; \
  1599. float3 norm : NORMAL; \
  1600. }; \
  1601. \
  1602. struct HSPerVertexData \
  1603. { \
  1604. PSSceneIn v; \
  1605. }; \
  1606. struct HSPerPatchData \
  1607. { \
  1608. float edges[ 3 ] : SV_TessFactor; \
  1609. float inside : SV_InsideTessFactor; \
  1610. }; \
  1611. HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 3 > points, \
  1612. OutputPatch<HSPerVertexData, 3> outpoints) \
  1613. { \
  1614. HSPerPatchData d; \
  1615. \
  1616. d.edges[ 0 ] = points[0].tex.x + outpoints[0].v.tex.x; \
  1617. d.edges[ 1 ] = 1; \
  1618. d.edges[ 2 ] = 1; \
  1619. d.inside = 1; \
  1620. \
  1621. return d; \
  1622. }\
  1623. [domain(\"tri\")]\
  1624. [partitioning(\"fractional_odd\")]\
  1625. [outputtopology(\"triangle_cw\")]\
  1626. [patchconstantfunc(\"HSPerPatchFunc\")]\
  1627. [outputcontrolpoints(3)]\
  1628. HSPerVertexData main( const uint id : SV_OutputControlPointID,\
  1629. const InputPatch< PSSceneIn, 3 > points )\
  1630. {\
  1631. HSPerVertexData v;\
  1632. \
  1633. v.v = points[ id ];\
  1634. \
  1635. return v;\
  1636. }\
  1637. ",
  1638. "hs_6_0",
  1639. "ret void",
  1640. "call i32 @dx.op.outputControlPointID.i32(i32 107)\n ret void",
  1641. "opcode 'OutputControlPointID' should only be used in 'hull function'");
  1642. }
  1643. TEST_F(ValidationTest, ClipCullMaxComponents) {
  1644. RewriteAssemblyCheckMsg(" \
  1645. struct VSOut { \
  1646. float3 clip0 : SV_ClipDistance; \
  1647. float3 clip1 : SV_ClipDistance1; \
  1648. float cull0 : SV_CullDistance; \
  1649. float cull1 : SV_CullDistance1; \
  1650. float cull2 : CullDistance2; \
  1651. }; \
  1652. VSOut main() { \
  1653. VSOut Out; \
  1654. Out.clip0 = 0.1; \
  1655. Out.clip1 = 0.2; \
  1656. Out.cull0 = 0.3; \
  1657. Out.cull1 = 0.4; \
  1658. Out.cull2 = 0.5; \
  1659. return Out; \
  1660. } \
  1661. ",
  1662. "vs_6_0",
  1663. "!{i32 4, !\"CullDistance\", i8 9, i8 0,",
  1664. "!{i32 4, !\"SV_CullDistance\", i8 9, i8 7,",
  1665. "ClipDistance and CullDistance use more than the maximum of 8 components combined.");
  1666. }
  1667. TEST_F(ValidationTest, ClipCullMaxRows) {
  1668. RewriteAssemblyCheckMsg(" \
  1669. struct VSOut { \
  1670. float3 clip0 : SV_ClipDistance; \
  1671. float3 clip1 : SV_ClipDistance1; \
  1672. float2 cull0 : CullDistance; \
  1673. }; \
  1674. VSOut main() { \
  1675. VSOut Out; \
  1676. Out.clip0 = 0.1; \
  1677. Out.clip1 = 0.2; \
  1678. Out.cull0 = 0.3; \
  1679. return Out; \
  1680. } \
  1681. ",
  1682. "vs_6_0",
  1683. "!{i32 2, !\"CullDistance\", i8 9, i8 0,",
  1684. "!{i32 2, !\"SV_CullDistance\", i8 9, i8 7,",
  1685. "ClipDistance and CullDistance occupy more than the maximum of 2 rows combined.");
  1686. }
  1687. TEST_F(ValidationTest, DuplicateSysValue) {
  1688. RewriteAssemblyCheckMsg(" \
  1689. float4 main(uint vid : SV_VertexID, uint iid : SV_InstanceID) : SV_Position { \
  1690. return (float4)0 + vid + iid; \
  1691. } \
  1692. ",
  1693. "vs_6_0",
  1694. "!{i32 1, !\"SV_InstanceID\", i8 5, i8 2,",
  1695. "!{i32 1, !\"\", i8 5, i8 1,",
  1696. //"System value SV_VertexID appears more than once in the same signature.");
  1697. "Semantic 'SV_VertexID' overlap at 0");
  1698. }
  1699. TEST_F(ValidationTest, SemTargetMax) {
  1700. RewriteAssemblyCheckMsg(" \
  1701. float4 main(float4 col : COLOR) : SV_Target7 { return col; } \
  1702. ",
  1703. "ps_6_0",
  1704. { "!{i32 0, !\"SV_Target\", i8 9, i8 16, ![0-9]+, i8 0, i32 1, i8 4, i32 7, i8 0, (.*)}",
  1705. "?!dx.viewIdState ="},
  1706. { "!{i32 0, !\"SV_Target\", i8 9, i8 16, !101, i8 0, i32 1, i8 4, i32 8, i8 0, \\1}\n!101 = !{i32 8}",
  1707. "!1012 ="},
  1708. "SV_Target semantic index exceeds maximum \\(7\\)",
  1709. /*bRegex*/true);
  1710. }
  1711. TEST_F(ValidationTest, SemTargetIndexMatchesRow) {
  1712. RewriteAssemblyCheckMsg(" \
  1713. float4 main(float4 col : COLOR) : SV_Target7 { return col; } \
  1714. ",
  1715. "ps_6_0",
  1716. { "!{i32 0, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 4, i32 7, i8 0, (.*)}",
  1717. "?!dx.viewIdState ="},
  1718. { "!{i32 0, !\"SV_Target\", i8 9, i8 16, !\\1, i8 0, i32 1, i8 4, i32 6, i8 0, \\2}",
  1719. "!1012 ="},
  1720. "SV_Target semantic index must match packed row location",
  1721. /*bRegex*/true);
  1722. }
  1723. TEST_F(ValidationTest, SemTargetCol0) {
  1724. RewriteAssemblyCheckMsg(" \
  1725. float3 main(float4 col : COLOR) : SV_Target7 { return col.xyz; } \
  1726. ",
  1727. "ps_6_0",
  1728. "!{i32 0, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 3, i32 7, i8 0, (.*)}",
  1729. "!{i32 0, !\"SV_Target\", i8 9, i8 16, !\\1, i8 0, i32 1, i8 3, i32 7, i8 1, \\2}",
  1730. "SV_Target packed location must start at column 0",
  1731. /*bRegex*/true);
  1732. }
  1733. TEST_F(ValidationTest, SemIndexMax) {
  1734. RewriteAssemblyCheckMsg(" \
  1735. float4 main(uint vid : SV_VertexID, uint iid : SV_InstanceID) : SV_Position { \
  1736. return (float4)0 + vid + iid; \
  1737. } \
  1738. ",
  1739. "vs_6_0",
  1740. "!{i32 0, !\"SV_VertexID\", i8 5, i8 1, ![0-9]+, i8 0, i32 1, i8 1, i32 0, i8 0, (.*)}",
  1741. "!{i32 0, !\"SV_VertexID\", i8 5, i8 1, !101, i8 0, i32 1, i8 1, i32 0, i8 0, \\1}\n!101 = !{i32 1}",
  1742. "SV_VertexID semantic index exceeds maximum \\(0\\)",
  1743. /*bRegex*/true);
  1744. }
  1745. TEST_F(ValidationTest, SemTessFactorIndexMax) {
  1746. RewriteAssemblyCheckMsg(" \
  1747. struct Vertex { \
  1748. float4 pos : SV_Position; \
  1749. }; \
  1750. struct PatchConstant { \
  1751. float edges[ 3 ] : SV_TessFactor; \
  1752. float inside : SV_InsideTessFactor; \
  1753. }; \
  1754. PatchConstant PCMain( InputPatch<Vertex, 3> patch) { \
  1755. PatchConstant PC; \
  1756. PC.edges = (float[3])patch[1].pos.xyz; \
  1757. PC.inside = patch[1].pos.w; \
  1758. return PC; \
  1759. } \
  1760. [domain(\"tri\")] \
  1761. [partitioning(\"fractional_odd\")] \
  1762. [outputtopology(\"triangle_cw\")] \
  1763. [patchconstantfunc(\"PCMain\")] \
  1764. [outputcontrolpoints(3)] \
  1765. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 3 > patch) { \
  1766. Vertex Out = patch[id]; \
  1767. Out.pos.w += 0.25; \
  1768. return Out; \
  1769. } \
  1770. ",
  1771. "hs_6_0",
  1772. "!{i32 0, !\"SV_TessFactor\", i8 9, i8 25, ![0-9]+, i8 0, i32 3, i8 1, i32 0, i8 3, (.*)}",
  1773. "!{i32 0, !\"SV_TessFactor\", i8 9, i8 25, !101, i8 0, i32 2, i8 1, i32 0, i8 3, \\1}\n!101 = !{i32 0, i32 1}",
  1774. "TessFactor rows, columns \\(2, 1\\) invalid for domain Tri. Expected 3 rows and 1 column.",
  1775. /*bRegex*/true);
  1776. }
  1777. TEST_F(ValidationTest, SemInsideTessFactorIndexMax) {
  1778. RewriteAssemblyCheckMsg(" \
  1779. struct Vertex { \
  1780. float4 pos : SV_Position; \
  1781. }; \
  1782. struct PatchConstant { \
  1783. float edges[ 3 ] : SV_TessFactor; \
  1784. float inside : SV_InsideTessFactor; \
  1785. }; \
  1786. PatchConstant PCMain( InputPatch<Vertex, 3> patch) { \
  1787. PatchConstant PC; \
  1788. PC.edges = (float[3])patch[1].pos.xyz; \
  1789. PC.inside = patch[1].pos.w; \
  1790. return PC; \
  1791. } \
  1792. [domain(\"tri\")] \
  1793. [partitioning(\"fractional_odd\")] \
  1794. [outputtopology(\"triangle_cw\")] \
  1795. [patchconstantfunc(\"PCMain\")] \
  1796. [outputcontrolpoints(3)] \
  1797. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 3 > patch) { \
  1798. Vertex Out = patch[id]; \
  1799. Out.pos.w += 0.25; \
  1800. return Out; \
  1801. } \
  1802. ",
  1803. "hs_6_0",
  1804. { "!{i32 1, !\"SV_InsideTessFactor\", i8 9, i8 26, !([0-9]+), i8 0, i32 1, i8 1, i32 3, i8 0, (.*)}",
  1805. "?!dx.viewIdState =" },
  1806. { "!{i32 1, !\"SV_InsideTessFactor\", i8 9, i8 26, !101, i8 0, i32 2, i8 1, i32 3, i8 0, \\2}\n!101 = !{i32 0, i32 1}",
  1807. "!1012 =" },
  1808. "InsideTessFactor rows, columns \\(2, 1\\) invalid for domain Tri. Expected 1 rows and 1 column.",
  1809. /*bRegex*/true);
  1810. }
  1811. TEST_F(ValidationTest, SemShouldBeAllocated) {
  1812. RewriteAssemblyCheckMsg(" \
  1813. struct Vertex { \
  1814. float4 pos : SV_Position; \
  1815. }; \
  1816. struct PatchConstant { \
  1817. float edges[ 3 ] : SV_TessFactor; \
  1818. float inside : SV_InsideTessFactor; \
  1819. }; \
  1820. PatchConstant PCMain( InputPatch<Vertex, 3> patch) { \
  1821. PatchConstant PC; \
  1822. PC.edges = (float[3])patch[1].pos.xyz; \
  1823. PC.inside = patch[1].pos.w; \
  1824. return PC; \
  1825. } \
  1826. [domain(\"tri\")] \
  1827. [partitioning(\"fractional_odd\")] \
  1828. [outputtopology(\"triangle_cw\")] \
  1829. [patchconstantfunc(\"PCMain\")] \
  1830. [outputcontrolpoints(3)] \
  1831. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 3 > patch) { \
  1832. Vertex Out = patch[id]; \
  1833. Out.pos.w += 0.25; \
  1834. return Out; \
  1835. } \
  1836. ",
  1837. "hs_6_0",
  1838. "!{i32 0, !\"SV_TessFactor\", i8 9, i8 25, !([0-9]+), i8 0, i32 3, i8 1, i32 0, i8 3, (.*)}",
  1839. "!{i32 0, !\"SV_TessFactor\", i8 9, i8 25, !\\1, i8 0, i32 3, i8 1, i32 -1, i8 -1, \\2}",
  1840. "PatchConstant Semantic 'SV_TessFactor' should have a valid packing location",
  1841. /*bRegex*/true);
  1842. }
  1843. TEST_F(ValidationTest, SemShouldNotBeAllocated) {
  1844. RewriteAssemblyCheckMsg(" \
  1845. float4 main(float4 col : COLOR, out uint coverage : SV_Coverage) : SV_Target7 { coverage = 7; return col; } \
  1846. ",
  1847. "ps_6_0",
  1848. "!\"SV_Coverage\", i8 5, i8 14, !([0-9]+), i8 0, i32 1, i8 1, i32 -1, i8 -1, (.*)}",
  1849. "!\"SV_Coverage\", i8 5, i8 14, !\\1, i8 0, i32 1, i8 1, i32 2, i8 0, \\2}",
  1850. "Output Semantic 'SV_Coverage' should have a packing location of -1",
  1851. /*bRegex*/true);
  1852. }
  1853. TEST_F(ValidationTest, SemComponentOrder) {
  1854. RewriteAssemblyCheckMsg(" \
  1855. void main( \
  1856. float2 f2in : f2in, \
  1857. float3 f3in : f3in, \
  1858. uint vid : SV_VertexID, \
  1859. uint iid : SV_InstanceID, \
  1860. out float4 pos : SV_Position, \
  1861. out float2 f2out : f2out, \
  1862. out float3 f3out : f3out, \
  1863. out float2 ClipDistance : SV_ClipDistance, \
  1864. out float CullDistance : SV_CullDistance) \
  1865. { \
  1866. pos = float4(f3in, f2in.x); \
  1867. ClipDistance = f2in.x; \
  1868. CullDistance = f2in.y; \
  1869. } \
  1870. ",
  1871. "vs_6_0",
  1872. { "= !{i32 1, !\"f2out\", i8 9, i8 0, !([0-9]+), i8 2, i32 1, i8 2, i32 1, i8 0, (.*)}\n"
  1873. "!([0-9]+) = !{i32 2, !\"f3out\", i8 9, i8 0, !([0-9]+), i8 2, i32 1, i8 3, i32 2, i8 0, (.*)}\n"
  1874. "!([0-9]+) = !{i32 3, !\"SV_ClipDistance\", i8 9, i8 6, !([0-9]+), i8 2, i32 1, i8 2, i32 3, i8 0, (.*)}\n"
  1875. "!([0-9]+) = !{i32 4, !\"SV_CullDistance\", i8 9, i8 7, !([0-9]+), i8 2, i32 1, i8 1, i32 3, i8 2, (.*)}\n",
  1876. "?!dx.viewIdState =" },
  1877. { "= !{i32 1, !\"f2out\", i8 9, i8 0, !\\1, i8 2, i32 1, i8 2, i32 1, i8 2, \\2}\n"
  1878. "!\\3 = !{i32 2, !\"f3out\", i8 9, i8 0, !\\4, i8 2, i32 1, i8 3, i32 2, i8 1, \\5}\n"
  1879. "!\\6 = !{i32 3, !\"SV_ClipDistance\", i8 9, i8 6, !\\7, i8 2, i32 1, i8 2, i32 2, i8 0, \\8}\n"
  1880. "!\\9 = !{i32 4, !\"SV_CullDistance\", i8 9, i8 7, !\\10, i8 2, i32 1, i8 1, i32 1, i8 0, \\11}\n",
  1881. "!1012 =" },
  1882. "signature element SV_ClipDistance at location \\(2,0\\) size \\(1,2\\) violates component ordering rule \\(arb < sv < sgv\\).\n"
  1883. "signature element SV_CullDistance at location \\(1,0\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).",
  1884. /*bRegex*/true);
  1885. }
  1886. TEST_F(ValidationTest, SemComponentOrder2) {
  1887. RewriteAssemblyCheckMsg(" \
  1888. float4 main( \
  1889. float4 col : Color, \
  1890. uint2 val : Value, \
  1891. uint pid : SV_PrimitiveID, \
  1892. bool ff : SV_IsFrontFace) : SV_Target \
  1893. { \
  1894. return col; \
  1895. } \
  1896. ",
  1897. "ps_6_0",
  1898. "= !{i32 1, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 2, i32 1, i8 0, null}\n"
  1899. "!([0-9]+) = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
  1900. "!([0-9]+) = !{i32 3, !\"SV_IsFrontFace\", i8 ([15]), i8 13, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 3, null}\n",
  1901. "= !{i32 1, !\"Value\", i8 5, i8 0, !\\1, i8 1, i32 1, i8 2, i32 1, i8 2, null}\n"
  1902. "!\\2 = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !\\3, i8 1, i32 1, i8 1, i32 1, i8 0, null}\n"
  1903. "!\\4 = !{i32 3, !\"SV_IsFrontFace\", i8 \\5, i8 13, !\\6, i8 1, i32 1, i8 1, i32 1, i8 1, null}\n",
  1904. "signature element SV_PrimitiveID at location \\(1,0\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).\n"
  1905. "signature element SV_IsFrontFace at location \\(1,1\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).",
  1906. /*bRegex*/true);
  1907. }
  1908. TEST_F(ValidationTest, SemComponentOrder3) {
  1909. RewriteAssemblyCheckMsg(" \
  1910. float4 main( \
  1911. float4 col : Color, \
  1912. uint val : Value, \
  1913. uint pid : SV_PrimitiveID, \
  1914. bool ff : SV_IsFrontFace, \
  1915. uint vpid : ViewPortArrayIndex) : SV_Target \
  1916. { \
  1917. return col; \
  1918. } \
  1919. ",
  1920. "ps_6_0",
  1921. { "= !{i32 1, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 0, null}\n"
  1922. "!([0-9]+) = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 1, null}\n"
  1923. "!([0-9]+) = !{i32 3, !\"SV_IsFrontFace\", i8 ([15]), i8 13, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
  1924. "!([0-9]+) = !{i32 4, !\"ViewPortArrayIndex\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 1, i32 2, i8 0, null}\n",
  1925. "?!dx.viewIdState ="},
  1926. { "= !{i32 1, !\"Value\", i8 5, i8 0, !\\1, i8 1, i32 1, i8 1, i32 1, i8 1, null}\n"
  1927. "!\\2 = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !\\3, i8 1, i32 1, i8 1, i32 1, i8 0, null}\n"
  1928. "!\\4 = !{i32 3, !\"SV_IsFrontFace\", i8 \\5, i8 13, !\\6, i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
  1929. "!\\7 = !{i32 4, !\"ViewPortArrayIndex\", i8 5, i8 0, !\\8, i8 1, i32 1, i8 1, i32 1, i8 3, null}\n",
  1930. "!1012 ="},
  1931. "signature element SV_PrimitiveID at location \\(1,0\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).\n"
  1932. "signature element ViewPortArrayIndex at location \\(1,3\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).",
  1933. /*bRegex*/true);
  1934. }
  1935. TEST_F(ValidationTest, SemIndexConflictArbSV) {
  1936. RewriteAssemblyCheckMsg(" \
  1937. void main( \
  1938. float4 inpos : Position, \
  1939. uint iid : SV_InstanceID, \
  1940. out float4 pos : SV_Position, \
  1941. out uint id[2] : Array, \
  1942. out uint vpid : SV_ViewPortArrayIndex, \
  1943. out float2 ClipDistance : SV_ClipDistance, \
  1944. out float CullDistance : SV_CullDistance) \
  1945. { \
  1946. pos = inpos; \
  1947. ClipDistance = inpos.x; \
  1948. CullDistance = inpos.y; \
  1949. vpid = iid; \
  1950. id[0] = iid; \
  1951. id[1] = iid + 1; \
  1952. } \
  1953. ",
  1954. "vs_6_0",
  1955. "!{i32 2, !\"SV_ViewportArrayIndex\", i8 5, i8 5, !([0-9]+), i8 1, i32 1, i8 1, i32 3, i8 0, (.*)}",
  1956. "!{i32 2, !\"SV_ViewportArrayIndex\", i8 5, i8 5, !\\1, i8 1, i32 1, i8 1, i32 1, i8 3, \\2}",
  1957. "signature element SV_ViewportArrayIndex at location \\(1,3\\) size \\(1,1\\) has an indexing conflict with another signature element packed into the same row.",
  1958. /*bRegex*/true);
  1959. }
  1960. TEST_F(ValidationTest, SemIndexConflictTessfactors) {
  1961. RewriteAssemblyCheckMsg(" \
  1962. struct Vertex { \
  1963. float4 pos : SV_Position; \
  1964. }; \
  1965. struct PatchConstant { \
  1966. float edges[ 4 ] : SV_TessFactor; \
  1967. float inside[ 2 ] : SV_InsideTessFactor; \
  1968. }; \
  1969. PatchConstant PCMain( InputPatch<Vertex, 4> patch) { \
  1970. PatchConstant PC; \
  1971. PC.edges = (float[4])patch[1].pos; \
  1972. PC.inside = (float[2])patch[1].pos.xy; \
  1973. return PC; \
  1974. } \
  1975. [domain(\"quad\")] \
  1976. [partitioning(\"fractional_odd\")] \
  1977. [outputtopology(\"triangle_cw\")] \
  1978. [patchconstantfunc(\"PCMain\")] \
  1979. [outputcontrolpoints(4)] \
  1980. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 4 > patch) { \
  1981. Vertex Out = patch[id]; \
  1982. Out.pos.w += 0.25; \
  1983. return Out; \
  1984. } \
  1985. ",
  1986. "hs_6_0",
  1987. //!{i32 0, !"SV_TessFactor", i8 9, i8 25, !23, i8 0, i32 4, i8 1, i32 0, i8 3, null}
  1988. { "!{i32 1, !\"SV_InsideTessFactor\", i8 9, i8 26, !([0-9]+), i8 0, i32 2, i8 1, i32 4, i8 3, (.*)}",
  1989. "?!dx.viewIdState =" },
  1990. { "!{i32 1, !\"SV_InsideTessFactor\", i8 9, i8 26, !\\1, i8 0, i32 2, i8 1, i32 0, i8 2, \\2}",
  1991. "!1012 =" },
  1992. "signature element SV_InsideTessFactor at location \\(0,2\\) size \\(2,1\\) has an indexing conflict with another signature element packed into the same row.",
  1993. /*bRegex*/true);
  1994. }
  1995. TEST_F(ValidationTest, SemIndexConflictTessfactors2) {
  1996. RewriteAssemblyCheckMsg(" \
  1997. struct Vertex { \
  1998. float4 pos : SV_Position; \
  1999. }; \
  2000. struct PatchConstant { \
  2001. float edges[ 4 ] : SV_TessFactor; \
  2002. float inside[ 2 ] : SV_InsideTessFactor; \
  2003. float arb [ 3 ] : Arb; \
  2004. }; \
  2005. PatchConstant PCMain( InputPatch<Vertex, 4> patch) { \
  2006. PatchConstant PC; \
  2007. PC.edges = (float[4])patch[1].pos; \
  2008. PC.inside = (float[2])patch[1].pos.xy; \
  2009. PC.arb[0] = 1; PC.arb[1] = 2; PC.arb[2] = 3; \
  2010. return PC; \
  2011. } \
  2012. [domain(\"quad\")] \
  2013. [partitioning(\"fractional_odd\")] \
  2014. [outputtopology(\"triangle_cw\")] \
  2015. [patchconstantfunc(\"PCMain\")] \
  2016. [outputcontrolpoints(4)] \
  2017. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 4 > patch) { \
  2018. Vertex Out = patch[id]; \
  2019. Out.pos.w += 0.25; \
  2020. return Out; \
  2021. } \
  2022. ",
  2023. "hs_6_0",
  2024. "!{i32 2, !\"Arb\", i8 9, i8 0, !([0-9]+), i8 0, i32 3, i8 1, i32 0, i8 0, (.*)}",
  2025. "!{i32 2, !\"Arb\", i8 9, i8 0, !\\1, i8 0, i32 3, i8 1, i32 2, i8 0, \\2}",
  2026. "signature element Arb at location \\(2,0\\) size \\(3,1\\) has an indexing conflict with another signature element packed into the same row.",
  2027. /*bRegex*/true);
  2028. }
  2029. TEST_F(ValidationTest, SemRowOutOfRange) {
  2030. RewriteAssemblyCheckMsg(" \
  2031. struct Vertex { \
  2032. float4 pos : SV_Position; \
  2033. }; \
  2034. struct PatchConstant { \
  2035. float edges[ 4 ] : SV_TessFactor; \
  2036. float inside[ 2 ] : SV_InsideTessFactor; \
  2037. float arb [ 3 ] : Arb; \
  2038. }; \
  2039. PatchConstant PCMain( InputPatch<Vertex, 4> patch) { \
  2040. PatchConstant PC; \
  2041. PC.edges = (float[4])patch[1].pos; \
  2042. PC.inside = (float[2])patch[1].pos.xy; \
  2043. PC.arb[0] = 1; PC.arb[1] = 2; PC.arb[2] = 3; \
  2044. return PC; \
  2045. } \
  2046. [domain(\"quad\")] \
  2047. [partitioning(\"fractional_odd\")] \
  2048. [outputtopology(\"triangle_cw\")] \
  2049. [patchconstantfunc(\"PCMain\")] \
  2050. [outputcontrolpoints(4)] \
  2051. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 4 > patch) { \
  2052. Vertex Out = patch[id]; \
  2053. Out.pos.w += 0.25; \
  2054. return Out; \
  2055. } \
  2056. ",
  2057. "hs_6_0",
  2058. { "!{i32 2, !\"Arb\", i8 9, i8 0, !([0-9]+), i8 0, i32 3, i8 1, i32 0, i8 0, (.*)}",
  2059. "?!dx.viewIdState =" },
  2060. { "!{i32 2, !\"Arb\", i8 9, i8 0, !\\1, i8 0, i32 3, i8 1, i32 31, i8 0, \\2}",
  2061. "!1012 =" },
  2062. "signature element Arb at location \\(31,0\\) size \\(3,1\\) is out of range.",
  2063. /*bRegex*/true);
  2064. }
  2065. TEST_F(ValidationTest, SemPackOverlap) {
  2066. RewriteAssemblyCheckMsg(" \
  2067. struct Vertex { \
  2068. float4 pos : SV_Position; \
  2069. }; \
  2070. struct PatchConstant { \
  2071. float edges[ 4 ] : SV_TessFactor; \
  2072. float inside[ 2 ] : SV_InsideTessFactor; \
  2073. float arb [ 3 ] : Arb; \
  2074. }; \
  2075. PatchConstant PCMain( InputPatch<Vertex, 4> patch) { \
  2076. PatchConstant PC; \
  2077. PC.edges = (float[4])patch[1].pos; \
  2078. PC.inside = (float[2])patch[1].pos.xy; \
  2079. PC.arb[0] = 1; PC.arb[1] = 2; PC.arb[2] = 3; \
  2080. return PC; \
  2081. } \
  2082. [domain(\"quad\")] \
  2083. [partitioning(\"fractional_odd\")] \
  2084. [outputtopology(\"triangle_cw\")] \
  2085. [patchconstantfunc(\"PCMain\")] \
  2086. [outputcontrolpoints(4)] \
  2087. Vertex main(uint id : SV_OutputControlPointID, InputPatch< Vertex, 4 > patch) { \
  2088. Vertex Out = patch[id]; \
  2089. Out.pos.w += 0.25; \
  2090. return Out; \
  2091. } \
  2092. ",
  2093. "hs_6_0",
  2094. "!{i32 2, !\"Arb\", i8 9, i8 0, !([0-9]+), i8 0, i32 3, i8 1, i32 0, i8 0, (.*)}",
  2095. "!{i32 2, !\"Arb\", i8 9, i8 0, !\\1, i8 0, i32 3, i8 1, i32 1, i8 3, \\2}",
  2096. "signature element Arb at location \\(1,3\\) size \\(3,1\\) overlaps another signature element.",
  2097. /*bRegex*/true);
  2098. }
  2099. TEST_F(ValidationTest, SemPackOverlap2) {
  2100. RewriteAssemblyCheckMsg(" \
  2101. void main( \
  2102. float4 inpos : Position, \
  2103. uint iid : SV_InstanceID, \
  2104. out float4 pos : SV_Position, \
  2105. out uint id[2] : Array, \
  2106. out uint3 value : Value, \
  2107. out float2 ClipDistance : SV_ClipDistance, \
  2108. out float CullDistance : SV_CullDistance) \
  2109. { \
  2110. pos = inpos; \
  2111. ClipDistance = inpos.x; \
  2112. CullDistance = inpos.y; \
  2113. value = iid; \
  2114. id[0] = iid; \
  2115. id[1] = iid + 1; \
  2116. } \
  2117. ",
  2118. "vs_6_0",
  2119. {"!{i32 1, !\"Array\", i8 5, i8 0, !([0-9]+), i8 1, i32 2, i8 1, i32 1, i8 0, (.*)}(.*)"
  2120. "!\\1 = !{i32 0, i32 1}\n",
  2121. "= !{i32 2, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 3, i32 1, i8 1, (.*)}"},
  2122. {"!{i32 1, !\"Array\", i8 5, i8 0, !\\1, i8 1, i32 2, i8 1, i32 1, i8 1, \\2}\\3"
  2123. "!\\1 = !{i32 0, i32 1}\n",
  2124. "= !{i32 2, !\"Value\", i8 5, i8 0, !\\1, i8 1, i32 1, i8 3, i32 2, i8 0, \\2}"},
  2125. "signature element Value at location \\(2,0\\) size \\(1,3\\) overlaps another signature element.",
  2126. /*bRegex*/true);
  2127. }
  2128. TEST_F(ValidationTest, SemMultiDepth) {
  2129. RewriteAssemblyCheckMsg(" \
  2130. float4 main(float4 f4 : Input, out float d0 : SV_Depth, out float d1 : SV_Target) : SV_Target1 \
  2131. { d0 = f4.z; d1 = f4.w; return f4; } \
  2132. ",
  2133. "ps_6_0",
  2134. {"!{i32 2, !\"SV_Target\", i8 9, i8 16, !([0-9]+), i8 0, i32 1, i8 1, i32 0, i8 0, (.*)}"},
  2135. {"!{i32 2, !\"SV_DepthGreaterEqual\", i8 9, i8 19, !\\1, i8 0, i32 1, i8 1, i32 -1, i8 -1, \\2}"},
  2136. "Pixel Shader only allows one type of depth semantic to be declared",
  2137. /*bRegex*/true);
  2138. }
  2139. TEST_F(ValidationTest, WhenRootSigMismatchThenFail) {
  2140. ReplaceContainerPartsCheckMsgs(
  2141. "float c; [RootSignature ( \"RootConstants(b0, num32BitConstants = 1)\" )] float4 main() : semantic { return c; }",
  2142. "[RootSignature ( \"\" )] float4 main() : semantic { return 0; }",
  2143. "vs_6_0",
  2144. {DFCC_RootSignature},
  2145. {
  2146. "Root Signature in DXIL container is not compatible with shader.",
  2147. "Validation failed."
  2148. }
  2149. );
  2150. }
  2151. TEST_F(ValidationTest, WhenRootSigCompatThenSucceed) {
  2152. ReplaceContainerPartsCheckMsgs(
  2153. "[RootSignature ( \"\" )] float4 main() : semantic { return 0; }",
  2154. "float c; [RootSignature ( \"RootConstants(b0, num32BitConstants = 1)\" )] float4 main() : semantic { return c; }",
  2155. "vs_6_0",
  2156. {DFCC_RootSignature},
  2157. {}
  2158. );
  2159. }
  2160. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootConstVis) {
  2161. ReplaceContainerPartsCheckMsgs(
  2162. "float c; float4 main() : semantic { return c; }",
  2163. "[RootSignature ( \"RootConstants(b0, visibility = SHADER_VISIBILITY_VERTEX, num32BitConstants = 1)\" )]"
  2164. " float4 main() : semantic { return 0; }",
  2165. "vs_6_0",
  2166. {DFCC_RootSignature},
  2167. {}
  2168. );
  2169. }
  2170. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootConstVis) {
  2171. ReplaceContainerPartsCheckMsgs(
  2172. "float c; float4 main() : semantic { return c; }",
  2173. "[RootSignature ( \"RootConstants(b0, visibility = SHADER_VISIBILITY_PIXEL, num32BitConstants = 1)\" )]"
  2174. " float4 main() : semantic { return 0; }",
  2175. "vs_6_0",
  2176. {DFCC_RootSignature},
  2177. {
  2178. "Root Signature in DXIL container is not compatible with shader.",
  2179. "Validation failed."
  2180. }
  2181. );
  2182. }
  2183. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootCBV) {
  2184. ReplaceContainerPartsCheckMsgs(
  2185. "struct Foo { float a; int4 b; }; "
  2186. "ConstantBuffer<Foo> cb1 : register(b2, space5); "
  2187. "float4 main() : semantic { return cb1.b.x; }",
  2188. "[RootSignature ( \"CBV(b2, space = 5)\" )]"
  2189. " float4 main() : semantic { return 0; }",
  2190. "vs_6_0",
  2191. {DFCC_RootSignature},
  2192. {}
  2193. );
  2194. }
  2195. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootCBV_Range) {
  2196. ReplaceContainerPartsCheckMsgs(
  2197. "struct Foo { float a; int4 b; }; "
  2198. "ConstantBuffer<Foo> cb1 : register(b0, space5); "
  2199. "float4 main() : semantic { return cb1.b.x; }",
  2200. "[RootSignature ( \"CBV(b2, space = 5)\" )]"
  2201. " float4 main() : semantic { return 0; }",
  2202. "vs_6_0",
  2203. {DFCC_RootSignature},
  2204. {
  2205. "Root Signature in DXIL container is not compatible with shader.",
  2206. "Validation failed."
  2207. }
  2208. );
  2209. }
  2210. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootCBV_Space) {
  2211. ReplaceContainerPartsCheckMsgs(
  2212. "struct Foo { float a; int4 b; }; "
  2213. "ConstantBuffer<Foo> cb1 : register(b2, space7); "
  2214. "float4 main() : semantic { return cb1.b.x; }",
  2215. "[RootSignature ( \"CBV(b2, space = 5)\" )]"
  2216. " float4 main() : semantic { return 0; }",
  2217. "vs_6_0",
  2218. {DFCC_RootSignature},
  2219. {
  2220. "Root Signature in DXIL container is not compatible with shader.",
  2221. "Validation failed."
  2222. }
  2223. );
  2224. }
  2225. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootSRV) {
  2226. ReplaceContainerPartsCheckMsgs(
  2227. "struct Foo { float4 a; }; "
  2228. "StructuredBuffer<Foo> buf1 : register(t1, space3); "
  2229. "float4 main(float4 a : AAA) : SV_Target { return buf1[a.x].a; }",
  2230. "[RootSignature ( \"SRV(t1, space = 3)\" )]"
  2231. " float4 main() : SV_Target { return 0; }",
  2232. "ps_6_0",
  2233. {DFCC_RootSignature},
  2234. {}
  2235. );
  2236. }
  2237. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootSRV_ResType) {
  2238. ReplaceContainerPartsCheckMsgs(
  2239. "struct Foo { float4 a; }; "
  2240. "StructuredBuffer<Foo> buf1 : register(t1, space3); "
  2241. "float4 main(float4 a : AAA) : SV_Target { return buf1[a.x].a; }",
  2242. "[RootSignature ( \"UAV(u1, space = 3)\" )]"
  2243. " float4 main() : SV_Target { return 0; }",
  2244. "ps_6_0",
  2245. {DFCC_RootSignature},
  2246. {
  2247. "Root Signature in DXIL container is not compatible with shader.",
  2248. "Validation failed."
  2249. }
  2250. );
  2251. }
  2252. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootUAV) {
  2253. ReplaceContainerPartsCheckMsgs(
  2254. "struct Foo { float4 a; }; "
  2255. "RWStructuredBuffer<Foo> buf1 : register(u1, space3); "
  2256. "float4 main(float4 a : AAA) : SV_Target { return buf1[a.x].a; }",
  2257. "[RootSignature ( \"UAV(u1, space = 3)\" )]"
  2258. " float4 main() : SV_Target { return 0; }",
  2259. "ps_6_0",
  2260. {DFCC_RootSignature},
  2261. {}
  2262. );
  2263. }
  2264. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_DescTable) {
  2265. ReplaceContainerPartsCheckMsgs(
  2266. "struct Foo { int a; float4 b; };"
  2267. ""
  2268. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2269. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2270. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2271. "SamplerState sampler1[5] : register(s0, space0);"
  2272. ""
  2273. "float4 main(float4 a : AAA) : SV_TARGET"
  2274. "{"
  2275. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2276. "}",
  2277. "[RootSignature(\"DescriptorTable( SRV(t1,space=3,numDescriptors=8), "
  2278. "CBV(b2,space=5,numDescriptors=4), "
  2279. "UAV(u33,space=17,numDescriptors=6)), "
  2280. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2281. " float4 main() : SV_Target { return 0; }",
  2282. "ps_6_0",
  2283. {DFCC_RootSignature},
  2284. {}
  2285. );
  2286. }
  2287. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_DescTable_GoodRange) {
  2288. ReplaceContainerPartsCheckMsgs(
  2289. "struct Foo { int a; float4 b; };"
  2290. ""
  2291. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2292. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2293. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2294. "SamplerState sampler1[5] : register(s0, space0);"
  2295. ""
  2296. "float4 main(float4 a : AAA) : SV_TARGET"
  2297. "{"
  2298. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2299. "}",
  2300. "[RootSignature(\"DescriptorTable( SRV(t0,space=3,numDescriptors=20), "
  2301. "CBV(b2,space=5,numDescriptors=4), "
  2302. "UAV(u33,space=17,numDescriptors=6)), "
  2303. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2304. " float4 main() : SV_Target { return 0; }",
  2305. "ps_6_0",
  2306. {DFCC_RootSignature},
  2307. {}
  2308. );
  2309. }
  2310. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_DescTable_Unbounded) {
  2311. ReplaceContainerPartsCheckMsgs(
  2312. "struct Foo { int a; float4 b; };"
  2313. ""
  2314. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2315. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2316. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2317. "SamplerState sampler1[5] : register(s0, space0);"
  2318. ""
  2319. "float4 main(float4 a : AAA) : SV_TARGET"
  2320. "{"
  2321. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2322. "}",
  2323. "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=4), "
  2324. "SRV(t1,space=3,numDescriptors=8), "
  2325. "UAV(u10,space=17,numDescriptors=unbounded)), "
  2326. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2327. " float4 main() : SV_Target { return 0; }",
  2328. "ps_6_0",
  2329. {DFCC_RootSignature},
  2330. {}
  2331. );
  2332. }
  2333. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Range1) {
  2334. ReplaceContainerPartsCheckMsgs(
  2335. "struct Foo { int a; float4 b; };"
  2336. ""
  2337. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2338. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2339. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2340. "SamplerState sampler1[5] : register(s0, space0);"
  2341. ""
  2342. "float4 main(float4 a : AAA) : SV_TARGET"
  2343. "{"
  2344. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2345. "}",
  2346. "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=4), "
  2347. "SRV(t2,space=3,numDescriptors=8), "
  2348. "UAV(u33,space=17,numDescriptors=6)), "
  2349. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2350. " float4 main() : SV_Target { return 0; }",
  2351. "ps_6_0",
  2352. {DFCC_RootSignature},
  2353. {
  2354. "Shader SRV descriptor range (RegisterSpace=3, NumDescriptors=8, BaseShaderRegister=1) is not fully bound in root signature.",
  2355. "Root Signature in DXIL container is not compatible with shader.",
  2356. "Validation failed."
  2357. }
  2358. );
  2359. }
  2360. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Range2) {
  2361. ReplaceContainerPartsCheckMsgs(
  2362. "struct Foo { int a; float4 b; };"
  2363. ""
  2364. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2365. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2366. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2367. "SamplerState sampler1[5] : register(s0, space0);"
  2368. ""
  2369. "float4 main(float4 a : AAA) : SV_TARGET"
  2370. "{"
  2371. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2372. "}",
  2373. "[RootSignature(\"DescriptorTable( SRV(t2,space=3,numDescriptors=8), "
  2374. "CBV(b20,space=5,numDescriptors=4), "
  2375. "UAV(u33,space=17,numDescriptors=6)), "
  2376. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2377. " float4 main() : SV_Target { return 0; }",
  2378. "ps_6_0",
  2379. {DFCC_RootSignature},
  2380. {
  2381. "Root Signature in DXIL container is not compatible with shader.",
  2382. "Validation failed."
  2383. }
  2384. );
  2385. }
  2386. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Range3) {
  2387. ReplaceContainerPartsCheckMsgs(
  2388. "struct Foo { int a; float4 b; };"
  2389. ""
  2390. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2391. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2392. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2393. "SamplerState sampler1[5] : register(s0, space0);"
  2394. ""
  2395. "float4 main(float4 a : AAA) : SV_TARGET"
  2396. "{"
  2397. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2398. "}",
  2399. "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=4), "
  2400. "SRV(t1,space=3,numDescriptors=8), "
  2401. "UAV(u33,space=17,numDescriptors=5)), "
  2402. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2403. " float4 main() : SV_Target { return 0; }",
  2404. "ps_6_0",
  2405. {DFCC_RootSignature},
  2406. {
  2407. "Root Signature in DXIL container is not compatible with shader.",
  2408. "Validation failed."
  2409. }
  2410. );
  2411. }
  2412. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Space) {
  2413. ReplaceContainerPartsCheckMsgs(
  2414. "struct Foo { int a; float4 b; };"
  2415. ""
  2416. "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
  2417. "Texture2D<float4> tex1[8] : register(t1, space3);"
  2418. "RWBuffer<float4> buf1[6] : register(u33, space17);"
  2419. "SamplerState sampler1[5] : register(s0, space0);"
  2420. ""
  2421. "float4 main(float4 a : AAA) : SV_TARGET"
  2422. "{"
  2423. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2424. "}",
  2425. "[RootSignature(\"DescriptorTable( SRV(t2,space=3,numDescriptors=8), "
  2426. "CBV(b2,space=5,numDescriptors=4), "
  2427. "UAV(u33,space=0,numDescriptors=6)), "
  2428. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2429. " float4 main() : SV_Target { return 0; }",
  2430. "ps_6_0",
  2431. {DFCC_RootSignature},
  2432. {
  2433. "Root Signature in DXIL container is not compatible with shader.",
  2434. "Validation failed."
  2435. }
  2436. );
  2437. }
  2438. TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_Unbounded) {
  2439. ReplaceContainerPartsCheckMsgs(
  2440. "struct Foo { int a; float4 b; };"
  2441. ""
  2442. "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
  2443. "Texture2D<float4> tex1[] : register(t1, space3);"
  2444. "RWBuffer<float4> buf1[] : register(u33, space17);"
  2445. "SamplerState sampler1[] : register(s0, space0);"
  2446. ""
  2447. "float4 main(float4 a : AAA) : SV_TARGET"
  2448. "{"
  2449. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2450. "}",
  2451. "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=1)), "
  2452. "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
  2453. "DescriptorTable( UAV(u10,space=17,numDescriptors=100)), "
  2454. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2455. " float4 main() : SV_Target { return 0; }",
  2456. "ps_6_0",
  2457. {DFCC_RootSignature},
  2458. {}
  2459. );
  2460. }
  2461. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_Unbounded1) {
  2462. ReplaceContainerPartsCheckMsgs(
  2463. "struct Foo { int a; float4 b; };"
  2464. ""
  2465. "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
  2466. "Texture2D<float4> tex1[] : register(t1, space3);"
  2467. "RWBuffer<float4> buf1[] : register(u33, space17);"
  2468. "SamplerState sampler1[] : register(s0, space0);"
  2469. ""
  2470. "float4 main(float4 a : AAA) : SV_TARGET"
  2471. "{"
  2472. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2473. "}",
  2474. "[RootSignature(\"DescriptorTable( CBV(b3,space=5,numDescriptors=1)), "
  2475. "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
  2476. "DescriptorTable( UAV(u10,space=17,numDescriptors=unbounded)), "
  2477. "DescriptorTable( Sampler(s0, numDescriptors=5))\")]"
  2478. " float4 main() : SV_Target { return 0; }",
  2479. "ps_6_0",
  2480. {DFCC_RootSignature},
  2481. {
  2482. "Root Signature in DXIL container is not compatible with shader.",
  2483. "Validation failed."
  2484. }
  2485. );
  2486. }
  2487. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_Unbounded2) {
  2488. ReplaceContainerPartsCheckMsgs(
  2489. "struct Foo { int a; float4 b; };"
  2490. ""
  2491. "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
  2492. "Texture2D<float4> tex1[] : register(t1, space3);"
  2493. "RWBuffer<float4> buf1[] : register(u33, space17);"
  2494. "SamplerState sampler1[] : register(s0, space0);"
  2495. ""
  2496. "float4 main(float4 a : AAA) : SV_TARGET"
  2497. "{"
  2498. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2499. "}",
  2500. "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=1)), "
  2501. "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
  2502. "DescriptorTable( UAV(u10,space=17,numDescriptors=unbounded)), "
  2503. "DescriptorTable( Sampler(s5, numDescriptors=unbounded))\")]"
  2504. " float4 main() : SV_Target { return 0; }",
  2505. "ps_6_0",
  2506. {DFCC_RootSignature},
  2507. {
  2508. "Root Signature in DXIL container is not compatible with shader.",
  2509. "Validation failed."
  2510. }
  2511. );
  2512. }
  2513. TEST_F(ValidationTest, WhenRootSigMatchShaderFail_Unbounded3) {
  2514. ReplaceContainerPartsCheckMsgs(
  2515. "struct Foo { int a; float4 b; };"
  2516. ""
  2517. "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
  2518. "Texture2D<float4> tex1[] : register(t1, space3);"
  2519. "RWBuffer<float4> buf1[] : register(u33, space17);"
  2520. "SamplerState sampler1[] : register(s0, space0);"
  2521. ""
  2522. "float4 main(float4 a : AAA) : SV_TARGET"
  2523. "{"
  2524. " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
  2525. "}",
  2526. "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=1)), "
  2527. "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
  2528. "DescriptorTable( UAV(u10,space=17,numDescriptors=7)), "
  2529. "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
  2530. " float4 main() : SV_Target { return 0; }",
  2531. "ps_6_0",
  2532. {DFCC_RootSignature},
  2533. {
  2534. "Root Signature in DXIL container is not compatible with shader.",
  2535. "Validation failed."
  2536. }
  2537. );
  2538. }
  2539. #define VERTEX_STRUCT1 \
  2540. "struct PSSceneIn \n\
  2541. { \n\
  2542. float4 pos : SV_Position; \n\
  2543. float2 tex : TEXCOORD0; \n\
  2544. float3 norm : NORMAL; \n\
  2545. }; \n"
  2546. #define VERTEX_STRUCT2 \
  2547. "struct PSSceneIn \n\
  2548. { \n\
  2549. float4 pos : SV_Position; \n\
  2550. float2 tex : TEXCOORD0; \n\
  2551. }; \n"
  2552. #define PC_STRUCT1 "struct HSPerPatchData { \n\
  2553. float edges[ 3 ] : SV_TessFactor; \n\
  2554. float inside : SV_InsideTessFactor; \n\
  2555. float foo : FOO; \n\
  2556. }; \n"
  2557. #define PC_STRUCT2 "struct HSPerPatchData { \n\
  2558. float edges[ 3 ] : SV_TessFactor; \n\
  2559. float inside : SV_InsideTessFactor; \n\
  2560. }; \n"
  2561. #define PC_FUNC "HSPerPatchData HSPerPatchFunc( InputPatch< PSSceneIn, 3 > points, \n\
  2562. OutputPatch<PSSceneIn, 3> outpoints) { \n\
  2563. HSPerPatchData d = (HSPerPatchData)0; \n\
  2564. d.edges[ 0 ] = points[0].tex.x + outpoints[0].tex.x; \n\
  2565. d.edges[ 1 ] = 1; \n\
  2566. d.edges[ 2 ] = 1; \n\
  2567. d.inside = 1; \n\
  2568. return d; \n\
  2569. } \n"
  2570. #define PC_FUNC_NOOUT "HSPerPatchData HSPerPatchFunc( InputPatch< PSSceneIn, 3 > points ) { \n\
  2571. HSPerPatchData d = (HSPerPatchData)0; \n\
  2572. d.edges[ 0 ] = points[0].tex.x; \n\
  2573. d.edges[ 1 ] = 1; \n\
  2574. d.edges[ 2 ] = 1; \n\
  2575. d.inside = 1; \n\
  2576. return d; \n\
  2577. } \n"
  2578. #define PC_FUNC_NOIN "HSPerPatchData HSPerPatchFunc( OutputPatch<PSSceneIn, 3> outpoints) { \n\
  2579. HSPerPatchData d = (HSPerPatchData)0; \n\
  2580. d.edges[ 0 ] = outpoints[0].tex.x; \n\
  2581. d.edges[ 1 ] = 1; \n\
  2582. d.edges[ 2 ] = 1; \n\
  2583. d.inside = 1; \n\
  2584. return d; \n\
  2585. } \n"
  2586. #define HS_ATTR "[domain(\"tri\")] \n\
  2587. [partitioning(\"fractional_odd\")] \n\
  2588. [outputtopology(\"triangle_cw\")] \n\
  2589. [patchconstantfunc(\"HSPerPatchFunc\")] \n\
  2590. [outputcontrolpoints(3)] \n"
  2591. #define HS_FUNC \
  2592. "PSSceneIn main(const uint id : SV_OutputControlPointID, \n\
  2593. const InputPatch< PSSceneIn, 3 > points ) { \n\
  2594. return points[ id ]; \n\
  2595. } \n"
  2596. #define HS_FUNC_NOOUT \
  2597. "void main(const uint id : SV_OutputControlPointID, \n\
  2598. const InputPatch< PSSceneIn, 3 > points ) { \n\
  2599. } \n"
  2600. #define HS_FUNC_NOIN \
  2601. "PSSceneIn main( const uint id : SV_OutputControlPointID ) { \n\
  2602. return (PSSceneIn)0; \n\
  2603. } \n"
  2604. #define DS_FUNC \
  2605. "[domain(\"tri\")] PSSceneIn main(const float3 bary : SV_DomainLocation, \n\
  2606. const OutputPatch<PSSceneIn, 3> patch, \n\
  2607. const HSPerPatchData perPatchData) { \n\
  2608. PSSceneIn v = patch[0]; \n\
  2609. v.pos = patch[0].pos * bary.x; \n\
  2610. v.pos += patch[1].pos * bary.y; \n\
  2611. v.pos += patch[2].pos * bary.z; \n\
  2612. return v; \n\
  2613. } \n"
  2614. #define DS_FUNC_NOPC \
  2615. "[domain(\"tri\")] PSSceneIn main(const float3 bary : SV_DomainLocation, \n\
  2616. const OutputPatch<PSSceneIn, 3> patch) { \n\
  2617. PSSceneIn v = patch[0]; \n\
  2618. v.pos = patch[0].pos * bary.x; \n\
  2619. v.pos += patch[1].pos * bary.y; \n\
  2620. v.pos += patch[2].pos * bary.z; \n\
  2621. return v; \n\
  2622. } \n"
  2623. TEST_F(ValidationTest, WhenProgramOutSigMissingThenFail) {
  2624. ReplaceContainerPartsCheckMsgs(
  2625. VERTEX_STRUCT1
  2626. PC_STRUCT1
  2627. PC_FUNC
  2628. HS_ATTR
  2629. HS_FUNC,
  2630. VERTEX_STRUCT1
  2631. PC_STRUCT1
  2632. PC_FUNC_NOOUT
  2633. HS_ATTR
  2634. HS_FUNC_NOOUT,
  2635. "hs_6_0",
  2636. {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
  2637. {
  2638. "Container part 'Program Output Signature' does not match expected for module.",
  2639. "Validation failed."
  2640. }
  2641. );
  2642. }
  2643. TEST_F(ValidationTest, WhenProgramOutSigUnexpectedThenFail) {
  2644. ReplaceContainerPartsCheckMsgs(
  2645. VERTEX_STRUCT1
  2646. PC_STRUCT1
  2647. PC_FUNC_NOOUT
  2648. HS_ATTR
  2649. HS_FUNC_NOOUT,
  2650. VERTEX_STRUCT1
  2651. PC_STRUCT1
  2652. PC_FUNC
  2653. HS_ATTR
  2654. HS_FUNC,
  2655. "hs_6_0",
  2656. {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
  2657. {
  2658. "Container part 'Program Output Signature' does not match expected for module.",
  2659. "Validation failed."
  2660. }
  2661. );
  2662. }
  2663. TEST_F(ValidationTest, WhenProgramSigMismatchThenFail) {
  2664. ReplaceContainerPartsCheckMsgs(
  2665. VERTEX_STRUCT1
  2666. PC_STRUCT1
  2667. PC_FUNC
  2668. HS_ATTR
  2669. HS_FUNC,
  2670. VERTEX_STRUCT2
  2671. PC_STRUCT2
  2672. PC_FUNC
  2673. HS_ATTR
  2674. HS_FUNC,
  2675. "hs_6_0",
  2676. {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
  2677. {
  2678. "Container part 'Program Input Signature' does not match expected for module.",
  2679. "Container part 'Program Output Signature' does not match expected for module.",
  2680. "Container part 'Program Patch Constant Signature' does not match expected for module.",
  2681. "Validation failed."
  2682. }
  2683. );
  2684. }
  2685. TEST_F(ValidationTest, WhenProgramInSigMissingThenFail) {
  2686. ReplaceContainerPartsCheckMsgs(
  2687. VERTEX_STRUCT1
  2688. PC_STRUCT1
  2689. PC_FUNC
  2690. HS_ATTR
  2691. HS_FUNC,
  2692. // Compiling the HS_FUNC_NOIN produces the following error
  2693. //error: validation errors
  2694. //HS input control point count must be [1..32]. 0 specified
  2695. VERTEX_STRUCT1
  2696. PC_STRUCT1
  2697. PC_FUNC_NOIN
  2698. HS_ATTR
  2699. HS_FUNC_NOIN,
  2700. "hs_6_0",
  2701. {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
  2702. {
  2703. "Container part 'Program Input Signature' does not match expected for module.",
  2704. "Validation failed."
  2705. }
  2706. );
  2707. }
  2708. TEST_F(ValidationTest, WhenProgramSigMismatchThenFail2) {
  2709. ReplaceContainerPartsCheckMsgs(
  2710. VERTEX_STRUCT1
  2711. PC_STRUCT1
  2712. DS_FUNC,
  2713. VERTEX_STRUCT2
  2714. PC_STRUCT2
  2715. DS_FUNC,
  2716. "ds_6_0",
  2717. {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
  2718. {
  2719. "Container part 'Program Input Signature' does not match expected for module.",
  2720. "Container part 'Program Output Signature' does not match expected for module.",
  2721. "Container part 'Program Patch Constant Signature' does not match expected for module.",
  2722. "Validation failed."
  2723. }
  2724. );
  2725. }
  2726. TEST_F(ValidationTest, WhenProgramPCSigMissingThenFail) {
  2727. ReplaceContainerPartsCheckMsgs(
  2728. VERTEX_STRUCT1
  2729. PC_STRUCT1
  2730. DS_FUNC,
  2731. VERTEX_STRUCT2
  2732. PC_STRUCT2
  2733. DS_FUNC_NOPC,
  2734. "ds_6_0",
  2735. {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
  2736. {
  2737. "Container part 'Program Input Signature' does not match expected for module.",
  2738. "Container part 'Program Output Signature' does not match expected for module.",
  2739. "Missing part 'Program Patch Constant Signature' required by module.",
  2740. "Validation failed."
  2741. }
  2742. );
  2743. }
  2744. #undef VERTEX_STRUCT1
  2745. #undef VERTEX_STRUCT2
  2746. #undef PC_STRUCT1
  2747. #undef PC_STRUCT2
  2748. #undef PC_FUNC
  2749. #undef PC_FUNC_NOOUT
  2750. #undef PC_FUNC_NOIN
  2751. #undef HS_ATTR
  2752. #undef HS_FUNC
  2753. #undef HS_FUNC_NOOUT
  2754. #undef HS_FUNC_NOIN
  2755. #undef DS_FUNC
  2756. #undef DS_FUNC_NOPC
  2757. TEST_F(ValidationTest, WhenPSVMismatchThenFail) {
  2758. ReplaceContainerPartsCheckMsgs(
  2759. "float c; [RootSignature ( \"RootConstants(b0, num32BitConstants = 1)\" )] float4 main() : semantic { return c; }",
  2760. "[RootSignature ( \"\" )] float4 main() : semantic { return 0; }",
  2761. "vs_6_0",
  2762. {DFCC_PipelineStateValidation},
  2763. {
  2764. "Container part 'Pipeline State Validation' does not match expected for module.",
  2765. "Validation failed."
  2766. }
  2767. );
  2768. }
  2769. TEST_F(ValidationTest, WhenRDATMismatchThenFail) {
  2770. ReplaceContainerPartsCheckMsgs(
  2771. "export float4 main(float f) : semantic { return f; }",
  2772. "export float4 main() : semantic { return 0; }",
  2773. "lib_6_3",
  2774. { DFCC_RuntimeData },
  2775. {
  2776. "Container part 'Runtime Data (RDAT)' does not match expected for module.",
  2777. "Validation failed."
  2778. }
  2779. );
  2780. }
  2781. TEST_F(ValidationTest, WhenFeatureInfoMismatchThenFail) {
  2782. ReplaceContainerPartsCheckMsgs(
  2783. "float4 main(uint2 foo : FOO) : SV_Target { return asdouble(foo.x, foo.y) * 2.0; }",
  2784. "float4 main() : SV_Target { return 0; }",
  2785. "ps_6_0",
  2786. {DFCC_FeatureInfo},
  2787. {
  2788. "Container part 'Feature Info' does not match expected for module.",
  2789. "Validation failed."
  2790. }
  2791. );
  2792. }
  2793. TEST_F(ValidationTest, RayShaderWithSignaturesFail) {
  2794. if (m_ver.SkipDxilVersion(1, 3)) return;
  2795. RewriteAssemblyCheckMsg(
  2796. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  2797. "struct Param { float f; };\n"
  2798. "[shader(\"raygeneration\")] void RayGenProto() { return; }\n"
  2799. "[shader(\"intersection\")] void IntersectionProto() { return; }\n"
  2800. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  2801. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  2802. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  2803. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  2804. "[shader(\"vertex\")] float VSOutOnly() : OUTPUT { return 1; }\n"
  2805. "[shader(\"vertex\")] void VSInOnly(float f : INPUT) : OUTPUT {}\n"
  2806. "[shader(\"vertex\")] float VSInOut(float f : INPUT) : OUTPUT { return f; }\n"
  2807. , "lib_6_3",
  2808. { "!{void \\(\\)\\* @VSInOnly, !\"VSInOnly\", !([0-9]+), null,(.*)!\\1 = "
  2809. ,"!{void \\(\\)\\* @VSOutOnly, !\"VSOutOnly\", !([0-9]+), null,(.*)!\\1 = "
  2810. ,"!{void \\(\\)\\* @VSInOut, !\"VSInOut\", !([0-9]+), null,(.*)!\\1 = "
  2811. ,"!{void \\(\\)\\* @\"\\\\01\\?RayGenProto@@YAXXZ\", !\"\\\\01\\?RayGenProto@@YAXXZ\", null, null,"
  2812. ,"!{void \\(\\)\\* @\"\\\\01\\?IntersectionProto@@YAXXZ\", !\"\\\\01\\?IntersectionProto@@YAXXZ\", null, null,"
  2813. ,"!{void \\(%struct.Payload\\*, %struct.Attributes\\*\\)\\* @\"\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", null, null,"
  2814. ,"!{void \\(%struct.Payload\\*, %struct.Attributes\\*\\)\\* @\"\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", null, null,"
  2815. ,"!{void \\(%struct.Payload\\*\\)\\* @\"\\\\01\\?MissProto@@YAXUPayload@@@Z\", !\"\\\\01\\?MissProto@@YAXUPayload@@@Z\", null, null,"
  2816. ,"!{void \\(%struct.Param\\*\\)\\* @\"\\\\01\\?CallableProto@@YAXUParam@@@Z\", !\"\\\\01\\?CallableProto@@YAXUParam@@@Z\", null, null,"
  2817. },
  2818. { "!{void ()* @VSInOnly, !\"VSInOnly\", !1001, null,\\2!1001 = "
  2819. ,"!{void ()* @VSOutOnly, !\"VSOutOnly\", !1002, null,\\2!1002 = "
  2820. ,"!{void ()* @VSInOut, !\"VSInOut\", !1003, null,\\2!1003 = "
  2821. ,"!{void ()* @\"\\\\01?RayGenProto@@YAXXZ\", !\"\\\\01?RayGenProto@@YAXXZ\", !1001, null,"
  2822. ,"!{void ()* @\"\\\\01?IntersectionProto@@YAXXZ\", !\"\\\\01?IntersectionProto@@YAXXZ\", !1002, null,"
  2823. ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !1003, null,"
  2824. ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !1001, null,"
  2825. ,"!{void (%struct.Payload*)* @\"\\\\01?MissProto@@YAXUPayload@@@Z\", !\"\\\\01?MissProto@@YAXUPayload@@@Z\", !1002, null,"
  2826. ,"!{void (%struct.Param*)* @\"\\\\01?CallableProto@@YAXUParam@@@Z\", !\"\\\\01?CallableProto@@YAXUParam@@@Z\", !1003, null,"
  2827. },
  2828. { "Ray tracing shader '\\\\01\\?RayGenProto@@YAXXZ' should not have any shader signatures"
  2829. ,"Ray tracing shader '\\\\01\\?IntersectionProto@@YAXXZ' should not have any shader signatures"
  2830. ,"Ray tracing shader '\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z' should not have any shader signatures"
  2831. ,"Ray tracing shader '\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z' should not have any shader signatures"
  2832. ,"Ray tracing shader '\\\\01\\?MissProto@@YAXUPayload@@@Z' should not have any shader signatures"
  2833. ,"Ray tracing shader '\\\\01\\?CallableProto@@YAXUParam@@@Z' should not have any shader signatures"
  2834. },
  2835. /*bRegex*/true);
  2836. }
  2837. TEST_F(ValidationTest, ViewIDInCSFail) {
  2838. if (m_ver.SkipDxilVersion(1,1)) return;
  2839. RewriteAssemblyCheckMsg(" \
  2840. RWStructuredBuffer<uint> Buf; \
  2841. [numthreads(1,1,1)] \
  2842. void main(uint id : SV_GroupIndex) \
  2843. { Buf[id] = 0; } \
  2844. ",
  2845. "cs_6_1",
  2846. {"dx.op.flattenedThreadIdInGroup.i32(i32 96",
  2847. "declare i32 @dx.op.flattenedThreadIdInGroup.i32(i32)"},
  2848. {"dx.op.viewID.i32(i32 138",
  2849. "declare i32 @dx.op.viewID.i32(i32)"},
  2850. "Opcode ViewID not valid in shader model cs_6_1",
  2851. /*bRegex*/false);
  2852. }
  2853. TEST_F(ValidationTest, ViewIDIn60Fail) {
  2854. if (m_ver.SkipDxilVersion(1,1)) return;
  2855. RewriteAssemblyCheckMsg(" \
  2856. [domain(\"tri\")] \
  2857. float4 main(float3 pos : Position, uint id : SV_PrimitiveID) : SV_Position \
  2858. { return float4(pos, id); } \
  2859. ",
  2860. "ds_6_0",
  2861. {"dx.op.primitiveID.i32(i32 108",
  2862. "declare i32 @dx.op.primitiveID.i32(i32)"},
  2863. {"dx.op.viewID.i32(i32 138",
  2864. "declare i32 @dx.op.viewID.i32(i32)"},
  2865. "Opcode ViewID not valid in shader model ds_6_0",
  2866. /*bRegex*/false);
  2867. }
  2868. TEST_F(ValidationTest, ViewIDNoSpaceFail) {
  2869. if (m_ver.SkipDxilVersion(1,1)) return;
  2870. RewriteAssemblyCheckMsg(" \
  2871. float4 main(uint vid : SV_ViewID, float3 In[31] : INPUT) : SV_Target \
  2872. { return float4(In[vid], 1); } \
  2873. ",
  2874. "ps_6_1",
  2875. { "!{i32 0, !\"INPUT\", i8 9, i8 0, !([0-9]+), i8 2, i32 31",
  2876. "!{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30}",
  2877. "?!dx.viewIdState =" },
  2878. { "!{i32 0, !\"INPUT\", i8 9, i8 0, !\\1, i8 2, i32 32",
  2879. "!{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31}",
  2880. "!1012 =" },
  2881. "Pixel shader input signature lacks available space for ViewID",
  2882. /*bRegex*/true);
  2883. }
  2884. // Regression test for a double-delete when failing to parse bitcode.
  2885. TEST_F(ValidationTest, WhenDisassembleInvalidBlobThenFail) {
  2886. if (!m_dllSupport.IsEnabled()) {
  2887. VERIFY_SUCCEEDED(m_dllSupport.Initialize());
  2888. }
  2889. CComPtr<IDxcBlobEncoding> pInvalidBitcode;
  2890. Utf8ToBlob(m_dllSupport, "This text is certainly not bitcode", &pInvalidBitcode);
  2891. CComPtr<IDxcCompiler> pCompiler;
  2892. VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
  2893. CComPtr<IDxcBlobEncoding> pDisassembly;
  2894. VERIFY_FAILED(pCompiler->Disassemble(pInvalidBitcode, &pDisassembly));
  2895. }
  2896. TEST_F(ValidationTest, GSMainMissingAttributeFail) {
  2897. TestCheck(L"..\\CodeGenHLSL\\attributes-gs-no-inout-main.hlsl");
  2898. }
  2899. TEST_F(ValidationTest, GSOtherMissingAttributeFail) {
  2900. TestCheck(L"..\\CodeGenHLSL\\attributes-gs-no-inout-other.hlsl");
  2901. }
  2902. TEST_F(ValidationTest, GSMissingMaxVertexCountFail) {
  2903. TestCheck(L"..\\CodeGenHLSL\\attributes-gs-no-maxvertexcount.hlsl");
  2904. }
  2905. TEST_F(ValidationTest, HSMissingPCFFail) {
  2906. TestCheck(L"..\\CodeGenHLSL\\attributes-hs-no-pcf.hlsl");
  2907. }
  2908. TEST_F(ValidationTest, GetAttributeAtVertexInVSFail) {
  2909. if (m_ver.SkipDxilVersion(1,1)) return;
  2910. RewriteAssemblyCheckMsg(
  2911. "float4 main(float4 pos: POSITION) : SV_POSITION { return pos.x; }",
  2912. "vs_6_1",
  2913. { "call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)",
  2914. "declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32)" },
  2915. { "call float @dx.op.attributeAtVertex.f32(i32 137, i32 0, i32 0, i8 0, i8 0)",
  2916. "declare float @dx.op.attributeAtVertex.f32(i32, i32, i32, i8, i8)" },
  2917. "Opcode AttributeAtVertex not valid in shader model vs_6_1",
  2918. /*bRegex*/ false);
  2919. }
  2920. TEST_F(ValidationTest, GetAttributeAtVertexIn60Fail) {
  2921. if (m_ver.SkipDxilVersion(1,1)) return;
  2922. RewriteAssemblyCheckMsg(
  2923. "float4 main(float4 col : COLOR) : "
  2924. "SV_Target { return EvaluateAttributeCentroid(col).x; }",
  2925. "ps_6_0",
  2926. { "call float @dx.op.evalCentroid.f32(i32 89, i32 0, i32 0, i8 0)",
  2927. "declare float @dx.op.evalCentroid.f32(i32, i32, i32, i8)"
  2928. },
  2929. { "call float @dx.op.attributeAtVertex.f32(i32 137, i32 0, i32 0, i8 0, i8 0)",
  2930. "declare float @dx.op.attributeAtVertex.f32(i32, i32, i32, i8, i8)" },
  2931. "Opcode AttributeAtVertex not valid in shader model ps_6_0", /*bRegex*/ false);
  2932. }
  2933. TEST_F(ValidationTest, GetAttributeAtVertexInterpFail) {
  2934. if (m_ver.SkipDxilVersion(1,1)) return;
  2935. RewriteAssemblyCheckMsg("float4 main(nointerpolation float4 col : COLOR) : "
  2936. "SV_Target { return GetAttributeAtVertex(col, 0); }",
  2937. "ps_6_1", {"!\"COLOR\", i8 9, i8 0, (![0-9]+), i8 1"},
  2938. {"!\"COLOR\", i8 9, i8 0, \\1, i8 2"},
  2939. "Attribute COLOR must have nointerpolation mode in "
  2940. "order to use GetAttributeAtVertex function.",
  2941. /*bRegex*/ true);
  2942. }
  2943. TEST_F(ValidationTest, BarycentricMaxIndexFail) {
  2944. if (m_ver.SkipDxilVersion(1,1)) return;
  2945. RewriteAssemblyCheckMsg(
  2946. "float4 main(float3 bary : SV_Barycentrics, noperspective float3 bary1 : "
  2947. "SV_Barycentrics1) : SV_Target { return 1; }",
  2948. "ps_6_1",
  2949. {"!([0-9]+) = !{i32 0, !\"SV_Barycentrics\", i8 9, i8 28, !([0-9]+), i8 "
  2950. "2, i32 1, i8 3, i32 -1, i8 -1, null}\n"
  2951. "!([0-9]+) = !{i32 0}"},
  2952. {"!\\1 = !{i32 0, !\"SV_Barycentrics\", i8 9, i8 28, !\\2, i8 2, i32 1, "
  2953. "i8 3, i32 -1, i8 -1, null}\n"
  2954. "!\\3 = !{i32 2}"},
  2955. "SV_Barycentrics semantic index exceeds maximum", /*bRegex*/ true);
  2956. }
  2957. TEST_F(ValidationTest, BarycentricNoInterpolationFail) {
  2958. if (m_ver.SkipDxilVersion(1,1)) return;
  2959. RewriteAssemblyCheckMsg(
  2960. "float4 main(float3 bary : SV_Barycentrics) : "
  2961. "SV_Target { return bary.x * float4(1,0,0,0) + bary.y * float4(0,1,0,0) "
  2962. "+ bary.z * float4(0,0,1,0); }",
  2963. "ps_6_1", {"!\"SV_Barycentrics\", i8 9, i8 28, (![0-9]+), i8 2"},
  2964. {"!\"SV_Barycentrics\", i8 9, i8 28, \\1, i8 1"},
  2965. "SV_Barycentrics cannot be used with 'nointerpolation' type",
  2966. /*bRegex*/ true);
  2967. }
  2968. TEST_F(ValidationTest, BarycentricFloat4Fail) {
  2969. if (m_ver.SkipDxilVersion(1,1)) return;
  2970. RewriteAssemblyCheckMsg(
  2971. "float4 main(float4 col : COLOR) : SV_Target { return col; }", "ps_6_1",
  2972. {"!\"COLOR\", i8 9, i8 0"}, {"!\"SV_Barycentrics\", i8 9, i8 28"},
  2973. "only 'float3' type is allowed for SV_Barycentrics.", false);
  2974. }
  2975. TEST_F(ValidationTest, BarycentricSamePerspectiveFail) {
  2976. if (m_ver.SkipDxilVersion(1,1)) return;
  2977. RewriteAssemblyCheckMsg(
  2978. "float4 main(float3 bary : SV_Barycentrics, noperspective float3 bary1 : "
  2979. "SV_Barycentrics1) : SV_Target { return 1; }",
  2980. "ps_6_1", {"!\"SV_Barycentrics\", i8 9, i8 28, (![0-9]+), i8 4"},
  2981. {"!\"SV_Barycentrics\", i8 9, i8 28, \\1, i8 2"},
  2982. "There can only be up to two input attributes of SV_Barycentrics with "
  2983. "different perspective interpolation mode.",
  2984. true);
  2985. }
  2986. TEST_F(ValidationTest, Float32DenormModeAttribute) {
  2987. if (m_ver.SkipDxilVersion(1, 2)) return;
  2988. std::vector<LPCWSTR> pArguments = { L"-denorm", L"ftz" };
  2989. RewriteAssemblyCheckMsg(
  2990. "float4 main(float4 col: COL) : SV_Target { return col; }", "ps_6_2",
  2991. pArguments.data(), 2, nullptr, 0,
  2992. { "\"fp32-denorm-mode\"=\"ftz\"" },
  2993. { "\"fp32-denorm-mode\"=\"invalid_mode\"" },
  2994. "contains invalid attribute 'fp32-denorm-mode' with value 'invalid_mode'",
  2995. false);
  2996. }
  2997. TEST_F(ValidationTest, ResCounter) {
  2998. if (m_ver.SkipDxilVersion(1, 3)) return;
  2999. RewriteAssemblyCheckMsg(
  3000. "RWStructuredBuffer<float4> buf; export float GetCounter() {return buf.IncrementCounter();}",
  3001. "lib_6_3",
  3002. { "!\"buf\", i32 -1, i32 -1, i32 1, i32 12, i1 false, i1 true, i1 false, !" },
  3003. { "!\"buf\", i32 -1, i32 -1, i32 1, i32 12, i1 false, i1 false, i1 false, !" },
  3004. "BufferUpdateCounter valid only when HasCounter is true",
  3005. true);
  3006. }
  3007. TEST_F(ValidationTest, FunctionAttributes) {
  3008. if (m_ver.SkipDxilVersion(1, 2)) return;
  3009. std::vector<LPCWSTR> pArguments = { L"-denorm", L"ftz" };
  3010. RewriteAssemblyCheckMsg(
  3011. "float4 main(float4 col: COL) : SV_Target { return col; }", "ps_6_2",
  3012. pArguments.data(), 2, nullptr, 0,
  3013. { "\"fp32-denorm-mode\"=\"ftz\"" },
  3014. { "\"dummy_attribute\"=\"invalid_mode\"" },
  3015. "contains invalid attribute 'dummy_attribute' with value 'invalid_mode'",
  3016. false);
  3017. }// TODO: reject non-zero padding
  3018. TEST_F(ValidationTest, LibFunctionResInSig) {
  3019. if (m_ver.SkipDxilVersion(1, 3)) return;
  3020. RewriteAssemblyCheckMsg(
  3021. "Texture2D<float4> T1;\n"
  3022. "struct ResInStruct { float f; Texture2D<float4> T; };\n"
  3023. "struct ResStructInStruct { float f; ResInStruct S; };\n"
  3024. "ResStructInStruct fnResInReturn(float f) : SV_Target {\n"
  3025. " ResStructInStruct S1; S1.f = S1.S.f = f; S1.S.T = T1;\n"
  3026. " return S1; }\n"
  3027. "float fnResInArg(ResStructInStruct S1) : SV_Target {\n"
  3028. " return S1.f; }\n"
  3029. "struct Data { float f; };\n"
  3030. "float fnStreamInArg(float f, inout PointStream<Data> S1) : SV_Target {\n"
  3031. " S1.Append((Data)f); return 1.0; }\n"
  3032. , "lib_6_x",
  3033. { "!{!\"lib\", i32 6, i32 15}", "!dx.valver = !{!([0-9]+)}", "= !{i32 20, !([0-9]+), !([0-9]+), !([0-9]+)}" },
  3034. { "!{!\"lib\", i32 6, i32 3}", "!dx.valver = !{!100\\1}\n!1002 = !{i32 1, i32 3}", "= !{i32 20, !\\1, !\\2}" },
  3035. { "Function '\\\\01\\?fnResInReturn@@YA\\?AUResStructInStruct@@M@Z' uses resource in function signature"
  3036. ,"Function '\\\\01\\?fnResInArg@@YAMUResStructInStruct@@@Z' uses resource in function signature"
  3037. ,"Function '\\\\01\\?fnStreamInArg@@YAMMV\\?\\$PointStream@UData@@@@@Z' uses resource in function signature"
  3038. // TODO: Unable to lower stream append, since it's used in a non-GS function.
  3039. // Should we fail to compile earlier (even on lib_6_x), or add lowering to linker?
  3040. ,"Function 'dx\\.hl\\.op\\.\\.void \\(i32, %\"class\\.PointStream<Data>\"\\*, float\\*\\)' uses resource in function signature"
  3041. },
  3042. /*bRegex*/ true);
  3043. }
  3044. TEST_F(ValidationTest, RayPayloadIsStruct) {
  3045. if (m_ver.SkipDxilVersion(1, 3)) return;
  3046. RewriteAssemblyCheckMsg(
  3047. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3048. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3049. "export void BadAnyHit(inout float f, in Attributes a) { f += a.b.x; }\n"
  3050. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3051. "export void BadClosestHit(inout float f, in Attributes a) { f += a.b.y; }\n"
  3052. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  3053. "export void BadMiss(inout float f) { f += 1.0; }\n"
  3054. , "lib_6_3",
  3055. { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3056. "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3057. "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3058. "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3059. "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
  3060. "!\"\\01?MissProto@@YAXUPayload@@@Z\","
  3061. },
  3062. { "!{void (float*, %struct.Attributes*)* @\"\\01?BadAnyHit@@YAXAIAMUAttributes@@@Z\", "
  3063. "!\"\\01?BadAnyHit@@YAXAIAMUAttributes@@@Z\",",
  3064. "!{void (float*, %struct.Attributes*)* @\"\\01?BadClosestHit@@YAXAIAMUAttributes@@@Z\", "
  3065. "!\"\\01?BadClosestHit@@YAXAIAMUAttributes@@@Z\",",
  3066. "!{void (float*)* @\"\\01?BadMiss@@YAXAIAM@Z\", "
  3067. "!\"\\01?BadMiss@@YAXAIAM@Z\","
  3068. },
  3069. { "Argument 'f' must be a struct type for payload in shader function '\\01?BadAnyHit@@YAXAIAMUAttributes@@@Z'"
  3070. ,"Argument 'f' must be a struct type for payload in shader function '\\01?BadClosestHit@@YAXAIAMUAttributes@@@Z'"
  3071. ,"Argument 'f' must be a struct type for payload in shader function '\\01?BadMiss@@YAXAIAM@Z'"
  3072. },
  3073. false);
  3074. }
  3075. TEST_F(ValidationTest, RayAttrIsStruct) {
  3076. if (m_ver.SkipDxilVersion(1, 3)) return;
  3077. RewriteAssemblyCheckMsg(
  3078. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3079. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3080. "export void BadAnyHit(inout Payload p, in float a) { p.f += a; }\n"
  3081. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3082. "export void BadClosestHit(inout Payload p, in float a) { p.f += a; }\n"
  3083. , "lib_6_3",
  3084. { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3085. "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3086. "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3087. "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\","
  3088. },
  3089. { "!{void (%struct.Payload*, float)* @\"\\01?BadAnyHit@@YAXUPayload@@M@Z\", "
  3090. "!\"\\01?BadAnyHit@@YAXUPayload@@M@Z\",",
  3091. "!{void (%struct.Payload*, float)* @\"\\01?BadClosestHit@@YAXUPayload@@M@Z\", "
  3092. "!\"\\01?BadClosestHit@@YAXUPayload@@M@Z\","
  3093. },
  3094. { "Argument 'a' must be a struct type for attributes in shader function '\\01?BadAnyHit@@YAXUPayload@@M@Z'"
  3095. ,"Argument 'a' must be a struct type for attributes in shader function '\\01?BadClosestHit@@YAXUPayload@@M@Z'"
  3096. },
  3097. false);
  3098. }
  3099. TEST_F(ValidationTest, CallableParamIsStruct) {
  3100. if (m_ver.SkipDxilVersion(1, 3)) return;
  3101. RewriteAssemblyCheckMsg(
  3102. "struct Param { float f; };\n"
  3103. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  3104. "export void BadCallable(inout float f) { f += 1.0; }\n"
  3105. , "lib_6_3",
  3106. { "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
  3107. "!\"\\01?CallableProto@@YAXUParam@@@Z\","
  3108. },
  3109. { "!{void (float*)* @\"\\01?BadCallable@@YAXAIAM@Z\", "
  3110. "!\"\\01?BadCallable@@YAXAIAM@Z\","
  3111. },
  3112. { "Argument 'f' must be a struct type for callable shader function '\\01?BadCallable@@YAXAIAM@Z'"
  3113. },
  3114. false);
  3115. }
  3116. TEST_F(ValidationTest, RayShaderExtraArg) {
  3117. if (m_ver.SkipDxilVersion(1, 3)) return;
  3118. RewriteAssemblyCheckMsg(
  3119. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3120. "struct Param { float f; };\n"
  3121. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3122. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3123. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  3124. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  3125. "export void BadAnyHit(inout Payload p, in Attributes a, float f) { p.f += f; }\n"
  3126. "export void BadClosestHit(inout Payload p, in Attributes a, float f) { p.f += f; }\n"
  3127. "export void BadMiss(inout Payload p, float f) { p.f += f; }\n"
  3128. "export void BadCallable(inout Param p, float f) { p.f += f; }\n"
  3129. , "lib_6_3",
  3130. { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3131. "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\"",
  3132. "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3133. "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\"",
  3134. "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
  3135. "!\"\\01?MissProto@@YAXUPayload@@@Z\"",
  3136. "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
  3137. "!\"\\01?CallableProto@@YAXUParam@@@Z\""
  3138. },
  3139. { "!{void (%struct.Payload*, %struct.Attributes*, float)* @\"\\01?BadAnyHit@@YAXUPayload@@UAttributes@@M@Z\", "
  3140. "!\"\\01?BadAnyHit@@YAXUPayload@@UAttributes@@M@Z\"",
  3141. "!{void (%struct.Payload*, %struct.Attributes*, float)* @\"\\01?BadClosestHit@@YAXUPayload@@UAttributes@@M@Z\", "
  3142. "!\"\\01?BadClosestHit@@YAXUPayload@@UAttributes@@M@Z\"",
  3143. "!{void (%struct.Payload*, float)* @\"\\01?BadMiss@@YAXUPayload@@M@Z\", "
  3144. "!\"\\01?BadMiss@@YAXUPayload@@M@Z\"",
  3145. "!{void (%struct.Param*, float)* @\"\\01?BadCallable@@YAXUParam@@M@Z\", "
  3146. "!\"\\01?BadCallable@@YAXUParam@@M@Z\""
  3147. },
  3148. { "Extra argument 'f' not allowed for shader function '\\01?BadAnyHit@@YAXUPayload@@UAttributes@@M@Z'"
  3149. ,"Extra argument 'f' not allowed for shader function '\\01?BadClosestHit@@YAXUPayload@@UAttributes@@M@Z'"
  3150. ,"Extra argument 'f' not allowed for shader function '\\01?BadMiss@@YAXUPayload@@M@Z'"
  3151. ,"Extra argument 'f' not allowed for shader function '\\01?BadCallable@@YAXUParam@@M@Z'"
  3152. },
  3153. false);
  3154. }
  3155. TEST_F(ValidationTest, ResInShaderStruct) {
  3156. if (m_ver.SkipDxilVersion(1, 3)) return;
  3157. // Verify resource not used in shader argument structure
  3158. RewriteAssemblyCheckMsg(
  3159. "struct ResInStruct { float f; Texture2D<float4> T; };\n"
  3160. "struct ResStructInStruct { float f; ResInStruct S; };\n"
  3161. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3162. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3163. "export void BadAnyHit(inout ResStructInStruct p, in Attributes a) { p.f += a.b.x; }\n"
  3164. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3165. "export void BadClosestHit(inout ResStructInStruct p, in Attributes a) { p.f += a.b.x; }\n"
  3166. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  3167. "export void BadMiss(inout ResStructInStruct p) { p.f += 1.0; }\n"
  3168. "struct Param { float f; };\n"
  3169. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  3170. "export void BadCallable(inout ResStructInStruct p) { p.f += 1.0; }\n"
  3171. , "lib_6_x",
  3172. { "!{!\"lib\", i32 6, i32 15}", "!dx.valver = !{!([0-9]+)}", "= !{i32 20, !([0-9]+), !([0-9]+), !([0-9]+)}",
  3173. "!{void \\(%struct\\.Payload\\*, %struct\\.Attributes\\*\\)\\* @\"\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3174. "!\"\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3175. "!{void \\(%struct\\.Payload\\*, %struct\\.Attributes\\*\\)\\* @\"\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3176. "!\"\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3177. "!{void \\(%struct\\.Payload\\*\\)\\* @\"\\\\01\\?MissProto@@YAXUPayload@@@Z\", "
  3178. "!\"\\\\01\\?MissProto@@YAXUPayload@@@Z\",",
  3179. "!{void \\(%struct\\.Param\\*\\)\\* @\"\\\\01\\?CallableProto@@YAXUParam@@@Z\", "
  3180. "!\"\\\\01\\?CallableProto@@YAXUParam@@@Z\","
  3181. },
  3182. { "!{!\"lib\", i32 6, i32 3}", "!dx.valver = !{!100\\1}\n!1002 = !{i32 1, i32 3}", "= !{i32 20, !\\1, !\\2}",
  3183. "!{void (%struct.ResStructInStruct*, %struct.Attributes*)* @\"\\\\01?BadAnyHit@@YAXUResStructInStruct@@UAttributes@@@Z\", "
  3184. "!\"\\\\01?BadAnyHit@@YAXUResStructInStruct@@UAttributes@@@Z\",",
  3185. "!{void (%struct.ResStructInStruct*, %struct.Attributes*)* @\"\\\\01?BadClosestHit@@YAXUResStructInStruct@@UAttributes@@@Z\", "
  3186. "!\"\\\\01?BadClosestHit@@YAXUResStructInStruct@@UAttributes@@@Z\",",
  3187. "!{void (%struct.ResStructInStruct*)* @\"\\\\01?BadMiss@@YAXUResStructInStruct@@@Z\", "
  3188. "!\"\\\\01?BadMiss@@YAXUResStructInStruct@@@Z\",",
  3189. "!{void (%struct.ResStructInStruct*)* @\"\\\\01?BadCallable@@YAXUResStructInStruct@@@Z\", "
  3190. "!\"\\\\01?BadCallable@@YAXUResStructInStruct@@@Z\",",
  3191. },
  3192. { "Function '\\\\01\\?BadAnyHit@@YAXUResStructInStruct@@UAttributes@@@Z' uses resource in function signature"
  3193. ,"Function '\\\\01\\?BadClosestHit@@YAXUResStructInStruct@@UAttributes@@@Z' uses resource in function signature"
  3194. ,"Function '\\\\01\\?BadMiss@@YAXUResStructInStruct@@@Z' uses resource in function signature"
  3195. ,"Function '\\\\01\\?BadCallable@@YAXUResStructInStruct@@@Z' uses resource in function signature"
  3196. },
  3197. /*bRegex*/ true);
  3198. }
  3199. TEST_F(ValidationTest, WhenPayloadSizeTooSmallThenFail) {
  3200. if (m_ver.SkipDxilVersion(1, 3)) return;
  3201. RewriteAssemblyCheckMsg(
  3202. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3203. "struct Param { float f; };\n"
  3204. "[shader(\"raygeneration\")] void RayGenProto() { return; }\n"
  3205. "[shader(\"intersection\")] void IntersectionProto() { return; }\n"
  3206. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3207. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3208. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  3209. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  3210. "\n"
  3211. "struct BadPayload { float2 f; }; struct BadAttributes { float3 b; };\n"
  3212. "struct BadParam { float2 f; };\n"
  3213. "export void BadRayGen() { return; }\n"
  3214. "export void BadIntersection() { return; }\n"
  3215. "export void BadAnyHit(inout BadPayload p, in BadAttributes a) { p.f += a.b.x; }\n"
  3216. "export void BadClosestHit(inout BadPayload p, in BadAttributes a) { p.f += a.b.y; }\n"
  3217. "export void BadMiss(inout BadPayload p) { p.f += 1.0; }\n"
  3218. "export void BadCallable(inout BadParam p) { p.f += 1.0; }\n"
  3219. , "lib_6_3",
  3220. { "!{void ()* @\"\\01?RayGenProto@@YAXXZ\", !\"\\01?RayGenProto@@YAXXZ\","
  3221. ,"!{void ()* @\"\\01?IntersectionProto@@YAXXZ\", !\"\\01?IntersectionProto@@YAXXZ\","
  3222. ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\","
  3223. ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\","
  3224. ,"!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", !\"\\01?MissProto@@YAXUPayload@@@Z\","
  3225. ,"!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", !\"\\01?CallableProto@@YAXUParam@@@Z\","
  3226. },
  3227. { "!{void ()* @\"\\01?BadRayGen@@YAXXZ\", !\"\\01?BadRayGen@@YAXXZ\","
  3228. ,"!{void ()* @\"\\01?BadIntersection@@YAXXZ\", !\"\\01?BadIntersection@@YAXXZ\","
  3229. ,"!{void (%struct.BadPayload*, %struct.BadAttributes*)* @\"\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z\", !\"\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z\","
  3230. ,"!{void (%struct.BadPayload*, %struct.BadAttributes*)* @\"\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z\", !\"\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z\","
  3231. ,"!{void (%struct.BadPayload*)* @\"\\01?BadMiss@@YAXUBadPayload@@@Z\", !\"\\01?BadMiss@@YAXUBadPayload@@@Z\","
  3232. ,"!{void (%struct.BadParam*)* @\"\\01?BadCallable@@YAXUBadParam@@@Z\", !\"\\01?BadCallable@@YAXUBadParam@@@Z\","
  3233. },
  3234. { "For shader '\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z', payload size is smaller than argument's allocation size"
  3235. ,"For shader '\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z', attribute size is smaller than argument's allocation size"
  3236. ,"For shader '\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z', payload size is smaller than argument's allocation size"
  3237. ,"For shader '\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z', attribute size is smaller than argument's allocation size"
  3238. ,"For shader '\\01?BadMiss@@YAXUBadPayload@@@Z', payload size is smaller than argument's allocation size"
  3239. ,"For shader '\\01?BadCallable@@YAXUBadParam@@@Z', params size is smaller than argument's allocation size"
  3240. },
  3241. false);
  3242. }
  3243. TEST_F(ValidationTest, WhenMissingPayloadThenFail) {
  3244. if (m_ver.SkipDxilVersion(1, 3)) return;
  3245. RewriteAssemblyCheckMsg(
  3246. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3247. "struct Param { float f; };\n"
  3248. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3249. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3250. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  3251. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  3252. "export void BadAnyHit(inout Payload p) { p.f += 1.0; }\n"
  3253. "export void BadClosestHit() {}\n"
  3254. "export void BadMiss() {}\n"
  3255. "export void BadCallable() {}\n"
  3256. , "lib_6_3",
  3257. { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\","
  3258. ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\","
  3259. ,"!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", !\"\\01?MissProto@@YAXUPayload@@@Z\","
  3260. ,"!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", !\"\\01?CallableProto@@YAXUParam@@@Z\","
  3261. },
  3262. { "!{void (%struct.Payload*)* @\"\\01?BadAnyHit@@YAXUPayload@@@Z\", !\"\\01?BadAnyHit@@YAXUPayload@@@Z\","
  3263. ,"!{void ()* @\"\\01?BadClosestHit@@YAXXZ\", !\"\\01?BadClosestHit@@YAXXZ\","
  3264. ,"!{void ()* @\"\\01?BadMiss@@YAXXZ\", !\"\\01?BadMiss@@YAXXZ\","
  3265. ,"!{void ()* @\"\\01?BadCallable@@YAXXZ\", !\"\\01?BadCallable@@YAXXZ\","
  3266. },
  3267. { "anyhit shader '\\01?BadAnyHit@@YAXUPayload@@@Z' missing required attributes parameter"
  3268. ,"closesthit shader '\\01?BadClosestHit@@YAXXZ' missing required payload parameter"
  3269. ,"closesthit shader '\\01?BadClosestHit@@YAXXZ' missing required attributes parameter"
  3270. ,"miss shader '\\01?BadMiss@@YAXXZ' missing required payload parameter"
  3271. ,"callable shader '\\01?BadCallable@@YAXXZ' missing required params parameter"
  3272. },
  3273. false);
  3274. }
  3275. TEST_F(ValidationTest, ShaderFunctionReturnTypeVoid) {
  3276. if (m_ver.SkipDxilVersion(1, 3)) return;
  3277. // Verify resource not used in shader argument structure
  3278. RewriteAssemblyCheckMsg(
  3279. "struct Payload { float f; }; struct Attributes { float2 b; };\n"
  3280. "struct Param { float f; };\n"
  3281. "[shader(\"raygeneration\")] void RayGenProto() { return; }\n"
  3282. "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
  3283. "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
  3284. "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
  3285. "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
  3286. "export float BadRayGen() { return 1; }\n"
  3287. "export float BadAnyHit(inout Payload p, in Attributes a) { return p.f; }\n"
  3288. "export float BadClosestHit(inout Payload p, in Attributes a) { return p.f; }\n"
  3289. "export float BadMiss(inout Payload p) { return p.f; }\n"
  3290. "export float BadCallable(inout Param p) { return p.f; }\n"
  3291. , "lib_6_3",
  3292. { "!{void ()* @\"\\01?RayGenProto@@YAXXZ\", "
  3293. "!\"\\01?RayGenProto@@YAXXZ\",",
  3294. "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3295. "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3296. "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
  3297. "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\",",
  3298. "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
  3299. "!\"\\01?MissProto@@YAXUPayload@@@Z\",",
  3300. "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
  3301. "!\"\\01?CallableProto@@YAXUParam@@@Z\","
  3302. },
  3303. { "!{float ()* @\"\\01?BadRayGen@@YAMXZ\", "
  3304. "!\"\\01?BadRayGen@@YAMXZ\",",
  3305. "!{float (%struct.Payload*, %struct.Attributes*)* @\"\\01?BadAnyHit@@YAMUPayload@@UAttributes@@@Z\", "
  3306. "!\"\\01?BadAnyHit@@YAMUPayload@@UAttributes@@@Z\",",
  3307. "!{float (%struct.Payload*, %struct.Attributes*)* @\"\\01?BadClosestHit@@YAMUPayload@@UAttributes@@@Z\", "
  3308. "!\"\\01?BadClosestHit@@YAMUPayload@@UAttributes@@@Z\",",
  3309. "!{float (%struct.Payload*)* @\"\\01?BadMiss@@YAMUPayload@@@Z\", "
  3310. "!\"\\01?BadMiss@@YAMUPayload@@@Z\",",
  3311. "!{float (%struct.Param*)* @\"\\01?BadCallable@@YAMUParam@@@Z\", "
  3312. "!\"\\01?BadCallable@@YAMUParam@@@Z\","
  3313. },
  3314. { "Shader function '\\01?BadRayGen@@YAMXZ' must have void return type"
  3315. ,"Shader function '\\01?BadAnyHit@@YAMUPayload@@UAttributes@@@Z' must have void return type"
  3316. ,"Shader function '\\01?BadClosestHit@@YAMUPayload@@UAttributes@@@Z' must have void return type"
  3317. ,"Shader function '\\01?BadMiss@@YAMUPayload@@@Z' must have void return type"
  3318. ,"Shader function '\\01?BadCallable@@YAMUParam@@@Z' must have void return type"
  3319. },
  3320. false);
  3321. }
  3322. TEST_F(ValidationTest, MeshMultipleSetMeshOutputCounts) {
  3323. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\multipleSetMeshOutputCounts.hlsl");
  3324. }
  3325. TEST_F(ValidationTest, MeshMissingSetMeshOutputCounts) {
  3326. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\missingSetMeshOutputCounts.hlsl");
  3327. }
  3328. TEST_F(ValidationTest, MeshNonDominatingSetMeshOutputCounts) {
  3329. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\nonDominatingSetMeshOutputCounts.hlsl");
  3330. }
  3331. TEST_F(ValidationTest, MeshOversizePayload) {
  3332. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\msOversizePayload.hlsl");
  3333. }
  3334. TEST_F(ValidationTest, MeshOversizeOutput) {
  3335. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\msOversizeOutput.hlsl");
  3336. }
  3337. TEST_F(ValidationTest, MeshOversizePayloadOutput) {
  3338. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\msOversizePayloadOutput.hlsl");
  3339. }
  3340. TEST_F(ValidationTest, MeshMultipleGetMeshPayload) {
  3341. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3342. "%([0-9]+) = call %struct.MeshPayload\\* @dx.op.getMeshPayload.struct.MeshPayload\\(i32 170\\) ; GetMeshPayload\\(\\)",
  3343. "%\\1 = call %struct.MeshPayload* @dx.op.getMeshPayload.struct.MeshPayload(i32 170) ; GetMeshPayload()\n"
  3344. " %.extra.unused.payload. = call %struct.MeshPayload* @dx.op.getMeshPayload.struct.MeshPayload(i32 170) ; GetMeshPayload()",
  3345. "GetMeshPayload cannot be called multiple times.",
  3346. true);
  3347. }
  3348. TEST_F(ValidationTest, MeshOutofRangeMaxVertexCount) {
  3349. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3350. "= !{!([0-9]+), i32 32, i32 16, i32 2, i32 40}",
  3351. "= !{!\\1, i32 257, i32 16, i32 2, i32 40}",
  3352. "MS max vertex output count must be \\[0..256\\]. 257 specified",
  3353. true);
  3354. }
  3355. TEST_F(ValidationTest, MeshOutofRangeMaxPrimitiveCount) {
  3356. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3357. "= !{!([0-9]+), i32 32, i32 16, i32 2, i32 40}",
  3358. "= !{!\\1, i32 32, i32 257, i32 2, i32 40}",
  3359. "MS max primitive output count must be \\[0..256\\]. 257 specified",
  3360. true);
  3361. }
  3362. TEST_F(ValidationTest, MeshLessThanMinX) {
  3363. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3364. "= !{i32 32, i32 1, i32 1}",
  3365. "= !{i32 0, i32 1, i32 1}",
  3366. "Declared Thread Group X size 0 outside valid range [1..128]");
  3367. }
  3368. TEST_F(ValidationTest, MeshGreaterThanMaxX) {
  3369. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3370. "= !{i32 32, i32 1, i32 1}",
  3371. "= !{i32 129, i32 1, i32 1}",
  3372. "Declared Thread Group X size 129 outside valid range [1..128]");
  3373. }
  3374. TEST_F(ValidationTest, MeshLessThanMinY) {
  3375. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3376. "= !{i32 32, i32 1, i32 1}",
  3377. "= !{i32 32, i32 0, i32 1}",
  3378. "Declared Thread Group Y size 0 outside valid range [1..128]");
  3379. }
  3380. TEST_F(ValidationTest, MeshGreaterThanMaxY) {
  3381. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3382. "= !{i32 32, i32 1, i32 1}",
  3383. "= !{i32 1, i32 129, i32 1}",
  3384. "Declared Thread Group Y size 129 outside valid range [1..128]");
  3385. }
  3386. TEST_F(ValidationTest, MeshLessThanMinZ) {
  3387. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3388. "= !{i32 32, i32 1, i32 1}",
  3389. "= !{i32 32, i32 1, i32 0}",
  3390. "Declared Thread Group Z size 0 outside valid range [1..128]");
  3391. }
  3392. TEST_F(ValidationTest, MeshGreaterThanMaxZ) {
  3393. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3394. "= !{i32 32, i32 1, i32 1}",
  3395. "= !{i32 1, i32 1, i32 129}",
  3396. "Declared Thread Group Z size 129 outside valid range [1..128]");
  3397. }
  3398. TEST_F(ValidationTest, MeshGreaterThanMaxXYZ) {
  3399. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3400. "= !{i32 32, i32 1, i32 1}",
  3401. "= !{i32 32, i32 2, i32 4}",
  3402. "Declared Thread Group Count 256 (X*Y*Z) is beyond the valid maximum of 128");
  3403. }
  3404. TEST_F(ValidationTest, MeshGreaterThanMaxVSigRowCount) {
  3405. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3406. "!([0-9]+) = !{i32 1, !\"COLOR\", i8 9, i8 0, !([0-9]+), i8 2, i32 4, i8 1, i32 1, i8 0, (.*)"
  3407. "!\\2 = !{i32 0, i32 1, i32 2, i32 3}",
  3408. "!\\1 = !{i32 1, !\"COLOR\", i8 9, i8 0, !\\2, i8 2, i32 32, i8 1, i32 1, i8 0, \\3"
  3409. "!\\2 = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10,"
  3410. "i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20,"
  3411. "i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31}",
  3412. "For shader 'main', vertex output signatures are taking up more than 32 rows",
  3413. true);
  3414. }
  3415. TEST_F(ValidationTest, MeshGreaterThanMaxPSigRowCount) {
  3416. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3417. "!([0-9]+) = !{i32 4, !\"LAYER\", i8 4, i8 0, !([0-9]+), i8 1, i32 6, i8 1, i32 1, i8 0, (.*)"
  3418. "!\\2 = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5}",
  3419. "!\\1 = !{i32 4, !\"LAYER\", i8 4, i8 0, !\\2, i8 1, i32 32, i8 1, i32 1, i8 0, \\3"
  3420. "!\\2 = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10,"
  3421. "i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20,"
  3422. "i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31}",
  3423. "For shader 'main', primitive output signatures are taking up more than 32 rows",
  3424. true);
  3425. }
  3426. TEST_F(ValidationTest, MeshGreaterThanMaxTotalSigRowCount) {
  3427. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\mesh.hlsl", "ms_6_5",
  3428. { "!([0-9]+) = !{i32 1, !\"COLOR\", i8 9, i8 0, !([0-9]+), i8 2, i32 4, i8 1, i32 1, i8 0, (.*)"
  3429. "!\\2 = !{i32 0, i32 1, i32 2, i32 3}",
  3430. "!([0-9]+) = !{i32 4, !\"LAYER\", i8 4, i8 0, !([0-9]+), i8 1, i32 6, i8 1, i32 1, i8 0, (.*)"
  3431. "!\\2 = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5}" },
  3432. { "!\\1 = !{i32 1, !\"COLOR\", i8 9, i8 0, !\\2, i8 2, i32 16, i8 1, i32 1, i8 0, \\3"
  3433. "!\\2 = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10,"
  3434. "i32 11, i32 12, i32 13, i32 14, i32 15}",
  3435. "!\\1 = !{i32 4, !\"LAYER\", i8 4, i8 0, !\\2, i8 1, i32 16, i8 1, i32 1, i8 0, \\3"
  3436. "!\\2 = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10,"
  3437. "i32 11, i32 12, i32 13, i32 14, i32 15}",
  3438. },
  3439. "For shader 'main', vertex and primitive output signatures are taking up more than 32 rows",
  3440. true);
  3441. }
  3442. TEST_F(ValidationTest, MeshOversizeSM) {
  3443. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\oversizeSM.hlsl");
  3444. }
  3445. TEST_F(ValidationTest, AmplificationMultipleDispatchMesh) {
  3446. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\multipleDispatchMesh.hlsl");
  3447. }
  3448. TEST_F(ValidationTest, AmplificationMissingDispatchMesh) {
  3449. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\missingDispatchMesh.hlsl");
  3450. }
  3451. TEST_F(ValidationTest, AmplificationNonDominatingDispatchMesh) {
  3452. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\nonDominatingDispatchMesh.hlsl");
  3453. }
  3454. TEST_F(ValidationTest, AmplificationOversizePayload) {
  3455. TestCheck(L"..\\CodeGenHLSL\\mesh-val\\asOversizePayload.hlsl");
  3456. }
  3457. TEST_F(ValidationTest, AmplificationLessThanMinX) {
  3458. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3459. "= !{i32 32, i32 1, i32 1}",
  3460. "= !{i32 0, i32 1, i32 1}",
  3461. "Declared Thread Group X size 0 outside valid range [1..128]");
  3462. }
  3463. TEST_F(ValidationTest, AmplificationGreaterThanMaxX) {
  3464. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3465. "= !{i32 32, i32 1, i32 1}",
  3466. "= !{i32 129, i32 1, i32 1}",
  3467. "Declared Thread Group X size 129 outside valid range [1..128]");
  3468. }
  3469. TEST_F(ValidationTest, AmplificationLessThanMinY) {
  3470. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3471. "= !{i32 32, i32 1, i32 1}",
  3472. "= !{i32 32, i32 0, i32 1}",
  3473. "Declared Thread Group Y size 0 outside valid range [1..128]");
  3474. }
  3475. TEST_F(ValidationTest, AmplificationGreaterThanMaxY) {
  3476. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3477. "= !{i32 32, i32 1, i32 1}",
  3478. "= !{i32 1, i32 129, i32 1}",
  3479. "Declared Thread Group Y size 129 outside valid range [1..128]");
  3480. }
  3481. TEST_F(ValidationTest, AmplificationLessThanMinZ) {
  3482. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3483. "= !{i32 32, i32 1, i32 1}",
  3484. "= !{i32 32, i32 1, i32 0}",
  3485. "Declared Thread Group Z size 0 outside valid range [1..128]");
  3486. }
  3487. TEST_F(ValidationTest, AmplificationGreaterThanMaxZ) {
  3488. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3489. "= !{i32 32, i32 1, i32 1}",
  3490. "= !{i32 1, i32 1, i32 129}",
  3491. "Declared Thread Group Z size 129 outside valid range [1..128]");
  3492. }
  3493. TEST_F(ValidationTest, AmplificationGreaterThanMaxXYZ) {
  3494. RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\mesh-val\\amplification.hlsl", "as_6_5",
  3495. "= !{i32 32, i32 1, i32 1}",
  3496. "= !{i32 32, i32 2, i32 4}",
  3497. "Declared Thread Group Count 256 (X*Y*Z) is beyond the valid maximum of 128");
  3498. }