xref: /openbsd-src/gnu/llvm/clang/docs/HLSL/EntryFunctions.rst (revision 12c855180aad702bbcca06e0398d774beeafb155)
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