Yes. What is copied into what direction and when depends on the buffer type (input/output/input_output) and mapping arguments (e.g. write_discard).
David explained that here before:
Basically for geometry data your buffers should be input only and if you change the whole input buffer content you map() with write_discard, to avoid needless copies to host.
The unmap() operation marks the buffer contents dirty and again depending on additional buffer flags, either the unmap() or normally the next launch() will copy the input buffer data to the GPU device(s).
Here’s some code doing that for custom geometry nodes (OptiX 5 based code had no GeometryTriangles), but would be the same thing for OptiX 6 buffers.
This chapter on buffers in the OptiX Programming Guide explains some more details:
But you said “where geometries are updated during runtime”.
If the data is all static, even better, then the whole procedure above only needs to happen once, but that’s the usual method.
Really, the presence of the setBuffer() function in the code should be the least of your problems.
The setVertices() function only makes the buffer object and it’s layout description known to the GeometryTriangles object for the following acceleration structure build. That call doesn’t involve any buffer data upload to the device. The map(), write, unmap() operation is normally required to fill input buffers. (The exception would be CUDA interop which is even more involved.)
If you want to access the contents of a buffer you either need to have it assigned to an existing rtBuffer variable on the device and that is done per that variable’s name at that scope.
Explaining with the code excerpts of the above link:
// Assigning the buffer to a variable on host side:
And the matching code on device side accessing the buffer contents, here inside the intersection program. With GeometryTriangles that would happen inside the attribute program.
Or you would need to use bindless buffer IDs which are integers which allow to have buffers accessible in structures or arrays.
One example is here, for data needed by the importance sampling of a spherical environment light:
Now with all that said, I understood that you’ve been implementing a flip-book animation in OptiX 5 using Selector nodes and visit programs, which have been removed in OptiX 6 and beyond because they interfered with the hardware BVH traversal. (I was in a conference call with your development department before.)
If your selector node was the top-level object and you switched through the individual animated geometry by selecting one of many children to traverse in the selector visit program, the exact same could be achieved in OptiX 7 by having an array of top-level OptixTraversableHandles which could be all uploaded at once and then animated through the same way, just by using a different top level handle in the primary ray optixTrace() call for each animation step.
That is not so easy in OptiX 6 because that doesn’t have arrays of rtObjects, but would require individual variables and a really ugly switch-case, which you described in one of your previous posts.
If the animation is not the top object, things get complicated.
OptiX 7 also allows to access the triangle vertex position (only) data inside the acceleration structure, so that the vertex positions don’t need to be kept on the host after the acceleration structure has been built:
As a company, you’d need to prepare for faster qualification of newer display drivers, because that is where the complete graphics core implementation resides. I would really recommend to bite the bullet and update to OptiX 7 as soon as possible.