In this PR, we change the mechanism involved in setting shader binding table record data to be more type safe.
Before this change, GPRT users were required to provide a list of declarations in the SBT record for each program handle and geometry type made. This has several disadvantages:
User defined declarations go out of date as device code is updated.
User defined declarations can only be checked for type correctness at runtime
Iterating over user defined declarations during SBT construction is expensive, and locks us out of a device-side SBT construction
Writing a list of declarations for every program is tedious and unnecessarily verbose
It is easy to forget the names of declarations in the map
It is unclear to end users later in their programs how declaration keys map to the actual SBT record structures.
Therefore, this PR does away with declaration lists, and instead exposes a gprtProgramGetPointer API, where the returned pointer belongs to a struct matching the SBT record type.
By working with this pointer directly, the compiler can catch incorrect types during compilation time. Further, many IDEs can intelligently provide a list of all available fields in the SBT record.
In the GPRT backend, we now copy the entire SBT record template into the SBT at once, rather than field by field. This greatly simplifies the SBT construction process and opens the door to a device side construction, which would be required for device-side instance creation.
For additional type safety, this PR also introduces GPRTTypeOf, where the T is the SBT record type. This allows users to avoid casting void pointers to the SBT record type. This also applies to buffers:
In this PR, we change the mechanism involved in setting shader binding table record data to be more type safe.
Before this change, GPRT users were required to provide a list of declarations in the SBT record for each program handle and geometry type made. This has several disadvantages:
Therefore, this PR does away with declaration lists, and instead exposes a gprtProgramGetPointer API, where the returned pointer belongs to a struct matching the SBT record type.
By working with this pointer directly, the compiler can catch incorrect types during compilation time. Further, many IDEs can intelligently provide a list of all available fields in the SBT record.
In the GPRT backend, we now copy the entire SBT record template into the SBT at once, rather than field by field. This greatly simplifies the SBT construction process and opens the door to a device side construction, which would be required for device-side instance creation.
For additional type safety, this PR also introduces GPRTTypeOf, where the T is the SBT record type. This allows users to avoid casting void pointers to the SBT record type. This also applies to buffers:
float* tmp = (float*) GPRTBufferGetPointer(buffer);
becomes
float* tmp = GPRTBufferGetPointer(buffer)