1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3
4 #include <vector>
5
6 #include "../fb/DistributedFrameBuffer.h"
7 #include "MPICommon.h"
8 #include "OSPWork.h"
9 #include "common/Data.h"
10 #include "common/Library.h"
11 #include "common/ObjectHandle.h"
12 #include "common/World.h"
13 #include "geometry/GeometricModel.h"
14 #include "ospray/MPIDistributedDevice.h"
15 #include "render/RenderTask.h"
16 #include "rkcommon/array3D/for_each.h"
17 #include "rkcommon/utility/ArrayView.h"
18 #include "rkcommon/utility/OwnedArray.h"
19 #include "texture/Texture.h"
20 #include "volume/VolumetricModel.h"
21
22 namespace ospray {
23 namespace mpi {
24 namespace work {
25
FrameBufferInfo(const vec2i & size,OSPFrameBufferFormat format,uint32_t channels)26 FrameBufferInfo::FrameBufferInfo(
27 const vec2i &size, OSPFrameBufferFormat format, uint32_t channels)
28 : size(size), format(format), channels(channels)
29 {}
30
pixelSize(uint32_t channel) const31 size_t FrameBufferInfo::pixelSize(uint32_t channel) const
32 {
33 switch (channel) {
34 case OSP_FB_COLOR:
35 switch (format) {
36 case OSP_FB_RGBA8:
37 case OSP_FB_SRGBA:
38 return sizeof(uint32_t);
39 case OSP_FB_RGBA32F:
40 return sizeof(vec4f);
41 default:
42 return 0;
43 }
44 case OSP_FB_DEPTH:
45 return channels & OSP_FB_DEPTH ? sizeof(float) : 0;
46 case OSP_FB_NORMAL:
47 return channels & OSP_FB_NORMAL ? sizeof(vec3f) : 0;
48 case OSP_FB_ALBEDO:
49 return channels & OSP_FB_ALBEDO ? sizeof(vec3f) : 0;
50 default:
51 return 0;
52 }
53 }
54
getNumPixels() const55 size_t FrameBufferInfo::getNumPixels() const
56 {
57 return size.x * size.y;
58 }
59
getSharedDataHandle(int64_t handle) const60 Data *OSPState::getSharedDataHandle(int64_t handle) const
61 {
62 auto fnd = appSharedData.find(handle);
63 if (fnd != appSharedData.end()) {
64 return fnd->second;
65 }
66 return nullptr;
67 }
68
newRenderer(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)69 void newRenderer(
70 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
71 {
72 int64_t handle = 0;
73 std::string type;
74 cmdBuf >> handle >> type;
75 state.objects[handle] = ospNewRenderer(type.c_str());
76 }
77
newWorld(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)78 void newWorld(
79 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
80 {
81 int64_t handle = 0;
82 cmdBuf >> handle;
83 state.objects[handle] = ospNewWorld();
84 }
85
newGeometry(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)86 void newGeometry(
87 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
88 {
89 int64_t handle = 0;
90 std::string type;
91 cmdBuf >> handle >> type;
92 state.objects[handle] = ospNewGeometry(type.c_str());
93 }
94
newGeometricModel(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)95 void newGeometricModel(
96 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
97 {
98 int64_t handle = 0;
99 int64_t geomHandle = 0;
100 cmdBuf >> handle >> geomHandle;
101 state.objects[handle] =
102 ospNewGeometricModel(state.getObject<OSPGeometry>(geomHandle));
103 }
104
newVolume(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)105 void newVolume(
106 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
107 {
108 int64_t handle = 0;
109 std::string type;
110 cmdBuf >> handle >> type;
111 state.objects[handle] = ospNewVolume(type.c_str());
112 }
113
newVolumetricModel(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)114 void newVolumetricModel(
115 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
116 {
117 int64_t handle = 0;
118 int64_t volHandle = 0;
119 cmdBuf >> handle >> volHandle;
120 state.objects[handle] =
121 ospNewVolumetricModel(state.getObject<OSPVolume>(volHandle));
122 }
123
newCamera(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)124 void newCamera(
125 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
126 {
127 int64_t handle = 0;
128 std::string type;
129 cmdBuf >> handle >> type;
130 state.objects[handle] = ospNewCamera(type.c_str());
131 }
132
newTransferFunction(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)133 void newTransferFunction(
134 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
135 {
136 int64_t handle = 0;
137 std::string type;
138 cmdBuf >> handle >> type;
139 state.objects[handle] = ospNewTransferFunction(type.c_str());
140 }
141
newImageOperation(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)142 void newImageOperation(
143 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
144 {
145 int64_t handle = 0;
146 std::string type;
147 cmdBuf >> handle >> type;
148 state.objects[handle] = ospNewImageOperation(type.c_str());
149 }
150
newMaterial(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)151 void newMaterial(
152 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
153 {
154 int64_t handle = 0;
155 std::string type;
156 cmdBuf >> handle >> type;
157 state.objects[handle] = ospNewMaterial(nullptr, type.c_str());
158 }
159
newLight(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)160 void newLight(
161 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
162 {
163 int64_t handle = 0;
164 std::string type;
165 cmdBuf >> handle >> type;
166 state.objects[handle] = ospNewLight(type.c_str());
167 }
168
dataTransfer(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)169 void dataTransfer(OSPState &state,
170 networking::BufferReader &cmdBuf,
171 networking::Fabric &fabric)
172 {
173 using namespace utility;
174
175 OSPDataType type;
176 vec3ul numItems = 0;
177 cmdBuf >> type >> numItems;
178
179 Data *data = new Data(type, numItems);
180
181 const uint64_t nbytes = data->size() * sizeOf(type);
182 auto view = std::make_shared<ArrayView<uint8_t>>(
183 reinterpret_cast<uint8_t *>(data->data()), nbytes);
184 fabric.recvBcast(*view);
185
186 state.dataTransfers.push(data);
187 }
188
retrieveData(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &,const OSPDataType type,const vec3ul numItems,Data * outputData)189 Data *retrieveData(OSPState &state,
190 networking::BufferReader &cmdBuf,
191 networking::Fabric &,
192 const OSPDataType type,
193 const vec3ul numItems,
194 Data *outputData)
195 {
196 using namespace utility;
197 uint32_t dataInline = 0;
198 cmdBuf >> dataInline;
199 const uint64_t nbytes = numItems.x * numItems.y * numItems.z * sizeOf(type);
200 if (dataInline) {
201 // If the data is inline we copy it out of the command buffer into
202 // a fixed array, since the command buffer will be destroyed after
203 // processing it
204 if (!outputData) {
205 outputData = new Data(type, numItems);
206 }
207 cmdBuf.read(outputData->data(), nbytes);
208 } else {
209 // All large data is sent before the command buffer using it, and will be
210 // in the state's data transfers list in order by the command referencing it
211 auto data = state.dataTransfers.front();
212 state.dataTransfers.pop();
213
214 if (outputData) {
215 // All data on the workers is compact, with the compaction done by the
216 // app rank before sending
217 std::memcpy(outputData->data(), data->data(), nbytes);
218 } else {
219 outputData = data;
220 }
221 }
222
223 // If the data type is managed we need to convert the handles back into
224 // OSPObjects and increment the refcount because we're populating the data
225 // object manually
226 if (mpicommon::isManagedObject(type)) {
227 for (size_t i = 0; i < array3D::longProduct(numItems); ++i) {
228 char *addr = outputData->data() + i * sizeOf(type);
229 int64_t *h = reinterpret_cast<int64_t *>(addr);
230 OSPObject *obj = reinterpret_cast<OSPObject *>(addr);
231 *obj = state.objects[*h];
232
233 ManagedObject *m = lookupObject<ManagedObject>(*obj);
234 m->refInc();
235 }
236 }
237
238 return outputData;
239 }
240
newSharedData(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)241 void newSharedData(OSPState &state,
242 networking::BufferReader &cmdBuf,
243 networking::Fabric &fabric)
244 {
245 using namespace utility;
246
247 int64_t handle = 0;
248 OSPDataType format;
249 vec3ul numItems = 0;
250 cmdBuf >> handle >> format >> numItems;
251
252 auto data = retrieveData(state, cmdBuf, fabric, format, numItems, nullptr);
253
254 state.objects[handle] = (OSPData)data;
255 state.appSharedData[handle] = data;
256 }
257
newData(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)258 void newData(
259 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
260 {
261 int64_t handle = 0;
262 OSPDataType format;
263 vec3ul numItems = 0;
264 cmdBuf >> handle >> format >> numItems;
265
266 state.objects[handle] =
267 ospNewData(format, numItems.x, numItems.y, numItems.z);
268 }
269
copyData(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)270 void copyData(
271 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
272 {
273 int64_t sourceHandle = 0;
274 int64_t destinationHandle = 0;
275 vec3ul destinationIndex = 0;
276 cmdBuf >> sourceHandle >> destinationHandle >> destinationIndex;
277
278 ospCopyData(state.getObject<OSPData>(sourceHandle),
279 state.getObject<OSPData>(destinationHandle),
280 destinationIndex.x,
281 destinationIndex.y,
282 destinationIndex.z);
283 }
284
newTexture(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)285 void newTexture(
286 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
287 {
288 int64_t handle = 0;
289 std::string type;
290 cmdBuf >> handle >> type;
291 state.objects[handle] = ospNewTexture(type.c_str());
292 }
293
newGroup(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)294 void newGroup(
295 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
296 {
297 int64_t handle = 0;
298 cmdBuf >> handle;
299 state.objects[handle] = ospNewGroup();
300 }
301
newInstance(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)302 void newInstance(
303 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
304 {
305 int64_t handle = 0;
306 int64_t groupHandle = 0;
307 cmdBuf >> handle >> groupHandle;
308 state.objects[handle] =
309 ospNewInstance(state.getObject<OSPGroup>(groupHandle));
310 }
311
commit(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)312 void commit(OSPState &state,
313 networking::BufferReader &cmdBuf,
314 networking::Fabric &fabric)
315 {
316 int64_t handle = 0;
317 cmdBuf >> handle;
318
319 // If it's a data being committed, we need to retrieve the updated data
320 Data *d = state.getSharedDataHandle(handle);
321 if (d) {
322 retrieveData(state, cmdBuf, fabric, d->type, d->numItems, d);
323 }
324
325 ospCommit(state.objects[handle]);
326 }
327
release(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)328 void release(
329 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
330 {
331 int64_t handle = 0;
332 cmdBuf >> handle;
333 ospRelease(state.objects[handle]);
334 // Note: we keep the handle in the state.objects list as it may be referenced
335 // by other objects in the scene as a parameter or data.
336
337 // Check if we can release a referenced framebuffer info
338 {
339 auto fnd = state.framebuffers.find(handle);
340 if (fnd != state.framebuffers.end()) {
341 OSPObject obj = state.objects[handle];
342 ManagedObject *m = lookupDistributedObject<ManagedObject>(obj);
343 // Framebuffers are given an extra ref count by the worker so that
344 // we can track the lifetime of their framebuffer info. Use count == 1
345 // means only the worker rank has a reference to the object
346 if (m->useCount() == 1) {
347 ospRelease(state.objects[handle]);
348 state.framebuffers.erase(fnd);
349 }
350 }
351 }
352
353 if (state.getSharedDataHandle(handle)) {
354 state.appSharedData.erase(handle);
355 }
356 }
357
retain(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)358 void retain(
359 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
360 {
361 int64_t handle = 0;
362 cmdBuf >> handle;
363 ospRetain(state.objects[handle]);
364 }
365
loadModule(OSPState &,networking::BufferReader & cmdBuf,networking::Fabric &)366 void loadModule(
367 OSPState &, networking::BufferReader &cmdBuf, networking::Fabric &)
368 {
369 std::string module;
370 cmdBuf >> module;
371 ospLoadModule(module.c_str());
372 }
373
createFramebuffer(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)374 void createFramebuffer(
375 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
376 {
377 int64_t handle = 0;
378 vec2i size(0, 0);
379 uint32_t format;
380 uint32_t channels = 0;
381 cmdBuf >> handle >> size >> format >> channels;
382 state.objects[handle] =
383 ospNewFrameBuffer(size.x, size.y, (OSPFrameBufferFormat)format, channels);
384 state.framebuffers[handle] =
385 FrameBufferInfo(size, (OSPFrameBufferFormat)format, channels);
386
387 // Offload device keeps +1 ref for tracking the lifetime of the framebuffer
388 ospRetain(state.objects[handle]);
389 }
390
mapFramebuffer(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)391 void mapFramebuffer(OSPState &state,
392 networking::BufferReader &cmdBuf,
393 networking::Fabric &fabric)
394 {
395 // Map the channel and send the image back over the fabric
396 int64_t handle = 0;
397 uint32_t channel = 0;
398 cmdBuf >> handle >> channel;
399
400 if (mpicommon::worker.rank == 0) {
401 using namespace utility;
402
403 const FrameBufferInfo &fbInfo = state.framebuffers[handle];
404 uint64_t nbytes = fbInfo.pixelSize(channel) * fbInfo.getNumPixels();
405
406 auto bytesView = std::make_shared<OwnedArray<uint8_t>>(
407 reinterpret_cast<uint8_t *>(&nbytes), sizeof(nbytes));
408 fabric.send(bytesView, 0);
409
410 if (nbytes != 0) {
411 OSPFrameBuffer fb = state.getObject<OSPFrameBuffer>(handle);
412 void *map = const_cast<void *>(
413 ospMapFrameBuffer(fb, (OSPFrameBufferChannel)channel));
414
415 auto fbView = std::make_shared<OwnedArray<uint8_t>>(
416 reinterpret_cast<uint8_t *>(map), nbytes);
417
418 fabric.send(fbView, 0);
419 ospUnmapFrameBuffer(map, fb);
420 }
421 }
422 }
423
getVariance(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)424 void getVariance(OSPState &state,
425 networking::BufferReader &cmdBuf,
426 networking::Fabric &fabric)
427 {
428 // Map the channel and send the image back over the fabric
429 int64_t handle = 0;
430 cmdBuf >> handle;
431
432 if (mpicommon::worker.rank == 0) {
433 using namespace utility;
434
435 float variance = ospGetVariance(state.getObject<OSPFrameBuffer>(handle));
436
437 auto bytesView = std::make_shared<OwnedArray<uint8_t>>(
438 reinterpret_cast<uint8_t *>(&variance), sizeof(variance));
439 fabric.send(bytesView, 0);
440 }
441 }
442
resetAccumulation(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)443 void resetAccumulation(
444 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
445 {
446 int64_t handle = 0;
447 cmdBuf >> handle;
448 ospResetAccumulation(state.getObject<OSPFrameBuffer>(handle));
449 }
450
renderFrame(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)451 void renderFrame(
452 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
453 {
454 int64_t futureHandle = 0;
455 int64_t fbHandle = 0;
456 int64_t rendererHandle = 0;
457 int64_t cameraHandle = 0;
458 int64_t worldHandle = 0;
459 cmdBuf >> fbHandle >> rendererHandle >> cameraHandle >> worldHandle
460 >> futureHandle;
461 state.objects[futureHandle] =
462 ospRenderFrame(state.getObject<OSPFrameBuffer>(fbHandle),
463 state.getObject<OSPRenderer>(rendererHandle),
464 state.getObject<OSPCamera>(cameraHandle),
465 state.getObject<OSPWorld>(worldHandle));
466 }
467
468 template <typename T>
setParam(networking::BufferReader & cmdBuf,OSPObject obj,const std::string & param,OSPDataType type)469 void setParam(networking::BufferReader &cmdBuf,
470 OSPObject obj,
471 const std::string ¶m,
472 OSPDataType type)
473 {
474 T val;
475 cmdBuf >> val;
476 ospSetParam(obj, param.c_str(), type, &val);
477 }
478
setParam(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)479 void setParam(
480 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
481 {
482 int64_t handle = 0;
483 std::string param;
484 OSPDataType type;
485 cmdBuf >> handle >> param >> type;
486
487 // OSP_OBJECT use the same style of setting param since it's just a handle
488 if (mpicommon::isManagedObject(type)) {
489 int64_t val = 0;
490 cmdBuf >> val;
491 ospSetParam(
492 state.objects[handle], param.c_str(), type, &state.objects[val]);
493 } else {
494 switch (type) {
495 case OSP_STRING: {
496 std::string val;
497 cmdBuf >> val;
498 ospSetParam(state.objects[handle], param.c_str(), type, val.c_str());
499 break;
500 }
501 case OSP_BOOL:
502 setParam<bool>(cmdBuf, state.objects[handle], param, type);
503 break;
504 case OSP_CHAR:
505 case OSP_BYTE:
506 setParam<char>(cmdBuf, state.objects[handle], param, type);
507 break;
508 case OSP_VEC2UC:
509 setParam<vec2uc>(cmdBuf, state.objects[handle], param, type);
510 break;
511 case OSP_VEC3UC:
512 setParam<vec3uc>(cmdBuf, state.objects[handle], param, type);
513 break;
514 case OSP_VEC4UC:
515 setParam<vec4uc>(cmdBuf, state.objects[handle], param, type);
516 break;
517 case OSP_SHORT:
518 setParam<short>(cmdBuf, state.objects[handle], param, type);
519 break;
520 case OSP_USHORT:
521 setParam<unsigned short>(cmdBuf, state.objects[handle], param, type);
522 break;
523 case OSP_INT:
524 setParam<int>(cmdBuf, state.objects[handle], param, type);
525 break;
526 case OSP_VEC2I:
527 setParam<vec2i>(cmdBuf, state.objects[handle], param, type);
528 break;
529 case OSP_VEC3I:
530 setParam<vec3i>(cmdBuf, state.objects[handle], param, type);
531 break;
532 case OSP_VEC4I:
533 setParam<vec4i>(cmdBuf, state.objects[handle], param, type);
534 break;
535 case OSP_UINT:
536 setParam<unsigned int>(cmdBuf, state.objects[handle], param, type);
537 break;
538 case OSP_VEC2UI:
539 setParam<vec2ui>(cmdBuf, state.objects[handle], param, type);
540 break;
541 case OSP_VEC3UI:
542 setParam<vec3ui>(cmdBuf, state.objects[handle], param, type);
543 break;
544 case OSP_VEC4UI:
545 setParam<vec4ui>(cmdBuf, state.objects[handle], param, type);
546 break;
547 case OSP_LONG:
548 setParam<long>(cmdBuf, state.objects[handle], param, type);
549 break;
550 case OSP_VEC2L:
551 setParam<vec2l>(cmdBuf, state.objects[handle], param, type);
552 break;
553 case OSP_VEC3L:
554 setParam<vec3l>(cmdBuf, state.objects[handle], param, type);
555 break;
556 case OSP_VEC4L:
557 setParam<vec4l>(cmdBuf, state.objects[handle], param, type);
558 break;
559 case OSP_ULONG:
560 setParam<unsigned long>(cmdBuf, state.objects[handle], param, type);
561 break;
562 case OSP_VEC2UL:
563 setParam<vec2ul>(cmdBuf, state.objects[handle], param, type);
564 break;
565 case OSP_VEC3UL:
566 setParam<vec3ul>(cmdBuf, state.objects[handle], param, type);
567 break;
568 case OSP_VEC4UL:
569 setParam<vec4ul>(cmdBuf, state.objects[handle], param, type);
570 break;
571 case OSP_FLOAT:
572 setParam<float>(cmdBuf, state.objects[handle], param, type);
573 break;
574 case OSP_VEC2F:
575 setParam<vec2f>(cmdBuf, state.objects[handle], param, type);
576 break;
577 case OSP_VEC3F:
578 setParam<vec3f>(cmdBuf, state.objects[handle], param, type);
579 break;
580 case OSP_VEC4F:
581 setParam<vec4f>(cmdBuf, state.objects[handle], param, type);
582 break;
583 case OSP_DOUBLE:
584 setParam<double>(cmdBuf, state.objects[handle], param, type);
585 break;
586 case OSP_BOX1I:
587 setParam<box1i>(cmdBuf, state.objects[handle], param, type);
588 break;
589 case OSP_BOX2I:
590 setParam<box2i>(cmdBuf, state.objects[handle], param, type);
591 break;
592 case OSP_BOX3I:
593 setParam<box3i>(cmdBuf, state.objects[handle], param, type);
594 break;
595 case OSP_BOX4I:
596 setParam<box4i>(cmdBuf, state.objects[handle], param, type);
597 break;
598 case OSP_BOX1F:
599 setParam<box1f>(cmdBuf, state.objects[handle], param, type);
600 break;
601 case OSP_BOX2F:
602 setParam<box2f>(cmdBuf, state.objects[handle], param, type);
603 break;
604 case OSP_BOX3F:
605 setParam<box3f>(cmdBuf, state.objects[handle], param, type);
606 break;
607 case OSP_BOX4F:
608 setParam<box4f>(cmdBuf, state.objects[handle], param, type);
609 break;
610 case OSP_LINEAR2F:
611 setParam<linear2f>(cmdBuf, state.objects[handle], param, type);
612 break;
613 case OSP_LINEAR3F:
614 setParam<linear3f>(cmdBuf, state.objects[handle], param, type);
615 break;
616 case OSP_AFFINE2F:
617 setParam<affine2f>(cmdBuf, state.objects[handle], param, type);
618 break;
619 case OSP_AFFINE3F:
620 setParam<affine3f>(cmdBuf, state.objects[handle], param, type);
621 break;
622 default:
623 throw std::runtime_error("Unrecognized param type!");
624 }
625 }
626 }
627
removeParam(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)628 void removeParam(
629 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
630 {
631 int64_t handle = 0;
632 std::string param;
633 cmdBuf >> handle >> param;
634 ospRemoveParam(state.objects[handle], param.c_str());
635 }
636
pick(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)637 void pick(OSPState &state,
638 networking::BufferReader &cmdBuf,
639 networking::Fabric &fabric)
640 {
641 int64_t fbHandle = 0;
642 int64_t rendererHandle = 0;
643 int64_t cameraHandle = 0;
644 int64_t worldHandle = 0;
645 vec2f screenPos;
646 cmdBuf >> fbHandle >> rendererHandle >> cameraHandle >> worldHandle
647 >> screenPos;
648
649 OSPPickResult res;
650 ospPick(&res,
651 state.getObject<OSPFrameBuffer>(fbHandle),
652 state.getObject<OSPRenderer>(rendererHandle),
653 state.getObject<OSPCamera>(cameraHandle),
654 state.getObject<OSPWorld>(worldHandle),
655 screenPos.x,
656 screenPos.y);
657
658 if (mpicommon::worker.rank == 0) {
659 using namespace utility;
660 auto view = std::make_shared<OwnedArray<uint8_t>>(
661 reinterpret_cast<uint8_t *>(&res), sizeof(OSPPickResult));
662 fabric.send(view, 0);
663 }
664 }
665
getBounds(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)666 void getBounds(OSPState &state,
667 networking::BufferReader &cmdBuf,
668 networking::Fabric &fabric)
669 {
670 int64_t handle = 0;
671 cmdBuf >> handle;
672
673 OSPBounds res = ospGetBounds(state.objects[handle]);
674
675 if (mpicommon::worker.rank == 0) {
676 using namespace utility;
677 auto view = std::make_shared<OwnedArray<uint8_t>>(
678 reinterpret_cast<uint8_t *>(&res), sizeof(OSPBounds));
679 fabric.send(view, 0);
680 }
681 }
682
futureIsReady(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)683 void futureIsReady(OSPState &state,
684 networking::BufferReader &cmdBuf,
685 networking::Fabric &fabric)
686 {
687 int64_t handle = 0;
688 uint32_t event = 0;
689 cmdBuf >> handle >> event;
690 int ready =
691 ospIsReady(state.getObject<OSPFuture>(handle), (OSPSyncEvent)event);
692
693 if (mpicommon::worker.rank == 0) {
694 using namespace utility;
695 auto view = std::make_shared<OwnedArray<uint8_t>>(
696 reinterpret_cast<uint8_t *>(&ready), sizeof(ready));
697 fabric.send(view, 0);
698 }
699 }
700
futureWait(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)701 void futureWait(OSPState &state,
702 networking::BufferReader &cmdBuf,
703 networking::Fabric &fabric)
704 {
705 int64_t handle = 0;
706 uint32_t event = 0;
707 cmdBuf >> handle >> event;
708 ospWait(state.getObject<OSPFuture>(handle), (OSPSyncEvent)event);
709
710 if (mpicommon::worker.rank == 0) {
711 using namespace utility;
712 auto view = std::make_shared<OwnedArray<uint8_t>>(
713 reinterpret_cast<uint8_t *>(&event), sizeof(event));
714 fabric.send(view, 0);
715 }
716 }
717
futureCancel(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric &)718 void futureCancel(
719 OSPState &state, networking::BufferReader &cmdBuf, networking::Fabric &)
720 {
721 int64_t handle = 0;
722 cmdBuf >> handle;
723 ospCancel(state.getObject<OSPFuture>(handle));
724 }
725
futureGetProgress(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)726 void futureGetProgress(OSPState &state,
727 networking::BufferReader &cmdBuf,
728 networking::Fabric &fabric)
729 {
730 int64_t handle = 0;
731 cmdBuf >> handle;
732 float progress = ospGetProgress(state.getObject<OSPFuture>(handle));
733
734 if (mpicommon::worker.rank == 0) {
735 using namespace utility;
736 auto view = std::make_shared<OwnedArray<uint8_t>>(
737 reinterpret_cast<uint8_t *>(&progress), sizeof(progress));
738 fabric.send(view, 0);
739 }
740 }
741
futureGetTaskDuration(OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)742 void futureGetTaskDuration(OSPState &state,
743 networking::BufferReader &cmdBuf,
744 networking::Fabric &fabric)
745 {
746 int64_t handle = 0;
747 cmdBuf >> handle;
748 float progress = ospGetTaskDuration(state.getObject<OSPFuture>(handle));
749
750 if (mpicommon::worker.rank == 0) {
751 using namespace utility;
752 auto view = std::make_shared<OwnedArray<uint8_t>>(
753 reinterpret_cast<uint8_t *>(&progress), sizeof(progress));
754 fabric.send(view, 0);
755 }
756 }
757
dispatchWork(TAG t,OSPState & state,networking::BufferReader & cmdBuf,networking::Fabric & fabric)758 void dispatchWork(TAG t,
759 OSPState &state,
760 networking::BufferReader &cmdBuf,
761 networking::Fabric &fabric)
762 {
763 switch (t) {
764 case NEW_RENDERER:
765 newRenderer(state, cmdBuf, fabric);
766 break;
767 case NEW_WORLD:
768 newWorld(state, cmdBuf, fabric);
769 break;
770 case NEW_GEOMETRY:
771 newGeometry(state, cmdBuf, fabric);
772 break;
773 case NEW_GEOMETRIC_MODEL:
774 newGeometricModel(state, cmdBuf, fabric);
775 break;
776 case NEW_VOLUME:
777 newVolume(state, cmdBuf, fabric);
778 break;
779 case NEW_VOLUMETRIC_MODEL:
780 newVolumetricModel(state, cmdBuf, fabric);
781 break;
782 case NEW_CAMERA:
783 newCamera(state, cmdBuf, fabric);
784 break;
785 case NEW_TRANSFER_FUNCTION:
786 newTransferFunction(state, cmdBuf, fabric);
787 break;
788 case NEW_IMAGE_OPERATION:
789 newImageOperation(state, cmdBuf, fabric);
790 break;
791 case NEW_MATERIAL:
792 newMaterial(state, cmdBuf, fabric);
793 break;
794 case NEW_LIGHT:
795 newLight(state, cmdBuf, fabric);
796 break;
797 case DATA_TRANSFER:
798 dataTransfer(state, cmdBuf, fabric);
799 break;
800 case NEW_SHARED_DATA:
801 newSharedData(state, cmdBuf, fabric);
802 break;
803 case NEW_DATA:
804 newData(state, cmdBuf, fabric);
805 break;
806 case COPY_DATA:
807 copyData(state, cmdBuf, fabric);
808 break;
809 case NEW_TEXTURE:
810 newTexture(state, cmdBuf, fabric);
811 break;
812 case NEW_GROUP:
813 newGroup(state, cmdBuf, fabric);
814 break;
815 case NEW_INSTANCE:
816 newInstance(state, cmdBuf, fabric);
817 break;
818 case COMMIT:
819 commit(state, cmdBuf, fabric);
820 break;
821 case RELEASE:
822 release(state, cmdBuf, fabric);
823 break;
824 case RETAIN:
825 retain(state, cmdBuf, fabric);
826 break;
827 case LOAD_MODULE:
828 loadModule(state, cmdBuf, fabric);
829 break;
830 case CREATE_FRAMEBUFFER:
831 createFramebuffer(state, cmdBuf, fabric);
832 break;
833 case MAP_FRAMEBUFFER:
834 mapFramebuffer(state, cmdBuf, fabric);
835 break;
836 case GET_VARIANCE:
837 getVariance(state, cmdBuf, fabric);
838 break;
839 case RESET_ACCUMULATION:
840 resetAccumulation(state, cmdBuf, fabric);
841 break;
842 case RENDER_FRAME:
843 renderFrame(state, cmdBuf, fabric);
844 break;
845 case SET_PARAM:
846 setParam(state, cmdBuf, fabric);
847 break;
848 case REMOVE_PARAM:
849 removeParam(state, cmdBuf, fabric);
850 break;
851 case PICK:
852 pick(state, cmdBuf, fabric);
853 break;
854 case GET_BOUNDS:
855 getBounds(state, cmdBuf, fabric);
856 break;
857 case FUTURE_IS_READY:
858 futureIsReady(state, cmdBuf, fabric);
859 break;
860 case FUTURE_WAIT:
861 futureWait(state, cmdBuf, fabric);
862 break;
863 case FUTURE_CANCEL:
864 futureCancel(state, cmdBuf, fabric);
865 break;
866 case FUTURE_GET_PROGRESS:
867 futureGetProgress(state, cmdBuf, fabric);
868 break;
869 case FUTURE_GET_TASK_DURATION:
870 futureGetTaskDuration(state, cmdBuf, fabric);
871 break;
872 case NONE:
873 default:
874 throw std::runtime_error("Invalid work tag!");
875 }
876 }
877
tagName(work::TAG t)878 const char *tagName(work::TAG t)
879 {
880 switch (t) {
881 case NEW_RENDERER:
882 return "NEW_RENDERER";
883 case NEW_WORLD:
884 return "NEW_WORLD";
885 case NEW_GEOMETRY:
886 return "NEW_GEOMETRY";
887 case NEW_GEOMETRIC_MODEL:
888 return "NEW_GEOMETRIC_MODEL";
889 case NEW_VOLUME:
890 return "NEW_VOLUME";
891 case NEW_VOLUMETRIC_MODEL:
892 return "NEW_VOLUMETRIC_MODEL";
893 case NEW_CAMERA:
894 return "NEW_CAMERA";
895 case NEW_TRANSFER_FUNCTION:
896 return "NEW_TRANSFER_FUNCTION";
897 case NEW_IMAGE_OPERATION:
898 return "NEW_IMAGE_OPERATION";
899 case NEW_MATERIAL:
900 return "NEW_MATERIAL";
901 case NEW_LIGHT:
902 return "NEW_LIGHT";
903 case DATA_TRANSFER:
904 return "DATA_TRANSFER";
905 case NEW_SHARED_DATA:
906 return "NEW_SHARED_DATA";
907 case NEW_DATA:
908 return "NEW_DATA";
909 case COPY_DATA:
910 return "COPY_DATA";
911 case NEW_TEXTURE:
912 return "NEW_TEXTURE";
913 case NEW_GROUP:
914 return "NEW_GROUP";
915 case NEW_INSTANCE:
916 return "NEW_INSTANCE";
917 case COMMIT:
918 return "COMMIT";
919 case RELEASE:
920 return "RELEASE";
921 case RETAIN:
922 return "RETAIN";
923 case LOAD_MODULE:
924 return "LOAD_MODULE";
925 case CREATE_FRAMEBUFFER:
926 return "CREATE_FRAMEBUFFER";
927 case MAP_FRAMEBUFFER:
928 return "MAP_FRAMEBUFFER";
929 case GET_VARIANCE:
930 return "GET_VARIANCE";
931 case RESET_ACCUMULATION:
932 return "RESET_ACCUMULATION";
933 case RENDER_FRAME:
934 return "RENDER_FRAME";
935 case SET_PARAM:
936 return "SET_PARAM";
937 case REMOVE_PARAM:
938 return "REMOVE_PARAM";
939 case PICK:
940 return "PICK";
941 case GET_BOUNDS:
942 return "GET_BOUNDS";
943 case FUTURE_IS_READY:
944 return "FUTURE_IS_READY";
945 case FUTURE_WAIT:
946 return "FUTURE_WAIT";
947 case FUTURE_CANCEL:
948 return "FUTURE_CANCEL";
949 case FUTURE_GET_PROGRESS:
950 return "FUTURE_GET_PROGRESS";
951 case FINALIZE:
952 return "FINALIZE";
953 case NONE:
954 default:
955 return "NONE/UNKNOWN/INVALID";
956 }
957 }
958
959 } // namespace work
960 } // namespace mpi
961 } // namespace ospray
962