Closed devshgraphicsprogramming closed 1 month ago
The main reason is time and resources. Adopting a new base version of C++ isn't just flipping a switch in the compiler. It also involves updating and tweaking the design and implementation of HLSL features to adjust to the new base version. Iteratively raising the base version gives us the opportunity to review each new C++ feature, identify how they interact with HLSL and make adjustments as we go.
It is important to remember that C++ 11 was a massive feature version over C++98/03. In order to make C++11 our base we'll have dozens of new features that need to be adjusted and tweaked to work with HLSL. We'll have existing HLSL syntax that will need to be deprecated in 202x and removed in 202y (specifically HLSL's initializer lists which cannot be used under variadic template pack expansions).
Choosing to start at C++ 11 for the Clang implementation gives us a head start on resolving those issues, but also doesn't fully flood our team resolving 20 years of C++ evolution at the same time.
We are very interested in adding C++20, in particular concepts
to HLSL, and we may even add concepts
before we move the base version to C++ 20 because we're actually using them internally in the compiler implementation for Clang.
Longer term we definitely want to bring in more features from later C++ standards, however for proposal 23 the plan is to target C++11, as described above.
Which proposal does this relate to?
https://github.com/microsoft/hlsl-specs/blob/main/proposals/0023-cxx11-base.md
Describe the issue or outstanding question.
First of all, I'm a bit let down that C++20 isn't the default as we'd really appreciate the ability to use
concept
s. We do a lot of very horribleenable_if
in our HLSL codebase to achieve the equivalent.C++20 also introduces
consteval
andconstinit
which would be quite useful for the domain of GPU programming (I find myself needing to deal with consteval-like expressions a lot more in shaders than host code).Also templated lambdas are what I'd deem "the final cleanup" of changes C++14 did to lambdas https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0428r2.pdf
That being said, one can view C++14 and C++17 as very minor increments over C++11
Why C++14 ?
IIRC Metal SL was based off C++14 so its rather weird that HLSL 202y starting many years after metal would choose to use a lower C++ version as the baseline.
First of all some C++14 features are already supported by DXC, such as variable templates. We already make use of them in our
type_traits
header.Secondly, C++14 allows for far more useful
constexpr
functions which can do conditional branches and loops. This means we can actually hope for a constant evaluation of higher order mathematical functions such aserf
that we write ourselves.Lastly, Lambda expressions from C+11 aren't that useful by themselves. C++14 allows Generic Lambdas. These are awesome as they allow you to implement
if constexpr
from C++17 as a workaround (which we used before transitioning to C++17).https://github.com/Garcia6l20/if_constexpr14
Mind you that with current C++98 with 11 extensions codebase we have to implement all of our would-be
if constexpr
as named structs which have partial specializations on thebool
. But a C++11 lambda cannot be used as aif constexpr
replacement because the arguments cannot beauto
.Generic Lambdas are not only useful to emulate
if constexpr
they solve a very important issue we have right now which is mainly thatoperator()
can't be easily templated (in a way that its transparent to the functor calling code), either all functor's operator() must be templated or none.It really makes writing lambdas for
lower_bound
andupper_bound
a lot easier, you don't need to declare separate lambdas just because the type changed (as long as lets say the members being compared / logic inside stay the same).Why C++17 ?
First, The above shows why C++17's
if constexpr
is pretty and useful, as its a pretty horrible hack and doesn't work the same as anif constexpr
and has limitations where it won't work the same.Second lambda improvement is the ability to capture
this
by value, I see this as a very important addition.Third,
typename
in "template template parameter" makes code partial specializing onvector
-like more "correct.A scalar type is a
typename
and not aclass
orstruct
. And yes we already do that, because we made anemulated_float64_t
scalar type for Intel ARC GPUs which don't supportshaderFloat64
, so we also madeemulated_vector
andemulated_matrix
plus partial specs of<function>
https://github.com/Devsh-Graphics-Programming/Nabla/tree/23843c84e22f29af1ac7b0c321bdb0377748138d/include/nbl/builtin/hlsl/emulatedFourth, fold expressions and initializers in
if
andswitch
are awesome.Finally nested namespace definitions are a nice cosmetic feature.