Closed paulmelis closed 4 years ago
Ah, found the reason, ospray_util.h
defines the previous version of the call:
So the above API is going away, meaning that for cases where you want to pass data that you don't want to keep allocated in the application you need to do something new. The porting guide alludes to new APIs ospNewData
(opaque mem allocated by OSPRay) and ospCopyData
. So would I need to do something like this to get data into an OSPRay-managed data array using a temporary shared OSPData
array?
std::vector<float> vertices;
// fill vertex array
int nv = vertices.size()/3;
OSPData data = ospNewSharedData1D(vertices.data(), OSP_VEC3F, nv);
OSPData managed = ospNewData1D(OSP_VEC3F, nv);
ospCopyData1D(data, managed, 0);
ospRelease(data);
ospSetData(geometry, "vertex.position", managed);
ospRelease(managed);
I'm curious: as it's possible to directly share a block of memory with OSPRay I assume no copy of the data is made underwater to a managed array in order for the actual rendering device to its thing? Otherwise, why not always use the two-step process above? And would it not be possible to directly access the data array allocated by a ospNewData1D
to avoid having to create the shared array?
With respect to the explanation in the porting guide of
ospSetObjectAsData(group, "geometry", OSP_GEOMETRIC_MODEL, model);
being equal to
OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1);
ospSetObject(group, "geometry", geometricModels);
ospRelease(geometricModels);
The use of ospNewSharedData1D
is a bit confusing as it suggests that &model
must keep pointing to a valid object even after ospSetObjectAsData()
has returned (as the lifetime of the geometricModels
array isn't exactly known).
But looking at https://github.com/ospray/ospray/blob/9527f27984f6ba7daeb3d64df7c0d4615866ddab/ospray/api/ospray_util_impl.cpp#L156-L164
and
the actual behaviour of ospSetObjectAsData
is to copy into an opaque array
OSPData src = ospNewSharedData(&model, OSP_GEOMETRIC_MODEL, 1);
OSPData data = ospNewData(OSP_GEOMETRIC_MODEL, 1);
ospCopyData(src, data);
ospRelease(src);
ospSetObject(group, "geometry", data);
ospRelease(data);
so the normal reference counting ways can be used. Which is what I see here
I'm actually not even sure I convinced myself with the above explanation but I'm trying to get my head around the ospNewSharedData1D
equivalence :grin:
We ended up settling on 64-bit sizes for data arrays for v2.x
.
Shared data represents memory from the application that OSPRay can read, which is trivially cheap to call. However, the constraint is that the application must keep that memory around as long as the OSPRay data looking at it is also valid. Opaque data objects allow these lifetimes to be separated, but populating the opaque data requires copying from a shared data (i.e. the shared data just describes the input, which could be strided!).
Hope this helps anyone reading this!
In bcecfe6577bad4b0a689196a3d6d485d1c4e1dd4
ospNewData
was changed fromto
But in, for example,
apps/tutorials/ospTutorialStructuredVolume.cpp
I see calls like https://github.com/ospray/ospray/blob/9527f27984f6ba7daeb3d64df7c0d4615866ddab/apps/tutorials/ospTutorialVolumePathTracer.cpp#L189How can that work (and compile) given the
uint32_t
parameters onospNewData
? Shouldn't that give precision errors on 64-bit systems due to a pointer having more bits than anuint32_t
?I'm mostly trying to understand why it works :)