12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173 |
- # Copyright (C) Microsoft Corporation. All rights reserved.
- # This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
- ###############################################################################
- # DXIL information. #
- ###############################################################################
- import os
- all_stages = (
- 'vertex',
- 'pixel',
- 'geometry',
- 'compute',
- 'hull',
- 'domain',
- 'library',
- 'raygeneration',
- 'intersection',
- 'anyhit',
- 'closesthit',
- 'miss',
- 'callable',
- 'mesh',
- 'amplification',
- )
- # These counters aren't collected directly from instructions,
- # so they need to be added manually so they can be accessed
- # with custom code in DxilCounters.cpp.
- extra_counters = [
- 'insts',
- 'branches',
- 'array_tgsm_bytes',
- 'array_static_bytes',
- 'array_local_bytes',
- 'array_tgsm_ldst',
- 'array_static_ldst',
- 'array_local_ldst',
- ]
- class db_dxil_enum_value(object):
- "A representation for a value in an enumeration type"
- def __init__(self, name, value, doc):
- self.name = name # Name (identifier)
- self.value = value # Numeric value
- self.doc = doc # Documentation string
- self.category = None
- class db_dxil_enum(object):
- "A representation for an enumeration type"
- def __init__(self, name, doc, valNameDocTuples=()):
- self.name = name
- self.doc = doc
- self.values = [db_dxil_enum_value(n,v,d) for v,n,d in valNameDocTuples] # Note transmutation
- self.is_internal = False # whether this is never serialized
- def value_names(self):
- return [i.name for i in self.values]
- class db_dxil_inst(object):
- "A representation for a DXIL instruction"
- def __init__(self, name, **kwargs):
- self.name = name # short, unique name
- self.llvm_id = 0 # ID of LLVM instruction
- self.llvm_name = "" # name of LLVM instruction type
- self.is_bb_terminator = False # whether this is a basic block terminator
- self.is_binary = False # whether this is an arithmetic binary/logical operator
- self.is_memory = False # whether this is a memory manipulator operator
- self.is_cast = False # whether this is a casting operator
- self.is_dxil_op = False # whether this is a call into a built-in DXIL function
- self.dxil_op = "" # name of DXIL operation
- self.dxil_opid = 0 # ID of DXIL operation
- self.dxil_class = "" # name of the opcode class
- self.category = "" # classification for this instruction
- self.doc = "" # the documentation description of this instruction
- self.remarks = "" # long-form remarks on this instruction
- self.ops = [] # the operands that this instruction takes
- self.is_allowed = True # whether this instruction is allowed in a DXIL program
- self.oload_types = "" # overload types if applicable
- self.fn_attr = "" # attribute shorthands: rn=does not access memory,ro=only reads from memory,
- self.is_deriv = False # whether this is some kind of derivative
- self.is_gradient = False # whether this requires a gradient calculation
- self.is_feedback = False # whether this is a sampler feedback op
- self.is_wave = False # whether this requires in-wave, cross-lane functionality
- self.requires_uniform_inputs = False # whether this operation requires that all of its inputs are uniform across the wave
- self.shader_stages = () # shader stages to which this applies, empty for all.
- self.shader_model = 6,0 # minimum shader model required
- self.inst_helper_prefix = None
- self.fully_qualified_name_prefix = "hlsl::OP::OpCode"
- for k,v in list(kwargs.items()):
- setattr(self, k, v)
- self.is_dxil_op = self.dxil_op != "" # whether this is a DXIL operation
- self.is_reserved = self.dxil_class == "Reserved"
- self.shader_model_translated = () # minimum shader model required with translation by linker
- self.props = {} # extra properties
- def __str__(self):
- return self.name
-
- def fully_qualified_name(self):
- return "{}::{}".format(self.fully_qualified_name_prefix, self.name)
- class db_dxil_metadata(object):
- "A representation for a metadata record"
- def __init__(self, name, doc, **kwargs):
- self.name = name # named metadata, possibly empty
- self.doc = doc # the documentation description of this record
- for k,v in list(kwargs.items()):
- setattr(self, k, v)
- class db_dxil_param(object):
- "The parameter description for a DXIL instruction"
- def __init__(self, pos, llvm_type, name, doc, **kwargs):
- self.pos = pos # position in parameter list
- self.llvm_type = llvm_type # llvm type name, $o for overload, $r for resource type, $cb for legacy cbuffer, $u4 for u4 struct
- self.name = name # short, unique name
- self.doc = doc # the documentation description of this parameter
- self.is_const = False # whether this argument requires a constant value in the IR
- self.enum_name = "" # the name of the enum type if applicable
- self.max_value = None # the maximum value for this parameter if applicable
- for k,v in kwargs.items():
- setattr(self, k, v)
- class db_dxil_pass(object):
- "The description for a DXIL optimization pass"
- def __init__(self, name, **kwargs):
- self.name = name # name for the option, typically the command-line switch name
- self.args = [] # modifiers for the option
- self.type_name = "" # name of the class that implements the pass
- self.doc = "" # documentation for the pass
- self.category_lib = "" # lib which pass belongs to
- for k,v in kwargs.items():
- setattr(self, k, v)
- class db_dxil_pass_arg(object):
- "An argument to a DXIL optimization pass"
- def __init__(self, name, **kwargs):
- self.name = name # name for the option, typically the command-line switch name
- self.ident = "" # identifier for a parameter or global switch
- self.is_ctor_param = False # whether this is a constructor parameter
- for k,v in kwargs.items():
- setattr(self, k, v)
- if self.is_ctor_param:
- self.is_ctor_param = True
- class db_dxil_valrule(object):
- "The description of a validation rule."
- def __init__(self, name, id, **kwargs):
- self.name = name.upper() # short, unique name, eg META.KNOWN
- self.rule_id = id # unique identifier
- self.enum_name = name.replace(".", "") # remove period for enum name
- self.group_name = self.name[:self.name.index(".")] # group name, eg META
- self.rule_name = self.name[self.name.index(".")+1:] # rule name, eg KNOWN
- self.definition = "Check" + self.group_name + self.rule_name # function name that defines this constraint
- self.is_disabled = False # True if the validation rule does not apply
- self.err_msg = "" # error message associated with rule
- self.category = "" # classification for this rule
- self.doc = "" # the documentation description of this rule
- self.shader_stages = () # shader stages to which this applies, empty for all.
- self.shader_model = 6,0 # minimum shader model required
- for k,v in list(kwargs.items()):
- setattr(self, k, v)
- def __str__(self):
- return self.name
- class db_dxil(object):
- "A database of DXIL instruction data"
- def __init__(self):
- self.instr = [] # DXIL instructions
- self.enums = [] # enumeration types
- self.val_rules = [] # validation rules
- self.metadata = [] # named metadata (db_dxil_metadata)
- self.passes = [] # inventory of available passes (db_dxil_pass)
- self.name_idx = {} # DXIL instructions by name
- self.enum_idx = {} # enumerations by name
- self.dxil_version_info = {}
- # list of counters for instructions and dxil ops,
- # starting with extra ones specified here
- self.counters = extra_counters
- self.populate_llvm_instructions()
- self.call_instr = self.get_instr_by_llvm_name("CallInst")
- self.populate_dxil_operations()
- self.build_indices()
- self.populate_extended_docs()
- self.populate_categories_and_models()
- self.build_opcode_enum()
- self.mark_disallowed_operations()
- self.populate_metadata()
- self.populate_passes()
- self.build_valrules()
- self.build_semantics()
- self.build_indices()
- self.populate_counters()
- def __str__(self):
- return '\n'.join(str(i) for i in self.instr)
- def add_enum_type(self, name, doc, valNameDocTuples):
- "Adds a new enumeration type with name/value/doc tuples"
- self.enums.append(db_dxil_enum(name, doc, valNameDocTuples))
- def build_indices(self):
- "Build a name_idx dictionary with instructions and an enum_idx dictionary with enumeration types"
- self.name_idx = {}
- for i in self.instr:
- self.name_idx[i.name] = i
- self.enum_idx = {}
- for i in self.enums:
- self.enum_idx[i.name] = i
- def build_opcode_enum(self):
- # Build enumeration from instructions
- OpCodeEnum = db_dxil_enum("OpCode", "Enumeration for operations specified by DXIL")
- class_dict = {}
- class_dict["LlvmInst"] = "LLVM Instructions"
- for i in self.instr:
- if i.is_dxil_op:
- v = db_dxil_enum_value(i.dxil_op, i.dxil_opid, i.doc)
- v.category = i.category
- class_dict[i.dxil_class] = i.category
- OpCodeEnum.values.append(v)
- self.enums.append(OpCodeEnum);
- OpCodeClass = db_dxil_enum("OpCodeClass", "Groups for DXIL operations with equivalent function templates")
- OpCodeClass.is_internal = True
- for (k, v) in iter(class_dict.items()):
- ev = db_dxil_enum_value(k, 0, None)
- ev.category = v
- OpCodeClass.values.append(ev)
- self.enums.append(OpCodeClass);
- def mark_disallowed_operations(self):
- # Disallow indirect branching, unreachable instructions and support for exception unwinding.
- for i in "IndirectBr,Invoke,Resume,LandingPad,Unreachable".split(","):
- self.name_idx[i].is_allowed = False
- for i in "UserOp1,UserOp2,VAArg".split(","):
- self.name_idx[i].is_allowed = False
- # Disallow conversions used for pointer math; GEP is used exclusively in the current model.
- for i in "PtrToInt,IntToPtr".split(","):
- self.name_idx[i].is_allowed = False
- # Barrier supersedes Fence.
- self.name_idx["Fence"].is_allowed = False
- def verify_dense(self, it, pred, name_proj):
- val = None
- for i in it:
- i_val = pred(i)
- if not val is None:
- assert val + 1 == i_val, "values in predicate are not sequential and dense, %d follows %d for %s" % (i_val, val, name_proj(i))
- val = i_val
- def set_op_count_for_version(self, major, minor, op_count):
- info = self.dxil_version_info.setdefault((major, minor), dict())
- info['NumOpCodes'] = op_count
- info['NumOpClasses'] = len(set([op.dxil_class for op in self.instr]))
- def populate_categories_and_models(self):
- "Populate the category and shader_stages member of instructions."
- for i in "TempRegLoad,TempRegStore,MinPrecXRegLoad,MinPrecXRegStore,LoadInput,StoreOutput".split(","):
- self.name_idx[i].category = "Temporary, indexable, input, output registers"
- for i in "FAbs,Saturate,IsNaN,IsInf,IsFinite,IsNormal,Cos,Sin,Tan,Acos,Asin,Atan,Hcos,Hsin,Htan,Exp,Frc,Log,Sqrt,Rsqrt".split(","):
- self.name_idx[i].category = "Unary float"
- for i in "Round_ne,Round_ni,Round_pi,Round_z".split(","):
- self.name_idx[i].category = "Unary float - rounding"
- for i in "Bfrev,Countbits,FirstbitLo,FirstbitSHi".split(","):
- self.name_idx[i].category = "Unary int"
- for i in "FirstbitHi".split(","):
- self.name_idx[i].category = "Unary uint"
- for i in "FMax,FMin".split(","):
- self.name_idx[i].category = "Binary float"
- for i in "IMax,IMin,Add,Sub,Mul,SDiv,SRem,And,Or,Xor,AShr,LShr,Shl".split(","):
- self.name_idx[i].category = "Binary int"
- for i in "UMax,UMin,UMul,UDiv,URem".split(","):
- self.name_idx[i].category = "Binary uint"
- for i in "IMul".split(","):
- self.name_idx[i].category = "Binary int with two outputs"
- for i in "UMul,UDiv".split(","): # Rename this UDiv OpCode to UDivMod
- self.name_idx[i].category = "Binary uint with two outputs"
- for i in "UAddc,USubb".split(","):
- self.name_idx[i].category = "Binary uint with carry or borrow"
- for i in "FMad,Fma".split(","):
- self.name_idx[i].category = "Tertiary float"
- for i in "IMad,Msad,Ibfe".split(","):
- self.name_idx[i].category = "Tertiary int"
- for i in "UMad,Ubfe".split(","):
- self.name_idx[i].category = "Tertiary uint"
- for i in "Bfi".split(","):
- self.name_idx[i].category = "Quaternary"
- for i in "Dot2,Dot3,Dot4".split(","):
- self.name_idx[i].category = "Dot"
- for i in "CreateHandle,CBufferLoad,CBufferLoadLegacy,TextureLoad,TextureStore,BufferLoad,BufferStore,BufferUpdateCounter,CheckAccessFullyMapped,GetDimensions,RawBufferLoad,RawBufferStore".split(","):
- self.name_idx[i].category = "Resources"
- for i in "Sample,SampleBias,SampleLevel,SampleGrad,SampleCmp,SampleCmpLevelZero,Texture2DMSGetSamplePosition,RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","):
- self.name_idx[i].category = "Resources - sample"
- for i in "Sample,SampleBias,SampleCmp".split(","):
- self.name_idx[i].shader_stages = ("library", "pixel", "compute", "amplification", "mesh")
- for i in "RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","):
- self.name_idx[i].shader_stages = ("pixel",)
- for i in "TextureGather,TextureGatherCmp".split(","):
- self.name_idx[i].category = "Resources - gather"
- for i in "AtomicBinOp,AtomicCompareExchange,Barrier".split(","):
- self.name_idx[i].category = "Synchronization"
- for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY".split(","):
- self.name_idx[i].category = "Derivatives"
- self.name_idx[i].shader_stages = ("library", "pixel", "compute", "amplification", "mesh")
- for i in "Discard,EvalSnapped,EvalSampleIndex,EvalCentroid,SampleIndex,Coverage,InnerCoverage,AttributeAtVertex".split(","):
- self.name_idx[i].category = "Pixel shader"
- self.name_idx[i].shader_stages = ("pixel",)
- for i in "ThreadId,GroupId,ThreadIdInGroup,FlattenedThreadIdInGroup".split(","):
- self.name_idx[i].category = "Compute/Mesh/Amplification shader"
- self.name_idx[i].shader_stages = ("compute", "mesh", "amplification")
- for i in "EmitStream,CutStream,EmitThenCutStream,GSInstanceID".split(","):
- self.name_idx[i].category = "Geometry shader"
- self.name_idx[i].shader_stages = ("geometry",)
- for i in "LoadOutputControlPoint,LoadPatchConstant".split(","):
- self.name_idx[i].category = "Domain and hull shader"
- self.name_idx[i].shader_stages = ("domain", "hull")
- for i in "DomainLocation".split(","):
- self.name_idx[i].category = "Domain shader"
- self.name_idx[i].shader_stages = ("domain",)
- for i in "StorePatchConstant,OutputControlPointID".split(","):
- self.name_idx[i].category = "Hull shader"
- self.name_idx[i].shader_stages = ("hull",)
- for i in "PrimitiveID".split(","):
- self.name_idx[i].category = "Hull, Domain and Geometry shaders"
- self.name_idx[i].shader_stages = ("geometry", "domain", "hull")
- for i in "ViewID".split(","):
- self.name_idx[i].category = "Graphics shader"
- self.name_idx[i].shader_stages = ("vertex", "hull", "domain", "geometry", "pixel", "mesh")
- for i in "MakeDouble,SplitDouble,LegacyDoubleToFloat,LegacyDoubleToSInt32,LegacyDoubleToUInt32".split(","):
- self.name_idx[i].category = "Double precision"
- for i in "CycleCounterLegacy".split(","):
- self.name_idx[i].category = "Other"
- for i in "LegacyF32ToF16,LegacyF16ToF32".split(","):
- self.name_idx[i].category = "Legacy floating-point"
- for i in self.instr:
- if i.name.startswith("Wave"):
- i.category = "Wave"
- i.is_wave = True
- i.shader_stages = (
- "library", "compute", "amplification", "mesh",
- "pixel", "vertex", "hull", "domain", "geometry",
- "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable")
- elif i.name.startswith("Quad"):
- i.category = "Quad Wave Ops"
- i.is_wave = True
- i.shader_stages = ("library", "compute", "amplification", "mesh", "pixel")
- elif i.name.startswith("Bitcast"):
- i.category = "Bitcasts with different sizes"
- for i in "ViewID,AttributeAtVertex".split(","):
- self.name_idx[i].shader_model = 6,1
- for i in "RawBufferLoad,RawBufferStore".split(","):
- self.name_idx[i].shader_model = 6,2
- self.name_idx[i].shader_model_translated = 6,0
- for i in "DispatchRaysIndex,DispatchRaysDimensions".split(","):
- self.name_idx[i].category = "Ray Dispatch Arguments"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library", "raygeneration","intersection","anyhit", "closesthit","miss","callable")
- for i in "InstanceID,InstanceIndex,PrimitiveIndex".split(","):
- self.name_idx[i].category = "Raytracing object space uint System Values"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit")
- for i in "GeometryIndex".split(","):
- self.name_idx[i].category = "Raytracing object space uint System Values, raytracing tier 1.1"
- self.name_idx[i].shader_model = 6,5
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit")
- for i in "HitKind".split(","):
- self.name_idx[i].category = "Raytracing hit uint System Values"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit",)
- for i in "RayFlags".split(","):
- self.name_idx[i].category = "Raytracing uint System Values"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit","miss")
- for i in "WorldRayOrigin,WorldRayDirection".split(","):
- self.name_idx[i].category = "Ray Vectors"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit","miss")
- for i in "ObjectRayOrigin,ObjectRayDirection".split(","):
- self.name_idx[i].category = "Ray object space Vectors"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit")
- for i in "ObjectToWorld,WorldToObject".split(","):
- self.name_idx[i].category = "Ray Transforms"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit")
- for i in "RayTMin,RayTCurrent".split(","):
- self.name_idx[i].category = "RayT"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit", "miss")
- for i in "IgnoreHit,AcceptHitAndEndSearch".split(","):
- self.name_idx[i].category = "AnyHit Terminals"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("anyhit",)
- for i in "CallShader".split(","):
- self.name_idx[i].category = "Indirect Shader Invocation"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library", "closesthit","raygeneration","miss","callable")
- for i in "TraceRay".split(","):
- self.name_idx[i].category = "Indirect Shader Invocation"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library", "raygeneration","closesthit","miss")
- for i in "ReportHit".split(","):
- self.name_idx[i].category = "Indirect Shader Invocation"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_stages = ("library", "intersection")
- for i in "CreateHandleForLib".split(","):
- self.name_idx[i].category = "Library create handle from resource struct (like HL intrinsic)"
- self.name_idx[i].shader_model = 6,3
- self.name_idx[i].shader_model_translated = 6,0
- for i in "AnnotateHandle,CreateHandleFromBinding,CreateHandleFromHeap".split(","):
- self.name_idx[i].category = "Get handle from heap"
- self.name_idx[i].shader_model = 6,6
- for i in "Dot4AddU8Packed,Dot4AddI8Packed,Dot2AddHalf".split(","):
- self.name_idx[i].category = "Dot product with accumulate"
- self.name_idx[i].shader_model = 6,4
- for i in "WaveMatch,WaveMultiPrefixOp,WaveMultiPrefixBitCount".split(","):
- self.name_idx[i].category = "Wave"
- self.name_idx[i].shader_model = 6,5
- for i in "SetMeshOutputCounts,EmitIndices,GetMeshPayload,StoreVertexOutput,StorePrimitiveOutput".split(","):
- self.name_idx[i].category = "Mesh shader instructions"
- self.name_idx[i].shader_stages = ("mesh",)
- self.name_idx[i].shader_model = 6,5
- for i in "DispatchMesh".split(","):
- self.name_idx[i].category = "Amplification shader instructions"
- self.name_idx[i].shader_stages = ("amplification",)
- self.name_idx[i].shader_model = 6,5
- for i in "WriteSamplerFeedback,WriteSamplerFeedbackBias".split(","):
- self.name_idx[i].category = "Sampler Feedback"
- self.name_idx[i].is_feedback = True
- self.name_idx[i].is_gradient = True
- self.name_idx[i].shader_model = 6,5
- self.name_idx[i].shader_stages = ("library", "pixel",)
- for i in "WriteSamplerFeedbackLevel,WriteSamplerFeedbackGrad".split(","):
- self.name_idx[i].category = "Sampler Feedback"
- self.name_idx[i].is_feedback = True
- self.name_idx[i].shader_model = 6,5
- for i in ("AllocateRayQuery,RayQuery_TraceRayInline,RayQuery_Proceed,RayQuery_Abort,RayQuery_CommitNonOpaqueTriangleHit,RayQuery_CommitProceduralPrimitiveHit,RayQuery_RayFlags,RayQuery_WorldRayOrigin,RayQuery_WorldRayDirection,RayQuery_RayTMin,"+
- "RayQuery_CandidateTriangleRayT,RayQuery_CommittedRayT,RayQuery_CandidateInstanceIndex,RayQuery_CandidateInstanceID,RayQuery_CandidateGeometryIndex,RayQuery_CandidatePrimitiveIndex,"+
- "RayQuery_CandidateObjectRayOrigin,RayQuery_CandidateObjectRayDirection,RayQuery_CommittedInstanceIndex,RayQuery_CommittedInstanceID,RayQuery_CommittedGeometryIndex,RayQuery_CommittedPrimitiveIndex,"+
- "RayQuery_CommittedObjectRayOrigin,RayQuery_CommittedObjectRayDirection,RayQuery_CandidateProceduralPrimitiveNonOpaque,RayQuery_CandidateTriangleFrontFace,RayQuery_CommittedTriangleFrontFace,"+
- "RayQuery_CandidateTriangleBarycentrics,RayQuery_CommittedTriangleBarycentrics,RayQuery_CommittedStatus,RayQuery_CandidateType,RayQuery_CandidateObjectToWorld3x4,"+
- "RayQuery_CandidateWorldToObject3x4,RayQuery_CommittedObjectToWorld3x4,RayQuery_CommittedWorldToObject3x4,RayQuery_CandidateInstanceContributionToHitGroupIndex,RayQuery_CommittedInstanceContributionToHitGroupIndex").split(","):
- self.name_idx[i].category = "Inline Ray Query"
- self.name_idx[i].shader_model = 6,5
- for i in "Unpack4x8".split(","):
- self.name_idx[i].category = "Unpacking intrinsics"
- self.name_idx[i].shader_model = 6,6
- for i in "Pack4x8".split(","):
- self.name_idx[i].category = "Packing intrinsics"
- self.name_idx[i].shader_model = 6,6
- for i in "IsHelperLane".split(","):
- self.name_idx[i].category = "Helper Lanes"
- self.name_idx[i].shader_model = 6,6
- def populate_llvm_instructions(self):
- # Add instructions that map to LLVM instructions.
- # This is basically include\llvm\IR\Instruction.def
- #
- # Some instructions don't have their operands defined here because they are
- # very specific and expanding generality isn't worth it; for example,
- # branching refers to basic block arguments.
- retvoid_param = db_dxil_param(0, "v", "", "no return value")
- retoload_param = db_dxil_param(0, "$o", "", "no return value")
- oload_all_arith = "hfd1wil" # note that 8 is missing
- oload_all_arith_v = "v" + oload_all_arith
- oload_int_arith = "wil" # note that 8 is missing
- oload_int_arith_b = "1wil" # note that 8 is missing
- oload_float_arith = "hfd"
- oload_cast_params = [retoload_param, db_dxil_param(1, "$o", "value", "Value to cast/convert")]
- oload_binary_params = [retoload_param,
- db_dxil_param(1, "$o", "a", "first value"),
- db_dxil_param(2, "$o", "b", "second value")]
- self.add_llvm_instr("TERM", 1, "Ret", "ReturnInst", "returns a value (possibly void), from a function.", oload_all_arith_v, [retoload_param])
- self.add_llvm_instr("TERM", 2, "Br", "BranchInst", "branches (conditional or unconditional)", "", [])
- self.add_llvm_instr("TERM", 3, "Switch", "SwitchInst", "performs a multiway switch", "", [])
- self.add_llvm_instr("TERM", 4, "IndirectBr", "IndirectBrInst", "branches indirectly", "", [])
- self.add_llvm_instr("TERM", 5, "Invoke", "InvokeInst", "invokes function with normal and exceptional returns", "", [])
- self.add_llvm_instr("TERM", 6, "Resume", "ResumeInst", "resumes the propagation of an exception", "", [])
- self.add_llvm_instr("TERM", 7, "Unreachable", "UnreachableInst", "is unreachable", "", [])
- self.add_llvm_instr("BINARY", 8, "Add" , "BinaryOperator", "returns the sum of its two operands", oload_int_arith, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("BINARY", 9, "FAdd" , "BinaryOperator", "returns the sum of its two operands", oload_float_arith, oload_binary_params, counters=('floats',))
- self.add_llvm_instr("BINARY", 10, "Sub" , "BinaryOperator", "returns the difference of its two operands", oload_int_arith, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("BINARY", 11, "FSub" , "BinaryOperator", "returns the difference of its two operands", oload_float_arith, oload_binary_params, counters=('floats',))
- self.add_llvm_instr("BINARY", 12, "Mul" , "BinaryOperator", "returns the product of its two operands", oload_int_arith, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("BINARY", 13, "FMul" , "BinaryOperator", "returns the product of its two operands", oload_float_arith, oload_binary_params, counters=('floats',))
- self.add_llvm_instr("BINARY", 14, "UDiv" , "BinaryOperator", "returns the quotient of its two unsigned operands", oload_int_arith, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("BINARY", 15, "SDiv" , "BinaryOperator", "returns the quotient of its two signed operands", oload_int_arith, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("BINARY", 16, "FDiv" , "BinaryOperator", "returns the quotient of its two operands", oload_float_arith, oload_binary_params, counters=('floats',))
- self.add_llvm_instr("BINARY", 17, "URem" , "BinaryOperator", "returns the remainder from the unsigned division of its two operands", oload_int_arith, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("BINARY", 18, "SRem" , "BinaryOperator", "returns the remainder from the signed division of its two operands", oload_int_arith, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("BINARY", 19, "FRem" , "BinaryOperator", "returns the remainder from the division of its two operands", oload_float_arith, oload_binary_params, counters=('floats',))
- self.add_llvm_instr("BINARY", 20, "Shl", "BinaryOperator", "shifts left (logical)", oload_int_arith, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("BINARY", 21, "LShr", "BinaryOperator", "shifts right (logical), with zero bit fill", oload_int_arith, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("BINARY", 22, "AShr", "BinaryOperator", "shifts right (arithmetic), with 'a' operand sign bit fill", oload_int_arith, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("BINARY", 23, "And", "BinaryOperator", "returns a bitwise logical and of its two operands", oload_int_arith_b, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("BINARY", 24, "Or", "BinaryOperator", "returns a bitwise logical or of its two operands", oload_int_arith_b, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("BINARY", 25, "Xor", "BinaryOperator", "returns a bitwise logical xor of its two operands", oload_int_arith_b, oload_binary_params, counters=('uints',))
- self.add_llvm_instr("MEMORY", 26, "Alloca", "AllocaInst", "allocates memory on the stack frame of the currently executing function", "", [])
- self.add_llvm_instr("MEMORY", 27, "Load", "LoadInst", "reads from memory", "", [])
- self.add_llvm_instr("MEMORY", 28, "Store", "StoreInst", "writes to memory", "", [])
- self.add_llvm_instr("MEMORY", 29, "GetElementPtr", "GetElementPtrInst", "gets the address of a subelement of an aggregate value", "", [])
- self.add_llvm_instr("MEMORY", 30, "Fence", "FenceInst", "introduces happens-before edges between operations", "", [], counters=('fence',))
- self.add_llvm_instr("MEMORY", 31, "AtomicCmpXchg", "AtomicCmpXchgInst" , "atomically modifies memory", "", [], counters=('atomic',))
- self.add_llvm_instr("MEMORY", 32, "AtomicRMW", "AtomicRMWInst", "atomically modifies memory", "", [], counters=('atomic',))
- self.add_llvm_instr("CAST", 33, "Trunc", "TruncInst", "truncates an integer", oload_int_arith_b, oload_cast_params, counters=('ints',))
- self.add_llvm_instr("CAST", 34, "ZExt", "ZExtInst", "zero extends an integer", oload_int_arith_b, oload_cast_params, counters=('uints',))
- self.add_llvm_instr("CAST", 35, "SExt", "SExtInst", "sign extends an integer", oload_int_arith_b, oload_cast_params, counters=('ints',))
- self.add_llvm_instr("CAST", 36, "FPToUI", "FPToUIInst", "converts a floating point to UInt", oload_all_arith, oload_cast_params, counters=('floats',))
- self.add_llvm_instr("CAST", 37, "FPToSI", "FPToSIInst", "converts a floating point to SInt", oload_all_arith, oload_cast_params, counters=('floats',))
- self.add_llvm_instr("CAST", 38, "UIToFP", "UIToFPInst", "converts a UInt to floating point", oload_all_arith, oload_cast_params, counters=('floats',))
- self.add_llvm_instr("CAST", 39, "SIToFP" , "SIToFPInst", "converts a SInt to floating point", oload_all_arith, oload_cast_params, counters=('floats',))
- self.add_llvm_instr("CAST", 40, "FPTrunc", "FPTruncInst", "truncates a floating point", oload_float_arith, oload_cast_params, counters=('floats',))
- self.add_llvm_instr("CAST", 41, "FPExt", "FPExtInst", "extends a floating point", oload_float_arith, oload_cast_params, counters=('floats',))
- self.add_llvm_instr("CAST", 42, "PtrToInt", "PtrToIntInst", "converts a pointer to integer", "i", oload_cast_params)
- self.add_llvm_instr("CAST", 43, "IntToPtr", "IntToPtrInst", "converts an integer to Pointer", "i", oload_cast_params)
- self.add_llvm_instr("CAST", 44, "BitCast", "BitCastInst", "performs a bit-preserving type cast", oload_all_arith, oload_cast_params)
- self.add_llvm_instr("CAST", 45, "AddrSpaceCast", "AddrSpaceCastInst", "casts a value addrspace", "", oload_cast_params)
- self.add_llvm_instr("OTHER", 46, "ICmp", "ICmpInst", "compares integers", oload_int_arith_b, oload_binary_params, counters=('ints',))
- self.add_llvm_instr("OTHER", 47, "FCmp", "FCmpInst", "compares floating points", oload_float_arith, oload_binary_params, counters=('floats',))
- self.add_llvm_instr("OTHER", 48, "PHI", "PHINode", "is a PHI node instruction", "", [])
- self.add_llvm_instr("OTHER", 49, "Call", "CallInst", "calls a function", "", [])
- self.add_llvm_instr("OTHER", 50, "Select", "SelectInst", "selects an instruction", "", [])
- self.add_llvm_instr("OTHER", 51, "UserOp1", "Instruction", "may be used internally in a pass", "", [])
- self.add_llvm_instr("OTHER", 52, "UserOp2", "Instruction", "internal to passes only", "", [])
- self.add_llvm_instr("OTHER", 53, "VAArg", "VAArgInst", "vaarg instruction", "", [])
- self.add_llvm_instr("OTHER", 57, "ExtractValue", "ExtractValueInst", "extracts from aggregate", "", [])
- self.add_llvm_instr("OTHER", 59, "LandingPad", "LandingPadInst", "represents a landing pad", "", [])
-
- def populate_dxil_operations(self):
- # $o in a parameter type means the overload type
- # $r in a parameter type means the resource type
- # $cb in a parameter type means cbuffer legacy load return type
- # overload types are a string of (v)oid, (h)alf, (f)loat, (d)ouble, (1)-bit, (8)-bit, (w)ord, (i)nt, (l)ong
- self.opcode_param = db_dxil_param(1, "i32", "opcode", "DXIL opcode")
- retvoid_param = db_dxil_param(0, "v", "", "no return value")
- next_op_idx = 0
- self.add_dxil_op("TempRegLoad", next_op_idx, "TempRegLoad", "helper load operation", "hfwi", "ro", [
- db_dxil_param(0, "$o", "", "register value"),
- db_dxil_param(2, "u32", "index", "linearized register index")])
- next_op_idx += 1
- self.add_dxil_op("TempRegStore", next_op_idx, "TempRegStore", "helper store operation", "hfwi", "", [
- retvoid_param,
- db_dxil_param(2, "u32", "index", "linearized register index"),
- db_dxil_param(3, "$o", "value", "value to store")])
- next_op_idx += 1
- self.add_dxil_op("MinPrecXRegLoad", next_op_idx, "MinPrecXRegLoad", "helper load operation for minprecision", "hw", "ro", [
- db_dxil_param(0, "$o", "", "register value"),
- db_dxil_param(2, "pf32", "regIndex", "pointer to indexable register"),
- db_dxil_param(3, "i32", "index", "index"),
- db_dxil_param(4, "u8", "component", "component")])
- next_op_idx += 1
- self.add_dxil_op("MinPrecXRegStore", next_op_idx, "MinPrecXRegStore", "helper store operation for minprecision", "hw", "", [
- retvoid_param,
- db_dxil_param(2, "pf32", "regIndex", "pointer to indexable register"),
- db_dxil_param(3, "i32", "index", "index"),
- db_dxil_param(4, "u8", "component", "component"),
- db_dxil_param(5, "$o", "value", "value to store")])
- next_op_idx += 1
- self.add_dxil_op("LoadInput", next_op_idx, "LoadInput", "loads the value from shader input", "hfwi", "rn", [
- db_dxil_param(0, "$o", "", "input value"),
- db_dxil_param(2, "u32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "u32", "rowIndex", "row index relative to element"),
- db_dxil_param(4, "u8", "colIndex", "column index relative to element"),
- db_dxil_param(5, "i32", "gsVertexAxis", "gsVertexAxis")],
- counters=('sig_ld',))
- next_op_idx += 1
- self.add_dxil_op("StoreOutput", next_op_idx, "StoreOutput", "stores the value to shader output", "hfwi", "", [ # note, cannot store bit even though load supports it
- retvoid_param,
- db_dxil_param(2, "u32", "outputSigId", "output signature element ID"),
- db_dxil_param(3, "u32", "rowIndex", "row index relative to element"),
- db_dxil_param(4, "u8", "colIndex", "column index relative to element"),
- db_dxil_param(5, "$o", "value", "value to store")],
- counters=('sig_st',))
- next_op_idx += 1
- def UFI(name, **mappings):
- name = name.upper()
- for k,v in mappings.items():
- if name.startswith(k):
- return v
- if name.upper().startswith('F'):
- return 'floats'
- elif name.upper().startswith('U'):
- return 'uints'
- else:
- return 'ints'
- # Unary float operations are regular.
- for i in "FAbs,Saturate".split(","):
- self.add_dxil_op(i, next_op_idx, "Unary", "returns the " + i, "hfd", "rn", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")],
- counters=('floats',))
- next_op_idx += 1
- for i in "IsNaN,IsInf,IsFinite,IsNormal".split(","):
- self.add_dxil_op(i, next_op_idx, "IsSpecialFloat", "returns the " + i, "hf", "rn", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")],
- counters=('floats',))
- next_op_idx += 1
- for i in "Cos,Sin,Tan,Acos,Asin,Atan,Hcos,Hsin,Htan,Exp,Frc,Log,Sqrt,Rsqrt,Round_ne,Round_ni,Round_pi,Round_z".split(","):
- self.add_dxil_op(i, next_op_idx, "Unary", "returns the " + i, "hf", "rn", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")],
- counters=('floats',))
- next_op_idx += 1
- # Unary int operations are regular.
- for i in "Bfrev".split(","):
- self.add_dxil_op(i, next_op_idx, "Unary", "returns the reverse bit pattern of the input value", "wil", "rn", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")],
- counters=('uints',))
- next_op_idx += 1
- for i in "Countbits,FirstbitLo".split(","):
- self.add_dxil_op(i, next_op_idx, "UnaryBits", "returns the " + i, "wil", "rn", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")],
- counters=('uints',))
- next_op_idx += 1
- for i in "FirstbitHi,FirstbitSHi".split(","):
- self.add_dxil_op(i, next_op_idx, "UnaryBits", "returns src != 0? (BitWidth-1 - " + i + ") : -1", "wil", "rn", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")],
- counters=('uints',))
- next_op_idx += 1
- # Binary float operations
- for i in "FMax,FMin".split(","):
- self.add_dxil_op(i, next_op_idx, "Binary", "returns the " + i + " of the input values", "hfd", "rn", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "a", "input value"),
- db_dxil_param(3, "$o", "b", "input value")],
- counters=('floats',))
- next_op_idx += 1
- # Binary int operations
- for i in "IMax,IMin,UMax,UMin".split(","):
- self.add_dxil_op(i, next_op_idx, "Binary", "returns the " + i + " of the input values", "wil", "rn", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "a", "input value"),
- db_dxil_param(3, "$o", "b", "input value")],
- counters=(UFI(i),))
- next_op_idx += 1
- # Binary int operations with two outputs
- for i in "IMul,UMul,UDiv".split(","):
- self.add_dxil_op(i, next_op_idx, "BinaryWithTwoOuts", "returns the " + i + " of the input values", "i", "rn", [
- db_dxil_param(0, "twoi32", "", "operation result"),
- db_dxil_param(2, "$o", "a", "input value"),
- db_dxil_param(3, "$o", "b", "input value")],
- counters=(UFI(i),))
- next_op_idx += 1
- # Binary int operations with carry
- for i in "UAddc,USubb".split(","):
- self.add_dxil_op(i, next_op_idx, "BinaryWithCarryOrBorrow", "returns the " + i + " of the input values", "i", "rn", [
- db_dxil_param(0, "i32c", "", "operation result with carry/borrow value"),
- db_dxil_param(2, "$o", "a", "input value"),
- db_dxil_param(3, "$o", "b", "input value")],
- counters=('uints',))
- next_op_idx += 1
- # Tertiary float.
- self.add_dxil_op("FMad", next_op_idx, "Tertiary", "performs a fused multiply add (FMA) of the form a * b + c", "hfd", "rn", [
- db_dxil_param(0, "$o", "", "the fused multiply-addition of parameters a * b + c"),
- db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"),
- db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"),
- db_dxil_param(4, "$o", "c", "third value for FMA, the addend")])
- next_op_idx += 1
- self.add_dxil_op("Fma", next_op_idx, "Tertiary", "performs a fused multiply add (FMA) of the form a * b + c", "d", "rn", [
- db_dxil_param(0, "$o", "", "the double-precision fused multiply-addition of parameters a * b + c, accurate to 0.5 units of least precision (ULP)"),
- db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"),
- db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"),
- db_dxil_param(4, "$o", "c", "third value for FMA, the addend")],
- counters=('floats',))
- next_op_idx += 1
- # Tertiary int.
- for i in "IMad,UMad".split(","):
- self.add_dxil_op(i, next_op_idx, "Tertiary", "performs an integral " + i, "wil", "rn", [
- db_dxil_param(0, "$o", "", "the operation result"),
- db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"),
- db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"),
- db_dxil_param(4, "$o", "c", "third value for FMA, the addend")],
- counters=(UFI(i),))
- next_op_idx += 1
- for i in "Msad,Ibfe,Ubfe".split(","):
- self.add_dxil_op(i, next_op_idx, "Tertiary", "performs an integral " + i, "il", "rn", [
- db_dxil_param(0, "$o", "", "the operation result"),
- db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"),
- db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"),
- db_dxil_param(4, "$o", "c", "third value for FMA, the addend")],
- counters=(UFI(i, M='uints'),))
- next_op_idx += 1
- # Quaternary
- self.add_dxil_op("Bfi", next_op_idx, "Quaternary", "given a bit range from the LSB of a number, places that number of bits in another number at any offset", "i", "rn", [
- db_dxil_param(0, "$o", "", "the operation result"),
- db_dxil_param(2, "$o", "width", "the bitfield width to take from the value"),
- db_dxil_param(3, "$o", "offset", "the bitfield offset to replace in the value"),
- db_dxil_param(4, "$o", "value", "the number the bits are taken from"),
- db_dxil_param(5, "$o", "replacedValue", "the number with bits to be replaced")],
- counters=('uints',))
- next_op_idx += 1
- # Dot
- self.add_dxil_op("Dot2", next_op_idx, "Dot2", "two-dimensional vector dot-product", "hf", "rn", [
- db_dxil_param(0, "$o", "", "the operation result"),
- db_dxil_param(2, "$o", "ax", "the first component of the first vector"),
- db_dxil_param(3, "$o", "ay", "the second component of the first vector"),
- db_dxil_param(4, "$o", "bx", "the first component of the second vector"),
- db_dxil_param(5, "$o", "by", "the second component of the second vector")],
- counters=('floats',))
- next_op_idx += 1
- self.add_dxil_op("Dot3", next_op_idx, "Dot3", "three-dimensional vector dot-product", "hf", "rn", [
- db_dxil_param(0, "$o", "", "the operation result"),
- db_dxil_param(2, "$o", "ax", "the first component of the first vector"),
- db_dxil_param(3, "$o", "ay", "the second component of the first vector"),
- db_dxil_param(4, "$o", "az", "the third component of the first vector"),
- db_dxil_param(5, "$o", "bx", "the first component of the second vector"),
- db_dxil_param(6, "$o", "by", "the second component of the second vector"),
- db_dxil_param(7, "$o", "bz", "the third component of the second vector")],
- counters=('floats',))
- next_op_idx += 1
- self.add_dxil_op("Dot4", next_op_idx, "Dot4", "four-dimensional vector dot-product", "hf", "rn", [
- db_dxil_param(0, "$o", "", "the operation result"),
- db_dxil_param(2, "$o", "ax", "the first component of the first vector"),
- db_dxil_param(3, "$o", "ay", "the second component of the first vector"),
- db_dxil_param(4, "$o", "az", "the third component of the first vector"),
- db_dxil_param(5, "$o", "aw", "the fourth component of the first vector"),
- db_dxil_param(6, "$o", "bx", "the first component of the second vector"),
- db_dxil_param(7, "$o", "by", "the second component of the second vector"),
- db_dxil_param(8, "$o", "bz", "the third component of the second vector"),
- db_dxil_param(9, "$o", "bw", "the fourth component of the second vector")],
- counters=('floats',))
- next_op_idx += 1
- # Resources.
- self.add_dxil_op("CreateHandle", next_op_idx, "CreateHandle", "creates the handle to a resource", "v", "ro", [
- db_dxil_param(0, "res", "", "the handle to the resource"),
- db_dxil_param(2, "i8", "resourceClass", "the class of resource to create (SRV, UAV, CBuffer, Sampler)", is_const=True), # maps to DxilResourceBase::Class
- db_dxil_param(3, "i32", "rangeId", "range identifier for resource", is_const=True),
- db_dxil_param(4, "i32", "index", "zero-based index into range"),
- db_dxil_param(5, "i1", "nonUniformIndex", "non-uniform resource index", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("CBufferLoad", next_op_idx, "CBufferLoad", "loads a value from a constant buffer resource", "hfd8wil", "ro", [
- db_dxil_param(0, "$o", "", "the value for the constant buffer variable"),
- db_dxil_param(2, "res", "handle", "cbuffer handle"),
- db_dxil_param(3, "u32", "byteOffset", "linear byte offset of value"),
- db_dxil_param(4, "u32", "alignment", "load access alignment", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("CBufferLoadLegacy", next_op_idx, "CBufferLoadLegacy", "loads a value from a constant buffer resource", "hfdwil", "ro", [
- db_dxil_param(0, "$cb", "", "the value for the constant buffer variable"),
- db_dxil_param(2, "res", "handle", "cbuffer handle"),
- db_dxil_param(3, "u32", "regIndex", "0-based index into cbuffer instance")])
- next_op_idx += 1
- self.add_dxil_op("Sample", next_op_idx, "Sample", "samples a texture", "hf", "ro", [
- db_dxil_param(0, "$r", "", "the sampled value"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
- db_dxil_param(11, "f", "clamp", "clamp value")],
- counters=('tex_norm',))
- next_op_idx += 1
- self.add_dxil_op("SampleBias", next_op_idx, "SampleBias", "samples a texture after applying the input bias to the mipmap level", "hf", "ro", [
- db_dxil_param(0, "$r", "", "the sampled value"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
- db_dxil_param(11, "f", "bias", "bias value"),
- db_dxil_param(12, "f", "clamp", "clamp value")],
- counters=('tex_bias',))
- next_op_idx += 1
- self.add_dxil_op("SampleLevel", next_op_idx, "SampleLevel", "samples a texture using a mipmap-level offset", "hf", "ro", [
- db_dxil_param(0, "$r", "", "the sampled value"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
- db_dxil_param(11, "f", "LOD", "level of detail, biggest map if less than or equal to zero; fraction used to interpolate across levels")],
- counters=('tex_norm',))
- next_op_idx += 1
- self.add_dxil_op("SampleGrad", next_op_idx, "SampleGrad", "samples a texture using a gradient to influence the way the sample location is calculated", "hf", "ro", [
- db_dxil_param(0, "$r", "", "the sampled value"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
- db_dxil_param(11, "f", "ddx0", "rate of change of the texture coordinate in the x direction"),
- db_dxil_param(12, "f", "ddx1", "rate of change of the texture coordinate in the x direction"),
- db_dxil_param(13, "f", "ddx2", "rate of change of the texture coordinate in the x direction"),
- db_dxil_param(14, "f", "ddy0", "rate of change of the texture coordinate in the y direction"),
- db_dxil_param(15, "f", "ddy1", "rate of change of the texture coordinate in the y direction"),
- db_dxil_param(16, "f", "ddy2", "rate of change of the texture coordinate in the y direction"),
- db_dxil_param(17, "f", "clamp", "clamp value")],
- counters=('tex_grad',))
- next_op_idx += 1
- self.add_dxil_op("SampleCmp", next_op_idx, "SampleCmp", "samples a texture and compares a single component against the specified comparison value", "hf", "ro", [
- db_dxil_param(0, "$r", "", "the value for the constant buffer variable"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
- db_dxil_param(11, "f", "compareValue", "the value to compare with"),
- db_dxil_param(12, "f", "clamp", "clamp value")],
- counters=('tex_cmp',))
- next_op_idx += 1
- self.add_dxil_op("SampleCmpLevelZero", next_op_idx, "SampleCmpLevelZero", "samples a texture and compares a single component against the specified comparison value", "hf", "ro", [
- db_dxil_param(0, "$r", "", "the value for the constant buffer variable"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"),
- db_dxil_param(11, "f", "compareValue", "the value to compare with")],
- counters=('tex_cmp',))
- next_op_idx += 1
- self.add_dxil_op("TextureLoad", next_op_idx, "TextureLoad", "reads texel data without any filtering or sampling", "hfwi", "ro", [
- db_dxil_param(0, "$r", "", "the loaded value"),
- db_dxil_param(2, "res", "srv", "handle of SRV or UAV to sample"),
- db_dxil_param(3, "i32", "mipLevelOrSampleCount", "sample count for Texture2DMS, mip level otherwise"),
- db_dxil_param(4, "i32", "coord0", "coordinate"),
- db_dxil_param(5, "i32", "coord1", "coordinate"),
- db_dxil_param(6, "i32", "coord2", "coordinate"),
- db_dxil_param(7, "i32", "offset0", "optional offset"),
- db_dxil_param(8, "i32", "offset1", "optional offset"),
- db_dxil_param(9, "i32", "offset2", "optional offset")],
- counters=('tex_load',))
- next_op_idx += 1
- self.add_dxil_op("TextureStore", next_op_idx, "TextureStore", "reads texel data without any filtering or sampling", "hfwi", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "srv", "handle of UAV to store to"),
- db_dxil_param(3, "i32", "coord0", "coordinate"),
- db_dxil_param(4, "i32", "coord1", "coordinate"),
- db_dxil_param(5, "i32", "coord2", "coordinate"),
- db_dxil_param(6, "$o", "value0", "value"),
- db_dxil_param(7, "$o", "value1", "value"),
- db_dxil_param(8, "$o", "value2", "value"),
- db_dxil_param(9, "$o", "value3", "value"),
- db_dxil_param(10,"i8", "mask", "written value mask")],
- counters=('tex_store',))
- next_op_idx += 1
- self.add_dxil_op("BufferLoad", next_op_idx, "BufferLoad", "reads from a TypedBuffer", "hfwi", "ro", [
- db_dxil_param(0, "$r", "", "the loaded value"),
- db_dxil_param(2, "res", "srv", "handle of TypedBuffer SRV to sample"),
- db_dxil_param(3, "i32", "index", "element index"),
- db_dxil_param(4, "i32", "wot", "coordinate")],
- counters=('tex_load',))
- next_op_idx += 1
- self.add_dxil_op("BufferStore", next_op_idx, "BufferStore", "writes to a RWTypedBuffer", "hfwi", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "uav", "handle of UAV to store to"),
- db_dxil_param(3, "i32", "coord0", "coordinate in elements"),
- db_dxil_param(4, "i32", "coord1", "coordinate (unused?)"),
- db_dxil_param(5, "$o", "value0", "value"),
- db_dxil_param(6, "$o", "value1", "value"),
- db_dxil_param(7, "$o", "value2", "value"),
- db_dxil_param(8, "$o", "value3", "value"),
- db_dxil_param(9, "i8", "mask", "written value mask")],
- counters=('tex_store',))
- next_op_idx += 1
- self.add_dxil_op("BufferUpdateCounter", next_op_idx, "BufferUpdateCounter", "atomically increments/decrements the hidden 32-bit counter stored with a Count or Append UAV", "v", "", [
- db_dxil_param(0, "i32", "", "the new value in the buffer"),
- db_dxil_param(2, "res", "uav", "handle to a structured buffer UAV with the count or append flag"),
- db_dxil_param(3, "i8", "inc", "1 to increase, 0 to decrease")],
- counters=('atomic',))
- next_op_idx += 1
- self.add_dxil_op("CheckAccessFullyMapped", next_op_idx, "CheckAccessFullyMapped", "determines whether all values from a Sample, Gather, or Load operation accessed mapped tiles in a tiled resource", "i", "ro", [
- db_dxil_param(0, "i1", "", "nonzero if all values accessed mapped tiles in a tiled resource"),
- db_dxil_param(2, "u32", "status", "status result from the Sample, Gather or Load operation")])
- next_op_idx += 1
- self.add_dxil_op("GetDimensions", next_op_idx, "GetDimensions", "gets texture size information", "v", "ro", [
- db_dxil_param(0, "dims", "", "dimension information for texture"),
- db_dxil_param(2, "res", "handle", "resource handle to query"),
- db_dxil_param(3, "i32", "mipLevel", "mip level to query")])
- next_op_idx += 1
- self.add_dxil_op("TextureGather", next_op_idx, "TextureGather", "gathers the four texels that would be used in a bi-linear filtering operation", "hfwi", "ro", [
- db_dxil_param(0, "$r", "", "dimension information for texture"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "channel", "channel to sample")],
- counters=('tex_norm',))
- next_op_idx += 1
- self.add_dxil_op("TextureGatherCmp", next_op_idx, "TextureGatherCmp", "same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp", "hfwi", "ro", [
- db_dxil_param(0, "$r", "", "gathered texels"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "res", "sampler", "handle of sampler to use"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"),
- db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"),
- db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"),
- db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"),
- db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"),
- db_dxil_param(10, "i32", "channel", "channel to sample"),
- db_dxil_param(11, "f", "compareVale", "value to compare with")],
- counters=('tex_cmp',))
- next_op_idx += 1
- self.add_dxil_op("Texture2DMSGetSamplePosition", next_op_idx, "Texture2DMSGetSamplePosition", "gets the position of the specified sample", "v", "ro", [
- db_dxil_param(0, "SamplePos", "", "sample position"),
- db_dxil_param(2, "res", "srv", "handle of SRV to sample"),
- db_dxil_param(3, "i32", "index", "zero-based sample index")])
- next_op_idx += 1
- self.add_dxil_op("RenderTargetGetSamplePosition", next_op_idx, "RenderTargetGetSamplePosition", "gets the position of the specified sample", "v", "ro", [
- db_dxil_param(0, "SamplePos", "", "sample position"),
- db_dxil_param(2, "i32", "index", "zero-based sample index")])
- next_op_idx += 1
- self.add_dxil_op("RenderTargetGetSampleCount", next_op_idx, "RenderTargetGetSampleCount", "gets the number of samples for a render target", "v", "ro", [
- db_dxil_param(0, "u32", "", "number of sampling locations for a render target")])
- next_op_idx += 1
- # Atomics. Note that on TGSM, atomics are performed with LLVM instructions.
- self.add_dxil_op("AtomicBinOp", next_op_idx, "AtomicBinOp", "performs an atomic operation on two operands", "li", "", [
- db_dxil_param(0, "$o", "", "the original value in the location updated"),
- db_dxil_param(2, "res", "handle", "typed int or uint UAV handle"),
- db_dxil_param(3, "i32", "atomicOp", "atomic operation as per DXIL::AtomicBinOpCode"),
- db_dxil_param(4, "i32", "offset0", "offset in elements"),
- db_dxil_param(5, "i32", "offset1", "offset"),
- db_dxil_param(6, "i32", "offset2", "offset"),
- db_dxil_param(7, "$o", "newValue", "new value")],
- counters=('atomic',))
- next_op_idx += 1
- self.add_dxil_op("AtomicCompareExchange", next_op_idx, "AtomicCompareExchange", "atomic compare and exchange to memory", "li", "", [
- db_dxil_param(0, "$o", "", "the original value in the location updated"),
- db_dxil_param(2, "res", "handle", "typed int or uint UAV handle"),
- db_dxil_param(3, "i32", "offset0", "offset in elements"),
- db_dxil_param(4, "i32", "offset1", "offset"),
- db_dxil_param(5, "i32", "offset2", "offset"),
- db_dxil_param(6, "$o", "compareValue", "value to compare for exchange"),
- db_dxil_param(7, "$o", "newValue", "new value")],
- counters=('atomic',))
- next_op_idx += 1
- # Synchronization.
- self.add_dxil_op("Barrier", next_op_idx, "Barrier", "inserts a memory barrier in the shader", "v", "nd", [
- retvoid_param,
- db_dxil_param(2, "i32", "barrierMode", "a mask of DXIL::BarrierMode values", is_const=True)],
- counters=('barrier',))
- next_op_idx += 1
- # Pixel shader
- self.add_dxil_op("CalculateLOD", next_op_idx, "CalculateLOD", "calculates the level of detail", "f", "ro", [
- db_dxil_param(0, "f", "", "level of detail"),
- db_dxil_param(2, "res", "handle", "resource handle"),
- db_dxil_param(3, "res", "sampler", "sampler handle"),
- db_dxil_param(4, "f", "coord0", "coordinate"),
- db_dxil_param(5, "f", "coord1", "coordinate"),
- db_dxil_param(6, "f", "coord2", "coordinate"),
- db_dxil_param(7, "i1", "clamped", "1 if clampled LOD should be calculated, 0 for unclamped")])
- next_op_idx += 1
- self.add_dxil_op("Discard", next_op_idx, "Discard", "discard the current pixel", "v", "", [
- retvoid_param,
- db_dxil_param(2, "i1", "condition", "condition for conditional discard")])
- next_op_idx += 1
- self.add_dxil_op("DerivCoarseX", next_op_idx, "Unary", "computes the rate of change of components per stamp", "hf", "rn", [
- db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget x direction"),
- db_dxil_param(2, "$o", "value", "input to rate of change")])
- next_op_idx += 1
- self.add_dxil_op("DerivCoarseY", next_op_idx, "Unary", "computes the rate of change of components per stamp", "hf", "rn", [
- db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget y direction"),
- db_dxil_param(2, "$o", "value", "input to rate of change")])
- next_op_idx += 1
- self.add_dxil_op("DerivFineX", next_op_idx, "Unary", "computes the rate of change of components per pixel", "hf", "rn", [
- db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget x direction"),
- db_dxil_param(2, "$o", "value", "input to rate of change")])
- next_op_idx += 1
- self.add_dxil_op("DerivFineY", next_op_idx, "Unary", "computes the rate of change of components per pixel", "hf", "rn", [
- db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget y direction"),
- db_dxil_param(2, "$o", "value", "input to rate of change")])
- next_op_idx += 1
- self.add_dxil_op("EvalSnapped", next_op_idx, "EvalSnapped", "evaluates an input attribute at pixel center with an offset", "hf", "rn", [
- db_dxil_param(0, "$o", "", "result"),
- db_dxil_param(2, "i32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"),
- db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute"),
- db_dxil_param(5, "i32", "offsetX", "2D offset from the pixel center using a 16x16 grid"),
- db_dxil_param(6, "i32", "offsetY", "2D offset from the pixel center using a 16x16 grid")])
- next_op_idx += 1
- self.add_dxil_op("EvalSampleIndex", next_op_idx, "EvalSampleIndex", "evaluates an input attribute at a sample location", "hf", "rn", [
- db_dxil_param(0, "$o", "", "result"),
- db_dxil_param(2, "i32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"),
- db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute"),
- db_dxil_param(5, "i32", "sampleIndex", "sample location")])
- next_op_idx += 1
- self.add_dxil_op("EvalCentroid", next_op_idx, "EvalCentroid", "evaluates an input attribute at pixel center", "hf", "rn", [
- db_dxil_param(0, "$o", "", "result"),
- db_dxil_param(2, "i32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"),
- db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute")])
- next_op_idx += 1
- self.add_dxil_op("SampleIndex", next_op_idx, "SampleIndex", "returns the sample index in a sample-frequency pixel shader", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("Coverage", next_op_idx, "Coverage", "returns the coverage mask input in a pixel shader", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("InnerCoverage", next_op_idx, "InnerCoverage", "returns underestimated coverage input from conservative rasterization in a pixel shader", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- # Compute shader.
- self.add_dxil_op("ThreadId", next_op_idx, "ThreadId", "reads the thread ID", "i", "rn", [
- db_dxil_param(0, "i32", "", "thread ID component"),
- db_dxil_param(2, "i32", "component", "component to read (x,y,z)")])
- next_op_idx += 1
- self.add_dxil_op("GroupId", next_op_idx, "GroupId", "reads the group ID (SV_GroupID)", "i", "rn", [
- db_dxil_param(0, "i32", "", "group ID component"),
- db_dxil_param(2, "i32", "component", "component to read")])
- next_op_idx += 1
- self.add_dxil_op("ThreadIdInGroup", next_op_idx, "ThreadIdInGroup", "reads the thread ID within the group (SV_GroupThreadID)", "i", "rn", [
- db_dxil_param(0, "i32", "", "thread ID in group component"),
- db_dxil_param(2, "i32", "component", "component to read (x,y,z)")])
- next_op_idx += 1
- self.add_dxil_op("FlattenedThreadIdInGroup", next_op_idx, "FlattenedThreadIdInGroup", "provides a flattened index for a given thread within a given group (SV_GroupIndex)", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- # Geometry shader
- self.add_dxil_op("EmitStream", next_op_idx, "EmitStream", "emits a vertex to a given stream", "v", "", [
- retvoid_param,
- db_dxil_param(2, "i8", "streamId", "target stream ID for operation")],
- counters=('gs_emit',))
- next_op_idx += 1
- self.add_dxil_op("CutStream", next_op_idx, "CutStream", "completes the current primitive topology at the specified stream", "v", "", [
- retvoid_param,
- db_dxil_param(2, "i8", "streamId", "target stream ID for operation")],
- counters=('gs_cut',))
- next_op_idx += 1
- self.add_dxil_op("EmitThenCutStream", next_op_idx, "EmitThenCutStream", "equivalent to an EmitStream followed by a CutStream", "v", "", [
- retvoid_param,
- db_dxil_param(2, "i8", "streamId", "target stream ID for operation")],
- counters=('gs_emit','gs_cut'))
- next_op_idx += 1
- self.add_dxil_op("GSInstanceID", next_op_idx, "GSInstanceID", "GSInstanceID", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- # Double precision
- self.add_dxil_op("MakeDouble", next_op_idx, "MakeDouble", "creates a double value", "d", "rn", [
- db_dxil_param(0, "d", "", "result"),
- db_dxil_param(2, "i32", "lo", "low part of double"),
- db_dxil_param(3, "i32", "hi", "high part of double")])
- next_op_idx += 1
- self.add_dxil_op("SplitDouble", next_op_idx, "SplitDouble", "splits a double into low and high parts", "d", "rn", [
- db_dxil_param(0, "splitdouble", "", "result"),
- db_dxil_param(2, "d", "value", "value to split")])
- next_op_idx += 1
- # Domain & Hull shader.
- self.add_dxil_op("LoadOutputControlPoint", next_op_idx, "LoadOutputControlPoint", "LoadOutputControlPoint", "hfwi", "rn", [
- db_dxil_param(0, "$o", "", "result"),
- db_dxil_param(2, "i32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "i32", "row", "row, relative to the element"),
- db_dxil_param(4, "i8", "col", "column, relative to the element"),
- db_dxil_param(5, "i32", "index", "vertex/point index")],
- counters=('sig_ld',))
- next_op_idx += 1
- self.add_dxil_op("LoadPatchConstant", next_op_idx, "LoadPatchConstant", "LoadPatchConstant", "hfwi", "rn", [
- db_dxil_param(0, "$o", "", "result"),
- db_dxil_param(2, "i32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "i32", "row", "row, relative to the element"),
- db_dxil_param(4, "i8", "col", "column, relative to the element")],
- counters=('sig_ld',))
- next_op_idx += 1
- # Domain shader.
- self.add_dxil_op("DomainLocation", next_op_idx, "DomainLocation", "DomainLocation", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i8", "component", "input", is_const=True)])
- next_op_idx += 1
- # Hull shader.
- self.add_dxil_op("StorePatchConstant", next_op_idx, "StorePatchConstant", "StorePatchConstant", "hfwi", "", [
- retvoid_param,
- db_dxil_param(2, "i32", "outputSigID", "output signature element ID"),
- db_dxil_param(3, "i32", "row", "row, relative to the element"),
- db_dxil_param(4, "i8", "col", "column, relative to the element"),
- db_dxil_param(5, "$o", "value", "value to store")],
- counters=('sig_st',))
- next_op_idx += 1
- self.add_dxil_op("OutputControlPointID", next_op_idx, "OutputControlPointID", "OutputControlPointID", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("PrimitiveID", next_op_idx, "PrimitiveID", "PrimitiveID", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("CycleCounterLegacy", next_op_idx, "CycleCounterLegacy", "CycleCounterLegacy", "v", "", [
- db_dxil_param(0, "twoi32", "", "result")])
- next_op_idx += 1
-
- # Add wave intrinsics.
- self.add_dxil_op("WaveIsFirstLane", next_op_idx, "WaveIsFirstLane", "returns 1 for the first lane in the wave", "v", "", [
- db_dxil_param(0, "i1", "", "operation result")])
- next_op_idx += 1
- self.add_dxil_op("WaveGetLaneIndex", next_op_idx, "WaveGetLaneIndex", "returns the index of the current lane in the wave", "v", "rn", [
- db_dxil_param(0, "i32", "", "operation result")])
- next_op_idx += 1
- self.add_dxil_op("WaveGetLaneCount", next_op_idx, "WaveGetLaneCount", "returns the number of lanes in the wave", "v", "rn", [
- db_dxil_param(0, "i32", "", "operation result")])
- next_op_idx += 1
- self.add_dxil_op("WaveAnyTrue", next_op_idx, "WaveAnyTrue", "returns 1 if any of the lane evaluates the value to true", "v", "", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "i1", "cond", "condition to test")])
- next_op_idx += 1
- self.add_dxil_op("WaveAllTrue", next_op_idx, "WaveAllTrue", "returns 1 if all the lanes evaluate the value to true", "v", "", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "i1", "cond", "condition to test")])
- next_op_idx += 1
- self.add_dxil_op("WaveActiveAllEqual", next_op_idx, "WaveActiveAllEqual", "returns 1 if all the lanes have the same value", "hfd18wil", "", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "$o", "value", "value to compare")])
- next_op_idx += 1
- self.add_dxil_op("WaveActiveBallot", next_op_idx, "WaveActiveBallot", "returns a struct with a bit set for each lane where the condition is true", "v", "", [
- db_dxil_param(0, "fouri32", "", "operation result"),
- db_dxil_param(2, "i1", "cond", "condition to ballot on")])
- next_op_idx += 1
- self.add_dxil_op("WaveReadLaneAt", next_op_idx, "WaveReadLaneAt", "returns the value from the specified lane", "hfd18wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "value to read"),
- db_dxil_param(3, "i32", "lane", "lane index")])
- next_op_idx += 1
- self.add_dxil_op("WaveReadLaneFirst", next_op_idx, "WaveReadLaneFirst", "returns the value from the first lane", "hfd18wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "value to read")])
- next_op_idx += 1
- self.add_dxil_op("WaveActiveOp", next_op_idx, "WaveActiveOp", "returns the result the operation across waves", "hfd18wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value"),
- db_dxil_param(3, "i8", "op", "kind of operation to perform", enum_name="WaveOpKind", is_const=True),
- db_dxil_param(4, "i8", "sop", "sign of operands", enum_name="SignedOpKind", is_const=True)])
- next_op_idx += 1
- self.add_enum_type("SignedOpKind", "Sign vs. unsigned operands for operation", [
- (0, "Signed", "signed integer or floating-point operands"),
- (1, "Unsigned", "unsigned integer operands")])
- self.add_enum_type("WaveOpKind", "Kind of cross-lane operation", [
- (0, "Sum", "sum of values"),
- (1, "Product", "product of values"),
- (2, "Min", "minimum value"),
- (3, "Max", "maximum value")])
- self.add_dxil_op("WaveActiveBit", next_op_idx, "WaveActiveBit", "returns the result of the operation across all lanes", "8wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value"),
- db_dxil_param(3, "i8", "op", "kind of operation to perform", enum_name="WaveBitOpKind", is_const=True)])
- next_op_idx += 1
- self.add_enum_type("WaveBitOpKind", "Kind of bitwise cross-lane operation", [
- (0, "And", "bitwise and of values"),
- (1, "Or", "bitwise or of values"),
- (2, "Xor", "bitwise xor of values")])
- self.add_dxil_op("WavePrefixOp", next_op_idx, "WavePrefixOp", "returns the result of the operation on prior lanes", "hfd8wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value"),
- db_dxil_param(3, "i8", "op", "0=sum,1=product", enum_name="WaveOpKind", is_const=True),
- db_dxil_param(4, "i8", "sop", "sign of operands", enum_name="SignedOpKind", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("QuadReadLaneAt", next_op_idx, "QuadReadLaneAt", "reads from a lane in the quad", "hfd18wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "value to read"),
- db_dxil_param(3, "u32", "quadLane", "lane to read from (0-4)", max_value = 3, is_const=True)])
- next_op_idx += 1
- self.add_enum_type("QuadOpKind", "Kind of quad-level operation", [
- (0, "ReadAcrossX", "returns the value from the other lane in the quad in the horizontal direction"),
- (1, "ReadAcrossY", "returns the value from the other lane in the quad in the vertical direction"),
- (2, "ReadAcrossDiagonal", "returns the value from the lane across the quad in horizontal and vertical direction")])
- self.add_dxil_op("QuadOp", next_op_idx, "QuadOp", "returns the result of a quad-level operation", "hfd8wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "value for operation"),
- db_dxil_param(3, "i8", "op", "operation", enum_name = "QuadOpKind", is_const=True)])
- next_op_idx += 1
- # Add bitcasts
- self.add_dxil_op("BitcastI16toF16", next_op_idx, "BitcastI16toF16", "bitcast between different sizes", "v", "rn", [
- db_dxil_param(0, "h", "", "operation result"),
- db_dxil_param(2, "i16", "value", "input value")])
- next_op_idx += 1
- self.add_dxil_op("BitcastF16toI16", next_op_idx, "BitcastF16toI16", "bitcast between different sizes", "v", "rn", [
- db_dxil_param(0, "i16", "", "operation result"),
- db_dxil_param(2, "h", "value", "input value")])
- next_op_idx += 1
- self.add_dxil_op("BitcastI32toF32", next_op_idx, "BitcastI32toF32", "bitcast between different sizes", "v", "rn", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "value", "input value")])
- next_op_idx += 1
- self.add_dxil_op("BitcastF32toI32", next_op_idx, "BitcastF32toI32", "bitcast between different sizes", "v", "rn", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "f", "value", "input value")])
- next_op_idx += 1
- self.add_dxil_op("BitcastI64toF64", next_op_idx, "BitcastI64toF64", "bitcast between different sizes", "v", "rn", [
- db_dxil_param(0, "d", "", "operation result"),
- db_dxil_param(2, "i64", "value", "input value")])
- next_op_idx += 1
- self.add_dxil_op("BitcastF64toI64", next_op_idx, "BitcastF64toI64", "bitcast between different sizes", "v", "rn", [
- db_dxil_param(0, "i64", "", "operation result"),
- db_dxil_param(2, "d", "value", "input value")])
- next_op_idx += 1
-
- self.add_dxil_op("LegacyF32ToF16", next_op_idx, "LegacyF32ToF16", "legacy fuction to convert float (f32) to half (f16) (this is not related to min-precision)", "v", "rn", [
- db_dxil_param(0, "i32", "", "low 16 bits - half value, high 16 bits - zeroes"),
- db_dxil_param(2, "f", "value", "float value to convert")])
- next_op_idx += 1
- self.add_dxil_op("LegacyF16ToF32", next_op_idx, "LegacyF16ToF32", "legacy fuction to convert half (f16) to float (f32) (this is not related to min-precision)", "v", "rn", [
- db_dxil_param(0, "f", "", "converted float value"),
- db_dxil_param(2, "i32", "value", "half value to convert")])
- next_op_idx += 1
- self.add_dxil_op("LegacyDoubleToFloat", next_op_idx, "LegacyDoubleToFloat", "legacy fuction to convert double to float", "v", "rn", [
- db_dxil_param(0, "f", "", "float value"),
- db_dxil_param(2, "d", "value", "double value to convert")])
- next_op_idx += 1
- self.add_dxil_op("LegacyDoubleToSInt32", next_op_idx, "LegacyDoubleToSInt32", "legacy fuction to convert double to int32", "v", "rn", [
- db_dxil_param(0, "i32", "", "i32 value"),
- db_dxil_param(2, "d", "value", "double value to convert")])
- next_op_idx += 1
- self.add_dxil_op("LegacyDoubleToUInt32", next_op_idx, "LegacyDoubleToUInt32", "legacy fuction to convert double to uint32", "v", "rn", [
- db_dxil_param(0, "i32", "", "i32 value"),
- db_dxil_param(2, "d", "value", "double value to convert")])
- next_op_idx += 1
- self.add_dxil_op("WaveAllBitCount", next_op_idx, "WaveAllOp", "returns the count of bits set to 1 across the wave", "v", "", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i1", "value", "input value")])
- next_op_idx += 1
- # WavePrefixBitCount has different signature compare to WavePrefixOp, set its opclass to WavePrefixOp is not correct.
- # It works now because WavePrefixOp and WavePrefixBitCount don't interfere on overload types.
- # Keep it unchanged for back-compat.
- self.add_dxil_op("WavePrefixBitCount", next_op_idx, "WavePrefixOp", "returns the count of bits set to 1 on prior lanes", "v", "", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i1", "value", "input value")])
- next_op_idx += 1
- # End of DXIL 1.0 opcodes.
- self.set_op_count_for_version(1, 0, next_op_idx)
- self.add_dxil_op("AttributeAtVertex", next_op_idx, "AttributeAtVertex", "returns the values of the attributes at the vertex.", "hfiw", "rn", [
- db_dxil_param(0, "$o", "", "result"),
- db_dxil_param(2, "i32", "inputSigId", "input signature element ID"),
- db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"),
- db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute"),
- db_dxil_param(5, "i8", "VertexID", "Vertex Index")
- ])
- next_op_idx += 1
- self.add_dxil_op("ViewID", next_op_idx, "ViewID", "returns the view index", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- # End of DXIL 1.1 opcodes.
- self.set_op_count_for_version(1, 1, next_op_idx)
- self.add_dxil_op("RawBufferLoad", next_op_idx, "RawBufferLoad", "reads from a raw buffer and structured buffer", "hfwidl", "ro", [
- db_dxil_param(0, "$r", "", "the loaded value"),
- db_dxil_param(2, "res", "srv", "handle of TypedBuffer SRV to sample"),
- db_dxil_param(3, "i32", "index", "element index for StructuredBuffer, or byte offset for ByteAddressBuffer"),
- db_dxil_param(4, "i32", "elementOffset", "offset into element for StructuredBuffer, or undef for ByteAddressBuffer"),
- db_dxil_param(5, "i8", "mask", "loading value mask", is_const=True),
- db_dxil_param(6, "i32", "alignment", "relative load access alignment", is_const=True)],
- counters=('tex_load',))
- next_op_idx += 1
- self.add_dxil_op("RawBufferStore", next_op_idx, "RawBufferStore", "writes to a RWByteAddressBuffer or RWStructuredBuffer", "hfwidl", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "uav", "handle of UAV to store to"),
- db_dxil_param(3, "i32", "index", "element index for StructuredBuffer, or byte offset for ByteAddressBuffer"),
- db_dxil_param(4, "i32", "elementOffset", "offset into element for StructuredBuffer, or undef for ByteAddressBuffer"),
- db_dxil_param(5, "$o", "value0", "value"),
- db_dxil_param(6, "$o", "value1", "value"),
- db_dxil_param(7, "$o", "value2", "value"),
- db_dxil_param(8, "$o", "value3", "value"),
- db_dxil_param(9, "i8", "mask", "mask of contiguous components stored starting at first component (valid: 1, 3, 7, 15)", is_const=True),
- db_dxil_param(10, "i32", "alignment", "relative store access alignment", is_const=True)],
- counters=('tex_store',))
- next_op_idx += 1
- # End of DXIL 1.2 opcodes.
- self.set_op_count_for_version(1, 2, next_op_idx)
- assert next_op_idx == 141, "next operation index is %d rather than 141 and thus opcodes are broken" % next_op_idx
- self.add_dxil_op("InstanceID", next_op_idx, "InstanceID", "The user-provided InstanceID on the bottom-level acceleration structure instance within the top-level structure", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("InstanceIndex", next_op_idx, "InstanceIndex", "The autogenerated index of the current instance in the top-level structure", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("HitKind", next_op_idx, "HitKind", "Returns the value passed as HitKind in ReportIntersection(). If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("RayFlags", next_op_idx, "RayFlags", "uint containing the current ray flags.", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("DispatchRaysIndex", next_op_idx, "DispatchRaysIndex", "The current x and y location within the Width and Height", "i", "rn", [
- db_dxil_param(0, "i32", "", "result"),
- db_dxil_param(2, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("DispatchRaysDimensions", next_op_idx, "DispatchRaysDimensions", "The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.", "i", "rn", [
- db_dxil_param(0, "i32", "", "result"),
- db_dxil_param(2, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("WorldRayOrigin", next_op_idx, "WorldRayOrigin", "The world-space origin for the current ray.", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("WorldRayDirection", next_op_idx, "WorldRayDirection", "The world-space direction for the current ray.", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("ObjectRayOrigin", next_op_idx, "ObjectRayOrigin", "Object-space origin for the current ray.", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("ObjectRayDirection", next_op_idx, "ObjectRayDirection", "Object-space direction for the current ray.", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("ObjectToWorld", next_op_idx, "ObjectToWorld", "Matrix for transforming from object-space to world-space.", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i32", "row", "row, relative to the element"),
- db_dxil_param(3, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("WorldToObject", next_op_idx, "WorldToObject", "Matrix for transforming from world-space to object-space.", "f", "rn", [
- db_dxil_param(0, "f", "", "result"),
- db_dxil_param(2, "i32", "row", "row, relative to the element"),
- db_dxil_param(3, "i8", "col", "column, relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("RayTMin", next_op_idx, "RayTMin", "float representing the parametric starting point for the ray.", "f", "rn", [
- db_dxil_param(0, "f", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("RayTCurrent", next_op_idx, "RayTCurrent", "float representing the current parametric ending point for the ray", "f", "ro", [
- db_dxil_param(0, "f", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("IgnoreHit", next_op_idx, "IgnoreHit", "Used in an any hit shader to reject an intersection and terminate the shader", "v", "nr", [
- db_dxil_param(0, "v", "", "")])
- next_op_idx += 1
- self.add_dxil_op("AcceptHitAndEndSearch", next_op_idx, "AcceptHitAndEndSearch", "Used in an any hit shader to abort the ray query and the intersection shader (if any). The current hit is committed and execution passes to the closest hit shader with the closest hit recorded so far", "v", "nr", [
- db_dxil_param(0, "v", "", "")])
- next_op_idx += 1
- self.add_dxil_op("TraceRay", next_op_idx, "TraceRay", "initiates raytrace", "u", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "AccelerationStructure", "Top-level acceleration structure to use"),
- db_dxil_param(3, "i32", "RayFlags", "Valid combination of Ray_flags"),
- db_dxil_param(4, "i32", "InstanceInclusionMask", "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }"),
- db_dxil_param(5, "i32", "RayContributionToHitGroupIndex", "Offset to add into Addressing calculations within shader tables for hit group indexing. Only the bottom 4 bits of this value are used"),
- db_dxil_param(6, "i32", "MultiplierForGeometryContributionToShaderIndex", "Stride to multiply by per-geometry GeometryContributionToHitGroupIndex in Addressing calculations within shader tables for hit group indexing. Only the bottom 4 bits of this value are used"),
- db_dxil_param(7, "i32", "MissShaderIndex", "Miss shader index in Addressing calculations within shader tables. Only the bottom 16 bits of this value are used"),
- db_dxil_param(8, "f", "Origin_X", "Origin x of the ray"),
- db_dxil_param(9, "f", "Origin_Y", "Origin y of the ray"),
- db_dxil_param(10, "f", "Origin_Z", "Origin z of the ray"),
- db_dxil_param(11, "f", "TMin", "Tmin of the ray"),
- db_dxil_param(12, "f", "Direction_X", "Direction x of the ray"),
- db_dxil_param(13, "f", "Direction_Y", "Direction y of the ray"),
- db_dxil_param(14, "f", "Direction_Z", "Direction z of the ray"),
- db_dxil_param(15, "f", "TMax", "Tmax of the ray"),
- db_dxil_param(16, "udt", "payload", "User-defined intersection attribute structure")])
- next_op_idx += 1
- self.add_dxil_op("ReportHit", next_op_idx, "ReportHit", "returns true if hit was accepted", "u", "", [
- db_dxil_param(0, "i1", "", "result"),
- db_dxil_param(2, "f", "THit", "parametric distance of the intersection"),
- db_dxil_param(3, "i32", "HitKind", "User-specified value in range of 0-127 to identify the type of hit. Read by any_hit or closes_hit shaders with HitKind()"),
- db_dxil_param(4, "udt", "Attributes", "User-defined intersection attribute structure")])
- next_op_idx += 1
- self.add_dxil_op("CallShader", next_op_idx, "CallShader", "Call a shader in the callable shader table supplied through the DispatchRays() API", "u", "", [
- db_dxil_param(0, "v", "", "result"),
- db_dxil_param(2, "i32", "ShaderIndex", "Provides index into the callable shader table supplied through the DispatchRays() API"),
- db_dxil_param(3, "udt", "Parameter", "User-defined parameters to pass to the callable shader,This parameter structure must match the parameter structure used in the callable shader pointed to in the shader table")])
- next_op_idx += 1
- self.add_dxil_op("CreateHandleForLib", next_op_idx, "CreateHandleForLib", "create resource handle from resource struct for library", "o", "ro", [
- db_dxil_param(0, "res", "", "result"),
- db_dxil_param(2, "obj", "Resource", "resource to create the handle")])
- next_op_idx += 1
- # Maps to PrimitiveIndex() intrinsics for raytracing (same meaning as PrimitiveID)
- self.add_dxil_op("PrimitiveIndex", next_op_idx, "PrimitiveIndex", "PrimitiveIndex for raytracing shaders", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- # End of DXIL 1.3 opcodes.
- self.set_op_count_for_version(1, 3, next_op_idx)
- assert next_op_idx == 162, "next operation index is %d rather than 162 and thus opcodes are broken" % next_op_idx
- self.add_dxil_op("Dot2AddHalf", next_op_idx, "Dot2AddHalf", "2D half dot product with accumulate to float", "f", "rn", [
- db_dxil_param(0, "$o", "", "accumulated result"),
- db_dxil_param(2, "$o", "acc", "input accumulator"),
- db_dxil_param(3, "h", "ax", "the first component of the first vector"),
- db_dxil_param(4, "h", "ay", "the second component of the first vector"),
- db_dxil_param(5, "h", "bx", "the first component of the second vector"),
- db_dxil_param(6, "h", "by", "the second component of the second vector")],
- counters=('floats',))
- next_op_idx += 1
- self.add_dxil_op("Dot4AddI8Packed", next_op_idx, "Dot4AddPacked", "signed dot product of 4 x i8 vectors packed into i32, with accumulate to i32", "i", "rn", [
- db_dxil_param(0, "i32", "", "accumulated result"),
- db_dxil_param(2, "i32", "acc", "input accumulator"),
- db_dxil_param(3, "i32", "a", "first packed 4 x i8 for dot product"),
- db_dxil_param(4, "i32", "b", "second packed 4 x i8 for dot product")],
- counters=('ints',))
- next_op_idx += 1
- self.add_dxil_op("Dot4AddU8Packed", next_op_idx, "Dot4AddPacked", "unsigned dot product of 4 x u8 vectors packed into i32, with accumulate to i32", "i", "rn", [
- db_dxil_param(0, "i32", "", "accumulated result"),
- db_dxil_param(2, "i32", "acc", "input accumulator"),
- db_dxil_param(3, "i32", "a", "first packed 4 x u8 for dot product"),
- db_dxil_param(4, "i32", "b", "second packed 4 x u8 for dot product")],
- counters=('uints',))
- next_op_idx += 1
- # End of DXIL 1.4 opcodes.
- self.set_op_count_for_version(1, 4, next_op_idx)
- assert next_op_idx == 165, "next operation index is %d rather than 165 and thus opcodes are broken" % next_op_idx
- self.add_dxil_op("WaveMatch", next_op_idx, "WaveMatch", "returns the bitmask of active lanes that have the same value", "hfd8wil", "", [
- db_dxil_param(0, "fouri32", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value")])
- next_op_idx += 1
- self.add_dxil_op("WaveMultiPrefixOp", next_op_idx, "WaveMultiPrefixOp", "returns the result of the operation on groups of lanes identified by a bitmask", "hfd8wil", "", [
- db_dxil_param(0, "$o", "", "operation result"),
- db_dxil_param(2, "$o", "value", "input value"),
- db_dxil_param(3, "i32", "mask0", "mask 0"),
- db_dxil_param(4, "i32", "mask1", "mask 1"),
- db_dxil_param(5, "i32", "mask2", "mask 2"),
- db_dxil_param(6, "i32", "mask3", "mask 3"),
- db_dxil_param(7, "i8", "op", "operation", enum_name="WaveMultiPrefixOpKind", is_const=True),
- db_dxil_param(8, "i8", "sop", "sign of operands", enum_name="SignedOpKind", is_const=True)])
- next_op_idx += 1
- self.add_enum_type("WaveMultiPrefixOpKind", "Kind of cross-lane for multi-prefix operation", [
- (0, "Sum", "sum of values"),
- (1, "And", "bitwise and of values"),
- (2, "Or", "bitwise or of values"),
- (3, "Xor", "bitwise xor of values"),
- (4, "Product", "product of values")])
- self.add_dxil_op("WaveMultiPrefixBitCount", next_op_idx, "WaveMultiPrefixBitCount", "returns the count of bits set to 1 on groups of lanes identified by a bitmask", "v", "", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i1", "value", "input value"),
- db_dxil_param(3, "i32", "mask0", "mask 0"),
- db_dxil_param(4, "i32", "mask1", "mask 1"),
- db_dxil_param(5, "i32", "mask2", "mask 2"),
- db_dxil_param(6, "i32", "mask3", "mask 3")])
- next_op_idx += 1
- # Mesh Shader
- self.add_dxil_op("SetMeshOutputCounts", next_op_idx, "SetMeshOutputCounts", "Mesh shader intrinsic SetMeshOutputCounts", "v", "", [
- retvoid_param,
- db_dxil_param(2, "i32", "numVertices", "number of output vertices"),
- db_dxil_param(3, "i32", "numPrimitives", "number of output primitives")])
- next_op_idx += 1
- self.add_dxil_op("EmitIndices", next_op_idx, "EmitIndices", "emit a primitive's vertex indices in a mesh shader", "v", "", [
- retvoid_param,
- db_dxil_param(2, "u32", "PrimitiveIndex", "a primitive's index"),
- db_dxil_param(3, "u32", "VertexIndex0", "a primitive's first vertex index"),
- db_dxil_param(4, "u32", "VertexIndex1", "a primitive's second vertex index"),
- db_dxil_param(5, "u32", "VertexIndex2", "a primitive's third vertex index")])
- next_op_idx += 1
- self.add_dxil_op("GetMeshPayload", next_op_idx, "GetMeshPayload", "get the mesh payload which is from amplification shader", "u", "ro", [
- db_dxil_param(0, "$o", "", "mesh payload result")])
- next_op_idx += 1
- self.add_dxil_op("StoreVertexOutput", next_op_idx, "StoreVertexOutput", "stores the value to mesh shader vertex output", "hfwi", "", [
- retvoid_param,
- db_dxil_param(2, "u32", "outputSigId", "vertex output signature element ID"),
- db_dxil_param(3, "u32", "rowIndex", "row index relative to element"),
- db_dxil_param(4, "u8", "colIndex", "column index relative to element"),
- db_dxil_param(5, "$o", "value", "value to store"),
- db_dxil_param(6, "u32", "vertexIndex", "vertex index")],
- counters=('sig_st',))
- next_op_idx += 1
- self.add_dxil_op("StorePrimitiveOutput", next_op_idx, "StorePrimitiveOutput", "stores the value to mesh shader primitive output", "hfwi", "", [
- retvoid_param,
- db_dxil_param(2, "u32", "outputSigId", "primitive output signature element ID"),
- db_dxil_param(3, "u32", "rowIndex", "row index relative to element"),
- db_dxil_param(4, "u8", "colIndex", "column index relative to element"),
- db_dxil_param(5, "$o", "value", "value to store"),
- db_dxil_param(6, "u32", "primitiveIndex", "primitive index")],
- counters=('sig_st',))
- next_op_idx += 1
- # Amplification Shader
- self.add_dxil_op("DispatchMesh", next_op_idx, "DispatchMesh", "Amplification shader intrinsic DispatchMesh", "u", "", [
- retvoid_param,
- db_dxil_param(2, "i32", "threadGroupCountX", "thread group count x"),
- db_dxil_param(3, "i32", "threadGroupCountY", "thread group count y"),
- db_dxil_param(4, "i32", "threadGroupCountZ", "thread group count z"),
- db_dxil_param(5, "$o", "payload", "payload")])
- next_op_idx += 1
- # Sampler feedback
- self.add_dxil_op("WriteSamplerFeedback", next_op_idx, "WriteSamplerFeedback", "updates a feedback texture for a sampling operation", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"),
- db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"),
- db_dxil_param(4, "res", "sampler", "handle of sampler"),
- db_dxil_param(5, "f", "c0", "coordinate c0"),
- db_dxil_param(6, "f", "c1", "coordinate c1"),
- db_dxil_param(7, "f", "c2", "coordinate c2"),
- db_dxil_param(8, "f", "c3", "coordinate c3"),
- db_dxil_param(9, "f", "clamp", "clamp")],
- counters=('tex_store',))
- next_op_idx += 1
- self.add_dxil_op("WriteSamplerFeedbackBias", next_op_idx, "WriteSamplerFeedbackBias", "updates a feedback texture for a sampling operation with a bias on the mipmap level", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"),
- db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"),
- db_dxil_param(4, "res", "sampler", "handle of sampler"),
- db_dxil_param(5, "f", "c0", "coordinate c0"),
- db_dxil_param(6, "f", "c1", "coordinate c1"),
- db_dxil_param(7, "f", "c2", "coordinate c2"),
- db_dxil_param(8, "f", "c3", "coordinate c3"),
- db_dxil_param(9, "f", "bias", "bias in [-16.f,15.99f]"),
- db_dxil_param(10, "f", "clamp", "clamp")],
- counters=('tex_store',))
- next_op_idx += 1
- self.add_dxil_op("WriteSamplerFeedbackLevel", next_op_idx, "WriteSamplerFeedbackLevel", "updates a feedback texture for a sampling operation with a mipmap-level offset", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"),
- db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"),
- db_dxil_param(4, "res", "sampler", "handle of sampler"),
- db_dxil_param(5, "f", "c0", "coordinate c0"),
- db_dxil_param(6, "f", "c1", "coordinate c1"),
- db_dxil_param(7, "f", "c2", "coordinate c2"),
- db_dxil_param(8, "f", "c3", "coordinate c3"),
- db_dxil_param(9, "f", "lod", "LOD")],
- counters=('tex_store',))
- next_op_idx += 1
- self.add_dxil_op("WriteSamplerFeedbackGrad", next_op_idx, "WriteSamplerFeedbackGrad", "updates a feedback texture for a sampling operation with explicit gradients", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"),
- db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"),
- db_dxil_param(4, "res", "sampler", "handle of sampler"),
- db_dxil_param(5, "f", "c0", "coordinate c0"),
- db_dxil_param(6, "f", "c1", "coordinate c1"),
- db_dxil_param(7, "f", "c2", "coordinate c2"),
- db_dxil_param(8, "f", "c3", "coordinate c3"),
- db_dxil_param(9, "f", "ddx0", "rate of change of coordinate c0 in the x direction"),
- db_dxil_param(10, "f", "ddx1", "rate of change of coordinate c1 in the x direction"),
- db_dxil_param(11, "f", "ddx2", "rate of change of coordinate c2 in the x direction"),
- db_dxil_param(12, "f", "ddy0", "rate of change of coordinate c0 in the y direction"),
- db_dxil_param(13, "f", "ddy1", "rate of change of coordinate c1 in the y direction"),
- db_dxil_param(14, "f", "ddy2", "rate of change of coordinate c2 in the y direction"),
- db_dxil_param(15, "f", "clamp", "clamp")],
- counters=('tex_store',))
- next_op_idx += 1
- # RayQuery
- self.add_dxil_op("AllocateRayQuery", next_op_idx, "AllocateRayQuery", "allocates space for RayQuery and return handle", "v", "", [
- db_dxil_param(0, "i32", "", "handle to RayQuery state"),
- db_dxil_param(2, "u32", "constRayFlags", "Valid combination of RAY_FLAGS", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_TraceRayInline", next_op_idx, "RayQuery_TraceRayInline", "initializes RayQuery for raytrace", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "res", "accelerationStructure", "Top-level acceleration structure to use"),
- db_dxil_param(4, "i32", "rayFlags", "Valid combination of RAY_FLAGS, combined with constRayFlags provided to AllocateRayQuery"),
- db_dxil_param(5, "i32", "instanceInclusionMask", "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }"),
- db_dxil_param(6, "f", "origin_X", "Origin x of the ray"),
- db_dxil_param(7, "f", "origin_Y", "Origin y of the ray"),
- db_dxil_param(8, "f", "origin_Z", "Origin z of the ray"),
- db_dxil_param(9, "f", "tMin", "Tmin of the ray"),
- db_dxil_param(10, "f", "direction_X", "Direction x of the ray"),
- db_dxil_param(11, "f", "direction_Y", "Direction y of the ray"),
- db_dxil_param(12, "f", "direction_Z", "Direction z of the ray"),
- db_dxil_param(13, "f", "tMax", "Tmax of the ray")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_Proceed", next_op_idx, "RayQuery_Proceed", "advances a ray query", "1", "", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_Abort", next_op_idx, "RayQuery_Abort", "aborts a ray query", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommitNonOpaqueTriangleHit", next_op_idx, "RayQuery_CommitNonOpaqueTriangleHit", "commits a non opaque triangle hit", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommitProceduralPrimitiveHit", next_op_idx, "RayQuery_CommitProceduralPrimitiveHit", "commits a procedural primitive hit", "v", "", [
- db_dxil_param(0, "v", "", ""),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "f", "t", "Procedural primitive hit distance (t) to commit.")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedStatus", next_op_idx, "RayQuery_StateScalar", "returns uint status (COMMITTED_STATUS) of the committed hit in a ray query", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateType", next_op_idx, "RayQuery_StateScalar", "returns uint candidate type (CANDIDATE_TYPE) of the current hit candidate in a ray query, after Proceed() has returned true", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateObjectToWorld3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from object-space to world-space for a candidate hit.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"),
- db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateWorldToObject3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from world-space to object-space for a candidate hit.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"),
- db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedObjectToWorld3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from object-space to world-space for a Committed hit.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"),
- db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedWorldToObject3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from world-space to object-space for a Committed hit.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"),
- db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateProceduralPrimitiveNonOpaque", next_op_idx, "RayQuery_StateScalar", "returns if current candidate procedural primitive is non opaque", "1", "ro", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateTriangleFrontFace", next_op_idx, "RayQuery_StateScalar", "returns if current candidate triangle is front facing", "1", "ro", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedTriangleFrontFace", next_op_idx, "RayQuery_StateScalar", "returns if current committed triangle is front facing", "1", "ro", [
- db_dxil_param(0, "i1", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateTriangleBarycentrics", next_op_idx, "RayQuery_StateVector", "returns candidate triangle hit barycentrics", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedTriangleBarycentrics", next_op_idx, "RayQuery_StateVector", "returns committed triangle hit barycentrics", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_RayFlags", next_op_idx, "RayQuery_StateScalar", "returns ray flags", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_WorldRayOrigin", next_op_idx, "RayQuery_StateVector", "returns world ray origin", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_WorldRayDirection", next_op_idx, "RayQuery_StateVector", "returns world ray direction", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_RayTMin", next_op_idx, "RayQuery_StateScalar", "returns float representing the parametric starting point for the ray.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateTriangleRayT", next_op_idx, "RayQuery_StateScalar", "returns float representing the parametric point on the ray for the current candidate triangle hit.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedRayT", next_op_idx, "RayQuery_StateScalar", "returns float representing the parametric point on the ray for the current committed hit.", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateInstanceIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit instance index", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateInstanceID", next_op_idx, "RayQuery_StateScalar", "returns candidate hit instance ID", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateGeometryIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit geometry index", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidatePrimitiveIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit geometry index", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateObjectRayOrigin", next_op_idx, "RayQuery_StateVector", "returns candidate hit object ray origin", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateObjectRayDirection", next_op_idx, "RayQuery_StateVector", "returns candidate object ray direction", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedInstanceIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit instance index", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedInstanceID", next_op_idx, "RayQuery_StateScalar", "returns committed hit instance ID", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedGeometryIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit geometry index", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedPrimitiveIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit geometry index", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedObjectRayOrigin", next_op_idx, "RayQuery_StateVector", "returns committed hit object ray origin", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedObjectRayDirection", next_op_idx, "RayQuery_StateVector", "returns committed object ray direction", "f", "ro", [
- db_dxil_param(0, "f", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
- db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("GeometryIndex", next_op_idx, "GeometryIndex", "The autogenerated index of the current geometry in the bottom-level structure", "i", "rn", [
- db_dxil_param(0, "i32", "", "result")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CandidateInstanceContributionToHitGroupIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit InstanceContributionToHitGroupIndex", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- self.add_dxil_op("RayQuery_CommittedInstanceContributionToHitGroupIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit InstanceContributionToHitGroupIndex", "i", "ro", [
- db_dxil_param(0, "i32", "", "operation result"),
- db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")])
- next_op_idx += 1
- # End of DXIL 1.5 opcodes.
- self.set_op_count_for_version(1, 5, next_op_idx)
- assert next_op_idx == 216, "216 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx
- self.add_dxil_op("AnnotateHandle", next_op_idx, "AnnotateHandle", "annotate handle with resource properties", "v", "rn", [
- db_dxil_param(0, "res", "", "annotated handle"),
- db_dxil_param(2, "res", "res", "input handle"),
- db_dxil_param(3, "resproperty", "props", "details like component type, strutrure stride...", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("CreateHandleFromBinding", next_op_idx, "CreateHandleFromBinding", "create resource handle from binding", "v", "rn", [
- db_dxil_param(0, "res", "", "result"),
- db_dxil_param(2, "resbind", "bind", "resource binding", is_const=True), #{ rangeLowerBound, rangeUpperBound, spaceID, resourceClass }
- db_dxil_param(3, "i32", "index", "index"),
- db_dxil_param(4, "i1", "nonUniformIndex", "non-uniform resource index", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("CreateHandleFromHeap", next_op_idx, "CreateHandleFromHeap", "create resource handle from heap", "v", "rn", [
- db_dxil_param(0, "res", "", "result"),
- db_dxil_param(2, "i32", "index", "heap index"),
- db_dxil_param(3, "i1", "samplerHeap", "If samplerHeap is 1, the heap indexed is the sampler descriptor heap, otherwise it is the CBV_SRV_UAV (resource) descriptor heap", is_const=True),
- db_dxil_param(4, "i1", "nonUniformIndex", "non-uniform resource index", is_const=True)])
- next_op_idx += 1
- self.add_dxil_op("Unpack4x8", next_op_idx, "Unpack4x8", "unpacks 4 8-bit signed or unsigned values into int32 or int16 vector", "iw", "rn", [
- db_dxil_param(0, "$vec4", "", "result"),
- db_dxil_param(2, "i8", "unpackMode", "signed/unsigned"),
- db_dxil_param(3, "i32", "pk", "packed 4 x i8")])
- next_op_idx += 1
- self.add_dxil_op("Pack4x8", next_op_idx, "Pack4x8", "packs vector of 4 signed or unsigned values into a packed datatype, drops or clamps unused bits", "iw", "rn", [
- db_dxil_param(0, "i32", "", "result packed 4 x i8"),
- db_dxil_param(2, "i8", "packMode", "trunc/unsigned clamp/signed clamp"),
- db_dxil_param(3, "$o", "x", "the first component of the vector"),
- db_dxil_param(4, "$o", "y", "the second component of the vector"),
- db_dxil_param(5, "$o", "z", "the third component of the vector"),
- db_dxil_param(6, "$o", "w", "the fourth component of the vector")])
- next_op_idx += 1
- self.add_dxil_op("IsHelperLane", next_op_idx, "IsHelperLane", "returns true on helper lanes in pixel shaders", "1", "ro", [
- db_dxil_param(0, "i1", "", "result")])
- next_op_idx += 1
- # End of DXIL 1.6 opcodes.
- self.set_op_count_for_version(1, 6, next_op_idx)
- assert next_op_idx == 222, "222 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx
- # Set interesting properties.
- self.build_indices()
- for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp".split(","):
- self.name_idx[i].is_gradient = True
- for i in "DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY".split(","):
- assert self.name_idx[i].is_gradient == True, "all derivatives are marked as requiring gradients"
- self.name_idx[i].is_deriv = True
- # TODO - some arguments are required to be immediate constants in DXIL, eg resource kinds; add this information
- # consider - report instructions that are overloaded on a single type, then turn them into non-overloaded version of that type
- self.verify_dense(self.get_dxil_insts(), lambda x : x.dxil_opid, lambda x : x.name)
- for i in self.instr:
- self.verify_dense(i.ops, lambda x : x.pos, lambda x : i.name)
- for i in self.instr:
- if i.is_dxil_op:
- assert i.oload_types != "", "overload for DXIL operation %s should not be empty - use void if n/a" % (i.name)
- assert i.oload_types == "v" or i.oload_types.find("v") < 0, "void overload should be exclusive to other types (%s)" % i.name
- assert type(i.oload_types) is str, "overload for %s should be a string - use empty if n/a" % (i.name)
- # Verify that all operations in each class have the same signature.
- import itertools
- class_sort_func = lambda x, y: x < y
- class_key_func = lambda x : x.dxil_class
- instr_ordered_by_class = sorted([i for i in self.instr if i.is_dxil_op], key=class_key_func)
- instr_grouped_by_class = itertools.groupby(instr_ordered_by_class, key=class_key_func)
- def calc_oload_sig(inst):
- result = ""
- for o in inst.ops:
- result += o.llvm_type
- return result
- for k, g in instr_grouped_by_class:
- group = list(g)
- if len(group) > 1:
- first = group[0]
- first_group = calc_oload_sig(first)
- for other in group[1:]:
- other_group = calc_oload_sig(other)
- # TODO: uncomment assert when opcodes are fixed
- #assert first_group == other_group, "overload signature %s for instruction %s differs from %s in %s" % (first.name, first_group, other.name, other_group)
- def populate_extended_docs(self):
- "Update the documentation with text from external files."
- inst_starter = "* Inst: "
- block_starter = "* BLOCK-BEGIN"
- block_end = "* BLOCK-END"
- thisdir = os.path.dirname(os.path.realpath(__file__))
- with open(os.path.join(thisdir, "hctdb_inst_docs.txt")) as ops_file:
- inst_name = ""
- inst_doc = ""
- inst_remarks = ""
- is_block = False
- for idx, line in enumerate(ops_file):
- if line.startswith("#"): continue
- if line.startswith(block_starter):
- assert is_block == False, "unexpected block begin at line %i" % (idx+1)
- is_block = True
- continue
- if line.startswith(block_end):
- assert is_block == True, "unexpected block end at line %i" % (idx+1)
- is_block = False
- continue
- if line.startswith(inst_starter):
- if inst_name:
- # print(inst_name + " - " + inst_remarks.strip())
- self.name_idx[inst_name].doc = inst_doc
- self.name_idx[inst_name].remarks = inst_remarks.strip()
- inst_remarks = ""
- line = line[len(inst_starter):]
- sep_idx = line.find("-")
- inst_name = line[:sep_idx].strip()
- inst_doc = line[sep_idx+1:].strip()
- else:
- inst_remarks += line if is_block else "\n" + line.strip()
- if inst_name:
- self.name_idx[inst_name].remarks = inst_remarks.strip()
-
- def populate_metadata(self):
- # For now, simply describe the allowed named metadata.
- m = self.metadata
- m.append(db_dxil_metadata("dx.controlflow.hints", "Provides control flow hints to an instruction."))
- m.append(db_dxil_metadata("dx.entryPoints", "Entry point functions."))
- m.append(db_dxil_metadata("dx.precise", "Marks an instruction as precise."))
- m.append(db_dxil_metadata("dx.resources", "Resources used by the entry point shaders."))
- m.append(db_dxil_metadata("dx.shaderModel", "Shader model for the module."))
- m.append(db_dxil_metadata("dx.typeAnnotations", "Provides annotations for types."))
- m.append(db_dxil_metadata("dx.typevar.*", "."))
- m.append(db_dxil_metadata("dx.valver", "Optional validator version."))
- m.append(db_dxil_metadata("dx.version", "Optional DXIL version for the module."))
- # dx.typevar.* is not the name of metadata, but the prefix for global variables
- # that will be referenced by structure type annotations.
- def populate_passes(self):
- # Populate passes and their options.
- p = self.passes
- category_lib = "set this before add_pass"
- def add_pass(name, type_name, doc, opts):
- apass = db_dxil_pass(name, type_name=type_name, doc=doc, category_lib=category_lib)
- for o in opts:
- assert 'n' in o, "option in %s has no 'n' member" % name
- apass.args.append(db_dxil_pass_arg(o['n'], ident=o.get('i'), type_name=o.get('t'), is_ctor_param=o.get('c'), doc=o.get('d')))
- p.append(apass)
- category_lib = "llvm"
- # Add discriminators is a DWARF 4 thing, useful for the profiler.
- # Consider removing lib\Transforms\Utils\AddDiscriminators.cpp altogether
- add_pass("add-discriminators", "AddDiscriminators", "Add DWARF path discriminators",
- [{'n':"no-discriminators", 'i':"NoDiscriminators", 't':"bool"}])
- # Sample profile is part of the sample profiling infrastructure.
- # Consider removing lib\Transforms\Scalar\SampleProfile.cpp
- add_pass("sample-profile", "SampleProfileLoader", "Sample Profile loader", [
- {'n':"sample-profile-file", 'i':"SampleProfileFile", 't':"string"},
- {'n':"sample-profile-max-propagate-iterations", 'i':"SampleProfileMaxPropagateIterations", 't':"unsigned"}])
- # inline and always-inline share a base class - those are the arguments we document for each of them.
- inliner_args = [
- {'n':'InsertLifetime', 't':'bool', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'},
- {'n':'InlineThreshold', 't':'unsigned', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'}]
- add_pass("inline", "SimpleInliner", "Function Integration/Inlining", inliner_args)
- # {'n':"OptLevel", 't':"unsigned", 'c':1},
- # {'n':"SizeOptLevel", 't':'unsigned', 'c':1}
- add_pass('always-inline', 'AlwaysInliner', 'Inliner for always_inline functions', inliner_args)
- # {'n':'InsertLifetime', 't':'bool', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'}
- # Consider a review of the target-specific wrapper.
- add_pass("tti", "TargetTransformInfoWrapperPass", "Target Transform Information", [
- {'n':'TIRA', 't':'TargetIRAnalysis', 'c':1}])
- add_pass("verify", "VerifierLegacyPass", "Module Verifier", [
- {'n':'FatalErrors', 't':'bool', 'c':1},
- {'n':'verify-debug-info', 'i':'VerifyDebugInfo', 't':'bool'}])
- add_pass("targetlibinfo", "TargetLibraryInfoWrapperPass", "Target Library Information", [
- {'n':'TLIImpl', 't':'TargetLibraryInfoImpl', 'c':1},
- {'n':'vector-library', 'i':'ClVectorLibrary', 't':'TargetLibraryInfoImpl::VectorLibrary'}])
- add_pass("cfl-aa", "CFLAliasAnalysis", "CFL-Based AA implementation", [])
- add_pass("tbaa", "TypeBasedAliasAnalysis", "Type-Based Alias Analysis", [
- {'n':"enable-tbaa", 'i':'EnableTBAA', 't':'bool', 'd':'Use to disable TBAA functionality'}])
- add_pass("scoped-noalias", "ScopedNoAliasAA", "Scoped NoAlias Alias Analysis", [
- {'n':"enable-scoped-noalias", 'i':'EnableScopedNoAlias', 't':'bool', 'd':'Use to disable scoped no-alias'}])
- add_pass("basicaa", "BasicAliasAnalysis", "Basic Alias Analysis (stateless AA impl)", [])
- add_pass("simplifycfg", "CFGSimplifyPass", "Simplify the CFG", [
- {'n':'Threshold', 't':'int', 'c':1},
- {'n':'Ftor', 't':'std::function<bool(const Function &)>', 'c':1},
- {'n':'bonus-inst-threshold', 'i':'UserBonusInstThreshold', 't':'unsigned', 'd':'Control the number of bonus instructions (default = 1)'}])
- # UseNewSROA is used by PassManagerBuilder::populateFunctionPassManager, not a pass per se.
- add_pass("sroa", "SROA", "Scalar Replacement Of Aggregates", [
- {'n':'RequiresDomTree', 't':'bool', 'c':1},
- {'n':'SkipHLSLMat', 't':'bool', 'c':1},
- {'n':'force-ssa-updater', 'i':'ForceSSAUpdater', 't':'bool', 'd':'Force the pass to not use DomTree and mem2reg, insteadforming SSA values through the SSAUpdater infrastructure.'},
- {'n':'sroa-random-shuffle-slices', 'i':'SROARandomShuffleSlices', 't':'bool', 'd':'Enable randomly shuffling the slices to help uncover instability in their order.'},
- {'n':'sroa-strict-inbounds', 'i':'SROAStrictInbounds', 't':'bool', 'd':'Experiment with completely strict handling of inbounds GEPs.'}])
- add_pass("dxil-cond-mem2reg", "DxilConditionalMem2Reg", "Dxil Conditional Mem2Reg", [
- {'n':'NoOpt', 't':'bool', 'c':1},
- ])
- add_pass('scalarrepl', 'SROA_DT', 'Scalar Replacement of Aggregates (DT)', [
- {'n':'Threshold', 't':'int', 'c':1},
- {'n':'StructMemberThreshold', 't':'int', 'c':1},
- {'n':'ArrayElementThreshold', 't':'int', 'c':1},
- {'n':'ScalarLoadThreshold', 't':'int', 'c':1}])
- add_pass('scalarrepl-ssa', 'SROA_SSAUp', 'Scalar Replacement of Aggregates (SSAUp)', [
- {'n':'Threshold', 't':'int', 'c':1},
- {'n':'StructMemberThreshold', 't':'int', 'c':1},
- {'n':'ArrayElementThreshold', 't':'int', 'c':1},
- {'n':'ScalarLoadThreshold', 't':'int', 'c':1}])
- add_pass('early-cse', 'EarlyCSELegacyPass', 'Early CSE', [])
- # More branch weight support.
- add_pass('lower-expect', 'LowerExpectIntrinsic', "Lower 'expect' Intrinsics", [
- {'n':'likely-branch-weight', 'i':'LikelyBranchWeight', 't':'uint32_t', 'd':'Weight of the branch likely to be taken (default = 64)'},
- {'n':'unlikely-branch-weight', 'i':'UnlikelyBranchWeight', 't':'uint32_t', 'd':'Weight of the branch unlikely to be taken (default = 4)'}])
- # Consider removing lib\Transforms\Utils\SymbolRewriter.cpp
- add_pass('rewrite-symbols', 'RewriteSymbols', 'Rewrite Symbols', [
- {'n':'DL', 't':'SymbolRewriter::RewriteDescriptorList', 'c':1},
- {'n':'rewrite-map-file', 'i':'RewriteMapFiles', 't':'string'}])
- add_pass('mergefunc', 'MergeFunctions', 'Merge Functions', [
- {'n':'mergefunc-sanity', 'i':'NumFunctionsForSanityCheck', 't':'unsigned', 'd':"How many functions in module could be used for MergeFunctions pass sanity check. '0' disables this check. Works only with '-debug' key."}])
- # Consider removing GlobalExtensions globals altogether.
- add_pass('barrier', 'BarrierNoop', 'A No-Op Barrier Pass', [])
- add_pass('dce', 'DCE', 'Dead Code Elimination', [])
- add_pass('die', 'DeadInstElimination', 'Dead Instruction Elimination', [])
- add_pass('globaldce', 'GlobalDCE', 'Dead Global Elimination', [])
- add_pass('mem2reg', 'PromotePass', 'Promote Memory to Register', [])
- add_pass('scalarizer', 'Scalarizer', 'Scalarize vector operations', [])
- category_lib="pix"
- add_pass('hlsl-dxil-add-pixel-hit-instrmentation', 'DxilAddPixelHitInstrumentation', 'DXIL Count completed PS invocations and costs', [
- {'n':'force-early-z','t':'int','c':1},
- {'n':'add-pixel-cost','t':'int','c':1},
- {'n':'rt-width','t':'int','c':1},
- {'n':'sv-position-index','t':'int','c':1},
- {'n':'num-pixels','t':'int','c':1}])
- add_pass('hlsl-dxil-constantColor', 'DxilOutputColorBecomesConstant', 'DXIL Constant Color Mod', [
- {'n':'mod-mode','t':'int','c':1},
- {'n':'constant-red','t':'float','c':1},
- {'n':'constant-green','t':'float','c':1},
- {'n':'constant-blue','t':'float','c':1},
- {'n':'constant-alpha','t':'float','c':1}])
- add_pass('hlsl-dxil-remove-discards', 'DxilRemoveDiscards', 'HLSL DXIL Remove all discard instructions', [])
- add_pass('hlsl-dxil-force-early-z', 'DxilForceEarlyZ', 'HLSL DXIL Force the early Z global flag, if shader has no discard calls', [])
- add_pass('hlsl-dxil-pix-meshshader-output-instrumentation', 'DxilPIXMeshShaderOutputInstrumentation', 'DXIL mesh shader output instrumentation for PIX', [
- {'n':'UAVSize','t':'int','c':1}])
- add_pass('hlsl-dxil-pix-shader-access-instrumentation', 'DxilShaderAccessTracking', 'HLSL DXIL shader access tracking for PIX', [
- {'n':'config','t':'int','c':1},
- {'n':'checkForDynamicIndexing','t':'bool','c':1}])
- add_pass('hlsl-dxil-debug-instrumentation', 'DxilDebugInstrumentation', 'HLSL DXIL debug instrumentation for PIX', [
- {'n':'UAVSize','t':'int','c':1},
- {'n':'parameter0','t':'int','c':1},
- {'n':'parameter1','t':'int','c':1},
- {'n':'parameter2','t':'int','c':1}])
- add_pass('dxil-annotate-with-virtual-regs', 'DxilAnnotateWithVirtualRegister', 'Annotates each instruction in the DXIL module with a virtual register number', [])
- add_pass('dxil-dbg-value-to-dbg-declare', 'DxilDbgValueToDbgDeclare', 'Converts llvm.dbg.value uses to llvm.dbg.declare.', [])
- add_pass('hlsl-dxil-reduce-msaa-to-single', 'DxilReduceMSAAToSingleSample', 'HLSL DXIL Reduce all MSAA reads to single-sample reads', [])
- category_lib="dxil_gen"
- add_pass('hlsl-hlemit', 'HLEmitMetadata', 'HLSL High-Level Metadata Emit.', [])
- add_pass("hl-expand-store-intrinsics", "HLExpandStoreIntrinsics", "Expand HLSL store intrinsics", [])
- add_pass("hl-legalize-parameter", "HLLegalizeParameter", "Legalize parameter", [])
- add_pass('scalarrepl-param-hlsl', 'SROA_Parameter_HLSL', 'Scalar Replacement of Aggregates HLSL (parameters)', [])
- add_pass('static-global-to-alloca', 'LowerStaticGlobalIntoAlloca', 'Lower static global into Alloca', [])
- add_pass('hlmatrixlower', 'HLMatrixLowerPass', 'HLSL High-Level Matrix Lower', [])
- add_pass('matrixbitcastlower', 'MatrixBitcastLowerPass', 'Matrix Bitcast lower', [])
- add_pass("reg2mem_hlsl", "RegToMemHlsl", "Demote values with phi-node usage to stack slots", [])
- add_pass('dynamic-vector-to-array', 'DynamicIndexingVectorToArray', 'Replace dynamic indexing vector with array', [
- {'n':'ReplaceAllVectors','t':'bool','c':1}])
- add_pass('hlsl-dxil-promote-local-resources', 'DxilPromoteLocalResources', 'DXIL promote local resource use', [])
- add_pass('hlsl-dxil-promote-static-resources', 'DxilPromoteStaticResources', 'DXIL promote static resource use', [])
- add_pass('hlsl-dxil-legalize-resources', 'DxilLegalizeResources', 'DXIL legalize resource use', [])
- add_pass('hlsl-dxil-legalize-eval-operations', 'DxilLegalizeEvalOperations', 'DXIL legalize eval operations', [])
- add_pass('dxilgen', 'DxilGenerationPass', 'HLSL DXIL Generation', [
- {'n':'NotOptimized','t':'bool','c':1}])
- add_pass('invalidate-undef-resource', 'InvalidateUndefResources', 'Invalidate undef resources', [])
- add_pass('simplify-inst', 'SimplifyInst', 'Simplify Instructions', [])
- add_pass('hlsl-dxil-precise', 'DxilPrecisePropagatePass', 'DXIL precise attribute propagate', [])
- add_pass('dxil-legalize-sample-offset', 'DxilLegalizeSampleOffsetPass', 'DXIL legalize sample offset', [])
- add_pass('dxil-gvn-hoist', 'DxilSimpleGVNHoist', 'DXIL simple gvn hoist', [])
- add_pass('hlsl-hlensure', 'HLEnsureMetadata', 'HLSL High-Level Metadata Ensure', [])
- add_pass('multi-dim-one-dim', 'MultiDimArrayToOneDimArray', 'Flatten multi-dim array into one-dim array', [])
- add_pass('resource-handle', 'ResourceToHandle', 'Lower resource into handle', [])
- add_pass('hlsl-passes-nopause', 'NoPausePasses', 'Clears metadata used for pause and resume', [])
- add_pass('hlsl-passes-pause', 'PausePasses', 'Prepare to pause passes', [])
- add_pass('hlsl-passes-resume', 'ResumePasses', 'Prepare to resume passes', [])
- add_pass('hlsl-dxil-condense', 'DxilCondenseResources', 'DXIL Condense Resources', [])
- add_pass('hlsl-dxil-lower-handle-for-lib', 'DxilLowerCreateHandleForLib', 'DXIL Lower createHandleForLib', [])
- add_pass('hlsl-dxil-allocate-resources-for-lib', 'DxilAllocateResourcesForLib', 'DXIL Allocate Resources For Library', [])
- add_pass('hlsl-dxil-convergent-mark', 'DxilConvergentMark', 'Mark convergent', [])
- add_pass('hlsl-dxil-convergent-clear', 'DxilConvergentClear', 'Clear convergent before dxil emit', [])
- add_pass('hlsl-dxil-eliminate-output-dynamic', 'DxilEliminateOutputDynamicIndexing', 'DXIL eliminate ouptut dynamic indexing', [])
- add_pass('hlsl-dxilfinalize', 'DxilFinalizeModule', 'HLSL DXIL Finalize Module', [])
- add_pass('hlsl-dxilemit', 'DxilEmitMetadata', 'HLSL DXIL Metadata Emit', [])
- add_pass('hlsl-dxilload', 'DxilLoadMetadata', 'HLSL DXIL Metadata Load', [])
- add_pass('dxil-dfe', 'DxilDeadFunctionElimination', 'Remove all unused function except entry from DxilModule', [])
- add_pass('hl-dfe', 'HLDeadFunctionElimination', 'Remove all unused function except entry from HLModule', [])
- add_pass('hl-preprocess', 'HLPreprocess', 'Preprocess HLModule after inline', [])
- add_pass('hlsl-dxil-expand-trig', 'DxilExpandTrigIntrinsics', 'DXIL expand trig intrinsics', [])
- add_pass('hlsl-hca', 'HoistConstantArray', 'HLSL constant array hoisting', [])
- add_pass('hlsl-dxil-preserve-all-outputs', 'DxilPreserveAllOutputs', 'DXIL write to all outputs in signature', [])
- add_pass('red', 'ReducibilityAnalysis', 'Reducibility Analysis', [])
- add_pass('viewid-state', 'ComputeViewIdState', 'Compute information related to ViewID', [])
- add_pass('hlsl-translate-dxil-opcode-version', 'DxilTranslateRawBuffer', 'Translates one version of dxil to another', [])
- add_pass('hlsl-dxil-cleanup-addrspacecast', 'DxilCleanupAddrSpaceCast', 'HLSL DXIL Cleanup Address Space Cast (part of hlsl-dxilfinalize)', [])
- add_pass('dxil-fix-array-init', 'DxilFixConstArrayInitializer', 'Dxil Fix Array Initializer', [])
- add_pass('hlsl-validate-wave-sensitivity', 'DxilValidateWaveSensitivity', 'HLSL DXIL wave sensitiveity validation', [])
- add_pass('dxil-elim-vector', 'DxilEliminateVector', 'Dxil Eliminate Vectors', [])
- add_pass('dxil-rewrite-output-arg-debug-info', 'DxilRewriteOutputArgDebugInfo', 'Dxil Rewrite Output Arg Debug Info', [])
- add_pass('dxil-finalize-preserves', 'DxilFinalizePreserves', 'Dxil Finalize Preserves', [])
- add_pass('dxil-insert-preserves', 'DxilInsertPreserves', 'Dxil Insert Noops', [
- {'n':'AllowPreserves', 't':'bool', 'c':1},
- ])
- add_pass('dxil-preserves-to-select', 'DxilPreserveToSelect', 'Dxil Preserves To Select', [])
- add_pass('dxil-delete-loop', 'DxilLoopDeletion', 'Dxil Loop Deletion', [])
- add_pass('dxil-value-cache', 'DxilValueCache', 'Dxil Value Cache',[])
- add_pass('hlsl-cleanup-dxbreak', 'CleanupDxBreak', 'HLSL Remove unnecessary dx.break conditions', [])
- add_pass('dxil-rename-resources', 'DxilRenameResources', 'Rename resources to prevent merge by name during linking', [
- {'n':'prefix', 'i':'Prefix', 't':'string', 'd':'Prefix to add to resource names'},
- {'n':'from-binding', 'i':'FromBinding', 't':'bool', 'c':1, 'd':'Append binding to name when bound'},
- {'n':'keep-name', 'i':'KeepName', 't':'bool', 'c':1, 'd':'Keep name when appending binding'},
- ])
- add_pass('hlsl-dxil-resources-to-handle', 'DxilMutateResourceToHandle', 'Mutate resource to handle',[])
- category_lib="llvm"
- add_pass('ipsccp', 'IPSCCP', 'Interprocedural Sparse Conditional Constant Propagation', [])
- add_pass('globalopt', 'GlobalOpt', 'Global Variable Optimizer', [])
- add_pass('deadargelim', 'DAE', 'Dead Argument Elimination', [])
- # Should we get rid of this, or invest in bugpoint support?
- add_pass('deadarghaX0r', 'DAH', 'Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)', [])
- add_pass('instcombine', 'InstructionCombiningPass', 'Combine redundant instructions', [])
- add_pass('prune-eh', 'PruneEH', 'Remove unused exception handling info', [])
- add_pass('functionattrs', 'FunctionAttrs', 'Deduce function attributes', [])
- add_pass('argpromotion', 'ArgPromotion', "Promote 'by reference' arguments to scalars", [
- {'n':'maxElements', 't':'unsigned', 'c':1}])
- add_pass('jump-threading', 'JumpThreading', 'Jump Threading', [
- {'n':'Threshold', 't':'int', 'c':1},
- {'n':'jump-threading-threshold', 'i':'BBDuplicateThreshold', 't':'unsigned', 'd':'Max block size to duplicate for jump threading'}])
- add_pass('correlated-propagation', 'CorrelatedValuePropagation', 'Value Propagation', [])
- # createTailCallEliminationPass is removed - but is this checked before?
- add_pass('reassociate', 'Reassociate', 'Reassociate expressions', [])
- add_pass('loop-rotate', 'LoopRotate', 'Rotate Loops', [
- {'n':'MaxHeaderSize', 't':'int', 'c':1},
- {'n':'rotation-max-header-size', 'i':'DefaultRotationThreshold', 't':'unsigned', 'd':'The default maximum header size for automatic loop rotation'}])
- add_pass('licm', 'LICM', 'Loop Invariant Code Motion', [
- {'n':'disable-licm-promotion', 'i':'DisablePromotion', 't':'bool', 'd':'Disable memory promotion in LICM pass'}])
- add_pass('loop-unswitch', 'LoopUnswitch', 'Unswitch loops', [
- {'n':'Os', 't':'bool', 'c':1, 'd':'Optimize for size'},
- {'n':'loop-unswitch-threshold', 'i':'Threshold', 't':'unsigned', 'd':'Max loop size to unswitch'}])
- # C:\nobackup\work\HLSLonLLVM\lib\Transforms\IPO\PassManagerBuilder.cpp:353
- add_pass('indvars', 'IndVarSimplify', "Induction Variable Simplification", [])
- add_pass('loop-idiom', 'LoopIdiomRecognize', "Recognize loop idioms", [])
- add_pass('dxil-loop-unroll', 'DxilLoopUnroll', 'DxilLoopUnroll', [
- {'n':'MaxIterationAttempt', 't':'unsigned', 'c':1, 'd':'Maximum number of iterations to attempt when iteratively unrolling.'},
- {'n':'OnlyWarnOnFail', 't':'bool', 'c':1, 'd':'Whether to just warn when unrolling fails.'},
- ])
- add_pass('dxil-erase-dead-region', 'DxilEraseDeadRegion', 'DxilEraseDeadRegion', [])
- add_pass('dxil-remove-dead-blocks', 'DxilRemoveDeadBlocks', 'DxilRemoveDeadBlocks', [])
- add_pass('dxil-o0-legalize', 'DxilNoOptLegalize', 'DXIL No-Opt Legalize', [])
- add_pass('dxil-o0-simplify-inst', 'DxilNoOptSimplifyInstructions', 'DXIL No-Opt Simplify Inst', [])
- add_pass('loop-deletion', 'LoopDeletion', "Delete dead loops", [])
- add_pass('loop-interchange', 'LoopInterchange', 'Interchanges loops for cache reuse', [])
- add_pass('loop-unroll', 'LoopUnroll', 'Unroll loops', [
- {'n':'Threshold', 't':'int', 'c':1},
- {'n':'Count', 't':'int', 'c':1},
- {'n':'AllowPartial', 't':'int', 'c':1},
- {'n':'Runtime', 't':'int', 'c':1},
- {'n':'unroll-threshold', 'i':'UnrollThreshold', 't':'unsigned', 'd':'The baseline cost threshold for loop unrolling'},
- {'n':'unroll-percent-dynamic-cost-saved-threshold', 'i':'UnrollPercentDynamicCostSavedThreshold', 't':'unsigned', 'd':'The percentage of estimated dynamic cost which must be saved by unrolling to allow unrolling up to the max threshold.'},
- {'n':'unroll-dynamic-cost-savings-discount', 'i':'UnrollDynamicCostSavingsDiscount', 't':'unsigned', 'd':"This is the amount discounted from the total unroll cost when the unrolled form has a high dynamic cost savings (triggered by the '-unroll-perecent-dynamic-cost-saved-threshold' flag)."},
- {'n':'unroll-max-iteration-count-to-analyze', 'i':'UnrollMaxIterationsCountToAnalyze', 't':'unsigned', 'd':"Don't allow loop unrolling to simulate more than this number of iterations when checking full unroll profitability"},
- {'n':'unroll-count', 'i':'UnrollCount', 't':'unsigned', 'd':'Use this unroll count for all loops including those with unroll_count pragma values, for testing purposes'},
- {'n':'unroll-allow-partial', 'i':'UnrollAllowPartial', 't':'bool', 'd':'Allows loops to be partially unrolled until -unroll-threshold loop size is reached.'},
- {'n':'unroll-runtime', 'i':'UnrollRuntime', 't':'bool', 'd':'Unroll loops with run-time trip counts'},
- {'n':'pragma-unroll-threshold', 'i':'PragmaUnrollThreshold', 't':'unsigned', 'd':'Unrolled size limit for loops with an unroll(full) or unroll_count pragma.'}])
- add_pass('mldst-motion', 'MergedLoadStoreMotion', 'MergedLoadStoreMotion', [])
- add_pass('gvn', 'GVN', 'Global Value Numbering', [
- {'n':'noloads', 't':'bool', 'c':1},
- {'n':'enable-pre', 'i':'EnablePRE', 't':'bool'},
- {'n':'enable-load-pre', 'i':'EnableLoadPRE', 't':'bool'},
- {'n':'max-recurse-depth', 'i':'MaxRecurseDepth', 't':'uint32_t', 'd':'Max recurse depth'}])
- add_pass('sccp', 'SCCP', 'Sparse Conditional Constant Propagation', [])
- add_pass('bdce', 'BDCE', 'Bit-Tracking Dead Code Elimination', [])
- add_pass('dse', 'DSE', 'Dead Store Elimination', [])
- add_pass('loop-reroll', 'LoopReroll', 'Reroll loops', [
- {'n':'max-reroll-increment', 'i':'MaxInc', 't':'unsigned', 'd':'The maximum increment for loop rerolling'},
- {'n':'reroll-num-tolerated-failed-matches', 'i':'NumToleratedFailedMatches', 't':'unsigned', 'd':'The maximum number of failures to tolerate during fuzzy matching.'}])
- add_pass('load-combine', 'LoadCombine', 'Combine Adjacent Loads', [])
- add_pass('adce', 'ADCE', 'Aggressive Dead Code Elimination', [])
- add_pass('float2int', 'Float2Int', 'Float to int', [
- {'n':'float2int-max-integer-bw', 'i':'MaxIntegerBW', 't':'unsigned', 'd':'Max integer bitwidth to consider in float2int'}])
- add_pass('loop-distribute', 'LoopDistribute', 'Loop Distribition', [
- {'n':'loop-distribute-verify', 'i':'LDistVerify', 't':'bool', 'd':'Turn on DominatorTree and LoopInfo verification after Loop Distribution'},
- {'n':'loop-distribute-non-if-convertible', 'i':'DistributeNonIfConvertible', 't':'bool', 'd':'Whether to distribute into a loop that may not be if-convertible by the loop vectorizer'}])
- add_pass('alignment-from-assumptions', 'AlignmentFromAssumptions', 'Alignment from assumptions', [])
- add_pass('strip-dead-prototypes', 'StripDeadPrototypesPass', 'Strip Unused Function Prototypes', [])
- add_pass('elim-avail-extern', 'EliminateAvailableExternally', 'Eliminate Available Externally Globals', [])
- add_pass('constmerge', 'ConstantMerge', 'Merge Duplicate Global Constants', [])
- add_pass('lowerbitsets', 'LowerBitSets', 'Lower bitset metadata', [
- {'n':'lowerbitsets-avoid-reuse', 'i':'AvoidReuse', 't':'bool', 'd':'Try to avoid reuse of byte array addresses using aliases'}])
- # TODO: turn STATISTICS macros into ETW events
- # assert no duplicate names
- self.pass_idx_args = set()
- p_names = set()
- p_ids = set()
- for ap in p:
- assert ap.name not in p_names
- p_names.add(ap.name)
- for anarg in ap.args:
- assert anarg.is_ctor_param or anarg.name not in p_ids, "argument %s in %s is not ctor and is duplicate" % (anarg.name, ap.name)
- if not anarg.is_ctor_param:
- p_ids.add(anarg.name)
- self.pass_idx_args.add(anarg.name)
- def build_semantics(self):
- SemanticKind = db_dxil_enum("SemanticKind", "Semantic kind; Arbitrary or specific system value.", [
- (0, "Arbitrary", ""),
- (1, "VertexID", ""),
- (2, "InstanceID", ""),
- (3, "Position", ""),
- (4, "RenderTargetArrayIndex", ""),
- (5, "ViewPortArrayIndex", ""),
- (6, "ClipDistance", ""),
- (7, "CullDistance", ""),
- (8, "OutputControlPointID", ""),
- (9, "DomainLocation", ""),
- (10, "PrimitiveID", ""),
- (11, "GSInstanceID", ""),
- (12, "SampleIndex", ""),
- (13, "IsFrontFace", ""),
- (14, "Coverage", ""),
- (15, "InnerCoverage", ""),
- (16, "Target", ""),
- (17, "Depth", ""),
- (18, "DepthLessEqual", ""),
- (19, "DepthGreaterEqual", ""),
- (20, "StencilRef", ""),
- (21, "DispatchThreadID", ""),
- (22, "GroupID", ""),
- (23, "GroupIndex", ""),
- (24, "GroupThreadID", ""),
- (25, "TessFactor", ""),
- (26, "InsideTessFactor", ""),
- (27, "ViewID", ""),
- (28, "Barycentrics", ""),
- (29, "ShadingRate", ""),
- (30, "CullPrimitive", ""),
- (31, "Invalid", ""),
- ])
- self.enums.append(SemanticKind)
- SigPointKind = db_dxil_enum("SigPointKind", "Signature Point is more specific than shader stage or signature as it is unique in both stage and item dimensionality or frequency.", [
- (0, "VSIn", "Ordinary Vertex Shader input from Input Assembler"),
- (1, "VSOut", "Ordinary Vertex Shader output that may feed Rasterizer"),
- (2, "PCIn", "Patch Constant function non-patch inputs"),
- (3, "HSIn", "Hull Shader function non-patch inputs"),
- (4, "HSCPIn", "Hull Shader patch inputs - Control Points"),
- (5, "HSCPOut", "Hull Shader function output - Control Point"),
- (6, "PCOut", "Patch Constant function output - Patch Constant data passed to Domain Shader"),
- (7, "DSIn", "Domain Shader regular input - Patch Constant data plus system values"),
- (8, "DSCPIn", "Domain Shader patch input - Control Points"),
- (9, "DSOut", "Domain Shader output - vertex data that may feed Rasterizer"),
- (10, "GSVIn", "Geometry Shader vertex input - qualified with primitive type"),
- (11, "GSIn", "Geometry Shader non-vertex inputs (system values)"),
- (12, "GSOut", "Geometry Shader output - vertex data that may feed Rasterizer"),
- (13, "PSIn", "Pixel Shader input"),
- (14, "PSOut", "Pixel Shader output"),
- (15, "CSIn", "Compute Shader input"),
- (16, "MSIn", "Mesh Shader input"),
- (17, "MSOut", "Mesh Shader vertices output"),
- (18, "MSPOut", "Mesh Shader primitives output"),
- (19, "ASIn", "Amplification Shader input"),
- (21, "Invalid", ""),
- ])
- self.enums.append(SigPointKind)
- PackingKind = db_dxil_enum("PackingKind", "Kind of signature point", [
- (0, "None", "No packing should be performed"),
- (1, "InputAssembler", "Vertex Shader input from Input Assembler"),
- (2, "Vertex", "Vertex that may feed the Rasterizer"),
- (3, "PatchConstant", "Patch constant signature"),
- (4, "Target", "Render Target (Pixel Shader Output)"),
- (5, "Invalid", ""),
- ])
- Float32DenormMode = db_dxil_enum("Float32DenormMode", "float32 denorm behavior", [
- (0, "Any", "Undefined behavior for denormal numbers"),
- (1, "Preserve", "Preserve both input and output"),
- (2, "FTZ", "Preserve denormal inputs. Flush denorm outputs"),
- (3, "Reserve3", "Reserved Value. Not used for now"),
- (4, "Reserve4", "Reserved Value. Not used for now"),
- (5, "Reserve5", "Reserved Value. Not used for now"),
- (6, "Reserve6", "Reserved Value. Not used for now"),
- (7, "Reserve7", "Reserved Value. Not used for now"),
- ])
- self.enums.append(Float32DenormMode)
- SigPointCSV = """
- SigPoint, Related, ShaderKind, PackingKind, SignatureKind
- VSIn, Invalid, Vertex, InputAssembler, Input
- VSOut, Invalid, Vertex, Vertex, Output
- PCIn, HSCPIn, Hull, None, Invalid
- HSIn, HSCPIn, Hull, None, Invalid
- HSCPIn, Invalid, Hull, Vertex, Input
- HSCPOut, Invalid, Hull, Vertex, Output
- PCOut, Invalid, Hull, PatchConstant, PatchConstOrPrim
- DSIn, Invalid, Domain, PatchConstant, PatchConstOrPrim
- DSCPIn, Invalid, Domain, Vertex, Input
- DSOut, Invalid, Domain, Vertex, Output
- GSVIn, Invalid, Geometry, Vertex, Input
- GSIn, GSVIn, Geometry, None, Invalid
- GSOut, Invalid, Geometry, Vertex, Output
- PSIn, Invalid, Pixel, Vertex, Input
- PSOut, Invalid, Pixel, Target, Output
- CSIn, Invalid, Compute, None, Invalid
- MSIn, Invalid, Mesh, None, Invalid
- MSOut, Invalid, Mesh, Vertex, Output
- MSPOut, Invalid, Mesh, Vertex, PatchConstOrPrim
- ASIn, Invalid, Amplification, None, Invalid
- Invalid, Invalid, Invalid, Invalid, Invalid
- """
- table = [list(map(str.strip, line.split(','))) for line in SigPointCSV.splitlines() if line.strip()]
- for row in table[1:]: assert(len(row) == len(table[0])) # Ensure table is rectangular
- # Make sure labels match enums, otherwise the table isn't aligned or in-sync
- if not ([row[0] for row in table[1:]] == SigPointKind.value_names()):
- assert(False and 'SigPointKind does not align with SigPointCSV row labels')
- self.sigpoint_table = table
- self.enums.append(PackingKind)
- SemanticInterpretationKind = db_dxil_enum("SemanticInterpretationKind", "Defines how a semantic is interpreted at a particular SignaturePoint", [
- (0, "NA", "Not Available"),
- (1, "SV", "Normal System Value"),
- (2, "SGV", "System Generated Value (sorted last)"),
- (3, "Arb", "Treated as Arbitrary"),
- (4, "NotInSig", "Not included in signature (intrinsic access)"),
- (5, "NotPacked", "Included in signature, but does not contribute to packing"),
- (6, "Target", "Special handling for SV_Target"),
- (7, "TessFactor", "Special handling for tessellation factors"),
- (8, "Shadow", "Shadow element must be added to a signature for compatibility"),
- (8, "ClipCull", "Special packing rules for SV_ClipDistance or SV_CullDistance"),
- (9, "Invalid", ""),
- ])
- self.enums.append(SemanticInterpretationKind)
- # The following has SampleIndex, Coverage, and InnerCoverage as loaded with instructions rather than from the signature
- SemanticInterpretationCSV = """
- Semantic,VSIn,VSOut,PCIn,HSIn,HSCPIn,HSCPOut,PCOut,DSIn,DSCPIn,DSOut,GSVIn,GSIn,GSOut,PSIn,PSOut,CSIn,MSIn,MSOut,MSPOut,ASIn
- Arbitrary,Arb,Arb,NA,NA,Arb,Arb,Arb,Arb,Arb,Arb,Arb,NA,Arb,Arb,NA,NA,NA,Arb,Arb,NA
- VertexID,SV,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
- InstanceID,SV,Arb,NA,NA,Arb,Arb,NA,NA,Arb,Arb,Arb,NA,Arb,Arb,NA,NA,NA,NA,NA,NA
- Position,Arb,SV,NA,NA,SV,SV,Arb,Arb,SV,SV,SV,NA,SV,SV,NA,NA,NA,SV,NA,NA
- RenderTargetArrayIndex,Arb,SV,NA,NA,SV,SV,Arb,Arb,SV,SV,SV,NA,SV,SV,NA,NA,NA,NA,SV,NA
- ViewPortArrayIndex,Arb,SV,NA,NA,SV,SV,Arb,Arb,SV,SV,SV,NA,SV,SV,NA,NA,NA,NA,SV,NA
- ClipDistance,Arb,ClipCull,NA,NA,ClipCull,ClipCull,Arb,Arb,ClipCull,ClipCull,ClipCull,NA,ClipCull,ClipCull,NA,NA,NA,ClipCull,NA,NA
- CullDistance,Arb,ClipCull,NA,NA,ClipCull,ClipCull,Arb,Arb,ClipCull,ClipCull,ClipCull,NA,ClipCull,ClipCull,NA,NA,NA,ClipCull,NA,NA
- OutputControlPointID,NA,NA,NA,NotInSig,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
- DomainLocation,NA,NA,NA,NA,NA,NA,NA,NotInSig,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
- PrimitiveID,NA,NA,NotInSig,NotInSig,NA,NA,NA,NotInSig,NA,NA,NA,Shadow,SGV,SGV,NA,NA,NA,NA,SV,NA
- GSInstanceID,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NA,NA,NA,NA,NA,NA,NA,NA
- SampleIndex,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,Shadow _41,NA,NA,NA,NA,NA,NA
- IsFrontFace,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,SGV,SGV,NA,NA,NA,NA,NA,NA
- Coverage,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig _50,NotPacked _41,NA,NA,NA,NA,NA
- InnerCoverage,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig _50,NA,NA,NA,NA,NA,NA
- Target,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,Target,NA,NA,NA,NA,NA
- Depth,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotPacked,NA,NA,NA,NA,NA
- DepthLessEqual,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotPacked _50,NA,NA,NA,NA,NA
- DepthGreaterEqual,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotPacked _50,NA,NA,NA,NA,NA
- StencilRef,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotPacked _50,NA,NA,NA,NA,NA
- DispatchThreadID,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NotInSig,NA,NA,NotInSig
- GroupID,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NotInSig,NA,NA,NotInSig
- GroupIndex,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NotInSig,NA,NA,NotInSig
- GroupThreadID,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NotInSig,NA,NA,NotInSig
- TessFactor,NA,NA,NA,NA,NA,NA,TessFactor,TessFactor,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
- InsideTessFactor,NA,NA,NA,NA,NA,NA,TessFactor,TessFactor,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
- ViewID,NotInSig _61,NA,NotInSig _61,NotInSig _61,NA,NA,NA,NotInSig _61,NA,NA,NA,NotInSig _61,NA,NotInSig _61,NA,NA,NotInSig,NA,NA,NA
- Barycentrics,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotPacked _61,NA,NA,NA,NA,NA,NA
- ShadingRate,NA,SV _64,NA,NA,SV _64,SV _64,NA,NA,SV _64,SV _64,SV _64,NA,SV _64,SV _64,NA,NA,NA,NA,SV,NA
- CullPrimitive,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NA,NA,NA,NA,NotPacked,NA
- """
- table = [list(map(str.strip, line.split(','))) for line in SemanticInterpretationCSV.splitlines() if line.strip()]
- for row in table[1:]: assert(len(row) == len(table[0])) # Ensure table is rectangular
- # Make sure labels match enums, otherwise the table isn't aligned or in-sync
- assert(table[0][1:] == SigPointKind.value_names()[:-1]) # exclude Invalid
- if not ([row[0] for row in table[1:]] == SemanticKind.value_names()[:-1]): # exclude Invalid
- assert(False and 'SemanticKind does not align with SemanticInterpretationCSV row labels')
- self.interpretation_table = table
- def build_valrules(self):
- self.add_valrule_msg("Bitcode.Valid", "TODO - Module must be bitcode-valid", "Module bitcode is invalid.")
- self.add_valrule_msg("Container.PartMatches", "DXIL Container Parts must match Module", "Container part '%0' does not match expected for module.")
- self.add_valrule_msg("Container.PartRepeated", "DXIL Container must have only one of each part type", "More than one container part '%0'.")
- self.add_valrule_msg("Container.PartMissing", "DXIL Container requires certain parts, corresponding to module", "Missing part '%0' required by module.")
- self.add_valrule_msg("Container.PartInvalid", "DXIL Container must not contain unknown parts", "Unknown part '%0' found in DXIL container.")
- self.add_valrule_msg("Container.RootSignatureIncompatible", "Root Signature in DXIL Container must be compatible with shader", "Root Signature in DXIL container is not compatible with shader.")
- self.add_valrule("Meta.Required", "TODO - Required metadata missing.")
- self.add_valrule_msg("Meta.Known", "Named metadata should be known", "Named metadata '%0' is unknown.")
- self.add_valrule("Meta.Used", "All metadata must be used by dxil.")
- self.add_valrule_msg("Meta.Target", "Target triple must be 'dxil-ms-dx'", "Unknown target triple '%0'.")
- self.add_valrule("Meta.WellFormed", "TODO - Metadata must be well-formed in operand count and types.")
- self.add_valrule("Meta.SemanticLen", "Semantic length must be at least 1 and at most 64.")
- self.add_valrule_msg("Meta.InterpModeValid", "Interpolation mode must be valid", "Invalid interpolation mode for '%0'.")
- self.add_valrule_msg("Meta.SemaKindValid", "Semantic kind must be valid", "Semantic kind for '%0' is invalid.")
- self.add_valrule_msg("Meta.NoSemanticOverlap", "Semantics must not overlap", "Semantic '%0' overlap at %1.")
- self.add_valrule_msg("Meta.SemaKindMatchesName", "Semantic name must match system value, when defined.", "Semantic name %0 does not match System Value kind %1.")
- self.add_valrule_msg("Meta.DuplicateSysValue", "System value may only appear once in signature", "System value %0 appears more than once in the same signature.")
- self.add_valrule_msg("Meta.SemanticIndexMax", "System value semantics have a maximum valid semantic index", "%0 semantic index exceeds maximum (%1).")
- self.add_valrule_msg("Meta.SystemValueRows", "System value may only have 1 row", "rows for system value semantic %0 must be 1.")
- self.add_valrule_msg("Meta.SemanticShouldBeAllocated", "Semantic should have a valid packing location", "%0 Semantic '%1' should have a valid packing location.")
- self.add_valrule_msg("Meta.SemanticShouldNotBeAllocated", "Semantic should have a packing location of -1", "%0 Semantic '%1' should have a packing location of -1.")
- self.add_valrule("Meta.ValueRange", "Metadata value must be within range.")
- self.add_valrule("Meta.FlagsUsage", "Flags must match usage.")
- self.add_valrule("Meta.DenseResIDs", "Resource identifiers must be zero-based and dense.")
- self.add_valrule_msg("Meta.SignatureOverlap", "Signature elements may not overlap in packing location.", "signature element %0 at location (%1,%2) size (%3,%4) overlaps another signature element.")
- self.add_valrule_msg("Meta.SignatureOutOfRange", "Signature elements must fit within maximum signature size", "signature element %0 at location (%1,%2) size (%3,%4) is out of range.")
- self.add_valrule_msg("Meta.SignatureIndexConflict", "Only elements with compatible indexing rules may be packed together", "signature element %0 at location (%1,%2) size (%3,%4) has an indexing conflict with another signature element packed into the same row.")
- self.add_valrule_msg("Meta.SignatureIllegalComponentOrder", "Component ordering for packed elements must be: arbitrary < system value < system generated value", "signature element %0 at location (%1,%2) size (%3,%4) violates component ordering rule (arb < sv < sgv).")
- self.add_valrule_msg("Meta.SignatureDataWidth", "Data width must be identical for all elements packed into the same row.", "signature element %0 at location (%1, %2) size (%3, %4) has data width that differs from another element packed into the same row.")
- self.add_valrule_msg("Meta.IntegerInterpMode", "Interpolation mode on integer must be Constant", "signature element %0 specifies invalid interpolation mode for integer component type.")
- self.add_valrule_msg("Meta.InterpModeInOneRow", "Interpolation mode must be identical for all elements packed into the same row.", "signature element %0 at location (%1,%2) size (%3,%4) has interpolation mode that differs from another element packed into the same row.")
- self.add_valrule("Meta.SemanticCompType", "%0 must be %1.")
- self.add_valrule_msg("Meta.ClipCullMaxRows", "Combined elements of SV_ClipDistance and SV_CullDistance must fit in two rows.", "ClipDistance and CullDistance occupy more than the maximum of 2 rows combined.")
- self.add_valrule_msg("Meta.ClipCullMaxComponents", "Combined elements of SV_ClipDistance and SV_CullDistance must fit in 8 components", "ClipDistance and CullDistance use more than the maximum of 8 components combined.")
- self.add_valrule("Meta.SignatureCompType", "signature %0 specifies unrecognized or invalid component type.")
- self.add_valrule("Meta.TessellatorPartition", "Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.")
- self.add_valrule("Meta.TessellatorOutputPrimitive", "Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.")
- self.add_valrule("Meta.MaxTessFactor", "Hull Shader MaxTessFactor must be [%0..%1]. %2 specified.")
- self.add_valrule("Meta.ValidSamplerMode", "Invalid sampler mode on sampler .")
- self.add_valrule("Meta.GlcNotOnAppendConsume", "globallycoherent cannot be used with append/consume buffers: '%0'.")
- self.add_valrule_msg("Meta.StructBufAlignment", "StructuredBuffer stride not aligned","structured buffer element size must be a multiple of %0 bytes (actual size %1 bytes).")
- self.add_valrule_msg("Meta.StructBufAlignmentOutOfBound", "StructuredBuffer stride out of bounds","structured buffer elements cannot be larger than %0 bytes (actual size %1 bytes).")
- self.add_valrule("Meta.EntryFunction", "entrypoint not found.")
- self.add_valrule("Meta.InvalidControlFlowHint", "Invalid control flow hint.")
- self.add_valrule("Meta.BranchFlatten", "Can't use branch and flatten attributes together.")
- self.add_valrule("Meta.ForceCaseOnSwitch", "Attribute forcecase only works for switch.")
- self.add_valrule("Meta.ControlFlowHintNotOnControlFlow", "Control flow hint only works on control flow inst.")
- self.add_valrule("Meta.TextureType", "elements of typed buffers and textures must fit in four 32-bit quantities.")
- self.add_valrule("Meta.BarycentricsInterpolation", "SV_Barycentrics cannot be used with 'nointerpolation' type.")
- self.add_valrule("Meta.BarycentricsFloat3", "only 'float3' type is allowed for SV_Barycentrics.")
- self.add_valrule("Meta.BarycentricsTwoPerspectives", "There can only be up to two input attributes of SV_Barycentrics with different perspective interpolation mode.")
- self.add_valrule("Meta.NoEntryPropsForEntry", "Entry point %0 must have entry properties.")
- self.add_valrule("Instr.Oload", "DXIL intrinsic overload must be valid.")
- self.add_valrule_msg("Instr.CallOload", "Call to DXIL intrinsic must match overload signature", "Call to DXIL intrinsic '%0' does not match an allowed overload signature.")
- self.add_valrule("Instr.PtrBitCast", "Pointer type bitcast must be have same size.")
- self.add_valrule("Instr.MinPrecisonBitCast", "Bitcast on minprecison types is not allowed.")
- self.add_valrule("Instr.StructBitCast", "Bitcast on struct types is not allowed.")
- self.add_valrule("Instr.Status", "Resource status should only be used by CheckAccessFullyMapped.")
- self.add_valrule("Instr.CheckAccessFullyMapped", "CheckAccessFullyMapped should only be used on resource status.")
- self.add_valrule_msg("Instr.OpConst", "DXIL intrinsic requires an immediate constant operand", "%0 of %1 must be an immediate constant.")
- self.add_valrule("Instr.Allowed", "Instructions must be of an allowed type.")
- self.add_valrule("Instr.OpCodeReserved", "Instructions must not reference reserved opcodes.")
- self.add_valrule_msg("Instr.OperandRange", "DXIL intrinsic operand must be within defined range", "expect %0 between %1, got %2.")
- self.add_valrule("Instr.NoReadingUninitialized", "Instructions should not read uninitialized value.")
- self.add_valrule("Instr.NoGenericPtrAddrSpaceCast", "Address space cast between pointer types must have one part to be generic address space.")
- self.add_valrule("Instr.InBoundsAccess", "Access to out-of-bounds memory is disallowed.")
- self.add_valrule("Instr.OpConstRange", "Constant values must be in-range for operation.")
- self.add_valrule("Instr.ImmBiasForSampleB", "bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate.")
- # If streams have not been declared, you must use cut instead of cut_stream in GS - is there an equivalent rule here?
- # Need to clean up all error messages and actually implement.
- # Midlevel
- self.add_valrule("Instr.NoIndefiniteLog", "No indefinite logarithm.")
- self.add_valrule("Instr.NoIndefiniteAsin", "No indefinite arcsine.")
- self.add_valrule("Instr.NoIndefiniteAcos", "No indefinite arccosine.")
- self.add_valrule("Instr.NoIDivByZero", "No signed integer division by zero.")
- self.add_valrule("Instr.NoUDivByZero", "No unsigned integer division by zero.")
- self.add_valrule("Instr.NoIndefiniteDsxy", "No indefinite derivative calculation.")
- self.add_valrule("Instr.MinPrecisionNotPrecise", "Instructions marked precise may not refer to minprecision values.")
- # Backend
- self.add_valrule("Instr.OnlyOneAllocConsume", "RWStructuredBuffers may increment or decrement their counters, but not both.")
- # CCompiler
- self.add_valrule("Instr.TextureOffset", "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7.")
- # D3D12
- self.add_valrule_msg("Instr.CannotPullPosition", "pull-model evaluation of position disallowed", "%0 does not support pull-model evaluation of position.")
- #self.add_valrule("Instr.ERR_GUARANTEED_RACE_CONDITION_UAV", "TODO - race condition writing to shared resource detected, consider making this write conditional.") warning on fxc.
- #self.add_valrule("Instr.ERR_GUARANTEED_RACE_CONDITION_GSM", "TODO - race condition writing to shared memory detected, consider making this write conditional.") warning on fxc.
- #self.add_valrule("Instr.ERR_INFINITE_LOOP", "TODO - ERR_INFINITE_LOOP") fxc will report error if it can prove the loop is infinite.
- self.add_valrule("Instr.EvalInterpolationMode", "Interpolation mode on %0 used with eval_* instruction must be linear, linear_centroid, linear_noperspective, linear_noperspective_centroid, linear_sample or linear_noperspective_sample.")
- self.add_valrule("Instr.ResourceCoordinateMiss", "coord uninitialized.")
- self.add_valrule("Instr.ResourceCoordinateTooMany", "out of bound coord must be undef.")
- self.add_valrule("Instr.ResourceOffsetMiss", "offset uninitialized.")
- self.add_valrule("Instr.ResourceOffsetTooMany", "out of bound offset must be undef.")
- self.add_valrule("Instr.UndefResultForGetDimension", "GetDimensions used undef dimension %0 on %1.")
- self.add_valrule("Instr.SamplerModeForLOD", "lod instruction requires sampler declared in default mode.")
- self.add_valrule("Instr.SamplerModeForSample", "sample/_l/_d/_cl_s/gather instruction requires sampler declared in default mode.")
- self.add_valrule("Instr.SamplerModeForSampleC", "sample_c_*/gather_c instructions require sampler declared in comparison mode.")
- self.add_valrule("Instr.SampleCompType", "sample_* instructions require resource to be declared to return UNORM, SNORM or FLOAT.")
- self.add_valrule("Instr.BarrierModeUselessUGroup", "sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal.")
- self.add_valrule("Instr.BarrierModeNoMemory", "sync must include some form of memory barrier - _u (UAV) and/or _g (Thread Group Shared Memory). Only _t (thread group sync) is optional.")
- self.add_valrule("Instr.BarrierModeForNonCS", "sync in a non-Compute/Amplification/Mesh Shader must only sync UAV (sync_uglobal).")
- self.add_valrule("Instr.WriteMaskForTypedUAVStore", "store on typed uav must write to all four components of the UAV.")
- self.add_valrule("Instr.ResourceKindForCalcLOD","lod requires resource declared as texture1D/2D/3D/Cube/CubeArray/1DArray/2DArray.")
- self.add_valrule("Instr.ResourceKindForSample", "sample/_l/_d requires resource declared as texture1D/2D/3D/Cube/1DArray/2DArray/CubeArray.")
- self.add_valrule("Instr.ResourceKindForSampleC", "samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray.")
- self.add_valrule("Instr.ResourceKindForGather", "gather requires resource declared as texture/2D/Cube/2DArray/CubeArray.")
- self.add_valrule("Instr.WriteMaskMatchValueForUAVStore", "uav store write mask must match store value mask, write mask is %0 and store value mask is %1.")
- self.add_valrule("Instr.UndefinedValueForUAVStore", "Assignment of undefined values to UAV.")
- self.add_valrule("Instr.ResourceKindForBufferLoadStore", "buffer load/store only works on Raw/Typed/StructuredBuffer.")
- self.add_valrule("Instr.ResourceKindForTextureStore", "texture store only works on Texture1D/1DArray/2D/2DArray/3D.")
- self.add_valrule("Instr.ResourceKindForGetDim", "Invalid resource kind on GetDimensions.")
- self.add_valrule("Instr.ResourceKindForTextureLoad", "texture load only works on Texture1D/1DArray/2D/2DArray/3D/MS2D/MS2DArray.")
- self.add_valrule("Instr.ResourceClassForSamplerGather", "sample, lod and gather should be on srv resource.")
- self.add_valrule("Instr.ResourceClassForUAVStore", "store should be on uav resource.")
- self.add_valrule("Instr.ResourceClassForLoad", "load can only run on UAV/SRV resource.")
- self.add_valrule("Instr.ResourceMapToSingleEntry", "Fail to map resource to resource table.")
- self.add_valrule("Instr.ResourceUser", "Resource should only be used by Load/GEP/Call.")
- self.add_valrule("Instr.ResourceKindForTraceRay", "TraceRay should only use RTAccelerationStructure.")
- self.add_valrule("Instr.OffsetOnUAVLoad", "uav load don't support offset.")
- self.add_valrule("Instr.MipOnUAVLoad", "uav load don't support mipLevel/sampleIndex.")
- self.add_valrule("Instr.SampleIndexForLoad2DMS", "load on Texture2DMS/2DMSArray require sampleIndex.")
- self.add_valrule("Instr.CoordinateCountForRawTypedBuf", "raw/typed buffer don't need 2 coordinates.")
- self.add_valrule("Instr.CoordinateCountForStructBuf", "structured buffer require 2 coordinates.")
- self.add_valrule("Instr.MipLevelForGetDimension", "Use mip level on buffer when GetDimensions.")
- self.add_valrule("Instr.DxilStructUser", "Dxil struct types should only be used by ExtractValue.")
- self.add_valrule("Instr.DxilStructUserOutOfBound", "Index out of bound when extract value from dxil struct types.")
- self.add_valrule("Instr.HandleNotFromCreateHandle", "Resource handle should returned by createHandle.")
- self.add_valrule("Instr.BufferUpdateCounterOnUAV", "BufferUpdateCounter valid only on UAV.")
- self.add_valrule("Instr.BufferUpdateCounterOnResHasCounter", "BufferUpdateCounter valid only when HasCounter is true.")
- self.add_valrule("Instr.CBufferOutOfBound", "Cbuffer access out of bound.")
- self.add_valrule("Instr.CBufferClassForCBufferHandle", "Expect Cbuffer for CBufferLoad handle.")
- self.add_valrule("Instr.FailToResloveTGSMPointer", "TGSM pointers must originate from an unambiguous TGSM global variable.")
- self.add_valrule("Instr.ExtractValue", "ExtractValue should only be used on dxil struct types and cmpxchg.")
- self.add_valrule("Instr.TGSMRaceCond", "Race condition writing to shared memory detected, consider making this write conditional.")
- self.add_valrule("Instr.AttributeAtVertexNoInterpolation", "Attribute %0 must have nointerpolation mode in order to use GetAttributeAtVertex function.")
- self.add_valrule("Instr.CreateHandleImmRangeID", "Local resource must map to global resource.")
- self.add_valrule("Instr.SignatureOperationNotInEntry", "Dxil operation for input output signature must be in entryPoints.")
- self.add_valrule("Instr.MultipleSetMeshOutputCounts", "SetMeshOUtputCounts cannot be called multiple times.")
- self.add_valrule("Instr.MissingSetMeshOutputCounts", "Missing SetMeshOutputCounts call.")
- self.add_valrule("Instr.NonDominatingSetMeshOutputCounts", "Non-Dominating SetMeshOutputCounts call.")
- self.add_valrule("Instr.MultipleGetMeshPayload", "GetMeshPayload cannot be called multiple times.")
- self.add_valrule("Instr.NotOnceDispatchMesh", "DispatchMesh must be called exactly once in an Amplification shader.")
- self.add_valrule("Instr.NonDominatingDispatchMesh", "Non-Dominating DispatchMesh call.")
- # Some legacy rules:
- # - space is only supported for shader targets 5.1 and higher
- # - multiple rules regarding derivatives, which isn't a supported feature for DXIL
- # - multiple rules regarding library functions, which isn't a supported feature for DXIL (at this time)
- # - multiple rules regarding interfaces, which isn't a supported feature for DXIL
- # - rules for DX9-style intrinsics, which aren't supported for DXIL
-
- self.add_valrule_msg("Types.NoVector", "Vector types must not be present", "Vector type '%0' is not allowed.")
- self.add_valrule_msg("Types.Defined", "Type must be defined based on DXIL primitives", "Type '%0' is not defined on DXIL primitives.")
- self.add_valrule_msg("Types.IntWidth", "Int type must be of valid width", "Int type '%0' has an invalid width.")
- self.add_valrule("Types.NoMultiDim", "Only one dimension allowed for array type.")
- self.add_valrule("Types.NoPtrToPtr", "Pointers to pointers, or pointers in structures are not allowed.")
- self.add_valrule("Types.I8", "I8 can only be used as immediate value for intrinsic or as i8* via bitcast by lifetime intrinsics.")
- self.add_valrule_msg("Sm.Name", "Target shader model name must be known", "Unknown shader model '%0'.")
- self.add_valrule_msg("Sm.DxilVersion", "Target shader model requires specific Dxil Version", "Shader model requires Dxil Version %0,%1.")
- self.add_valrule_msg("Sm.Opcode", "Opcode must be defined in target shader model", "Opcode %0 not valid in shader model %1.")
- self.add_valrule("Sm.Operand", "Operand must be defined in target shader model.")
- self.add_valrule_msg("Sm.Semantic", "Semantic must be defined in target shader model", "Semantic '%0' is invalid as %1 %2.")
- self.add_valrule_msg("Sm.NoInterpMode", "Interpolation mode must be undefined for VS input/PS output/patch constant.", "Interpolation mode for '%0' is set but should be undefined.")
- self.add_valrule_msg("Sm.ConstantInterpMode", "Interpolation mode must be constant for MS primitive output.", "Interpolation mode for '%0' should be constant.")
- self.add_valrule("Sm.NoPSOutputIdx", "Pixel shader output registers are not indexable.")# TODO restrict to PS
- self.add_valrule("Sm.PSConsistentInterp", "Interpolation mode for PS input position must be linear_noperspective_centroid or linear_noperspective_sample when outputting oDepthGE or oDepthLE and not running at sample frequency (which is forced by inputting SV_SampleIndex or declaring an input linear_sample or linear_noperspective_sample).")
- self.add_valrule("Sm.ThreadGroupChannelRange", "Declared Thread Group %0 size %1 outside valid range [%2..%3].")
- self.add_valrule("Sm.MaxTheadGroup", "Declared Thread Group Count %0 (X*Y*Z) is beyond the valid maximum of %1.")
- self.add_valrule("Sm.MaxTGSMSize", "Total Thread Group Shared Memory storage is %0, exceeded %1.")
- self.add_valrule("Sm.WaveSizeValue", "Declared WaveSize %0 outside valid range [%1..%2], or not a power of 2.")
- self.add_valrule("Sm.WaveSizeNeedsDxil16Plus", "WaveSize is valid only for DXIL version 1.6 and higher.")
- self.add_valrule("Sm.ROVOnlyInPS", "RasterizerOrdered objects are only allowed in 5.0+ pixel shaders.")
- self.add_valrule("Sm.TessFactorForDomain", "Required TessFactor for domain not found declared anywhere in Patch Constant data.")
- self.add_valrule("Sm.TessFactorSizeMatchDomain", "TessFactor rows, columns (%0, %1) invalid for domain %2. Expected %3 rows and 1 column.")
- self.add_valrule("Sm.InsideTessFactorSizeMatchDomain", "InsideTessFactor rows, columns (%0, %1) invalid for domain %2. Expected %3 rows and 1 column.")
- self.add_valrule("Sm.DomainLocationIdxOOB", "DomainLocation component index out of bounds for the domain.")
- self.add_valrule("Sm.HullPassThruControlPointCountMatch", "For pass thru hull shader, input control point count must match output control point count");
- self.add_valrule("Sm.OutputControlPointsTotalScalars", "Total number of scalars across all HS output control points must not exceed .")
- self.add_valrule("Sm.IsoLineOutputPrimitiveMismatch", "Hull Shader declared with IsoLine Domain must specify output primitive point or line. Triangle_cw or triangle_ccw output are not compatible with the IsoLine Domain.")
- self.add_valrule("Sm.TriOutputPrimitiveMismatch", "Hull Shader declared with Tri Domain must specify output primitive point, triangle_cw or triangle_ccw. Line output is not compatible with the Tri domain.")
- self.add_valrule("Sm.ValidDomain", "Invalid Tessellator Domain specified. Must be isoline, tri or quad.")
- self.add_valrule("Sm.PatchConstantOnlyForHSDS", "patch constant signature only valid in HS and DS.")
- self.add_valrule("Sm.StreamIndexRange", "Stream index (%0) must between 0 and %1.")
- self.add_valrule("Sm.PSOutputSemantic", "Pixel Shader allows output semantics to be SV_Target, SV_Depth, SV_DepthGreaterEqual, SV_DepthLessEqual, SV_Coverage or SV_StencilRef, %0 found.")
- self.add_valrule("Sm.PSMultipleDepthSemantic", "Pixel Shader only allows one type of depth semantic to be declared.")
- self.add_valrule("Sm.PSTargetIndexMatchesRow", "SV_Target semantic index must match packed row location.")
- self.add_valrule("Sm.PSTargetCol0", "SV_Target packed location must start at column 0.")
- self.add_valrule("Sm.PSCoverageAndInnerCoverage", "InnerCoverage and Coverage are mutually exclusive.")
- self.add_valrule("Sm.GSOutputVertexCountRange", "GS output vertex count must be [0..%0]. %1 specified.")
- self.add_valrule("Sm.GSInstanceCountRange", "GS instance count must be [1..%0]. %1 specified.")
- self.add_valrule("Sm.DSInputControlPointCountRange", "DS input control point count must be [0..%0]. %1 specified.")
- self.add_valrule("Sm.HSInputControlPointCountRange", "HS input control point count must be [0..%0]. %1 specified.")
- self.add_valrule("Sm.ZeroHSInputControlPointWithInput", "When HS input control point count is 0, no input signature should exist.")
- self.add_valrule("Sm.OutputControlPointCountRange", "output control point count must be [0..%0]. %1 specified.")
- self.add_valrule("Sm.GSValidInputPrimitive", "GS input primitive unrecognized.")
- self.add_valrule("Sm.GSValidOutputPrimitiveTopology", "GS output primitive topology unrecognized.")
- self.add_valrule("Sm.AppendAndConsumeOnSameUAV", "BufferUpdateCounter inc and dec on a given UAV (%d) cannot both be in the same shader for shader model less than 5.1.")
- self.add_valrule("Sm.InvalidTextureKindOnUAV", "Texture2DMS[Array] or TextureCube[Array] resources are not supported with UAVs.")
- self.add_valrule("Sm.InvalidResourceKind", "Invalid resources kind.")
- self.add_valrule("Sm.InvalidResourceCompType","Invalid resource return type.")
- self.add_valrule("Sm.InvalidSamplerFeedbackType","Invalid sampler feedback type.")
- self.add_valrule("Sm.SampleCountOnlyOn2DMS","Only Texture2DMS/2DMSArray could has sample count.")
- self.add_valrule("Sm.CounterOnlyOnStructBuf", "BufferUpdateCounter valid only on structured buffers.")
- self.add_valrule("Sm.GSTotalOutputVertexDataRange", "Declared output vertex count (%0) multiplied by the total number of declared scalar components of output data (%1) equals %2. This value cannot be greater than %3.")
- self.add_valrule_msg("Sm.MultiStreamMustBePoint", "When multiple GS output streams are used they must be pointlists", "Multiple GS output streams are used but '%0' is not pointlist.")
- self.add_valrule("Sm.CompletePosition", "Not all elements of SV_Position were written.")
- self.add_valrule("Sm.UndefinedOutput", "Not all elements of output %0 were written.")
- self.add_valrule("Sm.CSNoSignatures", "Compute shaders must not have shader signatures.")
- self.add_valrule("Sm.CBufferTemplateTypeMustBeStruct", "D3D12 constant/texture buffer template element can only be a struct.")
- self.add_valrule_msg("Sm.ResourceRangeOverlap", "Resource ranges must not overlap", "Resource %0 with base %1 size %2 overlap with other resource with base %3 size %4 in space %5.")
- self.add_valrule_msg("Sm.CBufferOffsetOverlap", "CBuffer offsets must not overlap", "CBuffer %0 has offset overlaps at %1.")
- self.add_valrule_msg("Sm.CBufferElementOverflow", "CBuffer elements must not overflow", "CBuffer %0 size insufficient for element at offset %1.")
- self.add_valrule_msg("Sm.CBufferArrayOffsetAlignment", "CBuffer array offset must be aligned to 16-bytes", "CBuffer %0 has unaligned array offset at %1.")
- self.add_valrule_msg("Sm.OpcodeInInvalidFunction", "Invalid DXIL opcode usage like StorePatchConstant in patch constant function", "opcode '%0' should only be used in '%1'.")
- self.add_valrule_msg("Sm.ViewIDNeedsSlot", "ViewID requires compatible space in pixel shader input signature", "Pixel shader input signature lacks available space for ViewID.")
- self.add_valrule("Sm.64bitRawBufferLoadStore", "i64/f64 rawBufferLoad/Store overloads are allowed after SM 6.3.")
- self.add_valrule("Sm.RayShaderSignatures", "Ray tracing shader '%0' should not have any shader signatures.")
- self.add_valrule("Sm.RayShaderPayloadSize", "For shader '%0', %1 size is smaller than argument's allocation size.")
- self.add_valrule("Sm.MeshShaderMaxVertexCount", "MS max vertex output count must be [0..%0]. %1 specified.")
- self.add_valrule("Sm.MeshShaderMaxPrimitiveCount", "MS max primitive output count must be [0..%0]. %1 specified.")
- self.add_valrule("Sm.MeshShaderPayloadSize", "For mesh shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.")
- self.add_valrule("Sm.MeshShaderPayloadSizeDeclared", "For mesh shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.")
- self.add_valrule("Sm.MeshShaderOutputSize", "For shader '%0', vertex plus primitive output size is greater than %1.")
- self.add_valrule("Sm.MeshShaderInOutSize", "For shader '%0', payload plus output size is greater than %1.")
- self.add_valrule("Sm.MeshVSigRowCount", "For shader '%0', vertex output signatures are taking up more than %1 rows.")
- self.add_valrule("Sm.MeshPSigRowCount", "For shader '%0', primitive output signatures are taking up more than %1 rows.")
- self.add_valrule("Sm.MeshTotalSigRowCount", "For shader '%0', vertex and primitive output signatures are taking up more than %1 rows.")
- self.add_valrule("Sm.MaxMSSMSize", "Total Thread Group Shared Memory storage is %0, exceeded %1.")
- self.add_valrule("Sm.AmplificationShaderPayloadSize", "For amplification shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.")
- self.add_valrule("Sm.AmplificationShaderPayloadSizeDeclared", "For amplification shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.")
- # fxc relaxed check of gradient check.
- #self.add_valrule("Uni.NoUniInDiv", "TODO - No instruction requiring uniform execution can be present in divergent block")
- #self.add_valrule("Uni.GradientFlow", "TODO - No divergent gradient operations inside flow control") # a bit more specific than the prior rule
- #self.add_valrule("Uni.ThreadSync", "TODO - Thread sync operation must be in non-varying flow control due to a potential race condition, adding a sync after reading any values controlling shader execution at this point")
- #self.add_valrule("Uni.NoWaveSensitiveGradient", "Gradient operations are not affected by wave-sensitive data or control flow.")
-
- self.add_valrule("Flow.Reducible", "Execution flow must be reducible.")
- self.add_valrule("Flow.NoRecusion", "Recursion is not permitted.")
- self.add_valrule("Flow.DeadLoop", "Loop must have break.")
- self.add_valrule_msg("Flow.FunctionCall", "Function with parameter is not permitted", "Function %0 with parameter is not permitted, it should be inlined.")
- self.add_valrule_msg("Decl.DxilNsReserved", "The DXIL reserved prefixes must only be used by built-in functions and types", "Declaration '%0' uses a reserved prefix.")
- self.add_valrule_msg("Decl.DxilFnExtern", "External function must be a DXIL function", "External function '%0' is not a DXIL function.")
- self.add_valrule_msg("Decl.UsedInternal", "Internal declaration must be used", "Internal declaration '%0' is unused.")
- self.add_valrule_msg("Decl.NotUsedExternal", "External declaration should not be used", "External declaration '%0' is unused.")
- self.add_valrule_msg("Decl.UsedExternalFunction", "External function must be used", "External function '%0' is unused.")
- self.add_valrule_msg("Decl.FnIsCalled", "Functions can only be used by call instructions", "Function '%0' is used for something other than calling.")
- self.add_valrule_msg("Decl.FnFlattenParam", "Function parameters must not use struct types", "Type '%0' is a struct type but is used as a parameter in function '%1'.")
- self.add_valrule_msg("Decl.FnAttribute", "Functions should only contain known function attributes", "Function '%0' contains invalid attribute '%1' with value '%2'.")
- self.add_valrule_msg("Decl.ResourceInFnSig", "Resources not allowed in function signatures", "Function '%0' uses resource in function signature.")
- self.add_valrule_msg("Decl.PayloadStruct", "Payload parameter must be struct type", "Argument '%0' must be a struct type for payload in shader function '%1'.")
- self.add_valrule_msg("Decl.AttrStruct", "Attributes parameter must be struct type", "Argument '%0' must be a struct type for attributes in shader function '%1'.")
- self.add_valrule_msg("Decl.ParamStruct", "Callable function parameter must be struct type", "Argument '%0' must be a struct type for callable shader function '%1'.")
- self.add_valrule_msg("Decl.ExtraArgs", "Extra arguments not allowed for shader functions", "Extra argument '%0' not allowed for shader function '%1'.")
- self.add_valrule_msg("Decl.ShaderReturnVoid", "Shader functions must return void", "Shader function '%0' must have void return type.")
- self.add_valrule_msg("Decl.ShaderMissingArg", "payload/params/attributes parameter is required for certain shader types", "%0 shader '%1' missing required %2 parameter.")
- # Assign sensible category names and build up an enumeration description
- cat_names = {
- "CONTAINER": "Container",
- "BITCODE": "Bitcode",
- "META": "Metadata",
- "INSTR": "Instruction",
- "FLOW": "Program flow",
- "TYPES": "Type system",
- "SM": "Shader model",
- "UNI": "Uniform analysis",
- "DECL": "Declaration"
- }
- valrule_enum = db_dxil_enum("ValidationRule", "Known validation rules")
- valrule_enum.is_internal = True
- for vr in self.val_rules:
- vr.category = cat_names[vr.group_name]
- vrval = db_dxil_enum_value(vr.enum_name, vr.rule_id, vr.doc)
- vrval.category = vr.category
- vrval.err_msg = vr.err_msg
- valrule_enum.values.append(vrval)
- self.enums.append(valrule_enum)
- def populate_counters(self):
- self.llvm_op_counters = set()
- self.dxil_op_counters = set()
- for i in self.instr:
- counters = getattr(i, 'props', {}).get('counters', ())
- if i.dxil_opid:
- self.dxil_op_counters.update(counters)
- else:
- self.llvm_op_counters.update(counters)
- counter_set = set(self.counters)
- counter_set.update(self.llvm_op_counters)
- counter_set.update(self.dxil_op_counters)
- self.counters = list(sorted(counter_set))
- def add_valrule(self, name, desc):
- self.val_rules.append(db_dxil_valrule(name, len(self.val_rules), err_msg=desc, doc=desc))
- def add_valrule_msg(self, name, desc, err_msg):
- self.val_rules.append(db_dxil_valrule(name, len(self.val_rules), err_msg=err_msg, doc=desc))
- def add_llvm_instr(self, kind, llvm_id, name, llvm_name, doc, oload_types, op_params, **props):
- i = db_dxil_inst(name, llvm_id=llvm_id, llvm_name=llvm_name, doc=doc, ops=op_params, oload_types=oload_types)
- if kind == "TERM": i.is_bb_terminator=True
- if kind == "BINARY": i.is_binary=True
- if kind == "MEMORY": i.is_memory=True
- if kind == "CAST": i.is_cast=True
- i.props = props
- self.instr.append(i)
- def add_dxil_op(self, name, code_id, code_class, doc, oload_types, fn_attr, op_params, **props):
- # The return value is parameter 0, insert the opcode as 1.
- op_params.insert(1, self.opcode_param)
- i = db_dxil_inst(name,
- llvm_id=self.call_instr.llvm_id, llvm_name=self.call_instr.llvm_name,
- dxil_op=name, dxil_opid=code_id, doc=doc, ops=op_params, dxil_class=code_class,
- oload_types=oload_types, fn_attr=fn_attr)
- i.props = props
- self.instr.append(i)
- def add_dxil_op_reserved(self, name, code_id):
- # The return value is parameter 0, insert the opcode as 1.
- op_params = [db_dxil_param(0, "v", "", "reserved"), self.opcode_param]
- i = db_dxil_inst(name,
- llvm_id=self.call_instr.llvm_id, llvm_name=self.call_instr.llvm_name,
- dxil_op=name, dxil_opid=code_id, doc="reserved", ops=op_params, dxil_class="Reserved",
- oload_types="v", fn_attr="")
- self.instr.append(i)
- def get_instr_by_llvm_name(self, llvm_name):
- "Return the instruction with the given LLVM name"
- return next(i for i in self.instr if i.llvm_name == llvm_name)
- def get_dxil_insts(self):
- for i in self.instr:
- if i.dxil_op != "":
- yield i
- def print_stats(self):
- "Print some basic statistics on the instruction database."
- print ("Instruction count: %d" % len(self.instr))
- print ("Max parameter count in instruction: %d" % max(len(i.ops) - 1 for i in self.instr))
- print ("Parameter count: %d" % sum(len(i.ops) - 1 for i in self.instr))
- ###############################################################################
- # HLSL-specific information. #
- ###############################################################################
- class db_hlsl_attribute(object):
- "An HLSL attribute declaration"
- def __init__(self, title_name, scope, args, doc):
- self.name = title_name.lower() # lowercase attribute name
- self.title_name = title_name # title-case attribute name
- self.scope = scope # one of l (loop), c (condition), s (switch), f (function)
- self.args = args # list of arguments
- self.doc = doc # documentation
- class db_hlsl_intrinsic(object):
- "An HLSL intrinsic declaration"
- def __init__(self, name, idx, opname, params, ns, ns_idx, doc, ro, rn, wv, unsigned_op, overload_idx, hidden):
- self.name = name # Function name
- self.idx = idx # Unique number within namespace
- self.opname = opname # D3D-style name
- self.params = params # List of parameters
- self.ns = ns # Function namespace
- self.ns_idx = ns_idx # Namespace index
- self.doc = doc # Documentation
- id_prefix = "IOP" if ns == "Intrinsics" else "MOP"
- # SPIR-V Change Starts
- if ns == "VkIntrinsics":
- name = "Vk" + name
- self.name = "Vk" + self.name
- id_prefix = "IOP"
- # SPIR-V Change Ends
- self.enum_name = "%s_%s" % (id_prefix, name) # enum name
- self.readonly = ro # Only read memory
- self.readnone = rn # Not read memory
- self.wave = wv # Is wave-sensitive
- self.unsigned_op = unsigned_op # Unsigned opcode if exist
- if unsigned_op != "":
- self.unsigned_op = "%s_%s" % (id_prefix, unsigned_op)
- self.overload_param_index = overload_idx # Parameter determines the overload type, -1 means ret type
- self.hidden = hidden # Internal high-level op, not exposed to HLSL
- self.key = ("%3d" % ns_idx) + "!" + name + "!" + ("%2d" % len(params)) + "!" + ("%3d" % idx) # Unique key
- self.vulkanSpecific = ns.startswith("Vk") # Vulkan specific intrinsic - SPIRV change
- class db_hlsl_namespace(object):
- "A grouping of HLSL intrinsics"
- def __init__(self, name):
- self.name = name
- self.intrinsics = []
- class db_hlsl_intrisic_param(object):
- "An HLSL parameter declaration for an intrinsic"
- def __init__(self, name, param_qual, template_id, template_list, component_id, component_list, rows, cols, type_name, idx, template_id_idx, component_id_idx):
- self.name = name # Parameter name
- self.param_qual = param_qual # Parameter qualifier expressions
- self.template_id = template_id # Template ID (possibly identifier)
- self.template_list = template_list # Template list (possibly identifier)
- self.component_id = component_id # Component ID (possibly identifier)
- self.component_list = component_list # Component list (possibly identifier)
- self.rows = rows # Row count for parameter, possibly identifier
- self.cols = cols # Row count for parameter, possibly identifier
- self.type_name = type_name # Type name
- self.idx = idx # Argument index
- self.template_id_idx = template_id_idx # Template ID numeric value
- self.component_id_idx = component_id_idx # Component ID numeric value
- class db_hlsl(object):
- "A database of HLSL language data"
- def __init__(self, intrinsic_defs):
- self.base_types = {
- "bool": "LICOMPTYPE_BOOL",
- "int": "LICOMPTYPE_INT",
- "int32_only": "LICOMPTYPE_INT32_ONLY",
- "int64_only": "LICOMPTYPE_INT64_ONLY",
- "int16_t": "LICOMPTYPE_INT16",
- "uint": "LICOMPTYPE_UINT",
- "uint16_t": "LICOMPTYPE_UINT16",
- "u64": "LICOMPTYPE_UINT64",
- "any_int": "LICOMPTYPE_ANY_INT",
- "any_int32": "LICOMPTYPE_ANY_INT32",
- "any_int64": "LICOMPTYPE_ANY_INT64",
- "uint_only": "LICOMPTYPE_UINT_ONLY",
- "int8_t4_packed": "LICOMPTYPE_INT8_4PACKED",
- "uint8_t4_packed": "LICOMPTYPE_UINT8_4PACKED",
- "float16_t": "LICOMPTYPE_FLOAT16",
- "float": "LICOMPTYPE_FLOAT",
- "float32_only": "LICOMPTYPE_FLOAT32_ONLY",
- "fldbl": "LICOMPTYPE_FLOAT_DOUBLE",
- "any_float": "LICOMPTYPE_ANY_FLOAT",
- "float_like": "LICOMPTYPE_FLOAT_LIKE",
- "double": "LICOMPTYPE_DOUBLE",
- "double_only": "LICOMPTYPE_DOUBLE_ONLY",
- "numeric": "LICOMPTYPE_NUMERIC",
- "numeric16_only": "LICOMPTYPE_NUMERIC16_ONLY",
- "numeric32": "LICOMPTYPE_NUMERIC32",
- "numeric32_only": "LICOMPTYPE_NUMERIC32_ONLY",
- "any": "LICOMPTYPE_ANY",
- "sampler1d": "LICOMPTYPE_SAMPLER1D",
- "sampler2d": "LICOMPTYPE_SAMPLER2D",
- "sampler3d": "LICOMPTYPE_SAMPLER3D",
- "sampler_cube": "LICOMPTYPE_SAMPLERCUBE",
- "sampler_cmp": "LICOMPTYPE_SAMPLERCMP",
- "sampler": "LICOMPTYPE_SAMPLER",
- "resource": "LICOMPTYPE_RESOURCE",
- "ray_desc" : "LICOMPTYPE_RAYDESC",
- "acceleration_struct" : "LICOMPTYPE_ACCELERATION_STRUCT",
- "udt" : "LICOMPTYPE_USER_DEFINED_TYPE",
- "void": "LICOMPTYPE_VOID",
- "string": "LICOMPTYPE_STRING",
- "Texture2D": "LICOMPTYPE_TEXTURE2D",
- "Texture2DArray": "LICOMPTYPE_TEXTURE2DARRAY",
- "wave": "LICOMPTYPE_WAVE",
- "p32i8" : "LICOMPTYPE_INT8_4PACKED",
- "p32u8" : "LICOMPTYPE_UINT8_4PACKED",
- "any_int16or32": "LICOMPTYPE_ANY_INT16_OR_32",
- "sint16or32_only": "LICOMPTYPE_SINT16_OR_32_ONLY",
- }
- self.trans_rowcol = {
- "r": "IA_R",
- "c": "IA_C",
- "r2": "IA_R2",
- "c2": "IA_C2"}
- self.param_qual = {
- "in": "AR_QUAL_IN",
- "inout": "AR_QUAL_IN | AR_QUAL_OUT",
- "out": "AR_QUAL_OUT",
- "col_major": "AR_QUAL_COLMAJOR",
- "row_major": "AR_QUAL_ROWMAJOR"}
- self.intrinsics = []
- self.load_intrinsics(intrinsic_defs)
- self.create_namespaces()
- self.populate_attributes()
- self.opcode_namespace = "hlsl::IntrinsicOp"
- def create_namespaces(self):
- last_ns = None
- self.namespaces = {}
- for i in sorted(self.intrinsics, key=lambda x: x.key):
- if last_ns is None or last_ns.name != i.ns:
- last_ns = db_hlsl_namespace(i.ns)
- self.namespaces[i.ns] = last_ns
- last_ns.intrinsics.append(i)
- def load_intrinsics(self, intrinsic_defs):
- import re
- blank_re = re.compile(r"^\s*$")
- comment_re = re.compile(r"^\s*//")
- namespace_beg_re = re.compile(r"^namespace\s+(\w+)\s*{\s*$")
- namespace_end_re = re.compile(r"^}\s*namespace\s*$")
- intrinsic_re = re.compile(r"^\s*([^(]+)\s+\[\[(\S*)\]\]\s+(\w+)\s*\(\s*([^)]*)\s*\)\s*(:\s*\w+\s*)?;$")
- operand_re = re.compile(r"^:\s*(\w+)\s*$")
- bracket_cleanup_re = re.compile(r"<\s*(\S+)\s*,\s*(\S+)\s*>") # change <a,b> to <a@> to help split params and parse
- params_split_re = re.compile(r"\s*,\s*")
- ws_split_re = re.compile(r"\s+")
- typeref_re = re.compile(r"\$type(\d+)$")
- type_matrix_re = re.compile(r"(\S+)<(\S+)@(\S+)>$")
- type_vector_re = re.compile(r"(\S+)<(\S+)>$")
- type_any_re = re.compile(r"(\S+)<>$")
- digits_re = re.compile(r"^\d+$")
- opt_param_match_re = re.compile(r"^\$match<(\S+)@(\S+)>$")
- ns_idx = 0
- num_entries = 0
- def add_flag(val, new_val):
- if val == "" or val == "0":
- return new_val
- return val + " | " + new_val
- def translate_rowcol(val):
- digits_match = digits_re.match(val)
- if digits_match:
- return val
- assert val in self.trans_rowcol, "unknown row/col %s" % val
- return self.trans_rowcol[val]
- def process_arg(desc, idx, done_args, intrinsic_name):
- "Process a single parameter description."
- opt_list = []
- desc = desc.strip()
- if desc == "...":
- param_name = "..."
- type_name = "..."
- else:
- opt_list = ws_split_re.split(desc)
- assert len(opt_list) > 0, "malformed parameter desc %s" % (desc)
- param_name = opt_list.pop() # last token is name
- type_name = opt_list.pop() # next-to-last is type specifier
- param_qual = "0"
- template_id = str(idx)
- template_list = "LITEMPLATE_ANY"
- component_id = str(idx)
- component_list = "LICOMPTYPE_ANY"
- rows = "1"
- cols = "1"
- if type_name == "$classT":
- assert idx == 0, "'$classT' can only be used as the return type"
- # template_id may be -1 in other places other than return type, for example in Stream.Append().
- # $unspec is a shorthand for return types only though.
- template_id = "-1"
- component_id = "0"
- type_name = "void"
- if type_name == "$funcT":
- template_id = "-3"
- component_id = "0"
- type_name = "void"
- elif type_name == "...":
- assert idx != 0, "'...' can only be used in the parameter list"
- template_id = "-2"
- component_id = "0"
- type_name = "void"
- else:
- typeref_match = typeref_re.match(type_name)
- if typeref_match:
- template_id = typeref_match.group(1)
- component_id = template_id
- assert idx != 1, "Can't use $type on the first argument"
- assert template_id != "0", "Can't match an input to the return type"
- done_idx = int(template_id) - 1
- assert done_idx <= len(args) + 1, "$type must refer to a processed arg"
- done_arg = done_args[done_idx]
- type_name = done_arg.type_name
- # Determine matrix/vector/any/scalar type names.
- type_matrix_match = type_matrix_re.match(type_name)
- if type_matrix_match:
- base_type = type_matrix_match.group(1)
- rows = type_matrix_match.group(2)
- cols = type_matrix_match.group(3)
- template_list = "LITEMPLATE_MATRIX"
- else:
- type_vector_match = type_vector_re.match(type_name)
- if type_vector_match:
- base_type = type_vector_match.group(1)
- cols = type_vector_match.group(2)
- template_list = "LITEMPLATE_VECTOR"
- else:
- type_any_match = type_any_re.match(type_name)
- if type_any_match:
- base_type = type_any_match.group(1)
- rows = "r"
- cols = "c"
- template_list = "LITEMPLATE_ANY"
- else:
- base_type = type_name
- if base_type.startswith("sampler") or base_type.startswith("string") or base_type.startswith("Texture") or base_type.startswith("wave") or base_type.startswith("acceleration_struct") or base_type.startswith("ray_desc"):
- template_list = "LITEMPLATE_OBJECT"
- else:
- template_list = "LITEMPLATE_SCALAR"
- assert base_type in self.base_types, "Unknown base type '%s' in '%s'" % (base_type, desc)
- component_list = self.base_types[base_type]
- rows = translate_rowcol(rows)
- cols = translate_rowcol(cols)
- for opt in opt_list:
- if opt in self.param_qual:
- param_qual = add_flag(param_qual, self.param_qual[opt])
- else:
- opt_param_match_match = opt_param_match_re.match(opt)
- assert opt_param_match_match, "Unknown parameter qualifier '%s'" % (opt)
- template_id = opt_param_match_match.group(1)
- component_id = opt_param_match_match.group(2)
- if component_list == "LICOMPTYPE_VOID":
- if type_name == "void":
- template_list = "LITEMPLATE_VOID"
- rows = "0"
- cols = "0"
- if template_id == "0":
- param_qual = "0"
- # Keep these as numeric values.
- template_id_idx = int(template_id)
- component_id_idx = int(component_id)
- # Verify that references don't point to the right (except for the return value).
- assert idx == 0 or template_id_idx <= int(idx), "Argument '%s' has a forward reference" % (param_name)
- assert idx == 0 or component_id_idx <= int(idx), "Argument '%s' has a forward reference" % (param_name)
- if template_id == "-1":
- template_id = "INTRIN_TEMPLATE_FROM_TYPE"
- elif template_id == "-2":
- template_id = "INTRIN_TEMPLATE_VARARGS"
- elif template_id == "-3":
- template_id = "INTRIN_TEMPLATE_FROM_FUNCTION"
- if component_id == "-1":
- component_id = "INTRIN_COMPTYPE_FROM_TYPE_ELT0"
- return db_hlsl_intrisic_param(param_name, param_qual, template_id, template_list, component_id, component_list, rows, cols, type_name, idx, template_id_idx, component_id_idx)
- def process_attr(attr):
- attrs = attr.split(',')
- readonly = False # Only read memory
- readnone = False # Not read memory
- is_wave = False; # Is wave-sensitive
- unsigned_op = "" # Unsigned opcode if exist
- overload_param_index = -1 # Parameter determines the overload type, -1 means ret type.
- hidden = False
- for a in attrs:
- if (a == ""):
- continue
- if (a == "ro"):
- readonly = True
- continue
- if (a == "rn"):
- readnone = True
- continue
- if (a == "wv"):
- is_wave = True
- continue
- if (a == "hidden"):
- hidden = True
- continue
- assign = a.split('=')
- if (len(assign) != 2):
- assert False, "invalid attr %s" % (a)
- continue
- d = assign[0]
- v = assign[1]
- if (d == "unsigned_op"):
- unsigned_op = v
- continue
- if (d == "overload"):
- overload_param_index = int(v)
- continue
- assert False, "invalid attr %s" % (a)
- return readonly, readnone, is_wave, unsigned_op, overload_param_index, hidden
- current_namespace = None
- for line in intrinsic_defs:
- if blank_re.match(line): continue
- if comment_re.match(line): continue
- match_obj = namespace_beg_re.match(line)
- if match_obj:
- assert not current_namespace, "cannot open namespace without closing prior one"
- current_namespace = match_obj.group(1)
- num_entries = 0
- ns_idx += 1
- continue
- if namespace_end_re.match(line):
- assert current_namespace, "cannot close namespace without previously opening it"
- current_namespace = None
- continue
- match_obj = intrinsic_re.match(line)
- if match_obj:
- assert current_namespace, "instruction missing namespace %s" % (line)
- # Get a D3D-style operand name for the instruction.
- # Unused for DXIL.
- opts = match_obj.group(1)
- attr = match_obj.group(2)
- name = match_obj.group(3)
- params = match_obj.group(4)
- op = match_obj.group(5)
- if op:
- operand_match = operand_re.match(op)
- if operand_match:
- op = operand_match.group(1)
- if not op:
- op = name
- readonly, readnone, is_wave, unsigned_op, overload_param_index, hidden = process_attr(attr)
- # Add an entry for this intrinsic.
- if bracket_cleanup_re.search(opts):
- opts = bracket_cleanup_re.sub(r"<\1@\2>", opts)
- if bracket_cleanup_re.search(params):
- params = bracket_cleanup_re.sub(r"<\g<1>@\2>", params)
- ret_desc = "out " + opts + " " + name
- if len(params) > 0:
- in_args = params_split_re.split(params)
- else:
- in_args = []
- arg_idx = 1
- args = []
- for in_arg in in_args:
- args.append(process_arg(in_arg, arg_idx, args, name))
- arg_idx += 1
- # We have to process the return type description last
- # to match the compiler's handling of it and allow
- # the return type to match an input type.
- # It needs to be the first entry, so prepend it.
- args.insert(0, process_arg(ret_desc, 0, args, name))
- # TODO: verify a single level of indirection
- self.intrinsics.append(db_hlsl_intrinsic(
- name, num_entries, op, args, current_namespace, ns_idx, "pending doc for " + name,
- readonly, readnone, is_wave, unsigned_op, overload_param_index, hidden))
- num_entries += 1
- continue
- assert False, "cannot parse line %s" % (line)
- def populate_attributes(self):
- "Populate basic definitions for attributes."
- attributes = []
- def add_attr(title_name, scope, doc):
- attributes.append(db_hlsl_attribute(title_name, scope, [], doc))
- def add_attr_arg(title_name, scope, args, doc):
- attributes.append(db_hlsl_attribute(title_name, scope, args, doc))
- add_attr("Allow_UAV_Condition", "l", "Allows a compute shader loop termination condition to be based off of a UAV read. The loop must not contain synchronization intrinsics")
- add_attr("Branch", "c", "Evaluate only one side of the if statement depending on the given condition")
- add_attr("Call", "s", "The bodies of the individual cases in the switch will be moved into hardware subroutines and the switch will be a series of subroutine calls")
- add_attr("EarlyDepthStencil", "f", "Forces depth-stencil testing before a shader executes")
- add_attr("FastOpt", "l", "Reduces the compile time but produces less aggressive optimizations")
- add_attr("Flatten", "c", "Evaluate both sides of the if statement and choose between the two resulting values")
- add_attr("ForceCase", "s", "Force a switch statement in the hardware")
- add_attr("Loop", "l", "Generate code that uses flow control to execute each iteration of the loop")
- add_attr_arg("ClipPlanes", "f", "Optional list of clip planes", [{"name":"ClipPlane", "type":"int", "count":6}])
- add_attr_arg("Domain", "f", "Defines the patch type used in the HS", [{"name":"DomainType", type:"string"}])
- add_attr_arg("Instance", "f", "Use this attribute to instance a geometry shader", [{"name":"Count", "type":"int"}])
- add_attr_arg("MaxTessFactor", "f", "Indicates the maximum value that the hull shader would return for any tessellation factor.", [{"name":"Count", "type":"int"}])
- add_attr_arg("MaxVertexCount", "f", "maxvertexcount doc", [{"name":"Count", "type":"int"}])
- add_attr_arg("NumThreads", "f", "Defines the number of threads to be executed in a single thread group.", [{"name":"x", "type":"int"},{"name":"z", "type":"int"},{"name":"y", "type":"int"}])
- add_attr_arg("OutputControlPoints", "f", "Defines the number of output control points per thread that will be created in the hull shader", [{"name":"Count", "type":"int"}])
- add_attr_arg("OutputTopology", "f", "Defines the output primitive type for the tessellator", [{"name":"Topology", "type":"string"}])
- add_attr_arg("Partitioning", "f", "Defines the tesselation scheme to be used in the hull shader", [{"name":"Scheme", "type":"scheme"}])
- add_attr_arg("PatchConstantFunc", "f", "Defines the function for computing patch constant data", [{"name":"FunctionName", "type":"string"}])
- add_attr_arg("RootSignature", "f", "RootSignature doc", [{"name":"SignatureName", "type":"string"}])
- add_attr_arg("Unroll", "l", "Unroll the loop until it stops executing or a max count", [{"name":"Count", "type":"int"}])
- self.attributes = attributes
- if __name__ == "__main__":
- db = db_dxil()
- print(db)
- db.print_stats()
|