SPIR-V.rst 198 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913
  1. =====================================
  2. HLSL to SPIR-V Feature Mapping Manual
  3. =====================================
  4. .. contents::
  5. :local:
  6. :depth: 3
  7. Introduction
  8. ============
  9. This document describes the mappings from HLSL features to SPIR-V for Vulkan
  10. adopted by the SPIR-V codegen. For how to build, use, or contribute to the
  11. SPIR-V codegen and its internals, please see the
  12. `wiki <https://github.com/Microsoft/DirectXShaderCompiler/wiki/SPIR%E2%80%90V-CodeGen>`_
  13. page.
  14. `SPIR-V <https://www.khronos.org/registry/spir-v/>`_ is a binary intermediate
  15. language for representing graphical-shader stages and compute kernels for
  16. multiple Khronos APIs, such as Vulkan, OpenGL, and OpenCL. At the moment we
  17. only intend to support the Vulkan flavor of SPIR-V.
  18. DirectXShaderCompiler is the reference compiler for HLSL. Adding SPIR-V codegen
  19. in DirectXShaderCompiler will enable the usage of HLSL as a frontend language
  20. for Vulkan shader programming. Sharing the same code base also means we can
  21. track the evolution of HLSL more closely and always deliver the best of HLSL to
  22. developers. Moreover, developers will also have a unified compiler toolchain for
  23. targeting both DirectX and Vulkan. We believe this effort will benefit the
  24. general graphics ecosystem.
  25. Note that this document is expected to be an ongoing effort and grow as we
  26. implement more and more HLSL features.
  27. Overview
  28. ========
  29. Although they share the same basic concepts, DirectX and Vulkan are still
  30. different graphics APIs with semantic gaps. HLSL is the native shading language
  31. for DirectX, so certain HLSL features do not have corresponding mappings in
  32. Vulkan, and certain Vulkan specific information does not have native ways to
  33. express in HLSL source code. This section describes the general translation
  34. paradigms and how we close some of the major semantic gaps.
  35. Note that the term "semantic" is overloaded. In HLSL, it can mean the string
  36. attached to shader input or output. For such cases, we refer it as "HLSL
  37. semantic" or "semantic string". For other cases, we just use the normal
  38. "semantic" term.
  39. Shader entry function
  40. ---------------------
  41. HLSL entry functions can read data from the previous shader stage and write
  42. data to the next shader stage via function parameters and return value. On the
  43. contrary, Vulkan requires all SPIR-V entry functions taking no parameters and
  44. returning void. All data passing between stages should use global variables
  45. in the ``Input`` and ``Output`` storage class.
  46. To handle this difference, we emit a wrapper function as the SPIR-V entry
  47. function around the HLSL source code entry function. The wrapper function is
  48. responsible to read data from SPIR-V ``Input`` global variables and prepare
  49. them to the types required in the source code entry function signature, call
  50. the source code entry function, and then decompose the contents in return value
  51. (and ``out``/``inout`` parameters) to the types required by the SPIR-V
  52. ``Output`` global variables, and then write out. For details about the wrapper
  53. function, please refer to the `entry function wrapper`_ section.
  54. Shader stage IO interface matching
  55. ----------------------------------
  56. HLSL leverages semantic strings to link variables and pass data between shader
  57. stages. Great flexibility is allowed as for how to use the semantic strings.
  58. They can appear on function parameters, function returns, and struct members.
  59. In Vulkan, linking variables and passing data between shader stages is done via
  60. numeric ``Location`` decorations on SPIR-V global variables in the ``Input`` and
  61. ``Output`` storage class.
  62. To help handling such differences, we provide `Vulkan specific attributes`_ to
  63. let the developer to express precisely their intents. The compiler will also try
  64. its best to deduce the mapping from semantic strings to SPIR-V ``Location``
  65. numbers when such explicit Vulkan specific attributes are absent. Please see the
  66. `HLSL semantic and Vulkan Location`_ section for more details about the mapping
  67. and ``Location`` assignment.
  68. What makes the story complicated is Vulkan's strict requirements on interface
  69. matching. Basically, a variable in the previous stage is considered a match to
  70. a variable in the next stage if and only if they are decorated with the same
  71. ``Location`` number and with the exact same type, except for the outermost
  72. arrayness in hull/domain/geometry shader, which can be ignored regarding
  73. interface matching. This is causing problems together with the flexibility of
  74. HLSL semantic strings.
  75. Some HLSL system-value (SV) semantic strings will be mapped into SPIR-V
  76. variables with builtin decorations, some are not. HLSL non-SV semantic strings
  77. should all be mapped to SPIR-V variables without builtin decorations (but with
  78. ``Location`` decorations).
  79. With these complications, if we are grouping multiple semantic strings in a
  80. struct in the HLSL source code, that struct should be flattened and each of
  81. its members should be mapped separately. For example, for the following:
  82. .. code:: hlsl
  83. struct T {
  84. float2 clip0 : SV_ClipDistance0;
  85. float3 cull0 : SV_CullDistance0;
  86. float4 foo : FOO;
  87. };
  88. struct S {
  89. float4 pos : SV_Position;
  90. float2 clip1 : SV_ClipDistance1;
  91. float3 cull1 : SV_CullDistance1;
  92. float4 bar : BAR;
  93. T t;
  94. };
  95. If we have an ``S`` input parameter in pixel shader, we should flatten it
  96. recursively to generate five SPIR-V ``Input`` variables. Three of them are
  97. decorated by the ``Position``, ``ClipDistance``, ``CullDistance`` builtin,
  98. and two of them are decorated by the ``Location`` decoration. (Note that
  99. ``clip0`` and ``clip1`` are concatenated, also ``cull0`` and ``cull1``.
  100. The ``ClipDistance`` and ``CullDistance`` builtins are special and explained
  101. in the `ClipDistance & CullDistance`_ section.)
  102. Flattening is infective because of Vulkan interface matching rules. If we
  103. flatten a struct in the output of a previous stage, which may create multiple
  104. variables decorated with different ``Location`` numbers, we also need to
  105. flatten it in the input of the next stage. otherwise we may have ``Location``
  106. mismatch even if we share the same definition of the struct. Because
  107. hull/domain/geometry shader is optional, we can have different chains of shader
  108. stages, which means we need to flatten all shader stage interfaces. For
  109. hull/domain/geometry shader, their inputs/outputs have an additional arrayness.
  110. So if we are seeing an array of structs in these shaders, we need to flatten
  111. them into arrays of its fields.
  112. Vulkan specific features
  113. ------------------------
  114. We try to implement Vulkan specific features using the most intuitive and
  115. non-intrusive ways in HLSL, which means we will prefer native language
  116. constructs when possible. If that is inadequate, we then consider attaching
  117. `Vulkan specific attributes`_ to them, or introducing new syntax.
  118. Descriptors
  119. ~~~~~~~~~~~
  120. The compiler provides multiple mechanisms to specify which Vulkan descriptor
  121. a particular resource binds to.
  122. In the source code, you can use the ``[[vk::binding(X[, Y])]]`` and
  123. ``[[vk::counter_binding(X)]]`` attribute. The native ``:register()`` attribute
  124. is also respected.
  125. On the command-line, you can use the ``-fvk-{b|s|t|u}-shift`` or
  126. ``-fvk-bind-register`` option.
  127. If you can modify the source code, the ``[[vk::binding(X[, Y])]]`` and
  128. ``[[vk::counter_binding(X)]]`` attribute gives you find-grained control over
  129. descriptor assignment.
  130. If you cannot modify the source code, you can use command-line options to change
  131. how ``:register()`` attribute is handled by the compiler. ``-fvk-bind-register``
  132. lets you to specify the descriptor for the source at a certain register.
  133. ``-fvk-{b|s|t|u}-shift`` lets you to apply shifts to all register numbers
  134. of a certain register type. They cannot be used together, though.
  135. Without attribute and command-line option, ``:register(xX, spaceY)`` will be
  136. mapped to binding ``X`` in descriptor set ``Y``. Note that register type ``x``
  137. is ignored, so this may cause overlap.
  138. The more specific a mechanism is, the higher precedence it has, and command-line
  139. option has higher precedence over source code attribute.
  140. For more details, see `HLSL register and Vulkan binding`_, `Vulkan specific
  141. attributes`_, and `Vulkan-specific options`_.
  142. Subpass inputs
  143. ~~~~~~~~~~~~~~
  144. Within a Vulkan `rendering pass <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#renderpass>`_,
  145. a subpass can write results to an output target that can then be read by the
  146. next subpass as an input subpass. The "Subpass Input" feature regards the
  147. ability to read an output target.
  148. Subpasses are read through two new builtin resource types, available only in
  149. pixel shader:
  150. .. code:: hlsl
  151. class SubpassInput<T> {
  152. T SubpassLoad();
  153. };
  154. class SubpassInputMS<T> {
  155. T SubpassLoad(int sampleIndex);
  156. };
  157. In the above, ``T`` is a scalar or vector type. If omitted, it will defaults to
  158. ``float4``.
  159. Subpass inputs are implicitly addressed by the pixel's (x, y, layer) coordinate.
  160. These objects support reading the subpass input through the methods as shown
  161. in the above.
  162. A subpass input is selected by using a new attribute ``vk::input_attachment_index``.
  163. For example:
  164. .. code:: hlsl
  165. [[vk::input_attachment_index(i)]] SubpassInput input;
  166. An ``vk::input_attachment_index`` of ``i`` selects the ith entry in the input
  167. pass list. (See Vulkan API spec for more information.)
  168. Push constants
  169. ~~~~~~~~~~~~~~
  170. Vulkan push constant blocks are represented using normal global variables of
  171. struct types in HLSL. The variables (not the underlying struct types) should be
  172. annotated with the ``[[vk::push_constant]]`` attribute.
  173. Please note as per the requirements of Vulkan, "there must be no more than one
  174. push constant block statically used per shader entry point."
  175. Specialization constants
  176. ~~~~~~~~~~~~~~~~~~~~~~~~
  177. To use Vulkan specialization constants, annotate global constants with the
  178. ``[[vk::constant_id(X)]]`` attribute. For example,
  179. .. code:: hlsl
  180. [[vk::constant_id(1)]] const bool specConstBool = true;
  181. [[vk::constant_id(2)]] const int specConstInt = 42;
  182. [[vk::constant_id(3)]] const float specConstFloat = 1.5;
  183. Shader Record Buffer
  184. ~~~~~~~~~~~~~~~~~~~~
  185. SPV_NV_ray_tracing exposes user managed buffer in shader binding table by
  186. using storage class ShaderRecordBufferNV. ConstantBuffer or cbuffer blocks
  187. can now be mapped to this storage class under HLSL by using
  188. ``[[vk::shader_record_nv]]`` annotation. It is applicable only on ConstantBuffer
  189. and cbuffer declarations.
  190. Please note as per the requirements of VK_NV_ray_tracing, "there must be no
  191. more than one shader_record_nv block statically used per shader entry point
  192. otherwise results are undefined."
  193. The official Khronos ray tracing extension also comes with a SPIR-V storage class
  194. that has the same functionality. The ``[[vk::shader_record_ext]]`` annotation can
  195. be used when targeting the SPV_KHR_ray_tracing extension.
  196. Builtin variables
  197. ~~~~~~~~~~~~~~~~~
  198. Some of the Vulkan builtin variables have no equivalents in native HLSL
  199. language. To support them, ``[[vk::builtin("<builtin>")]]`` is introduced.
  200. Right now the following ``<builtin>`` are supported:
  201. * ``PointSize``: The GLSL equivalent is ``gl_PointSize``.
  202. * ``HelperInvocation``: The GLSL equivalent is ``gl_HelperInvocation``.
  203. * ``BaseVertex``: The GLSL equivalent is ``gl_BaseVertexARB``.
  204. Need ``SPV_KHR_shader_draw_parameters`` extension.
  205. * ``BaseInstance``: The GLSL equivalent is ``gl_BaseInstanceARB``.
  206. Need ``SPV_KHR_shader_draw_parameters`` extension.
  207. * ``DrawIndex``: The GLSL equivalent is ``gl_DrawIDARB``.
  208. Need ``SPV_KHR_shader_draw_parameters`` extension.
  209. * ``DeviceIndex``: The GLSL equivalent is ``gl_DeviceIndex``.
  210. Need ``SPV_KHR_device_group`` extension.
  211. * ``ViewportMaskNV``: The GLSL equivalent is ``gl_ViewportMask``.
  212. Please see Vulkan spec. `14.6. Built-In Variables <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#interfaces-builtin-variables>`_
  213. for detailed explanation of these builtins.
  214. Supported extensions
  215. ~~~~~~~~~~~~~~~~~~~~
  216. * SPV_KHR_16bit_storage
  217. * SPV_KHR_device_group
  218. * SPV_KHR_multivew
  219. * SPV_KHR_post_depth_coverage
  220. * SPV_KHR_shader_draw_parameters
  221. * SPV_EXT_descriptor_indexing
  222. * SPV_EXT_fragment_fully_covered
  223. * SPV_KHR_fragment_shading_rate
  224. * SPV_EXT_shader_stencil_support
  225. * SPV_AMD_shader_explicit_vertex_parameter
  226. * SPV_GOOGLE_hlsl_functionality1
  227. * SPV_NV_mesh_shader
  228. Vulkan specific attributes
  229. --------------------------
  230. `C++ attribute specifier sequence <http://en.cppreference.com/w/cpp/language/attributes>`_
  231. is a non-intrusive way of providing Vulkan specific information in HLSL.
  232. The namespace ``vk`` will be used for all Vulkan attributes:
  233. - ``location(X)``: For specifying the location (``X``) numbers for stage
  234. input/output variables. Allowed on function parameters, function returns,
  235. and struct fields.
  236. - ``binding(X[, Y])``: For specifying the descriptor set (``Y``) and binding
  237. (``X``) numbers for resource variables. The descriptor set (``Y``) is
  238. optional; if missing, it will be set to 0. Allowed on global variables.
  239. - ``counter_binding(X)``: For specifying the binding number (``X``) for the
  240. associated counter for RW/Append/Consume structured buffer. The descriptor
  241. set number for the associated counter is always the same as the main resource.
  242. - ``push_constant``: For marking a variable as the push constant block. Allowed
  243. on global variables of struct type. At most one variable can be marked as
  244. ``push_constant`` in a shader.
  245. - ``offset(X)``: For manually layout struct members. Annotating a struct member
  246. with this attribute will force the compiler to put the member at offset ``X``
  247. w.r.t. the beginning of the struct. Only allowed on struct members.
  248. - ``constant_id(X)``: For marking a global constant as a specialization constant.
  249. Allowed on global variables of boolean/integer/float types.
  250. - ``input_attachment_index(X)``: To associate the Xth entry in the input pass
  251. list to the annotated object. Only allowed on objects whose type are
  252. ``SubpassInput`` or ``SubpassInputMS``.
  253. - ``builtin("X")``: For specifying an entity should be translated into a certain
  254. Vulkan builtin variable. Allowed on function parameters, function returns,
  255. and struct fields.
  256. - ``index(X)``: For specifying the index at a specific pixel shader output
  257. location. Used for dual-source blending.
  258. - ``post_depth_coverage``: The input variable decorated with SampleMask will
  259. reflect the result of the EarlyFragmentTests. Only valid on pixel shader entry points.
  260. Only ``vk::`` attributes in the above list are supported. Other attributes will
  261. result in warnings and be ignored by the compiler. All C++11 attributes will
  262. only trigger warnings and be ignored if not compiling towards SPIR-V.
  263. For example, to specify the layout of resource variables and the location of
  264. interface variables:
  265. .. code:: hlsl
  266. struct S { ... };
  267. [[vk::binding(X, Y), vk::counter_binding(Z)]]
  268. RWStructuredBuffer<S> mySBuffer;
  269. [[vk::location(M)]] float4
  270. main([[vk::location(N)]] float4 input: A) : B
  271. { ... }
  272. SPIR-V version and extension
  273. ----------------------------
  274. SPIR-V CodeGen provides two command-line options for fine-grained SPIR-V target
  275. environment (hence SPIR-V version) and SPIR-V extension control:
  276. - ``-fspv-target-env=``: for specifying SPIR-V target environment
  277. - ``-fspv-extension=``: for specifying allowed SPIR-V extensions
  278. ``-fspv-target-env=`` only accepts ``vulkan1.0`` and ``vulkan1.1`` right now.
  279. If such an option is not given, the CodeGen defaults to ``vulkan1.0``. When
  280. targeting ``vulkan1.0``, trying to use features that are only available
  281. in Vulkan 1.1 (SPIR-V 1.3), like `Shader Model 6.0 wave intrinsics`_, will
  282. trigger a compiler error.
  283. If ``-fspv-extension=`` is not specified, the CodeGen will select suitable
  284. SPIR-V extensions to translate the source code. Otherwise, only extensions
  285. supplied via ``-fspv-extension=`` will be used. If that does not suffice, errors
  286. will be emitted explaining what additional extensions are required to translate
  287. what specific feature in the source code. If you want to allow all KHR
  288. extensions, you can use ``-fspv-extension=KHR``.
  289. Legalization, optimization, validation
  290. --------------------------------------
  291. After initial translation of the HLSL source code, SPIR-V CodeGen will further
  292. conduct legalization (if needed), optimization (if requested), and validation
  293. (if not turned off). All these three stages are outsourced to `SPIRV-Tools <https://github.com/KhronosGroup/SPIRV-Tools>`_.
  294. Here are the options controlling these stages:
  295. * ``-fcgl``: turn off legalization and optimization
  296. * ``-Od``: turn off optimization
  297. * ``-Vd``: turn off validation
  298. Legalization
  299. ~~~~~~~~~~~~
  300. HLSL is a fairly permissive language considering the flexibility it provides for
  301. manipulating resource objects. The developer can create local copies, pass
  302. them around as function parameters and return values, as long as after certain
  303. transformations (function inlining, constant evaluation and propagating, dead
  304. code elimination, etc.), the compiler can remove all temporary copies and
  305. pinpoint all uses to unique global resource objects.
  306. Resulting from the above property of HLSL, if we translate into SPIR-V for
  307. Vulkan literally from the input HLSL source code, we will sometimes generate
  308. illegal SPIR-V. Certain transformations are needed to legalize the literally
  309. translated SPIR-V. Performing such transformations at the frontend AST level
  310. is cumbersome or impossible (e.g., function inlining). They are better to be
  311. conducted at SPIR-V level. Therefore, legalization is delegated to SPIRV-Tools.
  312. Specifically, we need to legalize the following HLSL source code patterns:
  313. * Using resource types in struct types
  314. * Creating aliases of global resource objects
  315. * Control flows invovling the above cases
  316. Legalization transformations will not run unless the above patterns are
  317. encountered in the source code.
  318. For more details, please see the `SPIR-V cookbook <https://github.com/Microsoft/DirectXShaderCompiler/tree/master/docs/SPIRV-Cookbook.rst>`_,
  319. which contains examples of what HLSL code patterns will be accepted and
  320. generate valid SPIR-V for Vulkan.
  321. Optimization
  322. ~~~~~~~~~~~~
  323. Optimization is also delegated to SPIRV-Tools. Right now there are no difference
  324. between optimization levels greater than zero; they will all invoke the same
  325. optimization recipe. That is, the recipe behind ``spirv-opt -O``. If you want to
  326. run a custom optimization recipe, you can do so using the command line option
  327. ``-Oconfig=`` and specifying a comma-separated list of your desired passes.
  328. The passes are invoked in the specified order.
  329. For example, you can specify ``-Oconfig=--loop-unroll,--scalar-replacement=300,--eliminate-dead-code-aggressive``
  330. to firstly invoke loop unrolling, then invoke scalar replacement of aggregates,
  331. lastly invoke aggressive dead code elimination. All valid options to
  332. ``spirv-opt`` are accepted as components to the comma-separated list.
  333. Here are the typical passes in alphabetical order:
  334. * ``--ccp``
  335. * ``--cfg-cleanup``
  336. * ``--convert-local-access-chains``
  337. * ``--copy-propagate-arrays``
  338. * ``--eliminate-dead-branches``
  339. * ``--eliminate-dead-code-aggressive``
  340. * ``--eliminate-dead-functions``
  341. * ``--eliminate-local-multi-store``
  342. * ``--eliminate-local-single-block``
  343. * ``--eliminate-local-single-store``
  344. * ``--flatten-decorations``
  345. * ``--if-conversion``
  346. * ``--inline-entry-points-exhaustive``
  347. * ``--local-redundancy-elimination``
  348. * ``--loop-fission``
  349. * ``--loop-fusion``
  350. * ``--loop-unroll``
  351. * ``--loop-unroll-partial=[<n>]``
  352. * ``--loop-peeling`` (requires ``--loop-peeling-threshold``)
  353. * ``--merge-blocks``
  354. * ``--merge-return``
  355. * ``--loop-unswitch``
  356. * ``--private-to-local``
  357. * ``--reduce-load-size``
  358. * ``--redundancy-elimination``
  359. * ``--remove-duplicates``
  360. * ``--replace-invalid-opcode``
  361. * ``--ssa-rewrite``
  362. * ``--scalar-replacement[=<n>]``
  363. * ``--simplify-instructions``
  364. * ``--vector-dce``
  365. Besides, there are two special batch options; each stands for a recommended
  366. recipe by itself:
  367. * ``-O``: A bunch of passes in an appropriate order that attempt to improve
  368. performance of generated code. Same as ``spirv-opt -O``. Also same as SPIR-V
  369. CodeGen's default recipe.
  370. * ``-Os``: A bunch of passes in an appropriate order that attempt to reduce the
  371. size of the generated code. Same as ``spirv-opt -Os``.
  372. So if you want to run loop unrolling additionally after the default optimization
  373. recipe, you can specify ``-Oconfig=-O,--loop-unroll``.
  374. For the whole list of accepted passes and details about each one, please see
  375. ``spirv-opt``'s help manual (``spirv-opt --help``), or the SPIRV-Tools `optimizer header file <https://github.com/KhronosGroup/SPIRV-Tools/blob/master/include/spirv-tools/optimizer.hpp>`_.
  376. Validation
  377. ~~~~~~~~~~
  378. Validation is turned on by default as the last stage of SPIR-V CodeGen. Failing
  379. validation, which indicates there is a CodeGen bug, will trigger a fatal error.
  380. Please file an issue if you see that.
  381. Debugging
  382. ---------
  383. By default, the compiler will only emit names for types and variables as debug
  384. information, to aid reading of the generated SPIR-V. The ``-Zi`` option will
  385. let the compiler emit the following additional debug information:
  386. * Full path of the main source file using ``OpSource``
  387. * Preprocessed source code using ``OpSource`` and ``OpSourceContinued``
  388. * Line information for certain instructions using ``OpLine`` (WIP)
  389. * DXC Git commit hash using ``OpModuleProcessed`` (requires Vulkan 1.1)
  390. * DXC command-line options used to compile the shader using ``OpModuleProcessed``
  391. (requires Vulkan 1.1)
  392. We chose to embed preprocessed source code instead of original source code to
  393. avoid pulling in lots of contents unrelated to the current entry point, and
  394. boilerplate contents generated by engines. We may add a mode for selecting
  395. between preprocessed single source code and original separated source code in
  396. the future.
  397. One thing to note is that to keep the line numbers in consistent with the
  398. embedded source, the compiler is invoked twice; the first time is for
  399. preprocessing the source code, and the second time is for feeding the
  400. preprocessed source code as input for a whole compilation. So using ``-Zi``
  401. means performance penality.
  402. If you want to have fine-grained control over the categories of emitted debug
  403. information, you can use ``-fspv-debug=``. It accepts:
  404. * ``file``: for emitting full path of the main source file
  405. * ``source``: for emitting preprocessed source code (turns on ``file`` implicitly)
  406. * ``line``: for emitting line information (turns on ``source`` implicitly)
  407. * ``tool``: for emitting DXC Git commit hash and command-line options
  408. ``-fspv-debug=`` overrules ``-Zi``. And you can provide multiple instances of
  409. ``-fspv-debug=``. For example, you can use ``-fspv-debug=file -fspv-debug=tool``
  410. to turn on emitting file path and DXC information; source code and line
  411. information will not be emitted.
  412. Reflection
  413. ----------
  414. Making reflection easier is one of the goals of SPIR-V CodeGen. This section
  415. provides guidelines about how to reflect on certain facts.
  416. Note that we generate ``OpName``/``OpMemberName`` instructions for various
  417. types/variables both explicitly defined in the source code and interally created
  418. by the compiler. These names are primarily for debugging purposes in the
  419. compiler. They have "no semantic impact and can safely be removed" according
  420. to the SPIR-V spec. And they are subject to changes without notice. So we do
  421. not suggest to use them for reflection.
  422. Source code shader profile
  423. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  424. The source code shader profile version can be re-discovered by the "Version"
  425. operand in ``OpSource`` instruction. For ``*s_<major>_<minor>``, the "Verison"
  426. operand in ``OpSource`` will be set as ``<major>`` * 100 + ``<minor>`` * 10.
  427. For example, ``vs_5_1`` will have 510, ``ps_6_2`` will have 620.
  428. HLSL Semantic
  429. ~~~~~~~~~~~~~
  430. HLSL semantic strings are by default not emitted into the SPIR-V binary module.
  431. If you need them, by specifying ``-fspv-reflect``, the compiler will use
  432. the ``Op*DecorateStringGOOGLE`` instruction in `SPV_GOOGLE_hlsl_funtionality1 <https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/GOOGLE/SPV_GOOGLE_hlsl_functionality1.asciidoc>`_
  433. extension to emit them.
  434. Counter buffers for RW/Append/Consume StructuredBuffer
  435. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  436. The association between a counter buffer and its main RW/Append/Consume
  437. StructuredBuffer is conveyed by ``OpDecorateId <structured-buffer-id>
  438. HLSLCounterBufferGOOGLE <counter-buffer-id>`` instruction from the
  439. `SPV_GOOGLE_hlsl_funtionality1 <https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/GOOGLE/SPV_GOOGLE_hlsl_functionality1.asciidoc>`_
  440. extension. This information is by default missing; you need to specify
  441. ``-fspv-reflect`` to direct the compiler to emit them.
  442. Read-only vs. read-write resource types
  443. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  444. There are no clear and consistent decorations in the SPIR-V to show whether a
  445. resource type is translated from a read-only (RO) or read-write (RW) HLSL
  446. resource type. Instead, you need to use different checks for reflecting different
  447. resource types:
  448. * HLSL samplers: RO.
  449. * HLSL ``Buffer``/``RWBuffer``/``Texture*``/``RWTexture*``: Check the "Sampled"
  450. operand in the ``OpTypeImage`` instruction they translated into. "2" means RW,
  451. "1" means RO.
  452. * HLSL constant/texture/structured/byte buffers: Check both ``Block``/``BufferBlock``
  453. and ``NonWritable`` decoration. If decorated with ``Block`` (``cbuffer`` &
  454. ``ConstantBuffer``), then RO; if decorated with ``BufferBlock`` and ``NonWritable``
  455. (``tbuffer``, ``TextureBuffer``, ``StructuredBuffer``), then RO; Otherwise, RW.
  456. HLSL Types
  457. ==========
  458. This section lists how various HLSL types are mapped.
  459. Normal scalar types
  460. -------------------
  461. `Normal scalar types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509646(v=vs.85).aspx>`_
  462. in HLSL are relatively easy to handle and can be mapped directly to SPIR-V
  463. type instructions:
  464. ============================== ======================= ================== =========== =================================
  465. HLSL Command Line Option SPIR-V Capability Extension
  466. ============================== ======================= ================== =========== =================================
  467. ``bool`` ``OpTypeBool``
  468. ``int``/``int32_t`` ``OpTypeInt 32 1``
  469. ``int16_t`` ``-enable-16bit-types`` ``OpTypeInt 16 1`` ``Int16``
  470. ``uint``/``dword``/``uin32_t`` ``OpTypeInt 32 0``
  471. ``uint16_t`` ``-enable-16bit-types`` ``OpTypeInt 16 0`` ``Int16``
  472. ``half`` ``OpTypeFloat 32``
  473. ``half``/``float16_t`` ``-enable-16bit-types`` ``OpTypeFloat 16`` ``SPV_AMD_gpu_shader_half_float``
  474. ``float``/``float32_t`` ``OpTypeFloat 32``
  475. ``snorm float`` ``OpTypeFloat 32``
  476. ``unorm float`` ``OpTypeFloat 32``
  477. ``double``/``float64_t`` ``OpTypeFloat 64`` ``Float64``
  478. ============================== ======================= ================== =========== =================================
  479. Please note that ``half`` is translated into 32-bit floating point numbers
  480. if without ``-enable-16bit-types`` because MSDN says that "this data type
  481. is provided only for language compatibility. Direct3D 10 shader targets map
  482. all ``half`` data types to ``float`` data types."
  483. Minimal precision scalar types
  484. ------------------------------
  485. HLSL also supports various
  486. `minimal precision scalar types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509646(v=vs.85).aspx>`_,
  487. which graphics drivers can implement by using any precision greater than or
  488. equal to their specified bit precision.
  489. There are no direct mappings in SPIR-V for these types. We translate them into
  490. the corresponding 16-bit or 32-bit scalar types with the ``RelaxedPrecision`` decoration.
  491. We use the 16-bit variants if '-enable-16bit-types' command line option is present.
  492. For more information on these types, please refer to:
  493. https://github.com/Microsoft/DirectXShaderCompiler/wiki/16-Bit-Scalar-Types
  494. ============== ======================= ================== ==================== ============ =================================
  495. HLSL Command Line Option SPIR-V Decoration Capability Extension
  496. ============== ======================= ================== ==================== ============ =================================
  497. ``min16float`` ``OpTypeFloat 32`` ``RelaxedPrecision``
  498. ``min10float`` ``OpTypeFloat 32`` ``RelaxedPrecision``
  499. ``min16int`` ``OpTypeInt 32 1`` ``RelaxedPrecision``
  500. ``min12int`` ``OpTypeInt 32 1`` ``RelaxedPrecision``
  501. ``min16uint`` ``OpTypeInt 32 0`` ``RelaxedPrecision``
  502. ``min16float`` ``-enable-16bit-types`` ``OpTypeFloat 16`` ``SPV_AMD_gpu_shader_half_float``
  503. ``min10float`` ``-enable-16bit-types`` ``OpTypeFloat 16`` ``SPV_AMD_gpu_shader_half_float``
  504. ``min16int`` ``-enable-16bit-types`` ``OpTypeInt 16 1`` ``Int16``
  505. ``min12int`` ``-enable-16bit-types`` ``OpTypeInt 16 1`` ``Int16``
  506. ``min16uint`` ``-enable-16bit-types`` ``OpTypeInt 16 0`` ``Int16``
  507. ============== ======================= ================== ==================== ============ =================================
  508. Vectors and matrices
  509. --------------------
  510. `Vectors <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509707(v=vs.85).aspx>`_
  511. and `matrices <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509623(v=vs.85).aspx>`_
  512. are translated into:
  513. ==================================== ====================================================
  514. HLSL SPIR-V
  515. ==================================== ====================================================
  516. ``|type|N`` (``N`` > 1) ``OpTypeVector |type| N``
  517. ``|type|1`` The scalar type for ``|type|``
  518. ``|type|MxN`` (``M`` > 1, ``N`` > 1) ``%v = OpTypeVector |type| N`` ``OpTypeMatrix %v M``
  519. ``|type|Mx1`` (``M`` > 1) ``OpTypeVector |type| M``
  520. ``|type|1xN`` (``N`` > 1) ``OpTypeVector |type| N``
  521. ``|type|1x1`` The scalar type for ``|type|``
  522. ==================================== ====================================================
  523. The above table is for float matrices.
  524. A MxN HLSL float matrix is translated into a SPIR-V matrix with M vectors, each with
  525. N elements. Conceptually HLSL matrices are row-major while SPIR-V matrices are
  526. column-major, thus all HLSL matrices are represented by their transposes.
  527. Doing so may require special handling of certain matrix operations:
  528. - **Indexing**: no special handling required. ``matrix[m][n]`` will still access
  529. the correct element since ``m``/``n`` means the ``m``-th/``n``-th row/column
  530. in HLSL but ``m``-th/``n``-th vector/element in SPIR-V.
  531. - **Per-element operation**: no special handling required.
  532. - **Matrix multiplication**: need to swap the operands. ``mat1 x mat2`` should
  533. be translated as ``transpose(mat2) x transpose(mat1)``. Then the result is
  534. ``transpose(mat1 x mat2)``.
  535. - **Storage layout**: ``row_major``/``column_major`` will be translated into
  536. SPIR-V ``ColMajor``/``RowMajor`` decoration. This is because HLSL matrix
  537. row/column becomes SPIR-V matrix column/row. If elements in a row/column are
  538. packed together, they should be loaded into a column/row correspondingly.
  539. See `Appendix A. Matrix Representation`_ for further explanation regarding these design choices.
  540. Since the ``Shader`` capability in SPIR-V does not allow to parameterize matrix
  541. types with non-floating-point types, a non-floating-point MxN matrix is translated
  542. into an array with M elements, with each element being a vector with N elements.
  543. Structs
  544. -------
  545. `Structs <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509668(v=vs.85).aspx>`_
  546. in HLSL are defined in the a format similar to C structs. They are translated
  547. into SPIR-V ``OpTypeStruct``. Depending on the storage classes of the instances,
  548. a single struct definition may generate multiple ``OpTypeStruct`` instructions
  549. in SPIR-V. For example, for the following HLSL source code:
  550. .. code:: hlsl
  551. struct S { ... }
  552. ConstantBuffer<S> myCBuffer;
  553. StructuredBuffer<S> mySBuffer;
  554. float4 main() : A {
  555. S myLocalVar;
  556. ...
  557. }
  558. There will be three different ``OpTypeStruct`` generated, one for each variable
  559. defined in the above source code. This is because the ``OpTypeStruct`` for
  560. both ``myCBuffer`` and ``mySBuffer`` will have layout decorations (``Offset``,
  561. ``MatrixStride``, ``ArrayStride``, ``RowMajor``, ``ColMajor``). However, their
  562. layout rules are different (by default); ``myCBuffer`` will use vector-relaxed
  563. OpenGL ``std140`` while ``mySBuffer`` will use vector-relaxed OpenGL ``std430``.
  564. ``myLocalVar`` will have its ``OpTypeStruct`` without layout decorations.
  565. Read more about storage classes in the `Constant/Texture/Structured/Byte Buffers`_
  566. section.
  567. Structs used as stage inputs/outputs will have semantics attached to their
  568. members. These semantics are handled in the `entry function wrapper`_.
  569. Structs used as pixel shader inputs can have optional interpolation modifiers
  570. for their members, which will be translated according to the following table:
  571. =========================== ================= =====================
  572. HLSL Interpolation Modifier SPIR-V Decoration SPIR-V Capability
  573. =========================== ================= =====================
  574. ``linear`` <none>
  575. ``centroid`` ``Centroid``
  576. ``nointerpolation`` ``Flat``
  577. ``noperspective`` ``NoPerspective``
  578. ``sample`` ``Sample`` ``SampleRateShading``
  579. =========================== ================= =====================
  580. Arrays
  581. ------
  582. Sized (either explicitly or implicitly) arrays are translated into SPIR-V
  583. `OpTypeArray`. Unsized arrays are translated into `OpTypeRuntimeArray`.
  584. Arrays, if used for external resources (residing in SPIR-V `Uniform` or
  585. `UniformConstant` storage class), will need layout decorations like SPIR-V
  586. `ArrayStride` decoration. For arrays of opaque types, e.g., HLSL textures
  587. or samplers, we don't decorate with `ArrayStride` decorations since there is
  588. no meaningful strides. Similarly for arrays of structured/byte buffers.
  589. User-defined types
  590. ------------------
  591. `User-defined types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509702(v=vs.85).aspx>`_
  592. are type aliases introduced by typedef. No new types are introduced and we can
  593. rely on Clang to resolve to the original types.
  594. Samplers
  595. --------
  596. All `sampler types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509644(v=vs.85).aspx>`_
  597. will be translated into SPIR-V ``OpTypeSampler``.
  598. SPIR-V ``OpTypeSampler`` is an opaque type that cannot be parameterized;
  599. therefore state assignments on sampler types is not supported (yet).
  600. Textures
  601. --------
  602. `Texture types <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509700(v=vs.85).aspx>`_
  603. are translated into SPIR-V ``OpTypeImage``, with parameters:
  604. ======================= ==================== ===== =================== ========== ===== ======= == ======= ================ =================
  605. HLSL Vulkan SPIR-V
  606. ----------------------- -------------------------- ------------------------------------------------------------------------------------------
  607. Texture Type Descriptor Type RO/RW Storage Class Dim Depth Arrayed MS Sampled Image Format Capability
  608. ======================= ==================== ===== =================== ========== ===== ======= == ======= ================ =================
  609. ``Texture1D`` Sampled Image RO ``UniformConstant`` ``1D`` 2 0 0 1 ``Unknown``
  610. ``Texture2D`` Sampled Image RO ``UniformConstant`` ``2D`` 2 0 0 1 ``Unknown``
  611. ``Texture3D`` Sampled Image RO ``UniformConstant`` ``3D`` 2 0 0 1 ``Unknown``
  612. ``TextureCube`` Sampled Image RO ``UniformConstant`` ``Cube`` 2 0 0 1 ``Unknown``
  613. ``Texture1DArray`` Sampled Image RO ``UniformConstant`` ``1D`` 2 1 0 1 ``Unknown``
  614. ``Texture2DArray`` Sampled Image RO ``UniformConstant`` ``2D`` 2 1 0 1 ``Unknown``
  615. ``Texture2DMS`` Sampled Image RO ``UniformConstant`` ``2D`` 2 0 1 1 ``Unknown``
  616. ``Texture2DMSArray`` Sampled Image RO ``UniformConstant`` ``2D`` 2 1 1 1 ``Unknown`` ``ImageMSArray``
  617. ``TextureCubeArray`` Sampled Image RO ``UniformConstant`` ``3D`` 2 1 0 1 ``Unknown``
  618. ``Buffer<T>`` Uniform Texel Buffer RO ``UniformConstant`` ``Buffer`` 2 0 0 1 Depends on ``T`` ``SampledBuffer``
  619. ``RWBuffer<T>`` Storage Texel Buffer RW ``UniformConstant`` ``Buffer`` 2 0 0 2 Depends on ``T`` ``SampledBuffer``
  620. ``RWTexture1D<T>`` Storage Image RW ``UniformConstant`` ``1D`` 2 0 0 2 Depends on ``T``
  621. ``RWTexture2D<T>`` Storage Image RW ``UniformConstant`` ``2D`` 2 0 0 2 Depends on ``T``
  622. ``RWTexture3D<T>`` Storage Image RW ``UniformConstant`` ``3D`` 2 0 0 2 Depends on ``T``
  623. ``RWTexture1DArray<T>`` Storage Image RW ``UniformConstant`` ``1D`` 2 1 0 2 Depends on ``T``
  624. ``RWTexture2DArray<T>`` Storage Image RW ``UniformConstant`` ``2D`` 2 1 0 2 Depends on ``T``
  625. ======================= ==================== ===== =================== ========== ===== ======= == ======= ================ =================
  626. The meanings of the headers in the above table is explained in ``OpTypeImage``
  627. of the SPIR-V spec.
  628. Vulkan specific Image Formats
  629. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  630. Since HLSL lacks the syntax for fully specifying image formats for textures in
  631. SPIR-V, we introduce ``[[vk::image_format("FORMAT")]]`` attribute for texture types.
  632. For example,
  633. .. code:: hlsl
  634. [[vk::image_format("rgba8")]]
  635. RWBuffer<float4> Buf;
  636. [[vk::image_format("rg16f")]]
  637. RWTexture2D<float2> Tex;
  638. RWTexture2D<float2> Tex2; // Works like before
  639. ``rgba8`` means ``Rgba8`` `SPIR-V Image Format <https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_image_format_a_image_format>`_.
  640. The following table lists the mapping between ``FORMAT`` of
  641. ``[[vk::image_format("FORMAT")]]`` and its corresponding SPIR-V Image Format.
  642. ======================= ============================================
  643. FORMAT SPIR-V Image Format
  644. ======================= ============================================
  645. ``unknown`` ``Unknown``
  646. ``rgba32f`` ``Rgba32f``
  647. ``rgba16f`` ``Rgba16f``
  648. ``r32f`` ``R32f``
  649. ``rgba8`` ``Rgba8``
  650. ``rgba8snorm`` ``Rgba8Snorm``
  651. ``rg32f`` ``Rg32f``
  652. ``rg16f`` ``Rg16f``
  653. ``r11g11b10f`` ``R11fG11fB10f``
  654. ``r16f`` ``R16f``
  655. ``rgba16`` ``Rgba16``
  656. ``rgb10a2`` ``Rgb10A2``
  657. ``rg16`` ``Rg16``
  658. ``rg8`` ``Rg8``
  659. ``r16`` ``R16``
  660. ``r8`` ``R8``
  661. ``rgba16snorm`` ``Rgba16Snorm``
  662. ``rg16snorm`` ``Rg16Snorm``
  663. ``rg8snorm`` ``Rg8Snorm``
  664. ``r16snorm`` ``R16Snorm``
  665. ``r8snorm`` ``R8Snorm``
  666. ``rgba32i`` ``Rgba32i``
  667. ``rgba16i`` ``Rgba16i``
  668. ``rgba8i`` ``Rgba8i``
  669. ``r32i`` ``R32i``
  670. ``rg32i`` ``Rg32i``
  671. ``rg16i`` ``Rg16i``
  672. ``rg8i`` ``Rg8i``
  673. ``r16i`` ``R16i``
  674. ``r8i`` ``R8i``
  675. ``rgba32ui`` ``Rgba32ui``
  676. ``rgba16ui`` ``Rgba16ui``
  677. ``rgba8ui`` ``Rgba8ui``
  678. ``r32ui`` ``R32ui``
  679. ``rgb10a2ui`` ``Rgb10a2ui``
  680. ``rg32ui`` ``Rg32ui``
  681. ``rg16ui`` ``Rg16ui``
  682. ``rg8ui`` ``Rg8ui``
  683. ``r16ui`` ``R16ui``
  684. ``r8ui`` ``R8ui``
  685. ``r64ui`` ``R64ui``
  686. ``r64i`` ``R64i``
  687. ======================= ============================================
  688. Constant/Texture/Structured/Byte Buffers
  689. ----------------------------------------
  690. There are serveral buffer types in HLSL:
  691. - ``cbuffer`` and ``ConstantBuffer``
  692. - ``tbuffer`` and ``TextureBuffer``
  693. - ``StructuredBuffer`` and ``RWStructuredBuffer``
  694. - ``AppendStructuredBuffer`` and ``ConsumeStructuredBuffer``
  695. - ``ByteAddressBuffer`` and ``RWByteAddressBuffer``
  696. Note that ``Buffer`` and ``RWBuffer`` are considered as texture object in HLSL.
  697. They are listed in the above section.
  698. Please see the following sections for the details of each type. As a summary:
  699. =========================== ================== ================================ ==================== =================
  700. HLSL Type Vulkan Buffer Type Default Memory Layout Rule SPIR-V Storage Class SPIR-V Decoration
  701. =========================== ================== ================================ ==================== =================
  702. ``cbuffer`` Uniform Buffer Vector-relaxed OpenGL ``std140`` ``Uniform`` ``Block``
  703. ``ConstantBuffer`` Uniform Buffer Vector-relaxed OpenGL ``std140`` ``Uniform`` ``Block``
  704. ``tbuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  705. ``TextureBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  706. ``StructuredBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  707. ``RWStructuredBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  708. ``AppendStructuredBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  709. ``ConsumeStructuredBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  710. ``ByteAddressBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  711. ``RWByteAddressBuffer`` Storage Buffer Vector-relaxed OpenGL ``std430`` ``Uniform`` ``BufferBlock``
  712. =========================== ================== ================================ ==================== =================
  713. To know more about the Vulkan buffer types, please refer to the Vulkan spec
  714. `13.1 Descriptor Types <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#descriptorsets-types>`_.
  715. Memory layout rules
  716. ~~~~~~~~~~~~~~~~~~~
  717. SPIR-V CodeGen supports four sets of memory layout rules for buffer resources
  718. right now:
  719. 1. Vector-relaxed OpenGL ``std140`` for uniform buffers and vector-relaxed
  720. OpenGL ``std430`` for storage buffers: these rules satisfy Vulkan `"Standard
  721. Uniform Buffer Layout" and "Standard Storage Buffer Layout" <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#interfaces-resources-layout>`_,
  722. respectively.
  723. They are the default.
  724. 2. DirectX memory layout rules for uniform buffers and storage buffers:
  725. they allow packing data on the application side that can be shared with
  726. DirectX. They can be enabled by ``-fvk-use-dx-layout``.
  727. 3. Strict OpenGL ``std140`` for uniform buffers and strict OpenGL ``std430``
  728. for storage buffers: they allow packing data on the application side that
  729. can be shared with OpenGL. They can be enabled by ``-fvk-use-gl-layout``.
  730. 4. Scalar layout rules introduced via `VK_EXT_scalar_block_layout`, which
  731. basically aligns all aggregrate types according to their elements'
  732. natural alignment. They can be enabled by ``-fvk-use-scalar-layout``.
  733. To use scalar layout, the application side need to request
  734. ``VK_EXT_scalar_block_layout``. This is also true for using DirectX memory
  735. layout since there is no dedicated DirectX layout extension for Vulkan
  736. (at least for now). So we must request something more permissive.
  737. In the above, "vector-relaxed OpenGL ``std140``/``std430``" rules mean OpenGL
  738. ``std140``/``std430`` rules with the following modification for vector type
  739. alignment:
  740. 1. The alignment of a vector type is set to be the alignment of its element type
  741. 2. If the above causes an `improper straddle <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#interfaces-resources-layout>`_,
  742. the alignment will be set to 16 bytes.
  743. As an exmaple, for the following HLSL definition:
  744. .. code:: hlsl
  745. struct S {
  746. float3 f;
  747. };
  748. struct T {
  749. float a_float;
  750. float3 b_float3;
  751. S c_S_float3;
  752. float2x3 d_float2x3;
  753. row_major float2x3 e_float2x3;
  754. int f_int_3[3];
  755. float2 g_float2_2[2];
  756. };
  757. We will have the following offsets for each member:
  758. ============== ====== ====== ====== ========== ====== ====== ====== ==========
  759. HLSL Uniform Buffer Storage Buffer
  760. -------------- ------------------------------- -------------------------------
  761. Member 1 (VK) 2 (DX) 3 (GL) 4 (Scalar) 1 (VK) 2 (DX) 3 (GL) 4 (Scalar)
  762. ============== ====== ====== ====== ========== ====== ====== ====== ==========
  763. ``a_float`` 0 0 0 0 0 0 0 0
  764. ``b_float3`` 4 4 16 4 4 4 16 4
  765. ``c_S_float3`` 16 16 32 16 16 16 32 16
  766. ``d_float2x3`` 32 32 48 28 32 28 48 28
  767. ``e_float2x3`` 80 80 96 52 64 52 80 52
  768. ``f_int_3`` 112 112 128 76 96 76 112 76
  769. ``g_float2_2`` 160 160 176 88 112 88 128 88
  770. ============== ====== ====== ====== ========== ====== ====== ====== ==========
  771. If the above layout rules do not satisfy your needs and you want to manually
  772. control the layout of struct members, you can use either
  773. * The native HLSL ``:packoffset()`` attribute: only available for cbuffers; or
  774. * The Vulkan-specific ``[[vk::offset()]]`` attribute: applies to all resources.
  775. ``[[vk::offset]]`` overrules ``:packoffset``. Attaching ``[[vk::offset]]``
  776. to a struct memeber affects all variables of the struct type in question. So
  777. sharing the same struct definition having ``[[vk::offset]]`` annotations means
  778. also sharing the layout.
  779. For global variables (which are collected into the ``$Globals`` cbuffer), you
  780. can use the native HLSL ``:register(c#)`` attribute. Note that ``[[vk::offset]]``
  781. and ``:packoffset`` cannot be applied to these variables.
  782. If ``register(cX)`` is used on any global variable, the offset for that variable
  783. is set to ``X * 16``, and the offset for all other global variables without the
  784. ``register(c#)`` annotation will be set to the next available address after
  785. the highest explicit address. For example:
  786. .. code:: hlsl
  787. float x : register(c10); // Offset = 160 (10 * 16)
  788. float y; // Offset = 164 (160 + 4)
  789. float z: register(c1); // Offset = 16 (1 * 16)
  790. These attributes give great flexibility but also responsibility to the
  791. developer; the compiler will just take in what is specified in the source code
  792. and emit it to SPIR-V with no error checking.
  793. ``cbuffer`` and ``ConstantBuffer``
  794. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  795. These two buffer types are treated as uniform buffers using Vulkan's
  796. terminology. They are translated into an ``OpTypeStruct`` with the
  797. necessary layout decorations (``Offset``, ``ArrayStride``, ``MatrixStride``,
  798. ``RowMajor``, ``ColMajor``) and the ``Block`` decoration. The layout rule
  799. used is vector-relaxed OpenGL ``std140`` (by default). A variable declared as
  800. one of these types will be placed in the ``Uniform`` storage class.
  801. For example, for the following HLSL source code:
  802. .. code:: hlsl
  803. struct T {
  804. float a;
  805. float3 b;
  806. };
  807. ConstantBuffer<T> myCBuffer;
  808. will be translated into
  809. .. code:: spirv
  810. ; Layout decoration
  811. OpMemberDecorate %type_ConstantBuffer_T 0 Offset 0
  812. OpMemberDecorate %type_ConstantBuffer_T 0 Offset 4
  813. ; Block decoration
  814. OpDecorate %type_ConstantBuffer_T Block
  815. ; Types
  816. %type_ConstantBuffer_T = OpTypeStruct %float %v3float
  817. %_ptr_Uniform_type_ConstantBuffer_T = OpTypePointer Uniform %type_ConstantBuffer_T
  818. ; Variable
  819. %myCbuffer = OpVariable %_ptr_Uniform_type_ConstantBuffer_T Uniform
  820. ``tbuffer`` and ``TextureBuffer``
  821. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  822. These two buffer types are treated as storage buffers using Vulkan's
  823. terminology. They are translated into an ``OpTypeStruct`` with the
  824. necessary layout decorations (``Offset``, ``ArrayStride``, ``MatrixStride``,
  825. ``RowMajor``, ``ColMajor``) and the ``BufferBlock`` decoration. All the struct
  826. members are also decorated with ``NonWritable`` decoration. The layout rule
  827. used is vector-relaxed OpenGL ``std430`` (by default). A variable declared as
  828. one of these types will be placed in the ``Uniform`` storage class.
  829. ``StructuredBuffer`` and ``RWStructuredBuffer``
  830. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  831. ``StructuredBuffer<T>``/``RWStructuredBuffer<T>`` is treated as storage buffer
  832. using Vulkan's terminology. It is translated into an ``OpTypeStruct`` containing
  833. an ``OpTypeRuntimeArray`` of type ``T``, with necessary layout decorations
  834. (``Offset``, ``ArrayStride``, ``MatrixStride``, ``RowMajor``, ``ColMajor``) and
  835. the ``BufferBlock`` decoration. The default layout rule used is vector-relaxed
  836. OpenGL ``std430``. A variable declared as one of these types will be placed in
  837. the ``Uniform`` storage class.
  838. For ``RWStructuredBuffer<T>``, each variable will have an associated counter
  839. variable generated. The counter variable will be of ``OpTypeStruct`` type, which
  840. only contains a 32-bit integer. The counter variable takes its own binding
  841. number. ``.IncrementCounter()``/``.DecrementCounter()`` will modify this counter
  842. variable.
  843. For example, for the following HLSL source code:
  844. .. code:: hlsl
  845. struct T {
  846. float a;
  847. float3 b;
  848. };
  849. StructuredBuffer<T> mySBuffer;
  850. will be translated into
  851. .. code:: spirv
  852. ; Layout decoration
  853. OpMemberDecorate %T 0 Offset 0
  854. OpMemberDecorate %T 1 Offset 4
  855. OpDecorate %_runtimearr_T ArrayStride 16
  856. OpMemberDecorate %type_StructuredBuffer_T 0 Offset 0
  857. OpMemberDecorate %type_StructuredBuffer_T 0 NoWritable
  858. ; BufferBlock decoration
  859. OpDecorate %type_StructuredBuffer_T BufferBlock
  860. ; Types
  861. %T = OpTypeStruct %float %v3float
  862. %_runtimearr_T = OpTypeRuntimeArray %T
  863. %type_StructuredBuffer_T = OpTypeStruct %_runtimearr_T
  864. %_ptr_Uniform_type_StructuredBuffer_T = OpTypePointer Uniform %type_StructuredBuffer_T
  865. ; Variable
  866. %myCbuffer = OpVariable %_ptr_Uniform_type_ConstantBuffer_T Uniform
  867. ``AppendStructuredBuffer`` and ``ConsumeStructuredBuffer``
  868. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  869. ``AppendStructuredBuffer<T>``/``ConsumeStructuredBuffer<T>`` is treated as
  870. storage buffer using Vulkan's terminology. It is translated into an
  871. ``OpTypeStruct`` containing an ``OpTypeRuntimeArray`` of type ``T``, with
  872. necessary layout decorations (``Offset``, ``ArrayStride``, ``MatrixStride``,
  873. ``RowMajor``, ``ColMajor``) and the ``BufferBlock`` decoration. The default
  874. layout rule used is vector-relaxed OpenGL ``std430``.
  875. A variable declared as one of these types will be placed in the ``Uniform``
  876. storage class. Besides, each variable will have an associated counter variable
  877. generated. The counter variable will be of ``OpTypeStruct`` type, which only
  878. contains a 32-bit integer. The integer is the total number of elements in the
  879. buffer. The counter variable takes its own binding number.
  880. ``.Append()``/``.Consume()`` will use the counter variable as the index and
  881. adjust it accordingly.
  882. For example, for the following HLSL source code:
  883. .. code:: hlsl
  884. struct T {
  885. float a;
  886. float3 b;
  887. };
  888. AppendStructuredBuffer<T> mySBuffer;
  889. will be translated into
  890. .. code:: spirv
  891. ; Layout decorations
  892. OpMemberDecorate %T 0 Offset 0
  893. OpMemberDecorate %T 1 Offset 4
  894. OpDecorate %_runtimearr_T ArrayStride 16
  895. OpMemberDecorate %type_AppendStructuredBuffer_T 0 Offset 0
  896. OpDecorate %type_AppendStructuredBuffer_T BufferBlock
  897. OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
  898. OpDecorate %type_ACSBuffer_counter BufferBlock
  899. ; Binding numbers
  900. OpDecorate %myASbuffer DescriptorSet 0
  901. OpDecorate %myASbuffer Binding 0
  902. OpDecorate %counter_var_myASbuffer DescriptorSet 0
  903. OpDecorate %counter_var_myASbuffer Binding 1
  904. ; Types
  905. %T = OpTypeStruct %float %v3float
  906. %_runtimearr_T = OpTypeRuntimeArray %T
  907. %type_AppendStructuredBuffer_T = OpTypeStruct %_runtimearr_T
  908. %_ptr_Uniform_type_AppendStructuredBuffer_T = OpTypePointer Uniform %type_AppendStructuredBuffer_T
  909. %type_ACSBuffer_counter = OpTypeStruct %int
  910. %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
  911. ; Variables
  912. %myASbuffer = OpVariable %_ptr_Uniform_type_AppendStructuredBuffer_T Uniform
  913. %counter_var_myASbuffer = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
  914. ``ByteAddressBuffer`` and ``RWByteAddressBuffer``
  915. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  916. ``ByteAddressBuffer``/``RWByteAddressBuffer`` is treated as storage buffer using
  917. Vulkan's terminology. It is translated into an ``OpTypeStruct`` containing an
  918. ``OpTypeRuntimeArray`` of 32-bit unsigned integers, with ``BufferBlock``
  919. decoration.
  920. A variable declared as one of these types will be placed in the ``Uniform``
  921. storage class.
  922. For example, for the following HLSL source code:
  923. .. code:: hlsl
  924. ByteAddressBuffer myBuffer1;
  925. RWByteAddressBuffer myBuffer2;
  926. will be translated into
  927. .. code:: spirv
  928. ; Layout decorations
  929. OpDecorate %_runtimearr_uint ArrayStride 4
  930. OpDecorate %type_ByteAddressBuffer BufferBlock
  931. OpMemberDecorate %type_ByteAddressBuffer 0 Offset 0
  932. OpMemberDecorate %type_ByteAddressBuffer 0 NonWritable
  933. OpDecorate %type_RWByteAddressBuffer BufferBlock
  934. OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0
  935. ; Types
  936. %_runtimearr_uint = OpTypeRuntimeArray %uint
  937. %type_ByteAddressBuffer = OpTypeStruct %_runtimearr_uint
  938. %_ptr_Uniform_type_ByteAddressBuffer = OpTypePointer Uniform %type_ByteAddressBuffer
  939. %type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint
  940. %_ptr_Uniform_type_RWByteAddressBuffer = OpTypePointer Uniform %type_RWByteAddressBuffer
  941. ; Variables
  942. %myBuffer1 = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform
  943. %myBuffer2 = OpVariable %_ptr_Uniform_type_RWByteAddressBuffer Uniform
  944. HLSL Variables and Resources
  945. ============================
  946. This section lists how various HLSL variables and resources are mapped.
  947. According to `Shader Constants <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509581(v=vs.85).aspx>`_,
  948. There are two default constant buffers available, $Global and $Param. Variables
  949. that are placed in the global scope are added implicitly to the $Global cbuffer,
  950. using the same packing method that is used for cbuffers. Uniform parameters in
  951. the parameter list of a function appear in the $Param constant buffer when a
  952. shader is compiled outside of the effects framework.
  953. So all global externally-visible non-resource-type stand-alone variables will
  954. be collected into a cbuffer named as ``$Globals``, no matter whether they are
  955. statically referenced by the entry point or not. The ``$Globals`` cbuffer
  956. follows the layout rules like normal cbuffer.
  957. Storage class
  958. -------------
  959. Normal local variables (without any modifier) will be placed in the ``Function``
  960. SPIR-V storage class. Normal global variables (without any modifer) will be
  961. placed in the ``Uniform`` or ``UniformConstant`` storage class.
  962. - ``static``
  963. - Global variables with ``static`` modifier will be placed in the ``Private``
  964. SPIR-V storage class. Initalizers of such global variables will be translated
  965. into SPIR-V ``OpVariable`` initializers if possible; otherwise, they will be
  966. initialized at the very beginning of the `entry function wrapper`_ using
  967. SPIR-V ``OpStore``.
  968. - Local variables with ``static`` modifier will also be placed in the
  969. ``Private`` SPIR-V storage class. initializers of such local variables will
  970. also be translated into SPIR-V ``OpVariable`` initializers if possible;
  971. otherwise, they will be initialized at the very beginning of the enclosing
  972. function. To make sure that such a local variable is only initialized once,
  973. a second boolean variable of the ``Private`` SPIR-V storage class will be
  974. generated to mark its initialization status.
  975. - ``groupshared``
  976. - Global variables with ``groupshared`` modifier will be placed in the
  977. ``Workgroup`` storage class.
  978. - Note that this modifier overrules ``static``; if both ``groupshared`` and
  979. ``static`` are applied to a variable, ``static`` will be ignored.
  980. - ``uinform``
  981. - This does not affect codegen. Variables will be treated like normal global
  982. variables.
  983. - ``extern``
  984. - This does not affect codegen. Variables will be treated like normal global
  985. variables.
  986. - ``shared``
  987. - This is a hint to the compiler. It will be ingored.
  988. - ``volatile``
  989. - This is a hint to the compiler. It will be ingored.
  990. HLSL semantic and Vulkan ``Location``
  991. -------------------------------------
  992. Direct3D uses HLSL "`semantics <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx>`_"
  993. to compose and match the interfaces between subsequent stages. These semantic
  994. strings can appear after struct members, function parameters and return
  995. values. E.g.,
  996. .. code:: hlsl
  997. struct VSInput {
  998. float4 pos : POSITION;
  999. float3 norm : NORMAL;
  1000. };
  1001. float4 VSMain(in VSInput input,
  1002. in float4 tex : TEXCOORD,
  1003. out float4 pos : SV_Position) : TEXCOORD {
  1004. pos = input.pos;
  1005. return tex;
  1006. }
  1007. In contrary, Vulkan stage input and output interface matching is via explicit
  1008. ``Location`` numbers. Details can be found `here <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#interfaces-iointerfaces>`_.
  1009. To translate HLSL to SPIR-V for Vulkan, semantic strings need to be mapped to
  1010. Vulkan ``Location`` numbers properly. This can be done either explicitly via
  1011. information provided by the developer or implicitly by the compiler.
  1012. Explicit ``Location`` number assignment
  1013. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1014. ``[[vk::location(X)]]`` can be attached to the entities where semantic are
  1015. allowed to attach (struct fields, function parameters, and function returns).
  1016. For the above exmaple we can have:
  1017. .. code:: hlsl
  1018. struct VSInput {
  1019. [[vk::location(0)]] float4 pos : POSITION;
  1020. [[vk::location(1)]] float3 norm : NORMAL;
  1021. };
  1022. [[vk::location(1)]]
  1023. float4 VSMain(in VSInput input,
  1024. [[vk::location(2)]]
  1025. in float4 tex : TEXCOORD,
  1026. out float4 pos : SV_Position) : TEXCOORD {
  1027. pos = input.pos;
  1028. return tex;
  1029. }
  1030. In the above, input ``POSITION``, ``NORMAL``, and ``TEXCOORD`` will be mapped to
  1031. ``Location`` 0, 1, and 2, respectively, and output ``TEXCOORD`` will be mapped
  1032. to ``Location`` 1.
  1033. [TODO] Another explicit way: using command-line options
  1034. Please note that the compiler prohibits mixing the explicit and implicit
  1035. approach for the same SigPoint to avoid complexity and fallibility. However,
  1036. for a certain shader stage, one SigPoint using the explicit approach while the
  1037. other adopting the implicit approach is permitted.
  1038. Implicit ``Location`` number assignment
  1039. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1040. Without hints from the developer, the compiler will try its best to map
  1041. semantics to ``Location`` numbers. However, there is no single rule for this
  1042. mapping; semantic strings should be handled case by case.
  1043. Firstly, under certain `SigPoints <https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst#hlsl-signatures-and-semantics>`_,
  1044. some system-value (SV) semantic strings will be translated into SPIR-V
  1045. ``BuiltIn`` decorations:
  1046. .. table:: Mapping from HLSL SV semantic to SPIR-V builtin and execution mode
  1047. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1048. | HLSL Semantic | SigPoint | SPIR-V ``BuiltIn`` | SPIR-V Execution Mode | SPIR-V Capability |
  1049. +===========================+=============+========================================+=======================+=============================+
  1050. | | VSOut | ``Position`` | N/A | ``Shader`` |
  1051. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1052. | | HSCPIn | ``Position`` | N/A | ``Shader`` |
  1053. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1054. | | HSCPOut | ``Position`` | N/A | ``Shader`` |
  1055. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1056. | | DSCPIn | ``Position`` | N/A | ``Shader`` |
  1057. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1058. | SV_Position | DSOut | ``Position`` | N/A | ``Shader`` |
  1059. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1060. | | GSVIn | ``Position`` | N/A | ``Shader`` |
  1061. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1062. | | GSOut | ``Position`` | N/A | ``Shader`` |
  1063. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1064. | | PSIn | ``FragCoord`` | N/A | ``Shader`` |
  1065. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1066. | | MSOut | ``Position`` | N/A | ``Shader`` |
  1067. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1068. | | VSOut | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1069. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1070. | | HSCPIn | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1071. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1072. | | HSCPOut | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1073. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1074. | | DSCPIn | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1075. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1076. | SV_ClipDistance | DSOut | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1077. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1078. | | GSVIn | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1079. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1080. | | GSOut | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1081. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1082. | | PSIn | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1083. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1084. | | MSOut | ``ClipDistance`` | N/A | ``ClipDistance`` |
  1085. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1086. | | VSOut | ``CullDistance`` | N/A | ``CullDistance`` |
  1087. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1088. | | HSCPIn | ``CullDistance`` | N/A | ``CullDistance`` |
  1089. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1090. | | HSCPOut | ``CullDistance`` | N/A | ``CullDistance`` |
  1091. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1092. | | DSCPIn | ``CullDistance`` | N/A | ``CullDistance`` |
  1093. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1094. | SV_CullDistance | DSOut | ``CullDistance`` | N/A | ``CullDistance`` |
  1095. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1096. | | GSVIn | ``CullDistance`` | N/A | ``CullDistance`` |
  1097. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1098. | | GSOut | ``CullDistance`` | N/A | ``CullDistance`` |
  1099. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1100. | | PSIn | ``CullDistance`` | N/A | ``CullDistance`` |
  1101. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1102. | | MSOut | ``CullDistance`` | N/A | ``CullDistance`` |
  1103. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1104. | SV_VertexID | VSIn | ``VertexIndex`` | N/A | ``Shader`` |
  1105. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1106. | SV_InstanceID | VSIn | ``InstanceIndex`` or | N/A | ``Shader`` |
  1107. | | | ``InstanceIndex - BaseInstance`` | | |
  1108. | | | with | | |
  1109. | | | ``-fvk-support-nonzero-base-instance`` | | |
  1110. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1111. | SV_Depth | PSOut | ``FragDepth`` | N/A | ``Shader`` |
  1112. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1113. | SV_DepthGreaterEqual | PSOut | ``FragDepth`` | ``DepthGreater`` | ``Shader`` |
  1114. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1115. | SV_DepthLessEqual | PSOut | ``FragDepth`` | ``DepthLess`` | ``Shader`` |
  1116. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1117. | SV_IsFrontFace | PSIn | ``FrontFacing`` | N/A | ``Shader`` |
  1118. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1119. | | CSIn | ``GlobalInvocationId`` | N/A | ``Shader`` |
  1120. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1121. | SV_DispatchThreadID | MSIn | ``GlobalInvocationId`` | N/A | ``Shader`` |
  1122. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1123. | | ASIn | ``GlobalInvocationId`` | N/A | ``Shader`` |
  1124. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1125. | | CSIn | ``WorkgroupId`` | N/A | ``Shader`` |
  1126. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1127. | SV_GroupID | MSIn | ``WorkgroupId`` | N/A | ``Shader`` |
  1128. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1129. | | ASIn | ``WorkgroupId`` | N/A | ``Shader`` |
  1130. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1131. | | CSIn | ``LocalInvocationId`` | N/A | ``Shader`` |
  1132. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1133. | SV_GroupThreadID | MSIn | ``LocalInvocationId`` | N/A | ``Shader`` |
  1134. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1135. | | ASIn | ``LocalInvocationId`` | N/A | ``Shader`` |
  1136. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1137. | | CSIn | ``LocalInvocationIndex`` | N/A | ``Shader`` |
  1138. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1139. | SV_GroupIndex | MSIn | ``LocalInvocationIndex`` | N/A | ``Shader`` |
  1140. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1141. | | ASIn | ``LocalInvocationIndex`` | N/A | ``Shader`` |
  1142. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1143. | SV_OutputControlPointID | HSIn | ``InvocationId`` | N/A | ``Tessellation`` |
  1144. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1145. | SV_GSInstanceID | GSIn | ``InvocationId`` | N/A | ``Geometry`` |
  1146. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1147. | SV_DomainLocation | DSIn | ``TessCoord`` | N/A | ``Tessellation`` |
  1148. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1149. | | HSIn | ``PrimitiveId`` | N/A | ``Tessellation`` |
  1150. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1151. | | PCIn | ``PrimitiveId`` | N/A | ``Tessellation`` |
  1152. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1153. | | DsIn | ``PrimitiveId`` | N/A | ``Tessellation`` |
  1154. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1155. | SV_PrimitiveID | GSIn | ``PrimitiveId`` | N/A | ``Geometry`` |
  1156. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1157. | | GSOut | ``PrimitiveId`` | N/A | ``Geometry`` |
  1158. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1159. | | PSIn | ``PrimitiveId`` | N/A | ``Geometry`` |
  1160. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1161. | | MSOut | ``PrimitiveId`` | N/A | ``MeshShadingNV`` |
  1162. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1163. | | PCOut | ``TessLevelOuter`` | N/A | ``Tessellation`` |
  1164. | SV_TessFactor +-------------+----------------------------------------+-----------------------+-----------------------------+
  1165. | | DSIn | ``TessLevelOuter`` | N/A | ``Tessellation`` |
  1166. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1167. | | PCOut | ``TessLevelInner`` | N/A | ``Tessellation`` |
  1168. | SV_InsideTessFactor +-------------+----------------------------------------+-----------------------+-----------------------------+
  1169. | | DSIn | ``TessLevelInner`` | N/A | ``Tessellation`` |
  1170. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1171. | SV_SampleIndex | PSIn | ``SampleId`` | N/A | ``SampleRateShading`` |
  1172. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1173. | SV_StencilRef | PSOut | ``FragStencilRefEXT`` | N/A | ``StencilExportEXT`` |
  1174. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1175. | SV_Barycentrics | PSIn | ``BaryCoord*AMD`` | N/A | ``Shader`` |
  1176. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1177. | | GSOut | ``Layer`` | N/A | ``Geometry`` |
  1178. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1179. | SV_RenderTargetArrayIndex | PSIn | ``Layer`` | N/A | ``Geometry`` |
  1180. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1181. | | MSOut | ``Layer`` | N/A | ``MeshShadingNV`` |
  1182. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1183. | | GSOut | ``ViewportIndex`` | N/A | ``MultiViewport`` |
  1184. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1185. | SV_ViewportArrayIndex | PSIn | ``ViewportIndex`` | N/A | ``MultiViewport`` |
  1186. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1187. | | MSOut | ``ViewportIndex`` | N/A | ``MeshShadingNV`` |
  1188. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1189. | | PSIn | ``SampleMask`` | N/A | ``Shader`` |
  1190. | SV_Coverage +-------------+----------------------------------------+-----------------------+-----------------------------+
  1191. | | PSOut | ``SampleMask`` | N/A | ``Shader`` |
  1192. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1193. | SV_InnerCoverage | PSIn | ``FullyCoveredEXT`` | N/A | ``FragmentFullyCoveredEXT`` |
  1194. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1195. | | VSIn | ``ViewIndex`` | N/A | ``MultiView`` |
  1196. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1197. | | HSIn | ``ViewIndex`` | N/A | ``MultiView`` |
  1198. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1199. | | DSIn | ``ViewIndex`` | N/A | ``MultiView`` |
  1200. | SV_ViewID +-------------+----------------------------------------+-----------------------+-----------------------------+
  1201. | | GSIn | ``ViewIndex`` | N/A | ``MultiView`` |
  1202. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1203. | | PSIn | ``ViewIndex`` | N/A | ``MultiView`` |
  1204. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1205. | | MSIn | ``ViewIndex`` | N/A | ``MultiView`` |
  1206. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1207. | | VSOut | ``PrimitiveShadingRateKHR`` | N/A | ``FragmentShadingRate`` |
  1208. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1209. | | GSOut | ``PrimitiveShadingRateKHR`` | N/A | ``FragmentShadingRate`` |
  1210. | SV_ShadingRate +-------------+----------------------------------------+-----------------------+-----------------------------+
  1211. | | PSIn | ``ShadingRateKHR`` | N/A | ``FragmentShadingRate`` |
  1212. | +-------------+----------------------------------------+-----------------------+-----------------------------+
  1213. | | MSOut | ``PrimitiveShadingRateKHR`` | N/A | ``FragmentShadingRate`` |
  1214. +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+
  1215. For entities (function parameters, function return values, struct fields) with
  1216. the above SV semantic strings attached, SPIR-V variables of the
  1217. ``Input``/``Output`` storage class will be created. They will have the
  1218. corresponding SPIR-V ``Builtin`` decorations according to the above table.
  1219. SV semantic strings not translated into SPIR-V ``BuiltIn`` decorations will be
  1220. handled similarly as non-SV (arbitrary) semantic strings: a SPIR-V variable
  1221. of the ``Input``/``Output`` storage class will be created for each entity with
  1222. such semantic string. Then sort all semantic strings according to declaration
  1223. (the default, or if ``-fvk-stage-io-order=decl`` is given) or alphabetical
  1224. (if ``-fvk-stage-io-order=alpha`` is given) order, and assign ``Location``
  1225. numbers sequentially to the corresponding SPIR-V variables. Note that this means
  1226. flattening all structs if structs are used as function parameters or returns.
  1227. There is an exception to the above rule for SV_Target[N]. It will always be
  1228. mapped to ``Location`` number N.
  1229. ``ClipDistance & CullDistance``
  1230. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1231. Variables decorated with ``SV_ClipDistanceX`` can be float or vector of float
  1232. type. To map them into one float array in the struct, we firstly sort them
  1233. asecendingly according to ``X``, and then concatenate them tightly. For example,
  1234. .. code:: hlsl
  1235. struct T {
  1236. float clip0: SV_ClipDistance0,
  1237. };
  1238. struct S {
  1239. float3 clip5: SV_ClipDistance5;
  1240. ...
  1241. };
  1242. void main(T t, S s, float2 clip2 : SV_ClipDistance2) { ... }
  1243. Then we have an float array of size (1 + 2 + 3 =) 6 for ``ClipDistance``, with
  1244. ``clip0`` at offset 0, ``clip2`` at offset 1, ``clip5`` at offset 3.
  1245. Decorating a variable or struct member with the ``ClipDistance`` builtin but not
  1246. requiring the ``ClipDistance`` capability is legal as long as we don't read or
  1247. write the variable or struct member. But as per the way we handle `shader entry
  1248. function`_, this is not satisfied because we need to read their contents to
  1249. prepare for the source code entry function call or write back them after the
  1250. call. So annotating a variable or struct member with ``SV_ClipDistanceX`` means
  1251. requiring the ``ClipDistance`` capability in the generated SPIR-V.
  1252. Variables decorated with ``SV_CullDistanceX`` are mapped similarly as above.
  1253. HLSL register and Vulkan binding
  1254. --------------------------------
  1255. In shaders for DirectX, resources are accessed via registers; while in shaders
  1256. for Vulkan, it is done via descriptor set and binding numbers. The developer
  1257. can explicitly annotate variables in HLSL to specify descriptor set and binding
  1258. numbers, or leave it to the compiler to derive implicitly from registers.
  1259. Explicit binding number assignment
  1260. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1261. ``[[vk::binding(X[, Y])]]`` can be attached to global variables to specify the
  1262. descriptor set as ``Y`` and binding number as ``X``. The descriptor set number
  1263. is optional; if missing, it will be zero (If ``-auto-binding-space N`` command
  1264. line option is used, then descriptor set #N will be used instead of descriptor
  1265. set #0). RW/append/consume structured buffers have associated counters, which
  1266. will occupy their own Vulkan descriptors. ``[vk::counter_binding(Z)]`` can be
  1267. attached to a RW/append/consume structured buffers to specify the binding number
  1268. for the associated counter to ``Z``. Note that the set number of the counter is
  1269. always the same as the main buffer.
  1270. Implicit binding number assignment
  1271. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1272. Without explicit annotations, the compiler will try to deduce descriptor sets
  1273. and binding numbers in the following way:
  1274. If there is ``:register(xX, spaceY)`` specified for the given global variable,
  1275. the corresponding resource will be assigned to descriptor set ``Y`` and binding
  1276. number ``X``, regardless of the register type ``x``. Note that this will cause
  1277. binding number collision if, say, two resources are of different register
  1278. type but the same register number. To solve this problem, four command-line
  1279. options, ``-fvk-b-shift N M``, ``-fvk-s-shift N M``, ``-fvk-t-shift N M``, and
  1280. ``-fvk-u-shift N M``, are provided to shift by ``N`` all binding numbers
  1281. inferred for register type ``b``, ``s``, ``t``, and ``u`` in space ``M``,
  1282. respectively.
  1283. If there is no register specification, the corresponding resource will be
  1284. assigned to the next available binding number, starting from 0, in descriptor
  1285. set #0 (If ``-auto-binding-space N`` command line option is used, then
  1286. descriptor set #N will be used instead of descriptor set #0).
  1287. If there is no register specification AND ``-fvk-auto-shift-bindings`` is specified,
  1288. then the register type will be automatically identified based on the resource
  1289. type (according to the following table), and the appropriate shift will
  1290. automatically be applied according to ``-fvk-*shift N M``.
  1291. .. code:: spirv
  1292. t - for shader resource views (SRV)
  1293. TEXTURE1D
  1294. TEXTURE1DARRAY
  1295. TEXTURE2D
  1296. TEXTURE2DARRAY
  1297. TEXTURE3D
  1298. TEXTURECUBE
  1299. TEXTURECUBEARRAY
  1300. TEXTURE2DMS
  1301. TEXTURE2DMSARRAY
  1302. STRUCTUREDBUFFER
  1303. BYTEADDRESSBUFFER
  1304. BUFFER
  1305. TBUFFER
  1306. s - for samplers
  1307. SAMPLER
  1308. SAMPLER1D
  1309. SAMPLER2D
  1310. SAMPLER3D
  1311. SAMPLERCUBE
  1312. SAMPLERSTATE
  1313. SAMPLERCOMPARISONSTATE
  1314. u - for unordered access views (UAV)
  1315. RWBYTEADDRESSBUFFER
  1316. RWSTRUCTUREDBUFFER
  1317. APPENDSTRUCTUREDBUFFER
  1318. CONSUMESTRUCTUREDBUFFER
  1319. RWBUFFER
  1320. RWTEXTURE1D
  1321. RWTEXTURE1DARRAY
  1322. RWTEXTURE2D
  1323. RWTEXTURE2DARRAY
  1324. RWTEXTURE3D
  1325. b - for constant buffer views (CBV)
  1326. CBUFFER
  1327. CONSTANTBUFFER
  1328. Summary
  1329. ~~~~~~~
  1330. In summary, the compiler essentially assigns binding numbers in three passes.
  1331. - Firstly it handles all declarations with explicit ``[[vk::binding(X[, Y])]]``
  1332. annotation.
  1333. - Then the compiler processes all remaining declarations with
  1334. ``:register(xX, spaceY)`` annotation, by applying the shift passed in using
  1335. command-line option ``-fvk-{b|s|t|u}-shift N M``, if provided.
  1336. - If ``:register`` assignment is missing and ``-fvk-auto-shift-bindings`` is
  1337. specified, the register type will be automatically detected based on the
  1338. resource type, and the ``-fvk-{b|s|t|u}-shift N M`` will be applied.
  1339. - Finally, the compiler assigns next available binding numbers to the rest in
  1340. the declaration order.
  1341. As an example, for the following code:
  1342. .. code:: hlsl
  1343. struct S { ... };
  1344. ConstantBuffer<S> cbuffer1 : register(b0);
  1345. Texture2D<float4> texture1 : register(t0);
  1346. Texture2D<float4> texture2 : register(t1, space1);
  1347. SamplerState sampler1;
  1348. [[vk::binding(3)]]
  1349. RWBuffer<float4> rwbuffer1 : register(u5, space2);
  1350. If we compile with ``-fvk-t-shift 10 0 -fvk-t-shift 20 1``:
  1351. - ``rwbuffer1`` will take binding #3 in set #0, since explicit binding
  1352. assignment has precedence over the rest.
  1353. - ``cbuffer1`` will take binding #0 in set #0, since that's what deduced from
  1354. the register assignment, and there is no shift requested from command line.
  1355. - ``texture1`` will take binding #10 in set #0, and ``texture2`` will take
  1356. binding #21 in set #1, since we requested an 10 shift on t-type registers.
  1357. - ``sampler1`` will take binding 1 in set #0, since that's the next available
  1358. binding number in set #0.
  1359. HLSL global variables and Vulkan binding
  1360. ----------------------------------------
  1361. As mentioned above, all global externally-visible non-resource-type stand-alone
  1362. variables will be collected into a cbuffer named ``$Globals``. By default,
  1363. the ``$Globals`` cbuffer is placed in descriptor set #0, and the binding number
  1364. would be the next available binding number in that set. Meaning, the binding number
  1365. depends on where the very first global variable is in the code.
  1366. Example 1:
  1367. .. code:: hlsl
  1368. float4 someColors;
  1369. // $Globals cbuffer placed at DescriptorSet #0, Binding #0
  1370. Texture2D<float4> texture1;
  1371. // texture1 placed at DescriptorSet #0, Binding #1
  1372. Example 2:
  1373. .. code:: hlsl
  1374. Texture2D<float4> texture1;
  1375. // texture1 placed at DescriptorSet #0, Binding #0
  1376. float4 someColors;
  1377. // $Globals cbuffer placed at DescriptorSet #0, Binding #1
  1378. In order provide more control over the descriptor set and binding number of the
  1379. ``$Globals`` cbuffer, you can use the ``-fvk-bind-globals B S`` command line
  1380. option, which will place this cbuffer at descriptor set ``S``, and binding number ``B``.
  1381. Example 3: (compiled with ``-fvk-bind-globals 2 1``)
  1382. .. code:: hlsl
  1383. Texture2D<float4> texture1;
  1384. // texture1 placed at DescriptorSet #0, Binding #0
  1385. float4 someColors;
  1386. // $Globals cbuffer placed at DescriptorSet #1, Binding #2
  1387. Note that if the developer chooses to use this command line option, it is their
  1388. responsibility to provide proper numbers and avoid binding overlaps.
  1389. HLSL Expressions
  1390. ================
  1391. Unless explicitly noted, matrix per-element operations will be conducted on
  1392. each component vector and then collected into the result matrix. The following
  1393. sections lists the SPIR-V opcodes for scalars and vectors.
  1394. Arithmetic operators
  1395. --------------------
  1396. `Arithmetic operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Additive_and_Multiplicative_Operators>`_
  1397. (``+``, ``-``, ``*``, ``/``, ``%``) are translated into their corresponding
  1398. SPIR-V opcodes according to the following table.
  1399. +-------+-----------------------------+-------------------------------+--------------------+
  1400. | | (Vector of) Signed Integers | (Vector of) Unsigned Integers | (Vector of) Floats |
  1401. +=======+=============================+===============================+====================+
  1402. | ``+`` | ``OpIAdd`` | ``OpFAdd`` |
  1403. +-------+-------------------------------------------------------------+--------------------+
  1404. | ``-`` | ``OpISub`` | ``OpFSub`` |
  1405. +-------+-------------------------------------------------------------+--------------------+
  1406. | ``*`` | ``OpIMul`` | ``OpFMul`` |
  1407. +-------+-----------------------------+-------------------------------+--------------------+
  1408. | ``/`` | ``OpSDiv`` | ``OpUDiv`` | ``OpFDiv`` |
  1409. +-------+-----------------------------+-------------------------------+--------------------+
  1410. | ``%`` | ``OpSRem`` | ``OpUMod`` | ``OpFRem`` |
  1411. +-------+-----------------------------+-------------------------------+--------------------+
  1412. Note that for modulo operation, SPIR-V has two sets of instructions: ``Op*Rem``
  1413. and ``Op*Mod``. For ``Op*Rem``, the sign of a non-0 result comes from the first
  1414. operand; while for ``Op*Mod``, the sign of a non-0 result comes from the second
  1415. operand. HLSL doc does not mandate which set of instructions modulo operations
  1416. should be translated into; it only says "the % operator is defined only in cases
  1417. where either both sides are positive or both sides are negative." So technically
  1418. it's undefined behavior to use the modulo operation with operands of different
  1419. signs. But considering HLSL's C heritage and the behavior of Clang frontend, we
  1420. translate modulo operators into ``Op*Rem`` (there is no ``OpURem``).
  1421. For multiplications of float vectors and float scalars, the dedicated SPIR-V
  1422. operation ``OpVectorTimesScalar`` will be used. Similarly, for multiplications
  1423. of float matrices and float scalars, ``OpMatrixTimesScalar`` will be generated.
  1424. Bitwise operators
  1425. -----------------
  1426. `Bitwise operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Bitwise_Operators>`_
  1427. (``~``, ``&``, ``|``, ``^``, ``<<``, ``>>``) are translated into their
  1428. corresponding SPIR-V opcodes according to the following table.
  1429. +--------+-----------------------------+-------------------------------+
  1430. | | (Vector of) Signed Integers | (Vector of) Unsigned Integers |
  1431. +========+=============================+===============================+
  1432. | ``~`` | ``OpNot`` |
  1433. +--------+-------------------------------------------------------------+
  1434. | ``&`` | ``OpBitwiseAnd`` |
  1435. +--------+-------------------------------------------------------------+
  1436. | ``|`` | ``OpBitwiseOr`` |
  1437. +--------+-----------------------------+-------------------------------+
  1438. | ``^`` | ``OpBitwiseXor`` |
  1439. +--------+-----------------------------+-------------------------------+
  1440. | ``<<`` | ``OpShiftLeftLogical`` |
  1441. +--------+-----------------------------+-------------------------------+
  1442. | ``>>`` | ``OpShiftRightArithmetic`` | ``OpShiftRightLogical`` |
  1443. +--------+-----------------------------+-------------------------------+
  1444. Note that for ``<<``/``>>``, the right hand side will be culled: only the ``n``
  1445. - 1 least significant bits are considered, where ``n`` is the bitwidth of the
  1446. left hand side.
  1447. Comparison operators
  1448. --------------------
  1449. `Comparison operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Comparison_Operators>`_
  1450. (``<``, ``<=``, ``>``, ``>=``, ``==``, ``!=``) are translated into their
  1451. corresponding SPIR-V opcodes according to the following table.
  1452. +--------+-----------------------------+-------------------------------+------------------------------+
  1453. | | (Vector of) Signed Integers | (Vector of) Unsigned Integers | (Vector of) Floats |
  1454. +========+=============================+===============================+==============================+
  1455. | ``<`` | ``OpSLessThan`` | ``OpULessThan`` | ``OpFOrdLessThan`` |
  1456. +--------+-----------------------------+-------------------------------+------------------------------+
  1457. | ``<=`` | ``OpSLessThanEqual`` | ``OpULessThanEqual`` | ``OpFOrdLessThanEqual`` |
  1458. +--------+-----------------------------+-------------------------------+------------------------------+
  1459. | ``>`` | ``OpSGreaterThan`` | ``OpUGreaterThan`` | ``OpFOrdGreaterThan`` |
  1460. +--------+-----------------------------+-------------------------------+------------------------------+
  1461. | ``>=`` | ``OpSGreaterThanEqual`` | ``OpUGreaterThanEqual`` | ``OpFOrdGreaterThanEqual`` |
  1462. +--------+-----------------------------+-------------------------------+------------------------------+
  1463. | ``==`` | ``OpIEqual`` | ``OpFOrdEqual`` |
  1464. +--------+-------------------------------------------------------------+------------------------------+
  1465. | ``!=`` | ``OpINotEqual`` | ``OpFOrdNotEqual`` |
  1466. +--------+-------------------------------------------------------------+------------------------------+
  1467. Note that for comparison of (vectors of) floats, SPIR-V has two sets of
  1468. instructions: ``OpFOrd*``, ``OpFUnord*``. We translate into ``OpFOrd*`` ones.
  1469. Boolean math operators
  1470. ----------------------
  1471. `Boolean match operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Boolean_Math_Operators>`_
  1472. (``&&``, ``||``, ``?:``) are translated into their corresponding SPIR-V opcodes
  1473. according to the following table.
  1474. +--------+----------------------+
  1475. | | (Vector of) Booleans |
  1476. +========+======================+
  1477. | ``&&`` | ``OpLogicalAnd`` |
  1478. +--------+----------------------+
  1479. | ``||`` | ``OpLogicalOr`` |
  1480. +--------+----------------------+
  1481. | ``?:`` | ``OpSelect`` |
  1482. +--------+----------------------+
  1483. Please note that "unlike short-circuit evaluation of ``&&``, ``||``, and ``?:``
  1484. in C, HLSL expressions never short-circuit an evaluation because they are vector
  1485. operations. All sides of the expression are always evaluated."
  1486. Unary operators
  1487. ---------------
  1488. For `unary operators <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509631(v=vs.85).aspx#Unary_Operators>`_:
  1489. - ``!`` is translated into ``OpLogicalNot``. Parsing will gurantee the operands
  1490. are of boolean types by inserting necessary casts.
  1491. - ``+`` requires no additional SPIR-V instructions.
  1492. - ``-`` is translated into ``OpSNegate`` and ``OpFNegate`` for (vectors of)
  1493. integers and floats, respectively.
  1494. Casts
  1495. -----
  1496. Casting between (vectors) of scalar types is translated according to the following table:
  1497. +------------+-------------------+-------------------+-------------------+-------------------+
  1498. | From \\ To | Bool | SInt | UInt | Float |
  1499. +============+===================+===================+===================+===================+
  1500. | Bool | no-op | select between one and zero |
  1501. +------------+-------------------+-------------------+-------------------+-------------------+
  1502. | SInt | | no-op | ``OpBitcast`` | ``OpConvertSToF`` |
  1503. +------------+ +-------------------+-------------------+-------------------+
  1504. | UInt | compare with zero | ``OpBitcast`` | no-op | ``OpConvertUToF`` |
  1505. +------------+ +-------------------+-------------------+-------------------+
  1506. | Float | | ``OpConvertFToS`` | ``OpConvertFToU`` | no-op |
  1507. +------------+-------------------+-------------------+-------------------+-------------------+
  1508. It is also feasible in HLSL to cast a float matrix to another float matrix with a smaller size.
  1509. This is known as matrix truncation cast. For instance, the following code casts a 3x4 matrix
  1510. into a 2x3 matrix.
  1511. .. code:: hlsl
  1512. float3x4 m = { 1, 2, 3, 4,
  1513. 5, 6, 7, 8,
  1514. 9, 10, 11, 12 };
  1515. float2x3 a = (float2x3)m;
  1516. Such casting takes the upper-left most corner of the original matrix to generate the result.
  1517. In the above example, matrix ``a`` will have 2 rows, with 3 columns each. First row will be
  1518. ``1, 2, 3`` and the second row will be ``5, 6, 7``.
  1519. Indexing operator
  1520. -----------------
  1521. The ``[]`` operator can also be used to access elements in a matrix or vector.
  1522. A matrix whose row and/or column count is 1 will be translated into a vector or
  1523. scalar. If a variable is used as the index for the dimension whose count is 1,
  1524. that variable will be ignored in the generated SPIR-V code. This is because
  1525. out-of-bound indexing triggers undefined behavior anyway. For example, for a
  1526. 1xN matrix ``mat``, ``mat[index][0]`` will be translated into
  1527. ``OpAccessChain ... %mat %uint_0``. Similarly, variable index into a size 1
  1528. vector will also be ignored and the only element will be always returned.
  1529. Assignment operators
  1530. --------------------
  1531. Assigning to struct object may involve decomposing the source struct object and
  1532. assign each element separately and recursively. This happens when the source
  1533. struct object is of different memory layout from the destination struct object.
  1534. For example, for the following source code:
  1535. .. code:: hlsl
  1536. struct S {
  1537. float a;
  1538. float2 b;
  1539. float2x3 c;
  1540. };
  1541. ConstantBuffer<S> cbuf;
  1542. RWStructuredBuffer<S> sbuf;
  1543. ...
  1544. sbuf[0] = cbuf[0];
  1545. ...
  1546. We need to assign each element because ``ConstantBuffer`` and
  1547. ``RWStructuredBuffer`` has different memory layout.
  1548. HLSL Control Flows
  1549. ==================
  1550. This section lists how various HLSL control flows are mapped.
  1551. Switch statement
  1552. ----------------
  1553. HLSL `switch statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509669(v=vs.85).aspx>`_
  1554. are translated into SPIR-V using:
  1555. - **OpSwitch**: if (all case values are integer literals or constant integer
  1556. variables) and (no attribute or the ``forcecase`` attribute is specified)
  1557. - **A series of if statements**: for all other scenarios (e.g., when
  1558. ``flatten``, ``branch``, or ``call`` attribute is specified)
  1559. Loops (for, while, do)
  1560. ----------------------
  1561. HLSL `for statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509602(v=vs.85).aspx>`_,
  1562. `while statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509708(v=vs.85).aspx>`_,
  1563. and `do statements <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509593(v=vs.85).aspx>`_
  1564. are translated into SPIR-V by constructing all necessary basic blocks and using
  1565. ``OpLoopMerge`` to organize as structured loops.
  1566. The HLSL attributes for these statements are translated into SPIR-V loop control
  1567. masks according to the following table:
  1568. +-------------------------+--------------------------------------------------+
  1569. | HLSL loop attribute | SPIR-V Loop Control Mask |
  1570. +=========================+==================================================+
  1571. | ``unroll(x)`` | ``Unroll`` |
  1572. +-------------------------+--------------------------------------------------+
  1573. | ``loop`` | ``DontUnroll`` |
  1574. +-------------------------+--------------------------------------------------+
  1575. | ``fastopt`` | ``DontUnroll`` |
  1576. +-------------------------+--------------------------------------------------+
  1577. | ``allow_uav_condition`` | Currently Unimplemented |
  1578. +-------------------------+--------------------------------------------------+
  1579. HLSL Functions
  1580. ==============
  1581. All functions reachable from the entry-point function will be translated into
  1582. SPIR-V code. Functions not reachable from the entry-point function will be
  1583. ignored.
  1584. Entry function wrapper
  1585. ----------------------
  1586. HLSL entry functions takes in parameters and returns values. These parameters
  1587. and return values can have semantics attached or if they are struct type,
  1588. the struct fields can have semantics attached. However, in Vulkan, the entry
  1589. function must be of the ``void(void)`` signature. To handle this difference,
  1590. for a given entry function ``main``, we will emit a wrapper function for it.
  1591. The wrapper function will take the name of the source code entry function,
  1592. while the source code entry function will have its name prefixed with "src.".
  1593. The wrapper function reads in stage input/builtin variables created according
  1594. to semantics and groups them into composites meeting the requirements of the
  1595. source code entry point. Then the wrapper calls the source code entry point.
  1596. The return value is extracted and components of it will be written to stage
  1597. output/builtin variables created according to semantics. For example:
  1598. .. code:: hlsl
  1599. // HLSL source code
  1600. struct S {
  1601. bool a : A;
  1602. uint2 b: B;
  1603. float2x3 c: C;
  1604. };
  1605. struct T {
  1606. S x;
  1607. int y: D;
  1608. };
  1609. T main(T input) {
  1610. return input;
  1611. }
  1612. .. code:: spirv
  1613. ; SPIR-V code
  1614. %in_var_A = OpVariable %_ptr_Input_bool Input
  1615. %in_var_B = OpVariable %_ptr_Input_v2uint Input
  1616. %in_var_C = OpVariable %_ptr_Input_mat2v3float Input
  1617. %in_var_D = OpVariable %_ptr_Input_int Input
  1618. %out_var_A = OpVariable %_ptr_Output_bool Output
  1619. %out_var_B = OpVariable %_ptr_Output_v2uint Output
  1620. %out_var_C = OpVariable %_ptr_Output_mat2v3float Output
  1621. %out_var_D = OpVariable %_ptr_Output_int Output
  1622. ; Wrapper function starts
  1623. %main = OpFunction %void None ...
  1624. ... = OpLabel
  1625. %param_var_input = OpVariable %_ptr_Function_T Function
  1626. ; Load stage input variables and group into the expected composite
  1627. %inA = OpLoad %bool %in_var_A
  1628. %inB = OpLoad %v2uint %in_var_B
  1629. %inC = OpLoad %mat2v3float %in_var_C
  1630. %inS = OpCompositeConstruct %S %inA %inB %inC
  1631. %inD = OpLoad %int %in_var_D
  1632. %inT = OpCompositeConstruct %T %inS %inD
  1633. OpStore %param_var_input %inT
  1634. %ret = OpFunctionCall %T %src_main %param_var_input
  1635. ; Extract component values from the composite and store into stage output variables
  1636. %outS = OpCompositeExtract %S %ret 0
  1637. %outA = OpCompositeExtract %bool %outS 0
  1638. OpStore %out_var_A %outA
  1639. %outB = OpCompositeExtract %v2uint %outS 1
  1640. OpStore %out_var_B %outB
  1641. %outC = OpCompositeExtract %mat2v3float %outS 2
  1642. OpStore %out_var_C %outC
  1643. %outD = OpCompositeExtract %int %ret 1
  1644. OpStore %out_var_D %outD
  1645. OpReturn
  1646. OpFunctionEnd
  1647. ; Source code entry point starts
  1648. %src_main = OpFunction %T None ...
  1649. In this way, we can concentrate all stage input/output/builtin variable
  1650. manipulation in the wrapper function and handle the source code entry function
  1651. just like other nomal functions.
  1652. Function parameter
  1653. ------------------
  1654. For a function ``f`` which has a parameter of type ``T``, the generated SPIR-V
  1655. signature will use type ``T*`` for the parameter. At every call site of ``f``,
  1656. additional local variables will be allocated to hold the actual arguments.
  1657. The local variables are passed in as direct function arguments. For example:
  1658. .. code:: hlsl
  1659. // HLSL source code
  1660. float4 f(float a, int b) { ... }
  1661. void caller(...) {
  1662. ...
  1663. float4 result = f(...);
  1664. ...
  1665. }
  1666. .. code:: spirv
  1667. ; SPIR-V code
  1668. ...
  1669. %i32PtrType = OpTypePointer Function %int
  1670. %f32PtrType = OpTypePointer Function %float
  1671. %fnType = OpTypeFunction %v4float %f32PtrType %i32PtrType
  1672. ...
  1673. %f = OpFunction %v4float None %fnType
  1674. %a = OpFunctionParameter %f32PtrType
  1675. %b = OpFunctionParameter %i32PtrType
  1676. ...
  1677. %caller = OpFunction ...
  1678. ...
  1679. %aAlloca = OpVariable %_ptr_Function_float Function
  1680. %bAlloca = OpVariable %_ptr_Function_int Function
  1681. ...
  1682. OpStore %aAlloca ...
  1683. OpStore %bAlloca ...
  1684. %result = OpFunctioncall %v4float %f %aAlloca %bAlloca
  1685. ...
  1686. This approach gives us unified handling of function parameters and local
  1687. variables: both of them are accessed via load/store instructions.
  1688. Intrinsic functions
  1689. -------------------
  1690. The following intrinsic HLSL functions have no direct SPIR-V opcode or GLSL
  1691. extended instruction mapping, so they are handled with additional steps:
  1692. - ``dot`` : performs dot product of two vectors, each containing floats or
  1693. integers. If the two parameters are vectors of floats, we use SPIR-V's
  1694. ``OpDot`` instruction to perform the translation. If the two parameters are
  1695. vectors of integers, we multiply corresponding vector elements using
  1696. ``OpIMul`` and accumulate the results using ``OpIAdd`` to compute the dot
  1697. product.
  1698. - ``mul``: performs multiplications. Each argument may be a scalar, vector,
  1699. or matrix. Depending on the argument type, this will be translated into
  1700. one of the multiplication instructions.
  1701. - ``all``: returns true if all components of the given scalar, vector, or
  1702. matrix are true. Performs conversions to boolean where necessary. Uses SPIR-V
  1703. ``OpAll`` for scalar arguments and vector arguments. For matrix arguments,
  1704. performs ``OpAll`` on each row, and then again on the vector containing the
  1705. results of all rows.
  1706. - ``any``: returns true if any component of the given scalar, vector, or matrix
  1707. is true. Performs conversions to boolean where necessary. Uses SPIR-V
  1708. ``OpAny`` for scalar arguments and vector arguments. For matrix arguments,
  1709. performs ``OpAny`` on each row, and then again on the vector containing the
  1710. results of all rows.
  1711. - ``asfloat``: converts the component type of a scalar/vector/matrix from float,
  1712. uint, or int into float. Uses ``OpBitcast``. This method currently does not
  1713. support taking non-float matrix arguments.
  1714. - ``asint``: converts the component type of a scalar/vector/matrix from float or
  1715. uint into int. Uses ``OpBitcast``. This method currently does not support
  1716. conversion into integer matrices.
  1717. - ``asuint``: converts the component type of a scalar/vector/matrix from float
  1718. or int into uint. Uses ``OpBitcast``. This method currently does not support
  1719. - ``asuint``: Converts a double into two 32-bit unsigned integers. Uses SPIR-V ``OpBitCast``.
  1720. - ``asdouble``: Converts two 32-bit unsigned integers into a double, or four 32-bit unsigned
  1721. integers into two doubles. Uses SPIR-V ``OpVectorShuffle`` and ``OpBitCast``.
  1722. conversion into unsigned integer matrices.
  1723. - ``isfinite`` : Determines if the specified value is finite. Since ``OpIsFinite``
  1724. requires the ``Kernel`` capability, translation is done using ``OpIsNan`` and
  1725. ``OpIsInf``. A given value is finite iff it is not NaN and not infinite.
  1726. - ``clip``: Discards the current pixel if the specified value is less than zero.
  1727. Uses conditional control flow as well as SPIR-V ``OpKill``.
  1728. - ``rcp``: Calculates a fast, approximate, per-component reciprocal.
  1729. Uses SIR-V ``OpFDiv``.
  1730. - ``lit``: Returns a lighting coefficient vector. This vector is a float4 with
  1731. components of (ambient, diffuse, specular, 1). How ``diffuse`` and ``specular``
  1732. are calculated are explained `here <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509619(v=vs.85).aspx>`_.
  1733. - ``D3DCOLORtoUBYTE4``: Converts a floating-point, 4D vector set by a D3DCOLOR to a UBYTE4.
  1734. This is achieved by performing ``int4(input.zyxw * 255.002)`` using SPIR-V ``OpVectorShuffle``,
  1735. ``OpVectorTimesScalar``, and ``OpConvertFToS``, respectively.
  1736. - ``dst``: Calculates a distance vector. The resulting vector, ``dest``, has the following specifications:
  1737. ``dest.x = 1.0``, ``dest.y = src0.y * src1.y``, ``dest.z = src0.z``, and ``dest.w = src1.w``.
  1738. Uses SPIR-V ``OpCompositeExtract`` and ``OpFMul``.
  1739. Using SPIR-V opcode
  1740. ~~~~~~~~~~~~~~~~~~~
  1741. The following intrinsic HLSL functions have direct SPIR-V opcodes for them:
  1742. ==================================== =================================
  1743. HLSL Intrinsic Function SPIR-V Opcode
  1744. ==================================== =================================
  1745. ``AllMemoryBarrier`` ``OpMemoryBarrier``
  1746. ``AllMemoryBarrierWithGroupSync`` ``OpControlBarrier``
  1747. ``countbits`` ``OpBitCount``
  1748. ``DeviceMemoryBarrier`` ``OpMemoryBarrier``
  1749. ``DeviceMemoryBarrierWithGroupSync`` ``OpControlBarrier``
  1750. ``ddx`` ``OpDPdx``
  1751. ``ddy`` ``OpDPdy``
  1752. ``ddx_coarse`` ``OpDPdxCoarse``
  1753. ``ddy_coarse`` ``OpDPdyCoarse``
  1754. ``ddx_fine`` ``OpDPdxFine``
  1755. ``ddy_fine`` ``OpDPdyFine``
  1756. ``fmod`` ``OpFRem``
  1757. ``fwidth`` ``OpFwidth``
  1758. ``GroupMemoryBarrier`` ``OpMemoryBarrier``
  1759. ``GroupMemoryBarrierWithGroupSync`` ``OpControlBarrier``
  1760. ``InterlockedAdd`` ``OpAtomicIAdd``
  1761. ``InterlockedAnd`` ``OpAtomicAnd``
  1762. ``InterlockedOr`` ``OpAtomicOr``
  1763. ``InterlockedXor`` ``OpAtomicXor``
  1764. ``InterlockedMin`` ``OpAtomicUMin``/``OpAtomicSMin``
  1765. ``InterlockedMax`` ``OpAtomicUMax``/``OpAtomicSMax``
  1766. ``InterlockedExchange`` ``OpAtomicExchange``
  1767. ``InterlockedCompareExchange`` ``OpAtomicCompareExchange``
  1768. ``InterlockedCompareStore`` ``OpAtomicCompareExchange``
  1769. ``isnan`` ``OpIsNan``
  1770. ``isInf`` ``OpIsInf``
  1771. ``reversebits`` ``OpBitReverse``
  1772. ``transpose`` ``OpTranspose``
  1773. ``CheckAccessFullyMapped`` ``OpImageSparseTexelsResident``
  1774. ==================================== =================================
  1775. Using GLSL extended instructions
  1776. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1777. The following intrinsic HLSL functions are translated using their equivalent
  1778. instruction in the `GLSL extended instruction set <https://www.khronos.org/registry/spir-v/specs/1.0/GLSL.std.450.html>`_.
  1779. ======================= ===================================
  1780. HLSL Intrinsic Function GLSL Extended Instruction
  1781. ======================= ===================================
  1782. ``abs`` ``SAbs``/``FAbs``
  1783. ``acos`` ``Acos``
  1784. ``asin`` ``Asin``
  1785. ``atan`` ``Atan``
  1786. ``atan2`` ``Atan2``
  1787. ``ceil`` ``Ceil``
  1788. ``clamp`` ``SClamp``/``UClamp``/``FClamp``
  1789. ``cos`` ``Cos``
  1790. ``cosh`` ``Cosh``
  1791. ``cross`` ``Cross``
  1792. ``degrees`` ``Degrees``
  1793. ``distance`` ``Distance``
  1794. ``radians`` ``Radian``
  1795. ``determinant`` ``Determinant``
  1796. ``exp`` ``Exp``
  1797. ``exp2`` ``exp2``
  1798. ``f16tof32`` ``UnpackHalf2x16``
  1799. ``f32tof16`` ``PackHalf2x16``
  1800. ``faceforward`` ``FaceForward``
  1801. ``firstbithigh`` ``FindSMsb`` / ``FindUMsb``
  1802. ``firstbitlow`` ``FindILsb``
  1803. ``floor`` ``Floor``
  1804. ``fma`` ``Fma``
  1805. ``frac`` ``Fract``
  1806. ``frexp`` ``FrexpStruct``
  1807. ``ldexp`` ``Ldexp``
  1808. ``length`` ``Length``
  1809. ``lerp`` ``FMix``
  1810. ``log`` ``Log``
  1811. ``log10`` ``Log2`` (scaled by ``1/log2(10)``)
  1812. ``log2`` ``Log2``
  1813. ``mad`` ``Fma``
  1814. ``max`` ``SMax``/``UMax``/``FMax``
  1815. ``min`` ``SMin``/``UMin``/``FMin``
  1816. ``modf`` ``ModfStruct``
  1817. ``normalize`` ``Normalize``
  1818. ``pow`` ``Pow``
  1819. ``reflect`` ``Reflect``
  1820. ``refract`` ``Refract``
  1821. ``round`` ``Round``
  1822. ``rsqrt`` ``InverseSqrt``
  1823. ``saturate`` ``FClamp``
  1824. ``sign`` ``SSign``/``FSign``
  1825. ``sin`` ``Sin``
  1826. ``sincos`` ``Sin`` and ``Cos``
  1827. ``sinh`` ``Sinh``
  1828. ``smoothstep`` ``SmoothStep``
  1829. ``sqrt`` ``Sqrt``
  1830. ``step`` ``Step``
  1831. ``tan`` ``Tan``
  1832. ``tanh`` ``Tanh``
  1833. ``trunc`` ``Trunc``
  1834. ======================= ===================================
  1835. Synchronization intrinsics
  1836. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1837. Synchronization intrinsics are translated into ``OpMemoryBarrier`` (for those
  1838. non-``WithGroupSync`` variants) or ``OpControlBarrier`` (for those ``WithGroupSync``
  1839. variants) instructions with parameters:
  1840. ======================= ============ ===== ======= ========= ==============
  1841. HLSL SPIR-V SPIR-V Memory Semantics
  1842. ----------------------- ------------ --------------------------------------
  1843. Intrinsic Memory Scope Image Uniform Workgroup AcquireRelease
  1844. ======================= ============ ===== ======= ========= ==============
  1845. ``AllMemoryBarrier`` Device ✓ ✓ ✓ ✓
  1846. ``DeviceMemoryBarrier`` Device ✓ ✓ ✓
  1847. ``GroupMemoryBarrier`` Workgroup ✓ ✓
  1848. ======================= ============ ===== ======= ========= ==============
  1849. For the ``*WithGroupSync`` intrinsics, SPIR-V memory scope and semantics are the
  1850. same as their counterparts in the above. They have an additional execution
  1851. scope:
  1852. ==================================== ======================
  1853. HLSL Intrinsic SPIR-V Execution Scope
  1854. ==================================== ======================
  1855. ``AllMemoryBarrierWithGroupSync`` Workgroup
  1856. ``DeviceMemoryBarrierWithGroupSync`` Workgroup
  1857. ``GroupMemoryBarrierWithGroupSync`` Workgroup
  1858. ==================================== ======================
  1859. HLSL OO features
  1860. ================
  1861. A HLSL struct/class member method is translated into a normal SPIR-V function,
  1862. whose signature has an additional first parameter for the struct/class called
  1863. upon. Every calling site of the method is generated to pass in the object as
  1864. the first argument.
  1865. HLSL struct/class static member variables are translated into SPIR-V variables
  1866. in the ``Private`` storage class.
  1867. HLSL Methods
  1868. ============
  1869. This section lists how various HLSL methods are mapped.
  1870. Buffers
  1871. -------
  1872. ``Buffer``
  1873. ~~~~~~~~~~
  1874. ``.Load()``
  1875. +++++++++++
  1876. Since Buffers are represented as ``OpTypeImage`` with ``Sampled`` set to 1
  1877. (meaning to be used with a sampler), ``OpImageFetch`` is used to perform this
  1878. operation. The return value of ``OpImageFetch`` is always a four-component
  1879. vector; so proper additional instructions are generated to truncate the vector
  1880. and return the desired number of elements.
  1881. If an output unsigned integer ``status`` argument is present, ``OpImageSparseFetch``
  1882. is used instead. The resulting SPIR-V ``Residency Code`` will be written to ``status``.
  1883. ``operator[]``
  1884. ++++++++++++++
  1885. Handled similarly as ``.Load()``.
  1886. ``.GetDimensions()``
  1887. ++++++++++++++++++++
  1888. Since Buffers are represented as ``OpTypeImage`` with dimension of ``Buffer``,
  1889. ``OpImageQuerySize`` is used to perform this operation.
  1890. ``RWBuffer``
  1891. ~~~~~~~~~~~~
  1892. ``.Load()``
  1893. +++++++++++
  1894. Since RWBuffers are represented as ``OpTypeImage`` with ``Sampled`` set to 2
  1895. (meaning to be used without a sampler), ``OpImageRead`` is used to perform this
  1896. operation. If an output unsigned integer ``status`` argument is present, ``OpImageSparseRead``
  1897. is used instead. The resulting SPIR-V ``Residency Code`` will be written to ``status``.
  1898. ``operator[]``
  1899. ++++++++++++++
  1900. Using ``operator[]`` for reading is handled similarly as ``.Load()``, while for
  1901. writing, the ``OpImageWrite`` instruction is generated.
  1902. ``.GetDimensions()``
  1903. ++++++++++++++++++++
  1904. Since RWBuffers are represented as ``OpTypeImage`` with dimension of ``Buffer``,
  1905. ``OpImageQuerySize`` is used to perform this operation.
  1906. ``StructuredBuffer`` and ``RWStructuredBuffer``
  1907. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1908. ``.GetDimensions()``
  1909. ++++++++++++++++++++
  1910. Since StructuredBuffers/RWStructuredBuffers are represented as a struct with one
  1911. member that is a runtime array of structures, ``OpArrayLength`` is invoked on
  1912. the runtime array in order to find the dimension.
  1913. ``ByteAddressBuffer``
  1914. ~~~~~~~~~~~~~~~~~~~~~
  1915. ``.GetDimensions()``
  1916. ++++++++++++++++++++
  1917. Since ByteAddressBuffers are represented as a struct with one member that is a
  1918. runtime array of unsigned integers, ``OpArrayLength`` is invoked on the runtime array
  1919. in order to find the number of unsigned integers. This is then multiplied by 4 to find
  1920. the number of bytes.
  1921. ``.Load()``, ``.Load2()``, ``.Load3()``, ``.Load4()``
  1922. +++++++++++++++++++++++++++++++++++++++++++++++++++++
  1923. ByteAddressBuffers are represented as a struct with one member that is a runtime array of
  1924. unsigned integers. The ``address`` argument passed to the function is first divided by 4
  1925. in order to find the offset into the array (because each array element is 4 bytes). The
  1926. SPIR-V ``OpAccessChain`` instruction is then used to access that offset, and ``OpLoad`` is
  1927. used to load a 32-bit unsigned integer. For ``Load2``, ``Load3``, and ``Load4``, this is
  1928. done 2, 3, and 4 times, respectively. Each time the word offset is incremented by 1 before
  1929. performing ``OpAccessChain``. After all ``OpLoad`` operations are performed, a vector is
  1930. constructed with all the resulting values.
  1931. ``RWByteAddressBuffer``
  1932. ~~~~~~~~~~~~~~~~~~~~~~~
  1933. ``.GetDimensions()``
  1934. ++++++++++++++++++++
  1935. Since RWByteAddressBuffers are represented as a struct with one member that is a
  1936. runtime array of unsigned integers, ``OpArrayLength`` is invoked on the runtime array
  1937. in order to find the number of unsigned integers. This is then multiplied by 4 to find
  1938. the number of bytes.
  1939. ``.Load()``, ``.Load2()``, ``.Load3()``, ``.Load4()``
  1940. +++++++++++++++++++++++++++++++++++++++++++++++++++++
  1941. RWByteAddressBuffers are represented as a struct with one member that is a runtime array of
  1942. unsigned integers. The ``address`` argument passed to the function is first divided by 4
  1943. in order to find the offset into the array (because each array element is 4 bytes). The
  1944. SPIR-V ``OpAccessChain`` instruction is then used to access that offset, and ``OpLoad`` is
  1945. used to load a 32-bit unsigned integer. For ``Load2``, ``Load3``, and ``Load4``, this is
  1946. done 2, 3, and 4 times, respectively. Each time the word offset is incremented by 1 before
  1947. performing ``OpAccessChain``. After all ``OpLoad`` operations are performed, a vector is
  1948. constructed with all the resulting values.
  1949. ``.Store()``, ``.Store2()``, ``.Store3()``, ``.Store4()``
  1950. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1951. RWByteAddressBuffers are represented as a struct with one member that is a runtime array of
  1952. unsigned integers. The ``address`` argument passed to the function is first divided by 4
  1953. in order to find the offset into the array (because each array element is 4 bytes). The
  1954. SPIR-V ``OpAccessChain`` instruction is then used to access that offset, and ``OpStore`` is
  1955. used to store a 32-bit unsigned integer. For ``Store2``, ``Store3``, and ``Store4``, this is
  1956. done 2, 3, and 4 times, respectively. Each time the word offset is incremented by 1 before
  1957. performing ``OpAccessChain``.
  1958. ``.Interlocked*()``
  1959. +++++++++++++++++++
  1960. ================================= =================================
  1961. HLSL Intrinsic Method SPIR-V Opcode
  1962. ================================= =================================
  1963. ``.InterlockedAdd()`` ``OpAtomicIAdd``
  1964. ``.InterlockedAnd()`` ``OpAtomicAnd``
  1965. ``.InterlockedOr()`` ``OpAtomicOr``
  1966. ``.InterlockedXor()`` ``OpAtomicXor``
  1967. ``.InterlockedMin()`` ``OpAtomicUMin``/``OpAtomicSMin``
  1968. ``.InterlockedMax()`` ``OpAtomicUMax``/``OpAtomicSMax``
  1969. ``.InterlockedExchange()`` ``OpAtomicExchange``
  1970. ``.InterlockedCompareExchange()`` ``OpAtomicCompareExchange``
  1971. ``.InterlockedCompareStore()`` ``OpAtomicCompareExchange``
  1972. ================================= =================================
  1973. ``AppendStructuredBuffer``
  1974. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1975. ``.Append()``
  1976. +++++++++++++
  1977. The associated counter number will be increased by 1 using ``OpAtomicIAdd``.
  1978. The return value of ``OpAtomicIAdd``, which is the original count number, will
  1979. be used as the index for storing the new element. E.g., for ``buf.Append(vec)``:
  1980. .. code:: spirv
  1981. %counter = OpAccessChain %_ptr_Uniform_int %counter_var_buf %uint_0
  1982. %index = OpAtomicIAdd %uint %counter %uint_1 %uint_0 %uint_1
  1983. %ptr = OpAccessChain %_ptr_Uniform_v4float %buf %uint_0 %index
  1984. %val = OpLoad %v4float %vec
  1985. OpStore %ptr %val
  1986. ``.GetDimensions()``
  1987. ++++++++++++++++++++
  1988. Since AppendStructuredBuffers are represented as a struct with one member that
  1989. is a runtime array, ``OpArrayLength`` is invoked on the runtime array in order
  1990. to find the number of elements. The stride is also calculated based on GLSL
  1991. ``std430`` as explained above.
  1992. ``ConsumeStructuredBuffer``
  1993. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1994. ``.Consume()``
  1995. ++++++++++++++
  1996. The associated counter number will be decreased by 1 using ``OpAtomicISub``.
  1997. The return value of ``OpAtomicISub`` minus 1, which is the new count number,
  1998. will be used as the index for reading the new element. E.g., for
  1999. ``buf.Consume(vec)``:
  2000. .. code:: spirv
  2001. %counter = OpAccessChain %_ptr_Uniform_int %counter_var_buf %uint_0
  2002. %prev = OpAtomicISub %uint %counter %uint_1 %uint_0 %uint_1
  2003. %index = OpISub %uint %prev %uint_1
  2004. %ptr = OpAccessChain %_ptr_Uniform_v4float %buf %uint_0 %index
  2005. %val = OpLoad %v4float %vec
  2006. OpStore %ptr %val
  2007. ``.GetDimensions()``
  2008. ++++++++++++++++++++
  2009. Since ConsumeStructuredBuffers are represented as a struct with one member that
  2010. is a runtime array, ``OpArrayLength`` is invoked on the runtime array in order
  2011. to find the number of elements. The stride is also calculated based on GLSL
  2012. ``std430`` as explained above.
  2013. Read-only textures
  2014. ------------------
  2015. Methods common to all texture types are explained in the "common texture methods"
  2016. section. Methods unique to a specific texture type is explained in the section
  2017. for that texture type.
  2018. Common texture methods
  2019. ~~~~~~~~~~~~~~~~~~~~~~
  2020. ``.Sample(sampler, location[, offset][, clamp][, Status])``
  2021. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2022. Not available to ``Texture2DMS`` and ``Texture2DMSArray``.
  2023. The ``OpImageSampleImplicitLod`` instruction is used to translate ``.Sample()``
  2024. since texture types are represented as ``OpTypeImage``. An ``OpSampledImage`` is
  2025. created based on the ``sampler`` passed to the function. The resulting sampled
  2026. image and the ``location`` passed to the function are used as arguments to
  2027. ``OpImageSampleImplicitLod``, with the optional ``offset`` tranlated into
  2028. addtional SPIR-V image operands ``ConstOffset`` or ``Offset`` on it. The optional
  2029. ``clamp`` argument will be translated to the ``MinLod`` image operand.
  2030. If an output unsigned integer ``status`` argument is present,
  2031. ``OpImageSparseSampleImplicitLod`` is used instead. The resulting SPIR-V
  2032. ``Residency Code`` will be written to ``status``.
  2033. ``.SampleLevel(sampler, location, lod[, offset][, Status])``
  2034. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2035. Not available to ``Texture2DMS`` and ``Texture2DMSArray``.
  2036. The ``OpImageSampleExplicitLod`` instruction is used to translate this method.
  2037. An ``OpSampledImage`` is created based on the ``sampler`` passed to the function.
  2038. The resulting sampled image and the ``location`` passed to the function are used
  2039. as arguments to ``OpImageSampleExplicitLod``. The ``lod`` passed to the function
  2040. is attached to the instruction as an SPIR-V image operands ``Lod``. The optional
  2041. ``offset`` is also tranlated into addtional SPIR-V image operands ``ConstOffset``
  2042. or ``Offset`` on it.
  2043. If an output unsigned integer ``status`` argument is present,
  2044. ``OpImageSparseSampleExplicitLod`` is used instead. The resulting SPIR-V
  2045. ``Residency Code`` will be written to ``status``.
  2046. ``.SampleGrad(sampler, location, ddx, ddy[, offset][, clamp][, Status])``
  2047. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2048. Not available to ``Texture2DMS`` and ``Texture2DMSArray``.
  2049. Similarly to ``.SampleLevel``, the ``ddx`` and ``ddy`` parameter are attached to
  2050. the ``OpImageSampleExplicitLod`` instruction as an SPIR-V image operands
  2051. ``Grad``. The optional ``clamp`` argument will be translated into the ``MinLod``
  2052. image operand.
  2053. If an output unsigned integer ``status`` argument is present,
  2054. ``OpImageSparseSampleExplicitLod`` is used instead. The resulting SPIR-V
  2055. ``Residency Code`` will be written to ``status``.
  2056. ``.SampleBias(sampler, location, bias[, offset][, clamp][, Status])``
  2057. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2058. Not available to ``Texture2DMS`` and ``Texture2DMSArray``.
  2059. The translation is similar to ``.Sample()``, with the ``bias`` parameter
  2060. attached to the ``OpImageSampleImplicitLod`` instruction as an SPIR-V image
  2061. operands ``Bias``.
  2062. If an output unsigned integer ``status`` argument is present,
  2063. ``OpImageSparseSampleImplicitLod`` is used instead. The resulting SPIR-V
  2064. ``Residency Code`` will be written to ``status``.
  2065. ``.SampleCmp(sampler, location, comparator[, offset][, clamp][, Status])``
  2066. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2067. Not available to ``Texture3D``, ``Texture2DMS``, and ``Texture2DMSArray``.
  2068. The translation is similar to ``.Sample()``, but the
  2069. ``OpImageSampleDrefImplicitLod`` instruction are used.
  2070. If an output unsigned integer ``status`` argument is present,
  2071. ``OpImageSparseSampleDrefImplicitLod`` is used instead. The resulting SPIR-V
  2072. ``Residency Code`` will be written to ``status``.
  2073. ``.SampleCmpLevelZero(sampler, location, comparator[, offset][, Status])``
  2074. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2075. Not available to ``Texture3D``, ``Texture2DMS``, and ``Texture2DMSArray``.
  2076. The translation is similar to ``.Sample()``, but the
  2077. ``OpImageSampleDrefExplicitLod`` instruction are used, with the additional
  2078. ``Lod`` image operands set to 0.0.
  2079. If an output unsigned integer ``status`` argument is present,
  2080. ``OpImageSparseSampleDrefExplicitLod`` is used instead. The resulting SPIR-V
  2081. ``Residency Code`` will be written to ``status``.
  2082. ``.Gather()``
  2083. +++++++++++++
  2084. Available to ``Texture2D``, ``Texture2DArray``, ``TextureCube``, and
  2085. ``TextureCubeArray``.
  2086. The translation is similar to ``.Sample()``, but the ``OpImageGather``
  2087. instruction is used, with component setting to 0.
  2088. If an output unsigned integer ``status`` argument is present,
  2089. ``OpImageSparseGather`` is used instead. The resulting SPIR-V
  2090. ``Residency Code`` will be written to ``status``.
  2091. ``.GatherRed()``, ``.GatherGreen()``, ``.GatherBlue()``, ``.GatherAlpha()``
  2092. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2093. Available to ``Texture2D``, ``Texture2DArray``, ``TextureCube``, and
  2094. ``TextureCubeArray``.
  2095. The ``OpImageGather`` instruction is used to translate these functions, with
  2096. component setting to 0, 1, 2, and 3 respectively.
  2097. There are a few overloads for these functions:
  2098. - For those overloads taking 4 offset parameters, those offset parameters will
  2099. be conveyed as an additional ``ConstOffsets`` image operands to the
  2100. instruction if those offset parameters are all constants. Otherwise,
  2101. 4 separate ``OpImageGather`` instructions will be emitted to get each texel
  2102. from each offset, using the ``Offset`` image operands.
  2103. - For those overloads with the ``status`` parameter, ``OpImageSparseGather``
  2104. is used instead, and the resulting SPIR-V ``Residency Code`` will be
  2105. written to ``status``.
  2106. ``.GatherCmp()``
  2107. ++++++++++++++++
  2108. Available to ``Texture2D``, ``Texture2DArray``, ``TextureCube``, and
  2109. ``TextureCubeArray``.
  2110. The translation is similar to ``.Sample()``, but the ``OpImageDrefGather``
  2111. instruction is used.
  2112. For the overload with the output unsigned integer ``status`` argument,
  2113. ``OpImageSparseDrefGather`` is used instead. The resulting SPIR-V
  2114. ``Residency Code`` will be written to ``status``.
  2115. ``.GatherCmpRed()``
  2116. +++++++++++++++++++
  2117. Available to ``Texture2D``, ``Texture2DArray``, ``TextureCube``, and
  2118. ``TextureCubeArray``.
  2119. The translation is the same as ``.GatherCmp()``.
  2120. ``.Load(location[, sampleIndex][, offset])``
  2121. ++++++++++++++++++++++++++++++++++++++++++++
  2122. The ``OpImageFetch`` instruction is used for translation because texture types
  2123. are represented as ``OpTypeImage``. The last element in the ``location``
  2124. parameter will be used as arguments to the ``Lod`` SPIR-V image operand attached
  2125. to the ``OpImageFetch`` instruction, and the rest are used as the coordinate
  2126. argument to the instruction. ``offset`` is handled similarly to ``.Sample()``.
  2127. The return value of ``OpImageFetch`` is always a four-component vector; so
  2128. proper additional instructions are generated to truncate the vector and return
  2129. the desired number of elements.
  2130. For the overload with the output unsigned integer ``status`` argument,
  2131. ``OpImageSparseFetch`` is used instead. The resulting SPIR-V
  2132. ``Residency Code`` will be written to ``status``.
  2133. ``operator[]``
  2134. ++++++++++++++
  2135. Handled similarly as ``.Load()``.
  2136. ``.mips[lod][position]``
  2137. ++++++++++++++++++++++++
  2138. Not available to ``TextureCube``, ``TextureCubeArray``, ``Texture2DMS``, and
  2139. ``Texture2DMSArray``.
  2140. This method is translated into the ``OpImageFetch`` instruction. The ``lod``
  2141. parameter is attached to the instruction as the parameter to the ``Lod`` SPIR-V
  2142. image operands. The ``position`` parameter are used as the coordinate to the
  2143. instruction directly.
  2144. ``.CalculateLevelOfDetail()`` and ``.CalculateLevelOfDetailUnclamped()``
  2145. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2146. Not available to ``Texture2DMS`` and ``Texture2DMSArray``.
  2147. Since texture types are represented as ``OpTypeImage``, the ``OpImageQueryLod``
  2148. instruction is used for translation. An ``OpSampledImage`` is created based on
  2149. the ``SamplerState`` passed to the function. The resulting sampled image and
  2150. the coordinate passed to the function are used to invoke ``OpImageQueryLod``.
  2151. The result of ``OpImageQueryLod`` is a ``float2``. The first element contains
  2152. the mipmap array layer. The second element contains the unclamped level of detail.
  2153. ``Texture1D``
  2154. ~~~~~~~~~~~~~
  2155. ``.GetDimensions(width)`` or ``.GetDimensions(MipLevel, width, NumLevels)``
  2156. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2157. Since Texture1D is represented as ``OpTypeImage``, the ``OpImageQuerySizeLod`` instruction
  2158. is used for translation. If a ``MipLevel`` argument is passed to ``GetDimensions``, it will
  2159. be used as the ``Lod`` parameter of the query instruction. Otherwise, ``Lod`` of ``0`` be used.
  2160. ``Texture1DArray``
  2161. ~~~~~~~~~~~~~~~~~~
  2162. ``.GetDimensions(width, elements)`` or ``.GetDimensions(MipLevel, width, elements, NumLevels)``
  2163. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2164. Since Texture1DArray is represented as ``OpTypeImage``, the ``OpImageQuerySizeLod`` instruction
  2165. is used for translation. If a ``MipLevel`` argument is present, it will be used as the
  2166. ``Lod`` parameter of the query instruction. Otherwise, ``Lod`` of ``0`` be used.
  2167. ``Texture2D``
  2168. ~~~~~~~~~~~~~
  2169. ``.GetDimensions(width, height)`` or ``.GetDimensions(MipLevel, width, height, NumLevels)``
  2170. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2171. Since Texture2D is represented as ``OpTypeImage``, the ``OpImageQuerySizeLod`` instruction
  2172. is used for translation. If a ``MipLevel`` argument is present, it will be used as the
  2173. ``Lod`` parameter of the query instruction. Otherwise, ``Lod`` of ``0`` be used.
  2174. ``Texture2DArray``
  2175. ~~~~~~~~~~~~~~~~~~
  2176. ``.GetDimensions(width, height, elements)`` or ``.GetDimensions(MipLevel, width, height, elements, NumLevels)``
  2177. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2178. Since Texture2DArray is represented as ``OpTypeImage``, the ``OpImageQuerySizeLod`` instruction
  2179. is used for translation. If a ``MipLevel`` argument is present, it will be used as the
  2180. ``Lod`` parameter of the query instruction. Otherwise, ``Lod`` of ``0`` be used.
  2181. ``Texture3D``
  2182. ~~~~~~~~~~~~~
  2183. ``.GetDimensions(width, height, depth)`` or ``.GetDimensions(MipLevel, width, height, depth, NumLevels)``
  2184. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2185. Since Texture3D is represented as ``OpTypeImage``, the ``OpImageQuerySizeLod`` instruction
  2186. is used for translation. If a ``MipLevel`` argument is present, it will be used as the
  2187. ``Lod`` parameter of the query instruction. Otherwise, ``Lod`` of ``0`` be used.
  2188. ``Texture2DMS``
  2189. ~~~~~~~~~~~~~~~
  2190. ``.sample[sample][position]``
  2191. +++++++++++++++++++++++++++++
  2192. This method is translated into the ``OpImageFetch`` instruction. The ``sample``
  2193. parameter is attached to the instruction as the parameter to the ``Sample``
  2194. SPIR-V image operands. The ``position`` parameter are used as the coordinate to
  2195. the instruction directly.
  2196. ``.GetDimensions(width, height, numSamples)``
  2197. +++++++++++++++++++++++++++++++++++++++++++++
  2198. Since Texture2DMS is represented as ``OpTypeImage`` with ``MS`` of ``1``, the ``OpImageQuerySize`` instruction
  2199. is used to get the width and the height. Furthermore, ``OpImageQuerySamples`` is used to get the numSamples.
  2200. ``.GetSamplePosition(index)``
  2201. +++++++++++++++++++++++++++++
  2202. There are no direct mapping SPIR-V instructions for this method. Right now, it
  2203. is translated into the SPIR-V code for the following HLSL source code:
  2204. .. code:: hlsl
  2205. // count is the number of samples in the Texture2DMS(Array)
  2206. // index is the index of the sample we are trying to get the position
  2207. static const float2 pos2[] = {
  2208. { 4.0/16.0, 4.0/16.0 }, {-4.0/16.0, -4.0/16.0 },
  2209. };
  2210. static const float2 pos4[] = {
  2211. {-2.0/16.0, -6.0/16.0 }, { 6.0/16.0, -2.0/16.0 }, {-6.0/16.0, 2.0/16.0 }, { 2.0/16.0, 6.0/16.0 },
  2212. };
  2213. static const float2 pos8[] = {
  2214. { 1.0/16.0, -3.0/16.0 }, {-1.0/16.0, 3.0/16.0 }, { 5.0/16.0, 1.0/16.0 }, {-3.0/16.0, -5.0/16.0 },
  2215. {-5.0/16.0, 5.0/16.0 }, {-7.0/16.0, -1.0/16.0 }, { 3.0/16.0, 7.0/16.0 }, { 7.0/16.0, -7.0/16.0 },
  2216. };
  2217. static const float2 pos16[] = {
  2218. { 1.0/16.0, 1.0/16.0 }, {-1.0/16.0, -3.0/16.0 }, {-3.0/16.0, 2.0/16.0 }, { 4.0/16.0, -1.0/16.0 },
  2219. {-5.0/16.0, -2.0/16.0 }, { 2.0/16.0, 5.0/16.0 }, { 5.0/16.0, 3.0/16.0 }, { 3.0/16.0, -5.0/16.0 },
  2220. {-2.0/16.0, 6.0/16.0 }, { 0.0/16.0, -7.0/16.0 }, {-4.0/16.0, -6.0/16.0 }, {-6.0/16.0, 4.0/16.0 },
  2221. {-8.0/16.0, 0.0/16.0 }, { 7.0/16.0, -4.0/16.0 }, { 6.0/16.0, 7.0/16.0 }, {-7.0/16.0, -8.0/16.0 },
  2222. };
  2223. float2 position = float2(0.0f, 0.0f);
  2224. if (count == 2) {
  2225. position = pos2[index];
  2226. } else if (count == 4) {
  2227. position = pos4[index];
  2228. } else if (count == 8) {
  2229. position = pos8[index];
  2230. } else if (count == 16) {
  2231. position = pos16[index];
  2232. }
  2233. From the above, it's clear that the current implementation only supports standard
  2234. sample settings, i.e., with 1, 2, 4, 8, or 16 samples. For other cases, the
  2235. implementation will just return `(float2)0`.
  2236. ``Texture2DMSArray``
  2237. ~~~~~~~~~~~~~~~~~~~~
  2238. ``.sample[sample][position]``
  2239. +++++++++++++++++++++++++++++
  2240. This method is translated into the ``OpImageFetch`` instruction. The ``sample``
  2241. parameter is attached to the instruction as the parameter to the ``Sample``
  2242. SPIR-V image operands. The ``position`` parameter are used as the coordinate to
  2243. the instruction directly.
  2244. ``.GetDimensions(width, height, elements, numSamples)``
  2245. +++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2246. Since Texture2DMS is represented as ``OpTypeImage`` with ``MS`` of ``1``, the ``OpImageQuerySize`` instruction
  2247. is used to get the width, the height, and the elements. Furthermore, ``OpImageQuerySamples`` is used to get the numSamples.
  2248. ``.GetSamplePosition(index)``
  2249. +++++++++++++++++++++++++++++
  2250. Similar to Texture2D.
  2251. ``TextureCube``
  2252. ~~~~~~~~~~~~~~~
  2253. ``TextureCubeArray``
  2254. ~~~~~~~~~~~~~~~~~~~~
  2255. Read-write textures
  2256. -------------------
  2257. Methods common to all texture types are explained in the "common texture methods"
  2258. section. Methods unique to a specific texture type is explained in the section
  2259. for that texture type.
  2260. Common texture methods
  2261. ~~~~~~~~~~~~~~~~~~~~~~
  2262. ``.Load()``
  2263. +++++++++++
  2264. Since read-write texture types are represented as ``OpTypeImage`` with
  2265. ``Sampled`` set to 2 (meaning to be used without a sampler), ``OpImageRead`` is
  2266. used to perform this operation.
  2267. For the overload with the output unsigned integer ``status`` argument,
  2268. ``OpImageSparseRead`` is used instead. The resulting SPIR-V
  2269. ``Residency Code`` will be written to ``status``.
  2270. ``operator[]``
  2271. ++++++++++++++
  2272. Using ``operator[]`` for reading is handled similarly as ``.Load()``, while for
  2273. writing, the ``OpImageWrite`` instruction is generated.
  2274. ``RWTexture1D``
  2275. ~~~~~~~~~~~~~~~
  2276. ``.GetDimensions(width)``
  2277. +++++++++++++++++++++++++
  2278. The ``OpImageQuerySize`` instruction is used to find the width.
  2279. ``RWTexture1DArray``
  2280. ~~~~~~~~~~~~~~~~~~~~
  2281. ``.GetDimensions(width, elements)``
  2282. +++++++++++++++++++++++++++++++++++
  2283. The ``OpImageQuerySize`` instruction is used to get a uint2. The first element
  2284. is the width, and the second is the elements.
  2285. ``RWTexture2D``
  2286. ~~~~~~~~~~~~~~~
  2287. ``.GetDimensions(width, height)``
  2288. +++++++++++++++++++++++++++++++++
  2289. The ``OpImageQuerySize`` instruction is used to get a uint2. The first element is the width, and the second
  2290. element is the height.
  2291. ``RWTexture2DArray``
  2292. ~~~~~~~~~~~~~~~~~~~~
  2293. ``.GetDimensions(width, height, elements)``
  2294. +++++++++++++++++++++++++++++++++++++++++++
  2295. The ``OpImageQuerySize`` instruction is used to get a uint3. The first element is the width, the second
  2296. element is the height, and the third is the elements.
  2297. ``RWTexture3D``
  2298. ~~~~~~~~~~~~~~~
  2299. ``.GetDimensions(width, height, depth)``
  2300. ++++++++++++++++++++++++++++++++++++++++
  2301. The ``OpImageQuerySize`` instruction is used to get a uint3. The first element is the width, the second
  2302. element is the height, and the third element is the depth.
  2303. HLSL Shader Stages
  2304. ==================
  2305. Hull Shaders
  2306. ------------
  2307. Hull shaders corresponds to Tessellation Control Shaders (TCS) in Vulkan.
  2308. This section describes how Hull shaders are translated to SPIR-V for Vulkan.
  2309. Hull Entry Point Attributes
  2310. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2311. The following HLSL attributes are attached to the main entry point of hull shaders
  2312. and are translated to SPIR-V execution modes according to the table below:
  2313. .. table:: Mapping from HLSL attribute to SPIR-V execution mode
  2314. +-------------------------+---------------------+--------------------------+
  2315. | HLSL Attribute | value | SPIR-V Execution Mode |
  2316. +=========================+=====================+==========================+
  2317. | | ``quad`` | ``Quads`` |
  2318. | +---------------------+--------------------------+
  2319. | ``domain`` | ``tri`` | ``Triangles`` |
  2320. | +---------------------+--------------------------+
  2321. | | ``isoline`` | ``Isoline`` |
  2322. +-------------------------+---------------------+--------------------------+
  2323. | | ``integer`` | ``SpacingEqual`` |
  2324. | +---------------------+--------------------------+
  2325. | | ``fractional_even`` | ``SpacingFractionalEven``|
  2326. | ``partitioning`` +---------------------+--------------------------+
  2327. | | ``fractional_odd`` | ``SpacingFractionalOdd`` |
  2328. | +---------------------+--------------------------+
  2329. | | ``pow2`` | N/A |
  2330. +-------------------------+---------------------+--------------------------+
  2331. | | ``point`` | ``PointMode`` |
  2332. | +---------------------+--------------------------+
  2333. | | ``line`` | N/A |
  2334. | ``outputtopology`` +---------------------+--------------------------+
  2335. | | ``triangle_cw`` | ``VertexOrderCw`` |
  2336. | +---------------------+--------------------------+
  2337. | | ``triangle_ccw`` | ``VertexOrderCcw`` |
  2338. +-------------------------+---------------------+--------------------------+
  2339. |``outputcontrolpoints`` | ``n`` | ``OutputVertices n`` |
  2340. +-------------------------+---------------------+--------------------------+
  2341. The ``patchconstfunc`` attribute does not have a direct equivalent in SPIR-V.
  2342. It specifies the name of the Patch Constant Function. This function is run only
  2343. once per patch. This is further described below.
  2344. InputPatch and OutputPatch
  2345. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2346. Both of ``InputPatch<T, N>`` and ``OutputPatch<T, N>`` are translated to an array
  2347. of constant size ``N`` where each element is of type ``T``.
  2348. InputPatch can be passed to the Hull shader main entry function as well as the
  2349. patch constant function. This would include information about each of the ``N``
  2350. vertices that are input to the tessellation control shader.
  2351. OutputPatch is an array containing ``N`` elements (where ``N`` is the number of
  2352. output vertices). Each element of the array contains information about an
  2353. output vertex. OutputPatch may also be passed to the patch constant function.
  2354. The SPIR-V ``InvocationID`` (``SV_OutputControlPointID`` in HLSL) is used to index
  2355. into the InputPatch and OutputPatch arrays to read/write information for the given
  2356. vertex.
  2357. The hull main entry function in HLSL returns only one value (say, of type ``T``), but
  2358. that function is in fact executed once for each control point. The Vulkan spec requires that
  2359. "Tessellation control shader per-vertex output variables and blocks, and tessellation control,
  2360. tessellation evaluation, and geometry shader per-vertex input variables and blocks are required
  2361. to be declared as arrays, with each element representing input or output values for a single vertex
  2362. of a multi-vertex primitive". Therefore, we need to create a stage output variable that is an array
  2363. with elements of type ``T``. The number of elements of the array is equal to the number of
  2364. output control points. Each final output control point is written into the corresponding element in
  2365. the array using SV_OutputControlPointID as the index.
  2366. Patch Constant Function
  2367. ~~~~~~~~~~~~~~~~~~~~~~~
  2368. As mentioned above, the patch constant function is to be invoked only once per patch.
  2369. As a result, in the SPIR-V module, the `entry function wrapper`_ will first invoke the
  2370. main entry function, and then use an ``OpControlBarrier`` to wait for all vertex
  2371. processing to finish. After the barrier, *only* the first thread (with InvocationID of 0)
  2372. will invoke the patch constant function.
  2373. The information resulting from the patch constant function will also be returned
  2374. as stage output variables. The output struct of the patch constant function must include
  2375. ``SV_TessFactor`` and ``SV_InsideTessFactor`` fields which will translate to
  2376. ``TessLevelOuter`` and ``TessLevelInner`` builtin variables, respectively. And the rest
  2377. will be flattened and translated into normal stage output variables, one for each field.
  2378. Geometry Shaders
  2379. ----------------
  2380. This section describes how geometry shaders are translated to SPIR-V for Vulkan.
  2381. Geometry Shader Entry Point Attributes
  2382. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2383. The following HLSL attribute is attached to the main entry point of geometry shaders
  2384. and is translated to SPIR-V execution mode as follows:
  2385. .. table:: Mapping from geometry shader HLSL attribute to SPIR-V execution mode
  2386. +-------------------------+---------------------+--------------------------+
  2387. | HLSL Attribute | value | SPIR-V Execution Mode |
  2388. +=========================+=====================+==========================+
  2389. |``maxvertexcount`` | ``n`` | ``OutputVertices n`` |
  2390. +-------------------------+---------------------+--------------------------+
  2391. |``instance`` | ``n`` | ``Invocations n`` |
  2392. +-------------------------+---------------------+--------------------------+
  2393. Translation for Primitive Types
  2394. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2395. Geometry shader vertex inputs may be qualified with primitive types. Only one primitive type
  2396. is allowed to be used in a given geometry shader. The following table shows the SPIR-V execution
  2397. mode that is used in order to represent the given primitive type.
  2398. .. table:: Mapping from geometry shader primitive type to SPIR-V execution mode
  2399. +---------------------+-----------------------------+
  2400. | HLSL Primitive Type | SPIR-V Execution Mode |
  2401. +=====================+=============================+
  2402. |``point`` | ``InputPoints`` |
  2403. +---------------------+-----------------------------+
  2404. |``line`` | ``InputLines`` |
  2405. +---------------------+-----------------------------+
  2406. |``triangle`` | ``Triangles`` |
  2407. +---------------------+-----------------------------+
  2408. |``lineadj`` | ``InputLinesAdjacency`` |
  2409. +---------------------+-----------------------------+
  2410. |``triangleadj`` | ``InputTrianglesAdjacency`` |
  2411. +---------------------+-----------------------------+
  2412. Translation of Output Stream Types
  2413. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2414. Supported output stream types in geometry shaders are: ``PointStream<T>``,
  2415. ``LineStream<T>``, and ``TriangleStream<T>``. These types are translated as the underlying
  2416. type ``T``, which is recursively flattened into stand-alone variables for each field.
  2417. Furthermore, output stream objects passed to geometry shader entry points are
  2418. required to be annotated with ``inout``, but the generated SPIR-V only contains
  2419. stage output variables for them.
  2420. The following table shows the SPIR-V execution mode that is used in order to represent the
  2421. given output stream.
  2422. .. table:: Mapping from geometry shader output stream type to SPIR-V execution mode
  2423. +---------------------+-----------------------------+
  2424. | HLSL Output Stream | SPIR-V Execution Mode |
  2425. +=====================+=============================+
  2426. |``PointStream`` | ``OutputPoints`` |
  2427. +---------------------+-----------------------------+
  2428. |``LineStream`` | ``OutputLineStrip`` |
  2429. +---------------------+-----------------------------+
  2430. |``TriangleStream`` | ``OutputTriangleStrip`` |
  2431. +---------------------+-----------------------------+
  2432. In other shader stages, stage output variables are only written in the `entry
  2433. function wrapper`_ after calling the source code entry function. However,
  2434. geometry shaders can output as many vertices as they wish, by calling the
  2435. ``.Append()`` method on the output stream object. Therefore, it is incorrect to
  2436. have only one flush in the entry function wrapper like other stages. Instead,
  2437. each time a ``*Stream<T>::Append()`` is encountered, all stage output variables
  2438. behind ``T`` will be flushed before SPIR-V ``OpEmitVertex`` instruction is
  2439. generated. ``.RestartStrip()`` method calls will be translated into the SPIR-V
  2440. ``OpEndPrimitive`` instruction.
  2441. Raytracing Shader Stages
  2442. ------------------------
  2443. DirectX Raytracing adds six new shader stages for raytracing namely ray generation, intersection, closest-hit,
  2444. any-hit, miss and callable.
  2445. | Refer to following pages for details:
  2446. | https://docs.microsoft.com/en-us/windows/desktop/direct3d12/direct3d-12-raytracing
  2447. | https://docs.microsoft.com/en-us/windows/desktop/direct3d12/direct3d-12-raytracing-hlsl-reference
  2448. Flow chart for various stages in a raytracing pipeline is as follows:
  2449. ::
  2450. +---------------------+
  2451. | Ray generation |
  2452. +---------------------+
  2453. |
  2454. TraceRay() | +--------------+
  2455. | _ _ _ _ _ _ _ _ | Any Hit |
  2456. | | +--------------+
  2457. V V ^
  2458. +---------------------+ |
  2459. | Acceleration | +--------------+
  2460. | Structure | | Intersection |
  2461. | Traversal | +--------------+
  2462. +---------------------+ ^
  2463. | | |
  2464. | |_ _ _ _ _ _ _ _ _ _ _|
  2465. |
  2466. |
  2467. V
  2468. +--------------------+ +-------------+
  2469. | Is Hit ? | | Callable |
  2470. +--------------------+ +-------------+
  2471. | |
  2472. Yes | | No
  2473. V V
  2474. +---------+ +------+
  2475. | Closest | | Miss |
  2476. | Hit | | |
  2477. +---------+ +------+
  2478. | *Note : DXC does not add special shader profiles for raytracing under -T option.*
  2479. | *All raytracing shaders must be compiled as library using lib_6_3/lib_6_4 profile option.*
  2480. | *Note : DXC now targets SPV_KHR_ray_tracing extension by default.*
  2481. | *This extension is provisional and subject to change*.
  2482. | *To compile for NV extension use -fspv-extension=SPV_NV_ray_tracing.*
  2483. Ray Generation Stage
  2484. ~~~~~~~~~~~~~~~~~~~~
  2485. | Ray generation shaders start ray tracing work and work on a compute-like 3D grid of threads.
  2486. | Entry functions of this stage type are annotated with **[shader("raygeneration")]** in HLSL source.
  2487. | Such entry functions must return void and do not accept any arguments.
  2488. | For example:
  2489. .. code:: hlsl
  2490. RaytracingAccelerationStructure rs;
  2491. struct Payload
  2492. {
  2493. float4 color;
  2494. };
  2495. [shader("raygeneration")]
  2496. void main() {
  2497. Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) };
  2498. RayDesc rayDesc;
  2499. rayDesc.Origin = float3(0.0f, 0.0f, 0.0f);
  2500. rayDesc.Direction = float3(0.0f, 0.0f, -1.0f);
  2501. rayDesc.TMin = 0.0f;
  2502. rayDesc.TMax = 1000.0f;
  2503. TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload);
  2504. }
  2505. Intersection Stage
  2506. ~~~~~~~~~~~~~~~~~~
  2507. | Intersection shader stage is used to implement arbitrary ray-primitive intersections such spheres or axis-aligned bounding boxes (AABB). Triangle primitives do not require a custom intersection shader.
  2508. | Entry functions of this stage are annotated with **[shader("intersection")]** in HLSL source.
  2509. | Such entry functions must return void and do not accept any arguments.
  2510. | For example:
  2511. .. code:: hlsl
  2512. struct Attribute
  2513. {
  2514. float2 bary;
  2515. };
  2516. [shader("intersection")]
  2517. void main() {
  2518. Attribute myHitAttribute = { float2(0.0f,0.0f) };
  2519. ReportHit(0.0f, 0U, myHitAttribute);
  2520. }
  2521. Closest-Hit Stage
  2522. ~~~~~~~~~~~~~~~~~
  2523. | Hit shaders are invoked when a ray primitive intersection is found. A closest-hit shader
  2524. | is invoked for the closest intersection point along a ray and can be used to compute interactions
  2525. | at intersection point or spawn secondary rays.
  2526. | Entry functions of this stage are annotated with **[shader("closesthit")]** in HLSL source.
  2527. | Such entry functions must return void and accept exactly two arguments. First argument must be an inout
  2528. | variable of user defined structure type and second argument must be a in variable of user defined structure type.
  2529. | For example:
  2530. .. code:: hlsl
  2531. struct Attribute
  2532. {
  2533. float2 bary;
  2534. };
  2535. struct Payload {
  2536. float4 color;
  2537. };
  2538. [shader("closesthit")]
  2539. void main(inout Payload a, in Attribute b) {
  2540. a.color = float4(0.0f,1.0f,0.0f,0.0f);
  2541. }
  2542. Any-Hit Stage
  2543. ~~~~~~~~~~~~~~~~~
  2544. | Hit shaders are invoked when a ray primitive intersection is found. An any-hit shader
  2545. | is invoked for all intersections along a ray with a primitive.
  2546. | Entry functions of this stage are annotated with **[shader("anyhit")]** in HLSL source.
  2547. | Such entry functions must return void and accept exactly two arguments. First argument must be an inout
  2548. | variable of user defined structure type and second argument must be an in variable of user defined structure type.
  2549. | For example:
  2550. .. code:: hlsl
  2551. struct Attribute
  2552. {
  2553. float2 bary;
  2554. };
  2555. struct Payload {
  2556. float4 color;
  2557. };
  2558. [shader("anyhit")]
  2559. void main(inout Payload a, in Attribute b) {
  2560. a.color = float4(0.0f,1.0f,0.0f,0.0f);
  2561. }
  2562. Miss Stage
  2563. ~~~~~~~~~~
  2564. | Miss shaders are invoked when no intersection is found.
  2565. | Entry functions of this stage are annotated with **[shader("miss")]** in HLSL source.
  2566. | Such entry functions return void and accept exactly one argument. First argument must be an inout variable of user defined structure type.
  2567. | For example:
  2568. .. code:: hlsl
  2569. struct Payload {
  2570. float4 color;
  2571. };
  2572. [shader("miss")]
  2573. void main(inout Payload a) {
  2574. a.color = float4(0.0f,1.0f,0.0f,0.0f);
  2575. }
  2576. Callable Stage
  2577. ~~~~~~~~~~~~~~
  2578. | Callables are generic function calls which can be invoked from either raygeneration, closest-hit,
  2579. | miss or callable shader stages.
  2580. | Entry functions of this stage are annotated with **[shader("callable")]** in HLSL source.
  2581. | Such entry functions must return void and accept exactly one argument. First argument must be an inout
  2582. | variable of user defined structure type.
  2583. | For example:
  2584. .. code:: hlsl
  2585. struct CallData {
  2586. float4 data;
  2587. };
  2588. [shader("callable")]
  2589. void main(inout CallData a) {
  2590. a.color = float4(0.0f,1.0f,0.0f,0.0f);
  2591. }
  2592. Mesh and Amplification Shaders
  2593. ------------------------------
  2594. | DirectX adds 2 new shader stages for using MeshShading pipeline namely Mesh and Amplification.
  2595. | Amplification shaders corresponds to Task Shaders in Vulkan.
  2596. |
  2597. | Refer to following HLSL and SPIR-V specs for details:
  2598. | https://docs.microsoft.com/<TBD>
  2599. | https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/NV/SPV_NV_mesh_shader.asciidoc
  2600. |
  2601. | This section describes how Mesh and Amplification shaders are translated to SPIR-V for Vulkan.
  2602. Entry Point Attributes
  2603. ~~~~~~~~~~~~~~~~~~~~~~
  2604. The following HLSL attributes are attached to the main entry point of Mesh and/or Amplification
  2605. shaders and are translated to SPIR-V execution modes according to the table below:
  2606. .. table:: Mapping from HLSL attribute to SPIR-V execution mode
  2607. +-------------------+--------------------+-------------------------+
  2608. | HLSL Attribute | Value | SPIR-V Execution Mode |
  2609. +===================+====================+=========================+
  2610. |``outputtopology`` | ``point`` | ``OutputPoints`` |
  2611. | +--------------------+-------------------------+
  2612. |``(Mesh shader)`` | ``line`` | ``OutputLinesNV`` |
  2613. | +--------------------+-------------------------+
  2614. | | ``triangle`` | ``OutputTrianglesNV`` |
  2615. +-------------------+--------------------+-------------------------+
  2616. | ``numthreads`` | ``X, Y, Z`` | ``LocalSize X, Y, Z`` |
  2617. | | | |
  2618. | | ``(X*Y*Z <= 128)`` | |
  2619. +-------------------+--------------------+-------------------------+
  2620. Intrinsics
  2621. ~~~~~~~~~~
  2622. The following HLSL intrinsics are used in Mesh or Amplification shaders
  2623. and are translated to SPIR-V intrinsics according to the table below:
  2624. .. table:: Mapping from HLSL intrinsics to SPIR-V intrinsics
  2625. +---------------------------+--------------------+-----------------------------------------+
  2626. | HLSL Intrinsic | Parameters | SPIR-V Intrinsic |
  2627. +===========================+====================+=========================================+
  2628. | ``SetMeshOutputCounts`` | ``numVertices`` | ``PrimitiveCountNV numPrimitives`` |
  2629. | | | |
  2630. | ``(Mesh shader)`` | ``numPrimitives`` | |
  2631. +---------------------------+--------------------+-----------------------------------------+
  2632. | ``DispatchMesh`` | ``ThreadX`` | ``OpControlBarrier`` |
  2633. | | | |
  2634. | ``(Amplification shader)``| ``ThreadY`` | ``TaskCountNV ThreadX*ThreadY*ThreadZ`` |
  2635. | | | |
  2636. | | ``ThreadZ`` | |
  2637. | | | |
  2638. | | ``MeshPayload`` | |
  2639. +---------------------------+--------------------+-----------------------------------------+
  2640. | Note : For ``DispatchMesh`` intrinsic, we also emit ``MeshPayload`` as output block with ``PerTaskNV`` decoration
  2641. Mesh Interface Variables
  2642. ~~~~~~~~~~~~~~~~~~~~~~~~
  2643. | Interface variables are defined for Mesh shaders using HLSL modifiers.
  2644. | Following table gives high level overview of the mapping:
  2645. |
  2646. .. table:: Mapping from HLSL modifiers to SPIR-V definitions
  2647. +-----------------+-------------------------------------------------------------------------+
  2648. | HLSL modifier | SPIR-V definition |
  2649. +=================+=========================================================================+
  2650. | ``indices`` | Maps to SPIR-V intrinsic ``PrimitiveIndicesNV`` |
  2651. | | |
  2652. | | Defines SPIR-V Execution Mode ``OutputPrimitivesNV <array-size>`` |
  2653. +-----------------+-------------------------------------------------------------------------+
  2654. | ``vertices`` | Maps to per-vertex out attributes |
  2655. | | |
  2656. | | Defines existing SPIR-V Execution Mode ``OutputVertices <array-size>`` |
  2657. +-----------------+-------------------------------------------------------------------------+
  2658. | ``primitives`` | Maps to per-primitive out attributes with ``PerPrimitiveNV`` decoration |
  2659. +-----------------+-------------------------------------------------------------------------+
  2660. | ``payload`` | Maps to per-task in attributes with ``PerTaskNV`` decoration |
  2661. +-----------------+-------------------------------------------------------------------------+
  2662. Raytracing in Vulkan and SPIRV
  2663. ==============================
  2664. | SPIR-V codegen is currently supported for NVIDIA platforms via SPV_NV_ray_tracing extension or
  2665. | on other platforms via provisional cross vendor SPV_KHR_ray_tracing extension.
  2666. | SPIR-V specification for reference:
  2667. | https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/NV/SPV_NV_ray_tracing.asciidoc
  2668. | https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_ray_tracing.asciidoc
  2669. | Vulkan ray tracing samples:
  2670. | https://developer.nvidia.com/rtx/raytracing/vkray
  2671. Raytracing Mapping to SPIR-V
  2672. ----------------------------
  2673. Intrinsics
  2674. ~~~~~~~~~~
  2675. | Following table provides mapping for system value intrinsics along with supported shader stages.
  2676. ============================ =============================== ====== ============ =========== ======= ======== ========
  2677. HLSL SPIR-V HLSL Shader Stage
  2678. ---------------------------- ------------------------------- ---------------------------------------------------------
  2679. System Value Intrinsic Builtin Raygen Intersection Closest Hit Any Hit Miss Callable
  2680. ============================ =============================== ====== ============ =========== ======= ======== ========
  2681. ``DispatchRaysIndex()`` ``LaunchId{NV/KHR}`` ✓ ✓ ✓ ✓ ✓ ✓
  2682. ``DispatchRaysDimensions()`` ``LaunchSize{NV/KHR}`` ✓ ✓ ✓ ✓ ✓ ✓
  2683. ``WorldRayOrigin()`` ``WorldRayOrigin{NV/KHR}`` ✓ ✓ ✓ ✓
  2684. ``WorldRayDirection()`` ``WorldRayDirection{NV/KHR}`` ✓ ✓ ✓ ✓
  2685. ``RayTMin()`` ``RayTmin{NV/KHR}`` ✓ ✓ ✓ ✓
  2686. ``RayTCurrent()`` ``HitT{NV/KHR}`` ✓ ✓ ✓ ✓
  2687. ``RayFlags()`` ``IncomingRayFlags{NV/KHR}`` ✓ ✓ ✓ ✓
  2688. ``InstanceIndex()`` ``InstanceId`` ✓ ✓ ✓
  2689. ``GeometryIndex()`` ``RayGeometryIndexKHR`` ✓ ✓ ✓
  2690. ``InstanceID()`` ``InstanceCustomIndex{NV/KHR}`` ✓ ✓ ✓
  2691. ``PrimitiveIndex()`` ``PrimitiveId`` ✓ ✓ ✓
  2692. ``ObjectRayOrigin()`` ``ObjectRayOrigin{NV/KHR}`` ✓ ✓ ✓
  2693. ``ObjectRayDirection()`` ``ObjectRayDirection{NV/KHR}`` ✓ ✓ ✓
  2694. ``ObjectToWorld3x4()`` ``ObjectToWorld{NV/KHR}`` ✓ ✓ ✓
  2695. ``ObjectToWorld4x3()`` ``ObjectToWorld{NV/KHR}`` ✓ ✓ ✓
  2696. ``WorldToObject3x4()`` ``WorldToObject{NV/KHR}`` ✓ ✓ ✓
  2697. ``WorldToObject4x3()`` ``WorldToObject{NV/KHR}`` ✓ ✓ ✓
  2698. ``HitKind()`` ``HitKind{NV/KHR}`` ✓ ✓ ✓
  2699. ============================ =============================== ====== ============ =========== ======= ======== ========
  2700. | *There is no separate builtin for transposed matrices ObjectToWorld3x4 and WorldToObject3x4 in SPIR-V hence we internally transpose during translation*
  2701. | *GeometryIndex() is only supported under SPV_KHR_ray_tracing extension.*
  2702. | Following table provides mapping for other intrinsics along with supported shader stages.
  2703. =========================== ================================= ====== ============ =========== ======= ===== ========
  2704. HLSL SPIR-V HLSL Shader Stage
  2705. --------------------------- --------------------------------- ------------------------------------------------------
  2706. Intrinsic Opcode Raygen Intersection Closest Hit Any Hit Miss Callable
  2707. =========================== ================================= ====== ============ =========== ======= ===== ========
  2708. ``TraceRay`` ``OpTrace{NV/KHR}`` ✓ ✓ ✓
  2709. ``ReportHit`` ``OpReportIntersection{NV/KHR}`` ✓ ✓
  2710. ``IgnoreHit`` ``OpIgnoreIntersection{NV/KHR}`` ✓ ✓
  2711. ``AcceptHitAndEndSearch`` ``OpTerminateRay{NV/KHR}`` ✓ ✓
  2712. ``CallShader`` ``OpExecuteCallable{NV/KHR}`` ✓ ✓ ✓ ✓
  2713. =========================== ================================= ====== ============ =========== ======= ===== ========
  2714. Resource Types
  2715. ~~~~~~~~~~~~~~
  2716. | Following table provides mapping for new resource types supported in all raytracing shaders.
  2717. =================================== =======================================
  2718. HLSL Type SPIR-V Opcode
  2719. ----------------------------------- ---------------------------------------
  2720. ``RaytracingAccelerationStructure`` ``OpTypeAccelerationStructure{NV/KHR}``
  2721. =================================== =======================================
  2722. Interface Variables
  2723. ~~~~~~~~~~~~~~~~~~~
  2724. | Interface variables are created for various ray tracing storage classes based on intrinsic/shader stage
  2725. | Following table gives high level overview of the mapping.
  2726. ================================= ===========================================================
  2727. SPIR-V Storage Class Created For
  2728. --------------------------------- -----------------------------------------------------------
  2729. ``RayPayload{NV/KHR}`` Last argument to TraceRay
  2730. ``IncomingRayPayload{NV/KHR}`` First argument of entry for AnyHit/ClosestHit & Miss stage
  2731. ``HitAttribute{NV/KHR}`` Last argument to ReportHit
  2732. ``CallableData{NV/KHR}`` Last argument to CallShader
  2733. ``IncomingCallableData{NV/KHR}`` First argument of entry for Callable stage
  2734. ================================= ===========================================================
  2735. RayQuery
  2736. --------
  2737. Ray Query is subfeature of the DirectX ray tracing and belongs to the DirectX ray tracing spec 1.1 (DXR 1.1).
  2738. DirectX add RayQuery object type and its member TraceRayInline() to do the TraceRay() that doesn't
  2739. use any seperate ray-tracing shader stages.
  2740. Shaders can instantiate RayQuery objects as local variables, the RayQuery object acts as a state
  2741. machine for ray query. The shader interacts with the RayQuery object's methods to advance the
  2742. query through an acceleration structure and query traversal information
  2743. Refer to following pages for details:
  2744. https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html
  2745. A flow chart for a simple ray query process
  2746. ::
  2747. +------------------------------+
  2748. | RayQuery<RAY_FLAG_NONE> q |
  2749. +------------------------------+
  2750. |
  2751. V
  2752. +------------------------------+
  2753. | q.TraceRayInline() |
  2754. +------------------------------+
  2755. | — — — — — — — — — — — — —
  2756. | | |
  2757. | | +------------------------+
  2758. | | | Your intersection code |
  2759. | | +------------------------+
  2760. | | ^
  2761. V V |
  2762. +------------------------------+ +---------------------+
  2763. | q.Proceed() // AS traversal | | q.CandidateType() |
  2764. +------------------------------+ +---------------------+
  2765. | | ^
  2766. No | | Yes |
  2767. | |_ _ _ _ _ _ _ _ _ _ _ _|
  2768. V
  2769. +------------------------------+
  2770. | q.CommittedStatus() |
  2771. +------------------------------+
  2772. |
  2773. V
  2774. +----------------------------------+
  2775. | Your Intersection/shader code |
  2776. +----------------------------------+
  2777. Example:
  2778. .. code:: hlsl
  2779. void main() {
  2780. RayQuery<RAY_FLAG_CULL_NON_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;
  2781. q.TraceRayInline(myAccelerationStructure, 0 , 0xff, myRay);
  2782. // Proceed() is AccelerationStructure traversal loop take places
  2783. while(q.Proceed()) {
  2784. switch(q.CandidateType()) {
  2785. // retrieve intersection information/Do the shadering
  2786. }
  2787. }
  2788. // AccelerationStructure traversal end
  2789. // Get the Committed status
  2790. switch(q.CommittedStatus()) {
  2791. // retrieve intersection information/ Do the shadering
  2792. }
  2793. }
  2794. Ray Query in SPIRV
  2795. ~~~~~~~~~~~~~~~~~~
  2796. RayQuery SPIR-V codegen is currently supported via SPV_KHR_ray_query extension
  2797. SPIR-V specification for reference:
  2798. https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_ray_query.asciidoc
  2799. Object Type
  2800. ~~~~~~~~~~~
  2801. RayQuery<RAY_FLAGS>
  2802. RayQuery represents the state of an inline ray tracing call into an acceleration structure.
  2803. ============ ================================
  2804. HLSL Type SPIR-V Opcode
  2805. ------------ --------------------------------
  2806. ``RayQuery`` ``OpTypeRayQueryKHR``
  2807. ============ ================================
  2808. RayQuery Mapping to SPIR-V
  2809. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2810. +---------------------------------------------------+-------------------------------------------------------------------------+
  2811. | HLSL RayQuery member Intrinsic | SPIR-V Opcode |
  2812. +===================================================+=========================================================================+
  2813. |``.Abort`` | ``OpRayQueryTerminateKHR`` |
  2814. +---------------------------------------------------+-------------------------------------------------------------------------+
  2815. |``.CandidateType`` | ``OpRayQueryGetIntersectionTypeKHR`` |
  2816. +---------------------------------------------------+-------------------------------------------------------------------------+
  2817. |``.CandidateProceduralPrimitiveNonOpaque`` | ``OpRayQueryGetIntersectionCandidateAABBOpaqueKHR`` |
  2818. +---------------------------------------------------+-------------------------------------------------------------------------+
  2819. |``.CandidateInstanceIndex`` | ``OpRayQueryGetIntersectionInstanceIdKHR`` |
  2820. +---------------------------------------------------+-------------------------------------------------------------------------+
  2821. |``.CandidateInstanceID`` | ``OpRayQueryGetIntersectionInstanceCustomIndexKHR`` |
  2822. +---------------------------------------------------+-------------------------------------------------------------------------+
  2823. | ``.CandidateInstanceContributionToHitGroupIndex`` | ``OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR`` |
  2824. +---------------------------------------------------+-------------------------------------------------------------------------+
  2825. |``.CandidateGeometryIndex`` | ``OpRayQueryGetIntersectionGeometryIndexKHR`` |
  2826. +---------------------------------------------------+-------------------------------------------------------------------------+
  2827. |``.CandidatePrimitiveIndex`` | ``OpRayQueryGetIntersectionPrimitiveIndexKHR`` |
  2828. +---------------------------------------------------+-------------------------------------------------------------------------+
  2829. |``.CandidateObjectRayOrigin`` | ``OpRayQueryGetIntersectionObjectRayOriginKHR`` |
  2830. +---------------------------------------------------+-------------------------------------------------------------------------+
  2831. |``.CandidateObjectRayDirection`` | ``OpRayQueryGetIntersectionObjectRayDirectionKHR`` |
  2832. +---------------------------------------------------+-------------------------------------------------------------------------+
  2833. |``.CandidateObjectToWorld3x4`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` |
  2834. +---------------------------------------------------+-------------------------------------------------------------------------+
  2835. |``.CandidateObjectToWorld4x3`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` |
  2836. +---------------------------------------------------+-------------------------------------------------------------------------+
  2837. |``.CandidateWorldToObject3x4`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` |
  2838. +---------------------------------------------------+-------------------------------------------------------------------------+
  2839. |``.CandidateWorldToObject4x3`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` |
  2840. +---------------------------------------------------+-------------------------------------------------------------------------+
  2841. |``.CandidateTriangleBarycentrics`` | ``OpRayQueryGetIntersectionBarycentricsKHR`` |
  2842. +---------------------------------------------------+-------------------------------------------------------------------------+
  2843. |``.CandidateTriangleFrontFace`` | ``OpRayQueryGetIntersectionFrontFaceKHR`` |
  2844. +---------------------------------------------------+-------------------------------------------------------------------------+
  2845. |``.CommittedStatus`` | ``OpRayQueryGetIntersectionTypeKHR`` |
  2846. +---------------------------------------------------+-------------------------------------------------------------------------+
  2847. |``.CommittedInstanceIndex`` | ``OpRayQueryGetIntersectionInstanceIdKHR`` |
  2848. +---------------------------------------------------+-------------------------------------------------------------------------+
  2849. |``.CommittedInstanceID`` | ``OpRayQueryGetIntersectionInstanceCustomIndexKHR`` |
  2850. +---------------------------------------------------+-------------------------------------------------------------------------+
  2851. | ``.CommittedInstanceContributionToHitGroupIndex`` | ``OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR`` |
  2852. +---------------------------------------------------+-------------------------------------------------------------------------+
  2853. |``.CommittedGeometryIndex`` | ``OpRayQueryGetIntersectionGeometryIndexKHR`` |
  2854. +---------------------------------------------------+-------------------------------------------------------------------------+
  2855. |``.CommittedPrimitiveIndex`` | ``OpRayQueryGetIntersectionPrimitiveIndexKHR`` |
  2856. +---------------------------------------------------+-------------------------------------------------------------------------+
  2857. |``.CommittedRayT`` | ``OpRayQueryGetIntersectionTKHR`` |
  2858. +---------------------------------------------------+-------------------------------------------------------------------------+
  2859. |``.CommittedObjectRayOrigin`` | ``OpRayQueryGetIntersectionObjectRayOriginKHR`` |
  2860. +---------------------------------------------------+-------------------------------------------------------------------------+
  2861. |``.CommittedObjectRayDirection`` | ``OpRayQueryGetIntersectionObjectRayDirectionKHR`` |
  2862. +---------------------------------------------------+-------------------------------------------------------------------------+
  2863. |``.CommittedObjectToWorld3x4`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` |
  2864. +---------------------------------------------------+-------------------------------------------------------------------------+
  2865. |``.CommittedObjectToWorld4x3`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` |
  2866. +---------------------------------------------------+-------------------------------------------------------------------------+
  2867. |``.CommittedWorldToObject3x4`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` |
  2868. +---------------------------------------------------+-------------------------------------------------------------------------+
  2869. |``.CommittedWorldToObject4x3`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` |
  2870. +---------------------------------------------------+-------------------------------------------------------------------------+
  2871. |``.CommittedTriangleBarycentrics`` | ``OpRayQueryGetIntersectionBarycentricsKHR`` |
  2872. +---------------------------------------------------+-------------------------------------------------------------------------+
  2873. |``.CommittedTriangleFrontFace`` | ``OpRayQueryGetIntersectionFrontFaceKHR`` |
  2874. +---------------------------------------------------+-------------------------------------------------------------------------+
  2875. |``.CommitNonOpaqueTriangleHit`` | ``OpRayQueryConfirmIntersectionKHR`` |
  2876. +---------------------------------------------------+-------------------------------------------------------------------------+
  2877. |``.CommitProceduralPrimitiveHit`` | ``OpRayQueryGenerateIntersectionKHR`` |
  2878. +---------------------------------------------------+-------------------------------------------------------------------------+
  2879. |``.Proceed`` | ``OpRayQueryProceedKHR`` |
  2880. +---------------------------------------------------+-------------------------------------------------------------------------+
  2881. |``.RayFlags`` | ``OpRayQueryGetRayFlagsKHR`` |
  2882. +---------------------------------------------------+-------------------------------------------------------------------------+
  2883. |``.RayTMin`` | ``OpRayQueryGetRayTMinKHR`` |
  2884. +---------------------------------------------------+-------------------------------------------------------------------------+
  2885. |``.TraceRayInline`` | ``OpRayQueryInitializeKHR`` |
  2886. +---------------------------------------------------+-------------------------------------------------------------------------+
  2887. |``.WorldRayDirection`` | ``OpRayQueryGetWorldRayDirectionKHR`` |
  2888. +---------------------------------------------------+-------------------------------------------------------------------------+
  2889. |``.WorldRayOrigin` | ``OpRayQueryGetWorldRayOriginKHR`` |
  2890. +---------------------------------------------------+-------------------------------------------------------------------------+
  2891. Shader Model 6.0 Wave Intrinsics
  2892. ================================
  2893. Note that Wave intrinsics requires SPIR-V 1.3, which is supported by Vulkan 1.1.
  2894. If you use wave intrinsics in your source code, you will need to specify
  2895. -fspv-target-env=vulkan1.1 via the command line to target Vulkan 1.1.
  2896. Shader model 6.0 introduces a set of wave operations. Apart from
  2897. ``WaveGetLaneCount()`` and ``WaveGetLaneIndex()``, which are translated into
  2898. loading from SPIR-V builtin variable ``SubgroupSize`` and
  2899. ``SubgroupLocalInvocationId`` respectively, the rest are translated into SPIR-V
  2900. group operations with ``Subgroup`` scope according to the following chart:
  2901. ============= ============================ =================================== ======================
  2902. Wave Category Wave Intrinsics SPIR-V Opcode SPIR-V Group Operation
  2903. ============= ============================ =================================== ======================
  2904. Query ``WaveIsFirstLane()`` ``OpGroupNonUniformElect``
  2905. Vote ``WaveActiveAnyTrue()`` ``OpGroupNonUniformAny``
  2906. Vote ``WaveActiveAllTrue()`` ``OpGroupNonUniformAll``
  2907. Vote ``WaveActiveBallot()`` ``OpGroupNonUniformBallot``
  2908. Reduction ``WaveActiveAllEqual()`` ``OpGroupNonUniformAllEqual`` ``Reduction``
  2909. Reduction ``WaveActiveCountBits()`` ``OpGroupNonUniformBallotBitCount`` ``Reduction``
  2910. Reduction ``WaveActiveSum()`` ``OpGroupNonUniform*Add`` ``Reduction``
  2911. Reduction ``WaveActiveProduct()`` ``OpGroupNonUniform*Mul`` ``Reduction``
  2912. Reduction ``WaveActiveBitAdd()`` ``OpGroupNonUniformBitwiseAnd`` ``Reduction``
  2913. Reduction ``WaveActiveBitOr()`` ``OpGroupNonUniformBitwiseOr`` ``Reduction``
  2914. Reduction ``WaveActiveBitXor()`` ``OpGroupNonUniformBitwiseXor`` ``Reduction``
  2915. Reduction ``WaveActiveMin()`` ``OpGroupNonUniform*Min`` ``Reduction``
  2916. Reduction ``WaveActiveMax()`` ``OpGroupNonUniform*Max`` ``Reduction``
  2917. Scan/Prefix ``WavePrefixSum()`` ``OpGroupNonUniform*Add`` ``ExclusiveScan``
  2918. Scan/Prefix ``WavePrefixProduct()`` ``OpGroupNonUniform*Mul`` ``ExclusiveScan``
  2919. Scan/Prefix ``WavePrefixCountBits()`` ``OpGroupNonUniformBallotBitCount`` ``ExclusiveScan``
  2920. Broadcast ``WaveReadLaneAt()`` ``OpGroupNonUniformBroadcast``
  2921. Broadcast ``WaveReadLaneFirst()`` ``OpGroupNonUniformBroadcastFirst``
  2922. Quad ``QuadReadAcrossX()`` ``OpGroupNonUniformQuadSwap``
  2923. Quad ``QuadReadAcrossY()`` ``OpGroupNonUniformQuadSwap``
  2924. Quad ``QuadReadAcrossDiagonal()`` ``OpGroupNonUniformQuadSwap``
  2925. Quad ``QuadReadLaneAt()`` ``OpGroupNonUniformQuadBroadcast``
  2926. ============= ============================ =================================== ======================
  2927. The Implicit ``vk`` Namespace
  2928. =============================
  2929. Overview
  2930. --------
  2931. We have introduced an implicit namepace (called ``vk``) that will be home to all
  2932. Vulkan-specific functions, enums, etc. Given the similarity between HLSL and
  2933. C++, developers are likely familiar with namespaces -- and implicit namespaces
  2934. (e.g. ``std::`` in C++). The ``vk`` namespace provides an interface for expressing
  2935. Vulkan-specific features (core spec and KHR extensions).
  2936. **The compiler will generate the proper error message (** ``unknown 'vk' identifier`` **)
  2937. if** ``vk::`` **is used for compiling to DXIL.**
  2938. Any intrinsic function or enum in the vk namespace will be deprecated if an
  2939. equivalent one is added to the default namepsace.
  2940. Current Features
  2941. ----------------
  2942. The following intrinsic functions and constants are currently defined in the
  2943. implicit ``vk`` namepsace.
  2944. .. code:: hlsl
  2945. // Implicitly defined when compiling to SPIR-V.
  2946. namespace vk {
  2947. const uint CrossDeviceScope = 0;
  2948. const uint DeviceScope = 1;
  2949. const uint WorkgroupScope = 2;
  2950. const uint SubgroupScope = 3;
  2951. const uint InvocationScope = 4;
  2952. const uint QueueFamilyScope = 5;
  2953. uint64_t ReadClock(in uint scope);
  2954. } // end namespace
  2955. Intrinsic Constants
  2956. -------------------
  2957. The following constants are currently defined:
  2958. ======================== ============================================
  2959. Constant value (SPIR-V constant equivalent, if any)
  2960. ======================== ============================================
  2961. ``vk::CrossDeviceScope`` ``0`` (``CrossDevice``)
  2962. ``vk::DeviceScope`` ``1`` (``Device``)
  2963. ``vk::WorkgroupScope`` ``2`` (``Workgroup``)
  2964. ``vk::SubgroupScope`` ``3`` (``Subgroup``)
  2965. ``vk::InvocationScope`` ``4`` (``Invocation``)
  2966. ``vk::QueueFamilyScope`` ``5`` (``QueueFamily``)
  2967. ======================== ============================================
  2968. Intrinsic Functions
  2969. -------------------
  2970. ReadClock
  2971. ~~~~~~~~~
  2972. This intrinsic funcion has the following signature:
  2973. .. code:: hlsl
  2974. uint64_t ReadClock(in uint scope);
  2975. It translates to performing ``OpReadClockKHR`` defined in `VK_KHR_shader_clock <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_shader_clock.html>`_.
  2976. One can use the predefined scopes in the ``vk`` namepsace to specify the scope argument.
  2977. For example:
  2978. .. code:: hlsl
  2979. uint64_t clock = vk::ReadClock(vk::SubgroupScope);
  2980. Supported Command-line Options
  2981. ==============================
  2982. Command-line options supported by SPIR-V CodeGen are listed below. They are
  2983. also recognized by the library API calls.
  2984. General options
  2985. ---------------
  2986. - ``-T``: specifies shader profile
  2987. - ``-E``: specifies entry point
  2988. - ``-D``: Defines macro
  2989. - ``-I``: Adds directory to include search path
  2990. - ``-O{|0|1|2|3}``: Specifies optimization level
  2991. - ``-enable-16bit-types``: enables 16-bit types and disables min precision types
  2992. - ``-Zpc``: Packs matrices in column-major order by deafult
  2993. - ``-Zpr``: Packs matrices in row-major order by deafult
  2994. - ``-Fc``: outputs SPIR-V disassembly to the given file
  2995. - ``-Fe``: outputs warnings and errors to the given file
  2996. - ``-Fo``: outputs SPIR-V code to the given file
  2997. - ``-Fh``: outputs SPIR-V code as a header file
  2998. - ``-Vn``: specifies the variable name for SPIR-V code in generated header file
  2999. - ``-Zi``: Emits more debug information (see `Debugging`_)
  3000. - ``-Cc``: colorizes SPIR-V disassembly
  3001. - ``-No``: adds instruction byte offsets to SPIR-V disassembly
  3002. - ``-H``: Shows header includes and nesting depth
  3003. - ``-Vi``: Shows details about the include process
  3004. - ``-Vd``: Disables SPIR-V verification
  3005. - ``-WX``: Treats warnings as errors
  3006. - ``-no-warnings``: Suppresses all warnings
  3007. - ``-flegacy-macro-expansion``: expands the operands before performing
  3008. token-pasting operation (fxc behavior)
  3009. Vulkan-specific options
  3010. -----------------------
  3011. The following command line options are added into ``dxc`` to support SPIR-V
  3012. codegen for Vulkan:
  3013. - ``-spirv``: Generates SPIR-V code.
  3014. - ``-fvk-b-shift N M``: Shifts by ``N`` the inferred binding numbers for all
  3015. resources in b-type registers of space ``M``. Specifically, for a resouce
  3016. attached with ``:register(bX, spaceM)`` but not ``[vk::binding(...)]``,
  3017. sets its Vulkan descriptor set to ``M`` and binding number to ``X + N``. If
  3018. you need to shift the inferred binding numbers for more than one space,
  3019. provide more than one such option. If more than one such option is provided
  3020. for the same space, the last one takes effect. If you need to shift the
  3021. inferred binding numbers for all sets, use ``all`` as ``M``.
  3022. See `HLSL register and Vulkan binding`_ for explanation and examples.
  3023. - ``-fvk-t-shift N M``, similar to ``-fvk-b-shift``, but for t-type registers.
  3024. - ``-fvk-s-shift N M``, similar to ``-fvk-b-shift``, but for s-type registers.
  3025. - ``-fvk-u-shift N M``, similar to ``-fvk-b-shift``, but for u-type registers.
  3026. - ``-fvk-auto-shift-bindings``: Automatically detects the register type for
  3027. resources that are missing the ``:register`` assignment, so the above shifts
  3028. can be applied to them if needed.
  3029. - ``-fvk-bind-register xX Y N M`` (short alias: ``-vkbr``): Binds the resouce
  3030. at ``register(xX, spaceY)`` to descriptor set ``M`` and binding ``N``. This
  3031. option cannot be used together with other binding assignment options.
  3032. It requires all source code resources have ``:register()`` attribute and
  3033. all registers have corresponding Vulkan descriptors specified using this
  3034. option.
  3035. - ``-fvk-bind-globals N M``: Places the ``$Globals`` cbuffer at
  3036. descriptor set #M and binding #N. See `HLSL global variables and Vulkan binding`_
  3037. for explanation and examples.
  3038. - ``-fvk-use-gl-layout``: Uses strict OpenGL ``std140``/``std430``
  3039. layout rules for resources.
  3040. - ``-fvk-use-dx-layout``: Uses DirectX layout rules for resources.
  3041. - ``-fvk-invert-y``: Negates (additively inverts) SV_Position.y before writing
  3042. to stage output. Used to accommodate the difference between Vulkan's
  3043. coordinate system and DirectX's. Only allowed in VS/DS/GS.
  3044. - ``-fvk-use-dx-position-w``: Reciprocates (multiplicatively inverts)
  3045. SV_Position.w after reading from stage input. Used to accommodate the
  3046. difference between Vulkan DirectX: the w component of SV_Position in PS is
  3047. stored as 1/w in Vulkan. Only recognized in PS; applying to other stages
  3048. is no-op.
  3049. - ``-fvk-stage-io-order={alpha|decl}``: Assigns the stage input/output variable
  3050. location number according to alphabetical order or declaration order. See
  3051. `HLSL semantic and Vulkan Location`_ for more details.
  3052. - ``-fspv-reflect``: Emits additional SPIR-V instructions to aid reflection.
  3053. - ``-fspv-debug=<category>``: Controls what category of debug information
  3054. should be emitted. Accepted values are ``file``, ``source``, ``line``, and
  3055. ``tool``. See `Debugging`_ for more details.
  3056. - ``-fspv-extension=<extension>``: Only allows using ``<extension>`` in CodeGen.
  3057. If you want to allow multiple extensions, provide more than one such option. If you
  3058. want to allow *all* KHR extensions, use ``-fspv-extension=KHR``.
  3059. - ``-fspv-target-env=<env>``: Specifies the target environment for this compilation.
  3060. The current valid options are ``vulkan1.0`` and ``vulkan1.1``. If no target
  3061. environment is provided, ``vulkan1.0`` is used as default.
  3062. - ``-fspv-flatten-resource-arrays``: Flattens arrays of textures and samplers
  3063. into individual resources, each taking one binding number. For example, an
  3064. array of 3 textures will become 3 texture resources taking 3 binding numbers.
  3065. This makes the behavior similar to DX. Without this option, you would get 1
  3066. array object taking 1 binding number. Note that arrays of
  3067. {RW|Append|Consume}StructuredBuffers are currently not supported in the
  3068. SPIR-V backend. Also note that this requires the optimizer to be able to
  3069. resolve all array accesses with constant indeces. Therefore, all loops using
  3070. the resource arrays must be marked with ``[unroll]``.
  3071. - ``-Wno-vk-ignored-features``: Does not emit warnings on ignored features
  3072. resulting from no Vulkan support, e.g., cbuffer member initializer.
  3073. Unsupported HLSL Features
  3074. =========================
  3075. The following HLSL language features are not supported in SPIR-V codegen,
  3076. either because of no Vulkan equivalents at the moment, or because of deprecation.
  3077. * Literal/immediate sampler state: deprecated feature. The compiler will
  3078. emit a warning and ignore it.
  3079. * ``abort()`` intrinsic function: no Vulkan equivalent. The compiler will emit
  3080. an error.
  3081. * ``GetRenderTargetSampleCount()`` intrinsic function: no Vulkan equivalent.
  3082. (Its GLSL counterpart is ``gl_NumSamples``, which is not available in GLSL for
  3083. Vulkan.) The compiler will emit an error.
  3084. * ``GetRenderTargetSamplePosition()`` intrinsic function: no Vulkan equivalent.
  3085. (``gl_SamplePosition`` provides similar functionality but it's only for the
  3086. sample currently being processed.) The compiler will emit an error.
  3087. * ``tex*()`` intrinsic functions: deprecated features. The compiler will
  3088. emit errors.
  3089. * ``.GatherCmpGreen()``, ``.GatherCmpBlue()``, ``.GatherCmpAlpha()`` intrinsic
  3090. method: no Vulkan equivalent. (SPIR-V ``OpImageDrefGather`` instruction does
  3091. not take component as input.) The compiler will emit an error.
  3092. * Since ``StructuredBuffer``, ``RWStructuredBuffer``, ``ByteAddressBuffer``, and
  3093. ``RWByteAddressBuffer`` are not represented as image types in SPIR-V, using the
  3094. output unsigned integer ``status`` argument in their ``Load*`` methods is not
  3095. supported. Using these methods with the ``status`` argument will cause a compiler error.
  3096. * Applying ``row_major`` or ``column_major`` attributes to a stand-alone matrix will be
  3097. ignored by the compiler because ``RowMajor`` and ``ColMajor`` decorations in SPIR-V are
  3098. only allowed to be applied to members of structures. A warning will be issued by the compiler.
  3099. * The Hull shader ``partitioning`` attribute may not have the ``pow2`` value. The compiler
  3100. will emit an error. Other attribute values are supported and described in the
  3101. `Hull Entry Point Attributes`_ section.
  3102. * ``cbuffer``/``tbuffer`` member initializer: no Vulkan equivalent. The compiler
  3103. will emit an warning and ignore it.
  3104. Appendix
  3105. ==========
  3106. Appendix A. Matrix Representation
  3107. ---------------------------------
  3108. Consider a matrix in HLSL defined as ``float2x3 m;``. Conceptually, this is a matrix with 2 rows and 3 columns.
  3109. This means that you can access its elements via expressions such as ``m[i][j]``, where ``i`` can be ``{0, 1}`` and ``j`` can be ``{0, 1, 2}``.
  3110. Now let's look how matrices are defined in SPIR-V:
  3111. .. code:: spirv
  3112. %columnType = OpTypeVector %float <number of rows>
  3113. %matType = OpTypeMatrix %columnType <number of columns>
  3114. As you can see, SPIR-V conceptually represents matrices as a collection of vectors where each vector is a *column*.
  3115. Now, let's represent our float2x3 matrix in SPIR-V. If we choose a naive translation (3 columns, each of which is a vector of size 2), we get:
  3116. .. code:: spirv
  3117. %v2float = OpTypeVector %float 2
  3118. %mat3v2float = OpTypeMatrix %v2float 3
  3119. Now, let's use this naive translation to access into the matrix (e.g. ``m[0][2]``). This is evaluated by first finding ``n = m[0]``, and then finding ``n[2]``.
  3120. Notice that in HLSL, ``m[0]`` represents a row, which is a vector of size 3. But accessing the first dimension of the SPIR-V matrix give us
  3121. the first column which is a vector of size 2.
  3122. .. code:: spirv
  3123. ; n is a vector of size 2
  3124. %n = OpAccessChain %v2float %m %int_0
  3125. Notice that in HLSL access ``m[i][j]``, ``i`` can be ``{0, 1}`` and ``j`` can be ``{0, 1, 2}``.
  3126. But in SPIR-V OpAccessChain access, the first index (``i``) can be ``{0, 1, 2}`` and the second index (``j``) can be ``{1, 0}``.
  3127. Therefore, the naive translation does not work well with indexing.
  3128. As a result, we must translate a given HLSL float2x3 matrix (with 2 rows and 3 columns) as a SPIR-V matrix with 3 rows and 2 columns:
  3129. .. code:: spirv
  3130. %v3float = OpTypeVector %float 3
  3131. %mat2v3float = OpTypeMatrix %v3float 2
  3132. This way, all accesses into the matrix can be naturally handled correctly.
  3133. Packing
  3134. ~~~~~~~
  3135. The HLSL ``row_major`` and ``column_major`` type modifiers change the way packing is done.
  3136. The following table provides an example which should make our translation more clear:
  3137. +------------------+---------------------------+---------------------------+-----------------------------+-------------------+
  3138. | Host CPU Data | HLSL Variable | GPU (HLSL Representation) | GPU (SPIR-V Representation) | SPIR-V Decoration |
  3139. +==================+===========================+===========================+=============================+===================+
  3140. |``{1,2,3,4,5,6}`` | ``float2x3`` | ``[1 3 5]`` | ``[1 2]`` | |
  3141. | | | | | |
  3142. | | | ``[2 4 6]`` | ``[3 4]`` | ``RowMajor`` |
  3143. | | | | | |
  3144. | | | | ``[5 6]`` | |
  3145. +------------------+---------------------------+---------------------------+-----------------------------+-------------------+
  3146. |``{1,2,3,4,5,6}`` | ``column_major float2x3`` | ``[1 3 5]`` | ``[1 2]`` | |
  3147. | | | | | |
  3148. | | | ``[2 4 6]`` | ``[3 4]`` | ``RowMajor`` |
  3149. | | | | | |
  3150. | | | | ``[5 6]`` | |
  3151. +------------------+---------------------------+---------------------------+-----------------------------+-------------------+
  3152. |``{1,2,3,4,5,6}`` | ``row_major float2x3`` | ``[1 2 3]`` | ``[1 4]`` | |
  3153. | | | | | |
  3154. | | | ``[4 5 6]`` | ``[2 5]`` | ``ColMajor`` |
  3155. | | | | | |
  3156. | | | | ``[3 6]`` | |
  3157. +------------------+---------------------------+---------------------------+-----------------------------+-------------------+