|  | ==================== | 
|  | HLSL Entry Functions | 
|  | ==================== | 
|  |  | 
|  | .. contents:: | 
|  | :local: | 
|  |  | 
|  | Usage | 
|  | ===== | 
|  |  | 
|  | In HLSL, entry functions denote the starting point for shader execution. They | 
|  | must be known at compile time. For all non-library shaders, the compiler assumes | 
|  | the default entry function name ``main``, unless the DXC ``/E`` option is | 
|  | provided to specify an alternate entry point. For library shaders entry points | 
|  | are denoted using the ``[shader(...)]`` attribute. | 
|  |  | 
|  | All scalar parameters to entry functions must have semantic annotations, and all | 
|  | struct parameters must have semantic annotations on every field in the struct | 
|  | declaration. Additionally if the entry function has a return type, a semantic | 
|  | annotation must be provided for the return type as well. | 
|  |  | 
|  | HLSL entry functions can be called from other parts of the shader, which has | 
|  | implications on code generation. | 
|  |  | 
|  | Implementation Details | 
|  | ====================== | 
|  |  | 
|  | In Clang, the DXC ``/E`` option is translated to the cc1 flag ``-hlsl-entry``, | 
|  | which in turn applies the ``HLSLShader`` attribute to the function with the | 
|  | specified name. This allows code generation for entry functions to always key | 
|  | off the presence of the ``HLSLShader`` attribute, regardless of what shader | 
|  | profile you are compiling. | 
|  |  | 
|  | In code generation, two functions are generated. One is the user defined | 
|  | function, which is code generated as a mangled C++ function with internal | 
|  | linkage following normal function code generation. | 
|  |  | 
|  | The actual exported entry function which can be called by the GPU driver is a | 
|  | ``void(void)`` function that isn't name mangled. In code generation we generate | 
|  | the unmangled entry function to serve as the actual shader entry. The shader | 
|  | entry function is annotated with the ``hlsl.shader`` function attribute | 
|  | identifying the entry's pipeline stage. | 
|  |  | 
|  | The body of the unmangled entry function contains first a call to execute global | 
|  | constructors, then instantiations of the user-defined entry parameters with | 
|  | their semantic values populated, and a call to the user-defined function. | 
|  | After the call instruction the return value (if any) is saved using a | 
|  | target-appropriate intrinsic for storing outputs (for DirectX, the | 
|  | ``llvm.dx.store.output``). Lastly, any present global destructors will be called | 
|  | immediately before the return. HLSL does not support C++ ``atexit`` | 
|  | registrations, instead calls to global destructors are compile-time generated. | 
|  |  | 
|  | .. note:: | 
|  |  | 
|  | HLSL support in Clang is currently focused on compute shaders, which do not | 
|  | support output semantics. Support for output semantics will not be | 
|  | implemented until other shader profiles are supported. | 
|  |  | 
|  | Below is example IR that represents the planned implementation, subject to | 
|  | change as the ``llvm.dx.store.output`` and ``llvm.dx.load.input`` intrinsics are | 
|  | not yet implemented. | 
|  |  | 
|  | .. code-block:: none | 
|  |  | 
|  | ; Function Attrs: norecurse | 
|  | define void @main() #1 { | 
|  | entry: | 
|  | %0 = call i32 @llvm.dx.load.input.i32(...) | 
|  | %1 = call i32 @"?main@@YAXII@Z"(i32 %0) | 
|  | call @llvm.dx.store.output.i32(%1, ...) | 
|  | ret void | 
|  | } | 
|  |  |