1*12c85518Srobert==================== 2*12c85518SrobertHLSL Entry Functions 3*12c85518Srobert==================== 4*12c85518Srobert 5*12c85518Srobert.. contents:: 6*12c85518Srobert :local: 7*12c85518Srobert 8*12c85518SrobertUsage 9*12c85518Srobert===== 10*12c85518Srobert 11*12c85518SrobertIn HLSL, entry functions denote the starting point for shader execution. They 12*12c85518Srobertmust be known at compile time. For all non-library shaders, the compiler assumes 13*12c85518Srobertthe default entry function name ``main``, unless the DXC ``/E`` option is 14*12c85518Srobertprovided to specify an alternate entry point. For library shaders entry points 15*12c85518Srobertare denoted using the ``[shader(...)]`` attribute. 16*12c85518Srobert 17*12c85518SrobertAll scalar parameters to entry functions must have semantic annotations, and all 18*12c85518Srobertstruct parameters must have semantic annotations on every field in the struct 19*12c85518Srobertdeclaration. Additionally if the entry function has a return type, a semantic 20*12c85518Srobertannotation must be provided for the return type as well. 21*12c85518Srobert 22*12c85518SrobertHLSL entry functions can be called from other parts of the shader, which has 23*12c85518Srobertimplications on code generation. 24*12c85518Srobert 25*12c85518SrobertImplementation Details 26*12c85518Srobert====================== 27*12c85518Srobert 28*12c85518SrobertIn Clang, the DXC ``/E`` option is translated to the cc1 flag ``-hlsl-entry``, 29*12c85518Srobertwhich in turn applies the ``HLSLShader`` attribute to the function with the 30*12c85518Srobertspecified name. This allows code generation for entry functions to always key 31*12c85518Srobertoff the presence of the ``HLSLShader`` attribute, regardless of what shader 32*12c85518Srobertprofile you are compiling. 33*12c85518Srobert 34*12c85518SrobertIn code generation, two functions are generated. One is the user defined 35*12c85518Srobertfunction, which is code generated as a mangled C++ function with internal 36*12c85518Srobertlinkage following normal function code generation. 37*12c85518Srobert 38*12c85518SrobertThe actual exported entry function which can be called by the GPU driver is a 39*12c85518Srobert``void(void)`` function that isn't name mangled. In code generation we generate 40*12c85518Srobertthe unmangled entry function to serve as the actual shader entry. The shader 41*12c85518Srobertentry function is annotated with the ``hlsl.shader`` function attribute 42*12c85518Srobertidentifying the entry's pipeline stage. 43*12c85518Srobert 44*12c85518SrobertThe body of the unmangled entry function contains first a call to execute global 45*12c85518Srobertconstructors, then instantiations of the user-defined entry parameters with 46*12c85518Sroberttheir semantic values populated, and a call to the user-defined function. 47*12c85518SrobertAfter the call instruction the return value (if any) is saved using a 48*12c85518Sroberttarget-appropriate intrinsic for storing outputs (for DirectX, the 49*12c85518Srobert``llvm.dx.store.output``). Lastly, any present global destructors will be called 50*12c85518Srobertimmediately before the return. HLSL does not support C++ ``atexit`` 51*12c85518Srobertregistrations, instead calls to global destructors are compile-time generated. 52*12c85518Srobert 53*12c85518Srobert.. note:: 54*12c85518Srobert 55*12c85518Srobert HLSL support in Clang is currently focused on compute shaders, which do not 56*12c85518Srobert support output semantics. Support for output semantics will not be 57*12c85518Srobert implemented until other shader profiles are supported. 58*12c85518Srobert 59*12c85518SrobertBelow is example IR that represents the planned implementation, subject to 60*12c85518Srobertchange as the ``llvm.dx.store.output`` and ``llvm.dx.load.input`` intrinsics are 61*12c85518Srobertnot yet implemented. 62*12c85518Srobert 63*12c85518Srobert.. code-block:: none 64*12c85518Srobert 65*12c85518Srobert ; Function Attrs: norecurse 66*12c85518Srobert define void @main() #1 { 67*12c85518Srobert entry: 68*12c85518Srobert %0 = call i32 @llvm.dx.load.input.i32(...) 69*12c85518Srobert %1 = call i32 @"?main@@YAXII@Z"(i32 %0) 70*12c85518Srobert call @llvm.dx.store.output.i32(%1, ...) 71*12c85518Srobert ret void 72*12c85518Srobert } 73*12c85518Srobert 74