From 5e8fc1c9907930244f5fde075a61366a5a1a016a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 2 Feb 2016 21:33:22 +0100 Subject: [PATCH 001/310] API change: rework Textures to support sRGB format --- apps/modelViewer/modelViewer.cpp | 16 +- apps/qtViewer/sg/common/Texture2D.cpp | 5 +- apps/qtViewer/sg/common/Texture2D.h | 2 +- apps/qtViewer/sg/importer/ImportRIVL.cpp | 13 +- modules/opengl/util.cpp | 3 +- ospray/CMakeLists.txt | 1 - ospray/api/API.cpp | 19 +- ospray/api/COIDeviceHost.cpp | 22 +- ospray/api/COIDeviceWorker.cpp | 5 +- ospray/api/Device.h | 5 +- ospray/api/LocalDevice.cpp | 10 +- ospray/api/LocalDevice.h | 7 +- ospray/common/OSPCommon.cpp | 21 +- ospray/common/OSPCommon.h | 8 +- ospray/include/ospray/ospray.h | 71 ++++-- ospray/mpi/MPIDevice.cpp | 9 +- ospray/mpi/MPIDevice.h | 4 +- ospray/mpi/worker.cpp | 17 +- ospray/render/simpleAO/SimpleAO.h | 4 +- ospray/texture/Texture.h | 31 --- ospray/texture/Texture.ih | 43 ++-- ospray/texture/Texture2D.cpp | 30 +-- ospray/texture/Texture2D.h | 13 +- ospray/texture/Texture2D.ispc | 266 ++++++++--------------- 24 files changed, 268 insertions(+), 357 deletions(-) delete mode 100644 ospray/texture/Texture.h diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 3c3249c4fb..67f677ddde 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -464,18 +464,20 @@ namespace ospray { return alreadyCreatedTextures[msgTex]; //TODO: We need to come up with a better way to handle different possible pixel layouts - OSPDataType type = OSP_VOID_PTR; + OSPTextureFormat type = OSP_TEXTURE_R8; if (msgTex->depth == 1) { - if( msgTex->channels == 3 ) type = OSP_UCHAR3; - if( msgTex->channels == 4 ) type = OSP_UCHAR4; + if( msgTex->channels == 1 ) type = OSP_TEXTURE_R8; + if( msgTex->channels == 3 ) type = OSP_TEXTURE_RGB8; + if( msgTex->channels == 4 ) type = OSP_TEXTURE_RGBA8; } else if (msgTex->depth == 4) { - if( msgTex->channels == 3 ) type = OSP_FLOAT3; - if( msgTex->channels == 4 ) type = OSP_FLOAT3A; + if( msgTex->channels == 1 ) type = OSP_TEXTURE_R32F; + if( msgTex->channels == 3 ) type = OSP_TEXTURE_RGB32F; + if( msgTex->channels == 4 ) type = OSP_TEXTURE_RGBA32F; } - OSPTexture2D ospTex = ospNewTexture2D( msgTex->width, - msgTex->height, + vec2i texSize(msgTex->width, msgTex->height); + OSPTexture2D ospTex = ospNewTexture2D( (osp::vec2i&)texSize, type, msgTex->data, 0); diff --git a/apps/qtViewer/sg/common/Texture2D.cpp b/apps/qtViewer/sg/common/Texture2D.cpp index d59a95599e..45d1a40e1f 100644 --- a/apps/qtViewer/sg/common/Texture2D.cpp +++ b/apps/qtViewer/sg/common/Texture2D.cpp @@ -85,7 +85,7 @@ namespace ospray { tex = new Texture2D; tex->size = vec2i(width,height); - tex->texelType = OSP_UCHAR3; + tex->texelType = OSP_TEXTURE_RGB8; tex->texel = new unsigned char[width*height*3]; fread(tex->texel,width*height*3,1,file); // flip in y, because OSPRay's textures have the origin at the lower left corner @@ -105,8 +105,7 @@ namespace ospray { { if (ospTexture) return; - ospTexture = ospNewTexture2D(size.x, - size.y, + ospTexture = ospNewTexture2D((osp::vec2i&)size, texelType, texel, 0); diff --git a/apps/qtViewer/sg/common/Texture2D.h b/apps/qtViewer/sg/common/Texture2D.h index cfea9acdbc..1f4a5179f6 100644 --- a/apps/qtViewer/sg/common/Texture2D.h +++ b/apps/qtViewer/sg/common/Texture2D.h @@ -42,7 +42,7 @@ namespace ospray { //! pixel data, in whatever format specified in 'texelType' void *texel; //! format of each texel - OSPDataType texelType; + OSPTextureFormat texelType; OSPTexture2D ospTexture; }; diff --git a/apps/qtViewer/sg/importer/ImportRIVL.cpp b/apps/qtViewer/sg/importer/ImportRIVL.cpp index ba696515f6..6540f3e000 100644 --- a/apps/qtViewer/sg/importer/ImportRIVL.cpp +++ b/apps/qtViewer/sg/importer/ImportRIVL.cpp @@ -83,10 +83,15 @@ namespace ospray { assert(channels != size_t(-1) && "Channel count not properly parsed for Texture2D nodes"); assert(depth != size_t(-1) && "Depth not properly parsed for Texture2D nodes"); - if (channels == 4 && depth == 1) txt.ptr->texelType = OSP_UCHAR4; - else if (channels == 3 && depth == 1) txt.ptr->texelType = OSP_UCHAR3; - else if (channels == 4) txt.ptr->texelType = OSP_FLOAT3A; - else if (channels == 3) txt.ptr->texelType = OSP_FLOAT3; + txt.ptr->texelType = OSP_TEXTURE_R8; + if (channels == 4 && depth == 1) + txt.ptr->texelType = OSP_TEXTURE_RGBA8; + else if (channels == 3 && depth == 1) + txt.ptr->texelType = OSP_TEXTURE_RGB8; + else if (channels == 4) + txt.ptr->texelType = OSP_TEXTURE_RGBA32F; + else if (channels == 3) + txt.ptr->texelType = OSP_TEXTURE_RGB32F; txt.ptr->size = vec2i(width, height); diff --git a/modules/opengl/util.cpp b/modules/opengl/util.cpp index b9e8c92a60..ba1e6a58b3 100644 --- a/modules/opengl/util.cpp +++ b/modules/opengl/util.cpp @@ -120,7 +120,8 @@ namespace ospray { } // nearest texture filtering required for depth textures -- we don't want interpolation of depth values... - OSPTexture2D depthTexture = ospNewTexture2D(glDepthBufferWidth, glDepthBufferHeight, OSP_FLOAT, ospDepth, OSP_TEXTURE_FILTER_NEAREST); + vec2i texSize(glDepthBufferWidth, glDepthBufferHeight); + OSPTexture2D depthTexture = ospNewTexture2D((osp::vec2i&)texSize, OSP_TEXTURE_R32F, ospDepth, OSP_TEXTURE_FILTER_NEAREST); delete[] ospDepth; diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 722de6e6e6..794da01e6f 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -89,7 +89,6 @@ SET(OSPRAY_SOURCES common/Material.cpp common/Library.cpp common/Thread.cpp - common/Texture.h common/parallel_for.h fb/FrameBuffer.ispc diff --git a/ospray/api/API.cpp b/ospray/api/API.cpp index c9f079e1cf..c236bcf291 100644 --- a/ospray/api/API.cpp +++ b/ospray/api/API.cpp @@ -186,7 +186,7 @@ namespace ospray { extern "C" OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, const OSPFrameBufferFormat mode, - const int channels) + const uint32_t channels) { ASSERT_DEVICE(); return ospray::api::Device::current->frameBufferCreate((const vec2i&)size,mode,channels); @@ -245,7 +245,7 @@ namespace ospray { } /*! create a new data buffer, with optional init data and control flags */ - extern "C" OSPData ospNewData(size_t nitems, OSPDataType format, const void *init, int flags) + extern "C" OSPData ospNewData(size_t nitems, OSPDataType format, const void *init, const uint32_t flags) { ASSERT_DEVICE(); return ospray::api::Device::current->newData(nitems,format,(void*)init,flags); @@ -385,17 +385,16 @@ namespace ospray { return camera; } - extern "C" OSPTexture2D ospNewTexture2D(int width, - int height, - OSPDataType type, + extern "C" OSPTexture2D ospNewTexture2D(const osp::vec2i &size, + const OSPTextureFormat type, void *data, - int flags) + const uint32_t flags) { ASSERT_DEVICE(); - Assert2(width > 0, "Width must be greater than 0 in ospNewTexture2D"); - Assert2(height > 0, "Height must be greater than 0 in ospNewTexture2D"); - LOG("ospNewTexture2D( " << width << ", " << height << ", " << type << ", " << data << ", " << flags << ")"); - return ospray::api::Device::current->newTexture2D(width, height, type, data, flags); + Assert2(size.x > 0, "Width must be greater than 0 in ospNewTexture2D"); + Assert2(size.y > 0, "Height must be greater than 0 in ospNewTexture2D"); + LOG("ospNewTexture2D( (" << size.x << ", " << size.y << "), " << type << ", " << data << ", " << flags << ")"); + return ospray::api::Device::current->newTexture2D((const vec2i&)size, type, data, flags); } /*! \brief create a new volume of given type, return 'NULL' if that type is not known */ diff --git a/ospray/api/COIDeviceHost.cpp b/ospray/api/COIDeviceHost.cpp index 45904c9c13..d3e417fe08 100644 --- a/ospray/api/COIDeviceHost.cpp +++ b/ospray/api/COIDeviceHost.cpp @@ -358,11 +358,8 @@ namespace ospray { OSPLight newLight(OSPRenderer _renderer, const char *type) override; /*! create a new Texture2D object */ - OSPTexture2D newTexture2D(int width, - int height, - OSPDataType type, - void *data, - int flags) override; + OSPTexture2D newTexture2D(const vec2i &size, const OSPTextureFormat, + void *data, const uint32 flags) override; /*! call a renderer to render a frame buffer */ void renderFrame(OSPFrameBuffer _sc, @@ -886,26 +883,23 @@ namespace ospray { } /*! create a new texture2D */ - OSPTexture2D COIDevice::newTexture2D(int width, - int height, - OSPDataType type, - void *data, - int flags) + OSPTexture2D COIDevice::newTexture2D(const vec2i &sz, + const OSPTextureFormat type, void *data, const uint32 flags) { COIRESULT result; DataStream args; ObjectHandle ID = ObjectHandle::alloc(); - if (width * height == 0) { + if (sz.x * sz.y == 0) { throw std::runtime_error("cowardly refusing to create empty texture..."); } args.write(ID); - args.write((int32)width); - args.write((int32)height); + args.write((int32)sz.x); + args.write((int32)sz.y); args.write((int32)type); args.write((int32)flags); - int64 numBytes = sizeOf(type)*width*height; + int64 numBytes = sizeOf(type) * sz.x * sz.y; for (auto &engine : engines) { COIBUFFER coiBuffer; // PRINT(nitems); diff --git a/ospray/api/COIDeviceWorker.cpp b/ospray/api/COIDeviceWorker.cpp index bf7c3a77a2..ded3dcac8c 100644 --- a/ospray/api/COIDeviceWorker.cpp +++ b/ospray/api/COIDeviceWorker.cpp @@ -520,14 +520,13 @@ namespace ospray { { DataStream args(argsPtr); ObjectHandle handle = args.get(); - int width = args.get(); - int height = args.get(); + vec2i size = args.get(); int type = args.get(); int flags = args.get(); COIBufferAddRef(bufferPtr[0]); - Texture2D *tx = Texture2D::createTexture(width, height, (OSPDataType)type, bufferPtr[0], flags); + Texture2D *tx = Texture2D::createTexture(size, (OSPTextureFormat)type, bufferPtr[0], flags); handle.assign(tx); if (ospray::debugMode) COIProcessProxyFlush(); diff --git a/ospray/api/Device.h b/ospray/api/Device.h index 3aea6c1654..bbddf398a0 100644 --- a/ospray/api/Device.h +++ b/ospray/api/Device.h @@ -43,7 +43,7 @@ namespace ospray { /*! map frame buffer */ virtual const void *frameBufferMap(OSPFrameBuffer fb, - OSPFrameBufferChannel) = 0; + const OSPFrameBufferChannel) = 0; /*! unmap previously mapped frame buffer */ virtual void frameBufferUnmap(const void *mapped, @@ -171,7 +171,8 @@ namespace ospray { virtual OSPMaterial newMaterial(OSPRenderer _renderer, const char *type) = 0; /*! create a new Texture2D object */ - virtual OSPTexture2D newTexture2D(int width, int height, OSPDataType type, void *data, int flags) = 0; + virtual OSPTexture2D newTexture2D(const vec2i &size, + const OSPTextureFormat, void *data, const uint32 flags) = 0; /*! have given renderer create a new Light */ virtual OSPLight newLight(OSPRenderer _renderer, const char *type) = 0; diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index a2c75f071e..eef08dfc58 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -613,10 +613,12 @@ namespace ospray { } /*! create a new Texture2D object */ - OSPTexture2D LocalDevice::newTexture2D(int width, int height, OSPDataType type, void *data, int flags) { - Assert(width > 0 && "Width must be greater than 0 in LocalDevice::newTexture2D"); - Assert(height > 0 && "Height must be greater than 0 in LocalDevice::newTexture2D"); - Texture2D *tx = Texture2D::createTexture(width, height, type, data, flags); + OSPTexture2D LocalDevice::newTexture2D(const vec2i &size, + const OSPTextureFormat type, void *data, const uint32 flags) + { + Assert(size.x > 0 && "Width must be greater than 0 in LocalDevice::newTexture2D"); + Assert(size.y > 0 && "Height must be greater than 0 in LocalDevice::newTexture2D"); + Texture2D *tx = Texture2D::createTexture(size, type, data, flags); if(tx) tx->refInc(); return (OSPTexture2D)tx; } diff --git a/ospray/api/LocalDevice.h b/ospray/api/LocalDevice.h index b644a3b8a4..fc419e8df8 100644 --- a/ospray/api/LocalDevice.h +++ b/ospray/api/LocalDevice.h @@ -195,11 +195,8 @@ namespace ospray { OSPLight newLight(OSPRenderer _renderer, const char *type) override; /*! create a new Texture2D object */ - OSPTexture2D newTexture2D(int width, - int height, - OSPDataType type, - void *data, - int flags) override; + OSPTexture2D newTexture2D(const vec2i &size, const OSPTextureFormat, + void *data, const uint32 flags) override; /*! clear the specified channel(s) of the frame buffer specified in 'whichChannels' diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index b9cd166552..3383733d02 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -157,8 +157,7 @@ namespace ospray { abort(); } - size_t sizeOf(OSPDataType type) { - + size_t sizeOf(const OSPDataType type) { switch (type) { case OSP_VOID_PTR: return sizeof(void *); case OSP_OBJECT: return sizeof(void *); @@ -196,11 +195,9 @@ namespace ospray { std::stringstream error; error << __FILE__ << ":" << __LINE__ << ": unknown OSPDataType " << (int)type; throw std::runtime_error(error.str()); - } OSPDataType typeForString(const char *string) { - if (string == NULL) return(OSP_UNKNOWN); if (strcmp(string, "char" ) == 0) return(OSP_CHAR); if (strcmp(string, "double") == 0) return(OSP_DOUBLE); @@ -221,7 +218,23 @@ namespace ospray { if (strcmp(string, "uint3" ) == 0) return(OSP_UINT3); if (strcmp(string, "uint4" ) == 0) return(OSP_UINT4); return(OSP_UNKNOWN); + } + size_t sizeOf(const OSPTextureFormat type) { + switch (type) { + case OSP_TEXTURE_RGBA8: + case OSP_TEXTURE_SRGBA: return sizeof(uint32); + case OSP_TEXTURE_RGBA32F: return sizeof(vec4f); + case OSP_TEXTURE_RGB8: + case OSP_TEXTURE_SRGB: return sizeof(vec3uc); + case OSP_TEXTURE_RGB32F: return sizeof(vec3f); + case OSP_TEXTURE_R8: return sizeof(uint8); + case OSP_TEXTURE_R32F: return sizeof(float); + } + + std::stringstream error; + error << __FILE__ << ":" << __LINE__ << ": unknown OSPTextureFormat " << (int)type; + throw std::runtime_error(error.str()); } } // ::ospray diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index d60837d313..04d2d31022 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -73,6 +73,7 @@ namespace ospray { #endif // ospray +#include "ospray/ospray.h" #include "ospray/common/OSPDataType.h" // std @@ -225,11 +226,14 @@ namespace ospray { extern int32 numThreads; /*! size of OSPDataType */ - OSPRAY_INTERFACE size_t sizeOf(OSPDataType type); + OSPRAY_INTERFACE size_t sizeOf(const OSPDataType); /*! Convert a type string to an OSPDataType. */ OSPRAY_INTERFACE OSPDataType typeForString(const char *string); + /*! size of OSPTextureFormat */ + OSPRAY_INTERFACE size_t sizeOf(const OSPTextureFormat); + struct WarnOnce { WarnOnce(const std::string &s); private: @@ -264,5 +268,3 @@ namespace ospray { template inline T divRoundUp(const T&a, const T&b) { return (a+(b-T(1)))/b; } - - diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 1ce3d0efa3..36d0e7e540 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -89,6 +89,7 @@ namespace osp { } // ::osp +/*! OSPRay channel constants for Frame Buffer (can be OR'ed together) */ typedef enum { OSP_FB_COLOR=(1<<0), OSP_FB_DEPTH=(1<<1), @@ -96,20 +97,27 @@ typedef enum { // OSP_FB_ALPHA=(1<<3) // not used anywhere; use OSP_FB_COLOR with a frame buffer format containing alpha in 4th channel } OSPFrameBufferChannel; -/*! OSPRay constants for Frame Buffer creation ('and' ed together) */ +/*! OSPRay format constants for Frame Buffer creation */ typedef enum { - OSP_RGBA_NONE, - OSP_RGBA_I8, /*!< one dword per pixel: rgb+alpha, each one byte */ - OSP_RGB_I8, /*!< three 8-bit unsigned chars per pixel XXX unsupported! */ - OSP_RGBA_F32, /*!< one float4 per pixel: rgb+alpha, each one float */ -// OSP_SRGBA_I8, /*!< one dword per pixel: rgb (in sRGB space) + alpha, each one byte */ -// OSP_SRGB_I8, /*!< three 8-bit unsigned chars (in sRGB space) per pixel */ + OSP_FB_NONE, //!< framebuffer will not be mapped by application + OSP_FB_RGBA8, //!< one dword per pixel: rgb+alpha, each one byte + OSP_FB_RGBA32F, //!< one float4 per pixel: rgb+alpha, each one float +/* TODO + OSP_FB_RGB8, //!< three 8-bit unsigned chars per pixel + OSP_FB_RGB32F, ? + OSP_FB_SRGBA, //!< one dword per pixel: rgb (in sRGB space) + alpha, each one byte + OSP_FB_SRGB, //!< three 8-bit unsigned chars (in sRGB space) per pixel +*/ +// deprecated names + OSP_RGBA_NONE = OSP_FB_NONE, + OSP_RGBA_I8 = OSP_FB_RGBA8, + OSP_RGBA_F32 = OSP_FB_RGBA32F, + OSP_RGB_I8/* = OSP_FB_RGB8 XXX unsupported! */ } OSPFrameBufferFormat; //! constants for switching the OSPRay MPI Scope between 'per rank' and 'all ranks' /*! \see ospdApiMode */ typedef enum { - //! \brief all ospNew(), ospSet(), etc calls affect only the current rank /*! \detailed in this mode, all ospXyz() calls made on a given rank will ONLY affect state ont hat rank. This allows for configuring a @@ -154,6 +162,25 @@ typedef enum { OSP_DATA_SHARED_BUFFER = (1<<0), } OSPDataCreationFlags; +/*! OSPRay format constants for Texture creation */ +typedef enum { + OSP_TEXTURE_RGBA8, + OSP_TEXTURE_SRGBA, + OSP_TEXTURE_RGBA32F, + OSP_TEXTURE_RGB8, + OSP_TEXTURE_SRGB, + OSP_TEXTURE_RGB32F, + OSP_TEXTURE_R8, + OSP_TEXTURE_R32F, +/* TODO + OSP_LogLuv, + OSP_RGBA16F + OSP_RGB16F + OSP_RGBE, // radiance hdr + compressed (RGTC, BPTC, ETC, ...) +*/ +} OSPTextureFormat; + /*! flags that can be passed to ospNewTexture2D(); can be OR'ed together */ typedef enum { OSP_TEXTURE_SHARED_BUFFER = (1<<0), @@ -216,7 +243,7 @@ extern "C" { renderer's parameters, typically in "world". */ OSPRAY_INTERFACE void ospRenderFrame(OSPFrameBuffer fb, OSPRenderer renderer, - const uint32_t fbChannelFlags=OSP_FB_COLOR); + const uint32_t whichChannels=OSP_FB_COLOR); //! create a new renderer of given type /*! return 'NULL' if that type is not known */ @@ -277,16 +304,17 @@ extern "C" { //! \brief create a new Texture2D with the given parameters /*! \detailed return 'NULL' if the texture could not be created with the given parameters */ - OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(int width, int height, OSPDataType type, void *data = NULL, int flags = 0); + OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(const osp::vec2i &size, + const OSPTextureFormat, void *data = NULL, const uint32_t flags = 0); //! \brief clears the specified channel(s) of the frame buffer /*! \detailed clear the specified channel(s) of the frame buffer specified in 'whichChannels' - if whichChannel&OSP_FB_COLOR!=0, clear the color buffer to '0,0,0,0' - if whichChannel&OSP_FB_DEPTH!=0, clear the depth buffer to +inf - if whichChannel&OSP_FB_ACCUM!=0, clear the accum buffer to 0,0,0,0, and reset accumID + if whichChannels & OSP_FB_COLOR != 0, clear the color buffer to '0,0,0,0' + if whichChannels & OSP_FB_DEPTH != 0, clear the depth buffer to +inf + if whichChannels & OSP_FB_ACCUM != 0, clear the accum buffer to 0,0,0,0, and reset accumID */ - OSPRAY_INTERFACE void ospFrameBufferClear(OSPFrameBuffer fb, const uint32_t whichChannel); + OSPRAY_INTERFACE void ospFrameBufferClear(OSPFrameBuffer, const uint32_t whichChannels); // ------------------------------------------------------- /*! \defgroup ospray_data Data Buffer Handling @@ -297,12 +325,13 @@ extern "C" { */ /*! create a new data buffer, with optional init data and control flags - Valid flags that can be or'ed together into the flags value: + Valid flags that can be OR'ed together into the flags value: - OSP_DATA_SHARED_BUFFER: indicates that the buffer can be shared with the app. In this case the calling program guarantees that the 'init' pointer will remain valid for the duration that this data array is being used. */ - OSPRAY_INTERFACE OSPData ospNewData(size_t numItems, OSPDataType format, const void *init=NULL, int flags=0); + OSPRAY_INTERFACE OSPData ospNewData(size_t numItems, OSPDataType format, + const void *init=NULL, const uint32_t dataCreationFlags=0); /*! \} */ @@ -329,7 +358,7 @@ extern "C" { corner (as in OpenGL). \param channelFlags specifies which channels the frame buffer has, - and is or'ed together from the values OSP_FB_COLOR, + and is OR'ed together from the values OSP_FB_COLOR, OSP_FB_DEPTH, and/or OSP_FB_ACCUM. If a certain buffer value is _not_ specified, the given buffer will not be present (see notes below). @@ -357,8 +386,8 @@ extern "C" { never ever be transferred to the application. */ OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, - const OSPFrameBufferFormat externalFormat=OSP_RGBA_I8, - const int channelFlags=OSP_FB_COLOR); + const OSPFrameBufferFormat=OSP_RGBA_I8, + const uint32_t whichChannels=OSP_FB_COLOR); /*! \brief free a framebuffer @@ -368,7 +397,7 @@ extern "C" { /*! \brief map app-side content of a framebuffer (see \ref frame_buffer_handling) */ OSPRAY_INTERFACE const void *ospMapFrameBuffer(OSPFrameBuffer fb, - OSPFrameBufferChannel=OSP_FB_COLOR); + const OSPFrameBufferChannel=OSP_FB_COLOR); /*! \brief unmap a previously mapped frame buffer (see \ref frame_buffer_handling) */ OSPRAY_INTERFACE void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer fb); @@ -446,7 +475,7 @@ extern "C" { OSPRAY_INTERFACE int ospSetRegion(/*! the object we're writing this block of pixels into */ OSPVolume object, /* points to the first voxel to be copies. The - voxels at 'soruce' MUST have dimensions + voxels at 'source' MUST have dimensions 'regionSize', must be organized in 3D-array order, and must have the same voxel type as the volume.*/ diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index 95a900fa09..d8b70e7f94 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -1085,18 +1085,17 @@ namespace ospray { } /*! create a new Texture2D object */ - OSPTexture2D MPIDevice::newTexture2D(int width, int height, - OSPDataType type, void *data, int flags) + OSPTexture2D MPIDevice::newTexture2D(const vec2i &sz, + const OSPTextureFormat type, void *data, const uint32 flags) { ObjectHandle handle = ObjectHandle::alloc(); cmd.newCommand(CMD_NEW_TEXTURE2D); cmd.send(handle); - cmd.send((int32)width); - cmd.send((int32)height); + cmd.send(sz); cmd.send((int32)type); cmd.send((int32)flags); assert(data); - size_t size = ospray::sizeOf(type)*width*height; + size_t size = ospray::sizeOf(type) * sz.x * sz.y; cmd.send(size); cmd.send(data,size); diff --git a/ospray/mpi/MPIDevice.h b/ospray/mpi/MPIDevice.h index 1991b2f3e3..b633bba44a 100644 --- a/ospray/mpi/MPIDevice.h +++ b/ospray/mpi/MPIDevice.h @@ -242,8 +242,8 @@ namespace ospray { void setMaterial(OSPGeometry _geom, OSPMaterial _mat) override; /*! create a new Texture2D object */ - OSPTexture2D newTexture2D(int width, int height, OSPDataType type, - void *data, int flags) override; + OSPTexture2D newTexture2D(const vec2i &size, const OSPTextureFormat, + void *data, const uint32 flags) override; /*! switch API mode for distriubted API extensions */ void apiMode(OSPDApiMode mode) override; diff --git a/ospray/mpi/worker.cpp b/ospray/mpi/worker.cpp index 8839fbe1bc..d700b5ebea 100644 --- a/ospray/mpi/worker.cpp +++ b/ospray/mpi/worker.cpp @@ -313,11 +313,11 @@ namespace ospray { case ospray::CMD_FRAMEBUFFER_CREATE: { const ObjectHandle handle = cmd.get_handle(); - const vec2i size = cmd.get_vec2i(); + const vec2i size = cmd.get_vec2i(); const OSPFrameBufferFormat mode = (OSPFrameBufferFormat)cmd.get_int32(); const uint32 channelFlags = cmd.get_int32(); - bool hasDepthBuffer = (channelFlags & OSP_FB_DEPTH); - bool hasAccumBuffer = (channelFlags & OSP_FB_ACCUM); + const bool hasDepthBuffer = (channelFlags & OSP_FB_DEPTH); + const bool hasAccumBuffer = (channelFlags & OSP_FB_ACCUM); // #if USE_DFB FrameBuffer *fb = new DistributedFrameBuffer(ospray::mpi::async::CommLayer::WORLD, size,handle,mode, @@ -418,15 +418,14 @@ namespace ospray { const ObjectHandle handle = cmd.get_handle(); Texture2D *texture2D = NULL; - int32 width = cmd.get_int32(); - int32 height = cmd.get_int32(); - int32 type = cmd.get_int32(); - int32 flags = cmd.get_int32(); - size_t size = cmd.get_size_t(); + const vec2i sz = cmd.get_vec2i(); + const int32 type = cmd.get_int32(); + const int32 flags = cmd.get_int32(); + const size_t size = cmd.get_size_t(); void *data = malloc(size); cmd.get_data(size,data); - texture2D = Texture2D::createTexture(width,height,(OSPDataType)type,data, + texture2D = Texture2D::createTexture(sz, (OSPTextureFormat)type, data, flags | OSP_DATA_SHARED_BUFFER); assert(texture2D); diff --git a/ospray/render/simpleAO/SimpleAO.h b/ospray/render/simpleAO/SimpleAO.h index 6a245a3472..beed40ac2d 100644 --- a/ospray/render/simpleAO/SimpleAO.h +++ b/ospray/render/simpleAO/SimpleAO.h @@ -33,7 +33,7 @@ // ospray #include "ospray/render/Renderer.h" -#include "ospray/texture/Texture.h" +#include "ospray/texture/Texture2D.h" namespace ospray { @@ -80,7 +80,7 @@ namespace ospray { vec3f Kd; //! \brief diffuse texture, if available - Ref map_Kd; + Ref map_Kd; }; diff --git a/ospray/texture/Texture.h b/ospray/texture/Texture.h deleted file mode 100644 index 952eeac354..0000000000 --- a/ospray/texture/Texture.h +++ /dev/null @@ -1,31 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - -#include "ospray/common/Managed.h" - -namespace ospray { - - /*! \brief implements the basic abstraction for anything that is a 'texture' */ - struct Texture : public ManagedObject - { - //! \brief common function to help printf-debugging - /*! Every derived class should overrride this! */ - virtual std::string toString() const { return "ospray::Texture"; } - }; - -} // ::ospray diff --git a/ospray/texture/Texture.ih b/ospray/texture/Texture.ih index b358cd53f7..6c8c709cbc 100644 --- a/ospray/texture/Texture.ih +++ b/ospray/texture/Texture.ih @@ -16,33 +16,30 @@ #pragma once -#include "ospray/math/vec.ih" - -struct Texture; +/*! OSPRay format constants for Texture creation */ +/*! \note Make sure these match the application-side definitions in ospray.h. */ +typedef enum { + OSP_TEXTURE_RGBA8, + OSP_TEXTURE_SRGBA, + OSP_TEXTURE_RGBA32F, + OSP_TEXTURE_RGB8, + OSP_TEXTURE_SRGB, + OSP_TEXTURE_RGB32F, + OSP_TEXTURE_R8, + OSP_TEXTURE_R32F, +/* TODO + OSP_LogLuv, + OSP_RGBA16F + OSP_RGB16F + OSP_RGBE, // radiance hdr + compressed (RGTC, BPTC, ETC, ...) +*/ +} OSPTextureFormat; //! \brief Texture creation flags provided by the application /*! \note Make sure these match the application-side definitions in ospray.h. */ typedef enum { OSP_TEXTURE_SHARED_BUFFER = (1<<0), OSP_TEXTURE_FILTER_NEAREST = (1<<1) -} Texture_CreationFlags; - -//!\brief virtual function type for sampling a Texture (of any type) -/*! \note Accessing y, z, or a from the returned value is undefined if the - texture has less than 4 channels */ -typedef varying vec4f (*Texture__get)(const uniform Texture *uniform this, - const varying vec2f& p); - -//! \brief Abstract base class for any type of (2D) texture -struct Texture -{ - //! virtual function for sampling this texture - Texture__get get; -}; +} OSPTextureCreationFlags; -//! constructor for 2D texture base class -inline void Texture__Constructor(uniform Texture* uniform self, - uniform Texture__get get) -{ - self->get = get; -} diff --git a/ospray/texture/Texture2D.cpp b/ospray/texture/Texture2D.cpp index 9c494da5dc..6d1f9fd55e 100644 --- a/ospray/texture/Texture2D.cpp +++ b/ospray/texture/Texture2D.cpp @@ -21,20 +21,21 @@ namespace ospray { Texture2D::~Texture2D() { - if (!(flags & OSP_TEXTURE_SHARED_BUFFER)) delete[] (unsigned char *)data; + if (!(flags & OSP_TEXTURE_SHARED_BUFFER)) + delete[] (unsigned char *)data; } - Texture2D *Texture2D::createTexture(int sx, int sy, OSPDataType type, void *data, int flags) + Texture2D *Texture2D::createTexture(const vec2i &size, + const OSPTextureFormat type, void *data, const int flags) { Texture2D *tx = new Texture2D; - tx->width = sx; - tx->height = sy; + tx->size = size; tx->type = type; tx->flags = flags; tx->managedObjectType = OSP_TEXTURE; - const size_t bytes = size_t(sx) * sy * sizeOf(type); + const size_t bytes = sizeOf(type) * size.x * size.y; assert(data); @@ -45,24 +46,7 @@ namespace ospray { memcpy(tx->data, data, bytes); } - switch (type) { - case OSP_UCHAR4: - tx->ispcEquivalent = ispc::Texture2D_4uc_create(sx,sy,tx->data,flags); - break; - case OSP_UCHAR3: - tx->ispcEquivalent = ispc::Texture2D_3uc_create(sx,sy,tx->data,flags); - break; - case OSP_FLOAT: - tx->ispcEquivalent = ispc::Texture2D_1f_create(sx,sy,tx->data,flags); - break; - case OSP_FLOAT3: - tx->ispcEquivalent = ispc::Texture2D_3f_create(sx,sy,tx->data,flags); - break; - case OSP_FLOAT3A: - tx->ispcEquivalent = ispc::Texture2D_4f_create(sx,sy,tx->data,flags); - break; - default: throw std::runtime_error("Could not determine bytes per pixel in " __FILE__); - } + tx->ispcEquivalent = ispc::Texture2D_create((ispc::vec2i&)size, tx->data, type, flags); return tx; } diff --git a/ospray/texture/Texture2D.h b/ospray/texture/Texture2D.h index 862883e66b..85b0f34295 100644 --- a/ospray/texture/Texture2D.h +++ b/ospray/texture/Texture2D.h @@ -16,13 +16,13 @@ #pragma once -#include "Texture.h" +#include "ospray/common/Managed.h" #include "../include/ospray/ospray.h" namespace ospray { /*! \brief A Texture defined through a 2D Image. */ - struct Texture2D : public Texture { + struct Texture2D : public ManagedObject { //! \brief common function to help printf-debugging /*! Every derived class should overrride this! */ @@ -31,12 +31,11 @@ namespace ospray { virtual ~Texture2D(); /*! \brief creates a Texture2D object with the given parameter */ - static Texture2D *createTexture(int width, int height, OSPDataType type, - void *data, int flags); + static Texture2D *createTexture(const vec2i &size, const OSPTextureFormat, + void *data, const int flags); - int width; - int height; - OSPDataType type; + vec2i size; + OSPTextureFormat type; void *data; int flags; }; diff --git a/ospray/texture/Texture2D.ispc b/ospray/texture/Texture2D.ispc index 35d15095e7..55d9b7a594 100644 --- a/ospray/texture/Texture2D.ispc +++ b/ospray/texture/Texture2D.ispc @@ -20,10 +20,12 @@ // Low-level texel accessors ////////////////////////////////////////////////////////////////////////////// -inline vec4f getTexel4uc(const uniform Texture2D *uniform self, const vec2i i) +// TODO blocking + +inline vec4f getTexel_rgba8(const uniform Texture2D *uniform self, const vec2i i) { assert(self); - const uint32 c = ((uniform uint32 *uniform)self->data)[i.y*self->size.x + i.x]; + const uint32 c = ((const uniform uint32 *uniform)self->data)[i.y*self->size.x + i.x]; const uint32 r = c & 255; const uint32 g = (c >> 8) & 255; const uint32 b = (c >> 16) & 255; @@ -31,7 +33,7 @@ inline vec4f getTexel4uc(const uniform Texture2D *uniform self, const vec2i i) return make_vec4f(r, g, b, a)*(1.f/255.f); } -inline vec4f getTexel3uc(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_rgb8(const uniform Texture2D *uniform self, const vec2i i) { assert(self); const uniform uint8 *uniform texel = (const uniform uint8 *uniform)self->data; @@ -42,25 +44,51 @@ inline vec4f getTexel3uc(const uniform Texture2D *uniform self, const vec2i i) return make_vec4f(make_vec3f(r, g, b)*(1.f/255.f), 1.f); } -// TODO: getTexel1uc, getTexel[34]uc_sRGB +inline vec4f getTexel_r8(const uniform Texture2D *uniform self, const vec2i i) +{ + assert(self); + const uint8 c = ((const uniform uint8 *uniform)self->data)[i.y*self->size.x + i.x]; + return make_vec4f(c*(1.f/255.f), 0.0f, 0.0f, 1.f); +} + +inline float srgb(const float c) +{ +// return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f); // exact + return pow(c, 2.2f); // approximate +} + +inline vec4f srgba(const vec4f c) +{ + return make_vec4f(srgb(c.x), srgb(c.y), srgb(c.z), c.w); +} + +inline vec4f getTexel_srgba(const uniform Texture2D *uniform self, const vec2i i) +{ + return srgba(getTexel_rgba8(self, i)); +} + +inline vec4f getTexel_srgb(const uniform Texture2D *uniform self, const vec2i i) +{ + return srgba(getTexel_rgb8(self, i)); +} -inline vec4f getTexel4f(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_rgba32f(const uniform Texture2D *uniform self, const vec2i i) { assert(self); - return ((uniform vec4f *uniform)self->data)[i.y*self->size.x + i.x]; + return ((const uniform vec4f *uniform)self->data)[i.y*self->size.x + i.x]; } -inline vec4f getTexel3f(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_rgb32f(const uniform Texture2D *uniform self, const vec2i i) { assert(self); - vec3f v = ((uniform vec3f*uniform )self->data)[i.y*self->size.x + i.x]; + vec3f v = ((const uniform vec3f*uniform )self->data)[i.y*self->size.x + i.x]; return make_vec4f(v, 1.f); } -inline vec4f getTexel1f(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_r32f(const uniform Texture2D *uniform self, const vec2i i) { assert(self); - float v = ((uniform float*uniform)self->data)[i.y*self->size.x + i.x]; + float v = ((const uniform float*uniform)self->data)[i.y*self->size.x + i.x]; return make_vec4f(v, 0.f, 0.f, 1.f); } @@ -122,175 +150,69 @@ inline vec4f bilerp(const vec2f frac, const vec4f c00, const vec4f c01, const ve // Implementations of Texture2D_get for different formats and filter modi ////////////////////////////////////////////////////////////////////////////// -static varying vec4f Texture2D_4uc_bilinear(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - BilinCoords coords = bilinear_coords(self, p); - - const vec4f c00 = getTexel4uc(self, make_vec2i(coords.st0.x, coords.st0.y)); - const vec4f c01 = getTexel4uc(self, make_vec2i(coords.st1.x, coords.st0.y)); - const vec4f c10 = getTexel4uc(self, make_vec2i(coords.st0.x, coords.st1.y)); - const vec4f c11 = getTexel4uc(self, make_vec2i(coords.st1.x, coords.st1.y)); - - return bilerp(coords.frac, c00, c01, c10, c11); -} - -static varying vec4f Texture2D_4uc_nearest(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - - return getTexel4uc(self, nearest_coords(self, p)); -} - -static varying vec4f Texture2D_3uc_bilinear(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - BilinCoords coords = bilinear_coords(self, p); - - const vec4f c00 = getTexel3uc(self, make_vec2i(coords.st0.x, coords.st0.y)); - const vec4f c01 = getTexel3uc(self, make_vec2i(coords.st1.x, coords.st0.y)); - const vec4f c10 = getTexel3uc(self, make_vec2i(coords.st0.x, coords.st1.y)); - const vec4f c11 = getTexel3uc(self, make_vec2i(coords.st1.x, coords.st1.y)); - - return bilerp(coords.frac, c00, c01, c10, c11); -} - -static varying vec4f Texture2D_3uc_nearest(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - - return getTexel3uc(self, nearest_coords(self, p)); -} - - -static varying vec4f Texture2D_4f_bilinear(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - BilinCoords coords = bilinear_coords(self, p); - - const vec4f c00 = getTexel4f(self, make_vec2i(coords.st0.x, coords.st0.y)); - const vec4f c01 = getTexel4f(self, make_vec2i(coords.st1.x, coords.st0.y)); - const vec4f c10 = getTexel4f(self, make_vec2i(coords.st0.x, coords.st1.y)); - const vec4f c11 = getTexel4f(self, make_vec2i(coords.st1.x, coords.st1.y)); - - return bilerp(coords.frac, c00, c01, c10, c11); -} - -static varying vec4f Texture2D_4f_nearest(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - - return getTexel4f(self, nearest_coords(self, p)); -} - - -static varying vec4f Texture2D_3f_bilinear(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - - BilinCoords coords = bilinear_coords(self, p); - - const vec4f c00 = getTexel3f(self, make_vec2i(coords.st0.x, coords.st0.y)); - const vec4f c01 = getTexel3f(self, make_vec2i(coords.st1.x, coords.st0.y)); - const vec4f c10 = getTexel3f(self, make_vec2i(coords.st0.x, coords.st1.y)); - const vec4f c11 = getTexel3f(self, make_vec2i(coords.st1.x, coords.st1.y)); - - return bilerp(coords.frac, c00, c01, c10, c11); -} - -static varying vec4f Texture2D_3f_nearest(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - - return getTexel3f(self, nearest_coords(self, p)); -} - - -static varying vec4f Texture2D_1f_bilinear(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - BilinCoords coords = bilinear_coords(self, p); - - const vec4f c00 = getTexel1f(self, make_vec2i(coords.st0.x, coords.st0.y)); - const vec4f c01 = getTexel1f(self, make_vec2i(coords.st1.x, coords.st0.y)); - const vec4f c10 = getTexel1f(self, make_vec2i(coords.st0.x, coords.st1.y)); - const vec4f c11 = getTexel1f(self, make_vec2i(coords.st1.x, coords.st1.y)); - - return bilerp(coords.frac, c00, c01, c10, c11); -} - -static varying vec4f Texture2D_1f_nearest(const uniform Texture2D *uniform self, - const varying vec2f &p) -{ - assert(self); - - return getTexel1f(self, nearest_coords(self, p)); -} +#define __define_tex_get(FMT) \ + \ +static vec4f Texture2D_nearest_##FMT(const uniform Texture2D *uniform self, \ + const vec2f &p) \ +{ \ + return getTexel_##FMT(self, nearest_coords(self, p)); \ +} \ + \ +static vec4f Texture2D_bilinear_##FMT(const uniform Texture2D *uniform self, \ + const vec2f &p) \ +{ \ + BilinCoords cs = bilinear_coords(self, p); \ + \ + const vec4f c00 = getTexel_##FMT(self, make_vec2i(cs.st0.x, cs.st0.y)); \ + const vec4f c01 = getTexel_##FMT(self, make_vec2i(cs.st1.x, cs.st0.y)); \ + const vec4f c10 = getTexel_##FMT(self, make_vec2i(cs.st0.x, cs.st1.y)); \ + const vec4f c11 = getTexel_##FMT(self, make_vec2i(cs.st1.x, cs.st1.y)); \ + \ + return bilerp(cs.frac, c00, c01, c10, c11); \ +} + +#define __define_tex_get_addr(FMT) \ + &Texture2D_bilinear_##FMT, \ + &Texture2D_nearest_##FMT, + +// same order as in OSPTextureFormat! +#define __foreach_fetcher(FCT) \ + FCT(rgba8) \ + FCT(srgba) \ + FCT(rgba32f) \ + FCT(rgb8) \ + FCT(srgb) \ + FCT(rgb32f) \ + FCT(r8) \ + FCT(r32f) + +__foreach_fetcher(__define_tex_get) + +static uniform Texture2D_get Texture2D_get_addr[] = { + __foreach_fetcher(__define_tex_get_addr) +}; - -uniform Texture2D *uniform Texture2D_create(uniform uint32 sizeX, - uniform uint32 sizeY, - void *uniform data, - uniform Texture2D_get get) -{ - uniform Texture2D *uniform self = uniform new uniform Texture2D; - self->size = make_vec2i(sizeX, sizeY); - self->sizef = make_vec2f(sizeX, sizeY) - 1e-12f; - self->halfTexel = make_vec2f(0.5f/sizeX, 0.5f/sizeY); - self->data = data; - self->get = get; - return self; -} +#undef __define_tex_get +#undef __define_tex_get_addr +#undef __foreach_fetcher // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// -export void *uniform Texture2D_4uc_create(uniform uint32 sizeX, - uniform uint32 sizeY, - void *uniform data, - uniform int flags) -{ - return Texture2D_create(sizeX,sizeY,data,flags & OSP_TEXTURE_FILTER_NEAREST ? &Texture2D_4uc_nearest : &Texture2D_4uc_bilinear); -} - -export void *uniform Texture2D_3uc_create(uniform uint32 sizeX, - uniform uint32 sizeY, - void *uniform data, - uniform int flags) +export void *uniform Texture2D_create(uniform vec2i &size, void *uniform data, + uniform uint32 type, uniform uint32 flags) { - return Texture2D_create(sizeX,sizeY,data,flags & OSP_TEXTURE_FILTER_NEAREST ? &Texture2D_3uc_nearest : &Texture2D_3uc_bilinear); -} - -export void *uniform Texture2D_4f_create(uniform uint32 sizeX, - uniform uint32 sizeY, - void *uniform data, - uniform int flags) -{ - return Texture2D_create(sizeX,sizeY,data,flags & OSP_TEXTURE_FILTER_NEAREST ? &Texture2D_4f_nearest : &Texture2D_4f_bilinear); -} + uniform Texture2D *uniform self = uniform new uniform Texture2D; + self->size = size; + self->sizef = make_vec2f(size.x, size.y) - 1e-12f; + self->halfTexel = make_vec2f(0.5f/size.x, 0.5f/size.y); + self->data = data; -export void *uniform Texture2D_3f_create(uniform uint32 sizeX, - uniform uint32 sizeY, - void *uniform data, - uniform int flags) -{ - return Texture2D_create(sizeX,sizeY,data,flags & OSP_TEXTURE_FILTER_NEAREST ? &Texture2D_3f_nearest : &Texture2D_3f_bilinear); -} + // select texture fetch function depending on format and filter + uniform int filter = flags & OSP_TEXTURE_FILTER_NEAREST ? 1 : 0; + uniform int fct_nr = type * 2 + filter; + self->get = Texture2D_get_addr[fct_nr]; -export void *uniform Texture2D_1f_create(uniform uint32 sizeX, - uniform uint32 sizeY, - void *uniform data, - uniform int flags) -{ - return Texture2D_create(sizeX,sizeY,data,flags & OSP_TEXTURE_FILTER_NEAREST ? &Texture2D_1f_nearest : &Texture2D_1f_bilinear); + return self; } From 4b6ddc1285de412ba6f51b73f9b7d456f2bee7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 3 Feb 2016 11:46:43 +0100 Subject: [PATCH 002/310] Use heuristic to import textures as linear or sRGB --- apps/modelViewer/miniSG/importOBJ.cpp | 8 ++++---- apps/modelViewer/miniSG/importRIVL.cpp | 1 + apps/modelViewer/miniSG/miniSG.cpp | 4 +++- apps/modelViewer/miniSG/miniSG.h | 3 ++- apps/modelViewer/modelViewer.cpp | 6 ++++-- apps/qtViewer/sg/common/Texture2D.cpp | 4 ++-- apps/qtViewer/sg/common/Texture2D.h | 2 +- apps/qtViewer/sg/importer/ImportOBJ.cpp | 12 ++++++------ 8 files changed, 23 insertions(+), 17 deletions(-) diff --git a/apps/modelViewer/miniSG/importOBJ.cpp b/apps/modelViewer/miniSG/importOBJ.cpp index eb55fde47e..223cba65f7 100644 --- a/apps/modelViewer/miniSG/importOBJ.cpp +++ b/apps/modelViewer/miniSG/importOBJ.cpp @@ -294,16 +294,16 @@ namespace ospray { if (!strncmp(token, "Ks", 2)) { parseSep(token += 2); cur->setParam("Ks", getVec3f(token)); continue; } if (!strncmp(token, "Tf", 2)) { parseSep(token += 2); cur->setParam("Tf", getVec3f(token)); continue; } - if (!strncmp(token, "map_d" , 5)) { parseSepOpt(token += 5); cur->setParam("map_d", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } - if (!strncmp(token, "map_Ns" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ns", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } + if (!strncmp(token, "map_d" , 5)) { parseSepOpt(token += 5); cur->setParam("map_d", loadTexture(path, std::string(token), true),Material::Param::TEXTURE); continue; } + if (!strncmp(token, "map_Ns" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ns", loadTexture(path, std::string(token), true),Material::Param::TEXTURE); continue; } if (!strncmp(token, "map_Ka" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ka", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } if (!strncmp(token, "map_Kd" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Kd", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } if (!strncmp(token, "map_Ks" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ks", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } /*! the following are extensions to the standard */ if (!strncmp(token, "map_Refl" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Refl", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } - if (!strncmp(token, "map_Bump" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Bump", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } + if (!strncmp(token, "map_Bump" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Bump", loadTexture(path, std::string(token), true),Material::Param::TEXTURE); continue; } - if (!strncmp(token, "bumpMap" , 7)) { parseSepOpt(token += 7); cur->setParam("map_Bump", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } + if (!strncmp(token, "bumpMap" , 7)) { parseSepOpt(token += 7); cur->setParam("map_Bump", loadTexture(path, std::string(token), true),Material::Param::TEXTURE); continue; } if (!strncmp(token, "colorMap" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Kd", loadTexture(path, std::string(token)),Material::Param::TEXTURE); continue; } if (!strncmp(token, "color", 5)) { parseSep(token += 5); cur->setParam("color", getVec3f(token)); continue; } diff --git a/apps/modelViewer/miniSG/importRIVL.cpp b/apps/modelViewer/miniSG/importRIVL.cpp index a5637b88f6..ce7040533c 100644 --- a/apps/modelViewer/miniSG/importRIVL.cpp +++ b/apps/modelViewer/miniSG/importRIVL.cpp @@ -234,6 +234,7 @@ namespace ospray { txt.ptr->texData->channels = channels; txt.ptr->texData->depth = depth; + txt.ptr->texData->prefereLinear = true; txt.ptr->texData->width = width; txt.ptr->texData->height = height; if (channels == 4) { // RIVL bin stores alpha channel inverted, fix here diff --git a/apps/modelViewer/miniSG/miniSG.cpp b/apps/modelViewer/miniSG/miniSG.cpp index 6607aa55d9..ca3069181a 100644 --- a/apps/modelViewer/miniSG/miniSG.cpp +++ b/apps/modelViewer/miniSG/miniSG.cpp @@ -44,7 +44,7 @@ namespace ospray { // setParam( "Ka", vec3f(0.f) ); } - Texture2D *loadTexture(const std::string &path, const std::string &fileNameBase) + Texture2D *loadTexture(const std::string &path, const std::string &fileNameBase, const bool prefereLinear) { const embree::FileName fileName = path+"/"+fileNameBase; @@ -111,6 +111,7 @@ namespace ospray { tex->height = height; tex->channels = 3; tex->depth = 1; + tex->prefereLinear = prefereLinear; tex->data = new unsigned char[width*height*3]; fread(tex->data,width*height*3,1,file); // flip in y, because OSPRay's textures have the origin at the lower left corner @@ -129,6 +130,7 @@ namespace ospray { tex->height = image.rows(); tex->channels = image.matte() ? 4 : 3; tex->depth = 4; + tex->prefereLinear = prefereLinear; float rcpMaxRGB = 1.0f/float(MaxRGB); const Magick::PixelPacket* pixels = image.getConstPixels(0,0,tex->width,tex->height); if (!pixels) { diff --git a/apps/modelViewer/miniSG/miniSG.h b/apps/modelViewer/miniSG/miniSG.h index ed69ec2021..04c205709f 100644 --- a/apps/modelViewer/miniSG/miniSG.h +++ b/apps/modelViewer/miniSG/miniSG.h @@ -37,12 +37,13 @@ namespace ospray { int channels; //Number of color channels per pixel int depth; //Bytes per color channel + bool prefereLinear; //A linear texel format is preferred over sRGB int width; //Pixels per row int height; //Pixels per column void *data; //Pointer to binary texture data }; - Texture2D *loadTexture(const std::string &path, const std::string &fileName); + Texture2D *loadTexture(const std::string &path, const std::string &fileName, const bool prefereLinear = false); struct Material : public RefCount { struct Param : public RefCount { diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 67f677ddde..8878ebf525 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -468,8 +468,10 @@ namespace ospray { if (msgTex->depth == 1) { if( msgTex->channels == 1 ) type = OSP_TEXTURE_R8; - if( msgTex->channels == 3 ) type = OSP_TEXTURE_RGB8; - if( msgTex->channels == 4 ) type = OSP_TEXTURE_RGBA8; + if( msgTex->channels == 3 ) + type = msgTex->prefereLinear ? OSP_TEXTURE_RGB8 : OSP_TEXTURE_SRGB; + if( msgTex->channels == 4 ) + type = msgTex->prefereLinear ? OSP_TEXTURE_RGBA8 : OSP_TEXTURE_SRGBA; } else if (msgTex->depth == 4) { if( msgTex->channels == 1 ) type = OSP_TEXTURE_R32F; if( msgTex->channels == 3 ) type = OSP_TEXTURE_RGB32F; diff --git a/apps/qtViewer/sg/common/Texture2D.cpp b/apps/qtViewer/sg/common/Texture2D.cpp index 45d1a40e1f..f94bbed5f1 100644 --- a/apps/qtViewer/sg/common/Texture2D.cpp +++ b/apps/qtViewer/sg/common/Texture2D.cpp @@ -23,7 +23,7 @@ namespace ospray { /*! \detailed if file does not exist, or cannot be loaded for some reason, return NULL. Multiple loads from the same file will return the *same* texture object */ - Ref Texture2D::load(const FileName &fileName) + Ref Texture2D::load(const FileName &fileName, const bool prefereLinear) { static std::map textureCache; if (textureCache.find(fileName.str()) != textureCache.end()) @@ -85,7 +85,7 @@ namespace ospray { tex = new Texture2D; tex->size = vec2i(width,height); - tex->texelType = OSP_TEXTURE_RGB8; + tex->texelType = prefereLinear ? OSP_TEXTURE_RGB8 : OSP_TEXTURE_SRGB; tex->texel = new unsigned char[width*height*3]; fread(tex->texel,width*height*3,1,file); // flip in y, because OSPRay's textures have the origin at the lower left corner diff --git a/apps/qtViewer/sg/common/Texture2D.h b/apps/qtViewer/sg/common/Texture2D.h index 1f4a5179f6..7f95943ee9 100644 --- a/apps/qtViewer/sg/common/Texture2D.h +++ b/apps/qtViewer/sg/common/Texture2D.h @@ -34,7 +34,7 @@ namespace ospray { /*! \detailed if file does not exist, or cannot be loaded for some reason, return NULL. Multiple loads from the same file will return the *same* texture object */ - static Ref load(const FileName &fileName); + static Ref load(const FileName &fileName, const bool prefereLinear = false); virtual void render(RenderContext &ctx); //! texture size, in pixels diff --git a/apps/qtViewer/sg/importer/ImportOBJ.cpp b/apps/qtViewer/sg/importer/ImportOBJ.cpp index 82be8e4aac..cf46d428e9 100644 --- a/apps/qtViewer/sg/importer/ImportOBJ.cpp +++ b/apps/qtViewer/sg/importer/ImportOBJ.cpp @@ -33,8 +33,8 @@ namespace ospray { using std::cout; using std::endl; - Ref loadTexture(const std::string &path, const std::string &fileName) - { return Texture2D::load(path+"/"+fileName); } + Ref loadTexture(const std::string &path, const std::string &fileName, const bool prefereLinear = false) + { return Texture2D::load(path+"/"+fileName, prefereLinear); } /*! Three-index vertex, indexing start at 0, -1 means invalid vertex. */ struct Vertex { @@ -291,16 +291,16 @@ namespace ospray { if (!strncmp(token, "Ks", 2)) { parseSep(token += 2); cur->setParam("Ks", getVec3f(token)); continue; } if (!strncmp(token, "Tf", 2)) { parseSep(token += 2); cur->setParam("Tf", getVec3f(token)); continue; } - if (!strncmp(token, "map_d" , 5)) { parseSepOpt(token += 5); cur->setParam("map_d", loadTexture(path, std::string(token))); continue; } - if (!strncmp(token, "map_Ns" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ns", loadTexture(path, std::string(token))); continue; } + if (!strncmp(token, "map_d" , 5)) { parseSepOpt(token += 5); cur->setParam("map_d", loadTexture(path, std::string(token), true)); continue; } + if (!strncmp(token, "map_Ns" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ns", loadTexture(path, std::string(token), true)); continue; } if (!strncmp(token, "map_Ka" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ka", loadTexture(path, std::string(token))); continue; } if (!strncmp(token, "map_Kd" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Kd", loadTexture(path, std::string(token))); continue; } if (!strncmp(token, "map_Ks" , 6)) { parseSepOpt(token += 6); cur->setParam("map_Ks", loadTexture(path, std::string(token))); continue; } /*! the following are extensions to the standard */ if (!strncmp(token, "map_Refl" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Refl", loadTexture(path, std::string(token))); continue; } - if (!strncmp(token, "map_Bump" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Bump", loadTexture(path, std::string(token))); continue; } + if (!strncmp(token, "map_Bump" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Bump", loadTexture(path, std::string(token), true)); continue; } - if (!strncmp(token, "bumpMap" , 7)) { parseSepOpt(token += 7); cur->setParam("map_Bump", loadTexture(path, std::string(token))); continue; } + if (!strncmp(token, "bumpMap" , 7)) { parseSepOpt(token += 7); cur->setParam("map_Bump", loadTexture(path, std::string(token), true)); continue; } if (!strncmp(token, "colorMap" , 8)) { parseSepOpt(token += 8); cur->setParam("map_Kd", loadTexture(path, std::string(token))); continue; } if (!strncmp(token, "color", 5)) { parseSep(token += 5); cur->setParam("color", getVec3f(token)); continue; } From 88b2f9f4917cddbf536a62c8dd3181e3a6eac72d Mon Sep 17 00:00:00 2001 From: Pavol Klacansky Date: Wed, 3 Feb 2016 14:43:12 +0000 Subject: [PATCH 003/310] Arguments to init function can be NULL --- ospray/common/OSPCommon.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 3383733d02..0caa922e62 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -106,6 +106,9 @@ namespace ospray { throw std::runtime_error("Error. OSPRay only runs on CPUs that support at least SSE4.1."); #endif + if (!_ac || !_av) + return; + int &ac = *_ac; char ** &av = *(char ***)_av; for (int i=1;i Date: Wed, 3 Feb 2016 15:46:23 +0100 Subject: [PATCH 004/310] Move OSPTexture enums into own header, shared with ISPC --- cmake/ospray.cmake | 2 ++ ospray/CMakeLists.txt | 3 +++ ospray/common/OSPCommon.h | 2 +- .../ospray/OSPTexture.h} | 7 +++-- ospray/include/ospray/ospray.h | 26 +------------------ ospray/texture/Texture2D.h | 2 +- ospray/texture/Texture2D.ih | 2 +- 7 files changed, 12 insertions(+), 32 deletions(-) rename ospray/{texture/Texture.ih => include/ospray/OSPTexture.h} (86%) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index f01a5f51b3..2e2c7e7d8b 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -183,9 +183,11 @@ MACRO(CONFIGURE_OSPRAY_NO_ARCH) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/ispc.cmake) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) + INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRECTORIES}) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}) + INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}/ospray/include) INCLUDE_DIRECTORIES_ISPC(${EMBREE_INCLUDE_DIRECTORIES}) # for auto-generated cmakeconfig etc diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 794da01e6f..c661dcfd8d 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -70,6 +70,9 @@ ENDIF() # ------------------------------------------------------- SET(OSPRAY_SOURCES + include/ospray/ospray.h + include/ospray/OSPTexture.h + device/nwlayer.cpp math/box.ispc diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index 04d2d31022..8e993d111f 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -73,8 +73,8 @@ namespace ospray { #endif // ospray -#include "ospray/ospray.h" #include "ospray/common/OSPDataType.h" +#include "ospray/OSPTexture.h" // std #include // for int64_t etc diff --git a/ospray/texture/Texture.ih b/ospray/include/ospray/OSPTexture.h similarity index 86% rename from ospray/texture/Texture.ih rename to ospray/include/ospray/OSPTexture.h index 6c8c709cbc..b79719447f 100644 --- a/ospray/texture/Texture.ih +++ b/ospray/include/ospray/OSPTexture.h @@ -14,10 +14,10 @@ // limitations under the License. // // ======================================================================== // +/*! This header is shared with ISPC. */ #pragma once /*! OSPRay format constants for Texture creation */ -/*! \note Make sure these match the application-side definitions in ospray.h. */ typedef enum { OSP_TEXTURE_RGBA8, OSP_TEXTURE_SRGBA, @@ -36,10 +36,9 @@ typedef enum { */ } OSPTextureFormat; -//! \brief Texture creation flags provided by the application -/*! \note Make sure these match the application-side definitions in ospray.h. */ +/*! flags that can be passed to ospNewTexture2D(); can be OR'ed together */ typedef enum { OSP_TEXTURE_SHARED_BUFFER = (1<<0), - OSP_TEXTURE_FILTER_NEAREST = (1<<1) + OSP_TEXTURE_FILTER_NEAREST = (1<<1) /*!< use nearest-neighbor interpolation rather than the default bilinear interpolation */ } OSPTextureCreationFlags; diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 36d0e7e540..322b99e8ab 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -38,6 +38,7 @@ #include #include "ospray/common/OSPDataType.h" +#include "ospray/OSPTexture.h" #ifdef _WIN32 # ifdef ospray_EXPORTS @@ -162,31 +163,6 @@ typedef enum { OSP_DATA_SHARED_BUFFER = (1<<0), } OSPDataCreationFlags; -/*! OSPRay format constants for Texture creation */ -typedef enum { - OSP_TEXTURE_RGBA8, - OSP_TEXTURE_SRGBA, - OSP_TEXTURE_RGBA32F, - OSP_TEXTURE_RGB8, - OSP_TEXTURE_SRGB, - OSP_TEXTURE_RGB32F, - OSP_TEXTURE_R8, - OSP_TEXTURE_R32F, -/* TODO - OSP_LogLuv, - OSP_RGBA16F - OSP_RGB16F - OSP_RGBE, // radiance hdr - compressed (RGTC, BPTC, ETC, ...) -*/ -} OSPTextureFormat; - -/*! flags that can be passed to ospNewTexture2D(); can be OR'ed together */ -typedef enum { - OSP_TEXTURE_SHARED_BUFFER = (1<<0), - OSP_TEXTURE_FILTER_NEAREST = (1<<1) /*!< use nearest-neighbor interpolation rather than the default bilinear interpolation */ -} OSPTextureCreationFlags; - typedef enum { OSP_OK=0, /*! no error; any value other than zero means 'some kind of error' */ OSP_GENERAL_ERROR /*! unspecified error */ diff --git a/ospray/texture/Texture2D.h b/ospray/texture/Texture2D.h index 85b0f34295..6862ffc5a2 100644 --- a/ospray/texture/Texture2D.h +++ b/ospray/texture/Texture2D.h @@ -17,7 +17,7 @@ #pragma once #include "ospray/common/Managed.h" -#include "../include/ospray/ospray.h" +#include "ospray/OSPTexture.h" namespace ospray { diff --git a/ospray/texture/Texture2D.ih b/ospray/texture/Texture2D.ih index dba5c7e235..8a564adf6f 100644 --- a/ospray/texture/Texture2D.ih +++ b/ospray/texture/Texture2D.ih @@ -16,7 +16,7 @@ #pragma once -#include "Texture.ih" +#include "ospray/OSPTexture.h" #include "ospray/common/default.ih" #include "ospray/math/vec.ih" From c9d25b18f1a86287d0dee23d91130c7a6ec2fba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 3 Feb 2016 15:51:21 +0100 Subject: [PATCH 005/310] Move OSPDataType.h to include dir --- ospray/CMakeLists.txt | 2 +- ospray/common/OSPCommon.h | 2 +- .../{common => include/ospray}/OSPDataType.h | 0 ospray/include/ospray/ospray.h | 2 +- ospray/volume/BlockBrickedVolume.ih | 2 +- ospray/volume/DataDistributedBlockedVolume.ih | 19 ------------------- ospray/volume/GhostBlockBrickedVolume.ih | 2 +- ospray/volume/SharedStructuredVolume.ih | 2 +- 8 files changed, 6 insertions(+), 25 deletions(-) rename ospray/{common => include/ospray}/OSPDataType.h (100%) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index c661dcfd8d..eac48c143c 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -71,6 +71,7 @@ ENDIF() SET(OSPRAY_SOURCES include/ospray/ospray.h + include/ospray/OSPDataType.h include/ospray/OSPTexture.h device/nwlayer.cpp @@ -85,7 +86,6 @@ SET(OSPRAY_SOURCES common/ISPC_KNL_Backend.h common/Managed.cpp common/ObjectHandle.cpp - common/OSPDataType.h common/Data.cpp common/Model.ispc common/Model.cpp diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index 8e993d111f..6fd5a3a2f9 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -73,7 +73,7 @@ namespace ospray { #endif // ospray -#include "ospray/common/OSPDataType.h" +#include "ospray/OSPDataType.h" #include "ospray/OSPTexture.h" // std diff --git a/ospray/common/OSPDataType.h b/ospray/include/ospray/OSPDataType.h similarity index 100% rename from ospray/common/OSPDataType.h rename to ospray/include/ospray/OSPDataType.h diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 322b99e8ab..dab2daffa1 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -37,7 +37,7 @@ #include #include -#include "ospray/common/OSPDataType.h" +#include "ospray/OSPDataType.h" #include "ospray/OSPTexture.h" #ifdef _WIN32 diff --git a/ospray/volume/BlockBrickedVolume.ih b/ospray/volume/BlockBrickedVolume.ih index 0d7f3dd548..593e91ff8d 100644 --- a/ospray/volume/BlockBrickedVolume.ih +++ b/ospray/volume/BlockBrickedVolume.ih @@ -16,7 +16,7 @@ #pragma once -#include "ospray/common/OSPDataType.h" +#include "ospray/OSPDataType.h" #include "ospray/volume/StructuredVolume.ih" //! \brief ISPC variables and functions for the BlockBrickedVolume class diff --git a/ospray/volume/DataDistributedBlockedVolume.ih b/ospray/volume/DataDistributedBlockedVolume.ih index 928c38277e..2ab56a962b 100644 --- a/ospray/volume/DataDistributedBlockedVolume.ih +++ b/ospray/volume/DataDistributedBlockedVolume.ih @@ -14,27 +14,8 @@ // limitations under the License. // // ======================================================================== // -#include "ospray/volume/BlockBrickedVolume.ih" - -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - #pragma once -#include "ospray/common/OSPDataType.h" #include "ospray/volume/StructuredVolume.ih" diff --git a/ospray/volume/GhostBlockBrickedVolume.ih b/ospray/volume/GhostBlockBrickedVolume.ih index f340fd1878..f0ede4cf06 100644 --- a/ospray/volume/GhostBlockBrickedVolume.ih +++ b/ospray/volume/GhostBlockBrickedVolume.ih @@ -16,7 +16,7 @@ #pragma once -#include "ospray/common/OSPDataType.h" +#include "ospray/OSPDataType.h" #include "ospray/volume/StructuredVolume.ih" //! \brief ISPC variables and functions for the GhostBlockBrickedVolume class diff --git a/ospray/volume/SharedStructuredVolume.ih b/ospray/volume/SharedStructuredVolume.ih index 547e6c2ac9..a1f77667d5 100644 --- a/ospray/volume/SharedStructuredVolume.ih +++ b/ospray/volume/SharedStructuredVolume.ih @@ -16,7 +16,7 @@ #pragma once -#include "ospray/common/OSPDataType.h" +#include "ospray/OSPDataType.h" #include "ospray/volume/StructuredVolume.ih" //! \brief ISPC variables and functions for the SharedStructuredVolume class From 67a8afe3b1a723c6206e6934dfffc1cdcb458a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 4 Feb 2016 14:20:51 +0100 Subject: [PATCH 006/310] Fix segfaults by *robustly* making sizef slightly smaller than size --- ospray/texture/Texture2D.ispc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ospray/texture/Texture2D.ispc b/ospray/texture/Texture2D.ispc index 55d9b7a594..ad489f642c 100644 --- a/ospray/texture/Texture2D.ispc +++ b/ospray/texture/Texture2D.ispc @@ -205,7 +205,12 @@ export void *uniform Texture2D_create(uniform vec2i &size, void *uniform data, { uniform Texture2D *uniform self = uniform new uniform Texture2D; self->size = size; - self->sizef = make_vec2f(size.x, size.y) - 1e-12f; + + // Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small + // negative x), although is should be strictly smaller than 1.0f. We handle + // this case by having sizef slightly smaller than size, such that + // frac(x)*sizef is always < size. + self->sizef = make_vec2f(nextafter(size.x, -1.0f), nextafter(size.y, -1.0f)); self->halfTexel = make_vec2f(0.5f/size.x, 0.5f/size.y); self->data = data; From 78cd04b12c6fd05fb9724cb3d425844fb9042ffb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 11 Feb 2016 10:44:58 -0600 Subject: [PATCH 007/310] fix merge bug --- ospray/render/simpleAO/SimpleAOMaterial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/render/simpleAO/SimpleAOMaterial.h b/ospray/render/simpleAO/SimpleAOMaterial.h index dc05f75e9c..5e0944d509 100644 --- a/ospray/render/simpleAO/SimpleAOMaterial.h +++ b/ospray/render/simpleAO/SimpleAOMaterial.h @@ -43,7 +43,7 @@ namespace ospray { vec3f Kd; //! \brief diffuse texture, if available - Ref map_Kd; + Ref map_Kd; }; }//namespace ospray::simpleao }//namespace ospray From 028e5aeca3cb37b8059db09a6a0d64dadfc7d186 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Thu, 18 Feb 2016 17:38:01 -0600 Subject: [PATCH 008/310] removed virtual createISPCEquivalent() in base Volume class - it's specific to structured volumes, but base volumes shouldnt care as long as they do the right thing in their commit() method --- ospray/volume/Volume.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/ospray/volume/Volume.h b/ospray/volume/Volume.h index cca919b774..72a95c396e 100644 --- a/ospray/volume/Volume.h +++ b/ospray/volume/Volume.h @@ -101,9 +101,6 @@ namespace ospray { protected: - //! Create the equivalent ISPC volume container. - virtual void createEquivalentISPC() = 0; - //! Complete volume initialization (only on first commit). virtual void finish(); From 1621464b23942cdb98d63b22a9f0480a031db995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 19 Feb 2016 16:09:39 +0100 Subject: [PATCH 009/310] Cleanups and syncs in (Ghost)BlockBrickedVolume --- ospray/volume/BlockBrickedVolume.cpp | 38 ++-- ospray/volume/BlockBrickedVolume.h | 8 +- ospray/volume/BlockBrickedVolume.ih | 4 +- ospray/volume/BlockBrickedVolume.ispc | 46 ++-- ospray/volume/GhostBlockBrickedVolume.cpp | 73 ++++--- ospray/volume/GhostBlockBrickedVolume.h | 1 - ospray/volume/GhostBlockBrickedVolume.ih | 13 +- ospray/volume/GhostBlockBrickedVolume.ispc | 231 +++++++++------------ 8 files changed, 187 insertions(+), 227 deletions(-) diff --git a/ospray/volume/BlockBrickedVolume.cpp b/ospray/volume/BlockBrickedVolume.cpp index 0a6021a1a2..0d7dc0c081 100644 --- a/ospray/volume/BlockBrickedVolume.cpp +++ b/ospray/volume/BlockBrickedVolume.cpp @@ -50,24 +50,21 @@ namespace ospray { StructuredVolume::commit(); } - int BlockBrickedVolume::setRegion(// points to the first voxel to be copies. - // The voxels at 'source' MUST have - // dimensions 'regionSize', must be - // organized in 3D-array order, and must - // have the same voxel type as the volume. - const void *source, - // coordinates of the lower, - // left, front corner of the target - // region. - const vec3i ®ionCoords, - // size of the region that we're writing to - // MUST be the same as the dimensions of - // source[][][] - const vec3i ®ionSize) + int BlockBrickedVolume::setRegion( + // points to the first voxel to be copied. The voxels at 'source' MUST + // have dimensions 'regionSize', must be organized in 3D-array order, and + // must have the same voxel type as the volume. + const void *source, + // coordinates of the lower, left, front corner of the target region + const vec3i ®ionCoords, + // size of the region that we're writing to, MUST be the same as the + // dimensions of source[][][] + const vec3i ®ionSize) { // Create the equivalent ISPC volume container and allocate memory for voxel // data. - if (ispcEquivalent == nullptr) createEquivalentISPC(); + if (ispcEquivalent == nullptr) + createEquivalentISPC(); /*! \todo check if we still need this 'computevoxelrange' - in theory we need this only if the app is allowed to query these @@ -101,11 +98,11 @@ namespace ospray { // Copy voxel data into the volume. const int NTASKS = regionSize.y * regionSize.z; parallel_for(NTASKS, [&](int taskIndex){ - ispc::BlockBrickedVolume_setRegion(ispcEquivalent, - source, - (const ispc::vec3i &) regionCoords, - (const ispc::vec3i &) regionSize, - taskIndex); + ispc::BlockBrickedVolume_setRegion(ispcEquivalent, + source, + (const ispc::vec3i &) regionCoords, + (const ispc::vec3i &) regionSize, + taskIndex); }); return true; @@ -139,5 +136,6 @@ namespace ospray { // A volume type with 64-bit addressing and multi-level bricked storage order. OSP_REGISTER_VOLUME(BlockBrickedVolume, block_bricked_volume); #endif + } // ::ospray diff --git a/ospray/volume/BlockBrickedVolume.h b/ospray/volume/BlockBrickedVolume.h index 0f488a7431..b8e7896a39 100644 --- a/ospray/volume/BlockBrickedVolume.h +++ b/ospray/volume/BlockBrickedVolume.h @@ -30,21 +30,21 @@ namespace ospray { ~BlockBrickedVolume(); //! A string description of this class. - std::string toString() const; + std::string toString() const override; //! Allocate storage and populate the volume, called through the OSPRay API. - void commit(); + void commit() override; //! Copy voxels into the volume at the given index (non-zero return value //! indicates success). int setRegion(const void *source, const vec3i &index, - const vec3i &count); + const vec3i &count) override; private: //! Create the equivalent ISPC volume container. - void createEquivalentISPC(); + void createEquivalentISPC() override; }; diff --git a/ospray/volume/BlockBrickedVolume.ih b/ospray/volume/BlockBrickedVolume.ih index 593e91ff8d..e6f12286c2 100644 --- a/ospray/volume/BlockBrickedVolume.ih +++ b/ospray/volume/BlockBrickedVolume.ih @@ -44,8 +44,8 @@ struct BlockBrickedVolume { /*! copy given block of voxels into the volume, where source[0] will be written to volume[targetCoord000] */ - void (*uniform setRegion)(BlockBrickedVolume *uniform _volume, - const void *uniform _source, + void (*uniform setRegion)(BlockBrickedVolume *uniform self, + const void *uniform source, const uniform vec3i ®ionSize, const uniform vec3i &targetCoord000, const uniform int taskIndex); diff --git a/ospray/volume/BlockBrickedVolume.ispc b/ospray/volume/BlockBrickedVolume.ispc index eb2486d589..a688a759af 100644 --- a/ospray/volume/BlockBrickedVolume.ispc +++ b/ospray/volume/BlockBrickedVolume.ispc @@ -317,25 +317,25 @@ inline varying float BlockBrickedVolumeFloat_computeSample(void *uniform _volume volume->transformWorldToLocal(volume, worldCoordinates, localCoordinates); // Coordinates outside the volume are clamped to the volume bounds. - const vec3f clampedLocalCoordinates = clamp(localCoordinates, make_vec3f(0.0f), + const vec3f clampedLocalCoordinates = clamp(localCoordinates, make_vec3f(0.0f), volume->localCoordinatesUpperBound); // Lower and upper corners of the box straddling the voxels to be interpolated. - const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); + const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); const vec3i voxelIndex_1 = voxelIndex_0 + 1; // Fractional coordinates within the lower corner voxel used during interpolation. const vec3f fractionalLocalCoordinates = clampedLocalCoordinates - float_cast(voxelIndex_0); // Look up the voxel values to be interpolated. - float voxelValue_000; - float voxelValue_001; - float voxelValue_010; - float voxelValue_011; - float voxelValue_100; - float voxelValue_101; - float voxelValue_110; - float voxelValue_111; + float voxelValue_000; + float voxelValue_001; + float voxelValue_010; + float voxelValue_011; + float voxelValue_100; + float voxelValue_101; + float voxelValue_110; + float voxelValue_111; BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_0.x, voxelIndex_0.y, voxelIndex_0.z), voxelValue_000); BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_1.x, voxelIndex_0.y, voxelIndex_0.z), voxelValue_001); BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_0.x, voxelIndex_1.y, voxelIndex_0.z), voxelValue_010); @@ -373,21 +373,17 @@ export void *uniform BlockBrickedVolume_createInstance(void *uniform cppEquivale return volume; } -export void -BlockBrickedVolume_setRegion(void *uniform _self, - /* points to the first voxel to be copies. The - voxels at 'soruce' MUST have dimensions - 'regionSize', must be organized in 3D-array - order, and must have the same voxel type as the - volume.*/ - const void *uniform _source, - /*! coordinates of the lower, left, front corner of - the target region.*/ - const uniform vec3i ®ionCoords, - /*! size of the region that we're writing to; MUST - be the same as the dimensions of source[][][] */ - const uniform vec3i ®ionSize, - const uniform int taskIndex) +export void BlockBrickedVolume_setRegion(void *uniform _self, + // points to the first voxel to be copied. The voxels at 'source' MUST have + // dimensions 'regionSize', must be organized in 3D-array order, and must + // have the same voxel type as the volume. + const void *uniform _source, + // coordinates of the lower, left, front corner of the target region + const uniform vec3i ®ionCoords, + // size of the region that we're writing to, MUST be the same as the + // dimensions of source[][][] + const uniform vec3i ®ionSize, + const uniform int taskIndex) { // Cast to the actual Volume subtype. BlockBrickedVolume *uniform self = (BlockBrickedVolume *uniform)_self; diff --git a/ospray/volume/GhostBlockBrickedVolume.cpp b/ospray/volume/GhostBlockBrickedVolume.cpp index c70a0ed494..759cd5c537 100644 --- a/ospray/volume/GhostBlockBrickedVolume.cpp +++ b/ospray/volume/GhostBlockBrickedVolume.cpp @@ -16,6 +16,7 @@ //ospray #include "ospray/volume/GhostBlockBrickedVolume.h" +#include "ospray/common/parallel_for.h" #include "GhostBlockBrickedVolume_ispc.h" // std #include @@ -27,7 +28,7 @@ namespace ospray { GhostBlockBrickedVolume::~GhostBlockBrickedVolume() { if (ispcEquivalent) { - ispc::GGBV_freeVolume(ispcEquivalent); + ispc::GBBV_freeVolume(ispcEquivalent); } } @@ -43,7 +44,7 @@ namespace ospray { // to 'setRegion', and only a final commit at the // end. 'dimensions' etc may/will _not_ be committed before // setregion. - exitOnCondition(ispcEquivalent == NULL, + exitOnCondition(ispcEquivalent == nullptr, "the volume data must be set via ospSetRegion() " "prior to commit for this volume type"); @@ -51,30 +52,29 @@ namespace ospray { StructuredVolume::commit(); } - int GhostBlockBrickedVolume::setRegion(/* points to the first voxel to be copies. The - voxels at 'source' MUST have dimensions - 'regionSize', must be organized in 3D-array - order, and must have the same voxel type as the - volume.*/ - const void *source, - /*! coordinates of the lower, - left, front corner of the target - region.*/ - const vec3i ®ionCoords, - /*! size of the region that we're writing to; MUST - be the same as the dimensions of source[][][] */ + int GhostBlockBrickedVolume::setRegion( + // points to the first voxel to be copied. The voxels at 'source' MUST + // have dimensions 'regionSize', must be organized in 3D-array order, and + // must have the same voxel type as the volume. + const void *source, + // coordinates of the lower, left, front corner of the target region + const vec3i ®ionCoords, + // size of the region that we're writing to, MUST be the same as the + // dimensions of source[][][] const vec3i ®ionSize) { - if (g_dbg) PING; - // Create the equivalent ISPC volume container and allocate memory for voxel data. - if (ispcEquivalent == NULL) createEquivalentISPC(); + // Create the equivalent ISPC volume container and allocate memory for voxel + // data. + if (ispcEquivalent == nullptr) + createEquivalentISPC(); /*! \todo check if we still need this 'computevoxelrange' - in theory we need this only if the app is allowed to query these values, and they're not being set in sharedstructuredvolume, either, so should we actually set them at all!? */ - // Compute the voxel value range for unsigned byte voxels if none was previously specified. - Assert2(source,"NULL source in GhostBlockBrickedVolume::setRegion()"); + // Compute the voxel value range for unsigned byte voxels if none was + // previously specified. + Assert2(source,"nullptr source in GhostBlockBrickedVolume::setRegion()"); #ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP if (findParam("voxelRange") == NULL) { @@ -84,38 +84,45 @@ namespace ospray { = (size_t)regionSize.x * + (size_t)regionSize.y * + (size_t)regionSize.z; - if (voxelType == "uchar") + if (voxelType == "uchar") computeVoxelRange((unsigned char *)source, numVoxelsInRegion); - else if (voxelType == "float") + else if (voxelType == "float") computeVoxelRange((float *)source, numVoxelsInRegion); - else if (voxelType == "double") + else if (voxelType == "double") computeVoxelRange((double *) source, numVoxelsInRegion); - else + else throw std::runtime_error("invalid voxelType in GhostBlockBrickedVolume::setRegion()"); } #endif // Copy voxel data into the volume. - ispc::GGBV_setRegion(ispcEquivalent, source, - (const ispc::vec3i &) regionCoords, - (const ispc::vec3i &) regionSize); + const int NTASKS = regionSize.y * regionSize.z; + parallel_for(NTASKS, [&](int taskIndex){ + ispc::GBBV_setRegion(ispcEquivalent, + source, + (const ispc::vec3i &) regionCoords, + (const ispc::vec3i &) regionSize, + taskIndex); + }); + return true; } - void GhostBlockBrickedVolume::createEquivalentISPC() + void GhostBlockBrickedVolume::createEquivalentISPC() { // Get the voxel type. - voxelType = getParamString("voxelType", "unspecified"); - exitOnCondition(getVoxelType() == OSP_UNKNOWN, + voxelType = getParamString("voxelType", "unspecified"); + exitOnCondition(getVoxelType() == OSP_UNKNOWN, "unrecognized voxel type (must be set before calling ospSetRegion())"); // Get the volume dimensions. this->dimensions = getParam3i("dimensions", vec3i(0)); - exitOnCondition(reduce_min(this->dimensions) <= 0, + exitOnCondition(reduce_min(this->dimensions) <= 0, "invalid volume dimensions (must be set before calling ospSetRegion())"); - // Create an ISPC GhostBlockBrickedVolume object and assign type-specific function pointers. - ispcEquivalent = ispc::GGBV_createInstance(this, - (int)getVoxelType(), + // Create an ISPC GhostBlockBrickedVolume object and assign type-specific + // function pointers. + ispcEquivalent = ispc::GBBV_createInstance(this, + (int)getVoxelType(), (const ispc::vec3i &)this->dimensions); } diff --git a/ospray/volume/GhostBlockBrickedVolume.h b/ospray/volume/GhostBlockBrickedVolume.h index 618ed9d605..d2965d84e1 100644 --- a/ospray/volume/GhostBlockBrickedVolume.h +++ b/ospray/volume/GhostBlockBrickedVolume.h @@ -27,7 +27,6 @@ namespace ospray { class GhostBlockBrickedVolume : public StructuredVolume { public: - //! Destructor. ~GhostBlockBrickedVolume(); //! A string description of this class. diff --git a/ospray/volume/GhostBlockBrickedVolume.ih b/ospray/volume/GhostBlockBrickedVolume.ih index f0ede4cf06..f5b9b3889f 100644 --- a/ospray/volume/GhostBlockBrickedVolume.ih +++ b/ospray/volume/GhostBlockBrickedVolume.ih @@ -44,14 +44,15 @@ struct GhostBlockBrickedVolume { /*! copy given block of voxels into the volume, where source[0] will be written to volume[targetCoord000] */ - void (*uniform setRegion)(void *uniform _volume, - const void *uniform _source, - const uniform vec3i ®ionSize, - const uniform vec3i &targetCoord000); + void (*uniform setRegion)(GhostBlockBrickedVolume *uniform self, + const void *uniform source, + const uniform vec3i ®ionSize, + const uniform vec3i &targetCoord000, + const uniform int taskIndex); }; -void GhostBlockBrickedVolume_Constructor(GhostBlockBrickedVolume *uniform volume, +void GhostBlockBrickedVolume_Constructor(GhostBlockBrickedVolume *uniform volume, /*! pointer to the c++-equivalent class of this entity */ void *uniform cppEquivalent, - const uniform int voxelType, + const uniform int voxelType, const uniform vec3i &dimensions); diff --git a/ospray/volume/GhostBlockBrickedVolume.ispc b/ospray/volume/GhostBlockBrickedVolume.ispc index b9adaf959a..9e2c17a660 100644 --- a/ospray/volume/GhostBlockBrickedVolume.ispc +++ b/ospray/volume/GhostBlockBrickedVolume.ispc @@ -19,7 +19,7 @@ /*! total number of bits per block dimension. '6' would mean 18 bits = 1/4million voxels per block, which for alots would be 1MB, so should all fit into a single 2M page (assuming we do 2M allocs, of course) */ -#define BLOCK_BITS (6) +#define BLOCK_BITS (6) #define BRICK_BITS (2) /*! @{ number of voxels per block per dimension */ @@ -34,7 +34,7 @@ /*! size of one block, in voxels */ #define VOXELS_PER_BLOCK (BLOCK_WIDTH*BLOCK_WIDTH*BLOCK_WIDTH) -/*! @{ start bit for given section of address in bricked offset field +/*! @{ start bit for given section of address in bricked offset field lo is the address part for inside a brick, hi is the remaining part inside the blcok ex the brick part @@ -73,15 +73,15 @@ type */ /*! do a simple type rename/abbreviation, to we have shorter type names */ -typedef GhostBlockBrickedVolume GGBV; +typedef GhostBlockBrickedVolume GBBV; /*! structure that encodes a block:offset style address for a single - sample */ + sample */ struct Address { - + //! The 1D address of the block in the volume containing the voxel. varying uint32 block; - + //! The 1D offset of the voxel in the enclosing block. varying uint32 voxel; }; @@ -91,10 +91,10 @@ struct Address { ID, base of the lower-left, and offset's to the +1's in x,y,and z. Deltas fully contain the effet of bricking */ struct Address8 { - + //! The 1D address of the block in the volume containing the voxel. varying uint32 block; - + //! The 1D offset (in bytes!) of the voxel in the enclosing block. varying uint32 voxelOfs; /*! the offset we have to add to voxelofs to go to the next voxel in @@ -161,7 +161,7 @@ template_brickTranslation(double); #define template_getAddress(type) \ /* IMPORTANT: this function computes RAW adresses that are to be */ \ /* directy added to "unsigned char *" pointers */ \ - inline void GGBV_getAddress_##type(GGBV *uniform volume, \ + inline void GBBV_getAddress_##type(GBBV *uniform volume, \ const vec3f &voxelIdxInVolume_f, \ const vec3i &voxelIdxInVolume, \ varying Address8 &address) \ @@ -186,7 +186,7 @@ template_brickTranslation(double); /* IMPORTANT: this function computes type-relative offsets, so */ \ /* values returned from this function should only be added to */ \ /* "type *" pointers */ \ - inline void GGBV_getIndices_##type(GGBV *uniform volume, \ + inline void GBBV_getIndices_##type(GBBV *uniform volume, \ const varying vec3i &voxelIdxInVolume, \ varying Address &address) \ { \ @@ -242,7 +242,7 @@ template_getAddress(double); because certain values will get recomputed for each of the 7 direction (plus the original cell itself) but this is the easiest (I could find). */ -inline bool GGBV_getGhostIndices(GGBV *uniform volume, +inline bool GBBV_getGhostIndices(GBBV *uniform volume, const varying vec3i &voxelIdxInVolume, const uniform vec3i delta, varying Address &address) @@ -250,7 +250,7 @@ inline bool GGBV_getGhostIndices(GGBV *uniform volume, // do not set offset value for original sample if ((delta.x == 0) && (delta.y == 0) && (delta.z == 0)) return false; - + // Compute the 3D index of the block containing the brick containing the voxel. // vec3i blockIndex = voxelIdxInVolume / make_vec3i(BLOCK_WIDTH-1); vec3i blockIndex = make_vec3i(intDiv(voxelIdxInVolume.x), @@ -278,24 +278,24 @@ inline bool GGBV_getGhostIndices(GGBV *uniform volume, --blockIndex.z; valid = true; } - + // Compute the 1D address of the block in the volume. address.block = blockIndex.x + volume->blockCount.x * (blockIndex.y + volume->blockCount.y * blockIndex.z); - + const vec3i brickIdxInBlock = voxelIdxInBlock >> BRICK_BITS; const vec3i voxelIdxInBrick = bitwise_AND(voxelIdxInBlock,BRICK_MASK); - + // Compute the 1D address of the voxel in the block. address.voxel = - (voxelIdxInBrick.x << (BRICK_BIT_X_LO)) | - (voxelIdxInBrick.y << (BRICK_BIT_Y_LO)) | - (voxelIdxInBrick.z << (BRICK_BIT_Z_LO)) | - (brickIdxInBlock.x << (BRICK_BIT_X_HI)) | - (brickIdxInBlock.y << (BRICK_BIT_Y_HI)) | - (brickIdxInBlock.z << (BRICK_BIT_Z_HI)); + (voxelIdxInBrick.x << (BRICK_BIT_X_LO)) | + (voxelIdxInBrick.y << (BRICK_BIT_Y_LO)) | + (voxelIdxInBrick.z << (BRICK_BIT_Z_LO)) | + (brickIdxInBlock.x << (BRICK_BIT_X_HI)) | + (brickIdxInBlock.y << (BRICK_BIT_Y_HI)) | + (brickIdxInBlock.z << (BRICK_BIT_Z_HI)); return valid && (blockIndex.x >=0) && (blockIndex.y >= 0) && (blockIndex.z >= 0); } @@ -313,21 +313,21 @@ inline bool GGBV_getGhostIndices(GGBV *uniform volume, uniform uint8 *uniform base = (uniform uint8 *uniform)basePtr; \ return *((uniform type *)(base+offset)); \ } \ - + template_accessArray(uint8); template_accessArray(float); template_accessArray(double); #undef template_accessArray - + #define template_getVoxel(type) \ /*! get a single voxel. careful - THIS function operates on */ \ /* typed offsets, not byte-offsets */ \ - inline void GGBV_getVoxel_##type(void *uniform _volume, \ + inline void GBBV_getVoxel_##type(void *uniform _volume, \ const varying vec3i &index, \ varying float &value) \ { \ /* Cast to the actual Volume subtype. */ \ - GGBV *uniform volume = (GGBV *uniform) _volume; \ + GBBV *uniform volume = (GBBV *uniform) _volume; \ \ /* Cast to the actual voxel type.*/ \ const type *uniform blockMem \ @@ -335,7 +335,7 @@ template_accessArray(double); \ /* Compute the 1D address of the block in the volume and the voxel in the block. */ \ Address address; \ - GGBV_getIndices_##type(volume, index, address); \ + GBBV_getIndices_##type(volume, index, address); \ \ /* The voxel value at the 1D address.*/ \ foreach_unique(blockID in address.block) { \ @@ -351,7 +351,7 @@ template_getVoxel(float) template_getVoxel(double) #undef template_getVoxel -inline void GGBV_allocateMemory(GGBV *uniform volume) +inline void GBBV_allocateMemory(GBBV *uniform volume) { // Memory may already have been allocated. if (volume->blockMem != NULL) return; @@ -372,11 +372,13 @@ inline void GGBV_allocateMemory(GGBV *uniform volume) } } -task void PBBVUChar_setRegionTask(GGBV *uniform self, - const uint8 *uniform source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize) +void GBBVUChar_setRegionTask(GBBV *uniform self, + const void *uniform _source, + const uniform vec3i &targetCoord000, + const uniform vec3i ®ionSize, + const uniform int taskIndex) { + const uint8 *uniform source = (const uint8 *uniform)_source; const uniform uint32 region_y = taskIndex % regionSize.y; const uniform uint32 region_z = taskIndex / regionSize.y; const uniform uint64 runOfs @@ -384,7 +386,7 @@ task void PBBVUChar_setRegionTask(GGBV *uniform self, const uint8 *uniform run = source + runOfs; vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); foreach (x = 0 ... regionSize.x) { - Address address; + Address address; coord.x = targetCoord000.x + x; if (coord.x < 0 || coord.y < 0 || @@ -395,20 +397,20 @@ task void PBBVUChar_setRegionTask(GGBV *uniform self, ) continue; - GGBV_getIndices_uint8(self, coord, address); + GBBV_getIndices_uint8(self, coord, address); foreach_unique(blockID in address.block) { uint8 *uniform blockPtr - = ((uint8*uniform)self->blockMem) + = ((uint8*uniform)self->blockMem) + blockID * (uint64)VOXELS_PER_BLOCK; blockPtr[address.voxel] = run[x]; } for (uniform int32 iz=0;iz<2;iz++) for (uniform int32 iy=0;iy<2;iy++) for (uniform int32 ix=0;ix<2;ix++) { - if (GGBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { + if (GBBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { foreach_unique(blockID in address.block) { uint8 *uniform blockPtr - = ((uint8*uniform)self->blockMem) + = ((uint8*uniform)self->blockMem) + (uint64)blockID * (uint64)VOXELS_PER_BLOCK; blockPtr[address.voxel] = run[x]; } @@ -417,11 +419,13 @@ task void PBBVUChar_setRegionTask(GGBV *uniform self, } } -task void PBBVFloat_setRegionTask(GGBV *uniform self, - const float *uniform source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize) +void GBBVFloat_setRegionTask(GBBV *uniform self, + const void *uniform _source, + const uniform vec3i &targetCoord000, + const uniform vec3i ®ionSize, + const uniform int taskIndex) { + const float *uniform source = (const float *uniform)_source; const uniform uint32 region_y = taskIndex % regionSize.y; const uniform uint32 region_z = taskIndex / regionSize.y; const uniform uint64 runOfs @@ -429,7 +433,7 @@ task void PBBVFloat_setRegionTask(GGBV *uniform self, const float *uniform run = source + runOfs; vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); foreach (x = 0 ... regionSize.x) { - Address address; + Address address; coord.x = targetCoord000.x + x; if (coord.x < 0 || coord.y < 0 || @@ -440,11 +444,11 @@ task void PBBVFloat_setRegionTask(GGBV *uniform self, ) continue; - GGBV_getIndices_float(self, coord, address); + GBBV_getIndices_float(self, coord, address); // set voxel itself foreach_unique(blockID in address.block) { float *uniform blockPtr - = ((float*uniform)self->blockMem) + = ((float*uniform)self->blockMem) + blockID * (uint64)VOXELS_PER_BLOCK; blockPtr[address.voxel] = run[x]; } @@ -452,10 +456,10 @@ task void PBBVFloat_setRegionTask(GGBV *uniform self, for (uniform int32 iz=0;iz<2;iz++) for (uniform int32 iy=0;iy<2;iy++) for (uniform int32 ix=0;ix<2;ix++) { - if (GGBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { + if (GBBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { foreach_unique(blockID in address.block) { float *uniform blockPtr - = ((float*uniform)self->blockMem) + = ((float*uniform)self->blockMem) + blockID * (uint64)VOXELS_PER_BLOCK; blockPtr[address.voxel] = run[x]; } @@ -464,11 +468,13 @@ task void PBBVFloat_setRegionTask(GGBV *uniform self, } } -task void PBBVDouble_setRegionTask(GGBV *uniform self, - const double *uniform source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize) +void GBBVDouble_setRegionTask(GBBV *uniform self, + const void *uniform _source, + const uniform vec3i &targetCoord000, + const uniform vec3i ®ionSize, + const uniform int taskIndex) { + const double *uniform source = (const double *uniform)_source; const uniform uint32 region_y = taskIndex % regionSize.y; const uniform uint32 region_z = taskIndex / regionSize.y; const uniform uint64 runOfs = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); @@ -485,7 +491,7 @@ task void PBBVDouble_setRegionTask(GGBV *uniform self, coord.z >= self->super.dimensions.z ) continue; - GGBV_getIndices_double(self, coord, address); + GBBV_getIndices_double(self, coord, address); foreach_unique(blockID in address.block) { double *uniform blockPtr = ((double*uniform)self->blockMem) @@ -494,51 +500,6 @@ task void PBBVDouble_setRegionTask(GGBV *uniform self, } } } - -/*! copy given block of voxels into the volume, where source[0] will - be written to volume[targetCoord000] */ -void GGBVUChar_setRegion(void *uniform _volume, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize) -{ - // a 'run' is sequence of connected voxels in x direction - uniform uint32 numRuns = regionSize.y * regionSize.z; - launch[numRuns] PBBVUChar_setRegionTask((GGBV*uniform)_volume, - (const uint8*uniform)_source, - targetCoord000, - regionSize); -} - -/*! copy given block of voxels into the volume, where source[0] will - be written to volume[targetCoord000] */ -void GGBVFloat_setRegion(void *uniform _volume, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize) -{ - // a 'run' is sequence of connected voxels in x direction - uniform uint32 numRuns = regionSize.y * regionSize.z; - launch[numRuns] PBBVFloat_setRegionTask((GGBV*uniform)_volume, - (const float*uniform)_source, - targetCoord000, - regionSize); -} - -/*! copy given block of voxels into the volume, where source[0] will - be written to volume[targetCoord000] */ -void GGBVDouble_setRegion(void *uniform _volume, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize) -{ - // a 'run' is sequence of connected voxels in x direction - uniform uint32 numRuns = regionSize.y * regionSize.z; - launch[numRuns] PBBVDouble_setRegionTask((GGBV*uniform)_volume, - (const double*uniform)_source, - targetCoord000, - regionSize); -} /*! perform trilinear interpolation for given sample. unlike old way of doing this (a single computesample on the StructuredVolume level @@ -547,11 +508,11 @@ void GGBVDouble_setRegion(void *uniform _volume, (inlined), and thus be about 50% faster (wall-time, meaning even much faster in pure sample speed) */ #define template_computeSample(type) \ - inline float GGBV_computeSample_##type(void *uniform _volume, \ + inline float GBBV_computeSample_##type(void *uniform _volume, \ const vec3f &worldCoordinates) \ { \ /* Cast to the actual Volume subtype. */ \ - GGBV *uniform volume = (GGBV *uniform) _volume; \ + GBBV *uniform volume = (GBBV *uniform) _volume; \ \ /* Transform the sample location into the local coordinate system. */ \ vec3f localCoordinates; \ @@ -572,7 +533,7 @@ void GGBVDouble_setRegion(void *uniform _volume, \ /* Compute the 1D address of the block in the volume and the voxel in the block. */ \ Address8 address8; \ - GGBV_getAddress_##type(volume, clampedLocalCoordinates, \ + GBBV_getAddress_##type(volume, clampedLocalCoordinates, \ voxelIndex_0, address8); \ /* split block into 24+8 bits; we'll have to do a foreach_unique */ \ /* over the upper 24 bits to satify 64-bit addressing, but at */ \ @@ -629,34 +590,34 @@ template_computeSample(float) template_computeSample(double) #undef template_computeSample -void GGBV_Constructor(GGBV *uniform volume, +void GBBV_Constructor(GBBV *uniform volume, /*! pointer to the c++-equivalent class of this entity */ void *uniform cppEquivalent, - const uniform int voxelType, + const uniform int voxelType, const uniform vec3i &dimensions) { StructuredVolume_Constructor(&volume->super, cppEquivalent, dimensions); - + volume->blockMem = NULL; volume->voxelType = (OSPDataType) voxelType; - + if (volume->voxelType == OSP_UCHAR) { volume->voxelSize = sizeof(uniform uint8); - volume->super.getVoxel = GGBV_getVoxel_uint8; - volume->setRegion = &GGBVUChar_setRegion; - volume->super.super.computeSample = GGBV_computeSample_uint8; + volume->super.getVoxel = GBBV_getVoxel_uint8; + volume->setRegion = &GBBVUChar_setRegionTask; + volume->super.super.computeSample = GBBV_computeSample_uint8; } else if (volume->voxelType == OSP_FLOAT) { volume->voxelSize = sizeof(uniform float); - volume->super.getVoxel = GGBV_getVoxel_float; - volume->setRegion = &GGBVFloat_setRegion; - volume->super.super.computeSample = GGBV_computeSample_float; + volume->super.getVoxel = GBBV_getVoxel_float; + volume->setRegion = &GBBVFloat_setRegionTask; + volume->super.super.computeSample = GBBV_computeSample_float; } else if (volume->voxelType == OSP_DOUBLE) { - volume->voxelSize = sizeof(uniform double); - volume->super.getVoxel = GGBV_getVoxel_double; - volume->setRegion = &GGBVDouble_setRegion; - volume->super.super.computeSample = GGBV_computeSample_double; + volume->voxelSize = sizeof(uniform double); + volume->super.getVoxel = GBBV_getVoxel_double; + volume->setRegion = &GBBVDouble_setRegionTask; + volume->super.super.computeSample = GBBV_computeSample_double; } else { print("#osp:block_bricked_volume: unknown voxel type\n"); @@ -664,43 +625,41 @@ void GGBV_Constructor(GGBV *uniform volume, } // Allocate memory. - GGBV_allocateMemory(volume); + GBBV_allocateMemory(volume); } -export void *uniform GGBV_createInstance(void *uniform cppEquivalent, - const uniform int voxelType, +export void *uniform GBBV_createInstance(void *uniform cppEquivalent, + const uniform int voxelType, const uniform vec3i &dimensions) { // create instance of actual volume type ... - GGBV *uniform volume = uniform new uniform GGBV; + GBBV *uniform volume = uniform new uniform GBBV; // ... call constructor to initialize it ... - GGBV_Constructor(volume, cppEquivalent, voxelType, dimensions); + GBBV_Constructor(volume, cppEquivalent, voxelType, dimensions); // ... and return object to caller return volume; } - -export void GGBV_setRegion(void *uniform _self, - /* points to the first voxel to be copies. The - voxels at 'soruce' MUST have dimensions - 'regionSize', must be organized in 3D-array - order, and must have the same voxel type as the - volume.*/ - const void *uniform _source, - /*! coordinates of the lower, left, front corner of - the target region.*/ - const uniform vec3i ®ionCoords, - /*! size of the region that we're writing to; MUST - be the same as the dimensions of source[][][] */ - const uniform vec3i ®ionSize) + +export void GBBV_setRegion(void *uniform _self, + // points to the first voxel to be copied. The voxels at 'source' MUST have + // dimensions 'regionSize', must be organized in 3D-array order, and must + // have the same voxel type as the volume. + const void *uniform _source, + // coordinates of the lower, left, front corner of the target region + const uniform vec3i ®ionCoords, + // size of the region that we're writing to, MUST be the same as the + // dimensions of source[][][] + const uniform vec3i ®ionSize, + const uniform int taskIndex) { // Cast to the actual Volume subtype. - GGBV *uniform self = (GGBV *uniform)_self; - self->setRegion(_self,_source,regionCoords,regionSize); + GBBV *uniform self = (GBBV *uniform)_self; + self->setRegion(self, _source, regionCoords, regionSize, taskIndex); } - -export void GGBV_freeVolume(void *uniform _self) + +export void GBBV_freeVolume(void *uniform _self) { - GGBV *uniform self = (GGBV *uniform)_self; + GBBV *uniform self = (GBBV *uniform)_self; if (self->blockMem) { free64(self->blockMem); } From 3ac678bd7fe3ef01cd0fe03b9fe1e48d5e679a85 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 16:04:19 -0700 Subject: [PATCH 010/310] removed superfluous abstract virtual createISPCequivalent from base Volume class --- ospray/volume/Volume.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/ospray/volume/Volume.h b/ospray/volume/Volume.h index ca7d66042e..cca17ebec8 100644 --- a/ospray/volume/Volume.h +++ b/ospray/volume/Volume.h @@ -101,9 +101,6 @@ namespace ospray { protected: - //! Create the equivalent ISPC volume container. - virtual void createEquivalentISPC() = 0; - //! Complete volume initialization (only on first commit). virtual void finish(); From 5e4d812eb91ec3062e8881f7264508370d9fabd6 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 17:29:38 -0600 Subject: [PATCH 011/310] cleanups in dvr renderer --- ospray/render/volume/RaycastVolumeRenderer.ispc | 13 +++++++------ ospray/volume/Volume.ih | 12 ++++-------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 52876e3846..f0df4d4133 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -68,15 +68,14 @@ inline void RaycastVolumeRenderer_computeVolumeSample(RaycastVolumeRenderer *uni varying Ray &ray, varying vec4f &color) { - // if (!volume) { print("NULL VOLUME IN VOLUMESAMPLE()\n"); } - // if (!volume->computeSample) { print("trying to sample volume w/o sample function!!!!\n"); } - // Sample the volume at the hit point in world coordinates. const vec3f coordinates = ray.org + ray.t0 * ray.dir; const float sample = volume->computeSample(volume, coordinates); + TransferFunction *uniform xf = volume->transferFunction; + // Look up the color associated with the volume sample. - vec3f sampleColor = volume->transferFunction->getColorForValue(volume->transferFunction, sample); + vec3f sampleColor = xf->getColorForValue(xf, sample); // Compute gradient shading, if enabled. if(volume->gradientShadingEnabled) { @@ -105,10 +104,12 @@ inline void RaycastVolumeRenderer_computeVolumeSample(RaycastVolumeRenderer *uni } // Look up the opacity associated with the volume sample. - const float sampleOpacity = volume->transferFunction->getOpacityForValue(volume->transferFunction, sample); + const float sampleOpacity = xf->getOpacityForValue(xf, sample); // Set the color contribution for this sample only (do not accumulate). - color = clamp(sampleOpacity / volume->samplingRate) * make_vec4f(sampleColor.x, sampleColor.y, sampleColor.z, 1.0f); + color + = clamp(sampleOpacity / volume->samplingRate) + * make_vec4f(sampleColor.x, sampleColor.y, sampleColor.z, 1.0f); // Advance the ray for the next sample. volume->intersect(volume, ray); diff --git a/ospray/volume/Volume.ih b/ospray/volume/Volume.ih index b28cd8ebe6..c933c84620 100644 --- a/ospray/volume/Volume.ih +++ b/ospray/volume/Volume.ih @@ -58,23 +58,19 @@ struct Volume { //! Bounding box for the volume in world coordinates. uniform box3f boundingBox; -// #if EXP_DATA_PARALLEL -// // uniform DataParallelInfo dataParallel; -// #endif - //! The value at the given sample location in world coordinates. - varying float (*uniform computeSample)(void *uniform volume, + varying float (*uniform computeSample)(void *uniform _self, const varying vec3f &worldCoordinates); //! The gradient at the given sample location in world coordinates. - varying vec3f (*uniform computeGradient)(void *uniform volume, + varying vec3f (*uniform computeGradient)(void *uniform _self, const varying vec3f &worldCoordinates); //! Find the next hit point in the volume for ray casting based renderers. - void (*uniform intersect)(void *uniform volume, varying Ray &ray); + void (*uniform intersect)(void *uniform _self, varying Ray &ray); //! Find the next isosurface hit point in the volume for ray casting based renderers. - void (*uniform intersectIsosurface)(void *uniform volume, + void (*uniform intersectIsosurface)(void *uniform _self, uniform float *uniform isovalues, uniform int numIsovalues, varying Ray &ray); From 886849f8e931052e598d16b4ab150e60d1e415dd Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 17:42:03 -0600 Subject: [PATCH 012/310] cleanups - dead code eliminmation --- .../render/volume/RaycastVolumeRenderer.ispc | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 802b5f34c6..7546d079de 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -25,18 +25,6 @@ #include "ospray/camera/Camera.ih" #include "ospray/common/Model.ih" -#if 0//Cannot enable here b/c RENDERTILE_PIXELS_PER_JOB doesn't match C++ side? -#ifdef RENDERTILE_PIXELS_PER_JOB -# undef RENDERTILE_PIXELS_PER_JOB -#endif - -/*! number of pixels that each job in a parallel rendertile task - executes together. Must be a multipel of the maximum possible - programCount (16), and must be smaller than TILE_SIZE (in one - dimension) */ -#define RENDERTILE_PIXELS_PER_JOB 32 -#endif - struct PassInfo { // region to integrate over in this pass varying region1f region; @@ -205,18 +193,6 @@ RaycastVolumeRenderer_intersectVolumes(uniform RaycastVolumeRenderer *uniform se // Intersect volume bounding box. float t0, t1; Volume *uniform volume_i = passInfo.block->ispcVolume; -#if 0 - print("bb %\n % % %\n % % %\n", - volume_i, - volume_i->boundingBox.lower.x, - volume_i->boundingBox.lower.y, - volume_i->boundingBox.lower.z, - volume_i->boundingBox.upper.x, - volume_i->boundingBox.upper.y, - volume_i->boundingBox.upper.z); - if (eq(volume_i->boundingBox.lower,volume_i->boundingBox.upper)) - print("EMPTY BBOX!!!!\n"); -#endif intersectBox(ray, volume_i->boundingBox, t0, t1); t0 = max(t0,passInfo.region.lower); t1 = min(t1,passInfo.region.upper); @@ -231,17 +207,7 @@ RaycastVolumeRenderer_intersectVolumes(uniform RaycastVolumeRenderer *uniform se // If we intersected a volume, offset ray by a fraction of the nominal ray step. -#if 0 - if (volume) { - float dt = volume->samplingStep * rcpf(volume->samplingRate); - float t0 = ray.t0; - int i0 = (int)(ray.t0 / dt); - ray.t0 = (i0 + rayOffset)*dt; - if (ray.t0 < t0) ray.t0 += dt; - } -#else if (volume) ray.t0 += rayOffset * volume->samplingStep * rcpf(volume->samplingRate); -#endif // Return the first intersected volume. return volume; From c17ec2d5789afa982f6d39718f28eae6498260ea Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 17:43:28 -0600 Subject: [PATCH 013/310] bugfix - symbol registry for transfer function now static, as it should be... --- ospray/transferFunction/TransferFunction.cpp | 10 ++++++---- ospray/transferFunction/TransferFunction.h | 5 +---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ospray/transferFunction/TransferFunction.cpp b/ospray/transferFunction/TransferFunction.cpp index 21062d48f9..40c90df12d 100644 --- a/ospray/transferFunction/TransferFunction.cpp +++ b/ospray/transferFunction/TransferFunction.cpp @@ -22,13 +22,13 @@ namespace ospray { - TransferFunction *TransferFunction::createInstance(std::string type) { - + TransferFunction *TransferFunction::createInstance(const std::string &type) + { // Function pointer type for creating a concrete instance of a subtype of this class. typedef TransferFunction *(*creationFunctionPointer)(); // Function pointers corresponding to each subtype. - std::map symbolRegistry; + static std::map symbolRegistry; // Return a concrete instance of the requested subtype if the creation function is already known. if (symbolRegistry.count(type) > 0 && symbolRegistry[type] != NULL) return((*symbolRegistry[type])()); @@ -40,7 +40,9 @@ namespace ospray { symbolRegistry[type] = (creationFunctionPointer) getSymbol(creationFunctionName); // The named function may not be found if the requested subtype is not known. - if (!symbolRegistry[type] && ospray::logLevel >= 1) std::cerr << " ospray::TransferFunction WARNING: unrecognized subtype '" + type + "'." << std::endl; + if (!symbolRegistry[type] && ospray::logLevel >= 1) + std::cerr << " ospray::TransferFunction WARNING: unrecognized subtype '" + << type << "'." << std::endl; // Create a concrete instance of the requested subtype. TransferFunction *transferFunction = (symbolRegistry[type]) ? (*symbolRegistry[type])() : NULL; diff --git a/ospray/transferFunction/TransferFunction.h b/ospray/transferFunction/TransferFunction.h index f666846588..3cc730236d 100644 --- a/ospray/transferFunction/TransferFunction.h +++ b/ospray/transferFunction/TransferFunction.h @@ -55,16 +55,13 @@ namespace ospray { virtual void commit() = 0; //! Create a transfer function of the given type. - static TransferFunction *createInstance(std::string type); + static TransferFunction *createInstance(const std::string &type); //! A string description of this class. virtual std::string toString() const { return("ospray::TransferFunction"); } protected: - //! Create the equivalent ISPC transfer function. - virtual void createEquivalentISPC() = 0; - //! Print an error message. void emitMessage(const std::string &kind, const std::string &message) const { std::cerr << " " + toString() + " " + kind + ": " + message + "." << std::endl; } From 016be2eeb7c4249c0e8fdece03ae4c8f91342a29 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 17:53:26 -0600 Subject: [PATCH 014/310] more random cleanups - fixed comment style, removed dead code, moved some inlined functions from header to impl, and moved multtiple 'exitOnCondition's etc all into base managedobject class (no reason to have multiple) --- apps/qtViewer/sg/common/TransferFunction.cpp | 9 ++++ apps/qtViewer/sg/common/TransferFunction.h | 10 ++-- apps/qtViewer/sg/volume/Volume.cpp | 7 +++ apps/qtViewer/sg/volume/Volume.h | 7 +-- ospray/common/Managed.cpp | 30 +++++++++++ ospray/common/Managed.h | 11 ++++ ospray/transferFunction/TransferFunction.h | 51 +++++++----------- ospray/volume/Volume.cpp | 27 +--------- ospray/volume/Volume.h | 56 ++++++++------------ 9 files changed, 107 insertions(+), 101 deletions(-) diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index 7664bf597d..e359463820 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -21,6 +21,15 @@ namespace ospray { namespace sg { + //! constructor + TransferFunction::TransferFunction() + : ospTransferFunction(NULL), + ospColorData(NULL), + ospAlphaData(NULL) + { + setDefaultValues(); + } + //! \brief Sets a new 'texture map' to be used for the color mapping void TransferFunction::setColorMap(const std::vector &colorArray) { diff --git a/apps/qtViewer/sg/common/TransferFunction.h b/apps/qtViewer/sg/common/TransferFunction.h index f96feaa72d..4d2aacd1e0 100644 --- a/apps/qtViewer/sg/common/TransferFunction.h +++ b/apps/qtViewer/sg/common/TransferFunction.h @@ -25,9 +25,10 @@ namespace ospray { uniformly spaced color and alpha values between which the value will be linearly interpolated (similar to a 1D texture for each) */ - struct TransferFunction : public sg::Node { - - TransferFunction() : ospTransferFunction(NULL), ospColorData(NULL), ospAlphaData(NULL) { setDefaultValues(); } + struct TransferFunction : public sg::Node + { + //! constructor + TransferFunction(); //! \brief initialize color and alpha arrays to 'some' useful values void setDefaultValues(); @@ -58,8 +59,7 @@ namespace ospray { std::vector colorArray; std::vector alphaArray; - }; - + }; } // ::ospray::sg } // ::ospray diff --git a/apps/qtViewer/sg/volume/Volume.cpp b/apps/qtViewer/sg/volume/Volume.cpp index 7b432561c0..c4a6c66c29 100644 --- a/apps/qtViewer/sg/volume/Volume.cpp +++ b/apps/qtViewer/sg/volume/Volume.cpp @@ -30,6 +30,13 @@ namespace ospray { /*! \brief returns a std::string with the c++ name of this class */ std::string Volume::toString() const { return "ospray::sg::Volume"; } + + void Volume::serialize(sg::Serialization::State &state) + { + Node::serialize(state); + if (transferFunction) + transferFunction->serialize(state); + } // ======================================================= // structured volume class diff --git a/apps/qtViewer/sg/volume/Volume.h b/apps/qtViewer/sg/volume/Volume.h index 276925faf5..a260bc19b1 100644 --- a/apps/qtViewer/sg/volume/Volume.h +++ b/apps/qtViewer/sg/volume/Volume.h @@ -37,12 +37,7 @@ namespace ospray { virtual box3f getBounds() = 0; //! serialize into given serialization state - virtual void serialize(sg::Serialization::State &state) - { - Node::serialize(state); - if (transferFunction) - transferFunction->serialize(state); - } + virtual void serialize(sg::Serialization::State &state); static bool useDataDistributedVolume; diff --git a/ospray/common/Managed.cpp b/ospray/common/Managed.cpp index 97b42f13fc..577a5758de 100644 --- a/ospray/common/Managed.cpp +++ b/ospray/common/Managed.cpp @@ -70,6 +70,7 @@ namespace ospray { ptr = object; type = OSP_OBJECT; } + void ManagedObject::Param::set(const char *str) { Assert2(this,"trying to set null parameter"); @@ -77,6 +78,7 @@ namespace ospray { this->s = strdup(str); type = OSP_STRING; } + void ManagedObject::Param::set(void *ptr) { Assert2(this,"trying to set null parameter"); @@ -84,6 +86,7 @@ namespace ospray { (void*&)this->ptr = ptr; type = OSP_VOID_PTR; } + void ManagedObject::Param::clear() { Assert2(this,"trying to clear null parameter"); @@ -94,6 +97,7 @@ namespace ospray { type = OSP_OBJECT; ptr = NULL; } + ManagedObject::Param::Param(const char *name) : name(NULL), type(OSP_FLOAT), ptr(NULL) { @@ -160,4 +164,30 @@ namespace ospray { } } + void ManagedObject::emitMessage(const std::string &kind, + const std::string &message) const + { + std::cerr << " " + toString() + << " " + kind + ": " + message + "." << std::endl; + } + + void ManagedObject::exitOnCondition(bool condition, + const std::string &message) const + { + if (!condition) + return; + emitMessage("ERROR", message); + exit(1); + } + + void ManagedObject::warnOnCondition(bool condition, + const std::string &message) const + { + if (!condition) + return; + + emitMessage("WARNING", message); + } + + } // ::ospray diff --git a/ospray/common/Managed.h b/ospray/common/Managed.h index fe1a269a18..371cc1fbbf 100644 --- a/ospray/common/Managed.h +++ b/ospray/common/Managed.h @@ -248,6 +248,17 @@ namespace ospray { /*! \detailed this object will no longer get update notifications from us */ void unregisterListener(ManagedObject *noLongerListening); + + //! Print an error message. + void emitMessage(const std::string &kind, const std::string &message) const; + + //! Error checking. + void exitOnCondition(bool condition, const std::string &message) const; + + //! Warning condition. + void warnOnCondition(bool condition, const std::string &message) const; + + // ------------------------------------------------------- // member variables // ------------------------------------------------------- diff --git a/ospray/transferFunction/TransferFunction.h b/ospray/transferFunction/TransferFunction.h index 3cc730236d..98d12ea333 100644 --- a/ospray/transferFunction/TransferFunction.h +++ b/ospray/transferFunction/TransferFunction.h @@ -18,31 +18,32 @@ #include "ospray/common/Managed.h" -//! \brief Define a function to create an instance of the InternalClass -//! associated with ExternalName. -//! -//! \internal The function generated by this macro is used to create an -//! instance of a concrete subtype of an abstract base class. This -//! macro is needed since the subclass type may not be known to OSPRay -//! at build time. Rather, the subclass can be defined in an external -//! module and registered with OSPRay using this macro. -//! +/*! \brief Define a function to create an instance of the InternalClass + associated with ExternalName. + + \internal The function generated by this macro is used to create an + instance of a concrete subtype of an abstract base class. This + macro is needed since the subclass type may not be known to OSPRay + at build time. Rather, the subclass can be defined in an external + module and registered with OSPRay using this macro. +*/ #define OSP_REGISTER_TRANSFER_FUNCTION(InternalClass, ExternalName) \ extern "C" OSPRAY_INTERFACE TransferFunction *ospray_create_transfer_function_##ExternalName() \ { return(new InternalClass()); } namespace ospray { - //! \brief A TransferFunction is an abstraction that maps a value to - //! a color and opacity for rendering. - //! - //! The actual mapping is unknown to this class, and is implemented - //! in subclasses. A type string specifies a particular concrete - //! implementation to createInstance(). This type string must be - //! registered in OSPRay proper, or in a loaded module using - //! OSP_REGISTER_TRANSFER_FUNCTION. - //! - class TransferFunction : public ManagedObject { + /*! \brief A TransferFunction is an abstraction that maps a value to + a color and opacity for rendering. + + The actual mapping is unknown to this class, and is implemented + in subclasses. A type string specifies a particular concrete + implementation to createInstance(). This type string must be + registered in OSPRay proper, or in a loaded module using + OSP_REGISTER_TRANSFER_FUNCTION. + */ + class TransferFunction : public ManagedObject + { public: //! Constructor. @@ -62,18 +63,6 @@ namespace ospray { protected: - //! Print an error message. - void emitMessage(const std::string &kind, const std::string &message) const - { std::cerr << " " + toString() + " " + kind + ": " + message + "." << std::endl; } - - //! Error checking. - void exitOnCondition(bool condition, const std::string &message) const - { if (!condition) return; emitMessage("ERROR", message); exit(1); } - - //! Warning condition. - void warnOnCondition(bool condition, const std::string &message) const - { if (!condition) return; emitMessage("WARNING", message); } - }; } // ::ospray diff --git a/ospray/volume/Volume.cpp b/ospray/volume/Volume.cpp index d955464a41..0069cc6db3 100644 --- a/ospray/volume/Volume.cpp +++ b/ospray/volume/Volume.cpp @@ -39,7 +39,7 @@ namespace ospray { return("ospray::Volume"); } - Volume *Volume::createInstance(std::string type) + Volume *Volume::createInstance(const std::string &type) { // Function pointer type for creating a concrete instance of a subtype of // this class. @@ -116,31 +116,6 @@ namespace ospray { vec3f(boundingBox.upper.x, boundingBox.upper.y, boundingBox.upper.z)); } - void Volume::emitMessage(const std::string &kind, - const std::string &message) const - { - std::cerr << " " + toString() - << " " + kind + ": " + message + "." << std::endl; - } - - void Volume::exitOnCondition(bool condition, - const std::string &message) const - { - if (!condition) - return; - emitMessage("ERROR", message); - exit(1); - } - - void Volume::warnOnCondition(bool condition, - const std::string &message) const - { - if (!condition) - return; - - emitMessage("WARNING", message); - } - void Volume::updateEditableParameters() { // Set the gradient shading flag for the renderer. diff --git a/ospray/volume/Volume.h b/ospray/volume/Volume.h index 72a95c396e..ed711d26b3 100644 --- a/ospray/volume/Volume.h +++ b/ospray/volume/Volume.h @@ -18,15 +18,15 @@ #include "ospray/common/Managed.h" -//! \brief Define a function to create an instance of the InternalClass -//! associated with ExternalName. -//! -//! \internal The function generated by this macro is used to create an -//! instance of a concrete subtype of an abstract base class. This -//! macro is needed since the subclass type may not be known to OSPRay -//! at build time. Rather, the subclass can be defined in an external -//! module and registered with OSPRay using this macro. -//! +/*! \brief Define a function to create an instance of the InternalClass + associated with ExternalName. + + \internal The function generated by this macro is used to create an + instance of a concrete subtype of an abstract base class. This + macro is needed since the subclass type may not be known to OSPRay + at build time. Rather, the subclass can be defined in an external + module and registered with OSPRay using this macro. +*/ #define OSP_REGISTER_VOLUME(InternalClass, ExternalName) \ extern "C" OSPRAY_INTERFACE Volume *ospray_create_volume_##ExternalName() \ { \ @@ -35,17 +35,18 @@ namespace ospray { - //! \brief A Volume is an abstraction for the concrete object which - //! performs the volume sampling. - //! - //! The actual memory layout, dimensionality, and source of samples - //! are unknown to this class. Subclasses may implement structured - //! volumes, unstructured volumes, radial basis functions, etc. A - //! type string specifies a particular concrete implementation to - //! createInstance(). This type string must be registered either in - //! OSPRay proper, or in a loaded module using OSP_REGISTER_VOLUME. - //! - class Volume : public ManagedObject { + /*! \brief A Volume is an abstraction for the concrete object which + performs the volume sampling. + + The actual memory layout, dimensionality, and source of samples + are unknown to this class. Subclasses may implement structured + volumes, unstructured volumes, radial basis functions, etc. A + type string specifies a particular concrete implementation to + createInstance(). This type string must be registered either in + OSPRay proper, or in a loaded module using OSP_REGISTER_VOLUME. + */ + class Volume : public ManagedObject + { public: #if EXP_DATA_PARALLEL @@ -79,7 +80,7 @@ namespace ospray { virtual std::string toString() const; //! Create a volume container of the given type. - static Volume *createInstance(std::string type); + static Volume *createInstance(const std::string &type); //! Allocate storage and populate the volume. virtual void commit() = 0; @@ -103,18 +104,7 @@ namespace ospray { //! Complete volume initialization (only on first commit). virtual void finish(); - - //! Print an error message. - void emitMessage(const std::string &kind, - const std::string &message) const; - - //! Error checking. - void exitOnCondition(bool condition, - const std::string &message) const; - - //! Warning condition. - void warnOnCondition(bool condition, - const std::string &message) const; }; + } // ::ospray From 2aa1581fc35be32b0a2d734ccce0912e0ee7248f Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 18:11:13 -0600 Subject: [PATCH 015/310] removed some more s-code (transferfunction) --- ospray/geometry/Isosurfaces.h | 8 +- .../LinearTransferFunction.cpp | 16 ++- .../LinearTransferFunction.ispc | 101 ++++++++++++------ ospray/transferFunction/TransferFunction.cpp | 18 ++-- 4 files changed, 94 insertions(+), 49 deletions(-) diff --git a/ospray/geometry/Isosurfaces.h b/ospray/geometry/Isosurfaces.h index 1bce521a50..7c7fe5a42f 100644 --- a/ospray/geometry/Isosurfaces.h +++ b/ospray/geometry/Isosurfaces.h @@ -47,7 +47,11 @@ namespace ospray { Implements the \ref geometry_isosurfaces geometry */ - struct Isosurfaces : public Geometry { + struct Isosurfaces : public Geometry + { + //! constructor + Isosurfaces(); + //! \brief common function to help printf-debugging virtual std::string toString() const { return "ospray::Isosurfaces"; } @@ -60,8 +64,6 @@ namespace ospray { size_t numIsovalues; float *isovalues; - - Isosurfaces(); }; /*! @} */ diff --git a/ospray/transferFunction/LinearTransferFunction.cpp b/ospray/transferFunction/LinearTransferFunction.cpp index 67f3623ae2..52057223c3 100644 --- a/ospray/transferFunction/LinearTransferFunction.cpp +++ b/ospray/transferFunction/LinearTransferFunction.cpp @@ -27,16 +27,24 @@ namespace ospray { if (ispcEquivalent == NULL) createEquivalentISPC(); // Retrieve the color and opacity values. - colorValues = getParamData("colors", NULL); opacityValues = getParamData("opacities", NULL); + colorValues = getParamData("colors", NULL); + opacityValues = getParamData("opacities", NULL); // Set the color values. - if (colorValues) ispc::LinearTransferFunction_setColorValues(ispcEquivalent, colorValues->numItems, (ispc::vec3f *) colorValues->data); + if (colorValues) + ispc::LinearTransferFunction_setColorValues(ispcEquivalent, + colorValues->numItems, + (ispc::vec3f *) colorValues->data); // Set the opacity values. - if (opacityValues) ispc::LinearTransferFunction_setOpacityValues(ispcEquivalent, opacityValues->numItems, (float *) opacityValues->data); + if (opacityValues) + ispc::LinearTransferFunction_setOpacityValues(ispcEquivalent, + opacityValues->numItems, + (float *)opacityValues->data); // Set the value range that the transfer function covers. - vec2f valueRange = getParam2f("valueRange", vec2f(0.0f, 1.0f)); ispc::TransferFunction_setValueRange(ispcEquivalent, (const ispc::vec2f &) valueRange); + vec2f valueRange = getParam2f("valueRange", vec2f(0.0f, 1.0f)); + ispc::TransferFunction_setValueRange(ispcEquivalent, (const ispc::vec2f &) valueRange); // Notify listeners that the transfer function has changed. notifyListenersThatObjectGotChanged(); diff --git a/ospray/transferFunction/LinearTransferFunction.ispc b/ospray/transferFunction/LinearTransferFunction.ispc index 84f65546ff..9522eb5b22 100644 --- a/ospray/transferFunction/LinearTransferFunction.ispc +++ b/ospray/transferFunction/LinearTransferFunction.ispc @@ -21,19 +21,24 @@ LinearTransferFunction_getColorForValue(const void *uniform pointer, varying float value) { // Return (0,0,0) for NaN values. - if (isnan(value)) return(make_vec3f(0.0f)); + if (isnan(value)) + return(make_vec3f(0.0f)); // Cast to the actual TransferFunction subtype. - const LinearTransferFunction *uniform transferFunction = (const LinearTransferFunction *uniform) pointer; + const LinearTransferFunction *uniform transferFunction + = (const LinearTransferFunction *uniform) pointer; // No color values may be available. - if (transferFunction->colorValueCount == 0) return(make_vec3f(1.0f)); + if (transferFunction->colorValueCount == 0) + return make_vec3f(1.0f); // Clamp the value to the lower bound of the value range. - if (value <= transferFunction->super.valueRange.x) return(transferFunction->colorValues[0]); + if (value <= transferFunction->super.valueRange.x) + return transferFunction->colorValues[0]; // Clamp the value to the upper bound of the value range. - if (value >= transferFunction->super.valueRange.y) return(transferFunction->colorValues[transferFunction->colorValueCount - 1]); + if (value >= transferFunction->super.valueRange.y) + return transferFunction->colorValues[transferFunction->colorValueCount - 1]; // Map the value into the range [0.0, 1.0]. value @@ -84,58 +89,74 @@ LinearTransferFunction_getOpacityForValue(const void *uniform pointer, if (isnan(value)) return(0.0f); // Cast to the actual TransferFunction subtype. - const LinearTransferFunction *uniform transferFunction = (const LinearTransferFunction *uniform) pointer; + const LinearTransferFunction *uniform transferFunction + = (const LinearTransferFunction *uniform) pointer; // No opacity values may be available. - if (transferFunction->opacityValueCount == 0) return(1.0f); + if (transferFunction->opacityValueCount == 0) + return 1.0f; // Clamp the value to the lower bound of the value range. - if (value <= transferFunction->super.valueRange.x) return(transferFunction->opacityValues[0]); + if (value <= transferFunction->super.valueRange.x) + return transferFunction->opacityValues[0]; // Clamp the value to the upper bound of the value range. - if (value >= transferFunction->super.valueRange.y) return(transferFunction->opacityValues[transferFunction->opacityValueCount - 1]); + if (value >= transferFunction->super.valueRange.y) + return transferFunction->opacityValues[transferFunction->opacityValueCount - 1]; // Map the value into the range [0.0, 1.0]. - value = (value - transferFunction->super.valueRange.x) / (transferFunction->super.valueRange.y - transferFunction->super.valueRange.x) * (transferFunction->opacityValueCount - 1.0f); + value + = (value - transferFunction->super.valueRange.x) + / (transferFunction->super.valueRange.y - transferFunction->super.valueRange.x) + * (transferFunction->opacityValueCount - 1.0f); // Compute the opacity index and fractional offset. - int index = floor(value); float remainder = value - index; + int index = floor(value); + float remainder = value - index; // The interpolated opacity. - return((1.0f - remainder) * transferFunction->opacityValues[index] + remainder * transferFunction->opacityValues[min(index + 1, transferFunction->opacityValueCount - 1)]); + return + (1.0f - remainder) * transferFunction->opacityValues[index] + + remainder * transferFunction->opacityValues[min(index + 1, transferFunction->opacityValueCount - 1)]; } void LinearTransferFunction_precomputeMinMaxOpacityRanges(void *uniform pointer) { - uniform LinearTransferFunction *uniform transferFunction = (uniform LinearTransferFunction *uniform) pointer; + uniform LinearTransferFunction *uniform transferFunction + = (uniform LinearTransferFunction *uniform) pointer; // Compute the diagonal. - for (uniform int i=0 ; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT ; i++) { + for (uniform int i=0; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; i++) { // Figure out the range of values in the array we are going to compare. - const uniform int checkRangeLow = transferFunction->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); - const uniform int checkRangeHigh = transferFunction->opacityValueCount * (((float) i + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); - - uniform vec2f range = make_vec2f(transferFunction->opacityValues[checkRangeLow], transferFunction->opacityValues[checkRangeLow]); - for (uniform int opacityIDX = checkRangeLow + 1 ; opacityIDX < checkRangeHigh ; opacityIDX++) - range = make_vec2f(min(range.x, transferFunction->opacityValues[opacityIDX]), max(range.y, transferFunction->opacityValues[opacityIDX])); + const uniform int checkRangeLow + = transferFunction->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); + const uniform int checkRangeHigh + = transferFunction->opacityValueCount * (((float)i + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); + + uniform vec2f range = make_vec2f(transferFunction->opacityValues[checkRangeLow]); + for (uniform int opacityIDX = checkRangeLow + 1; + opacityIDX < checkRangeHigh; + opacityIDX++) + range = make_vec2f(min(range.x, transferFunction->opacityValues[opacityIDX]), + max(range.y, transferFunction->opacityValues[opacityIDX])); transferFunction->minMaxOpacityInRange[i][i] = range; - } // Fill out each column from the diagonal up. - for (uniform int i=0 ; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT ; i++) { - for (uniform int j = i + 1 ; j < PRECOMPUTED_OPACITY_SUBRANGE_COUNT ; j++) { + for (uniform int i=0; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; i++) { + for (uniform int j = i + 1; j < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; j++) { // Figure out the range of values in the array we are going to compare. const uniform int checkRangeLow = transferFunction->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); const uniform int checkRangeHigh = transferFunction->opacityValueCount * (((float) j + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); uniform vec2f range = transferFunction->minMaxOpacityInRange[i][i]; - for (uniform int opacityIDX = checkRangeLow + 1 ; opacityIDX < checkRangeHigh ; opacityIDX++) - range = make_vec2f(min(range.x, transferFunction->opacityValues[opacityIDX]), max(range.y, transferFunction->opacityValues[opacityIDX])); + for (uniform int opacityIDX = checkRangeLow + 1; opacityIDX < checkRangeHigh; opacityIDX++) + range = make_vec2f(min(range.x, transferFunction->opacityValues[opacityIDX]), + max(range.y, transferFunction->opacityValues[opacityIDX])); transferFunction->minMaxOpacityInRange[i][j] = range; @@ -163,10 +184,12 @@ export void *uniform LinearTransferFunction_createInstance() transferFunction->super.getMinMaxOpacityInRange = LinearTransferFunction_getMinMaxOpacityInRange; // Transfer function colors and count. - transferFunction->colorValues = NULL; transferFunction->colorValueCount = 0; + transferFunction->colorValues = NULL; + transferFunction->colorValueCount = 0; // Transfer function opacity values and count. - transferFunction->opacityValues = NULL; transferFunction->opacityValueCount = 0; + transferFunction->opacityValues = NULL; + transferFunction->opacityValueCount = 0; // The default transfer function value range. transferFunction->super.valueRange = make_vec2f(0.0f, 1.0f); @@ -195,16 +218,20 @@ export void LinearTransferFunction_setColorValues(void *uniform pointer, vec3f *uniform source) { // Cast to the actual TransferFunction subtype. - LinearTransferFunction *uniform transferFunction = (LinearTransferFunction *uniform) pointer; + LinearTransferFunction *uniform transferFunction + = (LinearTransferFunction *uniform) pointer; // Free memory for any existing color values. - if (transferFunction->colorValues != NULL) delete[] transferFunction->colorValues; + if (transferFunction->colorValues != NULL) + delete[] transferFunction->colorValues; // Allocate memory for the incoming color values. - transferFunction->colorValueCount = count; transferFunction->colorValues = uniform new uniform vec3f[count]; + transferFunction->colorValueCount = count; + transferFunction->colorValues = uniform new uniform vec3f[count]; // Copy the color values into the transfer function. - for (uniform size_t i=0 ; i < count ; i++) transferFunction->colorValues[i] = source[i]; + for (uniform size_t i=0; i < count; i++) + transferFunction->colorValues[i] = source[i]; } @@ -213,16 +240,20 @@ export void LinearTransferFunction_setOpacityValues(void *uniform pointer, float *uniform source) { // Cast to the actual TransferFunction subtype. - LinearTransferFunction *uniform transferFunction = (LinearTransferFunction *uniform) pointer; + LinearTransferFunction *uniform transferFunction + = (LinearTransferFunction *uniform) pointer; // Free memory for any existing opacity values. - if (transferFunction->opacityValues != NULL) delete[] transferFunction->opacityValues; + if (transferFunction->opacityValues != NULL) + delete[] transferFunction->opacityValues; // Allocate memory for the incoming opacity values. - transferFunction->opacityValueCount = count; transferFunction->opacityValues = uniform new uniform float[count]; + transferFunction->opacityValueCount = count; + transferFunction->opacityValues = uniform new uniform float[count]; // Copy the opacity values into the transfer function. - for (uniform size_t i=0 ; i < count ; i++) transferFunction->opacityValues[i] = source[i]; + for (uniform size_t i=0; i < count; i++) + transferFunction->opacityValues[i] = source[i]; // Precompute the min / max opacity ranges. LinearTransferFunction_precomputeMinMaxOpacityRanges(pointer); diff --git a/ospray/transferFunction/TransferFunction.cpp b/ospray/transferFunction/TransferFunction.cpp index 40c90df12d..4c2b92b64b 100644 --- a/ospray/transferFunction/TransferFunction.cpp +++ b/ospray/transferFunction/TransferFunction.cpp @@ -24,14 +24,17 @@ namespace ospray { TransferFunction *TransferFunction::createInstance(const std::string &type) { - // Function pointer type for creating a concrete instance of a subtype of this class. + // Function pointer type for creating a concrete instance of a + // subtype of this class. typedef TransferFunction *(*creationFunctionPointer)(); // Function pointers corresponding to each subtype. static std::map symbolRegistry; - // Return a concrete instance of the requested subtype if the creation function is already known. - if (symbolRegistry.count(type) > 0 && symbolRegistry[type] != NULL) return((*symbolRegistry[type])()); + // Return a concrete instance of the requested subtype if the + // creation function is already known. + if (symbolRegistry.count(type) > 0 && symbolRegistry[type] != NULL) + return((*symbolRegistry[type])()); // Otherwise construct the name of the creation function to look for. std::string creationFunctionName = "ospray_create_transfer_function_" + type; @@ -45,14 +48,15 @@ namespace ospray { << type << "'." << std::endl; // Create a concrete instance of the requested subtype. - TransferFunction *transferFunction = (symbolRegistry[type]) ? (*symbolRegistry[type])() : NULL; + TransferFunction *transferFunction + = (symbolRegistry[type]) ? (*symbolRegistry[type])() : NULL; // Denote the subclass type in the ManagedObject base class. - if (transferFunction) transferFunction->managedObjectType = OSP_TRANSFER_FUNCTION; + if (transferFunction) + transferFunction->managedObjectType = OSP_TRANSFER_FUNCTION; // The initialized transfer function. - return(transferFunction); - + return transferFunction; } } // ::ospray From 14b2895c3996066daf82bcf970649d3ff2ebfaa3 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 19 Feb 2016 18:53:46 -0600 Subject: [PATCH 016/310] minor cleanups --- ospray/transferFunction/LinearTransferFunction.cpp | 7 +++++++ ospray/transferFunction/LinearTransferFunction.h | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ospray/transferFunction/LinearTransferFunction.cpp b/ospray/transferFunction/LinearTransferFunction.cpp index 52057223c3..b7cebbf8f2 100644 --- a/ospray/transferFunction/LinearTransferFunction.cpp +++ b/ospray/transferFunction/LinearTransferFunction.cpp @@ -21,6 +21,13 @@ namespace ospray { + //! Destructor. + LinearTransferFunction::~LinearTransferFunction() + { + if (ispcEquivalent != NULL) + ispc::LinearTransferFunction_destroy(ispcEquivalent); + } + void LinearTransferFunction::commit() { // Create the equivalent ISPC transfer function. diff --git a/ospray/transferFunction/LinearTransferFunction.h b/ospray/transferFunction/LinearTransferFunction.h index 1cb569f888..ac890c2a10 100644 --- a/ospray/transferFunction/LinearTransferFunction.h +++ b/ospray/transferFunction/LinearTransferFunction.h @@ -25,17 +25,18 @@ namespace ospray { - //! \brief A concrete implementation of the TransferFunction class for - //! piecewise linear transfer functions. - //! - class LinearTransferFunction : public TransferFunction { + /*! \brief A concrete implementation of the TransferFunction class for + piecewise linear transfer functions. + */ + class LinearTransferFunction : public TransferFunction + { public: //! Constructor. LinearTransferFunction() {} //! Destructor. - virtual ~LinearTransferFunction() { if (ispcEquivalent != NULL) ispc::LinearTransferFunction_destroy(ispcEquivalent); } + virtual ~LinearTransferFunction(); //! Allocate storage and populate the transfer function. virtual void commit(); From 6c9415ebccfcba93fd1ab5099673862201745819 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sat, 20 Feb 2016 17:40:17 -0600 Subject: [PATCH 017/310] first draft of ospcommon library used in all apps (not yet in ospray/, though! - none of those apps/ include any embree/ or ospray/ files any more. --- CMakeLists.txt | 13 + apps/CMakeLists.txt | 3 - apps/common/widgets/CMakeLists.txt | 7 +- apps/common/widgets/glut3D.cpp | 66 +- apps/common/widgets/glut3D.h | 67 +- apps/common/xml/XML.cpp | 3 +- apps/common/xml/XML.h | 19 +- apps/modelViewer/miniSG/importHBP.cpp | 2 +- apps/modelViewer/miniSG/importMSG.cpp | 2 +- apps/modelViewer/miniSG/importOBJ.cpp | 26 +- apps/modelViewer/miniSG/importRIVL.cpp | 33 +- apps/modelViewer/miniSG/importSTL.cpp | 12 +- apps/modelViewer/miniSG/importTRI.cpp | 4 +- apps/modelViewer/miniSG/importX3D.cpp | 5 +- apps/modelViewer/miniSG/importer.cpp | 4 +- apps/modelViewer/miniSG/importer.h | 14 +- apps/modelViewer/miniSG/miniSG.cpp | 8 +- apps/modelViewer/miniSG/miniSG.h | 65 +- apps/modelViewer/modelViewer.cpp | 25 +- apps/qtViewer/FPSCounter.cpp | 4 +- apps/qtViewer/ModelViewer.cpp | 4 +- apps/qtViewer/ModelViewer.h | 2 + apps/qtViewer/main.cpp | 4 +- apps/qtViewer/sg/CMakeLists.txt | 1 + apps/qtViewer/sg/Renderer.h | 2 +- apps/qtViewer/sg/SceneGraph.cpp | 2 +- apps/qtViewer/sg/SceneGraph.h | 7 +- apps/qtViewer/sg/common/Common.h | 13 +- apps/qtViewer/sg/common/Data.h | 8 +- apps/qtViewer/sg/common/Node.h | 10 +- apps/qtViewer/sg/common/Serialization.h | 14 +- apps/qtViewer/sg/common/Texture2D.h | 6 +- apps/qtViewer/sg/common/TimeStamp.h | 13 +- apps/qtViewer/sg/common/TransferFunction.cpp | 16 +- apps/qtViewer/sg/common/World.cpp | 4 +- apps/qtViewer/sg/geometry/Spheres.cpp | 2 +- apps/qtViewer/sg/geometry/Spheres.h | 4 +- apps/qtViewer/sg/geometry/TriangleMesh.h | 4 +- apps/qtViewer/sg/importer/ImportOBJ.cpp | 28 +- apps/qtViewer/sg/importer/ImportOSP.cpp | 5 +- apps/qtViewer/sg/importer/ImportRIVL.cpp | 22 +- apps/qtViewer/sg/importer/Importer.h | 5 +- apps/qtViewer/sg/module/Module.cpp | 8 +- apps/qtViewer/sg/volume/Volume.cpp | 12 +- apps/qtViewer/sg/volume/Volume.h | 8 +- .../affineSpaceManipulator/HelperGeometry.cpp | 2 +- .../affineSpaceManipulator/HelperGeometry.h | 3 +- .../QAffineSpaceManipulator.cpp | 6 +- .../QAffineSpaceManipulator.h | 8 +- .../lightManipulator/QLightManipulator.cpp | 2 + .../lightManipulator/QLightManipulator.h | 12 +- .../QTransferFunctionEditor.cpp | 84 +- .../QTransferFunctionEditor.h | 16 +- apps/test1.cpp | 104 --- apps/testMC.cpp | 42 - common/AffineSpace.h | 157 ++++ common/CMakeLists.txt | 10 + common/FileName.cpp | 151 +++ common/FileName.h | 94 ++ common/LinearSpace.h | 315 +++++++ common/Quaternion.h | 209 +++++ common/RefCount.h | 122 +++ common/bak.vec.h | 136 +++ common/box.h | 84 ++ common/common.cpp | 185 ++++ common/common.h | 84 ++ common/constants.h | 166 ++++ common/intrinsics.h | 863 ++++++++++++++++++ common/math.h | 302 ++++++ common/mpi.h | 62 ++ common/platform.h | 343 +++++++ common/sysinfo.cpp | 515 +++++++++++ common/sysinfo.h | 178 ++++ common/vec.h | 428 +++++++++ ospray/common/OSPCommon.cpp | 31 +- ospray/common/OSPCommon.h | 11 +- ospray/embree-v2.7.1/common/sys/filename.h | 4 + 77 files changed, 4819 insertions(+), 496 deletions(-) delete mode 100644 apps/test1.cpp delete mode 100644 apps/testMC.cpp create mode 100644 common/AffineSpace.h create mode 100644 common/CMakeLists.txt create mode 100644 common/FileName.cpp create mode 100644 common/FileName.h create mode 100644 common/LinearSpace.h create mode 100644 common/Quaternion.h create mode 100644 common/RefCount.h create mode 100644 common/bak.vec.h create mode 100644 common/box.h create mode 100644 common/common.cpp create mode 100644 common/common.h create mode 100644 common/constants.h create mode 100644 common/intrinsics.h create mode 100644 common/math.h create mode 100644 common/mpi.h create mode 100644 common/platform.h create mode 100644 common/sysinfo.cpp create mode 100644 common/sysinfo.h create mode 100644 common/vec.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 51b2fd4117..636e6d8222 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,19 @@ ENDIF() SET(OSPRAY_INSTALL_TARGET ospray-${OSPRAY_VERSION}-${CMAKE_SYSTEM_NAME}) STRING(TOLOWER "${OSPRAY_INSTALL_TARGET}" OSPRAY_INSTALL_TARGET_LC) +############################################################## +# the ospray common library that's shared across all projects +############################################################## + +#INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) +#INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) +SET (OSPRAY_TARGET "intel64") +ADD_SUBDIRECTORY(common builddir/ospcommon/intel64) +IF (OSPRAY_MIC) + SET (OSPRAY_TARGET "mic") + ADD_SUBDIRECTORY(common builddir/ospcommon/mic) +ENDIF() + ############################################################## # the ospray library ############################################################## diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 3668ea0daf..67e864025e 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -76,7 +76,4 @@ IF(NOT THIS_IS_MIC) ENDIF(NOT WIN32) -# ADD_EXECUTABLE(test1 test1.cpp) -# TARGET_LINK_LIBRARIES(test1 ospray) - ENDIF() diff --git a/apps/common/widgets/CMakeLists.txt b/apps/common/widgets/CMakeLists.txt index 9e8ce579aa..47d2edd442 100644 --- a/apps/common/widgets/CMakeLists.txt +++ b/apps/common/widgets/CMakeLists.txt @@ -20,7 +20,12 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) ADD_LIBRARY(ospray_glut3d SHARED glut3D.cpp) -TARGET_LINK_LIBRARIES(ospray_glut3d ospray ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES}) +TARGET_LINK_LIBRARIES(ospray_glut3d + ospray + ospray_ospcommon + ${OPENGL_LIBRARIES} + ${GLUT_LIBRARIES} + ) # ------------------------------------------------------------ SET_TARGET_PROPERTIES(ospray_glut3d${OSPRAY_LIB_SUFFIX} PROPERTIES VERSION ${OSPRAY_VERSION} SOVERSION ${OSPRAY_SOVERSION}) diff --git a/apps/common/widgets/glut3D.cpp b/apps/common/widgets/glut3D.cpp index 11f58a763c..cef8a97f02 100644 --- a/apps/common/widgets/glut3D.cpp +++ b/apps/common/widgets/glut3D.cpp @@ -32,6 +32,7 @@ # include # include // for usleep #endif +#include namespace ospray { @@ -39,10 +40,28 @@ namespace ospray { bool dumpScreensDuringAnimation = false; + FPSCounter::FPSCounter() + { + smooth_nom = 0.; + smooth_den = 0.; + frameStartTime = 0.; + } + + void FPSCounter::startRender() + { + frameStartTime = ospcommon::getSysTime(); + } + + void FPSCounter::doneRender() { + double seconds = ospcommon::getSysTime() - frameStartTime; + smooth_nom = smooth_nom * 0.8f + seconds; + smooth_den = smooth_den * 0.8f + 1.f; + } + /*! write given frame buffer to file, in PPM P6 format. */ void saveFrameBufferToFile(const char *fileName, - const uint32 *pixel, - const uint32 sizeX, const uint32 sizeY) + const uint32_t *pixel, + const uint32_t sizeX, const uint32_t sizeY) { FILE *file = fopen(fileName,"wb"); if (!file) { @@ -82,7 +101,7 @@ namespace ospray { // glut event handlers // ------------------------------------------------------------------ - void glut3dReshape(int32 x, int32 y) + void glut3dReshape(int32_t x, int32_t y) { if (Glut3DWidget::activeWindow) Glut3DWidget::activeWindow->reshape(vec2i(x,y)); @@ -98,12 +117,12 @@ namespace ospray { Glut3DWidget::activeWindow->display(); } - void glut3dKeyboard(unsigned char key, int32 x, int32 y) + void glut3dKeyboard(unsigned char key, int32_t x, int32_t y) { if (Glut3DWidget::activeWindow) Glut3DWidget::activeWindow->keypress(key,vec2i(x,y)); } - void glut3dSpecial(int32 key, int32 x, int32 y) + void glut3dSpecial(int32_t key, int32_t x, int32_t y) { if (Glut3DWidget::activeWindow) Glut3DWidget::activeWindow->specialkey(key,vec2i(x,y)); @@ -114,13 +133,13 @@ namespace ospray { if (Glut3DWidget::activeWindow) Glut3DWidget::activeWindow->idle(); } - void glut3dMotionFunc(int32 x, int32 y) + void glut3dMotionFunc(int32_t x, int32_t y) { if (Glut3DWidget::activeWindow) Glut3DWidget::activeWindow->motion(vec2i(x,y)); } - void glut3dMouseFunc(int32 whichButton, int32 released, int32 x, int32 y) + void glut3dMouseFunc(int32_t whichButton, int32_t released, int32_t x, int32_t y) { if (Glut3DWidget::activeWindow) Glut3DWidget::activeWindow->mouseButton(whichButton,released,vec2i(x,y)); @@ -138,7 +157,7 @@ namespace ospray { openingAngle(60.f*M_PI/360.f), modified(true) { - frame = AffineSpace3fa::translate(from) * AffineSpace3fa(embree::one); + frame = AffineSpace3fa::translate(from) * AffineSpace3fa(ospcommon::one); } void Glut3DWidget::ViewPort::snapUp() @@ -153,7 +172,7 @@ namespace ospray { // ------------------------------------------------------------------ // implementation of glut3d widget // ------------------------------------------------------------------ - void Glut3DWidget::mouseButton(int32 whichButton, bool released, const vec2i &pos) + void Glut3DWidget::mouseButton(int32_t whichButton, bool released, const vec2i &pos) { if (pos != currMousePos) @@ -279,7 +298,6 @@ namespace ospray { void Glut3DWidget::display() { if (frameBufferMode == Glut3DWidget::FRAMEBUFFER_UCHAR && ucharFB) { - //double before = getSysTime(); glDrawPixels(windowSize.x, windowSize.y, GL_RGBA, GL_UNSIGNED_BYTE, ucharFB); #ifndef _WIN32 if (animating && dumpScreensDuringAnimation) { @@ -313,7 +331,7 @@ namespace ospray { glutSwapBuffers(); } - void Glut3DWidget::drawPixels(const uint32 *framebuffer) + void Glut3DWidget::drawPixels(const uint32_t *framebuffer) { throw std::runtime_error("should not be used right now"); glDrawPixels(windowSize.x, windowSize.y, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); @@ -347,10 +365,10 @@ namespace ospray { void Glut3DWidget::setWorldBounds(const box3f &worldBounds) { - vec3f center = embree::center(worldBounds); + vec3f center = ospcommon::center(worldBounds); vec3f diag = worldBounds.size(); diag = max(diag,vec3f(0.3f*length(diag))); - vec3f from = center - .75f*vec3f(-.6*diag.x,-1.2*diag.y,.8*diag.z); + vec3f from = center - .75f*vec3f(-.6*diag.x,-1.2f*diag.y,.8f*diag.z); vec3f dir = center - from; vec3f up = viewPort.up; @@ -405,7 +423,7 @@ namespace ospray { glutMainLoop(); } - void initGLUT(int32 *ac, const char **av) + void initGLUT(int32_t *ac, const char **av) { glutInit(ac, (char **) av); @@ -502,11 +520,11 @@ namespace ospray { // ------------------------------------------------------------------ InspectCenter::InspectCenter(Glut3DWidget *widget) : Manipulator(widget) - , pivot(center(widget->worldBounds)) + , pivot(ospcommon::center(widget->worldBounds)) {} void InspectCenter::keypress(Glut3DWidget *widget, - int32 key) + int32_t key) { switch(key) { case 'a': { @@ -547,7 +565,7 @@ namespace ospray { } void InspectCenter::specialkey(Glut3DWidget *widget, - int32 key) + int32_t key) { switch(key) { case GLUT_KEY_LEFT: { @@ -600,7 +618,7 @@ namespace ospray { vec2i delta_mouse = (to - from); AffineSpace3fa xfm = AffineSpace3fa::translate( widget->motionSpeed * dv * cam.frame.l.vz ) - * AffineSpace3fa::translate( -1.0 * widget->motionSpeed * du * cam.frame.l.vx ); + * AffineSpace3fa::translate( -1.0f * widget->motionSpeed * du * cam.frame.l.vx ); cam.frame = xfm * cam.frame; cam.from = xfmPoint(xfm, cam.from); @@ -649,7 +667,7 @@ namespace ospray { */ void MoveMode::keypress(Glut3DWidget *widget, - int32 key) + int32_t key) { Glut3DWidget::ViewPort &cam = widget->viewPort; switch(key) { @@ -712,7 +730,7 @@ namespace ospray { vec2i delta_mouse = (to - from); AffineSpace3fa xfm = AffineSpace3fa::translate( widget->motionSpeed * dv * cam.frame.l.vz ) - * AffineSpace3fa::translate( -1.0 * widget->motionSpeed * du * cam.frame.l.vx ); + * AffineSpace3fa::translate( -1.0f * widget->motionSpeed * du * cam.frame.l.vx ); cam.frame = xfm * cam.frame; cam.from = xfmPoint(xfm, cam.from); @@ -742,11 +760,11 @@ namespace ospray { cam.modified = true; } - void Glut3DWidget::specialkey(int32 key, const vec2f where) + void Glut3DWidget::specialkey(int32_t key, const vec2i &where) { if (manipulator) manipulator->specialkey(this,key); } - void Glut3DWidget::keypress(char key, const vec2f where) + void Glut3DWidget::keypress(char key, const vec2i &where) { if (key == '!') { if (animating) { @@ -809,7 +827,7 @@ namespace ospray { - void Manipulator::keypress(Glut3DWidget *widget, const int32 key) + void Manipulator::keypress(Glut3DWidget *widget, const int32_t key) { switch(key) { case 27 /*ESC*/: @@ -818,7 +836,7 @@ namespace ospray { _exit(0); } }; - void Manipulator::specialkey(Glut3DWidget *widget, const int32 key) + void Manipulator::specialkey(Glut3DWidget *widget, const int32_t key) { }; diff --git a/apps/common/widgets/glut3D.h b/apps/common/widgets/glut3D.h index 272fd84c38..9ab0b95147 100644 --- a/apps/common/widgets/glut3D.h +++ b/apps/common/widgets/glut3D.h @@ -16,8 +16,9 @@ #pragma once -#include "ospray/common/OSPCommon.h" -#include /*embree*/"common/math/affinespace.h" +#include "common/common.h" +#include "common/box.h" +#include "common/AffineSpace.h" #ifdef __APPLE__ #include @@ -44,33 +45,27 @@ namespace ospray { //! dedicated namespace for 3D glut viewer widget namespace glut3D { + using namespace ospcommon; + /*! initialize everything GLUT-related */ - OSPRAY_GLUT3D_INTERFACE void initGLUT(int32 *ac, const char **av); + OSPRAY_GLUT3D_INTERFACE void initGLUT(int32_t *ac, const char **av); /*! switch over to GLUT for control flow. This functoin will not return */ OSPRAY_GLUT3D_INTERFACE void runGLUT(); - using embree::AffineSpace3fa; + using ospcommon::AffineSpace3fa; /*! helper class that allows for easily computing (smoothed) frame rate */ struct FPSCounter { + OSPRAY_GLUT3D_INTERFACE FPSCounter(); + OSPRAY_GLUT3D_INTERFACE void startRender(); + OSPRAY_GLUT3D_INTERFACE void doneRender(); + OSPRAY_GLUT3D_INTERFACE double getFPS() const { return smooth_den / smooth_nom; } + + private: double smooth_nom; double smooth_den; double frameStartTime; - - FPSCounter() - { - smooth_nom = 0.; - smooth_den = 0.; - frameStartTime = 0.; - } - OSPRAY_GLUT3D_INTERFACE void startRender() { frameStartTime = ospray::getSysTime(); } - OSPRAY_GLUT3D_INTERFACE void doneRender() { - double seconds = ospray::getSysTime() - frameStartTime; - smooth_nom = smooth_nom * 0.8f + seconds; - smooth_den = smooth_den * 0.8f + 1.f; - } - OSPRAY_GLUT3D_INTERFACE double getFPS() const { return smooth_den / smooth_nom; } }; @@ -85,8 +80,8 @@ namespace ospray { // pressed or released in the associated window OSPRAY_GLUT3D_INTERFACE virtual void button(Glut3DWidget *widget, const vec2i &pos) {}; /*! key press handler - override this fct to catch keyboard. */ - OSPRAY_GLUT3D_INTERFACE virtual void keypress(Glut3DWidget *widget, const int32 key); - OSPRAY_GLUT3D_INTERFACE virtual void specialkey(Glut3DWidget *widget, const int32 key); + OSPRAY_GLUT3D_INTERFACE virtual void keypress(Glut3DWidget *widget, const int32_t key); + OSPRAY_GLUT3D_INTERFACE virtual void specialkey(Glut3DWidget *widget, const int32_t key); OSPRAY_GLUT3D_INTERFACE Manipulator(Glut3DWidget *widget) : widget(widget) {}; protected: @@ -111,8 +106,8 @@ namespace ospray { const vec2i &to, const vec2i &from); virtual void dragMiddle(Glut3DWidget *widget, const vec2i &to, const vec2i &from); - virtual void specialkey(Glut3DWidget *widget, const int32 key); - virtual void keypress(Glut3DWidget *widget, int32 key); + virtual void specialkey(Glut3DWidget *widget, const int32_t key); + virtual void keypress(Glut3DWidget *widget, int32_t key); virtual void button(Glut3DWidget *widget, const vec2i &pos); InspectCenter(Glut3DWidget *widget); void rotate(float du, float dv); @@ -128,7 +123,7 @@ namespace ospray { const vec2i &to, const vec2i &from); virtual void dragMiddle(Glut3DWidget *widget, const vec2i &to, const vec2i &from); - virtual void keypress(Glut3DWidget *widget, int32 key); + virtual void keypress(Glut3DWidget *widget, int32_t key); virtual void button(Glut3DWidget *widget, const vec2i &pos) {} MoveMode(Glut3DWidget *widget) : Manipulator(widget) {} }; @@ -216,7 +211,7 @@ namespace ospray { // event handling - override this to change this widgets behavior // to input events // ------------------------------------------------------------------ - OSPRAY_GLUT3D_INTERFACE virtual void mouseButton(int32 which, bool released, const vec2i &pos); + OSPRAY_GLUT3D_INTERFACE virtual void mouseButton(int32_t which, bool released, const vec2i &pos); OSPRAY_GLUT3D_INTERFACE virtual void motion(const vec2i &pos); // /*! mouse moved to this location, with given left/right/middle buttons pressed */ // virtual void mouseMotion(const vec2i &from, @@ -247,8 +242,8 @@ namespace ospray { /*! clear the frame buffer color and depth bits */ OSPRAY_GLUT3D_INTERFACE void clearPixels(); - /*! draw uint32 pixels into the GLUT window (assumes window and buffer dimensions are equal) */ - OSPRAY_GLUT3D_INTERFACE void drawPixels(const uint32 *framebuffer); + /*! draw uint32_t pixels into the GLUT window (assumes window and buffer dimensions are equal) */ + OSPRAY_GLUT3D_INTERFACE void drawPixels(const uint32_t *framebuffer); /*! draw float4 pixels into the GLUT window (assumes window and buffer dimensions are equal) */ OSPRAY_GLUT3D_INTERFACE void drawPixels(const vec3fa *framebuffer); @@ -269,11 +264,11 @@ namespace ospray { vec2i lastMousePos; /*! last mouse screen position of mouse before current motion */ vec2i currMousePos; /*! current screen position of mouse */ - int64 lastButtonState, currButtonState, currModifiers; + int64_t lastButtonState, currButtonState, currModifiers; ViewPort viewPort; box3f worldBounds; /*!< world bounds, to automatically set viewPort lookat, mouse speed, etc */ - int32 windowID; + int32_t windowID; vec2i windowSize; /*! camera speed modifier - affects how many units the camera _moves_ with each unit on the screen */ @@ -293,20 +288,20 @@ namespace ospray { and deallocate the frame buffer pointer */ union { /*! uchar[4] RGBA-framebuffer, if applicable */ - uint32 *ucharFB; + uint32_t *ucharFB; /*! float[4] RGBA-framebuffer, if applicable */ vec3fa *floatFB; }; - friend void glut3dReshape(int32 x, int32 y); + friend void glut3dReshape(int32_t x, int32_t y); friend void glut3dDisplay(void); - friend void glut3dKeyboard(char key, int32 x, int32 y); + friend void glut3dKeyboard(char key, int32_t x, int32_t y); friend void glut3dIdle(void); - friend void glut3dMotionFunc(int32 x, int32 y); - friend void glut3dMouseFunc(int32 whichButton, int32 released, - int32 x, int32 y); + friend void glut3dMotionFunc(int32_t x, int32_t y); + friend void glut3dMouseFunc(int32_t whichButton, int32_t released, + int32_t x, int32_t y); - OSPRAY_GLUT3D_INTERFACE virtual void keypress(char key, const vec2f where); - OSPRAY_GLUT3D_INTERFACE virtual void specialkey(int32 key, const vec2f where); + OSPRAY_GLUT3D_INTERFACE virtual void keypress(char key, const vec2i &where); + OSPRAY_GLUT3D_INTERFACE virtual void specialkey(int32_t key, const vec2i &where); }; std::ostream &operator<<(std::ostream &o, const Glut3DWidget::ViewPort &cam); diff --git a/apps/common/xml/XML.cpp b/apps/common/xml/XML.cpp index c0a839cd35..60c8337e2a 100644 --- a/apps/common/xml/XML.cpp +++ b/apps/common/xml/XML.cpp @@ -15,6 +15,7 @@ // ======================================================================== // #include "XML.h" +#include namespace ospray { namespace xml { @@ -22,7 +23,7 @@ namespace ospray { std::string toString(const float f) { std::stringstream ss; ss << f; return ss.str(); } - std::string toString(const vec3f &v) + std::string toString(const ospcommon::vec3f &v) { std::stringstream ss; ss << v.x << " " << v.y << " " << v.z; return ss.str(); } Node::~Node() diff --git a/apps/common/xml/XML.h b/apps/common/xml/XML.h index db536e7048..d346650975 100644 --- a/apps/common/xml/XML.h +++ b/apps/common/xml/XML.h @@ -16,10 +16,15 @@ #pragma once -// ospray -#include "ospray/common/OSPCommon.h" -// embree -#include "common/sys/filename.h" +// // ospray +// #include "ospray/common/OSPCommon.h" +// // embree +// #include "common/sys/filename.h" + +// ospcomon +#include "common/common.h" +#include "common/vec.h" +#include "common/FileName.h" // stl #include #include @@ -38,7 +43,7 @@ namespace ospray { namespace xml { struct Node; - using embree::FileName; + using ospcommon::FileName; struct XMLDoc; /*! 'prop'erties in xml nodes are the 'name="value"' inside the @@ -112,9 +117,9 @@ namespace ospray { /*! @{ */ //! \brief helper function(s) to convert data tyeps into strings - std::string toString(const int64 value); + std::string toString(const int64_t value); std::string toString(const float value); - std::string toString(const ospray::vec3f &value); + std::string toString(const ospcommon::vec3f &value); /*! @} */ /*! helper class for writing sg nodes in XML format */ diff --git a/apps/modelViewer/miniSG/importHBP.cpp b/apps/modelViewer/miniSG/importHBP.cpp index 10dd20f616..8e8f43eb42 100644 --- a/apps/modelViewer/miniSG/importHBP.cpp +++ b/apps/modelViewer/miniSG/importHBP.cpp @@ -24,7 +24,7 @@ namespace ospray { using std::endl; /*! import a HBP file, and add it to the specified model */ - void importHBP(Model &model, const embree::FileName &fileName) + void importHBP(Model &model, const ospcommon::FileName &fileName) { std::string vtxName = fileName.str()+".vtx"; std::string triName = fileName.str()+".tri"; diff --git a/apps/modelViewer/miniSG/importMSG.cpp b/apps/modelViewer/miniSG/importMSG.cpp index d236f20462..1287267ee3 100644 --- a/apps/modelViewer/miniSG/importMSG.cpp +++ b/apps/modelViewer/miniSG/importMSG.cpp @@ -23,7 +23,7 @@ namespace ospray { using std::endl; void importMSG(Model &model, - const embree::FileName &fileName) + const ospcommon::FileName &fileName) { error("importMSG: not implemented yet"); } diff --git a/apps/modelViewer/miniSG/importOBJ.cpp b/apps/modelViewer/miniSG/importOBJ.cpp index 223cba65f7..adf2f29b53 100644 --- a/apps/modelViewer/miniSG/importOBJ.cpp +++ b/apps/modelViewer/miniSG/importOBJ.cpp @@ -107,17 +107,17 @@ namespace ospray { std::map material; /*! Constructor. */ - OBJLoader(Model &model, const embree::FileName& fileName); + OBJLoader(Model &model, const ospcommon::FileName& fileName); /*! Destruction */ ~OBJLoader(); /*! Public methods. */ - void loadMTL(const embree::FileName& fileName); + void loadMTL(const ospcommon::FileName& fileName); private: - embree::FileName path; + ospcommon::FileName path; /*! Geometry buffer. */ std::vector v; @@ -136,10 +136,10 @@ namespace ospray { int fix_vn(int index); void flushFaceGroup(); Vertex getInt3(const char*& token); - uint32 getVertex(std::map& vertexMap, Mesh *mesh, const Vertex& i); + uint32_t getVertex(std::map& vertexMap, Mesh *mesh, const Vertex& i); }; - OBJLoader::OBJLoader(Model &model, const embree::FileName &fileName) + OBJLoader::OBJLoader(Model &model, const ospcommon::FileName &fileName) : model(model), curMaterial(NULL), path(fileName.path()) @@ -227,7 +227,7 @@ namespace ospray { } /* load material file */ - void OBJLoader::loadMTL(const embree::FileName &fileName) + void OBJLoader::loadMTL(const ospcommon::FileName &fileName) { std::ifstream cin; cin.open(fileName.c_str()); @@ -355,10 +355,10 @@ namespace ospray { return(v); } - uint32 OBJLoader::getVertex(std::map& vertexMap, + uint32_t OBJLoader::getVertex(std::map& vertexMap, Mesh *mesh, const Vertex& i) { - const std::map::iterator& entry = vertexMap.find(i); + const std::map::iterator& entry = vertexMap.find(i); if (entry != vertexMap.end()) return(entry->second); if (std::isnan(v[i.v].x) || std::isnan(v[i.v].y) || std::isnan(v[i.v].z)) @@ -389,7 +389,7 @@ namespace ospray { // std::vector &normals; // std::vector &texcoords; // std::vector &triangles; - std::map vertexMap; + std::map vertexMap; Mesh *mesh = new Mesh; model.mesh.push_back(mesh); model.instance.push_back(Instance(model.mesh.size()-1)); @@ -404,9 +404,9 @@ namespace ospray { /* triangulate the face with a triangle fan */ for (size_t k=2; k < face.size(); k++) { i1 = i2; i2 = face[k]; - int32 v0 = getVertex(vertexMap, mesh, i0); - int32 v1 = getVertex(vertexMap, mesh, i1); - int32 v2 = getVertex(vertexMap, mesh, i2); + int32_t v0 = getVertex(vertexMap, mesh, i0); + int32_t v1 = getVertex(vertexMap, mesh, i1); + int32_t v2 = getVertex(vertexMap, mesh, i2); if (v0 < 0 || v1 < 0 || v2 < 0) continue; Triangle tri; @@ -420,7 +420,7 @@ namespace ospray { } void importOBJ(Model &model, - const embree::FileName &fileName) + const ospcommon::FileName &fileName) { std::cout << "ospray::miniSG::importOBJ: importing from " << fileName << endl; OBJLoader loader(model,fileName); diff --git a/apps/modelViewer/miniSG/importRIVL.cpp b/apps/modelViewer/miniSG/importRIVL.cpp index fa86a0eab2..cefb0b30c7 100644 --- a/apps/modelViewer/miniSG/importRIVL.cpp +++ b/apps/modelViewer/miniSG/importRIVL.cpp @@ -21,12 +21,13 @@ #define O_LARGEFILE 0 #endif +#define WARN_ON_INCLUDING_OSPCOMMON 1 + // header -#include "ospray/common/Managed.h" -#include "ospray/common/Data.h" #include "miniSG.h" // stl #include +#include // // libxml #include "apps/common/xml/XML.h" // stdlib, for mmap @@ -52,7 +53,7 @@ namespace ospray { unsigned char *binBasePtr = NULL; /*! Base class for all scene graph node types */ - struct Node : public embree::RefCount + struct Node : public ospcommon::RefCount { virtual string toString() const { return "ospray::miniSG::Node"; } @@ -338,31 +339,31 @@ namespace ospray { } else if (!childType.compare("int")) { //This *could* be a texture, handle it! if(childName.find("map_") == std::string::npos) { - mat->setParam(childName.c_str(), (int32)atol(s)); + mat->setParam(childName.c_str(), (int32_t)atol(s)); } else { - Texture2D* tex = mat->textures[(int32)atol(s)].ptr; + Texture2D* tex = mat->textures[(int32_t)atol(s)].ptr; mat->setParam(childName.c_str(), (void*)tex, Material::Param::TEXTURE); } } else if (!childType.compare("int2")) { - int32 x = atol(s); + int32_t x = atol(s); s = NEXT_TOK; - int32 y = atol(s); + int32_t y = atol(s); mat->setParam(childName.c_str(), vec2i(x,y)); } else if (!childType.compare("int3")) { - int32 x = atol(s); + int32_t x = atol(s); s = NEXT_TOK; - int32 y = atol(s); + int32_t y = atol(s); s = NEXT_TOK; - int32 z = atol(s); + int32_t z = atol(s); mat->setParam(childName.c_str(), vec3i(x,y,z)); } else if (!childType.compare("int4")) { - int32 x = atol(s); + int32_t x = atol(s); s = NEXT_TOK; - int32 y = atol(s); + int32_t y = atol(s); s = NEXT_TOK; - int32 z = atol(s); + int32_t z = atol(s); s = NEXT_TOK; - int32 w = atol(s); + int32_t w = atol(s); mat->setParam(childName.c_str(), vec4i(x,y,z,w)); } else { //error! @@ -651,7 +652,7 @@ namespace ospray { return node; } - void traverseSG(Model &model, Ref &node, const affine3f &xfm=embree::one) + void traverseSG(Model &model, Ref &node, const affine3f &xfm=ospcommon::one) { Group *g = dynamic_cast(node.ptr); if (g) { @@ -760,7 +761,7 @@ namespace ospray { } /*! import a wavefront OBJ file, and add it to the specified model */ - void importRIVL(Model &model, const embree::FileName &fileName) + void importRIVL(Model &model, const ospcommon::FileName &fileName) { nodeList.clear(); Ref sg = importRIVL(fileName); diff --git a/apps/modelViewer/miniSG/importSTL.cpp b/apps/modelViewer/miniSG/importSTL.cpp index c156356bbd..0f01588ecd 100644 --- a/apps/modelViewer/miniSG/importSTL.cpp +++ b/apps/modelViewer/miniSG/importSTL.cpp @@ -25,11 +25,11 @@ namespace ospray { struct STLTriangle { vec3f normal; vec3f v0, v1, v2; - uint16 attribute; + uint16_t attribute; }; /*! import a list of STL files */ - void importSTL(std::vector &animation, const embree::FileName &fileName) + void importSTL(std::vector &animation, const ospcommon::FileName &fileName) { FILE *file = fopen(fileName.c_str(),"rb"); if (!file) error("could not open input file"); @@ -47,15 +47,15 @@ namespace ospray { } void importSTL(Model &model, - const embree::FileName &fileName) + const ospcommon::FileName &fileName) { FILE *file = fopen(fileName.c_str(),"rb"); if (!file) error("could not open input file"); char header[80]; - int32 rc = fread(header,1,80,file); + int32_t rc = fread(header,1,80,file); if (rc < 80) error("could not read header"); - int32 numTriangles; + int32_t numTriangles; rc = fread(&numTriangles,sizeof(int),1,file); Assert(rc == 1 && "could not read num triangles from STL file"); cout << "miniSG::importSTL: #tris=" @@ -65,7 +65,7 @@ namespace ospray { miniSG::Triangle triangle; STLTriangle stlTri; - for (int32 i=0 ; i < numTriangles ; i++) { + for (int32_t i=0 ; i < numTriangles ; i++) { rc = fread(&stlTri.normal,sizeof(stlTri.normal),1,file); Assert(rc == 1 && "partial or broken STL file!?"); rc = fread(&stlTri.v0,sizeof(stlTri.v0),1,file); diff --git a/apps/modelViewer/miniSG/importTRI.cpp b/apps/modelViewer/miniSG/importTRI.cpp index 7a8184382b..c3d6bdf6ee 100644 --- a/apps/modelViewer/miniSG/importTRI.cpp +++ b/apps/modelViewer/miniSG/importTRI.cpp @@ -23,12 +23,12 @@ namespace ospray { using std::endl; void importTRI(Model &model, - const embree::FileName &fileName) + const ospcommon::FileName &fileName) { FILE *file = fopen(fileName.c_str(),"rb"); if (!file) error("could not open input file"); - int32 numVertices; + int32_t numVertices; fread(&numVertices,1,sizeof(numVertices),file); Mesh *mesh = new Mesh; diff --git a/apps/modelViewer/miniSG/importX3D.cpp b/apps/modelViewer/miniSG/importX3D.cpp index 4bf9289302..bb471eddfc 100644 --- a/apps/modelViewer/miniSG/importX3D.cpp +++ b/apps/modelViewer/miniSG/importX3D.cpp @@ -23,6 +23,7 @@ #include "apps/common/xml/XML.h" // std #include +#include namespace ospray { namespace miniSG { @@ -201,7 +202,7 @@ namespace ospray { continue; } if (node->name == "Transform") { - affine3f xfm = embree::one; + affine3f xfm = ospcommon::one; parseTransform(model,xfm,node); /* ignore */ continue; @@ -212,7 +213,7 @@ namespace ospray { /*! import a list of X3D files */ void importX3D(Model &model, - const embree::FileName &fileName) + const ospcommon::FileName &fileName) { xml::XMLDoc *doc = xml::readXML(fileName); assert(doc); diff --git a/apps/modelViewer/miniSG/importer.cpp b/apps/modelViewer/miniSG/importer.cpp index 66f8d10d40..0e5b54ce83 100644 --- a/apps/modelViewer/miniSG/importer.cpp +++ b/apps/modelViewer/miniSG/importer.cpp @@ -23,7 +23,7 @@ namespace ospray { : model(&model) { mesh = new Mesh; - mesh->bounds = embree::empty; + mesh->bounds = ospcommon::empty; } void ImportHelper::finalize() @@ -39,7 +39,7 @@ namespace ospray { } /*! find given vertex and return its ID, or add if it doesn't yet exist */ - uint32 ImportHelper::addVertex(const vec3f &position) + uint32_t ImportHelper::addVertex(const vec3f &position) { Assert(mesh); if (known_positions.find(position) == known_positions.end()) { diff --git a/apps/modelViewer/miniSG/importer.h b/apps/modelViewer/miniSG/importer.h index ff28c936c4..793bcb11bc 100644 --- a/apps/modelViewer/miniSG/importer.h +++ b/apps/modelViewer/miniSG/importer.h @@ -33,22 +33,22 @@ namespace ospray { Mesh *mesh; /*!< current mesh we're importing */ /*! to tell the ID of any known position in the mesh's list of vertex positions */ - std::map known_positions; + std::map known_positions; /*! to tell the ID of any known vtx normal in the mesh's list of vertex normals */ - std::map known_normals; + std::map known_normals; /*! to tell the ID of any known texcoord in the mesh's list of texcoords */ - std::map known_texcoords; + std::map known_texcoords; ImportHelper(Model &model, const std::string &name = ""); /*! find given vertex and return its ID, or add if it doesn't yet exist */ - uint32 addVertex(const vec3f &position); + uint32_t addVertex(const vec3f &position); /*! find given vertex and return its ID, or add if it doesn't yet exist */ - uint32 addVertex(const vec3f &position, const vec2f &texcoord); + uint32_t addVertex(const vec3f &position, const vec2f &texcoord); /*! find given vertex and return its ID, or add if it doesn't yet exist */ - uint32 addVertex(const vec3f &position, const vec3f &normal, const vec2f &texcoord); + uint32_t addVertex(const vec3f &position, const vec3f &normal, const vec2f &texcoord); /*! find given vertex and return its ID, or add if it doesn't yet exist */ - uint32 addVertex(const vec3f &position, const vec3f &normal); + uint32_t addVertex(const vec3f &position, const vec3f &normal); /*! add new triangle to the mesh. may discard the triangle if it is degenerated. */ void addTriangle(const miniSG::Triangle &triangle); diff --git a/apps/modelViewer/miniSG/miniSG.cpp b/apps/modelViewer/miniSG/miniSG.cpp index ca3069181a..4e4ac703e3 100644 --- a/apps/modelViewer/miniSG/miniSG.cpp +++ b/apps/modelViewer/miniSG/miniSG.cpp @@ -46,7 +46,7 @@ namespace ospray { Texture2D *loadTexture(const std::string &path, const std::string &fileNameBase, const bool prefereLinear) { - const embree::FileName fileName = path+"/"+fileNameBase; + const FileName fileName = path+"/"+fileNameBase; static std::map textureCache; if (textureCache.find(fileName.str()) != textureCache.end()) @@ -203,7 +203,7 @@ namespace ospray { return defaultVal; } - int32 Material::getParam(const char *name, int32 defaultVal) + int32_t Material::getParam(const char *name, int32_t defaultVal) { ParamMap::iterator it = params.find(name); if (it != params.end()) { @@ -248,7 +248,7 @@ namespace ospray { } - uint32 Material::getParam(const char *name, uint32 defaultVal) + uint32_t Material::getParam(const char *name, uint32_t defaultVal) { ParamMap::iterator it = params.find(name); if (it != params.end()) { @@ -340,7 +340,7 @@ namespace ospray { box3f Model::getBBox() { // this does not yet properly support instancing with transforms! - box3f bBox = embree::empty; + box3f bBox = ospcommon::empty; if (!instance.empty()) { std::vector meshBounds; for (int i=0;i #include namespace ospray { namespace miniSG { + using namespace ospcommon; + typedef ospcommon::AffineSpace3f affine3f; struct Camera : public RefCount { vec3f from, at, up; @@ -97,12 +105,12 @@ namespace ospray { void set(vec3f v) { clear(); type = FLOAT_3; f[0] = v.x; f[1] = v.y; f[2] = v.z; } void set(vec4f v) { clear(); type = FLOAT_3; f[0] = v.x; f[1] = v.y; f[2] = v.z; f[3] = v.w; } - void set(int32 v) { clear(); type = INT; i[0] = v; } + void set(int32_t v) { clear(); type = INT; i[0] = v; } void set(vec2i v) { clear(); type = INT_2; i[0] = v.x; i[1] = v.y; } void set(vec3i v) { clear(); type = INT_3; i[0] = v.x; i[1] = v.y; i[2] = v.z; } void set(vec4i v) { clear(); type = INT_3; i[0] = v.x; i[1] = v.y; i[2] = v.z; i[3] = v.w; } - void set(uint32 v) { clear(); type = UINT; i[0] = v; } + void set(uint32_t v) { clear(); type = UINT; i[0] = v; } void set(vec2ui v) { clear(); type = UINT_2; i[0] = v.x; i[1] = v.y; } void set(vec3ui v) { clear(); type = UINT_3; i[0] = v.x; i[1] = v.y; i[2] = v.z; } void set(vec4ui v) { clear(); type = UINT_3; i[0] = v.x; i[1] = v.y; i[2] = v.z; i[3] = v.w; } @@ -113,8 +121,8 @@ namespace ospray { } union { float f[4]; - int32 i[4]; - uint32 ui[4]; + int32_t i[4]; + uint32_t ui[4]; const char *s; void *ptr; }; @@ -131,12 +139,12 @@ namespace ospray { vec3f getParam(const char *name, vec3f defaultVal); vec4f getParam(const char *name, vec4f devaultVal); - int32 getParam(const char *name, int32 defaultVal); + int32_t getParam(const char *name, int32_t defaultVal); vec2i getParam(const char *name, vec2i defaultVal); vec3i getParam(const char *name, vec3i defaultVal); vec4i getParam(const char *name, vec4i defaultVal); - uint32 getParam(const char *name, uint32 defaultVal); + uint32_t getParam(const char *name, uint32_t defaultVal); vec2ui getParam(const char *name, vec2ui defaultVal); vec3ui getParam(const char *name, vec3ui defaultVal); vec4ui getParam(const char *name, vec4ui defaultVal); @@ -172,7 +180,7 @@ namespace ospray { }; struct Triangle { - uint32 v0, v1, v2; + uint32_t v0, v1, v2; }; /*! default triangle mesh layout */ @@ -197,7 +205,7 @@ namespace ospray { 'materialList'. Will eventually get merged into the foruth component of the triangle, but right now ospray/embree do not yet allow this ... */ - std::vector triangleMaterialId; + std::vector triangleMaterialId; box3f bounds; /*!< bounding box of all vertices */ @@ -205,19 +213,24 @@ namespace ospray { int size() const { return triangle.size(); } Ref material; box3f getBBox(); - Mesh() : bounds(embree::empty) {}; + Mesh() : bounds(ospcommon::empty) {}; }; struct Instance : public RefCount { + Instance() : meshID(0), xfm(ospcommon::one), ospGeometry(NULL) {} + Instance(int meshID, affine3f xfm=ospcommon::one) + : meshID(meshID), xfm(xfm), ospGeometry(NULL) + {}; + Instance(const Instance &o) + : meshID(o.meshID), xfm(o.xfm), ospGeometry(o.ospGeometry) + {} + affine3f xfm; int meshID; OSPGeometry ospGeometry; - - Instance(int meshID=0, affine3f xfm=embree::one) - : meshID(meshID), xfm(xfm), ospGeometry(NULL) - {}; }; + bool operator==(const Instance &a, const Instance &b); bool operator!=(const Instance &a, const Instance &b); @@ -238,28 +251,28 @@ namespace ospray { }; /*! import a wavefront OBJ file, and add it to the specified model */ - void importOBJ(Model &model, const embree::FileName &fileName); + void importOBJ(Model &model, const FileName &fileName); /*! import a HBP file, and add it to the specified model */ - void importHBP(Model &model, const embree::FileName &fileName); + void importHBP(Model &model, const FileName &fileName); /*! import a TRI file (format:vec3fa[3][numTris]), and add it to the specified model */ - void importTRI(Model &model, const embree::FileName &fileName); + void importTRI(Model &model, const FileName &fileName); /*! import a wavefront OBJ file, and add it to the specified model */ - void importRIVL(Model &model, const embree::FileName &fileName); + void importRIVL(Model &model, const FileName &fileName); /*! import a STL file, and add it to the specified model */ - void importSTL(Model &model, const embree::FileName &fileName); + void importSTL(Model &model, const FileName &fileName); /*! import a list of STL files */ - void importSTL(std::vector &animation, const embree::FileName &fileName); + void importSTL(std::vector &animation, const FileName &fileName); /*! import a list of X3D files */ - void importX3D(Model &model, const embree::FileName &fileName); + void importX3D(Model &model, const FileName &fileName); /*! import a MiniSG MSG file, and add it to the specified model */ - void importMSG(Model &model, const embree::FileName &fileName); + void importMSG(Model &model, const FileName &fileName); void error(const std::string &err); diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 8878ebf525..40d70f3899 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -14,6 +14,8 @@ // limitations under the License. // // ======================================================================== // +#define WARN_ON_INCLUDING_OSPCOMMON 1 + // viewer widget #include "apps/common/widgets/glut3D.h" // mini scene graph for loading the model @@ -23,8 +25,11 @@ // stl #include +#include namespace ospray { + using namespace ospcommon; + using std::cout; using std::endl; bool doShadows = 1; @@ -47,7 +52,7 @@ namespace ospray { int maxAccum = 64; int spp = 1; /*! number of samples per pixel */ int maxDepth = 2; // only set with home/end - unsigned int maxObjectsToConsider = (uint32)-1; + unsigned int maxObjectsToConsider = (uint32_t)-1; // if turned on, we'll put each triangle mesh into its own instance, no matter what bool forceInstancing = false; /*! if turned on we're showing the depth buffer rather than the (accum'ed) color buffer */ @@ -94,7 +99,7 @@ namespace ospray { // helper function to write the rendered image as PPM file void writePPM(const char *fileName, const int sizeX, const int sizeY, - const uint32 *pixel) + const uint32_t *pixel) { FILE *file = fopen(fileName, "wb"); fprintf(file, "P6\n%i %i\n255\n", sizeX, sizeY); @@ -189,7 +194,7 @@ namespace ospray { forceRedraw(); } - void keypress(char key, const vec2f where) override + void keypress(char key, const vec2i &where) override { switch (key) { case 'R': @@ -219,7 +224,7 @@ namespace ospray { forceRedraw(); break; case '!': { - const uint32 * p = (uint32*)ospMapFrameBuffer(fb, OSP_FB_COLOR); + const uint32_t * p = (uint32_t*)ospMapFrameBuffer(fb, OSP_FB_COLOR); writePPM("ospmodelviewer.ppm", g_windowSize.x, g_windowSize.y, p); // ospUnmapFrameBuffer(fb,p); printf("#ospModelViewer: saved current frame to 'ospmodelviewer.ppm'\n"); @@ -265,7 +270,7 @@ namespace ospray { } } - void specialkey(int32 key, const vec2f where) override + void specialkey(int32_t key, const vec2i &where) override { switch(key) { case GLUT_KEY_PAGE_UP: @@ -295,7 +300,7 @@ namespace ospray { } } - void mouseButton(int32 whichButton, bool released, const vec2i &pos) override + void mouseButton(int32_t whichButton, bool released, const vec2i &pos) override { Glut3DWidget::mouseButton(whichButton, released, pos); if(currButtonState == (1< namespace ospray { namespace viewer { diff --git a/apps/qtViewer/ModelViewer.h b/apps/qtViewer/ModelViewer.h index 780a29159f..5f6a8345cb 100644 --- a/apps/qtViewer/ModelViewer.h +++ b/apps/qtViewer/ModelViewer.h @@ -16,6 +16,8 @@ #pragma once +#define WARN_ON_INCLUDING_OSPCOMMON 1 + // widgets #include "widgets/affineSpaceManipulator/QAffineSpaceManipulator.h" #include "widgets/transferFunction/QTransferFunctionEditor.h" diff --git a/apps/qtViewer/main.cpp b/apps/qtViewer/main.cpp index 6fe649c9da..7a971f3980 100644 --- a/apps/qtViewer/main.cpp +++ b/apps/qtViewer/main.cpp @@ -22,8 +22,6 @@ #include // viewer #include "ModelViewer.h" -// embree -#include "common/sys/filename.h" // scene graph #include "sg/module/Module.h" #include "sg/importer/Importer.h" @@ -124,7 +122,7 @@ namespace ospray { throw std::runtime_error("#osp:qtv: unknown cmdline param '"+arg+"'"); } } else { - embree::FileName fn = arg; + FileName fn = arg; if (fn.ext() == "osp" || fn.ext() == "pkd") { world = sg::loadOSP(fn.str()); // } else if (fn.ext() == "atom") { diff --git a/apps/qtViewer/sg/CMakeLists.txt b/apps/qtViewer/sg/CMakeLists.txt index 4a54176bd9..10fa07ee4c 100644 --- a/apps/qtViewer/sg/CMakeLists.txt +++ b/apps/qtViewer/sg/CMakeLists.txt @@ -54,6 +54,7 @@ ADD_LIBRARY(ospray_sg${OSPRAY_LIB_SUFFIX} SHARED TARGET_LINK_LIBRARIES(ospray_sg${OSPRAY_LIB_SUFFIX} ospray_xml${OSPRAY_LIB_SUFFIX} ospray${OSPRAY_LIB_SUFFIX} + ospray_ospcommon ) diff --git a/apps/qtViewer/sg/Renderer.h b/apps/qtViewer/sg/Renderer.h index 2041edf590..d3601b93b6 100644 --- a/apps/qtViewer/sg/Renderer.h +++ b/apps/qtViewer/sg/Renderer.h @@ -20,7 +20,7 @@ namespace ospray { namespace sg { - struct Renderer : public embree::RefCount { + struct Renderer : public RefCount { Renderer(); /*! re-start accumulation (for progressive rendering). make sure diff --git a/apps/qtViewer/sg/SceneGraph.cpp b/apps/qtViewer/sg/SceneGraph.cpp index 95a86edb2d..df050093cb 100644 --- a/apps/qtViewer/sg/SceneGraph.cpp +++ b/apps/qtViewer/sg/SceneGraph.cpp @@ -41,7 +41,7 @@ namespace ospray { template<> OSPDataType ParamT::getOSPDataType() const { return OSP_FLOAT4; } - template<> OSPDataType ParamT::getOSPDataType() const + template<> OSPDataType ParamT::getOSPDataType() const { return OSP_INT; } template<> OSPDataType ParamT::getOSPDataType() const { return OSP_INT2; } diff --git a/apps/qtViewer/sg/SceneGraph.h b/apps/qtViewer/sg/SceneGraph.h index c77ef80f46..392a91b7ad 100644 --- a/apps/qtViewer/sg/SceneGraph.h +++ b/apps/qtViewer/sg/SceneGraph.h @@ -18,7 +18,6 @@ #ifndef OSP_SG_INCLUDED #define OSP_SG_INCLUDED 1 - // std #include @@ -32,12 +31,12 @@ #include "sg/common/Data.h" #include "sg/common/FrameBuffer.h" -// embree -#include "common/sys/filename.h" +// ospcommon +#include "common/FileName.h" namespace ospray { namespace sg { - using embree::FileName; + using ospcommon::FileName; /*! \brief allows for adding semantical info to a model/scene graph. \note will not do anything by itself. */ diff --git a/apps/qtViewer/sg/common/Common.h b/apps/qtViewer/sg/common/Common.h index 87392ad578..cff6c7c3ff 100644 --- a/apps/qtViewer/sg/common/Common.h +++ b/apps/qtViewer/sg/common/Common.h @@ -16,14 +16,23 @@ #pragma once +#define WARN_ON_INCLUDING_OSPCOMMON 1 + // ospray API #include "ospray/ospray.h" -// ospray -#include "ospray/common/OSPCommon.h" +// ospcommon +#include "common/common.h" +#include "common/vec.h" +#include "common/box.h" +#include "common/AffineSpace.h" // STL namespace ospray { namespace sg { + using namespace ospcommon; + + typedef AffineSpace3f affine3f; + typedef LinearSpace3f linear3f; #define THROW_SG_ERROR(where,err) \ throw std::runtime_error("in "+std::string(__PRETTY_FUNCTION__)+":"+std::string(err)); diff --git a/apps/qtViewer/sg/common/Data.h b/apps/qtViewer/sg/common/Data.h index 8e09718acb..97c62b6e3c 100644 --- a/apps/qtViewer/sg/common/Data.h +++ b/apps/qtViewer/sg/common/Data.h @@ -108,11 +108,11 @@ namespace ospray { virtual vec3fa get3fa(index_t idx) const { return this->base[idx]; } }; - struct DataArray1i : public DataArrayT { - DataArray1i(int32 *base, size_t size, bool mine=true) - : DataArrayT(base,size,mine) + struct DataArray1i : public DataArrayT { + DataArray1i(int32_t *base, size_t size, bool mine=true) + : DataArrayT(base,size,mine) {} - virtual int32 get1i(index_t idx) const { return this->base[idx]; } + virtual int32_t get1i(index_t idx) const { return this->base[idx]; } }; struct DataArray3i : public DataArrayT { diff --git a/apps/qtViewer/sg/common/Node.h b/apps/qtViewer/sg/common/Node.h index 302bab08a4..7e99235b14 100644 --- a/apps/qtViewer/sg/common/Node.h +++ b/apps/qtViewer/sg/common/Node.h @@ -49,7 +49,7 @@ namespace ospray { \note This is only the abstract base class, actual instantiations are the in the 'ParamT' template. */ - struct Param : public embree::RefCount { + struct Param : public RefCount { /*! constructor. the passed name alwasys remains constant */ Param(const std::string &name) : name(name) {}; /*! return name of this parameter. the value is in the derived class */ @@ -79,7 +79,7 @@ namespace ospray { const affine3f xfm; //!< affine geometry transform matrix //! create a new context - RenderContext() : world(NULL), integrator(NULL), xfm(embree::one) {}; + RenderContext() : world(NULL), integrator(NULL), xfm(one) {}; //! create a new context with new transformation matrix RenderContext(const RenderContext &other, const affine3f &newXfm) @@ -88,7 +88,7 @@ namespace ospray { }; /*! \brief base node of all scene graph nodes */ - struct Node : public embree::RefCount + struct Node : public RefCount { Node() : lastModified(1), lastCommitted(0) {}; @@ -135,8 +135,8 @@ namespace ospray { This function can be used by the viewer(s) for calibrating camera motion, setting default camera position, etc. Nodes for which that does not apply can simpy return - box3f(embree::empty) */ - virtual box3f getBounds() { return box3f(embree::empty); }; + box3f(empty) */ + virtual box3f getBounds() { return box3f(empty); }; //! return when this node was last modified inline TimeStamp getLastModified() const { return lastModified; }; diff --git a/apps/qtViewer/sg/common/Serialization.h b/apps/qtViewer/sg/common/Serialization.h index 79b21967f6..1566a7a1ba 100644 --- a/apps/qtViewer/sg/common/Serialization.h +++ b/apps/qtViewer/sg/common/Serialization.h @@ -17,10 +17,16 @@ #pragma once #include "sg/common/Common.h" +// ospcommon +#include "common/RefCount.h" +#include "common/AffineSpace.h" +// std +#include namespace ospray { namespace sg { - + typedef ospcommon::AffineSpace3f affine3f; + /*! class one can use to serialize all nodes in the scene graph */ struct Serialization { typedef enum { @@ -34,14 +40,14 @@ namespace ospray { instantiation vector */ DONT_FOLLOW_INSTANCES } Mode; - struct Instantiation : public embree::RefCount { + struct Instantiation : public RefCount { Ref parentWorld; affine3f xfm; - Instantiation() : parentWorld(NULL), xfm(embree::one) {} + Instantiation() : parentWorld(NULL), xfm(one) {} }; /*! describes one object that we encountered */ - struct Object : public embree::RefCount { + struct Object : public RefCount { /*! the node itself */ Ref node; diff --git a/apps/qtViewer/sg/common/Texture2D.h b/apps/qtViewer/sg/common/Texture2D.h index 7f95943ee9..e1a76dae8c 100644 --- a/apps/qtViewer/sg/common/Texture2D.h +++ b/apps/qtViewer/sg/common/Texture2D.h @@ -18,12 +18,12 @@ // sg #include "sg/common/Node.h" -// embree -#include "common/sys/filename.h" +// ospcommon +#include "common/FileName.h" namespace ospray { namespace sg { - using embree::FileName; + using ospcommon::FileName; /*! \brief C++ wrapper for a 2D Texture */ struct Texture2D : public Node { diff --git a/apps/qtViewer/sg/common/TimeStamp.h b/apps/qtViewer/sg/common/TimeStamp.h index cd06c7cac6..5c97757f78 100644 --- a/apps/qtViewer/sg/common/TimeStamp.h +++ b/apps/qtViewer/sg/common/TimeStamp.h @@ -17,6 +17,7 @@ #pragma once #include "sg/common/Common.h" +#include "common/intrinsics.h" namespace ospray { namespace sg { @@ -26,17 +27,17 @@ namespace ospray { node's last 'lastupdated' and /lastmodified' time stamps */ struct TimeStamp { //! \brief constructor - TimeStamp(uint64 t) : t(t) {}; + TimeStamp(uint64_t t) : t(t) {}; //! \brief returns global time(stamp) at time of calling - static inline TimeStamp now() { return ospray::rdtsc(); } + static inline TimeStamp now() { return ospcommon::rdtsc(); } - //! \brief Allows ot typecast to a uint64 (so times can be compared) - inline operator uint64 () const { return t; } + //! \brief Allows ot typecast to a uint64_t (so times can be compared) + inline operator uint64_t () const { return t; } private: - //! \brief the uint64 that stores the time value - uint64 t; + //! \brief the uint64_t that stores the time value + uint64_t t; }; } // ::ospray::sg diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index e359463820..90aea29e52 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -60,7 +60,7 @@ namespace ospray { lastModified = TimeStamp::now(); } if (lastModified > lastCommitted) { - lastCommitted = ospray::rdtsc(); + lastCommitted = rdtsc(); ospCommit(ospTransferFunction); } } @@ -77,13 +77,13 @@ namespace ospray { void TransferFunction::setDefaultValues() { colorArray.clear(); - colorArray.push_back(ospray::vec3f(0 , 0 , 0.562493 )); - colorArray.push_back(ospray::vec3f(0 , 0 , 1 )); - colorArray.push_back(ospray::vec3f(0 , 1 , 1 )); - colorArray.push_back(ospray::vec3f(0.500008 , 1 , 0.500008 )); - colorArray.push_back(ospray::vec3f(1 , 1 , 0 )); - colorArray.push_back(ospray::vec3f(1 , 0 , 0 )); - colorArray.push_back(ospray::vec3f(0.500008 , 0 , 0 )); + colorArray.push_back(ospcommon::vec3f(0 , 0 , 0.562493 )); + colorArray.push_back(ospcommon::vec3f(0 , 0 , 1 )); + colorArray.push_back(ospcommon::vec3f(0 , 1 , 1 )); + colorArray.push_back(ospcommon::vec3f(0.500008 , 1 , 0.500008 )); + colorArray.push_back(ospcommon::vec3f(1 , 1 , 0 )); + colorArray.push_back(ospcommon::vec3f(1 , 0 , 0 )); + colorArray.push_back(ospcommon::vec3f(0.500008 , 0 , 0 )); alphaArray.clear(); for (int i=0;igetBounds()); return bounds; @@ -46,7 +46,7 @@ namespace ospray { if (ospModel) throw std::runtime_error("World::ospModel alrady exists!?"); ospModel = ospNewModel(); - affine3f xfm = embree::one; + affine3f xfm = one; for (size_t i=0;irender(ctx); } diff --git a/apps/qtViewer/sg/geometry/Spheres.cpp b/apps/qtViewer/sg/geometry/Spheres.cpp index 46bf4c2db9..f5eb6e3c90 100644 --- a/apps/qtViewer/sg/geometry/Spheres.cpp +++ b/apps/qtViewer/sg/geometry/Spheres.cpp @@ -38,7 +38,7 @@ namespace ospray { box3f Spheres::getBounds() { - box3f bounds = embree::empty; + box3f bounds = empty; for (size_t i=0;i > materialList; - std::vector materialIDs; + std::vector materialIDs; // to allow memory-mapping triangle arrays (or in general, // sharing data with an application) we use data arrays, not std::vector's diff --git a/apps/qtViewer/sg/importer/ImportOBJ.cpp b/apps/qtViewer/sg/importer/ImportOBJ.cpp index cf46d428e9..f43fa4699b 100644 --- a/apps/qtViewer/sg/importer/ImportOBJ.cpp +++ b/apps/qtViewer/sg/importer/ImportOBJ.cpp @@ -16,6 +16,8 @@ #undef NDEBUG +#define WARN_INCLUDE_EMBREE_FILENAME 1 + // O_LARGEFILE is a GNU extension. #ifdef __APPLE__ #define O_LARGEFILE 0 @@ -108,17 +110,17 @@ namespace ospray { std::map material; /*! Constructor. */ - OBJLoader(World *world, const embree::FileName& fileName); + OBJLoader(World *world, const FileName& fileName); /*! Destruction */ ~OBJLoader(); /*! Public methods. */ - void loadMTL(const embree::FileName& fileName); + void loadMTL(const FileName& fileName); private: - embree::FileName path; + FileName path; /*! Geometry buffer. */ std::vector v; @@ -137,10 +139,10 @@ namespace ospray { int fix_vn(int index); void flushFaceGroup(); Vertex getInt3(const char*& token); - uint32 getVertex(std::map& vertexMap, TriangleMesh *mesh, const Vertex& i); + uint32_t getVertex(std::map& vertexMap, TriangleMesh *mesh, const Vertex& i); }; - OBJLoader::OBJLoader(World *world, const embree::FileName &fileName) + OBJLoader::OBJLoader(World *world, const FileName &fileName) : world(world), curMaterial(NULL), path(fileName.path()) @@ -228,7 +230,7 @@ namespace ospray { } /* load material file */ - void OBJLoader::loadMTL(const embree::FileName &fileName) + void OBJLoader::loadMTL(const FileName &fileName) { std::ifstream cin; cin.open(fileName.c_str()); @@ -352,10 +354,10 @@ namespace ospray { return(v); } - uint32 OBJLoader::getVertex(std::map& vertexMap, + uint32_t OBJLoader::getVertex(std::map& vertexMap, TriangleMesh *mesh, const Vertex& i) { - const std::map::iterator& entry = vertexMap.find(i); + const std::map::iterator& entry = vertexMap.find(i); if (entry != vertexMap.end()) return(entry->second); if (std::isnan(v[i.v].x) || std::isnan(v[i.v].y) || std::isnan(v[i.v].z)) @@ -381,7 +383,7 @@ namespace ospray { { if (curGroup.empty()) return; - std::map vertexMap; + std::map vertexMap; TriangleMesh *mesh = new TriangleMesh; mesh->vertex = new DataVector3f; mesh->normal = new DataVector3f; @@ -399,16 +401,16 @@ namespace ospray { /* triangulate the face with a triangle fan */ for (size_t k=2; k < face.size(); k++) { i1 = i2; i2 = face[k]; - int32 v0 = getVertex(vertexMap, mesh, i0); - int32 v1 = getVertex(vertexMap, mesh, i1); - int32 v2 = getVertex(vertexMap, mesh, i2); + int32_t v0 = getVertex(vertexMap, mesh, i0); + int32_t v1 = getVertex(vertexMap, mesh, i1); + int32_t v2 = getVertex(vertexMap, mesh, i2); if (v0 < 0 || v1 < 0 || v2 < 0) continue; vec3i tri(v0,v1,v2); mesh->index.cast()->push_back(tri); //Vec3i(v0, v1, v2)); } - } + } curGroup.clear(); } diff --git a/apps/qtViewer/sg/importer/ImportOSP.cpp b/apps/qtViewer/sg/importer/ImportOSP.cpp index 463253f2f0..ca0aa58d20 100644 --- a/apps/qtViewer/sg/importer/ImportOSP.cpp +++ b/apps/qtViewer/sg/importer/ImportOSP.cpp @@ -32,9 +32,6 @@ #include // xml #include "apps/common/xml/XML.h" -#include "ospray/common/Library.h" -// embree stuff -#include "common/sys/library.h" namespace ospray { namespace sg { @@ -104,7 +101,7 @@ namespace ospray { return true; } if (node->name == "int") { - target->addParam(new ParamT(name,atoi(node->content.c_str()))); + target->addParam(new ParamT(name,atoi(node->content.c_str()))); return true; } if (node->name == "float") { diff --git a/apps/qtViewer/sg/importer/ImportRIVL.cpp b/apps/qtViewer/sg/importer/ImportRIVL.cpp index aa66bec07f..e83c07013b 100644 --- a/apps/qtViewer/sg/importer/ImportRIVL.cpp +++ b/apps/qtViewer/sg/importer/ImportRIVL.cpp @@ -21,6 +21,8 @@ #define O_LARGEFILE 0 #endif +#define WARN_ON_INCLUDING_OSPCOMMON 1 + #include "SceneGraph.h" #include "sg/common/Texture2D.h" #include "sg/geometry/TriangleMesh.h" @@ -198,28 +200,28 @@ namespace ospray { float w = atof(s); mat->setParam(childName, vec4f(x,y,z,w)); } else if (!childType.compare("int")) { - mat->setParam(childName, (int32)atol(s)); + mat->setParam(childName, (int32_t)atol(s)); } else if (!childType.compare("int2")) { - int32 x = atol(s); + int32_t x = atol(s); s = NEXT_TOK; - int32 y = atol(s); + int32_t y = atol(s); // mat->setParam(childName.c_str(), vec2i(x,y)); mat->setParam(childName, vec2i(x,y)); } else if (!childType.compare("int3")) { - int32 x = atol(s); + int32_t x = atol(s); s = NEXT_TOK; - int32 y = atol(s); + int32_t y = atol(s); s = NEXT_TOK; - int32 z = atol(s); + int32_t z = atol(s); mat->setParam(childName, vec3i(x,y,z)); } else if (!childType.compare("int4")) { - int32 x = atol(s); + int32_t x = atol(s); s = NEXT_TOK; - int32 y = atol(s); + int32_t y = atol(s); s = NEXT_TOK; - int32 z = atol(s); + int32_t z = atol(s); s = NEXT_TOK; - int32 w = atol(s); + int32_t w = atol(s); mat->setParam(childName, vec4i(x,y,z,w)); } else { //error! diff --git a/apps/qtViewer/sg/importer/Importer.h b/apps/qtViewer/sg/importer/Importer.h index c6794909ed..0c7f4e3eca 100644 --- a/apps/qtViewer/sg/importer/Importer.h +++ b/apps/qtViewer/sg/importer/Importer.h @@ -18,8 +18,7 @@ // ospray::sg #include "../common/World.h" -// embree -#include "common/sys/filename.h" +#include "common/FileName.h" /*! \file sg/module/Importer.h Defines the interface for writing file importers for the ospray::sg */ @@ -27,8 +26,6 @@ namespace ospray { namespace sg { - using embree::FileName; - struct ImportState { Ref world; // std::vector searchPaths; diff --git a/apps/qtViewer/sg/module/Module.cpp b/apps/qtViewer/sg/module/Module.cpp index 03efe4294a..2821b54fbf 100644 --- a/apps/qtViewer/sg/module/Module.cpp +++ b/apps/qtViewer/sg/module/Module.cpp @@ -18,7 +18,9 @@ #include "Module.h" #include "../common/RuntimeError.h" // ospray -#include "ospray/common/Library.h" +#include "common/common.h" +// std +#include /*! \file sg/module/Module.cpp Defines the interface for writing ospray::sg modules */ @@ -38,8 +40,8 @@ namespace ospray { const std::string libName = "ospray_sg_"+moduleName; const std::string symName = "ospray_sg_"+moduleName+"_init"; - ospray::loadLibrary(libName); - void *sym = ospray::getSymbol(symName); + ospcommon::loadLibrary(libName); + void *sym = ospcommon::getSymbol(symName); if (!sym) throw sg::RuntimeError("could not load module '"+moduleName+"' (symbol '"+symName+"' not found)"); diff --git a/apps/qtViewer/sg/volume/Volume.cpp b/apps/qtViewer/sg/volume/Volume.cpp index c4a6c66c29..9539697d5e 100644 --- a/apps/qtViewer/sg/volume/Volume.cpp +++ b/apps/qtViewer/sg/volume/Volume.cpp @@ -200,9 +200,9 @@ namespace ospray { } delete[] slice; } else { - uint8 *slice = new uint8[nPerSlice]; + uint8_t *slice = new uint8_t[nPerSlice]; for (int z=0;zgetProp("baseName"); firstSliceID = node->getPropl("firstSliceID"); numSlices = node->getPropl("numSlices"); - if (voxelType != "uint8") - throw std::runtime_error("unknown StackedRawSlices.voxelType (currently only supporting 'uint8')"); + if (voxelType != "uint8_t") + throw std::runtime_error("unknown StackedRawSlices.voxelType (currently only supporting 'uint8_t')"); if (!transferFunction) setTransferFunction(new TransferFunction); @@ -287,7 +287,7 @@ namespace ospray { ospSetString(volume,"voxelType",voxelType.c_str()); ospSetVec3i(volume,"dimensions",(const osp::vec3i&)dimensions); size_t nPerSlice = dimensions.x*dimensions.y; - uint8 *slice = new uint8[nPerSlice]; + uint8_t *slice = new uint8_t[nPerSlice]; for (int sliceID=0;sliceID namespace ospray { namespace viewer { + using namespace sg; //! \brief Helper class for storing tessellated geometry (with //! single color per mesh); that can be used to store 3D geometry diff --git a/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp b/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp index 7013d6968b..6285d9a955 100644 --- a/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp +++ b/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp @@ -14,6 +14,8 @@ // limitations under the License. // // ======================================================================== // +#define WARN_ON_INCLUDING_OSPCOMMON 1 + // viewer #include "QAffineSpaceManipulator.h" #include "HelperGeometry.h" @@ -54,7 +56,7 @@ namespace ospray { : sourcePoint(0,-4,0), targetPoint(0,0,0), upVector(0,1,0), - orientation(embree::one) + orientation(ospcommon::one) {} void QAffineSpaceManipulator::ReferenceFrame::snapUp() @@ -344,7 +346,7 @@ namespace ospray { glBegin(GL_TRIANGLES); for (int i=0;i #include namespace ospray { namespace viewer { + using namespace ospcommon; + typedef LinearSpace3f linear3f; + // ================================================================== //! \brief A QT Widget that allows mouse manipulation of a reference /*! The Widget works by keeping and manipulating a reference frame diff --git a/apps/qtViewer/widgets/lightManipulator/QLightManipulator.cpp b/apps/qtViewer/widgets/lightManipulator/QLightManipulator.cpp index 582906fda3..3749808b56 100644 --- a/apps/qtViewer/widgets/lightManipulator/QLightManipulator.cpp +++ b/apps/qtViewer/widgets/lightManipulator/QLightManipulator.cpp @@ -16,7 +16,9 @@ // viewer #include "QLightManipulator.h" +// std #include +#include namespace ospray { namespace viewer { diff --git a/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h b/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h index d557887909..2faabe14a9 100644 --- a/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h +++ b/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h @@ -16,17 +16,19 @@ #pragma once -// ospray interna -#include "ospray/common/OSPCommon.h" // ospray public api #include "ospray/ospray.h" // qt #include //sg #include "sg/Renderer.h" +// ospcomon +#include "common/common.h" namespace ospray { namespace viewer { + using namespace ospcommon; + // ================================================================== //! \brief A QT Widget that allows mouse manipulation of a reference /*! The Widget works by keeping and manipulating a reference frame @@ -54,8 +56,8 @@ namespace ospray { // ================================================================== struct LightInfo { OSPLight ospLight; - ospray::vec3f color; - ospray::vec3f direction; + vec3f color; + vec3f direction; float intensity; }; @@ -102,7 +104,7 @@ namespace ospray { QPushButton *applyButton; private: - ospray::vec3f upVector; + vec3f upVector; }; } } diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp index 9870b89ef0..330530debe 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp @@ -25,7 +25,7 @@ namespace ospray { float QTransferFunctionAlphaEditor::pointPixelRadius = 8.; float QTransferFunctionAlphaEditor::linePixelWidth = 2.; - bool comparePointsByX(const ospray::vec2f &i, const ospray::vec2f &j) + bool comparePointsByX(const ospcommon::vec2f &i, const ospcommon::vec2f &j) { return (i.x < j.x); } @@ -40,9 +40,9 @@ namespace ospray { colorMapImage.fill(QColor::fromRgbF(1,1,1,1).rgb()); // default transfer function points - // points.push_back(ospray::vec2f(0.,1.)); - points.push_back(ospray::vec2f(0.,0.)); - points.push_back(ospray::vec2f(1.,1.)); + // points.push_back(ospcommon::vec2f(0.,1.)); + points.push_back(ospcommon::vec2f(0.,0.)); + points.push_back(ospcommon::vec2f(1.,1.)); } void QTransferFunctionAlphaEditor::setColorMapImage(const QImage &image) @@ -109,7 +109,7 @@ namespace ospray { if(selectedPointIndex == -1) { // no point selected, create a new one - ospray::vec2f newPoint = widgetPointToPoint(widgetClickPoint); + ospcommon::vec2f newPoint = widgetPointToPoint(widgetClickPoint); // insert into points vector and sort ascending by x points.push_back(newPoint); @@ -177,7 +177,7 @@ namespace ospray { return; QPointF widgetMousePoint = event->posF(); - ospray::vec2f mousePoint = widgetPointToPoint(widgetMousePoint); + ospcommon::vec2f mousePoint = widgetPointToPoint(widgetMousePoint); // clamp x value if(selectedPointIndex == 0) { @@ -204,14 +204,14 @@ namespace ospray { emit transferFunctionChanged(); } - QPointF QTransferFunctionAlphaEditor::pointToWidgetPoint(const ospray::vec2f &point) + QPointF QTransferFunctionAlphaEditor::pointToWidgetPoint(const ospcommon::vec2f &point) { return QPointF(point.x * float(width()), (1.f - point.y) * float(height())); } - ospray::vec2f QTransferFunctionAlphaEditor::widgetPointToPoint(const QPointF &widgetPoint) + ospcommon::vec2f QTransferFunctionAlphaEditor::widgetPointToPoint(const QPointF &widgetPoint) { - return ospray::vec2f(float(widgetPoint.x()) / float(width()), + return ospcommon::vec2f(float(widgetPoint.x()) / float(width()), 1.f - float(widgetPoint.y()) / float(height())); } @@ -301,57 +301,57 @@ namespace ospray { void QTransferFunctionEditor::setDefaultColorMaps() { // color maps based on ParaView default color maps - std::vector colors; + std::vector colors; // jet colors.clear(); - colors.push_back(ospray::vec3f(0 , 0 , 0.562493 )); - colors.push_back(ospray::vec3f(0 , 0 , 1 )); - colors.push_back(ospray::vec3f(0 , 1 , 1 )); - colors.push_back(ospray::vec3f(0.500008 , 1 , 0.500008 )); - colors.push_back(ospray::vec3f(1 , 1 , 0 )); - colors.push_back(ospray::vec3f(1 , 0 , 0 )); - colors.push_back(ospray::vec3f(0.500008 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 0.562493 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 1 )); + colors.push_back(ospcommon::vec3f(0 , 1 , 1 )); + colors.push_back(ospcommon::vec3f(0.500008 , 1 , 0.500008 )); + colors.push_back(ospcommon::vec3f(1 , 1 , 0 )); + colors.push_back(ospcommon::vec3f(1 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0.500008 , 0 , 0 )); addColorMap(new ColorMap("Jet", colors)); // ice / fire colors.clear(); - colors.push_back(ospray::vec3f(0 , 0 , 0 )); - colors.push_back(ospray::vec3f(0 , 0.120394 , 0.302678 )); - colors.push_back(ospray::vec3f(0 , 0.216587 , 0.524575 )); - colors.push_back(ospray::vec3f(0.0552529 , 0.345022 , 0.659495 )); - colors.push_back(ospray::vec3f(0.128054 , 0.492592 , 0.720287 )); - colors.push_back(ospray::vec3f(0.188952 , 0.641306 , 0.792096 )); - colors.push_back(ospray::vec3f(0.327672 , 0.784939 , 0.873426 )); - colors.push_back(ospray::vec3f(0.60824 , 0.892164 , 0.935546 )); - colors.push_back(ospray::vec3f(0.881376 , 0.912184 , 0.818097 )); - colors.push_back(ospray::vec3f(0.9514 , 0.835615 , 0.449271 )); - colors.push_back(ospray::vec3f(0.904479 , 0.690486 , 0 )); - colors.push_back(ospray::vec3f(0.854063 , 0.510857 , 0 )); - colors.push_back(ospray::vec3f(0.777096 , 0.330175 , 0.000885023 )); - colors.push_back(ospray::vec3f(0.672862 , 0.139086 , 0.00270085 )); - colors.push_back(ospray::vec3f(0.508812 , 0 , 0 )); - colors.push_back(ospray::vec3f(0.299413 , 0.000366217 , 0.000549325 )); - colors.push_back(ospray::vec3f(0.0157473 , 0.00332647 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0.120394 , 0.302678 )); + colors.push_back(ospcommon::vec3f(0 , 0.216587 , 0.524575 )); + colors.push_back(ospcommon::vec3f(0.0552529 , 0.345022 , 0.659495 )); + colors.push_back(ospcommon::vec3f(0.128054 , 0.492592 , 0.720287 )); + colors.push_back(ospcommon::vec3f(0.188952 , 0.641306 , 0.792096 )); + colors.push_back(ospcommon::vec3f(0.327672 , 0.784939 , 0.873426 )); + colors.push_back(ospcommon::vec3f(0.60824 , 0.892164 , 0.935546 )); + colors.push_back(ospcommon::vec3f(0.881376 , 0.912184 , 0.818097 )); + colors.push_back(ospcommon::vec3f(0.9514 , 0.835615 , 0.449271 )); + colors.push_back(ospcommon::vec3f(0.904479 , 0.690486 , 0 )); + colors.push_back(ospcommon::vec3f(0.854063 , 0.510857 , 0 )); + colors.push_back(ospcommon::vec3f(0.777096 , 0.330175 , 0.000885023 )); + colors.push_back(ospcommon::vec3f(0.672862 , 0.139086 , 0.00270085 )); + colors.push_back(ospcommon::vec3f(0.508812 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0.299413 , 0.000366217 , 0.000549325 )); + colors.push_back(ospcommon::vec3f(0.0157473 , 0.00332647 , 0 )); addColorMap(new ColorMap("Ice / Fire", colors)); // cool to warm colors.clear(); - colors.push_back(ospray::vec3f(0.231373 , 0.298039 , 0.752941 )); - colors.push_back(ospray::vec3f(0.865003 , 0.865003 , 0.865003 )); - colors.push_back(ospray::vec3f(0.705882 , 0.0156863 , 0.14902 )); + colors.push_back(ospcommon::vec3f(0.231373 , 0.298039 , 0.752941 )); + colors.push_back(ospcommon::vec3f(0.865003 , 0.865003 , 0.865003 )); + colors.push_back(ospcommon::vec3f(0.705882 , 0.0156863 , 0.14902 )); addColorMap(new ColorMap("Cool to Warm", colors)); // blue to red rainbow colors.clear(); - colors.push_back(ospray::vec3f(0 , 0 , 1 )); - colors.push_back(ospray::vec3f(1 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 1 )); + colors.push_back(ospcommon::vec3f(1 , 0 , 0 )); addColorMap(new ColorMap("Blue to Red Rainbow", colors)); // grayscale colors.clear(); - colors.push_back(ospray::vec3f(0.)); - colors.push_back(ospray::vec3f(1.)); + colors.push_back(ospcommon::vec3f(0.)); + colors.push_back(ospcommon::vec3f(1.)); addColorMap(new ColorMap("Grayscale", colors)); } @@ -384,7 +384,7 @@ namespace ospray { } QTransferFunctionEditor::ColorMap::ColorMap(const std::string &name, - const std::vector &colors) + const std::vector &colors) : name(name), colors(colors) {} diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h index 4eb7e377c9..baabd4cb10 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h @@ -16,7 +16,7 @@ #pragma once -// ospray +// ospray, PUBLIC #include // stl #include @@ -25,9 +25,11 @@ #include // scene graph #include "sg/SceneGraph.h" +// ospcommon namespace ospray { namespace viewer { + using namespace ospcommon; /*! the editor widget to edit a transfer function's alpha values. This will show the current color map as a background @@ -63,10 +65,10 @@ namespace ospray { //! @} // transform normalized coordinates to widget coordinates - QPointF pointToWidgetPoint(const ospray::vec2f &point); + QPointF pointToWidgetPoint(const ospcommon::vec2f &point); // transform widget coordinates to normalized coordinates - ospray::vec2f widgetPointToPoint(const QPointF &widgetPoint); + ospcommon::vec2f widgetPointToPoint(const QPointF &widgetPoint); // get the index of the selected point based on the clicked point in widget coordinates // returns -1 if no selected point @@ -77,7 +79,7 @@ namespace ospray { //! the points that define the transfer function, in normalize //! coordinates ([0,0], [1,1]) - std::vector points; + std::vector points; //! currently selected point int selectedPointIndex; @@ -101,7 +103,7 @@ namespace ospray { public: //! construct a new color map from given colors - ColorMap(const std::string &name, const std::vector &colors); + ColorMap(const std::string &name, const std::vector &colors); //! return the name of this color map inline std::string getName() const { return name; }; @@ -112,12 +114,12 @@ namespace ospray { //! query function that returns the current color map (to be //! used in a scene graph node, for example - std::vector getColors() const { return colors; }; + std::vector getColors() const { return colors; }; protected: const std::string name; - const std::vector colors; + const std::vector colors; }; public: diff --git a/apps/test1.cpp b/apps/test1.cpp deleted file mode 100644 index 626cba1df1..0000000000 --- a/apps/test1.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "ospray/common/OSPCommon.h" -#include "ospray/common/Thread.h" -#include "common/sys/sync/barrier.h" -#include - -namespace ospray { - - using namespace std; - - volatile size_t sum = 0; - volatile int nextFreeID = 0; - volatile bool done = 0; - double timeToRun = 1.f; - embree::MutexSys mutex; - embree::BarrierSys barrier; - - struct MyThread : public Thread { - MyThread(int numThreads) - { - } - - virtual void run() - { - mutex.lock(); - int myID = nextFreeID++; -#ifdef __LINUX__ - printf("ID no %i runs on core %i\n",myID,sched_getcpu()); -#endif - mutex.unlock(); - - barrier.wait(); - double t0 = getSysTime(); - int lastPing = 0; - while (1) { - barrier.wait(); - if (done) { - break; - } - mutex.lock(); - sum += 1; - mutex.unlock(); - barrier.wait(); - - double t1 = getSysTime(); - - if (myID == 0) { - int numSecs = int(t1-t0); - if (numSecs > lastPing) { - printf("after t=%5.fs: num ops =%8li, that's %f ops/sec\n", - t1-t0,sum,sum/(t1-t0)); - lastPing = numSecs; - } - } - if (myID == 0 && (t1 - t0) >= timeToRun) - done = true; - } - - if (myID == 0) - cout << "total number of OPs: " << sum << endl; - } - - }; - - int numThreads = 10; - int firstThreadID = 1; - - extern "C" int main(int ac, char **av) - { -#ifdef __LINUX__ - printf("main thread runs on core %i\n",sched_getcpu()); -#endif - printf("address of global variables is %li\n",(long)&sum); - - for (int i=1;istart(firstThreadID+i); - } - - while (1) { - sleep(1); - if (done) break; - } - - - for (int i=0;ijoin(); - return 0; - } - -} diff --git a/apps/testMC.cpp b/apps/testMC.cpp deleted file mode 100644 index d85a86bf6c..0000000000 --- a/apps/testMC.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "testMC.h" -#include - -#include "testMC_ispc.h" - -namespace ospray { - float sqr(float f) { return f*f; } - - Field *createTestField(const vec3i &size) - { - Field *field = new Field(size); - for (int z=0;zset(vec3i(x,y,z),f); - } - return field; - } - - void testMC(int ac, const char **av) - { - ospInit(&ac,av); - Field *field = createTestField(vec3i(256)); - field->ie = ispc::createField(field->size.x,field->size.y,field->size.z,field->voxel); - ispc::marchingCubes(field->ie,0.4f); - } -} - -int main(int ac, const char **av) -{ - ospray::testMC(ac,av); -} - - diff --git a/common/AffineSpace.h b/common/AffineSpace.h new file mode 100644 index 0000000000..2b602b0a31 --- /dev/null +++ b/common/AffineSpace.h @@ -0,0 +1,157 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "LinearSpace.h" +#include "box.h" + +namespace ospcommon { + +#define VectorT typename L::Vector +#define ScalarT typename L::Vector::Scalar + + //////////////////////////////////////////////////////////////////////////////// + // Affine Space + //////////////////////////////////////////////////////////////////////////////// + + template + struct AffineSpaceT + { + L l; /*< linear part of affine space */ + VectorT p; /*< affine part of affine space */ + + //////////////////////////////////////////////////////////////////////////////// + // Constructors, Assignment, Cast, Copy Operations + //////////////////////////////////////////////////////////////////////////////// + + inline AffineSpaceT ( ) { } + inline AffineSpaceT ( const AffineSpaceT& other ) { l = other.l; p = other.p; } + inline AffineSpaceT ( const L & other ) { l = other ; p = VectorT(zero); } + inline AffineSpaceT& operator=( const AffineSpaceT& other ) { l = other.l; p = other.p; return *this; } + + inline AffineSpaceT( const VectorT& vx, const VectorT& vy, const VectorT& vz, const VectorT& p ) : l(vx,vy,vz), p(p) {} + inline AffineSpaceT( const L& l, const VectorT& p ) : l(l), p(p) {} + + template inline AffineSpaceT( const AffineSpaceT& s ) : l(s.l), p(s.p) {} + + //////////////////////////////////////////////////////////////////////////////// + // Constants + //////////////////////////////////////////////////////////////////////////////// + + inline AffineSpaceT( ZeroTy ) : l(zero), p(zero) {} + inline AffineSpaceT( OneTy ) : l(one), p(zero) {} + + /*! return matrix for scaling */ + static inline AffineSpaceT scale(const VectorT& s) { return L::scale(s); } + + /*! return matrix for translation */ + static inline AffineSpaceT translate(const VectorT& p) { return AffineSpaceT(one,p); } + + /*! return matrix for rotation, only in 2D */ + static inline AffineSpaceT rotate(const ScalarT& r) { return L::rotate(r); } + + /*! return matrix for rotation around arbitrary point (2D) or axis (3D) */ + static inline AffineSpaceT rotate(const VectorT& u, const ScalarT& r) { return L::rotate(u,r); } + + /*! return matrix for rotation around arbitrary axis and point, only in 3D */ + static inline AffineSpaceT rotate(const VectorT& p, const VectorT& u, const ScalarT& r) { return translate(+p) * rotate(u,r) * translate(-p); } + + /*! return matrix for looking at given point, only in 3D */ + static inline AffineSpaceT lookat(const VectorT& eye, const VectorT& point, const VectorT& up) { + VectorT Z = normalize(point-eye); + VectorT U = normalize(cross(up,Z)); + VectorT V = normalize(cross(Z,U)); + return AffineSpaceT(L(U,V,Z),eye); + } + + }; + + //////////////////////////////////////////////////////////////////////////////// + // Unary Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline AffineSpaceT operator -( const AffineSpaceT& a ) { return AffineSpaceT(-a.l,-a.p); } + template inline AffineSpaceT operator +( const AffineSpaceT& a ) { return AffineSpaceT(+a.l,+a.p); } + template inline AffineSpaceT rcp( const AffineSpaceT& a ) { L il = rcp(a.l); return AffineSpaceT(il,-(il*a.p)); } + + //////////////////////////////////////////////////////////////////////////////// + // Binary Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline const AffineSpaceT operator +( const AffineSpaceT& a, const AffineSpaceT& b ) { return AffineSpaceT(a.l+b.l,a.p+b.p); } + template inline const AffineSpaceT operator -( const AffineSpaceT& a, const AffineSpaceT& b ) { return AffineSpaceT(a.l-b.l,a.p-b.p); } + + template inline const AffineSpaceT operator *( const ScalarT & a, const AffineSpaceT& b ) { return AffineSpaceT(a*b.l,a*b.p); } + template inline const AffineSpaceT operator *( const AffineSpaceT& a, const AffineSpaceT& b ) { return AffineSpaceT(a.l*b.l,a.l*b.p+a.p); } + template inline const AffineSpaceT operator /( const AffineSpaceT& a, const AffineSpaceT& b ) { return a * rcp(b); } + template inline const AffineSpaceT operator /( const AffineSpaceT& a, const ScalarT & b ) { return a * rcp(b); } + + template inline AffineSpaceT& operator *=( AffineSpaceT& a, const AffineSpaceT& b ) { return a = a * b; } + template inline AffineSpaceT& operator *=( AffineSpaceT& a, const ScalarT & b ) { return a = a * b; } + template inline AffineSpaceT& operator /=( AffineSpaceT& a, const AffineSpaceT& b ) { return a = a / b; } + template inline AffineSpaceT& operator /=( AffineSpaceT& a, const ScalarT & b ) { return a = a / b; } + + template inline const VectorT xfmPoint (const AffineSpaceT& m, const VectorT& p) { return madd(VectorT(p.x),m.l.vx,madd(VectorT(p.y),m.l.vy,madd(VectorT(p.z),m.l.vz,m.p))); } + template inline const VectorT xfmVector(const AffineSpaceT& m, const VectorT& v) { return xfmVector(m.l,v); } + template inline const VectorT xfmNormal(const AffineSpaceT& m, const VectorT& n) { return xfmNormal(m.l,n); } + + inline const box3fa xfmBounds(const AffineSpaceT >& m, const box3fa& b) + { + box3fa dst = empty; + const vec3fa p0(b.lower.x,b.lower.y,b.lower.z); dst.extend(xfmPoint(m,p0)); + const vec3fa p1(b.lower.x,b.lower.y,b.upper.z); dst.extend(xfmPoint(m,p1)); + const vec3fa p2(b.lower.x,b.upper.y,b.lower.z); dst.extend(xfmPoint(m,p2)); + const vec3fa p3(b.lower.x,b.upper.y,b.upper.z); dst.extend(xfmPoint(m,p3)); + const vec3fa p4(b.upper.x,b.lower.y,b.lower.z); dst.extend(xfmPoint(m,p4)); + const vec3fa p5(b.upper.x,b.lower.y,b.upper.z); dst.extend(xfmPoint(m,p5)); + const vec3fa p6(b.upper.x,b.upper.y,b.lower.z); dst.extend(xfmPoint(m,p6)); + const vec3fa p7(b.upper.x,b.upper.y,b.upper.z); dst.extend(xfmPoint(m,p7)); + return dst; + } + + //////////////////////////////////////////////////////////////////////////////// + /// Comparison Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline bool operator ==( const AffineSpaceT& a, const AffineSpaceT& b ) { return a.l == b.l && a.p == b.p; } + template inline bool operator !=( const AffineSpaceT& a, const AffineSpaceT& b ) { return a.l != b.l || a.p != b.p; } + + //////////////////////////////////////////////////////////////////////////////// + // Output Operators + //////////////////////////////////////////////////////////////////////////////// + + template static std::ostream& operator<<(std::ostream& cout, const AffineSpaceT& m) { + return cout << "{ l = " << m.l << ", p = " << m.p << " }"; + } + + //////////////////////////////////////////////////////////////////////////////// + // Template Instantiations + //////////////////////////////////////////////////////////////////////////////// + + typedef AffineSpaceT AffineSpace2f; + typedef AffineSpaceT AffineSpace3f; + typedef AffineSpaceT AffineSpace3fa; + typedef AffineSpaceT OrthonormalSpace3f; + + //////////////////////////////////////////////////////////////////////////////// + /*! Template Specialization for 2D: return matrix for rotation around point (rotation around arbitrarty vector is not meaningful in 2D) */ + template<> inline AffineSpace2f AffineSpace2f::rotate(const vec2f& p, const float& r) { return translate(+p) * AffineSpace2f(LinearSpace2f::rotate(r)) * translate(-p); } + +#undef VectorT +#undef ScalarT + +} // ::ospcommon diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000000..9908867a12 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,10 @@ +ADD_LIBRARY(ospray_ospcommon SHARED +# STATIC + common.cpp + FileName.cpp + sysinfo.cpp + ) + + + + diff --git a/common/FileName.cpp b/common/FileName.cpp new file mode 100644 index 0000000000..65b0e11dc1 --- /dev/null +++ b/common/FileName.cpp @@ -0,0 +1,151 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "FileName.h" +#include "sysinfo.h" + +namespace ospcommon +{ +#ifdef __WIN32__ + const char path_sep = '\\'; +#else + const char path_sep = '/'; +#endif + + /*! create an empty filename */ + FileName::FileName () {} + + /*! create a valid filename from a string */ + FileName::FileName (const char* in) { + filename = in; + for (size_t i=0; i struct LinearSpace2 + { + typedef T Vector; + typedef typename T::scalar_t Scalar; + + /*! default matrix constructor */ + inline LinearSpace2 ( ) {} + inline LinearSpace2 ( const LinearSpace2& other ) { vx = other.vx; vy = other.vy; } + inline LinearSpace2& operator=( const LinearSpace2& other ) { vx = other.vx; vy = other.vy; return *this; } + + template inline LinearSpace2( const LinearSpace2& s ) : vx(s.vx), vy(s.vy) {} + + /*! matrix construction from column vectors */ + inline LinearSpace2(const Vector& vx, const Vector& vy) + : vx(vx), vy(vy) {} + + /*! matrix construction from row mayor data */ + inline LinearSpace2(const Scalar& m00, const Scalar& m01, + const Scalar& m10, const Scalar& m11) + : vx(m00,m10), vy(m01,m11) {} + + /*! compute the determinant of the matrix */ + inline const Scalar det() const { return vx.x*vy.y - vx.y*vy.x; } + + /*! compute adjoint matrix */ + inline const LinearSpace2 adjoint() const { return LinearSpace2(vy.y,-vy.x,-vx.y,vx.x); } + + /*! compute inverse matrix */ + inline const LinearSpace2 inverse() const { return adjoint()/det(); } + + /*! compute transposed matrix */ + inline const LinearSpace2 transposed() const { return LinearSpace2(vx.x,vx.y,vy.x,vy.y); } + + /*! returns first row of matrix */ + inline const Vector row0() const { return Vector(vx.x,vy.x); } + + /*! returns second row of matrix */ + inline const Vector row1() const { return Vector(vx.y,vy.y); } + + //////////////////////////////////////////////////////////////////////////////// + /// Constants + //////////////////////////////////////////////////////////////////////////////// + + inline LinearSpace2( ZeroTy ) : vx(zero), vy(zero) {} + inline LinearSpace2( OneTy ) : vx(one, zero), vy(zero, one) {} + + /*! return matrix for scaling */ + static inline LinearSpace2 scale(const Vector& s) { + return LinearSpace2(s.x, 0, + 0 , s.y); + } + + /*! return matrix for rotation */ + static inline LinearSpace2 rotate(const Scalar& r) { + Scalar s = sin(r), c = cos(r); + return LinearSpace2(c, -s, + s, c); + } + + /*! return closest orthogonal matrix (i.e. a general rotation including reflection) */ + LinearSpace2 orthogonal() const { + LinearSpace2 m = *this; + + // mirrored? + Scalar mirror(one); + if (m.det() < Scalar(zero)) { + m.vx = -m.vx; + mirror = -mirror; + } + + // rotation + for (int i = 0; i < 99; i++) { + const LinearSpace2 m_next = 0.5 * (m + m.transposed().inverse()); + const LinearSpace2 d = m_next - m; + m = m_next; + // norm^2 of difference small enough? + if (max(dot(d.vx, d.vx), dot(d.vy, d.vy)) < 1e-8) + break; + } + + // rotation * mirror_x + return LinearSpace2(mirror*m.vx, m.vy); + } + + public: + + /*! the column vectors of the matrix */ + Vector vx,vy; + }; + + //////////////////////////////////////////////////////////////////////////////// + // Unary Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline LinearSpace2 operator -( const LinearSpace2& a ) { return LinearSpace2(-a.vx,-a.vy); } + template inline LinearSpace2 operator +( const LinearSpace2& a ) { return LinearSpace2(+a.vx,+a.vy); } + template inline LinearSpace2 rcp ( const LinearSpace2& a ) { return a.inverse(); } + + //////////////////////////////////////////////////////////////////////////////// + // Binary Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline LinearSpace2 operator +( const LinearSpace2& a, const LinearSpace2& b ) { return LinearSpace2(a.vx+b.vx,a.vy+b.vy); } + template inline LinearSpace2 operator -( const LinearSpace2& a, const LinearSpace2& b ) { return LinearSpace2(a.vx-b.vx,a.vy-b.vy); } + + template inline LinearSpace2 operator*(const typename T::Scalar & a, const LinearSpace2& b) { return LinearSpace2(a*b.vx, a*b.vy); } + template inline T operator*(const LinearSpace2& a, const T & b) { return b.x*a.vx + b.y*a.vy; } + template inline LinearSpace2 operator*(const LinearSpace2& a, const LinearSpace2& b) { return LinearSpace2(a*b.vx, a*b.vy); } + + template inline LinearSpace2 operator/(const LinearSpace2& a, const typename T::Scalar & b) { return LinearSpace2(a.vx/b, a.vy/b); } + template inline LinearSpace2 operator/(const LinearSpace2& a, const LinearSpace2& b) { return a * rcp(b); } + + template inline LinearSpace2& operator *=( LinearSpace2& a, const LinearSpace2& b ) { return a = a * b; } + template inline LinearSpace2& operator /=( LinearSpace2& a, const LinearSpace2& b ) { return a = a / b; } + + //////////////////////////////////////////////////////////////////////////////// + /// Comparison Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline bool operator ==( const LinearSpace2& a, const LinearSpace2& b ) { return a.vx == b.vx && a.vy == b.vy; } + template inline bool operator !=( const LinearSpace2& a, const LinearSpace2& b ) { return a.vx != b.vx || a.vy != b.vy; } + + //////////////////////////////////////////////////////////////////////////////// + /// Output Operators + //////////////////////////////////////////////////////////////////////////////// + + template static std::ostream& operator<<(std::ostream& cout, const LinearSpace2& m) { + return cout << "{ vx = " << m.vx << ", vy = " << m.vy << "}"; + } + + //////////////////////////////////////////////////////////////////////////////// + /// 3D Linear Transform (3x3 Matrix) + //////////////////////////////////////////////////////////////////////////////// + + template struct LinearSpace3 + { + typedef T Vector; + typedef typename T::scalar_t Scalar; + + /*! default matrix constructor */ + inline LinearSpace3 ( ) {} + inline LinearSpace3 ( const LinearSpace3& other ) { vx = other.vx; vy = other.vy; vz = other.vz; } + inline LinearSpace3& operator=( const LinearSpace3& other ) { vx = other.vx; vy = other.vy; vz = other.vz; return *this; } + + template inline LinearSpace3( const LinearSpace3& s ) : vx(s.vx), vy(s.vy), vz(s.vz) {} + + /*! matrix construction from column vectors */ + inline LinearSpace3(const Vector& vx, const Vector& vy, const Vector& vz) + : vx(vx), vy(vy), vz(vz) {} + + /*! construction from quaternion */ + inline LinearSpace3( const QuaternionT& q ) + : vx((q.r*q.r + q.i*q.i - q.j*q.j - q.k*q.k), 2.0f*(q.i*q.j + q.r*q.k), 2.0f*(q.i*q.k - q.r*q.j)) + , vy(2.0f*(q.i*q.j - q.r*q.k), (q.r*q.r - q.i*q.i + q.j*q.j - q.k*q.k), 2.0f*(q.j*q.k + q.r*q.i)) + , vz(2.0f*(q.i*q.k + q.r*q.j), 2.0f*(q.j*q.k - q.r*q.i), (q.r*q.r - q.i*q.i - q.j*q.j + q.k*q.k)) {} + + /*! matrix construction from row mayor data */ + inline LinearSpace3(const Scalar& m00, const Scalar& m01, const Scalar& m02, + const Scalar& m10, const Scalar& m11, const Scalar& m12, + const Scalar& m20, const Scalar& m21, const Scalar& m22) + : vx(m00,m10,m20), vy(m01,m11,m21), vz(m02,m12,m22) {} + + /*! compute the determinant of the matrix */ + inline const Scalar det() const { return dot(vx,cross(vy,vz)); } + + /*! compute adjoint matrix */ + inline const LinearSpace3 adjoint() const { return LinearSpace3(cross(vy,vz),cross(vz,vx),cross(vx,vy)).transposed(); } + + /*! compute inverse matrix */ + inline const LinearSpace3 inverse() const { return adjoint()/det(); } + + /*! compute transposed matrix */ + inline const LinearSpace3 transposed() const { return LinearSpace3(vx.x,vx.y,vx.z,vy.x,vy.y,vy.z,vz.x,vz.y,vz.z); } + + /*! returns first row of matrix */ + inline const Vector row0() const { return Vector(vx.x,vy.x,vz.x); } + + /*! returns second row of matrix */ + inline const Vector row1() const { return Vector(vx.y,vy.y,vz.y); } + + /*! returns third row of matrix */ + inline const Vector row2() const { return Vector(vx.z,vy.z,vz.z); } + + //////////////////////////////////////////////////////////////////////////////// + /// Constants + //////////////////////////////////////////////////////////////////////////////// + + inline LinearSpace3( ZeroTy ) : vx(zero), vy(zero), vz(zero) {} + inline LinearSpace3( OneTy ) : vx(one, zero, zero), vy(zero, one, zero), vz(zero, zero, one) {} + + /*! return matrix for scaling */ + static inline LinearSpace3 scale(const Vector& s) { + return LinearSpace3(s.x, 0, 0, + 0 , s.y, 0, + 0 , 0, s.z); + } + + /*! return matrix for rotation around arbitrary axis */ + static inline LinearSpace3 rotate(const Vector& _u, const Scalar& r) { + Vector u = normalize(_u); + Scalar s = sin(r), c = cos(r); + return LinearSpace3(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)-u.z*s, u.x*u.z*(1-c)+u.y*s, + u.x*u.y*(1-c)+u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)-u.x*s, + u.x*u.z*(1-c)-u.y*s, u.y*u.z*(1-c)+u.x*s, u.z*u.z+(1-u.z*u.z)*c); + } + + public: + + /*! the column vectors of the matrix */ + Vector vx,vy,vz; + }; + + //////////////////////////////////////////////////////////////////////////////// + // Unary Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline LinearSpace3 operator -( const LinearSpace3& a ) { return LinearSpace3(-a.vx,-a.vy,-a.vz); } + template inline LinearSpace3 operator +( const LinearSpace3& a ) { return LinearSpace3(+a.vx,+a.vy,+a.vz); } + template inline LinearSpace3 rcp ( const LinearSpace3& a ) { return a.inverse(); } + + /* constructs a coordinate frame form a normalized normal */ + template inline LinearSpace3 frame(const T& N) + { + const T dx0 = cross(T(one,zero,zero),N); + const T dx1 = cross(T(zero,one,zero),N); + const T dx = normalize(select(dot(dx0,dx0) > dot(dx1,dx1),dx0,dx1)); + const T dy = normalize(cross(N,dx)); + return LinearSpace3(dx,dy,N); + } + + /* constructs a coordinate frame from a normal and approximate x-direction */ + template inline LinearSpace3 frame(const T& N, const T& dxi) + { + if (abs(dot(dxi,N)) > 0.99f) return frame(N); // fallback in case N and dxi are very parallel + const T dx = normalize(cross(dxi,N)); + const T dy = normalize(cross(N,dx)); + return LinearSpace3(dx,dy,N); + } + + /* clamps linear space to range -1 to +1 */ + template inline LinearSpace3 clamp(const LinearSpace3& space) { + return LinearSpace3(clamp(space.vx,T(-1.0f),T(1.0f)), + clamp(space.vy,T(-1.0f),T(1.0f)), + clamp(space.vz,T(-1.0f),T(1.0f))); + } + + //////////////////////////////////////////////////////////////////////////////// + // Binary Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline LinearSpace3 operator +( const LinearSpace3& a, const LinearSpace3& b ) { return LinearSpace3(a.vx+b.vx,a.vy+b.vy,a.vz+b.vz); } + template inline LinearSpace3 operator -( const LinearSpace3& a, const LinearSpace3& b ) { return LinearSpace3(a.vx-b.vx,a.vy-b.vy,a.vz-b.vz); } + + template inline LinearSpace3 operator*(const typename T::Scalar & a, const LinearSpace3& b) { return LinearSpace3(a*b.vx, a*b.vy, a*b.vz); } + template inline T operator*(const LinearSpace3& a, const T & b) { return b.x*a.vx + b.y*a.vy + b.z*a.vz; } + template inline LinearSpace3 operator*(const LinearSpace3& a, const LinearSpace3& b) { return LinearSpace3(a*b.vx, a*b.vy, a*b.vz); } + + template inline LinearSpace3 operator/(const LinearSpace3& a, const typename T::Scalar & b) { return LinearSpace3(a.vx/b, a.vy/b, a.vz/b); } + template inline LinearSpace3 operator/(const LinearSpace3& a, const LinearSpace3& b) { return a * rcp(b); } + + template inline LinearSpace3& operator *=( LinearSpace3& a, const LinearSpace3& b ) { return a = a * b; } + template inline LinearSpace3& operator /=( LinearSpace3& a, const LinearSpace3& b ) { return a = a / b; } + + template inline T xfmPoint (const LinearSpace3& s, const T & a) { return madd(T(a.x),s.vx,madd(T(a.y),s.vy,T(a.z)*s.vz)); } + template inline T xfmVector(const LinearSpace3& s, const T & a) { return madd(T(a.x),s.vx,madd(T(a.y),s.vy,T(a.z)*s.vz)); } + template inline T xfmNormal(const LinearSpace3& s, const T & a) { return xfmVector(s.inverse().transposed(),a); } + + //////////////////////////////////////////////////////////////////////////////// + /// Comparison Operators + //////////////////////////////////////////////////////////////////////////////// + + template inline bool operator ==( const LinearSpace3& a, const LinearSpace3& b ) { return a.vx == b.vx && a.vy == b.vy && a.vz == b.vz; } + template inline bool operator !=( const LinearSpace3& a, const LinearSpace3& b ) { return a.vx != b.vx || a.vy != b.vy || a.vz != b.vz; } + + //////////////////////////////////////////////////////////////////////////////// + /// Output Operators + //////////////////////////////////////////////////////////////////////////////// + + template static std::ostream& operator<<(std::ostream& cout, const LinearSpace3& m) { + return cout << "{ vx = " << m.vx << ", vy = " << m.vy << ", vz = " << m.vz << "}"; + } + + /*! Shortcuts for common linear spaces. */ + typedef LinearSpace2 LinearSpace2f; + typedef LinearSpace3 LinearSpace3f; + typedef LinearSpace3 LinearSpace3fa; + +} // ::ospcommon diff --git a/common/Quaternion.h b/common/Quaternion.h new file mode 100644 index 0000000000..d1d130f163 --- /dev/null +++ b/common/Quaternion.h @@ -0,0 +1,209 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "vec.h" + +namespace ospcommon +{ + //////////////////////////////////////////////////////////////// + // Quaternion Struct + //////////////////////////////////////////////////////////////// + + template + struct QuaternionT + { + typedef vec_t Vector; + + //////////////////////////////////////////////////////////////////////////////// + /// Construction + //////////////////////////////////////////////////////////////////////////////// + + __forceinline QuaternionT ( void ) { } + __forceinline QuaternionT ( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; } + __forceinline QuaternionT& operator=( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; return *this; } + + __forceinline QuaternionT( const T& r ) : r(r), i(zero), j(zero), k(zero) {} + __forceinline explicit QuaternionT( const Vector& v ) : r(zero), i(v.x), j(v.y), k(v.z) {} + __forceinline QuaternionT( const T& r, const T& i, const T& j, const T& k ) : r(r), i(i), j(j), k(k) {} + __forceinline QuaternionT( const T& r, const Vector& v ) : r(r), i(v.x), j(v.y), k(v.z) {} + + __inline QuaternionT( const Vector& vx, const Vector& vy, const Vector& vz ); + __inline QuaternionT( const T& yaw, const T& pitch, const T& roll ); + + //////////////////////////////////////////////////////////////////////////////// + /// Constants + //////////////////////////////////////////////////////////////////////////////// + + __forceinline QuaternionT( ZeroTy ) : r(zero), i(zero), j(zero), k(zero) {} + __forceinline QuaternionT( OneTy ) : r( one), i(zero), j(zero), k(zero) {} + + /*! return quaternion for rotation around arbitrary axis */ + static __forceinline QuaternionT rotate(const Vector& u, const T& r) { + return QuaternionT(cos(T(0.5)*r),sin(T(0.5)*r)*normalize(u)); + } + + /*! returns the rotation axis of the quaternion as a vector */ + __forceinline const Vector v( ) const { return Vector(i, j, k); } + + public: + T r, i, j, k; + }; + + template __forceinline QuaternionT operator *( const T & a, const QuaternionT& b ) { return QuaternionT(a * b.r, a * b.i, a * b.j, a * b.k); } + template __forceinline QuaternionT operator *( const QuaternionT& a, const T & b ) { return QuaternionT(a.r * b, a.i * b, a.j * b, a.k * b); } + + //////////////////////////////////////////////////////////////// + // Unary Operators + //////////////////////////////////////////////////////////////// + + template __forceinline QuaternionT operator +( const QuaternionT& a ) { return QuaternionT(+a.r, +a.i, +a.j, +a.k); } + template __forceinline QuaternionT operator -( const QuaternionT& a ) { return QuaternionT(-a.r, -a.i, -a.j, -a.k); } + template __forceinline QuaternionT conj ( const QuaternionT& a ) { return QuaternionT(a.r, -a.i, -a.j, -a.k); } + template __forceinline T abs ( const QuaternionT& a ) { return sqrt(a.r*a.r + a.i*a.i + a.j*a.j + a.k*a.k); } + template __forceinline QuaternionT rcp ( const QuaternionT& a ) { return conj(a)*rcp(a.r*a.r + a.i*a.i + a.j*a.j + a.k*a.k); } + template __forceinline QuaternionT normalize ( const QuaternionT& a ) { return a*rsqrt(a.r*a.r + a.i*a.i + a.j*a.j + a.k*a.k); } + + //////////////////////////////////////////////////////////////// + // Binary Operators + //////////////////////////////////////////////////////////////// + + template __forceinline QuaternionT operator +( const T & a, const QuaternionT& b ) { return QuaternionT(a + b.r, b.i, b.j, b.k); } + template __forceinline QuaternionT operator +( const QuaternionT& a, const T & b ) { return QuaternionT(a.r + b, a.i, a.j, a.k); } + template __forceinline QuaternionT operator +( const QuaternionT& a, const QuaternionT& b ) { return QuaternionT(a.r + b.r, a.i + b.i, a.j + b.j, a.k + b.k); } + template __forceinline QuaternionT operator -( const T & a, const QuaternionT& b ) { return QuaternionT(a - b.r, -b.i, -b.j, -b.k); } + template __forceinline QuaternionT operator -( const QuaternionT& a, const T & b ) { return QuaternionT(a.r - b, a.i, a.j, a.k); } + template __forceinline QuaternionT operator -( const QuaternionT& a, const QuaternionT& b ) { return QuaternionT(a.r - b.r, a.i - b.i, a.j - b.j, a.k - b.k); } + + template __forceinline typename QuaternionT::Vector operator *( const QuaternionT& a, const typename QuaternionT::Vector & b ) { return (a*QuaternionT(b)*conj(a)).v(); } + template __forceinline QuaternionT operator *( const QuaternionT& a, const QuaternionT& b ) { + return QuaternionT(a.r*b.r - a.i*b.i - a.j*b.j - a.k*b.k, + a.r*b.i + a.i*b.r + a.j*b.k - a.k*b.j, + a.r*b.j - a.i*b.k + a.j*b.r + a.k*b.i, + a.r*b.k + a.i*b.j - a.j*b.i + a.k*b.r); + } + template __forceinline QuaternionT operator /( const T & a, const QuaternionT& b ) { return a*rcp(b); } + template __forceinline QuaternionT operator /( const QuaternionT& a, const T & b ) { return a*rcp(b); } + template __forceinline QuaternionT operator /( const QuaternionT& a, const QuaternionT& b ) { return a*rcp(b); } + + template __forceinline QuaternionT& operator +=( QuaternionT& a, const T & b ) { return a = a+b; } + template __forceinline QuaternionT& operator +=( QuaternionT& a, const QuaternionT& b ) { return a = a+b; } + template __forceinline QuaternionT& operator -=( QuaternionT& a, const T & b ) { return a = a-b; } + template __forceinline QuaternionT& operator -=( QuaternionT& a, const QuaternionT& b ) { return a = a-b; } + template __forceinline QuaternionT& operator *=( QuaternionT& a, const T & b ) { return a = a*b; } + template __forceinline QuaternionT& operator *=( QuaternionT& a, const QuaternionT& b ) { return a = a*b; } + template __forceinline QuaternionT& operator /=( QuaternionT& a, const T & b ) { return a = a*rcp(b); } + template __forceinline QuaternionT& operator /=( QuaternionT& a, const QuaternionT& b ) { return a = a*rcp(b); } + + template __forceinline typename QuaternionT::Vector + xfmPoint ( const QuaternionT& a, + const typename QuaternionT::Vector& b ) + { return (a*QuaternionT(b)*conj(a)).v(); } + + template __forceinline typename QuaternionT::Vector + xfmQuaternion( const QuaternionT& a, + const typename QuaternionT::Vector& b ) + { return (a*QuaternionT(b)*conj(a)).v(); } + + + template __forceinline typename QuaternionT::Vector + xfmNormal( const QuaternionT& a, + const typename QuaternionT::Vector& b ) + { return (a*QuaternionT(b)*conj(a)).v(); } + + //////////////////////////////////////////////////////////////////////////////// + /// Comparison Operators + //////////////////////////////////////////////////////////////////////////////// + + template __forceinline bool operator ==( const QuaternionT& a, const QuaternionT& b ) { return a.r == b.r && a.i == b.i && a.j == b.j && a.k == b.k; } + + template __forceinline bool operator !=( const QuaternionT& a, const QuaternionT& b ) { return a.r != b.r || a.i != b.i || a.j != b.j || a.k != b.k; } + + + //////////////////////////////////////////////////////////////////////////////// + /// Orientation Functions + //////////////////////////////////////////////////////////////////////////////// + + template + QuaternionT::QuaternionT(const typename QuaternionT::Vector& vx, + const typename QuaternionT::Vector& vy, + const typename QuaternionT::Vector& vz ) + { + if ( vx.x + vy.y + vz.z >= T(zero) ) + { + const T t = T(one) + (vx.x + vy.y + vz.z); + const T s = rsqrt(t)*T(0.5f); + r = t*s; + i = (vy.z - vz.y)*s; + j = (vz.x - vx.z)*s; + k = (vx.y - vy.x)*s; + } + else if ( vx.x >= max(vy.y, vz.z) ) + { + const T t = (T(one) + vx.x) - (vy.y + vz.z); + const T s = rsqrt(t)*T(0.5f); + r = (vy.z - vz.y)*s; + i = t*s; + j = (vx.y + vy.x)*s; + k = (vz.x + vx.z)*s; + } + else if ( vy.y >= vz.z ) // if ( vy.y >= max(vz.z, vx.x) ) + { + const T t = (T(one) + vy.y) - (vz.z + vx.x); + const T s = rsqrt(t)*T(0.5f); + r = (vz.x - vx.z)*s; + i = (vx.y + vy.x)*s; + j = t*s; + k = (vy.z + vz.y)*s; + } + else //if ( vz.z >= max(vy.y, vx.x) ) + { + const T t = (T(one) + vz.z) - (vx.x + vy.y); + const T s = rsqrt(t)*T(0.5f); + r = (vx.y - vy.x)*s; + i = (vz.x + vx.z)*s; + j = (vy.z + vz.y)*s; + k = t*s; + } + } + + template QuaternionT::QuaternionT( const T& yaw, const T& pitch, const T& roll ) + { + const T cya = cos(yaw *T(0.5f)); + const T cpi = cos(pitch*T(0.5f)); + const T cro = cos(roll *T(0.5f)); + const T sya = sin(yaw *T(0.5f)); + const T spi = sin(pitch*T(0.5f)); + const T sro = sin(roll *T(0.5f)); + r = cro*cya*cpi + sro*sya*spi; + i = cro*cya*spi + sro*sya*cpi; + j = cro*sya*cpi - sro*cya*spi; + k = sro*cya*cpi - cro*sya*spi; + } + + //////////////////////////////////////////////////////////////////////////////// + /// Output Operators + //////////////////////////////////////////////////////////////////////////////// + + template static std::ostream& operator<<(std::ostream& cout, const QuaternionT& q) { + return cout << "{ r = " << q.r << ", i = " << q.i << ", j = " << q.j << ", k = " << q.k << " }"; + } + + /*! default template instantiations */ + typedef QuaternionT Quaternion3f; + typedef QuaternionT Quaternion3d; +} diff --git a/common/RefCount.h b/common/RefCount.h new file mode 100644 index 0000000000..62e7f5b05c --- /dev/null +++ b/common/RefCount.h @@ -0,0 +1,122 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" +#include // c++11 ... + +/*! iw: TODO: move to c++11-style refcoutned object instead of this + homebrewed one */ +namespace ospcommon +{ +#if defined(__X86_64__) + typedef std::atomic_llong atomic_t; +#else + typedef std::atomic_int atomic_t; +#endif + + static struct NullTy { + } null MAYBE_UNUSED; + + class RefCount + { + public: + RefCount(int val = 0) : refCounter(val) {} + virtual ~RefCount() {}; + + virtual void refInc() { refCounter++; } + virtual void refDec() { if ((--refCounter) == 0) delete this; } + private: + atomic_t refCounter; + }; + + //////////////////////////////////////////////////////////////////////////////// + /// Reference to single object + //////////////////////////////////////////////////////////////////////////////// + + template + class Ref { + public: + Type* const ptr; + + //////////////////////////////////////////////////////////////////////////////// + /// Constructors, Assignment & Cast Operators + //////////////////////////////////////////////////////////////////////////////// + + __forceinline Ref( void ) : ptr(nullptr) {} + __forceinline Ref(NullTy) : ptr(nullptr) {} + __forceinline Ref( const Ref& input ) : ptr(input.ptr) { if ( ptr ) ptr->refInc(); } + + __forceinline Ref( Type* const input ) : ptr(input) { + if ( ptr ) + ptr->refInc(); + } + + __forceinline ~Ref( void ) { + if (ptr) ptr->refDec(); + } + + __forceinline Ref& operator= ( const Ref& input ) + { + if ( input.ptr ) input.ptr->refInc(); + if (ptr) ptr->refDec(); + *(Type**)&ptr = input.ptr; + return *this; + } + + __forceinline Ref& operator= ( Type* const input ) + { + if ( input ) input->refInc(); + if (ptr) ptr->refDec(); + *(Type**)&ptr = input; + return *this; + } + + __forceinline Ref& operator= ( NullTy ) { + if (ptr) ptr->refDec(); + *(Type**)&ptr = nullptr; + return *this; + } + + __forceinline operator bool( void ) const { return ptr != nullptr; } + + __forceinline const Type& operator *( void ) const { return *ptr; } + __forceinline Type& operator *( void ) { return *ptr; } + __forceinline const Type* operator ->( void ) const { return ptr; } + __forceinline Type* operator ->( void ) { return ptr; } + + template + __forceinline Ref cast() { return Ref(static_cast(ptr)); } + template + __forceinline const Ref cast() const { return Ref(static_cast(ptr)); } + + template + __forceinline Ref dynamicCast() { return Ref(dynamic_cast(ptr)); } + template + __forceinline const Ref dynamicCast() const { return Ref(dynamic_cast(ptr)); } + }; + + template __forceinline bool operator < ( const Ref& a, const Ref& b ) { return a.ptr < b.ptr ; } + + template __forceinline bool operator ==( const Ref& a, NullTy ) { return a.ptr == nullptr ; } + template __forceinline bool operator ==( NullTy , const Ref& b ) { return nullptr == b.ptr ; } + template __forceinline bool operator ==( const Ref& a, const Ref& b ) { return a.ptr == b.ptr ; } + + template __forceinline bool operator !=( const Ref& a, NullTy ) { return a.ptr != nullptr ; } + template __forceinline bool operator !=( NullTy , const Ref& b ) { return nullptr != b.ptr ; } + template __forceinline bool operator !=( const Ref& a, const Ref& b ) { return a.ptr != b.ptr ; } +} diff --git a/common/bak.vec.h b/common/bak.vec.h new file mode 100644 index 0000000000..e77a4b6ae3 --- /dev/null +++ b/common/bak.vec.h @@ -0,0 +1,136 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "../common/common.h" + +namespace ospcommon { + + template + struct vec2_t { + typedef T scalar_t; + + inline vec2_t() {}; + inline vec2_t(const vec2_t &o) : x(o.x), y(o.y) {} + inline vec2_t(scalar_t s) : x(s), y(s) {}; + inline vec2_t(scalar_t x, scalar_t y) : x(x), y(y) {}; + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y; } + + T x, y; + }; + + template + struct vec3_t { + typedef T scalar_t; + + inline vec3_t() {}; + inline vec3_t(scalar_t s) : x(s), y(s) {}; + inline vec3_t(scalar_t x, scalar_t y, scalar_t z) : x(x), y(y), z(z) {}; + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y+z; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y*z; } + + T x, y, z; + }; + + template + struct vec4_t { + typedef T scalar_t; + + inline vec4_t() {}; + inline vec4_t(scalar_t s) : x(s), y(s) {}; + inline vec4_t(scalar_t x, scalar_t y, scalar_t z, scalar_t w) : x(x), y(y), z(z), w(w) {}; + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y+z+w; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y*z*w; } + + T x, y, z, w; + }; + + + + // ------------------------------------------------------- + // all vec2 variants + // ------------------------------------------------------- + typedef vec2_t vec2ui; + typedef vec2_t vec2i; + typedef vec2_t vec2f; + typedef vec2_t vec2d; + + // ------------------------------------------------------- + // all vec3 variants + // ------------------------------------------------------- + typedef vec3_t vec3ui; + typedef vec3_t vec3i; + typedef vec3_t vec3f; + typedef vec3_t vec3d; + + // ------------------------------------------------------- + // binary operators + // ------------------------------------------------------- +#define define_operator(operator,op) \ + template \ + inline vec2_t operator(const vec2_t &a, const vec2_t &b) \ + { return vec2_t(a.x op b.x, a.y op b.y); } \ + \ + template \ + inline vec3_t operator(const vec3_t &a, const vec3_t &b) \ + { return vec3_t(a.x op b.x, a.y op b.y, a.z op b.z); } \ + \ + template \ + inline vec4_t operator(const vec4_t &a, const vec4_t &b) \ + { return vec4_t(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); } \ + + define_operator(operator*,*); + define_operator(operator/,/); + define_operator(operator-,-); + define_operator(operator+,+); +#undef define_operator + + // "inherit" std::min/max/etc for basic types + using std::min; + using std::max; + + // ------------------------------------------------------- + // binary functors + // ------------------------------------------------------- +#define define_functor(f) \ + template \ + inline vec2_t f(const vec2_t &a, const vec2_t &b) \ + { return vec2_t(f(a.x,b.x),f(a.y,b.y)); } \ + \ + template \ + inline vec3_t f(const vec3_t &a, const vec3_t &b) \ + { return vec3_t(f(a.x,b.x),f(a.y,b.y),f(a.z,b.z)); } \ + \ + template \ + inline vec4_t f(const vec4_t &a, const vec4_t &b) \ + { return vec4_t(f(a.x,b.x),f(a.y,b.y),f(a.z,b.z),f(a.w,b.w)); } \ + + define_functor(min); + define_functor(max); +#undef define_functor + +} // ::ospcommon diff --git a/common/box.h b/common/box.h new file mode 100644 index 0000000000..63f6c5ae40 --- /dev/null +++ b/common/box.h @@ -0,0 +1,84 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "vec.h" + +namespace ospcommon { + + /*! over over scalar type T and N dimensions */ + template + struct box_t { + typedef T scalar_t; + typedef typename ospcommon::vec_t vec_t; + + inline box_t() {} + inline box_t( EmptyTy ) : lower(pos_inf), upper(neg_inf) {} + inline box_t(const box_t &o) : lower(o.lower), upper(o.upper) {} + inline box_t(const vec_t &lower, const vec_t &upper) : lower(lower), upper(upper) {} + + inline vec_t size() const { return upper - lower; } + inline void extend(const vec_t &v) { lower=min(lower,v), upper=max(upper,v); } + inline void extend(const box_t &b) { lower=min(lower,b.lower), upper=max(upper,b.upper); } + + /*! returns the center of the box (not valid for empty boxes) */ + inline vec_t center() const { return 0.5f * (lower+upper); } + inline bool empty() const { return anyLessThan(upper,lower); } + + vec_t lower, upper; + }; + + template + inline scalar_t area(const box_t &b) { return b.size().product(); } + + /*! compute the intersection of two boxes */ + template + inline box_t intersectionOf(const box_t &a, const box_t &b) + { return box_t(max(a.lower,b.lower), min(a.upper,b.upper)); } + + /*! returns the center of the box (not valid for empty boxes) */ + template + inline vec_t center(const box_t &b) + { return b.center(); } + + // ------------------------------------------------------- + // comparison operator + // ------------------------------------------------------- + template + inline bool operator==(const box_t &a, const box_t &b) + { return a.lower == b.lower && a.upper == b.upper; } + template + inline bool operator!=(const box_t &a, const box_t &b) + { return !(a == b); } + + // ------------------------------------------------------- + // output operator + // ------------------------------------------------------- + template + std::ostream &operator<<(std::ostream &o, const box_t &b) + { o << "[" << b.lower <<":"< box2i; + typedef box_t box3f; + typedef box_t box3fa; + // typedef box_t box2i; + + // this is just a renaming - in some cases the code reads cleaner if + // we're talking about 'regions' than about boxes + typedef box2i region2i; +} // ::ospcommon diff --git a/common/common.cpp b/common/common.cpp new file mode 100644 index 0000000000..9a779d7781 --- /dev/null +++ b/common/common.cpp @@ -0,0 +1,185 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "common.h" +#include "FileName.h" +#include "sysinfo.h" + +// std +#include +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include // for GetSystemTime +#else +# include +# include +# include +#endif + +// std +#include + +namespace ospcommon { + + /*! type for shared library */ + typedef struct opaque_lib_t* lib_t; + + + struct Library + { + std::string name; + lib_t lib; + }; + + /*! return system time in seconds */ + double getSysTime() { +#ifdef _WIN32 + SYSTEMTIME tp; GetSystemTime(&tp); + return double(tp.wSecond) + double(tp.wMilliseconds) / 1E3; +#else + struct timeval tp; gettimeofday(&tp,NULL); + return double(tp.tv_sec) + double(tp.tv_usec)/1E6; +#endif + } + + void removeArgs(int &ac, char **&av, int where, int howMany) + { + for (int i=where+howMany;i loadedLibs; + + + +#if defined(__WIN32__) + /* opens a shared library */ + lib_t openLibrary(const std::string& file) + { + std::string fullName = file+".dll"; + FileName executable = getExecutableFileName(); + HANDLE handle = LoadLibrary((executable.path() + fullName).c_str()); + return lib_t(handle); + } +#else + /* opens a shared library */ + lib_t openLibrary(const std::string& file) + { +#if defined(__MACOSX__) + std::string fullName = "lib"+file+".dylib"; +#else + std::string fullName = "lib"+file+".so"; +#endif + void* lib = dlopen(fullName.c_str(), RTLD_NOW); + if (lib) return lib_t(lib); + FileName executable = getExecutableFileName(); + lib = dlopen((executable.path() + fullName).c_str(),RTLD_NOW); + if (lib == NULL) throw std::runtime_error(dlerror()); + return lib_t(lib); + } +#endif + + void loadLibrary(const std::string &_name) + { +#ifdef OSPRAY_TARGET_MIC + std::string name = _name+"_mic"; +#else + std::string name = _name; +#endif + + for (int i=0;iname == name) + // lib already loaded. + return; + + Library *lib = new Library; + lib->name = name; + lib->lib = openLibrary(name); + if (lib->lib == NULL) + throw std::runtime_error("could not open module lib "+name); + + loadedLibs.push_back(lib); + } + void *getSymbol(const std::string &name) + { + for (int i=0;ilib, name); + if (sym) return sym; + } + + // if none found in the loaded libs, try the default lib ... +#ifdef _WIN32 + void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) + if (!sym) { + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function + sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) + } +#else + void *sym = dlsym(RTLD_DEFAULT,name.c_str()); +#endif + return sym; + } + +// void *getSymbol(const std::string &name) +// { +// // for (int i=0;ilib, name); +// // if (sym) return sym; +// // } + +// // if none found in the loaded libs, try the default lib ... +// #ifdef _WIN32 +// void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) +// if (!sym) { +// MEMORY_BASIC_INFORMATION mbi; +// VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function +// sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) +// } +// #else +// void *sym = dlsym(RTLD_DEFAULT,name.c_str()); +// #endif +// return sym; +// } + +} // ::ospcommon + diff --git a/common/common.h b/common/common.h new file mode 100644 index 0000000000..c2b35d5a49 --- /dev/null +++ b/common/common.h @@ -0,0 +1,84 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" +// c runtime +#include +// std +#include + +#ifdef _WIN32 + typedef unsigned long long id_t; +#endif + +#if defined(__WIN32__) || defined(_WIN32) +// ----------- windows only ----------- +# define _USE_MATH_DEFINES 1 +# include +# include +# ifdef _M_X64 +typedef long long ssize_t; +# else +typedef int ssize_t; +# endif +#else +// ----------- NOT windows ----------- +# include "unistd.h" +#endif + +#include + +#ifdef _WIN32 +# ifdef ospcommon_EXPORTS +# define OSPCOMMON_INTERFACE __declspec(dllexport) +# else +# define OSPCOMMON_INTERFACE __declspec(dllimport) +# endif +#else +# define OSPCOMMON_INTERFACE +#endif + +#ifdef NDEBUG +# define Assert(expr) /* nothing */ +# define Assert2(expr,expl) /* nothing */ +# define AssertError(errMsg) /* nothing */ +#else +# define Assert(expr) \ + ((void)((expr) ? 0 : ((void)ospcommon::doAssertion(__FILE__, __LINE__, #expr, NULL), 0))) +# define Assert2(expr,expl) \ + ((void)((expr) ? 0 : ((void)ospcommon::doAssertion(__FILE__, __LINE__, #expr, expl), 0))) +# define AssertError(errMsg) \ + doAssertion(__FILE__,__LINE__, (errMsg), NULL) +#endif + +#ifdef _WIN32 +#define __PRETTY_FUNCTION__ __FUNCSIG__ +#endif +#define NOTIMPLEMENTED throw std::runtime_error(std::string(__PRETTY_FUNCTION__)+": not implemented..."); + +namespace ospcommon { + + /*! return system time in seconds */ + OSPCOMMON_INTERFACE double getSysTime(); + OSPCOMMON_INTERFACE void doAssertion(const char *file, int line, const char *expr, const char *expl); + /*! remove specified num arguments from an ac/av arglist */ + OSPCOMMON_INTERFACE void removeArgs(int &ac, char **&av, int where, int howMany); + OSPCOMMON_INTERFACE void loadLibrary(const std::string &_name); + OSPCOMMON_INTERFACE void *getSymbol(const std::string &name); + +} // ::ospcommon diff --git a/common/constants.h b/common/constants.h new file mode 100644 index 0000000000..7125844a70 --- /dev/null +++ b/common/constants.h @@ -0,0 +1,166 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "./platform.h" +#include + +#define _USE_MATH_DEFINES +#include // using cmath causes issues under Windows +#include + +namespace ospcommon +{ + static const float one_over_255 = 1.0f/255.0f; + static const float min_rcp_input = 1E-18f; // for abs(x) >= min_rcp_input the newton raphson rcp calculation does not fail + + /* we consider floating point numbers in that range as valid input numbers */ + static float FLT_LARGE = 1.844E18f; + + static struct TrueTy { + __forceinline operator bool( ) const { return true; } + } True MAYBE_UNUSED; + + static struct FalseTy { + __forceinline operator bool( ) const { return false; } + } False MAYBE_UNUSED; + + static struct ZeroTy + { + __forceinline operator double ( ) const { return 0; } + __forceinline operator float ( ) const { return 0; } + __forceinline operator long long( ) const { return 0; } + __forceinline operator unsigned long long( ) const { return 0; } + __forceinline operator long ( ) const { return 0; } + __forceinline operator unsigned long ( ) const { return 0; } + __forceinline operator int ( ) const { return 0; } + __forceinline operator unsigned int ( ) const { return 0; } + __forceinline operator short ( ) const { return 0; } + __forceinline operator unsigned short ( ) const { return 0; } + __forceinline operator char ( ) const { return 0; } + __forceinline operator unsigned char ( ) const { return 0; } + } zero MAYBE_UNUSED; + + static struct OneTy + { + __forceinline operator double ( ) const { return 1; } + __forceinline operator float ( ) const { return 1; } + __forceinline operator long long( ) const { return 1; } + __forceinline operator unsigned long long( ) const { return 1; } + __forceinline operator long ( ) const { return 1; } + __forceinline operator unsigned long ( ) const { return 1; } + __forceinline operator int ( ) const { return 1; } + __forceinline operator unsigned int ( ) const { return 1; } + __forceinline operator short ( ) const { return 1; } + __forceinline operator unsigned short ( ) const { return 1; } + __forceinline operator char ( ) const { return 1; } + __forceinline operator unsigned char ( ) const { return 1; } + } one MAYBE_UNUSED; + + static struct NegInfTy + { + __forceinline operator double ( ) const { return -std::numeric_limits::infinity(); } + __forceinline operator float ( ) const { return -std::numeric_limits::infinity(); } + __forceinline operator long long( ) const { return std::numeric_limits::min(); } + __forceinline operator unsigned long long( ) const { return std::numeric_limits::min(); } + __forceinline operator long ( ) const { return std::numeric_limits::min(); } + __forceinline operator unsigned long ( ) const { return std::numeric_limits::min(); } + __forceinline operator int ( ) const { return std::numeric_limits::min(); } + __forceinline operator unsigned int ( ) const { return std::numeric_limits::min(); } + __forceinline operator short ( ) const { return std::numeric_limits::min(); } + __forceinline operator unsigned short ( ) const { return std::numeric_limits::min(); } + __forceinline operator char ( ) const { return std::numeric_limits::min(); } + __forceinline operator unsigned char ( ) const { return std::numeric_limits::min(); } + + } neg_inf MAYBE_UNUSED; + + static struct PosInfTy + { + __forceinline operator double ( ) const { return std::numeric_limits::infinity(); } + __forceinline operator float ( ) const { return std::numeric_limits::infinity(); } + __forceinline operator long long( ) const { return std::numeric_limits::max(); } + __forceinline operator unsigned long long( ) const { return std::numeric_limits::max(); } + __forceinline operator long ( ) const { return std::numeric_limits::max(); } + __forceinline operator unsigned long ( ) const { return std::numeric_limits::max(); } + __forceinline operator int ( ) const { return std::numeric_limits::max(); } + __forceinline operator unsigned int ( ) const { return std::numeric_limits::max(); } + __forceinline operator short ( ) const { return std::numeric_limits::max(); } + __forceinline operator unsigned short ( ) const { return std::numeric_limits::max(); } + __forceinline operator char ( ) const { return std::numeric_limits::max(); } + __forceinline operator unsigned char ( ) const { return std::numeric_limits::max(); } + } inf MAYBE_UNUSED, pos_inf MAYBE_UNUSED; + + static struct NaNTy + { + __forceinline operator double( ) const { return std::numeric_limits::quiet_NaN(); } + __forceinline operator float ( ) const { return std::numeric_limits::quiet_NaN(); } + } nan MAYBE_UNUSED; + + static struct UlpTy + { + __forceinline operator double( ) const { return std::numeric_limits::epsilon(); } + __forceinline operator float ( ) const { return std::numeric_limits::epsilon(); } + } ulp MAYBE_UNUSED; + + static struct PiTy + { + __forceinline operator double( ) const { return M_PI; } + __forceinline operator float ( ) const { return M_PI; } + } pi MAYBE_UNUSED; + + static struct OneOverPiTy + { + __forceinline operator double( ) const { return M_1_PI; } + __forceinline operator float ( ) const { return M_1_PI; } + } one_over_pi MAYBE_UNUSED; + + static struct TwoPiTy + { + __forceinline operator double( ) const { return 2.0*M_PI; } + __forceinline operator float ( ) const { return 2.0*M_PI; } + } two_pi MAYBE_UNUSED; + + static struct OneOverTwoPiTy + { + __forceinline operator double( ) const { return 0.5*M_1_PI; } + __forceinline operator float ( ) const { return 0.5*M_1_PI; } + } one_over_two_pi MAYBE_UNUSED; + + static struct FourPiTy + { + __forceinline operator double( ) const { return 4.0*M_PI; } + __forceinline operator float ( ) const { return 4.0*M_PI; } + } four_pi MAYBE_UNUSED; + + static struct OneOverFourPiTy + { + __forceinline operator double( ) const { return 0.25*M_1_PI; } + __forceinline operator float ( ) const { return 0.25*M_1_PI; } + } one_over_four_pi MAYBE_UNUSED; + + static struct StepTy { + } step MAYBE_UNUSED; + + static struct ReverseStepTy { + } reverse_step MAYBE_UNUSED; + + static struct EmptyTy { + } empty MAYBE_UNUSED; + + static struct FullTy { + } full MAYBE_UNUSED; +} diff --git a/common/intrinsics.h b/common/intrinsics.h new file mode 100644 index 0000000000..18bb6f7790 --- /dev/null +++ b/common/intrinsics.h @@ -0,0 +1,863 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" + +#if defined(__WIN32__) +#include +#endif + +#if defined(__SSE__) +#include +#endif + +#if defined(__SSE2__) +#include +#endif + +#if defined(__SSE3__) +#include +#endif + +#if defined(__SSSE3__) +#include +#endif + +#if defined (__SSE4_1__) +#include +#endif + +#if defined (__SSE4_2__) +#include +#endif + +#if defined(__AVX__) || defined(__MIC__) +#include +#endif + +#if defined(__BMI__) && defined(__GNUC__) + #if !defined(_tzcnt_u32) + #define _tzcnt_u32 __tzcnt_u32 + #endif + #if !defined(_tzcnt_u64) + #define _tzcnt_u64 __tzcnt_u64 + #endif +#endif + +#if defined(__LZCNT__) + #if !defined(_lzcnt_u32) + #define _lzcnt_u32 __lzcnt32 + #endif + #if !defined(_lzcnt_u64) + #define _lzcnt_u64 __lzcnt64 + #endif +#endif + +#if defined(__MIC__) +# include +#endif + +#if defined(__WIN32__) +# define NOMINMAX +# include +#endif + +/* normally defined in pmmintrin.h, but we always need this */ +#if !defined(_MM_SET_DENORMALS_ZERO_MODE) +#define _MM_DENORMALS_ZERO_ON (0x0040) +#define _MM_DENORMALS_ZERO_OFF (0x0000) +#define _MM_DENORMALS_ZERO_MASK (0x0040) +#define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x))) +#endif + +namespace ospcommon +{ + +//////////////////////////////////////////////////////////////////////////////// +/// Windows Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__WIN32__) + + __forceinline size_t read_tsc() + { + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + return li.QuadPart; + } + +#if defined(__SSE4_2__) + + __forceinline int __popcnt(int in) { + return _mm_popcnt_u32(in); + } + + __forceinline unsigned __popcnt(unsigned in) { + return _mm_popcnt_u32(in); + } + +#if defined(__X86_64__) + __forceinline size_t __popcnt(size_t in) { + return _mm_popcnt_u64(in); + } +#endif + +#endif + + __forceinline int __bsf(int v) { +#if defined(__AVX2__) + return _tzcnt_u32(v); +#else + unsigned long r = 0; _BitScanForward(&r,v); return r; +#endif + } + + __forceinline unsigned __bsf(unsigned v) { +#if defined(__AVX2__) + return _tzcnt_u32(v); +#else + unsigned long r = 0; _BitScanForward(&r,v); return r; +#endif + } + +#if defined(__X86_64__) + __forceinline size_t __bsf(size_t v) { +#if defined(__AVX2__) + return _tzcnt_u64(v); +#else + unsigned long r = 0; _BitScanForward64(&r,v); return r; +#endif + } +#endif + + __forceinline int __bscf(int& v) + { + int i = __bsf(v); + v &= v-1; + return i; + } + + __forceinline unsigned __bscf(unsigned& v) + { + unsigned i = __bsf(v); + v &= v-1; + return i; + } + +#if defined(__X86_64__) + __forceinline size_t __bscf(size_t& v) + { + size_t i = __bsf(v); + v &= v-1; + return i; + } +#endif + + __forceinline int __bsr(int v) { +#if defined(__AVX2__) + return _lzcnt_u32(v); +#else + unsigned long r = 0; _BitScanReverse(&r,v); return r; +#endif + } + + __forceinline unsigned __bsr(unsigned v) { +#if defined(__AVX2__) + return _lzcnt_u32(v); +#else + unsigned long r = 0; _BitScanReverse(&r,v); return r; +#endif + } + +#if defined(__X86_64__) + __forceinline size_t __bsr(size_t v) { +#if defined(__AVX2__) + return _lzcnt_u64(v); +#else + unsigned long r = 0; _BitScanReverse64(&r,v); return r; +#endif + } +#endif + + __forceinline int lzcnt(const int x) + { +#if defined(__AVX2__) + return _lzcnt_u32(x); +#else + if (unlikely(x == 0)) return 32; + return 31 - __bsr(x); +#endif + } + + __forceinline int __btc(int v, int i) { + long r = v; _bittestandcomplement(&r,i); return r; + } + + __forceinline int __bts(int v, int i) { + long r = v; _bittestandset(&r,i); return r; + } + + __forceinline int __btr(int v, int i) { + long r = v; _bittestandreset(&r,i); return r; + } + +#if defined(__X86_64__) + + __forceinline size_t __btc(size_t v, size_t i) { + size_t r = v; _bittestandcomplement64((__int64*)&r,i); return r; + } + + __forceinline size_t __bts(size_t v, size_t i) { + __int64 r = v; _bittestandset64(&r,i); return r; + } + + __forceinline size_t __btr(size_t v, size_t i) { + __int64 r = v; _bittestandreset64(&r,i); return r; + } + +#endif + +// typedef int16_t atomic16_t; + +// __forceinline int16_t atomic_add(volatile int16_t* p, const int16_t v) { +// return _InterlockedExchangeAdd16((volatile short*)p,v); +// } + +// __forceinline int16_t atomic_sub(volatile int16_t* p, const int16_t v) { +// return _InterlockedExchangeAdd16((volatile short*)p,-v); +// } + +// __forceinline int16_t atomic_xchg(volatile int16_t *p, int16_t v) { +// return _InterlockedExchange16((volatile short*)p, v); +// } + +// __forceinline int16_t atomic_cmpxchg(volatile int16_t* p, const int16_t c, const int16_t v) { +// return _InterlockedCompareExchange16((volatile short*)p,v,c); +// } + +// __forceinline int16_t atomic_and(volatile int16_t* p, const int16_t v) { +// return _InterlockedAnd16((volatile short*)p,v); +// } + +// __forceinline int16_t atomic_or(volatile int16_t* p, const int16_t v) { +// return _InterlockedOr16((volatile short*)p,v); +// } + +// typedef int32_t atomic32_t; + +// __forceinline int32_t atomic_add(volatile int32_t* p, const int32_t v) { +// return _InterlockedExchangeAdd((volatile long*)p,v); +// } + +// __forceinline int32_t atomic_sub(volatile int32_t* p, const int32_t v) { +// return _InterlockedExchangeAdd((volatile long*)p,-v); +// } + +// __forceinline int32_t atomic_xchg(volatile int32_t *p, int32_t v) { +// return _InterlockedExchange((volatile long*)p, v); +// } + +// __forceinline int32_t atomic_cmpxchg(volatile int32_t* p, const int32_t c, const int32_t v) { +// return _InterlockedCompareExchange((volatile long*)p,v,c); +// } + +// __forceinline int32_t atomic_and(volatile int32_t* p, const int32_t v) { +// return _InterlockedAnd((volatile long*)p,v); +// } + +// __forceinline int32_t atomic_or(volatile int32_t* p, const int32_t v) { +// return _InterlockedOr((volatile long*)p,v); +// } + +// #if defined(__X86_64__) + +// typedef int64_t atomic64_t; + +// __forceinline int64_t atomic_add(volatile int64_t* m, const int64_t v) { +// return _InterlockedExchangeAdd64(m,v); +// } + +// __forceinline int64_t atomic_sub(volatile int64_t* m, const int64_t v) { +// return _InterlockedExchangeAdd64(m,-v); +// } + +// __forceinline int64_t atomic_xchg(volatile int64_t *p, int64_t v) { +// return _InterlockedExchange64((volatile long long *)p, v); +// } + +// __forceinline int64_t atomic_cmpxchg(volatile int64_t* m, const int64_t c, const int64_t v) { +// return _InterlockedCompareExchange64(m,v,c); +// } + +// __forceinline int64_t atomic_and(volatile int64_t* p, const int64_t v) { +// return _InterlockedAnd64((volatile int64_t*)p,v); +// } + +// __forceinline int64_t atomic_or(volatile int64_t* p, const int64_t v) { +// return _InterlockedOr64((volatile int64_t*)p,v); +// } + +// #endif + +//////////////////////////////////////////////////////////////////////////////// +/// Unix Platform +//////////////////////////////////////////////////////////////////////////////// + +#else + +#if defined(__i386__) && defined(__PIC__) + + __forceinline void __cpuid(int out[4], int op) + { + asm volatile ("xchg{l}\t{%%}ebx, %1\n\t" + "cpuid\n\t" + "xchg{l}\t{%%}ebx, %1\n\t" + : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) + : "0"(op)); + } + + __forceinline void __cpuid_count(int out[4], int op1, int op2) + { + asm volatile ("xchg{l}\t{%%}ebx, %1\n\t" + "cpuid\n\t" + "xchg{l}\t{%%}ebx, %1\n\t" + : "=a" (out[0]), "=r" (out[1]), "=c" (out[2]), "=d" (out[3]) + : "0" (op1), "2" (op2)); + } + +#else + + __forceinline void __cpuid(int out[4], int op) { + asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op)); + } + + __forceinline void __cpuid_count(int out[4], int op1, int op2) { + asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op1), "c"(op2)); + } + +#endif + + __forceinline uint64_t read_tsc() { + uint32_t high,low; + asm volatile ("rdtsc" : "=d"(high), "=a"(low)); + return (((uint64_t)high) << 32) + (uint64_t)low; + } + +#if !defined(__MIC__) + +#if defined(__SSE4_2__) + __forceinline unsigned int __popcnt(unsigned int in) { + int r = 0; asm ("popcnt %1,%0" : "=r"(r) : "r"(in)); return r; + } +#endif + + __forceinline int __bsf(int v) { +#if defined(__AVX2__) + return _tzcnt_u32(v); +#else + int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; +#endif + } + + __forceinline unsigned __bsf(unsigned v) + { +#if defined(__AVX2__) + return _tzcnt_u32(v); +#else + unsigned r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; +#endif + } + + __forceinline size_t __bsf(size_t v) { +#if defined(__AVX2__) +#if defined(__X86_64__) + return _tzcnt_u64(v); +#else + return _tzcnt_u32(v); +#endif +#else + size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; +#endif + } + + __forceinline int __bscf(int& v) + { + int i = __bsf(v); + v &= v-1; + return i; + } + + __forceinline unsigned int __bscf(unsigned int& v) + { + unsigned int i = __bsf(v); + v &= v-1; + return i; + } + + __forceinline size_t __bscf(size_t& v) + { + size_t i = __bsf(v); + v &= v-1; + return i; + } + + __forceinline int __bsr(int v) { +#if defined(__AVX2__) + return 31 - _lzcnt_u32(v); +#else + int r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; +#endif + } + + __forceinline unsigned __bsr(unsigned v) { +#if defined(__AVX2__) + return 31 - _lzcnt_u32(v); +#else + unsigned r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; +#endif + } + + __forceinline size_t __bsr(size_t v) { +#if defined(__AVX2__) +#if defined(__X86_64__) + return 63 - _lzcnt_u64(v); +#else + return 31 - _lzcnt_u32(v); +#endif +#else + size_t r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; +#endif + } + + __forceinline int lzcnt(const int x) + { +#if defined(__AVX2__) + return _lzcnt_u32(x); +#else + if (unlikely(x == 0)) return 32; + return 31 - __bsr(x); +#endif + } + + __forceinline size_t __blsr(size_t v) { +#if defined(__AVX2__) +#if defined(__INTEL_COMPILER) + return _blsr_u64(v); +#else + return __blsr_u64(v); +#endif +#else + return v & (v-1); +#endif + } + + __forceinline int __btc(int v, int i) { + int r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r; + } + + __forceinline int __bts(int v, int i) { + int r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; + } + + __forceinline int __btr(int v, int i) { + int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; + } + + __forceinline size_t __btc(size_t v, size_t i) { + size_t r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r; + } + + __forceinline size_t __bts(size_t v, size_t i) { + size_t r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; + } + + __forceinline size_t __btr(size_t v, size_t i) { + size_t r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; + } + +#else + + static const unsigned int BITSCAN_NO_BIT_SET_32 = 32; + static const size_t BITSCAN_NO_BIT_SET_64 = 64; + + __forceinline unsigned int clz(const unsigned int x) { + return _lzcnt_u32(x); + } + + __forceinline size_t clz(const size_t x) { + return _lzcnt_u64(x); + } + + __forceinline unsigned int bitscan(unsigned int v) { + return _mm_tzcnt_32(v); + } + + __forceinline size_t bitscan64(size_t v) { + return _mm_tzcnt_64(v); + } + + __forceinline unsigned int bitscan(const int index, const unsigned int v) { + return _mm_tzcnti_32(index,v); + }; + + __forceinline size_t bitscan64(const ssize_t index, const size_t v) { + return _mm_tzcnti_64(index,v); + }; + + __forceinline int __popcnt(int v) { + return _mm_countbits_32(v); + } + + __forceinline unsigned int __popcnt(unsigned int v) { + return _mm_countbits_32(v); + } + + __forceinline unsigned int countbits(unsigned int v) { + return _mm_countbits_32(v); + }; + + __forceinline size_t __popcnt(size_t v) { + return _mm_countbits_64(v); + } + + __forceinline size_t countbits64(size_t v) { + return _mm_countbits_64(v); + }; + + __forceinline int __bsf(int v) { + return bitscan(v); + } + + __forceinline unsigned int __bsf(unsigned int v) { + return bitscan(v); + } + + __forceinline size_t __bsf(size_t v) { + return bitscan(v); + } + + __forceinline size_t __btc(size_t v, size_t i) { + return v ^ (size_t(1) << i); + } + + __forceinline unsigned int __bsr(unsigned int v) { + return 31 - _lzcnt_u32(v); + } + + __forceinline size_t __bsr(size_t v) { + return 63 - _lzcnt_u64(v); + } + +#endif + +// typedef int8_t atomic8_t; + +// __forceinline int8_t atomic_add( int8_t volatile* value, int8_t input ) { +// return __sync_fetch_and_add(value, input); +// } + +// __forceinline int8_t atomic_sub( int8_t volatile* value, int8_t input ) { +// return __sync_fetch_and_add(value, -input); +// } + +// __forceinline int8_t atomic_xchg( int8_t volatile* value, int8_t input ) { +// return __sync_lock_test_and_set(value, input); +// } + +// __forceinline int8_t atomic_cmpxchg( int8_t volatile* value, int8_t comparand, const int8_t input ) { +// return __sync_val_compare_and_swap(value, comparand, input); +// } + +// typedef int16_t atomic16_t; + +// __forceinline int16_t atomic_add( int16_t volatile* value, int16_t input ) { +// return __sync_fetch_and_add(value, input); +// } + +// __forceinline int16_t atomic_sub( int16_t volatile* value, int16_t input ) { +// return __sync_fetch_and_add(value, -input); +// } + +// __forceinline int16_t atomic_xchg( int16_t volatile* value, int16_t input ) { +// return __sync_lock_test_and_set(value, input); +// } + +// __forceinline int16_t atomic_cmpxchg( int16_t volatile* value, int16_t comparand, const int16_t input ) { +// return __sync_val_compare_and_swap(value, comparand, input); +// } + +// typedef int32_t atomic32_t; + +// __forceinline int32_t atomic_add( int32_t volatile* value, int32_t input ) { +// return __sync_fetch_and_add(value, input); +// } + +// __forceinline int32_t atomic_sub( int32_t volatile* value, int32_t input ) { +// return __sync_fetch_and_add(value, -input); +// } + +// __forceinline int32_t atomic_xchg( int32_t volatile* value, int32_t input ) { +// return __sync_lock_test_and_set(value, input); +// } + +// __forceinline int32_t atomic_cmpxchg( int32_t volatile* value, int32_t comparand, const int32_t input ) { +// return __sync_val_compare_and_swap(value, comparand, input); +// } + +// __forceinline int32_t atomic_or(int32_t volatile* value, int32_t input) { +// return __sync_fetch_and_or(value, input); +// } + +// __forceinline int32_t atomic_and(int32_t volatile* value, int32_t input) { +// return __sync_fetch_and_and(value, input); +// } + +// #if defined(__X86_64__) + +// typedef int64_t atomic64_t; + +// __forceinline int64_t atomic_add( int64_t volatile* value, int64_t input ) { +// return __sync_fetch_and_add(value, input); +// } + +// __forceinline int64_t atomic_sub( int64_t volatile* value, int64_t input ) { +// return __sync_fetch_and_add(value, -input); +// } + +// __forceinline int64_t atomic_xchg( int64_t volatile* value, int64_t input ) { +// return __sync_lock_test_and_set(value, input); +// } + +// __forceinline int64_t atomic_cmpxchg( int64_t volatile* value, int64_t comparand, const int64_t input) { +// return __sync_val_compare_and_swap(value, comparand, input); +// } + +// __forceinline int64_t atomic_or(int64_t volatile* value, int64_t input) { +// return __sync_fetch_and_or(value, input); +// } + +// __forceinline int64_t atomic_and(int64_t volatile* value, int64_t input) { +// return __sync_fetch_and_and(value, input); +// } + +// #endif + +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// All Platforms +//////////////////////////////////////////////////////////////////////////////// + +// #if defined(__X86_64__) +// typedef atomic64_t atomic_t; +// #else +// typedef atomic32_t atomic_t; +// #endif + +// #if defined(__X86_64__) + +// template +// __forceinline T* atomic_xchg_ptr( T* volatile* value, const T* input) +// { return (T*)atomic_xchg((int64_t*)value,(int64_t)input); } + +// template +// __forceinline T* atomic_cmpxchg_ptr( T* volatile* value, T* comparand, const T* input ) +// { return (T*)atomic_cmpxchg((int64_t*)value,(int64_t)comparand,(int64_t)input); } + +// #else + +// template +// __forceinline T* atomic_xchg_ptr( T* volatile* value, const T* input) +// { return (T*)atomic_xchg((int32_t*)value,(int32_t)input); } + +// template +// __forceinline T* atomic_cmpxchg_ptr( T* volatile* value, T* comparand, const T* input ) +// { return (T*)atomic_cmpxchg((int32_t*)value,(int32_t)comparand,(int32_t)input); } + +// #endif + +// __forceinline void atomic_min_f32(volatile float *__restrict__ ptr, const float b) +// { +// const int int_b = *(int*)&b; +// while (1) +// { +// float a = *ptr; +// if (a <= b) break; +// const int int_a = *(int*)&a; +// const int result = atomic_cmpxchg((int*)ptr,int_a,int_b); +// if (result == int_a) break; +// } +// } + +// __forceinline void atomic_max_f32(volatile float *__restrict__ ptr, const float b) +// { +// const int int_b = *(int*)&b; +// while (1) +// { +// float a = *ptr; +// if (a >= b) break; +// const int int_a = *(int*)&a; +// const int result = atomic_cmpxchg((int*)ptr,int_a,int_b); +// if (result == int_a) break; +// } +// } + +// __forceinline void atomic_min_i32(volatile int *__restrict__ ptr, const int b) +// { +// while (1) +// { +// int a = *ptr; +// if (a <= b) break; +// const int int_a = *(int*)&a; +// const int result = atomic_cmpxchg((int*)ptr,int_a,b); +// if (result == int_a) break; +// } +// } + +// __forceinline void atomic_max_i32(volatile int *__restrict__ ptr, const int b) +// { +// while (1) +// { +// int a = *ptr; +// if (a >= b) break; +// const int int_a = *(int*)&a; +// const int result = atomic_cmpxchg((int*)ptr,int_a,b); +// if (result == int_a) break; +// } +// } + +// __forceinline void atomic_min_ui32(volatile unsigned int *__restrict__ ptr, const unsigned int b) +// { +// while (1) +// { +// unsigned int a = *ptr; +// if (a <= b) break; +// const unsigned int int_a = *(unsigned int*)&a; +// const unsigned int result = atomic_cmpxchg((int*)ptr,int_a,b); +// if (result == int_a) break; +// } +// } + +// __forceinline void atomic_max_ui32(volatile unsigned int *__restrict__ ptr, const unsigned int b) +// { +// while (1) +// { +// unsigned int a = *ptr; +// if (a >= b) break; +// const unsigned int int_a = *(unsigned int*)&a; +// const unsigned int result = atomic_cmpxchg((int*)ptr,int_a,b); +// if (result == int_a) break; +// } +// } + +// __forceinline void atomic_add_f32(volatile float *__restrict__ ptr, const float b) +// { +// while (1) +// { +// float a = *ptr; +// float ab = a + b; +// const int int_a = *(int*)&a; +// const int int_ab = *(int*)&ab; +// const int result = atomic_cmpxchg((int*)ptr,int_a,int_ab); +// if (result == int_a) break; +// } +// } + + __forceinline uint64_t rdtsc() + { +#if !defined(__MIC__) + int dummy[4]; + __cpuid(dummy,0); + uint64_t clock = read_tsc(); + __cpuid(dummy,0); + return clock; +#else + return read_tsc(); +#endif + } + +// #if defined(__MIC__) +// __forceinline void __pause_cpu (const unsigned int cycles = 1024) { +// _mm_delay_32(cycles); +// } +// #else +// __forceinline void __pause_cpu (const int cycles = 0) { +// for (size_t i=0; i<8; i++) +// _mm_pause(); +// } +// #endif + +// __forceinline void __pause_cpu_expfalloff(unsigned int &cycles, const unsigned int max_cycles) +// { +// __pause_cpu(cycles); +// cycles += cycles; +// if (cycles > max_cycles) +// cycles = max_cycles; +// } + +// /* prefetches */ +// __forceinline void prefetchL1 (const void* ptr) { _mm_prefetch((const char*)ptr,_MM_HINT_T0); } +// __forceinline void prefetchL2 (const void* ptr) { _mm_prefetch((const char*)ptr,_MM_HINT_T1); } +// __forceinline void prefetchL3 (const void* ptr) { _mm_prefetch((const char*)ptr,_MM_HINT_T2); } +// __forceinline void prefetchNTA(const void* ptr) { _mm_prefetch((const char*)ptr,_MM_HINT_NTA); } +// __forceinline void prefetchEX (const void* ptr) { +// #if defined(__INTEL_COMPILER) +// _mm_prefetch((const char*)ptr,_MM_HINT_ET0); +// #else +// _mm_prefetch((const char*)ptr,_MM_HINT_T0); +// #endif +// } + +// __forceinline void prefetchL1EX(const void* ptr) { +// #if defined(__MIC__) +// _mm_prefetch((const char*)ptr,_MM_HINT_ET0); +// #else +// prefetchEX(ptr); +// #endif +// } + +// __forceinline void prefetchL2EX(const void* ptr) { +// #if defined(__MIC__) +// _mm_prefetch((const char*)ptr,_MM_HINT_ET2); +// #else +// prefetchEX(ptr); +// #endif +// } + +// #if defined(__MIC__) +// __forceinline void evictL1(const void * __restrict__ m) { +// _mm_clevict(m,_MM_HINT_T0); +// } + +// __forceinline void evictL2(const void * __restrict__ m) { +// _mm_clevict(m,_MM_HINT_T1); +// } +// #endif + +// /* compiler memory barriers */ +// #if defined(__GNUC__) || defined(__clang__) +// # define __memory_barrier() asm volatile("" ::: "memory") +// #elif defined(__MIC__) +// #define __memory_barrier() +// #elif defined(__INTEL_COMPILER) +// //#define __memory_barrier() __memory_barrier() +// #elif defined(_MSC_VER) +// # define __memory_barrier() _ReadWriteBarrier() +// #endif + +} diff --git a/common/math.h b/common/math.h new file mode 100644 index 0000000000..03b3e59e36 --- /dev/null +++ b/common/math.h @@ -0,0 +1,302 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" +#include "constants.h" +#include + +#if defined(__WIN32__) +#include +#if (__MSV_VER <= 1700) +namespace std +{ + __forceinline bool isinf ( const float x ) { return !_finite(x); } + __forceinline bool isnan ( const float x ) { return _isnan(x); } + __forceinline bool isfinite (const float x) { return _finite(x); } +} +#endif +#else +#include +#endif + +namespace ospcommon +{ + __forceinline bool isvalid ( const float& v ) { + return (v > -FLT_LARGE) & (v < +FLT_LARGE); + } + + __forceinline int cast_f2i(float f) { + union { float f; int i; } v; v.f = f; return v.i; + } + + __forceinline float cast_i2f(int i) { + union { float f; int i; } v; v.i = i; return v.f; + } + +#if defined(__WIN32__) + __forceinline bool finite ( const float x ) { return _finite(x) != 0; } +#endif + + __forceinline float sign ( const float x ) { return x<0?-1.0f:1.0f; } + __forceinline float sqr ( const float x ) { return x*x; } + +#ifndef __MIC__ + __forceinline float rcp ( const float x ) + { + const __m128 a = _mm_set_ss(x); + const __m128 r = _mm_rcp_ps(a); +#if defined(__AVX2__) + return _mm_cvtss_f32(_mm_mul_ps(r,_mm_fnmadd_ps(r, a, _mm_set_ss(2.0f)))); +#else + return _mm_cvtss_f32(_mm_mul_ps(r,_mm_sub_ps(_mm_set_ss(2.0f), _mm_mul_ps(r, a)))); +#endif + } + + __forceinline float signmsk ( const float x ) { + return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(0x80000000)))); + } + __forceinline float xorf( const float x, const float y ) { + return _mm_cvtss_f32(_mm_xor_ps(_mm_set_ss(x),_mm_set_ss(y))); + } + __forceinline float andf( const float x, const unsigned y ) { + return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(y)))); + } + __forceinline float rsqrt( const float x ) { + const __m128 a = _mm_set_ss(x); + const __m128 r = _mm_rsqrt_ps(a); + const __m128 c = _mm_add_ps(_mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r), + _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r), _mm_mul_ps(r, r))); + return _mm_cvtss_f32(c); + } +#else + __forceinline float rcp ( const float x ) { return 1.0f/x; } + __forceinline float signmsk ( const float x ) { return cast_i2f(cast_f2i(x)&0x80000000); } + __forceinline float xorf( const float x, const float y ) { return cast_i2f(cast_f2i(x) ^ cast_f2i(y)); } + __forceinline float andf( const float x, const float y ) { return cast_i2f(cast_f2i(x) & cast_f2i(y)); } + __forceinline float rsqrt( const float x ) { return 1.0f/sqrtf(x); } +#endif + +#if !defined(__WIN32__) + __forceinline float abs ( const float x ) { return ::fabsf(x); } + __forceinline float acos ( const float x ) { return ::acosf (x); } + __forceinline float asin ( const float x ) { return ::asinf (x); } + __forceinline float atan ( const float x ) { return ::atanf (x); } + __forceinline float atan2( const float y, const float x ) { return ::atan2f(y, x); } + __forceinline float cos ( const float x ) { return ::cosf (x); } + __forceinline float cosh ( const float x ) { return ::coshf (x); } + __forceinline float exp ( const float x ) { return ::expf (x); } + __forceinline float fmod ( const float x, const float y ) { return ::fmodf (x, y); } + __forceinline float log ( const float x ) { return ::logf (x); } + __forceinline float log10( const float x ) { return ::log10f(x); } + __forceinline float pow ( const float x, const float y ) { return ::powf (x, y); } + __forceinline float sin ( const float x ) { return ::sinf (x); } + __forceinline float sinh ( const float x ) { return ::sinhf (x); } + __forceinline float sqrt ( const float x ) { return ::sqrtf (x); } + __forceinline float tan ( const float x ) { return ::tanf (x); } + __forceinline float tanh ( const float x ) { return ::tanhf (x); } + __forceinline float floor( const float x ) { return ::floorf (x); } + __forceinline float ceil ( const float x ) { return ::ceilf (x); } +#endif + __forceinline float frac ( const float x ) { return x-floor(x); } + + __forceinline double abs ( const double x ) { return ::fabs(x); } + __forceinline double sign ( const double x ) { return x<0?-1.0:1.0; } + __forceinline double acos ( const double x ) { return ::acos (x); } + __forceinline double asin ( const double x ) { return ::asin (x); } + __forceinline double atan ( const double x ) { return ::atan (x); } + __forceinline double atan2( const double y, const double x ) { return ::atan2(y, x); } + __forceinline double cos ( const double x ) { return ::cos (x); } + __forceinline double cosh ( const double x ) { return ::cosh (x); } + __forceinline double exp ( const double x ) { return ::exp (x); } + __forceinline double fmod ( const double x, const double y ) { return ::fmod (x, y); } + __forceinline double log ( const double x ) { return ::log (x); } + __forceinline double log10( const double x ) { return ::log10(x); } + __forceinline double pow ( const double x, const double y ) { return ::pow (x, y); } + __forceinline double rcp ( const double x ) { return 1.0/x; } + __forceinline double rsqrt( const double x ) { return 1.0/::sqrt(x); } + __forceinline double sin ( const double x ) { return ::sin (x); } + __forceinline double sinh ( const double x ) { return ::sinh (x); } + __forceinline double sqr ( const double x ) { return x*x; } + __forceinline double sqrt ( const double x ) { return ::sqrt (x); } + __forceinline double tan ( const double x ) { return ::tan (x); } + __forceinline double tanh ( const double x ) { return ::tanh (x); } + __forceinline double floor( const double x ) { return ::floor (x); } + __forceinline double ceil ( const double x ) { return ::ceil (x); } + +#if defined(__SSE4_1__) + __forceinline float mini(float a, float b) { + const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); + const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); + const __m128i ci = _mm_min_epi32(ai,bi); + return _mm_cvtss_f32(_mm_castsi128_ps(ci)); + } +#endif + +#if defined(__SSE4_1__) + __forceinline float maxi(float a, float b) { + const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); + const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); + const __m128i ci = _mm_max_epi32(ai,bi); + return _mm_cvtss_f32(_mm_castsi128_ps(ci)); + } +#endif + + __forceinline int min(int a, int b) { return a __forceinline T min(const T& a, const T& b, const T& c) { return min(min(a,b),c); } + template __forceinline T min(const T& a, const T& b, const T& c, const T& d) { return min(min(a,b),min(c,d)); } + template __forceinline T min(const T& a, const T& b, const T& c, const T& d, const T& e) { return min(min(min(a,b),min(c,d)),e); } + + __forceinline int max(int a, int b) { return a __forceinline T max(const T& a, const T& b, const T& c) { return max(max(a,b),c); } + template __forceinline T max(const T& a, const T& b, const T& c, const T& d) { return max(max(a,b),max(c,d)); } + template __forceinline T max(const T& a, const T& b, const T& c, const T& d, const T& e) { return max(max(max(a,b),max(c,d)),e); } + +#if defined(__MACOSX__) + __forceinline ssize_t min(ssize_t a, ssize_t b) { return a __forceinline T clamp(const T& x, const T& lower = T(zero), const T& upper = T(one)) { return max(min(x,upper),lower); } + template __forceinline T clampz(const T& x, const T& upper) { return max(T(zero), min(x,upper)); } + + template __forceinline T deg2rad ( const T& x ) { return x * T(1.74532925199432957692e-2f); } + template __forceinline T rad2deg ( const T& x ) { return x * T(5.72957795130823208768e1f); } + template __forceinline T sin2cos ( const T& x ) { return sqrt(max(T(zero),T(one)-x*x)); } + template __forceinline T cos2sin ( const T& x ) { return sin2cos(x); } + +#if defined(__AVX2__) + __forceinline float madd ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fmadd_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } + __forceinline float msub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } + __forceinline float nmadd ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmadd_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } + __forceinline float nmsub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } +#else + __forceinline float madd ( const float a, const float b, const float c) { return a*b+c; } + __forceinline float msub ( const float a, const float b, const float c) { return a*b-c; } + __forceinline float nmadd ( const float a, const float b, const float c) { return -a*b+c;} + __forceinline float nmsub ( const float a, const float b, const float c) { return -a*b-c; } +#endif + + /*! random functions */ + template T random() { return T(0); } +#if defined(_WIN32) + template<> __forceinline int random() { return int(rand()) ^ (int(rand()) << 8) ^ (int(rand()) << 16); } + template<> __forceinline uint32_t random() { return uint32_t(rand()) ^ (uint32_t(rand()) << 8) ^ (uint32_t(rand()) << 16); } +#else + template<> __forceinline int random() { return int(rand()); } + template<> __forceinline uint32_t random() { return uint32_t(rand()) ^ (uint32_t(rand()) << 16); } +#endif + template<> __forceinline float random() { return rand()/float(RAND_MAX); } + template<> __forceinline double random() { return rand()/double(RAND_MAX); } + +#if _WIN32 + __forceinline double drand48() { + return double(rand())/double(RAND_MAX); + } + + __forceinline void srand48(long seed) { + return srand(seed); + } +#endif + + /*! selects */ + __forceinline bool select(bool s, bool t , bool f) { return s ? t : f; } + __forceinline int select(bool s, int t, int f) { return s ? t : f; } + __forceinline float select(bool s, float t, float f) { return s ? t : f; } + + template + __forceinline T lerp2(const float x0, const float x1, const float x2, const float x3,const T &u, const T &v) { + return (1.0f-u)*(1.0f-v)*x0 + u*(1.0f-v)*x1 + (1.0f-u)*v*x2 + u*v*x3; + } + + /*! exchange */ + template __forceinline void xchg ( T& a, T& b ) { const T tmp = a; a = b; b = tmp; } + + /*! bit reverse operation */ + template + __forceinline T bitReverse(const T& vin) + { + T v = vin; + v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1); + v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2); + v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4); + v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8); + v = ( v >> 16 ) | ( v << 16); + return v; + } + + /*! bit interleave operation */ + template + __forceinline T bitInterleave(const T& xin, const T& yin, const T& zin) + { + T x = xin, y = yin, z = zin; + x = (x | (x << 16)) & 0x030000FF; + x = (x | (x << 8)) & 0x0300F00F; + x = (x | (x << 4)) & 0x030C30C3; + x = (x | (x << 2)) & 0x09249249; + + y = (y | (y << 16)) & 0x030000FF; + y = (y | (y << 8)) & 0x0300F00F; + y = (y | (y << 4)) & 0x030C30C3; + y = (y | (y << 2)) & 0x09249249; + + z = (z | (z << 16)) & 0x030000FF; + z = (z | (z << 8)) & 0x0300F00F; + z = (z | (z << 4)) & 0x030C30C3; + z = (z | (z << 2)) & 0x09249249; + + return x | (y << 1) | (z << 2); + } + + /*! bit interleave operation for 64bit data types*/ + template + __forceinline T bitInterleave64(const T& xin, const T& yin, const T& zin){ + T x = xin & 0x1fffff; + T y = yin & 0x1fffff; + T z = zin & 0x1fffff; + + x = (x | x << 32) & 0x1f00000000ffff; + x = (x | x << 16) & 0x1f0000ff0000ff; + x = (x | x << 8) & 0x100f00f00f00f00f; + x = (x | x << 4) & 0x10c30c30c30c30c3; + x = (x | x << 2) & 0x1249249249249249; + + y = (y | y << 32) & 0x1f00000000ffff; + y = (y | y << 16) & 0x1f0000ff0000ff; + y = (y | y << 8) & 0x100f00f00f00f00f; + y = (y | y << 4) & 0x10c30c30c30c30c3; + y = (y | y << 2) & 0x1249249249249249; + + z = (z | z << 32) & 0x1f00000000ffff; + z = (z | z << 16) & 0x1f0000ff0000ff; + z = (z | z << 8) & 0x100f00f00f00f00f; + z = (z | z << 4) & 0x10c30c30c30c30c3; + z = (z | z << 2) & 0x1249249249249249; + + return x | (y << 1) | (z << 2); + } +} diff --git a/common/mpi.h b/common/mpi.h new file mode 100644 index 0000000000..2fa5c7a6a9 --- /dev/null +++ b/common/mpi.h @@ -0,0 +1,62 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include +#include + +#define MPI_CALL(cmd) { int rc = MPI_##cmd; if (rc != MPI_SUCCESS) throw std::runtime_error("mpi error"); } + +#define error(msg) throw std::runtime_error(msg) + + +namespace ospcommon { + + struct MPIComm { + MPI_Comm comm; + int size, rank, isInterComm; + + void setTo(MPI_Comm comm); + void dupFrom(MPI_Comm comm); + void setSizeAndRank(); + }; + + inline void MPIComm::setSizeAndRank() + { + MPI_CALL(Comm_test_inter(comm,&isInterComm)); + if (isInterComm) { + MPI_CALL(Comm_remote_size(comm,&size)); + rank = -1; + } else { + MPI_CALL(Comm_size(comm,&size)); + MPI_CALL(Comm_rank(comm,&rank)); + } + } + + inline void MPIComm::setTo(MPI_Comm comm) + { + this->comm = comm; + setSizeAndRank(); + } + + inline void MPIComm::dupFrom(MPI_Comm comm) + { + MPI_CALL(Comm_dup(comm,&this->comm)); + setSizeAndRank(); + } + +} // ::ospcommon + + diff --git a/common/platform.h b/common/platform.h new file mode 100644 index 0000000000..37916d72e4 --- /dev/null +++ b/common/platform.h @@ -0,0 +1,343 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +/// detect platform +//////////////////////////////////////////////////////////////////////////////// + +/* detect 32 or 64 platform */ +#if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64) +#define __X86_64__ +#endif + +/* detect Linux platform */ +#if defined(linux) || defined(__linux__) || defined(__LINUX__) +# if !defined(__LINUX__) +# define __LINUX__ +# endif +# if !defined(__UNIX__) +# define __UNIX__ +# endif +#endif + +/* detect FreeBSD platform */ +#if defined(__FreeBSD__) || defined(__FREEBSD__) +# if !defined(__FREEBSD__) +# define __FREEBSD__ +# endif +# if !defined(__UNIX__) +# define __UNIX__ +# endif +#endif + +/* detect Windows 95/98/NT/2000/XP/Vista/7 platform */ +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(__CYGWIN__) +# if !defined(__WIN32__) +# define __WIN32__ +# endif +#endif + +/* detect Cygwin platform */ +#if defined(__CYGWIN__) +# if !defined(__UNIX__) +# define __UNIX__ +# endif +#endif + +/* detect MAC OS X platform */ +#if defined(__APPLE__) || defined(MACOSX) || defined(__MACOSX__) +# if !defined(__MACOSX__) +# define __MACOSX__ +# endif +# if !defined(__UNIX__) +# define __UNIX__ +# endif +#endif + +/* try to detect other Unix systems */ +#if defined(__unix__) || defined (unix) || defined(__unix) || defined(_unix) +# if !defined(__UNIX__) +# define __UNIX__ +# endif +#endif + +#if defined (_DEBUG) +#define DEBUG +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// ISA configuration +//////////////////////////////////////////////////////////////////////////////// + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) + #define __SSE__ + #define __SSE2__ +#endif + +#if defined(__WIN32__) && !defined(__clang__) +#if defined(CONFIG_SSE41) + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #define __SSE3__ + #define __SSSE3__ + #define __SSE4_1__ + #endif +#endif +#if defined(CONFIG_SSE42) + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #define __SSE3__ + #define __SSSE3__ + #define __SSE4_1__ + #define __SSE4_2__ + #endif +#endif +#if defined(CONFIG_AVX) + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #define __SSE3__ + #define __SSSE3__ + #define __SSE4_1__ + #define __SSE4_2__ + #if !defined(__AVX__) + #define __AVX__ + #endif + #endif +#endif +#if defined(CONFIG_AVX2) + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #define __SSE3__ + #define __SSSE3__ + #define __SSE4_1__ + #define __SSE4_2__ + #if !defined(__AVX__) + #define __AVX__ + #endif + #if !defined(__AVX2__) + #define __AVX2__ + #endif + #endif +#endif +#if defined(CONFIG_AVX512) + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #define __SSE3__ + #define __SSSE3__ + #define __SSE4_1__ + #define __SSE4_2__ + #if !defined(__AVX__) + #define __AVX__ + #endif + #if !defined(__AVX2__) + #define __AVX2__ + #endif + #if !defined(__AVX512F__) + #define __AVX512F__ + #endif + #endif +#endif + +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Makros +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __WIN32__ +#define __dllexport __declspec(dllexport) +#define __dllimport __declspec(dllimport) +#else +#define __dllexport __attribute__ ((visibility ("default"))) +#define __dllimport +#endif + +#ifdef __WIN32__ +#undef __noinline +#define __noinline __declspec(noinline) +//#define __forceinline __forceinline +//#define __restrict __restrict +#if defined(__INTEL_COMPILER) +#define __restrict__ __restrict +#else +#define __restrict__ //__restrict // causes issues with MSVC +#endif +#define __thread __declspec(thread) +#define __aligned(...) __declspec(align(__VA_ARGS__)) +//#define __FUNCTION__ __FUNCTION__ +#define debugbreak() __debugbreak() + +#else +#undef __noinline +#undef __forceinline +#define __noinline __attribute__((noinline)) +#define __forceinline inline __attribute__((always_inline)) +//#define __restrict __restrict +//#define __thread __thread +#define __aligned(...) __attribute__((aligned(__VA_ARGS__))) +#define __FUNCTION__ __PRETTY_FUNCTION__ +#define debugbreak() asm ("int $3") +#endif + +#ifdef __GNUC__ + #define MAYBE_UNUSED __attribute__((used)) +#else + #define MAYBE_UNUSED +#endif + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#define likely(expr) (expr) +#define unlikely(expr) (expr) +#else +#define likely(expr) __builtin_expect((bool)(expr),true ) +#define unlikely(expr) __builtin_expect((bool)(expr),false) +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Error handling and debugging +//////////////////////////////////////////////////////////////////////////////// + +/* debug printing macros */ +#define STRING(x) #x +#define TOSTRING(x) STRING(x) +#define PING std::cout << __FILE__ << " (" << __LINE__ << "): " << __FUNCTION__ << std::endl +#define PRINT(x) std::cout << STRING(x) << " = " << (x) << std::endl +#define PRINT2(x,y) std::cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << std::endl +#define PRINT3(x,y,z) std::cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << std::endl +#define PRINT4(x,y,z,w) std::cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << std::endl + +#define THROW_RUNTIME_ERROR(str) \ + throw std::runtime_error(std::string(__FILE__) + " (" + std::to_string((long long)__LINE__) + "): " + std::string(str)); + +#if defined(__MIC__) +#define FATAL(x) { std::cerr << "Error in " << __FUNCTION__ << " : " << x << std::endl << std::flush; exit(1); } +#define WARNING(x) std::cerr << "Warning:" << std::string(x) << std::endl +#else +#define FATAL(x) THROW_RUNTIME_ERROR(x) +#define WARNING(x) std::cerr << "Warning:" << std::string(x) << std::endl +#endif + +#define NOT_IMPLEMENTED FATAL(std::string(__FUNCTION__) + " not implemented") + +//////////////////////////////////////////////////////////////////////////////// +/// Basic Types +//////////////////////////////////////////////////////////////////////////////// + +/* default floating-point type */ +typedef float real; + +/* windows does not have ssize_t */ +#if defined(__WIN32__) +#if defined(__X86_64__) +typedef int64_t ssize_t; +#else +typedef int32_t ssize_t; +#endif +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Disable some compiler warnings +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__INTEL_COMPILER) +#pragma warning(disable:265 ) // floating-point operation result is out of range +#pragma warning(disable:383 ) // value copied to temporary, reference to temporary used +#pragma warning(disable:869 ) // parameter was never referenced +#pragma warning(disable:981 ) // operands are evaluated in unspecified order +#pragma warning(disable:1418) // external function definition with no prior declaration +#pragma warning(disable:1419) // external declaration in primary source file +#pragma warning(disable:1572) // floating-point equality and inequality comparisons are unreliable +#pragma warning(disable:94 ) // the size of an array must be greater than zero +#pragma warning(disable:1599) // declaration hides parameter +#pragma warning(disable:424 ) // extra ";" ignored +#pragma warning(disable:2196) // routine is both "inline" and "noinline" +#pragma warning(disable:177 ) // label was declared but never referenced +#pragma warning(disable:114 ) // function was referenced but not defined +#endif + +#if defined(_MSC_VER) +#pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union +#pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) +#pragma warning(disable:4267) // '=' : conversion from 'size_t' to 'unsigned long', possible loss of data +#pragma warning(disable:4244) // 'argument' : conversion from 'ssize_t' to 'unsigned int', possible loss of data +#pragma warning(disable:4355) // 'this' : used in base member initializer list +#pragma warning(disable:391 ) // '<=' : signed / unsigned mismatch +#pragma warning(disable:4018) // '<' : signed / unsigned mismatch +#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float' +#pragma warning(disable:4068) // unknown pragma +#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable:4838) // conversion from 'unsigned int' to 'const int' requires a narrowing conversion) +#pragma warning(disable:4227) // anachronism used : qualifiers on reference are ignored +#endif + +#if defined(__clang__) && !defined(__INTEL_COMPILER) +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wreorder" +#pragma clang diagnostic ignored "-Wmicrosoft" +#pragma clang diagnostic ignored "-Wunused-private-field" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Some macros for static profiling +//////////////////////////////////////////////////////////////////////////////// + +#if defined (__GNUC__) +#define IACA_SSC_MARK( MARK_ID ) \ +__asm__ __volatile__ ( \ + "\n\t movl $"#MARK_ID", %%ebx" \ + "\n\t .byte 0x64, 0x67, 0x90" \ + : : : "memory" ); + +#define IACA_UD_BYTES __asm__ __volatile__ ("\n\t .byte 0x0F, 0x0B"); + +#else +#define IACA_UD_BYTES {__asm _emit 0x0F \ + __asm _emit 0x0B} + +#define IACA_SSC_MARK(x) {__asm mov ebx, x\ + __asm _emit 0x64 \ + __asm _emit 0x67 \ + __asm _emit 0x90 } + +#define IACA_VC64_START __writegsbyte(111, 111); +#define IACA_VC64_END __writegsbyte(222, 222); + +#endif + +#define IACA_START {IACA_UD_BYTES \ + IACA_SSC_MARK(111)} +#define IACA_END {IACA_SSC_MARK(222) \ + IACA_UD_BYTES} + +namespace ospcommon { + +} + diff --git a/common/sysinfo.cpp b/common/sysinfo.cpp new file mode 100644 index 0000000000..0d54268c59 --- /dev/null +++ b/common/sysinfo.cpp @@ -0,0 +1,515 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "sysinfo.h" +//#include "string.h" +#include "intrinsics.h" +#include + +//////////////////////////////////////////////////////////////////////////////// +/// All Platforms +//////////////////////////////////////////////////////////////////////////////// + +namespace ospcommon +{ + std::string to_string(long long l) + { + std::stringstream ss; + ss << l; + return ss.str(); + } + + std::string getPlatformName() + { +#if defined(__LINUX__) && !defined(__X86_64__) + return "Linux (32bit)"; +#elif defined(__LINUX__) && defined(__X86_64__) + return "Linux (64bit)"; +#elif defined(__FREEBSD__) && !defined(__X86_64__) + return "FreeBSD (32bit)"; +#elif defined(__FREEBSD__) && defined(__X86_64__) + return "FreeBSD (64bit)"; +#elif defined(__CYGWIN__) && !defined(__X86_64__) + return "Cygwin (32bit)"; +#elif defined(__CYGWIN__) && defined(__X86_64__) + return "Cygwin (64bit)"; +#elif defined(__WIN32__) && !defined(__X86_64__) + return "Windows (32bit)"; +#elif defined(__WIN32__) && defined(__X86_64__) + return "Windows (64bit)"; +#elif defined(__MACOSX__) && !defined(__X86_64__) + return "Mac OS X (32bit)"; +#elif defined(__MACOSX__) && defined(__X86_64__) + return "Mac OS X (64bit)"; +#elif defined(__UNIX__) && !defined(__X86_64__) + return "Unix (32bit)"; +#elif defined(__UNIX__) && defined(__X86_64__) + return "Unix (64bit)"; +#else + return "Unknown"; +#endif + } + + std::string getCompilerName() + { +#if defined(__INTEL_COMPILER) + int icc_mayor = __INTEL_COMPILER / 100 % 100; + int icc_minor = __INTEL_COMPILER % 100; + std::string version = "Intel Compiler "; + version += ospcommon::to_string((long long)icc_mayor); + version += "." + ospcommon::to_string((long long)icc_minor); +#if defined(__INTEL_COMPILER_UPDATE) + version += "." + ospcommon::to_string((long long)__INTEL_COMPILER_UPDATE); +#endif + return version; +#elif defined(__clang__) + return "CLANG " __clang_version__; +#elif defined (__GNUC__) + return "GCC " __VERSION__; +#elif defined(_MSC_VER) + std::string version = ospcommon::to_string((long long)_MSC_FULL_VER); + version.insert(4,"."); + version.insert(9,"."); + version.insert(2,"."); + return "Visual C++ Compiler " + version; +#else + return "Unknown Compiler"; +#endif + } + + std::string getCPUVendor() + { + int cpuinfo[4]; + __cpuid (cpuinfo, 0); + int name[4]; + name[0] = cpuinfo[1]; + name[1] = cpuinfo[3]; + name[2] = cpuinfo[2]; + name[3] = 0; + return (char*)name; + } + + CPUModel getCPUModel() + { + int out[4]; + __cpuid(out, 0); + if (out[0] < 1) return CPU_UNKNOWN; + __cpuid(out, 1); + int family = ((out[0] >> 8) & 0x0F) + ((out[0] >> 20) & 0xFF); + int model = ((out[0] >> 4) & 0x0F) | ((out[0] >> 12) & 0xF0); + if (family == 11) return CPU_KNC; + if (family != 6) return CPU_UNKNOWN; // earlier than P6 + if (model == 0x0E) return CPU_CORE1; // Core 1 + if (model == 0x0F) return CPU_CORE2; // Core 2, 65 nm + if (model == 0x16) return CPU_CORE2; // Core 2, 65 nm Celeron + if (model == 0x17) return CPU_CORE2; // Core 2, 45 nm + if (model == 0x1A) return CPU_CORE_NEHALEM; // Core i7, Nehalem + if (model == 0x1E) return CPU_CORE_NEHALEM; // Core i7 + if (model == 0x1F) return CPU_CORE_NEHALEM; // Core i7 + if (model == 0x2C) return CPU_CORE_NEHALEM; // Core i7, Xeon + if (model == 0x2E) return CPU_CORE_NEHALEM; // Core i7, Xeon + if (model == 0x2A) return CPU_CORE_SANDYBRIDGE; // Core i7, SandyBridge + if (model == 0x2D) return CPU_CORE_SANDYBRIDGE; // Core i7, SandyBridge + if (model == 0x45) return CPU_HASWELL; // Haswell + if (model == 0x3C) return CPU_HASWELL; // Haswell + return CPU_UNKNOWN; + } + + std::string stringOfCPUModel(CPUModel model) + { + switch (model) { + case CPU_KNC : return "Knights Corner"; + case CPU_CORE1 : return "Core1"; + case CPU_CORE2 : return "Core2"; + case CPU_CORE_NEHALEM : return "Nehalem"; + case CPU_CORE_SANDYBRIDGE: return "SandyBridge"; + case CPU_HASWELL : return "Haswell"; + default : return "Unknown CPU"; + } + } + + /* constants to access destination registers of CPUID instruction */ + static const int EAX = 0; + static const int EBX = 1; + static const int ECX = 2; + static const int EDX = 3; + + /* cpuid[eax=0].ecx */ + static const int CPU_FEATURE_BIT_SSE3 = 1 << 0; + static const int CPU_FEATURE_BIT_SSSE3 = 1 << 9; + static const int CPU_FEATURE_BIT_FMA3 = 1 << 12; + static const int CPU_FEATURE_BIT_SSE4_1 = 1 << 19; + static const int CPU_FEATURE_BIT_SSE4_2 = 1 << 20; + static const int CPU_FEATURE_BIT_MOVBE = 1 << 22; + static const int CPU_FEATURE_BIT_POPCNT = 1 << 23; + static const int CPU_FEATURE_BIT_XSAVE = 1 << 26; + static const int CPU_FEATURE_BIT_OXSAVE = 1 << 27; + static const int CPU_FEATURE_BIT_AVX = 1 << 28; + static const int CPU_FEATURE_BIT_F16C = 1 << 29; + static const int CPU_FEATURE_BIT_RDRAND = 1 << 30; + + /* cpuid[eax=1].edx */ + static const int CPU_FEATURE_BIT_SSE = 1 << 25; + static const int CPU_FEATURE_BIT_SSE2 = 1 << 26; + + /* cpuid[eax=0x80000001].ecx */ + static const int CPU_FEATURE_BIT_LZCNT = 1 << 5; + + /* cpuid[eax=7,ecx=0].ebx */ + static const int CPU_FEATURE_BIT_BMI1 = 1 << 3; + static const int CPU_FEATURE_BIT_AVX2 = 1 << 5; + static const int CPU_FEATURE_BIT_BMI2 = 1 << 8; + static const int CPU_FEATURE_BIT_AVX512F = 1 << 16; // AVX512F (foundation) + static const int CPU_FEATURE_BIT_AVX512DQ = 1 << 17; // AVX512DQ + static const int CPU_FEATURE_BIT_AVX512PF = 1 << 26; // AVX512PF (prefetch) + static const int CPU_FEATURE_BIT_AVX512ER = 1 << 27; // AVX512ER (exponential and reciprocal) + static const int CPU_FEATURE_BIT_AVX512CD = 1 << 28; // AVX512CD (conflict detection) + static const int CPU_FEATURE_BIT_AVX512BW = 1 << 30; // AVX512BW + static const int CPU_FEATURE_BIT_AVX512VL = 1 << 31; // AVX512VL (EVEX.128 and EVEX.256 AVX512 instructions) + static const int CPU_FEATURE_BIT_AVX512IFMA = 1 << 21; // AVX512IFMA + + /* cpuid[eax=7,ecx=0].ecx */ + static const int CPU_FEATURE_BIT_AVX512VBMI = 1 << 1; // AVX512VBMI + + __noinline int64_t get_xcr0() + { +#if defined (__WIN32__) + int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 +#if defined(__INTEL_COMPILER) + xcr0 = _xgetbv(0); +#elif (defined(_MSC_VER) && (_MSC_FULL_VER >= 160040219)) // min VS2010 SP1 compiler is required + xcr0 = _xgetbv(0); +#else +#pragma message ("WARNING: AVX not supported by your compiler.") + xcr0 = 0; +#endif + return xcr0; + +#else + + int xcr0 = 0; +#if defined(__INTEL_COMPILER) + __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx" ); +#elif ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && (!defined(__MACOSX__) || defined(__TARGET_AVX__) || defined(__TARGET_AVX2__)) + __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx" ); +#elif ((__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ >= 1)) + __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx" ); +#else +#pragma message ("WARNING: AVX not supported by your compiler.") + xcr0 = 0; +#endif + return xcr0; +#endif + } + + int getCPUFeatures() + { + /* cache CPU features access */ + static int cpu_features = 0; + if (cpu_features) + return cpu_features; + + /* get number of CPUID leaves */ + int cpuid_leaf0[4]; + __cpuid(cpuid_leaf0, 0x00000000); + unsigned nIds = cpuid_leaf0[EAX]; + + /* get number of extended CPUID leaves */ + int cpuid_leafe[4]; + __cpuid(cpuid_leafe, 0x80000000); + unsigned nExIds = cpuid_leafe[EAX]; + + /* get CPUID leaves for EAX = 1,7, and 0x80000001 */ + int cpuid_leaf_1[4] = { 0,0,0,0 }; + int cpuid_leaf_7[4] = { 0,0,0,0 }; + int cpuid_leaf_e1[4] = { 0,0,0,0 }; + if (nIds >= 1) __cpuid (cpuid_leaf_1,0x00000001); +#if _WIN32 +#if _MSC_VER && (_MSC_FULL_VER < 160040219) +#else + if (nIds >= 7) __cpuidex(cpuid_leaf_7,0x00000007,0); +#endif +#else + if (nIds >= 7) __cpuid_count(cpuid_leaf_7,0x00000007,0); +#endif + if (nExIds >= 0x80000001) __cpuid(cpuid_leaf_e1,0x80000001); + + /* detect if OS saves XMM, YMM, and ZMM states */ + bool xmm_enabled = true; + bool ymm_enabled = false; + bool zmm_enabled = false; + if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_OXSAVE) { + int64_t xcr0 = get_xcr0(); + xmm_enabled = ((xcr0 & 0x02) == 0x02); /* check if xmm are enabled in XCR0 */ + ymm_enabled = xmm_enabled && ((xcr0 & 0x04) == 0x04); /* check if ymm state are enabled in XCR0 */ + zmm_enabled = ymm_enabled && ((xcr0 & 0xE0) == 0xE0); /* check if OPMASK state, upper 256-bit of ZMM0-ZMM15 and ZMM16-ZMM31 state are enabled in XCR0 */ + } + + if (xmm_enabled && cpuid_leaf_1[EDX] & CPU_FEATURE_BIT_SSE ) cpu_features |= CPU_FEATURE_SSE; + if (xmm_enabled && cpuid_leaf_1[EDX] & CPU_FEATURE_BIT_SSE2 ) cpu_features |= CPU_FEATURE_SSE2; + if (xmm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE3 ) cpu_features |= CPU_FEATURE_SSE3; + if (xmm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSSE3 ) cpu_features |= CPU_FEATURE_SSSE3; + if (xmm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE4_1) cpu_features |= CPU_FEATURE_SSE41; + if (xmm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE4_2) cpu_features |= CPU_FEATURE_SSE42; + if ( cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_POPCNT) cpu_features |= CPU_FEATURE_POPCNT; + if (ymm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_AVX ) cpu_features |= CPU_FEATURE_AVX; + if (xmm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_F16C ) cpu_features |= CPU_FEATURE_F16C; + if ( cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_RDRAND) cpu_features |= CPU_FEATURE_RDRAND; + if (ymm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX2 ) cpu_features |= CPU_FEATURE_AVX2; + if (ymm_enabled && cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_FMA3 ) cpu_features |= CPU_FEATURE_FMA3; + if (cpuid_leaf_e1[ECX] & CPU_FEATURE_BIT_LZCNT) cpu_features |= CPU_FEATURE_LZCNT; + if (cpuid_leaf_7 [EBX] & CPU_FEATURE_BIT_BMI1 ) cpu_features |= CPU_FEATURE_BMI1; + if (cpuid_leaf_7 [EBX] & CPU_FEATURE_BIT_BMI2 ) cpu_features |= CPU_FEATURE_BMI2; + + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512F ) cpu_features |= CPU_FEATURE_AVX512F; + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512DQ) cpu_features |= CPU_FEATURE_AVX512DQ; + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512PF) cpu_features |= CPU_FEATURE_AVX512PF; + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512ER) cpu_features |= CPU_FEATURE_AVX512ER; + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512CD) cpu_features |= CPU_FEATURE_AVX512CD; + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512BW) cpu_features |= CPU_FEATURE_AVX512BW; + if (zmm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512IFMA) cpu_features |= CPU_FEATURE_AVX512IFMA; + if (ymm_enabled && cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512VL) cpu_features |= CPU_FEATURE_AVX512VL; // on purpose ymm_enabled! + if (zmm_enabled && cpuid_leaf_7[ECX] & CPU_FEATURE_BIT_AVX512VBMI) cpu_features |= CPU_FEATURE_AVX512VBMI; + +#if defined(__MIC__) + cpu_features |= CPU_FEATURE_KNC; +#endif + return cpu_features; + } + + std::string stringOfCPUFeatures(int features) + { + std::string str; + if (features & CPU_FEATURE_SSE ) str += "SSE "; + if (features & CPU_FEATURE_SSE2 ) str += "SSE2 "; + if (features & CPU_FEATURE_SSE3 ) str += "SSE3 "; + if (features & CPU_FEATURE_SSSE3 ) str += "SSSE3 "; + if (features & CPU_FEATURE_SSE41 ) str += "SSE41 "; + if (features & CPU_FEATURE_SSE42 ) str += "SSE42 "; + if (features & CPU_FEATURE_POPCNT) str += "POPCNT "; + if (features & CPU_FEATURE_AVX ) str += "AVX "; + if (features & CPU_FEATURE_F16C ) str += "F16C "; + if (features & CPU_FEATURE_RDRAND) str += "RDRAND "; + if (features & CPU_FEATURE_AVX2 ) str += "AVX2 "; + if (features & CPU_FEATURE_FMA3 ) str += "FMA3 "; + if (features & CPU_FEATURE_LZCNT ) str += "LZCNT "; + if (features & CPU_FEATURE_BMI1 ) str += "BMI1 "; + if (features & CPU_FEATURE_BMI2 ) str += "BMI2 "; + if (features & CPU_FEATURE_KNC ) str += "KNC "; + if (features & CPU_FEATURE_AVX512F) str += "AVX512F "; + if (features & CPU_FEATURE_AVX512DQ) str += "AVX512DQ "; + if (features & CPU_FEATURE_AVX512PF) str += "AVX512PF "; + if (features & CPU_FEATURE_AVX512ER) str += "AVX512ER "; + if (features & CPU_FEATURE_AVX512CD) str += "AVX512CD "; + if (features & CPU_FEATURE_AVX512BW) str += "AVX512BW "; + if (features & CPU_FEATURE_AVX512VL) str += "AVX512VL "; + if (features & CPU_FEATURE_AVX512IFMA) str += "AVX512IFMA "; + if (features & CPU_FEATURE_AVX512VBMI) str += "AVX512VBMI "; + return str; + } + + std::string stringOfISA (int isa) + { + if (isa == SSE) return "SSE"; + if (isa == SSE2) return "SSE2"; + if (isa == SSE3) return "SSE3"; + if (isa == SSSE3) return "SSSE3"; + if (isa == SSE41) return "SSE4_1"; + if (isa == SSE42) return "SSE4_2"; + if (isa == AVX) return "AVX"; + if (isa == AVXI) return "AVXI"; + if (isa == AVX2) return "AVX2"; + if (isa == KNC) return "KNC"; + if (isa == AVX512KNL) return "AVX512KNL"; + return "UNKNOWN"; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// Windows Platform +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __WIN32__ + +#define WIN32_LEAN_AND_MEAN +#include + +namespace ospcommon +{ + std::string getExecutableFileName() { + char filename[1024]; + if (!GetModuleFileName(nullptr, filename, sizeof(filename))) return std::string(); + return std::string(filename); + } + + size_t getNumberOfLogicalThreads() + { + static int nThreads = -1; + if (nThreads != -1) return nThreads; + + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + + typedef WORD (WINAPI *GetActiveProcessorGroupCountFunc)(); + typedef DWORD (WINAPI *GetActiveProcessorCountFunc)(WORD); + HMODULE hlib = LoadLibrary("Kernel32"); + GetActiveProcessorGroupCountFunc pGetActiveProcessorGroupCount = (GetActiveProcessorGroupCountFunc)GetProcAddress(hlib, "GetActiveProcessorGroupCount"); + GetActiveProcessorCountFunc pGetActiveProcessorCount = (GetActiveProcessorCountFunc) GetProcAddress(hlib, "GetActiveProcessorCount"); + + if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount && + ((osvi.dwMajorVersion > 6) || ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion >= 1)))) + { + int groups = pGetActiveProcessorGroupCount(); + int totalProcessors = 0; + for (int i = 0; i < groups; i++) + totalProcessors += pGetActiveProcessorCount(i); + nThreads = totalProcessors; + } + else + { + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + nThreads = sysinfo.dwNumberOfProcessors; + } + return nThreads; + } + + int getTerminalWidth() + { + HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (handle == INVALID_HANDLE_VALUE) return 80; + CONSOLE_SCREEN_BUFFER_INFO info = { { 0 } }; + GetConsoleScreenBufferInfo(handle, &info); + return info.dwSize.X; + } + + double getSeconds() { + LARGE_INTEGER freq, val; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&val); + return (double)val.QuadPart / (double)freq.QuadPart; + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Linux Platform +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __LINUX__ + +#include +#include + +namespace ospcommon +{ + std::string getExecutableFileName() + { + char pid[32]; sprintf(pid, "/proc/%d/exe", getpid()); + char buf[1024]; + int bytes = readlink(pid, buf, sizeof(buf)-1); + if (bytes != -1) buf[bytes] = '\0'; + return std::string(buf); + } +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Mac OS X Platform +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __MACOSX__ + +#include + +namespace ospcommon +{ + std::string getExecutableFileName() + { + char buf[1024]; + uint32_t size = sizeof(buf); + if (_NSGetExecutablePath(buf, &size) != 0) return std::string(); + return std::string(buf); + } +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Unix Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__UNIX__) + +#include +#include +#include + +namespace ospcommon +{ + size_t getNumberOfLogicalThreads() { + static int nThreads = -1; + if (nThreads == -1) nThreads = sysconf(_SC_NPROCESSORS_CONF); + return nThreads; + } + + int getTerminalWidth() + { + struct winsize info; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &info) < 0) return 80; + return info.ws_col; + } + +#if defined(__MIC__) + + static double getFrequencyInMHz() + { + struct timeval tvstart, tvstop; + unsigned long long int cycles[2]; + + gettimeofday(&tvstart, nullptr); + cycles[0] = rdtsc(); + gettimeofday(&tvstart, nullptr); + usleep(250000); + gettimeofday(&tvstop, nullptr); + cycles[1] = rdtsc(); + gettimeofday(&tvstop, nullptr); + + const unsigned long microseconds = ((tvstop.tv_sec-tvstart.tv_sec)*1000000) + (tvstop.tv_usec-tvstart.tv_usec); + unsigned long mhz = (unsigned long) (cycles[1]-cycles[0]) / microseconds; + + //std::cout << "MIC frequency is " << mhz << " MHz" << std::endl; + return (double)mhz; + } + + static double micFrequency = getFrequencyInMHz(); + +#endif + + double getSeconds() { +#if !defined(__MIC__) + struct timeval tp; gettimeofday(&tp,NULL); + return double(tp.tv_sec) + double(tp.tv_usec)/1E6; +#else + return double(rdtsc()) / double(micFrequency*1E6); +#endif + } +} +#endif + diff --git a/common/sysinfo.h b/common/sysinfo.h new file mode 100644 index 0000000000..9d9859fc82 --- /dev/null +++ b/common/sysinfo.h @@ -0,0 +1,178 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#define CACHELINE_SIZE 64 + +#if !defined(PAGE_SIZE) + #define PAGE_SIZE 4096 +#endif + +#define MAX_THREADS 512 +#define MAX_MIC_CORES (MAX_THREADS/4) + +#include "platform.h" + +/* define isa namespace and ISA bitvector */ +#if defined(__MIC__) +# define isa knc +# define ISA KNC +# define ISA_STR "KNC" +#elif defined (__AVX512F__) +# define isa avx512 +# define ISA AVX512KNL +# define ISA_STR "AVX512KNL" +#elif defined (__AVX2__) +# define isa avx2 +# define ISA AVX2 +# define ISA_STR "AVX2" +#elif defined(__AVXI__) +# define isa avxi +# define ISA AVXI +# define ISA_STR "AVXI" +#elif defined(__AVX__) +# define isa avx +# define ISA AVX +# define ISA_STR "AVX" +#elif defined (__SSE4_2__) +# define isa sse42 +# define ISA SSE42 +# define ISA_STR "SSE4.2" +#elif defined (__SSE4_1__) +# define isa sse41 +# define ISA SSE41 +# define ISA_STR "SSE4.1" +#elif defined(__SSSE3__) +# define isa ssse3 +# define ISA SSSE3 +# define ISA_STR "SSSE3" +#elif defined(__SSE3__) +# define isa sse3 +# define ISA SSE3 +# define ISA_STR "SSE3" +#elif defined(__SSE2__) +# define isa sse2 +# define ISA SSE2 +# define ISA_STR "SSE2" +#elif defined(__SSE__) +# define isa sse +# define ISA SSE +# define ISA_STR "SSE" +#else +#error Unknown ISA +#endif + +#if defined (__MACOSX__) +#if defined (__INTEL_COMPILER) +#define DEFAULT_ISA SSSE3 +#else +#define DEFAULT_ISA SSE3 +#endif +#else +#define DEFAULT_ISA SSE2 +#endif + +namespace ospcommon +{ + enum CPUModel { + CPU_UNKNOWN, + CPU_CORE1, + CPU_CORE2, + CPU_CORE_NEHALEM, + CPU_CORE_SANDYBRIDGE, + CPU_HASWELL, + CPU_KNC, + CPU_KNL + }; + + /*! get the full path to the running executable */ + std::string getExecutableFileName(); + + /*! return platform name */ + std::string getPlatformName(); + + /*! get the full name of the compiler */ + std::string getCompilerName(); + + /*! return the name of the CPU */ + std::string getCPUVendor(); + + /*! get microprocessor model */ + CPUModel getCPUModel(); + + /*! converts CPU model into string */ + std::string stringOfCPUModel(CPUModel model); + + /*! CPU features */ + static const int CPU_FEATURE_SSE = 1 << 0; + static const int CPU_FEATURE_SSE2 = 1 << 1; + static const int CPU_FEATURE_SSE3 = 1 << 2; + static const int CPU_FEATURE_SSSE3 = 1 << 3; + static const int CPU_FEATURE_SSE41 = 1 << 4; + static const int CPU_FEATURE_SSE42 = 1 << 5; + static const int CPU_FEATURE_POPCNT = 1 << 6; + static const int CPU_FEATURE_AVX = 1 << 7; + static const int CPU_FEATURE_F16C = 1 << 8; + static const int CPU_FEATURE_RDRAND = 1 << 9; + static const int CPU_FEATURE_AVX2 = 1 << 10; + static const int CPU_FEATURE_FMA3 = 1 << 11; + static const int CPU_FEATURE_LZCNT = 1 << 12; + static const int CPU_FEATURE_BMI1 = 1 << 13; + static const int CPU_FEATURE_BMI2 = 1 << 14; + static const int CPU_FEATURE_KNC = 1 << 15; + static const int CPU_FEATURE_AVX512F = 1 << 16; + static const int CPU_FEATURE_AVX512DQ = 1 << 17; + static const int CPU_FEATURE_AVX512PF = 1 << 18; + static const int CPU_FEATURE_AVX512ER = 1 << 19; + static const int CPU_FEATURE_AVX512CD = 1 << 20; + static const int CPU_FEATURE_AVX512BW = 1 << 21; + static const int CPU_FEATURE_AVX512VL = 1 << 22; + static const int CPU_FEATURE_AVX512IFMA = 1 << 23; + static const int CPU_FEATURE_AVX512VBMI = 1 << 24; + + /*! get CPU features */ + int getCPUFeatures(); + + /*! convert CPU features into a string */ + std::string stringOfCPUFeatures(int features); + + /*! ISAs */ + static const int SSE = CPU_FEATURE_SSE; + static const int SSE2 = SSE | CPU_FEATURE_SSE2; + static const int SSE3 = SSE2 | CPU_FEATURE_SSE3; + static const int SSSE3 = SSE3 | CPU_FEATURE_SSSE3; + static const int SSE41 = SSSE3 | CPU_FEATURE_SSE41; + static const int SSE42 = SSE41 | CPU_FEATURE_SSE42 | CPU_FEATURE_POPCNT; + static const int AVX = SSE42 | CPU_FEATURE_AVX; + static const int AVXI = AVX | CPU_FEATURE_F16C | CPU_FEATURE_RDRAND; + static const int AVX2 = AVXI | CPU_FEATURE_AVX2 | CPU_FEATURE_FMA3 | CPU_FEATURE_BMI1 | CPU_FEATURE_BMI2 | CPU_FEATURE_LZCNT; + static const int KNC = CPU_FEATURE_KNC; + static const int AVX512F = AVX2 | CPU_FEATURE_AVX512F; // FIXME: shouldn't we also test for the CPU_FEATURE_AVX512VL flag? + static const int AVX512KNL = AVX512F | CPU_FEATURE_AVX512PF | CPU_FEATURE_AVX512ER | CPU_FEATURE_AVX512CD; + + /*! converts ISA bitvector into a string */ + std::string stringOfISA(int features); + + /*! return the number of logical threads of the system */ + size_t getNumberOfLogicalThreads(); + + /*! returns the size of the terminal window in characters */ + int getTerminalWidth(); + + /*! returns performance counter in seconds */ + double getSeconds(); +} diff --git a/common/vec.h b/common/vec.h new file mode 100644 index 0000000000..b46883c6af --- /dev/null +++ b/common/vec.h @@ -0,0 +1,428 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "../common/common.h" +#include "./constants.h" +#include "./math.h" + +namespace ospcommon { + + template struct vec_t + { + typedef T scalar_t; + typedef T Scalar; + }; + + template + struct vec_t { + typedef T scalar_t; + typedef T Scalar; + + inline vec_t() {}; + inline vec_t(scalar_t s) : x(s), y(s) {}; + inline vec_t(scalar_t x, scalar_t y) : x(x), y(y) {}; + inline vec_t(const vec_t &o) : x(o.x), y(o.y) {} + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y; } + + T x, y; + }; + + template + struct vec_t { + typedef T scalar_t; + typedef T Scalar; + + inline vec_t() {}; + inline vec_t(scalar_t s) : x(s), y(s), z(s) {}; + inline vec_t(scalar_t x, scalar_t y, scalar_t z) : x(x), y(y), z(z) {}; + inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z) {} + + template + explicit inline vec_t(const vec_t &o) + : x(x), y(y), z(z) + {} + + inline const T& operator []( const size_t axis ) const { assert(axis < 3); return (&x)[axis]; } + inline T& operator []( const size_t axis ) { assert(axis < 3); return (&x)[axis]; } + + // inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z) {} + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y+z; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y*z; } + + T x, y, z; + }; + + template + struct vec_t { + typedef T scalar_t; + typedef T Scalar; + + inline vec_t() {}; + inline vec_t(scalar_t s) : x(s), y(s), z(s) {}; + inline vec_t(scalar_t x, scalar_t y, scalar_t z) : x(x), y(y), z(z) {}; + inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z) {} + inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z) {} + + inline const T& operator []( const size_t axis ) const { assert(axis < 3); return (&x)[axis]; } + inline T& operator []( const size_t axis ) { assert(axis < 3); return (&x)[axis]; } + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y+z; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y*z; } + + inline operator vec_t() const { return vec_t(x,y,a); } + + T x, y, z; + union { float w; unsigned u; int a; }; + }; + + template + struct vec_t { + typedef T scalar_t; + typedef T Scalar; + + inline vec_t() {}; + inline vec_t(scalar_t s) : x(s), y(s), z(s), w(s) {}; + inline vec_t(scalar_t x, scalar_t y, scalar_t z, scalar_t w) : x(x), y(y), z(z), w(w) {}; + inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z), w(o.w) {} + + /*! return result of reduce_add() across all components */ + inline scalar_t sum() const { return x+y+z+w; } + /*! return result of reduce_mul() across all components */ + inline scalar_t product() const { return x*y*z*w; } + + T x, y, z, w; + }; + + // ------------------------------------------------------- + // unary operators + // ------------------------------------------------------- + template inline vec_t operator-(const vec_t &v) + { return vec_t(-v.x,-v.y); } + template inline vec_t operator-(const vec_t &v) + { return vec_t(-v.x,-v.y,-v.z); } + template inline vec_t operator-(const vec_t &v) + { return vec_t(-v.x,-v.y,-v.z); } + template inline vec_t operator-(const vec_t &v) + { return vec_t(-v.x,-v.y,-v.z,-v.w); } + + template inline vec_t operator+(const vec_t &v) + { return vec_t(+v.x,+v.y); } + template inline vec_t operator+(const vec_t &v) + { return vec_t(+v.x,+v.y,+v.z); } + template inline vec_t operator+(const vec_t &v) + { return vec_t(+v.x,+v.y,+v.z); } + template inline vec_t operator+(const vec_t &v) + { return vec_t(+v.x,+v.y,+v.z,+v.w); } + + // ------------------------------------------------------- + // binary operators, same type + // ------------------------------------------------------- +#define binary_operator(name,op) \ + /* "vec op vec" */ \ + template \ + inline vec_t name(const vec_t &a, \ + const vec_t &b) \ + { return vec_t(a.x op b.x,a.y op b.y); } \ + \ + template \ + inline vec_t name(const vec_t &a, \ + const vec_t &b) \ + { return vec_t(a.x op b.x,a.y op b.y,a.z op b.z); } \ + \ + template \ + inline vec_t name(const vec_t &a, \ + const vec_t &b) \ + { return vec_t(a.x op b.x,a.y op b.y,a.z op b.z,a.w op b.w); } \ + \ + /* "vec op scalar" */ \ + template \ + inline vec_t name(const vec_t &a, \ + const T &b) \ + { return vec_t(a.x op b,a.y op b); } \ + \ + template \ + inline vec_t name(const vec_t &a, \ + const T &b) \ + { return vec_t(a.x op b,a.y op b,a.z op b); } \ + \ + template \ + inline vec_t name(const vec_t &a, \ + const T &b) \ + { return vec_t(a.x op b,a.y op b,a.z op b,a.w op b); } \ + \ + /* "scalar op vec" */ \ + template \ + inline vec_t name(const T a, \ + const vec_t &b) \ + { return vec_t(a op b.x,a op b.y); } \ + \ + template \ + inline vec_t name(const T a, \ + const vec_t &b) \ + { return vec_t(a op b.x,a op b.y,a op b.z); } \ + \ + template \ + inline vec_t name(const T a, \ + const vec_t &b) \ + { return vec_t(a op b.x,a op b.y,a op b.z,a op b.w); } \ + + binary_operator(operator+,+); + binary_operator(operator-,-); + binary_operator(operator*,*); + binary_operator(operator/,/); +#undef binary_operator + + // ------------------------------------------------------- + // binary operators, same type + // ------------------------------------------------------- +#define binary_operator(name,op) \ + /* "vec op vec" */ \ + template \ + inline vec_t &name(vec_t &a, \ + const vec_t &b) \ + { a.x op b.x; a.y op b.y; return a; } \ + \ + template \ + inline vec_t &name(vec_t &a, \ + const vec_t &b) \ + { a.x op b.x; a.y op b.y; a.z op b.z; return a; } \ + \ + template \ + inline vec_t &name(vec_t &a, \ + const vec_t &b) \ + { a.x op b.x; a.y op b.y; a.z op b.z; a.w op b.w; return a; } \ + \ + + binary_operator(operator+=,+=); + binary_operator(operator-=,-=); + binary_operator(operator*=,*=); + binary_operator(operator/=,/=); +#undef binary_operator + + // ------------------------------------------------------- + // ternary operators (just for compatibilty with old embree + // ------------------------------------------------------- + template inline + vec_t madd(const vec_t &a, const vec_t &b, const vec_t &c) + { return vec_t( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z)); } + + // ------------------------------------------------------- + // comparison operators + // ------------------------------------------------------- + template + inline bool operator==(const vec_t &a, const vec_t &b) + { return a.x==b.x && a.y==b.y; } + + template + inline bool operator==(const vec_t &a, const vec_t &b) + { return a.x==b.x && a.y==b.y && a.z==b.z; } + + template + inline bool operator==(const vec_t &a, const vec_t &b) + { return a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w; } + + template + inline bool operator!=(const vec_t &a, const vec_t &b) + { return !(a==b); } + + template + inline bool operator!=(const vec_t &a, const vec_t &b) + { return !(a==b); } + + template + inline bool operator!=(const vec_t &a, const vec_t &b) + { return !(a==b); } + + template + inline bool operator<(const vec_t &a, const vec_t &b) + { + return (a.x + inline bool operator<(const vec_t &a, const vec_t &b) + { + return + (a.x< b.x) || + (a.x==b.x && ((a.y< b.y) || + (a.y==b.y) && (a.z + inline bool operator<(const vec_t &a, const vec_t &b) + { + return + (a.x< b.x) || + (a.x==b.x && ((a.y< b.y) || + (a.y==b.y) && ((a.z< b.z) || + (a.z==b.z) && (a.w < b.w)))); + } + + // 'anyLessThan' - return true if any component is less than the other vec's + template + inline bool anyLessThan(const vec_t &a, const vec_t &b) + { return a.x + inline bool anyLessThan(const vec_t &a, const vec_t &b) + { return a.x + inline bool anyLessThan(const vec_t &a, const vec_t &b) + { return a.x inline T dot(const vec_t &a, const vec_t &b) + { return a.x*b.x+a.y*b.y; } + template inline T dot(const vec_t &a, const vec_t &b) + { return a.x*b.x+a.y*b.y+a.z*b.z; } + template inline T dot(const vec_t &a, const vec_t &b) + { return a.x*b.x+a.y*b.y+a.z*b.z; } + template inline T dot(const vec_t &a, const vec_t &b) + { return a.x*b.x+a.y*b.y+a.z*b.z; } + template inline T dot(const vec_t &a, const vec_t &b) + { return a.x*b.x+a.y*b.y+a.z*b.z; } + template inline T dot(const vec_t &a, const vec_t &b) + { return a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w; } + + // ------------------------------------------------------- + // length functions + // ------------------------------------------------------- + template + inline T length(const vec_t &v) + { return sqrt(dot(v,v)); } + + // ------------------------------------------------------- + // cross product + // ------------------------------------------------------- + template inline vec_t cross(const vec_t &a, + const vec_t &b) + { return vec_t(a.y*b.z-a.z*b.y, + a.z*b.x-a.x*b.z, + a.x*b.y-a.y*b.x); } + + // ------------------------------------------------------- + // normalize() + // ------------------------------------------------------- + template inline vec_t normalize(const vec_t &v) + { return v * rsqrt(dot(v,v)); } + + // ------------------------------------------------------- + // ostream operators + // ------------------------------------------------------- + template + inline std::ostream &operator<<(std::ostream &o, const vec_t &v) + { o << "(" << v.x << "," << v.y << ")"; return o; } + template + inline std::ostream &operator<<(std::ostream &o, const vec_t &v) + { o << "(" << v.x << "," << v.y << "," << v.z << ")"; return o; } + template + inline std::ostream &operator<<(std::ostream &o, const vec_t &v) + { o << "(" << v.x << "," << v.y << "," << v.z << "," << v.w << ")"; return o; } + + // ------------------------------------------------------- + // scalar functors we eventually define for vec's, too + // ------------------------------------------------------- + template + inline T divRoundUp(T a, T b) { return (a+b-1)/b; } + + // "inherit" std::min/max/etc for basic types + using std::min; + using std::max; + + // ------------------------------------------------------- + // binary functors + // ------------------------------------------------------- +#define define_functor(f) \ + template \ + inline vec_t f(const vec_t &a, const vec_t &b) \ + { return vec_t(f(a.x,b.x),f(a.y,b.y)); } \ + \ + template \ + inline vec_t f(const vec_t &a, const vec_t &b) \ + { return vec_t(f(a.x,b.x),f(a.y,b.y),f(a.z,b.z)); } \ + \ + template \ + inline vec_t f(const vec_t &a, const vec_t &b) \ + { return vec_t(f(a.x,b.x),f(a.y,b.y),f(a.z,b.z),f(a.w,b.w)); } \ + + define_functor(min); + define_functor(max); + define_functor(divRoundUp); +#undef define_functor + + // ------------------------------------------------------- + // reductions + // ------------------------------------------------------- + template + inline T reduce_add(const vec_t &v) + { return v.x+v.y; } + template + inline T reduce_add(const vec_t &v) + { return v.x+v.y+v.z; } + template + inline T reduce_add(const vec_t &v) + { return v.x+v.y+v.z+v.w; } + + // ------------------------------------------------------- + // select + // ------------------------------------------------------- + template + inline vec_t select(bool s, const vec_t &a, const vec_t &b) + { return vec_t(select(s,a.x,b.x),select(s,a.y,b.y),select(s,a.z,b.z)); } + + // ------------------------------------------------------- + // all vec2 variants + // ------------------------------------------------------- + typedef vec_t vec2ui; + typedef vec_t vec2i; + typedef vec_t vec2f; + typedef vec_t vec2d; + + // ------------------------------------------------------- + // all vec3 variants + // ------------------------------------------------------- + typedef vec_t vec3ui; + typedef vec_t vec3i; + typedef vec_t vec3f; + typedef vec_t vec3fa; + typedef vec_t vec3d; + + // ------------------------------------------------------- + // all vec4 variants + // ------------------------------------------------------- + typedef vec_t vec4uc; + typedef vec_t vec4ui; + typedef vec_t vec4i; + typedef vec_t vec4f; + typedef vec_t vec4d; + + +} // ::ospcommon diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 0caa922e62..046b117122 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -18,17 +18,6 @@ // embree #include "embree2/rtcore.h" #include "common/sys/sysinfo.h" -// std -#include -#ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include // for GetSystemTime -#else -#include -#include -#endif namespace ospray { @@ -87,14 +76,11 @@ namespace ospray { abort(); } - double getSysTime() { -#ifdef _WIN32 - SYSTEMTIME tp; GetSystemTime(&tp); - return double(tp.wSecond) + double(tp.wMilliseconds) / 1E3; -#else - struct timeval tp; gettimeofday(&tp,NULL); - return double(tp.tv_sec) + double(tp.tv_usec)/1E6; -#endif + void removeArgs(int &ac, char **&av, int where, int howMany) + { + for (int i=where+howMany;i inline T divRoundUp(const T&a, const T&b) { return (a+(b-T(1)))/b; } +#if WARN_ON_INCLUDING_OSPCOMMON +# error "should not include OSPCOMMON.h from outside of ospray/* files!" +#endif + diff --git a/ospray/embree-v2.7.1/common/sys/filename.h b/ospray/embree-v2.7.1/common/sys/filename.h index 39bfa5ad07..84b5be9164 100644 --- a/ospray/embree-v2.7.1/common/sys/filename.h +++ b/ospray/embree-v2.7.1/common/sys/filename.h @@ -18,6 +18,10 @@ #include "platform.h" +#if WARN_INCLUDE_EMBREE_FILENAME +# error "warning: includign embree/filename" +#endif + namespace embree { /*! Convenience class for handling file names and paths. */ From 6fd9bf111fa2d9cf7601d5fcc3b50823c071adcb Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 11:49:24 -0600 Subject: [PATCH 018/310] embree and ospray fully separated - even ospray/* files no longer include any embree stuff (that I coudld find so far) --- common/AffineSpace.h | 3 + common/CMakeLists.txt | 1 + common/LinearSpace.h | 6 +- common/box.h | 5 ++ common/malloc.h | 124 ++++++++++++++++++++++++++ common/math.h | 6 ++ common/vec.h | 84 +++++++++++++++--- ospray/api/API.cpp | 4 +- ospray/api/LocalDevice.cpp | 4 +- ospray/common/Data.cpp | 3 - ospray/common/Managed.h | 2 +- ospray/common/Model.cpp | 2 +- ospray/common/OSPCommon.cpp | 46 +++++----- ospray/common/OSPCommon.h | 146 +++++++++++++++---------------- ospray/fb/LocalFB.cpp | 3 - ospray/fb/PixelOp.h | 2 +- ospray/geometry/Geometry.h | 2 +- ospray/geometry/Instance.cpp | 2 +- ospray/geometry/TriangleMesh.cpp | 3 +- 19 files changed, 319 insertions(+), 129 deletions(-) create mode 100644 common/malloc.h diff --git a/common/AffineSpace.h b/common/AffineSpace.h index 2b602b0a31..47cecd8184 100644 --- a/common/AffineSpace.h +++ b/common/AffineSpace.h @@ -147,6 +147,9 @@ namespace ospcommon { typedef AffineSpaceT AffineSpace3fa; typedef AffineSpaceT OrthonormalSpace3f; + typedef AffineSpace2f affine2f; + typedef AffineSpace3f affine3f; + //////////////////////////////////////////////////////////////////////////////// /*! Template Specialization for 2D: return matrix for rotation around point (rotation around arbitrarty vector is not meaningful in 2D) */ template<> inline AffineSpace2f AffineSpace2f::rotate(const vec2f& p, const float& r) { return translate(+p) * AffineSpace2f(LinearSpace2f::rotate(r)) * translate(-p); } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 9908867a12..dc58569ff3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -3,6 +3,7 @@ ADD_LIBRARY(ospray_ospcommon SHARED common.cpp FileName.cpp sysinfo.cpp + malloc.cpp ) diff --git a/common/LinearSpace.h b/common/LinearSpace.h index cb05d1a5b7..d079901bb3 100644 --- a/common/LinearSpace.h +++ b/common/LinearSpace.h @@ -308,8 +308,10 @@ namespace ospcommon { } /*! Shortcuts for common linear spaces. */ - typedef LinearSpace2 LinearSpace2f; - typedef LinearSpace3 LinearSpace3f; + typedef LinearSpace2 LinearSpace2f; + typedef LinearSpace3 LinearSpace3f; typedef LinearSpace3 LinearSpace3fa; + typedef LinearSpace2f linear2f; + typedef LinearSpace3f linear3f; } // ::ospcommon diff --git a/common/box.h b/common/box.h index 63f6c5ae40..3ed65e271e 100644 --- a/common/box.h +++ b/common/box.h @@ -50,6 +50,11 @@ namespace ospcommon { inline box_t intersectionOf(const box_t &a, const box_t &b) { return box_t(max(a.lower,b.lower), min(a.upper,b.upper)); } + template + inline bool disjoint(const box_t &a, const box_t &b) + { return anyLessThen(a.upper,b.lower) || anyLessThan(b.lower,a.upper); } + + /*! returns the center of the box (not valid for empty boxes) */ template inline vec_t center(const box_t &b) diff --git a/common/malloc.h b/common/malloc.h new file mode 100644 index 0000000000..dc566d8924 --- /dev/null +++ b/common/malloc.h @@ -0,0 +1,124 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" + +namespace ospcommon +{ +#define ALIGN_PTR(ptr,alignment) \ + ((((size_t)ptr)+alignment-1)&((size_t)-(ssize_t)alignment)) + + +// #define ALIGNED_STRUCT \ +// void* operator new(size_t size) { return alignedMalloc(size); } \ +// void operator delete(void* ptr) { alignedFree(ptr); } \ +// void* operator new[](size_t size) { return alignedMalloc(size); } \ +// void operator delete[](void* ptr) { alignedFree(ptr); } \ + +// #define ALIGNED_STRUCT_(align) \ +// void* operator new(size_t size) { return alignedMalloc(size,align); } \ +// void operator delete(void* ptr) { alignedFree(ptr); } \ +// void* operator new[](size_t size) { return alignedMalloc(size,align); } \ +// void operator delete[](void* ptr) { alignedFree(ptr); } \ + +// #define ALIGNED_CLASS \ +// public: \ +// ALIGNED_STRUCT \ +// private: + +// #define ALIGNED_CLASS_(align) \ +// public: \ +// ALIGNED_STRUCT_(align) \ +// private: + + /*! aligned allocation */ + void* alignedMalloc(size_t size, size_t align = 64); + void alignedFree(void* ptr); + + // /*! alloca that returns aligned data */ + // template + // __forceinline T* aligned_alloca(size_t elements, const size_t alignment = 64) { + // return (T*)ALIGN_PTR(alloca(elements * sizeof(T) + alignment),alignment); + // } + + // /*! allocator that performs aligned allocations */ + // template + // struct aligned_allocator + // { + // typedef T value_type; + // typedef T* pointer; + // typedef const T* const_pointer; + // typedef T& reference; + // typedef const T& const_reference; + // typedef std::size_t size_type; + // typedef std::ptrdiff_t difference_type; + + // __forceinline pointer allocate( size_type n ) { + // return (pointer) alignedMalloc(n*sizeof(value_type),alignment); + // } + + // __forceinline void deallocate( pointer p, size_type n ) { + // return alignedFree(p); + // } + + // __forceinline void construct( pointer p, const_reference val ) { + // new (p) T(val); + // } + + // __forceinline void destroy( pointer p ) { + // p->~T(); + // } + // }; + + // /*! allocates pages directly from OS */ + // void* os_malloc (size_t bytes, const int additional_flags = 0); + // void* os_reserve(size_t bytes); + // void os_commit (void* ptr, size_t bytes); + // size_t os_shrink (void* ptr, size_t bytesNew, size_t bytesOld); + // void os_free (void* ptr, size_t bytes); + + // /*! allocator that performs OS allocations */ + // template + // struct os_allocator + // { + // typedef T value_type; + // typedef T* pointer; + // typedef const T* const_pointer; + // typedef T& reference; + // typedef const T& const_reference; + // typedef std::size_t size_type; + // typedef std::ptrdiff_t difference_type; + + // __forceinline pointer allocate( size_type n ) { + // return (pointer) os_malloc(n*sizeof(value_type)); + // } + + // __forceinline void deallocate( pointer p, size_type n ) { + // return os_free(p,n*sizeof(value_type)); + // } + + // __forceinline void construct( pointer p, const_reference val ) { + // new (p) T(val); + // } + + // __forceinline void destroy( pointer p ) { + // p->~T(); + // } + // }; +} + diff --git a/common/math.h b/common/math.h index 03b3e59e36..516e379223 100644 --- a/common/math.h +++ b/common/math.h @@ -233,6 +233,12 @@ namespace ospcommon return (1.0f-u)*(1.0f-v)*x0 + u*(1.0f-v)*x1 + (1.0f-u)*v*x2 + u*v*x3; } + // ------------------------------------------------------- + // scalar functors we eventually define for vec's, too + // ------------------------------------------------------- + template + inline T divRoundUp(T a, T b) { return (a+b-1)/b; } + /*! exchange */ template __forceinline void xchg ( T& a, T& b ) { const T tmp = a; a = b; b = tmp; } diff --git a/common/vec.h b/common/vec.h index b46883c6af..d3d6190e4f 100644 --- a/common/vec.h +++ b/common/vec.h @@ -37,6 +37,9 @@ namespace ospcommon { inline vec_t(scalar_t s) : x(s), y(s) {}; inline vec_t(scalar_t x, scalar_t y) : x(x), y(y) {}; inline vec_t(const vec_t &o) : x(o.x), y(o.y) {} + + template + explicit inline vec_t(const vec_t &o) : x(o.x), y(o.y) {} /*! return result of reduce_add() across all components */ inline scalar_t sum() const { return x+y; } @@ -57,9 +60,7 @@ namespace ospcommon { inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z) {} template - explicit inline vec_t(const vec_t &o) - : x(x), y(y), z(z) - {} + explicit inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z) {} inline const T& operator []( const size_t axis ) const { assert(axis < 3); return (&x)[axis]; } inline T& operator []( const size_t axis ) { assert(axis < 3); return (&x)[axis]; } @@ -108,6 +109,9 @@ namespace ospcommon { inline vec_t(scalar_t s) : x(s), y(s), z(s), w(s) {}; inline vec_t(scalar_t x, scalar_t y, scalar_t z, scalar_t w) : x(x), y(y), z(z), w(w) {}; inline vec_t(const vec_t &o) : x(o.x), y(o.y), z(o.z), w(o.w) {} + template + explicit inline vec_t(const vec_t &o) : x(x), y(y), z(o.z), w(o.w) {} + /*! return result of reduce_add() across all components */ inline scalar_t sum() const { return x+y+z+w; } @@ -138,6 +142,24 @@ namespace ospcommon { template inline vec_t operator+(const vec_t &v) { return vec_t(+v.x,+v.y,+v.z,+v.w); } + // ------------------------------------------------------- + // unary functors + // ------------------------------------------------------- +#define unary_functor(op) \ + template inline vec_t op(const vec_t &v)\ + { return vec_t(op(v.x),op(v.y)); }\ + template inline vec_t op(const vec_t &v)\ + { return vec_t(op(v.x),op(v.y),op(v.z)); }\ + template inline vec_t op(const vec_t &v)\ + { return vec_t(op(v.x),op(v.y),op(v.z)); }\ + template inline vec_t op(const vec_t &v)\ + { return vec_t(op(v.x),op(v.y),op(v.z),op(v.w)); }\ + + unary_functor(rcp); + unary_functor(sin); + unary_functor(cos); +#undef unary_functor + // ------------------------------------------------------- // binary operators, same type // ------------------------------------------------------- @@ -216,6 +238,21 @@ namespace ospcommon { const vec_t &b) \ { a.x op b.x; a.y op b.y; a.z op b.z; a.w op b.w; return a; } \ \ + /* "vec op scalar" */ \ + template \ + inline vec_t &name(vec_t &a, \ + const T &b) \ + { a.x op b; a.y op b; return a; } \ + \ + template \ + inline vec_t &name(vec_t &a, \ + const T &b) \ + { a.x op b; a.y op b; a.z op b; return a; } \ + \ + template \ + inline vec_t &name(vec_t &a, \ + const T &b) \ + { a.x op b; a.y op b; a.z op b; a.w op b; return a; } \ binary_operator(operator+=,+=); binary_operator(operator-=,-=); @@ -347,12 +384,6 @@ namespace ospcommon { inline std::ostream &operator<<(std::ostream &o, const vec_t &v) { o << "(" << v.x << "," << v.y << "," << v.z << "," << v.w << ")"; return o; } - // ------------------------------------------------------- - // scalar functors we eventually define for vec's, too - // ------------------------------------------------------- - template - inline T divRoundUp(T a, T b) { return (a+b-1)/b; } - // "inherit" std::min/max/etc for basic types using std::min; using std::max; @@ -391,6 +422,26 @@ namespace ospcommon { inline T reduce_add(const vec_t &v) { return v.x+v.y+v.z+v.w; } + template + inline T reduce_min(const vec_t &v) + { return min(v.x,v.y); } + template + inline T reduce_min(const vec_t &v) + { return min(min(v.x,v.y),v.z); } + template + inline T reduce_min(const vec_t &v) + { return min(min(v.x,v.y),min(v.z,v.w)); } + + template + inline T reduce_max(const vec_t &v) + { return max(v.x,v.y); } + template + inline T reduce_max(const vec_t &v) + { return max(max(v.x,v.y),v.z); } + template + inline T reduce_max(const vec_t &v) + { return max(max(v.x,v.y),max(v.z,v.w)); } + // ------------------------------------------------------- // select // ------------------------------------------------------- @@ -401,26 +452,39 @@ namespace ospcommon { // ------------------------------------------------------- // all vec2 variants // ------------------------------------------------------- + typedef vec_t vec2uc; + typedef vec_t vec2c; typedef vec_t vec2ui; typedef vec_t vec2i; + typedef vec_t vec2ul; + typedef vec_t vec2l; typedef vec_t vec2f; typedef vec_t vec2d; // ------------------------------------------------------- // all vec3 variants // ------------------------------------------------------- + typedef vec_t vec3uc; + typedef vec_t vec3c; typedef vec_t vec3ui; typedef vec_t vec3i; + typedef vec_t vec3ul; + typedef vec_t vec3l; typedef vec_t vec3f; - typedef vec_t vec3fa; typedef vec_t vec3d; + typedef vec_t vec3fa; + typedef vec_t vec3ia; + // ------------------------------------------------------- // all vec4 variants // ------------------------------------------------------- typedef vec_t vec4uc; + typedef vec_t vec4c; typedef vec_t vec4ui; typedef vec_t vec4i; + typedef vec_t vec4ul; + typedef vec_t vec4l; typedef vec_t vec4f; typedef vec_t vec4d; diff --git a/ospray/api/API.cpp b/ospray/api/API.cpp index 354e893d43..4bf79ea047 100644 --- a/ospray/api/API.cpp +++ b/ospray/api/API.cpp @@ -601,14 +601,14 @@ namespace ospray { extern "C" void ospSet3i(OSPObject _object, const char *id, int x, int y, int z) { ASSERT_DEVICE(); - ospray::api::Device::current->setVec3i(_object,id,vec3f(x,y,z)); + ospray::api::Device::current->setVec3i(_object,id,vec3i(x,y,z)); } /*! add a vec3i parameter to another object */ extern "C" void ospSet3iv(OSPObject _object, const char *id, const int *xyz) { ASSERT_DEVICE(); - ospray::api::Device::current->setVec3i(_object,id,vec3f(xyz[0],xyz[1],xyz[2])); + ospray::api::Device::current->setVec3i(_object,id,vec3i(xyz[0],xyz[1],xyz[2])); } /*! add a vec4f parameter to another object */ diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index eef08dfc58..ed37e0b55c 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -171,7 +171,7 @@ namespace ospray { /*! remove an existing geometry from a model */ struct GeometryLocator { - bool operator()(const embree::Ref &g) const { + bool operator()(const Ref &g) const { return ptr == &*g; } Geometry *ptr; @@ -207,7 +207,7 @@ namespace ospray { /*! remove an existing volume from a model */ struct VolumeLocator { - bool operator()(const embree::Ref &g) const { + bool operator()(const Ref &g) const { return ptr == &*g; } Volume *ptr; diff --git a/ospray/common/Data.cpp b/ospray/common/Data.cpp index fdfda67d76..a8862a56f9 100644 --- a/ospray/common/Data.cpp +++ b/ospray/common/Data.cpp @@ -19,9 +19,6 @@ // stl #include -using embree::alignedFree; -using embree::alignedMalloc; - namespace ospray { Data::Data(size_t numItems, OSPDataType type, void *init, int flags) : diff --git a/ospray/common/Managed.h b/ospray/common/Managed.h index 371cc1fbbf..e6664e8f91 100644 --- a/ospray/common/Managed.h +++ b/ospray/common/Managed.h @@ -103,7 +103,7 @@ namespace ospray { */ - struct ManagedObject : public embree::RefCount + struct ManagedObject : public RefCount { /*! \brief constructor */ ManagedObject(); diff --git a/ospray/common/Model.cpp b/ospray/common/Model.cpp index 90bc095a8b..5586f77da7 100644 --- a/ospray/common/Model.cpp +++ b/ospray/common/Model.cpp @@ -47,7 +47,7 @@ namespace ospray { ispc::Model_init(getIE(), geometry.size(), volume.size()); embreeSceneHandle = (RTCScene)ispc::Model_getEmbreeSceneHandle(getIE()); - bounds = embree::empty; + bounds = empty; // for now, only implement triangular geometry... for (size_t i=0; i < geometry.size(); i++) { diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 046b117122..f804984c4f 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -24,20 +24,20 @@ namespace ospray { /*! 64-bit malloc. allows for alloc'ing memory larger than 64 bits */ extern "C" void *malloc64(size_t size) { - return embree::alignedMalloc(size); + return ospcommon::alignedMalloc(size); } /*! 64-bit malloc. allows for alloc'ing memory larger than 64 bits */ extern "C" void free64(void *ptr) { - return embree::alignedFree(ptr); + return ospcommon::alignedFree(ptr); } /*! logging level - '0' means 'no logging at all', increasing numbers mean increasing verbosity of log messages */ - uint32 logLevel = 0; + uint32_t logLevel = 0; bool debugMode = false; - int32 numThreads = -1; //!< for default (==maximum) number of OSPRay/Embree threads + int32_t numThreads = -1; //!< for default (==maximum) number of OSPRay/Embree threads WarnOnce::WarnOnce(const std::string &s) : s(s) @@ -146,30 +146,30 @@ namespace ospray { case OSP_DATA: return sizeof(void *); case OSP_CHAR: return sizeof(int8); case OSP_UCHAR: return sizeof(uint8); - case OSP_UCHAR2: return sizeof(embree::Vec2); - case OSP_UCHAR3: return sizeof(embree::Vec3); - case OSP_UCHAR4: return sizeof(uint32); + case OSP_UCHAR2: return sizeof(vec2uc); + case OSP_UCHAR3: return sizeof(vec3uc); + case OSP_UCHAR4: return sizeof(vec4uc); case OSP_INT: return sizeof(int32); - case OSP_INT2: return sizeof(embree::Vec2); - case OSP_INT3: return sizeof(embree::Vec3); - case OSP_INT4: return sizeof(embree::Vec4); + case OSP_INT2: return sizeof(vec2i); + case OSP_INT3: return sizeof(vec3i); + case OSP_INT4: return sizeof(vec4i); case OSP_UINT: return sizeof(uint32); - case OSP_UINT2: return sizeof(embree::Vec2); - case OSP_UINT3: return sizeof(embree::Vec3); - case OSP_UINT4: return sizeof(embree::Vec4); + case OSP_UINT2: return sizeof(vec2ui); + case OSP_UINT3: return sizeof(vec3ui); + case OSP_UINT4: return sizeof(vec4ui); case OSP_LONG: return sizeof(int64); - case OSP_LONG2: return sizeof(embree::Vec2); - case OSP_LONG3: return sizeof(embree::Vec3); - case OSP_LONG4: return sizeof(embree::Vec4); + case OSP_LONG2: return sizeof(vec2l); + case OSP_LONG3: return sizeof(vec3l); + case OSP_LONG4: return sizeof(vec4l); case OSP_ULONG: return sizeof(uint64); - case OSP_ULONG2: return sizeof(embree::Vec2); - case OSP_ULONG3: return sizeof(embree::Vec3); - case OSP_ULONG4: return sizeof(embree::Vec4); + case OSP_ULONG2: return sizeof(vec2ul); + case OSP_ULONG3: return sizeof(vec3ul); + case OSP_ULONG4: return sizeof(vec4ul); case OSP_FLOAT: return sizeof(float); - case OSP_FLOAT2: return sizeof(embree::Vec2); - case OSP_FLOAT3: return sizeof(embree::Vec3); - case OSP_FLOAT4: return sizeof(embree::Vec4); - case OSP_FLOAT3A: return sizeof(embree::Vec3fa); + case OSP_FLOAT2: return sizeof(vec2f); + case OSP_FLOAT3: return sizeof(vec3f); + case OSP_FLOAT4: return sizeof(vec4f); + case OSP_FLOAT3A: return sizeof(vec3fa); case OSP_DOUBLE: return sizeof(double); default: break; }; diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index 761dab2d3e..f656a4dd98 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -41,6 +41,12 @@ typedef int ssize_t; # include "unistd.h" #endif +#if 1 +#include "../../common/AffineSpace.h" +#include "../../common/intrinsics.h" +#include "../../common/RefCount.h" +#include "../../common/malloc.h" +#else // embree #include "common/math/vec2.h" #include "common/math/vec3.h" @@ -49,6 +55,7 @@ typedef int ssize_t; #include "common/math/affinespace.h" // includes "common/math/linearspace[23].h" #include "common/sys/ref.h" #include "common/sys/alloc.h" +#endif // C++11 #include @@ -65,6 +72,7 @@ namespace ospray { typedef std::lock_guard LockGuard; typedef std::condition_variable Condition; + using namespace ospcommon; } #define SCOPED_LOCK(x) \ @@ -98,26 +106,18 @@ namespace ospray { #pragma warning(disable:177 ) // variable declared but was never referenced #endif -#if 0//NOTE: this causes crashes in standard library containers on MIC... -//#ifdef OSPRAY_TARGET_MIC -inline void* operator new(size_t size) throw(std::bad_alloc) { return embree::alignedMalloc(size); } -inline void operator delete(void* ptr) throw() { embree::alignedFree(ptr); } -inline void* operator new[](size_t size) throw(std::bad_alloc) { return embree::alignedMalloc(size); } -inline void operator delete[](void* ptr) throw() { embree::alignedFree(ptr); } -#endif - //! main namespace for all things ospray (for internal code) namespace ospray { - using embree::one; - using embree::empty; - using embree::zero; - using embree::inf; - using embree::deg2rad; - using embree::rad2deg; - using embree::sign; - using embree::clamp; - using embree::frac; + // using embree::one; + // using embree::empty; + // using embree::zero; + // using embree::inf; + // using embree::deg2rad; + // using embree::rad2deg; + // using embree::sign; + // using embree::clamp; + // using embree::frac; /*! basic types */ typedef ::int64_t int64; @@ -134,62 +134,62 @@ namespace ospray { typedef ::int64_t index_t; - /*! OSPRay's two-int vector class */ - typedef embree::Vec2i vec2i; - /*! OSPRay's three-unsigned char vector class */ - typedef embree::Vec3 vec3uc; - /*! OSPRay's 4x unsigned char vector class */ - typedef embree::Vec4 vec4uc; - /*! OSPRay's 2x uint32 vector class */ - typedef embree::Vec2 vec2ui; - /*! OSPRay's 3x uint32 vector class */ - typedef embree::Vec3 vec3ui; - /*! OSPRay's 4x uint32 vector class */ - typedef embree::Vec4 vec4ui; - /*! OSPRay's 3x int32 vector class */ - typedef embree::Vec3 vec3i; - /*! OSPRay's four-int vector class */ - typedef embree::Vec4i vec4i; - /*! OSPRay's two-float vector class */ - typedef embree::Vec2f vec2f; - /*! OSPRay's three-float vector class */ - typedef embree::Vec3f vec3f; - /*! OSPRay's three-float vector class (aligned to 16b-boundaries) */ - typedef embree::Vec3fa vec3fa; - /*! OSPRay's four-float vector class */ - typedef embree::Vec4f vec4f; - - typedef embree::BBox box2ui; - typedef embree::BBox region2i; - typedef embree::BBox region2ui; - - typedef embree::BBox box3i; - typedef embree::BBox box3ui; + // /*! OSPRay's two-int vector class */ + // typedef embree::Vec2i vec2i; + // /*! OSPRay's three-unsigned char vector class */ + // typedef embree::Vec3 vec3uc; + // /*! OSPRay's 4x unsigned char vector class */ + // typedef embree::Vec4 vec4uc; + // /*! OSPRay's 2x uint32 vector class */ + // typedef embree::Vec2 vec2ui; + // /*! OSPRay's 3x uint32 vector class */ + // typedef embree::Vec3 vec3ui; + // /*! OSPRay's 4x uint32 vector class */ + // typedef embree::Vec4 vec4ui; + // /*! OSPRay's 3x int32 vector class */ + // typedef embree::Vec3 vec3i; + // /*! OSPRay's four-int vector class */ + // typedef embree::Vec4i vec4i; + // /*! OSPRay's two-float vector class */ + // typedef embree::Vec2f vec2f; + // /*! OSPRay's three-float vector class */ + // typedef embree::Vec3f vec3f; + // /*! OSPRay's three-float vector class (aligned to 16b-boundaries) */ + // typedef embree::Vec3fa vec3fa; + // /*! OSPRay's four-float vector class */ + // typedef embree::Vec4f vec4f; + + // typedef embree::BBox box2ui; + // typedef embree::BBox region2i; + // typedef embree::BBox region2ui; + + // typedef embree::BBox box3i; + // typedef embree::BBox box3ui; - typedef embree::BBox3f box3f; - typedef embree::BBox3fa box3fa; - typedef embree::BBox box3uc; - typedef embree::BBox box4f; - typedef embree::BBox3fa box3fa; + // typedef embree::BBox3f box3f; + // typedef embree::BBox3fa box3fa; + // typedef embree::BBox box3uc; + // typedef embree::BBox box4f; + // typedef embree::BBox3fa box3fa; - /*! affice space transformation */ - typedef embree::AffineSpace2f affine2f; - typedef embree::AffineSpace3f affine3f; - typedef embree::AffineSpace3fa affine3fa; - typedef embree::AffineSpace3f AffineSpace3f; - typedef embree::AffineSpace3fa AffineSpace3fa; + // /*! affice space transformation */ + // typedef embree::AffineSpace2f affine2f; + // typedef embree::AffineSpace3f affine3f; + // typedef embree::AffineSpace3fa affine3fa; + // typedef embree::AffineSpace3f AffineSpace3f; + // typedef embree::AffineSpace3fa AffineSpace3fa; - typedef embree::LinearSpace2f linear2f; - typedef embree::LinearSpace3f linear3f; - typedef embree::LinearSpace3fa linear3fa; - typedef embree::LinearSpace3f LinearSpace3f; - typedef embree::LinearSpace3fa LinearSpace3fa; + // typedef embree::LinearSpace2f linear2f; + // typedef embree::LinearSpace3f linear3f; + // typedef embree::LinearSpace3fa linear3fa; + // typedef embree::LinearSpace3f LinearSpace3f; + // typedef embree::LinearSpace3fa LinearSpace3fa; - using embree::Ref; - using embree::RefCount; + // using embree::Ref; + // using embree::RefCount; - using embree::cross; - using embree::volume; + // using embree::cross; + // using embree::volume; void init(int *ac, const char ***av); @@ -212,7 +212,7 @@ namespace ospray { #endif #endif - inline size_t rdtsc() { return embree::rdtsc(); } + inline size_t rdtsc() { return ospcommon::rdtsc(); } /*! logging level (cmdline: --osp:loglevel \) */ extern uint32 logLevel; @@ -261,11 +261,3 @@ namespace ospray { #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif #define NOTIMPLEMENTED throw std::runtime_error(std::string(__PRETTY_FUNCTION__)+": not implemented..."); - -template -inline T divRoundUp(const T&a, const T&b) { return (a+(b-T(1)))/b; } - -#if WARN_ON_INCLUDING_OSPCOMMON -# error "should not include OSPCOMMON.h from outside of ospray/* files!" -#endif - diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 329d666fc0..3a8d7e1039 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -17,9 +17,6 @@ #include "LocalFB.h" #include "LocalFB_ispc.h" -using embree::alignedFree; -using embree::alignedMalloc; - namespace ospray { LocalFrameBuffer::LocalFrameBuffer(const vec2i &size, diff --git a/ospray/fb/PixelOp.h b/ospray/fb/PixelOp.h index 98276187e1..0f77e71576 100644 --- a/ospray/fb/PixelOp.h +++ b/ospray/fb/PixelOp.h @@ -41,7 +41,7 @@ namespace ospray { */ struct PixelOp : public ManagedObject { - struct Instance : public embree::RefCount + struct Instance : public RefCount { FrameBuffer *fb; /*! gets called every time the frame buffer got 'commit'ted */ diff --git a/ospray/geometry/Geometry.h b/ospray/geometry/Geometry.h index bb5b6b817a..79578244a8 100644 --- a/ospray/geometry/Geometry.h +++ b/ospray/geometry/Geometry.h @@ -37,7 +37,7 @@ namespace ospray { struct Geometry : public ManagedObject { //! constructor - Geometry() : bounds(embree::empty) { managedObjectType = OSP_GEOMETRY; } + Geometry() : bounds(empty) { managedObjectType = OSP_GEOMETRY; } //! set given geometry's material. /*! all material assignations should go through this function; the diff --git a/ospray/geometry/Instance.cpp b/ospray/geometry/Instance.cpp index 4b07ce95d0..10db1408de 100644 --- a/ospray/geometry/Instance.cpp +++ b/ospray/geometry/Instance.cpp @@ -69,7 +69,7 @@ namespace ospray { const vec3f v110(b.lower.x,b.upper.y,b.upper.z); const vec3f v111(b.upper.x,b.upper.y,b.upper.z); - bounds = embree::empty; + bounds = empty; bounds.extend(xfmPoint(xfm,v000)); bounds.extend(xfmPoint(xfm,v001)); bounds.extend(xfmPoint(xfm,v010)); diff --git a/ospray/geometry/TriangleMesh.cpp b/ospray/geometry/TriangleMesh.cpp index e6be0b77d8..e6931af209 100644 --- a/ospray/geometry/TriangleMesh.cpp +++ b/ospray/geometry/TriangleMesh.cpp @@ -22,7 +22,6 @@ # include "ospray/mpi/MPICommon.h" #endif - // ospray #include "TriangleMesh.h" #include "ospray/common/Model.h" @@ -186,7 +185,7 @@ namespace ospray { (void*)this->index,0, sizeOf(indexData->type)); - bounds = embree::empty; + bounds = empty; for (int i=0;i Date: Sun, 21 Feb 2016 11:53:28 -0600 Subject: [PATCH 019/310] opengl util now uses ospcommon, too, no longer ospray internals --- modules/opengl/util.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/opengl/util.cpp b/modules/opengl/util.cpp index ba1e6a58b3..00f70d921c 100644 --- a/modules/opengl/util.cpp +++ b/modules/opengl/util.cpp @@ -15,7 +15,8 @@ // ======================================================================== // #include "util.h" -#include +#include "common/vec.h" +// #include #ifdef __APPLE__ #include @@ -25,9 +26,10 @@ #include namespace ospray { - namespace opengl { + typedef ospcommon::vec2i vec2i; + typedef ospcommon::vec3f vec3f; - using embree::cross; + namespace opengl { OSPTexture2D getOSPDepthTextureFromOpenGLPerspective() { From b73d3fab59ab84e06a24bee766f96df871e49815 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 11:56:35 -0600 Subject: [PATCH 020/310] particle viewer ported to ospcommon --- apps/particleViewer/Model.cpp | 8 +++++--- apps/particleViewer/Model.h | 13 ++++++++----- apps/particleViewer/ParticleViewer.cpp | 24 ++++++++++++------------ apps/particleViewer/uintah.cpp | 6 +++--- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/apps/particleViewer/Model.cpp b/apps/particleViewer/Model.cpp index ca70f60810..cb9dbf5891 100644 --- a/apps/particleViewer/Model.cpp +++ b/apps/particleViewer/Model.cpp @@ -15,6 +15,8 @@ // ======================================================================== // #include "Model.h" +// stl +#include extern int yyparse(); extern void yyerror(const char* msg); @@ -31,14 +33,14 @@ namespace ospray { const int mx = 13*17*43; const int my = 11*29; const int mz = 7*23*63; - const uint32 g = (i * (3*5*127)+12312314); + const uint32_t g = (i * (3*5*127)+12312314); return vec3f((g % mx)*(1.f/(mx-1)), (g % my)*(1.f/(my-1)), (g % mz)*(1.f/(mz-1))); } /*! read given file with atom type definitions */ - void Model::readAtomTypeDefinitions(const embree::FileName &fn) + void Model::readAtomTypeDefinitions(const FileName &fn) { FILE *file = fopen(fn.str().c_str(),"r"); if (!file) { @@ -192,7 +194,7 @@ namespace ospray { box3f Model::getBBox() const { - box3f bbox = embree::empty; + box3f bbox = empty; for (int i=0;i #include namespace ospray { namespace particle { + using namespace ospcommon; struct Model { struct AtomType { @@ -49,7 +52,7 @@ namespace ospray { std::map *> attribute; /*! read given file with atom type definitions */ - void readAtomTypeDefinitions(const embree::FileName &fn); + void readAtomTypeDefinitions(const FileName &fn); int getAtomType(const std::string &name); diff --git a/apps/particleViewer/ParticleViewer.cpp b/apps/particleViewer/ParticleViewer.cpp index abad8a6340..178221e98d 100644 --- a/apps/particleViewer/ParticleViewer.cpp +++ b/apps/particleViewer/ParticleViewer.cpp @@ -85,7 +85,7 @@ namespace ospray { ospCommit(renderer); }; - virtual void reshape(const ospray::vec2i &_newSize) + virtual void reshape(const ospcommon::vec2i &_newSize) { Glut3DWidget::reshape(_newSize); if (fb) ospFreeFrameBuffer(fb); @@ -101,7 +101,7 @@ namespace ospray { setTitle("OSPRay Particle Viewer"); } - virtual void keypress(char key, const vec2f where) + virtual void keypress(char key, const vec2i &where) { switch(key) { case 'Q': exit(0); @@ -168,7 +168,7 @@ namespace ospray { if (accumID < maxAccum) forceRedraw(); - ucharFB = (uint32 *) ospMapFrameBuffer(fb); + ucharFB = (uint32_t *) ospMapFrameBuffer(fb); frameBufferMode = Glut3DWidget::FRAMEBUFFER_UCHAR; Glut3DWidget::display(); @@ -225,17 +225,17 @@ namespace ospray { struct DeferredLoadJob { DeferredLoadJob(particle::Model *model, - const embree::FileName &xyzFileName, - const embree::FileName &defFileName) + const FileName &xyzFileName, + const FileName &defFileName) : model(model), xyzFileName(xyzFileName), defFileName(defFileName) {} //! the mode we still have to load particle::Model *model; //! file name of xyz file to be loaded into this model - embree::FileName xyzFileName; + FileName xyzFileName; //! name of atom type defintion file active when this xyz file was added - embree::FileName defFileName; + FileName defFileName; }; void ospParticleViewerMain(int &ac, const char **&av) @@ -244,7 +244,7 @@ namespace ospray { cout << "ospParticleViewer: starting to process cmdline arguments" << endl; std::vector deferredLoadingListXYZ; - embree::FileName defFileName = ""; + FileName defFileName = ""; for (int i=1;iloadXYZ(fn); - // std::pair loadJob(m,fn.str()); + // std::pair loadJob(m,fn.str()); deferredLoadingListXYZ.push_back(new DeferredLoadJob(m,fn,defFileName)); particleModel.push_back(m); } else if (fn.ext() == "xyz2") { @@ -298,8 +298,8 @@ namespace ospray { #pragma omp parallel for for (int i=0;idefFileName; - embree::FileName xyzFileName = deferredLoadingListXYZ[i]->xyzFileName; + FileName defFileName = deferredLoadingListXYZ[i]->defFileName; + FileName xyzFileName = deferredLoadingListXYZ[i]->xyzFileName; particle::Model *model = deferredLoadingListXYZ[i]->model; if (defFileName.str() != "") diff --git a/apps/particleViewer/uintah.cpp b/apps/particleViewer/uintah.cpp index 20deb6817e..73e48701d8 100644 --- a/apps/particleViewer/uintah.cpp +++ b/apps/particleViewer/uintah.cpp @@ -257,7 +257,7 @@ namespace ospray { void parse__Uintah_Datafile(Model *model, const std::string &fileName) { - std::string basePath = embree::FileName(fileName).path(); + std::string basePath = FileName(fileName).path(); xml::XMLDoc *doc = NULL; try { @@ -349,7 +349,7 @@ namespace ospray { assert(doc); assert(doc->child.size() == 1); assert(doc->child[0]->name == "Uintah_timestep"); - std::string basePath = embree::FileName(s).path(); + std::string basePath = FileName(s).path(); parse__Uintah_timestep(model, basePath, doc->child[0]); std::stringstream attrs; @@ -361,7 +361,7 @@ namespace ospray { std::cout << "#osp:mpm: read " << s << " : " << model->atom.size() << " particles (" << attrs.str() << ")" << std::endl; - box3f bounds = embree::empty; + box3f bounds = empty; for (int i=0;iatom.size();i++) { bounds.extend(model->atom[i].position); } From 68b00dfc11ef0ac6639e760dd76527aacc9e1052 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 12:28:46 -0600 Subject: [PATCH 021/310] all included modules and viewers (incl loaders module and volume viewer) now free of internal ospray and embree includes added missing common/malloc files that I forgot earlier --- apps/particleViewer/uintah.cpp | 5 +- apps/volumeViewer/ColorMap.cpp | 4 +- apps/volumeViewer/ColorMap.h | 11 +- apps/volumeViewer/IsosurfaceEditor.cpp | 2 +- apps/volumeViewer/IsosurfaceEditor.h | 6 +- apps/volumeViewer/IsovalueWidget.cpp | 2 +- apps/volumeViewer/IsovalueWidget.h | 6 +- .../volumeViewer/OpenGLAnnotationRenderer.cpp | 4 +- apps/volumeViewer/PreferencesDialog.cpp | 8 +- apps/volumeViewer/PreferencesDialog.h | 4 +- apps/volumeViewer/ProbeWidget.cpp | 10 +- apps/volumeViewer/ProbeWidget.h | 10 +- apps/volumeViewer/QOSPRayWindow.cpp | 22 +- apps/volumeViewer/QOSPRayWindow.h | 23 ++- apps/volumeViewer/SliceEditor.cpp | 3 +- apps/volumeViewer/SliceEditor.h | 4 +- apps/volumeViewer/SliceWidget.cpp | 18 +- apps/volumeViewer/SliceWidget.h | 10 +- apps/volumeViewer/TransferFunctionEditor.cpp | 70 +++---- apps/volumeViewer/TransferFunctionEditor.h | 2 +- apps/volumeViewer/VolumeViewer.cpp | 22 +- apps/volumeViewer/VolumeViewer.h | 8 +- apps/volumeViewer/main.cpp | 17 +- common/box.h | 5 + common/malloc.cpp | 191 ++++++++++++++++++ common/vec.h | 1 + modules/loaders/CMakeLists.txt | 5 +- modules/loaders/OSPObjectFile.cpp | 11 +- modules/loaders/ObjectFile.cpp | 6 +- modules/loaders/ObjectFile.h | 2 +- modules/loaders/PLYTriangleMeshFile.cpp | 14 +- modules/loaders/PLYTriangleMeshFile.h | 18 +- modules/loaders/RMVolumeFile.cpp | 28 +-- modules/loaders/RMVolumeFile.h | 2 +- modules/loaders/RawVolumeFile.cpp | 22 +- modules/loaders/RawVolumeFile.h | 5 +- modules/loaders/TriangleMeshFile.cpp | 6 +- modules/loaders/VolumeFile.cpp | 7 +- modules/loaders/VolumeFile.h | 13 +- ospray/CMakeLists.txt | 2 + ospray/common/OSPCommon.h | 4 + 41 files changed, 421 insertions(+), 192 deletions(-) create mode 100644 common/malloc.cpp diff --git a/apps/particleViewer/uintah.cpp b/apps/particleViewer/uintah.cpp index 73e48701d8..62fa19e025 100644 --- a/apps/particleViewer/uintah.cpp +++ b/apps/particleViewer/uintah.cpp @@ -16,11 +16,12 @@ #undef NDEBUG -#include "ospray/common/OSPCommon.h" #include "apps/common/xml/XML.h" #include "Model.h" // embree -#include "common/sys/filename.h" +#include "common/FileName.h" +// std +#include namespace ospray { namespace particle { diff --git a/apps/volumeViewer/ColorMap.cpp b/apps/volumeViewer/ColorMap.cpp index 22042086ae..90d67b439d 100644 --- a/apps/volumeViewer/ColorMap.cpp +++ b/apps/volumeViewer/ColorMap.cpp @@ -16,7 +16,7 @@ #include "ColorMap.h" -ColorMap::ColorMap(std::string name, std::vector colors) +ColorMap::ColorMap(std::string name, std::vector colors) { this->name = name; this->colors = colors; @@ -27,7 +27,7 @@ std::string ColorMap::getName() return name; } -std::vector ColorMap::getColors() +std::vector ColorMap::getColors() { return colors; } diff --git a/apps/volumeViewer/ColorMap.h b/apps/volumeViewer/ColorMap.h index 0601ac6fae..e0d63b3d93 100644 --- a/apps/volumeViewer/ColorMap.h +++ b/apps/volumeViewer/ColorMap.h @@ -16,8 +16,11 @@ #pragma once +// ospray public #include -#include "ospray/common/OSPCommon.h" +// ospcommon +#include "common/vec.h" +// std #include #include #include @@ -26,15 +29,15 @@ class ColorMap { public: - ColorMap(std::string name, std::vector colors); + ColorMap(std::string name, std::vector colors); std::string getName(); - std::vector getColors(); + std::vector getColors(); QImage getImage(); protected: std::string name; - std::vector colors; + std::vector colors; }; diff --git a/apps/volumeViewer/IsosurfaceEditor.cpp b/apps/volumeViewer/IsosurfaceEditor.cpp index 0c6781fad5..61b7088c6a 100644 --- a/apps/volumeViewer/IsosurfaceEditor.cpp +++ b/apps/volumeViewer/IsosurfaceEditor.cpp @@ -29,7 +29,7 @@ IsosurfaceEditor::IsosurfaceEditor() connect(addIsovalueButton, SIGNAL(clicked()), this, SLOT(addIsovalue())); } -void IsosurfaceEditor::setDataValueRange(ospray::vec2f dataValueRange) +void IsosurfaceEditor::setDataValueRange(ospcommon::vec2f dataValueRange) { this->dataValueRange = dataValueRange; diff --git a/apps/volumeViewer/IsosurfaceEditor.h b/apps/volumeViewer/IsosurfaceEditor.h index b110aca1d7..a044a4708e 100644 --- a/apps/volumeViewer/IsosurfaceEditor.h +++ b/apps/volumeViewer/IsosurfaceEditor.h @@ -17,7 +17,7 @@ #pragma once #include -#include "ospray/common/OSPCommon.h" +#include "common/vec.h" #include #include @@ -37,7 +37,7 @@ Q_OBJECT public slots: - void setDataValueRange(ospray::vec2f dataValueRange); + void setDataValueRange(ospcommon::vec2f dataValueRange); void apply(); @@ -47,7 +47,7 @@ protected slots: protected: - ospray::vec2f dataValueRange; + ospcommon::vec2f dataValueRange; QVBoxLayout layout; diff --git a/apps/volumeViewer/IsovalueWidget.cpp b/apps/volumeViewer/IsovalueWidget.cpp index 4ce63c46c9..ca2293233e 100644 --- a/apps/volumeViewer/IsovalueWidget.cpp +++ b/apps/volumeViewer/IsovalueWidget.cpp @@ -44,7 +44,7 @@ IsovalueWidget::IsovalueWidget(IsosurfaceEditor *isosurfaceEditor) : dataRangeSe connect(this, SIGNAL(isovalueChanged()), isosurfaceEditor, SLOT(apply())); } -void IsovalueWidget::setDataValueRange(ospray::vec2f dataValueRange) +void IsovalueWidget::setDataValueRange(ospcommon::vec2f dataValueRange) { this->dataValueRange = dataValueRange; diff --git a/apps/volumeViewer/IsovalueWidget.h b/apps/volumeViewer/IsovalueWidget.h index 0ee4bd221f..96a8c8b8ee 100644 --- a/apps/volumeViewer/IsovalueWidget.h +++ b/apps/volumeViewer/IsovalueWidget.h @@ -17,7 +17,7 @@ #pragma once #include -#include "ospray/common/OSPCommon.h" +#include "common/vec.h" #include class IsosurfaceEditor; @@ -33,7 +33,7 @@ Q_OBJECT bool getIsovalueEnabled() { return isovalueCheckBox.isChecked(); } float getIsovalue() { return isovalueSpinBox.value(); } - void setDataValueRange(ospray::vec2f dataValueRange); + void setDataValueRange(ospcommon::vec2f dataValueRange); signals: @@ -45,7 +45,7 @@ protected slots: protected: - ospray::vec2f dataValueRange; + ospcommon::vec2f dataValueRange; //! Indicates if the data value range has been set; we don't automatically set the isovalue after the first time it's set. bool dataRangeSet; diff --git a/apps/volumeViewer/OpenGLAnnotationRenderer.cpp b/apps/volumeViewer/OpenGLAnnotationRenderer.cpp index 51f4bc39b1..990e210740 100644 --- a/apps/volumeViewer/OpenGLAnnotationRenderer.cpp +++ b/apps/volumeViewer/OpenGLAnnotationRenderer.cpp @@ -29,9 +29,9 @@ void OpenGLAnnotationRenderer::render() glEnable(GL_DEPTH_TEST); // render volume bounding box - ospray::box3f boundingBox = volumeViewer->getBoundingBox(); + ospcommon::box3f boundingBox = volumeViewer->getBoundingBox(); - ospray::vec3f size(boundingBox.upper - boundingBox.lower); + ospcommon::vec3f size(boundingBox.upper - boundingBox.lower); glPushMatrix(); glTranslatef(boundingBox.lower.x, boundingBox.lower.y, boundingBox.lower.z); diff --git a/apps/volumeViewer/PreferencesDialog.cpp b/apps/volumeViewer/PreferencesDialog.cpp index 2835169af4..b3dc2b1014 100644 --- a/apps/volumeViewer/PreferencesDialog.cpp +++ b/apps/volumeViewer/PreferencesDialog.cpp @@ -17,7 +17,7 @@ #include "VolumeViewer.h" #include "PreferencesDialog.h" -PreferencesDialog::PreferencesDialog(VolumeViewer *volumeViewer, ospray::box3f boundingBox) : QDialog(volumeViewer), volumeViewer(volumeViewer) +PreferencesDialog::PreferencesDialog(VolumeViewer *volumeViewer, ospcommon::box3f boundingBox) : QDialog(volumeViewer), volumeViewer(volumeViewer) { setWindowTitle("Preferences"); @@ -91,12 +91,12 @@ PreferencesDialog::PreferencesDialog(VolumeViewer *volumeViewer, ospray::box3f b void PreferencesDialog::updateVolumeClippingBox() { - ospray::vec3f lower(volumeClippingBoxSpinBoxes[0]->value(), + ospcommon::vec3f lower(volumeClippingBoxSpinBoxes[0]->value(), volumeClippingBoxSpinBoxes[1]->value(), volumeClippingBoxSpinBoxes[2]->value()); - ospray::vec3f upper(volumeClippingBoxSpinBoxes[3]->value(), + ospcommon::vec3f upper(volumeClippingBoxSpinBoxes[3]->value(), volumeClippingBoxSpinBoxes[4]->value(), volumeClippingBoxSpinBoxes[5]->value()); - volumeViewer->setVolumeClippingBox(ospray::box3f(lower, upper)); + volumeViewer->setVolumeClippingBox(ospcommon::box3f(lower, upper)); } diff --git a/apps/volumeViewer/PreferencesDialog.h b/apps/volumeViewer/PreferencesDialog.h index 180ee27603..3e8611174e 100644 --- a/apps/volumeViewer/PreferencesDialog.h +++ b/apps/volumeViewer/PreferencesDialog.h @@ -17,7 +17,7 @@ #pragma once #include -#include "ospray/common/OSPCommon.h" +#include "common/box.h" #include #include @@ -29,7 +29,7 @@ Q_OBJECT public: - PreferencesDialog(VolumeViewer *volumeViewer, ospray::box3f boundingBox); + PreferencesDialog(VolumeViewer *volumeViewer, ospcommon::box3f boundingBox); protected slots: diff --git a/apps/volumeViewer/ProbeWidget.cpp b/apps/volumeViewer/ProbeWidget.cpp index 24aaf7b6d8..86600c0fd9 100644 --- a/apps/volumeViewer/ProbeWidget.cpp +++ b/apps/volumeViewer/ProbeWidget.cpp @@ -24,7 +24,7 @@ #include #endif -ProbeCoordinateWidget::ProbeCoordinateWidget(const std::string &label, ospray::vec2f range) : range(range) +ProbeCoordinateWidget::ProbeCoordinateWidget(const std::string &label, ospcommon::vec2f range) : range(range) { QHBoxLayout *layout = new QHBoxLayout(); setLayout(layout); @@ -89,9 +89,9 @@ ProbeWidget::ProbeWidget(VolumeViewer *volumeViewer) : volumeViewer(volumeViewer coordinatesGroupBox->setLayout(coordinatesLayout); connect(this, SIGNAL(enabled(bool)), coordinatesGroupBox, SLOT(setEnabled(bool))); - probeCoordinateWidgets.push_back(new ProbeCoordinateWidget("x", ospray::vec2f(boundingBox.lower.x, boundingBox.upper.x))); - probeCoordinateWidgets.push_back(new ProbeCoordinateWidget("y", ospray::vec2f(boundingBox.lower.y, boundingBox.upper.y))); - probeCoordinateWidgets.push_back(new ProbeCoordinateWidget("z", ospray::vec2f(boundingBox.lower.z, boundingBox.upper.z))); + probeCoordinateWidgets.push_back(new ProbeCoordinateWidget("x", ospcommon::vec2f(boundingBox.lower.x, boundingBox.upper.x))); + probeCoordinateWidgets.push_back(new ProbeCoordinateWidget("y", ospcommon::vec2f(boundingBox.lower.y, boundingBox.upper.y))); + probeCoordinateWidgets.push_back(new ProbeCoordinateWidget("z", ospcommon::vec2f(boundingBox.lower.z, boundingBox.upper.z))); for (int i=0; i<3; i++) { coordinatesLayout->addWidget(probeCoordinateWidgets[i]); @@ -132,7 +132,7 @@ void ProbeWidget::updateProbe() return; } - coordinate = ospray::vec3f(probeCoordinateWidgets[0]->getValue(), probeCoordinateWidgets[1]->getValue(), probeCoordinateWidgets[2]->getValue()); + coordinate = ospcommon::vec3f(probeCoordinateWidgets[0]->getValue(), probeCoordinateWidgets[1]->getValue(), probeCoordinateWidgets[2]->getValue()); if (volume) { diff --git a/apps/volumeViewer/ProbeWidget.h b/apps/volumeViewer/ProbeWidget.h index d48f3a0926..3d7d6745d3 100644 --- a/apps/volumeViewer/ProbeWidget.h +++ b/apps/volumeViewer/ProbeWidget.h @@ -17,7 +17,7 @@ #pragma once #include -#include "ospray/common/OSPCommon.h" +#include "common/box.h" #include #include @@ -30,7 +30,7 @@ Q_OBJECT public: - ProbeCoordinateWidget(const std::string &label, ospray::vec2f range); + ProbeCoordinateWidget(const std::string &label, ospcommon::vec2f range); float getValue() { return spinBox.value(); } @@ -44,7 +44,7 @@ protected slots: protected: - ospray::vec2f range; + ospcommon::vec2f range; QSlider slider; QDoubleSpinBox spinBox; @@ -80,7 +80,7 @@ public slots: QOSPRayWindow *osprayWindow; //! Bounding box to consider. - ospray::box3f boundingBox; + ospcommon::box3f boundingBox; //! Active volume to probe. OSPVolume volume; @@ -89,7 +89,7 @@ public slots: bool isEnabled; //! The probe coordinate. - ospray::vec3f coordinate; + ospcommon::vec3f coordinate; // UI elements. std::vector probeCoordinateWidgets; diff --git a/apps/volumeViewer/QOSPRayWindow.cpp b/apps/volumeViewer/QOSPRayWindow.cpp index 5a40c98537..c9b5538b54 100644 --- a/apps/volumeViewer/QOSPRayWindow.cpp +++ b/apps/volumeViewer/QOSPRayWindow.cpp @@ -105,7 +105,7 @@ void QOSPRayWindow::setBenchmarkParameters(int benchmarkWarmUpFrames, int benchm this->benchmarkFrames = benchmarkFrames; } -void QOSPRayWindow::setWorldBounds(const ospray::box3f &worldBounds) +void QOSPRayWindow::setWorldBounds(const ospcommon::box3f &worldBounds) { this->worldBounds = worldBounds; @@ -131,7 +131,7 @@ void QOSPRayWindow::paintGL() // update OSPRay camera if viewport has been modified if(viewport.modified) { - const ospray::vec3f dir = viewport.at - viewport.from; + const ospcommon::vec3f dir = viewport.at - viewport.from; ospSetVec3f(camera,"pos" ,(const osp::vec3f&)viewport.from); ospSetVec3f(camera,"dir" ,(const osp::vec3f&)dir); ospSetVec3f(camera,"up", (const osp::vec3f&)viewport.up); @@ -216,7 +216,7 @@ void QOSPRayWindow::paintGL() void QOSPRayWindow::resizeGL(int width, int height) { - windowSize = ospray::vec2i(width, height); + windowSize = ospcommon::vec2i(width, height); // reallocate OSPRay framebuffer for new size if(frameBuffer) @@ -313,12 +313,12 @@ void QOSPRayWindow::mouseMoveEvent(QMouseEvent * event) void QOSPRayWindow::rotateCenter(float du, float dv) { - const ospray::vec3f pivot = viewport.at; + const ospcommon::vec3f pivot = viewport.at; - ospray::affine3f xfm = ospray::affine3f::translate(pivot) - * ospray::affine3f::rotate(viewport.frame.l.vx, -dv) - * ospray::affine3f::rotate(viewport.frame.l.vz, -du) - * ospray::affine3f::translate(-pivot); + ospcommon::affine3f xfm = ospcommon::affine3f::translate(pivot) + * ospcommon::affine3f::rotate(viewport.frame.l.vx, -dv) + * ospcommon::affine3f::rotate(viewport.frame.l.vz, -du) + * ospcommon::affine3f::translate(-pivot); viewport.frame = xfm * viewport.frame; viewport.from = xfmPoint(xfm, viewport.from); @@ -330,8 +330,8 @@ void QOSPRayWindow::rotateCenter(float du, float dv) void QOSPRayWindow::strafe(float du, float dv) { - ospray::affine3f xfm = ospray::affine3f::translate(dv * viewport.frame.l.vz) - * ospray::affine3f::translate(-du * viewport.frame.l.vx); + ospcommon::affine3f xfm = ospcommon::affine3f::translate(dv * viewport.frame.l.vz) + * ospcommon::affine3f::translate(-du * viewport.frame.l.vx); viewport.frame = xfm * viewport.frame; viewport.from = xfmPoint(xfm, viewport.from); @@ -344,7 +344,7 @@ void QOSPRayWindow::strafe(float du, float dv) void QOSPRayWindow::renderGL() { // setup OpenGL state to match OSPRay view - const ospray::vec3f bgColor = ospray::vec3f(1.f); + const ospcommon::vec3f bgColor = ospcommon::vec3f(1.f); glClearColor(bgColor.x, bgColor.y, bgColor.z, 1.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/apps/volumeViewer/QOSPRayWindow.h b/apps/volumeViewer/QOSPRayWindow.h index 691413eceb..5ebe855d51 100644 --- a/apps/volumeViewer/QOSPRayWindow.h +++ b/apps/volumeViewer/QOSPRayWindow.h @@ -16,8 +16,11 @@ #pragma once +// ospray public #include -#include "ospray/common/OSPCommon.h" +// ospcommon +#include "common/AffineSpace.h" +// qt #include #include @@ -30,12 +33,12 @@ struct Viewport fovY(60.f), modified(true) { - frame = ospray::affine3f::translate(from) * ospray::affine3f(embree::one); + frame = ospcommon::affine3f::translate(from) * ospcommon::affine3f(ospcommon::one); } - ospray::vec3f from; - ospray::vec3f at; - ospray::vec3f up; + ospcommon::vec3f from; + ospcommon::vec3f at; + ospcommon::vec3f up; /*! aspect ratio (width / height) */ float aspect; @@ -49,10 +52,10 @@ struct Viewport /*! camera frame in which the Y axis is the depth axis, and X and Z axes are parallel to the screen X and Y axis. The frame itself remains normalized. */ - ospray::affine3f frame; + ospcommon::affine3f frame; /*! set up vector */ - void setUp(const ospray::vec3f &vec) + void setUp(const ospcommon::vec3f &vec) { up = vec; snapUp(); @@ -87,7 +90,7 @@ Q_OBJECT void setRenderingEnabled(bool renderingEnabled); void setRotationRate(float rotationRate); void setBenchmarkParameters(int benchmarkWarmUpFrames, int benchmarkFrames); - virtual void setWorldBounds(const ospray::box3f &worldBounds); + virtual void setWorldBounds(const ospcommon::box3f &worldBounds); Viewport * getViewport() { return &viewport; } @@ -150,9 +153,9 @@ Q_OBJECT /*! Timer to measure elapsed time over a single frame. */ QTime renderFrameTimer; - ospray::vec2i windowSize; + ospcommon::vec2i windowSize; Viewport viewport; - ospray::box3f worldBounds; + ospcommon::box3f worldBounds; QPoint lastMousePosition; OSPFrameBuffer frameBuffer; diff --git a/apps/volumeViewer/SliceEditor.cpp b/apps/volumeViewer/SliceEditor.cpp index ecdc12ecba..f7da6beeea 100644 --- a/apps/volumeViewer/SliceEditor.cpp +++ b/apps/volumeViewer/SliceEditor.cpp @@ -17,7 +17,8 @@ #include "SliceEditor.h" #include -SliceEditor::SliceEditor(ospray::box3f boundingBox) : boundingBox(boundingBox) +SliceEditor::SliceEditor(ospcommon::box3f boundingBox) + : boundingBox(boundingBox) { // Setup UI elements. layout.setSizeConstraint(QLayout::SetMinimumSize); diff --git a/apps/volumeViewer/SliceEditor.h b/apps/volumeViewer/SliceEditor.h index bc47e70fb1..d9ed334182 100644 --- a/apps/volumeViewer/SliceEditor.h +++ b/apps/volumeViewer/SliceEditor.h @@ -29,7 +29,7 @@ Q_OBJECT public: - SliceEditor(ospray::box3f boundingBox); + SliceEditor(ospcommon::box3f boundingBox); signals: @@ -44,7 +44,7 @@ public slots: protected: //! Bounding box of the volume. - ospray::box3f boundingBox; + ospcommon::box3f boundingBox; //! UI elements. QVBoxLayout layout; diff --git a/apps/volumeViewer/SliceWidget.cpp b/apps/volumeViewer/SliceWidget.cpp index 1db5f8e801..98538ba459 100644 --- a/apps/volumeViewer/SliceWidget.cpp +++ b/apps/volumeViewer/SliceWidget.cpp @@ -17,12 +17,12 @@ #include "SliceWidget.h" #include "SliceEditor.h" -SliceWidget::SliceWidget(SliceEditor *sliceEditor, ospray::box3f boundingBox) +SliceWidget::SliceWidget(SliceEditor *sliceEditor, ospcommon::box3f boundingBox) : boundingBox(boundingBox), originSliderAnimationDirection(1) { // Check parameters. - if(ospray::volume(boundingBox) <= 0.f) + if(ospcommon::volume(boundingBox) <= 0.f) throw std::runtime_error("invalid volume bounds"); // Setup UI elements. @@ -164,8 +164,8 @@ SliceParameters SliceWidget::getSliceParameters() SliceParameters sliceParameters; // Get the origin and normal values. - sliceParameters.origin = ospray::vec3f(float(originXSpinBox.value()), float(originYSpinBox.value()), float(originZSpinBox.value())); - sliceParameters.normal = ospray::vec3f(float(normalXSpinBox.value()), float(normalYSpinBox.value()), float(normalZSpinBox.value())); + sliceParameters.origin = ospcommon::vec3f(float(originXSpinBox.value()), float(originYSpinBox.value()), float(originZSpinBox.value())); + sliceParameters.normal = ospcommon::vec3f(float(normalXSpinBox.value()), float(normalYSpinBox.value()), float(normalZSpinBox.value())); return sliceParameters; } @@ -258,15 +258,15 @@ void SliceWidget::originSliderValueChanged(int value) { float sliderPosition = float(value) / float(originSlider.maximum() - originSlider.minimum()); // Get origin and (normalized) normal vectors. - ospray::vec3f origin(originXSpinBox.value(), originYSpinBox.value(), originZSpinBox.value()); - ospray::vec3f normal = normalize(ospray::vec3f(normalXSpinBox.value(), normalYSpinBox.value(), normalZSpinBox.value())); + ospcommon::vec3f origin(originXSpinBox.value(), originYSpinBox.value(), originZSpinBox.value()); + ospcommon::vec3f normal = normalize(ospcommon::vec3f(normalXSpinBox.value(), normalYSpinBox.value(), normalZSpinBox.value())); // Compute allowed range along normal for the volume bounds. - ospray::vec3f upper(normal.x >= 0.f ? boundingBox.upper.x : boundingBox.lower.x, + ospcommon::vec3f upper(normal.x >= 0.f ? boundingBox.upper.x : boundingBox.lower.x, normal.y >= 0.f ? boundingBox.upper.y : boundingBox.lower.y, normal.z >= 0.f ? boundingBox.upper.z : boundingBox.lower.z); - ospray::vec3f lower(normal.x >= 0.f ? boundingBox.lower.x : boundingBox.upper.x, + ospcommon::vec3f lower(normal.x >= 0.f ? boundingBox.lower.x : boundingBox.upper.x, normal.y >= 0.f ? boundingBox.lower.y : boundingBox.upper.y, normal.z >= 0.f ? boundingBox.lower.z : boundingBox.upper.z); @@ -281,7 +281,7 @@ void SliceWidget::originSliderValueChanged(int value) { t = std::max(std::min(t, tMax-epsilon), tMin+epsilon); // Compute updated origin, clamped within the volume bounds. - ospray::vec3f updatedOrigin = clamp(origin + t*normal, boundingBox.lower, boundingBox.upper); + ospcommon::vec3f updatedOrigin = clamp(origin + t*normal, boundingBox.lower, boundingBox.upper); // Finally, set the new origin value. originXSpinBox.setValue(updatedOrigin.x); diff --git a/apps/volumeViewer/SliceWidget.h b/apps/volumeViewer/SliceWidget.h index d636c898a9..1551a1c05e 100644 --- a/apps/volumeViewer/SliceWidget.h +++ b/apps/volumeViewer/SliceWidget.h @@ -17,13 +17,13 @@ #pragma once #include -#include "ospray/common/OSPCommon.h" +#include "common/box.h" #include struct SliceParameters { - ospray::vec3f origin; - ospray::vec3f normal; + ospcommon::vec3f origin; + ospcommon::vec3f normal; }; class SliceEditor; @@ -35,7 +35,7 @@ Q_OBJECT public: - SliceWidget(SliceEditor *sliceEditor, ospray::box3f boundingBox); + SliceWidget(SliceEditor *sliceEditor, ospcommon::box3f boundingBox); ~SliceWidget(); SliceParameters getSliceParameters(); @@ -60,7 +60,7 @@ protected slots: protected: //! Bounding box of the volume. - ospray::box3f boundingBox; + ospcommon::box3f boundingBox; //! UI elements. QDoubleSpinBox originXSpinBox; diff --git a/apps/volumeViewer/TransferFunctionEditor.cpp b/apps/volumeViewer/TransferFunctionEditor.cpp index cb13e57c66..bffa02c2ad 100644 --- a/apps/volumeViewer/TransferFunctionEditor.cpp +++ b/apps/volumeViewer/TransferFunctionEditor.cpp @@ -149,12 +149,12 @@ void TransferFunctionEditor::load(std::string filename) // Update transfer function state. Update values of the UI elements directly to signal appropriate slots. colorMapComboBox.setCurrentIndex(colorMapIndex); - setDataValueRange(ospray::vec2f(dataValueMin, dataValueMax), true); + setDataValueRange(ospcommon::vec2f(dataValueMin, dataValueMax), true); opacityValuesWidget.setPoints(points); opacityScalingSlider.setValue(opacityScalingIndex); } -void TransferFunctionEditor::setDataValueRange(ospray::vec2f dataValueRange, bool force) +void TransferFunctionEditor::setDataValueRange(ospcommon::vec2f dataValueRange, bool force) { // Only update widget values the first time. if(dataRangeSet && !force) @@ -232,7 +232,7 @@ void TransferFunctionEditor::save() void TransferFunctionEditor::setColorMapIndex(int index) { // Set transfer function color properties for this color map. - std::vector colors = colorMaps[index].getColors(); + std::vector colors = colorMaps[index].getColors(); OSPData colorsData = ospNewData(colors.size(), OSP_FLOAT3, colors.data()); ospSetData(transferFunction, "colors", colorsData); @@ -262,56 +262,56 @@ void TransferFunctionEditor::loadColorMaps() { // Color maps based on ParaView default color maps. - std::vector colors; + std::vector colors; // Jet. colors.clear(); - colors.push_back(ospray::vec3f(0 , 0 , 0.562493 )); - colors.push_back(ospray::vec3f(0 , 0 , 1 )); - colors.push_back(ospray::vec3f(0 , 1 , 1 )); - colors.push_back(ospray::vec3f(0.500008 , 1 , 0.500008 )); - colors.push_back(ospray::vec3f(1 , 1 , 0 )); - colors.push_back(ospray::vec3f(1 , 0 , 0 )); - colors.push_back(ospray::vec3f(0.500008 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 0.562493 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 1 )); + colors.push_back(ospcommon::vec3f(0 , 1 , 1 )); + colors.push_back(ospcommon::vec3f(0.500008 , 1 , 0.500008 )); + colors.push_back(ospcommon::vec3f(1 , 1 , 0 )); + colors.push_back(ospcommon::vec3f(1 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0.500008 , 0 , 0 )); colorMaps.push_back(ColorMap("Jet", colors)); // Ice / fire. colors.clear(); - colors.push_back(ospray::vec3f(0 , 0 , 0 )); - colors.push_back(ospray::vec3f(0 , 0.120394 , 0.302678 )); - colors.push_back(ospray::vec3f(0 , 0.216587 , 0.524575 )); - colors.push_back(ospray::vec3f(0.0552529 , 0.345022 , 0.659495 )); - colors.push_back(ospray::vec3f(0.128054 , 0.492592 , 0.720287 )); - colors.push_back(ospray::vec3f(0.188952 , 0.641306 , 0.792096 )); - colors.push_back(ospray::vec3f(0.327672 , 0.784939 , 0.873426 )); - colors.push_back(ospray::vec3f(0.60824 , 0.892164 , 0.935546 )); - colors.push_back(ospray::vec3f(0.881376 , 0.912184 , 0.818097 )); - colors.push_back(ospray::vec3f(0.9514 , 0.835615 , 0.449271 )); - colors.push_back(ospray::vec3f(0.904479 , 0.690486 , 0 )); - colors.push_back(ospray::vec3f(0.854063 , 0.510857 , 0 )); - colors.push_back(ospray::vec3f(0.777096 , 0.330175 , 0.000885023 )); - colors.push_back(ospray::vec3f(0.672862 , 0.139086 , 0.00270085 )); - colors.push_back(ospray::vec3f(0.508812 , 0 , 0 )); - colors.push_back(ospray::vec3f(0.299413 , 0.000366217 , 0.000549325 )); - colors.push_back(ospray::vec3f(0.0157473 , 0.00332647 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0.120394 , 0.302678 )); + colors.push_back(ospcommon::vec3f(0 , 0.216587 , 0.524575 )); + colors.push_back(ospcommon::vec3f(0.0552529 , 0.345022 , 0.659495 )); + colors.push_back(ospcommon::vec3f(0.128054 , 0.492592 , 0.720287 )); + colors.push_back(ospcommon::vec3f(0.188952 , 0.641306 , 0.792096 )); + colors.push_back(ospcommon::vec3f(0.327672 , 0.784939 , 0.873426 )); + colors.push_back(ospcommon::vec3f(0.60824 , 0.892164 , 0.935546 )); + colors.push_back(ospcommon::vec3f(0.881376 , 0.912184 , 0.818097 )); + colors.push_back(ospcommon::vec3f(0.9514 , 0.835615 , 0.449271 )); + colors.push_back(ospcommon::vec3f(0.904479 , 0.690486 , 0 )); + colors.push_back(ospcommon::vec3f(0.854063 , 0.510857 , 0 )); + colors.push_back(ospcommon::vec3f(0.777096 , 0.330175 , 0.000885023 )); + colors.push_back(ospcommon::vec3f(0.672862 , 0.139086 , 0.00270085 )); + colors.push_back(ospcommon::vec3f(0.508812 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0.299413 , 0.000366217 , 0.000549325 )); + colors.push_back(ospcommon::vec3f(0.0157473 , 0.00332647 , 0 )); colorMaps.push_back(ColorMap("Ice / Fire", colors)); // Cool to warm. colors.clear(); - colors.push_back(ospray::vec3f(0.231373 , 0.298039 , 0.752941 )); - colors.push_back(ospray::vec3f(0.865003 , 0.865003 , 0.865003 )); - colors.push_back(ospray::vec3f(0.705882 , 0.0156863 , 0.14902 )); + colors.push_back(ospcommon::vec3f(0.231373 , 0.298039 , 0.752941 )); + colors.push_back(ospcommon::vec3f(0.865003 , 0.865003 , 0.865003 )); + colors.push_back(ospcommon::vec3f(0.705882 , 0.0156863 , 0.14902 )); colorMaps.push_back(ColorMap("Cool to Warm", colors)); // Blue to red rainbow. colors.clear(); - colors.push_back(ospray::vec3f(0 , 0 , 1 )); - colors.push_back(ospray::vec3f(1 , 0 , 0 )); + colors.push_back(ospcommon::vec3f(0 , 0 , 1 )); + colors.push_back(ospcommon::vec3f(1 , 0 , 0 )); colorMaps.push_back(ColorMap("Blue to Red Rainbow", colors)); // Grayscale. colors.clear(); - colors.push_back(ospray::vec3f(0.)); - colors.push_back(ospray::vec3f(1.)); + colors.push_back(ospcommon::vec3f(0.)); + colors.push_back(ospcommon::vec3f(1.)); colorMaps.push_back(ColorMap("Grayscale", colors)); } diff --git a/apps/volumeViewer/TransferFunctionEditor.h b/apps/volumeViewer/TransferFunctionEditor.h index 45d9f93763..145e52b7f5 100644 --- a/apps/volumeViewer/TransferFunctionEditor.h +++ b/apps/volumeViewer/TransferFunctionEditor.h @@ -41,7 +41,7 @@ public slots: void load(std::string filename = std::string()); //! Set the data value range for the transfer function editor. - void setDataValueRange(ospray::vec2f dataValueRange, bool force=false); + void setDataValueRange(ospcommon::vec2f dataValueRange, bool force=false); //! Slot called to update transfer function opacity values based on widget values. void updateOpacityValues(); diff --git a/apps/volumeViewer/VolumeViewer.cpp b/apps/volumeViewer/VolumeViewer.cpp index 2b13cff80c..a04c3a7cce 100644 --- a/apps/volumeViewer/VolumeViewer.cpp +++ b/apps/volumeViewer/VolumeViewer.cpp @@ -14,9 +14,9 @@ // limitations under the License. // // ======================================================================== // -#include "ospray/common/OSPCommon.h" -#include "VolumeViewer.h" #include +// own +#include "VolumeViewer.h" #include "modules/loaders/ObjectFile.h" #include "modules/loaders/TriangleMeshFile.h" #include "TransferFunctionEditor.h" @@ -40,7 +40,7 @@ VolumeViewer::VolumeViewer(const std::vector &objectFileFilenames, : objectFileFilenames(objectFileFilenames), modelIndex(0), ownModelPerObject(ownModelPerObject), - boundingBox(ospray::vec3f(0.f), ospray::vec3f(1.f)), + boundingBox(ospcommon::vec3f(0.f), ospcommon::vec3f(1.f)), renderer(NULL), rendererInitialized(false), transferFunction(NULL), @@ -77,7 +77,7 @@ VolumeViewer::VolumeViewer(const std::vector &objectFileFilenames, show(); } -ospray::box3f VolumeViewer::getBoundingBox() +ospcommon::box3f VolumeViewer::getBoundingBox() { return boundingBox; } @@ -102,7 +102,7 @@ void VolumeViewer::setModel(size_t index) rendererInitialized = true; // Update transfer function and isosurface editor data value range with the voxel range of the current model's first volume. - ospray::vec2f voxelRange(0.f); + ospcommon::vec2f voxelRange(0.f); OSPVolume volume = modelStates[index].volumes[0]; #ifdef OSPRAY_VOLUME_VOXELRANGE_IN_APP voxelRange = VolumeFile::voxelRangeOf[volume]; @@ -110,7 +110,7 @@ void VolumeViewer::setModel(size_t index) ospGetVec2f(modelStates[index].volumes[0], "voxelRange", (osp::vec2f*)&voxelRange); #endif - if(voxelRange != ospray::vec2f(0.f)) { + if(voxelRange != ospcommon::vec2f(0.f)) { transferFunctionEditor->setDataValueRange(voxelRange); isosurfaceEditor->setDataValueRange(voxelRange); } @@ -210,7 +210,7 @@ void VolumeViewer::addGeometry(std::string filename) ospAddGeometry(modelInstance, triangleMesh); ospCommit(modelInstance); - ospray::affine3f xfm = embree::one; + ospcommon::affine3f xfm = ospcommon::one; OSPGeometry triangleMeshInstance = ospNewInstance(modelInstance, (osp::affine3f&)xfm); ospCommit(triangleMeshInstance); @@ -310,7 +310,7 @@ void VolumeViewer::setSamplingRate(double value) render(); } -void VolumeViewer::setVolumeClippingBox(ospray::box3f value) +void VolumeViewer::setVolumeClippingBox(ospcommon::box3f value) { for(size_t i=0; i sliceParameters) { // Provide the slices to OSPRay as the coefficients (a,b,c,d) of the plane equation ax + by + cz + d = 0. - std::vector planes; + std::vector planes; for(size_t i=0; i @@ -55,7 +55,7 @@ Q_OBJECT std::string writeFramesFilename); //! Get the volume bounding box. - ospray::box3f getBoundingBox(); + ospcommon::box3f getBoundingBox(); //! Get the OSPRay output window. QOSPRayWindow *getWindow(); @@ -111,7 +111,7 @@ public slots: void setSamplingRate(double value); //! Set volume clipping box on all volumes. - void setVolumeClippingBox(ospray::box3f value); + void setVolumeClippingBox(ospcommon::box3f value); //! Set slices on all volumes. void setSlices(std::vector sliceParameters); @@ -132,7 +132,7 @@ public slots: size_t modelIndex; //! Bounding box of the (first) volume. - ospray::box3f boundingBox; + ospcommon::box3f boundingBox; //! OSPRay renderer. OSPRenderer renderer; diff --git a/apps/volumeViewer/main.cpp b/apps/volumeViewer/main.cpp index 718b1d6db7..04087ceb54 100644 --- a/apps/volumeViewer/main.cpp +++ b/apps/volumeViewer/main.cpp @@ -14,14 +14,17 @@ // limitations under the License. // // ======================================================================== // +// own #include "VolumeViewer.h" +#include "TransferFunctionEditor.h" +// ospray public +#include "ospray/ospray.h" +// std #include -#include #include #include -#include "VolumeViewer.h" -#include "TransferFunctionEditor.h" -#include "ospray/include/ospray/ospray.h" +// qt +#include int main(int argc, char *argv[]) { @@ -73,8 +76,8 @@ int main(int argc, char *argv[]) int benchmarkFrames = 0; int viewSizeWidth = 0; int viewSizeHeight = 0; - ospray::vec3f viewUp(0.f); - ospray::vec3f viewAt(0.f), viewFrom(0.f); + ospcommon::vec3f viewUp(0.f); + ospcommon::vec3f viewAt(0.f), viewFrom(0.f); bool showFrameRate = false; bool fullScreen = false; bool ownModelPerObject = false; @@ -260,7 +263,7 @@ int main(int argc, char *argv[]) // Set the view up vector if specified. - if(viewUp != ospray::vec3f(0.f)) { + if(viewUp != ospcommon::vec3f(0.f)) { volumeViewer->getWindow()->getViewport()->setUp(viewUp); volumeViewer->getWindow()->resetAccumulationBuffer(); } diff --git a/common/box.h b/common/box.h index 3ed65e271e..ff8897b47c 100644 --- a/common/box.h +++ b/common/box.h @@ -45,6 +45,11 @@ namespace ospcommon { template inline scalar_t area(const box_t &b) { return b.size().product(); } + /*! return the volume of the 3D box - undefined for empty boxes */ + template + inline scalar_t volume(const box_t &b) { return b.size().product(); } + + /*! compute the intersection of two boxes */ template inline box_t intersectionOf(const box_t &a, const box_t &b) diff --git a/common/malloc.cpp b/common/malloc.cpp new file mode 100644 index 0000000000..32e766b648 --- /dev/null +++ b/common/malloc.cpp @@ -0,0 +1,191 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "malloc.h" +#include "intrinsics.h" +#if defined(TASKING_TBB) +# define __TBB_NO_IMPLICIT_LINKAGE 1 +# include "tbb/scalable_allocator.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Windows Platform +//////////////////////////////////////////////////////////////////////////////// + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include +#include + +namespace embree +{ + void* os_malloc(size_t bytes, const int additional_flags) + { + int flags = MEM_COMMIT|MEM_RESERVE|additional_flags; + char* ptr = (char*) VirtualAlloc(NULL,bytes,flags,PAGE_READWRITE); + if (ptr == NULL) throw std::bad_alloc(); + return ptr; + } + + void* os_reserve(size_t bytes) + { + char* ptr = (char*) VirtualAlloc(NULL,bytes,MEM_RESERVE,PAGE_READWRITE); + if (ptr == NULL) throw std::bad_alloc(); + return ptr; + } + + void os_commit (void* ptr, size_t bytes) { + VirtualAlloc(ptr,bytes,MEM_COMMIT,PAGE_READWRITE); + } + + size_t os_shrink(void* ptr, size_t bytesNew, size_t bytesOld) + { + size_t pageSize = 4096; + bytesNew = (bytesNew+pageSize-1) & ~(pageSize-1); + assert(bytesNew <= bytesOld); + if (bytesNew < bytesOld) + VirtualFree((char*)ptr+bytesNew,bytesOld-bytesNew,MEM_DECOMMIT); + return bytesNew; + } + + void os_free(void* ptr, size_t bytes) { + if (bytes == 0) return; + VirtualFree(ptr,0,MEM_RELEASE); + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Unix Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__UNIX__) + +#include +#include +#include +#include + +#if defined(__MIC__) +#define USE_HUGE_PAGES 1 +#else +#define USE_HUGE_PAGES 0 +#endif + +namespace ospcommon +{ + void* os_malloc(size_t bytes, const int additional_flags) + { + int flags = MAP_PRIVATE | MAP_ANON | additional_flags; +#if USE_HUGE_PAGES + if (bytes > 16*4096) { + flags |= MAP_HUGETLB; + bytes = (bytes+2*1024*1024-1)&ssize_t(-2*1024*1024); + } else { + bytes = (bytes+4095)&ssize_t(-4096); + } +#endif +#if __MIC__ + flags |= MAP_POPULATE; +#endif + char* ptr = (char*) mmap(0, bytes, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == NULL || ptr == MAP_FAILED) throw std::bad_alloc(); + return ptr; + } + + void* os_reserve(size_t bytes) + { + int flags = MAP_PRIVATE | MAP_ANON | MAP_NORESERVE; +#if USE_HUGE_PAGES + if (bytes > 16*4096) { + flags |= MAP_HUGETLB; + bytes = (bytes+2*1024*1024-1)&ssize_t(-2*1024*1024); + } else { + bytes = (bytes+4095)&ssize_t(-4096); + } +#endif +#if __MIC__ + flags |= MAP_POPULATE; +#endif + + char* ptr = (char*) mmap(0, bytes, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == NULL || ptr == MAP_FAILED) throw std::bad_alloc(); + return ptr; + } + + void os_commit (void* ptr, size_t bytes) { + } + + size_t os_shrink(void* ptr, size_t bytesNew, size_t bytesOld) + { + size_t pageSize = 4096; +#if USE_HUGE_PAGES + if (bytesOld > 16*4096) pageSize = 2*1024*1024; +#endif + bytesNew = (bytesNew+pageSize-1) & ~(pageSize-1); + assert(bytesNew <= bytesOld); + if (bytesNew < bytesOld) + if (munmap((char*)ptr+bytesNew,bytesOld-bytesNew) == -1) + throw std::bad_alloc(); + + return bytesNew; + } + + void os_free(void* ptr, size_t bytes) + { + if (bytes == 0) + return; + +#if USE_HUGE_PAGES + if (bytes > 16*4096) { + bytes = (bytes+2*1024*1024-1)&ssize_t(-2*1024*1024); + } else { + bytes = (bytes+4095)&ssize_t(-4096); + } +#endif + if (munmap(ptr,bytes) == -1) + throw std::bad_alloc(); + } +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// All Platforms +//////////////////////////////////////////////////////////////////////////////// + +namespace ospcommon +{ + void* alignedMalloc(size_t size, size_t align) + { + assert((align & (align-1)) == 0); +//#if defined(TASKING_TBB) // FIXME: have to disable this for now as the TBB allocator itself seems to access some uninitialized value when using valgrind +// return scalable_aligned_malloc(size,align); +//#else + return _mm_malloc(size,align); +//#endif + } + + void alignedFree(void* ptr) + { +//#if defined(TASKING_TBB) +// scalable_aligned_free(ptr); +//#else + _mm_free(ptr); +//#endif + } +} diff --git a/common/vec.h b/common/vec.h index d3d6190e4f..b15744949d 100644 --- a/common/vec.h +++ b/common/vec.h @@ -156,6 +156,7 @@ namespace ospcommon { { return vec_t(op(v.x),op(v.y),op(v.z),op(v.w)); }\ unary_functor(rcp); + unary_functor(abs); unary_functor(sin); unary_functor(cos); #undef unary_functor diff --git a/modules/loaders/CMakeLists.txt b/modules/loaders/CMakeLists.txt index ade108cb59..ea30802c81 100644 --- a/modules/loaders/CMakeLists.txt +++ b/modules/loaders/CMakeLists.txt @@ -38,7 +38,10 @@ IF (NOT THIS_IS_MIC) VolumeFile.cpp ) - TARGET_LINK_LIBRARIES(ospray_module_loaders${OSPRAY_LIB_SUFFIX} ospray${OSPRAY_LIB_SUFFIX}) + TARGET_LINK_LIBRARIES(ospray_module_loaders${OSPRAY_LIB_SUFFIX} + ospray${OSPRAY_LIB_SUFFIX} + ospray_ospcommon${OSPRAY_LIB_SUFFIX} + ) SET_TARGET_PROPERTIES(ospray_module_loaders${OSPRAY_LIB_SUFFIX} PROPERTIES VERSION ${OSPRAY_VERSION} SOVERSION ${OSPRAY_SOVERSION}) diff --git a/modules/loaders/OSPObjectFile.cpp b/modules/loaders/OSPObjectFile.cpp index f2aa15a008..75445f528b 100644 --- a/modules/loaders/OSPObjectFile.cpp +++ b/modules/loaders/OSPObjectFile.cpp @@ -14,13 +14,16 @@ // limitations under the License. // // ======================================================================== // -#include "ospray/common/OSPCommon.h" +// our own +#include "OSPObjectFile.h" +#include "TriangleMeshFile.h" +#include "VolumeFile.h" +// ospcommon +#include "common/common.h" +// std #include #include #include -#include "modules/loaders/OSPObjectFile.h" -#include "modules/loaders/TriangleMeshFile.h" -#include "modules/loaders/VolumeFile.h" OSPObject *OSPObjectFile::importObjects() { diff --git a/modules/loaders/ObjectFile.cpp b/modules/loaders/ObjectFile.cpp index 05980aeccd..9402d748e1 100644 --- a/modules/loaders/ObjectFile.cpp +++ b/modules/loaders/ObjectFile.cpp @@ -15,8 +15,8 @@ // ======================================================================== // #include -#include "ospray/common/Library.h" -#include "modules/loaders/ObjectFile.h" +#include "common/common.h" +#include "ObjectFile.h" OSPObject *ObjectFile::importObjects(const std::string &filename) { @@ -40,7 +40,7 @@ OSPObject *ObjectFile::importObjects(const std::string &filename) std::string creationFunctionName = "ospray_import_object_file_" + std::string(type); // Look for the named function. - symbolRegistry[type] = (creationFunctionPointer) ospray::getSymbol(creationFunctionName); + symbolRegistry[type] = (creationFunctionPointer) ospcommon::getSymbol(creationFunctionName); // The named function may not be found if the requested subtype is not known. if (!symbolRegistry[type]) std::cerr << " ospray_module_loaders::ObjectFile WARNING: unrecognized file type '" + type + "'." << std::endl; diff --git a/modules/loaders/ObjectFile.h b/modules/loaders/ObjectFile.h index 28f12cab7b..126c87835b 100644 --- a/modules/loaders/ObjectFile.h +++ b/modules/loaders/ObjectFile.h @@ -18,7 +18,7 @@ #include #include -#include "ospray/include/ospray/ospray.h" +#include "ospray/ospray.h" //! \brief Define a function to create an instance of the InternalClass //! associated with ExternalName. diff --git a/modules/loaders/PLYTriangleMeshFile.cpp b/modules/loaders/PLYTriangleMeshFile.cpp index 2943f3c58e..3dfca58b7b 100644 --- a/modules/loaders/PLYTriangleMeshFile.cpp +++ b/modules/loaders/PLYTriangleMeshFile.cpp @@ -29,7 +29,7 @@ bool startsWith(const std::string &haystack, const std::string &needle) PLYTriangleMeshFile::PLYTriangleMeshFile(const std::string &filename) : filename(filename), - scale(ospray::vec3f(1.f)), + scale(ospcommon::vec3f(1.f)), verbose(true) { } @@ -181,16 +181,16 @@ bool PLYTriangleMeshFile::parse() } // Add to vertices vector with scaling applied. - vertices.push_back(scale * ospray::vec3fa(vertexProperties[xIndex], vertexProperties[yIndex], vertexProperties[zIndex])); + vertices.push_back(scale * ospcommon::vec3fa(vertexProperties[xIndex], vertexProperties[yIndex], vertexProperties[zIndex])); // Vertex normals will be computed later. - vertexNormals.push_back(ospray::vec3fa(0.f)); + vertexNormals.push_back(ospcommon::vec3fa(0.f)); // Use vertex colors if we have them; otherwise default to white (note that the volume renderer currently requires a color for every vertex). if(haveVertexColors) - vertexColors.push_back(1.f/255.f * ospray::vec4f(vertexProperties[rIndex], vertexProperties[gIndex], vertexProperties[bIndex], vertexProperties[aIndex])); + vertexColors.push_back(1.f/255.f * ospcommon::vec4f(vertexProperties[rIndex], vertexProperties[gIndex], vertexProperties[bIndex], vertexProperties[aIndex])); else - vertexColors.push_back(ospray::vec4f(1.f)); + vertexColors.push_back(ospcommon::vec4f(1.f)); } // Read the face data. @@ -200,14 +200,14 @@ bool PLYTriangleMeshFile::parse() in >> count; exitOnCondition(count != 3, "only triangle faces are supported."); - ospray::vec3i triangle; + ospcommon::vec3i triangle; in >> triangle.x >> triangle.y >> triangle.z; exitOnCondition(!in.good(), "error reading face data."); triangles.push_back(triangle); // Add vertex normal contributions. - ospray::vec3fa triangleNormal = cross(vertices[triangle.y] - vertices[triangle.x], vertices[triangle.z] - vertices[triangle.x]); + ospcommon::vec3fa triangleNormal = cross(vertices[triangle.y] - vertices[triangle.x], vertices[triangle.z] - vertices[triangle.x]); vertexNormals[triangle.x] += triangleNormal; vertexNormals[triangle.y] += triangleNormal; vertexNormals[triangle.z] += triangleNormal; diff --git a/modules/loaders/PLYTriangleMeshFile.h b/modules/loaders/PLYTriangleMeshFile.h index 818e2bdaef..65ee6299b8 100644 --- a/modules/loaders/PLYTriangleMeshFile.h +++ b/modules/loaders/PLYTriangleMeshFile.h @@ -16,9 +16,13 @@ #pragma once -#include "ospray/common/OSPCommon.h" +// ospcommon +#include "common/vec.h" +// std #include -#include "modules/loaders/TriangleMeshFile.h" +#include +// own +#include "TriangleMeshFile.h" //! \brief A concrete implementation of the TriangleMeshFile class //! for reading triangle data stored in the PLY file format on disk. @@ -44,22 +48,22 @@ class PLYTriangleMeshFile : public TriangleMeshFile { std::string filename; //! Scaling for vertex coordinates. - ospray::vec3f scale; + ospcommon::vec3f scale; //! Verbose logging. bool verbose; //! Vertices. - std::vector vertices; + std::vector vertices; //! Vertex colors. - std::vector vertexColors; + std::vector vertexColors; //! Vertex normals. - std::vector vertexNormals; + std::vector vertexNormals; //! Triangle definitions. - std::vector triangles; + std::vector triangles; //! Parse the file, determining the vertices, vertex colors, and triangles. bool parse(); diff --git a/modules/loaders/RMVolumeFile.cpp b/modules/loaders/RMVolumeFile.cpp index cac58a3fb7..df736a8ce3 100644 --- a/modules/loaders/RMVolumeFile.cpp +++ b/modules/loaders/RMVolumeFile.cpp @@ -17,18 +17,18 @@ #include #include #include "modules/loaders/RMVolumeFile.h" -#include "ospray/common/OSPCommon.h" -#include "common/sys/sysinfo.h" -#include "common/sys/thread.h" #ifdef __LINUX__ # include #endif +// std:: #include - +#include +// ospcommon +#include "common/sysinfo.h" struct RMLoaderThreads { OSPVolume volume; - embree::MutexSys mutex; + std::mutex mutex; int nextBlockID; int nextPinID; int numThreads; @@ -36,7 +36,7 @@ struct RMLoaderThreads { pthread_t *thread; std::string inFilesDir; bool useGZip; - ospray::vec2f voxelRange; + ospcommon::vec2f voxelRange; struct Block { uint8_t voxel[256*256*128]; }; @@ -112,7 +112,7 @@ struct RMLoaderThreads { { mutex.lock(); int threadID = nextPinID++; - embree::setAffinity(threadID); + // embree::setAffinity(threadID); mutex.unlock(); Block *block = new Block; @@ -140,12 +140,12 @@ struct RMLoaderThreads { for (int i=0;i<5;i++) printf("[%i]",block->voxel[i]); #endif - ospray::vec3i region_lo(I*256,J*256,K*128); - ospray::vec3i region_sz(256,256,128); + ospcommon::vec3i region_lo(I*256,J*256,K*128); + ospcommon::vec3i region_sz(256,256,128); ospSetRegion(volume,block->voxel,(osp::vec3i&)region_lo,(osp::vec3i&)region_sz); mutex.unlock(); - ospray::vec2f blockRange(block->voxel[0]); + ospcommon::vec2f blockRange(block->voxel[0]); extendVoxelRange(blockRange,&block->voxel[0],256*256*128); #ifdef OSPRAY_VOLUME_VOXELRANGE_IN_APP @@ -166,21 +166,21 @@ struct RMLoaderThreads { OSPVolume RMVolumeFile::importVolume(OSPVolume volume) { // Update the provided dimensions of the volume for the subvolume specified. - ospray::vec3i dims(2048,2048,1920); + ospcommon::vec3i dims(2048,2048,1920); ospSetVec3i(volume, "dimensions", (osp::vec3i&)dims); ospSetString(volume,"voxelType", "uchar"); #ifdef __LINUX__ - int numThreads = embree::getNumberOfLogicalThreads(); //20; + int numThreads = ospcommon::getNumberOfLogicalThreads(); //20; #else int numThreads = 1; #endif - double t0 = ospray::getSysTime(); + double t0 = ospcommon::getSysTime(); RMLoaderThreads(volume,fileName,numThreads); - double t1 = ospray::getSysTime(); + double t1 = ospcommon::getSysTime(); std::cout << "done loading " << fileName << ", needed " << (t1-t0) << " seconds" << std::endl; diff --git a/modules/loaders/RMVolumeFile.h b/modules/loaders/RMVolumeFile.h index 993fcbe995..32f9d48f49 100644 --- a/modules/loaders/RMVolumeFile.h +++ b/modules/loaders/RMVolumeFile.h @@ -17,7 +17,7 @@ #pragma once #include -#include "modules/loaders/VolumeFile.h" +#include "VolumeFile.h" //! \brief specific importer for the LLNL "RM" (Richtmyer-Meshkov) instability files /*! Note this exists only for a specific demo */ diff --git a/modules/loaders/RawVolumeFile.cpp b/modules/loaders/RawVolumeFile.cpp index ce695a12ba..b19d8a1c9c 100644 --- a/modules/loaders/RawVolumeFile.cpp +++ b/modules/loaders/RawVolumeFile.cpp @@ -41,7 +41,7 @@ OSPVolume RawVolumeFile::importVolume(OSPVolume volume) ospGeti(volume, "filename offset", &offset); fseek(file, offset, SEEK_SET); // Volume dimensions. - ospray::vec3i volumeDimensions; + ospcommon::vec3i volumeDimensions; exitOnCondition(!ospGetVec3i(volume, "dimensions", &(osp::vec3i&)volumeDimensions), @@ -68,20 +68,20 @@ OSPVolume RawVolumeFile::importVolume(OSPVolume volume) // Subvolume params: subvolumeOffsets, subvolumeDimensions, subvolumeSteps. // The subvolume defaults to full dimensions (allowing for just subsampling, // for example). - ospray::vec3i subvolumeOffsets = ospray::vec3i(0); + ospcommon::vec3i subvolumeOffsets = ospcommon::vec3i(0); ospGetVec3i(volume, "subvolumeOffsets", (osp::vec3i*)&subvolumeOffsets); exitOnCondition(reduce_min(subvolumeOffsets) < 0 || reduce_max(subvolumeOffsets - volumeDimensions) >= 0, "invalid subvolume offsets"); - ospray::vec3i subvolumeDimensions = volumeDimensions - subvolumeOffsets; + ospcommon::vec3i subvolumeDimensions = volumeDimensions - subvolumeOffsets; ospGetVec3i(volume, "subvolumeDimensions", (osp::vec3i*)&subvolumeDimensions); exitOnCondition(reduce_min(subvolumeDimensions) < 1 || reduce_max(subvolumeDimensions - (volumeDimensions - subvolumeOffsets)) > 0, "invalid subvolume dimension(s) specified"); - ospray::vec3i subvolumeSteps = ospray::vec3i(1); + ospcommon::vec3i subvolumeSteps = ospcommon::vec3i(1); ospGetVec3i(volume, "subvolumeSteps", (osp::vec3i*)&subvolumeSteps); exitOnCondition(reduce_min(subvolumeSteps) < 1 || reduce_max(subvolumeSteps - @@ -92,7 +92,7 @@ OSPVolume RawVolumeFile::importVolume(OSPVolume volume) // The dimensions of the volume to be imported; this will be changed if a // subvolume is specified. - ospray::vec3i importVolumeDimensions = volumeDimensions; + ospcommon::vec3i importVolumeDimensions = volumeDimensions; if (reduce_max(subvolumeOffsets) > 0 || subvolumeDimensions != volumeDimensions || @@ -108,7 +108,7 @@ OSPVolume RawVolumeFile::importVolume(OSPVolume volume) (subvolumeDimensions.y % subvolumeSteps.y != 0); int zdim = subvolumeDimensions.z / subvolumeSteps.z + (subvolumeDimensions.z % subvolumeSteps.z != 0); - importVolumeDimensions = ospray::vec3i(xdim, ydim, zdim); + importVolumeDimensions = ospcommon::vec3i(xdim, ydim, zdim); // Range check. exitOnCondition(reduce_min(importVolumeDimensions) <= 0, @@ -119,7 +119,7 @@ OSPVolume RawVolumeFile::importVolume(OSPVolume volume) } #ifdef OSPRAY_VOLUME_VOXELRANGE_IN_APP -ospray::vec2f voxelRange(+std::numeric_limits::infinity(), +ospcommon::vec2f voxelRange(+std::numeric_limits::infinity(), -std::numeric_limits::infinity()); #endif @@ -172,8 +172,8 @@ ospray::vec2f voxelRange(+std::numeric_limits::infinity(), #endif - ospray::vec3i region_lo(0, 0, z); - ospray::vec3i region_sz(volumeDimensions.x, + ospcommon::vec3i region_lo(0, 0, z); + ospcommon::vec3i region_sz(volumeDimensions.x, volumeDimensions.y, slicesToRead); // Copy the voxels into the volume. @@ -237,10 +237,10 @@ ospray::vec2f voxelRange(+std::numeric_limits::infinity(), } // Copy subvolume row into the volume. - ospray::vec3i region_lo(0, + ospcommon::vec3i region_lo(0, (i2 - subvolumeOffsets.y) / subvolumeSteps.y, (i3 - subvolumeOffsets.z) / subvolumeSteps.z); - ospray::vec3i region_sz(importVolumeDimensions.x, 1, 1); + ospcommon::vec3i region_sz(importVolumeDimensions.x, 1, 1); ospSetRegion(volume, &subvolumeRowData[0], (osp::vec3i&)region_lo, diff --git a/modules/loaders/RawVolumeFile.h b/modules/loaders/RawVolumeFile.h index cb9c908cce..969c3c35f2 100644 --- a/modules/loaders/RawVolumeFile.h +++ b/modules/loaders/RawVolumeFile.h @@ -16,9 +16,10 @@ #pragma once -#include "ospray/common/OSPCommon.h" +// own +#include "VolumeFile.h" +// std #include -#include "modules/loaders/VolumeFile.h" //! \brief A concrete implementation of the VolumeFile class for reading //! voxel data stored in a file on disk as a single monolithic brick, diff --git a/modules/loaders/TriangleMeshFile.cpp b/modules/loaders/TriangleMeshFile.cpp index 2a9d79c8fa..7175cf748a 100644 --- a/modules/loaders/TriangleMeshFile.cpp +++ b/modules/loaders/TriangleMeshFile.cpp @@ -14,9 +14,9 @@ // limitations under the License. // // ======================================================================== // +#include "TriangleMeshFile.h" #include -#include "ospray/common/Library.h" -#include "modules/loaders/TriangleMeshFile.h" +#include "common/common.h" OSPGeometry TriangleMeshFile::importTriangleMesh(const std::string &filename, OSPGeometry triangleMesh) @@ -41,7 +41,7 @@ OSPGeometry TriangleMeshFile::importTriangleMesh(const std::string &filename, std::string creationFunctionName = "ospray_import_trianglemesh_file_" + std::string(type); // Look for the named function. - symbolRegistry[type] = (creationFunctionPointer) ospray::getSymbol(creationFunctionName); + symbolRegistry[type] = (creationFunctionPointer) ospcommon::getSymbol(creationFunctionName); // The named function may not be found if the requested subtype is not known. if (!symbolRegistry[type]) std::cerr << " ospray_module_loaders::TriangleMeshFile WARNING: unrecognized file type '" + type + "'." << std::endl; diff --git a/modules/loaders/VolumeFile.cpp b/modules/loaders/VolumeFile.cpp index e703e6096d..0acfc93c87 100644 --- a/modules/loaders/VolumeFile.cpp +++ b/modules/loaders/VolumeFile.cpp @@ -14,9 +14,8 @@ // limitations under the License. // // ======================================================================== // -#include -#include "ospray/common/Library.h" #include "modules/loaders/VolumeFile.h" +#include OSPVolume VolumeFile::importVolume(const std::string &filename, OSPVolume volume) { @@ -40,7 +39,7 @@ OSPVolume VolumeFile::importVolume(const std::string &filename, OSPVolume volume std::string creationFunctionName = "ospray_import_volume_file_" + std::string(type); // Look for the named function. - symbolRegistry[type] = (creationFunctionPointer) ospray::getSymbol(creationFunctionName); + symbolRegistry[type] = (creationFunctionPointer) ospcommon::getSymbol(creationFunctionName); // The named function may not be found of the requested subtype is not known. if (!symbolRegistry[type]) std::cerr << " ospray_module_loaders::VolumeFile WARNING: unrecognized file type '" + type + "'." << std::endl; @@ -50,6 +49,6 @@ OSPVolume VolumeFile::importVolume(const std::string &filename, OSPVolume volume } #ifdef OSPRAY_VOLUME_VOXELRANGE_IN_APP -std::map VolumeFile::voxelRangeOf; +std::map VolumeFile::voxelRangeOf; #endif diff --git a/modules/loaders/VolumeFile.h b/modules/loaders/VolumeFile.h index 8a4f5baf64..cf9b71cc27 100644 --- a/modules/loaders/VolumeFile.h +++ b/modules/loaders/VolumeFile.h @@ -16,12 +16,17 @@ #pragma once +// ospcommon +#include "common/common.h" +#include "common/vec.h" +// ospray public +#include "ospray/include/ospray/ospray.h" +// std #include #include -#include "ospray/include/ospray/ospray.h" -#include "ospray/common/OSPCommon.h" //stl #include +#include //! \brief Define a function to create an instance of the InternalClass //! associated with ExternalName. @@ -38,7 +43,7 @@ /*! helper function to help build voxel ranges during parsing */ template -inline void extendVoxelRange(ospray::vec2f &voxelRange, const T *voxel, size_t num) +inline void extendVoxelRange(ospcommon::vec2f &voxelRange, const T *voxel, size_t num) { for (size_t i=0;i voxelRangeOf; + static std::map voxelRangeOf; #endif //! Print an error message. diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 2efc1b0e76..69f577f11f 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -18,6 +18,7 @@ # on which target we build for ) CONFIGURE_OSPRAY() + IF(OSPRAY_BUILD_MPI_DEVICE) OPTION(OSPRAY_EXP_DATA_PARALLEL "Experimental data-parallel compositing mode") OPTION(OSPRAY_PIN_ASYNC "Pin async mpi comm threads?" OFF) @@ -311,6 +312,7 @@ ENDIF() ############################################################## OSPRAY_ADD_LIBRARY(ospray${OSPRAY_LIB_SUFFIX} SHARED ${OSPRAY_SOURCES}) +SET_TARGET_PROPERTIES(ospray PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_OSPCOMMON_H=1") TARGET_LINK_LIBRARIES(ospray${OSPRAY_LIB_SUFFIX} ${CMAKE_THREAD_LIBS_INIT} diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index f656a4dd98..2969d3e34b 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -261,3 +261,7 @@ namespace ospray { #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif #define NOTIMPLEMENTED throw std::runtime_error(std::string(__PRETTY_FUNCTION__)+": not implemented..."); + +#ifndef DONT_WARN_INCLUDE_OSPCOMMON_H +# error "warning: including OSPCommon.h from outside of ospray/ directory!" +#endif From 03584e3a8b53988b168f5baf2b057b75b3254f04 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 12:33:15 -0600 Subject: [PATCH 022/310] - moved loaders from module to volumeviewer - it's only part of volumeviewer, anyway - found one or two more usages of internal embree files --- apps/volumeViewer/CMakeLists.txt | 1 + apps/volumeViewer/VolumeViewer.cpp | 4 ++-- {modules => apps/volumeViewer}/loaders/CMakeLists.txt | 0 .../volumeViewer}/loaders/OSPObjectFile.cpp | 0 {modules => apps/volumeViewer}/loaders/OSPObjectFile.h | 6 +++--- {modules => apps/volumeViewer}/loaders/ObjectFile.cpp | 0 {modules => apps/volumeViewer}/loaders/ObjectFile.h | 0 .../volumeViewer}/loaders/PLYTriangleMeshFile.cpp | 0 .../volumeViewer}/loaders/PLYTriangleMeshFile.h | 0 {modules => apps/volumeViewer}/loaders/README.txt | 0 .../volumeViewer}/loaders/RMVolumeFile.cpp | 8 ++++---- {modules => apps/volumeViewer}/loaders/RMVolumeFile.h | 0 .../volumeViewer}/loaders/RawVolumeFile.cpp | 10 ++++++---- {modules => apps/volumeViewer}/loaders/RawVolumeFile.h | 0 .../volumeViewer}/loaders/SymbolRegistry.cpp | 8 ++++---- {modules => apps/volumeViewer}/loaders/TinyXML2.cpp | 0 {modules => apps/volumeViewer}/loaders/TinyXML2.h | 0 .../volumeViewer}/loaders/TriangleMeshFile.cpp | 0 .../volumeViewer}/loaders/TriangleMeshFile.h | 0 {modules => apps/volumeViewer}/loaders/VolumeFile.cpp | 2 +- {modules => apps/volumeViewer}/loaders/VolumeFile.h | 0 21 files changed, 21 insertions(+), 18 deletions(-) rename {modules => apps/volumeViewer}/loaders/CMakeLists.txt (100%) rename {modules => apps/volumeViewer}/loaders/OSPObjectFile.cpp (100%) rename {modules => apps/volumeViewer}/loaders/OSPObjectFile.h (96%) rename {modules => apps/volumeViewer}/loaders/ObjectFile.cpp (100%) rename {modules => apps/volumeViewer}/loaders/ObjectFile.h (100%) rename {modules => apps/volumeViewer}/loaders/PLYTriangleMeshFile.cpp (100%) rename {modules => apps/volumeViewer}/loaders/PLYTriangleMeshFile.h (100%) rename {modules => apps/volumeViewer}/loaders/README.txt (100%) rename {modules => apps/volumeViewer}/loaders/RMVolumeFile.cpp (99%) rename {modules => apps/volumeViewer}/loaders/RMVolumeFile.h (100%) rename {modules => apps/volumeViewer}/loaders/RawVolumeFile.cpp (98%) rename {modules => apps/volumeViewer}/loaders/RawVolumeFile.h (100%) rename {modules => apps/volumeViewer}/loaders/SymbolRegistry.cpp (89%) rename {modules => apps/volumeViewer}/loaders/TinyXML2.cpp (100%) rename {modules => apps/volumeViewer}/loaders/TinyXML2.h (100%) rename {modules => apps/volumeViewer}/loaders/TriangleMeshFile.cpp (100%) rename {modules => apps/volumeViewer}/loaders/TriangleMeshFile.h (100%) rename {modules => apps/volumeViewer}/loaders/VolumeFile.cpp (98%) rename {modules => apps/volumeViewer}/loaders/VolumeFile.h (100%) diff --git a/apps/volumeViewer/CMakeLists.txt b/apps/volumeViewer/CMakeLists.txt index 7e1a10ae48..f713d7a9bd 100644 --- a/apps/volumeViewer/CMakeLists.txt +++ b/apps/volumeViewer/CMakeLists.txt @@ -76,6 +76,7 @@ SET(MOC_HEADERS QT4_WRAP_CPP(MOC_OUTFILES ${MOC_HEADERS}) +ADD_SUBDIRECTORY(loaders) ADD_EXECUTABLE(ospVolumeViewer ${SRCS} ${MOC_OUTFILES}) TARGET_LINK_LIBRARIES(ospVolumeViewer ${LIBS}) # ------------------------------------------------------------ diff --git a/apps/volumeViewer/VolumeViewer.cpp b/apps/volumeViewer/VolumeViewer.cpp index a04c3a7cce..347b9895d1 100644 --- a/apps/volumeViewer/VolumeViewer.cpp +++ b/apps/volumeViewer/VolumeViewer.cpp @@ -17,8 +17,8 @@ #include // own #include "VolumeViewer.h" -#include "modules/loaders/ObjectFile.h" -#include "modules/loaders/TriangleMeshFile.h" +#include "loaders/ObjectFile.h" +#include "loaders/TriangleMeshFile.h" #include "TransferFunctionEditor.h" #include "IsosurfaceEditor.h" #include "LightEditor.h" diff --git a/modules/loaders/CMakeLists.txt b/apps/volumeViewer/loaders/CMakeLists.txt similarity index 100% rename from modules/loaders/CMakeLists.txt rename to apps/volumeViewer/loaders/CMakeLists.txt diff --git a/modules/loaders/OSPObjectFile.cpp b/apps/volumeViewer/loaders/OSPObjectFile.cpp similarity index 100% rename from modules/loaders/OSPObjectFile.cpp rename to apps/volumeViewer/loaders/OSPObjectFile.cpp diff --git a/modules/loaders/OSPObjectFile.h b/apps/volumeViewer/loaders/OSPObjectFile.h similarity index 96% rename from modules/loaders/OSPObjectFile.h rename to apps/volumeViewer/loaders/OSPObjectFile.h index 8f46b4c877..1f1fe03444 100644 --- a/modules/loaders/OSPObjectFile.h +++ b/apps/volumeViewer/loaders/OSPObjectFile.h @@ -16,9 +16,9 @@ #pragma once -#include "modules/loaders/RawVolumeFile.h" -#include "modules/loaders/ObjectFile.h" -#include "modules/loaders/TinyXML2.h" +#include "RawVolumeFile.h" +#include "ObjectFile.h" +#include "TinyXML2.h" // stl #include diff --git a/modules/loaders/ObjectFile.cpp b/apps/volumeViewer/loaders/ObjectFile.cpp similarity index 100% rename from modules/loaders/ObjectFile.cpp rename to apps/volumeViewer/loaders/ObjectFile.cpp diff --git a/modules/loaders/ObjectFile.h b/apps/volumeViewer/loaders/ObjectFile.h similarity index 100% rename from modules/loaders/ObjectFile.h rename to apps/volumeViewer/loaders/ObjectFile.h diff --git a/modules/loaders/PLYTriangleMeshFile.cpp b/apps/volumeViewer/loaders/PLYTriangleMeshFile.cpp similarity index 100% rename from modules/loaders/PLYTriangleMeshFile.cpp rename to apps/volumeViewer/loaders/PLYTriangleMeshFile.cpp diff --git a/modules/loaders/PLYTriangleMeshFile.h b/apps/volumeViewer/loaders/PLYTriangleMeshFile.h similarity index 100% rename from modules/loaders/PLYTriangleMeshFile.h rename to apps/volumeViewer/loaders/PLYTriangleMeshFile.h diff --git a/modules/loaders/README.txt b/apps/volumeViewer/loaders/README.txt similarity index 100% rename from modules/loaders/README.txt rename to apps/volumeViewer/loaders/README.txt diff --git a/modules/loaders/RMVolumeFile.cpp b/apps/volumeViewer/loaders/RMVolumeFile.cpp similarity index 99% rename from modules/loaders/RMVolumeFile.cpp rename to apps/volumeViewer/loaders/RMVolumeFile.cpp index df736a8ce3..7b934de23d 100644 --- a/modules/loaders/RMVolumeFile.cpp +++ b/apps/volumeViewer/loaders/RMVolumeFile.cpp @@ -14,17 +14,17 @@ // limitations under the License. // // ======================================================================== // +#include "RMVolumeFile.h" +// ospcommon +#include "common/sysinfo.h" +// std:: #include #include -#include "modules/loaders/RMVolumeFile.h" #ifdef __LINUX__ # include #endif -// std:: #include #include -// ospcommon -#include "common/sysinfo.h" struct RMLoaderThreads { OSPVolume volume; diff --git a/modules/loaders/RMVolumeFile.h b/apps/volumeViewer/loaders/RMVolumeFile.h similarity index 100% rename from modules/loaders/RMVolumeFile.h rename to apps/volumeViewer/loaders/RMVolumeFile.h diff --git a/modules/loaders/RawVolumeFile.cpp b/apps/volumeViewer/loaders/RawVolumeFile.cpp similarity index 98% rename from modules/loaders/RawVolumeFile.cpp rename to apps/volumeViewer/loaders/RawVolumeFile.cpp index b19d8a1c9c..c1e3bffbfa 100644 --- a/modules/loaders/RawVolumeFile.cpp +++ b/apps/volumeViewer/loaders/RawVolumeFile.cpp @@ -14,18 +14,20 @@ // limitations under the License. // // ======================================================================== // -#include "modules/loaders/RawVolumeFile.h" +#include "RawVolumeFile.h" + #include #include -#include "modules/loaders/RawVolumeFile.h" -#include "common/sys/filename.h" +#include "common/FileName.h" + +using ospcommon::FileName; OSPVolume RawVolumeFile::importVolume(OSPVolume volume) { // Look for the volume data file at the given path. FILE *file = NULL; - embree::FileName fn = filename; + FileName fn = filename; bool gzipped = fn.ext() == "gz"; if (gzipped) { std::string cmd = "/usr/bin/gunzip -c "+filename; diff --git a/modules/loaders/RawVolumeFile.h b/apps/volumeViewer/loaders/RawVolumeFile.h similarity index 100% rename from modules/loaders/RawVolumeFile.h rename to apps/volumeViewer/loaders/RawVolumeFile.h diff --git a/modules/loaders/SymbolRegistry.cpp b/apps/volumeViewer/loaders/SymbolRegistry.cpp similarity index 89% rename from modules/loaders/SymbolRegistry.cpp rename to apps/volumeViewer/loaders/SymbolRegistry.cpp index 591f6f395b..f4072ceb46 100644 --- a/modules/loaders/SymbolRegistry.cpp +++ b/apps/volumeViewer/loaders/SymbolRegistry.cpp @@ -14,10 +14,10 @@ // limitations under the License. // // ======================================================================== // -#include "modules/loaders/OSPObjectFile.h" -#include "modules/loaders/RawVolumeFile.h" -#include "modules/loaders/RMVolumeFile.h" -#include "modules/loaders/PLYTriangleMeshFile.h" +#include "OSPObjectFile.h" +#include "RawVolumeFile.h" +#include "RMVolumeFile.h" +#include "PLYTriangleMeshFile.h" // Loader for XML object files. OSP_REGISTER_OBJECT_FILE(OSPObjectFile, osp); diff --git a/modules/loaders/TinyXML2.cpp b/apps/volumeViewer/loaders/TinyXML2.cpp similarity index 100% rename from modules/loaders/TinyXML2.cpp rename to apps/volumeViewer/loaders/TinyXML2.cpp diff --git a/modules/loaders/TinyXML2.h b/apps/volumeViewer/loaders/TinyXML2.h similarity index 100% rename from modules/loaders/TinyXML2.h rename to apps/volumeViewer/loaders/TinyXML2.h diff --git a/modules/loaders/TriangleMeshFile.cpp b/apps/volumeViewer/loaders/TriangleMeshFile.cpp similarity index 100% rename from modules/loaders/TriangleMeshFile.cpp rename to apps/volumeViewer/loaders/TriangleMeshFile.cpp diff --git a/modules/loaders/TriangleMeshFile.h b/apps/volumeViewer/loaders/TriangleMeshFile.h similarity index 100% rename from modules/loaders/TriangleMeshFile.h rename to apps/volumeViewer/loaders/TriangleMeshFile.h diff --git a/modules/loaders/VolumeFile.cpp b/apps/volumeViewer/loaders/VolumeFile.cpp similarity index 98% rename from modules/loaders/VolumeFile.cpp rename to apps/volumeViewer/loaders/VolumeFile.cpp index 0acfc93c87..80815e8307 100644 --- a/modules/loaders/VolumeFile.cpp +++ b/apps/volumeViewer/loaders/VolumeFile.cpp @@ -14,7 +14,7 @@ // limitations under the License. // // ======================================================================== // -#include "modules/loaders/VolumeFile.h" +#include "VolumeFile.h" #include OSPVolume VolumeFile::importVolume(const std::string &filename, OSPVolume volume) diff --git a/modules/loaders/VolumeFile.h b/apps/volumeViewer/loaders/VolumeFile.h similarity index 100% rename from modules/loaders/VolumeFile.h rename to apps/volumeViewer/loaders/VolumeFile.h From a7e90affdf4a0194149ab8c43aa8aa88564fbd79 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 12:56:18 -0600 Subject: [PATCH 023/310] more missing files --- common/CMakeLists.txt | 1 + common/common.cpp | 121 ------- common/library.cpp | 155 ++++++++ common/library.h | 34 ++ common/network.cpp | 331 ++++++++++++++++++ common/network.h | 86 +++++ common/thread.h | 124 +++++++ ospray/common/Library.cpp | 6 +- ospray/common/Library.h | 4 +- ospray/common/OSPCommon.cpp | 6 +- ospray/common/Thread.cpp | 8 +- ospray/common/Thread.h | 6 +- ospray/device/nwlayer.h | 4 +- .../common/lexers/CMakeLists.txt | 1 + .../embree-v2.7.1/common/simd/CMakeLists.txt | 1 + .../embree-v2.7.1/common/sys/CMakeLists.txt | 1 + ospray/embree-v2.7.1/common/sys/platform.h | 4 + .../embree-v2.7.1/kernels/xeon/CMakeLists.txt | 14 +- 18 files changed, 765 insertions(+), 142 deletions(-) create mode 100644 common/library.cpp create mode 100644 common/library.h create mode 100644 common/network.cpp create mode 100644 common/network.h create mode 100644 common/thread.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index dc58569ff3..af8a46918d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -4,6 +4,7 @@ ADD_LIBRARY(ospray_ospcommon SHARED FileName.cpp sysinfo.cpp malloc.cpp + library.cpp ) diff --git a/common/common.cpp b/common/common.cpp index 9a779d7781..f584e3793b 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -15,7 +15,6 @@ // ======================================================================== // #include "common.h" -#include "FileName.h" #include "sysinfo.h" // std @@ -31,21 +30,8 @@ # include #endif -// std -#include - namespace ospcommon { - /*! type for shared library */ - typedef struct opaque_lib_t* lib_t; - - - struct Library - { - std::string name; - lib_t lib; - }; - /*! return system time in seconds */ double getSysTime() { #ifdef _WIN32 @@ -74,112 +60,5 @@ namespace ospcommon { abort(); } -#if defined(__WIN32__) - /* returns address of a symbol from the library */ - void* getSymbol(lib_t lib, const std::string& sym) { - return GetProcAddress(HMODULE(lib),sym.c_str()); - } -#else - /* returns address of a symbol from the library */ - void* getSymbol(lib_t lib, const std::string& sym) { - return dlsym(lib,sym.c_str()); - } -#endif - - - std::vector loadedLibs; - - - -#if defined(__WIN32__) - /* opens a shared library */ - lib_t openLibrary(const std::string& file) - { - std::string fullName = file+".dll"; - FileName executable = getExecutableFileName(); - HANDLE handle = LoadLibrary((executable.path() + fullName).c_str()); - return lib_t(handle); - } -#else - /* opens a shared library */ - lib_t openLibrary(const std::string& file) - { -#if defined(__MACOSX__) - std::string fullName = "lib"+file+".dylib"; -#else - std::string fullName = "lib"+file+".so"; -#endif - void* lib = dlopen(fullName.c_str(), RTLD_NOW); - if (lib) return lib_t(lib); - FileName executable = getExecutableFileName(); - lib = dlopen((executable.path() + fullName).c_str(),RTLD_NOW); - if (lib == NULL) throw std::runtime_error(dlerror()); - return lib_t(lib); - } -#endif - - void loadLibrary(const std::string &_name) - { -#ifdef OSPRAY_TARGET_MIC - std::string name = _name+"_mic"; -#else - std::string name = _name; -#endif - - for (int i=0;iname == name) - // lib already loaded. - return; - - Library *lib = new Library; - lib->name = name; - lib->lib = openLibrary(name); - if (lib->lib == NULL) - throw std::runtime_error("could not open module lib "+name); - - loadedLibs.push_back(lib); - } - void *getSymbol(const std::string &name) - { - for (int i=0;ilib, name); - if (sym) return sym; - } - - // if none found in the loaded libs, try the default lib ... -#ifdef _WIN32 - void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) - if (!sym) { - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function - sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) - } -#else - void *sym = dlsym(RTLD_DEFAULT,name.c_str()); -#endif - return sym; - } - -// void *getSymbol(const std::string &name) -// { -// // for (int i=0;ilib, name); -// // if (sym) return sym; -// // } - -// // if none found in the loaded libs, try the default lib ... -// #ifdef _WIN32 -// void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) -// if (!sym) { -// MEMORY_BASIC_INFORMATION mbi; -// VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function -// sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) -// } -// #else -// void *sym = dlsym(RTLD_DEFAULT,name.c_str()); -// #endif -// return sym; -// } - } // ::ospcommon diff --git a/common/library.cpp b/common/library.cpp new file mode 100644 index 0000000000..fea93937f4 --- /dev/null +++ b/common/library.cpp @@ -0,0 +1,155 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "library.h" +#include "FileName.h" +#include "sysinfo.h" + +// std +#include +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include // for GetSystemTime +#else +# include +# include +# include +#endif +// std +#include + + +namespace ospcommon { + + /*! type for shared library */ + typedef struct opaque_lib_t* lib_t; + + struct Library + { + std::string name; + lib_t lib; + }; + +#if defined(__WIN32__) + /* returns address of a symbol from the library */ + void* getSymbol(lib_t lib, const std::string& sym) { + return GetProcAddress(HMODULE(lib),sym.c_str()); + } +#else + /* returns address of a symbol from the library */ + void* getSymbol(lib_t lib, const std::string& sym) { + return dlsym(lib,sym.c_str()); + } +#endif + + + std::vector loadedLibs; + + + +#if defined(__WIN32__) + /* opens a shared library */ + lib_t openLibrary(const std::string& file) + { + std::string fullName = file+".dll"; + FileName executable = getExecutableFileName(); + HANDLE handle = LoadLibrary((executable.path() + fullName).c_str()); + return lib_t(handle); + } +#else + /* opens a shared library */ + lib_t openLibrary(const std::string& file) + { +#if defined(__MACOSX__) + std::string fullName = "lib"+file+".dylib"; +#else + std::string fullName = "lib"+file+".so"; +#endif + void* lib = dlopen(fullName.c_str(), RTLD_NOW); + if (lib) return lib_t(lib); + FileName executable = getExecutableFileName(); + lib = dlopen((executable.path() + fullName).c_str(),RTLD_NOW); + if (lib == NULL) throw std::runtime_error(dlerror()); + return lib_t(lib); + } +#endif + + void loadLibrary(const std::string &_name) + { +#ifdef OSPRAY_TARGET_MIC + std::string name = _name+"_mic"; +#else + std::string name = _name; +#endif + + for (int i=0;iname == name) + // lib already loaded. + return; + + Library *lib = new Library; + lib->name = name; + lib->lib = openLibrary(name); + if (lib->lib == NULL) + throw std::runtime_error("could not open module lib "+name); + + loadedLibs.push_back(lib); + } + void *getSymbol(const std::string &name) + { + for (int i=0;ilib, name); + if (sym) return sym; + } + + // if none found in the loaded libs, try the default lib ... +#ifdef _WIN32 + void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) + if (!sym) { + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function + sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) + } +#else + void *sym = dlsym(RTLD_DEFAULT,name.c_str()); +#endif + return sym; + } + +// void *getSymbol(const std::string &name) +// { +// // for (int i=0;ilib, name); +// // if (sym) return sym; +// // } + +// // if none found in the loaded libs, try the default lib ... +// #ifdef _WIN32 +// void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) +// if (!sym) { +// MEMORY_BASIC_INFORMATION mbi; +// VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function +// sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) +// } +// #else +// void *sym = dlsym(RTLD_DEFAULT,name.c_str()); +// #endif +// return sym; +// } +} + diff --git a/common/library.h b/common/library.h new file mode 100644 index 0000000000..f88e421809 --- /dev/null +++ b/common/library.h @@ -0,0 +1,34 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "common.h" + +namespace ospcommon { + + /*! type for shared library */ + typedef struct opaque_lib_t* lib_t; + + /*! loads a shared library */ + lib_t openLibrary(const std::string& file); + + /*! returns address of a symbol from the library */ + void* getSymbol(lib_t lib, const std::string& sym); + + /*! unloads a shared library */ + void closeLibrary(lib_t lib); + +} + diff --git a/common/network.cpp b/common/network.cpp new file mode 100644 index 0000000000..ef25c16a1d --- /dev/null +++ b/common/network.cpp @@ -0,0 +1,331 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "network.h" +#include "string.h" +//#include "mutex.h" + +//////////////////////////////////////////////////////////////////////////////// +/// Platforms supporting Socket interface +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__WIN32__) +#define _WINSOCK_DEPRECATED_NO_WARNINGS +//#include +//#include +typedef int socklen_t; +#define SHUT_RDWR 0x2 +#else +#include +#include +#include +#include +#include +#include +#include +#define SOCKET int +#define INVALID_SOCKET -1 +#define closesocket close +#endif + +/*! ignore if not supported */ +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +#define BUFFERING 1 + +namespace ospcommon +{ + namespace network + { + __forceinline void initialize() { +#ifdef __WIN32__ + static bool initialized = false; + static MutexSys initMutex; + Lock lock(initMutex); + WSADATA wsaData; + short version = MAKEWORD(1,1); + if (WSAStartup(version,&wsaData) != 0) + THROW_RUNTIME_ERROR("Winsock initialization failed"); + initialized = true; +#endif + } + + struct buffered_socket_t + { + buffered_socket_t (SOCKET fd, size_t isize = 64*1024, size_t osize = 64*1024) + : fd(fd), + ibuf(new char[isize]), isize(isize), istart(0), iend(0), + obuf(new char[osize]), osize(osize), oend(0) { + } + + ~buffered_socket_t () { + delete[] ibuf; ibuf = nullptr; + delete[] obuf; obuf = nullptr; + } + + SOCKET fd; //!< file descriptor of the socket + char* ibuf; + size_t isize; + size_t istart,iend; + char* obuf; + size_t osize; + size_t oend; + }; + + socket_t connect(const char* host, unsigned short port) + { + initialize(); + + /*! create a new socket */ + SOCKET sockfd = ::socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot create socket"); + + /*! perform DNS lookup */ + struct hostent* server = ::gethostbyname(host); + if (server == nullptr) THROW_RUNTIME_ERROR("server "+std::string(host)+" not found"); + + /*! perform connection */ + struct sockaddr_in serv_addr; + memset((char*)&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = (unsigned short) htons(port); + memcpy((char*)&serv_addr.sin_addr.s_addr, (char*)server->h_addr, server->h_length); + + if (::connect(sockfd,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0) + THROW_RUNTIME_ERROR("connection to "+std::string(host)+":"+std::to_string((long long)port)+" failed"); + + /*! enable TCP_NODELAY */ +#ifdef TCP_NODELAY + { int flag = 1; ::setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(int)); } +#endif + + /*! we do not want SIGPIPE to be thrown */ +#ifdef SO_NOSIGPIPE + { int flag = 1; setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (const char*) &flag, sizeof(int)); } +#endif + + return (socket_t) new buffered_socket_t(sockfd); + } + + socket_t bind(unsigned short port) + { + initialize(); + + /*! create a new socket */ + SOCKET sockfd = ::socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot create socket"); + + /* When the server completes, the server socket enters a time-wait state during which the local + address and port used by the socket are believed to be in use by the OS. The wait state may + last several minutes. This socket option allows bind() to reuse the port immediately. */ +#ifdef SO_REUSEADDR + { int flag = true; ::setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(int)); } +#endif + + /*! bind socket to port */ + struct sockaddr_in serv_addr; + memset((char *) &serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = (unsigned short) htons(port); + serv_addr.sin_addr.s_addr = INADDR_ANY; + + if (::bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) + THROW_RUNTIME_ERROR("binding to port "+std::to_string((long long)port)+" failed"); + + /*! listen to port, up to 5 pending connections */ + if (::listen(sockfd,5) < 0) + THROW_RUNTIME_ERROR("listening on socket failed"); + + return (socket_t) new buffered_socket_t(sockfd); + } + + socket_t listen(socket_t hsock) + { + SOCKET sockfd = ((buffered_socket_t*) hsock)->fd; + + /*! accept incoming connection */ + struct sockaddr_in addr; + socklen_t len = sizeof(addr); + SOCKET fd = ::accept(sockfd, (struct sockaddr *) &addr, &len); + if (fd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot accept connection"); + + /*! enable TCP_NODELAY */ +#ifdef TCP_NODELAY + { int flag = 1; ::setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char*)&flag,sizeof(int)); } +#endif + + /*! we do not want SIGPIPE to be thrown */ +#ifdef SO_NOSIGPIPE + { int flag = 1; setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&flag, sizeof(int)); } +#endif + + return (socket_t) new buffered_socket_t(fd); + } + + void read(socket_t hsock_i, void* data_i, size_t bytes) + { +#if BUFFERING + char* data = (char*)data_i; + buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; + while (bytes) { + if (hsock->istart == hsock->iend) { + ssize_t n = ::recv(hsock->fd,hsock->ibuf,hsock->isize,MSG_NOSIGNAL); + if (n == 0) throw Disconnect(); + else if (n < 0) THROW_RUNTIME_ERROR("error reading from socket"); + hsock->istart = 0; + hsock->iend = n; + } + size_t bsize = hsock->iend-hsock->istart; + if (bytes < bsize) bsize = bytes; + memcpy(data,hsock->ibuf+hsock->istart,bsize); + data += bsize; + hsock->istart += bsize; + bytes -= bsize; + } +#else + char* data = (char*) data_i; + buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; + while (bytes) { + ssize_t n = ::read(hsock->fd,data,bytes); + if (n == 0) throw Disconnect(); + else if (n < 0) THROW_RUNTIME_ERROR("error reading from socket"); + data+=n; + bytes-=n; + } +#endif + } + + void write(socket_t hsock_i, const void* data_i, size_t bytes) + { +#if BUFFERING + const char* data = (const char*) data_i; + buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; + while (bytes) { + if (hsock->oend == hsock->osize) flush(hsock_i); + size_t bsize = hsock->osize-hsock->oend; + if (bytes < bsize) bsize = bytes; + memcpy(hsock->obuf+hsock->oend,data,bsize); + data += bsize; + hsock->oend += bsize; + bytes -= bsize; + } +#else + const char* data = (const char*) data_i; + buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; + while (bytes) { + ssize_t n = ::write(hsock->fd,data,bytes); + if (n < 0) THROW_RUNTIME_ERROR("error writing to socket"); + data+=n; + bytes-=n; + } +#endif + } + + void flush(socket_t hsock_i) + { +#if BUFFERING + buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; + char* data = hsock->obuf; + size_t bytes = hsock->oend; + while (bytes > 0) { + ssize_t n = ::send(hsock->fd,data,(int)bytes,MSG_NOSIGNAL); + if (n < 0) THROW_RUNTIME_ERROR("error writing to socket"); + bytes -= n; + data += n; + } + hsock->oend = 0; +#endif + } + + void close(socket_t hsock_i) { + buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; + ::shutdown(hsock->fd,SHUT_RDWR); + delete hsock; + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// All Platforms +//////////////////////////////////////////////////////////////////////////////// + +namespace ospcommon +{ + namespace network + { + bool read_bool(socket_t socket) + { + bool value = 0; + read(socket,&value,sizeof(bool)); + return value; + } + + char read_char(socket_t socket) + { + char value = 0; + read(socket,&value,sizeof(char)); + return value; + } + + int read_int(socket_t socket) + { + int value = 0; + read(socket,&value,sizeof(int)); + return value; + } + + float read_float(socket_t socket) + { + float value = 0.0f; + read(socket,&value,sizeof(float)); + return value; + } + + std::string read_string(socket_t socket) + { + int bytes = read_int(socket); + char* str = new char[bytes+1]; + read(socket,str,bytes); + str[bytes] = 0x00; + std::string s(str); + delete[] str; + return s; + } + + void write(socket_t socket, bool value) { + write(socket,&value,sizeof(bool)); + } + + void write(socket_t socket, char value) { + write(socket,&value,sizeof(char)); + } + + void write(socket_t socket, int value) { + write(socket,&value,sizeof(int)); + } + + void write(socket_t socket, float value) { + write(socket,&value,sizeof(float)); + } + + void write(socket_t socket, const std::string& str) { + write(socket,(int)str.size()); + write(socket,str.c_str(),str.size()); + } + } +} diff --git a/common/network.h b/common/network.h new file mode 100644 index 0000000000..83c6b18ab1 --- /dev/null +++ b/common/network.h @@ -0,0 +1,86 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" + +namespace ospcommon +{ + namespace network + { + /*! type for a socket */ + typedef struct opaque_socket_t* socket_t; + + /*! exception thrown when other side disconnects */ + struct Disconnect : public std::exception { + virtual const char* what() const throw() { + return "network disconnect"; + } + }; + + /*! creates a socket bound to a port */ + socket_t bind(unsigned short port); + + /*! listens for an incoming connection and accepts that connection */ + socket_t listen(socket_t sockfd); + + /*! initiates a connection */ + socket_t connect(const char* host, unsigned short port); + + /*! read data from the socket */ + void read(socket_t socket, void* data, size_t bytes); + + /*! write data to the socket */ + void write(socket_t socket, const void* data, size_t bytes); + + /*! flushes the write buffer */ + void flush(socket_t socket); + + /*! close a socket */ + void close(socket_t socket); + + /*! reads a bool from the socket */ + bool read_bool(socket_t socket); + + /*! reads a character from the socket */ + char read_char(socket_t socket); + + /*! reads an integer from the socket */ + int read_int(socket_t socket); + + /*! reads a float from the socket */ + float read_float(socket_t socket); + + /*! reads a string from the socket */ + std::string read_string(socket_t socket); + + /*! writes a bool to the socket */ + void write(socket_t socket, bool value); + + /*! writes a character to the socket */ + void write(socket_t socket, char value); + + /*! writes an integer to the socket */ + void write(socket_t socket, int value); + + /*! writes a float to the socket */ + void write(socket_t socket, float value); + + /*! writes a string to the socket */ + void write(socket_t socket, const std::string& str); + } +} diff --git a/common/thread.h b/common/thread.h new file mode 100644 index 0000000000..e1a16a0931 --- /dev/null +++ b/common/thread.h @@ -0,0 +1,124 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "platform.h" +//#include "mutex.h" + +namespace ospcommon +{ + /*! type for thread */ + typedef struct opaque_thread_t* thread_t; + + /*! signature of thread start function */ + typedef void (*thread_func)(void*); + + /*! creates a hardware thread running on specific logical thread */ + thread_t createThread(thread_func f, void* arg, size_t stack_size = 0, ssize_t threadID = -1); + + /*! set affinity of the calling thread */ + void setAffinity(ssize_t affinity); + + /*! the thread calling this function gets yielded */ + void yield(); + + /*! waits until the given thread has terminated */ + void join(thread_t tid); + + /*! destroy handle of a thread */ + void destroyThread(thread_t tid); + + // /*! type for handle to thread local storage */ + // typedef struct opaque_tls_t* tls_t; + + // /*! creates thread local storage */ + // tls_t createTls(); + + // /*! set thea thread local storage pointer */ + // void setTls(tls_t tls, void* const ptr); + + // /*! return the thread local storage pointer */ + // void* getTls(tls_t tls); + + // /*! destroys thread local storage identifier */ + // void destroyTls(tls_t tls); + + +// /*! manages thread local variables */ +// template +// struct ThreadLocalData +// { +// public: + +// __forceinline ThreadLocalData (void* init) +// : ptr(nullptr), init(init) {} + +// __forceinline ~ThreadLocalData () { +// clear(); +// } + +// __forceinline void clear() +// { +// if (ptr) destroyTls(ptr); ptr = nullptr; +// for (size_t i=0; ireset(); +// } + +// __forceinline Type* get() const +// { +// if (ptr == nullptr) { +// Lock lock(mutex); +// if (ptr == nullptr) ptr = createTls(); +// } +// Type* lptr = (Type*) getTls(ptr); +// if (unlikely(lptr == nullptr)) { +// setTls(ptr,lptr = new Type(init)); +// Lock lock(mutex); +// threads.push_back(lptr); +// } +// return lptr; +// } + +// __forceinline const Type& operator *( void ) const { return *get(); } +// __forceinline Type& operator *( void ) { return *get(); } +// __forceinline const Type* operator ->( void ) const { return get(); } +// __forceinline Type* operator ->( void ) { return get(); } + + +// private: +// mutable tls_t ptr; +// void* init; +// mutable AtomicMutex mutex; +// public: +// mutable std::vector threads; +// }; + +// #if defined(__MIC__) +// void printThreadInfo(); +// #endif +} diff --git a/ospray/common/Library.cpp b/ospray/common/Library.cpp index 42d2cbee11..c84799274f 100644 --- a/ospray/common/Library.cpp +++ b/ospray/common/Library.cpp @@ -16,6 +16,8 @@ // ospray #include "Library.h" +// ospcommmon +#include "common/library.h" // std #ifdef _WIN32 @@ -44,7 +46,7 @@ namespace ospray { Library *lib = new Library; lib->name = name; - lib->lib = embree::openLibrary(name); + lib->lib = ospcommon::openLibrary(name); if (lib->lib == NULL) throw std::runtime_error("could not open module lib "+name); @@ -53,7 +55,7 @@ namespace ospray { void *getSymbol(const std::string &name) { for (int i=0;ilib, name); + void *sym = ospcommon::getSymbol(loadedLibs[i]->lib, name); if (sym) return sym; } diff --git a/ospray/common/Library.h b/ospray/common/Library.h index 6971942e24..77bcb89c8c 100644 --- a/ospray/common/Library.h +++ b/ospray/common/Library.h @@ -20,13 +20,13 @@ #include "Managed.h" //embree stuff -#include "common/sys/library.h" +#include "common/library.h" namespace ospray { struct Library { std::string name; - embree::lib_t lib; + ospcommon::lib_t lib; }; void loadLibrary(const std::string &name); diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index f804984c4f..d88cf0e7af 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -17,7 +17,7 @@ #include "OSPCommon.h" // embree #include "embree2/rtcore.h" -#include "common/sys/sysinfo.h" +#include "common/sysinfo.h" namespace ospray { @@ -87,8 +87,8 @@ namespace ospray { { #ifndef OSPRAY_TARGET_MIC // If we're not on a MIC, check for SSE4.1 as minimum supported ISA. Will be increased to SSE4.2 in future. - int cpuFeatures = embree::getCPUFeatures(); - if ((cpuFeatures & embree::CPU_FEATURE_SSE41) == 0) + int cpuFeatures = ospcommon::getCPUFeatures(); + if ((cpuFeatures & ospcommon::CPU_FEATURE_SSE41) == 0) throw std::runtime_error("Error. OSPRay only runs on CPUs that support at least SSE4.1."); #endif diff --git a/ospray/common/Thread.cpp b/ospray/common/Thread.cpp index e700d1dc63..66e1b84dc1 100644 --- a/ospray/common/Thread.cpp +++ b/ospray/common/Thread.cpp @@ -18,7 +18,7 @@ #include "Thread.h" // embree -# include "common/sys/thread.h" +# include "common/thread.h" namespace ospray { @@ -27,7 +27,7 @@ namespace ospray { Thread *t = (Thread *)arg; if (t->desiredThreadID >= 0) { printf("pinning to thread %i\n",t->desiredThreadID); - embree::setAffinity(t->desiredThreadID); + ospcommon::setAffinity(t->desiredThreadID); } t->run(); @@ -35,14 +35,14 @@ namespace ospray { void Thread::join() { - embree::join(tid); + ospcommon::join(tid); } /*! start thread execution */ void Thread::start(int threadID) { desiredThreadID = threadID; - this->tid = embree::createThread(&ospray_Thread_runThread,this); + this->tid = ospcommon::createThread(&ospray_Thread_runThread,this); } } diff --git a/ospray/common/Thread.h b/ospray/common/Thread.h index a74de9cd0c..8c23707251 100644 --- a/ospray/common/Thread.h +++ b/ospray/common/Thread.h @@ -20,8 +20,8 @@ // ospray #include "OSPCommon.h" -// embree -#include "common/sys/thread.h" +// ospcommon +#include "common/thread.h" namespace ospray { @@ -43,7 +43,7 @@ namespace ospray { thread got started will not have any effect */ int desiredThreadID; //! the thread ID reported by embree's createThread - embree::thread_t tid; + ospcommon::thread_t tid; }; } diff --git a/ospray/device/nwlayer.h b/ospray/device/nwlayer.h index 23fab27379..070e523588 100644 --- a/ospray/device/nwlayer.h +++ b/ospray/device/nwlayer.h @@ -23,7 +23,7 @@ #include "ospray/device/command.h" #include "ospray/api/Device.h" // embree -#include "common/sys/network.h" +#include "common/network.h" namespace ospray { namespace nwlayer { @@ -46,7 +46,7 @@ namespace ospray { struct MPICommunicator : public Communicator { }; struct TCPCommunicator : public Communicator { - std::vector remote; + std::vector remote; }; diff --git a/ospray/embree-v2.7.1/common/lexers/CMakeLists.txt b/ospray/embree-v2.7.1/common/lexers/CMakeLists.txt index 4f2eeb2df4..3509c0f598 100644 --- a/ospray/embree-v2.7.1/common/lexers/CMakeLists.txt +++ b/ospray/embree-v2.7.1/common/lexers/CMakeLists.txt @@ -29,6 +29,7 @@ ADD_LIBRARY(lexers${EXT} STATIC TARGET_LINK_LIBRARIES(lexers${EXT} sys${EXT}) SET_PROPERTY(TARGET lexers${EXT} PROPERTY FOLDER common) +SET_TARGET_PROPERTIES(lexers${EXT} PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") INSTALL(TARGETS lexers${EXT} # EXPORT lexers${EXT}Export diff --git a/ospray/embree-v2.7.1/common/simd/CMakeLists.txt b/ospray/embree-v2.7.1/common/simd/CMakeLists.txt index 3a0383b5fb..fdef9c8db9 100644 --- a/ospray/embree-v2.7.1/common/simd/CMakeLists.txt +++ b/ospray/embree-v2.7.1/common/simd/CMakeLists.txt @@ -21,6 +21,7 @@ IF (__XEON__) # EXPORT simdExport DESTINATION lib ) + SET_TARGET_PROPERTIES(simd PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") # INSTALL(EXPORT simdExport # DESTINATION ${CMAKE_DIR} FILE libsimdTargets.cmake # ) diff --git a/ospray/embree-v2.7.1/common/sys/CMakeLists.txt b/ospray/embree-v2.7.1/common/sys/CMakeLists.txt index 273b675bf2..c0caf0a308 100644 --- a/ospray/embree-v2.7.1/common/sys/CMakeLists.txt +++ b/ospray/embree-v2.7.1/common/sys/CMakeLists.txt @@ -52,6 +52,7 @@ ADD_LIBRARY(sys STATIC TARGET_LINK_LIBRARIES(sys ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} ${ADDITIONAL_LIBRARIES}) SET_PROPERTY(TARGET sys PROPERTY FOLDER common) +SET_TARGET_PROPERTIES(sys PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") INSTALL(TARGETS sys # EXPORT sysExport diff --git a/ospray/embree-v2.7.1/common/sys/platform.h b/ospray/embree-v2.7.1/common/sys/platform.h index 7f986f472e..c30c7b3b11 100644 --- a/ospray/embree-v2.7.1/common/sys/platform.h +++ b/ospray/embree-v2.7.1/common/sys/platform.h @@ -16,6 +16,10 @@ #pragma once +#ifndef DONT_WARN_INCLUDE_EMBREE_INTERNALS +# error "warning: including embree internals (common/sys/platform.h) from outside of embree/ directory!" +#endif + #define _CRT_SECURE_NO_WARNINGS #include diff --git a/ospray/embree-v2.7.1/kernels/xeon/CMakeLists.txt b/ospray/embree-v2.7.1/kernels/xeon/CMakeLists.txt index 9689fcf2ed..fc879a009b 100644 --- a/ospray/embree-v2.7.1/kernels/xeon/CMakeLists.txt +++ b/ospray/embree-v2.7.1/kernels/xeon/CMakeLists.txt @@ -207,31 +207,32 @@ ENDIF() ADD_ISPC_LIBRARY(embree ${EMBREE_LIB_TYPE} ${EMBREE_LIBRARY_FILES}) SET_PROPERTY(TARGET embree PROPERTY FOLDER kernels) +SET_TARGET_PROPERTIES(embree PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") IF (TARGET_SSE42 AND EMBREE_LIBRARY_FILES_SSE42) ADD_LIBRARY(embree_sse42 STATIC ${EMBREE_LIBRARY_FILES_SSE42}) - SET_TARGET_PROPERTIES(embree_sse42 PROPERTIES COMPILE_FLAGS "${FLAGS_SSE42}") + SET_TARGET_PROPERTIES(embree_sse42 PROPERTIES COMPILE_FLAGS "${FLAGS_SSE42} -DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") SET_PROPERTY(TARGET embree_sse42 PROPERTY FOLDER kernels) SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_sse42) ENDIF () IF (TARGET_AVX AND EMBREE_LIBRARY_FILES_AVX) ADD_LIBRARY(embree_avx STATIC ${EMBREE_LIBRARY_FILES_AVX}) - SET_TARGET_PROPERTIES(embree_avx PROPERTIES COMPILE_FLAGS "${FLAGS_AVX}") + SET_TARGET_PROPERTIES(embree_avx PROPERTIES COMPILE_FLAGS "${FLAGS_AVX} -DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") SET_PROPERTY(TARGET embree_avx PROPERTY FOLDER kernels) SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx) - ENDIF() +ENDIF() IF (TARGET_AVX2 AND EMBREE_LIBRARY_FILES_AVX2) ADD_LIBRARY(embree_avx2 STATIC ${EMBREE_LIBRARY_FILES_AVX2}) - SET_TARGET_PROPERTIES(embree_avx2 PROPERTIES COMPILE_FLAGS "${FLAGS_AVX2}") + SET_TARGET_PROPERTIES(embree_avx2 PROPERTIES COMPILE_FLAGS "${FLAGS_AVX2} -DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") SET_PROPERTY(TARGET embree_avx2 PROPERTY FOLDER kernels) SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx2) ENDIF() IF (TARGET_AVX512 AND EMBREE_LIBRARY_FILES_AVX512) ADD_LIBRARY(embree_avx512 STATIC ${EMBREE_LIBRARY_FILES_AVX512}) - SET_TARGET_PROPERTIES(embree_avx512 PROPERTIES COMPILE_FLAGS "${FLAGS_AVX512}") + SET_TARGET_PROPERTIES(embree_avx512 PROPERTIES COMPILE_FLAGS "${FLAGS_AVX512} -DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") SET_PROPERTY(TARGET embree_avx512 PROPERTY FOLDER kernels) SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx512) ENDIF() @@ -253,3 +254,6 @@ ENDIF() IF (WIN32) INSTALL(TARGETS embree DESTINATION bin COMPONENT examples) ENDIF() + + +#SET_TARGET_PROPERTIES(embree PROPERTIES COMPILE_FLAGS " -DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") From 7e5b4abf1ab0b123a0cae095ac4b8b2e1587619b Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 13:03:55 -0600 Subject: [PATCH 024/310] now ABSOLUTELY no cross-includes between apps, ospray internals, and embree internals any more, except through the resp APIs. Added explicit traps in embree/sys/platofrm and ospray/OSPCommon that will get triggered by any file that's not in the respectively allowed subdirectory ... --- apps/particleViewer/ParticleViewer.cpp | 4 +- common/CMakeLists.txt | 1 + common/thread.cpp | 336 +++++++++++++++++++++++++ ospray/render/LoadBalancer.cpp | 8 +- 4 files changed, 343 insertions(+), 6 deletions(-) create mode 100644 common/thread.cpp diff --git a/apps/particleViewer/ParticleViewer.cpp b/apps/particleViewer/ParticleViewer.cpp index 178221e98d..ddec9185da 100644 --- a/apps/particleViewer/ParticleViewer.cpp +++ b/apps/particleViewer/ParticleViewer.cpp @@ -24,8 +24,8 @@ // particle viewer #include "Model.h" #include "uintah.h" -// embree -#include "sys/filename.h" +// ospcommon +#include "common/FileName.h" namespace ospray { namespace particle { diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index af8a46918d..2e6ae7b881 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -5,6 +5,7 @@ ADD_LIBRARY(ospray_ospcommon SHARED sysinfo.cpp malloc.cpp library.cpp + thread.cpp ) diff --git a/common/thread.cpp b/common/thread.cpp new file mode 100644 index 0000000000..00782be82a --- /dev/null +++ b/common/thread.cpp @@ -0,0 +1,336 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "thread.h" +#include "sysinfo.h" + +#include +#include + +#if defined(PTHREADS_WIN32) +#pragma comment (lib, "pthreadVC.lib") +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Windows Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__WIN32__) + +#define WIN32_LEAN_AND_MEAN +#include + +namespace ospcommon +{ + /*! set the affinity of a given thread */ + void setAffinity(HANDLE thread, ssize_t affinity) + { + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + typedef WORD (WINAPI *GetActiveProcessorGroupCountFunc)(); + typedef DWORD (WINAPI *GetActiveProcessorCountFunc)(WORD); + typedef BOOL (WINAPI *SetThreadGroupAffinityFunc)(HANDLE, const GROUP_AFFINITY *, PGROUP_AFFINITY); + typedef BOOL (WINAPI *SetThreadIdealProcessorExFunc)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); + HMODULE hlib = LoadLibrary("Kernel32"); + GetActiveProcessorGroupCountFunc pGetActiveProcessorGroupCount = (GetActiveProcessorGroupCountFunc)GetProcAddress(hlib, "GetActiveProcessorGroupCount"); + GetActiveProcessorCountFunc pGetActiveProcessorCount = (GetActiveProcessorCountFunc)GetProcAddress(hlib, "GetActiveProcessorCount"); + SetThreadGroupAffinityFunc pSetThreadGroupAffinity = (SetThreadGroupAffinityFunc)GetProcAddress(hlib, "SetThreadGroupAffinity"); + SetThreadIdealProcessorExFunc pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExFunc)GetProcAddress(hlib, "SetThreadIdealProcessorEx"); + if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount && pSetThreadGroupAffinity && pSetThreadIdealProcessorEx && + ((osvi.dwMajorVersion > 6) || ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion >= 1)))) + { + int groups = pGetActiveProcessorGroupCount(); + int totalProcessors = 0, group = 0, number = 0; + for (int i = 0; i affinity) { + group = i; + number = (int)affinity - totalProcessors; + break; + } + totalProcessors += processors; + } + + GROUP_AFFINITY groupAffinity; + groupAffinity.Group = (WORD)group; + groupAffinity.Mask = (KAFFINITY)(uint64_t(1) << number); + groupAffinity.Reserved[0] = 0; + groupAffinity.Reserved[1] = 0; + groupAffinity.Reserved[2] = 0; + if (!pSetThreadGroupAffinity(thread, &groupAffinity, NULL)) + WARNING("SetThreadGroupAffinity failed"); // on purpose only a warning + + PROCESSOR_NUMBER processorNumber; + processorNumber.Group = group; + processorNumber.Number = number; + processorNumber.Reserved = 0; + if (!pSetThreadIdealProcessorEx(thread, &processorNumber, NULL)) + WARNING("SetThreadIdealProcessorEx failed"); // on purpose only a warning + } + else + { + if (!SetThreadAffinityMask(thread, DWORD_PTR(uint64_t(1) << affinity))) + WARNING("SetThreadAffinityMask failed"); // on purpose only a warning + if (SetThreadIdealProcessor(thread, (DWORD)affinity) == (DWORD)-1) + WARNING("SetThreadIdealProcessor failed"); // on purpose only a warning + } + } + + /*! set affinity of the calling thread */ + void setAffinity(ssize_t affinity) { + setAffinity(GetCurrentThread(), affinity); + } + + struct ThreadStartupData + { + public: + ThreadStartupData (thread_func f, void* arg) + : f(f), arg(arg) {} + public: + thread_func f; + void* arg; + }; + + static void* threadStartup(ThreadStartupData* parg) + { + _mm_setcsr(_mm_getcsr() | /*FTZ:*/ (1<<15) | /*DAZ:*/ (1<<6)); + parg->f(parg->arg); + delete parg; + return NULL; + } + +#if !defined(PTHREADS_WIN32) + + /*! creates a hardware thread running on specific core */ + thread_t createThread(thread_func f, void* arg, size_t stack_size, ssize_t threadID) + { + HANDLE thread = CreateThread(NULL, stack_size, (LPTHREAD_START_ROUTINE)threadStartup, new ThreadStartupData(f,arg), 0, NULL); + if (thread == NULL) throw std::runtime_error("ospcommon::CreateThread failed"); + if (threadID >= 0) setAffinity(thread, threadID); + return thread_t(thread); + } + + /*! the thread calling this function gets yielded */ + void yield() { + SwitchToThread(); + } + + /*! waits until the given thread has terminated */ + void join(thread_t tid) { + WaitForSingleObject(HANDLE(tid), INFINITE); + CloseHandle(HANDLE(tid)); + } + + /*! destroy a hardware thread by its handle */ + void destroyThread(thread_t tid) { + TerminateThread(HANDLE(tid),0); + CloseHandle(HANDLE(tid)); + } + + // /*! creates thread local storage */ + // tls_t createTls() { + // return tls_t(size_t(TlsAlloc())); + // } + + // /*! set the thread local storage pointer */ + // void setTls(tls_t tls, void* const ptr) { + // TlsSetValue(DWORD(size_t(tls)), ptr); + // } + + // /*! return the thread local storage pointer */ + // void* getTls(tls_t tls) { + // return TlsGetValue(DWORD(size_t(tls))); + // } + + // /*! destroys thread local storage identifier */ + // void destroyTls(tls_t tls) { + // TlsFree(DWORD(size_t(tls))); + // } +#endif +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Linux Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__LINUX__) +namespace ospcommon +{ + /*! set affinity of the calling thread */ + void setAffinity(ssize_t affinity) + { + cpu_set_t cset; + CPU_ZERO(&cset); + CPU_SET(affinity, &cset); + + if (pthread_setaffinity_np(pthread_self(), sizeof(cset), &cset) != 0) + WARNING("pthread_setaffinity_np failed"); // on purpose only a warning + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// MacOSX Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__MACOSX__) + +#include +#include +#include + +namespace ospcommon +{ + /*! set affinity of the calling thread */ + void setAffinity(ssize_t affinity) + { + thread_affinity_policy ap; + ap.affinity_tag = affinity; + if (thread_policy_set(mach_thread_self(),THREAD_AFFINITY_POLICY,(thread_policy_t)&ap,THREAD_AFFINITY_POLICY_COUNT) != KERN_SUCCESS) + WARNING("setting thread affinity failed"); // on purpose only a warning + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// Unix Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__UNIX__) || defined(PTHREADS_WIN32) + +#include +#include + +#if defined(__USE_NUMA__) +#include +#endif + +namespace ospcommon +{ + struct ThreadStartupData + { + public: + ThreadStartupData (thread_func f, void* arg, int affinity) + : f(f), arg(arg), affinity(affinity) {} + public: + thread_func f; + void* arg; + ssize_t affinity; + }; + + static void* threadStartup(ThreadStartupData* parg) + { + _mm_setcsr(_mm_getcsr() | /*FTZ:*/ (1<<15) | /*DAZ:*/ (1<<6)); + +#if !defined(__LINUX__) + if (parg->affinity >= 0) + setAffinity(parg->affinity); +#endif + + parg->f(parg->arg); + delete parg; + return NULL; + } + + /*! creates a hardware thread running on specific core */ + thread_t createThread(thread_func f, void* arg, size_t stack_size, ssize_t threadID) + { +#ifdef __MIC__ + threadID++; // start counting at 1 on MIC +#endif + + /* set stack size */ + pthread_attr_t attr; + pthread_attr_init(&attr); + if (stack_size > 0) pthread_attr_setstacksize (&attr, stack_size); + + /* create thread */ + pthread_t* tid = new pthread_t; + if (pthread_create(tid,&attr,(void*(*)(void*))threadStartup,new ThreadStartupData(f,arg,threadID)) != 0) + throw std::runtime_error("ospcommon::pthread_create failed"); + + /* set affinity */ +#if defined(__LINUX__) + if (threadID >= 0) { + cpu_set_t cset; + CPU_ZERO(&cset); + CPU_SET(threadID, &cset); + if (pthread_setaffinity_np(*tid,sizeof(cpu_set_t),&cset)) + WARNING("pthread_setaffinity_np failed"); // on purpose only a warning + } +#endif + + return thread_t(tid); + } + + /*! the thread calling this function gets yielded */ + void yield() { + sched_yield(); + } + + /*! waits until the given thread has terminated */ + void join(thread_t tid) { + if (pthread_join(*(pthread_t*)tid, NULL) != 0) + throw std::runtime_error("ospcommon::pthread_join failed"); + delete (pthread_t*)tid; + } + + /*! destroy a hardware thread by its handle */ + void destroyThread(thread_t tid) { + pthread_cancel(*(pthread_t*)tid); + delete (pthread_t*)tid; + } + + // /*! creates thread local storage */ + // tls_t createTls() { + // static int cntr = 0; + // pthread_key_t* key = new pthread_key_t; + // if (pthread_key_create(key,NULL) != 0) + // FATAL("pthread_key_create failed"); + + // return tls_t(key); + // } + + // /*! return the thread local storage pointer */ + // void* getTls(tls_t tls) + // { + // assert(tls); + // return pthread_getspecific(*(pthread_key_t*)tls); + // } + + // /*! set the thread local storage pointer */ + // void setTls(tls_t tls, void* const ptr) + // { + // assert(tls); + // if (pthread_setspecific(*(pthread_key_t*)tls, ptr) != 0) + // FATAL("pthread_setspecific failed"); + // } + + // /*! destroys thread local storage identifier */ + // void destroyTls(tls_t tls) + // { + // assert(tls); + // if (pthread_key_delete(*(pthread_key_t*)tls) != 0) + // FATAL("pthread_key_delete failed"); + // delete (pthread_key_t*)tls; + // } +} + +#endif diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index 5b93edb93f..aec6bcecf1 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -14,15 +14,15 @@ // limitations under the License. // // ======================================================================== // +// own #include "LoadBalancer.h" #include "Renderer.h" -#include - +#include "ospray/common/parallel_for.h" +// ospc +#include "common/sysinfo.h" // stl #include -#include "ospray/common/parallel_for.h" - namespace ospray { using std::cout; From 2e230d401a2cab1110beca811a352989e4ac4193 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 13:40:14 -0600 Subject: [PATCH 025/310] bug fixed. feature-separate embree compiling and working (at least w/ modelviewer) --- apps/common/widgets/glut3D.cpp | 1 - common/vec.h | 2 +- ospray/render/raycast/RaycastRenderer.cpp | 6 ++++++ ospray/render/raycast/RaycastRenderer.ispc | 18 +++++++++++++++--- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/apps/common/widgets/glut3D.cpp b/apps/common/widgets/glut3D.cpp index cef8a97f02..a5af149fc8 100644 --- a/apps/common/widgets/glut3D.cpp +++ b/apps/common/widgets/glut3D.cpp @@ -635,7 +635,6 @@ namespace ospray { float dv = (to.y - from.y) * widget->rotateSpeed; vec2i delta_mouse = to - from; - // PRINT(delta_mouse); const vec3f pivot = cam.at; //center(widget->worldBounds); AffineSpace3fa xfm diff --git a/common/vec.h b/common/vec.h index b15744949d..88b7450e8b 100644 --- a/common/vec.h +++ b/common/vec.h @@ -94,7 +94,7 @@ namespace ospcommon { /*! return result of reduce_mul() across all components */ inline scalar_t product() const { return x*y*z; } - inline operator vec_t() const { return vec_t(x,y,a); } + inline operator vec_t() const { return vec_t(x,y,z); } T x, y, z; union { float w; unsigned u; int a; }; diff --git a/ospray/render/raycast/RaycastRenderer.cpp b/ospray/render/raycast/RaycastRenderer.cpp index 158904eb79..159208cf33 100644 --- a/ospray/render/raycast/RaycastRenderer.cpp +++ b/ospray/render/raycast/RaycastRenderer.cpp @@ -111,5 +111,11 @@ namespace ospray { RaycastRenderer_testFrame; OSP_REGISTER_RENDERER(RaycastRenderer_testFrame,testFrame); + /*! \brief Instantion of Ray Cast Renderer that renders a simple + test frame, without even calling postIntersct */ + typedef RaycastRenderer + RaycastRenderer_rayDir; + OSP_REGISTER_RENDERER(RaycastRenderer_rayDir,rayDir); + } // ::ospray diff --git a/ospray/render/raycast/RaycastRenderer.ispc b/ospray/render/raycast/RaycastRenderer.ispc index e9b216bc98..e0d35a7944 100644 --- a/ospray/render/raycast/RaycastRenderer.ispc +++ b/ospray/render/raycast/RaycastRenderer.ispc @@ -35,9 +35,9 @@ struct RaycastRenderer // int shadeMode; unused }; -//! a simple test-frame renderer that doesn't even trace a ray, just -//! returns a well-defined test frame (mostly useful for debugging -//! whether frame buffers are properly set up etcpp +/*! a simple test-frame renderer that doesn't even trace a ray, just + returns a well-defined test frame (mostly useful for debugging + whether frame buffers are properly set up etcpp */ void RaycastRenderer_renderSample_testFrame(uniform Renderer *uniform _self, void *uniform perFrameData, varying ScreenSample &sample) @@ -49,6 +49,17 @@ void RaycastRenderer_renderSample_testFrame(uniform Renderer *uniform _self, sample.z = 1.f; } +/*! a simple test-frame renderer that doesn't even trace a ray, just + returns the absolute of the ray direction */ +void RaycastRenderer_renderSample_rayDir(uniform Renderer *uniform _self, + void *uniform perFrameData, + varying ScreenSample &sample) +{ + sample.rgb = absf(sample.ray.dir); + sample.alpha = 1.f; + sample.z = 1.f; +} + void RaycastRenderer_renderSample_eyeLight(uniform Renderer *uniform _self, void *uniform perFrameData, varying ScreenSample &sample) @@ -286,6 +297,7 @@ void RaycastRenderer_renderSample_backfacing_Ns(uniform Renderer *uniform _self, } \ DEFINE_RAYCAST_RENDERER(testFrame); +DEFINE_RAYCAST_RENDERER(rayDir); DEFINE_RAYCAST_RENDERER(eyeLight); DEFINE_RAYCAST_RENDERER(Ng); DEFINE_RAYCAST_RENDERER(Ns); From ff1be9603ea865860c10cc7de5daa9a427d9476d Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 13:17:11 -0700 Subject: [PATCH 026/310] removing embree include dirs from ospray build, else (on mac) TBB actually "accidentally" includes some embree internal files!? --- cmake/ospray.cmake | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 9e759920cf..7c2862c55b 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -42,13 +42,13 @@ MACRO(CONFIGURE_OSPRAY_NO_ARCH) # Embree common include directories; others may be added depending on build target. # this section could be sooo much cleaner if embree only used # fully-qualified include names... - SET(EMBREE_INCLUDE_DIRECTORIES - ${OSPRAY_EMBREE_SOURCE_DIR}/ - ${OSPRAY_EMBREE_SOURCE_DIR}/include - ${OSPRAY_EMBREE_SOURCE_DIR}/common - ${OSPRAY_EMBREE_SOURCE_DIR}/ - ${OSPRAY_EMBREE_SOURCE_DIR}/kernels - ) +# SET(EMBREE_INCLUDE_DIRECTORIES +# ${OSPRAY_EMBREE_SOURCE_DIR}/ +# ${OSPRAY_EMBREE_SOURCE_DIR}/include +# ${OSPRAY_EMBREE_SOURCE_DIR}/common +# ${OSPRAY_EMBREE_SOURCE_DIR}/ +# ${OSPRAY_EMBREE_SOURCE_DIR}/kernels +# ) IF (OSPRAY_TARGET STREQUAL "mic") SET(OSPRAY_EXE_SUFFIX ".mic") From 4ab68cb1dd81df39b47fc4d241c33dfe0b62c9d6 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 13:17:41 -0700 Subject: [PATCH 027/310] need the include dir, though --- cmake/ospray.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 7c2862c55b..111719d897 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -42,13 +42,13 @@ MACRO(CONFIGURE_OSPRAY_NO_ARCH) # Embree common include directories; others may be added depending on build target. # this section could be sooo much cleaner if embree only used # fully-qualified include names... -# SET(EMBREE_INCLUDE_DIRECTORIES + SET(EMBREE_INCLUDE_DIRECTORIES # ${OSPRAY_EMBREE_SOURCE_DIR}/ -# ${OSPRAY_EMBREE_SOURCE_DIR}/include + ${OSPRAY_EMBREE_SOURCE_DIR}/include # ${OSPRAY_EMBREE_SOURCE_DIR}/common # ${OSPRAY_EMBREE_SOURCE_DIR}/ # ${OSPRAY_EMBREE_SOURCE_DIR}/kernels -# ) + ) IF (OSPRAY_TARGET STREQUAL "mic") SET(OSPRAY_EXE_SUFFIX ".mic") From c2300a4a5b46df77e651b9c4ea831dabd4f6b7f2 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 21 Feb 2016 16:51:56 -0700 Subject: [PATCH 028/310] now working on mac, too --- common/vec.h | 12 ++++++------ ospray/CMakeLists.txt | 19 +------------------ ospray/volume/StructuredVolume.h | 6 +++--- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/common/vec.h b/common/vec.h index 88b7450e8b..f7e99d13b6 100644 --- a/common/vec.h +++ b/common/vec.h @@ -298,7 +298,7 @@ namespace ospcommon { template inline bool operator<(const vec_t &a, const vec_t &b) { - return (a.x @@ -306,8 +306,8 @@ namespace ospcommon { { return (a.x< b.x) || - (a.x==b.x && ((a.y< b.y) || - (a.y==b.y) && (a.z @@ -315,9 +315,9 @@ namespace ospcommon { { return (a.x< b.x) || - (a.x==b.x && ((a.y< b.y) || - (a.y==b.y) && ((a.z< b.z) || - (a.z==b.z) && (a.w < b.w)))); + ((a.x==b.x) && ((a.y< b.y) || + ((a.y==b.y) && ((a.z< b.z) || + ((a.z==b.z) && (a.w < b.w)))))); } // 'anyLessThan' - return true if any component is less than the other vec's diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 69f577f11f..9bbd817514 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -250,24 +250,6 @@ IF (OSPRAY_MPI) fb/DisplayWall.cpp ) - # ============================================ - ADD_EXECUTABLE(ospCreateCompositeTestCubes${OSPRAY_EXE_SUFFIX} - mpi/testing/createCompositeTestCubes - ) - TARGET_LINK_LIBRARIES(ospCreateCompositeTestCubes${OSPRAY_EXE_SUFFIX} - ospray${OSPRAY_LIB_SUFFIX} - ) - - # ============================================ -# INCLUDE(${PROJECT_SOURCE_DIR}/cmake/glut.cmake) -# INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) -# ADD_EXECUTABLE(ospTestDistributedApp${OSPRAY_EXE_SUFFIX} -# mpi/testing/TestDistributedApp -# ) -# TARGET_LINK_LIBRARIES(ospTestDistributedApp${OSPRAY_EXE_SUFFIX} -# ospray${OSPRAY_LIB_SUFFIX} -# ) - ENDIF() # ------------------------------------------------------- @@ -315,6 +297,7 @@ OSPRAY_ADD_LIBRARY(ospray${OSPRAY_LIB_SUFFIX} SHARED ${OSPRAY_SOURCES}) SET_TARGET_PROPERTIES(ospray PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_OSPCOMMON_H=1") TARGET_LINK_LIBRARIES(ospray${OSPRAY_LIB_SUFFIX} + ospray_ospcommon${OSPRAY_LIB_SUFFIX} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} ) diff --git a/ospray/volume/StructuredVolume.h b/ospray/volume/StructuredVolume.h index bec23a180b..41f899b213 100644 --- a/ospray/volume/StructuredVolume.h +++ b/ospray/volume/StructuredVolume.h @@ -52,9 +52,9 @@ namespace ospray { //! Copy voxels into the volume at the given index /*! \returns 0 on error, any non-zero value indicates success */ - virtual int setRegion(const void *source_pointer, - const vec3i &target_index, - const vec3i &source_count) = 0; + // virtual int setRegion(const void *source_pointer, + // const vec3i &target_index, + // const vec3i &source_count) = 0; protected: From a5a29bd24f0027909255dd628588039b0c2098ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 22 Feb 2016 11:26:36 +0100 Subject: [PATCH 029/310] Include ospTutorial in normal build to catch any errors --- ospray/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 2efc1b0e76..d110f8fbc8 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -354,6 +354,10 @@ INSTALL(TARGETS ospray${OSPRAY_LIB_SUFFIX} ############################################################## +# build ospTutorial, for testing +ADD_EXECUTABLE(ospTutorial${OSPRAY_EXE_SUFFIX} ../apps/ospTutorial) +TARGET_LINK_LIBRARIES(ospTutorial${OSPRAY_EXE_SUFFIX} ospray${OSPRAY_LIB_SUFFIX}) + ############################################################## # MPI DEVICE - mpi worker From 13f2f2948cfba243da435d19a4987c7b7a9293c5 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 22 Feb 2016 13:21:02 -0600 Subject: [PATCH 030/310] fixed two race conditions in DFB code --- ospray/mpi/DistributedFrameBuffer.cpp | 35 +++++-------------------- ospray/mpi/DistributedFrameBuffer.h | 37 --------------------------- 2 files changed, 6 insertions(+), 66 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 165e39c61d..b7db16a0a6 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -122,7 +122,6 @@ namespace ospray { } } } - int size = bufferedTile.size(); if (missingInCurrentGeneration == 0) { Tile **tileArray = (Tile**)alloca(sizeof(Tile*)*bufferedTile.size()); @@ -291,24 +290,6 @@ namespace ospray { } } -#if QUEUE_PROCESSING_JOBS - void DistributedFrameBuffer::ProcThread::run() - { - embree::setAffinity(53); - return; - while (1) { - while (dfb->msgTaskQueue.queue.empty()) -#ifdef _WIN32 - Sleep(1); // 10x longer... -#else - usleep(100); -#endif - dfb->msgTaskQueue.waitAll(); - } - } -#endif - - DFB::DistributedFrameBuffer(mpi::async::CommLayer *comm, const vec2i &numPixels, size_t myID, @@ -322,9 +303,6 @@ namespace ospray { numTiles((numPixels.x+TILE_SIZE-1)/TILE_SIZE, (numPixels.y+TILE_SIZE-1)/TILE_SIZE), frameIsActive(false), frameIsDone(false), localFBonMaster(NULL), -#if QUEUE_PROCESSING_JOBS - procThread(this), -#endif frameMode(WRITE_ONCE) { assert(comm); @@ -350,9 +328,6 @@ namespace ospray { ispc::DFB_set(getIE(),numPixels.x,numPixels.y, colorBufferFormat); -#if QUEUE_PROCESSING_JOBS - // procThread.run(); -#endif } void DFB::setFrameMode(FrameMode newFrameMode) @@ -488,15 +463,16 @@ namespace ospray { DBG(printf("rank %i: tilecompleted %i,%i\n",mpi::world.rank, tile->begin.x,tile->begin.y)); if (IamTheMaster()) { + size_t numTilesCompletedByMyTile = 0; /*! we will not do anything with the tile other than mark it's done */ { SCOPED_LOCK(mutex); - numTilesCompletedThisFrame++; + numTilesCompletedByMyTile = ++numTilesCompletedThisFrame; DBG(printf("MASTER: MARKING AS COMPLETED %i,%i -> %li %i\n", tile->begin.x,tile->begin.y,numTilesCompletedThisFrame, numTiles.x*numTiles.y)); } - if (numTilesCompletedThisFrame == numTiles.x*numTiles.y) + if (numTilesCompletedByMyTile == numTiles.x*numTiles.y) closeCurrentFrame(); } else { if (pixelOp) { @@ -527,16 +503,17 @@ namespace ospray { "implemented for distributed frame buffer"); }; + size_t numTilesCompletedByMe = 0; { SCOPED_LOCK(mutex); - numTilesCompletedThisFrame++; + numTilesCompletedByMe = ++numTilesCompletedThisFrame; DBG(printf("rank %i: MARKING AS COMPLETED %i,%i -> %i %i\n", mpi::world.rank, tile->begin.x,tile->begin.y,numTilesCompletedThisFrame, numTiles.x*numTiles.y)); } - if (numTilesCompletedThisFrame == myTiles.size()) + if (numTilesCompletedByMe == myTiles.size()) closeCurrentFrame(); } } diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index c7d04d8efb..6ef07af0e6 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -26,21 +26,10 @@ namespace ospray { using std::cout; using std::endl; -#define QUEUE_PROCESSING_JOBS 0 - struct DistributedFrameBuffer : public mpi::async::CommLayer::Object, public virtual FrameBuffer { -#if QUEUE_PROCESSING_JOBS - struct ProcThread : public ospray::Thread { - DistributedFrameBuffer *dfb; - ProcThread(DistributedFrameBuffer *dfb) : dfb(dfb) {}; - virtual void run(); - }; - ProcThread procThread; -#endif - //! get number of pixels per tile, in x and y direction vec2i getTileSize() const { return vec2i(TILE_SIZE); }; @@ -263,32 +252,6 @@ namespace ospray { tiles. will be null on all workers, and _may_ be null on the master if the master does not have a color buffer */ Ref localFBonMaster; -#if QUEUE_PROCESSING_JOBS - struct MsgTaskQueue { - std::queue > queue; - Mutex mutex; - - void addJob(Task *task) { - mutex.lock(); - queue.push(task); - mutex.unlock(); - } - - void waitAll() { - mutex.lock(); - while (!queue.empty()) { - Ref task = queue.front(); - queue.pop(); - mutex.unlock(); - task->wait(); - mutex.lock(); - } - mutex.unlock(); - } - }; - MsgTaskQueue msgTaskQueue; -#endif - inline bool IamTheMaster() const { return comm->IamTheMaster(); } //! constructor From de8b6426b66d935b7fce10e00df0d0287d01582d Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 22 Feb 2016 13:52:06 -0600 Subject: [PATCH 031/310] mpi device compiling now, too --- ospray/CMakeLists.txt | 1 + ospray/mpi/DistributedFrameBuffer.cpp | 3 +-- ospray/mpi/async/Messaging.h | 2 -- ospray/mpi/worker.cpp | 4 ++-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index eb8fb46279..17a7806c9e 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -360,6 +360,7 @@ IF (OSPRAY_MPI) ADD_EXECUTABLE(ospray_mpi_worker${OSPRAY_EXE_SUFFIX} mpi/MPIWorker.cpp) TARGET_LINK_LIBRARIES(ospray_mpi_worker${OSPRAY_EXE_SUFFIX} ospray${OSPRAY_LIB_SUFFIX}) + SET_TARGET_PROPERTIES(ospray_mpi_worker${OSPRAY_EXE_SUFFIX} PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_OSPCOMMON_H=1") # ------------------------------------------------------------ INSTALL(TARGETS ospray_mpi_worker${OSPRAY_EXE_SUFFIX} DESTINATION bin) ENDIF() diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 3db10699dc..adacc2da41 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -17,8 +17,7 @@ #include "DistributedFrameBuffer.h" #include "DistributedFrameBuffer_ispc.h" -// embree -#include "common/sys/thread.h" +#include #include "ospray/common/parallel_for.h" diff --git a/ospray/mpi/async/Messaging.h b/ospray/mpi/async/Messaging.h index 798c52b9f4..54be512893 100644 --- a/ospray/mpi/async/Messaging.h +++ b/ospray/mpi/async/Messaging.h @@ -20,8 +20,6 @@ #include "ospray/common/Thread.h" namespace ospray { - using embree::thread_t; - namespace mpi { //! abstraction for any other peer node that we might want to communicate with diff --git a/ospray/mpi/worker.cpp b/ospray/mpi/worker.cpp index d700b5ebea..0a69dfb7ce 100644 --- a/ospray/mpi/worker.cpp +++ b/ospray/mpi/worker.cpp @@ -61,14 +61,14 @@ namespace ospray { using std::endl; struct GeometryLocator { - bool operator()(const embree::Ref &g) const { + bool operator()(const Ref &g) const { return ptr == &*g; } Geometry *ptr; }; struct VolumeLocator { - bool operator()(const embree::Ref &g) const { + bool operator()(const Ref &g) const { return ptr == &*g; } Volume *ptr; From 0c44c8c6122f465fdd06a6201774f4c5ea63f7c2 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 22 Feb 2016 15:17:21 -0600 Subject: [PATCH 032/310] knc and mpi working --- CMakeLists.txt | 26 ++++++++++++++----- apps/volumeViewer/CMakeLists.txt | 4 --- common/CMakeLists.txt | 11 +++++++- common/RefCount.h | 15 +++++++++-- ospray/CMakeLists.txt | 17 ++++++++++-- .../embree-v2.7.1/common/simd/CMakeLists.txt | 1 + .../embree-v2.7.1/common/sys/CMakeLists.txt | 1 + .../kernels/xeonphi/CMakeLists.txt | 2 +- 8 files changed, 61 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 636e6d8222..32dfd87997 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,14 +133,28 @@ STRING(TOLOWER "${OSPRAY_INSTALL_TARGET}" OSPRAY_INSTALL_TARGET_LC) # the ospray common library that's shared across all projects ############################################################## +SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}) +SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) + #INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) #INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) -SET (OSPRAY_TARGET "intel64") -ADD_SUBDIRECTORY(common builddir/ospcommon/intel64) -IF (OSPRAY_MIC) - SET (OSPRAY_TARGET "mic") - ADD_SUBDIRECTORY(common builddir/ospcommon/mic) -ENDIF() +#IF (OSPRAY_MIC) +# SET (OSPRAY_TARGET "mic") +# SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}/mic) +# SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}/mic) +# SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}/mic) + +# ADD_SUBDIRECTORY(common builddir/ospcommon/mic) +#ELSE() +# SET (OSPRAY_TARGET "intel64") +# SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}/intel64) +# SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}/intel64) +# SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +# ADD_SUBDIRECTORY(common builddir/ospcommon/intel64) +#ENDIF() + +#ADD_SUBDIRECTORY(common builddir/ospcommon/intel64) ############################################################## # the ospray library diff --git a/apps/volumeViewer/CMakeLists.txt b/apps/volumeViewer/CMakeLists.txt index f713d7a9bd..62a6ecb675 100644 --- a/apps/volumeViewer/CMakeLists.txt +++ b/apps/volumeViewer/CMakeLists.txt @@ -14,10 +14,6 @@ ## limitations under the License. ## ## ======================================================================== ## -IF (NOT OSPRAY_MODULE_LOADERS) - message(FATAL_ERROR "The 'loaders' module must be enabled to build the 'ospVolumeViewer' application.") -ENDIF (NOT OSPRAY_MODULE_LOADERS) - IF (NOT OSPRAY_MODULE_OPENGL_UTIL) message(FATAL_ERROR "The 'OpenGL util' module must be enabled to build the 'ospVolumeViewer' application.") ENDIF (NOT OSPRAY_MODULE_OPENGL_UTIL) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 2e6ae7b881..943a02a935 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,4 +1,13 @@ -ADD_LIBRARY(ospray_ospcommon SHARED +MESSAGE("including ospcommon... bin dir ${LIBRARY_OUTPUT_PATH}") + +IF (DEFINED FORCED_OSPCOMMON_LIB_NAME) + SET(OSPCOMMON_LIB_NAME ${FORCED_OSPCOMMON_LIB_NAME}) +ELSE() + SET(OSPCOMMON_LIB_NAME ospray_ospcommon) +ENDIF() + +ADD_LIBRARY(${OSPCOMMON_LIB_NAME} + SHARED # STATIC common.cpp FileName.cpp diff --git a/common/RefCount.h b/common/RefCount.h index 62e7f5b05c..2078f4dc8f 100644 --- a/common/RefCount.h +++ b/common/RefCount.h @@ -23,7 +23,7 @@ homebrewed one */ namespace ospcommon { -#if defined(__X86_64__) +#if defined(__X86_64__) || defined(__MIC__) typedef std::atomic_llong atomic_t; #else typedef std::atomic_int atomic_t; @@ -35,8 +35,19 @@ namespace ospcommon class RefCount { public: - RefCount(int val = 0) : refCounter(val) {} + inline RefCount(int val = 0) : refCounter(val) {} virtual ~RefCount() {}; + + /*! dummy copy-constructor and assignment operator because if they + do not exist icc throws some error about "delted function" + when auto-constructing those. they should NEVER get called, + though */ + inline RefCount(const RefCount &other) { throw std::runtime_error("should not copy-construc refence-counted objects!"); } + /*! dummy copy-constructor and assignment operator because if they + do not exist icc throws some error about "delted function" + when auto-constructing those. they should NEVER get called, + though */ + inline RefCount &operator=(const RefCount &other) { throw std::runtime_error("should not copy-construc refence-counted objects!"); return *this; } virtual void refInc() { refCounter++; } virtual void refDec() { if ((--refCounter) == 0) delete this; } diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 17a7806c9e..72af566b13 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -18,6 +18,19 @@ # on which target we build for ) CONFIGURE_OSPRAY() +IF(THIS_IS_MIC) + SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}/mic) + SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) + SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) + SET(FORCED_OSPCOMMON_LIB_NAME "ospray_ospcommon_mic") + ADD_SUBDIRECTORY(../common ospcommon_mic) +ELSE() + SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}) + SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) + SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) + SET(FORCED_OSPCOMMON_LIB_NAME "ospray_ospcommon") + ADD_SUBDIRECTORY(../common ospcommon) +ENDIF() IF(OSPRAY_BUILD_MPI_DEVICE) OPTION(OSPRAY_EXP_DATA_PARALLEL "Experimental data-parallel compositing mode") @@ -294,10 +307,10 @@ ENDIF() ############################################################## OSPRAY_ADD_LIBRARY(ospray${OSPRAY_LIB_SUFFIX} SHARED ${OSPRAY_SOURCES}) -SET_TARGET_PROPERTIES(ospray PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_OSPCOMMON_H=1") +SET_TARGET_PROPERTIES(ospray${OSPRAY_LIB_SUFFIX} PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_OSPCOMMON_H=1") TARGET_LINK_LIBRARIES(ospray${OSPRAY_LIB_SUFFIX} - ospray_ospcommon${OSPRAY_LIB_SUFFIX} + ${FORCED_OSPCOMMON_LIB_NAME} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} ) diff --git a/ospray/embree-v2.7.1/common/simd/CMakeLists.txt b/ospray/embree-v2.7.1/common/simd/CMakeLists.txt index fdef9c8db9..1a7a830fda 100644 --- a/ospray/embree-v2.7.1/common/simd/CMakeLists.txt +++ b/ospray/embree-v2.7.1/common/simd/CMakeLists.txt @@ -28,5 +28,6 @@ IF (__XEON__) ELSE () INCLUDE(icc_xeonphi) ADD_LIBRARY(simd_xeonphi STATIC vboolf16_avx512.cpp) + SET_TARGET_PROPERTIES(simd_xeonphi PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") ENDIF () diff --git a/ospray/embree-v2.7.1/common/sys/CMakeLists.txt b/ospray/embree-v2.7.1/common/sys/CMakeLists.txt index c0caf0a308..9b7d378602 100644 --- a/ospray/embree-v2.7.1/common/sys/CMakeLists.txt +++ b/ospray/embree-v2.7.1/common/sys/CMakeLists.txt @@ -81,5 +81,6 @@ ADD_LIBRARY(sys_xeonphi STATIC ) TARGET_LINK_LIBRARIES(sys_xeonphi ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) +SET_TARGET_PROPERTIES(sys_xeonphi PROPERTIES COMPILE_FLAGS "-DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1") ENDIF () diff --git a/ospray/embree-v2.7.1/kernels/xeonphi/CMakeLists.txt b/ospray/embree-v2.7.1/kernels/xeonphi/CMakeLists.txt index 9005a723ca..5f875da26a 100644 --- a/ospray/embree-v2.7.1/kernels/xeonphi/CMakeLists.txt +++ b/ospray/embree-v2.7.1/kernels/xeonphi/CMakeLists.txt @@ -24,7 +24,7 @@ INCLUDE(icc_xeonphi) -ADD_DEFINITIONS(-D__TARGET_XEON_PHI__) +ADD_DEFINITIONS(-D__TARGET_XEON_PHI__ -DDONT_WARN_INCLUDE_EMBREE_INTERNALS=1) ADD_ISPC_LIBRARY(embree_xeonphi ${EMBREE_LIB_TYPE} From 7693568386c47d11ad9553a153bbe76bbbcdf51c Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 22 Feb 2016 15:19:11 -0600 Subject: [PATCH 033/310] no longer using /mic builddir, at last for now --- ospray/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 72af566b13..a1e4d61ae2 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -19,15 +19,15 @@ CONFIGURE_OSPRAY() IF(THIS_IS_MIC) - SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}/mic) - SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) - SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +# SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}/mic) +# SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +# SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) SET(FORCED_OSPCOMMON_LIB_NAME "ospray_ospcommon_mic") ADD_SUBDIRECTORY(../common ospcommon_mic) ELSE() - SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}) - SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) - SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +# SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}) +# SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +# SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) SET(FORCED_OSPCOMMON_LIB_NAME "ospray_ospcommon") ADD_SUBDIRECTORY(../common ospcommon) ENDIF() From fb39cab2aaad5cad2d599a08aeb33a58f3e9bcad Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 23 Feb 2016 20:26:51 -0600 Subject: [PATCH 034/310] DFB freezing issue seems to go away when tbb::priorty_high is removed --- ospray/mpi/DistributedFrameBuffer.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 9f37d0ed66..dbece32b22 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -558,13 +558,9 @@ namespace ospray { DBG(PING); -#if 0//NOTE(jda) - Using TBB here is causing a mysterious "freeze"...the process message task - // should be handled asynchronously without the need to hold on to any - // future to the task. Code currently disabled until it can be fixed, but - / / this will suffice as a "workaround" for now. -//#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_USE_TBB auto &t = *new(tbb::task::allocate_root())DFBProcessMessageTask(this, _msg); - tbb::task::enqueue(t, tbb::priority_high); + tbb::task::enqueue(t); #else DFBProcessMessageTask t(this, _msg); t.execute(); From 7ff68bdfb1d615994c449c8958c7813fd7c23695 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 24 Feb 2016 09:30:41 -0700 Subject: [PATCH 035/310] ispc version 1.8.2 --- apps/volumeViewer/CMakeLists.txt | 4 ---- apps/volumeViewer/loaders/CMakeLists.txt | 4 ---- cmake/ispc.cmake | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/apps/volumeViewer/CMakeLists.txt b/apps/volumeViewer/CMakeLists.txt index f713d7a9bd..62a6ecb675 100644 --- a/apps/volumeViewer/CMakeLists.txt +++ b/apps/volumeViewer/CMakeLists.txt @@ -14,10 +14,6 @@ ## limitations under the License. ## ## ======================================================================== ## -IF (NOT OSPRAY_MODULE_LOADERS) - message(FATAL_ERROR "The 'loaders' module must be enabled to build the 'ospVolumeViewer' application.") -ENDIF (NOT OSPRAY_MODULE_LOADERS) - IF (NOT OSPRAY_MODULE_OPENGL_UTIL) message(FATAL_ERROR "The 'OpenGL util' module must be enabled to build the 'ospVolumeViewer' application.") ENDIF (NOT OSPRAY_MODULE_OPENGL_UTIL) diff --git a/apps/volumeViewer/loaders/CMakeLists.txt b/apps/volumeViewer/loaders/CMakeLists.txt index ea30802c81..ddd40880e4 100644 --- a/apps/volumeViewer/loaders/CMakeLists.txt +++ b/apps/volumeViewer/loaders/CMakeLists.txt @@ -14,12 +14,9 @@ ## limitations under the License. ## ## ======================================================================== ## -OPTION(OSPRAY_MODULE_LOADERS "Build loaders for common file types." ON) - CONFIGURE_OSPRAY() IF (NOT THIS_IS_MIC) - IF (OSPRAY_MODULE_LOADERS) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) @@ -47,6 +44,5 @@ IF (NOT THIS_IS_MIC) PROPERTIES VERSION ${OSPRAY_VERSION} SOVERSION ${OSPRAY_SOVERSION}) INSTALL(TARGETS ospray_module_loaders${OSPRAY_LIB_SUFFIX} DESTINATION lib) - ENDIF (OSPRAY_MODULE_LOADERS) ENDIF (NOT THIS_IS_MIC) diff --git a/cmake/ispc.cmake b/cmake/ispc.cmake index 0d94a4d1d2..250f1d233f 100644 --- a/cmake/ispc.cmake +++ b/cmake/ispc.cmake @@ -17,7 +17,7 @@ IF(WIN32) SET(ISPC_VERSION_REQUIRED "1.8.2") ELSE() - SET(ISPC_VERSION_REQUIRED "1.8.1") + SET(ISPC_VERSION_REQUIRED "1.8.2") ENDIF() SET(ISPC_VERSION_RECOMMENDED_KNC "1.8.1") From 3931641b9dd72f8d7ca0a5ced0e9e6db03b6d4ee Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 24 Feb 2016 09:33:32 -0700 Subject: [PATCH 036/310] allowing both 1.8.1 and 1.8.2 of ispc on non-windows --- cmake/ispc.cmake | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/ispc.cmake b/cmake/ispc.cmake index 250f1d233f..e951f31e17 100644 --- a/cmake/ispc.cmake +++ b/cmake/ispc.cmake @@ -16,8 +16,10 @@ IF(WIN32) SET(ISPC_VERSION_REQUIRED "1.8.2") + SET(ISPC_VERSION_ALLOWED "1.8.2") ELSE() - SET(ISPC_VERSION_REQUIRED "1.8.2") + SET(ISPC_VERSION_REQUIRED "1.8.1") + SET(ISPC_VERSION_ALLOWED "1.8.2") ENDIF() SET(ISPC_VERSION_RECOMMENDED_KNC "1.8.1") @@ -30,7 +32,10 @@ IF (NOT ISPC_EXECUTABLE) ELSE() SET(ISPC_DIR_SUFFIX "linux") ENDIF() - SET(ISPC_DIR_HINT ${PROJECT_SOURCE_DIR}/../ispc-v${ISPC_VERSION_REQUIRED}-${ISPC_DIR_SUFFIX}) + SET(ISPC_DIR_HINT + ${PROJECT_SOURCE_DIR}/../ispc-v${ISPC_VERSION_REQUIRED}-${ISPC_DIR_SUFFIX} + ${PROJECT_SOURCE_DIR}/../ispc-v${ISPC_VERSION_ALLOWED}-${ISPC_DIR_SUFFIX} + ) FIND_PROGRAM(ISPC_EXECUTABLE ispc PATHS ${ISPC_DIR_HINT} DOC "Path to the ISPC executable.") IF (NOT ISPC_EXECUTABLE) From 0f4187a4b6c9f1c378151339afd149a6e01526a5 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 24 Feb 2016 12:38:08 -0700 Subject: [PATCH 037/310] first draft of strict-c ospray.h API. still using dummy osp::vec types in cplusplus mode --- apps/volumeViewer/ProbeWidget.cpp | 2 +- apps/volumeViewer/main.cpp | 2 +- ospray/api/API.cpp | 1408 ++++++++++++++-------------- ospray/api/Device.h | 1 + ospray/include/ospray/OSPTexture.h | 2 +- ospray/include/ospray/ospray.h | 502 ++++++---- 6 files changed, 1021 insertions(+), 896 deletions(-) diff --git a/apps/volumeViewer/ProbeWidget.cpp b/apps/volumeViewer/ProbeWidget.cpp index 86600c0fd9..8aa0daef7e 100644 --- a/apps/volumeViewer/ProbeWidget.cpp +++ b/apps/volumeViewer/ProbeWidget.cpp @@ -137,7 +137,7 @@ void ProbeWidget::updateProbe() if (volume) { float *results = NULL; - ospSampleVolume(&results, volume, (osp::vec3f*)&coordinate, 1); + ospSampleVolume(results, volume, (osp::vec3f*)&coordinate, 1); if (!results) std::cout << "error calling ospSampleVolume()" << std::endl; diff --git a/apps/volumeViewer/main.cpp b/apps/volumeViewer/main.cpp index 04087ceb54..64dbb2c430 100644 --- a/apps/volumeViewer/main.cpp +++ b/apps/volumeViewer/main.cpp @@ -203,7 +203,7 @@ int main(int argc, char *argv[]) if (i + 1 >= argc) throw std::runtime_error("missing argument"); std::string moduleName = argv[++i]; std::cout << "loading module '" << moduleName << "'." << std::endl; - error_t error = ospLoadModule(moduleName.c_str()); + int error = ospLoadModule(moduleName.c_str()); if(error != 0) { std::ostringstream ss; diff --git a/ospray/api/API.cpp b/ospray/api/API.cpp index 4bf79ea047..a71bb26763 100644 --- a/ospray/api/API.cpp +++ b/ospray/api/API.cpp @@ -64,11 +64,11 @@ namespace ospray { } // ::ospray - std::string getPidString() { - char s[100]; - sprintf(s, "(pid %i)", getpid()); - return s; - } +std::string getPidString() { + char s[100]; + sprintf(s, "(pid %i)", getpid()); + return s; +} #define ASSERT_DEVICE() if (ospray::api::Device::current == NULL) \ throw std::runtime_error("OSPRay not yet initialized " \ @@ -76,739 +76,747 @@ namespace ospray { "call an ospray API function before " \ "first calling ospInit())"+getPidString()); - using namespace ospray; +using namespace ospray; - extern "C" void ospInit(int *_ac, const char **_av) - { - if (ospray::api::Device::current) { - throw std::runtime_error("OSPRay error: device already exists " - "(did you call ospInit twice?)"); - } +extern "C" void ospInit(int *_ac, const char **_av) +{ + if (ospray::api::Device::current) { + throw std::runtime_error("OSPRay error: device already exists " + "(did you call ospInit twice?)"); + } - auto *nThreads = getenv("OSPRAY_THREADS"); - if (nThreads) { - numThreads = atoi(nThreads); - } + auto *nThreads = getenv("OSPRAY_THREADS"); + if (nThreads) { + numThreads = atoi(nThreads); + } - /* call ospray::init to properly parse common args like - --osp:verbose, --osp:debug etc */ - ospray::init(_ac,&_av); + /* call ospray::init to properly parse common args like + --osp:verbose, --osp:debug etc */ + ospray::init(_ac,&_av); - const char *OSP_MPI_LAUNCH_FROM_ENV = getenv("OSPRAY_MPI_LAUNCH"); + const char *OSP_MPI_LAUNCH_FROM_ENV = getenv("OSPRAY_MPI_LAUNCH"); - if (OSP_MPI_LAUNCH_FROM_ENV) { + if (OSP_MPI_LAUNCH_FROM_ENV) { #ifdef OSPRAY_MPI - std::cout << "#osp: launching ospray mpi ring - make sure that mpd is running" << std::endl; - ospray::api::Device::current - = mpi::createMPI_LaunchWorkerGroup(_ac,_av,OSP_MPI_LAUNCH_FROM_ENV); + std::cout << "#osp: launching ospray mpi ring - make sure that mpd is running" << std::endl; + ospray::api::Device::current + = mpi::createMPI_LaunchWorkerGroup(_ac,_av,OSP_MPI_LAUNCH_FROM_ENV); #else - throw std::runtime_error("OSPRay MPI support not compiled in"); + throw std::runtime_error("OSPRay MPI support not compiled in"); #endif - } + } - if (_ac && _av) { - // we're only supporting local rendering for now - network device - // etc to come. - for (int i=1;i<*_ac;i++) { + if (_ac && _av) { + // we're only supporting local rendering for now - network device + // etc to come. + for (int i=1;i<*_ac;i++) { - if (std::string(_av[i]) == "--osp:mpi") { + if (std::string(_av[i]) == "--osp:mpi") { #ifdef OSPRAY_MPI - removeArgs(*_ac,(char **&)_av,i,1); - ospray::api::Device::current - = mpi::createMPI_RanksBecomeWorkers(_ac,_av); + removeArgs(*_ac,(char **&)_av,i,1); + ospray::api::Device::current + = mpi::createMPI_RanksBecomeWorkers(_ac,_av); #else - throw std::runtime_error("OSPRay MPI support not compiled in"); + throw std::runtime_error("OSPRay MPI support not compiled in"); #endif - --i; - continue; - } + --i; + continue; + } - if (std::string(_av[i]) == "--osp:coi") { + if (std::string(_av[i]) == "--osp:coi") { #ifdef __MIC__ - throw std::runtime_error("The COI device can only be created on the host"); + throw std::runtime_error("The COI device can only be created on the host"); #elif defined(OSPRAY_MIC_COI) - removeArgs(*_ac,(char **&)_av,i,1); - ospray::api::Device::current - = ospray::coi::createCoiDevice(_ac,_av); + removeArgs(*_ac,(char **&)_av,i,1); + ospray::api::Device::current + = ospray::coi::createCoiDevice(_ac,_av); #else - throw std::runtime_error("OSPRay's COI support not compiled in"); + throw std::runtime_error("OSPRay's COI support not compiled in"); #endif - --i; - continue; - } + --i; + continue; + } - if (std::string(_av[i]) == "--osp:mpi-launch") { + if (std::string(_av[i]) == "--osp:mpi-launch") { #ifdef OSPRAY_MPI - if (i+2 > *_ac) - throw std::runtime_error("--osp:mpi-launch expects an argument"); - const char *launchCommand = strdup(_av[i+1]); - removeArgs(*_ac,(char **&)_av,i,2); - ospray::api::Device::current - = mpi::createMPI_LaunchWorkerGroup(_ac,_av,launchCommand); + if (i+2 > *_ac) + throw std::runtime_error("--osp:mpi-launch expects an argument"); + const char *launchCommand = strdup(_av[i+1]); + removeArgs(*_ac,(char **&)_av,i,2); + ospray::api::Device::current + = mpi::createMPI_LaunchWorkerGroup(_ac,_av,launchCommand); #else - throw std::runtime_error("OSPRay MPI support not compiled in"); + throw std::runtime_error("OSPRay MPI support not compiled in"); #endif - --i; - continue; - } + --i; + continue; + } - const char *listenArgName = "--osp:mpi-listen"; - if (!strncmp(_av[i],listenArgName,strlen(listenArgName))) { + const char *listenArgName = "--osp:mpi-listen"; + if (!strncmp(_av[i],listenArgName,strlen(listenArgName))) { #ifdef OSPRAY_MPI - const char *fileNameToStorePortIn = NULL; - if (strlen(_av[i]) > strlen(listenArgName)) { - fileNameToStorePortIn = strdup(_av[i]+strlen(listenArgName)+1); - } - removeArgs(*_ac,(char **&)_av,i,1); - ospray::api::Device::current - = mpi::createMPI_ListenForWorkers(_ac,_av,fileNameToStorePortIn); + const char *fileNameToStorePortIn = NULL; + if (strlen(_av[i]) > strlen(listenArgName)) { + fileNameToStorePortIn = strdup(_av[i]+strlen(listenArgName)+1); + } + removeArgs(*_ac,(char **&)_av,i,1); + ospray::api::Device::current + = mpi::createMPI_ListenForWorkers(_ac,_av,fileNameToStorePortIn); #else - throw std::runtime_error("OSPRay MPI support not compiled in"); + throw std::runtime_error("OSPRay MPI support not compiled in"); #endif - --i; - continue; - } - + --i; + continue; } - } - - // no device created on cmd line, yet, so default to localdevice - if (ospray::api::Device::current == NULL) { - ospray::api::Device::current = new ospray::api::LocalDevice(_ac,_av); - } - } - - - /*! destroy a given frame buffer. - - due to internal reference counting the framebuffer may or may not be deleted immediately - */ - extern "C" void ospFreeFrameBuffer(OSPFrameBuffer fb) - { - ASSERT_DEVICE(); - Assert(fb != NULL); - ospray::api::Device::current->release(fb); - } - - extern "C" OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, - const OSPFrameBufferFormat mode, - const uint32_t channels) - { - ASSERT_DEVICE(); - return ospray::api::Device::current->frameBufferCreate((const vec2i&)size,mode,channels); - } - - //! load module \ from shard lib libospray_module_\.so, or - extern "C" error_t ospLoadModule(const char *moduleName) - { - ASSERT_DEVICE(); - return ospray::api::Device::current->loadModule(moduleName); - } - - extern "C" const void *ospMapFrameBuffer(OSPFrameBuffer fb, - OSPFrameBufferChannel channel) - { - ASSERT_DEVICE(); - return ospray::api::Device::current->frameBufferMap(fb,channel); - } - - extern "C" void ospUnmapFrameBuffer(const void *mapped, - OSPFrameBuffer fb) - { - ASSERT_DEVICE(); - Assert(mapped != NULL && "invalid mapped pointer in ospUnmapFrameBuffer"); - ospray::api::Device::current->frameBufferUnmap(mapped,fb); - } - - extern "C" OSPModel ospNewModel() - { - ASSERT_DEVICE(); - return ospray::api::Device::current->newModel(); - } - - extern "C" void ospAddGeometry(OSPModel model, OSPGeometry geometry) - { - ASSERT_DEVICE(); - Assert(model != NULL && "invalid model in ospAddGeometry"); - Assert(geometry != NULL && "invalid geometry in ospAddGeometry"); - return ospray::api::Device::current->addGeometry(model,geometry); - } - - extern "C" void ospAddVolume(OSPModel model, OSPVolume volume) - { - ASSERT_DEVICE(); - Assert(model != NULL && "invalid model in ospAddVolume"); - Assert(volume != NULL && "invalid volume in ospAddVolume"); - return ospray::api::Device::current->addVolume(model, volume); - } - - extern "C" void ospRemoveGeometry(OSPModel model, OSPGeometry geometry) - { - ASSERT_DEVICE(); - Assert(model != NULL && "invalid model in ospRemoveGeometry"); - Assert(geometry != NULL && "invalid geometry in ospRemoveGeometry"); - return ospray::api::Device::current->removeGeometry(model, geometry); - } - - /*! create a new data buffer, with optional init data and control flags */ - extern "C" OSPData ospNewData(size_t nitems, OSPDataType format, const void *init, const uint32_t flags) - { - ASSERT_DEVICE(); - return ospray::api::Device::current->newData(nitems,format,(void*)init,flags); - } - /*! add a data array to another object */ - extern "C" void ospSetData(OSPObject object, const char *bufName, OSPData data) - { - // assert(!rendering); - ASSERT_DEVICE(); - LOG("ospSetData(...,\"" << bufName << "\",...)"); - return ospray::api::Device::current->setObject(object,bufName,(OSPObject)data); - } - - /*! add an object parameter to another object */ - extern "C" void ospSetParam(OSPObject target, const char *bufName, OSPObject value) - { - ASSERT_DEVICE(); - static bool warned = false; - if (!warned) { - std::cout << "'ospSetParam()' has been deprecated. Please use the new naming convention of 'ospSetObject()' instead" << std::endl; - warned = true; } - LOG("ospSetParam(...,\"" << bufName << "\",...)"); - return ospray::api::Device::current->setObject(target,bufName,value); - } - - /*! set/add a pixel op to a frame buffer */ - extern "C" void ospSetPixelOp(OSPFrameBuffer fb, OSPPixelOp op) - { - ASSERT_DEVICE(); - LOG("ospSetPixelOp(...,...)"); - return ospray::api::Device::current->setPixelOp(fb,op); - } - - /*! add an object parameter to another object */ - extern "C" void ospSetObject(OSPObject target, const char *bufName, OSPObject value) - { - ASSERT_DEVICE(); - LOG("ospSetObject(...,\"" << bufName << "\",...)"); - return ospray::api::Device::current->setObject(target,bufName,value); - } - - /*! \brief create a new pixelOp of given type - - return 'NULL' if that type is not known */ - extern "C" OSPPixelOp ospNewPixelOp(const char *_type) - { - ASSERT_DEVICE(); - Assert2(_type,"invalid render type identifier in ospNewPixelOp"); - LOG("ospNewPixelOp(" << _type << ")"); - int L = strlen(_type); - char *type = (char *)alloca(L+1); - for (int i=0;i<=L;i++) { - char c = _type[i]; - if (c == '-' || c == ':') - c = '_'; - type[i] = c; - } - OSPPixelOp pixelOp = ospray::api::Device::current->newPixelOp(type); - return pixelOp; - } - - /*! \brief create a new renderer of given type - - return 'NULL' if that type is not known */ - extern "C" OSPRenderer ospNewRenderer(const char *_type) - { - ASSERT_DEVICE(); - - Assert2(_type,"invalid render type identifier in ospNewRenderer"); - LOG("ospNewRenderer(" << _type << ")"); - - std::string type(_type); - for (size_t i = 0; i < type.size(); i++) { - if (type[i] == '-' || type[i] == ':') - type[i] = '_'; - } - OSPRenderer renderer = ospray::api::Device::current->newRenderer(type.c_str()); - if ((ospray::logLevel > 0) && (renderer == NULL)) { - std::cerr << "#ospray: could not create renderer '" << type << "'" << std::endl; - } - return renderer; - } - - /*! \brief create a new geometry of given type - - return 'NULL' if that type is not known */ - extern "C" OSPGeometry ospNewGeometry(const char *type) - { - ASSERT_DEVICE(); - Assert(type != NULL && "invalid geometry type identifier in ospNewGeometry"); - LOG("ospNewGeometry(" << type << ")"); - OSPGeometry geometry = ospray::api::Device::current->newGeometry(type); - if ((ospray::logLevel > 0) && (geometry == NULL)) - std::cerr << "#ospray: could not create geometry '" << type << "'" << std::endl; - return geometry; - } - - /*! \brief create a new material of given type - - return 'NULL' if that type is not known */ - extern "C" OSPMaterial ospNewMaterial(OSPRenderer renderer, const char *type) - { - ASSERT_DEVICE(); - // Assert2(renderer != NULL, "invalid renderer handle in ospNewMaterial"); - Assert2(type != NULL, "invalid material type identifier in ospNewMaterial"); - LOG("ospNewMaterial(" << renderer << ", " << type << ")"); - OSPMaterial material = ospray::api::Device::current->newMaterial(renderer, type); - if ((ospray::logLevel > 0) && (material == NULL)) - std::cerr << "#ospray: could not create material '" << type << "'" << std::endl; - return material; - } - - extern "C" OSPLight ospNewLight(OSPRenderer renderer, const char *type) - { - ASSERT_DEVICE(); - Assert2(type != NULL, "invalid light type identifier in ospNewLight"); - LOG("ospNewLight(" << renderer << ", " << type << ")"); - OSPLight light = ospray::api::Device::current->newLight(renderer, type); - if ((ospray::logLevel > 0) && (light == NULL)) - std::cerr << "#ospray: could not create light '" << type << "'" << std::endl; - return light; - } - - /*! \brief create a new camera of given type - - return 'NULL' if that type is not known */ - extern "C" OSPCamera ospNewCamera(const char *type) - { - ASSERT_DEVICE(); - Assert(type != NULL && "invalid camera type identifier in ospNewCamera"); - LOG("ospNewCamera(" << type << ")"); - OSPCamera camera = ospray::api::Device::current->newCamera(type); - if ((ospray::logLevel > 0) && (camera == NULL)) - std::cerr << "#ospray: could not create camera '" << type << "'" << std::endl; - return camera; } - extern "C" OSPTexture2D ospNewTexture2D(const osp::vec2i &size, - const OSPTextureFormat type, - void *data, - const uint32_t flags) - { - ASSERT_DEVICE(); - Assert2(size.x > 0, "Width must be greater than 0 in ospNewTexture2D"); - Assert2(size.y > 0, "Height must be greater than 0 in ospNewTexture2D"); - LOG("ospNewTexture2D( (" << size.x << ", " << size.y << "), " << type << ", " << data << ", " << flags << ")"); - return ospray::api::Device::current->newTexture2D((const vec2i&)size, type, data, flags); - } - - /*! \brief create a new volume of given type, return 'NULL' if that type is not known */ - extern "C" OSPVolume ospNewVolume(const char *type) - { - ASSERT_DEVICE(); - Assert(type != NULL && "invalid volume type identifier in ospNewVolume"); - LOG("ospNewVolume(" << type << ")"); - OSPVolume volume = ospray::api::Device::current->newVolume(type); - if (ospray::logLevel > 0) { - if (volume) - cout << "ospNewVolume: " << ((ospray::Volume*)volume)->toString() << endl; - else - std::cerr << "#ospray: could not create volume '" << type << "'" << std::endl; - } - if ((ospray::logLevel > 0) && (volume == NULL)) + // no device created on cmd line, yet, so default to localdevice + if (ospray::api::Device::current == NULL) { + ospray::api::Device::current = new ospray::api::LocalDevice(_ac,_av); + } +} + + +/*! destroy a given frame buffer. + + due to internal reference counting the framebuffer may or may not be deleted immediately +*/ +extern "C" void ospFreeFrameBuffer(OSPFrameBuffer fb) +{ + ASSERT_DEVICE(); + Assert(fb != NULL); + ospray::api::Device::current->release(fb); +} + +extern "C" OSPFrameBuffer ospNewFrameBuffer(const int *size, //osp::vec2i &size, + const OSPFrameBufferFormat mode, + const uint32_t channels) +{ + ASSERT_DEVICE(); + return ospray::api::Device::current->frameBufferCreate((const vec2i&)*size,mode,channels); +} + +//! load module \ from shard lib libospray_module_\.so, or +extern "C" int32_t ospLoadModule(const char *moduleName) +{ + ASSERT_DEVICE(); + return ospray::api::Device::current->loadModule(moduleName); +} + +extern "C" const void *ospMapFrameBuffer(OSPFrameBuffer fb, + OSPFrameBufferChannel channel) +{ + ASSERT_DEVICE(); + return ospray::api::Device::current->frameBufferMap(fb,channel); +} + +extern "C" void ospUnmapFrameBuffer(const void *mapped, + OSPFrameBuffer fb) +{ + ASSERT_DEVICE(); + Assert(mapped != NULL && "invalid mapped pointer in ospUnmapFrameBuffer"); + ospray::api::Device::current->frameBufferUnmap(mapped,fb); +} + +extern "C" OSPModel ospNewModel() +{ + ASSERT_DEVICE(); + return ospray::api::Device::current->newModel(); +} + +extern "C" void ospAddGeometry(OSPModel model, OSPGeometry geometry) +{ + ASSERT_DEVICE(); + Assert(model != NULL && "invalid model in ospAddGeometry"); + Assert(geometry != NULL && "invalid geometry in ospAddGeometry"); + return ospray::api::Device::current->addGeometry(model,geometry); +} + +extern "C" void ospAddVolume(OSPModel model, OSPVolume volume) +{ + ASSERT_DEVICE(); + Assert(model != NULL && "invalid model in ospAddVolume"); + Assert(volume != NULL && "invalid volume in ospAddVolume"); + return ospray::api::Device::current->addVolume(model, volume); +} + +extern "C" void ospRemoveGeometry(OSPModel model, OSPGeometry geometry) +{ + ASSERT_DEVICE(); + Assert(model != NULL && "invalid model in ospRemoveGeometry"); + Assert(geometry != NULL && "invalid geometry in ospRemoveGeometry"); + return ospray::api::Device::current->removeGeometry(model, geometry); +} + +/*! create a new data buffer, with optional init data and control flags */ +extern "C" OSPData ospNewData(size_t nitems, OSPDataType format, const void *init, const uint32_t flags) +{ + ASSERT_DEVICE(); + return ospray::api::Device::current->newData(nitems,format,(void*)init,flags); +} + +/*! add a data array to another object */ +extern "C" void ospSetData(OSPObject object, const char *bufName, OSPData data) +{ + // assert(!rendering); + ASSERT_DEVICE(); + LOG("ospSetData(...,\"" << bufName << "\",...)"); + return ospray::api::Device::current->setObject(object,bufName,(OSPObject)data); +} + +/*! add an object parameter to another object */ +extern "C" void ospSetParam(OSPObject target, const char *bufName, OSPObject value) +{ + ASSERT_DEVICE(); + static bool warned = false; + if (!warned) { + std::cout << "'ospSetParam()' has been deprecated. Please use the new naming convention of 'ospSetObject()' instead" << std::endl; + warned = true; + } + LOG("ospSetParam(...,\"" << bufName << "\",...)"); + return ospray::api::Device::current->setObject(target,bufName,value); +} + +/*! set/add a pixel op to a frame buffer */ +extern "C" void ospSetPixelOp(OSPFrameBuffer fb, OSPPixelOp op) +{ + ASSERT_DEVICE(); + LOG("ospSetPixelOp(...,...)"); + return ospray::api::Device::current->setPixelOp(fb,op); +} + +/*! add an object parameter to another object */ +extern "C" void ospSetObject(OSPObject target, const char *bufName, OSPObject value) +{ + ASSERT_DEVICE(); + LOG("ospSetObject(...,\"" << bufName << "\",...)"); + return ospray::api::Device::current->setObject(target,bufName,value); +} + +/*! \brief create a new pixelOp of given type + + return 'NULL' if that type is not known */ +extern "C" OSPPixelOp ospNewPixelOp(const char *_type) +{ + ASSERT_DEVICE(); + Assert2(_type,"invalid render type identifier in ospNewPixelOp"); + LOG("ospNewPixelOp(" << _type << ")"); + int L = strlen(_type); + char *type = (char *)alloca(L+1); + for (int i=0;i<=L;i++) { + char c = _type[i]; + if (c == '-' || c == ':') + c = '_'; + type[i] = c; + } + OSPPixelOp pixelOp = ospray::api::Device::current->newPixelOp(type); + return pixelOp; +} + +/*! \brief create a new renderer of given type + + return 'NULL' if that type is not known */ +extern "C" OSPRenderer ospNewRenderer(const char *_type) +{ + ASSERT_DEVICE(); + + Assert2(_type,"invalid render type identifier in ospNewRenderer"); + LOG("ospNewRenderer(" << _type << ")"); + + std::string type(_type); + for (size_t i = 0; i < type.size(); i++) { + if (type[i] == '-' || type[i] == ':') + type[i] = '_'; + } + OSPRenderer renderer = ospray::api::Device::current->newRenderer(type.c_str()); + if ((ospray::logLevel > 0) && (renderer == NULL)) { + std::cerr << "#ospray: could not create renderer '" << type << "'" << std::endl; + } + return renderer; +} + +/*! \brief create a new geometry of given type + + return 'NULL' if that type is not known */ +extern "C" OSPGeometry ospNewGeometry(const char *type) +{ + ASSERT_DEVICE(); + Assert(type != NULL && "invalid geometry type identifier in ospNewGeometry"); + LOG("ospNewGeometry(" << type << ")"); + OSPGeometry geometry = ospray::api::Device::current->newGeometry(type); + if ((ospray::logLevel > 0) && (geometry == NULL)) + std::cerr << "#ospray: could not create geometry '" << type << "'" << std::endl; + return geometry; +} + +/*! \brief create a new material of given type + + return 'NULL' if that type is not known */ +extern "C" OSPMaterial ospNewMaterial(OSPRenderer renderer, const char *type) +{ + ASSERT_DEVICE(); + // Assert2(renderer != NULL, "invalid renderer handle in ospNewMaterial"); + Assert2(type != NULL, "invalid material type identifier in ospNewMaterial"); + LOG("ospNewMaterial(" << renderer << ", " << type << ")"); + OSPMaterial material = ospray::api::Device::current->newMaterial(renderer, type); + if ((ospray::logLevel > 0) && (material == NULL)) + std::cerr << "#ospray: could not create material '" << type << "'" << std::endl; + return material; +} + +extern "C" OSPLight ospNewLight(OSPRenderer renderer, const char *type) +{ + ASSERT_DEVICE(); + Assert2(type != NULL, "invalid light type identifier in ospNewLight"); + LOG("ospNewLight(" << renderer << ", " << type << ")"); + OSPLight light = ospray::api::Device::current->newLight(renderer, type); + if ((ospray::logLevel > 0) && (light == NULL)) + std::cerr << "#ospray: could not create light '" << type << "'" << std::endl; + return light; +} + +/*! \brief create a new camera of given type + + return 'NULL' if that type is not known */ +extern "C" OSPCamera ospNewCamera(const char *type) +{ + ASSERT_DEVICE(); + Assert(type != NULL && "invalid camera type identifier in ospNewCamera"); + LOG("ospNewCamera(" << type << ")"); + OSPCamera camera = ospray::api::Device::current->newCamera(type); + if ((ospray::logLevel > 0) && (camera == NULL)) + std::cerr << "#ospray: could not create camera '" << type << "'" << std::endl; + return camera; +} + +extern "C" OSPTexture2D ospNewTexture2D(const int32_t *size, //osp::vec2i &size, + const OSPTextureFormat type, + void *data, + const uint32_t flags) +{ + ASSERT_DEVICE(); + assert(size != NULL); + Assert2(size[0] > 0, "Width must be greater than 0 in ospNewTexture2D"); + Assert2(size[1] > 0, "Height must be greater than 0 in ospNewTexture2D"); + LOG("ospNewTexture2D( (" << size[0] << ", " << size[1] << "), " << type << ", " << data << ", " << flags << ")"); + return ospray::api::Device::current->newTexture2D((const vec2i&)*size, type, data, flags); +} + +/*! \brief create a new volume of given type, return 'NULL' if that type is not known */ +extern "C" OSPVolume ospNewVolume(const char *type) +{ + ASSERT_DEVICE(); + Assert(type != NULL && "invalid volume type identifier in ospNewVolume"); + LOG("ospNewVolume(" << type << ")"); + OSPVolume volume = ospray::api::Device::current->newVolume(type); + if (ospray::logLevel > 0) { + if (volume) + cout << "ospNewVolume: " << ((ospray::Volume*)volume)->toString() << endl; + else std::cerr << "#ospray: could not create volume '" << type << "'" << std::endl; - return volume; - } - - /*! \brief create a new transfer function of given type - return 'NULL' if that type is not known */ - extern "C" OSPTransferFunction ospNewTransferFunction(const char *type) - { - ASSERT_DEVICE(); - Assert(type != NULL && "invalid transfer function type identifier in ospNewTransferFunction"); - LOG("ospNewTransferFunction(" << type << ")"); - OSPTransferFunction transferFunction = ospray::api::Device::current->newTransferFunction(type); - if(ospray::logLevel > 0) { - if(transferFunction) - cout << "ospNewTransferFunction: " << ((ospray::TransferFunction*)transferFunction)->toString() << endl; - else - std::cerr << "#ospray: could not create transfer function '" << type << "'" << std::endl; - } - if ((ospray::logLevel > 0) && (transferFunction == NULL)) - std::cerr << "#ospray: could not create transferFunction '" << type << "'" << std::endl; - return transferFunction; - } - - extern "C" void ospFrameBufferClear(OSPFrameBuffer fb, - const uint32_t fbChannelFlags) - { - ASSERT_DEVICE(); - ospray::api::Device::current->frameBufferClear(fb,fbChannelFlags); } - - /*! \brief call a renderer to render given model into given framebuffer - - model _may_ be empty (though most framebuffers will expect one!) */ - extern "C" void ospRenderFrame(OSPFrameBuffer fb, - OSPRenderer renderer, - const uint32_t fbChannelFlags - ) - { - ASSERT_DEVICE(); + if ((ospray::logLevel > 0) && (volume == NULL)) + std::cerr << "#ospray: could not create volume '" << type << "'" << std::endl; + return volume; +} + +/*! \brief create a new transfer function of given type + return 'NULL' if that type is not known */ +extern "C" OSPTransferFunction ospNewTransferFunction(const char *type) +{ + ASSERT_DEVICE(); + Assert(type != NULL && "invalid transfer function type identifier in ospNewTransferFunction"); + LOG("ospNewTransferFunction(" << type << ")"); + OSPTransferFunction transferFunction = ospray::api::Device::current->newTransferFunction(type); + if(ospray::logLevel > 0) { + if(transferFunction) + cout << "ospNewTransferFunction: " << ((ospray::TransferFunction*)transferFunction)->toString() << endl; + else + std::cerr << "#ospray: could not create transfer function '" << type << "'" << std::endl; + } + if ((ospray::logLevel > 0) && (transferFunction == NULL)) + std::cerr << "#ospray: could not create transferFunction '" << type << "'" << std::endl; + return transferFunction; +} + +extern "C" void ospFrameBufferClear(OSPFrameBuffer fb, + const uint32_t fbChannelFlags) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->frameBufferClear(fb,fbChannelFlags); +} + +/*! \brief call a renderer to render given model into given framebuffer + + model _may_ be empty (though most framebuffers will expect one!) */ +extern "C" void ospRenderFrame(OSPFrameBuffer fb, + OSPRenderer renderer, + const uint32_t fbChannelFlags + ) +{ + ASSERT_DEVICE(); #if 0 - double t0 = ospray::getSysTime(); - ospray::api::Device::current->renderFrame(fb,renderer,fbChannelFlags); - double t_frame = ospray::getSysTime() - t0; - static double nom = 0.f; - static double den = 0.f; - den = 0.95f*den + 1.f; - nom = 0.95f*nom + t_frame; - std::cout << "done rendering, time per frame = " << (t_frame*1000.f) << "ms, avg'ed fps = " << (den/nom) << std::endl; + double t0 = ospray::getSysTime(); + ospray::api::Device::current->renderFrame(fb,renderer,fbChannelFlags); + double t_frame = ospray::getSysTime() - t0; + static double nom = 0.f; + static double den = 0.f; + den = 0.95f*den + 1.f; + nom = 0.95f*nom + t_frame; + std::cout << "done rendering, time per frame = " << (t_frame*1000.f) << "ms, avg'ed fps = " << (den/nom) << std::endl; #else - // rendering = true; - ospray::api::Device::current->renderFrame(fb,renderer,fbChannelFlags); - // rendering = false; + // rendering = true; + ospray::api::Device::current->renderFrame(fb,renderer,fbChannelFlags); + // rendering = false; #endif - } - - extern "C" void ospCommit(OSPObject object) - { - // assert(!rendering); - - ASSERT_DEVICE(); - Assert(object && "invalid object handle to commit to"); - LOG("ospCommit(...)"); - ospray::api::Device::current->commit(object); - } - - extern "C" void ospSetString(OSPObject _object, const char *id, const char *s) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setString(_object,id,s); - } - - extern "C" void ospSetf(OSPObject _object, const char *id, float x) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setFloat(_object,id,x); - } - - extern "C" void ospSet1f(OSPObject _object, const char *id, float x) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setFloat(_object,id,x); - } - extern "C" void ospSet1i(OSPObject _object, const char *id, int32_t x) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setInt(_object,id,x); - } - - extern "C" void ospSeti(OSPObject _object, const char *id, int x) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setInt(_object,id,x); - } - - /*! Copy data into the given volume. */ - extern "C" int ospSetRegion(OSPVolume object, void *source, - const osp::vec3i &index, - const osp::vec3i &count) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->setRegion(object, source, (const vec3i&)index, (const vec3i&)count)); - } - - /*! add a vec2f parameter to an object */ - extern "C" void ospSetVec2f(OSPObject _object, const char *id, const osp::vec2f &v) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec2f(_object, id, (const vec2f &)v); - } - - /*! add a vec2i parameter to an object */ - extern "C" void ospSetVec2i(OSPObject _object, const char *id, const osp::vec2i &v) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec2i(_object, id, (const vec2i &)v); - } - - /*! add a vec3f parameter to another object */ - extern "C" void ospSetVec3f(OSPObject _object, const char *id, const osp::vec3f &v) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec3f(_object,id,(const vec3f &)v); - } - - /*! add a vec4f parameter to another object */ - extern "C" void ospSetVec4f(OSPObject _object, const char *id, const osp::vec4f &v) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec4f(_object,id,(const vec4f &)v); - } - - /*! add a vec3i parameter to another object */ - extern "C" void ospSetVec3i(OSPObject _object, const char *id, const osp::vec3i &v) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec3i(_object,id,(const vec3i &)v); - } - - /*! add a vec2f parameter to another object */ - extern "C" void ospSet2f(OSPObject _object, const char *id, float x, float y) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec2f(_object,id,ospray::vec2f(x,y)); - } - - /*! add a vec2f parameter to another object */ - extern "C" void ospSet2fv(OSPObject _object, const char *id, const float *xy) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec2f(_object,id,vec2f(xy[0],xy[1])); - } - - /*! add a vec2i parameter to another object */ - extern "C" void ospSet2i(OSPObject _object, const char *id, int x, int y) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec2i(_object,id,vec2i(x,y)); - } - - /*! add a vec2i parameter to another object */ - extern "C" void ospSet2iv(OSPObject _object, const char *id, const int *xy) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec2i(_object,id,vec2i(xy[0],xy[1])); - } - - /*! add a vec3f parameter to another object */ - extern "C" void ospSet3f(OSPObject _object, const char *id, float x, float y, float z) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec3f(_object,id,vec3f(x,y,z)); - } - - /*! add a vec3f parameter to another object */ - extern "C" void ospSet3fv(OSPObject _object, const char *id, const float *xyz) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec3f(_object,id,vec3f(xyz[0],xyz[1],xyz[2])); - } - - /*! add a vec3i parameter to another object */ - extern "C" void ospSet3i(OSPObject _object, const char *id, int x, int y, int z) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec3i(_object,id,vec3i(x,y,z)); - } - - /*! add a vec3i parameter to another object */ - extern "C" void ospSet3iv(OSPObject _object, const char *id, const int *xyz) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec3i(_object,id,vec3i(xyz[0],xyz[1],xyz[2])); - } - - /*! add a vec4f parameter to another object */ - extern "C" void ospSet4f(OSPObject _object, const char *id, float x, float y, float z, float w) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec4f(_object,id,vec4f(x,y,z,w)); - } - - /*! add a vec4f parameter to another object */ - extern "C" void ospSet4fv(OSPObject _object, const char *id, const float *xyzw) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVec4f(_object,id,vec4f(xyzw[0],xyzw[1],xyzw[2],xyzw[3])); - } - - /*! add a void pointer to another object */ - extern "C" void ospSetVoidPtr(OSPObject _object, const char *id, void *v) - { - ASSERT_DEVICE(); - ospray::api::Device::current->setVoidPtr(_object,id,v); - } - - extern "C" void ospRelease(OSPObject _object) - { - ASSERT_DEVICE(); - if (!_object) return; - ospray::api::Device::current->release(_object); - } - - //! assign given material to given geometry - extern "C" void ospSetMaterial(OSPGeometry geometry, OSPMaterial material) - { - ASSERT_DEVICE(); - Assert2(geometry,"NULL geometry passed to ospSetMaterial"); - ospray::api::Device::current->setMaterial(geometry,material); - } - - //! Get the handle of the named data array associated with an object. - extern "C" int ospGetData(OSPObject object, const char *name, OSPData *value) { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getData(object, name, value)); - } - - //! Get a copy of the data in an array (the application is responsible for freeing this pointer). - extern "C" int ospGetDataValues(OSPData object, void **pointer, size_t *count, OSPDataType *type) { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getDataValues(object, pointer, count, type)); - } - - //! Get the named scalar floating point value associated with an object. - extern "C" int ospGetf(OSPObject object, const char *name, float *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getf(object, name, value)); - } - - //! Get the named scalar integer associated with an object. - extern "C" int ospGeti(OSPObject object, const char *name, int *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->geti(object, name, value)); - } - - //! Get the material associated with a geometry object. - extern "C" int ospGetMaterial(OSPGeometry geometry, OSPMaterial *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getMaterial(geometry, value)); - } - - //! Get the named object associated with an object. - extern "C" int ospGetObject(OSPObject object, const char *name, OSPObject *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getObject(object, name, value)); - } - - //! Retrieve a NULL-terminated list of the parameter names associated with an object. - extern "C" int ospGetParameters(OSPObject object, char ***value) { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getParameters(object, value)); - } - - //! Get a pointer to a copy of the named character string associated with an object. - extern "C" int ospGetString(OSPObject object, const char *name, char **value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getString(object, name, value)); - } - - //! Get the type of the named parameter or the given object (if 'name' is NULL). - extern "C" int ospGetType(OSPObject object, const char *name, OSPDataType *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getType(object, name, value)); - } - - //! Get the named 2-vector floating point value associated with an object. - extern "C" int ospGetVec2f(OSPObject object, const char *name, osp::vec2f *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getVec2f(object, name, (vec2f *)value)); - } - - //! Get the named 3-vector floating point value associated with an object. - extern "C" int ospGetVec3f(OSPObject object, const char *name, osp::vec3f *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getVec3f(object, name, (vec3f *)value)); - } - - //! Get the named 3-vector integer value associated with an object. - extern "C" int ospGetVec3i(OSPObject object, const char *name, osp::vec3i *value) - { - ASSERT_DEVICE(); - return(ospray::api::Device::current->getVec3i(object, name, (vec3i *)value)); - } - - /*! \brief create a new instance geometry that instantiates another - model. the resulting geometry still has to be added to another - model via ospAddGeometry */ - extern "C" OSPGeometry ospNewInstance(OSPModel modelToInstantiate, - const osp::affine3f &xfm) - { - ASSERT_DEVICE(); - // return ospray::api::Device::current->newInstance(modelToInstantiate,xfm); - OSPGeometry geom = ospNewGeometry("instance"); - ospSet3fv(geom,"xfm.l.vx",&xfm.l.vx.x); - ospSet3fv(geom,"xfm.l.vy",&xfm.l.vy.x); - ospSet3fv(geom,"xfm.l.vz",&xfm.l.vz.x); - ospSet3fv(geom,"xfm.p",&xfm.p.x); - ospSetObject(geom,"model",modelToInstantiate); - return geom; - } - - extern "C" void ospPick(OSPPickResult *result, OSPRenderer renderer, const osp::vec2f &screenPos) - { - ASSERT_DEVICE(); - Assert2(renderer, "NULL renderer passed to ospPick"); - if (!result) return; - *result = ospray::api::Device::current->pick(renderer, (const vec2f &)screenPos); - } - - //! \brief allows for switching the MPI scope from "per rank" to "all ranks" - extern "C" void ospdApiMode(OSPDApiMode mode) - { - ASSERT_DEVICE(); - ospray::api::Device::current->apiMode(mode); - } +} + +extern "C" void ospCommit(OSPObject object) +{ + // assert(!rendering); + + ASSERT_DEVICE(); + Assert(object && "invalid object handle to commit to"); + LOG("ospCommit(...)"); + ospray::api::Device::current->commit(object); +} + +extern "C" void ospSetString(OSPObject _object, const char *id, const char *s) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setString(_object,id,s); +} + +extern "C" void ospSetf(OSPObject _object, const char *id, float x) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setFloat(_object,id,x); +} + +extern "C" void ospSet1f(OSPObject _object, const char *id, float x) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setFloat(_object,id,x); +} +extern "C" void ospSet1i(OSPObject _object, const char *id, int32_t x) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setInt(_object,id,x); +} + +extern "C" void ospSeti(OSPObject _object, const char *id, int x) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setInt(_object,id,x); +} + +/*! Copy data into the given volume. */ +extern "C" int ospSetRegion(OSPVolume object, + void *source, + const int *index, //const osp::vec3i &index, + const int *count //const osp::vec3i &count + ) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->setRegion(object, source, + (const vec3i&)*index, + (const vec3i&)*count)); +} + +/*! add a vec2f parameter to an object */ +extern "C" void ospSetVec2f(OSPObject _object, const char *id, const osp::vec2f &v) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec2f(_object, id, (const vec2f &)v); +} + +/*! add a vec2i parameter to an object */ +extern "C" void ospSetVec2i(OSPObject _object, const char *id, const osp::vec2i &v) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec2i(_object, id, (const vec2i &)v); +} + +/*! add a vec3f parameter to another object */ +extern "C" void ospSetVec3f(OSPObject _object, const char *id, const osp::vec3f &v) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec3f(_object,id,(const vec3f &)v); +} + +/*! add a vec4f parameter to another object */ +extern "C" void ospSetVec4f(OSPObject _object, const char *id, const osp::vec4f &v) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec4f(_object,id,(const vec4f &)v); +} + +/*! add a vec3i parameter to another object */ +extern "C" void ospSetVec3i(OSPObject _object, const char *id, const osp::vec3i &v) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec3i(_object,id,(const vec3i &)v); +} + +/*! add a vec2f parameter to another object */ +extern "C" void ospSet2f(OSPObject _object, const char *id, float x, float y) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec2f(_object,id,ospray::vec2f(x,y)); +} + +/*! add a vec2f parameter to another object */ +extern "C" void ospSet2fv(OSPObject _object, const char *id, const float *xy) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec2f(_object,id,vec2f(xy[0],xy[1])); +} + +/*! add a vec2i parameter to another object */ +extern "C" void ospSet2i(OSPObject _object, const char *id, int x, int y) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec2i(_object,id,vec2i(x,y)); +} + +/*! add a vec2i parameter to another object */ +extern "C" void ospSet2iv(OSPObject _object, const char *id, const int *xy) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec2i(_object,id,vec2i(xy[0],xy[1])); +} + +/*! add a vec3f parameter to another object */ +extern "C" void ospSet3f(OSPObject _object, const char *id, float x, float y, float z) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec3f(_object,id,vec3f(x,y,z)); +} + +/*! add a vec3f parameter to another object */ +extern "C" void ospSet3fv(OSPObject _object, const char *id, const float *xyz) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec3f(_object,id,vec3f(xyz[0],xyz[1],xyz[2])); +} + +/*! add a vec3i parameter to another object */ +extern "C" void ospSet3i(OSPObject _object, const char *id, int x, int y, int z) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec3i(_object,id,vec3i(x,y,z)); +} + +/*! add a vec3i parameter to another object */ +extern "C" void ospSet3iv(OSPObject _object, const char *id, const int *xyz) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec3i(_object,id,vec3i(xyz[0],xyz[1],xyz[2])); +} + +/*! add a vec4f parameter to another object */ +extern "C" void ospSet4f(OSPObject _object, const char *id, float x, float y, float z, float w) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec4f(_object,id,vec4f(x,y,z,w)); +} + +/*! add a vec4f parameter to another object */ +extern "C" void ospSet4fv(OSPObject _object, const char *id, const float *xyzw) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVec4f(_object,id,vec4f(xyzw[0],xyzw[1],xyzw[2],xyzw[3])); +} + +/*! add a void pointer to another object */ +extern "C" void ospSetVoidPtr(OSPObject _object, const char *id, void *v) +{ + ASSERT_DEVICE(); + ospray::api::Device::current->setVoidPtr(_object,id,v); +} + +extern "C" void ospRelease(OSPObject _object) +{ + ASSERT_DEVICE(); + if (!_object) return; + ospray::api::Device::current->release(_object); +} + +//! assign given material to given geometry +extern "C" void ospSetMaterial(OSPGeometry geometry, OSPMaterial material) +{ + ASSERT_DEVICE(); + Assert2(geometry,"NULL geometry passed to ospSetMaterial"); + ospray::api::Device::current->setMaterial(geometry,material); +} + +//! Get the handle of the named data array associated with an object. +extern "C" int ospGetData(OSPObject object, const char *name, OSPData *value) { + ASSERT_DEVICE(); + return(ospray::api::Device::current->getData(object, name, value)); +} + +//! Get a copy of the data in an array (the application is responsible for freeing this pointer). +extern "C" int ospGetDataValues(OSPData object, void **pointer, size_t *count, OSPDataType *type) { + ASSERT_DEVICE(); + return(ospray::api::Device::current->getDataValues(object, pointer, count, type)); +} + +//! Get the named scalar floating point value associated with an object. +extern "C" int ospGetf(OSPObject object, const char *name, float *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getf(object, name, value)); +} + +//! Get the named scalar integer associated with an object. +extern "C" int ospGeti(OSPObject object, const char *name, int *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->geti(object, name, value)); +} + +//! Get the material associated with a geometry object. +extern "C" int ospGetMaterial(OSPGeometry geometry, OSPMaterial *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getMaterial(geometry, value)); +} + +//! Get the named object associated with an object. +extern "C" int ospGetObject(OSPObject object, const char *name, OSPObject *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getObject(object, name, value)); +} + +//! Retrieve a NULL-terminated list of the parameter names associated with an object. +extern "C" int ospGetParameters(OSPObject object, char ***value) { + ASSERT_DEVICE(); + return(ospray::api::Device::current->getParameters(object, value)); +} + +//! Get a pointer to a copy of the named character string associated with an object. +extern "C" int ospGetString(OSPObject object, const char *name, char **value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getString(object, name, value)); +} + +//! Get the type of the named parameter or the given object (if 'name' is NULL). +extern "C" int ospGetType(OSPObject object, const char *name, OSPDataType *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getType(object, name, value)); +} + +//! Get the named 2-vector floating point value associated with an object. +extern "C" int ospGetVec2f(OSPObject object, const char *name, osp::vec2f *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getVec2f(object, name, (vec2f *)value)); +} + +//! Get the named 3-vector floating point value associated with an object. +extern "C" int ospGetVec3f(OSPObject object, const char *name, osp::vec3f *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getVec3f(object, name, (vec3f *)value)); +} + +//! Get the named 3-vector integer value associated with an object. +extern "C" int ospGetVec3i(OSPObject object, const char *name, osp::vec3i *value) +{ + ASSERT_DEVICE(); + return(ospray::api::Device::current->getVec3i(object, name, (vec3i *)value)); +} + +/*! \brief create a new instance geometry that instantiates another + model. the resulting geometry still has to be added to another + model via ospAddGeometry */ +extern "C" OSPGeometry ospNewInstance(OSPModel modelToInstantiate, + const float *_xfm) //const osp::affine3f &xfm) +{ + ASSERT_DEVICE(); + const osp::affine3f xfm = *(const osp::affine3f *)_xfm; + // return ospray::api::Device::current->newInstance(modelToInstantiate,xfm); + OSPGeometry geom = ospNewGeometry("instance"); + ospSet3fv(geom,"xfm.l.vx",&xfm.l.vx.x); + ospSet3fv(geom,"xfm.l.vy",&xfm.l.vy.x); + ospSet3fv(geom,"xfm.l.vz",&xfm.l.vz.x); + ospSet3fv(geom,"xfm.p",&xfm.p.x); + ospSetObject(geom,"model",modelToInstantiate); + return geom; +} + +extern "C" void ospPick(OSPPickResult *result, OSPRenderer renderer, + const float *screenPos//const osp::vec2f &screenPos + ) +{ + ASSERT_DEVICE(); + Assert2(renderer, "NULL renderer passed to ospPick"); + if (!result) return; + *result = ospray::api::Device::current->pick(renderer, (const vec2f &)*screenPos); +} + +//! \brief allows for switching the MPI scope from "per rank" to "all ranks" +// extern "C" void ospdApiMode(OSPDApiMode mode) +// { +// ASSERT_DEVICE(); +// ospray::api::Device::current->apiMode(mode); +// } #ifdef OSPRAY_MPI - //! \brief initialize the ospray engine (for use with MPI-parallel app) - /*! \detailed Note the application must call this function "INSTEAD OF" - MPI_Init(), NOT "in addition to" */ - extern "C" void ospdMpiInit(int *ac, char ***av, OSPDRenderMode mode) - { - if (ospray::api::Device::current != NULL) - throw std::runtime_error("#osp:mpi: OSPRay already initialized!?"); - ospray::mpi::initDistributedAPI(ac,av,mode); - } - - //! the 'lid to the pot' of ospdMpiInit(). - /*! does both an osp shutdown and an mpi shutdown for the mpi group - created with ospdMpiInit */ - extern "C" void ospdMpiShutdown() - { - } +//! \brief initialize the ospray engine (for use with MPI-parallel app) +/*! \detailed Note the application must call this function "INSTEAD OF" + MPI_Init(), NOT "in addition to" */ +extern "C" void ospdMpiInit(int *ac, char ***av, OSPDRenderMode mode) +{ + if (ospray::api::Device::current != NULL) + throw std::runtime_error("#osp:mpi: OSPRay already initialized!?"); + ospray::mpi::initDistributedAPI(ac,av,mode); +} + +//! the 'lid to the pot' of ospdMpiInit(). +/*! does both an osp shutdown and an mpi shutdown for the mpi group + created with ospdMpiInit */ +extern "C" void ospdMpiShutdown() +{ +} #endif - extern "C" OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos) - { - static bool warned = false; - if (!warned) { - std::cout << "'ospUnproject()' has been deprecated. Please use the new function 'ospPick()' instead" << std::endl; - warned = true; - } - ASSERT_DEVICE(); - Assert2(renderer, "NULL renderer passed to ospUnproject"); - vec2f flippedScreenPos = vec2f(screenPos.x, 1.0f - screenPos.y); - OSPPickResult pick = ospray::api::Device::current->pick(renderer, flippedScreenPos); - OSPPickData res = { pick.hit, pick.position.x, pick.position.y, pick.position.z }; - return res; - } - - extern "C" void ospSampleVolume(float **results, - OSPVolume volume, - const osp::vec3f *worldCoordinates, - const size_t &count) - { - ASSERT_DEVICE(); - Assert2(volume, "NULL volume passed to ospSampleVolume"); - - if (count == 0) { - *results = NULL; - return; - } - - Assert2(worldCoordinates, "NULL worldCoordinates passed to ospSampleVolume"); - - ospray::api::Device::current->sampleVolume(results, volume, (const vec3f *)worldCoordinates, count); - } +// extern "C" OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos) +// { +// static bool warned = false; +// if (!warned) { +// std::cout << "'ospUnproject()' has been deprecated. Please use the new function 'ospPick()' instead" << std::endl; +// warned = true; +// } +// ASSERT_DEVICE(); +// Assert2(renderer, "NULL renderer passed to ospUnproject"); +// vec2f flippedScreenPos = vec2f(screenPos.x, 1.0f - screenPos.y); +// OSPPickResult pick = ospray::api::Device::current->pick(renderer, flippedScreenPos); +// OSPPickData res = { pick.hit, pick.position.x, pick.position.y, pick.position.z }; +// return res; +// } + +extern "C" void ospSampleVolume(float **results, + OSPVolume volume, + const float *worldCoordinates, //const osp::vec3f *worldCoordinates, + const size_t count) +{ + ASSERT_DEVICE(); + Assert2(volume, "NULL volume passed to ospSampleVolume"); + + if (count == 0) { + *results = NULL; + return; + } + + Assert2(worldCoordinates, "NULL worldCoordinates passed to ospSampleVolume"); + + ospray::api::Device::current->sampleVolume(results, volume, (const vec3f *)worldCoordinates, count); +} diff --git a/ospray/api/Device.h b/ospray/api/Device.h index bbddf398a0..9044eb182b 100644 --- a/ospray/api/Device.h +++ b/ospray/api/Device.h @@ -228,6 +228,7 @@ namespace ospray { throw std::runtime_error("pick() not impelemnted for this device"); }; + typedef int OSPDApiMode; /*! switch API mode for distriubted API extensions */ virtual void apiMode(OSPDApiMode mode) { diff --git a/ospray/include/ospray/OSPTexture.h b/ospray/include/ospray/OSPTexture.h index b79719447f..55390cc281 100644 --- a/ospray/include/ospray/OSPTexture.h +++ b/ospray/include/ospray/OSPTexture.h @@ -19,7 +19,7 @@ /*! OSPRay format constants for Texture creation */ typedef enum { - OSP_TEXTURE_RGBA8, + OSP_TEXTURE_RGBA8=100, OSP_TEXTURE_SRGBA, OSP_TEXTURE_RGBA32F, OSP_TEXTURE_RGB8, diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 3cf55e58e5..f36c032478 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -23,7 +23,7 @@ \brief Defines the public API for the OSPRay core \{ - */ +*/ #pragma once @@ -46,113 +46,73 @@ #ifdef _WIN32 # ifdef ospray_EXPORTS -# define OSPRAY_INTERFACE __declspec(dllexport) +# define OSPRAY_INTERFACE __declspec(dllexport) # else -# define OSPRAY_INTERFACE __declspec(dllimport) +# define OSPRAY_INTERFACE __declspec(dllimport) # endif #else -# define OSPRAY_INTERFACE +# define OSPRAY_INTERFACE #endif #ifdef __GNUC__ - #define OSP_DEPRECATED __attribute__((deprecated)) +#define OSP_DEPRECATED __attribute__((deprecated)) #elif defined(_MSC_VER) - #define OSP_DEPRECATED __declspec(deprecated) +#define OSP_DEPRECATED __declspec(deprecated) #else - #define OSP_DEPRECATED +#define OSP_DEPRECATED #endif -/*! namespace for classes in the public core API */ -namespace osp { - - struct vec2f { float x, y; }; - struct vec2i { int x, y; }; - struct vec3f { float x, y, z; }; - struct vec3fa { float x, y, z; union { int a; unsigned u; float w; }; }; - struct vec3i { int x, y, z; }; - struct vec4f { float x, y, z, w; }; - struct box2i { vec2i lower, upper; }; - struct box3f { vec3f lower, upper; }; - struct linear3f { vec3f vx, vy, vz; }; - struct affine3f { linear3f l; vec3f p; }; - - typedef uint64_t uint64; - - struct ManagedObject { uint64 ID; virtual ~ManagedObject() {} }; - struct FrameBuffer : public ManagedObject {}; - struct Renderer : public ManagedObject {}; - struct Camera : public ManagedObject {}; - struct Model : public ManagedObject {}; - struct Data : public ManagedObject {}; - struct Geometry : public ManagedObject {}; - struct Material : public ManagedObject {}; - struct Volume : public ManagedObject {}; - struct TransferFunction : public ManagedObject {}; - struct Texture2D : public ManagedObject {}; - struct Light : public ManagedObject {}; - struct PixelOp : public ManagedObject {}; - -} // ::osp - -/*! OSPRay channel constants for Frame Buffer (can be OR'ed together) */ -typedef enum { - OSP_FB_COLOR=(1<<0), - OSP_FB_DEPTH=(1<<1), - OSP_FB_ACCUM=(1<<2), -// OSP_FB_ALPHA=(1<<3) // not used anywhere; use OSP_FB_COLOR with a frame buffer format containing alpha in 4th channel -} OSPFrameBufferChannel; - /*! OSPRay format constants for Frame Buffer creation */ typedef enum { OSP_FB_NONE, //!< framebuffer will not be mapped by application OSP_FB_RGBA8, //!< one dword per pixel: rgb+alpha, each one byte OSP_FB_RGBA32F, //!< one float4 per pixel: rgb+alpha, each one float -/* TODO - OSP_FB_RGB8, //!< three 8-bit unsigned chars per pixel - OSP_FB_RGB32F, ? - OSP_FB_SRGBA, //!< one dword per pixel: rgb (in sRGB space) + alpha, each one byte - OSP_FB_SRGB, //!< three 8-bit unsigned chars (in sRGB space) per pixel -*/ -// deprecated names + /* TODO + OSP_FB_RGB8, //!< three 8-bit unsigned chars per pixel + OSP_FB_RGB32F, ? + OSP_FB_SRGBA, //!< one dword per pixel: rgb (in sRGB space) + alpha, each one byte + OSP_FB_SRGB, //!< three 8-bit unsigned chars (in sRGB space) per pixel + */ + // deprecated names OSP_RGBA_NONE = OSP_FB_NONE, OSP_RGBA_I8 = OSP_FB_RGBA8, OSP_RGBA_F32 = OSP_FB_RGBA32F, OSP_RGB_I8/* = OSP_FB_RGB8 XXX unsupported! */ } OSPFrameBufferFormat; -//! constants for switching the OSPRay MPI Scope between 'per rank' and 'all ranks' -/*! \see ospdApiMode */ -typedef enum { - //! \brief all ospNew(), ospSet(), etc calls affect only the current rank - /*! \detailed in this mode, all ospXyz() calls made on a given rank - will ONLY affect state ont hat rank. This allows for configuring a - (globally known) object differnetly on each different rank (also - see OSP_MPI_SCOPE_GLOBAL) */ - OSPD_MODE_INDEPENDENT, - OSPD_RANK=OSPD_MODE_INDEPENDENT /*!< alias for OSP_MODE_INDEPENDENT, reads better in code */, - - //! \brief all ospNew(), ospSet() calls affect all ranks - /*! \detailed In this mode, ONLY rank 0 should call ospXyz() - functions, but all objects defined through those functions---and - all parameters set through those---will apply equally to all - ranks. E.g., a OSPVolume vol = ospNewVolume(...) would create a - volume object handle that exists on (and therefore, is valid on) - all ranks. The (distributed) app may then switch to 'current - rank only' mode, and may assign different data or parameters on - each rank (typically, in order to have different parts of the - volume on different nodes), but the object itself is globally - known */ - OSPD_MODE_MASTERED, - OSPD_MASTER=OSPD_MODE_MASTERED /*!< alias for OSP_MODE_MASTERED, reads better in code */, - - //! \brief all ospNew(), ospSet() are called collaboratively by all ranks - /*! \detailed In this mode, ALL ranks must call (the same!) api - function, the result is collaborative across all nodes in the - sense that any object being created gets created across all - nodes, and ALL ranks get a valid handle returned */ - OSPD_MODE_COLLABORATIVE, - OSPD_ALL=OSPD_MODE_COLLABORATIVE /*!< alias for OSP_MODE_COLLABORATIVE, reads better in code */ -} OSPDApiMode; +// //! constants for switching the OSPRay MPI Scope between 'per rank' and 'all ranks' +// /*! \see ospdApiMode */ +// typedef enum { +// //! \brief all ospNew(), ospSet(), etc calls affect only the current rank +// /*! \detailed in this mode, all ospXyz() calls made on a given rank +// will ONLY affect state ont hat rank. This allows for configuring a +// (globally known) object differnetly on each different rank (also +// see OSP_MPI_SCOPE_GLOBAL) */ +// OSPD_MODE_INDEPENDENT, +// OSPD_RANK=OSPD_MODE_INDEPENDENT /*!< alias for OSP_MODE_INDEPENDENT, reads better in code */, + +// //! \brief all ospNew(), ospSet() calls affect all ranks +// /*! \detailed In this mode, ONLY rank 0 should call ospXyz() +// functions, but all objects defined through those functions---and +// all parameters set through those---will apply equally to all +// ranks. E.g., a OSPVolume vol = ospNewVolume(...) would create a +// volume object handle that exists on (and therefore, is valid on) +// all ranks. The (distributed) app may then switch to 'current +// rank only' mode, and may assign different data or parameters on +// each rank (typically, in order to have different parts of the +// volume on different nodes), but the object itself is globally +// known */ +// OSPD_MODE_MASTERED, +// OSPD_MASTER=OSPD_MODE_MASTERED /*!< alias for OSP_MODE_MASTERED, reads better in code */, + +// //! \brief all ospNew(), ospSet() are called collaboratively by all ranks +// /*! \detailed In this mode, ALL ranks must call (the same!) api +// function, the result is collaborative across all nodes in the +// sense that any object being created gets created across all +// nodes, and ALL ranks get a valid handle returned */ +// OSPD_MODE_COLLABORATIVE, +// OSPD_ALL=OSPD_MODE_COLLABORATIVE /*!< alias for OSP_MODE_COLLABORATIVE, reads better in code */ +// } OSPDApiMode; // /*! flags that can be passed to OSPNewGeometry; can be OR'ed together */ // typedef enum { @@ -172,6 +132,51 @@ typedef enum { OSP_GENERAL_ERROR /*! unspecified error */ } OSPResult; +/*! OSPRay channel constants for Frame Buffer (can be OR'ed together) */ +typedef enum { + OSP_FB_COLOR=(1<<0), + OSP_FB_DEPTH=(1<<1), + OSP_FB_ACCUM=(1<<2), + // OSP_FB_ALPHA=(1<<3) // not used anywhere; use OSP_FB_COLOR with a frame buffer format containing alpha in 4th channel +} OSPFrameBufferChannel; + +typedef enum { + OSPD_Z_COMPOSITE +} OSPDRenderMode; + + +#ifdef __cplusplus +namespace osp { + /*! namespace for classes in the public core API */ + + struct vec2f { float x, y; }; + struct vec2i { int x, y; }; + struct vec3f { float x, y, z; }; + struct vec3fa { float x, y, z; union { int a; unsigned u; float w; }; }; + struct vec3i { int x, y, z; }; + struct vec4f { float x, y, z, w; }; + struct box2i { vec2i lower, upper; }; + struct box3f { vec3f lower, upper; }; + struct linear3f { vec3f vx, vy, vz; }; + struct affine3f { linear3f l; vec3f p; }; + + typedef uint64_t uint64; + + struct ManagedObject { uint64 ID; virtual ~ManagedObject() {} }; + struct FrameBuffer : public ManagedObject {}; + struct Renderer : public ManagedObject {}; + struct Camera : public ManagedObject {}; + struct Model : public ManagedObject {}; + struct Data : public ManagedObject {}; + struct Geometry : public ManagedObject {}; + struct Material : public ManagedObject {}; + struct Volume : public ManagedObject {}; + struct TransferFunction : public ManagedObject {}; + struct Texture2D : public ManagedObject {}; + struct Light : public ManagedObject {}; + struct PixelOp : public ManagedObject {}; +} // ::osp + typedef osp::FrameBuffer *OSPFrameBuffer; typedef osp::Renderer *OSPRenderer; typedef osp::Camera *OSPCamera; @@ -186,44 +191,73 @@ typedef osp::Texture2D *OSPTexture2D; typedef osp::ManagedObject *OSPObject; typedef osp::PixelOp *OSPPixelOp; -/*! an error type. '0' means 'no error' */ -typedef int32_t error_t; +/* c++ DOES support default initializers */ +#define OSP_DEFAULT_VAL(a) a +#else + +/*! std-C99 versions. This version doesn't need the vector classes + because c99 doesn't have references, anyway */ + +/*! abstract object types. in c99, those are all the same because c99 + doesn't know inheritance, and we want to make sure that a + OSPGeometry can still be passed to a function that expects a + OSPObject, etc */ +typedef struct _OSPManagedObject *OSPManagedObject, + *OSPRenderer, + *OSPCamera, + *OSPFrameBuffer, + *OSPModel, + *OSPData, + *OSPGeometry, + *OSPMaterial, + *OSPLight, + *OSPVolume, + *OSPTransferFunction, + *OSPTexture2D, + *OSPObject, + *OSPPixelOp; + +/* c99 does NOT support default initializers, so we use this macro + to define them away */ +#define OSP_DEFAULT_VAL(a) /* no default arguments on c99 */ + +#endif + +#ifdef __cplusplus extern "C" { +#endif + //! initialize the ospray engine (for single-node user application) OSPRAY_INTERFACE void ospInit(int *ac, const char **av); - - typedef enum { - OSPD_Z_COMPOSITE - } OSPDRenderMode; - -#ifdef OSPRAY_MPI_DISTRIBUTED - //! \brief allows for switching the MPI mode btween collaborative, mastered, and independent - OSPRAY_INTERFACE - void ospdApiMode(OSPDApiMode mode); - - //! the 'lid to the pot' of ospdMpiInit(). - /*! does both an osp shutdown and an mpi shutdown for the mpi group - created with ospdMpiInit */ - OSPRAY_INTERFACE - void ospdMpiInit(int *ac, char ***av, OSPDRenderMode renderMode=OSPD_Z_COMPOSITE); - - /*! the 'lid to the pot' of ospdMpiInit(). shuts down both ospray - *and* the MPI layer created with ospdMpiInit */ - OSPRAY_INTERFACE - void ospdMpiShutdown(); -#endif + + // #ifdef OSPRAY_MPI_DISTRIBUTED + // //! \brief allows for switching the MPI mode btween collaborative, mastered, and independent + // OSPRAY_INTERFACE + // void ospdApiMode(OSPDApiMode mode); + + // //! the 'lid to the pot' of ospdMpiInit(). + // /*! does both an osp shutdown and an mpi shutdown for the mpi group + // created with ospdMpiInit */ + // OSPRAY_INTERFACE + // void ospdMpiInit(int *ac, char ***av, OSPDRenderMode renderMode=OSPD_Z_COMPOSITE); + + // /*! the 'lid to the pot' of ospdMpiInit(). shuts down both ospray + // *and* the MPI layer created with ospdMpiInit */ + // OSPRAY_INTERFACE + // void ospdMpiShutdown(); + // #endif //! load plugin 'name' from shard lib libospray_module_.so /*! returns 0 if the module could be loaded, else it returns an error code > 0 */ - OSPRAY_INTERFACE error_t ospLoadModule(const char *pluginName); + OSPRAY_INTERFACE int32_t ospLoadModule(const char *pluginName); //! use renderer to render a frame. /*! What input to tuse for rendering the frame is encoded in the - renderer's parameters, typically in "world". */ + renderer's parameters, typically in "world". */ OSPRAY_INTERFACE void ospRenderFrame(OSPFrameBuffer fb, OSPRenderer renderer, - const uint32_t whichChannels=OSP_FB_COLOR); + const uint32_t whichChannels OSP_DEFAULT_VAL(=OSP_FB_COLOR)); //! create a new renderer of given type /*! return 'NULL' if that type is not known */ @@ -248,14 +282,14 @@ extern "C" { //! release (i.e., reduce refcount of) given object /*! note that all objects in ospray are refcounted, so one cannot - explicitly "delete" any object. instead, each object is created - with a refcount of 1, and this refcount will be - increased/decreased every time another object refers to this - object resp releases its hold on it; if the refcount is 0 the - object will automatically get deleted. For example, you can - create a new material, assign it to a geometry, and immediately - after this assignation release its refcount; the material will - stay 'alive' as long as the given geometry requires it. */ + explicitly "delete" any object. instead, each object is created + with a refcount of 1, and this refcount will be + increased/decreased every time another object refers to this + object resp releases its hold on it; if the refcount is 0 the + object will automatically get deleted. For example, you can + create a new material, assign it to a geometry, and immediately + after this assignation release its refcount; the material will + stay 'alive' as long as the given geometry requires it. */ OSPRAY_INTERFACE void ospRelease(OSPObject obj); //! assign given material to given geometry @@ -284,9 +318,10 @@ extern "C" { //! \brief create a new Texture2D with the given parameters /*! \detailed return 'NULL' if the texture could not be created with the given parameters */ - OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(const osp::vec2i &size, - const OSPTextureFormat, void *data = NULL, const uint32_t flags = 0); - + OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(const int32_t *size, + const OSPTextureFormat format, + void *data, + const uint32_t flags); //! \brief clears the specified channel(s) of the frame buffer /*! \detailed clear the specified channel(s) of the frame buffer specified in 'whichChannels' @@ -307,11 +342,13 @@ extern "C" { Valid flags that can be OR'ed together into the flags value: - OSP_DATA_SHARED_BUFFER: indicates that the buffer can be shared with the app. - In this case the calling program guarantees that the 'init' pointer will remain - valid for the duration that this data array is being used. - */ - OSPRAY_INTERFACE OSPData ospNewData(size_t numItems, OSPDataType format, - const void *init=NULL, const uint32_t dataCreationFlags=0); + In this case the calling program guarantees that the 'init' pointer will remain + valid for the duration that this data array is being used. + */ + OSPRAY_INTERFACE OSPData ospNewData(size_t numItems, + OSPDataType format, + const void *init OSP_DEFAULT_VAL(=NULL), + const uint32_t dataCreationFlags OSP_DEFAULT_VAL(=0)); /*! \} */ @@ -319,9 +356,9 @@ extern "C" { // ------------------------------------------------------- /*! \defgroup ospray_framebuffer Frame Buffer Manipulation - \ingroup ospray_api + \ingroup ospray_api - \{ + \{ */ /*! \brief create a new framebuffer (actual format is internal to ospray) @@ -364,11 +401,37 @@ extern "C" { the output of the tone mapper. In this case, when using a pixel format of OSP_FB_NONE the pixels from the path tracing stage will never ever be transferred to the application. - */ - OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, - const OSPFrameBufferFormat=OSP_RGBA_I8, - const uint32_t whichChannels=OSP_FB_COLOR); + */ + // OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, + // const OSPFrameBufferFormat OSP_DEFAULT_VAL(=OSP_RGBA_I8), + // const uint32_t whichChannels OSP_DEFAULT_VAL(=OSP_FB_COLOR)); + + OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const int32_t *size /*!< 2 ints: width x height */, + const OSPFrameBufferFormat format, + const uint32_t whichChannels); + + // \brief Set a given region of the volume to a given set of voxels + /*! \detailed Given a block of voxels (of dimensions 'blockDim', + located at the memory region pointed to by 'source', copy the + given voxels into volume, at the region of addresses + [regionCoords...regionCoord+regionSize]. + */ + OSPRAY_INTERFACE int ospSetRegion(/*! the object we're writing this block of pixels into */ + OSPVolume object, + /* points to the first voxel to be copies. The + voxels at 'source' MUST have dimensions + 'regionSize', must be organized in 3D-array + order, and must have the same voxel type as the + volume.*/ + void *source, + /*! coordinates of the lower, left, front corner of + the target region.*/ + const int32_t *regionCoords, + /*! size of the region that we're writing to; MUST + be the same as the dimensions of source[][][] */ + const int32_t *regionSize); + /*! \brief free a framebuffer due to refcounting the frame buffer may not immeidately be deleted @@ -377,7 +440,7 @@ extern "C" { /*! \brief map app-side content of a framebuffer (see \ref frame_buffer_handling) */ OSPRAY_INTERFACE const void *ospMapFrameBuffer(OSPFrameBuffer fb, - const OSPFrameBufferChannel=OSP_FB_COLOR); + const OSPFrameBufferChannel OSP_DEFAULT_VAL(=OSP_FB_COLOR)); /*! \brief unmap a previously mapped frame buffer (see \ref frame_buffer_handling) */ OSPRAY_INTERFACE void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer fb); @@ -397,7 +460,7 @@ extern "C" { /*! add a object-typed parameter to another object - \warning this call has been superseded by ospSetObject, and will eventually get removed */ + \warning this call has been superseded by ospSetObject, and will eventually get removed */ OSP_DEPRECATED OSPRAY_INTERFACE void ospSetParam(OSPObject _object, const char *id, OSPObject object); /*! add a object-typed parameter to another object */ @@ -443,48 +506,12 @@ extern "C" { OSPRAY_INTERFACE void ospSet3i(OSPObject _object, const char *id, int x, int y, int z); /*! add 3-int parameter to given object */ - void ospSet3iv(OSPObject _object, const char *id, const int *xyz); - - - // \brief Set a given region of the volume to a given set of voxels - /*! \detailed Given a block of voxels (of dimensions 'blockDim', - located at the memory region pointed to by 'source', copy the - given voxels into volume, at the region of addresses - [regionCoords...regionCoord+regionSize]. - */ - OSPRAY_INTERFACE int ospSetRegion(/*! the object we're writing this block of pixels into */ - OSPVolume object, - /* points to the first voxel to be copies. The - voxels at 'source' MUST have dimensions - 'regionSize', must be organized in 3D-array - order, and must have the same voxel type as the - volume.*/ - void *source, - /*! coordinates of the lower, left, front corner of - the target region.*/ - const osp::vec3i ®ionCoords, - /*! size of the region that we're writing to; MUST - be the same as the dimensions of source[][][] */ - const osp::vec3i ®ionSize); - - /*! add 2-float parameter to given object */ - OSPRAY_INTERFACE void ospSetVec2f(OSPObject _object, const char *id, const osp::vec2f &v); - - /*! add 2-int parameter to given object */ - OSPRAY_INTERFACE void ospSetVec2i(OSPObject _object, const char *id, const osp::vec2i &v); - - /*! add 3-float parameter to given object */ - OSPRAY_INTERFACE void ospSetVec3f(OSPObject _object, const char *id, const osp::vec3f &v); - - /*! add 4-float parameter to given object */ - OSPRAY_INTERFACE void ospSetVec4f(OSPObject _object, const char *id, const osp::vec4f &v); - - /*! add 3-int parameter to given object */ - OSPRAY_INTERFACE void ospSetVec3i(OSPObject _object, const char *id, const osp::vec3i &v); + OSPRAY_INTERFACE void ospSet3iv(OSPObject _object, const char *id, const int *xyz); /*! add untyped void pointer to object - this will *ONLY* work in local rendering! */ OSPRAY_INTERFACE void ospSetVoidPtr(OSPObject _object, const char *id, void *v); +#ifdef __cplusplus /*! \brief Object and parameter introspection. */ /*! */ /*! These functions are used to retrieve the type or handle of an object, */ @@ -502,7 +529,10 @@ extern "C" { /*! \brief Get a copy of the data in an array (the application is responsible for freeing this pointer). */ /*! \warning this call has been deprecated and will eventually be removed */ - OSP_DEPRECATED OSPRAY_INTERFACE int ospGetDataValues(OSPData object, void **pointer, size_t *count, OSPDataType *type); + OSP_DEPRECATED OSPRAY_INTERFACE int ospGetDataValues(OSPData object, + void **pointer, + size_t *count, + OSPDataType *type); /*! \brief Get the named scalar floating point value associated with an object. */ /*! \warning this call has been deprecated and will eventually be removed */ @@ -543,7 +573,7 @@ extern "C" { /*! \brief Get the named 3-vector integer value associated with an object. */ /*! \warning this call has been deprecated and will eventually be removed */ OSP_DEPRECATED OSPRAY_INTERFACE int ospGetVec3i(OSPObject object, const char *name, osp::vec3i *value); - +#endif /*! @} end of ospray_params */ // ------------------------------------------------------- @@ -559,13 +589,14 @@ extern "C" { /*! \brief remove an existing geometry from a model */ OSPRAY_INTERFACE void ospRemoveGeometry(OSPModel model, OSPGeometry mesh); - - + + /*! \brief create a new instance geometry that instantiates another model. the resulting geometry still has to be added to another model via ospAddGeometry */ OSPRAY_INTERFACE OSPGeometry ospNewInstance(OSPModel modelToInstantiate, - const osp::affine3f &xfm); + /*! affine3f transform matrix, to 4x3 floats */ + const float *affine3f_xfm); // ------------------------------------------------------- /*! \defgroup ospray_model OSPRay Model Handling @@ -590,21 +621,31 @@ extern "C" { OSPRAY_INTERFACE void ospCommit(OSPObject object); /*! \brief represents the result returned by an ospPick operation */ - extern "C" typedef struct { + typedef struct { +#ifdef __cplusplus osp::vec3f position; //< the position of the hit point (in world-space) bool hit; //< whether or not a hit actually occured +#else + float position[3]; //< the position of the hit point (in world-space) + unsigned char hit; //< whether or not a hit actually occured +#endif } OSPPickResult; - + /*! \brief returns the world-space position of the geometry seen at [0-1] normalized screen-space pixel coordinates (if any) */ - OSPRAY_INTERFACE void ospPick(OSPPickResult *result, OSPRenderer renderer, const osp::vec2f &screenPos); - - extern "C" /*OSP_DEPRECATED*/ typedef struct { - bool hit; - float world_x, world_y, world_z; - } OSPPickData; - - /*! \warning this call has been superseded by ospPick, and will eventually get removed */ - OSP_DEPRECATED OSPRAY_INTERFACE OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos); + OSPRAY_INTERFACE void ospPick(OSPPickResult *result, OSPRenderer renderer, const float *screenPos); + + // typedef struct { + // bool hit; + // float world_x, world_y, world_z; + // } OSPPickData; + + // /*! \warning this call has been superseded by ospPick, and will eventually get removed */ + // OSP_DEPRECATED OSPRAY_INTERFACE OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos); + // #ifdef __cplusplus + // /*! c++ version with references */ + // inline OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos) + // { OSPPickData res; ospUnproject(&res,renderer,&screenPos.x); } + // #endif /*! \brief Samples the given volume at the provided world-space coordinates. @@ -617,8 +658,83 @@ extern "C" { as needed for data probes, etc. in applications. It is not intended for large-scale sampling of volumes. */ - OSPRAY_INTERFACE void ospSampleVolume(float **results, OSPVolume volume, const osp::vec3f *worldCoordinates, const size_t &count); - + OSPRAY_INTERFACE void ospSampleVolume(float **results, + OSPVolume volume, + const float *worldCoordinates, + const size_t count); +#ifdef __cplusplus } // extern "C" +#endif + + +#ifdef __cplusplus +extern "C++" { + /*! c++ version with references */ + inline void ospPick(OSPPickResult *result, OSPRenderer renderer, const osp::vec2f &screenPos) + { ospPick(result,renderer,&screenPos.x); } + + inline void ospSampleVolume(float *&results, + OSPVolume volume, + const osp::vec3f *worldCoordinates, + const size_t &count) + { ospSampleVolume(&results,volume,(const float *)worldCoordinates,count); } + + /*! c++ variant of this function that uses references rather than pointers */ + extern "C++" inline OSPTexture2D ospNewTexture2D(const osp::vec2i &size, + const OSPTextureFormat format, + void *data = NULL, + const uint32_t flags = 0) + { return ospNewTexture2D(&size.x,format,data,flags); } + + /*! c++ variant of ospNewFrameBuffer that can also be called with + referneces rather than with pointers */ + inline OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, + const OSPFrameBufferFormat format=OSP_RGBA_I8, + const uint32_t whichChannels=OSP_FB_COLOR) + { return ospNewFrameBuffer(&size.x,format,whichChannels); } + + /*! c++ variant that uses refreences rather than pointerts */ + inline int ospSetRegion(/*! the object we're writing this block of pixels into */ + OSPVolume object, + /* points to the first voxel to be copies. The + voxels at 'source' MUST have dimensions + 'regionSize', must be organized in 3D-array + order, and must have the same voxel type as the + volume.*/ + void *source, + /*! coordinates of the lower, left, front corner of + the target region.*/ + const osp::vec3i ®ionCoords, + /*! size of the region that we're writing to; MUST + be the same as the dimensions of source[][][] */ + const osp::vec3i ®ionSize) + { return ospSetRegion(object,source,®ionCoords.x,®ionSize.x); } + + inline OSPGeometry ospNewInstance(OSPModel modelToInstantiate, + const osp::affine3f &xfm) + { return ospNewInstance(modelToInstantiate,(const float *)&xfm); } + +} // extern C++ + +extern "C" { + // probably want to deprecate those, or make c++ linkage. + + /*! add 2-float parameter to given object */ + OSPRAY_INTERFACE void ospSetVec2f(OSPObject _object, const char *id, const osp::vec2f &v); + + /*! add 2-int parameter to given object */ + OSPRAY_INTERFACE void ospSetVec2i(OSPObject _object, const char *id, const osp::vec2i &v); + + /*! add 3-float parameter to given object */ + OSPRAY_INTERFACE void ospSetVec3f(OSPObject _object, const char *id, const osp::vec3f &v); + + /*! add 4-float parameter to given object */ + OSPRAY_INTERFACE void ospSetVec4f(OSPObject _object, const char *id, const osp::vec4f &v); + + /*! add 3-int parameter to given object */ + OSPRAY_INTERFACE void ospSetVec3i(OSPObject _object, const char *id, const osp::vec3i &v); +} // extern C + +#endif // __cplusplus /*! \} */ From 41c5a0233dc105b84a69e8889ce2d7592176a7a9 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 24 Feb 2016 12:44:31 -0700 Subject: [PATCH 038/310] first draft of strict-c ospray.h API. still using dummy osp::vec types in cplusplus mode --- ospray/include/ospray/ospray.h | 37 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index f36c032478..c6d9721387 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -149,16 +149,37 @@ typedef enum { namespace osp { /*! namespace for classes in the public core API */ - struct vec2f { float x, y; }; - struct vec2i { int x, y; }; - struct vec3f { float x, y, z; }; - struct vec3fa { float x, y, z; union { int a; unsigned u; float w; }; }; - struct vec3i { int x, y, z; }; - struct vec4f { float x, y, z, w; }; - struct box2i { vec2i lower, upper; }; - struct box3f { vec3f lower, upper; }; +#ifdef OSPRAY_EXTERNAL_VECTOR_TYPES + /*! we assume the app already defines osp::vec types. Note those + HAVE to be compatible with the data layouts used below. + + Note: this feature allows the application to use its own vector + type library in the following way + + a) include your own vector library (say, ospcommon::vec3f etc, + when using the ospcommon library) + + b) make sure the proper vec3f etc are defined in a osp:: namespace, e.g., using + namespace osp { + typedef ospcommon::vec3f vec3f; + } + + c) defines OSPRAY_EXTERNAL_VECTOR_TYPES + + d) include ospray.h + ! */ +#else + struct vec2f { float x, y; }; + struct vec2i { int x, y; }; + struct vec3f { float x, y, z; }; + struct vec3fa { float x, y, z; union { int a; unsigned u; float w; }; }; + struct vec3i { int x, y, z; }; + struct vec4f { float x, y, z, w; }; + struct box2i { vec2i lower, upper; }; + struct box3f { vec3f lower, upper; }; struct linear3f { vec3f vx, vy, vz; }; struct affine3f { linear3f l; vec3f p; }; +#endif typedef uint64_t uint64; From dd784bc825b971a6dfbfdd16c91d22372355258f Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 29 Feb 2016 08:49:01 -0700 Subject: [PATCH 039/310] added override to structuredvolume --- ospray/volume/StructuredVolume.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/volume/StructuredVolume.h b/ospray/volume/StructuredVolume.h index bec23a180b..dc2d01c0b9 100644 --- a/ospray/volume/StructuredVolume.h +++ b/ospray/volume/StructuredVolume.h @@ -54,7 +54,7 @@ namespace ospray { /*! \returns 0 on error, any non-zero value indicates success */ virtual int setRegion(const void *source_pointer, const vec3i &target_index, - const vec3i &source_count) = 0; + const vec3i &source_count) override = 0; protected: From 95d4f80261f7a98f8c57b12837bbbda4c2f37da6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 29 Feb 2016 11:49:13 -0600 Subject: [PATCH 040/310] add cilk option for OSPRAY_TASKING_SYSTEM (only if using icc) --- CMakeLists.txt | 9 ----- .../ospray_cmake_config/osprayConfig.cmake.in | 4 +++ ospray/CMakeLists.txt | 36 +++++++++++++++++-- ospray/common/parallel_for.h | 6 ++++ 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f97d6cdf8b..e9c90ae5a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,15 +87,6 @@ STRING(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) SET(OSPRAY_MPI ${OSPRAY_BUILD_MPI_DEVICE}) -# Make OpenMP available to all apps/libraries/modules -FIND_PACKAGE(OpenMP QUIET) -IF (OPENMP_FOUND) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - SET(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") -ENDIF() - ############################################################## # create binary packages; before any INSTALL() invocation/definition ############################################################## diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index dc3c5a3679..ae22bcfda0 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -127,6 +127,10 @@ if (@USE_TBB@) list(APPEND OSPRAY_DEPENDENCIES ${TBB_LIBRARIES}) endif() +if (@USE_CILK@) + add_definitions(-DOSPRAY_USE_CILK) +endif() + # Restore state set(CMAKE_CURRENT_LIST_DIR ${OSPRAY_CMAKE_CURRENT_LIST_DIR}) set(CURRENT_CONFIG_INSTALL_DIR ${OSPRAY_CURRENT_CONFIG_INSTALL_DIR}) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index c60e655ed3..ab3f254cdc 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -33,17 +33,38 @@ FIND_PACKAGE(Threads REQUIRED) # Setup tasking system build configuration # ------------------------------------------------------- -SET(OSPRAY_TASKING_SYSTEM TBB CACHE STRING +IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + SET(CILK_STRING "Cilk") +ENDIF() + +IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + SET(TASKING_DEFAULT ${CILK_STRING}) +ELSE() + SET(TASKING_DEFAULT TBB) +ENDIF() + +SET(OSPRAY_TASKING_SYSTEM ${TASKING_DEFAULT} CACHE STRING "Use TBB or OpenMP as for per-node thread tasking system") -SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY STRINGS TBB OpenMP) + +SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY + STRINGS TBB ${CILK_STRING} OpenMP) MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") SET(USE_TBB TRUE) SET(USE_TBB TRUE PARENT_SCOPE) + SET(USE_CILK FALSE) + SET(USE_CILK FALSE PARENT_SCOPE) +ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") + SET(USE_TBB FALSE) + SET(USE_TBB FALSE PARENT_SCOPE) + SET(USE_CILK TRUE) + SET(USE_CILK TRUE PARENT_SCOPE) ELSE() SET(USE_TBB FALSE) SET(USE_TBB FALSE PARENT_SCOPE) + SET(USE_CILK FALSE) + SET(USE_CILK FALSE PARENT_SCOPE) ENDIF() IF(USE_TBB) @@ -59,6 +80,17 @@ ELSE(USE_TBB) UNSET(TBB_INCLUDE_DIR_MIC CACHE) UNSET(TBB_LIBRARY_MIC CACHE) UNSET(TBB_LIBRARY_MALLOC_MIC CACHE) + IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "OpenMP") + FIND_PACKAGE(OpenMP) + IF (OPENMP_FOUND) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + SET(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + ENDIF() + ELSE()#Cilk + ADD_DEFINITIONS(-DOSPRAY_USE_CILK) + ENDIF() ENDIF(USE_TBB) # ------------------------------------------------------- diff --git a/ospray/common/parallel_for.h b/ospray/common/parallel_for.h index 68375d9471..7b569bbca2 100644 --- a/ospray/common/parallel_for.h +++ b/ospray/common/parallel_for.h @@ -18,6 +18,8 @@ #ifdef OSPRAY_USE_TBB # include +#elif defined(OSPRAY_USE_CILK) +# include #endif namespace ospray { @@ -27,6 +29,10 @@ inline void parallel_for(int nTasks, const T& fcn) { #ifdef OSPRAY_USE_TBB tbb::parallel_for(0, nTasks, 1, fcn); +#elif defined(OSPRAY_USE_CILK) + cilk_for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { + fcn(taskIndex); + } #else # pragma omp parallel for schedule(dynamic) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { From 48b838658767d93fbc9747d6e9c9b556a7438e03 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 29 Feb 2016 19:01:16 -0600 Subject: [PATCH 041/310] increment version number --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9c90ae5a7..75f3730145 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ ENDIF() SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) SET(OSPRAY_VERSION_MAJOR 0) SET(OSPRAY_VERSION_MINOR 9) -SET(OSPRAY_VERSION_PATCH 1) +SET(OSPRAY_VERSION_PATCH 2) SET(OSPRAY_VERSION ${OSPRAY_VERSION_MAJOR}.${OSPRAY_VERSION_MINOR}.${OSPRAY_VERSION_PATCH} ) From 488539f4c851c4f25423c247635cb11025d99354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 1 Mar 2016 14:55:09 +0100 Subject: [PATCH 042/310] Formatting in README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9c9e841628..9d4ece609b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ OSPRay ====== -This is release v0.9.1 of OSPRay. For changes and new -features see the [changelog](CHANGELOG.md). Also visit -http://www.ospray.org for more information. +This is release v0.9.1 of OSPRay. For changes and new features see the +[changelog](CHANGELOG.md). Also visit http://www.ospray.org for more +information. OSPRay Overview =============== @@ -56,7 +56,7 @@ branch should always point to the latest tested bugfix release. Prerequisites ------------- -OSPRay currently supports both Linux and Mac OS X (and experimentally +OSPRay currently supports both Linux and Mac OS X (and experimentally Windows). In addition, before you can build OSPRay you need the following prerequisites: @@ -106,7 +106,7 @@ Type the following to install the dependencies using `apt-get`: sudo apt-get install freeglut3-dev sudo apt-get install libqt4-dev -Under Mac OS\ X these dependencies can be installed using +Under Mac OS X these dependencies can be installed using [MacPorts](http://www.macports.org/): sudo port install cmake tbb freeglut qt4 From 0866770ea9d57ff81870c52895d113fe074017fb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 1 Mar 2016 12:07:07 -0600 Subject: [PATCH 043/310] add (transparently, cmake advanced option) the old method of setting compiler --- CMakeLists.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75f3730145..8ca025fb85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,29 @@ ## limitations under the License. ## ## ======================================================================== ## +# Optional compiler selection - must be first! + +# enable ability for users to force a compiler using the pre-0.8.3 method +SET(OSPRAY_COMPILER "" CACHE STRING "Force compiler: GCC, ICC, CLANG") +SET_PROPERTY(CACHE OSPRAY_COMPILER PROPERTY STRINGS GCC ICC CLANG) +MARK_AS_ADVANCED(OSPRAY_COMPILER) + +IF(NOT ":${OSPRAY_COMPILER}" STREQUAL ":") + STRING(TOUPPER ${OSPRAY_COMPILER} OSPRAY_COMPILER) + IF(${OSPRAY_COMPILER} STREQUAL "GCC") + SET(CMAKE_C_COMPILER "gcc") + SET(CMAKE_CXX_COMPILER "g++") + ELSEIF(${OSPRAY_COMPILER} STREQUAL "ICC") + SET(CMAKE_C_COMPILER "icc") + SET(CMAKE_CXX_COMPILER "icpc") + ELSEIF(${OSPRAY_COMPILER} STREQUAL "CLANG") + SET(CMAKE_C_COMPILER "clang") + SET(CMAKE_CXX_COMPILER "clang++") + ENDIF() +ENDIF() + +# Configure all of OSPRay ##################################################### + PROJECT(OSPRay) CMAKE_MINIMUM_REQUIRED(VERSION 2.8) From 55b194bced322cbb9a60b43a7bddfbe7261a1424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 1 Mar 2016 17:18:31 +0100 Subject: [PATCH 044/310] Fixes for OSX dmg --- cmake/package.cmake | 23 ++++++++++++++--------- scripts/release_macosx.sh | 11 +++++++++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/cmake/package.cmake b/cmake/package.cmake index 9133727a4c..47c6ff2ba7 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -27,7 +27,7 @@ IF (OSPRAY_ZIP_MODE) # in tgz / zip let's have relative RPath SET(CMAKE_SKIP_INSTALL_RPATH OFF) IF (APPLE) - SET(CMAKE_INSTALL_RPATH "@executable_path:@executable_path/../lib") + SET(CMAKE_INSTALL_RPATH "@executable_path/:@executable_path/../lib") ELSE() SET(CMAKE_INSTALL_RPATH "\$ORIGIN:\$ORIGIN/../lib") # on per target basis: @@ -35,8 +35,13 @@ IF (OSPRAY_ZIP_MODE) #SET_TARGET_PROPERTIES(libs INSTALL_RPATH "$ORIGIN") ENDIF() ELSE() - # we do not want any RPath for installed binaries - SET(CMAKE_SKIP_INSTALL_RPATH ON) + IF (APPLE) + # use RPath on OSX + SET(CMAKE_SKIP_INSTALL_RPATH OFF) + ELSE() + # we do not want any RPath for installed binaries + SET(CMAKE_SKIP_INSTALL_RPATH ON) + ENDIF() ENDIF() ############################################################## @@ -60,10 +65,10 @@ INSTALL(FILES ${PROJECT_SOURCE_DIR}/CHANGELOG.md DESTINATION ${CMAKE_INSTALL_DOC INSTALL(FILES ${PROJECT_SOURCE_DIR}/README.md DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT lib) #INSTALL(FILES ${PROJECT_SOURCE_DIR}/readme.pdf DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT lib) -SET(CPACK_NSIS_MENU_LINKS ${CPACK_NSIS_MENU_LINKS} "${CMAKE_INSTALL_DOCDIR}/LICENSE.txt" "LICENSE") -SET(CPACK_NSIS_MENU_LINKS ${CPACK_NSIS_MENU_LINKS} "${CMAKE_INSTALL_DOCDIR}/CHANGELOG.txt" "CHANGELOG") -SET(CPACK_NSIS_MENU_LINKS ${CPACK_NSIS_MENU_LINKS} "${CMAKE_INSTALL_DOCDIR}/README.md" "README.md") -#SET(CPACK_NSIS_MENU_LINKS ${CPACK_NSIS_MENU_LINKS} "${CMAKE_INSTALL_DOCDIR}/readme.pdf" "readme.pdf") +LIST(APPEND CPACK_NSIS_MENU_LINKS "${CMAKE_INSTALL_DOCDIR}/LICENSE.txt" "LICENSE") +LIST(APPEND CPACK_NSIS_MENU_LINKS "${CMAKE_INSTALL_DOCDIR}/CHANGELOG.md" "CHANGELOG") +LIST(APPEND CPACK_NSIS_MENU_LINKS "${CMAKE_INSTALL_DOCDIR}/README.md" "README.md") +#LIST(APPEND CPACK_NSIS_MENU_LINKS "${CMAKE_INSTALL_DOCDIR}/readme.pdf" "readme.pdf") ############################################################## # CPack specific stuff @@ -140,8 +145,8 @@ IF(WIN32) # MacOSX specific settings ELSEIF(APPLE) - FILE(COPY ${PROJECT_SOURCE_DIR}/README.md DESTINATION ${PROJECT_BINARY_DIR}/README.txt) - SET(CPACK_RESOURCE_FILE_README ${PROJECT_BINARY_DIR}/README.txt) + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/README.md ${PROJECT_BINARY_DIR}/ReadMe.txt COPYONLY) + SET(CPACK_RESOURCE_FILE_README ${PROJECT_BINARY_DIR}/ReadMe.txt) IF (OSPRAY_ZIP_MODE) SET(CPACK_GENERATOR TGZ) diff --git a/scripts/release_macosx.sh b/scripts/release_macosx.sh index c978bb5992..acd18cd5c5 100755 --- a/scripts/release_macosx.sh +++ b/scripts/release_macosx.sh @@ -22,6 +22,13 @@ export LIBRARY_PATH= export DYLD_LIBRARY_PATH= TBB_PATH_LOCAL=$PWD/tbb +umask=`umask` +function onexit { + umask $umask +} +trap onexit EXIT +umask 002 + mkdir -p build_release cd build_release # make sure to use default settings @@ -41,8 +48,8 @@ cmake \ -D CMAKE_INSTALL_PREFIX=/opt/local \ -D CMAKE_INSTALL_INCLUDEDIR=include \ -D CMAKE_INSTALL_LIBDIR=lib \ --D CMAKE_INSTALL_DOCDIR=../../Applications/OSPRay/doc \ --D CMAKE_INSTALL_BINDIR=../../Applications/OSPRay/bin \ +-D CMAKE_INSTALL_DOCDIR=../../Applications/OSPRay.app/doc \ +-D CMAKE_INSTALL_BINDIR=../../Applications/OSPRay.app/bin \ .. #-D TBB_ROOT=/opt/local \ From 08c34ab689291200a83dcc202dcfaf75fc223194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 1 Mar 2016 20:10:13 +0100 Subject: [PATCH 045/310] Put apps directly in bin/ (bin/ospray/ is not necessary) --- cmake/package.cmake | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cmake/package.cmake b/cmake/package.cmake index 47c6ff2ba7..19e475a37e 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -16,11 +16,6 @@ INCLUDE(GNUInstallDirs) -IF (NOT OSPRAY_ZIP_MODE AND NOT WIN32 AND NOT APPLE) - SET(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR}/ospray) - SET(CMAKE_INSTALL_FULL_BINDIR ${CMAKE_INSTALL_FULL_BINDIR}/ospray) -ENDIF() - SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}) IF (OSPRAY_ZIP_MODE) From 8471abf0e13960b558a7b9494176c7b9a2d23be3 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 1 Mar 2016 13:35:01 -0600 Subject: [PATCH 046/310] move compiler configuration into a macro for cleanliness --- CMakeLists.txt | 27 ++------------------------- cmake/ospray.cmake | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ca025fb85..4a5efb6968 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,31 +14,6 @@ ## limitations under the License. ## ## ======================================================================== ## -# Optional compiler selection - must be first! - -# enable ability for users to force a compiler using the pre-0.8.3 method -SET(OSPRAY_COMPILER "" CACHE STRING "Force compiler: GCC, ICC, CLANG") -SET_PROPERTY(CACHE OSPRAY_COMPILER PROPERTY STRINGS GCC ICC CLANG) -MARK_AS_ADVANCED(OSPRAY_COMPILER) - -IF(NOT ":${OSPRAY_COMPILER}" STREQUAL ":") - STRING(TOUPPER ${OSPRAY_COMPILER} OSPRAY_COMPILER) - IF(${OSPRAY_COMPILER} STREQUAL "GCC") - SET(CMAKE_C_COMPILER "gcc") - SET(CMAKE_CXX_COMPILER "g++") - ELSEIF(${OSPRAY_COMPILER} STREQUAL "ICC") - SET(CMAKE_C_COMPILER "icc") - SET(CMAKE_CXX_COMPILER "icpc") - ELSEIF(${OSPRAY_COMPILER} STREQUAL "CLANG") - SET(CMAKE_C_COMPILER "clang") - SET(CMAKE_CXX_COMPILER "clang++") - ENDIF() -ENDIF() - -# Configure all of OSPRay ##################################################### - -PROJECT(OSPRay) - CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_POLICY(SET CMP0003 NEW) # since 2.6 IF(POLICY CMP0015) @@ -136,6 +111,8 @@ ENDIF() # the OSPRay library ############################################################## +OSPRAY_CONFIGURE_COMPILER() + INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) SET(OSPRAY_TARGET "intel64") diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 1bda6a0add..f000a53384 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -288,3 +288,37 @@ MACRO(OSPRAY_SET_LIBRARY_VERSION _name) SET_TARGET_PROPERTIES(${name} PROPERTIES VERSION ${OSPRAY_VERSION} SOVERSION ${OSPRAY_SOVERSION}) ENDMACRO() + +## Compiler configuration macro ## + +MACRO(OSPRAY_CONFIGURE_COMPILER) + # enable ability for users to force a compiler using the pre-0.8.3 method + SET(OSPRAY_COMPILER "" CACHE STRING "Force compiler: GCC, ICC, CLANG") + SET_PROPERTY(CACHE OSPRAY_COMPILER PROPERTY STRINGS GCC ICC CLANG) + MARK_AS_ADVANCED(OSPRAY_COMPILER) + + IF(NOT ":${OSPRAY_COMPILER}" STREQUAL ":") + STRING(TOUPPER ${OSPRAY_COMPILER} OSPRAY_COMPILER) + IF(${OSPRAY_COMPILER} STREQUAL "GCC") + FIND_PROGRAM(GCC_EXECUTABLE gcc DOC "Path to the gcc executable.") + FIND_PROGRAM(G++_EXECUTABLE g++ DOC "Path to the g++ executable.") + SET(CMAKE_C_COMPILER ${GCC_EXECUTABLE} CACHE STRING "C Compiler" FORCE) + SET(CMAKE_CXX_COMPILER ${G++_EXECUTABLE} CACHE STRING "CXX Compiler" FORCE) + SET(CMAKE_C_COMPILER "gcc") + SET(CMAKE_CXX_COMPILER "g++") + SET(CMAKE_CXX_COMPILER_ID "GNU") + ELSEIF(${OSPRAY_COMPILER} STREQUAL "ICC") + FIND_PROGRAM(ICC_EXECUTABLE icc DOC "Path to the icc executable.") + FIND_PROGRAM(ICPC_EXECUTABLE icpc DOC "Path to the icpc executable.") + SET(CMAKE_C_COMPILER ${ICC_EXECUTABLE} CACHE STRING "CXX Compiler" FORCE) + SET(CMAKE_CXX_COMPILER ${ICPC_EXECUTABLE} CACHE STRING "CXX Compiler" FORCE) + SET(CMAKE_CXX_COMPILER_ID "Intel") + ELSEIF(${OSPRAY_COMPILER} STREQUAL "CLANG") + FIND_PROGRAM(CLANG_EXECUTABLE clang DOC "Path to the clang executable.") + FIND_PROGRAM(CLANG_EXECUTABLE clang++ DOC "Path to the clang++ executable.") + SET(CMAKE_C_COMPILER ${CLANG_EXECUTABLE} CACHE STRING "C Compiler" FORCE) + SET(CMAKE_CXX_COMPILER ${CLANG_EXECUTABLE} CACHE STRING "CXX Compiler" FORCE) + SET(CMAKE_CXX_COMPILER_ID "Clang") + ENDIF() + ENDIF() +ENDMACRO() From 0454b352c6d7f459ff3c6eb70ce7bdfd60d318aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 1 Mar 2016 20:16:28 +0100 Subject: [PATCH 047/310] Revert "fixed cylinder/sphere intersection normal was not normalized." Normalization is not necessary -- will happen in Model.ih:postIntersect (if requested by renderer with DG_NORMALIZE). This reverts commit 5810f3ae. --- ospray/geometry/Cylinders.ispc | 2 +- ospray/geometry/Spheres.ispc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/geometry/Cylinders.ispc b/ospray/geometry/Cylinders.ispc index 1536cb9778..7d487f01c7 100644 --- a/ospray/geometry/Cylinders.ispc +++ b/ospray/geometry/Cylinders.ispc @@ -122,7 +122,7 @@ void Cylinders_intersect(uniform Cylinders *uniform geometry, // we need hit in object space, in postIntersect it is in world-space const vec3f P = ray.t*ray.dir - A; const vec3f V = cross(P,AB); - ray.Ng = normalize(cross(AB,V)); + ray.Ng = cross(AB,V); } } diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index 67e52f1079..b17a2e3bc9 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -139,7 +139,7 @@ void Spheres_intersect(uniform Spheres *uniform geometry, ray.instID = -1; // cannot easily be moved to postIntersect // we need hit in object space, in postIntersect it is in world-space - ray.Ng = normalize(ray.org + ray.t*ray.dir - center); + ray.Ng = ray.org + ray.t*ray.dir - center; } } From 15ba816051a163eb7c13c2d624c01556d08b9775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 2 Mar 2016 10:58:04 +0100 Subject: [PATCH 048/310] icc 16 installs in IntelSWTools per default on Windows --- cmake/FindTBB.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake index 1def6b352e..d6423c5404 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake @@ -50,6 +50,7 @@ IF (WIN32) HINTS ${TBB_ROOT} PATHS ${PROJECT_SOURCE_DIR}/tbb + "${PROGRAMFILES32}/IntelSWTools/compilers_and_libraries/windows/tbb" "${PROGRAMFILES32}/Intel/Composer XE/tbb" "${PROGRAMFILES32}/Intel/compilers_and_libraries/windows/tbb" ) From 5e43bc704b0f8672c5d51edf38bc4776a1712bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 2 Mar 2016 13:40:39 +0100 Subject: [PATCH 049/310] On OS X we need to use libc++ to get C++11 headers --- cmake/clang.cmake | 5 +++-- cmake/gcc.cmake | 5 +++-- cmake/icc.cmake | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cmake/clang.cmake b/cmake/clang.cmake index 74dcf92166..fed2c4e297 100644 --- a/cmake/clang.cmake +++ b/cmake/clang.cmake @@ -20,8 +20,9 @@ SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -Wstrict-aliasing=1") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -g -O3 -Wstrict-aliasing=1") IF (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 -stdlib=libc++") -ENDIF (APPLE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # we only use MacOSX 10.7 features + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against C++11 stdlib +ENDIF() # these flags apply ONLY to how embree is built; the rest of the ospray C++ code is ISA-agnostic SET(OSPRAY_ARCH_SSE3 "-msse3") diff --git a/cmake/gcc.cmake b/cmake/gcc.cmake index 33807374e4..d5a9b8669b 100644 --- a/cmake/gcc.cmake +++ b/cmake/gcc.cmake @@ -20,8 +20,9 @@ SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -Wstrict-aliasing=1 -ffast-m SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -g -O3 -Wstrict-aliasing=1 -ffast-math ") IF (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") -ENDIF (APPLE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # we only use MacOSX 10.7 features + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against C++11 stdlib +ENDIF() # these flags apply ONLY to how embree is built; the rest of the ospray C++ code is ISA-agnostic SET(OSPRAY_ARCH_SSE3 "-msse3") diff --git a/cmake/icc.cmake b/cmake/icc.cmake index db31511fa2..fc319530da 100644 --- a/cmake/icc.cmake +++ b/cmake/icc.cmake @@ -22,8 +22,9 @@ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -g -O3 -no-ansi-alias -restrict -fp IF (APPLE) SET (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS_INIT} -dynamiclib) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") -ENDIF (APPLE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # we only use MacOSX 10.7 features + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against C++11 stdlib +ENDIF() # these flags apply ONLY to how embree is built; the rest of the ospray C++ code is ISA-agnostic SET(OSPRAY_ARCH_SSE3 "-xsse3") From 335d714b178f7c598a06ce75df7be84a086b391e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 2 Mar 2016 16:21:02 +0100 Subject: [PATCH 050/310] ISPC 1.9 on Windows comes in two versions --- cmake/ispc.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake/ispc.cmake b/cmake/ispc.cmake index d8d1920315..23851eee83 100644 --- a/cmake/ispc.cmake +++ b/cmake/ispc.cmake @@ -29,11 +29,18 @@ IF (NOT ISPC_EXECUTABLE) SET(ISPC_DIR_SUFFIX "osx") ELSEIF(WIN32) SET(ISPC_DIR_SUFFIX "windows") + IF (MSVC14) + LIST(APPEND ISPC_DIR_SUFFIX "windows-vs2015") + ELSE() + LIST(APPEND ISPC_DIR_SUFFIX "windows-vs2013") + ENDIF() ELSE() SET(ISPC_DIR_SUFFIX "linux") ENDIF() FOREACH(ver ${ISPC_VERSION_WORKING}) - LIST(APPEND ISPC_DIR_HINT ${PROJECT_SOURCE_DIR}/../ispc-v${ver}-${ISPC_DIR_SUFFIX}) + FOREACH(suffix ${ISPC_DIR_SUFFIX}) + LIST(APPEND ISPC_DIR_HINT ${PROJECT_SOURCE_DIR}/../ispc-v${ver}-${suffix}) + ENDFOREACH() ENDFOREACH() FIND_PROGRAM(ISPC_EXECUTABLE ispc PATHS ${ISPC_DIR_HINT} DOC "Path to the ISPC executable.") From d81c84f8a57862e8854d49f2b8d0b7945da50f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 2 Mar 2016 16:56:10 +0100 Subject: [PATCH 051/310] Remove --clean-first for Windows release builds --- scripts/release_win.bat | 3 ++- scripts/release_win.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/release_win.bat b/scripts/release_win.bat index 771387c683..a4931bdc31 100755 --- a/scripts/release_win.bat +++ b/scripts/release_win.bat @@ -40,7 +40,8 @@ cmake -L ^ rem -D TBB_ROOT=%TBB_PATH_LOCAL% ^ rem compile and create installers -cmake --clean-first --build . --config Release --target PACKAGE -- /m /nologo +# option '--clean-first' somehow conflicts with options after '--' for msbuild +cmake --build . --config Release --target PACKAGE -- /m /nologo rem create ZIP files cmake -D OSPRAY_ZIP_MODE=ON .. diff --git a/scripts/release_win.sh b/scripts/release_win.sh index 55277d6ec1..146270c825 100755 --- a/scripts/release_win.sh +++ b/scripts/release_win.sh @@ -45,7 +45,7 @@ cmake -L \ # -D TBB_ROOT=%TBB_PATH_LOCAL% \ # compile and create installers -# option --clean-first' somehow conflicts with options after '--' for msbuild +# option '--clean-first' somehow conflicts with options after '--' for msbuild cmake --build . --config Release --target PACKAGE -- -m -nologo # create ZIP files From 405b64f5a7cc043503910a3107476d22f0c85865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 2 Mar 2016 17:11:56 +0100 Subject: [PATCH 052/310] OSPDataType.h already moved to include/ospray --- cmake/package.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmake/package.cmake b/cmake/package.cmake index 19e475a37e..1dd2f95140 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -48,8 +48,6 @@ INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/ospray/include/ospray COMPONENT devel FILES_MATCHING PATTERN "*.h" ) -# OSPDataType.h is included by ospray.h, should eventually move to include/ospray as well -INSTALL(FILES ${PROJECT_SOURCE_DIR}/ospray/common/OSPDataType.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ospray COMPONENT devel) ############################################################## # install documentation From 168e0699fbee51fc6b958071f361e20c4d62e969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 4 Mar 2016 16:15:48 +0100 Subject: [PATCH 053/310] Redistribute TBB for mic only if mic is enabled --- cmake/FindTBB.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake index d6423c5404..2798b867db 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake @@ -189,5 +189,7 @@ IF (WIN32) INSTALL(PROGRAMS ${TBB_DLL} ${TBB_DLL_MALLOC} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT apps) # 3rd party? ELSEIF (OSPRAY_ZIP_MODE) INSTALL(PROGRAMS ${TBB_LIBRARY} ${TBB_LIBRARY_MALLOC} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib) # /intel64? - INSTALL(PROGRAMS ${TBB_LIBRARIES_MIC} DESTINATION ${CMAKE_INSTALL_LIBDIR}/mic COMPONENT lib_mic) + IF(OSPRAY_MIC AND TBB_FOUND_MIC) + INSTALL(PROGRAMS ${TBB_LIBRARIES_MIC} DESTINATION ${CMAKE_INSTALL_LIBDIR}/mic COMPONENT lib_mic) + ENDIF() ENDIF() From 55767cc4a18a480f2eb55691e0696b3772a136b6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 4 Mar 2016 06:22:30 -0600 Subject: [PATCH 054/310] use cilk_spawn to asynchronously execute DFP message tasks --- ospray/mpi/DistributedFrameBuffer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 097bf438f6..89f44379f2 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -538,6 +538,13 @@ namespace ospray { #ifdef OSPRAY_USE_TBB auto &t = *new(tbb::task::allocate_root())DFBProcessMessageTask(this, _msg); tbb::task::enqueue(t); +#elif defined(OSPRAY_USE_CILK) + auto fcn = [&](){ + DFBProcessMessageTask t(this, _msg); + t.execute(); + }; + + cilk_spawn fcn(); #else DFBProcessMessageTask t(this, _msg); t.execute(); From fc63bd0fed761f8347af4ffa8806c0171f039f59 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 4 Mar 2016 11:46:37 -0600 Subject: [PATCH 055/310] patch to Embree to handle compile issues in some environments --- cmake/build_embree.cmake | 2 +- ospray/embree-v2.7.1/common/tasking/taskscheduler_tbb.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/build_embree.cmake b/cmake/build_embree.cmake index 7abafd2d6b..0851956bb4 100644 --- a/cmake/build_embree.cmake +++ b/cmake/build_embree.cmake @@ -41,7 +41,7 @@ set(RTCORE_RAY_PACKETS ON CACHE INTERNAL "" FORCE) if (USE_TBB) set(RTCORE_TASKING_SYSTEM TBB CACHE INTERNAL "" FORCE) else () - set(RTCORE_TASKING_SYSTEM Internal CACHE INTERNAL "" FORCE) + set(RTCORE_TASKING_SYSTEM INTERNAL CACHE INTERNAL "" FORCE) endif () if (OSPRAY_MIC) diff --git a/ospray/embree-v2.7.1/common/tasking/taskscheduler_tbb.h b/ospray/embree-v2.7.1/common/tasking/taskscheduler_tbb.h index 12e972fb42..475a64a49f 100644 --- a/ospray/embree-v2.7.1/common/tasking/taskscheduler_tbb.h +++ b/ospray/embree-v2.7.1/common/tasking/taskscheduler_tbb.h @@ -314,7 +314,7 @@ namespace embree /* remember exception to throw */ std::exception_ptr except = nullptr; - if (cancellingException) except = cancellingException; + if (cancellingException != nullptr) except = cancellingException; /* wait for all threads to terminate */ atomic_add(&threadCounter,-1); @@ -322,7 +322,7 @@ namespace embree cancellingException = nullptr; /* re-throw proper exception */ - if (except) + if (except != nullptr) std::rethrow_exception(except); } From 9c9fa02c6987b9d95179109639aee5669a794280 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Sat, 5 Mar 2016 21:57:53 -0600 Subject: [PATCH 056/310] use an async wrapper for different tasking backends, like parallel_for() --- .gitignore | 3 + ospray/CMakeLists.txt | 4 +- ospray/common/tasking/async.h | 51 ++++++++++++ ospray/common/{ => tasking}/parallel_for.h | 8 +- ospray/mpi/DistributedFrameBuffer.cpp | 78 +++++-------------- ospray/mpi/MPILoadBalancer.cpp | 2 +- ospray/render/LoadBalancer.cpp | 2 +- .../render/volume/RaycastVolumeRenderer.cpp | 2 +- ospray/volume/BlockBrickedVolume.cpp | 2 +- ospray/volume/GhostBlockBrickedVolume.cpp | 2 +- ospray/volume/StructuredVolume.h | 2 +- 11 files changed, 85 insertions(+), 71 deletions(-) create mode 100644 ospray/common/tasking/async.h rename ospray/common/{ => tasking}/parallel_for.h (92%) diff --git a/.gitignore b/.gitignore index 47a826c56e..caa003364c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ build tags .ycm_extra_conf.pyc *.autosave +*.gz +*.rpm +*.zip diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index ab3f254cdc..775ebca977 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -132,7 +132,9 @@ SET(OSPRAY_SOURCES common/Material.cpp common/Library.cpp common/Thread.cpp - common/parallel_for.h + + common/tasking/parallel_for.h + common/tasking/async.h fb/FrameBuffer.ispc fb/FrameBuffer.cpp diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h new file mode 100644 index 0000000000..33195ba236 --- /dev/null +++ b/ospray/common/tasking/async.h @@ -0,0 +1,51 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#ifdef OSPRAY_USE_TBB +# include +#elif defined(OSPRAY_USE_CILK) +# include +#endif + +namespace ospray { + +template +inline void async(const Task& fcn) +{ +#ifdef OSPRAY_USE_TBB + struct LocalTBBTask : public tbb::task + { + Task func; + tbb::task* execute() override + { + func(); + return nullptr; + } + + LocalTBBTask( const Task& f ) : func(f) {} + }; + + tbb::task::enqueue(*new(tbb::task::allocate_root())LocalTBBTask(fcn)); +#elif defined(OSPRAY_USE_CILK) + cilk_spawn fcn(); +#else// OpenMP --> synchronous! + fcn(); +#endif +} + +}//namespace ospray diff --git a/ospray/common/parallel_for.h b/ospray/common/tasking/parallel_for.h similarity index 92% rename from ospray/common/parallel_for.h rename to ospray/common/tasking/parallel_for.h index 7b569bbca2..abb36d3e00 100644 --- a/ospray/common/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -17,15 +17,15 @@ #pragma once #ifdef OSPRAY_USE_TBB -# include +# include #elif defined(OSPRAY_USE_CILK) -# include +# include #endif namespace ospray { -template -inline void parallel_for(int nTasks, const T& fcn) +template +inline void parallel_for(int nTasks, const Task& fcn) { #ifdef OSPRAY_USE_TBB tbb::parallel_for(0, nTasks, 1, fcn); diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 89f44379f2..bab635d3bc 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -20,20 +20,16 @@ // embree #include "common/sys/thread.h" -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/async.h" +#include "ospray/common/tasking/parallel_for.h" #include -//#include //NOTE(jda) - set note about std::async below... #ifdef _WIN32 # define NOMINMAX # include // for Sleep #endif -#ifdef OSPRAY_USE_TBB -# include -#endif - #define DBG(a) /* ignore */ namespace ospray { @@ -420,46 +416,6 @@ namespace ospray { this->tileIsCompleted(td); } - - struct DFBProcessMessageTask -#ifdef OSPRAY_USE_TBB - : public tbb::task -#endif - { - DFB *dfb; - mpi::async::CommLayer::Message *_msg; - - DFBProcessMessageTask(DFB *dfb, - mpi::async::CommLayer::Message *_msg) - : dfb(dfb), _msg(_msg) - {} - -#ifdef OSPRAY_USE_TBB - tbb::task* execute() override -#else - void execute() -#endif - { - switch (_msg->command) { - case DFB::MASTER_WRITE_TILE_NONE: - dfb->processMessage((DFB::MasterTileMessage_NONE*)_msg); - break; - case DFB::MASTER_WRITE_TILE_I8: - dfb->processMessage((DFB::MasterTileMessage_RGBA_I8*)_msg); - break; - case DFB::WORKER_WRITE_TILE: - dfb->processMessage((DFB::WriteTileMessage*)_msg); - break; - default: - assert(0); - }; - delete _msg; -#ifdef OSPRAY_USE_TBB - return nullptr; -#endif - } - }; - void DFB::tileIsCompleted(TileData *tile) { DBG(printf("rank %i: tilecompleted %i,%i\n",mpi::world.rank, @@ -535,20 +491,22 @@ namespace ospray { DBG(PING); -#ifdef OSPRAY_USE_TBB - auto &t = *new(tbb::task::allocate_root())DFBProcessMessageTask(this, _msg); - tbb::task::enqueue(t); -#elif defined(OSPRAY_USE_CILK) - auto fcn = [&](){ - DFBProcessMessageTask t(this, _msg); - t.execute(); - }; - - cilk_spawn fcn(); -#else - DFBProcessMessageTask t(this, _msg); - t.execute(); -#endif + async([&]() { + switch (_msg->command) { + case DFB::MASTER_WRITE_TILE_NONE: + this->processMessage((DFB::MasterTileMessage_NONE*)_msg); + break; + case DFB::MASTER_WRITE_TILE_I8: + this->processMessage((DFB::MasterTileMessage_RGBA_I8*)_msg); + break; + case DFB::WORKER_WRITE_TILE: + this->processMessage((DFB::WriteTileMessage*)_msg); + break; + default: + assert(0); + }; + delete _msg; + }); DBG(PING); } diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index 9ce2dce602..67e9c67b19 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -19,7 +19,7 @@ #include "ospray/render/Renderer.h" #include "ospray/fb/LocalFB.h" #include "ospray/mpi/DistributedFrameBuffer.h" -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/parallel_for.h" #include diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index a4f1110abe..854f962ae5 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -21,7 +21,7 @@ // stl #include -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/parallel_for.h" namespace ospray { diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index d98df69f60..b09e3f626a 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -18,7 +18,7 @@ #include "ospray/lights/Light.h" #include "ospray/common/Data.h" #include "ospray/common/Core.h" -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/parallel_for.h" #include "ospray/render/volume/RaycastVolumeRenderer.h" #include "RaycastVolumeMaterial.h" diff --git a/ospray/volume/BlockBrickedVolume.cpp b/ospray/volume/BlockBrickedVolume.cpp index 0d7dc0c081..bc71989a31 100644 --- a/ospray/volume/BlockBrickedVolume.cpp +++ b/ospray/volume/BlockBrickedVolume.cpp @@ -16,7 +16,7 @@ //ospray #include "ospray/volume/BlockBrickedVolume.h" -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/parallel_for.h" #include "BlockBrickedVolume_ispc.h" // std #include diff --git a/ospray/volume/GhostBlockBrickedVolume.cpp b/ospray/volume/GhostBlockBrickedVolume.cpp index 759cd5c537..a174ff81b3 100644 --- a/ospray/volume/GhostBlockBrickedVolume.cpp +++ b/ospray/volume/GhostBlockBrickedVolume.cpp @@ -16,7 +16,7 @@ //ospray #include "ospray/volume/GhostBlockBrickedVolume.h" -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/parallel_for.h" #include "GhostBlockBrickedVolume_ispc.h" // std #include diff --git a/ospray/volume/StructuredVolume.h b/ospray/volume/StructuredVolume.h index dc2d01c0b9..e3d3608cd6 100644 --- a/ospray/volume/StructuredVolume.h +++ b/ospray/volume/StructuredVolume.h @@ -17,7 +17,7 @@ #pragma once // ospray -#include "ospray/common/parallel_for.h" +#include "ospray/common/tasking/parallel_for.h" #include "ospray/volume/Volume.h" // stl #include From 4666f66ce06f57861b4336919713597674a40305 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Sun, 6 Mar 2016 09:53:45 -0600 Subject: [PATCH 057/310] fix bug when using TBB to execute DFB async tasks --- ospray/common/tasking/async.h | 8 ++++---- ospray/mpi/DistributedFrameBuffer.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index 33195ba236..b31a761ffe 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -24,20 +24,20 @@ namespace ospray { -template -inline void async(const Task& fcn) +template +inline void async(const TASK& fcn) { #ifdef OSPRAY_USE_TBB struct LocalTBBTask : public tbb::task { - Task func; + TASK func; tbb::task* execute() override { func(); return nullptr; } - LocalTBBTask( const Task& f ) : func(f) {} + LocalTBBTask( const TASK& f ) : func(f) {} }; tbb::task::enqueue(*new(tbb::task::allocate_root())LocalTBBTask(fcn)); diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index bab635d3bc..b34c63e9e0 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -491,7 +491,7 @@ namespace ospray { DBG(PING); - async([&]() { + async([=]() { switch (_msg->command) { case DFB::MASTER_WRITE_TILE_NONE: this->processMessage((DFB::MasterTileMessage_NONE*)_msg); From 56033690ebcdc987ae4e96e6258c30dcecdd9311 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Sun, 6 Mar 2016 12:11:53 -0600 Subject: [PATCH 058/310] condense DFB clear task --- ospray/mpi/DistributedFrameBuffer.cpp | 50 ++++++++++----------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index b34c63e9e0..82c6648bc6 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -551,36 +551,6 @@ namespace ospray { } } - struct DFBClearTask - { - DFB *dfb; - DFBClearTask(DFB *dfb, const uint32 fbChannelFlags) - : dfb(dfb), fbChannelFlags(fbChannelFlags) - {}; - void run(size_t jobID) - { - size_t tileID = jobID; - DFB::TileData *td = dfb->myTiles[tileID]; - assert(td); - if (fbChannelFlags & OSP_FB_ACCUM) { - for (int i=0;iaccum.r[i] = 0.f; - for (int i=0;iaccum.g[i] = 0.f; - for (int i=0;iaccum.b[i] = 0.f; - for (int i=0;iaccum.a[i] = 0.f; - for (int i=0;iaccum.z[i] = inf; - } - if (fbChannelFlags & OSP_FB_DEPTH) - for (int i=0;ifinal.z[i] = inf; - if (fbChannelFlags & OSP_FB_COLOR) { - for (int i=0;ifinal.r[i] = 0.f; - for (int i=0;ifinal.g[i] = 0.f; - for (int i=0;ifinal.b[i] = 0.f; - for (int i=0;ifinal.a[i] = 0.f; - } - } - const uint32 fbChannelFlags; - }; - /*! \brief clear (the specified channels of) this frame buffer \details for the *distributed* frame buffer, we assume that @@ -591,10 +561,26 @@ namespace ospray { void DFB::clear(const uint32 fbChannelFlags) { if (!myTiles.empty()) { - DFBClearTask clearTask(this, fbChannelFlags); parallel_for(myTiles.size(), [&](int taskIndex){ - clearTask.run(taskIndex); + DFB::TileData *td = this->myTiles[taskIndex]; + assert(td); + if (fbChannelFlags & OSP_FB_ACCUM) { + for (int i=0;iaccum.r[i] = 0.f; + for (int i=0;iaccum.g[i] = 0.f; + for (int i=0;iaccum.b[i] = 0.f; + for (int i=0;iaccum.a[i] = 0.f; + for (int i=0;iaccum.z[i] = inf; + } + if (fbChannelFlags & OSP_FB_DEPTH) + for (int i=0;ifinal.z[i] = inf; + if (fbChannelFlags & OSP_FB_COLOR) { + for (int i=0;ifinal.r[i] = 0.f; + for (int i=0;ifinal.g[i] = 0.f; + for (int i=0;ifinal.b[i] = 0.f; + for (int i=0;ifinal.a[i] = 0.f; + } }); + if (fbChannelFlags & OSP_FB_ACCUM) accumID = 0; } From 15e1d0ed6ad733721dd8452c859fd806318c1e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 7 Mar 2016 10:26:23 +0100 Subject: [PATCH 059/310] Fix include path of parallel_for.h for ParticleViewer --- apps/particleViewer/ParticleViewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/particleViewer/ParticleViewer.cpp b/apps/particleViewer/ParticleViewer.cpp index be68a946c1..3d04d8fc81 100644 --- a/apps/particleViewer/ParticleViewer.cpp +++ b/apps/particleViewer/ParticleViewer.cpp @@ -21,7 +21,7 @@ #include "apps/common/widgets/glut3D.h" // ospray, for rendering #include "ospray/ospray.h" -#include "common/parallel_for.h" +#include "common/tasking/parallel_for.h" // particle viewer #include "Model.h" #include "uintah.h" From 491910a3f561c567a0c0138bd1e272829bc0e054 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 7 Mar 2016 09:19:40 -0600 Subject: [PATCH 060/310] add tasking system configuration to CONFIGURE_OSPRAY macro for modules --- cmake/ospray.cmake | 71 ++++++++++++++++++++++++++++++++++++++++++- ospray/CMakeLists.txt | 67 ++-------------------------------------- 2 files changed, 72 insertions(+), 66 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index f000a53384..251a5bfe84 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -36,6 +36,7 @@ MARK_AS_ADVANCED(CLEAR CMAKE_CXX_COMPILER) # ".mic"-suffix trick, so we'll put libraries into separate # directories (names 'intel64' and 'mic', respectively) MACRO(CONFIGURE_OSPRAY) + CONFIGURE_TASKING_SYSTEM() # Embree common include directories; others may be added depending on build target. # this section could be sooo much cleaner if embree only used # fully-qualified include names... @@ -45,7 +46,7 @@ MACRO(CONFIGURE_OSPRAY) ${OSPRAY_EMBREE_SOURCE_DIR}/common ${OSPRAY_EMBREE_SOURCE_DIR}/ ${OSPRAY_EMBREE_SOURCE_DIR}/kernels - ) + ) IF (OSPRAY_TARGET STREQUAL "mic") SET(OSPRAY_EXE_SUFFIX ".mic") @@ -322,3 +323,71 @@ MACRO(OSPRAY_CONFIGURE_COMPILER) ENDIF() ENDIF() ENDMACRO() + +## Tasking system configuration macro ## + +MACRO(CONFIGURE_TASKING_SYSTEM) + # ------------------------------------------------------- + # Setup tasking system build configuration + # ------------------------------------------------------- + + IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + SET(CILK_STRING "Cilk") + ENDIF() + + IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + SET(TASKING_DEFAULT ${CILK_STRING}) + ELSE() + SET(TASKING_DEFAULT TBB) + ENDIF() + + SET(OSPRAY_TASKING_SYSTEM ${TASKING_DEFAULT} CACHE STRING + "Use TBB or OpenMP as for per-node thread tasking system") + + SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY + STRINGS TBB ${CILK_STRING} OpenMP) + MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) + + IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") + SET(USE_TBB TRUE) + SET(USE_TBB TRUE PARENT_SCOPE) + SET(USE_CILK FALSE) + SET(USE_CILK FALSE PARENT_SCOPE) + ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") + SET(USE_TBB FALSE) + SET(USE_TBB FALSE PARENT_SCOPE) + SET(USE_CILK TRUE) + SET(USE_CILK TRUE PARENT_SCOPE) + ELSE() + SET(USE_TBB FALSE) + SET(USE_TBB FALSE PARENT_SCOPE) + SET(USE_CILK FALSE) + SET(USE_CILK FALSE PARENT_SCOPE) + ENDIF() + + IF(USE_TBB) + FIND_PACKAGE(TBB REQUIRED) + ADD_DEFINITIONS(-DOSPRAY_USE_TBB) + INCLUDE_DIRECTORIES(${TBB_INCLUDE_DIRS}) + ELSE(USE_TBB) + UNSET(TBB_INCLUDE_DIR CACHE) + UNSET(TBB_LIBRARY CACHE) + UNSET(TBB_LIBRARY_DEBUG CACHE) + UNSET(TBB_LIBRARY_MALLOC CACHE) + UNSET(TBB_LIBRARY_MALLOC_DEBUG CACHE) + UNSET(TBB_INCLUDE_DIR_MIC CACHE) + UNSET(TBB_LIBRARY_MIC CACHE) + UNSET(TBB_LIBRARY_MALLOC_MIC CACHE) + IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "OpenMP") + FIND_PACKAGE(OpenMP) + IF (OPENMP_FOUND) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + SET(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + ENDIF() + ELSE()#Cilk + ADD_DEFINITIONS(-DOSPRAY_USE_CILK) + ENDIF() + ENDIF(USE_TBB) +ENDMACRO() diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 775ebca977..aed71085ad 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -29,75 +29,12 @@ MARK_AS_ADVANCED(EXP_NEW_BB_VOLUME_KERNELS) SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) FIND_PACKAGE(Threads REQUIRED) -# ------------------------------------------------------- -# Setup tasking system build configuration -# ------------------------------------------------------- - -IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") - SET(CILK_STRING "Cilk") -ENDIF() - -IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") - SET(TASKING_DEFAULT ${CILK_STRING}) -ELSE() - SET(TASKING_DEFAULT TBB) -ENDIF() - -SET(OSPRAY_TASKING_SYSTEM ${TASKING_DEFAULT} CACHE STRING - "Use TBB or OpenMP as for per-node thread tasking system") - -SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY - STRINGS TBB ${CILK_STRING} OpenMP) -MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) - -IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") - SET(USE_TBB TRUE) - SET(USE_TBB TRUE PARENT_SCOPE) - SET(USE_CILK FALSE) - SET(USE_CILK FALSE PARENT_SCOPE) -ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") - SET(USE_TBB FALSE) - SET(USE_TBB FALSE PARENT_SCOPE) - SET(USE_CILK TRUE) - SET(USE_CILK TRUE PARENT_SCOPE) -ELSE() - SET(USE_TBB FALSE) - SET(USE_TBB FALSE PARENT_SCOPE) - SET(USE_CILK FALSE) - SET(USE_CILK FALSE PARENT_SCOPE) -ENDIF() - -IF(USE_TBB) - FIND_PACKAGE(TBB REQUIRED) - ADD_DEFINITIONS(-DOSPRAY_USE_TBB) - INCLUDE_DIRECTORIES(${TBB_INCLUDE_DIRS}) -ELSE(USE_TBB) - UNSET(TBB_INCLUDE_DIR CACHE) - UNSET(TBB_LIBRARY CACHE) - UNSET(TBB_LIBRARY_DEBUG CACHE) - UNSET(TBB_LIBRARY_MALLOC CACHE) - UNSET(TBB_LIBRARY_MALLOC_DEBUG CACHE) - UNSET(TBB_INCLUDE_DIR_MIC CACHE) - UNSET(TBB_LIBRARY_MIC CACHE) - UNSET(TBB_LIBRARY_MALLOC_MIC CACHE) - IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "OpenMP") - FIND_PACKAGE(OpenMP) - IF (OPENMP_FOUND) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - SET(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") - ENDIF() - ELSE()#Cilk - ADD_DEFINITIONS(-DOSPRAY_USE_CILK) - ENDIF() -ENDIF(USE_TBB) - # ------------------------------------------------------- # Build and configure embree # ------------------------------------------------------- -# NOTE(jda) - Embree assumes that USE_TBB will be defined correctly (above)... +# NOTE(jda) - Embree assumes that USE_TBB will be defined correctly in +# CONFIGURE_OSPRAY().CONFIGURE_TASKING_SYSTEM() # NOTE(jda) - Only do the embree include once (Xeon), it will build both # Xeon and MIC code if both are enabled. IF (NOT THIS_IS_MIC) From ea09492c0069758febeaaf5bc6c2d660122b8e96 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 7 Mar 2016 10:21:10 -0600 Subject: [PATCH 061/310] default to TBB until Cilk can be verified correct, add notes about wrappers --- cmake/ospray.cmake | 10 ++++++---- ospray/common/tasking/async.h | 7 +++++++ ospray/common/tasking/parallel_for.h | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 251a5bfe84..84f8c7dc36 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -335,11 +335,13 @@ MACRO(CONFIGURE_TASKING_SYSTEM) SET(CILK_STRING "Cilk") ENDIF() - IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") - SET(TASKING_DEFAULT ${CILK_STRING}) - ELSE() + # NOTE(jda) - Always default to TBB, at least until Cilk is *exactly* the same + # as TBB... + #IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + # SET(TASKING_DEFAULT ${CILK_STRING}) + #ELSE() SET(TASKING_DEFAULT TBB) - ENDIF() + #ENDIF() SET(OSPRAY_TASKING_SYSTEM ${TASKING_DEFAULT} CACHE STRING "Use TBB or OpenMP as for per-node thread tasking system") diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index b31a761ffe..8ae1b136a7 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -24,6 +24,13 @@ namespace ospray { +// NOTE(jda) - This abstraction takes a lambda which should take captured +// variables by *value* to ensure no captured references race +// with the task itself. + +// NOTE(jda) - No priority is associated with this call, but could be added +// later with a hint enum, using a default value for the priority +// to not require specifying it. template inline void async(const TASK& fcn) { diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index abb36d3e00..0c17725003 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -24,6 +24,8 @@ namespace ospray { +// NOTE(jda) - This abstraction wraps "fork-join" parallelism, with an implied +// synchronizsation after all of the tasks have run. template inline void parallel_for(int nTasks, const Task& fcn) { From 35c98b98a71ca2d4cd8c150d06c5d80026c4d8b1 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 7 Mar 2016 13:58:41 -0600 Subject: [PATCH 062/310] added helper isnan() and out() functions for debugging ispc vec3f and affine3f; removed test cubes output --- apps/qtViewer/sg/common/Node.cpp | 7 +++++++ apps/qtViewer/sg/common/Node.h | 4 ++-- ospray/CMakeLists.txt | 8 -------- .../kernels/xeon/builders/heuristic_binning.h | 6 +++--- ospray/math/AffineSpace.ih | 10 ++++++++++ ospray/math/vec.ih | 8 ++++++++ 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/apps/qtViewer/sg/common/Node.cpp b/apps/qtViewer/sg/common/Node.cpp index 2f3491b9e8..56585a0efb 100644 --- a/apps/qtViewer/sg/common/Node.cpp +++ b/apps/qtViewer/sg/common/Node.cpp @@ -36,5 +36,12 @@ namespace ospray { namedNodes[name] = node; } + void Node::setFromXML(const xml::Node *const node, + const unsigned char *binBasePtr) + { + throw std::runtime_error(toString()+":setFromXML() not implemented for XML node type " + +node->name); + }; + } } diff --git a/apps/qtViewer/sg/common/Node.h b/apps/qtViewer/sg/common/Node.h index 302bab08a4..7eea808668 100644 --- a/apps/qtViewer/sg/common/Node.h +++ b/apps/qtViewer/sg/common/Node.h @@ -112,8 +112,8 @@ namespace ospray { existant) that contains additional binary data that the xml node fields may point into */ - virtual void setFromXML(const xml::Node *const node, const unsigned char *binBasePtr) - { throw std::runtime_error("setFromXML() not implemented for node type "+node->name); }; + virtual void setFromXML(const xml::Node *const node, + const unsigned char *binBasePtr); //! just for convenience; add a typed 'setParam' function template diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index aed71085ad..47efe80b17 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -219,14 +219,6 @@ IF (OSPRAY_MPI) fb/DisplayWall.cpp ) - # ============================================ - OSPRAY_ADD_EXECUTABLE(ospCreateCompositeTestCubes - mpi/testing/createCompositeTestCubes - ) - OSPRAY_EXE_LINK_LIBRARIES(ospCreateCompositeTestCubes - ospray - ) - ENDIF() # ------------------------------------------------------- diff --git a/ospray/embree-v2.7.1/kernels/xeon/builders/heuristic_binning.h b/ospray/embree-v2.7.1/kernels/xeon/builders/heuristic_binning.h index 42c6838623..f4e4fa41ce 100644 --- a/ospray/embree-v2.7.1/kernels/xeon/builders/heuristic_binning.h +++ b/ospray/embree-v2.7.1/kernels/xeon/builders/heuristic_binning.h @@ -43,7 +43,7 @@ namespace embree num = min(BINS,size_t(4.0f + 0.05f*pinfo.size())); #endif const vfloat4 diag = (vfloat4) pinfo.centBounds.size(); - scale = select(diag > vfloat4(1E-34f),vfloat4(0.99f*num)/diag,vfloat4(0.0f)); + scale = select(diag > vfloat4(1E-13f),vfloat4(0.99f*num)/diag,vfloat4(0.0f)); ofs = (vfloat4) pinfo.centBounds.lower; } @@ -156,7 +156,7 @@ namespace embree } /*! bins an array of primitives */ - __forceinline void bin (const PrimRef* prims, size_t N, const BinMapping& mapping) + __forceinline void bin(const PrimRef* prims, size_t N, const BinMapping& mapping) { if (N == 0) return; @@ -425,7 +425,7 @@ namespace embree } /*! bins an array of primitives */ - __forceinline void bin (const PrimRef* prims, size_t N, const BinMapping<16>& mapping) + __forceinline void bin(const PrimRef* prims, size_t N, const BinMapping<16>& mapping) { const vfloat16 init_min(pos_inf); diff --git a/ospray/math/AffineSpace.ih b/ospray/math/AffineSpace.ih index 0c45ec16eb..7694377e68 100644 --- a/ospray/math/AffineSpace.ih +++ b/ospray/math/AffineSpace.ih @@ -114,3 +114,13 @@ inline varying vec2f operator*(const varying AffineSpace2f a, const varying vec2 /*! short-hand name for AffineSpace3f */ typedef AffineSpace2f affine2f; +inline void out(uniform affine3f a) +{ + print("Affine3f("); + out(a.l.vx); + out(a.l.vy); + out(a.l.vz); + out(a.p); + print(")"); +} + diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 7d06850ca6..5910ce0f12 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -757,3 +757,11 @@ inline uniform bool isnan(uniform vec3f v) inline bool isnan(vec3f v) { return isnan(v.x+v.y+v.z); } + +inline uniform bool isnan(uniform vec3fa v) +{ return isnan(v.x+v.y+v.z); } + +inline bool isnan(vec3fa v) +{ return isnan(v.x+v.y+v.z); } + +inline void out(uniform vec3f v) { print("(%,%,%)",v.x,v.y,v.z); } From 42ffa0063a2af1d6ff1cf0ad2490cdcedfb68441 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 7 Mar 2016 15:06:12 -0600 Subject: [PATCH 063/310] compile fixes, BROKEN: viewers do not run --- CMakeLists.txt | 17 +++++++++++--- apps/common/xml/CMakeLists.txt | 2 +- apps/qtViewer/CMakeLists.txt | 2 +- apps/qtViewer/sg/CMakeLists.txt | 2 +- apps/volumeViewer/CMakeLists.txt | 6 +++-- common/CMakeLists.txt | 39 +++++++++++++++++++------------- ospray/CMakeLists.txt | 24 ++++---------------- 7 files changed, 49 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a5efb6968..97f85e7ec8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,14 +107,25 @@ IF(NOT WIN32) INCLUDE(cmake/doxygen.cmake) ENDIF() +OSPRAY_CONFIGURE_COMPILER() + ############################################################## -# the OSPRay library +# the OSPRay 'common' library ############################################################## -OSPRAY_CONFIGURE_COMPILER() - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) +SET(OSPRAY_TARGET "intel64") +ADD_SUBDIRECTORY(common builddir/ospray_common/intel64) +IF (OSPRAY_MIC) + SET(OSPRAY_TARGET "mic") + ADD_SUBDIRECTORY(common builddir/ospray_common/mic) +ENDIF() + +############################################################## +# the OSPRay library +############################################################## + SET(OSPRAY_TARGET "intel64") ADD_SUBDIRECTORY(ospray builddir/ospray/intel64) IF (OSPRAY_MIC) diff --git a/apps/common/xml/CMakeLists.txt b/apps/common/xml/CMakeLists.txt index eeda2bdb2e..1c2924f8f6 100644 --- a/apps/common/xml/CMakeLists.txt +++ b/apps/common/xml/CMakeLists.txt @@ -21,7 +21,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) ADD_LIBRARY(ospray_xml SHARED XML.cpp) -TARGET_LINK_LIBRARIES(ospray_xml ospray) +TARGET_LINK_LIBRARIES(ospray_xml ospray ospray_common) OSPRAY_SET_LIBRARY_VERSION(ospray_xml) INSTALL(TARGETS ospray_xml LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib diff --git a/apps/qtViewer/CMakeLists.txt b/apps/qtViewer/CMakeLists.txt index ce302c2d41..5590f88ef7 100644 --- a/apps/qtViewer/CMakeLists.txt +++ b/apps/qtViewer/CMakeLists.txt @@ -59,7 +59,7 @@ QT4_WRAP_CPP(MOC_OUTFILES ${MOC_HEADERS}) ADD_EXECUTABLE(ospQtViewer ${SRCS} ${MOC_OUTFILES}) TARGET_LINK_LIBRARIES(ospQtViewer ${LIBS} - ospray_sg${OSPRAY_LIB_SUFFIX} + ospray_sg ${TBB_LIBRARY_MALLOC} ${TBB_LIBRARY} ) diff --git a/apps/qtViewer/sg/CMakeLists.txt b/apps/qtViewer/sg/CMakeLists.txt index 8e860c9380..f52f6eb690 100644 --- a/apps/qtViewer/sg/CMakeLists.txt +++ b/apps/qtViewer/sg/CMakeLists.txt @@ -53,6 +53,6 @@ ADD_LIBRARY(ospray_sg STATIC TARGET_LINK_LIBRARIES(ospray_sg ospray - ospray_ospcommon + ospray_common ospray_xml ) diff --git a/apps/volumeViewer/CMakeLists.txt b/apps/volumeViewer/CMakeLists.txt index 2c6befd7ec..1c329fe7b0 100644 --- a/apps/volumeViewer/CMakeLists.txt +++ b/apps/volumeViewer/CMakeLists.txt @@ -21,8 +21,10 @@ ENDIF (NOT OSPRAY_MODULE_OPENGL_UTIL) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) # setup dependencies -SET(LIBS ${LIBS} ospray ospray_module_loaders) -SET(LIBS ${LIBS} ospray ospray_module_opengl_util) +SET(LIBS ${LIBS} ospray) +SET(LIBS ${LIBS} ospray_common) +SET(LIBS ${LIBS} ospray_module_loaders) +SET(LIBS ${LIBS} ospray_module_opengl_util) # link optional loaders-based modules if built IF (OSPRAY_MODULE_SEISMIC) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 943a02a935..98d014299e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,21 +1,28 @@ -MESSAGE("including ospcommon... bin dir ${LIBRARY_OUTPUT_PATH}") +## ======================================================================== ## +## Copyright 2009-2016 Intel Corporation ## +## ## +## Licensed under the Apache License, Version 2.0 (the "License"); ## +## you may not use this file except in compliance with the License. ## +## You may obtain a copy of the License at ## +## ## +## http://www.apache.org/licenses/LICENSE-2.0 ## +## ## +## Unless required by applicable law or agreed to in writing, software ## +## distributed under the License is distributed on an "AS IS" BASIS, ## +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ## +## See the License for the specific language governing permissions and ## +## limitations under the License. ## +## ======================================================================== ## -IF (DEFINED FORCED_OSPCOMMON_LIB_NAME) - SET(OSPCOMMON_LIB_NAME ${FORCED_OSPCOMMON_LIB_NAME}) -ELSE() - SET(OSPCOMMON_LIB_NAME ospray_ospcommon) -ENDIF() - -ADD_LIBRARY(${OSPCOMMON_LIB_NAME} - SHARED +OSPRAY_ADD_LIBRARY(ospray_common SHARED # STATIC - common.cpp - FileName.cpp - sysinfo.cpp - malloc.cpp - library.cpp - thread.cpp - ) + common.cpp + FileName.cpp + sysinfo.cpp + malloc.cpp + library.cpp + thread.cpp +) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 43cfc5cf25..db0c49cdd1 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -16,20 +16,6 @@ CONFIGURE_OSPRAY() -IF(THIS_IS_MIC) -# SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}/mic) -# SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) -# SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) - SET(FORCED_OSPCOMMON_LIB_NAME "ospray_ospcommon_mic") - ADD_SUBDIRECTORY(../common ospcommon_mic) -ELSE() -# SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}) -# SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) -# SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) - SET(FORCED_OSPCOMMON_LIB_NAME "ospray_ospcommon") - ADD_SUBDIRECTORY(../common ospcommon) -ENDIF() - IF(OSPRAY_BUILD_MPI_DEVICE) OPTION(OSPRAY_EXP_DATA_PARALLEL "Experimental data-parallel compositing mode") OPTION(OSPRAY_PIN_ASYNC "Pin async mpi comm threads?" OFF) @@ -207,6 +193,9 @@ SET(OSPRAY_SOURCES api/LocalDevice.cpp ) +# NOTE(jda) - To be removed when OSPCOMMON is merged for next release +ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) + # ------------------------------------------------------- # MPI components # ------------------------------------------------------- @@ -283,9 +272,6 @@ ENDIF() # CONFIGURE_OSPRAY() and/or CONFIGURE_MPI() ############################################################## -# NOTE(jda) - To be removed when OSPCOMMON is merged for next release -ADD_DEFINITIONS(-DDONT_WANT_INCLUDE_OSPCOMMON_H=1) - IF (THIS_IS_MIC) ADD_DEFINITIONS(-DOSPRAY_TARGET_MIC) ENDIF() @@ -321,8 +307,8 @@ OSPRAY_SET_LIBRARY_VERSION(ospray) OSPRAY_INSTALL_LIBRARY(ospray) # build ospTutorial, for testing -ADD_EXECUTABLE(ospTutorial${OSPRAY_EXE_SUFFIX} ../apps/ospTutorial) -TARGET_LINK_LIBRARIES(ospTutorial${OSPRAY_EXE_SUFFIX} ospray${OSPRAY_LIB_SUFFIX}) +OSPRAY_ADD_EXECUTABLE(ospTutorial ../apps/ospTutorial) +OSPRAY_EXE_LINK_LIBRARIES(ospTutorial ospray ospray_common) ############################################################## From a8b68778c96b1c0f599a4e3d3960807e3cdf1fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 8 Mar 2016 18:46:55 +0100 Subject: [PATCH 064/310] Try on setting RPM dependencies -- seems to vary with Linux distribution --- cmake/package.cmake | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmake/package.cmake b/cmake/package.cmake index 1dd2f95140..b4eb0af7ef 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -162,6 +162,20 @@ ELSE() SET(CPACK_GENERATOR TGZ) SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.linux") ELSE() + IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") + SET(TBB_REQ "tbb >= 3.0") + ENDIF() + IF(CMAKE_VERSION VERSION_LESS "3.4.0") + MESSAGE(WARNING "You need at least v3.4.0 of CMake for generating RPMs") + SET(CPACK_RPM_PACKAGE_REQUIRES ${TBB_REQ}) + ELSE() + # needs to use COMPONENT names in original capitalization (i.e. lowercase) + SET(CPACK_RPM_lib_PACKAGE_REQUIRES ${TBB_REQ}) + SET(CPACK_RPM_lib_mic_PACKAGE_REQUIRES "ospray-lib = ${OSPRAY_VERSION}") + SET(CPACK_RPM_apps_PACKAGE_REQUIRES "ospray-lib >= ${OSPRAY_VERSION}, qt = 4") + SET(CPACK_RPM_devel_PACKAGE_REQUIRES "ospray-lib = ${OSPRAY_VERSION}") + #SET(CPACK_RPM_PACKAGE_DEBUG ON) + ENDIF() SET(CPACK_GENERATOR RPM) SET(CPACK_RPM_PACKAGE_RELEASE 1) # scripts/release_linux.sh assumes "1" SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_RPM_PACKAGE_RELEASE}.x86_64") From 72939e0dc55c22a6e81cf11c0b0b0674ab7a6bcc Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 8 Mar 2016 14:13:59 -0600 Subject: [PATCH 065/310] fix CMake bug where packaging may encounter an unset variable --- CMakeLists.txt | 15 +++++++-------- cmake/ospray.cmake | 6 ------ cmake/package.cmake | 1 + 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a5efb6968..2899309b86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,13 +86,7 @@ SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) SET(OSPRAY_MPI ${OSPRAY_BUILD_MPI_DEVICE}) ############################################################## -# create binary packages; before any INSTALL() invocation/definition -############################################################## - -INCLUDE(package) - -############################################################## -# CMake modules +# CMake modules and macro files ############################################################## INCLUDE(cmake/ospray.cmake) @@ -100,13 +94,18 @@ INCLUDE(cmake/ispc.cmake) SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) - INCLUDE(cmake/mpi.cmake) IF(NOT WIN32) INCLUDE(cmake/doxygen.cmake) ENDIF() +############################################################## +# create binary packages; before any INSTALL() invocation/definition +############################################################## + +INCLUDE(package) + ############################################################## # the OSPRay library ############################################################## diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 84f8c7dc36..5ee6e343d8 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -352,19 +352,13 @@ MACRO(CONFIGURE_TASKING_SYSTEM) IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") SET(USE_TBB TRUE) - SET(USE_TBB TRUE PARENT_SCOPE) SET(USE_CILK FALSE) - SET(USE_CILK FALSE PARENT_SCOPE) ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") SET(USE_TBB FALSE) - SET(USE_TBB FALSE PARENT_SCOPE) SET(USE_CILK TRUE) - SET(USE_CILK TRUE PARENT_SCOPE) ELSE() SET(USE_TBB FALSE) - SET(USE_TBB FALSE PARENT_SCOPE) SET(USE_CILK FALSE) - SET(USE_CILK FALSE PARENT_SCOPE) ENDIF() IF(USE_TBB) diff --git a/cmake/package.cmake b/cmake/package.cmake index b4eb0af7ef..9bcef3e9ea 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -162,6 +162,7 @@ ELSE() SET(CPACK_GENERATOR TGZ) SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.linux") ELSE() + CONFIGURE_TASKING_SYSTEM()# NOTE(jda) - OSPRAY_TASKING_SYSTEM wasn't visible IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") SET(TBB_REQ "tbb >= 3.0") ENDIF() From b7c2ad304e12b31acbe827c7728605a991109988 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 8 Mar 2016 14:37:09 -0600 Subject: [PATCH 066/310] fix the find_package config based on new install paths --- cmake/ospray_cmake_config/osprayConfig.cmake.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index ae22bcfda0..15d233b132 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -18,9 +18,9 @@ # unsets all public (designed to be used externally) variables and reports # error message at priority depending upon [REQUIRED/QUIET/] argument. macro(OSPRAY_REPORT_NOT_FOUND REASON_MSG) - UNSET(OSPRAY_FOUND) - UNSET(OSPRAY_INCLUDE_DIRS) - UNSET(OSPRAY_LIBRARIES) + unset(OSPRAY_FOUND) + unset(OSPRAY_INCLUDE_DIRS) + unset(OSPRAY_LIBRARIES) # Reset the CMake module path to its state when this script was called. set(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH}) @@ -66,7 +66,7 @@ if(WIN32) ) else(WIN32) get_filename_component(CURRENT_ROOT_INSTALL_DIR - ${CURRENT_CONFIG_INSTALL_DIR}/../../ ABSOLUTE + ${CURRENT_CONFIG_INSTALL_DIR}/../../../ ABSOLUTE ) endif(WIN32) @@ -174,8 +174,8 @@ set(OSPRAY_LIBRARIES ${OSPRAY_DEPENDENCIES} #ospray# NOTE(jda) - target disabled (see above) #ospray_embree# NOTE(jda) - target disabled (see above) - ${CMAKE_CURRENT_LIST_DIR}/../../lib/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX} - ${CMAKE_CURRENT_LIST_DIR}/../../lib/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} + ${CURRENT_ROOT_INSTALL_DIR}/lib64/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX} + ${CURRENT_ROOT_INSTALL_DIR}/lib64/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} ) # Reset CMake module path to its state when this script was called. From d963836906f59590d7fb6d5fcc675d9515238f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 8 Mar 2016 19:15:53 +0100 Subject: [PATCH 067/310] Prototype of adaptive accumulation / variance detection for LocalFB only --- apps/modelViewer/modelViewer.cpp | 2 + ospray/fb/LocalFB.cpp | 16 +++- ospray/fb/LocalFB.h | 2 + ospray/fb/LocalFB.ih | 3 + ospray/fb/LocalFB.ispc | 100 +++++++++++++++++++++-- ospray/math/vec.ih | 2 +- ospray/render/pathtracer/PathTracer.ispc | 7 ++ 7 files changed, 122 insertions(+), 10 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 8878ebf525..863432866f 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -394,6 +394,8 @@ namespace ospray { if (displayWall) ospRenderFrame(displayWall->fb,renderer,OSP_FB_COLOR|OSP_FB_ACCUM); ++accumID; + if (accumID%10 == 0) + PRINT(accumID); // set the glut3d widget's frame buffer to the opsray frame buffer, then display ucharFB = (uint32 *) ospMapFrameBuffer(fb, OSP_FB_COLOR); diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 329d666fc0..1de8ce5cd5 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -54,15 +54,19 @@ namespace ospray { else depthBuffer = NULL; - if (hasAccumBuffer) + if (hasAccumBuffer) { accumBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); - else + accumHalfBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); + tileErrorBuffer = new float[divRoundUp(size.x,TILE_SIZE)*divRoundUp(size.y,TILE_SIZE)]; + } else accumBuffer = NULL; ispcEquivalent = ispc::LocalFrameBuffer_create(this,size.x,size.y, colorBufferFormat, colorBuffer, depthBuffer, - accumBuffer); + accumBuffer, + accumHalfBuffer, + tileErrorBuffer); } LocalFrameBuffer::~LocalFrameBuffer() @@ -80,7 +84,11 @@ namespace ospray { default: throw std::runtime_error("color buffer format not supported"); } - if (accumBuffer) alignedFree(accumBuffer); + if (accumBuffer) { + alignedFree(accumBuffer); + alignedFree(accumHalfBuffer); + delete[] tileErrorBuffer; + } } void LocalFrameBuffer::clear(const uint32 fbChannelFlags) diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index d60f48a60a..d8df31a270 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -28,6 +28,8 @@ namespace ospray { NULL */ float *depthBuffer; /*!< one float per pixel, may be NULL */ vec4f *accumBuffer; /*!< one RGBA per pixel, may be NULL */ + vec4f *accumHalfBuffer; /*!< one RGBA per pixel, may be NULL, accumulates every other sample, for variance estimation / stopping */ + float *tileErrorBuffer; /*!< holds error per tile, for variance estimation / stopping */ LocalFrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, diff --git a/ospray/fb/LocalFB.ih b/ospray/fb/LocalFB.ih index 41de71e671..0e8b879f8f 100644 --- a/ospray/fb/LocalFB.ih +++ b/ospray/fb/LocalFB.ih @@ -28,5 +28,8 @@ struct LocalFB void *colorBuffer; uniform float *depthBuffer; uniform vec4f *accumBuffer; + uniform vec4f *accumHalfBuffer; // accumulates every other sample, for variance estimation / stopping + vec2i numTiles; + uniform float *tileErrorBuffer; }; diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index dcc5459195..f2eef4d13b 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -16,11 +16,12 @@ #include "LocalFB.ih" -// number of floats each task is clearing; must be a a mulitple of 16 +// number of floats each task is clearing; must be a mulitple of 16 #define CLEAR_BLOCK_SIZE (32 * 1024) export void LocalFrameBuffer_clearAccum(void *uniform _fb) { + print("LocalFrameBuffer_clearAccum\n"); uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; fb->super.accumID = 0; @@ -32,14 +33,21 @@ export void LocalFrameBuffer_clearAccum(void *uniform _fb) for(uniform int taskIndex = 0; taskIndex < num_blocks; ++taskIndex) { uniform float *uniform fbPointer = (uniform float *uniform)&fb->accumBuffer[0].x; + uniform float *uniform fbHalfPointer + = (uniform float *uniform)&fb->accumHalfBuffer[0].x; uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; + uniform float *uniform blockHalf = fbHalfPointer + taskIndex * CLEAR_BLOCK_SIZE; uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; uniform int end = min(CLEAR_BLOCK_SIZE, num_floats - taskIndex * CLEAR_BLOCK_SIZE); - foreach (x=0 ... end) + foreach (x=0 ... end) { block[x] = 0.f; + blockHalf[x] = 0.f; + } } + foreach (x=0 ... fb->numTiles.x*fb->numTiles.y) + fb->tileErrorBuffer[x] = inf; } } @@ -210,9 +218,41 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, uniform vec4f *uniform accum = (uniform vec4f *uniform)fb->accumBuffer; if (!accum) return; - const float accScale = rcpf(fb->super.accumID+1); - + uniform vec4f *uniform accumHalf = (uniform vec4f *uniform)fb->accumHalfBuffer; + VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; + uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; + uniform float * uniform tileError = &fb->tileErrorBuffer[tileIdx.y*fb->numTiles.x+tileIdx.x]; +// print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, *tileError); + + if (*tileError < 0.0f) { + for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; + + uniform uint32 chunkID = iy*(TILE_SIZE/programCount); + + for (uint32 iix = tile.region.lower.x+programIndex; + iixsuper.size.x+iix; + + vec4f acc = accum[pixelID]; + unmasked { + varyTile->r[chunkID] = -*tileError * acc.x; + varyTile->g[chunkID] = -*tileError * acc.y; + varyTile->b[chunkID] = -*tileError * acc.z; + varyTile->a[chunkID] = -*tileError * acc.w; + } + } + } + return; + } + const uniform float accScale = rcpf(fb->super.accumID+1); + const uniform float accHalfScale = rcpf(fb->super.accumID/2+1); + float err = 0.f; + float cnt = 0.f; + for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; @@ -238,6 +278,25 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, accum[pixelID] = acc; + varying vec3f accHalf = make_vec3f(0.f); + if (fb->super.accumID > 0) + accHalf = make_vec3f(accumHalf[pixelID]); + if ((fb->super.accumID & 1) == 0) { + unmasked { + accHalf.x += varyTile->r[chunkID]; + accHalf.y += varyTile->g[chunkID]; + accHalf.z += varyTile->b[chunkID]; + } + + accumHalf[pixelID] = make_vec4f(accHalf); + } + vec3f accs = accScale * make_vec3f(acc); + vec3f diff = absf(accs - accHalfScale * accHalf); + float den = sqrtf(accs.x + accs.y + accs.z); + if (den > 0) + err = err + (diff.x + diff.y + diff.z) / den; + cnt += 1.0f; + unmasked { varyTile->r[chunkID] = accScale * acc.x; varyTile->g[chunkID] = accScale * acc.y; @@ -246,6 +305,32 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, } } } + uniform float r = sqrt(reduce_add(cnt) / tile.fbSize.x / tile.fbSize.y); + uniform float errf = r * reduce_add(err) / reduce_add(cnt); +// print("[%, %]: \t%\t%\n", tile.region.lower.x/TILE_SIZE, tile.region.lower.y/TILE_SIZE, errf); + if (fb->super.accumID > 3 && errf < 0.0002f) + *tileError = -accScale; + +#if 0 + for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; + + uniform uint32 chunkID = iy*(TILE_SIZE/programCount); + + for (uint32 iix = tile.region.lower.x+programIndex; + iixr[chunkID] = errf > 0.002 ? 1.0f : 0.0f; + varyTile->g[chunkID] = errf*100.f; + varyTile->b[chunkID] = errf > 0.0002f ? 0.4f : 0.0f; + varyTile->a[chunkID] = 1.f; + } + } + } +#endif + tile.g[0] = 1.0f; } @@ -255,7 +340,9 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, uniform int32 colorBufferFormat, void *uniform colorBuffer, void *uniform depthBuffer, - void *uniform accumBuffer) + void *uniform accumBuffer, + void *uniform accumHalfBuffer, + void *uniform tileErrorBuffer) { uniform LocalFB *uniform self = uniform new uniform LocalFB; FrameBuffer_Constructor(&self->super,cClassPtr); @@ -264,5 +351,8 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, self->colorBuffer = colorBuffer; self->depthBuffer = (uniform float *uniform)depthBuffer; self->accumBuffer = (uniform vec4f *uniform)accumBuffer; + self->accumHalfBuffer = (uniform vec4f *uniform)accumHalfBuffer; + self->numTiles = (self->super.size+(TILE_SIZE-1))/TILE_SIZE; + self->tileErrorBuffer = (uniform float *uniform)tileErrorBuffer; return self; } diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 5910ce0f12..755b8b3dc6 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -418,7 +418,7 @@ inline varying vec3f negate(const varying vec3f &a) } \ inline vec4##abb opname (const type a, const vec4##abb b) { \ return make_vec4##abb(a op b.x, a op b.y, a op b.z, a op b.w); \ - } \ + } #define __define_binary_operator(opname,op) \ __define_binary_operator_typed(opname,op,f,float) \ diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 14242abc72..0d589da762 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -20,6 +20,7 @@ #include "materials/Medium.ih" #include "materials/Material.ih" #include "math/random.ih" +#include "fb/LocalFB.ih" #define PDF_CULLING 0.0f //#define USE_DGCOLOR @@ -356,6 +357,12 @@ void PathTracer_renderTileJob(uniform PathTracer *uniform self, uniform int taskIndex) { uniform FrameBuffer *uniform fb = self->super.fb; + uniform LocalFB *uniform lfb = (uniform LocalFB *uniform )self->super.fb; + + uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; + if (lfb->tileErrorBuffer[tileIdx.y*lfb->numTiles.x+tileIdx.x] < 0.0f) + return; + uniform int32 spp = self->super.spp; const uniform int blocks = fb->accumID > 0 || spp > 0 ? From 6b64e14c4fa8a18f2be9bb067ec8992cd5dcf3c5 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Tue, 8 Mar 2016 19:02:57 -0600 Subject: [PATCH 068/310] minor fixes to ispc vec class --- ospray/math/vec.ih | 116 ++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 5910ce0f12..676b83afe5 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -103,14 +103,25 @@ __define_ispc_vector4(float,f); ret.z = v.z; \ return ret; \ } \ - inline UV vec3##ABB##a make_vec3##ABB##a(const UV vec3##IABB##a v) \ + inline UV vec3##ABB make_vec3##ABB(const UV ITYPE x, \ + const UV ITYPE y, \ + const UV ITYPE z) \ { \ - UV vec3##ABB##a ret; \ + UV vec3##ABB ret; \ + ret.x = x; \ + ret.y = y; \ + ret.z = z; \ + return ret; \ + } \ + inline UV vec3##ABB make_vec3##ABB(const UV vec4##IABB v) \ + { \ + UV vec3##ABB ret; \ ret.x = v.x; \ ret.y = v.y; \ ret.z = v.z; \ return ret; \ } \ + /* the '3a' variants */ \ inline UV vec3##ABB##a make_vec3##ABB##a(const UV ITYPE x) \ { \ UV vec3##ABB##a ret; \ @@ -119,14 +130,20 @@ __define_ispc_vector4(float,f); ret.z = x; \ return ret; \ } \ - inline UV vec3##ABB make_vec3##ABB(const UV ITYPE x, \ - const UV ITYPE y, \ - const UV ITYPE z) \ + inline UV vec3##ABB##a make_vec3##ABB##a(const UV vec3##IABB &v) \ { \ - UV vec3##ABB ret; \ - ret.x = x; \ - ret.y = y; \ - ret.z = z; \ + UV vec3##ABB##a ret; \ + ret.x = v.x; \ + ret.y = v.y; \ + ret.z = v.z; \ + return ret; \ + } \ + inline UV vec3##ABB##a make_vec3##ABB##a(const UV vec3##IABB##a v) \ + { \ + UV vec3##ABB##a ret; \ + ret.x = v.x; \ + ret.y = v.y; \ + ret.z = v.z; \ return ret; \ } \ inline UV vec3##ABB##a make_vec3##ABB##a(const UV ITYPE x, \ @@ -139,14 +156,6 @@ __define_ispc_vector4(float,f); ret.z = z; \ return ret; \ } \ - inline UV vec3##ABB make_vec3##ABB(const UV vec4##IABB v) \ - { \ - UV vec3##ABB ret; \ - ret.x = v.x; \ - ret.y = v.y; \ - ret.z = v.z; \ - return ret; \ - } \ inline UV vec3##ABB##a make_vec3##ABB##a(const UV vec4##IABB v) \ { \ UV vec3##ABB##a ret; \ @@ -156,6 +165,10 @@ __define_ispc_vector4(float,f); return ret; \ } \ + + + + /*! defines all constructors "make_vec4[T]" for 4-vector type */ #define __define_ispc_constructors4(UV,TYPE,ABB,ITYPE,IABB) \ /*! construct vec4 from a single scalar */ \ @@ -420,9 +433,9 @@ inline varying vec3f negate(const varying vec3f &a) return make_vec4##abb(a op b.x, a op b.y, a op b.z, a op b.w); \ } \ -#define __define_binary_operator(opname,op) \ - __define_binary_operator_typed(opname,op,f,float) \ - __define_binary_operator_typed(opname,op,i,int32) \ +#define __define_binary_operator(opname,op) \ + __define_binary_operator_typed(opname,op,f,float) \ + __define_binary_operator_typed(opname,op,i,int32) \ __define_binary_operator_typed(opname,op,ui,uint32) @@ -439,12 +452,20 @@ __define_binary_operator( mul, * ); #undef __define_binary_operator +inline float reduce_mul(const vec3f v) +{ return v.x * v.y * v.z; } +inline uniform float reduce_mul(const uniform vec3f v) +{ return v.x * v.y * v.z; } + inline float reduce_max(const vec3f v) { return max(max(v.x,v.y),v.z); } inline float reduce_add(const vec3f v) { return v.x+v.y+v.z; } +inline uniform float reduce_add(const uniform vec3f v) +{ return v.x+v.y+v.z; } + inline float reduce_avg(const vec3f v) { return (v.x+v.y+v.z)*(1.0f/3.0f); } @@ -519,22 +540,22 @@ inline vec3f safe_normalize(const vec3f v) { return v * (1.f/sqrt(max(1e-6f,dot(v,v)))); } -#define __lift_unary_fct(F) \ - inline uniform vec2f F(const uniform vec2f v) \ - { return make_vec2f(F(v.x),F(v.y)); } \ - inline vec2f F(const vec2f v) \ - { return make_vec2f(F(v.x),F(v.y)); } \ - inline uniform vec3f F(const uniform vec3f v) \ - { return make_vec3f(F(v.x),F(v.y),F(v.z)); } \ - inline vec3f F(const vec3f v) \ - { return make_vec3f(F(v.x),F(v.y),F(v.z)); } \ - inline uniform vec3fa F(const uniform vec3fa v) \ - { return make_vec3fa(F(v.x),F(v.y),F(v.z)); } \ - inline vec3fa F(const vec3fa v) \ - { return make_vec3fa(F(v.x),F(v.y),F(v.z)); } \ - inline uniform vec4f F(const uniform vec4f v) \ - { return make_vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); } \ - inline vec4f F(const vec4f v) \ +#define __lift_unary_fct(F) \ + inline uniform vec2f F(const uniform vec2f v) \ + { return make_vec2f(F(v.x),F(v.y)); } \ + inline vec2f F(const vec2f v) \ + { return make_vec2f(F(v.x),F(v.y)); } \ + inline uniform vec3f F(const uniform vec3f v) \ + { return make_vec3f(F(v.x),F(v.y),F(v.z)); } \ + inline vec3f F(const vec3f v) \ + { return make_vec3f(F(v.x),F(v.y),F(v.z)); } \ + inline uniform vec3fa F(const uniform vec3fa v) \ + { return make_vec3fa(F(v.x),F(v.y),F(v.z)); } \ + inline vec3fa F(const vec3fa v) \ + { return make_vec3fa(F(v.x),F(v.y),F(v.z)); } \ + inline uniform vec4f F(const uniform vec4f v) \ + { return make_vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); } \ + inline vec4f F(const vec4f v) \ { return make_vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); } __lift_unary_fct(absf) @@ -542,6 +563,8 @@ __lift_unary_fct(rcpf) __lift_unary_fct(expf) __lift_unary_fct(logf) +__lift_unary_fct(floor) +__lift_unary_fct(abs) __lift_unary_fct(rcp) __lift_unary_fct(exp) __lift_unary_fct(frac) @@ -676,21 +699,9 @@ inline vec3i operator-(const varying vec3i &a, const varying int32 b) inline uniform vec3i operator/(const uniform vec3i &a, const uniform int b) { return(make_vec3i(a.x / b, a.y / b, a.z / b)); } -inline vec3i max(const varying vec3i &a, const varying int32 b) -{ return(make_vec3i(max(a.x, b), max(a.y, b), max(a.z, b))); } - -// inline vec3i min(const uniform vec3i &a, const varying vec3i &b) -// { return(make_vec3i(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z))); } - -inline vec3f make_vec3f(const vec3i &a) -{ return make_vec3f(a.x, a.y, a.z); } - inline vec3f float_cast(const vec3i &a) { return make_vec3f(a); } -inline vec3i make_vec3i(const vec3f &a) -{ return make_vec3i((int)a.x, (int)a.y, (int)a.z); } - inline vec3i integer_cast(const vec3f &a) { return make_vec3i(a); } @@ -709,12 +720,6 @@ inline vec3f powf(const vec3f v, const float f) inline uniform vec3f powf(const uniform vec3f v, const uniform float f) { return make_vec3f(powf(v.x,f),powf(v.y,f),powf(v.z,f)); } -inline uniform vec3fa make_vec3fa(const uniform vec3f v) -{ return make_vec3fa(v.x,v.y,v.z); } - -inline vec3fa make_vec3fa(const vec3f v) -{ return make_vec3fa(v.x,v.y,v.z); } - inline vec3f clamp(const vec3f &a, const uniform vec3f &b, const uniform vec3f &c) { return(make_vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); } @@ -765,3 +770,6 @@ inline bool isnan(vec3fa v) { return isnan(v.x+v.y+v.z); } inline void out(uniform vec3f v) { print("(%,%,%)",v.x,v.y,v.z); } +inline void out(vec3f v) { print("\n(%\n %\n %)",v.x,v.y,v.z); } +inline void out(uniform vec3i v) { print("(%,%,%)",v.x,v.y,v.z); } +inline void out(vec3i v) { print("\n(%\n %\n %)",v.x,v.y,v.z); } From e7ca951f247cbc03d4c1befbb166c8caf38a682d Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 9 Mar 2016 09:57:15 -0600 Subject: [PATCH 069/310] add macro for warning about something only once (first configure) --- CMakeLists.txt | 4 ---- cmake/ospray.cmake | 15 +++++++++++++++ cmake/package.cmake | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2899309b86..725f354c07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,10 +35,6 @@ SET(OSPRAY_VERSION ) SET(OSPRAY_SOVERSION 0) -MACRO(PRINT var) - MESSAGE("${var} = ${${var}}") -ENDMACRO() - SET(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") IF (WIN32) IF (NOT OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 5ee6e343d8..1a63d71136 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -30,6 +30,12 @@ MARK_AS_ADVANCED(OSPRAY_PIXELS_PER_JOB) # unhide compiler to make it easier for users to see what they are using MARK_AS_ADVANCED(CLEAR CMAKE_CXX_COMPILER) +## Macro for printing CMake variables ## + +MACRO(PRINT var) + MESSAGE("${var} = ${${var}}") +ENDMACRO() + # Configure the output directories. To allow IMPI to do its magic we # will put *executables* into the (same) build directory, but tag # mic-executables with ".mic". *libraries* cannot use the @@ -196,6 +202,15 @@ MACRO(CONFIGURE_OSPRAY) ENDMACRO() +## Macro to make a warning message that only appears once ## + +MACRO(OSPRAY_WARN_ONCE message identifier) + SET(INTERNAL_WARNING "${identifier}_WARN_ONCE") + IF(NOT ${INTERNAL_WARNING}) + MESSAGE(WARNING ${message}) + SET(${INTERNAL_WARNING} ON CACHE INTERNAL "" FORCE) + ENDIF() +ENDMACRO() ## Target creation macros ## diff --git a/cmake/package.cmake b/cmake/package.cmake index 9bcef3e9ea..47e7bc94ec 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -167,7 +167,7 @@ ELSE() SET(TBB_REQ "tbb >= 3.0") ENDIF() IF(CMAKE_VERSION VERSION_LESS "3.4.0") - MESSAGE(WARNING "You need at least v3.4.0 of CMake for generating RPMs") + OSPRAY_WARN_ONCE("You need at least v3.4.0 of CMake for generating RPMs" PACKAGING) SET(CPACK_RPM_PACKAGE_REQUIRES ${TBB_REQ}) ELSE() # needs to use COMPONENT names in original capitalization (i.e. lowercase) From 7c57b8defb0bad40b16aad9175a001f857c526b6 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 9 Mar 2016 11:23:00 -0600 Subject: [PATCH 070/310] fixed bug in data distributed code when dealing with numblocks < num workers --- modules/loaders/RawVolumeFile.cpp | 6 +++--- ospray/volume/DataDistributedBlockedVolume.cpp | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/loaders/RawVolumeFile.cpp b/modules/loaders/RawVolumeFile.cpp index ce695a12ba..e14e2f62a6 100644 --- a/modules/loaders/RawVolumeFile.cpp +++ b/modules/loaders/RawVolumeFile.cpp @@ -182,9 +182,9 @@ ospray::vec2f voxelRange(+std::numeric_limits::infinity(), (osp::vec3i&)region_lo, (osp::vec3i&)region_sz); - std::cerr << "volume load: " - << float(z) / float(volumeDimensions.z) * 100. << " %" - << std::endl; + // std::cerr << "volume load: " + // << float(z) / float(volumeDimensions.z) * 100. << " %" + // << std::endl; } // Clean up. diff --git a/ospray/volume/DataDistributedBlockedVolume.cpp b/ospray/volume/DataDistributedBlockedVolume.cpp index 06be4a2448..7577773a3a 100644 --- a/ospray/volume/DataDistributedBlockedVolume.cpp +++ b/ospray/volume/DataDistributedBlockedVolume.cpp @@ -202,7 +202,8 @@ namespace ospray { } else { block->firstOwner = (blockID * numWorkers) / numDDBlocks; int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks; - block->numOwners = nextBlockFirstOwner - block->firstOwner + 1; + block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1; + std::cout << "block " << vec3i(ix,iy,iz) << " first=" << block->firstOwner << ", num = " << block->numOwners << std::endl; } block->isMine = (ospray::core::getWorkerRank() >= block->firstOwner) From 505d3975d1a25e13946649fe4f3eec6f79e9e06c Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 9 Mar 2016 11:24:54 -0600 Subject: [PATCH 071/310] removed debugging output from ddblockvol --- ospray/volume/DataDistributedBlockedVolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/volume/DataDistributedBlockedVolume.cpp b/ospray/volume/DataDistributedBlockedVolume.cpp index 7577773a3a..3a67e07ec9 100644 --- a/ospray/volume/DataDistributedBlockedVolume.cpp +++ b/ospray/volume/DataDistributedBlockedVolume.cpp @@ -203,7 +203,7 @@ namespace ospray { block->firstOwner = (blockID * numWorkers) / numDDBlocks; int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks; block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1; - std::cout << "block " << vec3i(ix,iy,iz) << " first=" << block->firstOwner << ", num = " << block->numOwners << std::endl; + // std::cout << "block " << vec3i(ix,iy,iz) << " first=" << block->firstOwner << ", num = " << block->numOwners << std::endl; } block->isMine = (ospray::core::getWorkerRank() >= block->firstOwner) From a16f905af902ecde4b07730e13d6bf8e97db13df Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 9 Mar 2016 13:02:51 -0600 Subject: [PATCH 072/310] thrown out all template code for AMR and AMRVolume - it all worked only for floats, anyway, and only complicated the code --- .../volume/DataDistributedBlockedVolume.cpp | 107 +++++++++--------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/ospray/volume/DataDistributedBlockedVolume.cpp b/ospray/volume/DataDistributedBlockedVolume.cpp index 3a67e07ec9..111b2a2816 100644 --- a/ospray/volume/DataDistributedBlockedVolume.cpp +++ b/ospray/volume/DataDistributedBlockedVolume.cpp @@ -85,7 +85,7 @@ namespace ospray { void DataDistributedBlockedVolume::buildAccelerator() { std::cout << "intentionally SKIP building an accelerator for data parallel " - << "volume" << std::endl; + << "volume (this'll be done on the brick level)" << std::endl; } std::string DataDistributedBlockedVolume::toString() const @@ -154,7 +154,6 @@ namespace ospray { "ospSetRegion())"); ddBlocks = getParam3i("num_dp_blocks",vec3i(4,4,4)); - PRINT(ddBlocks); blockSize = divRoundUp(dimensions,ddBlocks); std::cout << "#osp:dp: using data parallel volume of " << ddBlocks << " blocks, blockSize is " << blockSize << std::endl; @@ -183,65 +182,63 @@ namespace ospray { "mode..."); } int64 numWorkers = ospray::core::getWorkerCount(); - PRINT(numDDBlocks); - PRINT(numWorkers); + // PRINT(numDDBlocks); + // PRINT(numWorkers); voxelType = getParamString("voxelType", "unspecified"); // if (numDDBlocks >= numWorkers) { - // we have more workers than blocks - use one owner per block, - // meaning we'll end up with multiple blocks per worker - int blockID = 0; - for (int iz=0;iz= numWorkers) { - block->firstOwner = blockID % numWorkers; - block->numOwners = 1; - } else { - block->firstOwner = (blockID * numWorkers) / numDDBlocks; - int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks; - block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1; - // std::cout << "block " << vec3i(ix,iy,iz) << " first=" << block->firstOwner << ", num = " << block->numOwners << std::endl; - } - block->isMine - = (ospray::core::getWorkerRank() >= block->firstOwner) - && (ospray::core::getWorkerRank() < - (block->firstOwner + block->numOwners)); - block->domain.lower = vec3i(ix,iy,iz) * blockSize; - block->domain.upper = min(block->domain.lower+blockSize,dimensions); - block->bounds.lower = gridOrigin + - (gridSpacing * vec3f(block->domain.lower)); - block->bounds.upper = gridOrigin + - (gridSpacing * vec3f(block->domain.upper)); - - // XXX?? 1 overlap? - block->domain.upper = min(block->domain.upper+vec3i(1),dimensions); - + // we have more workers than blocks - use one owner per block, + // meaning we'll end up with multiple blocks per worker + int blockID = 0; + for (int iz=0;iz= numWorkers) { + block->firstOwner = blockID % numWorkers; + block->numOwners = 1; + } else { + block->firstOwner = (blockID * numWorkers) / numDDBlocks; + int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks; + block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1; + } + block->isMine + = (ospray::core::getWorkerRank() >= block->firstOwner) + && (ospray::core::getWorkerRank() < + (block->firstOwner + block->numOwners)); + block->domain.lower = vec3i(ix,iy,iz) * blockSize; + block->domain.upper = min(block->domain.lower+blockSize,dimensions); + block->bounds.lower = gridOrigin + + (gridSpacing * vec3f(block->domain.lower)); + block->bounds.upper = gridOrigin + + (gridSpacing * vec3f(block->domain.upper)); + + // iw: add one voxel overlap, so we can properly interpolate + // even across block boundaries (we need the full *cell* on + // the right side, not just the last *voxel*!) + block->domain.upper = min(block->domain.upper+vec3i(1),dimensions); + + + if (block->isMine) { + Ref volume = new BlockBrickedVolume; + vec3i blockDims = block->domain.upper - block->domain.lower; + volume->findParam("dimensions",1)->set(blockDims); + volume->findParam("gridOrigin",1)->set(block->bounds.lower); + volume->findParam("gridSpacing",1)->set(gridSpacing); + volume->findParam("voxelType",1)->set(voxelType.c_str()); - if (block->isMine) { - Ref volume = new BlockBrickedVolume; - vec3i blockDims = block->domain.upper - block->domain.lower; - volume->findParam("dimensions",1)->set(blockDims); - volume->findParam("gridOrigin",1)->set(block->bounds.lower); - volume->findParam("gridSpacing",1)->set(gridSpacing); - volume->findParam("voxelType",1)->set(voxelType.c_str()); - - printf("rank %li owns block %i,%i,%i (ID %i), dims %i %i %i\n", - (size_t)core::getWorkerRank(),ix,iy,iz, - blockID,blockDims.x,blockDims.y,blockDims.z); - block->cppVolume = volume; - block->ispcVolume = NULL; //volume->getIE(); - } else { - block->ispcVolume = NULL; - block->cppVolume = NULL; - } + printf("rank %li owns block %i,%i,%i (ID %i), dims %i %i %i\n", + (size_t)core::getWorkerRank(),ix,iy,iz, + blockID,blockDims.x,blockDims.y,blockDims.z); + block->cppVolume = volume; + block->ispcVolume = NULL; //volume->getIE(); + } else { + block->ispcVolume = NULL; + block->cppVolume = NULL; } - // } else { - // FATAL("not implemented yet - more workers than blocks ...");//TODO - // } - + } + // Create an ISPC BlockBrickedVolume object and assign type-specific // function pointers. ispcEquivalent = ispc::DDBVolume_create(this, From 3ec9068e0df4b5618466060341af1d3d8937a855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 10 Mar 2016 10:17:44 +0100 Subject: [PATCH 073/310] Use OSPRAY_WARN_ONCE everywhere --- cmake/ispc.cmake | 7 +++--- cmake/ospray.cmake | 55 +++++++++++++++++---------------------------- cmake/package.cmake | 2 +- 3 files changed, 25 insertions(+), 39 deletions(-) diff --git a/cmake/ispc.cmake b/cmake/ispc.cmake index 23851eee83..4b73e127fa 100644 --- a/cmake/ispc.cmake +++ b/cmake/ispc.cmake @@ -73,10 +73,9 @@ IF(NOT ISPC_VERSION) ENDIF() # warn about recommended ISPC version on KNC -IF (OSPRAY_MIC AND NOT ISPC_VERSION VERSION_EQUAL ISPC_VERSION_RECOMMENDED_KNC - AND NOT OSPRAY_WARNED_KNC_ISPC_VERSION) - MESSAGE("Warning: use of ISPC v${ISPC_VERSION_RECOMMENDED_KNC} is recommended on KNC.") - SET(OSPRAY_WARNED_KNC_ISPC_VERSION ON CACHE INTERNAL "Warned about recommended ISPC version with KNC.") +IF (OSPRAY_MIC AND NOT ISPC_VERSION VERSION_EQUAL ISPC_VERSION_RECOMMENDED_KNC) + OSPRAY_WARN_ONCE(KNC_ISPC_VERSION + "Use of ISPC v${ISPC_VERSION_RECOMMENDED_KNC} is recommended on KNC.") ENDIF() GET_FILENAME_COMPONENT(ISPC_DIR ${ISPC_EXECUTABLE} PATH) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 1a63d71136..b864044f00 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -31,11 +31,28 @@ MARK_AS_ADVANCED(OSPRAY_PIXELS_PER_JOB) MARK_AS_ADVANCED(CLEAR CMAKE_CXX_COMPILER) ## Macro for printing CMake variables ## - MACRO(PRINT var) MESSAGE("${var} = ${${var}}") ENDMACRO() +## Macro to print a warning message that only appears once ## +MACRO(OSPRAY_WARN_ONCE identifier message) + SET(INTERNAL_WARNING "OSPRAY_WARNED_${identifier}") + IF(NOT ${INTERNAL_WARNING}) + MESSAGE(WARNING ${message}) + SET(${INTERNAL_WARNING} ON CACHE INTERNAL "Warned about '${message}'") + ENDIF() +ENDMACRO() + +## Macro check for compiler support of ISA ## +MACRO(OSPRAY_CHECK_COMPILER_SUPPORT ISA) + IF (OSPRAY_EMBREE_ENABLE_${ISA} AND NOT OSPRAY_COMPILER_SUPPORTS_${ISA}) + OSPRAY_WARN_ONCE(MISSING_${ISA} "Need at least version ${GCC_VERSION_REQUIRED_${ISA}} of gcc for ${ISA}. Disabling ${ISA}.\nTo compile for ${ISA}, please switch to either 'ICC'-compiler, or upgrade your gcc version.") + SET(OSPRAY_EMBREE_ENABLE_${ISA} false) + ENDIF() +ENDMACRO() + + # Configure the output directories. To allow IMPI to do its magic we # will put *executables* into the (same) build directory, but tag # mic-executables with ".mic". *libraries* cannot use the @@ -157,29 +174,9 @@ MACRO(CONFIGURE_OSPRAY) ENDIF() - IF (OSPRAY_EMBREE_ENABLE_AVX AND NOT OSPRAY_COMPILER_SUPPORTS_AVX) - IF (NOT OSPRAY_WARNED_MISSING_AVX) - MESSAGE("Warning: Need at least version ${GCC_VERSION_REQUIRED_AVX} of gcc for AVX. Disabling AVX.\nTo compile for AVX, please switch to either 'ICC'-compiler, or upgrade your gcc version.") - SET(OSPRAY_WARNED_MISSING_AVX ON CACHE INTERNAL "Warned about missing AVX support.") - ENDIF() - SET(OSPRAY_EMBREE_ENABLE_AVX false) - ENDIF() - - IF (OSPRAY_EMBREE_ENABLE_AVX2 AND NOT OSPRAY_COMPILER_SUPPORTS_AVX2) - IF (NOT OSPRAY_WARNED_MISSING_AVX2) - MESSAGE("Warning: Need at least version ${GCC_VERSION_REQUIRED_AVX2} of gcc for AVX2. Disabling AVX2.\nTo compile for AVX2, please switch to either 'ICC'-compiler, or upgrade your gcc version.") - SET(OSPRAY_WARNED_MISSING_AVX2 ON CACHE INTERNAL "Warned about missing AVX2 support.") - ENDIF() - SET(OSPRAY_EMBREE_ENABLE_AVX2 false) - ENDIF() - - IF (OSPRAY_EMBREE_ENABLE_AVX512 AND NOT OSPRAY_COMPILER_SUPPORTS_AVX512) - IF (NOT OSPRAY_WARNED_MISSING_AVX2) - MESSAGE("Warning: Need at least version ${GCC_VERSION_REQUIRED_AVX512} of gcc for AVX512. Disabling AVX512.\nTo compile for AVX512, please switch to either 'ICC'-compiler, or upgrade your gcc version.") - SET(OSPRAY_WARNED_MISSING_AVX512 ON CACHE INTERNAL "Warned about missing AVX512 support.") - ENDIF() - SET(OSPRAY_EMBREE_ENABLE_AVX512 false) - ENDIF() + OSPRAY_CHECK_COMPILER_SUPPORT(AVX) + OSPRAY_CHECK_COMPILER_SUPPORT(AVX2) + OSPRAY_CHECK_COMPILER_SUPPORT(AVX512) IF (THIS_IS_MIC) # whether to build in MIC/xeon phi support @@ -202,16 +199,6 @@ MACRO(CONFIGURE_OSPRAY) ENDMACRO() -## Macro to make a warning message that only appears once ## - -MACRO(OSPRAY_WARN_ONCE message identifier) - SET(INTERNAL_WARNING "${identifier}_WARN_ONCE") - IF(NOT ${INTERNAL_WARNING}) - MESSAGE(WARNING ${message}) - SET(${INTERNAL_WARNING} ON CACHE INTERNAL "" FORCE) - ENDIF() -ENDMACRO() - ## Target creation macros ## MACRO(OSPRAY_ADD_EXECUTABLE name) diff --git a/cmake/package.cmake b/cmake/package.cmake index 47e7bc94ec..eea4e12d34 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -167,7 +167,7 @@ ELSE() SET(TBB_REQ "tbb >= 3.0") ENDIF() IF(CMAKE_VERSION VERSION_LESS "3.4.0") - OSPRAY_WARN_ONCE("You need at least v3.4.0 of CMake for generating RPMs" PACKAGING) + OSPRAY_WARN_ONCE(RPM_PACKAGING "You need at least v3.4.0 of CMake for generating RPMs") SET(CPACK_RPM_PACKAGE_REQUIRES ${TBB_REQ}) ELSE() # needs to use COMPONENT names in original capitalization (i.e. lowercase) From 4947f351dea9af4c1b66a1227a9a4707e632615c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 10 Mar 2016 10:59:17 +0100 Subject: [PATCH 074/310] Due to (braking) API changes next release will be v0.10.0 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 725f354c07..e7715ad2ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ ENDIF() SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) SET(OSPRAY_VERSION_MAJOR 0) -SET(OSPRAY_VERSION_MINOR 9) -SET(OSPRAY_VERSION_PATCH 2) +SET(OSPRAY_VERSION_MINOR 10) +SET(OSPRAY_VERSION_PATCH 0) SET(OSPRAY_VERSION ${OSPRAY_VERSION_MAJOR}.${OSPRAY_VERSION_MINOR}.${OSPRAY_VERSION_PATCH} ) From a1a20cc12cb428effa3ad2a616f73c18e8c23982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 10 Mar 2016 11:24:58 +0100 Subject: [PATCH 075/310] Workaround crash on Windows ISPC passes SIMD masks via pointer on Windows. The *_bounds functions are implemented in ISPC but called by C++ code by Embree, which did not pass a mask -- the mask is not used anyway, because the functions operate with uniforms only. However, the mask is still read, resulting in a crash when the pointer is not properly aligned. The workaround replaces the "if" with a conditional move, resulting in the mask (and the crash) optimized away. --- ospray/geometry/Cylinders.ispc | 8 +++----- ospray/geometry/Spheres.ispc | 9 +++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/ospray/geometry/Cylinders.ispc b/ospray/geometry/Cylinders.ispc index 7d487f01c7..75111a146d 100644 --- a/ospray/geometry/Cylinders.ispc +++ b/ospray/geometry/Cylinders.ispc @@ -50,10 +50,8 @@ void Cylinders_bounds(uniform Cylinders *uniform geometry, uniform box3fa &bbox) { uniform uint8 *uniform cylinderPtr = geometry->data + geometry->bytesPerCylinder*primID; - uniform float radius = geometry->radius; - if (geometry->offset_radius >= 0) { - radius = *((uniform float *)(cylinderPtr+geometry->offset_radius)); - } + uniform bool offr = geometry->offset_radius >= 0; + uniform float radius = offr ? *((uniform float *)(cylinderPtr+geometry->offset_radius)) : geometry->radius; uniform vec3f v0 = *((uniform vec3f*)(cylinderPtr+geometry->offset_v0)); uniform vec3f v1 = *((uniform vec3f*)(cylinderPtr+geometry->offset_v1)); bbox = make_box3fa(min(v0,v1)-make_vec3f(radius), @@ -155,7 +153,7 @@ static void Cylinders_postIntersect(uniform Geometry *uniform geometry, } } -export void *uniform Cylinders_create(void *uniform cppEquivalent) +export void *uniform Cylinders_create(void *uniform cppEquivalent) { uniform Cylinders *uniform geom = uniform new uniform Cylinders; Geometry_Constructor(&geom->geometry,cppEquivalent, diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index b17a2e3bc9..edd51d6505 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -92,11 +92,8 @@ void Spheres_bounds(uniform Spheres *uniform geometry, uniform box3fa &bbox) { uniform uint8 *uniform spherePtr = geometry->data + geometry->bytesPerSphere*((uniform int64)primID); - uniform float radius = geometry->radius; - - if (geometry->offset_radius >= 0) { - radius = *((uniform float *uniform)(spherePtr+geometry->offset_radius)); - } + uniform bool offr = geometry->offset_radius >= 0; + uniform float radius = offr ? *((uniform float *uniform)(spherePtr+geometry->offset_radius)) : geometry->radius; uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+geometry->offset_center)); bbox = make_box3fa(center-make_vec3f(radius),center+make_vec3f(radius)); } @@ -144,7 +141,7 @@ void Spheres_intersect(uniform Spheres *uniform geometry, } -export void *uniform Spheres_create(void *uniform cppEquivalent) +export void *uniform Spheres_create(void *uniform cppEquivalent) { uniform Spheres *uniform geom = uniform new uniform Spheres; Geometry_Constructor(&geom->geometry,cppEquivalent, From 73e5cb58fca8e20f48cc6d3063cc4cb6521ef332 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 13:53:11 -0600 Subject: [PATCH 076/310] add "Debug" tasking system option, removes tasking system for debugging --- cmake/ospray.cmake | 7 +++++-- ospray/common/tasking/async.h | 2 +- ospray/common/tasking/parallel_for.h | 6 +++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 3c0255d978..5abcf89f84 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -349,7 +349,7 @@ MACRO(CONFIGURE_TASKING_SYSTEM) "Use TBB or OpenMP as for per-node thread tasking system") SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY - STRINGS TBB ${CILK_STRING} OpenMP) + STRINGS TBB ${CILK_STRING} OpenMP Debug) MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") @@ -383,9 +383,12 @@ MACRO(CONFIGURE_TASKING_SYSTEM) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + ADD_DEFINITIONS(-DOSPRAY_USE_OMP) ENDIF() - ELSE()#Cilk + ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") ADD_DEFINITIONS(-DOSPRAY_USE_CILK) + ELSE()#Debug + # Do nothing, will fall back to scalar code (useful for debugging) ENDIF() ENDIF(USE_TBB) ENDMACRO() diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index 8ae1b136a7..368f80e0ae 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -50,7 +50,7 @@ inline void async(const TASK& fcn) tbb::task::enqueue(*new(tbb::task::allocate_root())LocalTBBTask(fcn)); #elif defined(OSPRAY_USE_CILK) cilk_spawn fcn(); -#else// OpenMP --> synchronous! +#else// OpenMP or Debug --> synchronous! fcn(); #endif } diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index 0c17725003..df7d4297d0 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -35,11 +35,15 @@ inline void parallel_for(int nTasks, const Task& fcn) cilk_for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); } -#else +#elif defined(OSPRAY_USE_OMP) # pragma omp parallel for schedule(dynamic) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); } +#else // Debug (no tasking system) + for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { + fcn(taskIndex); + } #endif } From 6e8d179a41980a7769d8e562aaac54d421a4e5a7 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 14:36:24 -0600 Subject: [PATCH 077/310] compile fixes for MPI enabled build --- ospray/CMakeLists.txt | 3 +- ospray/include/ospray/ospray.h | 112 +++++++++++++------------- ospray/mpi/DistributedFrameBuffer.cpp | 2 - ospray/mpi/MPIDevice.cpp | 3 +- ospray/mpi/MPIDevice.h | 2 +- 5 files changed, 59 insertions(+), 63 deletions(-) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 050145f114..5f74b73fc0 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -318,7 +318,7 @@ IF (OSPRAY_MPI) ENDIF() OSPRAY_ADD_EXECUTABLE(ospray_mpi_worker mpi/MPIWorker.cpp) - OSPRAY_EXE_LINK_LIBRARIES(ospray_mpi_worker ospray) + OSPRAY_EXE_LINK_LIBRARIES(ospray_mpi_worker ospray ospray_common) OSPRAY_INSTALL_EXE(ospray_mpi_worker) ENDIF() @@ -338,6 +338,7 @@ IF (OSPRAY_BUILD_COI_DEVICE) OSPRAY_ADD_EXECUTABLE(ospray_coi_worker api/COIDeviceWorker.cpp) OSPRAY_EXE_LINK_LIBRARIES(ospray_coi_worker ospray + ospray_common ${LIBCOI_DEVICE} ) # ------------------------------------------------------------ diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 3e5936cd37..297f8f23be 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -80,47 +80,47 @@ typedef enum { OSP_RGB_I8/* = OSP_FB_RGB8 XXX unsupported! */ } OSPFrameBufferFormat; -// //! constants for switching the OSPRay MPI Scope between 'per rank' and 'all ranks' -// /*! \see ospdApiMode */ -// typedef enum { -// //! \brief all ospNew(), ospSet(), etc calls affect only the current rank -// /*! \detailed in this mode, all ospXyz() calls made on a given rank -// will ONLY affect state ont hat rank. This allows for configuring a -// (globally known) object differnetly on each different rank (also -// see OSP_MPI_SCOPE_GLOBAL) */ -// OSPD_MODE_INDEPENDENT, -// OSPD_RANK=OSPD_MODE_INDEPENDENT /*!< alias for OSP_MODE_INDEPENDENT, reads better in code */, - -// //! \brief all ospNew(), ospSet() calls affect all ranks -// /*! \detailed In this mode, ONLY rank 0 should call ospXyz() -// functions, but all objects defined through those functions---and -// all parameters set through those---will apply equally to all -// ranks. E.g., a OSPVolume vol = ospNewVolume(...) would create a -// volume object handle that exists on (and therefore, is valid on) -// all ranks. The (distributed) app may then switch to 'current -// rank only' mode, and may assign different data or parameters on -// each rank (typically, in order to have different parts of the -// volume on different nodes), but the object itself is globally -// known */ -// OSPD_MODE_MASTERED, -// OSPD_MASTER=OSPD_MODE_MASTERED /*!< alias for OSP_MODE_MASTERED, reads better in code */, - -// //! \brief all ospNew(), ospSet() are called collaboratively by all ranks -// /*! \detailed In this mode, ALL ranks must call (the same!) api -// function, the result is collaborative across all nodes in the -// sense that any object being created gets created across all -// nodes, and ALL ranks get a valid handle returned */ -// OSPD_MODE_COLLABORATIVE, -// OSPD_ALL=OSPD_MODE_COLLABORATIVE /*!< alias for OSP_MODE_COLLABORATIVE, reads better in code */ -// } OSPDApiMode; - -// /*! flags that can be passed to OSPNewGeometry; can be OR'ed together */ -// typedef enum { -// /*! experimental: currently used to specify that the app ranks - -// together - hold a logical piece of geometry, with the back-end -// ospray workers then fetching that on demand..... */ -// OSP_DISTRIBUTED_GEOMETRY = (1<<0), -// } OSPGeometryCreationFlags; +//! constants for switching the OSPRay MPI Scope between 'per rank' and 'all ranks' +/*! \see ospdApiMode */ +typedef enum { + //! \brief all ospNew(), ospSet(), etc calls affect only the current rank + /*! \detailed in this mode, all ospXyz() calls made on a given rank + will ONLY affect state ont hat rank. This allows for configuring a + (globally known) object differnetly on each different rank (also + see OSP_MPI_SCOPE_GLOBAL) */ + OSPD_MODE_INDEPENDENT, + OSPD_RANK=OSPD_MODE_INDEPENDENT /*!< alias for OSP_MODE_INDEPENDENT, reads better in code */, + + //! \brief all ospNew(), ospSet() calls affect all ranks + /*! \detailed In this mode, ONLY rank 0 should call ospXyz() + functions, but all objects defined through those functions---and + all parameters set through those---will apply equally to all + ranks. E.g., a OSPVolume vol = ospNewVolume(...) would create a + volume object handle that exists on (and therefore, is valid on) + all ranks. The (distributed) app may then switch to 'current + rank only' mode, and may assign different data or parameters on + each rank (typically, in order to have different parts of the + volume on different nodes), but the object itself is globally + known */ + OSPD_MODE_MASTERED, + OSPD_MASTER=OSPD_MODE_MASTERED /*!< alias for OSP_MODE_MASTERED, reads better in code */, + + //! \brief all ospNew(), ospSet() are called collaboratively by all ranks + /*! \detailed In this mode, ALL ranks must call (the same!) api + function, the result is collaborative across all nodes in the + sense that any object being created gets created across all + nodes, and ALL ranks get a valid handle returned */ + OSPD_MODE_COLLABORATIVE, + OSPD_ALL=OSPD_MODE_COLLABORATIVE /*!< alias for OSP_MODE_COLLABORATIVE, reads better in code */ +} OSPDApiMode; + +/*! flags that can be passed to OSPNewGeometry; can be OR'ed together */ +typedef enum { + /*! experimental: currently used to specify that the app ranks - + together - hold a logical piece of geometry, with the back-end + ospray workers then fetching that on demand..... */ + OSP_DISTRIBUTED_GEOMETRY = (1<<0), +} OSPGeometryCreationFlags; /*! flags that can be passed to OSPNewData; can be OR'ed together */ typedef enum { @@ -252,22 +252,20 @@ extern "C" { //! initialize the ospray engine (for single-node user application) OSPRAY_INTERFACE void ospInit(int *ac, const char **av); - // #ifdef OSPRAY_MPI_DISTRIBUTED - // //! \brief allows for switching the MPI mode btween collaborative, mastered, and independent - // OSPRAY_INTERFACE - // void ospdApiMode(OSPDApiMode mode); - - // //! the 'lid to the pot' of ospdMpiInit(). - // /*! does both an osp shutdown and an mpi shutdown for the mpi group - // created with ospdMpiInit */ - // OSPRAY_INTERFACE - // void ospdMpiInit(int *ac, char ***av, OSPDRenderMode renderMode=OSPD_Z_COMPOSITE); - - // /*! the 'lid to the pot' of ospdMpiInit(). shuts down both ospray - // *and* the MPI layer created with ospdMpiInit */ - // OSPRAY_INTERFACE - // void ospdMpiShutdown(); - // #endif + //! \brief allows for switching the MPI mode btween collaborative, mastered, and independent + OSPRAY_INTERFACE + void ospdApiMode(OSPDApiMode mode); + + //! the 'lid to the pot' of ospdMpiInit(). + /*! does both an osp shutdown and an mpi shutdown for the mpi group + created with ospdMpiInit */ + OSPRAY_INTERFACE + void ospdMpiInit(int *ac, char ***av, OSPDRenderMode renderMode=OSPD_Z_COMPOSITE); + + /*! the 'lid to the pot' of ospdMpiInit(). shuts down both ospray + *and* the MPI layer created with ospdMpiInit */ + OSPRAY_INTERFACE + void ospdMpiShutdown(); //! load plugin 'name' from shard lib libospray_module_.so /*! returns 0 if the module could be loaded, else it returns an error code > 0 */ diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index e109a77020..d7413a2038 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -17,8 +17,6 @@ #include "DistributedFrameBuffer.h" #include "DistributedFrameBuffer_ispc.h" -#include - #include "ospray/common/tasking/async.h" #include "ospray/common/tasking/parallel_for.h" diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index d8b70e7f94..5790022826 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -1104,7 +1104,7 @@ namespace ospray { } /*! return a string represenging the given API Mode */ - const char *apiModeName(OSPDApiMode mode) + const char *apiModeName(int mode) { switch (mode) { case OSPD_MODE_INDEPENDENT: @@ -1117,7 +1117,6 @@ namespace ospray { PRINT(mode); NOTIMPLEMENTED; }; - } /*! switch API mode for distriubted API extensions */ diff --git a/ospray/mpi/MPIDevice.h b/ospray/mpi/MPIDevice.h index b633bba44a..3ea14d3af8 100644 --- a/ospray/mpi/MPIDevice.h +++ b/ospray/mpi/MPIDevice.h @@ -263,7 +263,7 @@ namespace ospray { // ================================================================== /*! return a string represenging the given API Mode */ - const char *apiModeName(OSPDApiMode mode); + const char *apiModeName(int mode); } // ::ospray::mpi } // ::ospray From 120c8cfecddbba03ec79209d88c49f740fd4aaf6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 19:22:00 -0600 Subject: [PATCH 078/310] update CMake description for OSPRAY_TASKING_SYSTEM to be more accurate --- cmake/ospray.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 5abcf89f84..a9ea0cba0b 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -346,7 +346,7 @@ MACRO(CONFIGURE_TASKING_SYSTEM) #ENDIF() SET(OSPRAY_TASKING_SYSTEM ${TASKING_DEFAULT} CACHE STRING - "Use TBB or OpenMP as for per-node thread tasking system") + "Per-node thread tasking system [TBB,OpenMP,Cilk,Debug]") SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY STRINGS TBB ${CILK_STRING} OpenMP Debug) From 016124f6562f8905ac68870a3e8cb94a18d00e72 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 20:20:39 -0600 Subject: [PATCH 079/310] fix bugs caused by converting reference->pointer->reference of vec types --- ospray/api/API.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/ospray/api/API.cpp b/ospray/api/API.cpp index 212d27aca5..b37a0e1417 100644 --- a/ospray/api/API.cpp +++ b/ospray/api/API.cpp @@ -189,12 +189,12 @@ extern "C" void ospFreeFrameBuffer(OSPFrameBuffer fb) ospray::api::Device::current->release(fb); } -extern "C" OSPFrameBuffer ospNewFrameBuffer(const int *size, //osp::vec2i &size, +extern "C" OSPFrameBuffer ospNewFrameBuffer(const int *size, const OSPFrameBufferFormat mode, const uint32_t channels) { ASSERT_DEVICE(); - return ospray::api::Device::current->frameBufferCreate((const vec2i&)*size,mode,channels); + return ospray::api::Device::current->frameBufferCreate(*(const vec2i*)size,mode,channels); } //! load module \ from shard lib libospray_module_\.so, or @@ -390,7 +390,7 @@ extern "C" OSPCamera ospNewCamera(const char *type) return camera; } -extern "C" OSPTexture2D ospNewTexture2D(const int32_t *size, //osp::vec2i &size, +extern "C" OSPTexture2D ospNewTexture2D(const int32_t *size, const OSPTextureFormat type, void *data, const uint32_t flags) @@ -400,7 +400,7 @@ extern "C" OSPTexture2D ospNewTexture2D(const int32_t *size, //osp::vec2i &size, Assert2(size[0] > 0, "Width must be greater than 0 in ospNewTexture2D"); Assert2(size[1] > 0, "Height must be greater than 0 in ospNewTexture2D"); LOG("ospNewTexture2D( (" << size[0] << ", " << size[1] << "), " << type << ", " << data << ", " << flags << ")"); - return ospray::api::Device::current->newTexture2D((const vec2i&)*size, type, data, flags); + return ospray::api::Device::current->newTexture2D(*(const vec2i*)size, type, data, flags); } /*! \brief create a new volume of given type, return 'NULL' if that type is not known */ @@ -512,16 +512,13 @@ extern "C" void ospSeti(OSPObject _object, const char *id, int x) } /*! Copy data into the given volume. */ -extern "C" int ospSetRegion(OSPVolume object, - void *source, - const int *index, //const osp::vec3i &index, - const int *count //const osp::vec3i &count - ) +extern "C" int ospSetRegion(OSPVolume object, void *source, + const int *index, const int *count) { ASSERT_DEVICE(); return(ospray::api::Device::current->setRegion(object, source, - (const vec3i&)*index, - (const vec3i&)*count)); + *(const vec3i*)index, + *(const vec3i*)count)); } /*! add a vec2f parameter to an object */ @@ -750,14 +747,14 @@ extern "C" OSPGeometry ospNewInstance(OSPModel modelToInstantiate, return geom; } -extern "C" void ospPick(OSPPickResult *result, OSPRenderer renderer, - const float *screenPos//const osp::vec2f &screenPos - ) +extern "C" void ospPick(OSPPickResult *result, + OSPRenderer renderer, + const float *screenPos) { ASSERT_DEVICE(); Assert2(renderer, "NULL renderer passed to ospPick"); if (!result) return; - *result = ospray::api::Device::current->pick(renderer, (const vec2f &)*screenPos); + *result = ospray::api::Device::current->pick(renderer, *(const vec2f *)screenPos); } //! \brief allows for switching the MPI scope from "per rank" to "all ranks" @@ -803,7 +800,7 @@ extern "C" void ospdMpiShutdown() extern "C" void ospSampleVolume(float **results, OSPVolume volume, - const float *worldCoordinates, //const osp::vec3f *worldCoordinates, + const float *worldCoordinates, const size_t count) { ASSERT_DEVICE(); From 20d7aa6b786bfd2def8e0b3cd19fe41b6a82b57d Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 21:40:09 -0600 Subject: [PATCH 080/310] crash fix (note added in code), warning fix, cleanups --- cmake/ospray.cmake | 20 ++------------------ ospray/api/Device.h | 3 +-- ospray/include/ospray/OSPTexture.h | 3 ++- ospray/render/Renderer.cpp | 18 +++++++++++++++--- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index a9ea0cba0b..f312c54666 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -60,16 +60,6 @@ ENDMACRO() # directories (names 'intel64' and 'mic', respectively) MACRO(CONFIGURE_OSPRAY) CONFIGURE_TASKING_SYSTEM() - # Embree common include directories; others may be added depending on build target. - # this section could be sooo much cleaner if embree only used - # fully-qualified include names... - SET(EMBREE_INCLUDE_DIRECTORIES -# ${OSPRAY_EMBREE_SOURCE_DIR}/ - ${OSPRAY_EMBREE_SOURCE_DIR}/include -# ${OSPRAY_EMBREE_SOURCE_DIR}/common -# ${OSPRAY_EMBREE_SOURCE_DIR}/ -# ${OSPRAY_EMBREE_SOURCE_DIR}/kernels - ) IF (OSPRAY_TARGET STREQUAL "mic") SET(OSPRAY_EXE_SUFFIX ".mic") @@ -80,9 +70,6 @@ MACRO(CONFIGURE_OSPRAY) SET(__XEON__ OFF) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/icc_xeonphi.cmake) - # additional Embree include directory - LIST(APPEND EMBREE_INCLUDE_DIRECTORIES ${OSPRAY_EMBREE_SOURCE_DIR}/kernels/xeonphi) - SET(OSPRAY_TARGET_MIC ON PARENT_SCOPE) ELSE() SET(OSPRAY_EXE_SUFFIX "") @@ -102,9 +89,6 @@ MACRO(CONFIGURE_OSPRAY) MESSAGE(FATAL_ERROR "Unsupported compiler specified: '${CMAKE_CXX_COMPILER_ID}'") ENDIF() - # additional Embree include directory - LIST(APPEND EMBREE_INCLUDE_DIRECTORIES ${OSPRAY_EMBREE_SOURCE_DIR}/kernels/xeon) - SET(OSPRAY_EMBREE_ENABLE_AVX512 false) IF (OSPRAY_BUILD_ISA STREQUAL "ALL") # ------------------------------------------------------------------ @@ -187,11 +171,11 @@ MACRO(CONFIGURE_OSPRAY) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) - INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRECTORIES}) + INCLUDE_DIRECTORIES(${OSPRAY_EMBREE_SOURCE_DIR}/include) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}/ospray/include) - INCLUDE_DIRECTORIES_ISPC(${EMBREE_INCLUDE_DIRECTORIES}) + INCLUDE_DIRECTORIES_ISPC(${OSPRAY_EMBREE_SOURCE_DIR}/include) # for auto-generated cmakeconfig etc INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) diff --git a/ospray/api/Device.h b/ospray/api/Device.h index 9044eb182b..db09053e64 100644 --- a/ospray/api/Device.h +++ b/ospray/api/Device.h @@ -226,9 +226,8 @@ namespace ospray { virtual OSPPickResult pick(OSPRenderer renderer, const vec2f &screenPos) { throw std::runtime_error("pick() not impelemnted for this device"); - }; + } - typedef int OSPDApiMode; /*! switch API mode for distriubted API extensions */ virtual void apiMode(OSPDApiMode mode) { diff --git a/ospray/include/ospray/OSPTexture.h b/ospray/include/ospray/OSPTexture.h index 55390cc281..0a3b525c00 100644 --- a/ospray/include/ospray/OSPTexture.h +++ b/ospray/include/ospray/OSPTexture.h @@ -19,7 +19,8 @@ /*! OSPRay format constants for Texture creation */ typedef enum { - OSP_TEXTURE_RGBA8=100, + OSP_TEXTURE_RGBA8 = 0,// NOTE(jda) - ispc::Texture2D_create relies on the int + // values of this enum to work correctly! OSP_TEXTURE_SRGBA, OSP_TEXTURE_RGBA32F, OSP_TEXTURE_RGB8, diff --git a/ospray/render/Renderer.cpp b/ospray/render/Renderer.cpp index 53567fe4fa..72c97feda9 100644 --- a/ospray/render/Renderer.cpp +++ b/ospray/render/Renderer.cpp @@ -40,8 +40,19 @@ namespace ospray { maxDepthTexture = (Texture2D*)getParamObject("maxDepthTexture", NULL); model = (Model*)getParamObject("model", getParamObject("world")); - if (maxDepthTexture && (maxDepthTexture->type != OSP_FLOAT || !(maxDepthTexture->flags & OSP_TEXTURE_FILTER_NEAREST))) - static WarnOnce warning("expected maxDepthTexture provided to the renderer to be type OSP_FLOAT and have the OSP_TEXTURE_FILTER_NEAREST flag"); + if (maxDepthTexture) { + auto type = maxDepthTexture->type; + // NOTE(jda) - are these the right types? + bool isFloat = (type == OSP_TEXTURE_RGBA32F || + type == OSP_TEXTURE_RGB32F || + type == OSP_TEXTURE_R32F); + + if (isFloat || !(maxDepthTexture->flags & OSP_TEXTURE_FILTER_NEAREST)) { + static WarnOnce warning("expected maxDepthTexture provided to the " + "renderer to be type OSP_FLOAT and have the " + "OSP_TEXTURE_FILTER_NEAREST flag"); + } + } vec3f bgColor; bgColor = getParam3f("bgColor", vec3f(1.f)); @@ -49,7 +60,8 @@ namespace ospray { if (getIE()) { ManagedObject* camera = getParamObject("camera"); if (model) { - const float diameter = model->bounds.empty() ? 1.0f : length(model->bounds.size()); + const float diameter = model->bounds.empty() ? + 1.0f : length(model->bounds.size()); epsilon *= diameter; } From b1dfd59f46b0857346589b362d44013dd3384e10 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 21:49:54 -0600 Subject: [PATCH 081/310] CMake fix for when mic device enabled --- common/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 98d014299e..3f696e0ab6 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -14,6 +14,8 @@ ## limitations under the License. ## ## ======================================================================== ## +CONFIGURE_OSPRAY() + OSPRAY_ADD_LIBRARY(ospray_common SHARED # STATIC common.cpp From 706f9543e9399c62519a96d076cbc468611cc6a9 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 21:55:07 -0600 Subject: [PATCH 082/310] COIDevice compile fixes --- ospray/api/COIDeviceWorker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/api/COIDeviceWorker.cpp b/ospray/api/COIDeviceWorker.cpp index ded3dcac8c..dd8aed98a4 100644 --- a/ospray/api/COIDeviceWorker.cpp +++ b/ospray/api/COIDeviceWorker.cpp @@ -641,7 +641,7 @@ namespace ospray { /*! remove an existing geometry from a model */ struct GeometryLocator { - bool operator()(const embree::Ref &g) const { + bool operator()(const Ref &g) const { return ptr == &*g; } Geometry *ptr; @@ -675,7 +675,7 @@ namespace ospray { /*! remove an existing volume from a model */ struct VolumeLocator { - bool operator()(const embree::Ref &g) const { + bool operator()(const Ref &g) const { return ptr == &*g; } Volume *ptr; From 1fd8709ae2907d2b916a892d586c59cb2a1bb078 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 10 Mar 2016 21:55:47 -0600 Subject: [PATCH 083/310] cleanups --- ospray/common/OSPCommon.h | 67 --------------------------------------- 1 file changed, 67 deletions(-) diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index 2969d3e34b..92b4e57282 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -109,16 +109,6 @@ namespace ospray { //! main namespace for all things ospray (for internal code) namespace ospray { - // using embree::one; - // using embree::empty; - // using embree::zero; - // using embree::inf; - // using embree::deg2rad; - // using embree::rad2deg; - // using embree::sign; - // using embree::clamp; - // using embree::frac; - /*! basic types */ typedef ::int64_t int64; typedef ::uint64_t uint64; @@ -134,63 +124,6 @@ namespace ospray { typedef ::int64_t index_t; - // /*! OSPRay's two-int vector class */ - // typedef embree::Vec2i vec2i; - // /*! OSPRay's three-unsigned char vector class */ - // typedef embree::Vec3 vec3uc; - // /*! OSPRay's 4x unsigned char vector class */ - // typedef embree::Vec4 vec4uc; - // /*! OSPRay's 2x uint32 vector class */ - // typedef embree::Vec2 vec2ui; - // /*! OSPRay's 3x uint32 vector class */ - // typedef embree::Vec3 vec3ui; - // /*! OSPRay's 4x uint32 vector class */ - // typedef embree::Vec4 vec4ui; - // /*! OSPRay's 3x int32 vector class */ - // typedef embree::Vec3 vec3i; - // /*! OSPRay's four-int vector class */ - // typedef embree::Vec4i vec4i; - // /*! OSPRay's two-float vector class */ - // typedef embree::Vec2f vec2f; - // /*! OSPRay's three-float vector class */ - // typedef embree::Vec3f vec3f; - // /*! OSPRay's three-float vector class (aligned to 16b-boundaries) */ - // typedef embree::Vec3fa vec3fa; - // /*! OSPRay's four-float vector class */ - // typedef embree::Vec4f vec4f; - - // typedef embree::BBox box2ui; - // typedef embree::BBox region2i; - // typedef embree::BBox region2ui; - - // typedef embree::BBox box3i; - // typedef embree::BBox box3ui; - - // typedef embree::BBox3f box3f; - // typedef embree::BBox3fa box3fa; - // typedef embree::BBox box3uc; - // typedef embree::BBox box4f; - // typedef embree::BBox3fa box3fa; - - // /*! affice space transformation */ - // typedef embree::AffineSpace2f affine2f; - // typedef embree::AffineSpace3f affine3f; - // typedef embree::AffineSpace3fa affine3fa; - // typedef embree::AffineSpace3f AffineSpace3f; - // typedef embree::AffineSpace3fa AffineSpace3fa; - - // typedef embree::LinearSpace2f linear2f; - // typedef embree::LinearSpace3f linear3f; - // typedef embree::LinearSpace3fa linear3fa; - // typedef embree::LinearSpace3f LinearSpace3f; - // typedef embree::LinearSpace3fa LinearSpace3fa; - - // using embree::Ref; - // using embree::RefCount; - - // using embree::cross; - // using embree::volume; - void init(int *ac, const char ***av); /*! for debugging. compute a checksum for given area range... */ From 63e6f6399c5f8a9e28916cc77e60999eee8490b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 11 Mar 2016 13:13:08 +0100 Subject: [PATCH 084/310] ObjectFile uses std::cerr and thus needs to include iostream --- modules/loaders/ObjectFile.h | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/loaders/ObjectFile.h b/modules/loaders/ObjectFile.h index 28f12cab7b..282fa6ce3b 100644 --- a/modules/loaders/ObjectFile.h +++ b/modules/loaders/ObjectFile.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include "ospray/include/ospray/ospray.h" From 348518a0ec13bf6279776a03f688c07f7cf0385b Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 11 Mar 2016 10:26:45 -0600 Subject: [PATCH 085/310] create option to use external embree install, only build ospTutorial on CPU --- cmake/ospray.cmake | 2 -- ospray/CMakeLists.txt | 45 ++++++++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index f312c54666..759952c679 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -171,11 +171,9 @@ MACRO(CONFIGURE_OSPRAY) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) - INCLUDE_DIRECTORIES(${OSPRAY_EMBREE_SOURCE_DIR}/include) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}/ospray/include) - INCLUDE_DIRECTORIES_ISPC(${OSPRAY_EMBREE_SOURCE_DIR}/include) # for auto-generated cmakeconfig etc INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 5f74b73fc0..cbad08d601 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -30,17 +30,33 @@ SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) FIND_PACKAGE(Threads REQUIRED) # ------------------------------------------------------- -# Build and configure embree +# Find or build Embree # ------------------------------------------------------- -# NOTE(jda) - Embree assumes that USE_TBB will be defined correctly in -# CONFIGURE_OSPRAY().CONFIGURE_TASKING_SYSTEM() -# NOTE(jda) - Only do the embree include once (Xeon), it will build both -# Xeon and MIC code if both are enabled. -IF (NOT THIS_IS_MIC) - INCLUDE(../cmake/build_embree.cmake) +OPTION(OSPRAY_USE_EXTERNAL_EMBREE + "Use a pre-built Embree instead of the internally built version" OFF) + +IF(OSPRAY_USE_EXTERNAL_EMBREE) + # Find existing Embree on the machine + FIND_PACKAGE(embree 2.7.1 REQUIRED) +ELSE() + # Build Embree included in the OSPRay tree + + # NOTE(jda) - Embree assumes that USE_TBB will be defined correctly in + # CONFIGURE_OSPRAY().CONFIGURE_TASKING_SYSTEM() + # NOTE(jda) - Only do the Embree include once (Xeon), it will build both + # Xeon and MIC code if both are enabled. + IF (NOT THIS_IS_MIC) + INCLUDE(../cmake/build_embree.cmake) + ENDIF() + SET(EMBREE_INCLUDE_DIRS ${OSPRAY_EMBREE_SOURCE_DIR}/include) + SET(EMBREE_LIBRARY embree) + SET(EMBREE_LIBRARY_XEONPHI embree_xeonphi) ENDIF() +INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES_ISPC(${EMBREE_INCLUDE_DIRS}) + # ------------------------------------------------------- # Setup ospray source files # ------------------------------------------------------- @@ -193,7 +209,7 @@ SET(OSPRAY_SOURCES api/LocalDevice.cpp ) -# NOTE(jda) - To be removed when OSPCOMMON is merged for next release +# NOTE(jda) - To be removed when OSPCOMMON is merged for next release (?) ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) # ------------------------------------------------------- @@ -249,6 +265,7 @@ IF (OSPRAY_BUILD_COI_DEVICE) MARK_AS_ADVANCED(LIBCOI_DEVICE) MARK_AS_ADVANCED(LIBCOI_HOST) SET(OSPRAY_MIC_COI ON PARENT_SCOPE) + # NOTE(jda) - hardcoded paths (!)...use a find_package() here? INCLUDE_DIRECTORIES(/opt/intel/mic/coi/include) INCLUDE_DIRECTORIES(/usr/include/intel-coi) IF (THIS_IS_MIC) @@ -277,12 +294,12 @@ OSPRAY_LIBRARY_LINK_LIBRARIES(ospray IF (THIS_IS_MIC) OSPRAY_LIBRARY_LINK_LIBRARIES(ospray - embree_xeonphi + ${EMBREE_LIBRARY_XEONPHI} ${TBB_LIBRARIES_MIC} ) ELSE() OSPRAY_LIBRARY_LINK_LIBRARIES(ospray - embree + ${EMBREE_LIBRARY} ${TBB_LIBRARIES} ) ENDIF() @@ -298,9 +315,11 @@ ENDIF() OSPRAY_SET_LIBRARY_VERSION(ospray) OSPRAY_INSTALL_LIBRARY(ospray) -# build ospTutorial, for testing -OSPRAY_ADD_EXECUTABLE(ospTutorial ../apps/ospTutorial) -OSPRAY_EXE_LINK_LIBRARIES(ospTutorial ospray ospray_common) +IF(NOT THIS_IS_MIC) + # build ospTutorial, for testing + ADD_EXECUTABLE(ospTutorial ../apps/ospTutorial) + TARGET_LINK_LIBRARIES(ospTutorial ospray ospray_common) +ENDIF() ############################################################## From 86ffe26b7e0287d99fcfd2fe1e9129c9fec2c41e Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 11 Mar 2016 11:02:22 -0600 Subject: [PATCH 086/310] fixes to the Tachyon module, some cleanups --- apps/common/widgets/glut3D.h | 47 ++++++++++++++++++++++------------ cmake/ospray.cmake | 3 ++- modules/tachyon/CMakeLists.txt | 10 +++++--- modules/tachyon/Model.cpp | 10 ++++---- modules/tachyon/Viewer.cpp | 4 +-- ospray/CMakeLists.txt | 4 +++ 6 files changed, 51 insertions(+), 27 deletions(-) diff --git a/apps/common/widgets/glut3D.h b/apps/common/widgets/glut3D.h index 9ab0b95147..1cb7ac8b12 100644 --- a/apps/common/widgets/glut3D.h +++ b/apps/common/widgets/glut3D.h @@ -78,23 +78,30 @@ namespace ospray { OSPRAY_GLUT3D_INTERFACE virtual void motion(Glut3DWidget *widget); // this is the fct that gets called when any mouse button got // pressed or released in the associated window - OSPRAY_GLUT3D_INTERFACE virtual void button(Glut3DWidget *widget, const vec2i &pos) {}; + OSPRAY_GLUT3D_INTERFACE virtual void button(Glut3DWidget *widget, + const vec2i &pos) {} /*! key press handler - override this fct to catch keyboard. */ - OSPRAY_GLUT3D_INTERFACE virtual void keypress(Glut3DWidget *widget, const int32_t key); - OSPRAY_GLUT3D_INTERFACE virtual void specialkey(Glut3DWidget *widget, const int32_t key); - OSPRAY_GLUT3D_INTERFACE Manipulator(Glut3DWidget *widget) : widget(widget) {}; + OSPRAY_GLUT3D_INTERFACE virtual void keypress(Glut3DWidget *widget, + const int32_t key); + OSPRAY_GLUT3D_INTERFACE virtual void specialkey(Glut3DWidget *widget, + const int32_t key); + OSPRAY_GLUT3D_INTERFACE Manipulator(Glut3DWidget *widget) + : widget(widget) {} protected: // helper functions called from the default 'motion' fct OSPRAY_GLUT3D_INTERFACE virtual void dragLeft(Glut3DWidget *widget, - const vec2i &to, const vec2i &from) - {}; + const vec2i &to, + const vec2i &from) + {} OSPRAY_GLUT3D_INTERFACE virtual void dragRight(Glut3DWidget *widget, - const vec2i &to, const vec2i &from) - {}; + const vec2i &to, + const vec2i &from) + {} OSPRAY_GLUT3D_INTERFACE virtual void dragMiddle(Glut3DWidget *widget, - const vec2i &to, const vec2i &from) - {}; + const vec2i &to, + const vec2i &from) + {} Glut3DWidget *widget; }; @@ -205,13 +212,17 @@ namespace ospray { /*! set window title */ OSPRAY_GLUT3D_INTERFACE void setTitle(const std::string &title) { setTitle(title.c_str()); } /*! set viewport to given values */ - OSPRAY_GLUT3D_INTERFACE void setViewPort(const vec3f from, const vec3f at, const vec3f up); + OSPRAY_GLUT3D_INTERFACE void setViewPort(const vec3f from, + const vec3f at, + const vec3f up); // ------------------------------------------------------------------ // event handling - override this to change this widgets behavior // to input events // ------------------------------------------------------------------ - OSPRAY_GLUT3D_INTERFACE virtual void mouseButton(int32_t which, bool released, const vec2i &pos); + OSPRAY_GLUT3D_INTERFACE virtual void mouseButton(int32_t which, + bool released, + const vec2i &pos); OSPRAY_GLUT3D_INTERFACE virtual void motion(const vec2i &pos); // /*! mouse moved to this location, with given left/right/middle buttons pressed */ // virtual void mouseMotion(const vec2i &from, @@ -242,10 +253,12 @@ namespace ospray { /*! clear the frame buffer color and depth bits */ OSPRAY_GLUT3D_INTERFACE void clearPixels(); - /*! draw uint32_t pixels into the GLUT window (assumes window and buffer dimensions are equal) */ + /*! draw uint32_t pixels into the GLUT window (assumes window and buffer + * dimensions are equal) */ OSPRAY_GLUT3D_INTERFACE void drawPixels(const uint32_t *framebuffer); - /*! draw float4 pixels into the GLUT window (assumes window and buffer dimensions are equal) */ + /*! draw float4 pixels into the GLUT window (assumes window and buffer + * dimensions are equal) */ OSPRAY_GLUT3D_INTERFACE void drawPixels(const vec3fa *framebuffer); // ------------------------------------------------------------------ @@ -300,8 +313,10 @@ namespace ospray { friend void glut3dMouseFunc(int32_t whichButton, int32_t released, int32_t x, int32_t y); - OSPRAY_GLUT3D_INTERFACE virtual void keypress(char key, const vec2i &where); - OSPRAY_GLUT3D_INTERFACE virtual void specialkey(int32_t key, const vec2i &where); + OSPRAY_GLUT3D_INTERFACE virtual void keypress(char key, + const vec2i &where); + OSPRAY_GLUT3D_INTERFACE virtual void specialkey(int32_t key, + const vec2i &where); }; std::ostream &operator<<(std::ostream &o, const Glut3DWidget::ViewPort &cam); diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 759952c679..df3d565b4f 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -164,7 +164,8 @@ MACRO(CONFIGURE_OSPRAY) IF (THIS_IS_MIC) # whether to build in MIC/xeon phi support - SET(OSPRAY_BUILD_COI_DEVICE OFF CACHE BOOL "Build COI Device for OSPRay's MIC support?") + SET(OSPRAY_BUILD_COI_DEVICE OFF CACHE BOOL + "Build COI Device for OSPRay's MIC support?") ENDIF() INCLUDE(${PROJECT_SOURCE_DIR}/cmake/ispc.cmake) diff --git a/modules/tachyon/CMakeLists.txt b/modules/tachyon/CMakeLists.txt index b20a16e606..fc9741fdf2 100644 --- a/modules/tachyon/CMakeLists.txt +++ b/modules/tachyon/CMakeLists.txt @@ -20,6 +20,9 @@ IF (OSPRAY_MODULE_TACHYON) CONFIGURE_OSPRAY() + # NOTE(jda) - To be removed when OSPCOMMON is merged for next release (?) + ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) + # ------------------------------------------------------- find_program(LEX_EXE flex) if(LEX_EXE STREQUAL "LEX_EXE-NOTFOUND") @@ -59,9 +62,10 @@ IF (OSPRAY_MODULE_TACHYON) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/) + INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS}) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES_ISPC(${PROJECT_SOURCE_DIR}/ospray) - INCLUDE_DIRECTORIES_ISPC(${EMBREE_DIR}/include) + INCLUDE_DIRECTORIES_ISPC(${EMBREE_INCLUDE_DIRS}) YACC_FILE(parser.yy) LEX_FILE(lexer.ll) @@ -71,7 +75,7 @@ IF (OSPRAY_MODULE_TACHYON) TachyonRenderer.ispc ) - OSPRAY_LIBRARY_LINK_LIBRARIES(ospray_module_tachyon ospray) + OSPRAY_LIBRARY_LINK_LIBRARIES(ospray_module_tachyon ospray ospray_common) IF (NOT THIS_IS_MIC) ADD_EXECUTABLE(ospTachyon @@ -81,6 +85,6 @@ IF (OSPRAY_MODULE_TACHYON) parser_y.cpp Loc.cpp ) - TARGET_LINK_LIBRARIES(ospTachyon ospray ospray_glut3d) + TARGET_LINK_LIBRARIES(ospTachyon ospray ospray_common ospray_glut3d) ENDIF() ENDIF() diff --git a/modules/tachyon/Model.cpp b/modules/tachyon/Model.cpp index 362545586d..69cbe1bd47 100644 --- a/modules/tachyon/Model.cpp +++ b/modules/tachyon/Model.cpp @@ -88,7 +88,7 @@ namespace ospray { } Model::Model() - : bounds(embree::empty), + : bounds(ospcommon::empty), camera(NULL), smoothTrisVA(NULL), backgroundColor(.1f), @@ -240,7 +240,7 @@ namespace ospray { tessellateSphereOctant(va,sphere,dw,dvw,duw,depth-1); tessellateSphereOctant(va,sphere,duv,dvw,duw,depth-1); } else { - vec3i base = vec3f(va->coord.size()); + vec3i base = vec3i(va->coord.size()); va->coord.push_back(sphere.center+sphere.rad*du); va->coord.push_back(sphere.center+sphere.rad*dv); va->coord.push_back(sphere.center+sphere.rad*dw); @@ -304,10 +304,10 @@ namespace ospray { void tessellateCylinder(VertexArray *va,Cylinder &cylinder) { vec3f dw = cylinder.apex - cylinder.base; - float l = embree::length(dw); + float l = length(dw); - embree::AffineSpace3f space; - space.l = embree::frame(normalize(dw)); + AffineSpace3f space; + space.l = frame(normalize(dw)); space.p = cylinder.base; vec3i base(va->coord.size()); diff --git a/modules/tachyon/Viewer.cpp b/modules/tachyon/Viewer.cpp index 400d97ac99..10fa287d73 100644 --- a/modules/tachyon/Viewer.cpp +++ b/modules/tachyon/Viewer.cpp @@ -205,9 +205,9 @@ namespace ospray { ospSet1i(renderer,"do_shadows",doShadows); ospCommit(renderer); - }; + } - virtual void keypress(char key, const vec2f where) + void keypress(char key, const vec2i &where) override { switch (key) { case 'X': diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index cbad08d601..c5b024115f 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -57,6 +57,10 @@ ENDIF() INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS}) INCLUDE_DIRECTORIES_ISPC(${EMBREE_INCLUDE_DIRS}) +SET(EMBREE_INCLUDE_DIRS ${EMBREE_INCLUDE_DIRS} PARENT_SCOPE) +SET(EMBREE_LIBRARY ${EMBREE_LIBRARY} PARENT_SCOPE) +SET(EMBREE_LIBRARY_XEONPHI ${EMBREE_LIBRARY_XEONHPI} PARENT_SCOPE) + # ------------------------------------------------------- # Setup ospray source files # ------------------------------------------------------- From 005ef78f6f57514073d8a63cdd5438e61d863b31 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 11 Mar 2016 11:50:49 -0600 Subject: [PATCH 087/310] disable ospcommon.h include error for all modules --- modules/CMakeLists.txt | 15 +++++++++------ modules/tachyon/CMakeLists.txt | 3 --- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 936d9a7b00..e9fdff6d58 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -15,10 +15,13 @@ ## ======================================================================== ## IF (NOT WIN32) # not yet... -FILE(GLOB plugins RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ *) -FOREACH(plugin ${plugins}) - IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${plugin}/CMakeLists.txt) - ADD_SUBDIRECTORY(${plugin}) - ENDIF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${plugin}/CMakeLists.txt) -ENDFOREACH(plugin ${plugins}) + # NOTE(jda) - To be removed when OSPCOMMON is merged for next release (?) + ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) + + FILE(GLOB plugins RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ *) + FOREACH(plugin ${plugins}) + IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${plugin}/CMakeLists.txt) + ADD_SUBDIRECTORY(${plugin}) + ENDIF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${plugin}/CMakeLists.txt) + ENDFOREACH(plugin ${plugins}) ENDIF() diff --git a/modules/tachyon/CMakeLists.txt b/modules/tachyon/CMakeLists.txt index fc9741fdf2..52e0513520 100644 --- a/modules/tachyon/CMakeLists.txt +++ b/modules/tachyon/CMakeLists.txt @@ -20,9 +20,6 @@ IF (OSPRAY_MODULE_TACHYON) CONFIGURE_OSPRAY() - # NOTE(jda) - To be removed when OSPCOMMON is merged for next release (?) - ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) - # ------------------------------------------------------- find_program(LEX_EXE flex) if(LEX_EXE STREQUAL "LEX_EXE-NOTFOUND") From 53ada1f2a3f24735b44817407533dd15c774b8d8 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 11 Mar 2016 11:57:40 -0600 Subject: [PATCH 088/310] add ospcommon to CMake for IDEs to pickup (like QtCreator) --- common/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 3f696e0ab6..4193cb0e44 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -24,6 +24,18 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED malloc.cpp library.cpp thread.cpp + + AffineSpace.h + box.h + constants.h + intrinsics.h + LinearSpace.h + math.h + mpi.h + platform.h + Quaternion.h + RefCount.h + vec.h ) From ecf3de887c50cd41fa4af6a614fdc0dbbf3bea1f Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 11 Mar 2016 21:04:03 -0600 Subject: [PATCH 089/310] cleanup logic in tasking system CMake --- cmake/ospray.cmake | 35 +++++++++++++++++++++-------------- ospray/CMakeLists.txt | 4 ++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index df3d565b4f..3b63121f5e 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -335,31 +335,37 @@ MACRO(CONFIGURE_TASKING_SYSTEM) STRINGS TBB ${CILK_STRING} OpenMP Debug) MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) + SET(USE_TBB FALSE) + SET(USE_CILK FALSE) + SET(USE_OPENMP FALSE) + IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") SET(USE_TBB TRUE) - SET(USE_CILK FALSE) ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") - SET(USE_TBB FALSE) SET(USE_CILK TRUE) - ELSE() - SET(USE_TBB FALSE) - SET(USE_CILK FALSE) + ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "OpenMP") + SET(USE_OPENMP TRUE) ENDIF() + UNSET(TASKING_SYSTEM_LIBS) + UNSET(TASKING_SYSTEM_LIBS_MIC) + IF(USE_TBB) FIND_PACKAGE(TBB REQUIRED) ADD_DEFINITIONS(-DOSPRAY_USE_TBB) INCLUDE_DIRECTORIES(${TBB_INCLUDE_DIRS}) + SET(TASKING_SYSTEM_LIBS ${TBB_LIBRARIES}) + SET(TASKING_SYSTEM_LIBS_MIC ${TBB_LIBRARIES_MIC}) ELSE(USE_TBB) - UNSET(TBB_INCLUDE_DIR CACHE) - UNSET(TBB_LIBRARY CACHE) - UNSET(TBB_LIBRARY_DEBUG CACHE) - UNSET(TBB_LIBRARY_MALLOC CACHE) + UNSET(TBB_INCLUDE_DIR CACHE) + UNSET(TBB_LIBRARY CACHE) + UNSET(TBB_LIBRARY_DEBUG CACHE) + UNSET(TBB_LIBRARY_MALLOC CACHE) UNSET(TBB_LIBRARY_MALLOC_DEBUG CACHE) - UNSET(TBB_INCLUDE_DIR_MIC CACHE) - UNSET(TBB_LIBRARY_MIC CACHE) - UNSET(TBB_LIBRARY_MALLOC_MIC CACHE) - IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "OpenMP") + UNSET(TBB_INCLUDE_DIR_MIC CACHE) + UNSET(TBB_LIBRARY_MIC CACHE) + UNSET(TBB_LIBRARY_MALLOC_MIC CACHE) + IF(USE_OPENMP) FIND_PACKAGE(OpenMP) IF (OPENMP_FOUND) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") @@ -368,10 +374,11 @@ MACRO(CONFIGURE_TASKING_SYSTEM) "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") ADD_DEFINITIONS(-DOSPRAY_USE_OMP) ENDIF() - ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") + ELSEIF(USE_CILK) ADD_DEFINITIONS(-DOSPRAY_USE_CILK) ELSE()#Debug # Do nothing, will fall back to scalar code (useful for debugging) ENDIF() ENDIF(USE_TBB) + ENDMACRO() diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index c5b024115f..4d4c2499b3 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -299,12 +299,12 @@ OSPRAY_LIBRARY_LINK_LIBRARIES(ospray IF (THIS_IS_MIC) OSPRAY_LIBRARY_LINK_LIBRARIES(ospray ${EMBREE_LIBRARY_XEONPHI} - ${TBB_LIBRARIES_MIC} + ${TASKING_SYSTEM_LIBS_MIC} ) ELSE() OSPRAY_LIBRARY_LINK_LIBRARIES(ospray ${EMBREE_LIBRARY} - ${TBB_LIBRARIES} + ${TASKING_SYSTEM_LIBS} ) ENDIF() From aa821dcace90de42ee86e1efb34d5d37b17145da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 14 Mar 2016 11:53:03 +0100 Subject: [PATCH 090/310] Make ispc::Texture2D_create independent of the values of OSPTextureFormat --- ospray/include/ospray/OSPTexture.h | 3 +- ospray/texture/Texture2D.ispc | 63 +++++++++++++++--------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/ospray/include/ospray/OSPTexture.h b/ospray/include/ospray/OSPTexture.h index 0a3b525c00..b79719447f 100644 --- a/ospray/include/ospray/OSPTexture.h +++ b/ospray/include/ospray/OSPTexture.h @@ -19,8 +19,7 @@ /*! OSPRay format constants for Texture creation */ typedef enum { - OSP_TEXTURE_RGBA8 = 0,// NOTE(jda) - ispc::Texture2D_create relies on the int - // values of this enum to work correctly! + OSP_TEXTURE_RGBA8, OSP_TEXTURE_SRGBA, OSP_TEXTURE_RGBA32F, OSP_TEXTURE_RGB8, diff --git a/ospray/texture/Texture2D.ispc b/ospray/texture/Texture2D.ispc index ad489f642c..4af84ca998 100644 --- a/ospray/texture/Texture2D.ispc +++ b/ospray/texture/Texture2D.ispc @@ -22,7 +22,7 @@ // TODO blocking -inline vec4f getTexel_rgba8(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_RGBA8(const uniform Texture2D *uniform self, const vec2i i) { assert(self); const uint32 c = ((const uniform uint32 *uniform)self->data)[i.y*self->size.x + i.x]; @@ -33,7 +33,7 @@ inline vec4f getTexel_rgba8(const uniform Texture2D *uniform self, const vec2i i return make_vec4f(r, g, b, a)*(1.f/255.f); } -inline vec4f getTexel_rgb8(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_RGB8(const uniform Texture2D *uniform self, const vec2i i) { assert(self); const uniform uint8 *uniform texel = (const uniform uint8 *uniform)self->data; @@ -44,7 +44,7 @@ inline vec4f getTexel_rgb8(const uniform Texture2D *uniform self, const vec2i i) return make_vec4f(make_vec3f(r, g, b)*(1.f/255.f), 1.f); } -inline vec4f getTexel_r8(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_R8(const uniform Texture2D *uniform self, const vec2i i) { assert(self); const uint8 c = ((const uniform uint8 *uniform)self->data)[i.y*self->size.x + i.x]; @@ -62,30 +62,30 @@ inline vec4f srgba(const vec4f c) return make_vec4f(srgb(c.x), srgb(c.y), srgb(c.z), c.w); } -inline vec4f getTexel_srgba(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_SRGBA(const uniform Texture2D *uniform self, const vec2i i) { - return srgba(getTexel_rgba8(self, i)); + return srgba(getTexel_RGBA8(self, i)); } -inline vec4f getTexel_srgb(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_SRGB(const uniform Texture2D *uniform self, const vec2i i) { - return srgba(getTexel_rgb8(self, i)); + return srgba(getTexel_RGB8(self, i)); } -inline vec4f getTexel_rgba32f(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_RGBA32F(const uniform Texture2D *uniform self, const vec2i i) { assert(self); return ((const uniform vec4f *uniform)self->data)[i.y*self->size.x + i.x]; } -inline vec4f getTexel_rgb32f(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_RGB32F(const uniform Texture2D *uniform self, const vec2i i) { assert(self); vec3f v = ((const uniform vec3f*uniform )self->data)[i.y*self->size.x + i.x]; return make_vec4f(v, 1.f); } -inline vec4f getTexel_r32f(const uniform Texture2D *uniform self, const vec2i i) +inline vec4f getTexel_R32F(const uniform Texture2D *uniform self, const vec2i i) { assert(self); float v = ((const uniform float*uniform)self->data)[i.y*self->size.x + i.x]; @@ -171,25 +171,28 @@ static vec4f Texture2D_bilinear_##FMT(const uniform Texture2D *uniform self, \ return bilerp(cs.frac, c00, c01, c10, c11); \ } -#define __define_tex_get_addr(FMT) \ - &Texture2D_bilinear_##FMT, \ - &Texture2D_nearest_##FMT, +#define __define_tex_get_case(FMT) \ + case OSP_TEXTURE_##FMT: return filter_nearest ? &Texture2D_nearest_##FMT : \ + &Texture2D_bilinear_##FMT; -// same order as in OSPTextureFormat! #define __foreach_fetcher(FCT) \ - FCT(rgba8) \ - FCT(srgba) \ - FCT(rgba32f) \ - FCT(rgb8) \ - FCT(srgb) \ - FCT(rgb32f) \ - FCT(r8) \ - FCT(r32f) + FCT(RGBA8) \ + FCT(SRGBA) \ + FCT(RGBA32F) \ + FCT(RGB8) \ + FCT(SRGB) \ + FCT(RGB32F) \ + FCT(R8) \ + FCT(R32F) __foreach_fetcher(__define_tex_get) -static uniform Texture2D_get Texture2D_get_addr[] = { - __foreach_fetcher(__define_tex_get_addr) +static uniform Texture2D_get Texture2D_get_addr(const uniform uint32 type, + const uniform bool filter_nearest) +{ + switch (type) { + __foreach_fetcher(__define_tex_get_case) + } }; #undef __define_tex_get @@ -207,17 +210,13 @@ export void *uniform Texture2D_create(uniform vec2i &size, void *uniform data, self->size = size; // Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small - // negative x), although is should be strictly smaller than 1.0f. We handle + // negative x), although it should be strictly smaller than 1.0f. We handle // this case by having sizef slightly smaller than size, such that // frac(x)*sizef is always < size. - self->sizef = make_vec2f(nextafter(size.x, -1.0f), nextafter(size.y, -1.0f)); + self->sizef = make_vec2f(nextafter(size.x, -1.0f), nextafter(size.y, -1.0f)); self->halfTexel = make_vec2f(0.5f/size.x, 0.5f/size.y); - self->data = data; - - // select texture fetch function depending on format and filter - uniform int filter = flags & OSP_TEXTURE_FILTER_NEAREST ? 1 : 0; - uniform int fct_nr = type * 2 + filter; - self->get = Texture2D_get_addr[fct_nr]; + self->data = data; + self->get = Texture2D_get_addr(type, flags & OSP_TEXTURE_FILTER_NEAREST); return self; } From d66d653cf808bac6cc7a5181d8cb01a598085c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 14 Mar 2016 12:40:20 +0100 Subject: [PATCH 091/310] Proper fix for crash on Windows (a1a20cc1) Use the "unmasked" qualifier to signal ISPC that a mask is not passed in the first place. --- ospray/geometry/Cylinders.ispc | 6 +++--- ospray/geometry/Spheres.ispc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ospray/geometry/Cylinders.ispc b/ospray/geometry/Cylinders.ispc index 75111a146d..c431216f76 100644 --- a/ospray/geometry/Cylinders.ispc +++ b/ospray/geometry/Cylinders.ispc @@ -45,9 +45,9 @@ struct Cylinders { typedef uniform float uniform_float; -void Cylinders_bounds(uniform Cylinders *uniform geometry, - uniform size_t primID, - uniform box3fa &bbox) +unmasked void Cylinders_bounds(uniform Cylinders *uniform geometry, + uniform size_t primID, + uniform box3fa &bbox) { uniform uint8 *uniform cylinderPtr = geometry->data + geometry->bytesPerCylinder*primID; uniform bool offr = geometry->offset_radius >= 0; diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index edd51d6505..6fb99d4192 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -87,9 +87,9 @@ static void Spheres_postIntersect(uniform Geometry *uniform geometry, } } -void Spheres_bounds(uniform Spheres *uniform geometry, - uniform size_t primID, - uniform box3fa &bbox) +unmasked void Spheres_bounds(uniform Spheres *uniform geometry, + uniform size_t primID, + uniform box3fa &bbox) { uniform uint8 *uniform spherePtr = geometry->data + geometry->bytesPerSphere*((uniform int64)primID); uniform bool offr = geometry->offset_radius >= 0; From 4f97acce053f62cf7b09834e52dfedc4b53a2cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 14 Mar 2016 15:42:27 +0100 Subject: [PATCH 092/310] Require "unmasked" for some (uniform only) renderer functions --- ospray/render/Renderer.ih | 6 +++--- ospray/render/Renderer.ispc | 6 +++--- ospray/render/pathtracer/PathTracer.ispc | 4 ++-- ospray/render/volume/RaycastVolumeRenderer.ispc | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ospray/render/Renderer.ih b/ospray/render/Renderer.ih index 18a3adf3a7..dcc3876433 100644 --- a/ospray/render/Renderer.ih +++ b/ospray/render/Renderer.ih @@ -56,13 +56,13 @@ typedef void (*Renderer_RenderSampleFct)(uniform Renderer *uniform self, typedef void (*Renderer_ToneMapFct)(uniform Renderer *uniform self, varying vec3f &color, const varying vec2i &pixelID); -typedef void (*Renderer_RenderTileFct)(uniform Renderer *uniform self, +typedef unmasked void (*Renderer_RenderTileFct)(uniform Renderer *uniform self, void *uniform perFrameData, uniform Tile &tile, uniform int taskIndex); -typedef void *uniform (*Renderer_BeginFrameFct)(uniform Renderer *uniform self, +typedef unmasked void *uniform (*Renderer_BeginFrameFct)(uniform Renderer *uniform self, uniform FrameBuffer *uniform fb); -typedef void (*Renderer_EndFrameFct)(uniform Renderer *uniform self, +typedef unmasked void (*Renderer_EndFrameFct)(uniform Renderer *uniform self, void *uniform perFrameData, const uniform int32 newAccumID); diff --git a/ospray/render/Renderer.ispc b/ospray/render/Renderer.ispc index 1c535d2a5b..5a452851f0 100644 --- a/ospray/render/Renderer.ispc +++ b/ospray/render/Renderer.ispc @@ -32,7 +32,7 @@ void Renderer_default_renderSample(uniform Renderer *uniform self, ); } -static void *uniform Renderer_default_beginFrame(uniform Renderer *uniform self, +static unmasked void *uniform Renderer_default_beginFrame(uniform Renderer *uniform self, uniform FrameBuffer *uniform fb) { self->fb = fb; @@ -43,7 +43,7 @@ static void *uniform Renderer_default_beginFrame(uniform Renderer *uniform self, return NULL; } -static void Renderer_default_endFrame(uniform Renderer *uniform self, +static unmasked void Renderer_default_endFrame(uniform Renderer *uniform self, void *uniform perFrameData, const uniform int32 accumID) { @@ -53,7 +53,7 @@ static void Renderer_default_endFrame(uniform Renderer *uniform self, } } -void Renderer_default_renderTileJob(uniform Renderer *uniform self, +unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, void *uniform perFrameData, uniform Tile &tile, uniform int taskIndex) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 14242abc72..d4334cb9e1 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -342,7 +342,7 @@ inline ScreenSample PathTracer_renderPixel(uniform PathTracer *uniform self, -void *uniform PathTracer_beginFrame(uniform Renderer *uniform _self, +unmasked void *uniform PathTracer_beginFrame(uniform Renderer *uniform _self, uniform FrameBuffer *uniform fb) { _self->fb = fb; @@ -379,7 +379,7 @@ void PathTracer_renderTileJob(uniform PathTracer *uniform self, } } -void PathTracer_renderTile(uniform Renderer *uniform _self, +unmasked void PathTracer_renderTile(uniform Renderer *uniform _self, void *uniform perFrameData, uniform Tile &tile, uniform int jobID) diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 7546d079de..3fdbf1d10d 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -34,7 +34,7 @@ struct PassInfo { uniform bool useBG; }; -void RaycastVolumeRenderer_endFrame(Renderer *uniform self, +unmasked void RaycastVolumeRenderer_endFrame(Renderer *uniform self, void *uniform perFrameData, const uniform int32 accumID) { @@ -44,7 +44,7 @@ void RaycastVolumeRenderer_endFrame(Renderer *uniform self, self->fb = NULL; } -void *uniform RaycastVolumeRenderer_beginFrame(Renderer *uniform self, +unmasked void *uniform RaycastVolumeRenderer_beginFrame(Renderer *uniform self, FrameBuffer *uniform framebuffer) { self->fb = framebuffer; From 3df689daebb88a9f032ce3873cdef57d0f849b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 14 Mar 2016 16:56:11 +0100 Subject: [PATCH 093/310] maxDepthTexture must have format OSP_TEXTURE_R32F --- ospray/render/Renderer.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ospray/render/Renderer.cpp b/ospray/render/Renderer.cpp index 72c97feda9..606db2d364 100644 --- a/ospray/render/Renderer.cpp +++ b/ospray/render/Renderer.cpp @@ -41,13 +41,8 @@ namespace ospray { model = (Model*)getParamObject("model", getParamObject("world")); if (maxDepthTexture) { - auto type = maxDepthTexture->type; - // NOTE(jda) - are these the right types? - bool isFloat = (type == OSP_TEXTURE_RGBA32F || - type == OSP_TEXTURE_RGB32F || - type == OSP_TEXTURE_R32F); - - if (isFloat || !(maxDepthTexture->flags & OSP_TEXTURE_FILTER_NEAREST)) { + if (maxDepthTexture->type != OSP_TEXTURE_R32F + || !(maxDepthTexture->flags & OSP_TEXTURE_FILTER_NEAREST)) { static WarnOnce warning("expected maxDepthTexture provided to the " "renderer to be type OSP_FLOAT and have the " "OSP_TEXTURE_FILTER_NEAREST flag"); From ab387ec64c6bff0bed07db7d899545a253e407b8 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 14 Mar 2016 11:39:51 -0500 Subject: [PATCH 094/310] use find_package(embree) in ospray's find_package config when appropriate --- cmake/ospray_cmake_config/osprayConfig.cmake.in | 11 +++++++++-- ospray/CMakeLists.txt | 4 +++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index 15d233b132..62e9a65cae 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -131,6 +131,13 @@ if (@USE_CILK@) add_definitions(-DOSPRAY_USE_CILK) endif() +if(@OSPRAY_USE_EXTERNAL_EMBREE@) + # Find existing Embree on the machine + find_package(embree @REQUIRED_MINIMUM_EMBREE@ REQUIRED) +else() + set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}) +endif() + # Restore state set(CMAKE_CURRENT_LIST_DIR ${OSPRAY_CMAKE_CURRENT_LIST_DIR}) set(CURRENT_CONFIG_INSTALL_DIR ${OSPRAY_CURRENT_CONFIG_INSTALL_DIR}) @@ -174,8 +181,8 @@ set(OSPRAY_LIBRARIES ${OSPRAY_DEPENDENCIES} #ospray# NOTE(jda) - target disabled (see above) #ospray_embree# NOTE(jda) - target disabled (see above) - ${CURRENT_ROOT_INSTALL_DIR}/lib64/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX} - ${CURRENT_ROOT_INSTALL_DIR}/lib64/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} + ${EMBREE_LIBRARY} + ${CURRENT_ROOT_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} ) # Reset CMake module path to its state when this script was called. diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 4d4c2499b3..16b75e18fd 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -33,12 +33,14 @@ FIND_PACKAGE(Threads REQUIRED) # Find or build Embree # ------------------------------------------------------- +SET(REQUIRED_MINIMUM_EMBREE 2.7.1) + OPTION(OSPRAY_USE_EXTERNAL_EMBREE "Use a pre-built Embree instead of the internally built version" OFF) IF(OSPRAY_USE_EXTERNAL_EMBREE) # Find existing Embree on the machine - FIND_PACKAGE(embree 2.7.1 REQUIRED) + FIND_PACKAGE(embree ${REQUIRED_MINIMUM_EMBREE} REQUIRED) ELSE() # Build Embree included in the OSPRay tree From 96dfd9ffa7211c1e20ae1fd87bd87c2f0cc3f1be Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 14 Mar 2016 16:03:03 -0500 Subject: [PATCH 095/310] add missing ospray_common library to ospray link list --- ospray/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 16b75e18fd..956c086ff4 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -294,6 +294,7 @@ ENDIF() OSPRAY_ADD_LIBRARY(ospray SHARED ${OSPRAY_SOURCES}) OSPRAY_LIBRARY_LINK_LIBRARIES(ospray + ospray_common ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} ) From a7285b60f631e0456380cde900445d1dd156fb79 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 14 Mar 2016 18:09:43 -0500 Subject: [PATCH 096/310] fix issue with finding embree after configuring with internal version --- ospray/CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 956c086ff4..7cf6b8db88 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -39,9 +39,24 @@ OPTION(OSPRAY_USE_EXTERNAL_EMBREE "Use a pre-built Embree instead of the internally built version" OFF) IF(OSPRAY_USE_EXTERNAL_EMBREE) + # Clear out embree directories if they were previously populated by an + # internal build + IF(NOT ${LAST_CONFIG_USED_EXTERNAL_EMBREE}) + UNSET(EMBREE_INCLUDE_DIRS) + UNSET(EMBREE_LIBRARY) + UNSET(EMBREE_LIBRARY_XEONPHI) + ENDIF() # Find existing Embree on the machine FIND_PACKAGE(embree ${REQUIRED_MINIMUM_EMBREE} REQUIRED) + SET(LAST_CONFIG_USED_EXTERNAL_EMBREE ON CACHE INTERNAL "" FORCE) ELSE() + # Clear out embree directories if they were previously populated by an + # external find_package() call + IF(${LAST_CONFIG_USED_EXTERNAL_EMBREE}) + UNSET(EMBREE_INCLUDE_DIRS) + UNSET(EMBREE_LIBRARY) + UNSET(EMBREE_LIBRARY_XEONPHI) + ENDIF() # Build Embree included in the OSPRay tree # NOTE(jda) - Embree assumes that USE_TBB will be defined correctly in @@ -54,6 +69,7 @@ ELSE() SET(EMBREE_INCLUDE_DIRS ${OSPRAY_EMBREE_SOURCE_DIR}/include) SET(EMBREE_LIBRARY embree) SET(EMBREE_LIBRARY_XEONPHI embree_xeonphi) + SET(LAST_CONFIG_USED_EXTERNAL_EMBREE OFF CACHE INTERNAL "" FORCE) ENDIF() INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS}) From e896e8300b96f801f96128c6ec0e8ea035c08612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 15 Mar 2016 10:49:38 +0100 Subject: [PATCH 097/310] "Fix" seismic module by including apps/volumeViewer/loader --- modules/seismic/SeismicHorizonFile.h | 2 +- modules/seismic/SeismicVolumeFile.h | 2 +- modules/seismic/SymbolRegistry.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/seismic/SeismicHorizonFile.h b/modules/seismic/SeismicHorizonFile.h index d5516d238f..1795404eb2 100644 --- a/modules/seismic/SeismicHorizonFile.h +++ b/modules/seismic/SeismicHorizonFile.h @@ -19,7 +19,7 @@ #include "ospray/common/OSPCommon.h" #include #include -#include "modules/loaders/TriangleMeshFile.h" +#include "apps/volumeViewer/loaders/TriangleMeshFile.h" //! \brief A concrete implementation of the TriangleMeshFile class //! for reading horizon data stored in seismic file formats on disk. diff --git a/modules/seismic/SeismicVolumeFile.h b/modules/seismic/SeismicVolumeFile.h index 6fef58279c..e7f8508dd5 100644 --- a/modules/seismic/SeismicVolumeFile.h +++ b/modules/seismic/SeismicVolumeFile.h @@ -19,7 +19,7 @@ #include "ospray/common/OSPCommon.h" #include #include -#include "modules/loaders/VolumeFile.h" +#include "apps/volumeViewer/loaders/VolumeFile.h" //! \brief A concrete implementation of the VolumeFile class //! for reading voxel data stored in seismic file formats on disk. diff --git a/modules/seismic/SymbolRegistry.cpp b/modules/seismic/SymbolRegistry.cpp index b53980035a..a8a7219f49 100644 --- a/modules/seismic/SymbolRegistry.cpp +++ b/modules/seismic/SymbolRegistry.cpp @@ -14,7 +14,7 @@ // limitations under the License. // // ======================================================================== // -#include "modules/loaders/OSPObjectFile.h" +#include "apps/volumeViewer/loaders/OSPObjectFile.h" #include "SeismicHorizonFile.h" #include "SeismicVolumeFile.h" From 7668ca38ea1e2a5e3db1a7cf8031f16d760e13a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 15 Mar 2016 12:31:46 +0100 Subject: [PATCH 098/310] Adapt StreamLineViewer to separate Embree --- apps/streamLineViewer/StreamLineViewer.cpp | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/apps/streamLineViewer/StreamLineViewer.cpp b/apps/streamLineViewer/StreamLineViewer.cpp index 9f8b78fe67..1ea260339a 100644 --- a/apps/streamLineViewer/StreamLineViewer.cpp +++ b/apps/streamLineViewer/StreamLineViewer.cpp @@ -20,13 +20,14 @@ // ospray, for rendering #include "ospray/ospray.h" // embree -#include "common/sys/filename.h" +#include "common/FileName.h" // xml #include "apps/common/xml/XML.h" namespace ospray { using std::cout; using std::endl; + using namespace ospcommon; const char *rendererType = "raycast_eyelight"; bool doShadows = 1; @@ -75,7 +76,7 @@ namespace ospray { else return vec3f(lerpf(f, .5f,1.f,vec3f(0,1,0),vec3f(1,0,0))); } - void parseSV(const embree::FileName &fn) + void parseSV(const FileName &fn) { FILE *file = fopen(fn.str().c_str(),"rb"); if (!file) return; @@ -94,7 +95,7 @@ namespace ospray { box3f getBounds() const { - box3f bounds = embree::empty; + box3f bounds = empty; for (int i=0;i filePoints; @@ -199,7 +200,7 @@ namespace ospray { fclose(file); } - void parse(const embree::FileName &fn) + void parse(const FileName &fn) { if (fn.ext() == "pnt") parsePNT(fn); @@ -218,7 +219,7 @@ namespace ospray { } box3f getBounds() const { - box3f bounds = embree::empty; + box3f bounds = empty; for (int i=0;i cylinders[3]; box3f bounds; - void parse(const embree::FileName &fn) + void parse(const FileName &fn) { std::vector filePoints; FILE *file = fopen(fn.c_str(),"r"); Assert(file); - bounds = embree::empty; + bounds = empty; for (char line[10000]; fgets(line,10000,file) && !feof(file); ) { if (line[0] == '#') continue; @@ -580,7 +581,7 @@ namespace ospray { ospCommit(renderer); }; - virtual void reshape(const ospray::vec2i &newSize) + virtual void reshape(const vec2i &newSize) { Glut3DWidget::reshape(newSize); if (fb) ospFreeFrameBuffer(fb); @@ -591,7 +592,7 @@ namespace ospray { ospCommit(camera); } - virtual void keypress(char key, const vec2f where) + virtual void keypress(char key, const vec2i where) { switch (key) { case 'S': @@ -602,7 +603,7 @@ namespace ospray { ospFrameBufferClear(fb,OSP_FB_ACCUM); break; default: - Glut3DWidget::keypress(key,where); + Glut3DWidget::keypress(key, where); } } virtual void display() @@ -658,7 +659,7 @@ namespace ospray { for (int i=1;i Date: Tue, 15 Mar 2016 10:13:45 -0500 Subject: [PATCH 099/310] fixed compilation for data parallel config --- CMakeLists.txt | 5 +++++ common/box.h | 3 ++- common/vec.h | 10 ++++++++++ ospray/CMakeLists.txt | 3 --- ospray/common/Model.ih | 1 + ospray/volume/DataDistributedBlockedVolume.cpp | 2 +- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfbb244757..ae3ee5adb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,11 @@ SET(OSPRAY_VERSION ) SET(OSPRAY_SOVERSION 0) + +OPTION(OSPRAY_USE_EXTERNAL_EMBREE + "Use a pre-built Embree instead of the internally built version" OFF) + + SET(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") IF (WIN32) IF (NOT OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET) diff --git a/common/box.h b/common/box.h index ff8897b47c..74a6d7c526 100644 --- a/common/box.h +++ b/common/box.h @@ -84,7 +84,8 @@ namespace ospcommon { typedef box_t box2i; - typedef box_t box3f; + typedef box_t box3i; + typedef box_t box3f; typedef box_t box3fa; // typedef box_t box2i; diff --git a/common/vec.h b/common/vec.h index f7e99d13b6..f0179f59b9 100644 --- a/common/vec.h +++ b/common/vec.h @@ -423,6 +423,16 @@ namespace ospcommon { inline T reduce_add(const vec_t &v) { return v.x+v.y+v.z+v.w; } + template + inline T reduce_mul(const vec_t &v) + { return v.x*v.y; } + template + inline T reduce_mul(const vec_t &v) + { return v.x*v.y*v.z; } + template + inline T reduce_mul(const vec_t &v) + { return v.x*v.y*v.z*v.w; } + template inline T reduce_min(const vec_t &v) { return min(v.x,v.y); } diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 7cf6b8db88..acdff0dfa5 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -35,9 +35,6 @@ FIND_PACKAGE(Threads REQUIRED) SET(REQUIRED_MINIMUM_EMBREE 2.7.1) -OPTION(OSPRAY_USE_EXTERNAL_EMBREE - "Use a pre-built Embree instead of the internally built version" OFF) - IF(OSPRAY_USE_EXTERNAL_EMBREE) # Clear out embree directories if they were previously populated by an # internal build diff --git a/ospray/common/Model.ih b/ospray/common/Model.ih index 0b28a2fc1b..fdd02d1586 100644 --- a/ospray/common/Model.ih +++ b/ospray/common/Model.ih @@ -22,6 +22,7 @@ #include "ospray/volume/Volume.ih" // embree stuff +#include "embree2/rtcore.isph" #include "embree2/rtcore_scene.isph" struct Model { diff --git a/ospray/volume/DataDistributedBlockedVolume.cpp b/ospray/volume/DataDistributedBlockedVolume.cpp index 111b2a2816..b43b61acaa 100644 --- a/ospray/volume/DataDistributedBlockedVolume.cpp +++ b/ospray/volume/DataDistributedBlockedVolume.cpp @@ -169,7 +169,7 @@ namespace ospray { // Set the grid spacing, default to (1,1,1). this->gridSpacing = getParam3f("gridSpacing", vec3f(1.f)); - numDDBlocks = embree::reduce_mul(ddBlocks); + numDDBlocks = ospcommon::reduce_mul(ddBlocks); ddBlock = new DDBlock[numDDBlocks]; printf("=======================================================\n"); From b36ecab04d2c04ee966c5c1f8dff1fadf7394281 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 10:44:14 -0500 Subject: [PATCH 100/310] disable Qt viewers when using ICC on OS X (unresolved compile issues) --- apps/CMakeLists.txt | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 7007c3156b..16b619fee2 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -41,10 +41,16 @@ IF(NOT THIS_IS_MIC) ENDIF() IF(NOT WIN32) + # NOTE(jda) - Disable Qt based viewers when on OS X using ICC due to + # unresolved issues + SET(OSX_AND_ICC (APPLE AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")) + # qt-based viewer for geometry (and soon volumes) - OPTION(OSPRAY_APPS_QTVIEWER "Build ospQtViewer (Qt-based model viewer)" ON) - IF (OSPRAY_APPS_QTVIEWER) - ADD_SUBDIRECTORY(qtViewer) + IF(NOT OSX_AND_ICC) + OPTION(OSPRAY_APPS_QTVIEWER "Build ospQtViewer (Qt-based model viewer)" ON) + IF (OSPRAY_APPS_QTVIEWER) + ADD_SUBDIRECTORY(qtViewer) + ENDIF() ENDIF() # stream line viewer for NASA Stream Line Demo @@ -61,11 +67,11 @@ IF(NOT THIS_IS_MIC) ENDIF() # volume viewer application - OPTION(OSPRAY_APPS_VOLUMEVIEWER "Build ospVolumeViewer application." ON) - IF(OSPRAY_APPS_VOLUMEVIEWER) - ADD_SUBDIRECTORY(volumeViewer) + IF(NOT OSX_AND_ICC) + OPTION(OSPRAY_APPS_VOLUMEVIEWER "Build ospVolumeViewer application." ON) + IF(OSPRAY_APPS_VOLUMEVIEWER) + ADD_SUBDIRECTORY(volumeViewer) + ENDIF() ENDIF() ENDIF(NOT WIN32) - - ENDIF() From 7fda0221a35a68c11a9be105af9d15b2d16313e4 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Tue, 15 Mar 2016 10:48:51 -0500 Subject: [PATCH 101/310] qtviewer - frame buffer now properly cleared upon resetting accum --- apps/qtViewer/ModelViewer.cpp | 1 + apps/qtViewer/sg/Renderer.cpp | 3 ++- apps/qtViewer/sg/common/TransferFunction.cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/qtViewer/ModelViewer.cpp b/apps/qtViewer/ModelViewer.cpp index 87ea46a2aa..2db2acda40 100644 --- a/apps/qtViewer/ModelViewer.cpp +++ b/apps/qtViewer/ModelViewer.cpp @@ -407,6 +407,7 @@ namespace ospray { void ModelViewer::render() { + PING; sgRenderer->resetAccumulation(); if (renderWidget) renderWidget->updateGL(); } diff --git a/apps/qtViewer/sg/Renderer.cpp b/apps/qtViewer/sg/Renderer.cpp index 306da2e9ed..f4d8c9fadb 100644 --- a/apps/qtViewer/sg/Renderer.cpp +++ b/apps/qtViewer/sg/Renderer.cpp @@ -54,6 +54,7 @@ namespace ospray { integrator->getOSPHandle(), OSP_FB_COLOR|OSP_FB_ACCUM); accumID++; + return 0; } @@ -70,7 +71,7 @@ namespace ospray { accumID = 0; // cout << "resetting accum" << endl; if (frameBuffer) - frameBuffer->clearAccum(); + frameBuffer->clear(); } } diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index 90aea29e52..a90e5e8cb2 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -33,6 +33,7 @@ namespace ospray { //! \brief Sets a new 'texture map' to be used for the color mapping void TransferFunction::setColorMap(const std::vector &colorArray) { + PING; if (ospColorData) { ospRelease(ospColorData); ospColorData = NULL; } this->colorArray = colorArray; } From 099f5f79a580f47ecdc4b9262cb683ec040c729b Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Tue, 15 Mar 2016 11:00:25 -0500 Subject: [PATCH 102/310] disbaled osx_and_icc test - it's not working properly --- apps/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 16b619fee2..9e1665a304 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -43,8 +43,8 @@ IF(NOT THIS_IS_MIC) IF(NOT WIN32) # NOTE(jda) - Disable Qt based viewers when on OS X using ICC due to # unresolved issues - SET(OSX_AND_ICC (APPLE AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")) - + SET(OSX_AND_ICC OFF) +# iw: this doesn't work - it disables even on linux! (APPLE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel"))) # qt-based viewer for geometry (and soon volumes) IF(NOT OSX_AND_ICC) OPTION(OSPRAY_APPS_QTVIEWER "Build ospQtViewer (Qt-based model viewer)" ON) From 46718f206c17a68f1602a105a98245b0476d7d7a Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 11:14:21 -0500 Subject: [PATCH 103/310] fix cmake expression bug --- apps/CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 9e1665a304..0df71eabeb 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -43,10 +43,8 @@ IF(NOT THIS_IS_MIC) IF(NOT WIN32) # NOTE(jda) - Disable Qt based viewers when on OS X using ICC due to # unresolved issues - SET(OSX_AND_ICC OFF) -# iw: this doesn't work - it disables even on linux! (APPLE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel"))) # qt-based viewer for geometry (and soon volumes) - IF(NOT OSX_AND_ICC) + IF(NOT (APPLE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel"))) OPTION(OSPRAY_APPS_QTVIEWER "Build ospQtViewer (Qt-based model viewer)" ON) IF (OSPRAY_APPS_QTVIEWER) ADD_SUBDIRECTORY(qtViewer) @@ -67,7 +65,7 @@ IF(NOT THIS_IS_MIC) ENDIF() # volume viewer application - IF(NOT OSX_AND_ICC) + IF(NOT (APPLE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel"))) OPTION(OSPRAY_APPS_VOLUMEVIEWER "Build ospVolumeViewer application." ON) IF(OSPRAY_APPS_VOLUMEVIEWER) ADD_SUBDIRECTORY(volumeViewer) From 5490b2b6b377a61d6d5bdd985d4b43663a169e6e Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 13:48:26 -0500 Subject: [PATCH 104/310] import internal tasking system found in "feature-ospray-tasking" branch --- cmake/ospray.cmake | 24 +++++++----- common/thread.h | 4 +- ospray/CMakeLists.txt | 1 + ospray/api/LocalDevice.cpp | 2 - ospray/common/OSPCommon.cpp | 55 ++++++++++++++++------------ ospray/common/tasking/parallel_for.h | 15 +++++++- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 3b63121f5e..8f6447b3e5 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -329,22 +329,27 @@ MACRO(CONFIGURE_TASKING_SYSTEM) #ENDIF() SET(OSPRAY_TASKING_SYSTEM ${TASKING_DEFAULT} CACHE STRING - "Per-node thread tasking system [TBB,OpenMP,Cilk,Debug]") + "Per-node thread tasking system [TBB,OpenMP,Cilk,Internal,Debug]") SET_PROPERTY(CACHE OSPRAY_TASKING_SYSTEM PROPERTY - STRINGS TBB ${CILK_STRING} OpenMP Debug) + STRINGS TBB ${CILK_STRING} OpenMP Internal Debug) MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) - SET(USE_TBB FALSE) - SET(USE_CILK FALSE) - SET(USE_OPENMP FALSE) + STRING(TOUPPER ${OSPRAY_TASKING_SYSTEM} OSPRAY_TASKING_SYSTEM_ID) - IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") + SET(USE_TBB FALSE) + SET(USE_CILK FALSE) + SET(USE_OPENMP FALSE) + SET(USE_INTERNAL FALSE) + + IF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "TBB") SET(USE_TBB TRUE) - ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "Cilk") + ELSEIF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "CILK") SET(USE_CILK TRUE) - ELSEIF(${OSPRAY_TASKING_SYSTEM} STREQUAL "OpenMP") + ELSEIF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "OPENMP") SET(USE_OPENMP TRUE) + ELSEIF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "INTERNAL") + SET(USE_INTERNAL TRUE) ENDIF() UNSET(TASKING_SYSTEM_LIBS) @@ -376,9 +381,10 @@ MACRO(CONFIGURE_TASKING_SYSTEM) ENDIF() ELSEIF(USE_CILK) ADD_DEFINITIONS(-DOSPRAY_USE_CILK) + ELSEIF(USE_INTERNAL) + ADD_DEFINITIONS(-DOSPRAY_USE_INTERNAL_TASKING) ELSE()#Debug # Do nothing, will fall back to scalar code (useful for debugging) ENDIF() ENDIF(USE_TBB) - ENDMACRO() diff --git a/common/thread.h b/common/thread.h index e1a16a0931..d4e1016d9f 100644 --- a/common/thread.h +++ b/common/thread.h @@ -17,7 +17,6 @@ #pragma once #include "platform.h" -//#include "mutex.h" namespace ospcommon { @@ -28,7 +27,8 @@ namespace ospcommon typedef void (*thread_func)(void*); /*! creates a hardware thread running on specific logical thread */ - thread_t createThread(thread_func f, void* arg, size_t stack_size = 0, ssize_t threadID = -1); + thread_t createThread(thread_func f, void* arg, + size_t stack_size = 0, ssize_t threadID = -1); /*! set affinity of the calling thread */ void setAffinity(ssize_t affinity); diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index acdff0dfa5..7804401659 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -107,6 +107,7 @@ SET(OSPRAY_SOURCES common/tasking/parallel_for.h common/tasking/async.h + common/tasking/TaskSys.cpp fb/FrameBuffer.ispc fb/FrameBuffer.cpp diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index e1ba15b2d2..2f185f2555 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -49,8 +49,6 @@ namespace ospray { else logLevel = 0; - ospray::init(_ac,&_av); - // ------------------------------------------------------- // initialize embree. (we need to do this here rather than in // ospray::init() because in mpi-mode the latter is also called diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index d88cf0e7af..855a972b59 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -15,6 +15,9 @@ // ======================================================================== // #include "OSPCommon.h" +#ifdef OSPRAY_USE_INTERNAL_TASKING +# include "ospray/common/tasking/TaskSys.h" +#endif // embree #include "embree2/rtcore.h" #include "common/sysinfo.h" @@ -92,32 +95,36 @@ namespace ospray { throw std::runtime_error("Error. OSPRay only runs on CPUs that support at least SSE4.1."); #endif - if (!_ac || !_av) - return; - - int &ac = *_ac; - char ** &av = *(char ***)_av; - for (int i=1;i #elif defined(OSPRAY_USE_CILK) # include +#elif defined(OSPRAY_USE_INTERNAL_TASKING) +# include "ospray/common/tasking/TaskSys.h" #endif namespace ospray { // NOTE(jda) - This abstraction wraps "fork-join" parallelism, with an implied // synchronizsation after all of the tasks have run. -template -inline void parallel_for(int nTasks, const Task& fcn) +template +inline void parallel_for(int nTasks, const TASK_T& fcn) { #ifdef OSPRAY_USE_TBB tbb::parallel_for(0, nTasks, 1, fcn); @@ -40,6 +42,15 @@ inline void parallel_for(int nTasks, const Task& fcn) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); } +#elif defined(OSPRAY_USE_INTERNAL_TASKING) + struct LocalTask : public Task { + const TASK_T &t; + LocalTask(const TASK_T& fcn) : Task("LocalTask"), t(fcn) {} + void run(size_t taskIndex) override { t(taskIndex); } + }; + + Ref task = new LocalTask(fcn); + task->scheduleAndWait(nTasks); #else // Debug (no tasking system) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); From 7b119ba3554844f5adfcdfe4cb9c2555bf457e33 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Tue, 15 Mar 2016 13:52:55 -0500 Subject: [PATCH 105/310] 2016-03-15 Ingo Wald * transfer function editor now properly initializes itself from a transfer function's values as set in the xml file (opacities only, color map not yet working) * sg::transfer function now properly reading itself from xml file, and registers itself under a name if so given. * sg::amrvolume can now a use assigned transfer function * ospray/transferFunction/LinearTransferFunction.ispc (LinearTransferFunction_destroy): ispc side of xf no longer copies opacity and color arrays; uses those from c side. renamed to self/super scheme got rid of return()'s * apps/qtViewer/sg/common/TransferFunction.h (ospray): transferfunction now parses itself from xml file transferFunction now uses a list of control poins rather than explit uni-sampled table of points * common/vec.cpp (ospcommon): added toVec<>(const char *) helper functions (in vec.cpp) --- apps/qtViewer/ModelViewer.cpp | 13 +- apps/qtViewer/sg/common/Node.h | 2 + apps/qtViewer/sg/common/TransferFunction.cpp | 138 ++++++++++-- apps/qtViewer/sg/common/TransferFunction.h | 29 ++- apps/qtViewer/sg/volume/Volume.cpp | 1 + .../QTransferFunctionEditor.cpp | 53 ++--- .../QTransferFunctionEditor.h | 10 +- common/CMakeLists.txt | 1 + common/vec.cpp | 77 +++++++ common/vec.h | 10 + .../LinearTransferFunction.cpp | 3 +- .../LinearTransferFunction.ih | 6 +- .../LinearTransferFunction.ispc | 207 +++++++++--------- 13 files changed, 390 insertions(+), 160 deletions(-) create mode 100644 common/vec.cpp diff --git a/apps/qtViewer/ModelViewer.cpp b/apps/qtViewer/ModelViewer.cpp index 2db2acda40..d78e62c3df 100644 --- a/apps/qtViewer/ModelViewer.cpp +++ b/apps/qtViewer/ModelViewer.cpp @@ -158,6 +158,7 @@ namespace ospray { sg::TransferFunction *xf = dynamic_cast (sgRenderer->uniqueNodes.object[i]->node.ptr); if (xf) xferFuncs.push_back(xf); + cout << "FOUND xf : " << xf << endl; } std::cout << "#osp:qtv: found " << xferFuncs.size() << " transfer function nodes" << std::endl; @@ -193,9 +194,18 @@ namespace ospray { // add combo box and stacked widget entries pageComboBox->addItem(tr(name.c_str())); + TransferFunction *xf = xferFuncs[i].ptr; + assert(xf); // create a transfer function editor for this transfer function node QOSPTransferFunctionEditor *xfEd - = new QOSPTransferFunctionEditor(xferFuncs[i]); + = new QOSPTransferFunctionEditor(xf); + const std::vector > &alpha = xf->getAlphaArray(); + if (!alpha.empty()) { + std::vector points; + for (int i=0;isetOpacityPoints(points); + } stackedWidget->addWidget(xfEd); connect(xfEd, SIGNAL(transferFunctionChanged()), this, SLOT(render())); @@ -407,7 +417,6 @@ namespace ospray { void ModelViewer::render() { - PING; sgRenderer->resetAccumulation(); if (renderWidget) renderWidget->updateGL(); } diff --git a/apps/qtViewer/sg/common/Node.h b/apps/qtViewer/sg/common/Node.h index f3d488647b..eb7fa0fdaa 100644 --- a/apps/qtViewer/sg/common/Node.h +++ b/apps/qtViewer/sg/common/Node.h @@ -23,6 +23,8 @@ #include // xml #include "apps/common/xml/XML.h" +// ospcommon +#include "common/vec.h" namespace ospray { diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index a90e5e8cb2..cdff38ad47 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -25,37 +25,92 @@ namespace ospray { TransferFunction::TransferFunction() : ospTransferFunction(NULL), ospColorData(NULL), - ospAlphaData(NULL) + ospAlphaData(NULL), + numSamples(128) { setDefaultValues(); } - //! \brief Sets a new 'texture map' to be used for the color mapping + // //! \brief Sets a new 'texture map' to be used for the color mapping void TransferFunction::setColorMap(const std::vector &colorArray) { PING; if (ospColorData) { ospRelease(ospColorData); ospColorData = NULL; } - this->colorArray = colorArray; + this->colorArray.clear(); + for (int i=0;icolorArray.push_back(std::pair(i,colorArray[i])); } //! \brief Sets a new 'texture map' to be used for the alpha mapping - void TransferFunction::setAlphaMap(const std::vector &alphaArray) + void TransferFunction::setAlphaMap(const std::vector &alphaArray) { if (ospAlphaData) { ospRelease(ospAlphaData); ospAlphaData = NULL; } - this->alphaArray = alphaArray; + this->alphaArray.clear(); + for (int i=0;ialphaArray.push_back(std::pair(alphaArray[i].x,alphaArray[i].y)); } + float TransferFunction::getInterpolatedAlphaValue(float x) + { + if (x <= alphaArray.front().first) + return alphaArray.front().second; + for (int i=1;i= 1.) + // return alphaArray.back().second; + + // // we could make this more efficient... + // for(unsigned int i=0; igetProp("name"); + if (name != "") + registerNamedNode(name,this); + + for (int ii = 0; ii != node->child.size(); ii++) { + const xml::Node *child = node->child[ii]; + // ------------------------------------------------------- + // colors + // ------------------------------------------------------- + if (child->name == "colors" || child->name == "color") { + colorArray.clear(); + char *cont = strdup(child->content.c_str()); + assert(cont); + + const char *c = strtok(cont,","); + while (c) { + colorArray.push_back(std::pair(colorArray.size(),toVec3f(c))); + c = strtok(NULL,","); + } + + free(cont); + } + + // ------------------------------------------------------- + // alpha + // ------------------------------------------------------- + if (child->name == "alphas" || child->name == "alpha") { + alphaArray.clear(); + char *cont = strdup(child->content.c_str()); + + assert(cont); + const char *c = strtok(cont,","); + while (c) { + vec2f cp = toVec2f(c); + alphaArray.push_back(std::pair(cp.x,cp.y)); + c = strtok(NULL,","); + } + + free(cont); + } + } + } + //! \brief Initialize this node's value from given corresponding XML node void TransferFunction::setDefaultValues() { + static float col[7][3] = {{0 , 0 , 0.562493 }, + {0 , 0 , 1 }, + {0 , 1 , 1 }, + {0.500008 , 1 , 0.500008 }, + {1 , 1 , 0 }, + {1 , 0 , 0 }, + {0.500008 , 0 , 0 }}; + colorArray.clear(); - colorArray.push_back(ospcommon::vec3f(0 , 0 , 0.562493 )); - colorArray.push_back(ospcommon::vec3f(0 , 0 , 1 )); - colorArray.push_back(ospcommon::vec3f(0 , 1 , 1 )); - colorArray.push_back(ospcommon::vec3f(0.500008 , 1 , 0.500008 )); - colorArray.push_back(ospcommon::vec3f(1 , 1 , 0 )); - colorArray.push_back(ospcommon::vec3f(1 , 0 , 0 )); - colorArray.push_back(ospcommon::vec3f(0.500008 , 0 , 0 )); - + for (int i=0;i<7;i++) + colorArray.push_back(std::pair(i,vec3f(col[i][0],col[i][1],col[i][2]))); + alphaArray.clear(); for (int i=0;i(i,1.f)); //i/float(colorArray.size()-1)); } OSP_REGISTER_SG_NODE(TransferFunction) diff --git a/apps/qtViewer/sg/common/TransferFunction.h b/apps/qtViewer/sg/common/TransferFunction.h index 4d2aacd1e0..d8cd9c9321 100644 --- a/apps/qtViewer/sg/common/TransferFunction.h +++ b/apps/qtViewer/sg/common/TransferFunction.h @@ -40,25 +40,38 @@ namespace ospray { virtual void render(RenderContext &ctx); //! \brief Initialize this node's value from given corresponding XML node - virtual void setFromXML(const xml::Node *const node) {} + virtual void setFromXML(const xml::Node *const node, + const unsigned char *binBasePtr); virtual void commit(); - /*! set a new color map array */ + // /*! set a new color map array (using array of uniformly samples colors) */ void setColorMap(const std::vector &colorArray); - /*! set a new alpha map array */ - void setAlphaMap(const std::vector &alphaArray); + /*! set a new alpha map array - x coordinate is point pos, y is point alpha value */ + void setAlphaMap(const std::vector &alphaArray); + + const std::vector > &getAlphaArray() const + { return alphaArray; } + + float getInterpolatedAlphaValue(float x); /*! return the ospray handle for this xfer fct, so we can assign - it to ospray obejcts that need a reference to the ospray - version of this xf */ + it to ospray obejcts that need a reference to the ospray + version of this xf */ OSPTransferFunction getOSPHandle() const { return ospTransferFunction; }; protected: OSPTransferFunction ospTransferFunction; OSPData ospColorData; OSPData ospAlphaData; + // number of samples we'll use in the colordata and alphadata arrays + int numSamples; - std::vector colorArray; - std::vector alphaArray; + // array of (x,color(x)) color samples; the first and last x + // determine the range of x'es, all values will be resampled + // uniformly into this range. samples must be sorted by x + // coordinate, and must span a non-empty range of x coordinates + std::vector > colorArray; + // array of (x,alpha(x)) opacity samples; otherwise same as colorArray + std::vector > alphaArray; }; } // ::ospray::sg diff --git a/apps/qtViewer/sg/volume/Volume.cpp b/apps/qtViewer/sg/volume/Volume.cpp index 9539697d5e..ce11467297 100644 --- a/apps/qtViewer/sg/volume/Volume.cpp +++ b/apps/qtViewer/sg/volume/Volume.cpp @@ -33,6 +33,7 @@ namespace ospray { void Volume::serialize(sg::Serialization::State &state) { + PING; PRINT(toString()); Node::serialize(state); if (transferFunction) transferFunction->serialize(state); diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp index 330530debe..281e7063e0 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp @@ -227,27 +227,27 @@ namespace ospray { return -1; } - float QTransferFunctionAlphaEditor::getInterpolatedValue(float x) - { - // boundary cases - if(x <= 0.) - return points[0].y; + // float QTransferFunctionAlphaEditor::getInterpolatedValue(float x) + // { + // // boundary cases + // if(x <= 0.) + // return points[0].y; - if(x >= 1.) - return points[points.size()-1].y; - - // we could make this more efficient... - for(unsigned int i=0; i= 1.) + // return points[points.size()-1].y; + + // // we could make this more efficient... + // for(unsigned int i=0; isetAlphaMap(transferFunctionAlphaEditor->getPoints()); // PING; - const int numAlphas = 256; - std::vector alphas; - for (int i=0;igetInterpolatedValue(i/float(numAlphas-1))); + // const int numAlphas = 256; + // std::vector alphas; + // for (int i=0;igetInterpolatedValue(i/float(numAlphas-1))); - // PING; - sgNode->setAlphaMap(alphas); + // // PING; + // sgNode->setAlphaMap(alphas); // PING; sgNode->commit(); // PING; diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h index baabd4cb10..96f226f56c 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h @@ -45,15 +45,15 @@ namespace ospray { /*! set background image for a given color map */ void setColorMapImage(const QImage &image); - + const std::vector &getPoints() const { return points; } + void setPoints(const std::vector &points) { this->points = points; } signals: void transferFunctionChanged(); - public: - // get y value based on linear interpolation of the points values for x in [0, 1] - float getInterpolatedValue(float x); + // // get y value based on linear interpolation of the points values for x in [0, 1] + // float getInterpolatedValue(float x); protected: @@ -128,6 +128,8 @@ namespace ospray { // add a new color map to the list of selectable color maps void addColorMap(const ColorMap *colorMap); + void setOpacityPoints(const std::vector &points) + { transferFunctionAlphaEditor->setPoints(points); } signals: void transferFunctionChanged(); diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 4193cb0e44..078cd53f2d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -24,6 +24,7 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED malloc.cpp library.cpp thread.cpp + vec.cpp AffineSpace.h box.h diff --git a/common/vec.cpp b/common/vec.cpp new file mode 100644 index 0000000000..f6c937a90c --- /dev/null +++ b/common/vec.cpp @@ -0,0 +1,77 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "vec.h" + +namespace ospcommon { + // ------------------------------------------------------- + // parsing from strings + // ------------------------------------------------------- + vec2f toVec2f(const char *ptr) + { + assert(ptr); + vec2f v; + int rc = sscanf(ptr,"%f %f",&v.x,&v.y); + assert(rc == 2); + return v; + } + + vec3f toVec3f(const char *ptr) + { + assert(ptr); + vec3f v; + int rc = sscanf(ptr,"%f %f %f",&v.x,&v.y,&v.z); + assert(rc == 3); + return v; + } + + vec4f toVec4f(const char *ptr) + { + assert(ptr); + vec4f v; + int rc = sscanf(ptr,"%f %f %f %f",&v.x,&v.y,&v.z,&v.w); + assert(rc == 4); + return v; + } + + vec2i toVec2i(const char *ptr) + { + assert(ptr); + vec2i v; + int rc = sscanf(ptr,"%i %i",&v.x,&v.y); + assert(rc == 2); + return v; + } + + vec3i toVec3i(const char *ptr) + { + assert(ptr); + vec3i v; + int rc = sscanf(ptr,"%i %i %i",&v.x,&v.y,&v.z); + assert(rc == 3); + return v; + } + + vec4i toVec4i(const char *ptr) + { + assert(ptr); + vec4i v; + int rc = sscanf(ptr,"%i %i %i %i",&v.x,&v.y,&v.z,&v.w); + assert(rc == 4); + return v; + } + +} // ::ospcommon diff --git a/common/vec.h b/common/vec.h index f0179f59b9..81a3784273 100644 --- a/common/vec.h +++ b/common/vec.h @@ -499,5 +499,15 @@ namespace ospcommon { typedef vec_t vec4f; typedef vec_t vec4d; + // ------------------------------------------------------- + // parsing from strings + // ------------------------------------------------------- + vec2f toVec2f(const char *ptr); + vec3f toVec3f(const char *ptr); + vec4f toVec4f(const char *ptr); + vec2i toVec2i(const char *ptr); + vec3i toVec3i(const char *ptr); + vec4i toVec4i(const char *ptr); + } // ::ospcommon diff --git a/ospray/transferFunction/LinearTransferFunction.cpp b/ospray/transferFunction/LinearTransferFunction.cpp index b7cebbf8f2..a772b08483 100644 --- a/ospray/transferFunction/LinearTransferFunction.cpp +++ b/ospray/transferFunction/LinearTransferFunction.cpp @@ -44,10 +44,11 @@ namespace ospray { (ispc::vec3f *) colorValues->data); // Set the opacity values. - if (opacityValues) + if (opacityValues) { ispc::LinearTransferFunction_setOpacityValues(ispcEquivalent, opacityValues->numItems, (float *)opacityValues->data); + } // Set the value range that the transfer function covers. vec2f valueRange = getParam2f("valueRange", vec2f(0.0f, 1.0f)); diff --git a/ospray/transferFunction/LinearTransferFunction.ih b/ospray/transferFunction/LinearTransferFunction.ih index 4cefd7b7e0..40971cfa0b 100644 --- a/ospray/transferFunction/LinearTransferFunction.ih +++ b/ospray/transferFunction/LinearTransferFunction.ih @@ -26,10 +26,12 @@ struct LinearTransferFunction { TransferFunction super; //! Transfer function opacity values and count. - float *uniform opacityValues; uniform int opacityValueCount; + uniform float *uniform opacityValues; + uniform int opacityValueCount; //! Transfer function color values and count. - vec3f *uniform colorValues; uniform int colorValueCount; + uniform vec3f *uniform colorValues; + uniform int colorValueCount; //! A 2D array that contains precomputed minimum and maximum opacity values for a transfer function. vec2f minMaxOpacityInRange[PRECOMPUTED_OPACITY_SUBRANGE_COUNT][PRECOMPUTED_OPACITY_SUBRANGE_COUNT]; diff --git a/ospray/transferFunction/LinearTransferFunction.ispc b/ospray/transferFunction/LinearTransferFunction.ispc index 9522eb5b22..a68e625987 100644 --- a/ospray/transferFunction/LinearTransferFunction.ispc +++ b/ospray/transferFunction/LinearTransferFunction.ispc @@ -17,34 +17,34 @@ #include "ospray/transferFunction/LinearTransferFunction.ih" inline varying vec3f -LinearTransferFunction_getColorForValue(const void *uniform pointer, +LinearTransferFunction_getColorForValue(const void *uniform _self, varying float value) { // Return (0,0,0) for NaN values. if (isnan(value)) - return(make_vec3f(0.0f)); + return make_vec3f(0.0f); // Cast to the actual TransferFunction subtype. - const LinearTransferFunction *uniform transferFunction - = (const LinearTransferFunction *uniform) pointer; + const LinearTransferFunction *uniform self + = (const LinearTransferFunction *uniform) _self; // No color values may be available. - if (transferFunction->colorValueCount == 0) + if (self->colorValueCount == 0) return make_vec3f(1.0f); // Clamp the value to the lower bound of the value range. - if (value <= transferFunction->super.valueRange.x) - return transferFunction->colorValues[0]; + if (value <= self->super.valueRange.x) + return self->colorValues[0]; // Clamp the value to the upper bound of the value range. - if (value >= transferFunction->super.valueRange.y) - return transferFunction->colorValues[transferFunction->colorValueCount - 1]; + if (value >= self->super.valueRange.y) + return self->colorValues[self->colorValueCount - 1]; // Map the value into the range [0.0, 1.0]. value - = (value - transferFunction->super.valueRange.x) - / (transferFunction->super.valueRange.y - transferFunction->super.valueRange.x) - * (transferFunction->colorValueCount - 1.0f); + = (value - self->super.valueRange.x) + / (self->super.valueRange.y - self->super.valueRange.x) + * (self->colorValueCount - 1.0f); // Compute the color index and fractional offset. int index = floor(value); @@ -52,97 +52,101 @@ LinearTransferFunction_getColorForValue(const void *uniform pointer, // The interpolated color. return - ((1.0f - remainder) * transferFunction->colorValues[index] - + remainder * transferFunction->colorValues[min(index + 1, transferFunction->colorValueCount - 1)]); + ((1.0f - remainder) * self->colorValues[index] + + remainder * self->colorValues[min(index + 1, self->colorValueCount - 1)]); } uniform vec2f -LinearTransferFunction_getMinMaxOpacityInRange(void *uniform pointer, +LinearTransferFunction_getMinMaxOpacityInRange(void *uniform _self, const uniform vec2f &range) { - uniform LinearTransferFunction *uniform transferFunction = (uniform LinearTransferFunction *uniform) pointer; + uniform LinearTransferFunction *uniform self = (uniform LinearTransferFunction *uniform) _self; const uniform int maxDim = PRECOMPUTED_OPACITY_SUBRANGE_COUNT - 1; - const uniform float denom = transferFunction->super.valueRange.y - transferFunction->super.valueRange.x; - const uniform int i = floor(clamp((range.x - transferFunction->super.valueRange.x) / denom) * maxDim); - const uniform int j = ceil(clamp((range.y - transferFunction->super.valueRange.x) / denom) * maxDim); - return(transferFunction->minMaxOpacityInRange[min(i,maxDim)][min(j,maxDim)]); + const uniform float denom = self->super.valueRange.y - self->super.valueRange.x; + const uniform int i = floor(clamp((range.x - self->super.valueRange.x) / denom) * maxDim); + const uniform int j = ceil(clamp((range.y - self->super.valueRange.x) / denom) * maxDim); + return self->minMaxOpacityInRange[min(i,maxDim)][min(j,maxDim)]; } varying float -LinearTransferFunction_getMaxOpacityInRange(void *uniform pointer, +LinearTransferFunction_getMaxOpacityInRange(void *uniform _self, const varying vec2f &range) { - uniform LinearTransferFunction *uniform transferFunction = (uniform LinearTransferFunction *uniform) pointer; + uniform LinearTransferFunction *uniform self = (uniform LinearTransferFunction *uniform) _self; const uniform int maxDim = PRECOMPUTED_OPACITY_SUBRANGE_COUNT - 1; - const uniform float denom = transferFunction->super.valueRange.y - transferFunction->super.valueRange.x; - const varying int i = floor(clamp((range.x - transferFunction->super.valueRange.x) / denom) * maxDim); - const varying int j = ceil(clamp((range.y - transferFunction->super.valueRange.x) / denom) * maxDim); - return(transferFunction->minMaxOpacityInRange[min(i,maxDim)][min(j,maxDim)].y); + const uniform float denom = self->super.valueRange.y - self->super.valueRange.x; + const varying int i = floor(clamp((range.x - self->super.valueRange.x) / denom) * maxDim); + const varying int j = ceil(clamp((range.y - self->super.valueRange.x) / denom) * maxDim); + return self->minMaxOpacityInRange[min(i,maxDim)][min(j,maxDim)].y; } inline varying float -LinearTransferFunction_getOpacityForValue(const void *uniform pointer, +LinearTransferFunction_getOpacityForValue(const void *uniform _self, varying float value) { // Return 0 for NaN values. - if (isnan(value)) return(0.0f); + if (isnan(value)) return 0.0f; // Cast to the actual TransferFunction subtype. - const LinearTransferFunction *uniform transferFunction - = (const LinearTransferFunction *uniform) pointer; + const LinearTransferFunction *uniform self + = (const LinearTransferFunction *uniform) _self; // No opacity values may be available. - if (transferFunction->opacityValueCount == 0) + if (self->opacityValueCount == 0) return 1.0f; // Clamp the value to the lower bound of the value range. - if (value <= transferFunction->super.valueRange.x) - return transferFunction->opacityValues[0]; + if (value <= self->super.valueRange.x) + return self->opacityValues[0]; + // print("numopacity %\n",self->opacityValueCount); // Clamp the value to the upper bound of the value range. - if (value >= transferFunction->super.valueRange.y) - return transferFunction->opacityValues[transferFunction->opacityValueCount - 1]; + if (value >= self->super.valueRange.y) + return self->opacityValues[self->opacityValueCount - 1]; - // Map the value into the range [0.0, 1.0]. - value - = (value - transferFunction->super.valueRange.x) - / (transferFunction->super.valueRange.y - transferFunction->super.valueRange.x) - * (transferFunction->opacityValueCount - 1.0f); + // Map the value into the range [0.0, numValues). + const float remapped + = (value - self->super.valueRange.x) + / (self->super.valueRange.y - self->super.valueRange.x) + * (self->opacityValueCount - 1.0f); // Compute the opacity index and fractional offset. - int index = floor(value); - float remainder = value - index; + int index = floor(remapped); + float remainder = remapped - index; // The interpolated opacity. - return - (1.0f - remainder) * transferFunction->opacityValues[index] - + remainder * transferFunction->opacityValues[min(index + 1, transferFunction->opacityValueCount - 1)]; - + float ret = + (1.0f - remainder) * self->opacityValues[index] + + remainder * self->opacityValues[min(index + 1, self->opacityValueCount - 1)]; + // print("opacity(%) = %\n",value,ret); + // print("index % rem %\n",index,remainder); + // print("val[index] = %\n",self->opacityValues[index] ); + return ret; } -void LinearTransferFunction_precomputeMinMaxOpacityRanges(void *uniform pointer) +void LinearTransferFunction_precomputeMinMaxOpacityRanges(void *uniform _self) { - uniform LinearTransferFunction *uniform transferFunction - = (uniform LinearTransferFunction *uniform) pointer; + uniform LinearTransferFunction *uniform self + = (uniform LinearTransferFunction *uniform) _self; // Compute the diagonal. for (uniform int i=0; i < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; i++) { // Figure out the range of values in the array we are going to compare. const uniform int checkRangeLow - = transferFunction->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); + = self->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); const uniform int checkRangeHigh - = transferFunction->opacityValueCount * (((float)i + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); + = self->opacityValueCount * (((float)i + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); - uniform vec2f range = make_vec2f(transferFunction->opacityValues[checkRangeLow]); + uniform vec2f range = make_vec2f(self->opacityValues[checkRangeLow]); for (uniform int opacityIDX = checkRangeLow + 1; opacityIDX < checkRangeHigh; opacityIDX++) - range = make_vec2f(min(range.x, transferFunction->opacityValues[opacityIDX]), - max(range.y, transferFunction->opacityValues[opacityIDX])); + range = make_vec2f(min(range.x, self->opacityValues[opacityIDX]), + max(range.y, self->opacityValues[opacityIDX])); - transferFunction->minMaxOpacityInRange[i][i] = range; + self->minMaxOpacityInRange[i][i] = range; } // Fill out each column from the diagonal up. @@ -150,15 +154,15 @@ void LinearTransferFunction_precomputeMinMaxOpacityRanges(void *uniform pointer) for (uniform int j = i + 1; j < PRECOMPUTED_OPACITY_SUBRANGE_COUNT; j++) { // Figure out the range of values in the array we are going to compare. - const uniform int checkRangeLow = transferFunction->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); - const uniform int checkRangeHigh = transferFunction->opacityValueCount * (((float) j + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); + const uniform int checkRangeLow = self->opacityValueCount * (((float) i) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); + const uniform int checkRangeHigh = self->opacityValueCount * (((float) j + 1) / PRECOMPUTED_OPACITY_SUBRANGE_COUNT); - uniform vec2f range = transferFunction->minMaxOpacityInRange[i][i]; + uniform vec2f range = self->minMaxOpacityInRange[i][i]; for (uniform int opacityIDX = checkRangeLow + 1; opacityIDX < checkRangeHigh; opacityIDX++) - range = make_vec2f(min(range.x, transferFunction->opacityValues[opacityIDX]), - max(range.y, transferFunction->opacityValues[opacityIDX])); + range = make_vec2f(min(range.x, self->opacityValues[opacityIDX]), + max(range.y, self->opacityValues[opacityIDX])); - transferFunction->minMaxOpacityInRange[i][j] = range; + self->minMaxOpacityInRange[i][j] = range; } @@ -169,94 +173,95 @@ void LinearTransferFunction_precomputeMinMaxOpacityRanges(void *uniform pointer) export void *uniform LinearTransferFunction_createInstance() { // The transfer function. - LinearTransferFunction *uniform transferFunction = uniform new uniform LinearTransferFunction; + LinearTransferFunction *uniform self = uniform new uniform LinearTransferFunction; // Function to get the interpolated color for a given value. - transferFunction->super.getColorForValue = LinearTransferFunction_getColorForValue; + self->super.getColorForValue = LinearTransferFunction_getColorForValue; // Function to get the interpolated opacity for a given value. - transferFunction->super.getOpacityForValue = LinearTransferFunction_getOpacityForValue; + self->super.getOpacityForValue = LinearTransferFunction_getOpacityForValue; // Virtual function to look up the maximum opacity based on an input range. - transferFunction->super.getMaxOpacityInRange = LinearTransferFunction_getMaxOpacityInRange; + self->super.getMaxOpacityInRange = LinearTransferFunction_getMaxOpacityInRange; // Virtual function to look up the min/max opacity based on an input range. - transferFunction->super.getMinMaxOpacityInRange = LinearTransferFunction_getMinMaxOpacityInRange; + self->super.getMinMaxOpacityInRange = LinearTransferFunction_getMinMaxOpacityInRange; // Transfer function colors and count. - transferFunction->colorValues = NULL; - transferFunction->colorValueCount = 0; + self->colorValues = NULL; + self->colorValueCount = 0; // Transfer function opacity values and count. - transferFunction->opacityValues = NULL; - transferFunction->opacityValueCount = 0; + self->opacityValues = NULL; + self->opacityValueCount = 0; // The default transfer function value range. - transferFunction->super.valueRange = make_vec2f(0.0f, 1.0f); + self->super.valueRange = make_vec2f(0.0f, 1.0f); // Freshly baked transfer function. - return(transferFunction); - + return self; } -export void LinearTransferFunction_destroy(void *uniform pointer) +export void LinearTransferFunction_destroy(void *uniform _self) { // Cast to the actual TransferFunction subtype. - LinearTransferFunction *uniform transferFunction = (LinearTransferFunction *uniform) pointer; + LinearTransferFunction *uniform self = (LinearTransferFunction *uniform) _self; - // Free memory for the color values. - if (transferFunction->colorValues != NULL) delete[] transferFunction->colorValues; + // // Free memory for the color values. + // if (self->colorValues != NULL) delete[] self->colorValues; - // Free memory for the opacity values. - if (transferFunction->opacityValues != NULL) delete[] transferFunction->opacityValues; + // // Free memory for the opacity values. + // if (self->opacityValues != NULL) delete[] self->opacityValues; // Container is deallocated by ~ManagedObject } -export void LinearTransferFunction_setColorValues(void *uniform pointer, +export void LinearTransferFunction_setColorValues(void *uniform _self, const uniform size_t &count, vec3f *uniform source) { // Cast to the actual TransferFunction subtype. - LinearTransferFunction *uniform transferFunction - = (LinearTransferFunction *uniform) pointer; + LinearTransferFunction *uniform self + = (LinearTransferFunction *uniform) _self; // Free memory for any existing color values. - if (transferFunction->colorValues != NULL) - delete[] transferFunction->colorValues; + if (self->colorValues != NULL) + delete[] self->colorValues; // Allocate memory for the incoming color values. - transferFunction->colorValueCount = count; - transferFunction->colorValues = uniform new uniform vec3f[count]; + self->colorValueCount = count; + self->colorValues = uniform new uniform vec3f[count]; // Copy the color values into the transfer function. for (uniform size_t i=0; i < count; i++) - transferFunction->colorValues[i] = source[i]; + self->colorValues[i] = source[i]; } -export void LinearTransferFunction_setOpacityValues(void *uniform pointer, +export void LinearTransferFunction_setOpacityValues(void *uniform _self, const uniform size_t &count, float *uniform source) { // Cast to the actual TransferFunction subtype. - LinearTransferFunction *uniform transferFunction - = (LinearTransferFunction *uniform) pointer; + LinearTransferFunction *uniform self + = (LinearTransferFunction *uniform) _self; - // Free memory for any existing opacity values. - if (transferFunction->opacityValues != NULL) - delete[] transferFunction->opacityValues; + self->opacityValues = source; + self->opacityValueCount = count; - // Allocate memory for the incoming opacity values. - transferFunction->opacityValueCount = count; - transferFunction->opacityValues = uniform new uniform float[count]; + // // Free memory for any existing opacity values. + // if (self->opacityValues != NULL) + // delete[] self->opacityValues; - // Copy the opacity values into the transfer function. - for (uniform size_t i=0; i < count; i++) - transferFunction->opacityValues[i] = source[i]; + // // Allocate memory for the incoming opacity values. + // self->opacityValueCount = count; + // self->opacityValues = uniform new uniform float[count]; + + // // Copy the opacity values into the transfer function. + // for (uniform size_t i=0; i < count; i++) + // selfy->opacityValues[i] = source[i]; // Precompute the min / max opacity ranges. - LinearTransferFunction_precomputeMinMaxOpacityRanges(pointer); + LinearTransferFunction_precomputeMinMaxOpacityRanges(_self); } - From ea268c78fb74e0a6aeeb9440eafb9eba5108d4e6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 13:53:53 -0500 Subject: [PATCH 106/310] add note about using upper-case version of OSPRAY_TASKING_SYSTEM internally --- cmake/ospray.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 8f6447b3e5..d760c15b8a 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -335,6 +335,7 @@ MACRO(CONFIGURE_TASKING_SYSTEM) STRINGS TBB ${CILK_STRING} OpenMP Internal Debug) MARK_AS_ADVANCED(OSPRAY_TASKING_SYSTEM) + # NOTE(jda) - Make the OSPRAY_TASKING_SYSTEM build option case-insensitive STRING(TOUPPER ${OSPRAY_TASKING_SYSTEM} OSPRAY_TASKING_SYSTEM_ID) SET(USE_TBB FALSE) From 2deb69f2c77decaae6deb1f009cc7daf22da3f59 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 14:24:37 -0500 Subject: [PATCH 107/310] update to the latest internal tasking system before we used TBB --- ospray/common/tasking/TaskSys.cpp | 265 ++++++++++++++++++++++++++++++ ospray/common/tasking/TaskSys.h | 125 ++++++++++++++ ospray/common/tasking/async.h | 19 ++- 3 files changed, 405 insertions(+), 4 deletions(-) create mode 100644 ospray/common/tasking/TaskSys.cpp create mode 100644 ospray/common/tasking/TaskSys.h diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp new file mode 100644 index 0000000000..d9db2e88f3 --- /dev/null +++ b/ospray/common/tasking/TaskSys.cpp @@ -0,0 +1,265 @@ +// ======================================================================== // +// Copyright 2009-2014 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#include "TaskSys.h" +//ospray +#include "common/sysinfo.h" +#include "common/thread.h" +//stl +#include +#include + +namespace ospray { + using std::cout; + using std::endl; + + struct TaskSys { + bool initialized; + bool running; + + void init(size_t maxNumRenderTasks); + static TaskSys global; + static void *threadStub(void *); + inline Task *getNextActiveTask(); + + //! queue of tasks that have ALREADY been acitvated, and that are ready to run + __aligned(64) Task *volatile activeListFirst; + __aligned(64) Task *volatile activeListLast; + + Mutex __aligned(64) mutex; + Condition __aligned(64) tasksAvailable; + + void threadFunction(); + + std::vector threads; + + TaskSys() + : activeListFirst(nullptr), activeListLast(nullptr), + initialized(false), running(false) + {} + + ~TaskSys(); + }; + + TaskSys __aligned(64) TaskSys::global; + + //! one of our depdencies tells us that he's finished + void Task::oneDependencyGotCompleted(Task *which) + { +#if TASKSYS_DEPENDENCIES + { + embree::Lock lock(mutex); + if (--numMissingDependencies == 0) { + allDependenciesFulfilledCond.broadcast(); + activate(); + } + } +#endif + } + + inline void Task::workOnIt() + { + // work on dependencies, until they are done + if (numMissingDependencies > 0) { +#if TASKSYS_DEPENDENCIES + for (size_t i=0;iworkOnIt(); + } + { + embree::Lock lock(mutex); + while (numMissingDependencies) + allDependenciesFulfilledCond.wait(mutex); + } +#endif + } + + size_t myCompleted = 0; + while (1) { + const size_t thisJobID = numJobsStarted++; + if (thisJobID >= numJobsInTask) + break; + + run(thisJobID); + ++myCompleted; + } + + if (myCompleted != 0) { + const size_t nowCompleted = (numJobsCompleted += myCompleted); //++numJobsCompleted; + if (nowCompleted == numJobsInTask) { + // Yay - I just finished the job, so I get some extra work do do ... just like in real life.... + finish(); + + { + SCOPED_LOCK(mutex); + status = Task::COMPLETED; + allJobsCompletedCond.notify_all(); + } +#if TASKSYS_DEPENDENCIES + for (int i=0;ioneDependencyGotCompleted(this); +#endif + } + } + } + + void Task::wait(bool workOnIt) + { + if (status == Task::COMPLETED) { + return; + } + + if (workOnIt) { + this->workOnIt(); + } + + std::unique_lock lock(mutex); + allJobsCompletedCond.wait(lock, [&](){return status == Task::COMPLETED;}); + } + + void Task::scheduleAndWait(size_t numJobs, ScheduleOrder order) + { + schedule(numJobs,order); + wait(); + } + + inline Task *TaskSys::getNextActiveTask() + { + while (1) { + std::unique_lock lock(mutex); + tasksAvailable.wait(lock, [&](){ + return !(activeListFirst == nullptr && running); + }); + + if (!running) { + return nullptr; + } + + Task *const front = activeListFirst; + if (front->numJobsStarted >= front->numJobsInTask) { + if (activeListFirst == activeListLast) { + activeListFirst = activeListLast = nullptr; + } else { + activeListFirst = activeListFirst->next; + } + front->refDec(); + continue; + } + front->refInc(); // becasue the thread calling us now owns it + assert(front); + return front; + } + } + + void Task::initTaskSystem(const size_t maxNumRenderTasks) + { + TaskSys::global.init(maxNumRenderTasks); + } + + void Task::schedule(size_t numJobs, ScheduleOrder order) + { + refInc(); + this->order = order; + numJobsInTask = numJobs; + status = Task::SCHEDULED; + if (numMissingDependencies == 0) + activate(); + } + + inline void Task::activate() + { + if (!TaskSys::global.initialized) + throw std::runtime_error("TASK SYSTEM NOT YET INITIALIZED"); + { + SCOPED_LOCK(TaskSys::global.mutex); + bool wasEmpty = TaskSys::global.activeListFirst == nullptr; + if (wasEmpty) { + TaskSys::global.activeListFirst = TaskSys::global.activeListLast = this; + this->next = nullptr; + TaskSys::global.tasksAvailable.notify_all(); + } else { + if (order == Task::BACK_OF_QUEUE) { + this->next = nullptr; + TaskSys::global.activeListLast->next = this; + TaskSys::global.activeListLast = this; + } else { + this->next = TaskSys::global.activeListFirst; + TaskSys::global.activeListFirst = this; + } + } + status = Task::ACTIVE; + } + } + + + void TaskSys::threadFunction() + { + while (1) { + Task *task = getNextActiveTask(); + if (!running) { + if (task) { + task->refDec(); + } + return; + } + assert(task); + task->workOnIt(); + task->refDec(); + } + } + + TaskSys::~TaskSys() + { + running = false; + tasksAvailable.notify_all(); + for (int i = 0; i < threads.size(); ++i) { + join(threads[i]); + } + } + + void *TaskSys::threadStub(void *) + { + TaskSys::global.threadFunction(); + return nullptr; + } + + void TaskSys::init(size_t numThreads) + { + if (initialized) + throw std::runtime_error("#osp: task system initialized twice!"); + initialized = true; + running = true; + + if (numThreads != 0) { +#if defined(__MIC__) + numThreads = std::min(numThreads, + (size_t)std::thread::hardware_concurrency()-4); +#else + numThreads = std::min(numThreads, + (size_t)std::thread::hardware_concurrency()); +#endif + } + + /* generate all threads */ + for (size_t t=1; t dependency; + + //! dependents: none of those can ven get active before we complete + std::vector dependent; +#endif + + // //! continuations: those become scheduled when we complete + // std::vector continuations; + + __aligned(64) Task *volatile next; + const char *name; + + /*! \brief initialize the task system with given number of worker + tasks. + + numThreads==-1 means 'use all that are available; numThreads=0 + means 'no worker thread, assume that whoever calls wait() will + do the work */ + static void initTaskSystem(const size_t numThreads); + }; + + __forceinline Task::Task(const char *name) + : status(Task::INITIALIZING), + name(name), + numJobsStarted(0), + numJobsCompleted(0), + numJobsInTask(0), + numMissingDependencies(0) + {} + +} diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index 368f80e0ae..3827465d38 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -20,6 +20,8 @@ # include #elif defined(OSPRAY_USE_CILK) # include +#elif defined(OSPRAY_USE_INTERNAL_TASKING) +# include "ospray/common/tasking/TaskSys.h" #endif namespace ospray { @@ -31,25 +33,34 @@ namespace ospray { // NOTE(jda) - No priority is associated with this call, but could be added // later with a hint enum, using a default value for the priority // to not require specifying it. -template -inline void async(const TASK& fcn) +template +inline void async(const TASK_T& fcn) { #ifdef OSPRAY_USE_TBB struct LocalTBBTask : public tbb::task { - TASK func; + TASK_T func; tbb::task* execute() override { func(); return nullptr; } - LocalTBBTask( const TASK& f ) : func(f) {} + LocalTBBTask( const TASK_T& f ) : func(f) {} }; tbb::task::enqueue(*new(tbb::task::allocate_root())LocalTBBTask(fcn)); #elif defined(OSPRAY_USE_CILK) cilk_spawn fcn(); +#elif defined(OSPRAY_USE_INTERNAL_TASKING) + struct LocalTask : public Task { + const TASK_T &t; + LocalTask(const TASK_T& fcn) : Task("LocalTask"), t(fcn) {} + void run(size_t) override { t(); } + }; + + Ref task = new LocalTask(fcn); + task->schedule(1, Task::FRONT_OF_QUEUE); #else// OpenMP or Debug --> synchronous! fcn(); #endif From baccb5413b8bb038efa824b8dd1519516600f567 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 14:29:59 -0500 Subject: [PATCH 108/310] cleanups, remove dead task dependency code --- ospray/common/tasking/TaskSys.cpp | 33 +---------------------- ospray/common/tasking/TaskSys.h | 45 +++++++++++++------------------ 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index d9db2e88f3..36b8fa9cb7 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -56,36 +56,8 @@ namespace ospray { TaskSys __aligned(64) TaskSys::global; - //! one of our depdencies tells us that he's finished - void Task::oneDependencyGotCompleted(Task *which) - { -#if TASKSYS_DEPENDENCIES - { - embree::Lock lock(mutex); - if (--numMissingDependencies == 0) { - allDependenciesFulfilledCond.broadcast(); - activate(); - } - } -#endif - } - inline void Task::workOnIt() { - // work on dependencies, until they are done - if (numMissingDependencies > 0) { -#if TASKSYS_DEPENDENCIES - for (size_t i=0;iworkOnIt(); - } - { - embree::Lock lock(mutex); - while (numMissingDependencies) - allDependenciesFulfilledCond.wait(mutex); - } -#endif - } - size_t myCompleted = 0; while (1) { const size_t thisJobID = numJobsStarted++; @@ -107,10 +79,6 @@ namespace ospray { status = Task::COMPLETED; allJobsCompletedCond.notify_all(); } -#if TASKSYS_DEPENDENCIES - for (int i=0;ioneDependencyGotCompleted(this); -#endif } } } @@ -262,4 +230,5 @@ namespace ospray { setAffinity(0); #endif } + } diff --git a/ospray/common/tasking/TaskSys.h b/ospray/common/tasking/TaskSys.h index 7b20f7f489..2d8003f4d0 100644 --- a/ospray/common/tasking/TaskSys.h +++ b/ospray/common/tasking/TaskSys.h @@ -20,8 +20,6 @@ namespace ospray { -#define TASKSYS_DEPENDENCIES 0 - struct __aligned(64) Task : public RefCount { // typedef enum { FRONT, BACK } ScheduleOrder; @@ -30,19 +28,15 @@ namespace ospray { // ------------------------------------------------------------------ Task(const char *name = "no name"); virtual void run(size_t jobID) = 0; - virtual void finish() {} - virtual ~Task() {} + virtual void finish(); + virtual ~Task(); // ------------------------------------------------------------------ // interface for scheduling a new task into the task system // ------------------------------------------------------------------ - //! add a new dependecy: task cannot become active until this depdency has completed + //! add a new dependecy: task cannot become active until this depdency has + //! completed void addDependency(Task *dependency); - // //! add a new continuation: continuation automatically becomes - // //! active when current task completes. this means the - // //! continuation depends on the current task, BUT it might get - // //! active way before other tasks in the task queue - // void addContinuation(Task *continuation); typedef enum { /*! schedule job to the END of the job queue, meaning it'll get @@ -54,7 +48,8 @@ namespace ospray { FRONT_OF_QUEUE } ScheduleOrder; - /*! the order in the queue that this job will get scheduled when activated */ + /*! the order in the queue that this job will get scheduled when + * activated */ ScheduleOrder order; //! schedule the given task with the given number of @@ -71,9 +66,6 @@ namespace ospray { //*! work on task until no more useful job available on this task void workOnIt(); - //! one of our depdencies tells us that he's finished - void oneDependencyGotCompleted(Task *which); - //! activate job, and insert into the task system. should never be //! called by the user, only by the task(system) whenever the task //! is a) scheduled and b) all dependencies are fulfilled @@ -90,17 +82,6 @@ namespace ospray { Condition __aligned(64) allDependenciesFulfilledCond; Condition __aligned(64) allJobsCompletedCond; -#if TASKSYS_DEPENDENCIES - //! depdencies: WE cannot become active until those are fulfilled - std::vector dependency; - - //! dependents: none of those can ven get active before we complete - std::vector dependent; -#endif - - // //! continuations: those become scheduled when we complete - // std::vector continuations; - __aligned(64) Task *volatile next; const char *name; @@ -113,6 +94,8 @@ namespace ospray { static void initTaskSystem(const size_t numThreads); }; +// Inlined function definitions /////////////////////////////////////////////// + __forceinline Task::Task(const char *name) : status(Task::INITIALIZING), name(name), @@ -120,6 +103,14 @@ namespace ospray { numJobsCompleted(0), numJobsInTask(0), numMissingDependencies(0) - {} + { + } + + __forceinline Task::~Task() + { + } -} + __forceinline void Task::finish() + { + } +}//namespace ospray From 2084f288d4ce46ee65344ac06318119e6d0abe5f Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 14:42:51 -0500 Subject: [PATCH 109/310] allow tasking system to be initialized twice, output warning when it is --- ospray/common/OSPCommon.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 855a972b59..21401ed5dd 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -123,7 +123,11 @@ namespace ospray { } #ifdef OSPRAY_USE_INTERNAL_TASKING - ospray::Task::initTaskSystem(debugMode ? 0 : numThreads); + try { + ospray::Task::initTaskSystem(debugMode ? 0 : numThreads); + } catch (const std::runtime_error &e) { + std::cerr << "WARNING: " << e.what() << std::endl; + } #endif } From 4570475fc27afde619479a59cb1c865b117bcba2 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 15 Mar 2016 20:20:15 -0500 Subject: [PATCH 110/310] fix destructor race in ospray::async() when using internal tasking system --- ospray/common/tasking/async.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index 3827465d38..acbf34ebca 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -54,8 +54,8 @@ inline void async(const TASK_T& fcn) cilk_spawn fcn(); #elif defined(OSPRAY_USE_INTERNAL_TASKING) struct LocalTask : public Task { - const TASK_T &t; - LocalTask(const TASK_T& fcn) : Task("LocalTask"), t(fcn) {} + TASK_T t; + LocalTask(const TASK_T& fcn) : Task("LocalTask"), t(std::move(fcn)) {} void run(size_t) override { t(); } }; From 97e16a6c7d1669ae502f485be4ae8758f9f083d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 15 Mar 2016 21:07:04 +0100 Subject: [PATCH 111/310] Fix for Windows and cleanup library implementation --- common/common.cpp | 11 +++ common/common.h | 7 +- common/library.cpp | 157 +++++++++++++++----------------------- common/library.h | 40 +++++++--- ospray/common/Library.cpp | 76 ------------------ ospray/common/Library.h | 14 +--- 6 files changed, 107 insertions(+), 198 deletions(-) delete mode 100644 ospray/common/Library.cpp diff --git a/common/common.cpp b/common/common.cpp index f584e3793b..55ed80e703 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -16,6 +16,7 @@ #include "common.h" #include "sysinfo.h" +#include "library.h" // std #include @@ -60,5 +61,15 @@ namespace ospcommon { abort(); } + void loadLibrary(const std::string& name) + { + LibraryRepository::getInstance()->add(name); + } + + void *getSymbol(const std::string& name) + { + return LibraryRepository::getInstance()->getSymbol(name); + } + } // ::ospcommon diff --git a/common/common.h b/common/common.h index c2b35d5a49..981a41a318 100644 --- a/common/common.h +++ b/common/common.h @@ -23,11 +23,8 @@ #include #ifdef _WIN32 - typedef unsigned long long id_t; -#endif - -#if defined(__WIN32__) || defined(_WIN32) // ----------- windows only ----------- +typedef unsigned long long id_t; # define _USE_MATH_DEFINES 1 # include # include @@ -78,7 +75,7 @@ namespace ospcommon { OSPCOMMON_INTERFACE void doAssertion(const char *file, int line, const char *expr, const char *expl); /*! remove specified num arguments from an ac/av arglist */ OSPCOMMON_INTERFACE void removeArgs(int &ac, char **&av, int where, int howMany); - OSPCOMMON_INTERFACE void loadLibrary(const std::string &_name); + OSPCOMMON_INTERFACE void loadLibrary(const std::string &name); OSPCOMMON_INTERFACE void *getSymbol(const std::string &name); } // ::ospcommon diff --git a/common/library.cpp b/common/library.cpp index fea93937f4..6fa26bd899 100644 --- a/common/library.cpp +++ b/common/library.cpp @@ -19,137 +19,102 @@ #include "sysinfo.h" // std -#include #ifdef _WIN32 # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include // for GetSystemTime +# include #else -# include # include # include #endif -// std -#include namespace ospcommon { - /*! type for shared library */ - typedef struct opaque_lib_t* lib_t; - - struct Library + Library::Library(const std::string& name) { - std::string name; - lib_t lib; - }; - -#if defined(__WIN32__) - /* returns address of a symbol from the library */ - void* getSymbol(lib_t lib, const std::string& sym) { - return GetProcAddress(HMODULE(lib),sym.c_str()); - } +#ifdef OSPRAY_TARGET_MIC + std::string file = name+"_mic"; #else - /* returns address of a symbol from the library */ - void* getSymbol(lib_t lib, const std::string& sym) { - return dlsym(lib,sym.c_str()); - } + std::string file = name; #endif - - - std::vector loadedLibs; - - - -#if defined(__WIN32__) - /* opens a shared library */ - lib_t openLibrary(const std::string& file) - { +#ifdef _WIN32 std::string fullName = file+".dll"; FileName executable = getExecutableFileName(); - HANDLE handle = LoadLibrary((executable.path() + fullName).c_str()); - return lib_t(handle); - } + lib = LoadLibrary((executable.path() + fullName).c_str()); #else - /* opens a shared library */ - lib_t openLibrary(const std::string& file) - { #if defined(__MACOSX__) std::string fullName = "lib"+file+".dylib"; #else std::string fullName = "lib"+file+".so"; #endif - void* lib = dlopen(fullName.c_str(), RTLD_NOW); - if (lib) return lib_t(lib); - FileName executable = getExecutableFileName(); - lib = dlopen((executable.path() + fullName).c_str(),RTLD_NOW); - if (lib == NULL) throw std::runtime_error(dlerror()); - return lib_t(lib); - } + lib = dlopen(fullName.c_str(), RTLD_NOW); + if (!lib) { + FileName executable = getExecutableFileName(); + lib = dlopen((executable.path() + fullName).c_str(), RTLD_NOW); + } #endif - void loadLibrary(const std::string &_name) + if (lib == NULL) + throw std::runtime_error("could not open module lib "+name); + } + + Library::Library(void* const lib) : lib(lib) {}; + + void* Library::getSymbol(const std::string& sym) const { -#ifdef OSPRAY_TARGET_MIC - std::string name = _name+"_mic"; +#ifdef _WIN32 + return GetProcAddress((HMODULE)lib, sym.c_str()); #else - std::string name = _name; + return dlsym(lib, sym.c_str()); #endif + } - for (int i=0;iname == name) - // lib already loaded. - return; - Library *lib = new Library; - lib->name = name; - lib->lib = openLibrary(name); - if (lib->lib == NULL) - throw std::runtime_error("could not open module lib "+name); - - loadedLibs.push_back(lib); + LibraryRepository* LibraryRepository::instance = NULL; + + LibraryRepository* LibraryRepository::getInstance() + { + if (instance == NULL) + instance = new LibraryRepository; + + return instance; } - void *getSymbol(const std::string &name) + + void LibraryRepository::add(const std::string& name) { - for (int i=0;ilib, name); - if (sym) return sym; - } + if (repo.find(name) != repo.end()) + return; // lib already loaded. + + repo[name] = new Library(name); + } + + void* LibraryRepository::getSymbol(const std::string& name) const + { + void *sym = NULL; + for (auto lib = repo.cbegin(); sym == NULL && lib != repo.end(); ++lib) + sym = lib->second->getSymbol(name); - // if none found in the loaded libs, try the default lib ... + return sym; + } + + LibraryRepository::LibraryRepository() + { + // already populate the repo with "virtual" libs, representing the default OSPRay core lib #ifdef _WIN32 - void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) - if (!sym) { - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function - sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) - } + // look in exe (i.e. when linked statically) + repo["exedefault"] = new Library(GetModuleHandle(0)); + + // get handle to current dll via a known function + const void * functionInOSPRayDLL = ospcommon::getSymbol; + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery(functionInOSPRayDLL, &mbi, sizeof(mbi)); + + // look in ospray.dll (i.e. when linked dynamically) + repo["dlldefault"] = new Library(mbi.AllocationBase); #else - void *sym = dlsym(RTLD_DEFAULT,name.c_str()); + repo["default"] = new Library(RTLD_DEFAULT); #endif - return sym; } - -// void *getSymbol(const std::string &name) -// { -// // for (int i=0;ilib, name); -// // if (sym) return sym; -// // } - -// // if none found in the loaded libs, try the default lib ... -// #ifdef _WIN32 -// void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) -// if (!sym) { -// MEMORY_BASIC_INFORMATION mbi; -// VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function -// sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) -// } -// #else -// void *sym = dlsym(RTLD_DEFAULT,name.c_str()); -// #endif -// return sym; -// } } - diff --git a/common/library.h b/common/library.h index f88e421809..c76b017701 100644 --- a/common/library.h +++ b/common/library.h @@ -15,20 +15,42 @@ // ======================================================================== // #include "common.h" +// std +#include +#include namespace ospcommon { - /*! type for shared library */ - typedef struct opaque_lib_t* lib_t; - - /*! loads a shared library */ - lib_t openLibrary(const std::string& file); + class Library + { + public: + /* opens a shared library */ + Library(const std::string& name); - /*! returns address of a symbol from the library */ - void* getSymbol(lib_t lib, const std::string& sym); + /* returns address of a symbol from the library */ + void* getSymbol(const std::string& sym) const; - /*! unloads a shared library */ - void closeLibrary(lib_t lib); + private: + Library(void* const lib); + void *lib; + friend class LibraryRepository; + }; + class LibraryRepository + { + public: + static LibraryRepository* getInstance(); + + /* add a library to the repo */ + void add(const std::string& name); + + /* returns address of a symbol from any library in the repo */ + void* getSymbol(const std::string& sym) const; + + private: + static LibraryRepository* instance; + LibraryRepository(); + std::map repo; + }; } diff --git a/ospray/common/Library.cpp b/ospray/common/Library.cpp deleted file mode 100644 index c84799274f..0000000000 --- a/ospray/common/Library.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -// ospray -#include "Library.h" -// ospcommmon -#include "common/library.h" -// std - -#ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# include -#else -# include -#endif - -namespace ospray { - - std::vector loadedLibs; - - void loadLibrary(const std::string &_name) - { -#ifdef OSPRAY_TARGET_MIC - std::string name = _name+"_mic"; -#else - std::string name = _name; -#endif - - for (int i=0;iname == name) - // lib already loaded. - return; - - Library *lib = new Library; - lib->name = name; - lib->lib = ospcommon::openLibrary(name); - if (lib->lib == NULL) - throw std::runtime_error("could not open module lib "+name); - - loadedLibs.push_back(lib); - } - void *getSymbol(const std::string &name) - { - for (int i=0;ilib, name); - if (sym) return sym; - } - - // if none found in the loaded libs, try the default lib ... -#ifdef _WIN32 - void *sym = GetProcAddress(GetModuleHandle(0), name.c_str()); // look in exe (i.e. when linked statically) - if (!sym) { - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery(getSymbol, &mbi, sizeof(mbi)); // get handle to current dll via a known function - sym = GetProcAddress((HINSTANCE)(mbi.AllocationBase), name.c_str()); // look in ospray.dll (i.e. when linked dynamically) - } -#else - void *sym = dlsym(RTLD_DEFAULT,name.c_str()); -#endif - return sym; - } - -} // ::ospray diff --git a/ospray/common/Library.h b/ospray/common/Library.h index 77bcb89c8c..4a383ce790 100644 --- a/ospray/common/Library.h +++ b/ospray/common/Library.h @@ -16,19 +16,9 @@ #pragma once -//ospray stuff -#include "Managed.h" - -//embree stuff #include "common/library.h" namespace ospray { - struct Library - { - std::string name; - ospcommon::lib_t lib; - }; - - void loadLibrary(const std::string &name); - void *getSymbol(const std::string &name); + using ospcommon::getSymbol; + using ospcommon::loadLibrary; } From 1d376b5c802bf29f352c5712754d6da545bdefb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 08:06:32 +0100 Subject: [PATCH 112/310] logLevel from commandline has preference over OSPRAY_LOG_LEVEL --- ospray/api/LocalDevice.cpp | 4 +--- ospray/mpi/MPIDevice.cpp | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index 2f185f2555..aa6cc7aa63 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -44,10 +44,8 @@ namespace ospray { LocalDevice::LocalDevice(int *_ac, const char **_av) { char *logLevelFromEnv = getenv("OSPRAY_LOG_LEVEL"); - if (logLevelFromEnv) + if (logLevelFromEnv && logLevel == 0) logLevel = atoi(logLevelFromEnv); - else - logLevel = 0; // ------------------------------------------------------- // initialize embree. (we need to do this here rather than in diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index 5790022826..d8445d84b6 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -332,10 +332,8 @@ namespace ospray { : currentApiMode(OSPD_MODE_MASTERED) { char *logLevelFromEnv = getenv("OSPRAY_LOG_LEVEL"); - if (logLevelFromEnv) + if (logLevelFromEnv && logLevel == 0) logLevel = atoi(logLevelFromEnv); - else - logLevel = 0; ospray::init(_ac,&_av); From 54e5728bcaca377647a1474236ecca34b4548565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 08:10:02 +0100 Subject: [PATCH 113/310] VERSIONs defined in version.h --- ospray/common/ospray.rc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ospray/common/ospray.rc b/ospray/common/ospray.rc index 8354fcb5aa..a764e0531f 100644 --- a/ospray/common/ospray.rc +++ b/ospray/common/ospray.rc @@ -1,10 +1,5 @@ #include "ospray/version.h" -#define OSPRAY_VERSION_MAJOR 0 -#define OSPRAY_VERSION_MINOR 9 -#define OSPRAY_VERSION_PATCH 1 -#define OSPRAY_VERSION "0.9.1" - 1 VERSIONINFO FILEVERSION OSPRAY_VERSION_MAJOR,OSPRAY_VERSION_MINOR,0 PRODUCTVERSION OSPRAY_VERSION_MAJOR,OSPRAY_VERSION_MINOR,0 From f7002b1c566162cbcf7936f8d397075b9d962c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 08:12:19 +0100 Subject: [PATCH 114/310] More fixes for Windows --- common/FileName.cpp | 4 ++-- common/FileName.h | 44 +++++++++++++++++++-------------------- common/RefCount.h | 7 ++++--- common/common.h | 6 ++++-- common/constants.h | 6 ++++-- common/intrinsics.h | 6 +++--- common/malloc.h | 6 +++--- common/math.h | 6 +++--- common/network.cpp | 4 ++-- common/platform.h | 8 ------- common/sysinfo.cpp | 4 ++-- common/sysinfo.h | 26 +++++++++++------------ common/thread.cpp | 2 +- common/thread.h | 14 ++++++------- common/vec.h | 7 ++++--- ospray/CMakeLists.txt | 3 +-- ospray/common/OSPCommon.h | 9 ++++---- ospray/mpi/MPICommon.h | 4 ++++ 18 files changed, 83 insertions(+), 83 deletions(-) diff --git a/common/FileName.cpp b/common/FileName.cpp index 65b0e11dc1..16f6d5003f 100644 --- a/common/FileName.cpp +++ b/common/FileName.cpp @@ -19,7 +19,7 @@ namespace ospcommon { -#ifdef __WIN32__ +#ifdef _WIN32 const char path_sep = '\\'; #else const char path_sep = '/'; @@ -51,7 +51,7 @@ namespace ospcommon /*! returns path to home folder */ FileName FileName::homeFolder() { -#ifdef __WIN32__ +#ifdef _WIN32 const char* home = getenv("UserProfile"); #else const char* home = getenv("HOME"); diff --git a/common/FileName.h b/common/FileName.h index 48fec3a929..afebde69a5 100644 --- a/common/FileName.h +++ b/common/FileName.h @@ -16,7 +16,7 @@ #pragma once -#include "./platform.h" +#include "common.h" namespace ospcommon { @@ -26,67 +26,67 @@ namespace ospcommon public: /*! create an empty filename */ - FileName (); + OSPCOMMON_INTERFACE FileName(); /*! create a valid filename from a string */ - FileName (const char* filename); + OSPCOMMON_INTERFACE FileName(const char* filename); /*! create a valid filename from a string */ - FileName (const std::string& filename); + OSPCOMMON_INTERFACE FileName(const std::string& filename); /*! returns path to home folder */ - static FileName homeFolder(); + OSPCOMMON_INTERFACE static FileName homeFolder(); /*! returns path to executable */ - static FileName executableFolder(); + OSPCOMMON_INTERFACE static FileName executableFolder(); /*! auto convert into a string */ - operator std::string() const { return filename; } + OSPCOMMON_INTERFACE operator std::string() const { return filename; } /*! returns a string of the filename */ - const std::string str() const { return filename; } + OSPCOMMON_INTERFACE const std::string str() const { return filename; } /*! returns a c-string of the filename */ - const char* c_str() const { return filename.c_str(); } + OSPCOMMON_INTERFACE const char* c_str() const { return filename.c_str(); } /*! returns the path of a filename */ - FileName path() const; + OSPCOMMON_INTERFACE FileName path() const; /*! returns the file of a filename */ - std::string base() const; + OSPCOMMON_INTERFACE std::string base() const; /*! returns the base of a filename without extension */ - std::string name() const; + OSPCOMMON_INTERFACE std::string name() const; /*! returns the file extension */ - std::string ext() const; + OSPCOMMON_INTERFACE std::string ext() const; /*! drops the file extension */ - FileName dropExt() const; + OSPCOMMON_INTERFACE FileName dropExt() const; /*! replaces the file extension */ - FileName setExt(const std::string& ext = "") const; + OSPCOMMON_INTERFACE FileName setExt(const std::string& ext = "") const; /*! adds file extension */ - FileName addExt(const std::string& ext = "") const; + OSPCOMMON_INTERFACE FileName addExt(const std::string& ext = "") const; /*! concatenates two filenames to this/other */ - FileName operator +( const FileName& other ) const; + OSPCOMMON_INTERFACE FileName operator+( const FileName& other ) const; /*! concatenates two filenames to this/other */ - FileName operator +( const std::string& other ) const; + OSPCOMMON_INTERFACE FileName operator+( const std::string& other ) const; /*! removes the base from a filename (if possible) */ - FileName operator -( const FileName& base ) const; + OSPCOMMON_INTERFACE FileName operator-( const FileName& base ) const; /*! == operator */ - friend bool operator==(const FileName& a, const FileName& b); + OSPCOMMON_INTERFACE friend bool operator==(const FileName& a, const FileName& b); /*! != operator */ - friend bool operator!=(const FileName& a, const FileName& b); + OSPCOMMON_INTERFACE friend bool operator!=(const FileName& a, const FileName& b); /*! output operator */ - friend std::ostream& operator<<(std::ostream& cout, const FileName& filename); + OSPCOMMON_INTERFACE friend std::ostream& operator<<(std::ostream& cout, const FileName& filename); private: std::string filename; diff --git a/common/RefCount.h b/common/RefCount.h index 2078f4dc8f..e446879688 100644 --- a/common/RefCount.h +++ b/common/RefCount.h @@ -24,10 +24,11 @@ namespace ospcommon { #if defined(__X86_64__) || defined(__MIC__) - typedef std::atomic_llong atomic_t; + typedef long long atomic_init_t; #else - typedef std::atomic_int atomic_t; + typedef int atomic_init_t; #endif + typedef std::atomic atomic_t; static struct NullTy { } null MAYBE_UNUSED; @@ -35,7 +36,7 @@ namespace ospcommon class RefCount { public: - inline RefCount(int val = 0) : refCounter(val) {} + inline RefCount(atomic_init_t val = 0) : refCounter(val) {} virtual ~RefCount() {}; /*! dummy copy-constructor and assignment operator because if they diff --git a/common/common.h b/common/common.h index 981a41a318..aa460b158b 100644 --- a/common/common.h +++ b/common/common.h @@ -25,7 +25,9 @@ #ifdef _WIN32 // ----------- windows only ----------- typedef unsigned long long id_t; -# define _USE_MATH_DEFINES 1 +# ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES +# endif # include # include # ifdef _M_X64 @@ -41,7 +43,7 @@ typedef int ssize_t; #include #ifdef _WIN32 -# ifdef ospcommon_EXPORTS +# ifdef ospray_common_EXPORTS # define OSPCOMMON_INTERFACE __declspec(dllexport) # else # define OSPCOMMON_INTERFACE __declspec(dllimport) diff --git a/common/constants.h b/common/constants.h index 7125844a70..f77d53db81 100644 --- a/common/constants.h +++ b/common/constants.h @@ -16,10 +16,12 @@ #pragma once -#include "./platform.h" +#include "platform.h" #include -#define _USE_MATH_DEFINES +#ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES +#endif #include // using cmath causes issues under Windows #include diff --git a/common/intrinsics.h b/common/intrinsics.h index 18bb6f7790..1ced7ac03d 100644 --- a/common/intrinsics.h +++ b/common/intrinsics.h @@ -18,7 +18,7 @@ #include "platform.h" -#if defined(__WIN32__) +#ifdef _WIN32 #include #endif @@ -72,7 +72,7 @@ # include #endif -#if defined(__WIN32__) +#ifdef _WIN32 # define NOMINMAX # include #endif @@ -92,7 +92,7 @@ namespace ospcommon /// Windows Platform //////////////////////////////////////////////////////////////////////////////// -#if defined(__WIN32__) +#ifdef _WIN32 __forceinline size_t read_tsc() { diff --git a/common/malloc.h b/common/malloc.h index dc566d8924..55c50d8aa0 100644 --- a/common/malloc.h +++ b/common/malloc.h @@ -16,7 +16,7 @@ #pragma once -#include "platform.h" +#include "common.h" namespace ospcommon { @@ -47,8 +47,8 @@ namespace ospcommon // private: /*! aligned allocation */ - void* alignedMalloc(size_t size, size_t align = 64); - void alignedFree(void* ptr); + OSPCOMMON_INTERFACE void* alignedMalloc(size_t size, size_t align = 64); + OSPCOMMON_INTERFACE void alignedFree(void* ptr); // /*! alloca that returns aligned data */ // template diff --git a/common/math.h b/common/math.h index 516e379223..291d963232 100644 --- a/common/math.h +++ b/common/math.h @@ -20,7 +20,7 @@ #include "constants.h" #include -#if defined(__WIN32__) +#ifdef _WIN32 #include #if (__MSV_VER <= 1700) namespace std @@ -48,7 +48,7 @@ namespace ospcommon union { float f; int i; } v; v.i = i; return v.f; } -#if defined(__WIN32__) +#ifdef _WIN32 __forceinline bool finite ( const float x ) { return _finite(x) != 0; } #endif @@ -91,7 +91,7 @@ namespace ospcommon __forceinline float rsqrt( const float x ) { return 1.0f/sqrtf(x); } #endif -#if !defined(__WIN32__) +#ifndef _WIN32 __forceinline float abs ( const float x ) { return ::fabsf(x); } __forceinline float acos ( const float x ) { return ::acosf (x); } __forceinline float asin ( const float x ) { return ::asinf (x); } diff --git a/common/network.cpp b/common/network.cpp index ef25c16a1d..3b819e9c45 100644 --- a/common/network.cpp +++ b/common/network.cpp @@ -22,7 +22,7 @@ /// Platforms supporting Socket interface //////////////////////////////////////////////////////////////////////////////// -#if defined(__WIN32__) +#ifdef _WIN32 #define _WINSOCK_DEPRECATED_NO_WARNINGS //#include //#include @@ -53,7 +53,7 @@ namespace ospcommon namespace network { __forceinline void initialize() { -#ifdef __WIN32__ +#ifdef _WIN32 static bool initialized = false; static MutexSys initMutex; Lock lock(initMutex); diff --git a/common/platform.h b/common/platform.h index 37916d72e4..8c328c5a73 100644 --- a/common/platform.h +++ b/common/platform.h @@ -169,14 +169,6 @@ /// Makros //////////////////////////////////////////////////////////////////////////////// -#ifdef __WIN32__ -#define __dllexport __declspec(dllexport) -#define __dllimport __declspec(dllimport) -#else -#define __dllexport __attribute__ ((visibility ("default"))) -#define __dllimport -#endif - #ifdef __WIN32__ #undef __noinline #define __noinline __declspec(noinline) diff --git a/common/sysinfo.cpp b/common/sysinfo.cpp index 0d54268c59..44a23029d4 100644 --- a/common/sysinfo.cpp +++ b/common/sysinfo.cpp @@ -186,7 +186,7 @@ namespace ospcommon __noinline int64_t get_xcr0() { -#if defined (__WIN32__) +#ifdef _WIN32 int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 #if defined(__INTEL_COMPILER) xcr0 = _xgetbv(0); @@ -342,7 +342,7 @@ namespace ospcommon /// Windows Platform //////////////////////////////////////////////////////////////////////////////// -#ifdef __WIN32__ +#ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include diff --git a/common/sysinfo.h b/common/sysinfo.h index 9d9859fc82..81c685fae4 100644 --- a/common/sysinfo.h +++ b/common/sysinfo.h @@ -25,7 +25,7 @@ #define MAX_THREADS 512 #define MAX_MIC_CORES (MAX_THREADS/4) -#include "platform.h" +#include "common.h" /* define isa namespace and ISA bitvector */ #if defined(__MIC__) @@ -100,22 +100,22 @@ namespace ospcommon }; /*! get the full path to the running executable */ - std::string getExecutableFileName(); + OSPCOMMON_INTERFACE std::string getExecutableFileName(); /*! return platform name */ - std::string getPlatformName(); + OSPCOMMON_INTERFACE std::string getPlatformName(); /*! get the full name of the compiler */ - std::string getCompilerName(); + OSPCOMMON_INTERFACE std::string getCompilerName(); /*! return the name of the CPU */ - std::string getCPUVendor(); + OSPCOMMON_INTERFACE std::string getCPUVendor(); /*! get microprocessor model */ - CPUModel getCPUModel(); + OSPCOMMON_INTERFACE CPUModel getCPUModel(); /*! converts CPU model into string */ - std::string stringOfCPUModel(CPUModel model); + OSPCOMMON_INTERFACE std::string stringOfCPUModel(CPUModel model); /*! CPU features */ static const int CPU_FEATURE_SSE = 1 << 0; @@ -145,10 +145,10 @@ namespace ospcommon static const int CPU_FEATURE_AVX512VBMI = 1 << 24; /*! get CPU features */ - int getCPUFeatures(); + OSPCOMMON_INTERFACE int getCPUFeatures(); /*! convert CPU features into a string */ - std::string stringOfCPUFeatures(int features); + OSPCOMMON_INTERFACE std::string stringOfCPUFeatures(int features); /*! ISAs */ static const int SSE = CPU_FEATURE_SSE; @@ -165,14 +165,14 @@ namespace ospcommon static const int AVX512KNL = AVX512F | CPU_FEATURE_AVX512PF | CPU_FEATURE_AVX512ER | CPU_FEATURE_AVX512CD; /*! converts ISA bitvector into a string */ - std::string stringOfISA(int features); + OSPCOMMON_INTERFACE std::string stringOfISA(int features); /*! return the number of logical threads of the system */ - size_t getNumberOfLogicalThreads(); + OSPCOMMON_INTERFACE size_t getNumberOfLogicalThreads(); /*! returns the size of the terminal window in characters */ - int getTerminalWidth(); + OSPCOMMON_INTERFACE int getTerminalWidth(); /*! returns performance counter in seconds */ - double getSeconds(); + OSPCOMMON_INTERFACE double getSeconds(); } diff --git a/common/thread.cpp b/common/thread.cpp index 00782be82a..13a57a4bb8 100644 --- a/common/thread.cpp +++ b/common/thread.cpp @@ -28,7 +28,7 @@ /// Windows Platform //////////////////////////////////////////////////////////////////////////////// -#if defined(__WIN32__) +#ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include diff --git a/common/thread.h b/common/thread.h index d4e1016d9f..2b81271118 100644 --- a/common/thread.h +++ b/common/thread.h @@ -16,7 +16,7 @@ #pragma once -#include "platform.h" +#include "common.h" namespace ospcommon { @@ -27,20 +27,20 @@ namespace ospcommon typedef void (*thread_func)(void*); /*! creates a hardware thread running on specific logical thread */ - thread_t createThread(thread_func f, void* arg, - size_t stack_size = 0, ssize_t threadID = -1); + OSPCOMMON_INTERFACE thread_t createThread(thread_func f, void* arg, size_t + stack_size = 0, ssize_t threadID = -1); /*! set affinity of the calling thread */ - void setAffinity(ssize_t affinity); + OSPCOMMON_INTERFACE void setAffinity(ssize_t affinity); /*! the thread calling this function gets yielded */ - void yield(); + OSPCOMMON_INTERFACE void yield(); /*! waits until the given thread has terminated */ - void join(thread_t tid); + OSPCOMMON_INTERFACE void join(thread_t tid); /*! destroy handle of a thread */ - void destroyThread(thread_t tid); + OSPCOMMON_INTERFACE void destroyThread(thread_t tid); // /*! type for handle to thread local storage */ // typedef struct opaque_tls_t* tls_t; diff --git a/common/vec.h b/common/vec.h index 81a3784273..933d6b6253 100644 --- a/common/vec.h +++ b/common/vec.h @@ -16,9 +16,10 @@ #pragma once -#include "../common/common.h" -#include "./constants.h" -#include "./math.h" +#include "common.h" +#include "constants.h" +#include "math.h" +#include namespace ospcommon { diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 7804401659..1c8a5da3c9 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -102,7 +102,6 @@ SET(OSPRAY_SOURCES common/Model.ispc common/Model.cpp common/Material.cpp - common/Library.cpp common/Thread.cpp common/tasking/parallel_for.h @@ -339,7 +338,7 @@ OSPRAY_INSTALL_LIBRARY(ospray) IF(NOT THIS_IS_MIC) # build ospTutorial, for testing ADD_EXECUTABLE(ospTutorial ../apps/ospTutorial) - TARGET_LINK_LIBRARIES(ospTutorial ospray ospray_common) + OSPRAY_EXE_LINK_LIBRARIES(ospTutorial ospray ospray_common) ENDIF() diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index 92b4e57282..2b4063ec91 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -23,12 +23,11 @@ #include "OSPConfig.h" #ifdef _WIN32 - typedef unsigned long long id_t; -#endif - -#if defined(__WIN32__) || defined(_WIN32) // ----------- windows only ----------- -# define _USE_MATH_DEFINES 1 +typedef unsigned long long id_t; +# ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES +# endif # include # include # ifdef _M_X64 diff --git a/ospray/mpi/MPICommon.h b/ospray/mpi/MPICommon.h index 840e55edcb..69449cdef4 100644 --- a/ospray/mpi/MPICommon.h +++ b/ospray/mpi/MPICommon.h @@ -19,6 +19,10 @@ #include #include "ospray/common/OSPCommon.h" +// IMPI on Windows defines MPI_CALL already, erroneously +#ifdef MPI_CALL +# undef MPI_CALL +#endif /*! helper macro that checks the return value of all MPI_xxx(...) calls via MPI_CALL(xxx(...)). */ #define MPI_CALL(a) { int rc = MPI_##a; if (rc != MPI_SUCCESS) throw std::runtime_error("MPI call returned error"); } From 0f747911e2f8ba3421bafd1b564d00aa4cae84ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 10:03:43 +0100 Subject: [PATCH 115/310] ospray_common now finds symbols also in ospray.dll --- common/CMakeLists.txt | 5 ----- common/library.cpp | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 078cd53f2d..175065e8bf 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -17,7 +17,6 @@ CONFIGURE_OSPRAY() OSPRAY_ADD_LIBRARY(ospray_common SHARED -# STATIC common.cpp FileName.cpp sysinfo.cpp @@ -38,7 +37,3 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED RefCount.h vec.h ) - - - - diff --git a/common/library.cpp b/common/library.cpp index 6fa26bd899..1359b1c3c0 100644 --- a/common/library.cpp +++ b/common/library.cpp @@ -103,18 +103,25 @@ namespace ospcommon { { // already populate the repo with "virtual" libs, representing the default OSPRay core lib #ifdef _WIN32 - // look in exe (i.e. when linked statically) + // look in exe (i.e. when OSPRay is linked statically into the application) repo["exedefault"] = new Library(GetModuleHandle(0)); - // get handle to current dll via a known function + // look in ospray.dll (i.e. when linked dynamically) +#if 0 + // we cannot get a function from ospray.dll, because this would create a + // cyclic dependency between ospray.dll and ospray_common.dll + + // only works when ospray_common is liked statically into ospray const void * functionInOSPRayDLL = ospcommon::getSymbol; + // get handle to current dll via a known function MEMORY_BASIC_INFORMATION mbi; VirtualQuery(functionInOSPRayDLL, &mbi, sizeof(mbi)); - - // look in ospray.dll (i.e. when linked dynamically) repo["dlldefault"] = new Library(mbi.AllocationBase); #else - repo["default"] = new Library(RTLD_DEFAULT); + repo["ospray"] = new Library(std::string("ospray")); +#endif +#else + repo["ospray"] = new Library(RTLD_DEFAULT); #endif } } From 58a74276fdee62fda0dd246c38b2aa46b37f1bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 16:52:10 +0100 Subject: [PATCH 116/310] Fix compile issues on Windows (atomic_t is default initialized to zero) --- ospray/common/tasking/TaskSys.cpp | 2 +- ospray/common/tasking/TaskSys.h | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index 36b8fa9cb7..91f3fe6105 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -1,5 +1,5 @@ // ======================================================================== // -// Copyright 2009-2014 Intel Corporation // +// Copyright 2009-2016 Intel Corporation // // // // Licensed under the Apache License, Version 2.0 (the "License"); // // you may not use this file except in compliance with the License. // diff --git a/ospray/common/tasking/TaskSys.h b/ospray/common/tasking/TaskSys.h index 2d8003f4d0..aa15a608a1 100644 --- a/ospray/common/tasking/TaskSys.h +++ b/ospray/common/tasking/TaskSys.h @@ -1,5 +1,5 @@ // ======================================================================== // -// Copyright 2009-2014 Intel Corporation // +// Copyright 2009-2016 Intel Corporation // // // // Licensed under the Apache License, Version 2.0 (the "License"); // // you may not use this file except in compliance with the License. // @@ -99,10 +99,7 @@ namespace ospray { __forceinline Task::Task(const char *name) : status(Task::INITIALIZING), name(name), - numJobsStarted(0), - numJobsCompleted(0), - numJobsInTask(0), - numMissingDependencies(0) + numJobsInTask(0) { } From e9f025280dbe3a42046287e13483207dc9f31e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 17:38:57 +0100 Subject: [PATCH 117/310] Tweaks for MACOSX_RPATH --- cmake/package.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/package.cmake b/cmake/package.cmake index eea4e12d34..1069a18c10 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -16,13 +16,12 @@ INCLUDE(GNUInstallDirs) -SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}) - IF (OSPRAY_ZIP_MODE) # in tgz / zip let's have relative RPath SET(CMAKE_SKIP_INSTALL_RPATH OFF) IF (APPLE) - SET(CMAKE_INSTALL_RPATH "@executable_path/:@executable_path/../lib") + SET(CMAKE_MACOSX_RPATH ON) + SET(CMAKE_INSTALL_RPATH "@executable_path/" "@executable_path/../lib") ELSE() SET(CMAKE_INSTALL_RPATH "\$ORIGIN:\$ORIGIN/../lib") # on per target basis: @@ -30,6 +29,7 @@ IF (OSPRAY_ZIP_MODE) #SET_TARGET_PROPERTIES(libs INSTALL_RPATH "$ORIGIN") ENDIF() ELSE() + SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}) IF (APPLE) # use RPath on OSX SET(CMAKE_SKIP_INSTALL_RPATH OFF) From 6705c067820b1d9d9f64e23bc3f4addcef005c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 16 Mar 2016 22:01:00 +0100 Subject: [PATCH 118/310] Fixes for OSX --- apps/qtViewer/sg/common/TransferFunction.cpp | 2 +- scripts/release_macosx.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index cdff38ad47..dd7bd8f085 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -95,7 +95,7 @@ namespace ospray { { if (ospColorData == NULL) { // for now, no resampling - just use the colors ... - vec3f colors[colorArray.size()]; + vec3f *colors = (vec3f*)alloca(sizeof(vec3f)*colorArray.size()); for (int i=0;i Date: Wed, 16 Mar 2016 22:05:41 +0100 Subject: [PATCH 119/310] Install ospray_common --- common/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 175065e8bf..9157a0c8bb 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -37,3 +37,6 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED RefCount.h vec.h ) + +OSPRAY_SET_LIBRARY_VERSION(ospray_common) +OSPRAY_INSTALL_LIBRARY(ospray_common) From 5858826848886bdccdb07313ee6d2572908afebd Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 16 Mar 2016 19:55:04 -0500 Subject: [PATCH 120/310] fix uninitialized member variables in ospray::Task constructor --- ospray/common/tasking/TaskSys.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ospray/common/tasking/TaskSys.h b/ospray/common/tasking/TaskSys.h index aa15a608a1..8e6559ef2c 100644 --- a/ospray/common/tasking/TaskSys.h +++ b/ospray/common/tasking/TaskSys.h @@ -99,6 +99,8 @@ namespace ospray { __forceinline Task::Task(const char *name) : status(Task::INITIALIZING), name(name), + numJobsCompleted(0), + numJobsStarted(0), numJobsInTask(0) { } From 87c9a26da3cae1d39500bbfc8a11eb5922d129e6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 16 Mar 2016 20:14:47 -0500 Subject: [PATCH 121/310] remove KNC CMake options when on Windows or not using icc (and add warnings) --- CMakeLists.txt | 38 +++++++++++++++++++++----------------- cmake/ospray.cmake | 4 ++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae3ee5adb7..19e1dc3fd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,11 +35,28 @@ SET(OSPRAY_VERSION ) SET(OSPRAY_SOVERSION 0) +############################################################## +# CMake modules and macro files +############################################################## + +INCLUDE(cmake/ospray.cmake) +INCLUDE(cmake/ispc.cmake) + +SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) + +INCLUDE(cmake/mpi.cmake) + +IF(NOT WIN32) + INCLUDE(cmake/doxygen.cmake) +ENDIF() + +############################################################## +# Global OSPRay build options +############################################################## OPTION(OSPRAY_USE_EXTERNAL_EMBREE "Use a pre-built Embree instead of the internally built version" OFF) - SET(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") IF (WIN32) IF (NOT OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET) @@ -65,7 +82,9 @@ OPTION(OSPRAY_VOLUME_VOXELRANGE_IN_APP "Move 'voxelrange' computations to app?" MARK_AS_ADVANCED(OSPRAY_VOLUME_VOXELRANGE_IN_APP) IF (WIN32) - SET(OSPRAY_BUILD_MIC_SUPPORT OFF CACHE INTERNAL "OSPRay with KNC not supported on Windows.") + OSPRAY_WARN_ONCE(KNC_SUPPORT "KNC options disabled: KNC not supported on Windows") +ELSEIF(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + OSPRAY_WARN_ONCE(KNC_SUPPORT "KNC options disabled: KNC requires the Intel Compiler") ELSE() OPTION(OSPRAY_BUILD_MIC_SUPPORT "Build OSPRay with KNC Support?") ENDIF() @@ -86,21 +105,6 @@ STRING(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) SET(OSPRAY_MPI ${OSPRAY_BUILD_MPI_DEVICE}) -############################################################## -# CMake modules and macro files -############################################################## - -INCLUDE(cmake/ospray.cmake) -INCLUDE(cmake/ispc.cmake) - -SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) - -INCLUDE(cmake/mpi.cmake) - -IF(NOT WIN32) - INCLUDE(cmake/doxygen.cmake) -ENDIF() - OSPRAY_CONFIGURE_COMPILER() ############################################################## diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index d760c15b8a..0ae3f4f719 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -164,8 +164,8 @@ MACRO(CONFIGURE_OSPRAY) IF (THIS_IS_MIC) # whether to build in MIC/xeon phi support - SET(OSPRAY_BUILD_COI_DEVICE OFF CACHE BOOL - "Build COI Device for OSPRay's MIC support?") + OPTION(OSPRAY_BUILD_COI_DEVICE + "Build COI Device for OSPRay's MIC support?" OFF) ENDIF() INCLUDE(${PROJECT_SOURCE_DIR}/cmake/ispc.cmake) From 93acedd91ee49b5fbff4668c19777dda2c1c16bb Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 16 Mar 2016 18:04:11 -0500 Subject: [PATCH 122/310] % opeartor on vecs --- common/vec.h | 1 + 1 file changed, 1 insertion(+) diff --git a/common/vec.h b/common/vec.h index 933d6b6253..32748ebc26 100644 --- a/common/vec.h +++ b/common/vec.h @@ -218,6 +218,7 @@ namespace ospcommon { binary_operator(operator-,-); binary_operator(operator*,*); binary_operator(operator/,/); + binary_operator(operator%,%); #undef binary_operator // ------------------------------------------------------- From 738f66dc26175b6ddc5955fbbedf8964eacdd75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 17 Mar 2016 11:17:47 +0100 Subject: [PATCH 123/310] Revert "remove KNC CMake options when on Windows or not using icc (and add warnings)" This reverts commit 87c9a26da3cae1d39500bbfc8a11eb5922d129e6. The options need to come first before including other .cmake files (e.g. MPI libs were not found). --- CMakeLists.txt | 38 +++++++++++++++++--------------------- cmake/ospray.cmake | 4 ++-- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19e1dc3fd2..ae3ee5adb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,28 +35,11 @@ SET(OSPRAY_VERSION ) SET(OSPRAY_SOVERSION 0) -############################################################## -# CMake modules and macro files -############################################################## - -INCLUDE(cmake/ospray.cmake) -INCLUDE(cmake/ispc.cmake) - -SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) - -INCLUDE(cmake/mpi.cmake) - -IF(NOT WIN32) - INCLUDE(cmake/doxygen.cmake) -ENDIF() - -############################################################## -# Global OSPRay build options -############################################################## OPTION(OSPRAY_USE_EXTERNAL_EMBREE "Use a pre-built Embree instead of the internally built version" OFF) + SET(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") IF (WIN32) IF (NOT OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET) @@ -82,9 +65,7 @@ OPTION(OSPRAY_VOLUME_VOXELRANGE_IN_APP "Move 'voxelrange' computations to app?" MARK_AS_ADVANCED(OSPRAY_VOLUME_VOXELRANGE_IN_APP) IF (WIN32) - OSPRAY_WARN_ONCE(KNC_SUPPORT "KNC options disabled: KNC not supported on Windows") -ELSEIF(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") - OSPRAY_WARN_ONCE(KNC_SUPPORT "KNC options disabled: KNC requires the Intel Compiler") + SET(OSPRAY_BUILD_MIC_SUPPORT OFF CACHE INTERNAL "OSPRay with KNC not supported on Windows.") ELSE() OPTION(OSPRAY_BUILD_MIC_SUPPORT "Build OSPRay with KNC Support?") ENDIF() @@ -105,6 +86,21 @@ STRING(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) SET(OSPRAY_MPI ${OSPRAY_BUILD_MPI_DEVICE}) +############################################################## +# CMake modules and macro files +############################################################## + +INCLUDE(cmake/ospray.cmake) +INCLUDE(cmake/ispc.cmake) + +SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) + +INCLUDE(cmake/mpi.cmake) + +IF(NOT WIN32) + INCLUDE(cmake/doxygen.cmake) +ENDIF() + OSPRAY_CONFIGURE_COMPILER() ############################################################## diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 0ae3f4f719..d760c15b8a 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -164,8 +164,8 @@ MACRO(CONFIGURE_OSPRAY) IF (THIS_IS_MIC) # whether to build in MIC/xeon phi support - OPTION(OSPRAY_BUILD_COI_DEVICE - "Build COI Device for OSPRay's MIC support?" OFF) + SET(OSPRAY_BUILD_COI_DEVICE OFF CACHE BOOL + "Build COI Device for OSPRay's MIC support?") ENDIF() INCLUDE(${PROJECT_SOURCE_DIR}/cmake/ispc.cmake) From f8d48e96d4b039df38e029697fa9668412c7de19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 17 Mar 2016 17:07:54 +0100 Subject: [PATCH 124/310] Better fix for initializing atomic on Windows --- ospray/common/tasking/TaskSys.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ospray/common/tasking/TaskSys.h b/ospray/common/tasking/TaskSys.h index 8e6559ef2c..a2347a5361 100644 --- a/ospray/common/tasking/TaskSys.h +++ b/ospray/common/tasking/TaskSys.h @@ -99,8 +99,9 @@ namespace ospray { __forceinline Task::Task(const char *name) : status(Task::INITIALIZING), name(name), - numJobsCompleted(0), - numJobsStarted(0), + numJobsCompleted(), + numJobsStarted(), + numMissingDependencies(), numJobsInTask(0) { } From 470e0fccebf8582cf53bac35fbe36aff235f86c9 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Thu, 17 Mar 2016 12:35:20 -0600 Subject: [PATCH 125/310] removed he WARN_OSPCOMMON stuff - no need any more --- modules/CMakeLists.txt | 3 --- ospray/CMakeLists.txt | 3 --- ospray/common/OSPCommon.h | 3 --- 3 files changed, 9 deletions(-) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index e9fdff6d58..d4be3743a0 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -15,9 +15,6 @@ ## ======================================================================== ## IF (NOT WIN32) # not yet... - # NOTE(jda) - To be removed when OSPCOMMON is merged for next release (?) - ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) - FILE(GLOB plugins RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ *) FOREACH(plugin ${plugins}) IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${plugin}/CMakeLists.txt) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 1c8a5da3c9..1d599d90d0 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -228,9 +228,6 @@ SET(OSPRAY_SOURCES api/LocalDevice.cpp ) -# NOTE(jda) - To be removed when OSPCOMMON is merged for next release (?) -ADD_DEFINITIONS(-DDONT_WARN_INCLUDE_OSPCOMMON_H) - # ------------------------------------------------------- # MPI components # ------------------------------------------------------- diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index 2b4063ec91..d8a98e3b38 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -194,6 +194,3 @@ namespace ospray { #endif #define NOTIMPLEMENTED throw std::runtime_error(std::string(__PRETTY_FUNCTION__)+": not implemented..."); -#ifndef DONT_WARN_INCLUDE_OSPCOMMON_H -# error "warning: including OSPCommon.h from outside of ospray/ directory!" -#endif From 748e257857542631e60bacb52f8b8df7bdfaa7f1 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 18 Mar 2016 13:48:19 -0500 Subject: [PATCH 126/310] semantic cleanups --> use of Ref<> instead of manual refInc() and refDec() --- ospray/common/tasking/TaskSys.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index 91f3fe6105..2f9e2c6e6a 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -33,9 +33,10 @@ namespace ospray { void init(size_t maxNumRenderTasks); static TaskSys global; static void *threadStub(void *); - inline Task *getNextActiveTask(); + inline Ref getNextActiveTask(); - //! queue of tasks that have ALREADY been acitvated, and that are ready to run + //! Queue of tasks that have ALREADY been acitvated, and that are ready + //! to run __aligned(64) Task *volatile activeListFirst; __aligned(64) Task *volatile activeListLast; @@ -103,7 +104,7 @@ namespace ospray { wait(); } - inline Task *TaskSys::getNextActiveTask() + inline Ref TaskSys::getNextActiveTask() { while (1) { std::unique_lock lock(mutex); @@ -115,18 +116,16 @@ namespace ospray { return nullptr; } - Task *const front = activeListFirst; + Ref front = activeListFirst; if (front->numJobsStarted >= front->numJobsInTask) { if (activeListFirst == activeListLast) { activeListFirst = activeListLast = nullptr; } else { activeListFirst = activeListFirst->next; } - front->refDec(); continue; } - front->refInc(); // becasue the thread calling us now owns it - assert(front); + assert(front.ptr()); return front; } } @@ -171,20 +170,15 @@ namespace ospray { } } - void TaskSys::threadFunction() { while (1) { - Task *task = getNextActiveTask(); + Ref task = getNextActiveTask(); if (!running) { - if (task) { - task->refDec(); - } return; } assert(task); task->workOnIt(); - task->refDec(); } } From 5d403b2c82b827330117517438a3079eebc3d0de Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 18 Mar 2016 14:40:57 -0500 Subject: [PATCH 127/310] more cleanups, enforce a "public" interface in ospray::Task --- ospray/common/tasking/TaskSys.cpp | 19 +++-------- ospray/common/tasking/TaskSys.h | 56 +++++++++++++++++++------------ 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index 2f9e2c6e6a..2085cf11a3 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -23,9 +23,6 @@ #include namespace ospray { - using std::cout; - using std::endl; - struct TaskSys { bool initialized; bool running; @@ -70,16 +67,11 @@ namespace ospray { } if (myCompleted != 0) { - const size_t nowCompleted = (numJobsCompleted += myCompleted); //++numJobsCompleted; + const size_t nowCompleted = (numJobsCompleted += myCompleted); if (nowCompleted == numJobsInTask) { - // Yay - I just finished the job, so I get some extra work do do ... just like in real life.... - finish(); - - { - SCOPED_LOCK(mutex); - status = Task::COMPLETED; - allJobsCompletedCond.notify_all(); - } + SCOPED_LOCK(mutex); + status = Task::COMPLETED; + allJobsCompletedCond.notify_all(); } } } @@ -224,5 +216,4 @@ namespace ospray { setAffinity(0); #endif } - -} +}//namespace ospray diff --git a/ospray/common/tasking/TaskSys.h b/ospray/common/tasking/TaskSys.h index a2347a5361..bc13fb1ede 100644 --- a/ospray/common/tasking/TaskSys.h +++ b/ospray/common/tasking/TaskSys.h @@ -21,23 +21,14 @@ namespace ospray { struct __aligned(64) Task : public RefCount { - // typedef enum { FRONT, BACK } ScheduleOrder; - // ------------------------------------------------------------------ - // callbacks used to define what the task is doing - // ------------------------------------------------------------------ Task(const char *name = "no name"); - virtual void run(size_t jobID) = 0; - virtual void finish(); virtual ~Task(); + // ------------------------------------------------------------------ // interface for scheduling a new task into the task system // ------------------------------------------------------------------ - //! add a new dependecy: task cannot become active until this depdency has - //! completed - void addDependency(Task *dependency); - typedef enum { /*! schedule job to the END of the job queue, meaning it'll get pulled only after all the ones already in the queue */ @@ -52,17 +43,44 @@ namespace ospray { * activated */ ScheduleOrder order; - //! schedule the given task with the given number of - //! sub-jobs. . if the task has dependencies, it may not be - //! immeately active. + //! schedule the given task with the given number of sub-jobs. void schedule(size_t numJobs, ScheduleOrder order=BACK_OF_QUEUE); + //! same as schedule(), but also wait for all jobs to complete void scheduleAndWait(size_t numJobs, ScheduleOrder order=BACK_OF_QUEUE); //! wait for the task to complete, optionally (by default) helping //! to actually work on completing this task. void wait(bool workOnIt = true); + //! get name of the task (useful for debugging) + const char *getName(); + + /*! \brief initialize the task system with given number of worker + tasks. + + numThreads==-1 means 'use all that are available; numThreads=0 + means 'no worker thread, assume that whoever calls wait() will + do the work */ + static void initTaskSystem(const size_t numThreads); + + private: + + //! Allow tasking system backend to access all parts of the class, but + //! prevent users from using data which is an implementation detail of the + //! task + friend class TaskSys; + + // ------------------------------------------------------------------ + // callback used to define what the task is doing + // ------------------------------------------------------------------ + + virtual void run(size_t jobID) = 0; + + // ------------------------------------------------------------------ + // internal data for the tasking systme to manage the task + // ------------------------------------------------------------------ + //*! work on task until no more useful job available on this task void workOnIt(); @@ -84,14 +102,6 @@ namespace ospray { __aligned(64) Task *volatile next; const char *name; - - /*! \brief initialize the task system with given number of worker - tasks. - - numThreads==-1 means 'use all that are available; numThreads=0 - means 'no worker thread, assume that whoever calls wait() will - do the work */ - static void initTaskSystem(const size_t numThreads); }; // Inlined function definitions /////////////////////////////////////////////// @@ -110,7 +120,9 @@ namespace ospray { { } - __forceinline void Task::finish() + __forceinline const char *Task::getName() { + return name; } + }//namespace ospray From 5556cfe74fd9f70a93ddd58c79c56bb111831f6a Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sat, 19 Mar 2016 12:25:16 -0500 Subject: [PATCH 128/310] prettyNumber to ospcommon --- common/CMakeLists.txt | 6 ++++++ common/common.h | 18 ++++++++++++++++++ common/network.cpp | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 9157a0c8bb..d69c809870 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -24,6 +24,7 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED library.cpp thread.cpp vec.cpp + network.cpp AffineSpace.h box.h @@ -38,5 +39,10 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED vec.h ) +TARGET_LINK_LIBRARIES(ospray_common + # for network.cpp + pthread +) + OSPRAY_SET_LIBRARY_VERSION(ospray_common) OSPRAY_INSTALL_LIBRARY(ospray_common) diff --git a/common/common.h b/common/common.h index aa460b158b..e6d9646f6d 100644 --- a/common/common.h +++ b/common/common.h @@ -80,4 +80,22 @@ namespace ospcommon { OSPCOMMON_INTERFACE void loadLibrary(const std::string &name); OSPCOMMON_INTERFACE void *getSymbol(const std::string &name); + /*! added pretty-print function for large numbers, printing 10000000 as "10M" instead */ + inline std::string prettyNumber(const size_t s) { + double val = s; + char result[100]; + if (val >= 1e12f) { + sprintf(result,"%.1fT",val/1e12f); + } else if (val >= 1e9f) { + sprintf(result,"%.1fG",val/1e9f); + } else if (val >= 1e6f) { + sprintf(result,"%.1fM",val/1e6f); + } else if (val >= 1e3f) { + sprintf(result,"%.1fK",val/1e3f); + } else { + sprintf(result,"%lu",s); + } + return result; + } + } // ::ospcommon diff --git a/common/network.cpp b/common/network.cpp index 3b819e9c45..c2441f6aa7 100644 --- a/common/network.cpp +++ b/common/network.cpp @@ -144,8 +144,9 @@ namespace ospcommon serv_addr.sin_port = (unsigned short) htons(port); serv_addr.sin_addr.s_addr = INADDR_ANY; - if (::bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) + if (::bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) { THROW_RUNTIME_ERROR("binding to port "+std::to_string((long long)port)+" failed"); + } /*! listen to port, up to 5 pending connections */ if (::listen(sockfd,5) < 0) From 50618ea15afe97c2ed8fd2ee1ae0f78f549483a7 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 20 Mar 2016 13:16:28 -0600 Subject: [PATCH 129/310] qtviewer/sg and qtviewer now use ospcommon files in ospray.h --- apps/qtViewer/main.cpp | 4 ++-- apps/qtViewer/sg/common/Common.h | 20 +++++++++++++------ .../QAffineSpaceManipulator.cpp | 2 -- .../QAffineSpaceManipulator.h | 2 ++ .../lightManipulator/QLightManipulator.h | 1 + .../QTransferFunctionEditor.h | 4 ++-- 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/apps/qtViewer/main.cpp b/apps/qtViewer/main.cpp index 7a971f3980..73587dd554 100644 --- a/apps/qtViewer/main.cpp +++ b/apps/qtViewer/main.cpp @@ -14,14 +14,14 @@ // limitations under the License. // // ======================================================================== // +// viewer +#include "ModelViewer.h" // ospray #include "ospray/ospray.h" // qt #include #include #include -// viewer -#include "ModelViewer.h" // scene graph #include "sg/module/Module.h" #include "sg/importer/Importer.h" diff --git a/apps/qtViewer/sg/common/Common.h b/apps/qtViewer/sg/common/Common.h index cff6c7c3ff..e2bfa751c0 100644 --- a/apps/qtViewer/sg/common/Common.h +++ b/apps/qtViewer/sg/common/Common.h @@ -16,15 +16,23 @@ #pragma once -#define WARN_ON_INCLUDING_OSPCOMMON 1 +// use ospcommon vector types in ospray.h +#define OSPRAY_EXTERNAL_VECTOR_TYPES 1 +// ospcommon +#include "common/AffineSpace.h" + +namespace osp { + using ospcommon::vec2i; + using ospcommon::vec2f; + using ospcommon::vec3i; + using ospcommon::vec3f; + using ospcommon::vec4f; + using ospcommon::affine3f; +} + // ospray API #include "ospray/ospray.h" -// ospcommon -#include "common/common.h" -#include "common/vec.h" -#include "common/box.h" -#include "common/AffineSpace.h" // STL namespace ospray { diff --git a/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp b/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp index 6285d9a955..31644b839b 100644 --- a/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp +++ b/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.cpp @@ -14,8 +14,6 @@ // limitations under the License. // // ======================================================================== // -#define WARN_ON_INCLUDING_OSPCOMMON 1 - // viewer #include "QAffineSpaceManipulator.h" #include "HelperGeometry.h" diff --git a/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.h b/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.h index 9f7afaafe9..778c5e60a7 100644 --- a/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.h +++ b/apps/qtViewer/widgets/affineSpaceManipulator/QAffineSpaceManipulator.h @@ -16,6 +16,8 @@ #pragma once +// sg +#include "sg/SceneGraph.h" // ospray public api #include "ospray/ospray.h" // ospcomon diff --git a/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h b/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h index 2faabe14a9..4f239e2552 100644 --- a/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h +++ b/apps/qtViewer/widgets/lightManipulator/QLightManipulator.h @@ -16,6 +16,7 @@ #pragma once +#include "sg/SceneGraph.h" // ospray public api #include "ospray/ospray.h" // qt diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h index 96f226f56c..ad029cebcf 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h @@ -16,6 +16,8 @@ #pragma once +// scene graph +#include "sg/SceneGraph.h" // ospray, PUBLIC #include // stl @@ -23,8 +25,6 @@ #include // qt #include -// scene graph -#include "sg/SceneGraph.h" // ospcommon namespace ospray { From 477d19b13f18a74e77d0c9551de2c106b4e13cd3 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sun, 20 Mar 2016 18:40:08 -0600 Subject: [PATCH 130/310] removing debug outputs in qt viewer --- apps/qtViewer/ModelViewer.cpp | 1 - apps/qtViewer/sg/volume/Volume.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/qtViewer/ModelViewer.cpp b/apps/qtViewer/ModelViewer.cpp index d78e62c3df..313c91e804 100644 --- a/apps/qtViewer/ModelViewer.cpp +++ b/apps/qtViewer/ModelViewer.cpp @@ -158,7 +158,6 @@ namespace ospray { sg::TransferFunction *xf = dynamic_cast (sgRenderer->uniqueNodes.object[i]->node.ptr); if (xf) xferFuncs.push_back(xf); - cout << "FOUND xf : " << xf << endl; } std::cout << "#osp:qtv: found " << xferFuncs.size() << " transfer function nodes" << std::endl; diff --git a/apps/qtViewer/sg/volume/Volume.cpp b/apps/qtViewer/sg/volume/Volume.cpp index ce11467297..9539697d5e 100644 --- a/apps/qtViewer/sg/volume/Volume.cpp +++ b/apps/qtViewer/sg/volume/Volume.cpp @@ -33,7 +33,6 @@ namespace ospray { void Volume::serialize(sg::Serialization::State &state) { - PING; PRINT(toString()); Node::serialize(state); if (transferFunction) transferFunction->serialize(state); From 1960b7ba8e2ab5567a082302d3677933cfcc0724 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 21 Mar 2016 10:07:09 -0500 Subject: [PATCH 131/310] fix debug compile error --- ospray/common/tasking/TaskSys.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index 2085cf11a3..858cb9b69a 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -117,7 +117,7 @@ namespace ospray { } continue; } - assert(front.ptr()); + assert(front.ptr); return front; } } From fd1a34604034233a47da8ebe2d8a5153c7026fd2 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 21 Mar 2016 11:55:46 -0500 Subject: [PATCH 132/310] minor cleanups, removal of dead code --- ospray/common/Ray.ih | 18 ------------------ ospray/render/Renderer.cpp | 21 +++++++++++++++------ 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/ospray/common/Ray.ih b/ospray/common/Ray.ih index 58e6dee134..74fd2511b7 100644 --- a/ospray/common/Ray.ih +++ b/ospray/common/Ray.ih @@ -20,14 +20,6 @@ #include "ospray/math/vec.ih" #include "ospray/math/box.ih" -#ifdef OSPRAY_INTERSECTION_FILTER -struct Geometry; -struct Ray; - -typedef void (*IntersectionFilterFunc)(uniform Geometry *uniform THIS, - varying Ray &ray); -#endif - /*! \brief ospray ray class This impelment the base ospray ray class; it is 'derived' @@ -75,10 +67,6 @@ struct Ray { int primID_hi64; void *uniform userData; -#ifdef OSPRAY_INTERSECTION_FILTER - uniform IntersectionFilterFunc intersectionFilter; -#endif - }; #define infinity (1e20f) @@ -106,9 +94,6 @@ inline void setRay(Ray &ray, const vec3f &ray_org, const vec3f &ray_dir) ray.geomID = -1; ray.primID = -1; ray.instID = -1; -#ifdef OSPRAY_INTERSECTION_FILTER - ray.intersectionFilter = NULL; -#endif } /*! initialize a new ray with given parameters */ @@ -127,9 +112,6 @@ inline void setRay(Ray &ray, const vec3f &ray_org, const vec3f &ray_dir, ray.geomID = -1; ray.primID = -1; ray.instID = -1; -#ifdef OSPRAY_INTERSECTION_FILTER - ray.intersectionFilter = NULL; -#endif } /*! helper function that performs a ray-box test */ diff --git a/ospray/render/Renderer.cpp b/ospray/render/Renderer.cpp index 606db2d364..d2bba959c0 100644 --- a/ospray/render/Renderer.cpp +++ b/ospray/render/Renderer.cpp @@ -81,7 +81,8 @@ namespace ospray { loadLibrary("ospray_module_" + libName); } - std::map::iterator it = rendererRegistry.find(type); + std::map::iterator it + = rendererRegistry.find(type); if (it != rendererRegistry.end()) { return it->second ? (it->second)() : NULL; } @@ -92,11 +93,12 @@ namespace ospray { } std::string creatorName = "ospray_create_renderer__" + type; - creatorFct creator = (creatorFct)getSymbol(creatorName); //dlsym(RTLD_DEFAULT,creatorName.c_str()); + creatorFct creator = (creatorFct)getSymbol(creatorName); rendererRegistry[type] = creator; if (creator == NULL) { if (ospray::logLevel >= 1) { - std::cout << "#ospray: could not find renderer type '" << type << "'" << std::endl; + std::cout << "#ospray: could not find renderer type '" << type << "'" + << std::endl; } return NULL; } @@ -104,8 +106,12 @@ namespace ospray { Renderer *renderer = (*creator)(); renderer->managedObjectType = OSP_RENDERER; if (renderer == NULL && ospray::logLevel >= 1) { - std::cout << "#osp:warning[ospNewRenderer(...)]: could not create renderer of that type." << endl; - std::cout << "#osp:warning[ospNewRenderer(...)]: Note: Requested renderer type was '" << type << "'" << endl; + std::cout << "#osp:warning[ospNewRenderer(...)]:" + << " could not create renderer of that type." + << endl; + std::cout << "#osp:warning[ospNewRenderer(...)]:" + << " Note: Requested renderer type was '" << type << "'" + << endl; } return renderer; @@ -143,7 +149,10 @@ namespace ospray { assert(getIE()); OSPPickResult res; - ispc::Renderer_pick(getIE(), (const ispc::vec2f&)screenPos, (ispc::vec3f&)res.position, res.hit); + ispc::Renderer_pick(getIE(), + (const ispc::vec2f&)screenPos, + (ispc::vec3f&)res.position, + res.hit); return res; } From 99deee8407e032d3dd673516102c9a30720b0b18 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 21 Mar 2016 12:30:56 -0500 Subject: [PATCH 133/310] compile fix in debug mode --- ospray/common/tasking/TaskSys.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index 2085cf11a3..858cb9b69a 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -117,7 +117,7 @@ namespace ospray { } continue; } - assert(front.ptr()); + assert(front.ptr); return front; } } From 6693d39d0897ab319f12f01d5872962cc5af55d1 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 21 Mar 2016 13:04:07 -0500 Subject: [PATCH 134/310] added XMLNode::getPropf() --- apps/common/xml/XML.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/common/xml/XML.h b/apps/common/xml/XML.h index d346650975..6ff0635f09 100644 --- a/apps/common/xml/XML.h +++ b/apps/common/xml/XML.h @@ -75,8 +75,18 @@ namespace ospray { /*! find properly with given name, and return as long ('l') int. return undefined if prop does not exist */ - inline size_t getPropl(const std::string &name) const - { return atol(getProp(name).c_str()); } + inline size_t getPropl(const std::string &name, const size_t defaultValue = 0) const + { + const std::string prop = getProp(name); + if (prop == "") return defaultValue; else return atol(getProp(name).c_str()); + } + /*! find properly with given name, and return as long ('l') + int. return undefined if prop does not exist */ + inline float getPropf(const std::string &name, const float defaultValue = 0.f) const + { + const std::string prop = getProp(name); + if (prop == "") return defaultValue; else return atof(getProp(name).c_str()); + } /*! name of the xml node (i.e., the thing that's in "....") */ From d4d3d941be54e2456f3012108540d6769ce05ecf Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 21 Mar 2016 14:41:13 -0500 Subject: [PATCH 135/310] fix flag denormals not being set for all threading backends --- ospray/common/OSPCommon.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 21401ed5dd..6cd2d5486a 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -18,9 +18,12 @@ #ifdef OSPRAY_USE_INTERNAL_TASKING # include "ospray/common/tasking/TaskSys.h" #endif +#include "ospray/common/tasking/async.h" // embree #include "embree2/rtcore.h" #include "common/sysinfo.h" +//stl +#include namespace ospray { @@ -129,6 +132,30 @@ namespace ospray { std::cerr << "WARNING: " << e.what() << std::endl; } #endif + + // NOTE(jda) - Make sure that each thread (both calling application thread + // and OSPRay worker threads) has the correct denormals flags + // set. + + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); + + const int NTASKS = std::min((uint32_t)numThreads, + std::thread::hardware_concurrency()) - 1; + + AtomicInt counter; + counter = 0; + + // Force each worker thread to pickup exactly one task which sets denormals + // flags, where each thread spins until they are all done. + for (int i = 0; i < NTASKS; ++i) { + async([&]() { + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); + counter++; + while(counter < NTASKS); + }); + } } void error_handler(const RTCError code, const char *str) From ec5331d0cf63742f486055f801bd93e54a6c36ef Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Tue, 22 Mar 2016 00:20:07 -0500 Subject: [PATCH 136/310] amr - first light --- apps/qtViewer/ModelViewer.cpp | 4 +-- apps/qtViewer/sg/common/TransferFunction.cpp | 12 ++++--- apps/qtViewer/sg/volume/Volume.cpp | 1 - .../QTransferFunctionEditor.cpp | 36 +++++++------------ .../QTransferFunctionEditor.h | 4 +-- .../LinearTransferFunction.cpp | 1 + .../LinearTransferFunction.ispc | 4 --- 7 files changed, 25 insertions(+), 37 deletions(-) diff --git a/apps/qtViewer/ModelViewer.cpp b/apps/qtViewer/ModelViewer.cpp index d78e62c3df..3632ba6fb3 100644 --- a/apps/qtViewer/ModelViewer.cpp +++ b/apps/qtViewer/ModelViewer.cpp @@ -158,7 +158,7 @@ namespace ospray { sg::TransferFunction *xf = dynamic_cast (sgRenderer->uniqueNodes.object[i]->node.ptr); if (xf) xferFuncs.push_back(xf); - cout << "FOUND xf : " << xf << endl; + // cout << "FOUND xf : " << xf << endl; } std::cout << "#osp:qtv: found " << xferFuncs.size() << " transfer function nodes" << std::endl; @@ -400,8 +400,8 @@ namespace ospray { createTimeSlider(); createEditorWidgetStack(); - createLightManipulator(); createTransferFunctionEditor(); + createLightManipulator(); if (fullscreen) { setWindowState(windowState() | Qt::WindowFullScreen); diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index dd7bd8f085..ca77712134 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -20,13 +20,15 @@ namespace ospray { namespace sg { + using std::cout; + using std::endl; //! constructor TransferFunction::TransferFunction() : ospTransferFunction(NULL), ospColorData(NULL), ospAlphaData(NULL), - numSamples(128) + numSamples(32) { setDefaultValues(); } @@ -34,7 +36,6 @@ namespace ospray { // //! \brief Sets a new 'texture map' to be used for the color mapping void TransferFunction::setColorMap(const std::vector &colorArray) { - PING; if (ospColorData) { ospRelease(ospColorData); ospColorData = NULL; } this->colorArray.clear(); for (int i=0;i(i,vec3f(col[i][0],col[i][1],col[i][2]))); alphaArray.clear(); - for (int i=0;i(i,1.f)); //i/float(colorArray.size()-1)); + alphaArray.push_back(std::pair(0.f,0.f)); + alphaArray.push_back(std::pair(1.f,1.f)); + // for (int i=0;i(i,1.f)); //i/float(colorArray.size()-1)); } OSP_REGISTER_SG_NODE(TransferFunction) diff --git a/apps/qtViewer/sg/volume/Volume.cpp b/apps/qtViewer/sg/volume/Volume.cpp index ce11467297..9539697d5e 100644 --- a/apps/qtViewer/sg/volume/Volume.cpp +++ b/apps/qtViewer/sg/volume/Volume.cpp @@ -33,7 +33,6 @@ namespace ospray { void Volume::serialize(sg::Serialization::State &state) { - PING; PRINT(toString()); Node::serialize(state); if (transferFunction) transferFunction->serialize(state); diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp index 281e7063e0..f99fae09f2 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.cpp @@ -1,6 +1,7 @@ // ======================================================================== // // Copyright 2009-2016 Intel Corporation // // // + // Licensed under the Apache License, Version 2.0 (the "License"); // // you may not use this file except in compliance with the License. // // You may obtain a copy of the License at // @@ -40,7 +41,6 @@ namespace ospray { colorMapImage.fill(QColor::fromRgbF(1,1,1,1).rgb()); // default transfer function points - // points.push_back(ospcommon::vec2f(0.,1.)); points.push_back(ospcommon::vec2f(0.,0.)); points.push_back(ospcommon::vec2f(1.,1.)); } @@ -151,7 +151,6 @@ namespace ospray { // trigger repaint repaint(); - PING; // emit signal emit transferFunctionChanged(); } @@ -362,17 +361,6 @@ namespace ospray { updateAlphaMap(); } - // void QTransferFunctionEditor::transferFunctionChanged() - // { - // PING; - // } - // void QTransferFunctionAlphaEditor::transferFunctionChanged() - // { - // PING; - // } - - - void QTransferFunctionEditor::selectColorMap(int index) { activeColorMap = colorMaps[index]; @@ -407,25 +395,25 @@ namespace ospray { void QOSPTransferFunctionEditor::updateColorMap() { - // PING; sgNode->setColorMap(activeColorMap->getColors()); sgNode->commit(); } + const std::vector &QTransferFunctionAlphaEditor::getPoints() const + { + return points; + } + + void QTransferFunctionAlphaEditor::setPoints(const std::vector &points) + { + this->points = points; + } + + void QOSPTransferFunctionEditor::updateAlphaMap() { sgNode->setAlphaMap(transferFunctionAlphaEditor->getPoints()); - // PING; - // const int numAlphas = 256; - // std::vector alphas; - // for (int i=0;igetInterpolatedValue(i/float(numAlphas-1))); - - // // PING; - // sgNode->setAlphaMap(alphas); - // PING; sgNode->commit(); - // PING; } } // ::ospray::viewer diff --git a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h index ad029cebcf..7552e56f01 100644 --- a/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h +++ b/apps/qtViewer/widgets/transferFunction/QTransferFunctionEditor.h @@ -45,8 +45,8 @@ namespace ospray { /*! set background image for a given color map */ void setColorMapImage(const QImage &image); - const std::vector &getPoints() const { return points; } - void setPoints(const std::vector &points) { this->points = points; } + const std::vector &getPoints() const; + void setPoints(const std::vector &points); signals: void transferFunctionChanged(); diff --git a/ospray/transferFunction/LinearTransferFunction.cpp b/ospray/transferFunction/LinearTransferFunction.cpp index a772b08483..6d113c8312 100644 --- a/ospray/transferFunction/LinearTransferFunction.cpp +++ b/ospray/transferFunction/LinearTransferFunction.cpp @@ -45,6 +45,7 @@ namespace ospray { // Set the opacity values. if (opacityValues) { + float *alpha = (float *)opacityValues->data; ispc::LinearTransferFunction_setOpacityValues(ispcEquivalent, opacityValues->numItems, (float *)opacityValues->data); diff --git a/ospray/transferFunction/LinearTransferFunction.ispc b/ospray/transferFunction/LinearTransferFunction.ispc index a68e625987..b2f4dcd6d8 100644 --- a/ospray/transferFunction/LinearTransferFunction.ispc +++ b/ospray/transferFunction/LinearTransferFunction.ispc @@ -99,7 +99,6 @@ LinearTransferFunction_getOpacityForValue(const void *uniform _self, // Clamp the value to the lower bound of the value range. if (value <= self->super.valueRange.x) return self->opacityValues[0]; - // print("numopacity %\n",self->opacityValueCount); // Clamp the value to the upper bound of the value range. if (value >= self->super.valueRange.y) @@ -119,9 +118,6 @@ LinearTransferFunction_getOpacityForValue(const void *uniform _self, float ret = (1.0f - remainder) * self->opacityValues[index] + remainder * self->opacityValues[min(index + 1, self->opacityValueCount - 1)]; - // print("opacity(%) = %\n",value,ret); - // print("index % rem %\n",index,remainder); - // print("val[index] = %\n",self->opacityValues[index] ); return ret; } From ee5c4c142d84e6803eb06e7da8f5bee5243607e0 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 22 Mar 2016 11:13:36 -0500 Subject: [PATCH 137/310] fix to cmake find_package config --- cmake/ospray_cmake_config/osprayConfig.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index 62e9a65cae..694bddfd84 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -135,7 +135,7 @@ if(@OSPRAY_USE_EXTERNAL_EMBREE@) # Find existing Embree on the machine find_package(embree @REQUIRED_MINIMUM_EMBREE@ REQUIRED) else() - set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.2) endif() # Restore state From 0740ede4df545b25b52d0d453d951e8fcd5d5d04 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Tue, 22 Mar 2016 12:27:32 -0500 Subject: [PATCH 138/310] sg::transfer function now cnotains a valuerange, and sets it --- apps/common/xml/XML.h | 2 +- apps/qtViewer/sg/common/TransferFunction.cpp | 33 +++++--------------- apps/qtViewer/sg/common/TransferFunction.h | 3 ++ 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/apps/common/xml/XML.h b/apps/common/xml/XML.h index 6ff0635f09..0ab4f56cce 100644 --- a/apps/common/xml/XML.h +++ b/apps/common/xml/XML.h @@ -87,7 +87,7 @@ namespace ospray { const std::string prop = getProp(name); if (prop == "") return defaultValue; else return atof(getProp(name).c_str()); } - + /*! name of the xml node (i.e., the thing that's in "....") */ std::string name; diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index ca77712134..c2a05534ab 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -28,7 +28,8 @@ namespace ospray { : ospTransferFunction(NULL), ospColorData(NULL), ospAlphaData(NULL), - numSamples(32) + numSamples(128), + valueRange(0.f,1.f) { setDefaultValues(); } @@ -65,35 +66,17 @@ namespace ospray { ; return alphaArray.back().second; } - // float x - // = (_x - alphaArray.front().first) - // / (alphaArray.back().first - alphaArray.front().first); - // // boundary cases - // if(x <= 0.f) - // return alphaArray.front().second; - - // if(x >= 1.) - // return alphaArray.back().second; - - // // we could make this more efficient... - // for(unsigned int i=0; i &colorArray); /*! set a new alpha map array - x coordinate is point pos, y is point alpha value */ @@ -62,6 +64,7 @@ namespace ospray { OSPTransferFunction ospTransferFunction; OSPData ospColorData; OSPData ospAlphaData; + vec2f valueRange; // number of samples we'll use in the colordata and alphadata arrays int numSamples; From 313d2994e924f8b995b14152aa2e11cf71790596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 23 Mar 2016 11:15:42 +0100 Subject: [PATCH 139/310] Fix GBBV for double (did not copy border voxel) --- ospray/volume/GhostBlockBrickedVolume.ispc | 227 +++++++-------------- 1 file changed, 77 insertions(+), 150 deletions(-) diff --git a/ospray/volume/GhostBlockBrickedVolume.ispc b/ospray/volume/GhostBlockBrickedVolume.ispc index 9e2c17a660..d88e16302e 100644 --- a/ospray/volume/GhostBlockBrickedVolume.ispc +++ b/ospray/volume/GhostBlockBrickedVolume.ispc @@ -351,155 +351,60 @@ template_getVoxel(float) template_getVoxel(double) #undef template_getVoxel -inline void GBBV_allocateMemory(GBBV *uniform volume) -{ - // Memory may already have been allocated. - if (volume->blockMem != NULL) return; - - // Volume size in blocks per dimension with padding to the nearest block. - volume->blockCount = (volume->super.dimensions + (BLOCK_WIDTH-1) - 1) / (BLOCK_WIDTH-1); - - // Volume size in blocks with padding. - const uniform size_t blockCount = volume->blockCount.x * volume->blockCount.y * volume->blockCount.z; - - // allocate the large array of blocks - uniform uint64 blockSize = VOXELS_PER_BLOCK * volume->voxelSize; - volume->blockMem = malloc64(blockSize * (uint64)blockCount); - - if (volume->blockMem == NULL) { - print("failed to allocate block memory!"); - return; - } +#define template_setRegion(type) \ +void GBBV_setRegionTask_##type(GBBV *uniform self, \ + const void *uniform _source, \ + const uniform vec3i &targetCoord000, \ + const uniform vec3i ®ionSize, \ + const uniform int taskIndex) \ +{ \ + const type *uniform source = (const type *uniform)_source; \ + const uniform uint32 region_y = taskIndex % regionSize.y; \ + const uniform uint32 region_z = taskIndex / regionSize.y; \ + const uniform uint64 runOfs \ + = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); \ + const type *uniform run = source + runOfs; \ + vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); \ + foreach (x = 0 ... regionSize.x) { \ + Address address; \ + coord.x = targetCoord000.x + x; \ + if (coord.x < 0 || \ + coord.y < 0 || \ + coord.z < 0 || \ + coord.x >= self->super.dimensions.x || \ + coord.y >= self->super.dimensions.y || \ + coord.z >= self->super.dimensions.z \ + ) \ + continue; \ + \ + GBBV_getIndices_##type(self, coord, address); \ + /* set voxel itself */ \ + foreach_unique(blockID in address.block) { \ + type *uniform blockPtr \ + = ((type*uniform)self->blockMem) \ + + blockID * (uint64)VOXELS_PER_BLOCK; \ + blockPtr[address.voxel] = run[x]; \ + } \ + /* copy voxel to end of lower/left/front block if it's on the boundary */ \ + for (uniform int32 iz=0;iz<2;iz++) \ + for (uniform int32 iy=0;iy<2;iy++) \ + for (uniform int32 ix=0;ix<2;ix++) { \ + if (GBBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { \ + foreach_unique(blockID in address.block) { \ + type *uniform blockPtr \ + = ((type*uniform)self->blockMem) \ + + (uint64)blockID * (uint64)VOXELS_PER_BLOCK; \ + blockPtr[address.voxel] = run[x]; \ + } \ + } \ + } \ + } \ } -void GBBVUChar_setRegionTask(GBBV *uniform self, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize, - const uniform int taskIndex) -{ - const uint8 *uniform source = (const uint8 *uniform)_source; - const uniform uint32 region_y = taskIndex % regionSize.y; - const uniform uint32 region_z = taskIndex / regionSize.y; - const uniform uint64 runOfs - = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); - const uint8 *uniform run = source + runOfs; - vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); - foreach (x = 0 ... regionSize.x) { - Address address; - coord.x = targetCoord000.x + x; - if (coord.x < 0 || - coord.y < 0 || - coord.z < 0 || - coord.x >= self->super.dimensions.x || - coord.y >= self->super.dimensions.y || - coord.z >= self->super.dimensions.z - ) - continue; - - GBBV_getIndices_uint8(self, coord, address); - foreach_unique(blockID in address.block) { - uint8 *uniform blockPtr - = ((uint8*uniform)self->blockMem) - + blockID * (uint64)VOXELS_PER_BLOCK; - blockPtr[address.voxel] = run[x]; - } - for (uniform int32 iz=0;iz<2;iz++) - for (uniform int32 iy=0;iy<2;iy++) - for (uniform int32 ix=0;ix<2;ix++) { - if (GBBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { - foreach_unique(blockID in address.block) { - uint8 *uniform blockPtr - = ((uint8*uniform)self->blockMem) - + (uint64)blockID * (uint64)VOXELS_PER_BLOCK; - blockPtr[address.voxel] = run[x]; - } - } - } - } -} - -void GBBVFloat_setRegionTask(GBBV *uniform self, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize, - const uniform int taskIndex) -{ - const float *uniform source = (const float *uniform)_source; - const uniform uint32 region_y = taskIndex % regionSize.y; - const uniform uint32 region_z = taskIndex / regionSize.y; - const uniform uint64 runOfs - = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); - const float *uniform run = source + runOfs; - vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); - foreach (x = 0 ... regionSize.x) { - Address address; - coord.x = targetCoord000.x + x; - if (coord.x < 0 || - coord.y < 0 || - coord.z < 0 || - coord.x >= self->super.dimensions.x || - coord.y >= self->super.dimensions.y || - coord.z >= self->super.dimensions.z - ) - continue; - - GBBV_getIndices_float(self, coord, address); - // set voxel itself - foreach_unique(blockID in address.block) { - float *uniform blockPtr - = ((float*uniform)self->blockMem) - + blockID * (uint64)VOXELS_PER_BLOCK; - blockPtr[address.voxel] = run[x]; - } - // copy voxel to end of lower/left/front block if it's on the boundary - for (uniform int32 iz=0;iz<2;iz++) - for (uniform int32 iy=0;iy<2;iy++) - for (uniform int32 ix=0;ix<2;ix++) { - if (GBBV_getGhostIndices(self, coord, make_vec3i(ix,iy,iz),address)) { - foreach_unique(blockID in address.block) { - float *uniform blockPtr - = ((float*uniform)self->blockMem) - + blockID * (uint64)VOXELS_PER_BLOCK; - blockPtr[address.voxel] = run[x]; - } - } - } - } -} - -void GBBVDouble_setRegionTask(GBBV *uniform self, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize, - const uniform int taskIndex) -{ - const double *uniform source = (const double *uniform)_source; - const uniform uint32 region_y = taskIndex % regionSize.y; - const uniform uint32 region_z = taskIndex / regionSize.y; - const uniform uint64 runOfs = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); - const double *uniform run = source + runOfs; - vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); - foreach (x = 0 ... regionSize.x) { - Address address; - coord.x = targetCoord000.x + x; - if (coord.x < 0 || - coord.y < 0 || - coord.z < 0 || - coord.x >= self->super.dimensions.x || - coord.y >= self->super.dimensions.y || - coord.z >= self->super.dimensions.z - ) - continue; - GBBV_getIndices_double(self, coord, address); - foreach_unique(blockID in address.block) { - double *uniform blockPtr - = ((double*uniform)self->blockMem) - + blockID * (uint64)VOXELS_PER_BLOCK; - blockPtr[address.voxel] = run[x]; - } - } -} +template_setRegion(uint8) +template_setRegion(float) +template_setRegion(double) +#undef template_setRegion /*! perform trilinear interpolation for given sample. unlike old way of doing this (a single computesample on the StructuredVolume level @@ -590,6 +495,28 @@ template_computeSample(float) template_computeSample(double) #undef template_computeSample + +inline void GBBV_allocateMemory(GBBV *uniform volume) +{ + // Memory may already have been allocated. + if (volume->blockMem != NULL) return; + + // Volume size in blocks per dimension with padding to the nearest block. + volume->blockCount = (volume->super.dimensions + (BLOCK_WIDTH-1) - 1) / (BLOCK_WIDTH-1); + + // Volume size in blocks with padding. + const uniform size_t blockCount = volume->blockCount.x * volume->blockCount.y * volume->blockCount.z; + + // allocate the large array of blocks + uniform uint64 blockSize = VOXELS_PER_BLOCK * volume->voxelSize; + volume->blockMem = malloc64(blockSize * (uint64)blockCount); + + if (volume->blockMem == NULL) { + print("failed to allocate block memory!"); + return; + } +} + void GBBV_Constructor(GBBV *uniform volume, /*! pointer to the c++-equivalent class of this entity */ void *uniform cppEquivalent, @@ -604,19 +531,19 @@ void GBBV_Constructor(GBBV *uniform volume, if (volume->voxelType == OSP_UCHAR) { volume->voxelSize = sizeof(uniform uint8); volume->super.getVoxel = GBBV_getVoxel_uint8; - volume->setRegion = &GBBVUChar_setRegionTask; + volume->setRegion = &GBBV_setRegionTask_uint8; volume->super.super.computeSample = GBBV_computeSample_uint8; } else if (volume->voxelType == OSP_FLOAT) { volume->voxelSize = sizeof(uniform float); volume->super.getVoxel = GBBV_getVoxel_float; - volume->setRegion = &GBBVFloat_setRegionTask; + volume->setRegion = &GBBV_setRegionTask_float; volume->super.super.computeSample = GBBV_computeSample_float; } else if (volume->voxelType == OSP_DOUBLE) { volume->voxelSize = sizeof(uniform double); volume->super.getVoxel = GBBV_getVoxel_double; - volume->setRegion = &GBBVDouble_setRegionTask; + volume->setRegion = &GBBV_setRegionTask_double; volume->super.super.computeSample = GBBV_computeSample_double; } else { From 89a7680dfe2e262538ceefc9b66bef3b1fa3f2d3 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 23 Mar 2016 21:02:49 -0500 Subject: [PATCH 140/310] parallelize accumulation buffer clearing for localFB, remove dead code --- ospray/fb/LocalFB.cpp | 20 +++++++++++++------- ospray/fb/LocalFB.ispc | 25 +++++++++++-------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 3a8d7e1039..c432155add 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -14,8 +14,14 @@ // limitations under the License. // // ======================================================================== // +//ospray #include "LocalFB.h" #include "LocalFB_ispc.h" +#include "ospray/common/tasking/parallel_for.h" + +// number of floats each task is clearing; must be a a mulitple of 16 +// NOTE(jda) - must match CLEAR_BLOCK_SIZE defined in LocalFB.ispc! +#define CLEAR_BLOCK_SIZE (32 * 1024) namespace ospray { @@ -83,14 +89,19 @@ namespace ospray { void LocalFrameBuffer::clear(const uint32 fbChannelFlags) { if (fbChannelFlags & OSP_FB_ACCUM) { - ispc::LocalFrameBuffer_clearAccum(getIE()); + void *thisIE = getIE(); + const int num_floats = 4 * size.x * size.y; + const int num_blocks = (num_floats + CLEAR_BLOCK_SIZE - 1) + / CLEAR_BLOCK_SIZE; + parallel_for(num_blocks,[&](int taskIndex) { + ispc::LocalFrameBuffer_clearAccum(thisIE, taskIndex); + }); accumID = 0; } } void LocalFrameBuffer::setTile(Tile &tile) { -#if 1 if (pixelOp) pixelOp->preAccum(tile); if (accumBuffer) @@ -109,21 +120,16 @@ namespace ospray { NOTIMPLEMENTED; } } -#else - ispc::LocalFrameBuffer_setTile(getIE(),(ispc::Tile&)tile); -#endif } const void *LocalFrameBuffer::mapDepthBuffer() { - // waitForRenderTaskToBeReady(); this->refInc(); return (const void *)depthBuffer; } const void *LocalFrameBuffer::mapColorBuffer() { - // waitForRenderTaskToBeReady(); this->refInc(); return (const void *)colorBuffer; } diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index dcc5459195..b6f4399263 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -17,28 +17,25 @@ #include "LocalFB.ih" // number of floats each task is clearing; must be a a mulitple of 16 +// NOTE(jda) - must match CLEAR_BLOCK_SIZE defined in LocalFB.cpp! #define CLEAR_BLOCK_SIZE (32 * 1024) -export void LocalFrameBuffer_clearAccum(void *uniform _fb) +export void LocalFrameBuffer_clearAccum(void *uniform _fb, + uniform int taskIndex) { uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; fb->super.accumID = 0; if (fb->accumBuffer) { + uniform float *uniform fbPointer + = (uniform float *uniform)&fb->accumBuffer[0].x; + uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; - uniform size_t num_blocks = (num_floats + CLEAR_BLOCK_SIZE - 1) / CLEAR_BLOCK_SIZE; - - //NOTE(jda) - this needs to be threaded? seems to perform ok as-is... - for(uniform int taskIndex = 0; taskIndex < num_blocks; ++taskIndex) { - uniform float *uniform fbPointer - = (uniform float *uniform)&fb->accumBuffer[0].x; - uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; - uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; - - uniform int end = min(CLEAR_BLOCK_SIZE, - num_floats - taskIndex * CLEAR_BLOCK_SIZE); - foreach (x=0 ... end) - block[x] = 0.f; + + uniform int end = min(CLEAR_BLOCK_SIZE, + num_floats - (taskIndex * CLEAR_BLOCK_SIZE)); + foreach (x=0 ... end) { + block[x] = 0.f; } } } From 530a09b7935d8ce2d6c329f6996e9641cf27d1f1 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 23 Mar 2016 21:07:34 -0500 Subject: [PATCH 141/310] fix CMake bug for KNC builds, remove unused header include --- common/CMakeLists.txt | 10 ++++++---- ospray/mpi/DistributedFrameBuffer.cpp | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d69c809870..48bb219ebb 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -39,10 +39,12 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED vec.h ) -TARGET_LINK_LIBRARIES(ospray_common - # for network.cpp - pthread -) +IF(NOT THIS_IS_MIC) + TARGET_LINK_LIBRARIES(ospray_common + # for network.cpp + pthread + ) +ENDIF() OSPRAY_SET_LIBRARY_VERSION(ospray_common) OSPRAY_INSTALL_LIBRARY(ospray_common) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index d7413a2038..553be09ac0 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -20,8 +20,6 @@ #include "ospray/common/tasking/async.h" #include "ospray/common/tasking/parallel_for.h" -#include - #ifdef _WIN32 # define NOMINMAX # include // for Sleep From 4630fcb4d1f8a05eec45d7b9dc251812d4f0f42c Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 23 Mar 2016 21:15:43 -0500 Subject: [PATCH 142/310] remove more dead code, minor formatting --- ospray/fb/LocalFB.ispc | 79 +++--------------------------------------- 1 file changed, 4 insertions(+), 75 deletions(-) diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index b6f4399263..61ddbb0478 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -76,80 +76,9 @@ export void LocalFrameBuffer_writeTile_RGBA_I8(void *uniform _fb, col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); const uint32 asRGBA = cvt_uint32(col); - - // uniform bool hasDepth = (fb->depthBuffer != NULL); - // const uniform float accScale = 1.f/(fb->inherited.accumID+1); - // if (fb->inherited.colorBufferFormat == ColorBufferFormat_RGBA_FLOAT32) { - // uniform vec4f *uniform color - // = fb->colorBuffer - // ? (uniform vec4f *uniform)fb->colorBuffer - // : NULL; - // uniform vec4f *uniform accum - // = fb->accumBuffer - // ? (uniform vec4f *uniform)fb->accumBuffer - // : NULL; - // uniform float *uniform depth - // = fb->depthBuffer - // ? (uniform float *uniform)fb->depthBuffer - // : NULL; - // for (uniform int i=0;iinherited.size.x+x; - // const vec4f value = getRGBA(tile,pixID); - // if (x < fb->inherited.size.x & y < fb->inherited.size.y) { - // if (accum) { - // vec4f acc = accum[ofs]+value; - // accum[ofs] = acc; - // if (color) { - // color[ofs] = pow(max(acc * accScale,make_vec4f(0.f)), rcpf(fb->inherited.gamma)); - // } - // } else - // if (color) - // color[ofs] = pow(max(value,make_vec4f(0.f)), rcpf(fb->inherited.gamma)); - // if (depth) - // fb->depthBuffer[ofs] = tile.z[pixID]; - // } - // } - // } else if (fb->super.colorBufferFormat == ColorBufferFormat_RGBA_UINT8) { - // uniform uint32 *uniform color - // = fb->colorBuffer - // ? (uniform uint32 *uniform)fb->colorBuffer - // : NULL; - // uniform vec4f *uniform accum - // = fb->accumBuffer - // ? (uniform vec4f *uniform)fb->accumBuffer - // : NULL; - // uniform float *uniform depth - // = fb->depthBuffer - // ? (uniform float *uniform)fb->depthBuffer - // : NULL; - - - // for (uniform int i=0;isuper.size.x+x; - // const vec4f value = getRGBA(tile,pixID); - // if (x < fb->super.size.x & y < fb->super.size.y) { - // if (accum) { - // vec4f acc = accum[ofs]+value; - // accum[ofs] = acc; - // if (color) { - // color[ofs] = cvt_uint32(pow(max(acc * accScale,make_vec4f(0.f)), rcpf(fb->super.gamma))); - // } - // } else - // if (color) - // color[ofs] = cvt_uint32(pow(max(value,make_vec4f(0.f)), rcpf(fb->super.gamma))); - // if (depth) - // fb->depthBuffer[ofs] = tile.z[pixID]; - // } } color[pixelID] = asRGBA; - if (depth) - fb->depthBuffer[pixelID] = varyTile->z[chunkID]; + if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; } } } @@ -185,12 +114,12 @@ export void LocalFrameBuffer_writeTile_RGBA_F32(void *uniform _fb, varyTile->b[chunkID], varyTile->a[chunkID]); - // XXX not even hardcoded gamma for float buffer, should use pixelops anyway + // XXX not even hardcoded gamma for float buffer, + // should use pixelops anyway col = max(col, make_vec4f(0.f)); } color[pixelID] = col; - if (depth) - fb->depthBuffer[pixelID] = varyTile->z[chunkID]; + if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; } } } From 4d4c27a37090407e2dc13f31b54ff88e5e30960d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 17 Mar 2016 22:49:17 +0100 Subject: [PATCH 143/310] Make variance buffer optional --- ospray/api/LocalDevice.cpp | 4 ++- ospray/fb/FrameBuffer.cpp | 4 ++- ospray/fb/FrameBuffer.h | 10 +++--- ospray/fb/LocalFB.cpp | 60 ++++++++++++++++------------------ ospray/fb/LocalFB.h | 9 ++--- ospray/fb/LocalFB.ih | 4 +-- ospray/fb/LocalFB.ispc | 45 +++++++++++++++++-------- ospray/include/ospray/ospray.h | 4 +-- 8 files changed, 82 insertions(+), 58 deletions(-) diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index aa6cc7aa63..ed2a10c89f 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -84,9 +84,11 @@ namespace ospray { FrameBuffer::ColorBufferFormat colorBufferFormat = mode; //FrameBuffer::RGBA_UINT8;//FLOAT32; bool hasDepthBuffer = (channels & OSP_FB_DEPTH)!=0; bool hasAccumBuffer = (channels & OSP_FB_ACCUM)!=0; + bool hasVarianceBuffer = (channels & OSP_FB_VARIANCE)!=0; FrameBuffer *fb = new LocalFrameBuffer(size,colorBufferFormat, - hasDepthBuffer,hasAccumBuffer); + hasDepthBuffer,hasAccumBuffer, + hasVarianceBuffer); fb->refInc(); return (OSPFrameBuffer)fb; } diff --git a/ospray/fb/FrameBuffer.cpp b/ospray/fb/FrameBuffer.cpp index 0af655a9d6..02fec8e62e 100644 --- a/ospray/fb/FrameBuffer.cpp +++ b/ospray/fb/FrameBuffer.cpp @@ -23,11 +23,13 @@ namespace ospray { FrameBuffer::FrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, bool hasDepthBuffer, - bool hasAccumBuffer) + bool hasAccumBuffer, + bool hasVarianceBuffer) : size(size), colorBufferFormat(colorBufferFormat), hasDepthBuffer(hasDepthBuffer), hasAccumBuffer(hasAccumBuffer), + hasVarianceBuffer(hasVarianceBuffer), accumID(-1) { managedObjectType = OSP_FRAMEBUFFER; diff --git a/ospray/fb/FrameBuffer.h b/ospray/fb/FrameBuffer.h index b554dfc0fe..888fa713ac 100644 --- a/ospray/fb/FrameBuffer.h +++ b/ospray/fb/FrameBuffer.h @@ -61,7 +61,8 @@ namespace ospray { FrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, bool hasDepthBuffer, - bool hasAccumBuffer); + bool hasAccumBuffer, + bool hasVarianceBuffer = false); virtual void commit(); @@ -79,12 +80,13 @@ namespace ospray { virtual std::string toString() const { return "ospray::FrameBuffer"; } - /*! indicates whether the app requested this frame buffer to have - an accumulation buffer */ - bool hasAccumBuffer; /*! indicates whether the app requested this frame buffer to have an (application-mappable) depth buffer */ bool hasDepthBuffer; + /*! indicates whether the app requested this frame buffer to have + an accumulation buffer */ + bool hasAccumBuffer; + bool hasVarianceBuffer; /*! buffer format of the color buffer */ ColorBufferFormat colorBufferFormat; diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 138f10e0a5..5b304747db 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -22,10 +22,11 @@ namespace ospray { LocalFrameBuffer::LocalFrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, bool hasDepthBuffer, - bool hasAccumBuffer, + bool hasAccumBuffer, + bool hasVarianceBuffer, void *colorBufferToUse) - : FrameBuffer(size, colorBufferFormat, hasDepthBuffer, hasAccumBuffer) - { + : FrameBuffer(size, colorBufferFormat, hasDepthBuffer, hasAccumBuffer, hasVarianceBuffer) + { Assert(size.x > 0); Assert(size.y > 0); if (colorBufferToUse) @@ -50,48 +51,45 @@ namespace ospray { depthBuffer = (float*)alignedMalloc(sizeof(float)*size.x*size.y); else depthBuffer = NULL; - - if (hasAccumBuffer) { + + if (hasAccumBuffer) accumBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); - accumHalfBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); - tileErrorBuffer = new float[divRoundUp(size.x,TILE_SIZE)*divRoundUp(size.y,TILE_SIZE)]; - } else + else accumBuffer = NULL; + + if (hasVarianceBuffer) { + varianceBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); + tileErrorBuffer = new float[divRoundUp(size.x,TILE_SIZE)*divRoundUp(size.y,TILE_SIZE)]; + } else { + varianceBuffer = NULL; + tileErrorBuffer = NULL; + } + ispcEquivalent = ispc::LocalFrameBuffer_create(this,size.x,size.y, colorBufferFormat, colorBuffer, depthBuffer, accumBuffer, - accumHalfBuffer, + varianceBuffer, tileErrorBuffer); } - - LocalFrameBuffer::~LocalFrameBuffer() - { - if (depthBuffer) alignedFree(depthBuffer); - if (colorBuffer) - switch(colorBufferFormat) { - case OSP_RGBA_F32: - alignedFree(colorBuffer); - break; - case OSP_RGBA_I8: - alignedFree(colorBuffer); - break; - default: - throw std::runtime_error("color buffer format not supported"); - } - if (accumBuffer) { - alignedFree(accumBuffer); - alignedFree(accumHalfBuffer); - delete[] tileErrorBuffer; - } + LocalFrameBuffer::~LocalFrameBuffer() + { + alignedFree(depthBuffer); + alignedFree(colorBuffer); + alignedFree(accumBuffer); + alignedFree(varianceBuffer); + delete[] tileErrorBuffer; } void LocalFrameBuffer::clear(const uint32 fbChannelFlags) { if (fbChannelFlags & OSP_FB_ACCUM) { ispc::LocalFrameBuffer_clearAccum(getIE()); + // always also clear variance buffer -- only clearing accumulation buffer + // is meaningless + ispc::LocalFrameBuffer_clearVariance(getIE()); accumID = 0; } } @@ -128,14 +126,14 @@ namespace ospray { this->refInc(); return (const void *)depthBuffer; } - + const void *LocalFrameBuffer::mapColorBuffer() { // waitForRenderTaskToBeReady(); this->refInc(); return (const void *)colorBuffer; } - + void LocalFrameBuffer::unmap(const void *mappedMem) { Assert(mappedMem == colorBuffer || mappedMem == depthBuffer ); diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index d8df31a270..90ce7342ff 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -28,17 +28,18 @@ namespace ospray { NULL */ float *depthBuffer; /*!< one float per pixel, may be NULL */ vec4f *accumBuffer; /*!< one RGBA per pixel, may be NULL */ - vec4f *accumHalfBuffer; /*!< one RGBA per pixel, may be NULL, accumulates every other sample, for variance estimation / stopping */ + vec4f *varianceBuffer; /*!< one RGBA per pixel, may be NULL, accumulates every other sample, for variance estimation / stopping */ float *tileErrorBuffer; /*!< holds error per tile, for variance estimation / stopping */ LocalFrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, bool hasDepthBuffer, - bool hasAccumBuffer, + bool hasAccumBuffer, + bool hasVarianceBuffer, void *colorBufferToUse=NULL); virtual ~LocalFrameBuffer(); - - //! \brief common function to help printf-debugging + + //! \brief common function to help printf-debugging /*! \detailed Every derived class should overrride this! */ virtual std::string toString() const { return "ospray::LocalFrameBuffer"; } diff --git a/ospray/fb/LocalFB.ih b/ospray/fb/LocalFB.ih index 0e8b879f8f..3861ab1136 100644 --- a/ospray/fb/LocalFB.ih +++ b/ospray/fb/LocalFB.ih @@ -22,13 +22,13 @@ /*! a Local FrameBuffer that stores all pixel values (color, depth, accum) in a plain 2D array of pixels (one array per component) */ -struct LocalFB +struct LocalFB { FrameBuffer super; /*!< superclass that we inherit from */ void *colorBuffer; uniform float *depthBuffer; uniform vec4f *accumBuffer; - uniform vec4f *accumHalfBuffer; // accumulates every other sample, for variance estimation / stopping + uniform vec4f *varianceBuffer; // accumulates every other sample, for variance estimation / stopping vec2i numTiles; uniform float *tileErrorBuffer; }; diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index f2eef4d13b..ba8a6b0852 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -21,7 +21,6 @@ export void LocalFrameBuffer_clearAccum(void *uniform _fb) { - print("LocalFrameBuffer_clearAccum\n"); uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; fb->super.accumID = 0; @@ -33,22 +32,42 @@ export void LocalFrameBuffer_clearAccum(void *uniform _fb) for(uniform int taskIndex = 0; taskIndex < num_blocks; ++taskIndex) { uniform float *uniform fbPointer = (uniform float *uniform)&fb->accumBuffer[0].x; - uniform float *uniform fbHalfPointer - = (uniform float *uniform)&fb->accumHalfBuffer[0].x; uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; - uniform float *uniform blockHalf = fbHalfPointer + taskIndex * CLEAR_BLOCK_SIZE; uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; uniform int end = min(CLEAR_BLOCK_SIZE, num_floats - taskIndex * CLEAR_BLOCK_SIZE); - foreach (x=0 ... end) { + foreach (x=0 ... end) block[x] = 0.f; - blockHalf[x] = 0.f; - } } + } +} + +export void LocalFrameBuffer_clearVariance(void *uniform _fb) +{ + print("LocalFrameBuffer_clearVariance"); + uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; + + if (fb->varianceBuffer) { + uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; + uniform size_t num_blocks = (num_floats + CLEAR_BLOCK_SIZE - 1) / CLEAR_BLOCK_SIZE; + + for(uniform int taskIndex = 0; taskIndex < num_blocks; ++taskIndex) { + uniform float *uniform fbPointer + = (uniform float *uniform)&fb->varianceBuffer[0].x; + uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; + uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; + + uniform int end = min(CLEAR_BLOCK_SIZE, + num_floats - taskIndex * CLEAR_BLOCK_SIZE); + foreach (x=0 ... end) + block[x] = 0.f; + } + } + + if (fb->tileErrorBuffer) foreach (x=0 ... fb->numTiles.x*fb->numTiles.y) fb->tileErrorBuffer[x] = inf; - } } //! \brief write tile into the given frame buffer's color buffer @@ -197,7 +216,7 @@ export void LocalFrameBuffer_writeTile_RGBA_F32(void *uniform _fb, varyTile->a[chunkID]); // XXX not even hardcoded gamma for float buffer, should use pixelops anyway - col = max(col, make_vec4f(0.f)); + col = max(col, make_vec4f(0.f)); } color[pixelID] = col; if (depth) @@ -218,8 +237,8 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, uniform vec4f *uniform accum = (uniform vec4f *uniform)fb->accumBuffer; if (!accum) return; - uniform vec4f *uniform accumHalf = (uniform vec4f *uniform)fb->accumHalfBuffer; - + uniform vec4f *uniform accumHalf = (uniform vec4f *uniform)fb->varianceBuffer; + VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; uniform float * uniform tileError = &fb->tileErrorBuffer[tileIdx.y*fb->numTiles.x+tileIdx.x]; @@ -341,7 +360,7 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, void *uniform colorBuffer, void *uniform depthBuffer, void *uniform accumBuffer, - void *uniform accumHalfBuffer, + void *uniform varianceBuffer, void *uniform tileErrorBuffer) { uniform LocalFB *uniform self = uniform new uniform LocalFB; @@ -351,7 +370,7 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, self->colorBuffer = colorBuffer; self->depthBuffer = (uniform float *uniform)depthBuffer; self->accumBuffer = (uniform vec4f *uniform)accumBuffer; - self->accumHalfBuffer = (uniform vec4f *uniform)accumHalfBuffer; + self->varianceBuffer = (uniform vec4f *uniform)varianceBuffer; self->numTiles = (self->super.size+(TILE_SIZE-1))/TILE_SIZE; self->tileErrorBuffer = (uniform float *uniform)tileErrorBuffer; return self; diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 297f8f23be..834145d89b 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -137,7 +137,7 @@ typedef enum { OSP_FB_COLOR=(1<<0), OSP_FB_DEPTH=(1<<1), OSP_FB_ACCUM=(1<<2), - // OSP_FB_ALPHA=(1<<3) // not used anywhere; use OSP_FB_COLOR with a frame buffer format containing alpha in 4th channel + OSP_FB_VARIANCE=(1<<3) } OSPFrameBufferChannel; typedef enum { @@ -709,7 +709,7 @@ extern "C++" { { return ospNewTexture2D(&size.x,format,data,flags); } /*! c++ variant of ospNewFrameBuffer that can also be called with - referneces rather than with pointers */ + references rather than with pointers */ inline OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, const OSPFrameBufferFormat format=OSP_RGBA_I8, const uint32_t whichChannels=OSP_FB_COLOR) From b0155337dfe276afd54403d7f95ed4016f8e45c7 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 24 Mar 2016 19:08:24 -0500 Subject: [PATCH 144/310] add initial gitlab-ci configuration and build script --- .gitlab-ci.yml | 12 ++++++++++++ scripts/build_gitlab.sh | 7 +++++++ 2 files changed, 19 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100755 scripts/build_gitlab.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..874c9650f6 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,12 @@ +stages: + - build + +cmake/make: + type: build + script: + - scripts/build_gitlab.sh +# tags: +# - intel +# - xeon + allow_failure: false + diff --git a/scripts/build_gitlab.sh b/scripts/build_gitlab.sh new file mode 100755 index 0000000000..1a256e52a0 --- /dev/null +++ b/scripts/build_gitlab.sh @@ -0,0 +1,7 @@ +#/bin/sh + +mkdir build +cd build +rm -rf * +cmake .. +make -j`nproc` From 481148dcda35764b95944d438d382eea557e724c Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 25 Mar 2016 01:01:19 -0500 Subject: [PATCH 145/310] update gitlab-ci config to build on multiple OS runners --- .gitlab-ci.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 874c9650f6..75b24f5d48 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,30 @@ stages: - build -cmake/make: +build-centos6: type: build script: - scripts/build_gitlab.sh -# tags: -# - intel -# - xeon - allow_failure: false + tags: + - centos6 +build-centos7: + type: build + script: + - scripts/build_gitlab.sh + tags: + - centos7 + +build-fedora: + type: build + script: + - scripts/build_gitlab.sh + tags: + - fedora + +build-ubuntu: + type: build + script: + - scripts/build_gitlab.sh + tags: + - fedora From 989973ffca0437529bad3d0d20998b7887f4c466 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 25 Mar 2016 10:24:57 -0500 Subject: [PATCH 146/310] fix typo in gitlab-ci config, add script to trigger builds manually --- .gitlab-ci.yml | 2 +- scripts/trigger_gitlab_ci.sh | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100755 scripts/trigger_gitlab_ci.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75b24f5d48..5aeebffa31 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,4 +27,4 @@ build-ubuntu: script: - scripts/build_gitlab.sh tags: - - fedora + - ubuntu diff --git a/scripts/trigger_gitlab_ci.sh b/scripts/trigger_gitlab_ci.sh new file mode 100755 index 0000000000..5a3c506a65 --- /dev/null +++ b/scripts/trigger_gitlab_ci.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +REF_NAME=${1} + +if [[ -n "${REF_NAME}" ]]; then + echo "Triggering CI build of branch '${REF_NAME}'" +else + echo "No branch name specified, defaulting to 'devel'" + REF_NAME="devel" +fi + +curl -X POST \ + -F token=32b3258c799f57f1c6159585ce133b \ + -F ref=${REF_NAME} \ + https://gitlab.com/api/v3/projects/998314/trigger/builds From bb6c9f1a8a47e276415fcbfe3b28fbec5627195a Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 28 Mar 2016 14:09:00 -0500 Subject: [PATCH 147/310] - qtviewer now by default uses scivis renderer - box now has 'contains(vec)' method --- apps/qtViewer/main.cpp | 2 +- common/box.h | 3 +++ ospray/math/vec.ih | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/qtViewer/main.cpp b/apps/qtViewer/main.cpp index 73587dd554..1507034cac 100644 --- a/apps/qtViewer/main.cpp +++ b/apps/qtViewer/main.cpp @@ -31,7 +31,7 @@ namespace ospray { using std::cout; using std::endl; - static const std::string DEFAULT_INTEGRATOR_NAME = "ao2"; + static const std::string DEFAULT_INTEGRATOR_NAME = "scivis"; //ao2"; // static const std::string DEFAULT_INTEGRATOR_NAME = "eyeLight_geomID"; diff --git a/common/box.h b/common/box.h index 74a6d7c526..f201252433 100644 --- a/common/box.h +++ b/common/box.h @@ -39,6 +39,9 @@ namespace ospcommon { inline vec_t center() const { return 0.5f * (lower+upper); } inline bool empty() const { return anyLessThan(upper,lower); } + inline bool contains(const vec_t &vec) const + { return !anyLessThan(vec,lower) && !anyLessThan(upper,vec); } + vec_t lower, upper; }; diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 676b83afe5..da4a76069e 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -723,6 +723,9 @@ inline uniform vec3f powf(const uniform vec3f v, const uniform float f) inline vec3f clamp(const vec3f &a, const uniform vec3f &b, const uniform vec3f &c) { return(make_vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); } +inline vec3i clamp(const vec3i &a, const uniform vec3i &b, const uniform vec3i &c) +{ return(make_vec3i(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); } + //! The next machine representable number from 'a' in the direction of 'b'. inline uniform vec3f nextafter(const uniform vec3i &a, const uniform vec3i &b) { return(make_vec3f(nextafter(a.x, b.x), nextafter(a.y, b.y), nextafter(a.z, b.z))); } From 5f1c78757338d5eac0fd873bb79dbfae36da37b7 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 28 Mar 2016 17:08:37 -0500 Subject: [PATCH 148/310] BUGFIX in common/box.h - 'extend()' didn't work properly --- common/box.h | 7 +++++-- ospray/include/ospray/OSPDataType.h | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/common/box.h b/common/box.h index f201252433..8659980e1d 100644 --- a/common/box.h +++ b/common/box.h @@ -32,8 +32,8 @@ namespace ospcommon { inline box_t(const vec_t &lower, const vec_t &upper) : lower(lower), upper(upper) {} inline vec_t size() const { return upper - lower; } - inline void extend(const vec_t &v) { lower=min(lower,v), upper=max(upper,v); } - inline void extend(const box_t &b) { lower=min(lower,b.lower), upper=max(upper,b.upper); } + inline void extend(const vec_t &v) { lower=min(lower,v); upper=max(upper,v); } + inline void extend(const box_t &b) { lower=min(lower,b.lower); upper=max(upper,b.upper); } /*! returns the center of the box (not valid for empty boxes) */ inline vec_t center() const { return 0.5f * (lower+upper); } @@ -42,6 +42,9 @@ namespace ospcommon { inline bool contains(const vec_t &vec) const { return !anyLessThan(vec,lower) && !anyLessThan(upper,vec); } + inline box_t &operator=(const box_t &o) + { lower = o.lower; upper = o.upper; return *this; } + vec_t lower, upper; }; diff --git a/ospray/include/ospray/OSPDataType.h b/ospray/include/ospray/OSPDataType.h index 6cb5c557ba..8044ab1544 100644 --- a/ospray/include/ospray/OSPDataType.h +++ b/ospray/include/ospray/OSPDataType.h @@ -47,7 +47,7 @@ typedef enum { OSP_CHAR =100, //! Unsigned character scalar and vector types. - OSP_UCHAR =110, OSP_UCHAR2, OSP_UCHAR3, OSP_UCHAR4, + OSP_UCHAR =110, OSP_UCHAR2, OSP_UCHAR3, OSP_UCHAR4, //! Signed integer scalar and vector types. OSP_INT =120, OSP_INT2, OSP_INT3, OSP_INT4, @@ -72,3 +72,4 @@ typedef enum { } OSPDataType; +#define OSP_RAW OSP_UCHAR From 18bc6573225f64736a621086a1b1d53ab854ebbb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 28 Mar 2016 19:37:04 -0500 Subject: [PATCH 149/310] disable denormals config code which casuses issues in icc builds --- ospray/common/OSPCommon.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 6cd2d5486a..84e573fc71 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -133,6 +133,9 @@ namespace ospray { } #endif + // NOTE(jda) - This doesn't seem to be the right solution, needs further + // investigation before enabling again....temporarily disable +#if 0 // NOTE(jda) - Make sure that each thread (both calling application thread // and OSPRay worker threads) has the correct denormals flags // set. @@ -156,6 +159,7 @@ namespace ospray { while(counter < NTASKS); }); } +#endif } void error_handler(const RTCError code, const char *str) From d8e7c36afa62cb7e929c7bbb48c5cc4b4b68e04c Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 28 Mar 2016 19:51:49 -0500 Subject: [PATCH 150/310] only set denormal flags in OSPRay threads, not library threads - leave it to threading libraries to decide, less invasive --- ospray/common/OSPCommon.cpp | 28 ---------------------------- ospray/common/Thread.cpp | 3 +++ 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 84e573fc71..9ef6dcd1ba 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -132,34 +132,6 @@ namespace ospray { std::cerr << "WARNING: " << e.what() << std::endl; } #endif - - // NOTE(jda) - This doesn't seem to be the right solution, needs further - // investigation before enabling again....temporarily disable -#if 0 - // NOTE(jda) - Make sure that each thread (both calling application thread - // and OSPRay worker threads) has the correct denormals flags - // set. - - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); - - const int NTASKS = std::min((uint32_t)numThreads, - std::thread::hardware_concurrency()) - 1; - - AtomicInt counter; - counter = 0; - - // Force each worker thread to pickup exactly one task which sets denormals - // flags, where each thread spins until they are all done. - for (int i = 0; i < NTASKS; ++i) { - async([&]() { - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); - counter++; - while(counter < NTASKS); - }); - } -#endif } void error_handler(const RTCError code, const char *str) diff --git a/ospray/common/Thread.cpp b/ospray/common/Thread.cpp index 66e1b84dc1..f5440693ee 100644 --- a/ospray/common/Thread.cpp +++ b/ospray/common/Thread.cpp @@ -30,6 +30,9 @@ namespace ospray { ospcommon::setAffinity(t->desiredThreadID); } + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); + t->run(); } From 0255469aa820f6d18a6b432f4329be8191dcbeba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Sat, 26 Mar 2016 00:08:15 +0100 Subject: [PATCH 151/310] Track accumID per tile for adaptive accumulation --- ospray/fb/FrameBuffer.cpp | 3 +- ospray/fb/FrameBuffer.h | 13 ++- ospray/fb/FrameBuffer.ih | 1 - ospray/fb/FrameBuffer.ispc | 2 - ospray/fb/LocalFB.cpp | 27 ++++-- ospray/fb/LocalFB.h | 4 + ospray/fb/LocalFB.ih | 4 +- ospray/fb/LocalFB.ispc | 108 +++++++---------------- ospray/fb/Tile.h | 1 + ospray/fb/Tile.ih | 2 + ospray/render/LoadBalancer.cpp | 24 +++-- ospray/render/Renderer.cpp | 4 +- ospray/render/Renderer.h | 7 +- ospray/render/Renderer.ih | 3 +- ospray/render/Renderer.ispc | 24 +++-- ospray/render/pathtracer/PathTracer.ispc | 19 ++-- 16 files changed, 112 insertions(+), 134 deletions(-) diff --git a/ospray/fb/FrameBuffer.cpp b/ospray/fb/FrameBuffer.cpp index 02fec8e62e..f89a0430ab 100644 --- a/ospray/fb/FrameBuffer.cpp +++ b/ospray/fb/FrameBuffer.cpp @@ -29,8 +29,7 @@ namespace ospray { colorBufferFormat(colorBufferFormat), hasDepthBuffer(hasDepthBuffer), hasAccumBuffer(hasAccumBuffer), - hasVarianceBuffer(hasVarianceBuffer), - accumID(-1) + hasVarianceBuffer(hasVarianceBuffer) { managedObjectType = OSP_FRAMEBUFFER; Assert(size.x > 0 && size.y > 0); diff --git a/ospray/fb/FrameBuffer.h b/ospray/fb/FrameBuffer.h index 888fa713ac..a04bd16644 100644 --- a/ospray/fb/FrameBuffer.h +++ b/ospray/fb/FrameBuffer.h @@ -91,15 +91,12 @@ namespace ospray { /*! buffer format of the color buffer */ ColorBufferFormat colorBufferFormat; - /*! tracks how many times we have already accumulated into this - frame buffer. A value of '<0' means that accumulation is - disabled (in which case the renderer may not access the - accumulation buffer); in all other cases this value indicates - how many frames have already been accumulated in this frame - buffer. Note that it is up to the application to properly - reset the accumulationID (using ospClearAccum(fb)) if anything + /*! how often has been accumulated into that tile + Note that it is up to the application to properly + reset the accumulationIDs (using ospClearAccum(fb)) if anything changes that requires clearing the accumulation buffer. */ - int32 accumID; + virtual int32 accumID(const vec2i &tile) = 0; + virtual float tileError(const vec2i &tile) = 0; Ref pixelOp; }; diff --git a/ospray/fb/FrameBuffer.ih b/ospray/fb/FrameBuffer.ih index 89c68bc05b..98e92105e8 100644 --- a/ospray/fb/FrameBuffer.ih +++ b/ospray/fb/FrameBuffer.ih @@ -38,7 +38,6 @@ struct FrameBuffer vec2i size; /*!< size (width x height) of frame buffer, in pixels */ vec2f rcpSize; /*! one over size (precomputed) */ uniform float gamma; /*! gamma correction */ - int32 accumID; FrameBuffer_ColorBufferFormat colorBufferFormat; diff --git a/ospray/fb/FrameBuffer.ispc b/ospray/fb/FrameBuffer.ispc index 3040efa41a..4561bbf33e 100644 --- a/ospray/fb/FrameBuffer.ispc +++ b/ospray/fb/FrameBuffer.ispc @@ -20,7 +20,6 @@ void FrameBuffer_Constructor(FrameBuffer *uniform self, void *uniform cClassPtr) { self->cClassPtr = cClassPtr; - self->accumID = -1; self->size.x = 0; self->size.y = 0; self->rcpSize.x = 0.f; @@ -33,7 +32,6 @@ void FrameBuffer_set(FrameBuffer *uniform self, const uniform uint32 size_y, uniform int32 colorBufferFormat) { - self->accumID = -1; self->size.x = size_x; self->size.y = size_y; self->rcpSize.x = 1.f/size_x; diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 5b304747db..ac15185d05 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -57,9 +57,13 @@ namespace ospray { else accumBuffer = NULL; + tilesx = divRoundUp(size.x, TILE_SIZE); + int tiles = tilesx * divRoundUp(size.y, TILE_SIZE); + tileAccumID = new int32[tiles]; + if (hasVarianceBuffer) { varianceBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); - tileErrorBuffer = new float[divRoundUp(size.x,TILE_SIZE)*divRoundUp(size.y,TILE_SIZE)]; + tileErrorBuffer = new float[tiles]; } else { varianceBuffer = NULL; tileErrorBuffer = NULL; @@ -71,6 +75,7 @@ namespace ospray { depthBuffer, accumBuffer, varianceBuffer, + tileAccumID, tileErrorBuffer); } @@ -80,6 +85,7 @@ namespace ospray { alignedFree(colorBuffer); alignedFree(accumBuffer); alignedFree(varianceBuffer); + delete[] tileAccumID; delete[] tileErrorBuffer; } @@ -90,13 +96,14 @@ namespace ospray { // always also clear variance buffer -- only clearing accumulation buffer // is meaningless ispc::LocalFrameBuffer_clearVariance(getIE()); - accumID = 0; + int tiles = hasVarianceBuffer ? tilesx * divRoundUp(size.y, TILE_SIZE) : 1; + for (int i = 0; i < tiles; i++) + tileAccumID[i] = 0; } } void LocalFrameBuffer::setTile(Tile &tile) { -#if 1 if (pixelOp) pixelOp->preAccum(tile); if (accumBuffer) @@ -115,9 +122,17 @@ namespace ospray { NOTIMPLEMENTED; } } -#else - ispc::LocalFrameBuffer_setTile(getIE(),(ispc::Tile&)tile); -#endif + } + + int32 LocalFrameBuffer::accumID(const vec2i &tile) + { + const int idx = hasVarianceBuffer ? tile.y * tilesx + tile.x : 0; + return tileAccumID[idx]; + } + + float LocalFrameBuffer::tileError(const vec2i &tile) + { + return hasVarianceBuffer ? tileErrorBuffer[tile.y * tilesx + tile.x] : 0.0f; } const void *LocalFrameBuffer::mapDepthBuffer() diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index 90ce7342ff..a4b95c2c97 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -29,7 +29,9 @@ namespace ospray { float *depthBuffer; /*!< one float per pixel, may be NULL */ vec4f *accumBuffer; /*!< one RGBA per pixel, may be NULL */ vec4f *varianceBuffer; /*!< one RGBA per pixel, may be NULL, accumulates every other sample, for variance estimation / stopping */ + int32 *tileAccumID; //< holds accumID per tile, for adaptive accumulation float *tileErrorBuffer; /*!< holds error per tile, for variance estimation / stopping */ + int32 tilesx; LocalFrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, @@ -45,6 +47,8 @@ namespace ospray { { return "ospray::LocalFrameBuffer"; } virtual void setTile(Tile &tile); + virtual int32 accumID(const vec2i &tile); + virtual float tileError(const vec2i &tile); virtual const void *mapColorBuffer(); virtual const void *mapDepthBuffer(); diff --git a/ospray/fb/LocalFB.ih b/ospray/fb/LocalFB.ih index 3861ab1136..a03fe5bc87 100644 --- a/ospray/fb/LocalFB.ih +++ b/ospray/fb/LocalFB.ih @@ -29,7 +29,7 @@ struct LocalFB uniform float *depthBuffer; uniform vec4f *accumBuffer; uniform vec4f *varianceBuffer; // accumulates every other sample, for variance estimation / stopping + uniform int32 *tileAccumID; //< holds accumID per tile, for adaptive accumulation + uniform float *tileErrorBuffer; // store error per tile vec2i numTiles; - uniform float *tileErrorBuffer; }; - diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index ba8a6b0852..ad1150d114 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -22,7 +22,6 @@ export void LocalFrameBuffer_clearAccum(void *uniform _fb) { uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - fb->super.accumID = 0; if (fb->accumBuffer) { uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; @@ -45,7 +44,6 @@ export void LocalFrameBuffer_clearAccum(void *uniform _fb) export void LocalFrameBuffer_clearVariance(void *uniform _fb) { - print("LocalFrameBuffer_clearVariance"); uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; if (fb->varianceBuffer) { @@ -63,11 +61,10 @@ export void LocalFrameBuffer_clearVariance(void *uniform _fb) foreach (x=0 ... end) block[x] = 0.f; } - } - if (fb->tileErrorBuffer) foreach (x=0 ... fb->numTiles.x*fb->numTiles.y) fb->tileErrorBuffer[x] = inf; + } } //! \brief write tile into the given frame buffer's color buffer @@ -234,41 +231,15 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, uniform Tile &tile) { uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - uniform vec4f *uniform accum = (uniform vec4f *uniform)fb->accumBuffer; + uniform vec4f *uniform accum = fb->accumBuffer; if (!accum) return; - uniform vec4f *uniform accumHalf = (uniform vec4f *uniform)fb->varianceBuffer; - VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; - uniform float * uniform tileError = &fb->tileErrorBuffer[tileIdx.y*fb->numTiles.x+tileIdx.x]; -// print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, *tileError); - - if (*tileError < 0.0f) { - for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; - - uniform uint32 chunkID = iy*(TILE_SIZE/programCount); - - for (uint32 iix = tile.region.lower.x+programIndex; - iixsuper.size.x+iix; - vec4f acc = accum[pixelID]; - unmasked { - varyTile->r[chunkID] = -*tileError * acc.x; - varyTile->g[chunkID] = -*tileError * acc.y; - varyTile->b[chunkID] = -*tileError * acc.z; - varyTile->a[chunkID] = -*tileError * acc.w; - } - } - } - return; - } - const uniform float accScale = rcpf(fb->super.accumID+1); - const uniform float accHalfScale = rcpf(fb->super.accumID/2+1); + uniform vec4f *uniform variance = fb->varianceBuffer; + const uniform float accScale = rcpf(tile.accumID+1); + const uniform float accHalfScale = rcpf(tile.accumID/2+1); float err = 0.f; float cnt = 0.f; @@ -286,7 +257,7 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, /*! todo: rather than gathering, replace this code with 'load4f's and swizzles */ varying vec4f acc = make_vec4f(0.f); - if (fb->super.accumID > 0) + if (tile.accumID > 0) acc = accum[pixelID]; unmasked { acc.x += varyTile->r[chunkID]; @@ -297,24 +268,26 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, accum[pixelID] = acc; - varying vec3f accHalf = make_vec3f(0.f); - if (fb->super.accumID > 0) - accHalf = make_vec3f(accumHalf[pixelID]); - if ((fb->super.accumID & 1) == 0) { - unmasked { - accHalf.x += varyTile->r[chunkID]; - accHalf.y += varyTile->g[chunkID]; - accHalf.z += varyTile->b[chunkID]; + if (variance) { + varying vec3f vari = make_vec3f(0.f); + if (tile.accumID > 0) + vari = make_vec3f(variance[pixelID]); + if ((tile.accumID & 1) == 0) { + unmasked { + vari.x += varyTile->r[chunkID]; + vari.y += varyTile->g[chunkID]; + vari.z += varyTile->b[chunkID]; + } + + variance[pixelID] = make_vec4f(vari); } - - accumHalf[pixelID] = make_vec4f(accHalf); + const vec3f accs = accScale * make_vec3f(acc); + const vec3f diff = absf(accs - accHalfScale * vari); + const float den = sqrtf(accs.x + accs.y + accs.z); + if (den > 0) + err = err + (diff.x + diff.y + diff.z) / den; + cnt += 1.0f; } - vec3f accs = accScale * make_vec3f(acc); - vec3f diff = absf(accs - accHalfScale * accHalf); - float den = sqrtf(accs.x + accs.y + accs.z); - if (den > 0) - err = err + (diff.x + diff.y + diff.z) / den; - cnt += 1.0f; unmasked { varyTile->r[chunkID] = accScale * acc.x; @@ -324,32 +297,15 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, } } } - uniform float r = sqrt(reduce_add(cnt) / tile.fbSize.x / tile.fbSize.y); - uniform float errf = r * reduce_add(err) / reduce_add(cnt); -// print("[%, %]: \t%\t%\n", tile.region.lower.x/TILE_SIZE, tile.region.lower.y/TILE_SIZE, errf); - if (fb->super.accumID > 3 && errf < 0.0002f) - *tileError = -accScale; -#if 0 - for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; - - uniform uint32 chunkID = iy*(TILE_SIZE/programCount); - - for (uint32 iix = tile.region.lower.x+programIndex; - iixr[chunkID] = errf > 0.002 ? 1.0f : 0.0f; - varyTile->g[chunkID] = errf*100.f; - varyTile->b[chunkID] = errf > 0.0002f ? 0.4f : 0.0f; - varyTile->a[chunkID] = 1.f; - } - } + const uniform tileId = tileIdx.y*fb->numTiles.x + tileIdx.x; + fb->tileAccumID[tileId]++; + if (variance) { + const uniform float r = sqrt(reduce_add(cnt) / tile.fbSize.x / tile.fbSize.y); + const uniform float errf = r * reduce_add(err) / reduce_add(cnt); + // print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, errf); + fb->tileErrorBuffer[tileId] = errf; } -#endif - tile.g[0] = 1.0f; } @@ -361,6 +317,7 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, void *uniform depthBuffer, void *uniform accumBuffer, void *uniform varianceBuffer, + void *uniform tileAccumID, void *uniform tileErrorBuffer) { uniform LocalFB *uniform self = uniform new uniform LocalFB; @@ -372,6 +329,7 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, self->accumBuffer = (uniform vec4f *uniform)accumBuffer; self->varianceBuffer = (uniform vec4f *uniform)varianceBuffer; self->numTiles = (self->super.size+(TILE_SIZE-1))/TILE_SIZE; + self->tileAccumID = (uniform int32 *uniform)tileAccumID; self->tileErrorBuffer = (uniform float *uniform)tileErrorBuffer; return self; } diff --git a/ospray/fb/Tile.h b/ospray/fb/Tile.h index bcd1c08090..8a496484ba 100644 --- a/ospray/fb/Tile.h +++ b/ospray/fb/Tile.h @@ -50,6 +50,7 @@ namespace ospray { vec2f rcp_fbSize; int32 generation; int32 children; + int32 accumID; //!< how often has been accumulated into this tile }; } // ::ospray diff --git a/ospray/fb/Tile.ih b/ospray/fb/Tile.ih index 3475975f6d..6b70ef10ea 100644 --- a/ospray/fb/Tile.ih +++ b/ospray/fb/Tile.ih @@ -32,6 +32,7 @@ struct Tile { uniform vec2f rcp_fbSize; uniform int32 generation; uniform int32 children; + uniform int32 accumID; }; struct VaryingTile { @@ -45,6 +46,7 @@ struct VaryingTile { uniform vec2f rcp_fbSize; uniform int32 generation; uniform int32 children; + uniform int32 accumID; }; inline vec4f setRGBA(uniform Tile &tile, varying uint32 i, const varying vec4f rgba) diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index 82da53c9db..ae2253322a 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -53,9 +53,15 @@ namespace ospray { const int NTASKS = numTiles_x * numTiles_y; parallel_for(NTASKS, [&](int taskIndex){ - Tile tile; const size_t tile_y = taskIndex / numTiles_x; const size_t tile_x = taskIndex - tile_y*numTiles_x; + const vec2i tileID(tile_x, tile_y); + const int32 accumID = fb->accumID(tileID); + + if (accumID > 3 && fb->tileError(tileID) < renderer->errorThreshold) + return; + + Tile tile; tile.region.lower.x = tile_x * TILE_SIZE; tile.region.lower.y = tile_y * TILE_SIZE; tile.region.upper.x = std::min(tile.region.lower.x+TILE_SIZE,fb->size.x); @@ -64,9 +70,11 @@ namespace ospray { tile.rcp_fbSize = rcp(vec2f(tile.fbSize)); tile.generation = 0; tile.children = 0; + tile.children = 0; + tile.accumID = accumID; const int spp = renderer->spp; - const int blocks = (fb->accumID > 0 || spp > 0) ? 1 : + const int blocks = (accumID > 0 || spp > 0) ? 1 : std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); const size_t numJobs = ((TILE_SIZE*TILE_SIZE)/ RENDERTILE_PIXELS_PER_JOB + blocks-1)/blocks; @@ -110,10 +118,15 @@ namespace ospray { parallel_for(NTASKS, [&](int taskIndex){ int tileIndex = deviceID + numDevices * taskIndex; - - Tile tile; const size_t tile_y = tileIndex / numTiles_x; const size_t tile_x = tileIndex - tile_y*numTiles_x; + const vec2i tileID(tile_x, tile_y); + const int32 accumID = fb->accumID(tileID); + + if (accumID > 3 && fb->tileError(tileID) < renderer->errorThreshold) + return; + + Tile tile; tile.region.lower.x = tile_x * TILE_SIZE; tile.region.lower.y = tile_y * TILE_SIZE; tile.region.upper.x = std::min(tile.region.lower.x+TILE_SIZE,fb->size.x); @@ -122,9 +135,10 @@ namespace ospray { tile.rcp_fbSize = rcp(vec2f(tile.fbSize)); tile.generation = 0; tile.children = 0; + tile.accumID = accumID; const int spp = renderer->spp; - const int blocks = (fb->accumID > 0 || spp > 0) ? 1 : + const int blocks = (accumID > 0 || spp > 0) ? 1 : std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); const size_t numJobs = ((TILE_SIZE*TILE_SIZE)/ RENDERTILE_PIXELS_PER_JOB + blocks-1)/blocks; diff --git a/ospray/render/Renderer.cpp b/ospray/render/Renderer.cpp index 606db2d364..9462f3c755 100644 --- a/ospray/render/Renderer.cpp +++ b/ospray/render/Renderer.cpp @@ -125,9 +125,7 @@ namespace ospray { void Renderer::endFrame(void *perFrameData, const int32 fbChannelFlags) { FrameBuffer *fb = this->currentFB; - if ((fbChannelFlags & OSP_FB_ACCUM)) - fb->accumID++; - ispc::Renderer_endFrame(getIE(),perFrameData,fb->accumID); + ispc::Renderer_endFrame(getIE(),perFrameData); } void Renderer::renderFrame(FrameBuffer *fb, const uint32 channelFlags) diff --git a/ospray/render/Renderer.h b/ospray/render/Renderer.h index df761cf416..cff4cea6fe 100644 --- a/ospray/render/Renderer.h +++ b/ospray/render/Renderer.h @@ -35,7 +35,7 @@ namespace ospray { compositing or even projection/splatting based approaches */ struct Renderer : public ManagedObject { - Renderer() : spp(1) {} + Renderer() : spp(1), errorThreshold(0.0f) {} /*! \brief creates an abstract renderer class of given type @@ -87,7 +87,10 @@ namespace ospray { float epsilon; /*! \brief number of samples to be used per pixel in a tile */ - int32 spp; + int32 spp; + + /*! adaptive accumulation: variance-based error to reach */ + float errorThreshold; /*! \brief whether the background should be rendered (e.g. for compositing the background may be disabled) */ bool backgroundEnabled; diff --git a/ospray/render/Renderer.ih b/ospray/render/Renderer.ih index dcc3876433..d3283cf4ab 100644 --- a/ospray/render/Renderer.ih +++ b/ospray/render/Renderer.ih @@ -63,8 +63,7 @@ typedef unmasked void (*Renderer_RenderTileFct)(uniform Renderer *uniform self, typedef unmasked void *uniform (*Renderer_BeginFrameFct)(uniform Renderer *uniform self, uniform FrameBuffer *uniform fb); typedef unmasked void (*Renderer_EndFrameFct)(uniform Renderer *uniform self, - void *uniform perFrameData, - const uniform int32 newAccumID); + void *uniform perFrameData); struct Renderer { Renderer_RenderSampleFct renderSample; diff --git a/ospray/render/Renderer.ispc b/ospray/render/Renderer.ispc index 5a452851f0..b8130d201a 100644 --- a/ospray/render/Renderer.ispc +++ b/ospray/render/Renderer.ispc @@ -44,13 +44,10 @@ static unmasked void *uniform Renderer_default_beginFrame(uniform Renderer *unif } static unmasked void Renderer_default_endFrame(uniform Renderer *uniform self, - void *uniform perFrameData, - const uniform int32 accumID) + void *uniform perFrameData) { - if (self->fb) { - self->fb->accumID = accumID; + if (self->fb) self->fb = NULL; - } } unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, @@ -76,7 +73,7 @@ unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, const uniform int begin = taskIndex * RENDERTILE_PIXELS_PER_JOB; const uniform int end = begin + RENDERTILE_PIXELS_PER_JOB; - const uniform int startSampleID = max(fb->accumID,0)*spp; + const uniform int startSampleID = max(tile.accumID, 0)*spp; for (uniform uint32 i=begin;iaccumID >= 0) { - pixel_du = precomputedHalton2(fb->accumID); - pixel_dv = precomputedHalton3(fb->accumID); + if (tile.accumID >= 0) { + pixel_du = precomputedHalton2(tile.accumID); + pixel_dv = precomputedHalton3(tile.accumID); } ScreenSample screenSample; - screenSample.sampleID.z = fb->accumID; + screenSample.sampleID.z = tile.accumID; screenSample.z = inf; screenSample.alpha = 0.f; CameraSample cameraSample; - const uniform int blocks = fb->accumID > 0 || spp > 0 ? 1 : min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); + const uniform int blocks = tile.accumID > 0 || spp > 0 ? 1 : min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); const uniform int begin = taskIndex * RENDERTILE_PIXELS_PER_JOB; const uniform int end = min(begin + RENDERTILE_PIXELS_PER_JOB, TILE_SIZE*TILE_SIZE/blocks); @@ -220,11 +217,10 @@ export void *uniform Renderer_beginFrame(void *uniform _self, export void Renderer_endFrame(void *uniform _self, - void *uniform perFrameData, - const uniform int32 newAccumID) + void *uniform perFrameData) { uniform Renderer *uniform self = (uniform Renderer *uniform)_self; - self->endFrame(self,perFrameData,newAccumID); + self->endFrame(self, perFrameData); } export void Renderer_set(void *uniform _self, diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 427d4e72fd..9ee7db838c 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -294,7 +294,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, inline ScreenSample PathTracer_renderPixel(uniform PathTracer *uniform self, const uint32 ix, - const uint32 iy) + const uint32 iy, + const uint32 accumID) { uniform FrameBuffer *uniform fb = self->super.fb; @@ -309,11 +310,11 @@ inline ScreenSample PathTracer_renderPixel(uniform PathTracer *uniform self, // init RNG RandomTEA rng_state; varying RandomTEA* const uniform rng = &rng_state; - RandomTEA__Constructor(rng, fb->size.x*iy+ix, fb->accumID); + RandomTEA__Constructor(rng, fb->size.x*iy+ix, accumID); const int spp = max(1, self->super.spp); for (uniform int s=0; s < spp; s++) { - screenSample.sampleID.z = fb->accumID*spp + s; + screenSample.sampleID.z = accumID*spp + s; CameraSample cameraSample; const vec2f pixelSample = RandomTEA__getFloats(rng); @@ -356,16 +357,10 @@ void PathTracer_renderTileJob(uniform PathTracer *uniform self, uniform Tile &tile, uniform int taskIndex) { - uniform FrameBuffer *uniform fb = self->super.fb; - uniform LocalFB *uniform lfb = (uniform LocalFB *uniform )self->super.fb; - - uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; - if (lfb->tileErrorBuffer[tileIdx.y*lfb->numTiles.x+tileIdx.x] < 0.0f) - return; + uniform FrameBuffer *uniform fb = self->super.fb; uniform int32 spp = self->super.spp; - - const uniform int blocks = fb->accumID > 0 || spp > 0 ? + const uniform int blocks = tile.accumID > 0 || spp > 0 ? 1 : min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); const uniform int begin = taskIndex * RENDERTILE_PIXELS_PER_JOB; @@ -377,7 +372,7 @@ void PathTracer_renderTileJob(uniform PathTracer *uniform self, if (ix >= fb->size.x || iy >= fb->size.y) continue; - ScreenSample screenSample = PathTracer_renderPixel(self, ix, iy); + ScreenSample screenSample = PathTracer_renderPixel(self, ix, iy, tile.accumID); for (uniform int p = 0; p < blocks; p++) { const uint32 pixel = z_order.xs[i*blocks+p] + (z_order.ys[i*blocks+p] * TILE_SIZE); From a214e98983d40ff062c855e2dc5f0013052d4784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Sat, 26 Mar 2016 00:42:53 +0100 Subject: [PATCH 152/310] renderFrame returns variance for automatic stopping --- ospray/api/API.cpp | 4 ++-- ospray/api/Device.h | 2 +- ospray/api/LocalDevice.cpp | 6 +++--- ospray/api/LocalDevice.h | 2 +- ospray/include/ospray/ospray.h | 7 ++++--- ospray/render/LoadBalancer.cpp | 15 +++++++++++++-- ospray/render/LoadBalancer.h | 6 +++--- ospray/render/Renderer.cpp | 5 +++-- ospray/render/Renderer.h | 2 +- 9 files changed, 31 insertions(+), 18 deletions(-) diff --git a/ospray/api/API.cpp b/ospray/api/API.cpp index b37a0e1417..26edb3f0e7 100644 --- a/ospray/api/API.cpp +++ b/ospray/api/API.cpp @@ -450,7 +450,7 @@ extern "C" void ospFrameBufferClear(OSPFrameBuffer fb, /*! \brief call a renderer to render given model into given framebuffer model _may_ be empty (though most framebuffers will expect one!) */ -extern "C" void ospRenderFrame(OSPFrameBuffer fb, +extern "C" float ospRenderFrame(OSPFrameBuffer fb, OSPRenderer renderer, const uint32_t fbChannelFlags ) @@ -467,7 +467,7 @@ extern "C" void ospRenderFrame(OSPFrameBuffer fb, std::cout << "done rendering, time per frame = " << (t_frame*1000.f) << "ms, avg'ed fps = " << (den/nom) << std::endl; #else // rendering = true; - ospray::api::Device::current->renderFrame(fb,renderer,fbChannelFlags); + return ospray::api::Device::current->renderFrame(fb,renderer,fbChannelFlags); // rendering = false; #endif } diff --git a/ospray/api/Device.h b/ospray/api/Device.h index db09053e64..bfcbdeae4c 100644 --- a/ospray/api/Device.h +++ b/ospray/api/Device.h @@ -192,7 +192,7 @@ namespace ospray { const uint32 fbChannelFlags) = 0; /*! call a renderer to render a frame buffer */ - virtual void renderFrame(OSPFrameBuffer _sc, + virtual float renderFrame(OSPFrameBuffer _sc, OSPRenderer _renderer, const uint32 fbChannelFlags) = 0; diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index ed2a10c89f..972f88e93c 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -651,11 +651,11 @@ namespace ospray { /*! call a renderer to render a frame buffer */ - void LocalDevice::renderFrame(OSPFrameBuffer _fb, + float LocalDevice::renderFrame(OSPFrameBuffer _fb, OSPRenderer _renderer, const uint32 fbChannelFlags) { - FrameBuffer *fb = (FrameBuffer *)_fb; + FrameBuffer *fb = (FrameBuffer *)_fb; // SwapChain *sc = (SwapChain *)_sc; Renderer *renderer = (Renderer *)_renderer; // Model *model = (Model *)_model; @@ -666,7 +666,7 @@ namespace ospray { // FrameBuffer *fb = sc->getBackBuffer(); try { - renderer->renderFrame(fb,fbChannelFlags); + return renderer->renderFrame(fb,fbChannelFlags); } catch (std::runtime_error e) { std::cerr << "=======================================================" << std::endl; std::cerr << "# >>> ospray fatal error <<< " << std::endl << e.what() << std::endl; diff --git a/ospray/api/LocalDevice.h b/ospray/api/LocalDevice.h index fc419e8df8..93a296102e 100644 --- a/ospray/api/LocalDevice.h +++ b/ospray/api/LocalDevice.h @@ -213,7 +213,7 @@ namespace ospray { const uint32 fbChannelFlags) override; /*! call a renderer to render a frame buffer */ - void renderFrame(OSPFrameBuffer _sc, + float renderFrame(OSPFrameBuffer _sc, OSPRenderer _renderer, const uint32 fbChannelFlags) override; diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 834145d89b..f7f1eed298 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -272,9 +272,10 @@ extern "C" { OSPRAY_INTERFACE int32_t ospLoadModule(const char *pluginName); //! use renderer to render a frame. - /*! What input to tuse for rendering the frame is encoded in the - renderer's parameters, typically in "world". */ - OSPRAY_INTERFACE void ospRenderFrame(OSPFrameBuffer fb, + /*! What input to use for rendering the frame is encoded in the + renderer's parameters, typically in "world". + return estimate of variance if framebuffer has VARIANCE buffer */ + OSPRAY_INTERFACE float ospRenderFrame(OSPFrameBuffer fb, OSPRenderer renderer, const uint32_t whichChannels OSP_DEFAULT_VAL(=OSP_FB_COLOR)); diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index ae2253322a..e151465bda 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -38,7 +38,7 @@ namespace ospray { } /*! render a frame via the tiled load balancer */ - void LocalTiledLoadBalancer::renderFrame(Renderer *renderer, + float LocalTiledLoadBalancer::renderFrame(Renderer *renderer, FrameBuffer *fb, const uint32 channelFlags) { @@ -87,6 +87,15 @@ namespace ospray { }); renderer->endFrame(perFrameData,channelFlags); + + float avgVar = 0.f; + for (int i = 0; i < NTASKS; i++) { + const size_t tile_y = i / numTiles_x; + const size_t tile_x = i - tile_y*numTiles_x; + const vec2i tileID(tile_x, tile_y); + avgVar += fb->tileError(tileID); + } + return avgVar / NTASKS; } std::string LocalTiledLoadBalancer::toString() const @@ -100,7 +109,7 @@ namespace ospray { return "ospray::InterleavedTiledLoadBalancer"; } - void InterleavedTiledLoadBalancer::renderFrame(Renderer *renderer, + float InterleavedTiledLoadBalancer::renderFrame(Renderer *renderer, FrameBuffer *fb, const uint32 channelFlags) { @@ -151,6 +160,8 @@ namespace ospray { }); renderer->endFrame(perFrameData,channelFlags); + + return 0.f;//XXX } } // ::ospray diff --git a/ospray/render/LoadBalancer.h b/ospray/render/LoadBalancer.h index 88091ec1f9..8646cbb2ad 100644 --- a/ospray/render/LoadBalancer.h +++ b/ospray/render/LoadBalancer.h @@ -36,7 +36,7 @@ namespace ospray { { static TiledLoadBalancer *instance; virtual std::string toString() const = 0; - virtual void renderFrame(Renderer *tiledRenderer, + virtual float renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags) = 0; }; @@ -50,7 +50,7 @@ namespace ospray { { LocalTiledLoadBalancer(); - void renderFrame(Renderer *renderer, + float renderFrame(Renderer *renderer, FrameBuffer *fb, const uint32 channelFlags) override; @@ -83,7 +83,7 @@ namespace ospray { std::string toString() const override; - void renderFrame(Renderer *tiledRenderer, + float renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags) override; }; diff --git a/ospray/render/Renderer.cpp b/ospray/render/Renderer.cpp index 9462f3c755..36e8ca549c 100644 --- a/ospray/render/Renderer.cpp +++ b/ospray/render/Renderer.cpp @@ -36,6 +36,7 @@ namespace ospray { { epsilon = getParam1f("epsilon", 1e-6f); spp = getParam1i("spp", 1); + errorThreshold = getParam1f("varianceThreshold", 0.f); backgroundEnabled = getParam1i("backgroundEnabled", 1); maxDepthTexture = (Texture2D*)getParamObject("maxDepthTexture", NULL); model = (Model*)getParamObject("model", getParamObject("world")); @@ -128,10 +129,10 @@ namespace ospray { ispc::Renderer_endFrame(getIE(),perFrameData); } - void Renderer::renderFrame(FrameBuffer *fb, const uint32 channelFlags) + float Renderer::renderFrame(FrameBuffer *fb, const uint32 channelFlags) { // double T0 = getSysTime(); - TiledLoadBalancer::instance->renderFrame(this,fb,channelFlags); + return TiledLoadBalancer::instance->renderFrame(this,fb,channelFlags); // double T1 = getSysTime(); // printf("time per frame %lf ms\n",(T1-T0)*1e3f); } diff --git a/ospray/render/Renderer.h b/ospray/render/Renderer.h index cff4cea6fe..6b4fd8edc0 100644 --- a/ospray/render/Renderer.h +++ b/ospray/render/Renderer.h @@ -51,7 +51,7 @@ namespace ospray { virtual std::string toString() const { return "ospray::Renderer"; } /*! \brief render one frame, and put it into given frame buffer */ - virtual void renderFrame(FrameBuffer *fb, + virtual float renderFrame(FrameBuffer *fb, const uint32 fbChannelFlags); //! \brief called to initialize a new frame From f4725469f1c06cc98e9b81f9150722a8c744041a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 10:01:27 +0200 Subject: [PATCH 153/310] Adapt other renderers to variance / adaptive accumulation --- ospray/render/simpleAO/SimpleAO.ispc | 20 +++++++------- ospray/render/util.ih | 19 +++++++++++++ .../render/volume/RaycastVolumeRenderer.ispc | 27 ------------------- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/ospray/render/simpleAO/SimpleAO.ispc b/ospray/render/simpleAO/SimpleAO.ispc index 12ab56c592..c1fad7ba46 100644 --- a/ospray/render/simpleAO/SimpleAO.ispc +++ b/ospray/render/simpleAO/SimpleAO.ispc @@ -82,12 +82,13 @@ inline vec3f getRandomDir(varying RandomTEA* uniform rng, inline void shade_ao(uniform SimpleAO *uniform self, varying vec3f &color, varying float &alpha, - int sampleCnt, + const uniform int sampleCnt, + const uniform int accumID, const Ray &ray, const int32 pixel_x, const int32 pixel_y, - const float rot_x, - const float rot_y) + const uniform float rot_x, + const uniform float rot_y) { if (ray.geomID < 0) { color = self->super.backgroundEnabled ? self->super.bgColor : @@ -119,7 +120,7 @@ inline void shade_ao(uniform SimpleAO *uniform self, uniform FrameBuffer *uniform fb = self->super.fb; RandomTEA rng_state; varying RandomTEA* const uniform rng = &rng_state; - RandomTEA__Constructor(rng, (fb->size.x * pixel_y) + pixel_x, fb->accumID); + RandomTEA__Constructor(rng, (fb->size.x * pixel_y) + pixel_x, accumID); int hits = 0; vec3f biNormU,biNormV; @@ -153,16 +154,15 @@ void SimpleAO_renderSample(uniform Renderer *uniform _self, traceRay(self->super.model, sample.ray); sample.z = sample.ray.t; - uniform int samplesPerFrame = self->samplesPerFrame; - uniform int framesPer16 = 16 / samplesPerFrame; - int accumID = sample.sampleID.z / framesPer16; - float rot_x = 1.f - precomputedHalton3(accumID); - float rot_y = 1.f - precomputedHalton5(accumID); + const uniform int accumID = reduce_max(sample.sampleID.z) * self->samplesPerFrame; + const uniform float rot_x = 1.f - precomputedHalton3(accumID); + const uniform float rot_y = 1.f - precomputedHalton5(accumID); shade_ao(self, sample.rgb, sample.alpha, - samplesPerFrame, + self->samplesPerFrame, + accumID, sample.ray, sample.sampleID.x, sample.sampleID.y, diff --git a/ospray/render/util.ih b/ospray/render/util.ih index d1134f26f1..2d4ed645fd 100644 --- a/ospray/render/util.ih +++ b/ospray/render/util.ih @@ -49,6 +49,25 @@ inline float precomputedHalton5(uint32 sampleID) } +inline uniform float precomputedHalton2(uniform uint32 sampleID) +{ + if (!precomputedHalton_initialized) precomputedHalton_create(); + return precomputedHalton[0][sampleID & (NUM_PRECOMPUTED_HALTON_VALUES-1)]; +} + +inline uniform float precomputedHalton3(uniform uint32 sampleID) +{ + if (!precomputedHalton_initialized) precomputedHalton_create(); + return precomputedHalton[1][sampleID & (NUM_PRECOMPUTED_HALTON_VALUES-1)]; +} + +inline uniform float precomputedHalton5(uniform uint32 sampleID) +{ + if (!precomputedHalton_initialized) precomputedHalton_create(); + return precomputedHalton[2][sampleID & (NUM_PRECOMPUTED_HALTON_VALUES-1)]; +} + + inline vec3f make_random_color(const int i) { diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 3fdbf1d10d..4d0501663f 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -34,23 +34,6 @@ struct PassInfo { uniform bool useBG; }; -unmasked void RaycastVolumeRenderer_endFrame(Renderer *uniform self, - void *uniform perFrameData, - const uniform int32 accumID) -{ - if (self->fb) - self->fb->accumID = accumID; - - self->fb = NULL; -} - -unmasked void *uniform RaycastVolumeRenderer_beginFrame(Renderer *uniform self, - FrameBuffer *uniform framebuffer) -{ - self->fb = framebuffer; - return NULL; -} - inline void RaycastVolumeRenderer_computeVolumeSample(RaycastVolumeRenderer *uniform self, Volume *uniform volume, varying Ray &ray, @@ -431,21 +414,11 @@ void RaycastVolumeRenderer_renderSample(Renderer *uniform pointer, export void *uniform RaycastVolumeRenderer_createInstance() { - // The self object. RaycastVolumeRenderer *uniform self = uniform new uniform RaycastVolumeRenderer; - // Constructor of the parent class. Renderer_Constructor(&self->super, NULL); - - // Function to compute the color and opacity for a screen space sample. self->super.renderSample = RaycastVolumeRenderer_renderSample; - // Function to perform per-frame state initialization. - self->super.beginFrame = RaycastVolumeRenderer_beginFrame; - - // Function to perform per-frame state completion. - self->super.endFrame = RaycastVolumeRenderer_endFrame; - return self; } From 50f70f72fcabed46b741b2c4b3eab9ee0e3db4c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 10:42:40 +0200 Subject: [PATCH 154/310] Adapt other devices to changed renderFrame --- ospray/api/COIDeviceHost.cpp | 8 +++++--- ospray/api/COIDeviceWorker.cpp | 3 ++- ospray/mpi/DistributedFrameBuffer.cpp | 9 +++++---- ospray/mpi/DistributedFrameBuffer.h | 4 ++++ ospray/mpi/MPIDevice.cpp | 4 ++-- ospray/mpi/MPIDevice.h | 2 +- ospray/mpi/MPILoadBalancer.cpp | 11 ++++++++--- ospray/mpi/MPILoadBalancer.h | 12 ++++++------ 8 files changed, 33 insertions(+), 20 deletions(-) diff --git a/ospray/api/COIDeviceHost.cpp b/ospray/api/COIDeviceHost.cpp index d3e417fe08..b5c2e70911 100644 --- a/ospray/api/COIDeviceHost.cpp +++ b/ospray/api/COIDeviceHost.cpp @@ -362,7 +362,7 @@ namespace ospray { void *data, const uint32 flags) override; /*! call a renderer to render a frame buffer */ - void renderFrame(OSPFrameBuffer _sc, + float renderFrame(OSPFrameBuffer _sc, OSPRenderer _renderer, const uint32 fbChannelFlags) override; @@ -740,7 +740,7 @@ namespace ospray { } /*! call a renderer to render a frame buffer */ - void COIDevice::renderFrame(OSPFrameBuffer _sc, + float COIDevice::renderFrame(OSPFrameBuffer _sc, OSPRenderer _renderer, const uint32 fbChannelFlags) { @@ -748,8 +748,10 @@ namespace ospray { args.write((ObjectHandle&)_sc); args.write((ObjectHandle&)_renderer); args.write((uint32&)fbChannelFlags); - callFunction(OSPCOI_RENDER_FRAME,args,nullptr,false); + float retValue = 1.0f; + callFunction(OSPCOI_RENDER_FRAME,args, &retValue, sizeof(retValue)); callFunction(OSPCOI_RENDER_FRAME_SYNC,args,nullptr,true); + return retValue; } diff --git a/ospray/api/COIDeviceWorker.cpp b/ospray/api/COIDeviceWorker.cpp index dd8aed98a4..2e39690753 100644 --- a/ospray/api/COIDeviceWorker.cpp +++ b/ospray/api/COIDeviceWorker.cpp @@ -722,7 +722,8 @@ namespace ospray { uint32 channelFlags = args.get(); FrameBuffer *fb = (FrameBuffer*)_fb.lookup(); Renderer *r = (Renderer*)renderer.lookup(); - r->renderFrame(fb,channelFlags); + float v = r->renderFrame(fb,channelFlags); + memcpy(retVal, &v, retValSize); } COINATIVELIBEXPORT diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index d7413a2038..c66ac24a0e 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -134,7 +134,7 @@ namespace ospray { (ispc::VaryingTile *)&this->final, (ispc::VaryingTile *)&this->accum, (ispc::VaryingRGBA_I8 *)&this->color, - dfb->hasAccumBuffer,dfb->accumID); + dfb->hasAccumBuffer,dfb->accumId); dfb->tileIsCompleted(this); for (int i=0;ifinal, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, - dfb->hasAccumBuffer,dfb->accumID); + dfb->hasAccumBuffer,dfb->accumId); dfb->tileIsCompleted(this); } @@ -198,7 +198,7 @@ namespace ospray { (ispc::VaryingTile*)&this->final, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, - dfb->hasAccumBuffer,dfb->accumID); + dfb->hasAccumBuffer,dfb->accumId); dfb->tileIsCompleted(this); } } @@ -317,6 +317,7 @@ namespace ospray { localFBonMaster = new LocalFrameBuffer(numPixels, colorBufferFormat, hasDepthBuffer, + false, false); } } @@ -579,7 +580,7 @@ namespace ospray { }); if (fbChannelFlags & OSP_FB_ACCUM) - accumID = 0; + accumId = 0; } } diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index 6ef07af0e6..0a6c71daf0 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -42,6 +42,10 @@ namespace ospray { //! number of tiles that "I" own size_t numMyTiles() const { return myTiles.size(); }; + int accumId; + virtual int32 accumID(const vec2i &tile) { return accumId; } + virtual float tileError(const vec2i &tile) { return 0.0f; } + /*! color buffer and depth buffer on master */ enum { diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index d8445d84b6..da6c6c7e1d 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -1033,7 +1033,7 @@ namespace ospray { /*! call a renderer to render a frame buffer */ - void MPIDevice::renderFrame(OSPFrameBuffer _fb, + float MPIDevice::renderFrame(OSPFrameBuffer _fb, OSPRenderer _renderer, const uint32 fbChannelFlags) { @@ -1052,7 +1052,7 @@ namespace ospray { cmd.send((int32)fbChannelFlags); cmd.flush(); - TiledLoadBalancer::instance->renderFrame(NULL,fb,fbChannelFlags); + return TiledLoadBalancer::instance->renderFrame(NULL,fb,fbChannelFlags); } //! release (i.e., reduce refcount of) given object diff --git a/ospray/mpi/MPIDevice.h b/ospray/mpi/MPIDevice.h index 3ea14d3af8..6f3aec954c 100644 --- a/ospray/mpi/MPIDevice.h +++ b/ospray/mpi/MPIDevice.h @@ -219,7 +219,7 @@ namespace ospray { OSPVolume newVolume(const char *type) override; /*! call a renderer to render a frame buffer */ - void renderFrame(OSPFrameBuffer _sc, + float renderFrame(OSPFrameBuffer _sc, OSPRenderer _renderer, const uint32 fbChannelFlags) override; diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index 67e9c67b19..a2dcb83219 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -35,7 +35,7 @@ namespace ospray { namespace staticLoadBalancer { - void Master::renderFrame(Renderer *tiledRenderer, + float Master::renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags) { @@ -49,6 +49,8 @@ namespace ospray { dfb->waitUntilFinished(); async_endFrame(); + + return 0.0f;//XXX } std::string Master::toString() const @@ -56,7 +58,7 @@ namespace ospray { return "ospray::mpi::staticLoadBalancer::Master"; } - void Slave::renderFrame(Renderer *tiledRenderer, + float Slave::renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags) { @@ -83,6 +85,7 @@ namespace ospray { #endif const size_t tile_y = tileID / numTiles_x; const size_t tile_x = tileID - tile_y*numTiles_x; + const vec2i tileId(tile_x, tile_y); tile.region.lower.x = tile_x * TILE_SIZE; tile.region.lower.y = tile_y * TILE_SIZE; tile.region.upper.x = std::min(tile.region.lower.x + TILE_SIZE, @@ -95,7 +98,7 @@ namespace ospray { tile.children = 0; const int spp = tiledRenderer->spp; - const int blocks = (fb->accumID > 0 || spp > 0) ? 1 : + const int blocks = (fb->accumID(tileId) > 0 || spp > 0) ? 1 : std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); const size_t numJobs = ((TILE_SIZE*TILE_SIZE)/ RENDERTILE_PIXELS_PER_JOB + blocks-1)/blocks; @@ -114,6 +117,8 @@ namespace ospray { tiledRenderer->endFrame(perFrameData,channelFlags); async_endFrame(); + + return 0.0f;//XXX } std::string Slave::toString() const diff --git a/ospray/mpi/MPILoadBalancer.h b/ospray/mpi/MPILoadBalancer.h index d351b14c0e..b87b87b015 100644 --- a/ospray/mpi/MPILoadBalancer.h +++ b/ospray/mpi/MPILoadBalancer.h @@ -35,10 +35,10 @@ namespace ospray { */ struct Master : public TiledLoadBalancer { - void renderFrame(Renderer *tiledRenderer, + float renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, - const uint32 channelFlags); - std::string toString() const; + const uint32 channelFlags) override; + std::string toString() const override; }; /*! \brief the 'slave' in a tile-based master-slave *static* @@ -56,10 +56,10 @@ namespace ospray { /*! total number of worker threads across all(!) slaves */ int32 numTotalThreads; - void renderFrame(Renderer *tiledRenderer, + float renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, - const uint32 channelFlags); - std::string toString() const; + const uint32 channelFlags) override; + std::string toString() const override; }; }// ::ospray::mpi::staticLoadBalancer } // ::ospray::mpi From 63f5cfc9fe5864581d089da97ebdd7454e50f6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 11:17:47 +0200 Subject: [PATCH 155/310] Always return per-tile accumID --- ospray/fb/LocalFB.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index d6390e0230..165b17e104 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -142,8 +142,7 @@ namespace ospray { int32 LocalFrameBuffer::accumID(const vec2i &tile) { - const int idx = hasVarianceBuffer ? tile.y * tilesx + tile.x : 0; - return tileAccumID[idx]; + return tileAccumID[tile.y * tilesx + tile.x]; } float LocalFrameBuffer::tileError(const vec2i &tile) From ad10653abf052eb8b3cce3cd3ac67f427452ffb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 11:29:39 +0200 Subject: [PATCH 156/310] Fix access tileErrorBuffer (only present if hasVarianceBuffer) --- ospray/fb/LocalFB.cpp | 17 ++++++++++------- ospray/fb/LocalFB.ispc | 14 ++++++-------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 165b17e104..22953e7240 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -105,15 +105,18 @@ namespace ospray { parallel_for(num_blocks,[&](int taskIndex) { ispc::LocalFrameBuffer_clearAccum(thisIE, taskIndex); }); - // always also clear variance buffer -- only clearing accumulation buffer - // is meaningless - parallel_for(num_blocks,[&](int taskIndex) { - ispc::LocalFrameBuffer_clearVariance(thisIE, taskIndex); - }); int tiles = tilesx * divRoundUp(size.y, TILE_SIZE); - for (int i = 0; i < tiles; i++) { + for (int i = 0; i < tiles; i++) tileAccumID[i] = 0; - tileErrorBuffer[i] = inf; + + // always also clear variance buffer (if presnet) -- only clearing + // accumulation buffer is meaningless + if (hasVarianceBuffer) { + parallel_for(num_blocks,[&](int taskIndex) { + ispc::LocalFrameBuffer_clearVariance(thisIE, taskIndex); + }); + for (int i = 0; i < tiles; i++) + tileErrorBuffer[i] = inf; } } } diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 87602d9c5f..1b1a1b17f4 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -43,15 +43,13 @@ export void LocalFrameBuffer_clearVariance(void *uniform _fb, uniform int taskIn { uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - if (fb->varianceBuffer) { - uniform float *uniform fbPointer = (uniform float *uniform)&fb->varianceBuffer[0].x; - uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; - uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; - uniform int end = min(CLEAR_BLOCK_SIZE, num_floats - taskIndex * CLEAR_BLOCK_SIZE); + uniform float *uniform fbPointer = (uniform float *uniform)&fb->varianceBuffer[0].x; + uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; + uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; + uniform int end = min(CLEAR_BLOCK_SIZE, num_floats - taskIndex * CLEAR_BLOCK_SIZE); - foreach (x=0 ... end) - block[x] = 0.f; - } + foreach (x=0 ... end) + block[x] = 0.f; } //! \brief write tile into the given frame buffer's color buffer From 6a3a44395865269674ea5af4dcd31f157aad6f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 13:55:21 +0200 Subject: [PATCH 157/310] modelViewer uses VARIANCE buffer --- apps/modelViewer/modelViewer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index ae9e362ea8..229a6dbcde 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -162,7 +162,7 @@ namespace ospray { Glut3DWidget::reshape(newSize); g_windowSize = newSize; if (fb) ospFreeFrameBuffer(fb); - fb = ospNewFrameBuffer((const osp::vec2i&)newSize,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_DEPTH|OSP_FB_ACCUM); + fb = ospNewFrameBuffer((const osp::vec2i&)newSize,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_DEPTH|OSP_FB_ACCUM|OSP_FB_VARIANCE); ospSet1f(fb, "gamma", 2.2f); ospCommit(fb); ospFrameBufferClear(fb,OSP_FB_ACCUM); @@ -399,8 +399,6 @@ namespace ospray { if (displayWall) ospRenderFrame(displayWall->fb,renderer,OSP_FB_COLOR|OSP_FB_ACCUM); ++accumID; - if (accumID%10 == 0) - PRINT(accumID); // set the glut3d widget's frame buffer to the opsray frame buffer, then display ucharFB = (uint32_t *) ospMapFrameBuffer(fb, OSP_FB_COLOR); @@ -689,6 +687,7 @@ namespace ospray { ospModel = ospNewModel(); ospRenderer = ospNewRenderer(rendererType.c_str()); + // ospSet1f(ospRenderer, "varianceThreshold", 0.0002); if (!ospRenderer) throw std::runtime_error("could not create ospRenderer '"+rendererType+"'"); Assert(ospRenderer != NULL && "could not create ospRenderer"); From 2ce3a5c617765767fbc68a0a8a3d0d750644f385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 14:11:18 +0200 Subject: [PATCH 158/310] Cleanup clearing of local framebuffer --- ospray/fb/LocalFB.cpp | 23 +++++++++++++++-------- ospray/fb/LocalFB.ispc | 36 ++++++++++++------------------------ 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 22953e7240..26de7d5e4d 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -20,7 +20,6 @@ #include "ospray/common/tasking/parallel_for.h" // number of floats each task is clearing; must be a a mulitple of 16 -// NOTE(jda) - must match CLEAR_BLOCK_SIZE defined in LocalFB.ispc! #define CLEAR_BLOCK_SIZE (32 * 1024) namespace ospray { @@ -100,21 +99,29 @@ namespace ospray { if (fbChannelFlags & OSP_FB_ACCUM) { void *thisIE = getIE(); const int num_floats = 4 * size.x * size.y; - const int num_blocks = (num_floats + CLEAR_BLOCK_SIZE - 1) - / CLEAR_BLOCK_SIZE; - parallel_for(num_blocks,[&](int taskIndex) { - ispc::LocalFrameBuffer_clearAccum(thisIE, taskIndex); - }); + const int num_blocks = divRoundUp(num_floats, CLEAR_BLOCK_SIZE); + + if (hasAccumBuffer) { + parallel_for(num_blocks,[&](int taskIndex) { + const int start = taskIndex * CLEAR_BLOCK_SIZE; + const int num = min(CLEAR_BLOCK_SIZE, num_floats - start); + ispc::LocalFrameBuffer_clearAccum(thisIE, start, num); + }); + } + int tiles = tilesx * divRoundUp(size.y, TILE_SIZE); for (int i = 0; i < tiles; i++) tileAccumID[i] = 0; - // always also clear variance buffer (if presnet) -- only clearing + // always also clear variance buffer (if present) -- only clearing // accumulation buffer is meaningless if (hasVarianceBuffer) { parallel_for(num_blocks,[&](int taskIndex) { - ispc::LocalFrameBuffer_clearVariance(thisIE, taskIndex); + const int start = taskIndex * CLEAR_BLOCK_SIZE; + const int num = min(CLEAR_BLOCK_SIZE, num_floats - start); + ispc::LocalFrameBuffer_clearVariance(thisIE, start, num); }); + for (int i = 0; i < tiles; i++) tileErrorBuffer[i] = inf; } diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 1b1a1b17f4..c9fd7e36c5 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -16,39 +16,27 @@ #include "LocalFB.ih" -// number of floats each task is clearing; must be a mulitple of 16 -// NOTE(jda) - must match CLEAR_BLOCK_SIZE defined in LocalFB.cpp! -#define CLEAR_BLOCK_SIZE (32 * 1024) - export void LocalFrameBuffer_clearAccum(void *uniform _fb, - uniform int taskIndex) + uniform int start, + uniform int num) { uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; + uniform float *uniform fbp = (uniform float *uniform)&fb->accumBuffer[0].x; + uniform float *uniform block = fbp + start; - if (fb->accumBuffer) { - uniform float *uniform fbPointer - = (uniform float *uniform)&fb->accumBuffer[0].x; - uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; - uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; - - uniform int end = min(CLEAR_BLOCK_SIZE, - num_floats - (taskIndex * CLEAR_BLOCK_SIZE)); - foreach (x=0 ... end) { - block[x] = 0.f; - } - } + foreach (x=0 ... num) + block[x] = 0.f; } -export void LocalFrameBuffer_clearVariance(void *uniform _fb, uniform int taskIndex) +export void LocalFrameBuffer_clearVariance(void *uniform _fb, + uniform int start, + uniform int num) { uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; + uniform float *uniform fbp = (uniform float *uniform)&fb->accumBuffer[0].x; + uniform float *uniform block = fbp + start; - uniform float *uniform fbPointer = (uniform float *uniform)&fb->varianceBuffer[0].x; - uniform float *uniform block = fbPointer + taskIndex * CLEAR_BLOCK_SIZE; - uniform size_t num_floats = 4*fb->super.size.x*fb->super.size.y; - uniform int end = min(CLEAR_BLOCK_SIZE, num_floats - taskIndex * CLEAR_BLOCK_SIZE); - - foreach (x=0 ... end) + foreach (x=0 ... num) block[x] = 0.f; } From c9f47115f93e274de91771b5a01e92788e7ca713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 16:55:59 +0200 Subject: [PATCH 159/310] Further optimize (away) clearing of local framebuffer --- ospray/fb/LocalFB.cpp | 24 ++++-------------------- ospray/fb/LocalFB.ispc | 29 +++-------------------------- 2 files changed, 7 insertions(+), 46 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 26de7d5e4d..61b30269c8 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -97,31 +97,15 @@ namespace ospray { void LocalFrameBuffer::clear(const uint32 fbChannelFlags) { if (fbChannelFlags & OSP_FB_ACCUM) { - void *thisIE = getIE(); - const int num_floats = 4 * size.x * size.y; - const int num_blocks = divRoundUp(num_floats, CLEAR_BLOCK_SIZE); - - if (hasAccumBuffer) { - parallel_for(num_blocks,[&](int taskIndex) { - const int start = taskIndex * CLEAR_BLOCK_SIZE; - const int num = min(CLEAR_BLOCK_SIZE, num_floats - start); - ispc::LocalFrameBuffer_clearAccum(thisIE, start, num); - }); - } - + // it is only necessary to reset the accumID, + // LocalFrameBuffer_accumulateTile takes care of clearing the + // accumulation buffers int tiles = tilesx * divRoundUp(size.y, TILE_SIZE); for (int i = 0; i < tiles; i++) tileAccumID[i] = 0; - // always also clear variance buffer (if present) -- only clearing - // accumulation buffer is meaningless + // always also also error buffer (if present) if (hasVarianceBuffer) { - parallel_for(num_blocks,[&](int taskIndex) { - const int start = taskIndex * CLEAR_BLOCK_SIZE; - const int num = min(CLEAR_BLOCK_SIZE, num_floats - start); - ispc::LocalFrameBuffer_clearVariance(thisIE, start, num); - }); - for (int i = 0; i < tiles; i++) tileErrorBuffer[i] = inf; } diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index c9fd7e36c5..bb448f16a9 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -16,30 +16,6 @@ #include "LocalFB.ih" -export void LocalFrameBuffer_clearAccum(void *uniform _fb, - uniform int start, - uniform int num) -{ - uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - uniform float *uniform fbp = (uniform float *uniform)&fb->accumBuffer[0].x; - uniform float *uniform block = fbp + start; - - foreach (x=0 ... num) - block[x] = 0.f; -} - -export void LocalFrameBuffer_clearVariance(void *uniform _fb, - uniform int start, - uniform int num) -{ - uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - uniform float *uniform fbp = (uniform float *uniform)&fb->accumBuffer[0].x; - uniform float *uniform block = fbp + start; - - foreach (x=0 ... num) - block[x] = 0.f; -} - //! \brief write tile into the given frame buffer's color buffer /*! \detailed this buffer _must_ exist when this fct is called, and it _must_ have RGBA_I8 format */ @@ -203,8 +179,9 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, const uniform tileId = tileIdx.y*fb->numTiles.x + tileIdx.x; fb->tileAccumID[tileId]++; if (variance) { - const uniform float r = sqrt(reduce_add(cnt) / tile.fbSize.x / tile.fbSize.y); - const uniform float errf = r * reduce_add(err) / reduce_add(cnt); + const uniform float cntu = reduce_add(cnt); + const uniform float r = sqrt(cntu / (tile.fbSize.x * tile.fbSize.y)); + const uniform float errf = r * reduce_add(err) / cntu; // print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, errf); fb->tileErrorBuffer[tileId] = errf; } From 6b732790e2f8c4f649c6658b4997e71ddd779885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 18:50:52 +0200 Subject: [PATCH 160/310] Use maximum tileError as frameError, default to 1.0 Error is also only updated every other frame to avoid alternating error (get a monotone sequence). --- ospray/fb/FrameBuffer.h | 1 + ospray/fb/LocalFB.cpp | 19 +++++++++++++++---- ospray/fb/LocalFB.h | 2 ++ ospray/fb/LocalFB.ispc | 23 ++++++++++++----------- ospray/mpi/DistributedFrameBuffer.h | 3 ++- ospray/mpi/MPILoadBalancer.cpp | 2 +- ospray/render/LoadBalancer.cpp | 15 ++++----------- 7 files changed, 37 insertions(+), 28 deletions(-) diff --git a/ospray/fb/FrameBuffer.h b/ospray/fb/FrameBuffer.h index a04bd16644..e3c91557c6 100644 --- a/ospray/fb/FrameBuffer.h +++ b/ospray/fb/FrameBuffer.h @@ -97,6 +97,7 @@ namespace ospray { changes that requires clearing the accumulation buffer. */ virtual int32 accumID(const vec2i &tile) = 0; virtual float tileError(const vec2i &tile) = 0; + virtual float frameError() = 0; Ref pixelOp; }; diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 61b30269c8..3b14118e7b 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -63,7 +63,7 @@ namespace ospray { accumBuffer = NULL; tilesx = divRoundUp(size.x, TILE_SIZE); - int tiles = tilesx * divRoundUp(size.y, TILE_SIZE); + tiles = tilesx * divRoundUp(size.y, TILE_SIZE); tileAccumID = new int32[tiles]; if (hasVarianceBuffer) { @@ -100,14 +100,13 @@ namespace ospray { // it is only necessary to reset the accumID, // LocalFrameBuffer_accumulateTile takes care of clearing the // accumulation buffers - int tiles = tilesx * divRoundUp(size.y, TILE_SIZE); for (int i = 0; i < tiles; i++) tileAccumID[i] = 0; // always also also error buffer (if present) if (hasVarianceBuffer) { for (int i = 0; i < tiles; i++) - tileErrorBuffer[i] = inf; + tileErrorBuffer[i] = 1.0f; } } } @@ -141,7 +140,19 @@ namespace ospray { float LocalFrameBuffer::tileError(const vec2i &tile) { - return hasVarianceBuffer ? tileErrorBuffer[tile.y * tilesx + tile.x] : 0.0f; + int idx = tile.y * tilesx + tile.x; + return hasVarianceBuffer && tileAccumID[idx] > 3 ? tileErrorBuffer[idx] : 1.0f; + } + + float LocalFrameBuffer::frameError() + { + if (hasVarianceBuffer) { + float maxErr = 0.0f; + for (int i = 0; i < tiles; i++) + maxErr = tileAccumID[i] > 3 ? std::max(maxErr, tileErrorBuffer[i]) : 1.0f; + return maxErr; + } else + return 1.0f; } const void *LocalFrameBuffer::mapDepthBuffer() diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index a4b95c2c97..1958a2bb6b 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -32,6 +32,7 @@ namespace ospray { int32 *tileAccumID; //< holds accumID per tile, for adaptive accumulation float *tileErrorBuffer; /*!< holds error per tile, for variance estimation / stopping */ int32 tilesx; + int32 tiles; LocalFrameBuffer(const vec2i &size, ColorBufferFormat colorBufferFormat, @@ -49,6 +50,7 @@ namespace ospray { virtual void setTile(Tile &tile); virtual int32 accumID(const vec2i &tile); virtual float tileError(const vec2i &tile); + virtual float frameError(); virtual const void *mapColorBuffer(); virtual const void *mapDepthBuffer(); diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index bb448f16a9..5662ca9c7c 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -143,22 +143,20 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, acc.z += varyTile->b[chunkID]; acc.w += varyTile->a[chunkID]; } - accum[pixelID] = acc; - if (variance) { + // variance buffer accumulates every other frame + if (variance && (tile.accumID & 1) == 0) { varying vec3f vari = make_vec3f(0.f); if (tile.accumID > 0) vari = make_vec3f(variance[pixelID]); - if ((tile.accumID & 1) == 0) { - unmasked { - vari.x += varyTile->r[chunkID]; - vari.y += varyTile->g[chunkID]; - vari.z += varyTile->b[chunkID]; - } - - variance[pixelID] = make_vec4f(vari); + unmasked { + vari.x += varyTile->r[chunkID]; + vari.y += varyTile->g[chunkID]; + vari.z += varyTile->b[chunkID]; } + variance[pixelID] = make_vec4f(vari); + const vec3f accs = accScale * make_vec3f(acc); const vec3f diff = absf(accs - accHalfScale * vari); const float den = sqrtf(accs.x + accs.y + accs.z); @@ -178,7 +176,10 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, const uniform tileId = tileIdx.y*fb->numTiles.x + tileIdx.x; fb->tileAccumID[tileId]++; - if (variance) { + + // error is also only updated every other frame to avoid alternating error + // (get a monotone sequence) + if (variance && (tile.accumID & 1) == 0) { const uniform float cntu = reduce_add(cnt); const uniform float r = sqrt(cntu / (tile.fbSize.x * tile.fbSize.y)); const uniform float errf = r * reduce_add(err) / cntu; diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index 0a6c71daf0..76cafc135f 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -44,7 +44,8 @@ namespace ospray { int accumId; virtual int32 accumID(const vec2i &tile) { return accumId; } - virtual float tileError(const vec2i &tile) { return 0.0f; } + virtual float tileError(const vec2i &tile) { return 1.0f; } + virtual float frameError() { return 1.0f; } /*! color buffer and depth buffer on master */ diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index a2dcb83219..ca6774e51a 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -118,7 +118,7 @@ namespace ospray { async_endFrame(); - return 0.0f;//XXX + return dfb->frameError(); } std::string Slave::toString() const diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index e151465bda..5add818536 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -58,7 +58,7 @@ namespace ospray { const vec2i tileID(tile_x, tile_y); const int32 accumID = fb->accumID(tileID); - if (accumID > 3 && fb->tileError(tileID) < renderer->errorThreshold) + if (fb->tileError(tileID) < renderer->errorThreshold) return; Tile tile; @@ -88,14 +88,7 @@ namespace ospray { renderer->endFrame(perFrameData,channelFlags); - float avgVar = 0.f; - for (int i = 0; i < NTASKS; i++) { - const size_t tile_y = i / numTiles_x; - const size_t tile_x = i - tile_y*numTiles_x; - const vec2i tileID(tile_x, tile_y); - avgVar += fb->tileError(tileID); - } - return avgVar / NTASKS; + return fb->frameError(); } std::string LocalTiledLoadBalancer::toString() const @@ -132,7 +125,7 @@ namespace ospray { const vec2i tileID(tile_x, tile_y); const int32 accumID = fb->accumID(tileID); - if (accumID > 3 && fb->tileError(tileID) < renderer->errorThreshold) + if (fb->tileError(tileID) < renderer->errorThreshold) return; Tile tile; @@ -161,7 +154,7 @@ namespace ospray { renderer->endFrame(perFrameData,channelFlags); - return 0.f;//XXX + return fb->frameError(); } } // ::ospray From b7f7d6d30b76149513122ffe89299df81ea073f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Mar 2016 18:10:38 +0200 Subject: [PATCH 161/310] Reduce duplicated code in load balancer --- ospray/fb/Tile.h | 12 ++++++++++ ospray/mpi/MPILoadBalancer.cpp | 32 +++++++------------------ ospray/render/LoadBalancer.cpp | 43 +++++----------------------------- ospray/render/LoadBalancer.h | 7 ++++++ 4 files changed, 34 insertions(+), 60 deletions(-) diff --git a/ospray/fb/Tile.h b/ospray/fb/Tile.h index 8a496484ba..a6d1d0a5ca 100644 --- a/ospray/fb/Tile.h +++ b/ospray/fb/Tile.h @@ -51,6 +51,18 @@ namespace ospray { int32 generation; int32 children; int32 accumID; //!< how often has been accumulated into this tile + + Tile() {} + Tile(const vec2i &tile, const vec2i &fbsize, const int32 accumId) + : fbSize(fbsize), + rcp_fbSize(rcp(vec2f(fbsize))), + generation(0), + children(0), + accumID(accumId) + { + region.lower = tile * TILE_SIZE; + region.upper = min(region.lower + TILE_SIZE, fbsize); + } }; } // ::ospray diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index ca6774e51a..a2e0a28974 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -77,33 +77,19 @@ namespace ospray { const size_t tileID = taskIndex; if ((tileID % worker.size) != worker.rank) return; + const size_t tile_y = tileID / numTiles_x; + const size_t tile_x = tileID - tile_y*numTiles_x; + const vec2i tileId(tile_x, tile_y); + const int32 accumID = fb->accumID(tileID); + #if TILE_SIZE>128 - Tile *tilePtr = new Tile; + Tile *tilePtr = new Tile(tileId, fb->size, accumID); Tile &tile = *tilePtr; #else - Tile __aligned(64) tile; + Tile __aligned(64) tile(tileId, fb->size, accumID); #endif - const size_t tile_y = tileID / numTiles_x; - const size_t tile_x = tileID - tile_y*numTiles_x; - const vec2i tileId(tile_x, tile_y); - tile.region.lower.x = tile_x * TILE_SIZE; - tile.region.lower.y = tile_y * TILE_SIZE; - tile.region.upper.x = std::min(tile.region.lower.x + TILE_SIZE, - fb->size.x); - tile.region.upper.y = std::min(tile.region.lower.y + TILE_SIZE, - fb->size.y); - tile.fbSize = fb->size; - tile.rcp_fbSize = rcp(vec2f(fb->size)); - tile.generation = 0; - tile.children = 0; - - const int spp = tiledRenderer->spp; - const int blocks = (fb->accumID(tileId) > 0 || spp > 0) ? 1 : - std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); - const size_t numJobs = ((TILE_SIZE*TILE_SIZE)/ - RENDERTILE_PIXELS_PER_JOB + blocks-1)/blocks; - - parallel_for(numJobs, [&](int taskIndex){ + + parallel_for(numJobs(tiledRenderer->spp, accumID), [&](int taskIndex){ tiledRenderer->renderTile(perFrameData, tile, taskIndex); }); diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index 5add818536..2b227540d0 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -61,25 +61,9 @@ namespace ospray { if (fb->tileError(tileID) < renderer->errorThreshold) return; - Tile tile; - tile.region.lower.x = tile_x * TILE_SIZE; - tile.region.lower.y = tile_y * TILE_SIZE; - tile.region.upper.x = std::min(tile.region.lower.x+TILE_SIZE,fb->size.x); - tile.region.upper.y = std::min(tile.region.lower.y+TILE_SIZE,fb->size.y); - tile.fbSize = fb->size; - tile.rcp_fbSize = rcp(vec2f(tile.fbSize)); - tile.generation = 0; - tile.children = 0; - tile.children = 0; - tile.accumID = accumID; - - const int spp = renderer->spp; - const int blocks = (accumID > 0 || spp > 0) ? 1 : - std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); - const size_t numJobs = ((TILE_SIZE*TILE_SIZE)/ - RENDERTILE_PIXELS_PER_JOB + blocks-1)/blocks; - - parallel_for(numJobs, [&](int taskIndex){ + Tile tile(tileID, fb->size, accumID); + + parallel_for(numJobs(renderer->spp, accumID), [&](int taskIndex){ renderer->renderTile(perFrameData, tile, taskIndex); }); @@ -128,24 +112,9 @@ namespace ospray { if (fb->tileError(tileID) < renderer->errorThreshold) return; - Tile tile; - tile.region.lower.x = tile_x * TILE_SIZE; - tile.region.lower.y = tile_y * TILE_SIZE; - tile.region.upper.x = std::min(tile.region.lower.x+TILE_SIZE,fb->size.x); - tile.region.upper.y = std::min(tile.region.lower.y+TILE_SIZE,fb->size.y); - tile.fbSize = fb->size; - tile.rcp_fbSize = rcp(vec2f(tile.fbSize)); - tile.generation = 0; - tile.children = 0; - tile.accumID = accumID; - - const int spp = renderer->spp; - const int blocks = (accumID > 0 || spp > 0) ? 1 : - std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); - const size_t numJobs = ((TILE_SIZE*TILE_SIZE)/ - RENDERTILE_PIXELS_PER_JOB + blocks-1)/blocks; - - parallel_for(numJobs, [&](int taskIndex){ + Tile tile(tileID, fb->size, accumID); + + parallel_for(numJobs(renderer->spp, accumID), [&](int taskIndex){ renderer->renderTile(perFrameData, tile, taskIndex); }); diff --git a/ospray/render/LoadBalancer.h b/ospray/render/LoadBalancer.h index 8646cbb2ad..b96f705ddb 100644 --- a/ospray/render/LoadBalancer.h +++ b/ospray/render/LoadBalancer.h @@ -39,6 +39,13 @@ namespace ospray { virtual float renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags) = 0; + + static size_t numJobs(const int spp, int accumID) + { + const int blocks = (accumID > 0 || spp > 0) ? 1 : + std::min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); + return divRoundUp((TILE_SIZE*TILE_SIZE)/RENDERTILE_PIXELS_PER_JOB, blocks); + } }; //! tiled load balancer for local rendering on the given machine From 66288d729ea49ab069aea7176d33c7338fcb57fc Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 29 Mar 2016 19:38:30 -0500 Subject: [PATCH 162/310] fix compile errors in data distributed rendering code --- ospray/render/volume/RaycastVolumeRenderer.cpp | 8 +++++--- ospray/render/volume/RaycastVolumeRenderer.h | 2 +- ospray/render/volume/RaycastVolumeRenderer.ispc | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index b09e3f626a..03ddf1efd3 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -229,7 +229,8 @@ namespace ospray { in regular mode; otherwise, compute some precomputations and return pointer to that (which'll switch the main renderframe fct to render data parallel) */ - void RaycastVolumeRenderer::renderFrame(FrameBuffer *fb, const uint32 channelFlags) + float RaycastVolumeRenderer::renderFrame(FrameBuffer *fb, + const uint32 channelFlags) { int workerRank = ospray::core::getWorkerRank(); @@ -248,8 +249,8 @@ namespace ospray { printed = true; } - Renderer::renderFrame(fb,channelFlags); - return; + + return Renderer::renderFrame(fb,channelFlags);; } // ======================================================= @@ -309,6 +310,7 @@ namespace ospray { dfb->waitUntilFinished(); Renderer::endFrame(NULL,channelFlags); + return fb->frameError(); } #endif diff --git a/ospray/render/volume/RaycastVolumeRenderer.h b/ospray/render/volume/RaycastVolumeRenderer.h index fd79e1123a..f02fb484d5 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.h +++ b/ospray/render/volume/RaycastVolumeRenderer.h @@ -45,7 +45,7 @@ namespace ospray { #if EXP_DATA_PARALLEL /*! per-frame data to describe the data-parallel components */ - void renderFrame(FrameBuffer *fb, const uint32 channelFlags); + float renderFrame(FrameBuffer *fb, const uint32 channelFlags) override; #endif private: diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 4d0501663f..3c84461451 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -582,7 +582,7 @@ export void DDDVRRenderer_renderTile(void*uniform _self, const uniform int begin = taskIndex * RENDERTILE_PIXELS_PER_JOB; const uniform int end = begin + RENDERTILE_PIXELS_PER_JOB; - const uniform int startSampleID = max(fb->accumID,0); + const uniform int startSampleID = max(fgTile.accumID,0); for (uniform uint32 i=begin;i Date: Tue, 29 Mar 2016 20:05:56 -0500 Subject: [PATCH 163/310] fix typo, some cleanups --- ospray/fb/LocalFB.cpp | 5 ++++ ospray/fb/LocalFB.h | 23 +++++++++---------- ospray/mpi/DistributedFrameBuffer.h | 6 ++--- ospray/mpi/MPILoadBalancer.cpp | 11 +++++---- ospray/render/LoadBalancer.cpp | 8 +++---- ospray/render/Renderer.cpp | 3 +-- .../render/volume/RaycastVolumeRenderer.cpp | 6 ++--- 7 files changed, 33 insertions(+), 29 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 3b14118e7b..95498d39f5 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -94,6 +94,11 @@ namespace ospray { delete[] tileErrorBuffer; } + std::string LocalFrameBuffer::toString() const + { + return "ospray::LocalFrameBuffer"; + } + void LocalFrameBuffer::clear(const uint32 fbChannelFlags) { if (fbChannelFlags & OSP_FB_ACCUM) { diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index 1958a2bb6b..00bccea0ef 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -44,18 +44,17 @@ namespace ospray { //! \brief common function to help printf-debugging /*! \detailed Every derived class should overrride this! */ - virtual std::string toString() const - { return "ospray::LocalFrameBuffer"; } - - virtual void setTile(Tile &tile); - virtual int32 accumID(const vec2i &tile); - virtual float tileError(const vec2i &tile); - virtual float frameError(); - - virtual const void *mapColorBuffer(); - virtual const void *mapDepthBuffer(); - virtual void unmap(const void *mappedMem); - virtual void clear(const uint32 fbChannelFlags); + virtual std::string toString() const; + + void setTile(Tile &tile) override; + int32 accumID(const vec2i &tile) override; + float tileError(const vec2i &tile) override; + float frameError() override; + + const void *mapColorBuffer() override; + const void *mapDepthBuffer() override; + void unmap(const void *mappedMem) override; + void clear(const uint32 fbChannelFlags) override; }; } // ::ospray diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index 76cafc135f..cdda5598e8 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -43,9 +43,9 @@ namespace ospray { size_t numMyTiles() const { return myTiles.size(); }; int accumId; - virtual int32 accumID(const vec2i &tile) { return accumId; } - virtual float tileError(const vec2i &tile) { return 1.0f; } - virtual float frameError() { return 1.0f; } + int32 accumID(const vec2i &tile) override { return accumId; } + float tileError(const vec2i &tile) override { return 1.0f; } + float frameError() override { return 1.0f; } /*! color buffer and depth buffer on master */ diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index a2e0a28974..553dbac455 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -36,11 +36,12 @@ namespace ospray { namespace staticLoadBalancer { float Master::renderFrame(Renderer *tiledRenderer, - FrameBuffer *fb, - const uint32 channelFlags) + FrameBuffer *fb, + const uint32 channelFlags) { async_beginFrame(); DistributedFrameBuffer *dfb = dynamic_cast(fb); + assert(dfb); dfb->startNewFrame(); /* the client will do its magic here, and the distributed @@ -50,7 +51,7 @@ namespace ospray { async_endFrame(); - return 0.0f;//XXX + return dfb->frameError();//XXX } std::string Master::toString() const @@ -59,8 +60,8 @@ namespace ospray { } float Slave::renderFrame(Renderer *tiledRenderer, - FrameBuffer *fb, - const uint32 channelFlags) + FrameBuffer *fb, + const uint32 channelFlags) { async_beginFrame(); diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index 2b227540d0..7131469cb2 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -39,8 +39,8 @@ namespace ospray { /*! render a frame via the tiled load balancer */ float LocalTiledLoadBalancer::renderFrame(Renderer *renderer, - FrameBuffer *fb, - const uint32 channelFlags) + FrameBuffer *fb, + const uint32 channelFlags) { Assert(renderer); Assert(fb); @@ -87,8 +87,8 @@ namespace ospray { } float InterleavedTiledLoadBalancer::renderFrame(Renderer *renderer, - FrameBuffer *fb, - const uint32 channelFlags) + FrameBuffer *fb, + const uint32 channelFlags) { Assert(renderer); Assert(fb); diff --git a/ospray/render/Renderer.cpp b/ospray/render/Renderer.cpp index 2e75ea5300..e80cddafff 100644 --- a/ospray/render/Renderer.cpp +++ b/ospray/render/Renderer.cpp @@ -129,9 +129,8 @@ namespace ospray { return ispc::Renderer_beginFrame(getIE(),fb->getIE()); } - void Renderer::endFrame(void *perFrameData, const int32 fbChannelFlags) + void Renderer::endFrame(void *perFrameData, const int32 /*fbChannelFlags*/) { - FrameBuffer *fb = this->currentFB; ispc::Renderer_endFrame(getIE(),perFrameData); } diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index 03ddf1efd3..062785f624 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -249,8 +249,7 @@ namespace ospray { printed = true; } - - return Renderer::renderFrame(fb,channelFlags);; + return Renderer::renderFrame(fb,channelFlags); } // ======================================================= @@ -327,9 +326,10 @@ namespace ospray { lights.clear(); - if (lightsData) + if (lightsData) { for (size_t i=0; isize(); i++) lights.push_back(((Light **)lightsData->data)[i]->getIE()); + } ispc::RaycastVolumeRenderer_setLights(ispcEquivalent, lights.empty() ? NULL : &lights[0], From d4b573885e4f04ce9f44a901549e278273878073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 30 Mar 2016 14:15:08 +0200 Subject: [PATCH 164/310] Use built-in for rsqrtf --- ospray/math/math.ih | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/math/math.ih b/ospray/math/math.ih index 49b1e42572..5704fe53a4 100644 --- a/ospray/math/math.ih +++ b/ospray/math/math.ih @@ -46,9 +46,9 @@ inline float sqrtf(const float f) { return sqrt(f); } inline uniform float sqrtf(const uniform float f) { return sqrt(f); } /*! c-style reciprocal square root. */ -inline float rsqrtf(const float f) { return rcpf(sqrtf(f)); } +inline float rsqrtf(const float f) { return rsqrt(f); } /*! c-style reciprocal square root */ -inline uniform float rsqrtf(const uniform float f) { return rcpf(sqrtf(f)); } +inline uniform float rsqrtf(const uniform float f) { return rsqrt(f); } /*! square. */ inline float sqr(const float f) { return f*f; } From 6ff94a244148e39fc310aafebe4326a291870c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 30 Mar 2016 15:21:02 +0200 Subject: [PATCH 165/310] Variance independent of image size, defaults to inf --- ospray/fb/LocalFB.cpp | 8 ++++---- ospray/fb/LocalFB.ispc | 27 +++++++++++++-------------- ospray/math/Distribution2D.ispc | 2 +- ospray/mpi/DistributedFrameBuffer.h | 4 ++-- ospray/mpi/MPILoadBalancer.cpp | 2 +- ospray/render/LoadBalancer.cpp | 4 ++-- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 95498d39f5..fdc5a475eb 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -111,7 +111,7 @@ namespace ospray { // always also also error buffer (if present) if (hasVarianceBuffer) { for (int i = 0; i < tiles; i++) - tileErrorBuffer[i] = 1.0f; + tileErrorBuffer[i] = inf; } } } @@ -146,7 +146,7 @@ namespace ospray { float LocalFrameBuffer::tileError(const vec2i &tile) { int idx = tile.y * tilesx + tile.x; - return hasVarianceBuffer && tileAccumID[idx] > 3 ? tileErrorBuffer[idx] : 1.0f; + return hasVarianceBuffer && tileAccumID[idx] > 1 ? tileErrorBuffer[idx] : inf; } float LocalFrameBuffer::frameError() @@ -154,10 +154,10 @@ namespace ospray { if (hasVarianceBuffer) { float maxErr = 0.0f; for (int i = 0; i < tiles; i++) - maxErr = tileAccumID[i] > 3 ? std::max(maxErr, tileErrorBuffer[i]) : 1.0f; + maxErr = tileAccumID[i] > 1 ? std::max(maxErr, tileErrorBuffer[i]) : inf; return maxErr; } else - return 1.0f; + return inf; } const void *LocalFrameBuffer::mapDepthBuffer() diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 5662ca9c7c..980a29ce37 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -113,13 +113,11 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, if (!accum) return; VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; - uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; uniform vec4f *uniform variance = fb->varianceBuffer; const uniform float accScale = rcpf(tile.accumID+1); const uniform float accHalfScale = rcpf(tile.accumID/2+1); float err = 0.f; - float cnt = 0.f; for (uniform uint32 iy=0;iy 0) + if (tile.accumID > 1) vari = make_vec3f(variance[pixelID]); unmasked { vari.x += varyTile->r[chunkID]; @@ -158,11 +156,11 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, variance[pixelID] = make_vec4f(vari); const vec3f accs = accScale * make_vec3f(acc); - const vec3f diff = absf(accs - accHalfScale * vari); - const float den = sqrtf(accs.x + accs.y + accs.z); - if (den > 0) - err = err + (diff.x + diff.y + diff.z) / den; - cnt += 1.0f; + const float den2 = accs.x + accs.y + accs.z; + if (den2 > 0.0f) { + const vec3f diff = absf(accs - accHalfScale * vari); + err += (diff.x + diff.y + diff.z) * rsqrtf(den2); + } } unmasked { @@ -174,15 +172,16 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, } } - const uniform tileId = tileIdx.y*fb->numTiles.x + tileIdx.x; + const uniform vec2i tileIdx = tile.region.lower/TILE_SIZE; + const uniform int32 tileId = tileIdx.y*fb->numTiles.x + tileIdx.x; fb->tileAccumID[tileId]++; // error is also only updated every other frame to avoid alternating error // (get a monotone sequence) - if (variance && (tile.accumID & 1) == 0) { - const uniform float cntu = reduce_add(cnt); - const uniform float r = sqrt(cntu / (tile.fbSize.x * tile.fbSize.y)); - const uniform float errf = r * reduce_add(err) / cntu; + if (variance && (tile.accumID & 1) == 1) { + uniform vec2i dia = tile.region.upper - tile.region.lower; + uniform float cntu = (uniform float)dia.x * dia.y; + const uniform float errf = reduce_add(err) * rsqrtf(cntu); // print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, errf); fb->tileErrorBuffer[tileId] = errf; } diff --git a/ospray/math/Distribution2D.ispc b/ospray/math/Distribution2D.ispc index 8afb72a729..cbeb3645fd 100644 --- a/ospray/math/Distribution2D.ispc +++ b/ospray/math/Distribution2D.ispc @@ -29,7 +29,7 @@ uniform float Distribution1D_create(const uniform int size, uniform float* unifo // compute reciprocal sum const uniform float rcpSum = 1.0f/sum; - // next representatble number in float greater than 1.0f + // next representable number in float greater than 1.0f const uniform float nextAfter1 = 0x1.000002p+0f; // normalize diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index cdda5598e8..e7bdadcbda 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -44,8 +44,8 @@ namespace ospray { int accumId; int32 accumID(const vec2i &tile) override { return accumId; } - float tileError(const vec2i &tile) override { return 1.0f; } - float frameError() override { return 1.0f; } + float tileError(const vec2i &tile) override { return inf; } + float frameError() override { return inf; } /*! color buffer and depth buffer on master */ diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index 553dbac455..6939b30058 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -51,7 +51,7 @@ namespace ospray { async_endFrame(); - return dfb->frameError();//XXX + return dfb->frameError(); } std::string Master::toString() const diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index 7131469cb2..b098a46de8 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -58,7 +58,7 @@ namespace ospray { const vec2i tileID(tile_x, tile_y); const int32 accumID = fb->accumID(tileID); - if (fb->tileError(tileID) < renderer->errorThreshold) + if (fb->tileError(tileID) <= renderer->errorThreshold) return; Tile tile(tileID, fb->size, accumID); @@ -109,7 +109,7 @@ namespace ospray { const vec2i tileID(tile_x, tile_y); const int32 accumID = fb->accumID(tileID); - if (fb->tileError(tileID) < renderer->errorThreshold) + if (fb->tileError(tileID) <= renderer->errorThreshold) return; Tile tile(tileID, fb->size, accumID); From c08fc5a2b0c69fae0c499f506e40e1df4eb79443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 30 Mar 2016 16:30:37 +0200 Subject: [PATCH 166/310] Estimate error (again) using valid pixel count --- ospray/fb/LocalFB.ispc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 980a29ce37..1bdb772216 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -118,6 +118,7 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, const uniform float accScale = rcpf(tile.accumID+1); const uniform float accHalfScale = rcpf(tile.accumID/2+1); float err = 0.f; + float cnt = 0.f; for (uniform uint32 iy=0;iy 0.0f) { const vec3f diff = absf(accs - accHalfScale * vari); err += (diff.x + diff.y + diff.z) * rsqrtf(den2); + cnt++; } } @@ -179,9 +181,8 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, // error is also only updated every other frame to avoid alternating error // (get a monotone sequence) if (variance && (tile.accumID & 1) == 1) { - uniform vec2i dia = tile.region.upper - tile.region.lower; - uniform float cntu = (uniform float)dia.x * dia.y; - const uniform float errf = reduce_add(err) * rsqrtf(cntu); + const uniform float cntu = reduce_add(cnt); + const uniform float errf = cntu > 0.f ? reduce_add(err) * rsqrtf(cntu) : 0.f; // print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, errf); fb->tileErrorBuffer[tileId] = errf; } From de6eb50218032f018b1f2c9fbeafa5130f380868 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 30 Mar 2016 13:55:02 -0500 Subject: [PATCH 167/310] add build job for SLES --- .gitlab-ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5aeebffa31..c8646ac99a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,3 +28,10 @@ build-ubuntu: - scripts/build_gitlab.sh tags: - ubuntu + +build-sles: + type: build + script: + - scripts/build_gitlab.sh + tags: + - sles From a61872b7998bf17f72a94e90592d4b989b0ed9e4 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 30 Mar 2016 20:41:41 -0500 Subject: [PATCH 168/310] add OS X build to CI --- .gitlab-ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c8646ac99a..5c1bdc95a5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,3 +35,10 @@ build-sles: - scripts/build_gitlab.sh tags: - sles + +build-osx: + type: build + script: + - scripts/build_gitlab.sh + tags: + - osx From fdeb7928f748aaf39aaab3e6a8afc56096d99bca Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 30 Mar 2016 20:56:30 -0500 Subject: [PATCH 169/310] udpate CI build scripts to be platform specific (can be further specialized) --- .gitlab-ci.yml | 12 ++++++------ scripts/{build_gitlab.sh => build_gitlab/linux.sh} | 0 scripts/build_gitlab/osx.sh | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) rename scripts/{build_gitlab.sh => build_gitlab/linux.sh} (100%) create mode 100755 scripts/build_gitlab/osx.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5c1bdc95a5..da42ceab58 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,41 +4,41 @@ stages: build-centos6: type: build script: - - scripts/build_gitlab.sh + - scripts/build_gitlab/linux.sh tags: - centos6 build-centos7: type: build script: - - scripts/build_gitlab.sh + - scripts/build_gitlab/linux.sh tags: - centos7 build-fedora: type: build script: - - scripts/build_gitlab.sh + - scripts/build_gitlab/linux.sh tags: - fedora build-ubuntu: type: build script: - - scripts/build_gitlab.sh + - scripts/build_gitlab/linux.sh tags: - ubuntu build-sles: type: build script: - - scripts/build_gitlab.sh + - scripts/build_gitlab/linux.sh tags: - sles build-osx: type: build script: - - scripts/build_gitlab.sh + - scripts/build_gitlab/osx.sh tags: - osx diff --git a/scripts/build_gitlab.sh b/scripts/build_gitlab/linux.sh similarity index 100% rename from scripts/build_gitlab.sh rename to scripts/build_gitlab/linux.sh diff --git a/scripts/build_gitlab/osx.sh b/scripts/build_gitlab/osx.sh new file mode 100755 index 0000000000..d1b7d496b6 --- /dev/null +++ b/scripts/build_gitlab/osx.sh @@ -0,0 +1,14 @@ +#/bin/sh + +alias nproc='sysctrl -n hw.ncpu' + +mkdir build +cd build +rm -rf * + +# NOTE(jda) - using Internal tasking system here temporarily to avoid installing TBB +cmake \ +-D OSPRAY_TASKING_SYSTEM=Internal \ +.. + +make -j`nproc` From fcf005a405cbce20ed44a413091d8e3b7e24d6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 31 Mar 2016 11:25:29 +0200 Subject: [PATCH 170/310] Fix build of ospray_common on Windows --- common/CMakeLists.txt | 14 +++++++++----- common/network.cpp | 8 ++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 48bb219ebb..b8f6decdc2 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -16,6 +16,9 @@ CONFIGURE_OSPRAY() +SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) +FIND_PACKAGE(Threads REQUIRED) + OSPRAY_ADD_LIBRARY(ospray_common SHARED common.cpp FileName.cpp @@ -39,11 +42,12 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED vec.h ) -IF(NOT THIS_IS_MIC) - TARGET_LINK_LIBRARIES(ospray_common - # for network.cpp - pthread - ) +OSPRAY_LIBRARY_LINK_LIBRARIES(ospray_common + ${CMAKE_THREAD_LIBS_INIT} + ${CMAKE_DL_LIBS} +) +IF (WIN32) + OSPRAY_LIBRARY_LINK_LIBRARIES(ospray_common ws2_32) ENDIF() OSPRAY_SET_LIBRARY_VERSION(ospray_common) diff --git a/common/network.cpp b/common/network.cpp index c2441f6aa7..f63129bbe9 100644 --- a/common/network.cpp +++ b/common/network.cpp @@ -16,15 +16,15 @@ #include "network.h" #include "string.h" -//#include "mutex.h" //////////////////////////////////////////////////////////////////////////////// /// Platforms supporting Socket interface //////////////////////////////////////////////////////////////////////////////// #ifdef _WIN32 +#include #define _WINSOCK_DEPRECATED_NO_WARNINGS -//#include +#include //#include typedef int socklen_t; #define SHUT_RDWR 0x2 @@ -55,8 +55,8 @@ namespace ospcommon __forceinline void initialize() { #ifdef _WIN32 static bool initialized = false; - static MutexSys initMutex; - Lock lock(initMutex); + static std::mutex initMutex; + std::lock_guard lock(initMutex); WSADATA wsaData; short version = MAKEWORD(1,1); if (WSAStartup(version,&wsaData) != 0) From cc1c89c018e125185f73a3dd62ae02db2e920e6e Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 31 Mar 2016 13:18:31 -0500 Subject: [PATCH 171/310] update linux CI build to include the particle viewer and tachyon module --- scripts/build_gitlab/linux.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/build_gitlab/linux.sh b/scripts/build_gitlab/linux.sh index 1a256e52a0..a4bfaefcce 100755 --- a/scripts/build_gitlab/linux.sh +++ b/scripts/build_gitlab/linux.sh @@ -3,5 +3,9 @@ mkdir build cd build rm -rf * -cmake .. +cmake \ + -D OSPRAY_BUILD_ISA=ALL \ + -D OSPRAY_APPS_PARTICLEVIEWER=ON \ + -D OSPRAY_MODULE_TACHYON=ON \ +.. make -j`nproc` From 923a48a6c5ebb4511579aa0f9ab63ad374cc2577 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Thu, 31 Mar 2016 16:33:25 -0600 Subject: [PATCH 172/310] Enable client-side search for doxygen docs --- doc/dox/doxyconfig.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/dox/doxyconfig.in b/doc/dox/doxyconfig.in index f00d311340..f739b0b8cc 100755 --- a/doc/dox/doxyconfig.in +++ b/doc/dox/doxyconfig.in @@ -1077,7 +1077,7 @@ FORMULA_FONTSIZE = 10 # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. -SEARCHENGINE = NO +SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client @@ -1087,7 +1087,7 @@ SEARCHENGINE = NO # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. -#SERVER_BASED_SEARCH = NO +SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output From fcc4aad8d7f4f3338cf8bc431278edf7bcf241fb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 31 Mar 2016 19:09:39 -0500 Subject: [PATCH 173/310] fix ospray find_package config --- cmake/ospray_cmake_config/osprayConfig.cmake.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index 694bddfd84..e20c141e32 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -135,7 +135,7 @@ if(@OSPRAY_USE_EXTERNAL_EMBREE@) # Find existing Embree on the machine find_package(embree @REQUIRED_MINIMUM_EMBREE@ REQUIRED) else() - set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.2) + set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.2) endif() # Restore state @@ -182,7 +182,7 @@ set(OSPRAY_LIBRARIES #ospray# NOTE(jda) - target disabled (see above) #ospray_embree# NOTE(jda) - target disabled (see above) ${EMBREE_LIBRARY} - ${CURRENT_ROOT_INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} + ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} ) # Reset CMake module path to its state when this script was called. From fd2d2aa8645de0749e6c39f741e271d1b139828a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 1 Apr 2016 13:08:03 +0200 Subject: [PATCH 174/310] Fix accumulation in MPI mode --- ospray/mpi/DistributedFrameBuffer.cpp | 11 +++++++---- ospray/mpi/DistributedFrameBuffer.ispc | 7 +++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index c0b9f75e5f..87c5ba3e02 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -132,7 +132,7 @@ namespace ospray { (ispc::VaryingTile *)&this->final, (ispc::VaryingTile *)&this->accum, (ispc::VaryingRGBA_I8 *)&this->color, - dfb->hasAccumBuffer,dfb->accumId); + dfb->hasAccumBuffer); dfb->tileIsCompleted(this); for (int i=0;ifinal, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, - dfb->hasAccumBuffer,dfb->accumId); + dfb->hasAccumBuffer); dfb->tileIsCompleted(this); } @@ -196,7 +196,7 @@ namespace ospray { (ispc::VaryingTile*)&this->final, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, - dfb->hasAccumBuffer,dfb->accumId); + dfb->hasAccumBuffer); dfb->tileIsCompleted(this); } } @@ -213,6 +213,9 @@ namespace ospray { DBG(printf("rank %i starting new frame\n",mpi::world.rank)); assert(!frameIsActive); + if (hasAccumBuffer) + accumId++; + if (pixelOp) pixelOp->beginFrame(); @@ -578,7 +581,7 @@ namespace ospray { }); if (fbChannelFlags & OSP_FB_ACCUM) - accumId = 0; + accumId = -1; // we increment at the start of the frame } } diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index b2cde53003..fc3449a803 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -78,10 +78,9 @@ export void DFB_accumulate(VaryingTile *uniform tile, VaryingTile *uniform final, VaryingTile *uniform accum, VaryingRGBA_I8 *uniform color, - uniform bool hasAccumBuffer, - uniform int32 accumID) + uniform bool hasAccumBuffer) { - if (!hasAccumBuffer || accumID < 1) { + if (!hasAccumBuffer || tile->accumID < 1) { for (uniform int i=0;ir[i], tile->g[i], @@ -98,7 +97,7 @@ export void DFB_accumulate(VaryingTile *uniform tile, color->color[i] = cvt_uint32(col); } } else { - const float rcpAccumID = 1.f/(accumID+1); + const uniform float rcpAccumID = 1.f/(tile->accumID+1); for (uniform int i=0;ir[i], From 4a7acc2585cfc863746ebf3d70c729d42c880bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 1 Apr 2016 13:47:42 +0200 Subject: [PATCH 175/310] Fix missing gamma correction in MPI mode --- ospray/mpi/DistributedFrameBuffer.ispc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index fc3449a803..fb82b38467 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -94,6 +94,12 @@ export void DFB_accumulate(VaryingTile *uniform tile, final->g[i] = col.y; final->b[i] = col.z; final->a[i] = col.w; + + // XXX hardcoded gamma, should use pixelops! + col = max(col,make_vec4f(0.f)); + // alpha is never gamma-corrected + col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); + color->color[i] = cvt_uint32(col); } } else { @@ -120,6 +126,12 @@ export void DFB_accumulate(VaryingTile *uniform tile, final->g[i] = col.y; final->b[i] = col.z; final->a[i] = col.w; + + // XXX hardcoded gamma, should use pixelops! + col = max(col,make_vec4f(0.f)); + // alpha is never gamma-corrected + col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); + color->color[i] = cvt_uint32(col); } } From 3ad7a701cef82a41805eb1ead8de94a6bddacf6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 1 Apr 2016 21:31:07 +0200 Subject: [PATCH 176/310] OSPRay does have a name again... --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae3ee5adb7..6f7b0a01a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,8 @@ ## limitations under the License. ## ## ======================================================================== ## +PROJECT(OSPRay) + CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_POLICY(SET CMP0003 NEW) # since 2.6 IF(POLICY CMP0015) From 79e7fbb5a88711a36eec68d13fd2e5c4d83f8632 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 1 Apr 2016 18:41:41 -0500 Subject: [PATCH 177/310] add clang CI build job for ubuntu, add compiler tags to each job --- .gitlab-ci.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index da42ceab58..371fc1543f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,7 @@ build-centos6: - scripts/build_gitlab/linux.sh tags: - centos6 + - gcc build-centos7: type: build @@ -14,6 +15,7 @@ build-centos7: - scripts/build_gitlab/linux.sh tags: - centos7 + - gcc build-fedora: type: build @@ -21,13 +23,25 @@ build-fedora: - scripts/build_gitlab/linux.sh tags: - fedora + - gcc -build-ubuntu: +build-ubuntu-gcc: type: build script: - scripts/build_gitlab/linux.sh tags: - ubuntu + - gcc + +build-ubuntu-clang: + type: build + script: + - export CC=clang + - export CXX=clang++ + - scripts/build_gitlab/linux.sh + tags: + - ubuntu + - clang build-sles: type: build @@ -35,6 +49,7 @@ build-sles: - scripts/build_gitlab/linux.sh tags: - sles + - gcc build-osx: type: build @@ -42,3 +57,4 @@ build-osx: - scripts/build_gitlab/osx.sh tags: - osx + - clang From 37788579cd6eaaf200f02de1fc6fc5154bb1dccd Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Sun, 3 Apr 2016 16:45:51 -0500 Subject: [PATCH 178/310] disable ubunt-clang CI build (doesn't work on 14.04), use naming convention --- .gitlab-ci.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 371fc1543f..9957eb185d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ stages: - build -build-centos6: +build-centos6-gcc: type: build script: - scripts/build_gitlab/linux.sh @@ -9,7 +9,7 @@ build-centos6: - centos6 - gcc -build-centos7: +build-centos7-gcc: type: build script: - scripts/build_gitlab/linux.sh @@ -17,7 +17,7 @@ build-centos7: - centos7 - gcc -build-fedora: +build-fedora-gcc: type: build script: - scripts/build_gitlab/linux.sh @@ -33,17 +33,17 @@ build-ubuntu-gcc: - ubuntu - gcc -build-ubuntu-clang: - type: build - script: - - export CC=clang - - export CXX=clang++ - - scripts/build_gitlab/linux.sh - tags: - - ubuntu - - clang +#build-ubuntu-clang: +# type: build +# script: +# - export CC=clang +# - export CXX=clang++ +# - scripts/build_gitlab/linux.sh +# tags: +# - ubuntu +# - clang -build-sles: +build-sles-gcc: type: build script: - scripts/build_gitlab/linux.sh @@ -51,7 +51,7 @@ build-sles: - sles - gcc -build-osx: +build-osx-clang: type: build script: - scripts/build_gitlab/osx.sh From 31542251cc57348b249b79dd4071eeda30424fe2 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Mon, 4 Apr 2016 09:26:42 -0500 Subject: [PATCH 179/310] missing box1f for amr module --- ospray/math/box.ih | 21 +++++++++++++++++++++ ospray/math/vec.ih | 14 ++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ospray/math/box.ih b/ospray/math/box.ih index 51b5f83757..d641b3eeee 100644 --- a/ospray/math/box.ih +++ b/ospray/math/box.ih @@ -18,6 +18,12 @@ #include "vec.ih" +//! a 1-d float bounding box (ie, a range +struct box1f { + float lower; + float upper; +}; + //! a 2-d float bounding box struct box2f { vec2f lower; @@ -57,6 +63,21 @@ struct box4f { }; +// ------------------------------------------------------- +// all box1f operations +// ------------------------------------------------------- + +/*! construct 1f range from a single float */ +inline uniform box1f make_box1f(const uniform float f) +{ uniform box1f bb; bb.lower = bb.upper = f; return bb; } + +/*! construct 1f range from lower and upper value */ +inline uniform box1f make_box1f(const uniform float lo, const uniform float hi) +{ uniform box1f bb; bb.lower = lo; bb.upper = hi; return bb; } + +inline uniform box1f box_union(const uniform box1f &a, const uniform box1f &b) +{ return make_box1f(min(a.lower,b.lower),max(a.upper,b.upper)); } + // ------------------------------------------------------- // box3f 'constructors' // ------------------------------------------------------- diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 566f271df9..fb23d34663 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -776,3 +776,17 @@ inline void out(uniform vec3f v) { print("(%,%,%)",v.x,v.y,v.z); } inline void out(vec3f v) { print("\n(%\n %\n %)",v.x,v.y,v.z); } inline void out(uniform vec3i v) { print("(%,%,%)",v.x,v.y,v.z); } inline void out(vec3i v) { print("\n(%\n %\n %)",v.x,v.y,v.z); } + + +// ------------------------------------------------------- +// set/get functions for vectors +// should eventually get moved to macros so they work for all types +// ------------------------------------------------------- + +/*! set vector 'v's value in dimension 'd' to 'f' */ +inline void set(uniform vec3f &v, const uniform uint32 dim, const uniform float f) +{ (&v.x)[dim] = f; } + +/*! get vector 'v's value in dimension 'd' */ +inline float get(const uniform vec3f &v, const uniform uint32 dim) +{ return (&v.x)[dim]; } From 332ad44eee8c83b0fc6bf641f417449750f3dbfb Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Wed, 6 Apr 2016 10:07:13 -0600 Subject: [PATCH 180/310] conflict eliminated --- apps/qtViewer/ModelViewer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/qtViewer/ModelViewer.cpp b/apps/qtViewer/ModelViewer.cpp index e9cf04557e..99cb2e5fc5 100644 --- a/apps/qtViewer/ModelViewer.cpp +++ b/apps/qtViewer/ModelViewer.cpp @@ -158,10 +158,6 @@ namespace ospray { sg::TransferFunction *xf = dynamic_cast (sgRenderer->uniqueNodes.object[i]->node.ptr); if (xf) xferFuncs.push_back(xf); -<<<<<<< HEAD -======= - // cout << "FOUND xf : " << xf << endl; ->>>>>>> 4630fcb4d1f8a05eec45d7b9dc251812d4f0f42c } std::cout << "#osp:qtv: found " << xferFuncs.size() << " transfer function nodes" << std::endl; From 5fbb44d1d5adbe4ba30de9cfa0bb07c1bc27c8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 5 Apr 2016 11:32:52 +0200 Subject: [PATCH 181/310] Precompute frame for DirectionalLight --- ospray/lights/DirectionalLight.ispc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 9f6f476e3f..c6006793d7 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -21,7 +21,7 @@ struct DirectionalLight { Light super; //!< inherited light fields - vec3f direction; //!< direction *towards* the light source + linear3f frame; //!< coordinate frame, with vz == direction *towards* the light source vec3f radiance; //!< RGB color and intensity of light float cosAngle; //!< Angular limit of the cone light in an easier to use form: cosine of the half angle in radians float pdf; //!< Probability to sample a direction to the light @@ -41,12 +41,12 @@ varying LightSample DirectionalLight_sample(const uniform Light *uniform _self, const DirectionalLight *uniform self = (DirectionalLight *uniform)_self; LightSample sample; - sample.direction = self->direction; + sample.direction = self->frame.vz; sample.distance = inf; sample.pdf = self->pdf; if (self->cosAngle < COS_ANGLE_MAX) - sample.direction = frame(sample.direction) * uniformSampleCone(self->cosAngle, s); + sample.direction = self->frame * uniformSampleCone(self->cosAngle, s); sample.radiance = self->radiance; @@ -57,7 +57,7 @@ varying vec3f DirectionalLight_evalEnv(const uniform Light *uniform _self, const varying vec3f &dir) { uniform DirectionalLight *uniform self = (uniform DirectionalLight *uniform)_self; - if (self->cosAngle < COS_ANGLE_MAX && dot(self->direction, dir) > self->cosAngle) + if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) return self->radiance * self->pdf; else return make_vec3f(0.f); @@ -74,7 +74,7 @@ export void DirectionalLight_set(void *uniform _self, const uniform float cosAngle) { uniform DirectionalLight *uniform self = (uniform DirectionalLight *uniform)_self; - self->direction = direction; + self->frame = frame(direction); self->radiance = radiance; self->cosAngle = cosAngle; self->pdf = cosAngle < COS_ANGLE_MAX ? uniformSampleConePDF(cosAngle) : 1.f; From 5438c11616f81e6fc0d6ba65c98904bfc46041aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 5 Apr 2016 17:33:25 +0200 Subject: [PATCH 182/310] Change light interface for eval --- ospray/lights/AmbientLight.ispc | 15 ++++++--- ospray/lights/DirectionalLight.ispc | 26 +++++++++----- ospray/lights/HDRILight.ispc | 17 +++++++--- ospray/lights/Light.ih | 23 +++++++++---- ospray/lights/Light.ispc | 11 ++++-- ospray/lights/PointLight.ispc | 43 ++++++++++++++++++++++-- ospray/render/pathtracer/PathTracer.ispc | 3 +- 7 files changed, 106 insertions(+), 32 deletions(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 933e58717f..90cc5abdc1 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -44,11 +44,18 @@ varying LightSample AmbientLight_sample(const uniform Light *uniform _self, return sample; } -varying vec3f AmbientLight_evalEnv(const uniform Light *uniform _self, - const varying vec3f &) +varying LightEval AmbientLight_eval(const uniform Light *uniform _self, + const varying vec3f &pos, + const varying vec3f &) { uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; - return self->radiance; + LightEval res; + + res.radiance = self->radiance; + res.distance = inf; + res.pdf = 1.f/(4.f * M_PI); // uniformSampleSpherePDF(); // XXX inconsistent to sample, need surface normal here + + return res; } @@ -59,7 +66,7 @@ void AmbientLight_Constructor(uniform AmbientLight *uniform self, Light_Constructor(&self->super, cppEquivalent); self->radiance = radiance; self->super.sample = AmbientLight_sample; - self->super.evalEnv = AmbientLight_evalEnv; + self->super.eval = AmbientLight_eval; } diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index c6006793d7..518e663572 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -48,19 +48,28 @@ varying LightSample DirectionalLight_sample(const uniform Light *uniform _self, if (self->cosAngle < COS_ANGLE_MAX) sample.direction = self->frame * uniformSampleCone(self->cosAngle, s); - sample.radiance = self->radiance; + sample.radiance = self->radiance; // *pdf/pdf cancel return sample; } -varying vec3f DirectionalLight_evalEnv(const uniform Light *uniform _self, - const varying vec3f &dir) +varying LightEval DirectionalLight_eval(const uniform Light *uniform _self, + const varying vec3f &pos, + const varying vec3f &dir) { uniform DirectionalLight *uniform self = (uniform DirectionalLight *uniform)_self; - if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) - return self->radiance * self->pdf; - else - return make_vec3f(0.f); + LightEval res; + res.distance = inf; + + if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) { + res.radiance = self->radiance * self->pdf; + res.pdf = self->pdf; + } else { + res.radiance = make_vec3f(0.f); + res.pdf = 0.f; + } + + return res; } @@ -86,8 +95,7 @@ export void *uniform DirectionalLight_create(void *uniform cppEquivalent) uniform DirectionalLight *uniform self = uniform new uniform DirectionalLight; Light_Constructor(&self->super, cppEquivalent); self->super.sample = DirectionalLight_sample; - // TODO: an (indirectly) visible sun disc causes too high variance, needs to be fixed with MIS - // self->super.evalEnv = DirectionalLight_evalEnv; + self->super.eval = DirectionalLight_eval; DirectionalLight_set(self, make_vec3f(0.f, 0.f, 1.f), make_vec3f(1.f), 1.f); return self; diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index 12e236e22d..648d0a5512 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -74,17 +74,24 @@ varying LightSample HDRILight_sample(const uniform Light *uniform _self, return sample; } -varying vec3f HDRILight_evalEnv(const uniform Light *uniform _self, - const varying vec3f &dir) +varying LightEval HDRILight_eval(const uniform Light *uniform _self, + const varying vec3f &, + const varying vec3f &dir) { uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; + LightEval res; const vec3f localDir = self->world2light * dir; const float u = atan2(localDir.y, localDir.x) * one_over_two_pi; const float v = acos(localDir.z) * one_over_pi; + const vec2f uv = make_vec2f(u, v); - return get3f(self->map, make_vec2f(u, v)) * self->intensity; + res.radiance = get3f(self->map, uv) * self->intensity; + res.distance = inf; + res.pdf = Distribution2D_pdf(self->distribution, uv); + + return res; } @@ -138,10 +145,10 @@ export void HDRILight_set(void *uniform _self, // no delete[] importance: ownership was transferred to Distribution2D self->super.sample = HDRILight_sample; - self->super.evalEnv = HDRILight_evalEnv; + self->super.eval = HDRILight_eval; } else { self->super.sample = HDRILight_sample_dummy; - self->super.evalEnv = defaultEvalEnv; + self->super.eval = defaultEval; } } diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index 2367cb6706..7a0a390dbc 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -31,30 +31,39 @@ struct LightSample //! compute the weighted radiance at a point caused by a sample on the light source // by convention, giving (0, 0) as "random" numbers should sample the "center" // of the light source (used by the raytracing renderers such as the OBJ renderer) -typedef varying LightSample (*Light_SampleFct)(const uniform Light *uniform _self, - /*! point to generate the sample for >*/ const varying DifferentialGeometry &dg, +typedef varying LightSample (*Light_SampleFct)(const uniform Light *uniform, + /*! point to generate the sample for >*/ const varying DifferentialGeometry&, /*! random numbers to generate the sample >*/ const varying vec2f &s); -//! compute the radiance caused by the light source (pointed to by the given direction) from inf -typedef varying vec3f (*Light_EvalEnvFct)(const uniform Light *uniform _self, + +struct LightEval +{ + vec3f radiance; //!< radiance that arrives at the given point (not weighted by pdf) + float distance; + float pdf; //!< probability that the direction would have been sampled +}; + +//! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction) from pos +typedef varying LightEval (*Light_EvalFct)(const uniform Light *uniform, + /*! position of point >*/const varying vec3f &pos, /*! direction towards the light source >*/const varying vec3f &dir); struct Light { Light_SampleFct sample; - Light_EvalEnvFct evalEnv; + Light_EvalFct eval; //! Pointer back to the C++ equivalent of this class. void *uniform cppEquivalent; }; -varying vec3f defaultEvalEnv(const uniform Light *uniform, const varying vec3f &); +varying LightEval defaultEval(const uniform Light *uniform, const varying vec3f &, const varying vec3f &); //! constructor for ispc-side light object inline void Light_Constructor(uniform Light *uniform self, void *uniform cppEquivalent) { self->cppEquivalent = cppEquivalent; - self->evalEnv = defaultEvalEnv; + self->eval = defaultEval; } diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index 7fe95752fe..7e8619cc8b 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -16,8 +16,13 @@ #include "Light.ih" -varying vec3f defaultEvalEnv(const uniform Light *uniform, - const varying vec3f &) +varying LightEval defaultEval(const uniform Light *uniform, + const varying vec3f &, + const varying vec3f &) { - return make_vec3f(0.f); + LightEval res; + res.radiance = make_vec3f(0.f); + res.distance = inf; + res.pdf = 0.f; + return res; } diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 39c6727bde..9c99cf8d61 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -49,10 +49,10 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, sample.pdf = 1.f; // per default we always take this sample // convert from power to radiance by attenuating by distance^2 - sample.radiance = self->power * (invdist * invdist); + sample.radiance = self->power * sqr(invdist); const float sinTheta = self->radius * invdist; - if (self->radius > 0. & sinTheta > 0.005f) { + if (self->radius > 0.f & sinTheta > 0.005f) { // sample surface of sphere as seen by hit point -> cone of directions // for very small cones treat as point light, because float precision is not good enough if (sinTheta < 1.f) { @@ -62,12 +62,13 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, sample.pdf = uniformSampleConePDF(cosTheta); const float c = localDir.z; sample.distance = c*sample.distance - sqrt(self->radius*self->radius - (1.f - c*c) * dist2); + // TODO scale radiance by actual distance } else { // inside sphere const vec3f localDir = cosineSampleHemisphere(s); sample.direction = frame(dg.Ns) * localDir; sample.pdf = cosineSampleHemispherePDF(localDir); // TODO: - sample.radiance = self->power * rcp(self->radius*self->radius); + sample.radiance = self->power * rcp(sqr(self->radius)); sample.distance = self->radius; } } @@ -75,6 +76,41 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, return sample; } +varying LightEval PointLight_eval(const uniform Light *uniform _self, + const varying vec3f &pos, + const varying vec3f &dir) +{ + const PointLight *uniform self = (PointLight *uniform)_self; + LightEval res; + res.radiance = make_vec3f(0.f); + res.distance = inf; + res.pdf = 0.f; + + if (self->radius > 0.f) { + const vec3f A = self->position - pos; + const float a = dot(dir, dir); + const float b = 2.f * dot(dir, A); + const float centerDist2 = dot(A, A); + const float c = centerDist2 - sqr(self->radius); + const float radical = sqr(b) - 4.f*a*c; + + if (radical > 0.f) { + const float t_near = (b - sqrt(radical)) / (2.f*a); + const float t_far = (b + sqrt(radical)) / (2.f*a); + + if (t_far > 0.0f) { + res.distance = t_near; + const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); + const float cosTheta = sqrt(1.f - sinTheta2); + res.pdf = uniformSampleConePDF(cosTheta); + const float invdist = rcp(t_near); + res.radiance = self->power * res.pdf * sqr(invdist); + } + } + } + + return res; +} // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// @@ -97,6 +133,7 @@ export void *uniform PointLight_create(void *uniform cppEquivalent) uniform PointLight *uniform self = uniform new uniform PointLight; Light_Constructor(&self->super, cppEquivalent); self->super.sample = PointLight_sample; + self->super.eval = PointLight_eval; PointLight_set(self, make_vec3f(0.f), make_vec3f(1.f), 0.f); return self; diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 9ee7db838c..a3f2cf3180 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -154,7 +154,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, } else if (!lightPath.ignoreVisibleLights) for (uniform int i = 0; i < self->numLights; i++) { // TODO: self->num_envLights const uniform Light *uniform l = self->lights[i]; - L = L + Lw * l->evalEnv(l, lightPath.ray.dir); + LightEval le = l->eval(l, lightPath.ray.org, lightPath.ray.dir); + L = L + Lw * le.radiance; } break; From ef089eab6a865412a88f58aa52c26a405114fbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 6 Apr 2016 15:06:06 +0200 Subject: [PATCH 183/310] Implement MIS --- ospray/render/pathtracer/PathTracer.ispc | 65 ++++++++++++------------ ospray/render/pathtracer/bsdfs/BSDF.ih | 3 ++ 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index a3f2cf3180..89109ae3b6 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -33,13 +33,8 @@ struct LightPath Ray ray; /*! Last ray in the path. */ Medium lastMedium; /*! Medium the last ray travels inside. */ uniform uint32 depth; /*! Recursion depth of path. */ - vec3f throughput; /*! Determines the fraction of - radiance reaches the pixel along - the path. */ - bool ignoreVisibleLights; /*! If the previous shade point used - shadow rays we have to ignore the - emission of geometrical lights to - not double count them. */ + float bsdfPdf; // for MIS + BSDFType bsdfType; // for MIS bool unbent; /*! True of the ray path is a straight line. */ }; @@ -48,8 +43,8 @@ inline void init_LightPath(LightPath& lp, const Ray &ray) lp.ray = ray; lp.lastMedium = make_Medium_Vacuum(); lp.depth = 0; - lp.throughput = make_vec3f(1.f); - lp.ignoreVisibleLights = false; + lp.bsdfPdf = 1.0f; + lp.bsdfType = BSDF_SPECULAR_TRANSMISSION; lp.unbent = true; } @@ -58,16 +53,22 @@ inline void extend_fast(LightPath& lp, const vec3f nextRay_dir, const float nextRay_near, const float nextRay_far, - const vec3f weight, - const bool ignoreVL) + const float bsdfPdf, + const BSDFType bsdfType) { lp.unbent = lp.unbent & eq(nextRay_dir,lp.ray.dir); setRay(lp.ray,nextRay_org,nextRay_dir,nextRay_near,nextRay_far); - lp.depth = lp.depth+1; - lp.throughput = mul(lp.throughput,weight); - lp.ignoreVisibleLights = ignoreVL; + lp.depth++; + lp.bsdfPdf = bsdfPdf; + lp.bsdfType = bsdfType; } +inline float misHeuristic(float pdf1, float pdf2) +{ + return sqr(pdf1) * rcp(sqr(pdf1) + sqr(pdf2)); // power heuristic with beta=2 +} + + ////////////////////////////////////////////////////////////////// // PathTracer @@ -129,8 +130,6 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, LightPath &lightPath, varying RandomTEA* uniform rng) { - uniform uint32/*BRDFType*/ directLightingBSDFTypes = (uniform uint32)(BSDF_DIFFUSE | BSDF_GLOSSY); - ScreenSample sample; sample.alpha = 1.f; vec3f L = make_vec3f(0.f); @@ -151,11 +150,12 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, sample.alpha = 1.0f - luminance(Lw); if ((bool)self->backplate & lightPath.unbent) { L = L + Lw * get3f(self->backplate, clamp2edge(self->backplate, pixel)); - } else if (!lightPath.ignoreVisibleLights) + } else for (uniform int i = 0; i < self->numLights; i++) { // TODO: self->num_envLights const uniform Light *uniform l = self->lights[i]; LightEval le = l->eval(l, lightPath.ray.org, lightPath.ray.dir); - L = L + Lw * le.radiance; + float weight = lightPath.bsdfType & BSDF_SMOOTH ? misHeuristic(lightPath.bsdfPdf, le.pdf) : 1.f; + L = L + Lw * le.radiance * weight; } break; @@ -199,11 +199,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, } #endif - /*! Check if any BSDF component uses direct lighting. */ - bool useDirectLighting = bsdf->type & directLightingBSDFTypes; - /*! Direct lighting. Shoot shadow rays to all light sources. */ - if (useDirectLighting) + if (bsdf->type & BSDF_SMOOTH) { uniform int numLights = self->lights ? min(MAX_LIGHTS, self->numLights) : 0; for (uniform int i = 0; i < numLights; i++) @@ -219,10 +216,10 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, /*! Evaluate BSDF */ vec3f bsdfValue; - float lsDirectionPdf; + float bsdfPdf; foreach_unique(b in bsdf) if (b != NULL) - bsdfValue = b->eval(b, wo, ls.direction, lsDirectionPdf); + bsdfValue = b->eval(b, wo, ls.direction, bsdfPdf); #ifdef USE_DGCOLOR bsdfValue = bsdfValue * make_vec3f(dg.color); @@ -239,7 +236,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, self->super.epsilon); shadow_ray.time = lightPath.ray.time; - vec3f unshaded_light_contrib = Lw * ls.radiance * bsdfValue; + vec3f unshaded_light_contrib = Lw * ls.radiance * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); L = L + transparentShadow(self, unshaded_light_contrib, shadow_ray, lightPath.lastMedium, rng); } } @@ -248,14 +245,16 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, if (lightPath.depth >= self->maxDepth) break; - /*! sample brdf */ - Sample3f wi = make_Sample3f(make_vec3f(0.0f),0.0f); uint32 type = 0; + /*! sample BSDF */ + vec3f wi; + uint32 bsdfType = 0; vec2f s = RandomTEA__getFloats(rng); vec2f ss = RandomTEA__getFloats(rng); // FIXME: should be only one component vec3f bsdfWeight; + float bsdfPdf = 0.f; foreach_unique(b in bsdf) if (b != NULL) - bsdfWeight = b->sample(b, wo, wi.v, wi.pdf, type, s, ss.x); + bsdfWeight = b->sample(b, wo, wi, bsdfPdf, bsdfType, s, ss.x); #ifdef USE_DGCOLOR if ((type & GLOSSY_REFLECTION) == NONE) // only colorize diffuse component @@ -263,7 +262,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, #endif /*! Continue only if we hit something valid. */ - if (reduce_max(bsdfWeight) <= 0.0f | wi.pdf <= PDF_CULLING) + if (reduce_max(bsdfWeight) <= 0.0f | bsdfPdf <= PDF_CULLING) break; /*! Compute simple volumetric effect. */ @@ -272,7 +271,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, bsdfWeight = bsdfWeight * powf(transmission,lightPath.ray.t); /*! Tracking medium if we hit a medium interface. */ - if (type & BSDF_TRANSMISSION) { + if (bsdfType & BSDF_TRANSMISSION) { foreach_unique(uniMat in dg.material) { uniform PathTraceMaterial* uniform m = (uniform PathTraceMaterial *)uniMat; if (m != NULL) m->selectNextMedium(m,lightPath.lastMedium); @@ -281,12 +280,12 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, /*! Continue the path. */ extend_fast(lightPath, - dg.P,wi.v,//dg.error* + dg.P,wi,//dg.error* self->super.epsilon,inf, - bsdfWeight*wi.pdf,(type & directLightingBSDFTypes) != BSDF_NONE); + bsdfPdf,bsdfType); Lw = Lw * bsdfWeight; - } while (reduce_max(lightPath.throughput) > self->minContribution); + } while (reduce_max(Lw) > self->minContribution); sample.rgb = L; return sample; diff --git a/ospray/render/pathtracer/bsdfs/BSDF.ih b/ospray/render/pathtracer/bsdfs/BSDF.ih index b2d7569d7f..fc842b2988 100644 --- a/ospray/render/pathtracer/bsdfs/BSDF.ih +++ b/ospray/render/pathtracer/bsdfs/BSDF.ih @@ -42,6 +42,9 @@ /*! all possible transmissions */ #define BSDF_TRANSMISSION (BSDF_DIFFUSE_TRANSMISSION | BSDF_GLOSSY_TRANSMISSION | BSDF_SPECULAR_TRANSMISSION) +/*! all non-dirac types */ +#define BSDF_SMOOTH (BSDF_DIFFUSE | BSDF_GLOSSY) + /*! no component set */ #define BSDF_NONE 0 From e07a7c2ba6f018f9f17238f93adabbdfdd3f153f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 6 Apr 2016 16:55:06 +0200 Subject: [PATCH 184/310] Specular_sample must return a bsdf type --- ospray/render/pathtracer/bsdfs/Specular.ih | 1 + 1 file changed, 1 insertion(+) diff --git a/ospray/render/pathtracer/bsdfs/Specular.ih b/ospray/render/pathtracer/bsdfs/Specular.ih index 65948bd3a1..7e3ad6f93f 100644 --- a/ospray/render/pathtracer/bsdfs/Specular.ih +++ b/ospray/render/pathtracer/bsdfs/Specular.ih @@ -51,6 +51,7 @@ inline vec3f Specular_sample(const varying BSDF* uniform super, const vec3f localDir = powerCosineSampleHemisphere(self->exp, s); wi = frame(refl) * localDir; pdf = powerCosineSampleHemispherePDF(localDir, self->exp); + type = BSDF_GLOSSY_REFLECTION; return mul(self->R, (self->exp+2) * rcp(self->exp+1) * clamp(dot(wi, getN(super)))); } From 64d1013a1500083fe9bde54330a04f591196bbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 7 Apr 2016 10:33:31 +0200 Subject: [PATCH 185/310] Handle (Dirac) delta distributions - the more appropriate pdf for the delta distribution is inf (not 1.0) - in the sample functions we anyway return the weight = value / pdf, where the delta (inf) in value and pdf is already canceled - guard against large pdf (inf) when computing MIS weight - adapt MultiBSDF appropriately --- ospray/lights/DirectionalLight.ispc | 2 +- ospray/lights/PointLight.ispc | 2 +- ospray/lights/SpotLight.ispc | 2 +- ospray/render/pathtracer/PathTracer.ispc | 27 ++++++++++--------- ospray/render/pathtracer/bsdfs/Conductor.ih | 2 +- ospray/render/pathtracer/bsdfs/Dielectric.ih | 14 +++------- .../pathtracer/bsdfs/DielectricLayer.ih | 15 ++++------- .../pathtracer/bsdfs/GGXDistribution.ih | 1 + ospray/render/pathtracer/bsdfs/MultiBSDF.ih | 18 ++++++------- ospray/render/pathtracer/bsdfs/Reflection.ih | 2 +- .../render/pathtracer/bsdfs/ThinDielectric.ih | 14 ++++------ .../render/pathtracer/bsdfs/Transmission.ih | 2 +- 12 files changed, 44 insertions(+), 57 deletions(-) diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 518e663572..31435c0eec 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -86,7 +86,7 @@ export void DirectionalLight_set(void *uniform _self, self->frame = frame(direction); self->radiance = radiance; self->cosAngle = cosAngle; - self->pdf = cosAngle < COS_ANGLE_MAX ? uniformSampleConePDF(cosAngle) : 1.f; + self->pdf = cosAngle < COS_ANGLE_MAX ? uniformSampleConePDF(cosAngle) : inf; } //! Create an ispc-side DirectionalLight object diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 9c99cf8d61..d6970f7532 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -46,7 +46,7 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, sample.direction = dir * invdist; sample.distance = dist2 * invdist; - sample.pdf = 1.f; // per default we always take this sample + sample.pdf = inf; // per default we always take this sample // convert from power to radiance by attenuating by distance^2 sample.radiance = self->power * sqr(invdist); diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index d9e7c445d2..381996aa19 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -60,7 +60,7 @@ varying LightSample SpotLight_sample(const uniform Light *uniform _self, if (self->radius > 0.) sample.pdf = uniformSampleDiskPDF(self->radius) * dist2 * abs(cosAngle); else - sample.pdf = 1.f; // we always take this sample + sample.pdf = inf; // we always take this sample // convert from power to radiance by attenuating by distance^2; attenuate by angle sample.radiance = self->power * (invdist * invdist * angularAttenuation); diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 89109ae3b6..5dc41ca725 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -33,8 +33,7 @@ struct LightPath Ray ray; /*! Last ray in the path. */ Medium lastMedium; /*! Medium the last ray travels inside. */ uniform uint32 depth; /*! Recursion depth of path. */ - float bsdfPdf; // for MIS - BSDFType bsdfType; // for MIS + float bsdfPdf; // for MIS bool unbent; /*! True of the ray path is a straight line. */ }; @@ -43,8 +42,7 @@ inline void init_LightPath(LightPath& lp, const Ray &ray) lp.ray = ray; lp.lastMedium = make_Medium_Vacuum(); lp.depth = 0; - lp.bsdfPdf = 1.0f; - lp.bsdfType = BSDF_SPECULAR_TRANSMISSION; + lp.bsdfPdf = inf; lp.unbent = true; } @@ -53,22 +51,26 @@ inline void extend_fast(LightPath& lp, const vec3f nextRay_dir, const float nextRay_near, const float nextRay_far, - const float bsdfPdf, - const BSDFType bsdfType) + const float bsdfPdf) { lp.unbent = lp.unbent & eq(nextRay_dir,lp.ray.dir); setRay(lp.ray,nextRay_org,nextRay_dir,nextRay_near,nextRay_far); lp.depth++; lp.bsdfPdf = bsdfPdf; - lp.bsdfType = bsdfType; } inline float misHeuristic(float pdf1, float pdf2) { - return sqr(pdf1) * rcp(sqr(pdf1) + sqr(pdf2)); // power heuristic with beta=2 + // power heuristic with beta=2 + const float p = sqr(pdf1) * rcp(sqr(pdf1) + sqr(pdf2)); + // guard against high pdf (including Dirac delta) + // using the limit when pdf1 approaches inf + // compare with bit less than sqrt(float_max) (when sqr starts to overflow) + return pdf1 > 1e17f ? 1.0f : p; } + ////////////////////////////////////////////////////////////////// // PathTracer @@ -154,8 +156,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, for (uniform int i = 0; i < self->numLights; i++) { // TODO: self->num_envLights const uniform Light *uniform l = self->lights[i]; LightEval le = l->eval(l, lightPath.ray.org, lightPath.ray.dir); - float weight = lightPath.bsdfType & BSDF_SMOOTH ? misHeuristic(lightPath.bsdfPdf, le.pdf) : 1.f; - L = L + Lw * le.radiance * weight; + L = L + Lw * le.radiance * misHeuristic(lightPath.bsdfPdf, le.pdf); } break; @@ -216,7 +217,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, /*! Evaluate BSDF */ vec3f bsdfValue; - float bsdfPdf; + float bsdfPdf = 0.f; foreach_unique(b in bsdf) if (b != NULL) bsdfValue = b->eval(b, wo, ls.direction, bsdfPdf); @@ -247,11 +248,11 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, /*! sample BSDF */ vec3f wi; - uint32 bsdfType = 0; vec2f s = RandomTEA__getFloats(rng); vec2f ss = RandomTEA__getFloats(rng); // FIXME: should be only one component vec3f bsdfWeight; float bsdfPdf = 0.f; + uint32 bsdfType = 0; foreach_unique(b in bsdf) if (b != NULL) bsdfWeight = b->sample(b, wo, wi, bsdfPdf, bsdfType, s, ss.x); @@ -282,7 +283,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, extend_fast(lightPath, dg.P,wi,//dg.error* self->super.epsilon,inf, - bsdfPdf,bsdfType); + bsdfPdf); Lw = Lw * bsdfWeight; } while (reduce_max(Lw) > self->minContribution); diff --git a/ospray/render/pathtracer/bsdfs/Conductor.ih b/ospray/render/pathtracer/bsdfs/Conductor.ih index 45df2305e3..50c5fcd7f1 100644 --- a/ospray/render/pathtracer/bsdfs/Conductor.ih +++ b/ospray/render/pathtracer/bsdfs/Conductor.ih @@ -39,7 +39,7 @@ inline vec3f Conductor_sample(const varying BSDF* uniform super, { const varying Conductor* uniform self = (const varying Conductor* uniform)super; wi = reflect(wo, getN(super)); - pdf = 1.0f; + pdf = inf; type = BSDF_SPECULAR_REFLECTION; return self->reflectance * fresnelConductor(dot(wo, getN(super)), self->eta, self->k); } diff --git a/ospray/render/pathtracer/bsdfs/Dielectric.ih b/ospray/render/pathtracer/bsdfs/Dielectric.ih index 2e76f46a26..98249b77ad 100644 --- a/ospray/render/pathtracer/bsdfs/Dielectric.ih +++ b/ospray/render/pathtracer/bsdfs/Dielectric.ih @@ -42,23 +42,17 @@ inline vec3f Dielectric_sample(const varying BSDF* uniform super, // Fresnel term float cosThetaT; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaT, self->eta); + pdf = inf; // Sample the reflection or the transmission - if (ss <= F) - { - // Reflection + if (ss <= F) { // Reflection wi = reflect(wo, getN(super), cosThetaO); type = BSDF_SPECULAR_REFLECTION; - pdf = F; return make_vec3f(1.0f); - } - else - { - // Transmission + } else { // Transmission wi = refract(wo, getN(super), cosThetaO, cosThetaT, self->eta); type = BSDF_SPECULAR_TRANSMISSION; - pdf = 1.0f-F; - return make_vec3f(sqrf(rcp(self->eta))); // solid angle compression + return make_vec3f(rsqrt(self->eta)); // solid angle compression } } diff --git a/ospray/render/pathtracer/bsdfs/DielectricLayer.ih b/ospray/render/pathtracer/bsdfs/DielectricLayer.ih index 451aee1f65..c728611963 100644 --- a/ospray/render/pathtracer/bsdfs/DielectricLayer.ih +++ b/ospray/render/pathtracer/bsdfs/DielectricLayer.ih @@ -68,24 +68,19 @@ inline vec3f DielectricLayer_sample(const varying BSDF* uniform super, const varying DielectricLayer* uniform self = (const varying DielectricLayer* uniform)super; float cosThetaO = dot(wo, getN(super)); - if (cosThetaO <= 0.0f) return make_vec3f(0.0f); + if (cosThetaO <= 0.0f) + return make_vec3f(0.0f); // Fresnel term float cosThetaO1; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaO1, self->eta); - // Sample the coating or the substrate reflection - if (ss < F) - { - // Sample the coating reflection + if (ss < F) { // Sample the coating reflection type = BSDF_SPECULAR_REFLECTION; wi = reflect(wo, getN(super), cosThetaO); - pdf = F; + pdf = inf; return make_vec3f(1.0f); - } - else - { - // Sample the substrate BRDF + } else { // Sample the substrate BRDF float ss1 = (ss - F) * rcp(1.0f-F); // reallocate sample float substratePdf; vec3f substrateWeight = self->substrate->sample(self->substrate, wo, wi, substratePdf, type, s, ss1); diff --git a/ospray/render/pathtracer/bsdfs/GGXDistribution.ih b/ospray/render/pathtracer/bsdfs/GGXDistribution.ih index 442f0372fb..6c2617530b 100644 --- a/ospray/render/pathtracer/bsdfs/GGXDistribution.ih +++ b/ospray/render/pathtracer/bsdfs/GGXDistribution.ih @@ -38,6 +38,7 @@ inline float eval(const GGXDistribution& self, return alpha2 * rcp(pi*sqr(tmp)); } +// TODO: remove dup, or return pdf inline float eval(const GGXDistribution& self, float cosTheta, float& pdf) { diff --git a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih index 2748b5c4a7..ec587b3125 100644 --- a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih +++ b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih @@ -110,21 +110,21 @@ inline vec3f MultiBSDF_sample(const varying BSDF* uniform super, if (eq(weight, make_vec3f(0.0f)) | (pdf == 0.0f)) return make_vec3f(0.0f); + if (type & BSDF_SPECULAR) + return weight; + // compute overall weight and pdf vec3f value = weight * pdf; pdf *= self->importances[choice]; - if (!(type & BSDF_SPECULAR)) + for (uniform int i = 0; i < self->numBsdfs; ++i) { - for (uniform int i = 0; i < self->numBsdfs; ++i) + if ((i != choice) & (self->importances[i] > 0.0f)) { - if ((i != choice) & (self->importances[i] > 0.0f)) - { - const varying BSDF* uniform curBsdf = self->bsdfs[i]; - float curPdf = 0.0f; - value = value + curBsdf->eval(curBsdf, wo, wi, curPdf); - pdf = pdf + curPdf * self->importances[i]; - } + const varying BSDF* uniform curBsdf = self->bsdfs[i]; + float curPdf = 0.0f; + value = value + curBsdf->eval(curBsdf, wo, wi, curPdf); + pdf = pdf + curPdf * self->importances[i]; } } diff --git a/ospray/render/pathtracer/bsdfs/Reflection.ih b/ospray/render/pathtracer/bsdfs/Reflection.ih index f09ed9e480..949b804a62 100644 --- a/ospray/render/pathtracer/bsdfs/Reflection.ih +++ b/ospray/render/pathtracer/bsdfs/Reflection.ih @@ -38,7 +38,7 @@ inline vec3f Reflection_sample(const varying BSDF* uniform super, const varying Reflection* uniform self = (const varying Reflection* uniform)super; wi = reflect(wo, getN(super)); - pdf = 1.0f; + pdf = inf; type = BSDF_SPECULAR_REFLECTION; return self->reflectance; } diff --git a/ospray/render/pathtracer/bsdfs/ThinDielectric.ih b/ospray/render/pathtracer/bsdfs/ThinDielectric.ih index f6d540a1df..407264b776 100644 --- a/ospray/render/pathtracer/bsdfs/ThinDielectric.ih +++ b/ospray/render/pathtracer/bsdfs/ThinDielectric.ih @@ -33,6 +33,8 @@ inline vec3f ThinDielectric_eval(const varying BSDF* uniform super, return make_vec3f(0.0f); } + +// TODO: account for multiple internal reflections with geometric sum inline vec3f ThinDielectric_sample(const varying BSDF* uniform super, const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, const vec2f& s, float ss) @@ -43,22 +45,16 @@ inline vec3f ThinDielectric_sample(const varying BSDF* uniform super, // Fresnel term float F = fresnelDielectric(cosThetaO, self->eta); + pdf = inf; // Sample the reflection or the transmission - if (ss <= F) - { - // Reflection + if (ss <= F) { // Reflection wi = reflect(wo, getN(super), cosThetaO); type = BSDF_SPECULAR_REFLECTION; - pdf = F; return make_vec3f(1.0f); - } - else - { - // Transmission + } else { // Transmission wi = neg(wo); type = BSDF_SPECULAR_TRANSMISSION; - pdf = 1.0f-F; float alpha = self->thickness * rcp(cosThetaO); return powf(self->transmission, alpha); } diff --git a/ospray/render/pathtracer/bsdfs/Transmission.ih b/ospray/render/pathtracer/bsdfs/Transmission.ih index 019dfe3d12..85cbf6b433 100644 --- a/ospray/render/pathtracer/bsdfs/Transmission.ih +++ b/ospray/render/pathtracer/bsdfs/Transmission.ih @@ -40,7 +40,7 @@ inline vec3f Transmission_sample(const varying BSDF* uniform super, { const varying Transmission* uniform self = (const varying Transmission* uniform)super; wi = neg(wo); - pdf = 1.0f; + pdf = inf; type = BSDF_SPECULAR_TRANSMISSION; return self->T; } From 893052554a18aa5848b4b87f3192a8fb8a97b341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 7 Apr 2016 14:37:47 +0200 Subject: [PATCH 186/310] Add light from virtual lights by intersecting them --- ospray/render/pathtracer/PathTracer.ispc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 5dc41ca725..bfbfd56610 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -146,22 +146,29 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, const vec3f wo = neg(lightPath.ray.dir); + float maxLightDist = lightPath.ray.t; // per default virtual lights are occluded by hit geometry + /*! Environment shading when nothing hit. */ if (noHit(lightPath.ray)) { + maxLightDist = inf; // also include envLights (i.e. the ones in infinity) if (lightPath.unbent) sample.alpha = 1.0f - luminance(Lw); if ((bool)self->backplate & lightPath.unbent) { L = L + Lw * get3f(self->backplate, clamp2edge(self->backplate, pixel)); - } else - for (uniform int i = 0; i < self->numLights; i++) { // TODO: self->num_envLights - const uniform Light *uniform l = self->lights[i]; - LightEval le = l->eval(l, lightPath.ray.org, lightPath.ray.dir); - L = L + Lw * le.radiance * misHeuristic(lightPath.bsdfPdf, le.pdf); - } + maxLightDist = 1e38; // backplate hides envLights (i.e. the ones in infinity) + } + } - break; + // add light from virtual lights by intersecting them + for (uniform int i = 0; i < self->numLights; i++) { + const uniform Light *uniform l = self->lights[i]; + LightEval le = l->eval(l, lightPath.ray.org, lightPath.ray.dir); + if (le.distance <= maxLightDist) + L = L + Lw * le.radiance * misHeuristic(lightPath.bsdfPdf, le.pdf); } + if (noHit(lightPath.ray)) + break; DifferentialGeometry dg; postIntersect(self->super.model, dg, lightPath.ray, From 02b8ec8f6ae4c1b964386ca0a0eb1cab8cd1c194 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 7 Apr 2016 10:18:48 -0700 Subject: [PATCH 187/310] add ospray_common to cmake find_package() config libraries list --- cmake/ospray_cmake_config/osprayConfig.cmake.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index e20c141e32..fe129c7b96 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -183,6 +183,7 @@ set(OSPRAY_LIBRARIES #ospray_embree# NOTE(jda) - target disabled (see above) ${EMBREE_LIBRARY} ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}ospray${CMAKE_SHARED_LIBRARY_SUFFIX} + ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}ospray_common${CMAKE_SHARED_LIBRARY_SUFFIX} ) # Reset CMake module path to its state when this script was called. From ffee6490ef81ab661ed3c416a5a79cbd3add25e5 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 7 Apr 2016 11:45:55 -0700 Subject: [PATCH 188/310] fix find_package config on OS X when compiling Embree internally --- cmake/ospray_cmake_config/osprayConfig.cmake.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index fe129c7b96..37afb87f67 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -135,7 +135,11 @@ if(@OSPRAY_USE_EXTERNAL_EMBREE@) # Find existing Embree on the machine find_package(embree @REQUIRED_MINIMUM_EMBREE@ REQUIRED) else() - set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.2) + if (APPLE) + set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}embree.2${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + set(EMBREE_LIBRARY ${CURRENT_ROOT_INSTALL_DIR}/@CMAKE_INSTALL_LIBDIR@/${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.2) + endif() endif() # Restore state From b4df57a0caab940f58333e393d06430469de3bd8 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Thu, 7 Apr 2016 18:33:50 -0500 Subject: [PATCH 189/310] first massaging of code - purely code-based optimizations --- apps/qtViewer/sg/common/TransferFunction.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/qtViewer/sg/common/TransferFunction.cpp b/apps/qtViewer/sg/common/TransferFunction.cpp index c2a05534ab..4e5e51a1dc 100644 --- a/apps/qtViewer/sg/common/TransferFunction.cpp +++ b/apps/qtViewer/sg/common/TransferFunction.cpp @@ -133,10 +133,11 @@ namespace ospray { char *cont = strdup(child->content.c_str()); assert(cont); - const char *c = strtok(cont,","); + const char *c = strtok(cont,",\n"); while (c) { + PRINT(c); colorArray.push_back(std::pair(colorArray.size(),toVec3f(c))); - c = strtok(NULL,","); + c = strtok(NULL,",\n"); } free(cont); @@ -150,11 +151,11 @@ namespace ospray { char *cont = strdup(child->content.c_str()); assert(cont); - const char *c = strtok(cont,","); + const char *c = strtok(cont,",\n"); while (c) { vec2f cp = toVec2f(c); alphaArray.push_back(std::pair(cp.x,cp.y)); - c = strtok(NULL,","); + c = strtok(NULL,",\n"); } free(cont); From d7c1ac38653d80ea3bb4a741827a42ee3fe77497 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 7 Apr 2016 22:10:14 -0700 Subject: [PATCH 190/310] use new embree device api to squash warnings, fix override warnings (clang) --- ospray/api/LocalDevice.cpp | 8 ++++---- ospray/api/LocalDevice.h | 17 ++++++++++++----- ospray/fb/LocalFB.h | 2 +- ospray/mpi/DistributedFrameBuffer.h | 8 ++++---- ospray/mpi/worker.cpp | 19 +++++++++++++++---- ospray/render/volume/RaycastVolumeRenderer.h | 6 +++--- ospray/volume/DataDistributedBlockedVolume.h | 6 +++--- 7 files changed, 42 insertions(+), 24 deletions(-) diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index 972f88e93c..8d6e56c70b 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -57,11 +57,11 @@ namespace ospray { embreeConfig << " threads=1,verbose=2"; else if(numThreads > 0) embreeConfig << " threads=" << numThreads; - rtcInit(embreeConfig.str().c_str()); + embreeDevice = rtcNewDevice(embreeConfig.str().c_str()); - rtcSetErrorFunction(embreeErrorFunc); // needs to come after rtcInit + rtcDeviceSetErrorFunction(embreeDevice, embreeErrorFunc); - RTCError erc = rtcGetError(); + RTCError erc = rtcDeviceGetError(embreeDevice); if (erc != RTC_NO_ERROR) { // why did the error function not get called !? std::cerr << "#osp:init: embree internal error number " << (int)erc << std::endl; @@ -73,7 +73,7 @@ namespace ospray { LocalDevice::~LocalDevice() { - rtcExit(); + rtcDeleteDevice(embreeDevice); } OSPFrameBuffer diff --git a/ospray/api/LocalDevice.h b/ospray/api/LocalDevice.h index 93a296102e..e777b60648 100644 --- a/ospray/api/LocalDevice.h +++ b/ospray/api/LocalDevice.h @@ -16,7 +16,11 @@ #pragma once +//ospray #include "Device.h" +//embree +#include "embree2/rtcore.h" + /*! \file localdevice.h Implements the "local" device for local rendering */ @@ -48,7 +52,7 @@ namespace ospray { /*! set a frame buffer's pixel op object */ void setPixelOp(OSPFrameBuffer _fb, OSPPixelOp _op) override; - + /*! create a new model */ OSPModel newModel() override; @@ -199,12 +203,12 @@ namespace ospray { void *data, const uint32 flags) override; /*! clear the specified channel(s) of the frame buffer specified in 'whichChannels' - + if whichChannel&OSP_FB_COLOR!=0, clear the color buffer to - '0,0,0,0'. + '0,0,0,0'. if whichChannel&OSP_FB_DEPTH!=0, clear the depth buffer to - +inf. + +inf. if whichChannel&OSP_FB_ACCUM!=0, clear the accum buffer to 0,0,0,0, and reset accumID. @@ -214,7 +218,7 @@ namespace ospray { /*! call a renderer to render a frame buffer */ float renderFrame(OSPFrameBuffer _sc, - OSPRenderer _renderer, + OSPRenderer _renderer, const uint32 fbChannelFlags) override; //! release (i.e., reduce refcount of) given object @@ -239,6 +243,9 @@ namespace ospray { const vec3f *worldCoordinates, const size_t &count) override; + // Data members ///////////////////////////////////////////////////////// + + RTCDevice embreeDevice; }; } // ::ospray::api diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index 00bccea0ef..444338ee42 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -44,7 +44,7 @@ namespace ospray { //! \brief common function to help printf-debugging /*! \detailed Every derived class should overrride this! */ - virtual std::string toString() const; + std::string toString() const override; void setTile(Tile &tile) override; int32 accumID(const vec2i &tile) override; diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index e7bdadcbda..aba40d565e 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -273,9 +273,9 @@ namespace ospray { // ================================================================== // framebuffer / device interface // ================================================================== - const void *mapDepthBuffer(); - const void *mapColorBuffer(); - void unmap(const void *mappedMem); + const void *mapDepthBuffer() override; + const void *mapColorBuffer() override; + void unmap(const void *mappedMem) override; /*! \brief clear (the specified channels of) this frame buffer @@ -335,7 +335,7 @@ namespace ospray { //! \brief common function to help printf-debugging /*! \detailed Every derived class should overrride this! */ - virtual std::string toString() const + std::string toString() const override { return "ospray::DistributedFrameBuffer"; } diff --git a/ospray/mpi/worker.cpp b/ospray/mpi/worker.cpp index 0a69dfb7ce..53fc42dbd9 100644 --- a/ospray/mpi/worker.cpp +++ b/ospray/mpi/worker.cpp @@ -100,13 +100,24 @@ namespace ospray { embreeConfig << " threads=1,verbose=2"; else if(numThreads > 0) embreeConfig << " threads=" << numThreads; - rtcInit(embreeConfig.str().c_str()); - rtcSetErrorFunction(embreeErrorFunc); // needs to come after rtcInit + // NOTE(jda) - This guard guarentees that the embree device gets cleaned + // up no matter how the scope of runWorker() is left + struct EmbreeDeviceScopeGuard { + RTCDevice embreeDevice; + ~EmbreeDeviceScopeGuard() { rtcDeleteDevice(embreeDevice); } + }; + + RTCDevice embreeDevice = rtcNewDevice(embreeConfig.str().c_str()); + EmbreeDeviceScopeGuard guard; + guard.embreeDevice = embreeDevice; + + rtcDeviceSetErrorFunction(embreeDevice, embreeErrorFunc); - if (rtcGetError() != RTC_NO_ERROR) { + if (rtcDeviceGetError(embreeDevice) != RTC_NO_ERROR) { // why did the error function not get called !? - std::cerr << "#osp:init: embree internal error number " << (int)rtcGetError() << std::endl; + std::cerr << "#osp:init: embree internal error number " + << (int)rtcDeviceGetError(embreeDevice) << std::endl; assert(rtcGetError() == RTC_NO_ERROR); } diff --git a/ospray/render/volume/RaycastVolumeRenderer.h b/ospray/render/volume/RaycastVolumeRenderer.h index f02fb484d5..ca7791df21 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.h +++ b/ospray/render/volume/RaycastVolumeRenderer.h @@ -34,14 +34,14 @@ namespace ospray { ~RaycastVolumeRenderer(); //! Create a material of the given type. - Material* createMaterial(const char *type); + Material* createMaterial(const char *type) override; //! Initialize the renderer state, and create the equivalent ISPC volume //! renderer object. - void commit(); + void commit() override; //! A string description of this class. - std::string toString() const; + std::string toString() const override; #if EXP_DATA_PARALLEL /*! per-frame data to describe the data-parallel components */ diff --git a/ospray/volume/DataDistributedBlockedVolume.h b/ospray/volume/DataDistributedBlockedVolume.h index d611431cf8..f1a3a197b4 100644 --- a/ospray/volume/DataDistributedBlockedVolume.h +++ b/ospray/volume/DataDistributedBlockedVolume.h @@ -64,10 +64,10 @@ namespace ospray { //! A string description of this class. std::string toString() const override; - + //! Allocate storage and populate the volume, called through the OSPRay API. void commit() override; - + //! Copy voxels into the volume at the given index (non-zero return value //! indicates success). int setRegion(const void *source, @@ -78,7 +78,7 @@ namespace ospray { //private: //! Create the equivalent ISPC volume container. - void createEquivalentISPC(); + void createEquivalentISPC() override; /*! size of each block, in voxels, WITHOUT padding (in practice the blocks * WILL be padded) */ From 96d7eed190be7315ac64526f67d882e4ae0ae3c2 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 8 Apr 2016 11:54:16 -0500 Subject: [PATCH 191/310] embreedevice is now global, and accessible to all devices; 'main' model now uses this embreedevice, and thus no longer crashes - THIS IS NOT FIXED FOR ALL MODULES YET --- ospray/api/LocalDevice.cpp | 10 ++++++---- ospray/api/LocalDevice.h | 4 ---- ospray/common/Model.cpp | 4 +++- ospray/common/Model.ispc | 18 +++++++++++------- ospray/common/OSPCommon.cpp | 2 ++ ospray/common/OSPCommon.h | 1 - .../include/embree2/rtcore_scene.isph | 6 +++--- ospray/embree-v2.7.1/kernels/common/rtcore.cpp | 1 + ospray/mpi/worker.cpp | 5 ++++- 9 files changed, 30 insertions(+), 21 deletions(-) diff --git a/ospray/api/LocalDevice.cpp b/ospray/api/LocalDevice.cpp index 8d6e56c70b..947caa9d85 100644 --- a/ospray/api/LocalDevice.cpp +++ b/ospray/api/LocalDevice.cpp @@ -33,6 +33,8 @@ #include namespace ospray { + extern RTCDevice g_embreeDevice; + namespace api { void embreeErrorFunc(const RTCError code, const char* str) @@ -57,11 +59,11 @@ namespace ospray { embreeConfig << " threads=1,verbose=2"; else if(numThreads > 0) embreeConfig << " threads=" << numThreads; - embreeDevice = rtcNewDevice(embreeConfig.str().c_str()); + g_embreeDevice = rtcNewDevice(embreeConfig.str().c_str()); - rtcDeviceSetErrorFunction(embreeDevice, embreeErrorFunc); + rtcDeviceSetErrorFunction(g_embreeDevice, embreeErrorFunc); - RTCError erc = rtcDeviceGetError(embreeDevice); + RTCError erc = rtcDeviceGetError(g_embreeDevice); if (erc != RTC_NO_ERROR) { // why did the error function not get called !? std::cerr << "#osp:init: embree internal error number " << (int)erc << std::endl; @@ -73,7 +75,7 @@ namespace ospray { LocalDevice::~LocalDevice() { - rtcDeleteDevice(embreeDevice); + rtcDeleteDevice(g_embreeDevice); } OSPFrameBuffer diff --git a/ospray/api/LocalDevice.h b/ospray/api/LocalDevice.h index e777b60648..38673bf23c 100644 --- a/ospray/api/LocalDevice.h +++ b/ospray/api/LocalDevice.h @@ -242,10 +242,6 @@ namespace ospray { OSPVolume volume, const vec3f *worldCoordinates, const size_t &count) override; - - // Data members ///////////////////////////////////////////////////////// - - RTCDevice embreeDevice; }; } // ::ospray::api diff --git a/ospray/common/Model.cpp b/ospray/common/Model.cpp index 5586f77da7..7255131409 100644 --- a/ospray/common/Model.cpp +++ b/ospray/common/Model.cpp @@ -30,6 +30,8 @@ namespace ospray { using std::cout; using std::endl; + extern RTCDevice g_embreeDevice; + Model::Model() { managedObjectType = OSP_MODEL; @@ -44,7 +46,7 @@ namespace ospray { << geometry.size() << " geometries and " << volume.size() << " volumes" << std::endl << std::flush; } - ispc::Model_init(getIE(), geometry.size(), volume.size()); + ispc::Model_init(getIE(), g_embreeDevice, geometry.size(), volume.size()); embreeSceneHandle = (RTCScene)ispc::Model_getEmbreeSceneHandle(getIE()); bounds = empty; diff --git a/ospray/common/Model.ispc b/ospray/common/Model.ispc index 13d5cc75ce..97a8065f0f 100644 --- a/ospray/common/Model.ispc +++ b/ospray/common/Model.ispc @@ -31,18 +31,22 @@ export void *uniform Model_create(void *uniform cppE) return (void *uniform)model; } -export void Model_init(void *uniform _model, uniform int32 numGeometries, uniform int32 numVolumes) +export void Model_init(void *uniform _model, + void *uniform embreeDevice, + uniform int32 numGeometries, + uniform int32 numVolumes) { uniform Model *uniform model = (uniform Model *uniform)_model; if (model->embreeSceneHandle) rtcDeleteScene(model->embreeSceneHandle); - model->embreeSceneHandle = rtcNewScene(//RTC_SCENE_STATIC|RTC_SCENE_HIGH_QUALITY, - RTC_SCENE_STATIC,//|RTC_SCENE_COMPACT, - //RTC_SCENE_DYNAMIC, - //RTC_SCENE_DYNAMIC|RTC_SCENE_COMPACT, - RTC_INTERSECT_UNIFORM|RTC_INTERSECT_VARYING); - + model->embreeSceneHandle = rtcDeviceNewScene((RTCDevice)embreeDevice, + //RTC_SCENE_STATIC|RTC_SCENE_HIGH_QUALITY, + RTC_SCENE_STATIC,//|RTC_SCENE_COMPACT, + //RTC_SCENE_DYNAMIC, + //RTC_SCENE_DYNAMIC|RTC_SCENE_COMPACT, + RTC_INTERSECT_UNIFORM|RTC_INTERSECT_VARYING); + if (model->geometry) delete[] model->geometry; model->geometryCount = numGeometries; if (numGeometries > 0) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 9ef6dcd1ba..a81d703b03 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -27,6 +27,8 @@ namespace ospray { + RTCDevice g_embreeDevice = NULL; + /*! 64-bit malloc. allows for alloc'ing memory larger than 64 bits */ extern "C" void *malloc64(size_t size) { diff --git a/ospray/common/OSPCommon.h b/ospray/common/OSPCommon.h index d8a98e3b38..c2757f0aed 100644 --- a/ospray/common/OSPCommon.h +++ b/ospray/common/OSPCommon.h @@ -186,7 +186,6 @@ namespace ospray { } return result; } - } // ::ospray #ifdef _WIN32 diff --git a/ospray/embree-v2.7.1/include/embree2/rtcore_scene.isph b/ospray/embree-v2.7.1/include/embree2/rtcore_scene.isph index bd9b7711b2..ae879177a1 100644 --- a/ospray/embree-v2.7.1/include/embree2/rtcore_scene.isph +++ b/ospray/embree-v2.7.1/include/embree2/rtcore_scene.isph @@ -53,9 +53,9 @@ enum RTCAlgorithmFlags typedef uniform struct __RTCScene {}* uniform RTCScene; /*! Creates a new scene. - WARNING: This function is deprecated, use rtcDeviceNewScene instead. -*/ -RTCORE_DEPRECATED RTCScene rtcNewScene (uniform RTCSceneFlags flags, uniform RTCAlgorithmFlags aflags); +// WARNING: This function is deprecated, use rtcDeviceNewScene instead. +// */ +// RTCORE_DEPRECATED RTCScene rtcNewScene (uniform RTCSceneFlags flags, uniform RTCAlgorithmFlags aflags); /*! Creates a new scene. */ RTCScene rtcDeviceNewScene (RTCDevice device, uniform RTCSceneFlags flags, uniform RTCAlgorithmFlags aflags); diff --git a/ospray/embree-v2.7.1/kernels/common/rtcore.cpp b/ospray/embree-v2.7.1/kernels/common/rtcore.cpp index 183c763f5f..836b2389d9 100644 --- a/ospray/embree-v2.7.1/kernels/common/rtcore.cpp +++ b/ospray/embree-v2.7.1/kernels/common/rtcore.cpp @@ -59,6 +59,7 @@ namespace embree Lock lock(g_mutex); if (g_device) throw_RTCError(RTC_INVALID_OPERATION,"already initialized"); g_device = new Device(cfg,true); + PING; PRINT(g_device); RTCORE_CATCH_END(g_device); } diff --git a/ospray/mpi/worker.cpp b/ospray/mpi/worker.cpp index 53fc42dbd9..5e0053d809 100644 --- a/ospray/mpi/worker.cpp +++ b/ospray/mpi/worker.cpp @@ -56,6 +56,9 @@ void sleep(unsigned int seconds) #endif namespace ospray { + + extern RTCDevice g_embreeDevice; + namespace mpi { using std::cout; using std::endl; @@ -109,6 +112,7 @@ namespace ospray { }; RTCDevice embreeDevice = rtcNewDevice(embreeConfig.str().c_str()); + g_embreeDevice = embreeDevice; EmbreeDeviceScopeGuard guard; guard.embreeDevice = embreeDevice; @@ -118,7 +122,6 @@ namespace ospray { // why did the error function not get called !? std::cerr << "#osp:init: embree internal error number " << (int)rtcDeviceGetError(embreeDevice) << std::endl; - assert(rtcGetError() == RTC_NO_ERROR); } // ------------------------------------------------------- From 181a471f8a34005d225a7379327a4915674d5fb2 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 8 Apr 2016 12:05:20 -0500 Subject: [PATCH 192/310] removed old-style rtcNewScene from header files of 'our' version of embree - apparently 'deprecated' doesn't work on ispc, so removing it completely to force an error every time anybody wants to use it --- ospray/embree-v2.7.1/include/embree2/rtcore_scene.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/embree-v2.7.1/include/embree2/rtcore_scene.h b/ospray/embree-v2.7.1/include/embree2/rtcore_scene.h index 1e0e703d74..8ace537f5a 100644 --- a/ospray/embree-v2.7.1/include/embree2/rtcore_scene.h +++ b/ospray/embree-v2.7.1/include/embree2/rtcore_scene.h @@ -59,7 +59,7 @@ typedef struct __RTCScene {}* RTCScene; /*! Creates a new scene. WARNING: This function is deprecated, use rtcDeviceNewScene instead. */ -RTCORE_API RTCORE_DEPRECATED RTCScene rtcNewScene (RTCSceneFlags flags, RTCAlgorithmFlags aflags); +// RTCORE_API RTCORE_DEPRECATED RTCScene rtcNewScene (RTCSceneFlags flags, RTCAlgorithmFlags aflags); /*! Creates a new scene. */ RTCORE_API RTCScene rtcDeviceNewScene (RTCDevice device, RTCSceneFlags flags, RTCAlgorithmFlags aflags); From e9e2156848b16495a7173a4e2d6aeb349929096f Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 8 Apr 2016 12:10:56 -0500 Subject: [PATCH 193/310] removed old-style rtcNewScene from header files of 'our' version of embree - apparently 'deprecated' doesn't work on ispc, so removing it completely to force an error every time anybody wants to use it --- ospray/embree-v2.7.1/kernels/common/rtcore_ispc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ospray/embree-v2.7.1/kernels/common/rtcore_ispc.cpp b/ospray/embree-v2.7.1/kernels/common/rtcore_ispc.cpp index 5c41bc7c32..dc7095cf20 100644 --- a/ospray/embree-v2.7.1/kernels/common/rtcore_ispc.cpp +++ b/ospray/embree-v2.7.1/kernels/common/rtcore_ispc.cpp @@ -90,7 +90,8 @@ namespace embree extern "C" RTCScene ispcNewScene (RTCSceneFlags flags, RTCAlgorithmFlags aflags) { if (!isCoherent(flags) && !isIncoherent(flags)) flags = RTCSceneFlags(flags | RTC_SCENE_COHERENT); - return rtcNewScene(flags,aflags); + throw std::runtime_error("ispcNewScene is no longer working in ospray - do not use any more"); + // return rtcNewScene(flags,aflags); } extern "C" RTCScene ispcNewScene2 (RTCDevice device, RTCSceneFlags flags, RTCAlgorithmFlags aflags) From a651a828d7b7924c58ede5a8f65b6e3ffae6eee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 8 Apr 2016 13:14:13 +0200 Subject: [PATCH 194/310] Fix pdf returned by HDRILight_eval Need to shift half a texel as well when looking up Distribution2D_pdf. Additionally, need to wrap around uv for Distribution2D_pdf. --- ospray/common/OSPCommon.ih | 2 ++ ospray/lights/HDRILight.ispc | 13 +++++++++---- ospray/math/math.ih | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ospray/common/OSPCommon.ih b/ospray/common/OSPCommon.ih index 6af070af8e..7cb0b38491 100644 --- a/ospray/common/OSPCommon.ih +++ b/ospray/common/OSPCommon.ih @@ -42,6 +42,8 @@ inline void* uniform align_ptr(void* uniform ptr) { #endif #define PRINT(x) print(#x" = %\n", x) +// prints first unmasked element +#define PRINT0(x) print(#x"[%] = %\n", count_trailing_zeros(lanemask()), extract(x, count_trailing_zeros(lanemask()))) /*! ispc copy of embree error handling callback */ void error_handler(const RTCError code, const int8* str); diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index 648d0a5512..ba27511429 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -46,14 +46,14 @@ varying LightSample HDRILight_sample_dummy(const uniform Light *uniform, } varying LightSample HDRILight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, + const varying DifferentialGeometry &, const varying vec2f &s) { uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; LightSample sample; Sample2D sample2d = Distribution2D_sample(self->distribution, s); - // Distribution2D samples wihtin bin i as (i, i+1), whereas we provided + // Distribution2D samples within bin i as (i, i+1), whereas we provided // average importance for (i-0.5, i+0.5), thus shift by 0.5 sample2d.uv = sample2d.uv - self->map->halfTexel; @@ -66,7 +66,7 @@ varying LightSample HDRILight_sample(const uniform Light *uniform _self, sample.direction = self->light2world * localDir; - sample.pdf = sample2d.pdf * rcp(two_pi * M_PI * sinTheta); + sample.pdf = sample2d.pdf * one_over_two_pi_sqr * rcp(sinTheta); sample.distance = inf; sample.radiance = get3f(self->map, sample2d.uv) * self->intensity / sample.pdf; @@ -89,7 +89,12 @@ varying LightEval HDRILight_eval(const uniform Light *uniform _self, res.radiance = get3f(self->map, uv) * self->intensity; res.distance = inf; - res.pdf = Distribution2D_pdf(self->distribution, uv); + + // domain of Distribution2D is shifted by half a texel compared to texture + // atan2 can get negative, shift can lead to values > 1.f: reproject to [0..1) + const vec2f uvd = frac(uv + self->map->halfTexel); + res.pdf = Distribution2D_pdf(self->distribution, uvd); + res.pdf *= one_over_two_pi_sqr * rsqrt(1.f - sqr(localDir.z)); return res; } diff --git a/ospray/math/math.ih b/ospray/math/math.ih index 5704fe53a4..c335e83a1c 100644 --- a/ospray/math/math.ih +++ b/ospray/math/math.ih @@ -34,6 +34,7 @@ #define one_over_pi 0.31830988618379069122f #define one_over_two_pi 0.15915494309189534561f #define one_over_four_pi 0.079577471545947672804f +#define one_over_two_pi_sqr 0.050660591821168885722f /*! c-style reciprocal. required since ispc 1.7 due to type changes in this version */ inline float rcpf(const float f) { return rcp(f); } From 5b3b5d976cb8bb81386df56598f76a3f77eddd7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 8 Apr 2016 15:03:58 +0200 Subject: [PATCH 195/310] Introduce maxRadiance parameter in PT as last resort against fireflies --- ospray/render/pathtracer/PathTracer.cpp | 3 ++- ospray/render/pathtracer/PathTracer.ih | 1 + ospray/render/pathtracer/PathTracer.ispc | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.cpp b/ospray/render/pathtracer/PathTracer.cpp index a13a30c9ab..624d831458 100644 --- a/ospray/render/pathtracer/PathTracer.cpp +++ b/ospray/render/pathtracer/PathTracer.cpp @@ -66,9 +66,10 @@ namespace ospray { const int32 maxDepth = getParam1i("maxDepth", 20); const float minContribution = getParam1f("minContribution", 0.01f); + const float maxRadiance = getParam1f("maxRadiance", inf); Texture2D *backplate = (Texture2D*)getParamObject("backplate", NULL); - ispc::PathTracer_set(getIE(), maxDepth, minContribution, + ispc::PathTracer_set(getIE(), maxDepth, minContribution, maxRadiance, backplate ? backplate->getIE() : NULL, lightPtr, lightArray.size()); } diff --git a/ospray/render/pathtracer/PathTracer.ih b/ospray/render/pathtracer/PathTracer.ih index 6da3584a22..61ebcf7e44 100644 --- a/ospray/render/pathtracer/PathTracer.ih +++ b/ospray/render/pathtracer/PathTracer.ih @@ -30,6 +30,7 @@ struct PathTracer { int32 maxDepth; float minContribution; + float maxRadiance; Texture2D* uniform backplate; const uniform Light *uniform *uniform lights; diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index bfbfd56610..c2c6653b01 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -339,7 +339,7 @@ inline ScreenSample PathTracer_renderPixel(uniform PathTracer *uniform self, ScreenSample sample = PathTraceIntegrator_Li(self, cameraSample.screen, lightPath, rng); - screenSample.rgb = screenSample.rgb + sample.rgb; + screenSample.rgb = screenSample.rgb + min(sample.rgb, make_vec3f(self->maxRadiance)); screenSample.alpha = screenSample.alpha + sample.alpha; screenSample.z = min(screenSample.z, sample.z); } @@ -406,6 +406,7 @@ unmasked void PathTracer_renderTile(uniform Renderer *uniform _self, export void PathTracer_set(void *uniform _self, const uniform int32 maxDepth, const uniform float minContribution, + const uniform float maxRadiance, void *uniform backplate, void **uniform lights, const uniform uint32 numLights) @@ -414,6 +415,7 @@ export void PathTracer_set(void *uniform _self, self->maxDepth = maxDepth; self->minContribution = minContribution; + self->maxRadiance = maxRadiance; self->backplate = (uniform Texture2D *uniform)backplate; self->lights = (const uniform Light *uniform *uniform)lights; self->numLights = numLights; @@ -426,7 +428,7 @@ export void* uniform PathTracer_create(void *uniform cppE) self->super.renderTile = PathTracer_renderTile; self->super.beginFrame = PathTracer_beginFrame; - PathTracer_set(self, 20, 0.01f, NULL, NULL, 0); + PathTracer_set(self, 20, 0.01f, inf, NULL, NULL, 0); precomputeZOrder(); From e764af25212b3c21893e057934f53254253ea625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 8 Apr 2016 19:17:28 +0200 Subject: [PATCH 196/310] Implement SpotLight_eval and optimizations --- ospray/lights/PointLight.cpp | 1 + ospray/lights/PointLight.ispc | 3 +- ospray/lights/SpotLight.cpp | 5 +-- ospray/lights/SpotLight.ispc | 58 ++++++++++++++++++++++++++++------- ospray/math/sampling.ih | 7 ++++- 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/ospray/lights/PointLight.cpp b/ospray/lights/PointLight.cpp index d317cf8ccc..bc9f79b4a1 100644 --- a/ospray/lights/PointLight.cpp +++ b/ospray/lights/PointLight.cpp @@ -40,6 +40,7 @@ namespace ospray { } OSP_REGISTER_LIGHT(PointLight, PointLight); + OSP_REGISTER_LIGHT(PointLight, point); OSP_REGISTER_LIGHT(PointLight, SphereLight); OSP_REGISTER_LIGHT(PointLight, sphere); } diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index d6970f7532..cb2fb9e3ec 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -61,7 +61,7 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, sample.direction = frame(sample.direction) * localDir; sample.pdf = uniformSampleConePDF(cosTheta); const float c = localDir.z; - sample.distance = c*sample.distance - sqrt(self->radius*self->radius - (1.f - c*c) * dist2); + sample.distance = c*sample.distance - sqrt(sqr(self->radius) - (1.f - c*c) * dist2); // TODO scale radiance by actual distance } else { // inside sphere const vec3f localDir = cosineSampleHemisphere(s); @@ -99,6 +99,7 @@ varying LightEval PointLight_eval(const uniform Light *uniform _self, const float t_far = (b + sqrt(radical)) / (2.f*a); if (t_far > 0.0f) { + // TODO: handle interior case res.distance = t_near; const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); const float cosTheta = sqrt(1.f - sinTheta2); diff --git a/ospray/lights/SpotLight.cpp b/ospray/lights/SpotLight.cpp index 599c217196..72a751e3b5 100644 --- a/ospray/lights/SpotLight.cpp +++ b/ospray/lights/SpotLight.cpp @@ -51,16 +51,17 @@ namespace ospray { const vec3f power = color * intensity; direction = normalize(direction); openingAngle = clamp(openingAngle, 0.f, 180.f); - penumbraAngle = clamp(penumbraAngle, 0.001f, 0.5f*openingAngle); + penumbraAngle = clamp(penumbraAngle, 0.f, 0.5f*openingAngle); const float cosAngleMax = cos(deg2rad(0.5f*openingAngle)); const float cosAngleMin = cos(deg2rad(0.5f*openingAngle - penumbraAngle)); + const float cosAngleScale = 1.0f/(cosAngleMin - cosAngleMax); ispc::SpotLight_set(getIE(), (ispc::vec3f&)position, (ispc::vec3f&)direction, (ispc::vec3f&)power, cosAngleMax, - cosAngleMin, + cosAngleScale, radius); } diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 381996aa19..9a8b48b542 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -22,11 +22,12 @@ struct SpotLight { Light super; //!< inherited light fields vec3f position; //!< Position of the SpotLight - vec3f direction; //!< Direction that the SpotLight is emitting; normalized + linear3f frame; //!< coordinate frame, with vz == direction that the SpotLight is emitting vec3f power; //!< RGB color and intensity of the SpotLight float cosAngleMax; //!< Angular limit of the spot in an easier to use form: cosine of the half angle in radians - float cosAngleMin; //!< Border of the penumbra area of the spot in an easier to use form; larger than cosAngleMax + float cosAngleScale; //!< 1/(cos(border of the penumbra area) - cosAngleMax); positive float radius; //!< defines the size of the (extended) SpotLight + float diskPdf; //!< pdf of disk with radius }; @@ -44,7 +45,7 @@ varying LightSample SpotLight_sample(const uniform Light *uniform _self, sample.direction = self->position - dg.P; if (self->radius > 0.) - sample.direction = frame(self->direction) * uniformSampleDisk(self->radius, s) + sample.direction; + sample.direction = self->frame * uniformSampleDisk(self->radius, s) + sample.direction; const float dist2 = dot(sample.direction, sample.direction); const float invdist = rsqrt(dist2); @@ -54,20 +55,53 @@ varying LightSample SpotLight_sample(const uniform Light *uniform _self, sample.distance = dist2 * invdist; // cosine of the negated light direction and light vector. - const float cosAngle = -dot(self->direction, sample.direction); - const float angularAttenuation = clamp((cosAngle - self->cosAngleMax) * rcp(self->cosAngleMin - self->cosAngleMax)); + const float cosAngle = -dot(self->frame.vz, sample.direction); + const float angularAttenuation = clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale); if (self->radius > 0.) - sample.pdf = uniformSampleDiskPDF(self->radius) * dist2 * abs(cosAngle); + sample.pdf = self->diskPdf * dist2 * abs(cosAngle); else sample.pdf = inf; // we always take this sample // convert from power to radiance by attenuating by distance^2; attenuate by angle - sample.radiance = self->power * (invdist * invdist * angularAttenuation); + sample.radiance = self->power * (sqr(invdist) * angularAttenuation); return sample; } +varying LightEval SpotLight_eval(const uniform Light *uniform _self, + const varying vec3f &pos, + const varying vec3f &dir) +{ + const SpotLight *uniform self = (SpotLight *uniform)_self; + LightEval res; + res.radiance = make_vec3f(0.f); + res.distance = inf; + res.pdf = 0.f; + + if (self->radius > 0.f) { + // intersect disk + const float cosAngle = -dot(dir, self->frame.vz); + if (cosAngle > self->cosAngleMax) { // inside illuminated cone? + const vec3f vp = pos - self->position; + const float dp = dot(vp, self->frame.vz); + if (dp > 0.f) { // in front of light? + const float t = dp*rcp(cosAngle); + const vec3f vd = vp + t * dir; + if (dot(vd, vd) < sqr(self->radius)) { // inside disk? + const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f); + const float pdf = self->diskPdf * cosAngle; + res.radiance = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels + res.distance = t; + res.pdf = pdf * sqr(t); + } + } + } + } + + return res; +} + // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// @@ -78,16 +112,17 @@ export void SpotLight_set(void *uniform _self, const uniform vec3f &direction, const uniform vec3f &power, const uniform float cosAngleMax, - const uniform float cosAngleMin, + const uniform float cosAngleScale, const uniform float radius) { uniform SpotLight *uniform self = (uniform SpotLight *uniform)_self; self->position = position; - self->direction = direction; + self->frame = frame(direction); self->power = power; self->cosAngleMax = cosAngleMax; - self->cosAngleMin = cosAngleMin; + self->cosAngleScale= cosAngleScale; self->radius = radius; + self->diskPdf = uniformSampleDiskPDF(radius); } //! Create an ispc-side SpotLight object @@ -97,13 +132,14 @@ export void *uniform SpotLight_create(void *uniform cppEquivalent) Light_Constructor(&self->super, cppEquivalent); self->super.sample = SpotLight_sample; + self->super.eval = SpotLight_eval; SpotLight_set(self, make_vec3f(0.f), make_vec3f(0.f, 0.f, 1.f), make_vec3f(1.f), 0.f, - 0.01f, + 100.f, 0.f); return self; diff --git a/ospray/math/sampling.ih b/ospray/math/sampling.ih index 579684390d..843dd25ccb 100644 --- a/ospray/math/sampling.ih +++ b/ospray/math/sampling.ih @@ -120,7 +120,12 @@ inline vec3f uniformSampleDisk(const float radius, const vec2f &s) inline float uniformSampleDiskPDF(const float radius) { - return rcp(M_PI * radius * radius); + return rcp(M_PI * sqr(radius)); +} + +inline uniform float uniformSampleDiskPDF(const uniform float radius) +{ + return rcp(M_PI * sqr(radius)); } From 4b37e27d8972c6b473502ed8143b47ed46abfc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 11 Apr 2016 10:14:28 +0200 Subject: [PATCH 197/310] Rename PT param maxRadiance to maxContribution --- ospray/render/pathtracer/PathTracer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/render/pathtracer/PathTracer.cpp b/ospray/render/pathtracer/PathTracer.cpp index 624d831458..2af527299c 100644 --- a/ospray/render/pathtracer/PathTracer.cpp +++ b/ospray/render/pathtracer/PathTracer.cpp @@ -66,7 +66,7 @@ namespace ospray { const int32 maxDepth = getParam1i("maxDepth", 20); const float minContribution = getParam1f("minContribution", 0.01f); - const float maxRadiance = getParam1f("maxRadiance", inf); + const float maxRadiance = getParam1f("maxContribution", getParam1f("maxRadiance", inf)); Texture2D *backplate = (Texture2D*)getParamObject("backplate", NULL); ispc::PathTracer_set(getIE(), maxDepth, minContribution, maxRadiance, From 9a5d3ef3337b85eb74591d5f5de27af4d269f036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 11 Apr 2016 10:39:07 +0200 Subject: [PATCH 198/310] Build COI device per default when KNC support enabled --- cmake/ospray.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index d760c15b8a..8269692b36 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -163,9 +163,7 @@ MACRO(CONFIGURE_OSPRAY) OSPRAY_CHECK_COMPILER_SUPPORT(AVX512) IF (THIS_IS_MIC) - # whether to build in MIC/xeon phi support - SET(OSPRAY_BUILD_COI_DEVICE OFF CACHE BOOL - "Build COI Device for OSPRay's MIC support?") + OPTION(OSPRAY_BUILD_COI_DEVICE "Build COI Device for OSPRay's MIC support?" ON) ENDIF() INCLUDE(${PROJECT_SOURCE_DIR}/cmake/ispc.cmake) From bf4763af9fec54b8e74238b1996b4bb0153f197b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 11 Apr 2016 11:01:58 +0200 Subject: [PATCH 199/310] Remove debug output --- apps/modelViewer/modelViewer.cpp | 4 ---- ospray/fb/LocalFB.cpp | 3 --- 2 files changed, 7 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 229a6dbcde..6f5537bdad 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -724,17 +724,13 @@ namespace ospray { std::vector instanceModels; for (size_t i=0;imesh.size();i++) { - printf("Mesh %li/%li\n",i,msgModel->mesh.size()); Ref msgMesh = msgModel->mesh[i]; - // DBG(PRINT(msgMesh.ptr)); // create ospray mesh OSPGeometry ospMesh = g_alpha ? ospNewGeometry("alpha_aware_triangle_mesh") : ospNewGeometry("trianglemesh"); // check if we have to transform the vertices: if (doesInstancing == false && msgModel->instance[i] != miniSG::Instance(i)) { - // cout << "Transforming vertex array ..." << endl; - // PRINT(msgMesh->position.size()); for (size_t vID=0;vIDposition.size();vID++) { msgMesh->position[vID] = xfmPoint(msgModel->instance[i].xfm, msgMesh->position[vID]); diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index fdc5a475eb..33cc872132 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -19,9 +19,6 @@ #include "LocalFB_ispc.h" #include "ospray/common/tasking/parallel_for.h" -// number of floats each task is clearing; must be a a mulitple of 16 -#define CLEAR_BLOCK_SIZE (32 * 1024) - namespace ospray { LocalFrameBuffer::LocalFrameBuffer(const vec2i &size, From 5ed6ac16646f0e86e6aeb1b8d714df7f9d6109b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 11 Apr 2016 19:00:15 +0200 Subject: [PATCH 200/310] Hierarchical adaptive variance-based stopping --- ospray/fb/FrameBuffer.h | 2 +- ospray/fb/LocalFB.cpp | 58 ++++++++++++++++++++++++++--- ospray/fb/LocalFB.h | 3 +- ospray/mpi/DistributedFrameBuffer.h | 8 ++-- ospray/mpi/MPILoadBalancer.cpp | 4 +- ospray/render/LoadBalancer.cpp | 4 +- 6 files changed, 63 insertions(+), 16 deletions(-) diff --git a/ospray/fb/FrameBuffer.h b/ospray/fb/FrameBuffer.h index e3c91557c6..4e9844b1c5 100644 --- a/ospray/fb/FrameBuffer.h +++ b/ospray/fb/FrameBuffer.h @@ -97,7 +97,7 @@ namespace ospray { changes that requires clearing the accumulation buffer. */ virtual int32 accumID(const vec2i &tile) = 0; virtual float tileError(const vec2i &tile) = 0; - virtual float frameError() = 0; + virtual float endFrame(const float errorThreshold) = 0; // returns error of frame Ref pixelOp; }; diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 33cc872132..fd7ec68f52 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -66,6 +66,8 @@ namespace ospray { if (hasVarianceBuffer) { varianceBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); tileErrorBuffer = new float[tiles]; + // maximum number of regions: all regions are of size 3 are split in half + errorRegion.reserve(divRoundUp(tiles*2, 3)); } else { varianceBuffer = NULL; tileErrorBuffer = NULL; @@ -105,10 +107,14 @@ namespace ospray { for (int i = 0; i < tiles; i++) tileAccumID[i] = 0; - // always also also error buffer (if present) + // always also clear error buffer (if present) if (hasVarianceBuffer) { for (int i = 0; i < tiles; i++) tileErrorBuffer[i] = inf; + + errorRegion.clear(); + // initially create one region covering the complete image + errorRegion.push_back(box2i(vec2i(0), vec2i(tilesx, divRoundUp(size.y, TILE_SIZE)))); } } } @@ -142,16 +148,58 @@ namespace ospray { float LocalFrameBuffer::tileError(const vec2i &tile) { - int idx = tile.y * tilesx + tile.x; - return hasVarianceBuffer && tileAccumID[idx] > 1 ? tileErrorBuffer[idx] : inf; + const int idx = tile.y * tilesx + tile.x; + return hasVarianceBuffer ? tileErrorBuffer[idx] : inf; } - float LocalFrameBuffer::frameError() + float LocalFrameBuffer::endFrame(const float errorThreshold) { if (hasVarianceBuffer) { + // process regions first, but don't process newly split regions again + int regions = errorThreshold > 0.f ? errorRegion.size() : 0; + for (int i = 0; i < regions; i++) { + box2i& region = errorRegion[i]; + float err = 0.f; + float maxErr = 0.0f; + for (int y = region.lower.y; y < region.upper.y; y++) + for (int x = region.lower.x; x < region.upper.x; x++) { + int idx = y * tilesx + x; + err += tileErrorBuffer[idx]; + maxErr = std::max(maxErr, tileErrorBuffer[idx]); + } + // set all tiles of this region to local max error to enforce their refinement as a group + for (int y = region.lower.y; y < region.upper.y; y++) + for (int x = region.lower.x; x < region.upper.x; x++) { + int idx = y * tilesx + x; + tileErrorBuffer[idx] = maxErr; + } + vec2i size = region.size(); + int area = reduce_mul(size); + err /= area; // avg + if (err < 4.f*errorThreshold) { // split region? + if (area <= 2) { // would just contain single tile after split: remove + region = errorRegion.back(); + errorRegion.pop_back(); + regions--; + i--; + continue; + } + vec2i split = region.lower + size / 2; // TODO: find split with equal variance + errorRegion.push_back(region); // region reference might become invalid + if (size.x > size.y) { + errorRegion[i].upper.x = split.x; + errorRegion.back().lower.x = split.x; + } else{ + errorRegion[i].upper.y = split.y; + errorRegion.back().lower.y = split.y; + } + } + } + float maxErr = 0.0f; for (int i = 0; i < tiles; i++) - maxErr = tileAccumID[i] > 1 ? std::max(maxErr, tileErrorBuffer[i]) : inf; + maxErr = std::max(maxErr, tileErrorBuffer[i]); + return maxErr; } else return inf; diff --git a/ospray/fb/LocalFB.h b/ospray/fb/LocalFB.h index 444338ee42..238fdd96ee 100644 --- a/ospray/fb/LocalFB.h +++ b/ospray/fb/LocalFB.h @@ -31,6 +31,7 @@ namespace ospray { vec4f *varianceBuffer; /*!< one RGBA per pixel, may be NULL, accumulates every other sample, for variance estimation / stopping */ int32 *tileAccumID; //< holds accumID per tile, for adaptive accumulation float *tileErrorBuffer; /*!< holds error per tile, for variance estimation / stopping */ + std::vector errorRegion; // image regions (in #tiles) which do not yet estimate the error on tile base int32 tilesx; int32 tiles; @@ -49,7 +50,7 @@ namespace ospray { void setTile(Tile &tile) override; int32 accumID(const vec2i &tile) override; float tileError(const vec2i &tile) override; - float frameError() override; + float endFrame(const float errorThreshold) override; const void *mapColorBuffer() override; const void *mapDepthBuffer() override; diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index aba40d565e..278b2c9b1c 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -43,9 +43,9 @@ namespace ospray { size_t numMyTiles() const { return myTiles.size(); }; int accumId; - int32 accumID(const vec2i &tile) override { return accumId; } - float tileError(const vec2i &tile) override { return inf; } - float frameError() override { return inf; } + int32 accumID(const vec2i &) override { return accumId; } + float tileError(const vec2i &) override { return inf; } + float endFrame(const float) override { return inf; }; /*! color buffer and depth buffer on master */ @@ -400,5 +400,3 @@ namespace ospray { }; } // ::ospray - - diff --git a/ospray/mpi/MPILoadBalancer.cpp b/ospray/mpi/MPILoadBalancer.cpp index 6939b30058..b869e2f0e0 100644 --- a/ospray/mpi/MPILoadBalancer.cpp +++ b/ospray/mpi/MPILoadBalancer.cpp @@ -51,7 +51,7 @@ namespace ospray { async_endFrame(); - return dfb->frameError(); + return dfb->endFrame(0.f); } std::string Master::toString() const @@ -105,7 +105,7 @@ namespace ospray { async_endFrame(); - return dfb->frameError(); + return dfb->endFrame(0.f); } std::string Slave::toString() const diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index b098a46de8..f8b9a62990 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -72,7 +72,7 @@ namespace ospray { renderer->endFrame(perFrameData,channelFlags); - return fb->frameError(); + return fb->endFrame(renderer->errorThreshold); } std::string LocalTiledLoadBalancer::toString() const @@ -123,7 +123,7 @@ namespace ospray { renderer->endFrame(perFrameData,channelFlags); - return fb->frameError(); + return fb->endFrame(renderer->errorThreshold); } } // ::ospray From 1fd0d047300c4ebc3241499801b565fec0bcd74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 12 Apr 2016 11:49:58 +0200 Subject: [PATCH 201/310] Simplifications in error calculation --- ospray/fb/LocalFB.ispc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 1bdb772216..37c3f0178f 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -118,7 +118,6 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, const uniform float accScale = rcpf(tile.accumID+1); const uniform float accHalfScale = rcpf(tile.accumID/2+1); float err = 0.f; - float cnt = 0.f; for (uniform uint32 iy=0;iya[chunkID]; } accum[pixelID] = acc; + acc = acc * accScale; // variance buffer accumulates every other frame if (variance && (tile.accumID & 1) == 1) { @@ -156,20 +156,19 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, } variance[pixelID] = make_vec4f(vari); - const vec3f accs = accScale * make_vec3f(acc); - const float den2 = accs.x + accs.y + accs.z; + const vec3f acc3 = make_vec3f(acc); + const float den2 = reduce_add(acc3); if (den2 > 0.0f) { - const vec3f diff = absf(accs - accHalfScale * vari); - err += (diff.x + diff.y + diff.z) * rsqrtf(den2); - cnt++; + const vec3f diff = absf(acc3 - accHalfScale * vari); + err += reduce_add(diff) * rsqrtf(den2); } } unmasked { - varyTile->r[chunkID] = accScale * acc.x; - varyTile->g[chunkID] = accScale * acc.y; - varyTile->b[chunkID] = accScale * acc.z; - varyTile->a[chunkID] = accScale * acc.w; + varyTile->r[chunkID] = acc.x; + varyTile->g[chunkID] = acc.y; + varyTile->b[chunkID] = acc.z; + varyTile->a[chunkID] = acc.w; } } } @@ -181,8 +180,9 @@ export void LocalFrameBuffer_accumulateTile(void *uniform _fb, // error is also only updated every other frame to avoid alternating error // (get a monotone sequence) if (variance && (tile.accumID & 1) == 1) { - const uniform float cntu = reduce_add(cnt); - const uniform float errf = cntu > 0.f ? reduce_add(err) * rsqrtf(cntu) : 0.f; + uniform vec2i dia = tile.region.upper - tile.region.lower; + uniform float cntu = (uniform float)dia.x * dia.y; + const uniform float errf = reduce_add(err) * rsqrtf(cntu); // print("[%, %]: \t%\t%\n", tileIdx.x, tileIdx.y, errf); fb->tileErrorBuffer[tileId] = errf; } From 043b064f7f873958e5fb5e92cb67af8a6998e83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 12 Apr 2016 14:36:33 +0200 Subject: [PATCH 202/310] Correctly remove region by replacing with a to be processed one --- ospray/fb/LocalFB.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index fd7ec68f52..a99e131d5e 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -178,9 +178,10 @@ namespace ospray { err /= area; // avg if (err < 4.f*errorThreshold) { // split region? if (area <= 2) { // would just contain single tile after split: remove - region = errorRegion.back(); - errorRegion.pop_back(); regions--; + errorRegion[i] = errorRegion[regions]; + errorRegion[regions]= errorRegion.back(); + errorRegion.pop_back(); i--; continue; } @@ -189,7 +190,7 @@ namespace ospray { if (size.x > size.y) { errorRegion[i].upper.x = split.x; errorRegion.back().lower.x = split.x; - } else{ + } else { errorRegion[i].upper.y = split.y; errorRegion.back().lower.y = split.y; } From 59438e9d6f9b03bac33a2721915575295ef27fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 12 Apr 2016 15:33:02 +0200 Subject: [PATCH 203/310] Adapt VolumeRenderer to changed FrameBuffer API --- ospray/render/volume/RaycastVolumeRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index 062785f624..aad6a77c56 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -309,7 +309,7 @@ namespace ospray { dfb->waitUntilFinished(); Renderer::endFrame(NULL,channelFlags); - return fb->frameError(); + return fb->endFrame(0.f); } #endif From 46c7e5dea7953235c17214575c4d3ac3522844be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 12 Apr 2016 16:44:42 +0200 Subject: [PATCH 204/310] Fix accumulation for EXP_DATA_PARALLEL --- .../render/volume/RaycastVolumeRenderer.cpp | 19 ++++--------------- ospray/render/volume/RaycastVolumeRenderer.ih | 5 ----- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index aad6a77c56..6ce1401faa 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -126,23 +126,12 @@ namespace ospray { void DPRenderTask::run(size_t taskIndex) const { const size_t tileID = taskIndex; - Tile bgTile, fgTile; const size_t tile_y = taskIndex / numTiles_x; const size_t tile_x = taskIndex - tile_y*numTiles_x; - bgTile.region.lower.x = tile_x * TILE_SIZE; - bgTile.region.lower.y = tile_y * TILE_SIZE; - bgTile.region.upper.x = std::min(bgTile.region.lower.x+TILE_SIZE,fb->size.x); - bgTile.region.upper.y = std::min(bgTile.region.lower.y+TILE_SIZE,fb->size.y); - bgTile.fbSize = fb->size; - bgTile.rcp_fbSize = rcp(vec2f(bgTile.fbSize)); - bgTile.generation = 0; - bgTile.children = 0; - - fgTile.region = bgTile.region; - fgTile.fbSize = bgTile.fbSize; - fgTile.rcp_fbSize = bgTile.rcp_fbSize; - fgTile.generation = 0; - fgTile.children = 0; + const vec2i tileId(tile_x, tile_y); + const int32 accumID = fb->accumID(tileID); + Tile bgTile(tileId, fb->size, accumID); + Tile fgTile(bgTile); size_t numBlocks = dpv->numDDBlocks; CacheForBlockTiles blockTileCache(numBlocks); diff --git a/ospray/render/volume/RaycastVolumeRenderer.ih b/ospray/render/volume/RaycastVolumeRenderer.ih index bc604010bc..f3c8645b3f 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ih +++ b/ospray/render/volume/RaycastVolumeRenderer.ih @@ -33,8 +33,3 @@ struct RaycastVolumeRenderer Light **uniform lights; uint32 numLights; }; - -void RaycastVolumeRenderer_renderFramePostamble(Renderer *uniform renderer, - const uniform int32 accumID); -void RaycastVolumeRenderer_renderFramePreamble(Renderer *uniform renderer, - FrameBuffer *uniform framebuffer); From 6ca1d49d36570c9a348b1864aeecbd5e34fb3e04 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Wed, 13 Apr 2016 18:55:53 -0600 Subject: [PATCH 205/310] Fix crash for distributed rendering when using BatchedIsendIrecv Memory allocated with `alloca` doesn't get free'd until the *function* scope exits, at least from how the man page reads. So re-calling alloca in the while loop will keep growing the stack until eventually we overflow the stack and crash. Similar to the RecvThread we now just put a constant `SEND_WINDOW_SIZE` size array of MPI_Request on the stack up front and use that. --- ospray/mpi/async/BatchedIsendIrecvMessaging.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/mpi/async/BatchedIsendIrecvMessaging.cpp b/ospray/mpi/async/BatchedIsendIrecvMessaging.cpp index dc2e42bc05..17059b62d9 100644 --- a/ospray/mpi/async/BatchedIsendIrecvMessaging.cpp +++ b/ospray/mpi/async/BatchedIsendIrecvMessaging.cpp @@ -38,10 +38,10 @@ namespace ospray { { Group *g = this->group; Action *actions[SEND_WINDOW_SIZE]; + MPI_Request request[SEND_WINDOW_SIZE]; while (1) { // usleep(80); size_t numActions = g->sendQueue.getSome(actions,SEND_WINDOW_SIZE); - auto *request = (MPI_Request*)alloca(numActions*sizeof(MPI_Request)); for (int i=0;idata,action->size,MPI_BYTE, From 8d235bbfc8ef8474ac02d0d5fc169f8096cdb9dc Mon Sep 17 00:00:00 2001 From: Carson Brownlee Date: Thu, 14 Apr 2016 17:43:38 -0500 Subject: [PATCH 206/310] fixing gamma --- ospray/fb/LocalFB.ispc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 37c3f0178f..27f1e7b8a0 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -49,7 +49,7 @@ export void LocalFrameBuffer_writeTile_RGBA_I8(void *uniform _fb, // XXX hardcoded gamma, should use pixelops! col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); + col = make_vec4f(pow(make_vec3f(col), fb->super.gamma), col.w); const uint32 asRGBA = cvt_uint32(col); } From 2c1606e2c1e68f7a8e5a2307140fbbfe276cfcab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 15 Apr 2016 13:53:36 +0200 Subject: [PATCH 207/310] Fix gamma by using reciprocal, default to 2.2 ...to be consistent with previous implementation --- ospray/fb/FrameBuffer.cpp | 2 +- ospray/fb/FrameBuffer.ih | 2 +- ospray/fb/FrameBuffer.ispc | 2 +- ospray/fb/LocalFB.ispc | 2 +- ospray/mpi/DistributedFrameBuffer.ispc | 2 ++ 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ospray/fb/FrameBuffer.cpp b/ospray/fb/FrameBuffer.cpp index f89a0430ab..7d15e38b7c 100644 --- a/ospray/fb/FrameBuffer.cpp +++ b/ospray/fb/FrameBuffer.cpp @@ -37,7 +37,7 @@ namespace ospray { void FrameBuffer::commit() { - const float gamma = getParam1f("gamma", 1.0f); + const float gamma = getParam1f("gamma", 2.2f); ispc::FrameBuffer_set_gamma(ispcEquivalent, gamma); } diff --git a/ospray/fb/FrameBuffer.ih b/ospray/fb/FrameBuffer.ih index 98e92105e8..b1548c49ac 100644 --- a/ospray/fb/FrameBuffer.ih +++ b/ospray/fb/FrameBuffer.ih @@ -37,7 +37,7 @@ struct FrameBuffer { vec2i size; /*!< size (width x height) of frame buffer, in pixels */ vec2f rcpSize; /*! one over size (precomputed) */ - uniform float gamma; /*! gamma correction */ + uniform float invGamma; /*! 1/gamma for gamma correction */ FrameBuffer_ColorBufferFormat colorBufferFormat; diff --git a/ospray/fb/FrameBuffer.ispc b/ospray/fb/FrameBuffer.ispc index 4561bbf33e..6a321f4722 100644 --- a/ospray/fb/FrameBuffer.ispc +++ b/ospray/fb/FrameBuffer.ispc @@ -43,5 +43,5 @@ export void FrameBuffer_set_gamma(void *uniform _self, const uniform float gamma) { uniform FrameBuffer *uniform self = (uniform FrameBuffer *uniform)_self; - self->gamma = gamma; + self->invGamma = 1.0f/gamma; } diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 27f1e7b8a0..550442e4e4 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -49,7 +49,7 @@ export void LocalFrameBuffer_writeTile_RGBA_I8(void *uniform _fb, // XXX hardcoded gamma, should use pixelops! col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), fb->super.gamma), col.w); + col = make_vec4f(pow(make_vec3f(col), fb->super.invGamma), col.w); const uint32 asRGBA = cvt_uint32(col); } diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index fb82b38467..26ac062040 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -96,6 +96,7 @@ export void DFB_accumulate(VaryingTile *uniform tile, final->a[i] = col.w; // XXX hardcoded gamma, should use pixelops! + // TODO use fb->super.invGamma col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); @@ -128,6 +129,7 @@ export void DFB_accumulate(VaryingTile *uniform tile, final->a[i] = col.w; // XXX hardcoded gamma, should use pixelops! + // TODO use fb->super.invGamma col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); From 186fa297947ce8aab6526623e31a07c498aeda5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 15 Apr 2016 16:14:26 +0200 Subject: [PATCH 208/310] Refactor light interface and cleanup: - sample returns weight=radiance/pdf, reflect this in naming - we need the normal in 'eval' as well (thus pass DifferentialGeometry similar to 'sample'), to consistently calculate pdf - eliminate unused cppEquivalent - comments - remove LightPath in PT --- ospray/lights/AmbientLight.cpp | 2 +- ospray/lights/AmbientLight.ispc | 11 +- ospray/lights/DirectionalLight.cpp | 2 +- ospray/lights/DirectionalLight.ispc | 8 +- ospray/lights/HDRILight.cpp | 2 +- ospray/lights/HDRILight.ispc | 9 +- ospray/lights/Light.ih | 29 ++-- ospray/lights/Light.ispc | 2 +- ospray/lights/PointLight.cpp | 2 +- ospray/lights/PointLight.ispc | 12 +- ospray/lights/QuadLight.cpp | 2 +- ospray/lights/QuadLight.ispc | 6 +- ospray/lights/SpotLight.cpp | 2 +- ospray/lights/SpotLight.ispc | 10 +- ospray/render/obj/OBJRenderer.ispc | 4 +- ospray/render/pathtracer/PathTracer.ispc | 156 +++++++----------- ospray/render/scivis/SciVisRenderer.ispc | 6 +- .../render/volume/RaycastVolumeRenderer.ispc | 4 +- 18 files changed, 118 insertions(+), 151 deletions(-) diff --git a/ospray/lights/AmbientLight.cpp b/ospray/lights/AmbientLight.cpp index 88ba440930..e308d9d31e 100644 --- a/ospray/lights/AmbientLight.cpp +++ b/ospray/lights/AmbientLight.cpp @@ -22,7 +22,7 @@ namespace ospray { : color(1.f) , intensity(1.f) { - ispcEquivalent = ispc::AmbientLight_create(this); + ispcEquivalent = ispc::AmbientLight_create(); } //! Commit parameters understood by the AmbientLight diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 90cc5abdc1..500ca98e73 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -39,13 +39,13 @@ varying LightSample AmbientLight_sample(const uniform Light *uniform _self, sample.direction = frame(dg.Ns) * localDir; sample.pdf = cosineSampleHemispherePDF(localDir); sample.distance = inf; - sample.radiance = self->radiance * rcp(sample.pdf); + sample.weight = self->radiance * rcp(sample.pdf); return sample; } varying LightEval AmbientLight_eval(const uniform Light *uniform _self, - const varying vec3f &pos, + const varying DifferentialGeometry &, const varying vec3f &) { uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; @@ -60,10 +60,9 @@ varying LightEval AmbientLight_eval(const uniform Light *uniform _self, void AmbientLight_Constructor(uniform AmbientLight *uniform self, - void *uniform cppEquivalent, const uniform vec3f &radiance) { - Light_Constructor(&self->super, cppEquivalent); + Light_Constructor(&self->super); self->radiance = radiance; self->super.sample = AmbientLight_sample; self->super.eval = AmbientLight_eval; @@ -74,10 +73,10 @@ void AmbientLight_Constructor(uniform AmbientLight *uniform self, ////////////////////////////////////////////////////////////////////////////// //! Create an ispc-side AmbientLight object -export void *uniform AmbientLight_create(void *uniform cppEquivalent) +export void *uniform AmbientLight_create() { uniform AmbientLight *uniform self = uniform new uniform AmbientLight; - AmbientLight_Constructor(self, cppEquivalent, make_vec3f(1.f)); + AmbientLight_Constructor(self, make_vec3f(1.f)); return self; } diff --git a/ospray/lights/DirectionalLight.cpp b/ospray/lights/DirectionalLight.cpp index da23d0b2b0..d5566c14c8 100644 --- a/ospray/lights/DirectionalLight.cpp +++ b/ospray/lights/DirectionalLight.cpp @@ -24,7 +24,7 @@ namespace ospray { , intensity(1.f) , angularDiameter(0.f) { - ispcEquivalent = ispc::DirectionalLight_create(this); + ispcEquivalent = ispc::DirectionalLight_create(); } //! Commit parameters understood by the DirectionalLight diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 31435c0eec..8f16eb8624 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -48,13 +48,13 @@ varying LightSample DirectionalLight_sample(const uniform Light *uniform _self, if (self->cosAngle < COS_ANGLE_MAX) sample.direction = self->frame * uniformSampleCone(self->cosAngle, s); - sample.radiance = self->radiance; // *pdf/pdf cancel + sample.weight = self->radiance; // *pdf/pdf cancel return sample; } varying LightEval DirectionalLight_eval(const uniform Light *uniform _self, - const varying vec3f &pos, + const varying DifferentialGeometry &, const varying vec3f &dir) { uniform DirectionalLight *uniform self = (uniform DirectionalLight *uniform)_self; @@ -90,10 +90,10 @@ export void DirectionalLight_set(void *uniform _self, } //! Create an ispc-side DirectionalLight object -export void *uniform DirectionalLight_create(void *uniform cppEquivalent) +export void *uniform DirectionalLight_create() { uniform DirectionalLight *uniform self = uniform new uniform DirectionalLight; - Light_Constructor(&self->super, cppEquivalent); + Light_Constructor(&self->super); self->super.sample = DirectionalLight_sample; self->super.eval = DirectionalLight_eval; diff --git a/ospray/lights/HDRILight.cpp b/ospray/lights/HDRILight.cpp index 9247760cac..416e96cbb4 100644 --- a/ospray/lights/HDRILight.cpp +++ b/ospray/lights/HDRILight.cpp @@ -25,7 +25,7 @@ namespace ospray { , map(NULL) , intensity(1.f) { - ispcEquivalent = ispc::HDRILight_create(this); + ispcEquivalent = ispc::HDRILight_create(); } HDRILight::~HDRILight() diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index ba27511429..2f281e43e4 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -36,6 +36,7 @@ struct HDRILight // Implementation ////////////////////////////////////////////////////////////////////////////// +// sample function used when no environment map is given: black varying LightSample HDRILight_sample_dummy(const uniform Light *uniform, const varying DifferentialGeometry &, const varying vec2f &) @@ -69,13 +70,13 @@ varying LightSample HDRILight_sample(const uniform Light *uniform _self, sample.pdf = sample2d.pdf * one_over_two_pi_sqr * rcp(sinTheta); sample.distance = inf; - sample.radiance = get3f(self->map, sample2d.uv) * self->intensity / sample.pdf; + sample.weight = get3f(self->map, sample2d.uv) * self->intensity / sample.pdf; return sample; } varying LightEval HDRILight_eval(const uniform Light *uniform _self, - const varying vec3f &, + const varying DifferentialGeometry &, const varying vec3f &dir) { uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; @@ -158,11 +159,11 @@ export void HDRILight_set(void *uniform _self, } //! Create an ispc-side HDRILight object -export void *uniform HDRILight_create(void *uniform cppEquivalent) +export void *uniform HDRILight_create() { uniform HDRILight *uniform self = uniform new uniform HDRILight; - Light_Constructor(&self->super, cppEquivalent); + Light_Constructor(&self->super); self->super.sample = HDRILight_sample_dummy; self->distribution = NULL; diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index 7a0a390dbc..e44ba7934a 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -22,10 +22,10 @@ struct Light; struct LightSample { - vec3f radiance; //!< radiance for this sample that arrives at the given point, already weighted by pdf + vec3f weight; //!< radiance that arrives at the given point divided by pdf vec3f direction; //!< direction towards the light source - float distance; //!< largest valid parameter value for a shadow ray - float pdf; //!< probability that this sample was taken + float distance; //!< largest valid t_far value for a shadow ray + float pdf; //!< probability density that this sample was taken }; //! compute the weighted radiance at a point caused by a sample on the light source @@ -40,30 +40,25 @@ struct LightEval { vec3f radiance; //!< radiance that arrives at the given point (not weighted by pdf) float distance; - float pdf; //!< probability that the direction would have been sampled + float pdf; //!< probability density that the direction would have been sampled }; -//! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction) from pos +//! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction) typedef varying LightEval (*Light_EvalFct)(const uniform Light *uniform, - /*! position of point >*/const varying vec3f &pos, -/*! direction towards the light source >*/const varying vec3f &dir); +/*! point to evaluate illumination for >*/ const varying DifferentialGeometry&, +/*! direction towards the light source >*/ const varying vec3f &dir); -struct Light { - Light_SampleFct sample; +struct Light +{ + Light_SampleFct sample; Light_EvalFct eval; - - //! Pointer back to the C++ equivalent of this class. - void *uniform cppEquivalent; }; -varying LightEval defaultEval(const uniform Light *uniform, const varying vec3f &, const varying vec3f &); +varying LightEval defaultEval(const uniform Light *uniform, const varying DifferentialGeometry&, const varying vec3f&); -//! constructor for ispc-side light object -inline void Light_Constructor(uniform Light *uniform self, - void *uniform cppEquivalent) +inline void Light_Constructor(uniform Light *uniform self) { - self->cppEquivalent = cppEquivalent; self->eval = defaultEval; } diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index 7e8619cc8b..81e5fa7ebd 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -17,7 +17,7 @@ #include "Light.ih" varying LightEval defaultEval(const uniform Light *uniform, - const varying vec3f &, + const varying DifferentialGeometry&, const varying vec3f &) { LightEval res; diff --git a/ospray/lights/PointLight.cpp b/ospray/lights/PointLight.cpp index bc9f79b4a1..c5b4390a73 100644 --- a/ospray/lights/PointLight.cpp +++ b/ospray/lights/PointLight.cpp @@ -24,7 +24,7 @@ namespace ospray { , intensity(1.f) , radius(0.f) { - ispcEquivalent = ispc::PointLight_create(this); + ispcEquivalent = ispc::PointLight_create(); } //! Commit parameters understood by the PointLight diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index cb2fb9e3ec..af210c8f0e 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -49,7 +49,7 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, sample.pdf = inf; // per default we always take this sample // convert from power to radiance by attenuating by distance^2 - sample.radiance = self->power * sqr(invdist); + sample.weight = self->power * sqr(invdist); const float sinTheta = self->radius * invdist; if (self->radius > 0.f & sinTheta > 0.005f) { @@ -68,7 +68,7 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, sample.direction = frame(dg.Ns) * localDir; sample.pdf = cosineSampleHemispherePDF(localDir); // TODO: - sample.radiance = self->power * rcp(sqr(self->radius)); + sample.weight = self->power * rcp(sqr(self->radius)); sample.distance = self->radius; } } @@ -77,7 +77,7 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, } varying LightEval PointLight_eval(const uniform Light *uniform _self, - const varying vec3f &pos, + const varying DifferentialGeometry &dg, const varying vec3f &dir) { const PointLight *uniform self = (PointLight *uniform)_self; @@ -87,7 +87,7 @@ varying LightEval PointLight_eval(const uniform Light *uniform _self, res.pdf = 0.f; if (self->radius > 0.f) { - const vec3f A = self->position - pos; + const vec3f A = self->position - dg.P; const float a = dot(dir, dir); const float b = 2.f * dot(dir, A); const float centerDist2 = dot(A, A); @@ -129,10 +129,10 @@ export void PointLight_set(void *uniform _self, } //! Create an ispc-side PointLight object -export void *uniform PointLight_create(void *uniform cppEquivalent) +export void *uniform PointLight_create() { uniform PointLight *uniform self = uniform new uniform PointLight; - Light_Constructor(&self->super, cppEquivalent); + Light_Constructor(&self->super); self->super.sample = PointLight_sample; self->super.eval = PointLight_eval; diff --git a/ospray/lights/QuadLight.cpp b/ospray/lights/QuadLight.cpp index 310d1020d7..996a934a42 100644 --- a/ospray/lights/QuadLight.cpp +++ b/ospray/lights/QuadLight.cpp @@ -32,7 +32,7 @@ namespace ospray { , color(1.f) , intensity(1.f) { - ispcEquivalent = ispc::QuadLight_create(this); + ispcEquivalent = ispc::QuadLight_create(); } //!< Copy understood parameters into class members diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index 7cb8f9c089..2b2e0d4dfc 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -56,7 +56,7 @@ varying LightSample QuadLight_sample(const uniform Light *uniform _self, sample.pdf = self->ppdf * (dist * dist) / abs(cosd); // emit only to one side - sample.radiance = cosd > 0.f ? self->radiance * rcp(sample.pdf) : make_vec3f(0.f); + sample.weight = cosd > 0.f ? self->radiance * rcp(sample.pdf) : make_vec3f(0.f); return sample; } @@ -84,11 +84,11 @@ export void QuadLight_set(void *uniform _self, } //! Create an ispc-side QuadLight object -export void *uniform QuadLight_create(void *uniform cppEquivalent) +export void *uniform QuadLight_create() { uniform QuadLight *uniform self = uniform new uniform QuadLight; - Light_Constructor(&self->super, cppEquivalent); + Light_Constructor(&self->super); self->super.sample = QuadLight_sample; QuadLight_set(self, diff --git a/ospray/lights/SpotLight.cpp b/ospray/lights/SpotLight.cpp index 72a751e3b5..04525966c2 100644 --- a/ospray/lights/SpotLight.cpp +++ b/ospray/lights/SpotLight.cpp @@ -34,7 +34,7 @@ namespace ospray { , penumbraAngle(5.f) , radius(0.f) { - ispcEquivalent = ispc::SpotLight_create(this); + ispcEquivalent = ispc::SpotLight_create(); } //!< Copy understood parameters into class members diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 9a8b48b542..fdaf0a9648 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -64,13 +64,13 @@ varying LightSample SpotLight_sample(const uniform Light *uniform _self, sample.pdf = inf; // we always take this sample // convert from power to radiance by attenuating by distance^2; attenuate by angle - sample.radiance = self->power * (sqr(invdist) * angularAttenuation); + sample.weight = self->power * (sqr(invdist) * angularAttenuation); return sample; } varying LightEval SpotLight_eval(const uniform Light *uniform _self, - const varying vec3f &pos, + const varying DifferentialGeometry &dg, const varying vec3f &dir) { const SpotLight *uniform self = (SpotLight *uniform)_self; @@ -83,7 +83,7 @@ varying LightEval SpotLight_eval(const uniform Light *uniform _self, // intersect disk const float cosAngle = -dot(dir, self->frame.vz); if (cosAngle > self->cosAngleMax) { // inside illuminated cone? - const vec3f vp = pos - self->position; + const vec3f vp = dg.P - self->position; const float dp = dot(vp, self->frame.vz); if (dp > 0.f) { // in front of light? const float t = dp*rcp(cosAngle); @@ -126,11 +126,11 @@ export void SpotLight_set(void *uniform _self, } //! Create an ispc-side SpotLight object -export void *uniform SpotLight_create(void *uniform cppEquivalent) +export void *uniform SpotLight_create() { uniform SpotLight *uniform self = uniform new uniform SpotLight; - Light_Constructor(&self->super, cppEquivalent); + Light_Constructor(&self->super); self->super.sample = SpotLight_sample; self->super.eval = SpotLight_eval; diff --git a/ospray/render/obj/OBJRenderer.ispc b/ospray/render/obj/OBJRenderer.ispc index 774832e2ff..f09b5f8dbf 100644 --- a/ospray/render/obj/OBJRenderer.ispc +++ b/ospray/render/obj/OBJRenderer.ispc @@ -168,10 +168,10 @@ inline void OBJRenderer_shadeRay(const uniform OBJRenderer *uniform self, varyin const vec2f s = make_vec2f(0.f); const LightSample light = l->sample(l, dg, s); - if (reduce_max(light.radiance) > 0.f) { // any potential contribution? + if (reduce_max(light.weight) > 0.f) { // any potential contribution? const float cosNL = abs(dot(light.direction, dg.Ns)); const float cosLR = max(0.f, dot(light.direction, R)); - const vec3f unshaded_light_contrib = local_opacity * (Kd * cosNL + Ks * powf(cosLR, Ns)) * light.radiance; + const vec3f unshaded_light_contrib = local_opacity * (Kd * cosNL + Ks * powf(cosLR, Ns)) * light.weight; if (self->shadowsEnabled) { const float max_contrib = reduce_max(unshaded_light_contrib); diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index c2c6653b01..c66d7ea5a4 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -25,39 +25,6 @@ #define PDF_CULLING 0.0f //#define USE_DGCOLOR -////////////////////////////////////////////////////////////////// -// LightPath - -struct LightPath -{ - Ray ray; /*! Last ray in the path. */ - Medium lastMedium; /*! Medium the last ray travels inside. */ - uniform uint32 depth; /*! Recursion depth of path. */ - float bsdfPdf; // for MIS - bool unbent; /*! True of the ray path is a straight line. */ -}; - -inline void init_LightPath(LightPath& lp, const Ray &ray) -{ - lp.ray = ray; - lp.lastMedium = make_Medium_Vacuum(); - lp.depth = 0; - lp.bsdfPdf = inf; - lp.unbent = true; -} - -inline void extend_fast(LightPath& lp, - const vec3f nextRay_org, - const vec3f nextRay_dir, - const float nextRay_near, - const float nextRay_far, - const float bsdfPdf) -{ - lp.unbent = lp.unbent & eq(nextRay_dir,lp.ray.dir); - setRay(lp.ray,nextRay_org,nextRay_dir,nextRay_near,nextRay_far); - lp.depth++; - lp.bsdfPdf = bsdfPdf; -} inline float misHeuristic(float pdf1, float pdf2) { @@ -69,11 +36,6 @@ inline float misHeuristic(float pdf1, float pdf2) return pdf1 > 1e17f ? 1.0f : p; } - - -////////////////////////////////////////////////////////////////// -// PathTracer - vec3f transparentShadow(const uniform PathTracer* uniform self, vec3f lightContrib, Ray &shadowRay, @@ -129,31 +91,42 @@ vec3f transparentShadow(const uniform PathTracer* uniform self, ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, const vec2f &pixel, // normalized, i.e. in [0..1] - LightPath &lightPath, + Ray &ray, varying RandomTEA* uniform rng) { ScreenSample sample; sample.alpha = 1.f; - vec3f L = make_vec3f(0.f); - vec3f Lw = make_vec3f(1.f); + + vec3f L = make_vec3f(0.f); // accumulated radiance + vec3f Lw = make_vec3f(1.f); // path throughput + Medium currentMedium = make_Medium_Vacuum(); + float lastBSDFPdf = inf; // probability density of previous sampled BSDF, for MIS + bool straightPath = true; // path from camera did not change direction, for alpha and backplate + uniform uint32 depth = 0; + // geometric configuration of last surface interaction + DifferentialGeometry dg; + // P and N also used by light eval + dg.P = ray.org; + dg.Ns = ray.dir; + dg.Ng = ray.dir; do { - /*! Traverse ray. */ - traceRay(self->super.model, lightPath.ray); + traceRay(self->super.model, ray); - if (lightPath.depth == 0) - sample.z = lightPath.ray.t; + // record depth of primary rays + if (depth == 0) + sample.z = ray.t; - const vec3f wo = neg(lightPath.ray.dir); + const vec3f wo = neg(ray.dir); - float maxLightDist = lightPath.ray.t; // per default virtual lights are occluded by hit geometry + float maxLightDist = ray.t; // per default virtual lights are occluded by hit geometry - /*! Environment shading when nothing hit. */ - if (noHit(lightPath.ray)) { + // environment shading when nothing hit + if (noHit(ray)) { maxLightDist = inf; // also include envLights (i.e. the ones in infinity) - if (lightPath.unbent) + if (straightPath) sample.alpha = 1.0f - luminance(Lw); - if ((bool)self->backplate & lightPath.unbent) { + if ((bool)self->backplate & straightPath) { L = L + Lw * get3f(self->backplate, clamp2edge(self->backplate, pixel)); maxLightDist = 1e38; // backplate hides envLights (i.e. the ones in infinity) } @@ -162,21 +135,26 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, // add light from virtual lights by intersecting them for (uniform int i = 0; i < self->numLights; i++) { const uniform Light *uniform l = self->lights[i]; - LightEval le = l->eval(l, lightPath.ray.org, lightPath.ray.dir); + LightEval le = l->eval(l, dg, ray.dir); if (le.distance <= maxLightDist) - L = L + Lw * le.radiance * misHeuristic(lightPath.bsdfPdf, le.pdf); + L = L + Lw * le.radiance * misHeuristic(lastBSDFPdf, le.pdf); } - if (noHit(lightPath.ray)) + if (noHit(ray)) break; - DifferentialGeometry dg; - postIntersect(self->super.model, dg, lightPath.ray, + + + //////////////////////////////////// + // handle next surface interaction + + // update DifferentialGeometry dg + postIntersect(self->super.model, dg, ray, DG_MATERIALID| DG_NS|DG_NG|DG_FACEFORWARD|DG_NORMALIZE|DG_TEXCOORD|DG_COLOR|DG_TANGENTS ); - /*! Shade surface. */ + // shade surface uniform ShadingContext ctx; ShadingContext_Constructor(&ctx); const varying BSDF* bsdf = NULL; @@ -184,7 +162,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, uniform PathTraceMaterial* m = (uniform PathTraceMaterial*)dg.material; foreach_unique(mm in m) if (mm != NULL) - bsdf = mm->getBSDF(mm, &ctx, dg, lightPath.ray, lightPath.lastMedium); + bsdf = mm->getBSDF(mm, &ctx, dg, ray, currentMedium); #else foreach_unique(geomID in lightPath.ray.geomID) { uniform PathTraceMaterial* uniform m @@ -207,7 +185,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, } #endif - /*! Direct lighting. Shoot shadow rays to all light sources. */ + // direct lighting including shadows and MIS if (bsdf->type & BSDF_SMOOTH) { uniform int numLights = self->lights ? min(MAX_LIGHTS, self->numLights) : 0; @@ -215,14 +193,13 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, { const uniform Light *uniform light = self->lights[i]; - /*! Either use precomputed samples for the light or sample light now. */ LightSample ls = light->sample(light, dg, RandomTEA__getFloats(rng)); - /*! Ignore zero radiance or illumination from the back. */ - if (reduce_max(ls.radiance) <= 0.0f | ls.pdf <= PDF_CULLING) //| dot(dg.Ns, ls.direction) <= 1e-8f) + // skip when zero contribution from light + if (reduce_max(ls.weight) <= 0.0f | ls.pdf <= PDF_CULLING) continue; - /*! Evaluate BSDF */ + // evaluate BSDF vec3f bsdfValue; float bsdfPdf = 0.f; foreach_unique(b in bsdf) @@ -232,67 +209,65 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, #ifdef USE_DGCOLOR bsdfValue = bsdfValue * make_vec3f(dg.color); #endif + // skip when zero contribution from material if (reduce_max(bsdfValue) <= 0.0f) continue; - /*! Test for shadows. */ + // test for shadows Ray shadow_ray; setRay(shadow_ray, dg.P, ls.direction, - //dg.error* self->super.epsilon, ls.distance- - //dg.error* self->super.epsilon); - shadow_ray.time = lightPath.ray.time; + shadow_ray.time = ray.time; - vec3f unshaded_light_contrib = Lw * ls.radiance * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); - L = L + transparentShadow(self, unshaded_light_contrib, shadow_ray, lightPath.lastMedium, rng); + vec3f unshaded_light_contrib = Lw * ls.weight * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); + L = L + transparentShadow(self, unshaded_light_contrib, shadow_ray, currentMedium, rng); } } - /*! Global illumination. Pick one BSDF component and sample it. */ - if (lightPath.depth >= self->maxDepth) + if (depth >= self->maxDepth) break; - /*! sample BSDF */ + // sample BSDF vec3f wi; vec2f s = RandomTEA__getFloats(rng); vec2f ss = RandomTEA__getFloats(rng); // FIXME: should be only one component vec3f bsdfWeight; - float bsdfPdf = 0.f; uint32 bsdfType = 0; + // also update lastBSDFPdf foreach_unique(b in bsdf) if (b != NULL) - bsdfWeight = b->sample(b, wo, wi, bsdfPdf, bsdfType, s, ss.x); + bsdfWeight = b->sample(b, wo, wi, lastBSDFPdf, bsdfType, s, ss.x); #ifdef USE_DGCOLOR if ((type & GLOSSY_REFLECTION) == NONE) // only colorize diffuse component bsdfWeight = bsdfWeight * make_vec3f(dg.color); #endif - /*! Continue only if we hit something valid. */ - if (reduce_max(bsdfWeight) <= 0.0f | bsdfPdf <= PDF_CULLING) + // terminate path when zero contribution from material + if (reduce_max(bsdfWeight) <= 0.0f | lastBSDFPdf <= PDF_CULLING) break; - /*! Compute simple volumetric effect. */ - const vec3f transmission = lightPath.lastMedium.transmission; + Lw = Lw * bsdfWeight; + + // compute simple volumetric effect + const vec3f transmission = currentMedium.transmission; if (ne(transmission,make_vec3f(1.f))) - bsdfWeight = bsdfWeight * powf(transmission,lightPath.ray.t); + Lw = Lw * powf(transmission, ray.t); - /*! Tracking medium if we hit a medium interface. */ + // update currentMedium if we hit a medium interface TODO: support nested dielectrics if (bsdfType & BSDF_TRANSMISSION) { foreach_unique(uniMat in dg.material) { uniform PathTraceMaterial* uniform m = (uniform PathTraceMaterial *)uniMat; - if (m != NULL) m->selectNextMedium(m,lightPath.lastMedium); + if (m != NULL) + m->selectNextMedium(m, currentMedium); } } - /*! Continue the path. */ - extend_fast(lightPath, - dg.P,wi,//dg.error* - self->super.epsilon,inf, - bsdfPdf); - - Lw = Lw * bsdfWeight; + // continue the path + straightPath &= eq(ray.dir, wi); + setRay(ray, dg.P, wi, self->super.epsilon, inf); + depth++; } while (reduce_max(Lw) > self->minContribution); sample.rgb = L; @@ -334,11 +309,8 @@ inline ScreenSample PathTracer_renderPixel(uniform PathTracer *uniform self, const vec2f timeSample = RandomTEA__getFloats(rng); screenSample.ray.time = timeSample.x; - LightPath lightPath; - init_LightPath(lightPath, screenSample.ray); - ScreenSample sample = PathTraceIntegrator_Li(self, cameraSample.screen, - lightPath, rng); + screenSample.ray, rng); screenSample.rgb = screenSample.rgb + min(sample.rgb, make_vec3f(self->maxRadiance)); screenSample.alpha = screenSample.alpha + sample.alpha; screenSample.z = min(screenSample.z, sample.z); diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 4cdcd0c3e0..6dffb02235 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -235,12 +235,12 @@ inline void shadeLights(const uniform SciVisRenderer *uniform self, const vec2f s = make_vec2f(0.5f); const LightSample light = l->sample(l, dg, s); - if (reduce_max(light.radiance) > 0.f) { // any potential contribution? + if (reduce_max(light.weight) > 0.f) { // any potential contribution? const float cosNL = abs(dot(light.direction, dg.Ns)); const float cosLR = max(0.f, dot(light.direction, R)); const vec3f brdf = info.Kd * cosNL + info.Ks * powf(cosLR, info.Ns); const vec3f light_contrib = info.local_opacity - * brdf * light.radiance; + * brdf * light.weight; if (self->shadowsEnabled) { const float max_contrib = reduce_max(light_contrib); @@ -301,7 +301,7 @@ inline void SciVisRenderer_computeVolumeSample(SciVisRenderer *uniform renderer, 1.f : abs(dot(safe_normalize(light.direction), gradient)); - shadedColor = shadedColor + sampleColor * cosNL * light.radiance; + shadedColor = shadedColor + sampleColor * cosNL * light.weight; } sampleColor = shadedColor; diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 3c84461451..600b042a84 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -68,7 +68,7 @@ inline void RaycastVolumeRenderer_computeVolumeSample(RaycastVolumeRenderer *uni const float cosNL = (gradient.x == 0.f && gradient.y == 0.f && gradient.z == 0.f) ? 1.f : abs(dot(safe_normalize(light.direction), gradient)); - shadedColor = shadedColor + sampleColor * cosNL * light.radiance; + shadedColor = shadedColor + sampleColor * cosNL * light.weight; } sampleColor = shadedColor; @@ -148,7 +148,7 @@ inline void RaycastVolumeRenderer_computeGeometrySample(RaycastVolumeRenderer *u const LightSample light = self->lights[i]->sample(self->lights[i], dg, s); const float cosNL = abs(dot(safe_normalize(light.direction), dg.Ns)); - shadedColor = shadedColor + geometryColor * cosNL * light.radiance; + shadedColor = shadedColor + geometryColor * cosNL * light.weight; } // Set the color contribution for this sample only (do not accumulate). From 230f09a45f4f981811ca0d183be1c36ea037b0d9 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 15 Apr 2016 10:52:59 -0500 Subject: [PATCH 209/310] propagate gamma value to all uses, correct gamma value in ospModelViewer --- apps/modelViewer/modelViewer.cpp | 11 +++++++---- ospray/fb/LocalFB.ispc | 5 +++-- ospray/mpi/DistributedFrameBuffer.cpp | 18 ++++++++++-------- ospray/mpi/DistributedFrameBuffer.ispc | 8 +++++--- ospray/mpi/MPIDevice.cpp | 5 +++-- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 6f5537bdad..fbc23973de 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -145,7 +145,6 @@ namespace ospray { Assert(camera != NULL && "could not create camera"); ospSet3f(camera,"pos",-1,1,-1); ospSet3f(camera,"dir",+1,-1,+1); -// ospSet1f(camera,"fovy",120); ospCommit(camera); ospSetObject(renderer,"world",model); @@ -162,8 +161,11 @@ namespace ospray { Glut3DWidget::reshape(newSize); g_windowSize = newSize; if (fb) ospFreeFrameBuffer(fb); - fb = ospNewFrameBuffer((const osp::vec2i&)newSize,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_DEPTH|OSP_FB_ACCUM|OSP_FB_VARIANCE); - ospSet1f(fb, "gamma", 2.2f); + fb = ospNewFrameBuffer((const osp::vec2i&)newSize, + OSP_RGBA_I8, + OSP_FB_COLOR|OSP_FB_DEPTH| + OSP_FB_ACCUM|OSP_FB_VARIANCE); + ospSet1f(fb, "gamma", 0.5f); ospCommit(fb); ospFrameBufferClear(fb,OSP_FB_ACCUM); @@ -174,7 +176,8 @@ namespace ospray { if (displayWall && displayWall->fb != fb) { PRINT(displayWall->size); displayWall->fb = ospNewFrameBuffer((const osp::vec2i&)displayWall->size, - OSP_RGBA_NONE,OSP_FB_COLOR|OSP_FB_DEPTH|OSP_FB_ACCUM); + OSP_RGBA_NONE,OSP_FB_COLOR| + OSP_FB_DEPTH|OSP_FB_ACCUM); ospFrameBufferClear(displayWall->fb,OSP_FB_ACCUM); if (displayWall->po == NULL) { displayWall->po = ospNewPixelOp("display_wall"); diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 27f1e7b8a0..d0a6bc137f 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -90,9 +90,10 @@ export void LocalFrameBuffer_writeTile_RGBA_F32(void *uniform _fb, varyTile->b[chunkID], varyTile->a[chunkID]); - // XXX not even hardcoded gamma for float buffer, - // should use pixelops anyway + // XXX hardcoded gamma, should use pixelops! col = max(col, make_vec4f(0.f)); + // alpha is never gamma-corrected + col = make_vec4f(pow(make_vec3f(col), fb->super.gamma), col.w); } color[pixelID] = col; if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 87c5ba3e02..e0758a4336 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -128,7 +128,8 @@ namespace ospray { this->final.region = tile.region; this->final.fbSize = tile.fbSize; this->final.rcp_fbSize = tile.rcp_fbSize; - ispc::DFB_accumulate((ispc::VaryingTile *)&bufferedTile[0]->tile, + ispc::DFB_accumulate(dfb->ispcEquivalent, + (ispc::VaryingTile *)&bufferedTile[0]->tile, (ispc::VaryingTile *)&this->final, (ispc::VaryingTile *)&this->accum, (ispc::VaryingRGBA_I8 *)&this->color, @@ -162,7 +163,8 @@ namespace ospray { this->final.region = tile.region; this->final.fbSize = tile.fbSize; this->final.rcp_fbSize = tile.rcp_fbSize; - ispc::DFB_accumulate((ispc::VaryingTile *)&tile, + ispc::DFB_accumulate(dfb->ispcEquivalent, + (ispc::VaryingTile *)&tile, (ispc::VaryingTile*)&this->final, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, @@ -192,7 +194,8 @@ namespace ospray { } if (done) { - ispc::DFB_accumulate((ispc::VaryingTile*)&this->compositedTileData, + ispc::DFB_accumulate(dfb->ispcEquivalent, + (ispc::VaryingTile*)&this->compositedTileData, (ispc::VaryingTile*)&this->final, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, @@ -201,8 +204,6 @@ namespace ospray { } } - - void DFB::startNewFrame() { std::vector delayedMessage; @@ -322,18 +323,19 @@ namespace ospray { false); } } + ispc::DFB_set(getIE(),numPixels.x,numPixels.y, colorBufferFormat); - } void DFB::setFrameMode(FrameMode newFrameMode) { if (frameMode == newFrameMode) return; + freeTiles(); this->frameMode = newFrameMode; createTiles(); - } + } const void *DFB::mapDepthBuffer() { @@ -536,7 +538,7 @@ namespace ospray { msg->coords = tile.region.lower; // TODO: compress pixels before sending ... memcpy(&msg->tile,&tile,sizeof(ospray::Tile)); - msg->command = WORKER_WRITE_TILE; + msg->command = WORKER_WRITE_TILE; comm->sendTo(this->worker[tileDesc->ownerID], msg,sizeof(*msg)); diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index fb82b38467..9d6a0bec80 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -74,12 +74,14 @@ export void DFB_alphaBlendTiles(VaryingTile *uniform prev, } } -export void DFB_accumulate(VaryingTile *uniform tile, +export void DFB_accumulate(void *uniform _self, + VaryingTile *uniform tile, VaryingTile *uniform final, VaryingTile *uniform accum, VaryingRGBA_I8 *uniform color, uniform bool hasAccumBuffer) { + DistributedFrameBuffer *uniform self = (DistributedFrameBuffer*)_self; if (!hasAccumBuffer || tile->accumID < 1) { for (uniform int i=0;ir[i], @@ -98,7 +100,7 @@ export void DFB_accumulate(VaryingTile *uniform tile, // XXX hardcoded gamma, should use pixelops! col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); + col = make_vec4f(pow(make_vec3f(col), self->super.gamma), col.w); color->color[i] = cvt_uint32(col); } @@ -130,7 +132,7 @@ export void DFB_accumulate(VaryingTile *uniform tile, // XXX hardcoded gamma, should use pixelops! col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), 1.f/2.2f), col.w); + col = make_vec4f(pow(make_vec3f(col), self->super.gamma), col.w); color->color[i] = cvt_uint32(col); } diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index da6c6c7e1d..7e7d9abf4c 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -421,7 +421,7 @@ namespace ospray { Assert(_object); cmd.newCommand(CMD_COMMIT); const ObjectHandle handle = (const ObjectHandle&)_object; - cmd.send((const ObjectHandle&)_object); + cmd.send(handle); cmd.flush(); MPI_Barrier(MPI_COMM_WORLD); @@ -498,7 +498,6 @@ namespace ospray { size_t size = typeSize * size_t(count.x) * size_t(count.y) * size_t(count.z); if (size > 1000000000LL) throw std::runtime_error("setregion does not currently work for region sizes >= 2GB"); - // OSPData data = newData(size, type, (void *)source, OSP_DATA_SHARED_BUFFER); cmd.newCommand(CMD_SET_REGION); cmd.send((const ObjectHandle &)_volume); @@ -512,6 +511,8 @@ namespace ospray { MPI_Status status; int rc = MPI_Recv(&numFails,1,MPI_INT,0,MPI_ANY_TAG,mpi::worker.comm,&status); + Assert(rc != MPI_SUCCESS); + return (numFails == 0); } From 700a68fa84bca42a2b19a688fb0d92fe8b4b8906 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 15 Apr 2016 11:00:08 -0500 Subject: [PATCH 210/310] more fixes to use new invGamma --- apps/modelViewer/modelViewer.cpp | 2 +- ospray/fb/LocalFB.ispc | 6 +++--- ospray/mpi/DistributedFrameBuffer.ispc | 10 ++++------ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index fbc23973de..2f15a9ecc8 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -165,7 +165,7 @@ namespace ospray { OSP_RGBA_I8, OSP_FB_COLOR|OSP_FB_DEPTH| OSP_FB_ACCUM|OSP_FB_VARIANCE); - ospSet1f(fb, "gamma", 0.5f); + ospSet1f(fb, "gamma", 2.2f); ospCommit(fb); ospFrameBufferClear(fb,OSP_FB_ACCUM); diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index f0c87ddad2..7d54777e23 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -46,7 +46,7 @@ export void LocalFrameBuffer_writeTile_RGBA_I8(void *uniform _fb, varyTile->b[chunkID], varyTile->a[chunkID]); - // XXX hardcoded gamma, should use pixelops! + // NOTE(jda) - no longer hardcoded, but should use pixelops col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected col = make_vec4f(pow(make_vec3f(col), fb->super.invGamma), col.w); @@ -90,10 +90,10 @@ export void LocalFrameBuffer_writeTile_RGBA_F32(void *uniform _fb, varyTile->b[chunkID], varyTile->a[chunkID]); - // XXX hardcoded gamma, should use pixelops! + // NOTE(jda) - no longer hardcoded, but should use pixelops col = max(col, make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), fb->super.gamma), col.w); + col = make_vec4f(pow(make_vec3f(col), fb->super.invGamma), col.w); } color[pixelID] = col; if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index 9182503928..106395ef6a 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -97,11 +97,10 @@ export void DFB_accumulate(void *uniform _self, final->b[i] = col.z; final->a[i] = col.w; - // XXX hardcoded gamma, should use pixelops! - // TODO use fb->super.invGamma + // NOTE(jda) - no longer hardcoded, but should use pixelops col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), self->super.gamma), col.w); + col = make_vec4f(pow(make_vec3f(col), self->super.invGamma), col.w); color->color[i] = cvt_uint32(col); } @@ -130,11 +129,10 @@ export void DFB_accumulate(void *uniform _self, final->b[i] = col.z; final->a[i] = col.w; - // XXX hardcoded gamma, should use pixelops! - // TODO use fb->super.invGamma + // NOTE(jda) - no longer hardcoded, but should use pixelops col = max(col,make_vec4f(0.f)); // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), self->super.gamma), col.w); + col = make_vec4f(pow(make_vec3f(col), self->super.invGamma), col.w); color->color[i] = cvt_uint32(col); } From 6b171f898f93ed1e86e691decd524bd5530da3ed Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 15 Apr 2016 11:39:29 -0500 Subject: [PATCH 211/310] fix assert logic typo in MPIDevice --- ospray/mpi/MPIDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index 7e7d9abf4c..c44c4cac45 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -511,7 +511,7 @@ namespace ospray { MPI_Status status; int rc = MPI_Recv(&numFails,1,MPI_INT,0,MPI_ANY_TAG,mpi::worker.comm,&status); - Assert(rc != MPI_SUCCESS); + Assert(rc == MPI_SUCCESS); return (numFails == 0); } From f62f9672f6ddfb6646e29f932d3cf437c9d64995 Mon Sep 17 00:00:00 2001 From: atafra Date: Mon, 18 Apr 2016 15:05:10 +0300 Subject: [PATCH 212/310] light function name cleanup --- ospray/lights/HDRILight.ispc | 9 ++++----- ospray/lights/Light.ih | 20 ++++++++++---------- ospray/lights/Light.ispc | 2 +- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index 2f281e43e4..215dae1c97 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -119,7 +119,7 @@ export void HDRILight_set(void *uniform _self, if (map) { self->light2world = light2world; - self->world2light = rcp(light2world); + self->world2light = rcp(light2world); self->map = (uniform Texture2D *uniform)map; self->intensity = intensity; @@ -133,7 +133,7 @@ export void HDRILight_set(void *uniform _self, // for i==0 we have a wrap-around, which is wanted for x (phi), but actually not for y (theta), // because then light (importance) from the south-pole is leaking to the north-pole // however, sin(theta) is zero then, thus we will never sample there - uniform float* uniform importance = uniform new uniform float[width*height]; + uniform float* uniform importance = uniform new uniform float[width*height]; for (uniform int y = 0; y < height; y++) { uniform float fy = y*self->rcpSize.y; uniform float sinTheta = sin(fy * M_PI); @@ -154,7 +154,7 @@ export void HDRILight_set(void *uniform _self, self->super.eval = HDRILight_eval; } else { self->super.sample = HDRILight_sample_dummy; - self->super.eval = defaultEval; + self->super.eval = Light_eval; } } @@ -174,9 +174,8 @@ export void *uniform HDRILight_create() //! Destroy an ispc-side HDRILight object export void HDRILight_destroy(void *uniform _self) -{ +{ uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; Distribution2D_destroy(self->distribution); delete self; } - diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index e44ba7934a..fac1bad1fc 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -31,9 +31,9 @@ struct LightSample //! compute the weighted radiance at a point caused by a sample on the light source // by convention, giving (0, 0) as "random" numbers should sample the "center" // of the light source (used by the raytracing renderers such as the OBJ renderer) -typedef varying LightSample (*Light_SampleFct)(const uniform Light *uniform, - /*! point to generate the sample for >*/ const varying DifferentialGeometry&, - /*! random numbers to generate the sample >*/ const varying vec2f &s); +typedef varying LightSample (*Light_SampleFunc)(const uniform Light *uniform, + /*! point to generate the sample for >*/ const varying DifferentialGeometry&, + /*! random numbers to generate the sample >*/ const varying vec2f &s); struct LightEval @@ -44,21 +44,21 @@ struct LightEval }; //! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction) -typedef varying LightEval (*Light_EvalFct)(const uniform Light *uniform, -/*! point to evaluate illumination for >*/ const varying DifferentialGeometry&, -/*! direction towards the light source >*/ const varying vec3f &dir); +typedef varying LightEval (*Light_EvalFunc)(const uniform Light *uniform, +/*! point to evaluate illumination for >*/ const varying DifferentialGeometry&, +/*! direction towards the light source >*/ const varying vec3f &dir); struct Light { - Light_SampleFct sample; - Light_EvalFct eval; + Light_SampleFunc sample; + Light_EvalFunc eval; }; -varying LightEval defaultEval(const uniform Light *uniform, const varying DifferentialGeometry&, const varying vec3f&); +varying LightEval Light_eval(const uniform Light *uniform, const varying DifferentialGeometry&, const varying vec3f&); inline void Light_Constructor(uniform Light *uniform self) { - self->eval = defaultEval; + self->eval = Light_eval; } diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index 81e5fa7ebd..445e709815 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -16,7 +16,7 @@ #include "Light.ih" -varying LightEval defaultEval(const uniform Light *uniform, +varying LightEval Light_eval(const uniform Light *uniform, const varying DifferentialGeometry&, const varying vec3f &) { From 3f856811777d4e4a06832c6ec3daeb7e9f41d7bb Mon Sep 17 00:00:00 2001 From: atafra Date: Mon, 18 Apr 2016 15:19:33 +0300 Subject: [PATCH 213/310] LightEval struct cleanup --- ospray/lights/AmbientLight.ispc | 2 +- ospray/lights/DirectionalLight.ispc | 6 +++--- ospray/lights/HDRILight.ispc | 2 +- ospray/lights/Light.ih | 2 +- ospray/lights/Light.ispc | 2 +- ospray/lights/PointLight.ispc | 6 +++--- ospray/lights/SpotLight.ispc | 4 ++-- ospray/render/pathtracer/PathTracer.ispc | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 500ca98e73..259701c471 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -51,7 +51,7 @@ varying LightEval AmbientLight_eval(const uniform Light *uniform _self, uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; LightEval res; - res.radiance = self->radiance; + res.value = self->radiance; res.distance = inf; res.pdf = 1.f/(4.f * M_PI); // uniformSampleSpherePDF(); // XXX inconsistent to sample, need surface normal here diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 8f16eb8624..b50bf981f6 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -27,7 +27,7 @@ struct DirectionalLight { float pdf; //!< Probability to sample a direction to the light }; -// for very small cones treat as singular light, because float precision is not good enough +// for very small cones treat as singular light, because float precision is not good enough #define COS_ANGLE_MAX 0.99999988f @@ -62,10 +62,10 @@ varying LightEval DirectionalLight_eval(const uniform Light *uniform _self, res.distance = inf; if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) { - res.radiance = self->radiance * self->pdf; + res.value = self->radiance * self->pdf; res.pdf = self->pdf; } else { - res.radiance = make_vec3f(0.f); + res.value = make_vec3f(0.f); res.pdf = 0.f; } diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index 215dae1c97..47550221df 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -88,7 +88,7 @@ varying LightEval HDRILight_eval(const uniform Light *uniform _self, const float v = acos(localDir.z) * one_over_pi; const vec2f uv = make_vec2f(u, v); - res.radiance = get3f(self->map, uv) * self->intensity; + res.value = get3f(self->map, uv) * self->intensity; res.distance = inf; // domain of Distribution2D is shifted by half a texel compared to texture diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index fac1bad1fc..7b83d29ab8 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -38,7 +38,7 @@ typedef varying LightSample (*Light_SampleFunc)(const uniform Light *uniform, struct LightEval { - vec3f radiance; //!< radiance that arrives at the given point (not weighted by pdf) + vec3f value; //!< radiance that arrives at the given point (not weighted by pdf) float distance; float pdf; //!< probability density that the direction would have been sampled }; diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index 445e709815..a966c078a6 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -21,7 +21,7 @@ varying LightEval Light_eval(const uniform Light *uniform, const varying vec3f &) { LightEval res; - res.radiance = make_vec3f(0.f); + res.value = make_vec3f(0.f); res.distance = inf; res.pdf = 0.f; return res; diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index af210c8f0e..827f1326ed 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -54,7 +54,7 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, if (self->radius > 0.f & sinTheta > 0.005f) { // sample surface of sphere as seen by hit point -> cone of directions - // for very small cones treat as point light, because float precision is not good enough + // for very small cones treat as point light, because float precision is not good enough if (sinTheta < 1.f) { const float cosTheta = sqrt(1.f - sinTheta * sinTheta); const vec3f localDir = uniformSampleCone(cosTheta, s); @@ -82,7 +82,7 @@ varying LightEval PointLight_eval(const uniform Light *uniform _self, { const PointLight *uniform self = (PointLight *uniform)_self; LightEval res; - res.radiance = make_vec3f(0.f); + res.value = make_vec3f(0.f); res.distance = inf; res.pdf = 0.f; @@ -105,7 +105,7 @@ varying LightEval PointLight_eval(const uniform Light *uniform _self, const float cosTheta = sqrt(1.f - sinTheta2); res.pdf = uniformSampleConePDF(cosTheta); const float invdist = rcp(t_near); - res.radiance = self->power * res.pdf * sqr(invdist); + res.value = self->power * res.pdf * sqr(invdist); } } } diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index fdaf0a9648..1117211cfd 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -75,7 +75,7 @@ varying LightEval SpotLight_eval(const uniform Light *uniform _self, { const SpotLight *uniform self = (SpotLight *uniform)_self; LightEval res; - res.radiance = make_vec3f(0.f); + res.value = make_vec3f(0.f); res.distance = inf; res.pdf = 0.f; @@ -91,7 +91,7 @@ varying LightEval SpotLight_eval(const uniform Light *uniform _self, if (dot(vd, vd) < sqr(self->radius)) { // inside disk? const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f); const float pdf = self->diskPdf * cosAngle; - res.radiance = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels + res.value = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels res.distance = t; res.pdf = pdf * sqr(t); } diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index c66d7ea5a4..e7770b38b2 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -129,7 +129,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, if ((bool)self->backplate & straightPath) { L = L + Lw * get3f(self->backplate, clamp2edge(self->backplate, pixel)); maxLightDist = 1e38; // backplate hides envLights (i.e. the ones in infinity) - } + } } // add light from virtual lights by intersecting them @@ -137,7 +137,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, const uniform Light *uniform l = self->lights[i]; LightEval le = l->eval(l, dg, ray.dir); if (le.distance <= maxLightDist) - L = L + Lw * le.radiance * misHeuristic(lastBSDFPdf, le.pdf); + L = L + Lw * le.value * misHeuristic(lastBSDFPdf, le.pdf); } if (noHit(ray)) From 41e805043757d25fbc68cf7e74caa3dbbd57d227 Mon Sep 17 00:00:00 2001 From: atafra Date: Mon, 18 Apr 2016 16:18:42 +0300 Subject: [PATCH 214/310] light cleanup --- ospray/lights/AmbientLight.ispc | 47 +++++------ ospray/lights/DirectionalLight.ispc | 49 +++++------ ospray/lights/HDRILight.ispc | 62 +++++++------- ospray/lights/Light.ih | 30 +++---- ospray/lights/Light.ispc | 8 +- ospray/lights/PointLight.ispc | 67 +++++++-------- ospray/lights/QuadLight.ispc | 51 ++++++------ ospray/lights/SpotLight.ispc | 81 ++++++++++--------- ospray/render/obj/OBJRenderer.ispc | 14 ++-- ospray/render/pathtracer/PathTracer.ispc | 13 ++- ospray/render/scivis/SciVisRenderer.ispc | 12 +-- .../render/volume/RaycastVolumeRenderer.ispc | 8 +- 12 files changed, 223 insertions(+), 219 deletions(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 259701c471..e49275b3c2 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -18,7 +18,8 @@ #include "ospray/math/sampling.ih" #include "ospray/math/LinearSpace.ih" -struct AmbientLight { +struct AmbientLight +{ Light super; //!< inherited light fields vec3f radiance; //!< RGB color and intensity of light @@ -28,39 +29,39 @@ struct AmbientLight { // Implementation ////////////////////////////////////////////////////////////////////////////// -varying LightSample AmbientLight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec2f &s) +varying Light_SampleRes AmbientLight_sample(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec2f& s) { - uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; - LightSample sample; + uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super; + Light_SampleRes res; const vec3f localDir = cosineSampleHemisphere(s); - sample.direction = frame(dg.Ns) * localDir; - sample.pdf = cosineSampleHemispherePDF(localDir); - sample.distance = inf; - sample.weight = self->radiance * rcp(sample.pdf); + res.dir = frame(dg.Ns) * localDir; + res.pdf = cosineSampleHemispherePDF(localDir); + res.dist = inf; + res.weight = self->radiance * rcp(res.pdf); - return sample; + return res; } -varying LightEval AmbientLight_eval(const uniform Light *uniform _self, - const varying DifferentialGeometry &, - const varying vec3f &) +varying Light_EvalRes AmbientLight_eval(const uniform Light* uniform super, + const varying DifferentialGeometry&, + const varying vec3f&) { - uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; - LightEval res; + uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super; + Light_EvalRes res; res.value = self->radiance; - res.distance = inf; + res.dist = inf; res.pdf = 1.f/(4.f * M_PI); // uniformSampleSpherePDF(); // XXX inconsistent to sample, need surface normal here return res; } -void AmbientLight_Constructor(uniform AmbientLight *uniform self, - const uniform vec3f &radiance) +void AmbientLight_Constructor(uniform AmbientLight* uniform self, + const uniform vec3f& radiance) { Light_Constructor(&self->super); self->radiance = radiance; @@ -75,15 +76,15 @@ void AmbientLight_Constructor(uniform AmbientLight *uniform self, //! Create an ispc-side AmbientLight object export void *uniform AmbientLight_create() { - uniform AmbientLight *uniform self = uniform new uniform AmbientLight; + uniform AmbientLight* uniform self = uniform new uniform AmbientLight; AmbientLight_Constructor(self, make_vec3f(1.f)); return self; } //! Set the parameters of an ispc-side AmbientLight object -export void AmbientLight_set(void *uniform _self, - const uniform vec3f &radiance) +export void AmbientLight_set(void* uniform super, + const uniform vec3f& radiance) { - uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; + uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super; self->radiance = radiance; } diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index b50bf981f6..59d68dd2a8 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -18,7 +18,8 @@ #include "ospray/math/sampling.ih" #include "ospray/math/LinearSpace.ih" -struct DirectionalLight { +struct DirectionalLight +{ Light super; //!< inherited light fields linear3f frame; //!< coordinate frame, with vz == direction *towards* the light source @@ -34,32 +35,32 @@ struct DirectionalLight { // Implementation ////////////////////////////////////////////////////////////////////////////// -varying LightSample DirectionalLight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec2f &s) +varying Light_SampleRes DirectionalLight_sample(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec2f& s) { - const DirectionalLight *uniform self = (DirectionalLight *uniform)_self; - LightSample sample; + const DirectionalLight* uniform self = (DirectionalLight* uniform)super; + Light_SampleRes res; - sample.direction = self->frame.vz; - sample.distance = inf; - sample.pdf = self->pdf; + res.dir = self->frame.vz; + res.dist = inf; + res.pdf = self->pdf; if (self->cosAngle < COS_ANGLE_MAX) - sample.direction = self->frame * uniformSampleCone(self->cosAngle, s); + res.dir = self->frame * uniformSampleCone(self->cosAngle, s); - sample.weight = self->radiance; // *pdf/pdf cancel + res.weight = self->radiance; // *pdf/pdf cancel - return sample; + return res; } -varying LightEval DirectionalLight_eval(const uniform Light *uniform _self, - const varying DifferentialGeometry &, - const varying vec3f &dir) +varying Light_EvalRes DirectionalLight_eval(const uniform Light* uniform super, + const varying DifferentialGeometry&, + const varying vec3f& dir) { - uniform DirectionalLight *uniform self = (uniform DirectionalLight *uniform)_self; - LightEval res; - res.distance = inf; + uniform DirectionalLight* uniform self = (uniform DirectionalLight* uniform)super; + Light_EvalRes res; + res.dist = inf; if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) { res.value = self->radiance * self->pdf; @@ -77,12 +78,12 @@ varying LightEval DirectionalLight_eval(const uniform Light *uniform _self, ////////////////////////////////////////////////////////////////////////////// //! Set the parameters of an ispc-side DirectionalLight object -export void DirectionalLight_set(void *uniform _self, - const uniform vec3f &direction, - const uniform vec3f &radiance, - const uniform float cosAngle) +export void DirectionalLight_set(void* uniform super, + const uniform vec3f& direction, + const uniform vec3f& radiance, + uniform float cosAngle) { - uniform DirectionalLight *uniform self = (uniform DirectionalLight *uniform)_self; + uniform DirectionalLight* uniform self = (uniform DirectionalLight* uniform)super; self->frame = frame(direction); self->radiance = radiance; self->cosAngle = cosAngle; @@ -92,7 +93,7 @@ export void DirectionalLight_set(void *uniform _self, //! Create an ispc-side DirectionalLight object export void *uniform DirectionalLight_create() { - uniform DirectionalLight *uniform self = uniform new uniform DirectionalLight; + uniform DirectionalLight* uniform self = uniform new uniform DirectionalLight; Light_Constructor(&self->super); self->super.sample = DirectionalLight_sample; self->super.eval = DirectionalLight_eval; diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index 47550221df..b0a7290561 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -37,21 +37,21 @@ struct HDRILight ////////////////////////////////////////////////////////////////////////////// // sample function used when no environment map is given: black -varying LightSample HDRILight_sample_dummy(const uniform Light *uniform, - const varying DifferentialGeometry &, - const varying vec2f &) +varying Light_SampleRes HDRILight_sample_dummy(const uniform Light* uniform, + const varying DifferentialGeometry&, + const varying vec2f&) { - LightSample sample; - memset(&sample, 0, sizeof(LightSample)); - return sample; + Light_SampleRes res; + memset(&res, 0, sizeof(Light_SampleRes)); + return res; } -varying LightSample HDRILight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &, - const varying vec2f &s) +varying Light_SampleRes HDRILight_sample(const uniform Light* uniform super, + const varying DifferentialGeometry&, + const varying vec2f& s) { - uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; - LightSample sample; + uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; + Light_SampleRes res; Sample2D sample2d = Distribution2D_sample(self->distribution, s); // Distribution2D samples within bin i as (i, i+1), whereas we provided @@ -65,22 +65,22 @@ varying LightSample HDRILight_sample(const uniform Light *uniform _self, sincos(theta, &sinTheta, &cosTheta); const vec3f localDir = cartesian(phi, sinTheta, cosTheta); - sample.direction = self->light2world * localDir; + res.dir = self->light2world * localDir; - sample.pdf = sample2d.pdf * one_over_two_pi_sqr * rcp(sinTheta); + res.pdf = sample2d.pdf * one_over_two_pi_sqr * rcp(sinTheta); - sample.distance = inf; - sample.weight = get3f(self->map, sample2d.uv) * self->intensity / sample.pdf; + res.dist = inf; + res.weight = get3f(self->map, sample2d.uv) * self->intensity / res.pdf; - return sample; + return res; } -varying LightEval HDRILight_eval(const uniform Light *uniform _self, - const varying DifferentialGeometry &, - const varying vec3f &dir) +varying Light_EvalRes HDRILight_eval(const uniform Light* uniform super, + const varying DifferentialGeometry&, + const varying vec3f& dir) { - uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; - LightEval res; + uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; + Light_EvalRes res; const vec3f localDir = self->world2light * dir; @@ -89,7 +89,7 @@ varying LightEval HDRILight_eval(const uniform Light *uniform _self, const vec2f uv = make_vec2f(u, v); res.value = get3f(self->map, uv) * self->intensity; - res.distance = inf; + res.dist = inf; // domain of Distribution2D is shifted by half a texel compared to texture // atan2 can get negative, shift can lead to values > 1.f: reproject to [0..1) @@ -105,12 +105,12 @@ varying LightEval HDRILight_eval(const uniform Light *uniform _self, ////////////////////////////////////////////////////////////////////////////// //! Set the parameters of an ispc-side HDRILight object -export void HDRILight_set(void *uniform _self, - const uniform linear3f &light2world, - void *uniform map, - const uniform float intensity) +export void HDRILight_set(void* uniform super, + const uniform linear3f& light2world, + void* uniform map, + uniform float intensity) { - uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; + uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; if (self->distribution != NULL) { Distribution2D_destroy(self->distribution); @@ -121,7 +121,7 @@ export void HDRILight_set(void *uniform _self, self->light2world = light2world; self->world2light = rcp(light2world); - self->map = (uniform Texture2D *uniform)map; + self->map = (uniform Texture2D* uniform)map; self->intensity = intensity; self->rcpSize = 1.f/self->map->sizef; @@ -161,7 +161,7 @@ export void HDRILight_set(void *uniform _self, //! Create an ispc-side HDRILight object export void *uniform HDRILight_create() { - uniform HDRILight *uniform self = uniform new uniform HDRILight; + uniform HDRILight* uniform self = uniform new uniform HDRILight; Light_Constructor(&self->super); self->super.sample = HDRILight_sample_dummy; @@ -173,9 +173,9 @@ export void *uniform HDRILight_create() } //! Destroy an ispc-side HDRILight object -export void HDRILight_destroy(void *uniform _self) +export void HDRILight_destroy(void* uniform super) { - uniform HDRILight *uniform self = (uniform HDRILight *uniform)_self; + uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; Distribution2D_destroy(self->distribution); delete self; } diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index 7b83d29ab8..0005d32722 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -20,33 +20,33 @@ struct Light; -struct LightSample +struct Light_SampleRes { - vec3f weight; //!< radiance that arrives at the given point divided by pdf - vec3f direction; //!< direction towards the light source - float distance; //!< largest valid t_far value for a shadow ray - float pdf; //!< probability density that this sample was taken + vec3f weight; //!< radiance that arrives at the given point divided by pdf + vec3f dir; //!< direction towards the light source + float dist; //!< largest valid t_far value for a shadow ray + float pdf; //!< probability density that this sample was taken }; //! compute the weighted radiance at a point caused by a sample on the light source // by convention, giving (0, 0) as "random" numbers should sample the "center" // of the light source (used by the raytracing renderers such as the OBJ renderer) -typedef varying LightSample (*Light_SampleFunc)(const uniform Light *uniform, - /*! point to generate the sample for >*/ const varying DifferentialGeometry&, - /*! random numbers to generate the sample >*/ const varying vec2f &s); +typedef varying Light_SampleRes (*Light_SampleFunc)(const uniform Light* uniform self, + /*! point to generate the sample for >*/ const varying DifferentialGeometry& dg, + /*! random numbers to generate the sample >*/ const varying vec2f& s); -struct LightEval +struct Light_EvalRes { vec3f value; //!< radiance that arrives at the given point (not weighted by pdf) - float distance; + float dist; float pdf; //!< probability density that the direction would have been sampled }; //! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction) -typedef varying LightEval (*Light_EvalFunc)(const uniform Light *uniform, -/*! point to evaluate illumination for >*/ const varying DifferentialGeometry&, -/*! direction towards the light source >*/ const varying vec3f &dir); +typedef varying Light_EvalRes (*Light_EvalFunc)(const uniform Light* uniform self, +/*! point to evaluate illumination for >*/ const varying DifferentialGeometry& dg, +/*! direction towards the light source >*/ const varying vec3f& dir); struct Light @@ -56,9 +56,9 @@ struct Light }; -varying LightEval Light_eval(const uniform Light *uniform, const varying DifferentialGeometry&, const varying vec3f&); +varying Light_EvalRes Light_eval(const uniform Light* uniform self, const varying DifferentialGeometry& dg, const varying vec3f& dir); -inline void Light_Constructor(uniform Light *uniform self) +inline void Light_Constructor(uniform Light* uniform self) { self->eval = Light_eval; } diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index a966c078a6..a1f936d2b8 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -16,13 +16,13 @@ #include "Light.ih" -varying LightEval Light_eval(const uniform Light *uniform, +varying Light_EvalRes Light_eval(const uniform Light* uniform, const varying DifferentialGeometry&, - const varying vec3f &) + const varying vec3f&) { - LightEval res; + Light_EvalRes res; res.value = make_vec3f(0.f); - res.distance = inf; + res.dist = inf; res.pdf = 0.f; return res; } diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 827f1326ed..4c81bc284b 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -18,7 +18,8 @@ #include "ospray/math/sampling.ih" #include "ospray/math/LinearSpace.ih" -struct PointLight { +struct PointLight +{ Light super; //!< inherited light fields vec3f position; //!< light position @@ -30,12 +31,12 @@ struct PointLight { // Implementation ////////////////////////////////////////////////////////////////////////////// -varying LightSample PointLight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec2f &s) +varying Light_SampleRes PointLight_sample(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec2f& s) { - const PointLight *uniform self = (PointLight *uniform)_self; - LightSample sample; + const PointLight* uniform self = (PointLight* uniform)super; + Light_SampleRes res; // extant light vector from the hit point const vec3f dir = self->position - dg.P; @@ -43,47 +44,47 @@ varying LightSample PointLight_sample(const uniform Light *uniform _self, const float invdist = rsqrt(dist2); // normalized light vector - sample.direction = dir * invdist; - sample.distance = dist2 * invdist; + res.dir = dir * invdist; + res.dist = dist2 * invdist; - sample.pdf = inf; // per default we always take this sample + res.pdf = inf; // per default we always take this res // convert from power to radiance by attenuating by distance^2 - sample.weight = self->power * sqr(invdist); + res.weight = self->power * sqr(invdist); const float sinTheta = self->radius * invdist; if (self->radius > 0.f & sinTheta > 0.005f) { - // sample surface of sphere as seen by hit point -> cone of directions + // res surface of sphere as seen by hit point -> cone of directions // for very small cones treat as point light, because float precision is not good enough if (sinTheta < 1.f) { const float cosTheta = sqrt(1.f - sinTheta * sinTheta); const vec3f localDir = uniformSampleCone(cosTheta, s); - sample.direction = frame(sample.direction) * localDir; - sample.pdf = uniformSampleConePDF(cosTheta); + res.dir = frame(res.dir) * localDir; + res.pdf = uniformSampleConePDF(cosTheta); const float c = localDir.z; - sample.distance = c*sample.distance - sqrt(sqr(self->radius) - (1.f - c*c) * dist2); + res.dist = c*res.dist - sqrt(sqr(self->radius) - (1.f - c*c) * dist2); // TODO scale radiance by actual distance } else { // inside sphere const vec3f localDir = cosineSampleHemisphere(s); - sample.direction = frame(dg.Ns) * localDir; - sample.pdf = cosineSampleHemispherePDF(localDir); + res.dir = frame(dg.Ns) * localDir; + res.pdf = cosineSampleHemispherePDF(localDir); // TODO: - sample.weight = self->power * rcp(sqr(self->radius)); - sample.distance = self->radius; + res.weight = self->power * rcp(sqr(self->radius)); + res.dist = self->radius; } } - return sample; + return res; } -varying LightEval PointLight_eval(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec3f &dir) +varying Light_EvalRes PointLight_eval(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec3f& dir) { - const PointLight *uniform self = (PointLight *uniform)_self; - LightEval res; + const PointLight* uniform self = (PointLight* uniform)super; + Light_EvalRes res; res.value = make_vec3f(0.f); - res.distance = inf; + res.dist = inf; res.pdf = 0.f; if (self->radius > 0.f) { @@ -100,7 +101,7 @@ varying LightEval PointLight_eval(const uniform Light *uniform _self, if (t_far > 0.0f) { // TODO: handle interior case - res.distance = t_near; + res.dist = t_near; const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); const float cosTheta = sqrt(1.f - sinTheta2); res.pdf = uniformSampleConePDF(cosTheta); @@ -117,21 +118,21 @@ varying LightEval PointLight_eval(const uniform Light *uniform _self, ////////////////////////////////////////////////////////////////////////////// //! Set the parameters of an ispc-side PointLight object -export void PointLight_set(void *uniform _self, - const uniform vec3f &position, - const uniform vec3f &power, - const uniform float radius) +export void PointLight_set(void* uniform super, + const uniform vec3f& position, + const uniform vec3f& power, + uniform float radius) { - uniform PointLight *uniform self = (uniform PointLight *uniform)_self; + uniform PointLight* uniform self = (uniform PointLight* uniform)super; self->position = position; self->power = power; self->radius = radius; } //! Create an ispc-side PointLight object -export void *uniform PointLight_create() +export void* uniform PointLight_create() { - uniform PointLight *uniform self = uniform new uniform PointLight; + uniform PointLight* uniform self = uniform new uniform PointLight; Light_Constructor(&self->super); self->super.sample = PointLight_sample; self->super.eval = PointLight_eval; diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index 2b2e0d4dfc..b0ae61a8db 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -16,7 +16,8 @@ #include "Light.ih" -struct QuadLight { +struct QuadLight +{ Light super; //!< inherited light fields vec3f position; //!< world-space corner position of the light @@ -32,14 +33,14 @@ struct QuadLight { // Implementation ////////////////////////////////////////////////////////////////////////////// -varying LightSample QuadLight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec2f &s) +varying Light_SampleRes QuadLight_sample(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec2f& s) { - const QuadLight *uniform self = (QuadLight *uniform)_self; - LightSample sample; + const QuadLight* uniform self = (QuadLight* uniform)super; + Light_SampleRes res; - // sample position on light with density ppdf = 1/area + // res position on light with density ppdf = 1/area // TODO: use solid angle sampling const vec3f pos = self->position + self->edge1 * s.x + self->edge2 * s.y; @@ -48,17 +49,17 @@ varying LightSample QuadLight_sample(const uniform Light *uniform _self, const float dist = length(dir); // normalized light vector - sample.direction = dir / dist; - sample.distance = dist; + res.dir = dir / dist; + res.dist = dist; // convert to pdf wrt. solid angle - const float cosd = dot(self->nnormal, sample.direction); - sample.pdf = self->ppdf * (dist * dist) / abs(cosd); + const float cosd = dot(self->nnormal, res.dir); + res.pdf = self->ppdf * (dist * dist) / abs(cosd); // emit only to one side - sample.weight = cosd > 0.f ? self->radiance * rcp(sample.pdf) : make_vec3f(0.f); + res.weight = cosd > 0.f ? self->radiance * rcp(res.pdf) : make_vec3f(0.f); - return sample; + return res; } @@ -66,17 +67,17 @@ varying LightSample QuadLight_sample(const uniform Light *uniform _self, ////////////////////////////////////////////////////////////////////////////// //! Set the parameters of an ispc-side QuadLight object -export void QuadLight_set(void *uniform _self, - const uniform vec3f &position, - const uniform vec3f &edge2, - const uniform vec3f &edge1, - const uniform vec3f &radiance) +export void QuadLight_set(void* uniform super, + const uniform vec3f& position, + const uniform vec3f& edge2, + const uniform vec3f& edge1, + const uniform vec3f& radiance) { - uniform QuadLight *uniform self = (uniform QuadLight *uniform)_self; - self->position = position; - self->edge1 = edge1; - self->edge2 = edge2; - self->radiance = radiance; + uniform QuadLight* uniform self = (uniform QuadLight* uniform)super; + self->position = position; + self->edge1 = edge1; + self->edge2 = edge2; + self->radiance = radiance; const uniform vec3f ndirection = cross(edge2, edge1); self->ppdf = rcp(length(ndirection)); @@ -84,9 +85,9 @@ export void QuadLight_set(void *uniform _self, } //! Create an ispc-side QuadLight object -export void *uniform QuadLight_create() +export void* uniform QuadLight_create() { - uniform QuadLight *uniform self = uniform new uniform QuadLight; + uniform QuadLight* uniform self = uniform new uniform QuadLight; Light_Constructor(&self->super); self->super.sample = QuadLight_sample; diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 1117211cfd..535f8bd3ce 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -18,7 +18,8 @@ #include "ospray/math/sampling.ih" #include "ospray/math/LinearSpace.ih" -struct SpotLight { +struct SpotLight +{ Light super; //!< inherited light fields vec3f position; //!< Position of the SpotLight @@ -34,49 +35,49 @@ struct SpotLight { // Implementation ////////////////////////////////////////////////////////////////////////////// -varying LightSample SpotLight_sample(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec2f &s) +varying Light_SampleRes SpotLight_sample(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec2f& s) { - const SpotLight *uniform self = (SpotLight *uniform)_self; - LightSample sample; + const SpotLight* uniform self = (SpotLight* uniform)super; + Light_SampleRes res; // extant light vector from the hit point - sample.direction = self->position - dg.P; + res.dir = self->position - dg.P; if (self->radius > 0.) - sample.direction = self->frame * uniformSampleDisk(self->radius, s) + sample.direction; + res.dir = self->frame * uniformSampleDisk(self->radius, s) + res.dir; - const float dist2 = dot(sample.direction, sample.direction); + const float dist2 = dot(res.dir, res.dir); const float invdist = rsqrt(dist2); // normalized light vector - sample.direction = sample.direction * invdist; - sample.distance = dist2 * invdist; + res.dir = res.dir * invdist; + res.dist = dist2 * invdist; // cosine of the negated light direction and light vector. - const float cosAngle = -dot(self->frame.vz, sample.direction); + const float cosAngle = -dot(self->frame.vz, res.dir); const float angularAttenuation = clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale); if (self->radius > 0.) - sample.pdf = self->diskPdf * dist2 * abs(cosAngle); + res.pdf = self->diskPdf * dist2 * abs(cosAngle); else - sample.pdf = inf; // we always take this sample + res.pdf = inf; // we always take this res // convert from power to radiance by attenuating by distance^2; attenuate by angle - sample.weight = self->power * (sqr(invdist) * angularAttenuation); + res.weight = self->power * (sqr(invdist) * angularAttenuation); - return sample; + return res; } -varying LightEval SpotLight_eval(const uniform Light *uniform _self, - const varying DifferentialGeometry &dg, - const varying vec3f &dir) +varying Light_EvalRes SpotLight_eval(const uniform Light* uniform super, + const varying DifferentialGeometry& dg, + const varying vec3f& dir) { - const SpotLight *uniform self = (SpotLight *uniform)_self; - LightEval res; + const SpotLight* uniform self = (SpotLight* uniform)super; + Light_EvalRes res; res.value = make_vec3f(0.f); - res.distance = inf; + res.dist = inf; res.pdf = 0.f; if (self->radius > 0.f) { @@ -92,7 +93,7 @@ varying LightEval SpotLight_eval(const uniform Light *uniform _self, const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f); const float pdf = self->diskPdf * cosAngle; res.value = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels - res.distance = t; + res.dist = t; res.pdf = pdf * sqr(t); } } @@ -107,28 +108,28 @@ varying LightEval SpotLight_eval(const uniform Light *uniform _self, ////////////////////////////////////////////////////////////////////////////// //! Set the parameters of an ispc-side SpotLight object -export void SpotLight_set(void *uniform _self, - const uniform vec3f &position, - const uniform vec3f &direction, - const uniform vec3f &power, - const uniform float cosAngleMax, - const uniform float cosAngleScale, - const uniform float radius) +export void SpotLight_set(void* uniform super, + const uniform vec3f& position, + const uniform vec3f& direction, + const uniform vec3f& power, + uniform float cosAngleMax, + uniform float cosAngleScale, + uniform float radius) { - uniform SpotLight *uniform self = (uniform SpotLight *uniform)_self; - self->position = position; - self->frame = frame(direction); - self->power = power; - self->cosAngleMax = cosAngleMax; - self->cosAngleScale= cosAngleScale; - self->radius = radius; - self->diskPdf = uniformSampleDiskPDF(radius); + uniform SpotLight* uniform self = (uniform SpotLight* uniform)super; + self->position = position; + self->frame = frame(direction); + self->power = power; + self->cosAngleMax = cosAngleMax; + self->cosAngleScale = cosAngleScale; + self->radius = radius; + self->diskPdf = uniformSampleDiskPDF(radius); } //! Create an ispc-side SpotLight object -export void *uniform SpotLight_create() +export void* uniform SpotLight_create() { - uniform SpotLight *uniform self = uniform new uniform SpotLight; + uniform SpotLight* uniform self = uniform new uniform SpotLight; Light_Constructor(&self->super); self->super.sample = SpotLight_sample; diff --git a/ospray/render/obj/OBJRenderer.ispc b/ospray/render/obj/OBJRenderer.ispc index f09b5f8dbf..f3362ade3c 100644 --- a/ospray/render/obj/OBJRenderer.ispc +++ b/ospray/render/obj/OBJRenderer.ispc @@ -14,7 +14,7 @@ // limitations under the License. // // ======================================================================== // -// ospray +// ospray #include "ospray/fb/FrameBuffer.ih" #include "ospray/render/util.ih" #include "ospray/common/Model.ih" @@ -82,7 +82,7 @@ inline float lightAlpha(Ray &ray, uniform Model *uniform model, const float weig } inline void OBJRenderer_shadeRay(const uniform OBJRenderer *uniform self, varying ScreenSample &sample) -{ +{ Ray &ray = sample.ray; // ISPC issue #703. Switch to 'nice' code once ISPC #703 is fixed. // print("ray.dir % % %\n",ray.dir.x,ray.dir.y,ray.dir.z); @@ -166,22 +166,22 @@ inline void OBJRenderer_shadeRay(const uniform OBJRenderer *uniform self, varyin for (uniform int i = 0; self->lights && i < self->numLights; i++) { const uniform Light *uniform l = self->lights[i]; const vec2f s = make_vec2f(0.f); - const LightSample light = l->sample(l, dg, s); + const Light_SampleRes light = l->sample(l, dg, s); if (reduce_max(light.weight) > 0.f) { // any potential contribution? - const float cosNL = abs(dot(light.direction, dg.Ns)); - const float cosLR = max(0.f, dot(light.direction, R)); + const float cosNL = abs(dot(light.dir, dg.Ns)); + const float cosLR = max(0.f, dot(light.dir, R)); const vec3f unshaded_light_contrib = local_opacity * (Kd * cosNL + Ks * powf(cosLR, Ns)) * light.weight; if (self->shadowsEnabled) { const float max_contrib = reduce_max(unshaded_light_contrib); if (max_contrib > .01f) { Ray shadowRay; - setRay(shadowRay, P, light.direction); + setRay(shadowRay, P, light.dir); const float light_alpha = lightAlpha(shadowRay, self->super.model, max_contrib, self->super.epsilon); local_shade_color = local_shade_color + light_alpha * unshaded_light_contrib; } - } else + } else local_shade_color = local_shade_color + unshaded_light_contrib; } } diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index e7770b38b2..12b92c0ba3 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -135,8 +135,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, // add light from virtual lights by intersecting them for (uniform int i = 0; i < self->numLights; i++) { const uniform Light *uniform l = self->lights[i]; - LightEval le = l->eval(l, dg, ray.dir); - if (le.distance <= maxLightDist) + Light_EvalRes le = l->eval(l, dg, ray.dir); + if (le.dist <= maxLightDist) L = L + Lw * le.value * misHeuristic(lastBSDFPdf, le.pdf); } @@ -193,7 +193,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, { const uniform Light *uniform light = self->lights[i]; - LightSample ls = light->sample(light, dg, RandomTEA__getFloats(rng)); + Light_SampleRes ls = light->sample(light, dg, RandomTEA__getFloats(rng)); // skip when zero contribution from light if (reduce_max(ls.weight) <= 0.0f | ls.pdf <= PDF_CULLING) @@ -204,7 +204,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, float bsdfPdf = 0.f; foreach_unique(b in bsdf) if (b != NULL) - bsdfValue = b->eval(b, wo, ls.direction, bsdfPdf); + bsdfValue = b->eval(b, wo, ls.dir, bsdfPdf); #ifdef USE_DGCOLOR bsdfValue = bsdfValue * make_vec3f(dg.color); @@ -215,9 +215,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, // test for shadows Ray shadow_ray; - setRay(shadow_ray, dg.P, ls.direction, - self->super.epsilon, ls.distance- - self->super.epsilon); + setRay(shadow_ray, dg.P, ls.dir, + self->super.epsilon, ls.dist - self->super.epsilon); shadow_ray.time = ray.time; vec3f unshaded_light_contrib = Lw * ls.weight * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 6dffb02235..fbe7fda9c6 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -233,11 +233,11 @@ inline void shadeLights(const uniform SciVisRenderer *uniform self, for (uniform int i = 0; self->lights && i < self->numLights; i++) { const uniform Light *uniform l = self->lights[i]; const vec2f s = make_vec2f(0.5f); - const LightSample light = l->sample(l, dg, s); + const Light_SampleRes light = l->sample(l, dg, s); if (reduce_max(light.weight) > 0.f) { // any potential contribution? - const float cosNL = abs(dot(light.direction, dg.Ns)); - const float cosLR = max(0.f, dot(light.direction, R)); + const float cosNL = abs(dot(light.dir, dg.Ns)); + const float cosLR = max(0.f, dot(light.dir, R)); const vec3f brdf = info.Kd * cosNL + info.Ks * powf(cosLR, info.Ns); const vec3f light_contrib = info.local_opacity * brdf * light.weight; @@ -246,7 +246,7 @@ inline void shadeLights(const uniform SciVisRenderer *uniform self, const float max_contrib = reduce_max(light_contrib); if (max_contrib > .01f) { Ray shadowRay; - setRay(shadowRay, P, light.direction); + setRay(shadowRay, P, light.dir); const float light_alpha = lightAlpha(shadowRay, self->super.model, max_contrib, @@ -294,11 +294,11 @@ inline void SciVisRenderer_computeVolumeSample(SciVisRenderer *uniform renderer, const vec2f s = make_vec2f(0.5f); for (uniform uint32 i=0; inumLights; i++) { - const LightSample light = renderer->lights[i]->sample(renderer->lights[i], dg, s); + const Light_SampleRes light = renderer->lights[i]->sample(renderer->lights[i], dg, s); const float cosNL = (gradient.x == 0.f && gradient.y == 0.f && gradient.z == 0.f) ? - 1.f : abs(dot(safe_normalize(light.direction), + 1.f : abs(dot(safe_normalize(light.dir), gradient)); shadedColor = shadedColor + sampleColor * cosNL * light.weight; diff --git a/ospray/render/volume/RaycastVolumeRenderer.ispc b/ospray/render/volume/RaycastVolumeRenderer.ispc index 600b042a84..3512c2e4e5 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.ispc +++ b/ospray/render/volume/RaycastVolumeRenderer.ispc @@ -64,9 +64,9 @@ inline void RaycastVolumeRenderer_computeVolumeSample(RaycastVolumeRenderer *uni const vec2f s = make_vec2f(0.5f); for (uniform uint32 i=0; inumLights; i++) { - const LightSample light = self->lights[i]->sample(self->lights[i], dg, s); + const Light_SampleRes light = self->lights[i]->sample(self->lights[i], dg, s); const float cosNL = (gradient.x == 0.f && gradient.y == 0.f && gradient.z == 0.f) ? - 1.f : abs(dot(safe_normalize(light.direction), gradient)); + 1.f : abs(dot(safe_normalize(light.dir), gradient)); shadedColor = shadedColor + sampleColor * cosNL * light.weight; } @@ -145,8 +145,8 @@ inline void RaycastVolumeRenderer_computeGeometrySample(RaycastVolumeRenderer *u const vec2f s = make_vec2f(0.5f); for (uniform uint32 i=0; inumLights; i++) { - const LightSample light = self->lights[i]->sample(self->lights[i], dg, s); - const float cosNL = abs(dot(safe_normalize(light.direction), dg.Ns)); + const Light_SampleRes light = self->lights[i]->sample(self->lights[i], dg, s); + const float cosNL = abs(dot(safe_normalize(light.dir), dg.Ns)); shadedColor = shadedColor + geometryColor * cosNL * light.weight; } From 815f61462848638943187b0dfd2bb1a685e5607e Mon Sep 17 00:00:00 2001 From: atafra Date: Mon, 18 Apr 2016 16:36:23 +0300 Subject: [PATCH 215/310] BSDF cleanup --- ospray/render/pathtracer/bsdfs/BSDF.ih | 8 ++++---- ospray/render/pathtracer/bsdfs/Conductor.ih | 2 +- ospray/render/pathtracer/bsdfs/Dielectric.ih | 2 +- ospray/render/pathtracer/bsdfs/DielectricLayer.ih | 2 +- ospray/render/pathtracer/bsdfs/Lambert.ih | 2 +- ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih | 2 +- .../render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih | 2 +- ospray/render/pathtracer/bsdfs/Minneart.ih | 2 +- ospray/render/pathtracer/bsdfs/MultiBSDF.ih | 2 +- ospray/render/pathtracer/bsdfs/Reflection.ih | 2 +- ospray/render/pathtracer/bsdfs/Specular.ih | 2 +- ospray/render/pathtracer/bsdfs/ThinDielectric.ih | 2 +- ospray/render/pathtracer/bsdfs/Transmission.ih | 2 +- ospray/render/pathtracer/bsdfs/Velvety.ih | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ospray/render/pathtracer/bsdfs/BSDF.ih b/ospray/render/pathtracer/bsdfs/BSDF.ih index fc842b2988..95904703a8 100644 --- a/ospray/render/pathtracer/bsdfs/BSDF.ih +++ b/ospray/render/pathtracer/bsdfs/BSDF.ih @@ -53,7 +53,7 @@ struct BSDF; -typedef uint32 BSDFType; +typedef uint32 BSDF_Type; /*! Result is multiplied by dot(wi,N). */ typedef vec3f (*BSDF_EvalFunc)(const varying BSDF* uniform super, @@ -61,19 +61,19 @@ typedef vec3f (*BSDF_EvalFunc)(const varying BSDF* uniform super, /*! Result is multiplied by dot(wi,N)/pdf. */ typedef vec3f (*BSDF_SampleFunc)(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss); struct BSDF { - uniform BSDFType type; + uniform BSDF_Type type; uniform BSDF_EvalFunc eval; uniform BSDF_SampleFunc sample; const varying linear3f* uniform frame; }; inline void BSDF_Constructor(varying BSDF* uniform self, - uniform BSDFType type, + uniform BSDF_Type type, uniform BSDF_EvalFunc eval, uniform BSDF_SampleFunc sample, const varying linear3f* uniform frame) diff --git a/ospray/render/pathtracer/bsdfs/Conductor.ih b/ospray/render/pathtracer/bsdfs/Conductor.ih index 50c5fcd7f1..6c59defac6 100644 --- a/ospray/render/pathtracer/bsdfs/Conductor.ih +++ b/ospray/render/pathtracer/bsdfs/Conductor.ih @@ -34,7 +34,7 @@ inline vec3f Conductor_eval(const varying BSDF* uniform super, } inline vec3f Conductor_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Conductor* uniform self = (const varying Conductor* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Dielectric.ih b/ospray/render/pathtracer/bsdfs/Dielectric.ih index 98249b77ad..66b7a49bef 100644 --- a/ospray/render/pathtracer/bsdfs/Dielectric.ih +++ b/ospray/render/pathtracer/bsdfs/Dielectric.ih @@ -32,7 +32,7 @@ inline vec3f Dielectric_eval(const varying BSDF* uniform super, } inline vec3f Dielectric_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Dielectric* uniform self = (const varying Dielectric* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/DielectricLayer.ih b/ospray/render/pathtracer/bsdfs/DielectricLayer.ih index c728611963..a7c220e3c0 100644 --- a/ospray/render/pathtracer/bsdfs/DielectricLayer.ih +++ b/ospray/render/pathtracer/bsdfs/DielectricLayer.ih @@ -62,7 +62,7 @@ inline vec3f DielectricLayer_eval(const varying BSDF* uniform super, } inline vec3f DielectricLayer_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying DielectricLayer* uniform self = (const varying DielectricLayer* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Lambert.ih b/ospray/render/pathtracer/bsdfs/Lambert.ih index 9a4838147c..beeb734ccc 100644 --- a/ospray/render/pathtracer/bsdfs/Lambert.ih +++ b/ospray/render/pathtracer/bsdfs/Lambert.ih @@ -34,7 +34,7 @@ inline vec3f Lambert_eval(const varying BSDF* uniform super, } inline vec3f Lambert_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Lambert* uniform self = (const varying Lambert* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih b/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih index 570555059f..81b72cfc6a 100644 --- a/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih +++ b/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih @@ -58,7 +58,7 @@ inline vec3f MicrofacetConductor_eval(const varying BSDF* uniform super, } inline vec3f MicrofacetConductor_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying MicrofacetConductor* uniform self = (const varying MicrofacetConductor* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih b/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih index ab8dc1bd5f..5de679b6e1 100644 --- a/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih +++ b/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih @@ -87,7 +87,7 @@ inline vec3f MicrofacetDielectricLayer_eval(const varying BSDF* uniform super, } inline vec3f MicrofacetDielectricLayer_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying MicrofacetDielectricLayer* uniform self = (const varying MicrofacetDielectricLayer* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Minneart.ih b/ospray/render/pathtracer/bsdfs/Minneart.ih index 93fe0da5fc..ced66e7f69 100644 --- a/ospray/render/pathtracer/bsdfs/Minneart.ih +++ b/ospray/render/pathtracer/bsdfs/Minneart.ih @@ -43,7 +43,7 @@ inline vec3f Minneart_eval(const varying BSDF* uniform super, } inline vec3f Minneart_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Minneart* uniform self = (const varying Minneart* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih index ec587b3125..8206aff87b 100644 --- a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih +++ b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih @@ -74,7 +74,7 @@ inline vec3f MultiBSDF_eval(const varying BSDF* uniform super, /*! Sample the multi-BSDF. */ inline vec3f MultiBSDF_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying MultiBSDF* uniform self = (const varying MultiBSDF* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Reflection.ih b/ospray/render/pathtracer/bsdfs/Reflection.ih index 949b804a62..06f1605f4a 100644 --- a/ospray/render/pathtracer/bsdfs/Reflection.ih +++ b/ospray/render/pathtracer/bsdfs/Reflection.ih @@ -32,7 +32,7 @@ inline vec3f Reflection_eval(const varying BSDF* uniform super, } inline vec3f Reflection_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Reflection* uniform self = (const varying Reflection* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Specular.ih b/ospray/render/pathtracer/bsdfs/Specular.ih index 7e3ad6f93f..e469b9483e 100644 --- a/ospray/render/pathtracer/bsdfs/Specular.ih +++ b/ospray/render/pathtracer/bsdfs/Specular.ih @@ -43,7 +43,7 @@ inline vec3f Specular_eval(const varying BSDF* uniform super, } inline vec3f Specular_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Specular* uniform self = (const varying Specular* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/ThinDielectric.ih b/ospray/render/pathtracer/bsdfs/ThinDielectric.ih index 407264b776..cec31b2e3e 100644 --- a/ospray/render/pathtracer/bsdfs/ThinDielectric.ih +++ b/ospray/render/pathtracer/bsdfs/ThinDielectric.ih @@ -36,7 +36,7 @@ inline vec3f ThinDielectric_eval(const varying BSDF* uniform super, // TODO: account for multiple internal reflections with geometric sum inline vec3f ThinDielectric_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying ThinDielectric* uniform self = (const varying ThinDielectric* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Transmission.ih b/ospray/render/pathtracer/bsdfs/Transmission.ih index 85cbf6b433..c5b153d772 100644 --- a/ospray/render/pathtracer/bsdfs/Transmission.ih +++ b/ospray/render/pathtracer/bsdfs/Transmission.ih @@ -35,7 +35,7 @@ inline vec3f Transmission_eval(const varying BSDF* uniform super, } inline vec3f Transmission_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Transmission* uniform self = (const varying Transmission* uniform)super; diff --git a/ospray/render/pathtracer/bsdfs/Velvety.ih b/ospray/render/pathtracer/bsdfs/Velvety.ih index 41bc8aa2c8..fa5041b82e 100644 --- a/ospray/render/pathtracer/bsdfs/Velvety.ih +++ b/ospray/render/pathtracer/bsdfs/Velvety.ih @@ -45,7 +45,7 @@ inline vec3f Velvety_eval(const varying BSDF* uniform super, } inline vec3f Velvety_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDFType& type, + const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, const vec2f& s, float ss) { const varying Velvety* uniform self = (const varying Velvety* uniform)super; From 6835d3064190edd045de73052a4883126e080172 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 18 Apr 2016 16:44:33 -0500 Subject: [PATCH 216/310] adapt OSPRAY_USE_EXTERNAL_EMBREE to use updated Embree find_package() config --- ospray/CMakeLists.txt | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 1d599d90d0..a49d673ce6 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -40,17 +40,35 @@ IF(OSPRAY_USE_EXTERNAL_EMBREE) # internal build IF(NOT ${LAST_CONFIG_USED_EXTERNAL_EMBREE}) UNSET(EMBREE_INCLUDE_DIRS) + UNSET(EMBREE_LIBRARIES) UNSET(EMBREE_LIBRARY) UNSET(EMBREE_LIBRARY_XEONPHI) ENDIF() + # Find existing Embree on the machine FIND_PACKAGE(embree ${REQUIRED_MINIMUM_EMBREE} REQUIRED) SET(LAST_CONFIG_USED_EXTERNAL_EMBREE ON CACHE INTERNAL "" FORCE) + + # NOTE(jda) - EMBREE_LIBRARIES is not defined until at lest v2.10.0, for now + # create a "faked" EMBREE_LIBRARIES until we set our min version + # to >= 2.10.0 of Embree + IF(NOT DEFINED EMBREE_LIBRARIES) + SET(EMBREE_LIBRARIES ${EMBREE_LIBRARY}) + ELSE() + # NOTE(jda) - We are using the updated Embree find_package() config, check + # if we need to add TBB to EMBREE_LIBRARIES + IF(${EMBREE_TASKING_TBB} AND NOT ${EMBREE_USE_PACKAGED_TBB}) + OSPRAY_WARN_ONCE(EMBREE_FORCE_TBB "WARNING: You *MUST* have TBB installed based on the Embree we found!") + FIND_PACKAGE(TBB REQUIRED) + SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} ${TBB_LIBRARIES}) + ENDIF() + ENDIF() ELSE() # Clear out embree directories if they were previously populated by an # external find_package() call IF(${LAST_CONFIG_USED_EXTERNAL_EMBREE}) UNSET(EMBREE_INCLUDE_DIRS) + UNSET(EMBREE_LIBRARIES) UNSET(EMBREE_LIBRARY) UNSET(EMBREE_LIBRARY_XEONPHI) ENDIF() @@ -65,6 +83,7 @@ ELSE() ENDIF() SET(EMBREE_INCLUDE_DIRS ${OSPRAY_EMBREE_SOURCE_DIR}/include) SET(EMBREE_LIBRARY embree) + SET(EMBREE_LIBRARIES ${EMBREE_LIBRARY}) SET(EMBREE_LIBRARY_XEONPHI embree_xeonphi) SET(LAST_CONFIG_USED_EXTERNAL_EMBREE OFF CACHE INTERNAL "" FORCE) ENDIF() @@ -73,6 +92,7 @@ INCLUDE_DIRECTORIES(${EMBREE_INCLUDE_DIRS}) INCLUDE_DIRECTORIES_ISPC(${EMBREE_INCLUDE_DIRS}) SET(EMBREE_INCLUDE_DIRS ${EMBREE_INCLUDE_DIRS} PARENT_SCOPE) +SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} PARENT_SCOPE) SET(EMBREE_LIBRARY ${EMBREE_LIBRARY} PARENT_SCOPE) SET(EMBREE_LIBRARY_XEONPHI ${EMBREE_LIBRARY_XEONHPI} PARENT_SCOPE) @@ -316,7 +336,7 @@ IF (THIS_IS_MIC) ) ELSE() OSPRAY_LIBRARY_LINK_LIBRARIES(ospray - ${EMBREE_LIBRARY} + ${EMBREE_LIBRARIES} ${TASKING_SYSTEM_LIBS} ) ENDIF() From 2951a4db5a15dcbfb638726a501b1d2d59136357 Mon Sep 17 00:00:00 2001 From: atafra Date: Tue, 19 Apr 2016 18:05:24 +0300 Subject: [PATCH 217/310] added BSDF_EvalRes and BSDF_SampleRes --- ospray/render/pathtracer/PathTracer.ispc | 41 +++++----- ospray/render/pathtracer/bsdfs/BSDF.ih | 42 ++++++++-- ospray/render/pathtracer/bsdfs/Conductor.ih | 21 ++--- ospray/render/pathtracer/bsdfs/Dielectric.ih | 34 +++++---- .../pathtracer/bsdfs/DielectricLayer.ih | 60 +++++++-------- ospray/render/pathtracer/bsdfs/Lambert.ih | 25 +++--- .../pathtracer/bsdfs/MicrofacetConductor.ih | 41 +++++----- .../bsdfs/MicrofacetDielectricLayer.ih | 76 +++++++++---------- ospray/render/pathtracer/bsdfs/Minneart.ih | 25 +++--- ospray/render/pathtracer/bsdfs/MultiBSDF.ih | 55 +++++++------- ospray/render/pathtracer/bsdfs/Reflection.ih | 21 ++--- ospray/render/pathtracer/bsdfs/Specular.ih | 29 ++++--- .../render/pathtracer/bsdfs/ThinDielectric.ih | 34 +++++---- .../render/pathtracer/bsdfs/Transmission.ih | 22 +++--- ospray/render/pathtracer/bsdfs/Velvety.ih | 25 +++--- 15 files changed, 301 insertions(+), 250 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 12b92c0ba3..1a669a9d6a 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -200,17 +200,16 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, continue; // evaluate BSDF - vec3f bsdfValue; - float bsdfPdf = 0.f; - foreach_unique(b in bsdf) - if (b != NULL) - bsdfValue = b->eval(b, wo, ls.dir, bsdfPdf); + BSDF_EvalRes fe; + foreach_unique(f in bsdf) + if (f != NULL) + fe = f->eval(f, wo, ls.dir); #ifdef USE_DGCOLOR - bsdfValue = bsdfValue * make_vec3f(dg.color); + fe.value = fe.value * make_vec3f(dg.color); #endif // skip when zero contribution from material - if (reduce_max(bsdfValue) <= 0.0f) + if (reduce_max(fe.value) <= 0.0f) continue; // test for shadows @@ -219,7 +218,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, self->super.epsilon, ls.dist - self->super.epsilon); shadow_ray.time = ray.time; - vec3f unshaded_light_contrib = Lw * ls.weight * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); + vec3f unshaded_light_contrib = Lw * ls.weight * fe.value * misHeuristic(ls.pdf, fe.pdf); L = L + transparentShadow(self, unshaded_light_contrib, shadow_ray, currentMedium, rng); } } @@ -228,26 +227,26 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, break; // sample BSDF - vec3f wi; vec2f s = RandomTEA__getFloats(rng); vec2f ss = RandomTEA__getFloats(rng); // FIXME: should be only one component - vec3f bsdfWeight; - uint32 bsdfType = 0; - // also update lastBSDFPdf - foreach_unique(b in bsdf) - if (b != NULL) - bsdfWeight = b->sample(b, wo, wi, lastBSDFPdf, bsdfType, s, ss.x); + BSDF_SampleRes fs; + foreach_unique(f in bsdf) + if (f != NULL) + fs = f->sample(f, wo, s, ss.x); + + // update lastBSDFPdf + lastBSDFPdf = fs.pdf; #ifdef USE_DGCOLOR if ((type & GLOSSY_REFLECTION) == NONE) // only colorize diffuse component - bsdfWeight = bsdfWeight * make_vec3f(dg.color); + fs.weight = fs.weight * make_vec3f(dg.color); #endif // terminate path when zero contribution from material - if (reduce_max(bsdfWeight) <= 0.0f | lastBSDFPdf <= PDF_CULLING) + if (reduce_max(fs.weight) <= 0.0f | fs.pdf <= PDF_CULLING) break; - Lw = Lw * bsdfWeight; + Lw = Lw * fs.weight; // compute simple volumetric effect const vec3f transmission = currentMedium.transmission; @@ -255,7 +254,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, Lw = Lw * powf(transmission, ray.t); // update currentMedium if we hit a medium interface TODO: support nested dielectrics - if (bsdfType & BSDF_TRANSMISSION) { + if (fs.type & BSDF_TRANSMISSION) { foreach_unique(uniMat in dg.material) { uniform PathTraceMaterial* uniform m = (uniform PathTraceMaterial *)uniMat; if (m != NULL) @@ -264,8 +263,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, } // continue the path - straightPath &= eq(ray.dir, wi); - setRay(ray, dg.P, wi, self->super.epsilon, inf); + straightPath &= eq(ray.dir, fs.wi); + setRay(ray, dg.P, fs.wi, self->super.epsilon, inf); depth++; } while (reduce_max(Lw) > self->minContribution); diff --git a/ospray/render/pathtracer/bsdfs/BSDF.ih b/ospray/render/pathtracer/bsdfs/BSDF.ih index 95904703a8..c374f51c0c 100644 --- a/ospray/render/pathtracer/bsdfs/BSDF.ih +++ b/ospray/render/pathtracer/bsdfs/BSDF.ih @@ -55,14 +55,40 @@ struct BSDF; typedef uint32 BSDF_Type; -/*! Result is multiplied by dot(wi,N). */ -typedef vec3f (*BSDF_EvalFunc)(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf); - -/*! Result is multiplied by dot(wi,N)/pdf. */ -typedef vec3f (*BSDF_SampleFunc)(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss); +struct BSDF_EvalRes +{ + vec3f value; //!< radiance multiplied by dot(wi,N) + float pdf; +}; + +inline BSDF_EvalRes make_BSDF_EvalRes_zero() +{ + BSDF_EvalRes res; + res.value = make_vec3f(0.0f); + res.pdf = 0.0f; + return res; +} + +typedef BSDF_EvalRes (*BSDF_EvalFunc)(const varying BSDF* uniform self, + const vec3f& wo, const vec3f& wi); + +struct BSDF_SampleRes +{ + vec3f weight; //!< radiance multiplied by dot(wi,N)/pdf + vec3f wi; + float pdf; + BSDF_Type type; +}; + +inline BSDF_SampleRes make_BSDF_SampleRes_zero() +{ + BSDF_SampleRes res; + res.weight = make_vec3f(0.0f); + return res; +} + +typedef BSDF_SampleRes (*BSDF_SampleFunc)(const varying BSDF* uniform self, + const vec3f& wo, const vec2f& s, float ss); struct BSDF { diff --git a/ospray/render/pathtracer/bsdfs/Conductor.ih b/ospray/render/pathtracer/bsdfs/Conductor.ih index 6c59defac6..a8425de7b6 100644 --- a/ospray/render/pathtracer/bsdfs/Conductor.ih +++ b/ospray/render/pathtracer/bsdfs/Conductor.ih @@ -27,21 +27,22 @@ struct Conductor vec3f k; //!< imaginary part of refraction index }; -inline vec3f Conductor_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Conductor_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { - return make_vec3f(0.0f); + return make_BSDF_EvalRes_zero(); } -inline vec3f Conductor_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Conductor_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Conductor* uniform self = (const varying Conductor* uniform)super; - wi = reflect(wo, getN(super)); - pdf = inf; - type = BSDF_SPECULAR_REFLECTION; - return self->reflectance * fresnelConductor(dot(wo, getN(super)), self->eta, self->k); + BSDF_SampleRes res; + res.wi = reflect(wo, getN(super)); + res.pdf = inf; + res.type = BSDF_SPECULAR_REFLECTION; + res.weight = self->reflectance * fresnelConductor(dot(wo, getN(super)), self->eta, self->k); + return res; } inline void Conductor_Constructor(varying Conductor* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/Dielectric.ih b/ospray/render/pathtracer/bsdfs/Dielectric.ih index 66b7a49bef..930497d72b 100644 --- a/ospray/render/pathtracer/bsdfs/Dielectric.ih +++ b/ospray/render/pathtracer/bsdfs/Dielectric.ih @@ -25,35 +25,39 @@ struct Dielectric float eta; }; -inline vec3f Dielectric_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Dielectric_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { - return make_vec3f(0.0f); + return make_BSDF_EvalRes_zero(); } -inline vec3f Dielectric_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Dielectric_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Dielectric* uniform self = (const varying Dielectric* uniform)super; + BSDF_SampleRes res; float cosThetaO = max(dot(wo, getN(super)), 0.0f); // Fresnel term float cosThetaT; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaT, self->eta); - pdf = inf; + res.pdf = inf; // Sample the reflection or the transmission - if (ss <= F) { // Reflection - wi = reflect(wo, getN(super), cosThetaO); - type = BSDF_SPECULAR_REFLECTION; - return make_vec3f(1.0f); - } else { // Transmission - wi = refract(wo, getN(super), cosThetaO, cosThetaT, self->eta); - type = BSDF_SPECULAR_TRANSMISSION; - return make_vec3f(rsqrt(self->eta)); // solid angle compression + if (ss <= F) { + // Reflection + res.wi = reflect(wo, getN(super), cosThetaO); + res.type = BSDF_SPECULAR_REFLECTION; + res.weight = make_vec3f(1.0f); + } else { + // Transmission + res.wi = refract(wo, getN(super), cosThetaO, cosThetaT, self->eta); + res.type = BSDF_SPECULAR_TRANSMISSION; + res.weight = make_vec3f(rsqrt(self->eta)); // solid angle compression } + + return res; } inline void Dielectric_Constructor(varying Dielectric* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/DielectricLayer.ih b/ospray/render/pathtracer/bsdfs/DielectricLayer.ih index a7c220e3c0..f07960ad7b 100644 --- a/ospray/render/pathtracer/bsdfs/DielectricLayer.ih +++ b/ospray/render/pathtracer/bsdfs/DielectricLayer.ih @@ -28,18 +28,15 @@ struct DielectricLayer float thickness; }; -inline vec3f DielectricLayer_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes DielectricLayer_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying DielectricLayer* uniform self = (const varying DielectricLayer* uniform)super; + BSDF_EvalRes res; float cosThetaO = dot(wo, getN(super)); float cosThetaI = dot(wi, getN(super)); - if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) - { - pdf = 0.0f; - return make_vec3f(0.0f); - } + if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) return make_BSDF_EvalRes_zero(); // Fresnel term float cosThetaO1; // positive @@ -47,54 +44,55 @@ inline vec3f DielectricLayer_eval(const varying BSDF* uniform super, // Evaluate the substrate BRDF // Ignore refraction - float substratePdf; - vec3f substrateValue = self->substrate->eval(self->substrate, wo, wi, substratePdf); + BSDF_EvalRes substrate = self->substrate->eval(self->substrate, wo, wi); // Apply the coating transmittance // Computing the path length from the original angles would result in too much absorption, so instead use the refracted angles float cosThetaI1 = refract(cosThetaI, self->eta); // positive - substrateValue = substrateValue * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); + substrate.value = substrate.value * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); // Compute the final subtrate reflection // Ignore Fresnel for the exiting ray - pdf = (1.0f-F) * substratePdf; - return (1.0f-F) * substrateValue; + res.pdf = (1.0f-F) * substrate.pdf; + res.value = (1.0f-F) * substrate.value; + return res; } -inline vec3f DielectricLayer_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes DielectricLayer_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying DielectricLayer* uniform self = (const varying DielectricLayer* uniform)super; + BSDF_SampleRes res; float cosThetaO = dot(wo, getN(super)); - if (cosThetaO <= 0.0f) - return make_vec3f(0.0f); + if (cosThetaO <= 0.0f) return make_BSDF_SampleRes_zero(); // Fresnel term float cosThetaO1; // positive float F = fresnelDielectricEx(cosThetaO, cosThetaO1, self->eta); - if (ss < F) { // Sample the coating reflection - type = BSDF_SPECULAR_REFLECTION; - wi = reflect(wo, getN(super), cosThetaO); - pdf = inf; - return make_vec3f(1.0f); - } else { // Sample the substrate BRDF + if (ss < F) { + // Sample the coating reflection + res.type = BSDF_SPECULAR_REFLECTION; + res.wi = reflect(wo, getN(super), cosThetaO); + res.pdf = inf; + res.weight = make_vec3f(1.0f); + } else { + // Sample the substrate BRDF float ss1 = (ss - F) * rcp(1.0f-F); // reallocate sample - float substratePdf; - vec3f substrateWeight = self->substrate->sample(self->substrate, wo, wi, substratePdf, type, s, ss1); - if (reduce_max(substrateWeight) <= 0.0f) return make_vec3f(0.0f); - float cosThetaI = max(dot(wi, getN(super)), 0.0f); // should be positive + res = self->substrate->sample(self->substrate, wo, s, ss1); + if (reduce_max(res.weight) <= 0.0f) return res; + float cosThetaI = max(dot(res.wi, getN(super)), 0.0f); // should be positive // Apply the coating transmittance float cosThetaI1 = refract(cosThetaI, self->eta); // positive - substrateWeight = substrateWeight * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); + res.weight = res.weight * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); - // Compute the final base reflection - pdf = (1.0f-F) * substratePdf; - return substrateWeight; + // Compute the final reflection + res.pdf = (1.0f-F) * res.pdf; } + + return res; } inline void DielectricLayer_Constructor(varying DielectricLayer* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/Lambert.ih b/ospray/render/pathtracer/bsdfs/Lambert.ih index beeb734ccc..6d7e41c979 100644 --- a/ospray/render/pathtracer/bsdfs/Lambert.ih +++ b/ospray/render/pathtracer/bsdfs/Lambert.ih @@ -25,24 +25,27 @@ struct Lambert vec3f R; }; -inline vec3f Lambert_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Lambert_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying Lambert* uniform self = (const varying Lambert* uniform)super; - pdf = clamp(dot(wi, getN(super))) * one_over_pi; - return self->R/pi * clamp(dot(wi, getN(super))); + BSDF_EvalRes res; + res.pdf = clamp(dot(wi, getN(super))) * one_over_pi; + res.value = self->R/pi * clamp(dot(wi, getN(super))); + return res; } -inline vec3f Lambert_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Lambert_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Lambert* uniform self = (const varying Lambert* uniform)super; const vec3f localDir = cosineSampleHemisphere(s); - wi = getFrame(super) * localDir; - pdf = cosineSampleHemispherePDF(localDir); - type = BSDF_DIFFUSE_REFLECTION; - return self->R; + BSDF_SampleRes res; + res.wi = getFrame(super) * localDir; + res.pdf = cosineSampleHemispherePDF(localDir); + res.type = BSDF_DIFFUSE_REFLECTION; + res.weight = self->R; + return res; } inline void Lambert_Constructor(varying Lambert* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih b/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih index 81b72cfc6a..7384dc8db2 100644 --- a/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih +++ b/ospray/render/pathtracer/bsdfs/MicrofacetConductor.ih @@ -29,18 +29,15 @@ struct MicrofacetConductor GGXDistribution distribution; }; -inline vec3f MicrofacetConductor_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes MicrofacetConductor_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying MicrofacetConductor* uniform self = (const varying MicrofacetConductor* uniform)super; + BSDF_EvalRes res; float cosThetaO = dot(wo, getN(super)); float cosThetaI = dot(wi, getN(super)); - if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) - { - pdf = 0.0f; - return make_vec3f(0.0f); - } + if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) return make_BSDF_EvalRes_zero(); vec3f wh = normalize(wi + wo); float cosThetaH = dot(wh, getN(super)); @@ -53,37 +50,39 @@ inline vec3f MicrofacetConductor_eval(const varying BSDF* uniform super, float D = evalVisible(self->distribution, cosThetaH, cosThetaO, cosThetaOH, whPdf); float G = G2(self->distribution, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); - pdf = whPdf * rcp(4.0f*abs(cosThetaOH)); - return F * (D * G * rcp(4.0f*cosThetaO)); + res.pdf = whPdf * rcp(4.0f*abs(cosThetaOH)); + res.value = F * (D * G * rcp(4.0f*cosThetaO)); + return res; } -inline vec3f MicrofacetConductor_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes MicrofacetConductor_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying MicrofacetConductor* uniform self = (const varying MicrofacetConductor* uniform)super; + BSDF_SampleRes res; float cosThetaO = dot(wo, getN(super)); - if (cosThetaO <= 0.0f) return make_vec3f(0.0f); + if (cosThetaO <= 0.0f) return make_BSDF_SampleRes_zero(); float whPdf; //vec3f wh = getFrame(super) * sample(self->distribution, whPdf, s); vec3f wh = getFrame(super) * sampleVisible(self->distribution, transposed(getFrame(super)) * wo, whPdf, s); - wi = reflect(wo, wh); - float cosThetaI = dot(wi, getN(super)); - if (cosThetaI <= 0.0f) return make_vec3f(0.0f); + res.wi = reflect(wo, wh); + float cosThetaI = dot(res.wi, getN(super)); + if (cosThetaI <= 0.0f) return make_BSDF_SampleRes_zero(); //float cosThetaH = dot(wh, getN(super)); float cosThetaOH = dot(wo, wh); - float cosThetaIH = dot(wi, wh); + float cosThetaIH = dot(res.wi, wh); vec3f F = fresnelConductor(cosThetaOH, self->eta, self->k); float G = G2(self->distribution, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); - type = BSDF_GLOSSY_REFLECTION; - pdf = whPdf * rcp(4.0f*abs(cosThetaOH)); - //return F * (G * abs(cosThetaOH * rcp(cosThetaO*cosThetaH))); - return F * (G * rcp_safe(G1(self->distribution, cosThetaO, cosThetaOH))); + res.type = BSDF_GLOSSY_REFLECTION; + res.pdf = whPdf * rcp(4.0f*abs(cosThetaOH)); + //res.weight = F * (G * abs(cosThetaOH * rcp(cosThetaO*cosThetaH))); + res.weight = F * (G * rcp_safe(G1(self->distribution, cosThetaO, cosThetaOH))); + return res; } inline void MicrofacetConductor_Constructor(varying MicrofacetConductor* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih b/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih index 5de679b6e1..ac276106da 100644 --- a/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih +++ b/ospray/render/pathtracer/bsdfs/MicrofacetDielectricLayer.ih @@ -30,18 +30,15 @@ struct MicrofacetDielectricLayer GGXDistribution distribution; }; -inline vec3f MicrofacetDielectricLayer_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes MicrofacetDielectricLayer_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying MicrofacetDielectricLayer* uniform self = (const varying MicrofacetDielectricLayer* uniform)super; + BSDF_EvalRes res; float cosThetaO = dot(wo, getN(super)); float cosThetaI = dot(wi, getN(super)); - if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) - { - pdf = 0.0f; - return make_vec3f(0.0f); - } + if (cosThetaO <= 0.0f || cosThetaI <= 0.0f) return make_BSDF_EvalRes_zero(); // Compute the microfacet normal vec3f wh = normalize(wi + wo); @@ -59,46 +56,46 @@ inline vec3f MicrofacetDielectricLayer_eval(const varying BSDF* uniform super, float D = evalVisible(self->distribution, cosThetaH, cosThetaO, cosThetaOH, whPdf); float G = G2(self->distribution, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); - float coatingPdf = whPdf * rcp(4.0f*cosThetaOH); - float coatingValue = F * D * G * rcp(4.0f*cosThetaO); + BSDF_EvalRes coating; + coating.pdf = whPdf * rcp(4.0f*cosThetaOH); + coating.value = make_vec3f(F * D * G * rcp(4.0f*cosThetaO)); // Evaluate the substrate // Ignore refraction - float substratePdf; - vec3f substrateValue = self->substrate->eval(self->substrate, wo, wi, substratePdf); + BSDF_EvalRes substrate = self->substrate->eval(self->substrate, wo, wi); // Apply the coating transmittance // Computing the path length from the original angles would result in too much absorption, so instead use the refracted angles float cosThetaO1 = refract(cosThetaO, self->eta); // positive float cosThetaI1 = refract(cosThetaI, self->eta); // positive - substrateValue = substrateValue * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); + substrate.value = substrate.value * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); // Compute the final substrate reflection // Ignore Fresnel for the exiting ray float Ft = 1.0f-fresnelDielectric(cosThetaO, self->eta); - substrateValue = substrateValue * Ft; + substrate.value = substrate.value * Ft; // Compute the total reflection float coatingPickProb = 1.0f-Ft; float substratePickProb = Ft; - pdf = coatingPickProb * coatingPdf + substratePickProb * substratePdf; - return coatingValue + substrateValue; + res.pdf = coatingPickProb * coating.pdf + substratePickProb * substrate.pdf; + res.value = coating.value + substrate.value; + return res; } -inline vec3f MicrofacetDielectricLayer_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes MicrofacetDielectricLayer_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying MicrofacetDielectricLayer* uniform self = (const varying MicrofacetDielectricLayer* uniform)super; + BSDF_SampleRes res; float cosThetaO = dot(wo, getN(super)); - if (cosThetaO <= 0.0f) return make_vec3f(0.0f); + if (cosThetaO <= 0.0f) return make_BSDF_SampleRes_zero(); // Sample the coating or the substrate reflection vec3f wh; - float substratePdf; - vec3f substrateValue; + BSDF_EvalRes substrate; float Ft = 1.0f-fresnelDielectric(cosThetaO, self->eta); float coatingPickProb = 1.0f-Ft; @@ -112,26 +109,27 @@ inline vec3f MicrofacetDielectricLayer_sample(const varying BSDF* uniform super, wh = getFrame(super) * sampleVisible(self->distribution, transposed(getFrame(super)) * wo, whPdf, s); float cosThetaOH = dot(wo, wh); - type = BSDF_GLOSSY_REFLECTION; - wi = reflect(wo, wh, cosThetaOH); + res.type = BSDF_GLOSSY_REFLECTION; + res.wi = reflect(wo, wh, cosThetaOH); // Evaluate the substrate - substrateValue = self->substrate->eval(self->substrate, wo, wi, substratePdf); + substrate = self->substrate->eval(self->substrate, wo, res.wi); } else { // Sample the substrate float ss1 = (ss - coatingPickProb) * rcp(substratePickProb); // reallocate sample - vec3f substrateWeight = self->substrate->sample(self->substrate, wo, wi, substratePdf, type, s, ss1); - if (reduce_max(substrateWeight) <= 0.0f) return make_vec3f(0.0f); - substrateValue = substrateWeight * substratePdf; + res = self->substrate->sample(self->substrate, wo, s, ss1); + if (reduce_max(res.weight) <= 0.0f) return res; + substrate.pdf = res.pdf; + substrate.value = res.weight * res.pdf; // Compute the microfacet normal - wh = normalize(wi + wo); + wh = normalize(res.wi + wo); } - float cosThetaI = dot(wi, getN(super)); - if (cosThetaI <= 0.0f) return make_vec3f(0.0f); + float cosThetaI = dot(res.wi, getN(super)); + if (cosThetaI <= 0.0f) return make_BSDF_SampleRes_zero(); float cosThetaOH = dot(wo, wh); // Fresnel term @@ -139,27 +137,29 @@ inline vec3f MicrofacetDielectricLayer_sample(const varying BSDF* uniform super, // Evaluate the coating reflection float cosThetaH = dot(wh, getN(super)); - float cosThetaIH = dot(wi, wh); + float cosThetaIH = dot(res.wi, wh); float whPdf; //float D = eval(self->distribution, cosThetaH, whPdf); float D = evalVisible(self->distribution, cosThetaH, cosThetaO, cosThetaOH, whPdf); float G = G2(self->distribution, cosThetaO, cosThetaI, cosThetaOH, cosThetaIH); - float coatingPdf = whPdf * rcp(4.0f*cosThetaOH); - float coatingValue = F * D * G * rcp(4.0f*cosThetaO); + BSDF_EvalRes coating; + coating.pdf = whPdf * rcp(4.0f*cosThetaOH); + coating.value = make_vec3f(F * D * G * rcp(4.0f*cosThetaO)); // Apply the coating transmittance float cosThetaO1 = refract(cosThetaO, self->eta); // positive float cosThetaI1 = refract(cosThetaI, self->eta); // positive - substrateValue = substrateValue * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); + substrate.value = substrate.value * pow(self->transmittance, self->thickness * (rcp(cosThetaO1) + rcp(cosThetaI1))); - // Compute the final base reflection - substrateValue = substrateValue * Ft; + // Compute the final substrate reflection + substrate.value = substrate.value * Ft; // Compute the total reflection - pdf = coatingPickProb * coatingPdf + substratePickProb * substratePdf; - return (coatingValue + substrateValue) * rcp(pdf); + res.pdf = coatingPickProb * coating.pdf + substratePickProb * substrate.pdf; + res.weight = (coating.value + substrate.value) * rcp(res.pdf); + return res; } inline void MicrofacetDielectricLayer_Constructor(varying MicrofacetDielectricLayer* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/Minneart.ih b/ospray/render/pathtracer/bsdfs/Minneart.ih index ced66e7f69..41c2865794 100644 --- a/ospray/render/pathtracer/bsdfs/Minneart.ih +++ b/ospray/render/pathtracer/bsdfs/Minneart.ih @@ -31,27 +31,32 @@ struct Minneart float b; }; -inline vec3f Minneart_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Minneart_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying Minneart* uniform self = (const varying Minneart* uniform)super; + BSDF_EvalRes res; const float cosThetaI = clamp(dot(wi,getN(super))); const float backScatter = pow(clamp(dot(wo,wi)), self->b); - pdf = cosineSampleHemispherePDF(cosThetaI); - return mul(backScatter * cosThetaI * one_over_pi, self->R); + res.pdf = cosineSampleHemispherePDF(cosThetaI); + res.value = mul(backScatter * cosThetaI * one_over_pi, self->R); + return res; } -inline vec3f Minneart_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Minneart_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Minneart* uniform self = (const varying Minneart* uniform)super; + BSDF_SampleRes res; const vec3f localDir = cosineSampleHemisphere(s); - wi = getFrame(super) * localDir; - type = BSDF_DIFFUSE_REFLECTION; - return Minneart_eval(super, wo, wi, pdf) * rcp(pdf); + res.wi = getFrame(super) * localDir; + res.type = BSDF_DIFFUSE_REFLECTION; + BSDF_EvalRes eval = Minneart_eval(super, wo, res.wi); + res.pdf = eval.pdf; + res.weight = eval.value * rcp(eval.pdf); + return res; } inline void Minneart_Constructor(varying Minneart* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih index 8206aff87b..4cc37e5c0e 100644 --- a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih +++ b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih @@ -49,43 +49,41 @@ inline void MultiBSDF_add(varying BSDF* uniform super, } /*! Evaluates all BSDF components. */ -inline vec3f MultiBSDF_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes MultiBSDF_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying MultiBSDF* uniform self = (const varying MultiBSDF* uniform)super; - vec3f value = make_vec3f(0.0f); - pdf = 0.0f; + BSDF_EvalRes res = make_BSDF_EvalRes_zero(); for (uniform int i = 0; i < self->numBsdfs; ++i) { if (self->importances[i] > 0.0f) { const varying BSDF* uniform curBsdf = self->bsdfs[i]; - float curPdf = 0.0f; - value = value + curBsdf->eval(curBsdf, wo, wi, curPdf); - pdf = pdf + curPdf * self->importances[i]; + BSDF_EvalRes cur = curBsdf->eval(curBsdf, wo, wi); + res.value = res.value + cur.value; + res.pdf = res.pdf + cur.pdf * self->importances[i]; } } - pdf *= rcp(self->importanceSum); - return value; + res.pdf *= rcp(self->importanceSum); + return res; } /*! Sample the multi-BSDF. */ -inline vec3f MultiBSDF_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes MultiBSDF_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying MultiBSDF* uniform self = (const varying MultiBSDF* uniform)super; if (self->importanceSum == 0.0f) - return make_vec3f(0.0f); + return make_BSDF_SampleRes_zero(); if (self->numBsdfs == 1) { const varying BSDF* uniform bsdf = self->bsdfs[0]; - return bsdf->sample(bsdf, wo, wi, pdf, type, s, ss); + return bsdf->sample(bsdf, wo, s, ss); } else if (self->numBsdfs > 1) { @@ -100,40 +98,41 @@ inline vec3f MultiBSDF_sample(const varying BSDF* uniform super, ss = (x + self->importances[choice] - prefixSum) * rcp(self->importances[choice]); // sample chosen BSDF - vec3f weight; + BSDF_SampleRes res; foreach_unique (i in choice) { const varying BSDF* uniform bsdf = self->bsdfs[i]; - weight = bsdf->sample(bsdf, wo, wi, pdf, type, s, ss); + res = bsdf->sample(bsdf, wo, s, ss); } - if (eq(weight, make_vec3f(0.0f)) | (pdf == 0.0f)) - return make_vec3f(0.0f); + if (eq(res.weight, make_vec3f(0.0f)) | (res.pdf == 0.0f)) + return make_BSDF_SampleRes_zero(); - if (type & BSDF_SPECULAR) - return weight; + if (res.type & BSDF_SPECULAR) + return res; // compute overall weight and pdf - vec3f value = weight * pdf; - pdf *= self->importances[choice]; + vec3f value = res.weight * res.pdf; + res.pdf *= self->importances[choice]; for (uniform int i = 0; i < self->numBsdfs; ++i) { if ((i != choice) & (self->importances[i] > 0.0f)) { const varying BSDF* uniform curBsdf = self->bsdfs[i]; - float curPdf = 0.0f; - value = value + curBsdf->eval(curBsdf, wo, wi, curPdf); - pdf = pdf + curPdf * self->importances[i]; + BSDF_EvalRes cur = curBsdf->eval(curBsdf, wo, res.wi); + value = value + cur.value; + res.pdf = res.pdf + cur.pdf * self->importances[i]; } } - pdf *= rcp(self->importanceSum); - return value * rcp(pdf); + res.pdf *= rcp(self->importanceSum); + res.weight = value * rcp(res.pdf); + return res; } else { - return make_vec3f(0.0f); + return make_BSDF_SampleRes_zero(); } } diff --git a/ospray/render/pathtracer/bsdfs/Reflection.ih b/ospray/render/pathtracer/bsdfs/Reflection.ih index 06f1605f4a..09b21e71ca 100644 --- a/ospray/render/pathtracer/bsdfs/Reflection.ih +++ b/ospray/render/pathtracer/bsdfs/Reflection.ih @@ -25,22 +25,23 @@ struct Reflection vec3f reflectance; }; -inline vec3f Reflection_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Reflection_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { - return make_vec3f(0.0f); + return make_BSDF_EvalRes_zero(); } -inline vec3f Reflection_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Reflection_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Reflection* uniform self = (const varying Reflection* uniform)super; + BSDF_SampleRes res; - wi = reflect(wo, getN(super)); - pdf = inf; - type = BSDF_SPECULAR_REFLECTION; - return self->reflectance; + res.wi = reflect(wo, getN(super)); + res.pdf = inf; + res.type = BSDF_SPECULAR_REFLECTION; + res.weight = self->reflectance; + return res; } inline void Reflection_Constructor(varying Reflection* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/Specular.ih b/ospray/render/pathtracer/bsdfs/Specular.ih index e469b9483e..e794f53545 100644 --- a/ospray/render/pathtracer/bsdfs/Specular.ih +++ b/ospray/render/pathtracer/bsdfs/Specular.ih @@ -32,27 +32,32 @@ struct Specular float exp; }; -inline vec3f Specular_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Specular_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying Specular* uniform self = (const varying Specular* uniform)super; + BSDF_EvalRes res; + const vec3f refl = reflect(wo, getN(super)); - if (dot(refl,wi) < 0.0f) return make_vec3f(0.0f); - pdf = powerCosineSampleHemispherePDF(dot(refl,wi), self->exp); - return mul(self->R, (self->exp+2) * one_over_two_pi * pow(dot(refl,wi),self->exp) * clamp(dot(wi, getN(super)))); + if (dot(refl,wi) < 0.0f) return make_BSDF_EvalRes_zero(); + res.pdf = powerCosineSampleHemispherePDF(dot(refl,wi), self->exp); + res.value = mul(self->R, (self->exp+2) * one_over_two_pi * pow(dot(refl,wi),self->exp) * clamp(dot(wi, getN(super)))); + return res; } -inline vec3f Specular_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Specular_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Specular* uniform self = (const varying Specular* uniform)super; + BSDF_SampleRes res; + const vec3f refl = reflect(wo, getN(super)); const vec3f localDir = powerCosineSampleHemisphere(self->exp, s); - wi = frame(refl) * localDir; - pdf = powerCosineSampleHemispherePDF(localDir, self->exp); - type = BSDF_GLOSSY_REFLECTION; - return mul(self->R, (self->exp+2) * rcp(self->exp+1) * clamp(dot(wi, getN(super)))); + res.wi = frame(refl) * localDir; + res.pdf = powerCosineSampleHemispherePDF(localDir, self->exp); + res.type = BSDF_GLOSSY_REFLECTION; + res.weight = mul(self->R, (self->exp+2) * rcp(self->exp+1) * clamp(dot(res.wi, getN(super)))); + return res; } inline void Specular_Constructor(varying Specular* uniform self, diff --git a/ospray/render/pathtracer/bsdfs/ThinDielectric.ih b/ospray/render/pathtracer/bsdfs/ThinDielectric.ih index cec31b2e3e..4a7c455334 100644 --- a/ospray/render/pathtracer/bsdfs/ThinDielectric.ih +++ b/ospray/render/pathtracer/bsdfs/ThinDielectric.ih @@ -27,37 +27,41 @@ struct ThinDielectric uniform float thickness; /*! thickness of the medium */ }; -inline vec3f ThinDielectric_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes ThinDielectric_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { - return make_vec3f(0.0f); + return make_BSDF_EvalRes_zero(); } // TODO: account for multiple internal reflections with geometric sum -inline vec3f ThinDielectric_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes ThinDielectric_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying ThinDielectric* uniform self = (const varying ThinDielectric* uniform)super; + BSDF_SampleRes res; float cosThetaO = max(dot(wo, getN(super)), 0.0f); // Fresnel term float F = fresnelDielectric(cosThetaO, self->eta); - pdf = inf; + res.pdf = inf; // Sample the reflection or the transmission - if (ss <= F) { // Reflection - wi = reflect(wo, getN(super), cosThetaO); - type = BSDF_SPECULAR_REFLECTION; - return make_vec3f(1.0f); - } else { // Transmission - wi = neg(wo); - type = BSDF_SPECULAR_TRANSMISSION; + if (ss <= F) { + // Reflection + res.wi = reflect(wo, getN(super), cosThetaO); + res.type = BSDF_SPECULAR_REFLECTION; + res.weight = make_vec3f(1.0f); + } else { + // Transmission + res.wi = neg(wo); + res.type = BSDF_SPECULAR_TRANSMISSION; float alpha = self->thickness * rcp(cosThetaO); - return powf(self->transmission, alpha); + res.weight = powf(self->transmission, alpha); } + + return res; } inline void ThinDielectric_Constructor(varying ThinDielectric* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/Transmission.ih b/ospray/render/pathtracer/bsdfs/Transmission.ih index c5b153d772..37e77c0082 100644 --- a/ospray/render/pathtracer/bsdfs/Transmission.ih +++ b/ospray/render/pathtracer/bsdfs/Transmission.ih @@ -28,21 +28,23 @@ struct Transmission vec3f T; }; -inline vec3f Transmission_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Transmission_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { - return make_vec3f(0.0f); + return make_BSDF_EvalRes_zero(); } -inline vec3f Transmission_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Transmission_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Transmission* uniform self = (const varying Transmission* uniform)super; - wi = neg(wo); - pdf = inf; - type = BSDF_SPECULAR_TRANSMISSION; - return self->T; + BSDF_SampleRes res; + + res.wi = neg(wo); + res.pdf = inf; + res.type = BSDF_SPECULAR_TRANSMISSION; + res.weight = self->T; + return res; } inline void Transmission_Constructor(varying Transmission* uniform self, const varying linear3f* uniform frame, diff --git a/ospray/render/pathtracer/bsdfs/Velvety.ih b/ospray/render/pathtracer/bsdfs/Velvety.ih index fa5041b82e..ace28dc0cf 100644 --- a/ospray/render/pathtracer/bsdfs/Velvety.ih +++ b/ospray/render/pathtracer/bsdfs/Velvety.ih @@ -31,29 +31,34 @@ struct Velvety float f; }; -inline vec3f Velvety_eval(const varying BSDF* uniform super, - const vec3f& wo, const vec3f& wi, float& pdf) +inline BSDF_EvalRes Velvety_eval(const varying BSDF* uniform super, + const vec3f& wo, const vec3f& wi) { const varying Velvety* uniform self = (const varying Velvety* uniform)super; + BSDF_EvalRes res; const float cosThetaO = clamp(dot(wo,getN(super))); const float cosThetaI = clamp(dot(wi,getN(super))); const float sinThetaO = sqrt(1.0f - cosThetaO * cosThetaO); const float horizonScatter = pow(sinThetaO, self->f); - pdf = cosineSampleHemispherePDF(cosThetaI); - return mul(horizonScatter * cosThetaI * one_over_pi, self->R); + res.pdf = cosineSampleHemispherePDF(cosThetaI); + res.value = mul(horizonScatter * cosThetaI * one_over_pi, self->R); + return res; } -inline vec3f Velvety_sample(const varying BSDF* uniform super, - const vec3f& wo, vec3f& wi, float& pdf, BSDF_Type& type, - const vec2f& s, float ss) +inline BSDF_SampleRes Velvety_sample(const varying BSDF* uniform super, + const vec3f& wo, const vec2f& s, float ss) { const varying Velvety* uniform self = (const varying Velvety* uniform)super; + BSDF_SampleRes res; const vec3f localDir = cosineSampleHemisphere(s); - wi = getFrame(super) * localDir; - type = BSDF_DIFFUSE_REFLECTION; - return Velvety_eval(super, wo, wi, pdf) * rcp(pdf); + res.wi = getFrame(super) * localDir; + res.type = BSDF_DIFFUSE_REFLECTION; + BSDF_EvalRes eval = Velvety_eval(super, wo, res.wi); + res.pdf = eval.pdf; + res.weight = eval.value * rcp(eval.pdf); + return res; } inline void Velvety_Constructor(varying Velvety* uniform self, const varying linear3f* uniform frame, From a7a4d876f4e8907d511febd9fc688397a0a88f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 18 Apr 2016 10:36:33 +0200 Subject: [PATCH 218/310] Fix pdf returned by AmbientLight_eval --- ospray/lights/AmbientLight.ispc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 500ca98e73..1f1e119f43 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -28,6 +28,8 @@ struct AmbientLight { // Implementation ////////////////////////////////////////////////////////////////////////////// +// XXX importance sampling is only done into the positive hemisphere +// ==> poor support for translucent materials varying LightSample AmbientLight_sample(const uniform Light *uniform _self, const varying DifferentialGeometry &dg, const varying vec2f &s) @@ -45,15 +47,15 @@ varying LightSample AmbientLight_sample(const uniform Light *uniform _self, } varying LightEval AmbientLight_eval(const uniform Light *uniform _self, - const varying DifferentialGeometry &, - const varying vec3f &) + const varying DifferentialGeometry &dg, + const varying vec3f &dir) { uniform AmbientLight *uniform self = (uniform AmbientLight *uniform)_self; LightEval res; res.radiance = self->radiance; res.distance = inf; - res.pdf = 1.f/(4.f * M_PI); // uniformSampleSpherePDF(); // XXX inconsistent to sample, need surface normal here + res.pdf = cosineSampleHemispherePDF(max(dot(dg.Ns, dir), 0.f)); return res; } From d87249af7f762230c4db20c875789138ebdd9cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 19 Apr 2016 13:32:04 +0200 Subject: [PATCH 219/310] Need to scale weight of a sampled SPECULAR BSDF with selection pdf --- ospray/render/pathtracer/bsdfs/MultiBSDF.ih | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih index ec587b3125..cd3bea3f4a 100644 --- a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih +++ b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih @@ -111,7 +111,8 @@ inline vec3f MultiBSDF_sample(const varying BSDF* uniform super, return make_vec3f(0.0f); if (type & BSDF_SPECULAR) - return weight; + // scale by rcp(selection pdf) + return weight * (self->importanceSum * rcp(self->importances[choice])); // compute overall weight and pdf vec3f value = weight * pdf; From 082622d64240a50cb3e6b7865d68bd4b9eff7eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 19 Apr 2016 16:39:05 +0200 Subject: [PATCH 220/310] Better combination of MIS with transparent shadows Does not work in all cases -- after all, transparent shadows are a hack. --- ospray/render/pathtracer/PathTracer.ispc | 56 +++++++++--------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index c66d7ea5a4..e7203bcdea 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -36,11 +36,11 @@ inline float misHeuristic(float pdf1, float pdf2) return pdf1 > 1e17f ? 1.0f : p; } +// TODO use intersection filters vec3f transparentShadow(const uniform PathTracer* uniform self, vec3f lightContrib, Ray &shadowRay, - Medium medium, - varying RandomTEA* uniform rng) + Medium medium) { int max_depth = self->maxDepth; const float org_t_max = shadowRay.t; @@ -104,11 +104,11 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, bool straightPath = true; // path from camera did not change direction, for alpha and backplate uniform uint32 depth = 0; // geometric configuration of last surface interaction - DifferentialGeometry dg; + DifferentialGeometry lastDg; // P and N also used by light eval - dg.P = ray.org; - dg.Ns = ray.dir; - dg.Ng = ray.dir; + lastDg.P = ray.org; + lastDg.Ns = ray.dir; + lastDg.Ng = ray.dir; do { traceRay(self->super.model, ray); @@ -135,7 +135,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, // add light from virtual lights by intersecting them for (uniform int i = 0; i < self->numLights; i++) { const uniform Light *uniform l = self->lights[i]; - LightEval le = l->eval(l, dg, ray.dir); + LightEval le = l->eval(l, lastDg, ray.dir); if (le.distance <= maxLightDist) L = L + Lw * le.radiance * misHeuristic(lastBSDFPdf, le.pdf); } @@ -148,7 +148,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, //////////////////////////////////// // handle next surface interaction - // update DifferentialGeometry dg + DifferentialGeometry dg; postIntersect(self->super.model, dg, ray, DG_MATERIALID| DG_NS|DG_NG|DG_FACEFORWARD|DG_NORMALIZE|DG_TEXCOORD|DG_COLOR|DG_TANGENTS @@ -158,32 +158,11 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, uniform ShadingContext ctx; ShadingContext_Constructor(&ctx); const varying BSDF* bsdf = NULL; -#if 1 + uniform PathTraceMaterial* m = (uniform PathTraceMaterial*)dg.material; foreach_unique(mm in m) if (mm != NULL) bsdf = mm->getBSDF(mm, &ctx, dg, ray, currentMedium); -#else - foreach_unique(geomID in lightPath.ray.geomID) { - uniform PathTraceMaterial* uniform m - = (uniform PathTraceMaterial*)(self->super.model->geometry[geomID]->material); - print("shading %\n",m); - if (m != NULL) m->shade(m,lightPath.ray, lightPath.lastMedium, dg, brdfs, Ns); - } -#endif - -#if 0 - // iw: disabled because we dont' have per-geometry lights yet - /*! Add light emitted by hit area light source. */ - if (!lightPath.ignoreVisibleLights) { - foreach_unique(geomID in lightPath.ray.geomID) { - const uniform AreaLight* uniform l = self->super.model->geometry[geomID]->light; - if (l != NULL) - // L = add(L, mul(Lw, l->Le(l,dg,wo))); - L = L + Lw * l->Le(l,dg,wo); - } - } -#endif // direct lighting including shadows and MIS if (bsdf->type & BSDF_SMOOTH) @@ -220,8 +199,8 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, self->super.epsilon); shadow_ray.time = ray.time; - vec3f unshaded_light_contrib = Lw * ls.weight * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); - L = L + transparentShadow(self, unshaded_light_contrib, shadow_ray, currentMedium, rng); + const vec3f unshaded_light_contrib = Lw * ls.weight * bsdfValue * misHeuristic(ls.pdf, bsdfPdf); + L = L + transparentShadow(self, unshaded_light_contrib, shadow_ray, currentMedium); } } @@ -233,11 +212,11 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, vec2f s = RandomTEA__getFloats(rng); vec2f ss = RandomTEA__getFloats(rng); // FIXME: should be only one component vec3f bsdfWeight; + float bsdfPdf; uint32 bsdfType = 0; - // also update lastBSDFPdf foreach_unique(b in bsdf) if (b != NULL) - bsdfWeight = b->sample(b, wo, wi, lastBSDFPdf, bsdfType, s, ss.x); + bsdfWeight = b->sample(b, wo, wi, bsdfPdf, bsdfType, s, ss.x); #ifdef USE_DGCOLOR if ((type & GLOSSY_REFLECTION) == NONE) // only colorize diffuse component @@ -245,7 +224,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, #endif // terminate path when zero contribution from material - if (reduce_max(bsdfWeight) <= 0.0f | lastBSDFPdf <= PDF_CULLING) + if (reduce_max(bsdfWeight) <= 0.0f | bsdfPdf <= PDF_CULLING) break; Lw = Lw * bsdfWeight; @@ -264,6 +243,13 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, } } + // keep lastBSDFPdf and lastDg when there was a Dirac transmission + // to better combine MIS with transparent shadows + if (bsdfType & ~BSDF_SPECULAR_TRANSMISSION) { + lastBSDFPdf = bsdfPdf; + lastDg = dg; + } + // continue the path straightPath &= eq(ray.dir, wi); setRay(ray, dg.P, wi, self->super.epsilon, inf); From 12042be34d90f4943a4afa2f62792e9dd92e8573 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 19 Apr 2016 12:10:20 -0500 Subject: [PATCH 221/310] handle transparent geometry in scivis renderer closes #50 --- ospray/render/scivis/SciVisRenderer.ispc | 61 ++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 6dffb02235..e6f3569fb2 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -326,6 +326,7 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, varying Ray &ray, varying vec4f &out_color) { +#if 0 //NOTE(jda) - no geometry opacity handled here... // We compute intersections on the model and provide the contribution for the @@ -357,6 +358,66 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, shadeLights(self, ray, dg, info, 0/*depth*/, color); out_color = make_vec4f(color.x, color.y, color.z, 1.f); +#else + vec3f color = make_vec3f(0.f); + float path_opacity = 1.f; + int depth = 0; + float ray_t_depth = 0.f; + + while (1) { + + traceRay(self->super.model, ray); + + // Check if we missed, if so we are done // + if (ray.geomID < 0) { + ray.t = infinity; + return; + } + + // Record depth of first hit in z buffer // + if (depth == 0) { + ray_t_depth = ray.t; + } + + // Start shading // + + // Calculate material information from DG // + DifferentialGeometry dg; + postIntersect(self->super.model, + dg, + ray, + DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| + DG_MATERIALID|DG_COLOR|DG_TEXCOORD); + + SciVisShadingInfo info; + initShadingInfo(info); + + shadeMaterials(dg, info); + + info.local_opacity = path_opacity * info.d; + + if (info.local_opacity > 0.01f) { // worth shading? + shadeAO(self, sampleID, dg, info, color); + shadeLights(self, ray, dg, info, depth, color); + } + + // Kill path when reached max depth or if remaining contribution too low + path_opacity = path_opacity * (1.f - info.d); + depth++; + if (depth >= self->maxDepth | path_opacity < 0.01f ) { + out_color = make_vec4f(color.x, color.y, color.z, 1.f); + ray.t = ray_t_depth; + return; + } + + // Reset ray + ray.t0 = ray.t + self->super.epsilon; + ray.t = infinity; + ray.primID = -1; + ray.geomID = -1; + ray.instID = -1; + } +#endif } /*! Returns the first hit volume for the provided ray and sets the ray bounds t0 and t, From eeb49db65c1329f979ee09f576e32d811b7a1a37 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 19 Apr 2016 12:12:27 -0500 Subject: [PATCH 222/310] cleanup unused code paths in scivis renderer --- ospray/render/scivis/SciVisRenderer.ispc | 110 ----------------------- 1 file changed, 110 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index e6f3569fb2..ab7ce80f50 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -326,39 +326,6 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, varying Ray &ray, varying vec4f &out_color) { -#if 0 - //NOTE(jda) - no geometry opacity handled here... - - // We compute intersections on the model and provide the contribution for the - // closest hit. - traceRay(self->super.model, ray); - - // No hit found. - if(ray.geomID < 0) { - ray.t = infinity; - return; - } - - // Calculate material information from DG // - DifferentialGeometry dg; - postIntersect(self->super.model, dg, ray, - DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| - DG_MATERIALID|DG_COLOR|DG_TEXCOORD); - - SciVisShadingInfo info; - initShadingInfo(info); - - shadeMaterials(dg, info); - - info.local_opacity = info.d; - - vec3f color = make_vec3f(0.f); - - shadeAO(self, sampleID, dg, info, color); - shadeLights(self, ray, dg, info, 0/*depth*/, color); - - out_color = make_vec4f(color.x, color.y, color.z, 1.f); -#else vec3f color = make_vec3f(0.f); float path_opacity = 1.f; int depth = 0; @@ -417,7 +384,6 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, ray.geomID = -1; ray.instID = -1; } -#endif } /*! Returns the first hit volume for the provided ray and sets the ray bounds t0 and t, @@ -594,85 +560,10 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, // Main shading function // -inline -void SciVisRenderer_shadeRay(const uniform SciVisRenderer *uniform self, - varying ScreenSample &sample) -{ - Ray &ray = sample.ray; - // ISPC issue #703. Switch to 'nice' code once ISPC #703 is fixed. - // print("ray.dir % % %\n",ray.dir.x,ray.dir.y,ray.dir.z); - vec3f color = make_vec3f(0.f); - float path_opacity = 1.f; - int depth = 0; - - while (1) { - - traceRay(self->super.model, ray); - - // Record depth of first hit in z buffer // - if (depth == 0) { - sample.z = ray.t; - } - - // Check if we missed, if so we are done // - if (ray.geomID < 0) { - sample.rgb = self->super.backgroundEnabled ? - color + path_opacity * self->super.bgColor : - color; - sample.alpha = 1.f - path_opacity; - return; - } - - // Start shading // - - // Calculate material information from DG // - DifferentialGeometry dg; - postIntersect(self->super.model, - dg, - ray, - DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| - DG_MATERIALID|DG_COLOR|DG_TEXCOORD); - - SciVisShadingInfo info; - initShadingInfo(info); - - shadeMaterials(dg, info); - - info.local_opacity = path_opacity * info.d; - - if (info.local_opacity > 0.01f) { // worth shading? - shadeAO(self, sample.sampleID, dg, info, color); - shadeLights(self, ray, dg, info, depth, color); - } - - // kill path when reached max depth or if remaining contribution too low - path_opacity = path_opacity * (1.f - info.d); - depth++; - if (depth >= self->maxDepth | path_opacity < 0.01f ) { - sample.rgb = color; - sample.alpha = 1.f - path_opacity; - return; - } - - ray.t0 = ray.t + self->super.epsilon; - ray.t = infinity; - ray.primID = -1; - ray.geomID = -1; - ray.instID = -1; - } -} - void SciVisRenderer_renderSample(uniform Renderer *uniform _self, void *uniform perFrameData, varying ScreenSample &sample) { - //NOTE(jda) - Eliminate #if'd out code path when satisfied with surface only - // scene performance and features -#if 0 - uniform SciVisRenderer *uniform self = - (uniform SciVisRenderer *uniform)_self; - SciVisRenderer_shadeRay(self, sample); -#else SciVisRenderer *uniform renderer = (SciVisRenderer *uniform) _self; @@ -720,7 +611,6 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, sample.rgb.z = color.z; sample.alpha = color.w; sample.z = depth; -#endif } // Exports (called from C++) From 2164202864ba3aa0267a22cbdf69edf0391b3135 Mon Sep 17 00:00:00 2001 From: atafra Date: Wed, 20 Apr 2016 14:32:37 +0300 Subject: [PATCH 223/310] light cleanup --- ospray/lights/AmbientLight.ispc | 12 ++++++------ ospray/lights/DirectionalLight.ispc | 14 +++++++------- ospray/lights/HDRILight.ispc | 18 +++++++++--------- ospray/lights/Light.ih | 15 +++++++-------- ospray/lights/Light.ispc | 6 +++--- ospray/lights/PointLight.ispc | 12 ++++++------ ospray/lights/QuadLight.ispc | 6 +++--- ospray/lights/SpotLight.ispc | 12 ++++++------ 8 files changed, 47 insertions(+), 48 deletions(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 14879ac52d..379acb4be9 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -31,9 +31,9 @@ struct AmbientLight // XXX importance sampling is only done into the positive hemisphere // ==> poor support for translucent materials -varying Light_SampleRes AmbientLight_sample(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec2f& s) +Light_SampleRes AmbientLight_sample(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec2f& s) { uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super; Light_SampleRes res; @@ -47,9 +47,9 @@ varying Light_SampleRes AmbientLight_sample(const uniform Light* uniform super, return res; } -varying Light_EvalRes AmbientLight_eval(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec3f& dir) +Light_EvalRes AmbientLight_eval(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec3f& dir) { uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super; Light_EvalRes res; diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 59d68dd2a8..2c516312d7 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -35,9 +35,9 @@ struct DirectionalLight // Implementation ////////////////////////////////////////////////////////////////////////////// -varying Light_SampleRes DirectionalLight_sample(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec2f& s) +Light_SampleRes DirectionalLight_sample(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec2f& s) { const DirectionalLight* uniform self = (DirectionalLight* uniform)super; Light_SampleRes res; @@ -54,9 +54,9 @@ varying Light_SampleRes DirectionalLight_sample(const uniform Light* uniform sup return res; } -varying Light_EvalRes DirectionalLight_eval(const uniform Light* uniform super, - const varying DifferentialGeometry&, - const varying vec3f& dir) +Light_EvalRes DirectionalLight_eval(const uniform Light* uniform super, + const DifferentialGeometry&, + const vec3f& dir) { uniform DirectionalLight* uniform self = (uniform DirectionalLight* uniform)super; Light_EvalRes res; @@ -91,7 +91,7 @@ export void DirectionalLight_set(void* uniform super, } //! Create an ispc-side DirectionalLight object -export void *uniform DirectionalLight_create() +export void* uniform DirectionalLight_create() { uniform DirectionalLight* uniform self = uniform new uniform DirectionalLight; Light_Constructor(&self->super); diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index b0a7290561..e15d43621a 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -37,18 +37,18 @@ struct HDRILight ////////////////////////////////////////////////////////////////////////////// // sample function used when no environment map is given: black -varying Light_SampleRes HDRILight_sample_dummy(const uniform Light* uniform, - const varying DifferentialGeometry&, - const varying vec2f&) +Light_SampleRes HDRILight_sample_dummy(const uniform Light* uniform, + const DifferentialGeometry&, + const vec2f&) { Light_SampleRes res; memset(&res, 0, sizeof(Light_SampleRes)); return res; } -varying Light_SampleRes HDRILight_sample(const uniform Light* uniform super, - const varying DifferentialGeometry&, - const varying vec2f& s) +Light_SampleRes HDRILight_sample(const uniform Light* uniform super, + const DifferentialGeometry&, + const vec2f& s) { uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; Light_SampleRes res; @@ -75,9 +75,9 @@ varying Light_SampleRes HDRILight_sample(const uniform Light* uniform super, return res; } -varying Light_EvalRes HDRILight_eval(const uniform Light* uniform super, - const varying DifferentialGeometry&, - const varying vec3f& dir) +Light_EvalRes HDRILight_eval(const uniform Light* uniform super, + const DifferentialGeometry&, + const vec3f& dir) { uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; Light_EvalRes res; diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index 0005d32722..d4ed16926d 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -31,9 +31,9 @@ struct Light_SampleRes //! compute the weighted radiance at a point caused by a sample on the light source // by convention, giving (0, 0) as "random" numbers should sample the "center" // of the light source (used by the raytracing renderers such as the OBJ renderer) -typedef varying Light_SampleRes (*Light_SampleFunc)(const uniform Light* uniform self, - /*! point to generate the sample for >*/ const varying DifferentialGeometry& dg, - /*! random numbers to generate the sample >*/ const varying vec2f& s); +typedef Light_SampleRes (*Light_SampleFunc)(const uniform Light* uniform self, + const DifferentialGeometry& dg, /*! point to generate the sample for >*/ + const vec2f& s); /*! random numbers to generate the sample >*/ struct Light_EvalRes @@ -44,9 +44,9 @@ struct Light_EvalRes }; //! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction) -typedef varying Light_EvalRes (*Light_EvalFunc)(const uniform Light* uniform self, -/*! point to evaluate illumination for >*/ const varying DifferentialGeometry& dg, -/*! direction towards the light source >*/ const varying vec3f& dir); +typedef Light_EvalRes (*Light_EvalFunc)(const uniform Light* uniform self, + const DifferentialGeometry& dg, /*! point to evaluate illumination for >*/ + const vec3f& dir); /*! direction towards the light source >*/ struct Light @@ -55,8 +55,7 @@ struct Light Light_EvalFunc eval; }; - -varying Light_EvalRes Light_eval(const uniform Light* uniform self, const varying DifferentialGeometry& dg, const varying vec3f& dir); +Light_EvalRes Light_eval(const uniform Light* uniform self, const DifferentialGeometry& dg, const vec3f& dir); inline void Light_Constructor(uniform Light* uniform self) { diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index a1f936d2b8..24c8051bee 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -16,9 +16,9 @@ #include "Light.ih" -varying Light_EvalRes Light_eval(const uniform Light* uniform, - const varying DifferentialGeometry&, - const varying vec3f&) +Light_EvalRes Light_eval(const uniform Light* uniform, + const DifferentialGeometry&, + const vec3f&) { Light_EvalRes res; res.value = make_vec3f(0.f); diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 4c81bc284b..7a5241a78b 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -31,9 +31,9 @@ struct PointLight // Implementation ////////////////////////////////////////////////////////////////////////////// -varying Light_SampleRes PointLight_sample(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec2f& s) +Light_SampleRes PointLight_sample(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec2f& s) { const PointLight* uniform self = (PointLight* uniform)super; Light_SampleRes res; @@ -77,9 +77,9 @@ varying Light_SampleRes PointLight_sample(const uniform Light* uniform super, return res; } -varying Light_EvalRes PointLight_eval(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec3f& dir) +Light_EvalRes PointLight_eval(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec3f& dir) { const PointLight* uniform self = (PointLight* uniform)super; Light_EvalRes res; diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index b0ae61a8db..20b9b8f06c 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -33,9 +33,9 @@ struct QuadLight // Implementation ////////////////////////////////////////////////////////////////////////////// -varying Light_SampleRes QuadLight_sample(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec2f& s) +Light_SampleRes QuadLight_sample(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec2f& s) { const QuadLight* uniform self = (QuadLight* uniform)super; Light_SampleRes res; diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 535f8bd3ce..10a249930a 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -35,9 +35,9 @@ struct SpotLight // Implementation ////////////////////////////////////////////////////////////////////////////// -varying Light_SampleRes SpotLight_sample(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec2f& s) +Light_SampleRes SpotLight_sample(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec2f& s) { const SpotLight* uniform self = (SpotLight* uniform)super; Light_SampleRes res; @@ -70,9 +70,9 @@ varying Light_SampleRes SpotLight_sample(const uniform Light* uniform super, return res; } -varying Light_EvalRes SpotLight_eval(const uniform Light* uniform super, - const varying DifferentialGeometry& dg, - const varying vec3f& dir) +Light_EvalRes SpotLight_eval(const uniform Light* uniform super, + const DifferentialGeometry& dg, + const vec3f& dir) { const SpotLight* uniform self = (SpotLight* uniform)super; Light_EvalRes res; From 2b577de711da75694f42a8f4a58d305528881007 Mon Sep 17 00:00:00 2001 From: atafra Date: Wed, 20 Apr 2016 18:43:11 +0300 Subject: [PATCH 224/310] minor material cleanup --- ospray/render/pathtracer/PathTracer.ispc | 2 +- ospray/render/pathtracer/materials/Glass.ispc | 2 +- ospray/render/pathtracer/materials/Material.ih | 10 +++++----- ospray/render/pathtracer/materials/Material.ispc | 2 +- ospray/render/pathtracer/materials/Medium.ih | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 78974274ab..682cd0efeb 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -99,7 +99,7 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, vec3f L = make_vec3f(0.f); // accumulated radiance vec3f Lw = make_vec3f(1.f); // path throughput - Medium currentMedium = make_Medium_Vacuum(); + Medium currentMedium = make_Medium_vacuum(); float lastBSDFPdf = inf; // probability density of previous sampled BSDF, for MIS bool straightPath = true; // path from camera did not change direction, for alpha and backplate uniform uint32 depth = 0; diff --git a/ospray/render/pathtracer/materials/Glass.ispc b/ospray/render/pathtracer/materials/Glass.ispc index 7d2dd495be..7ed53e5287 100644 --- a/ospray/render/pathtracer/materials/Glass.ispc +++ b/ospray/render/pathtracer/materials/Glass.ispc @@ -57,7 +57,7 @@ vec3f Glass_getTransparency(const uniform PathTraceMaterial* uniform material, } void Glass_selectNextMedium(const uniform PathTraceMaterial* uniform super, - varying Medium& currentMedium) + Medium& currentMedium) { const uniform Glass* uniform self = (const uniform Glass* uniform)super; diff --git a/ospray/render/pathtracer/materials/Material.ih b/ospray/render/pathtracer/materials/Material.ih index fa8097f85e..876d6e122f 100644 --- a/ospray/render/pathtracer/materials/Material.ih +++ b/ospray/render/pathtracer/materials/Material.ih @@ -26,7 +26,7 @@ struct PathTraceMaterial; -typedef const varying BSDF* uniform (*PathTraceMaterial_GetBSDFFunc)(const uniform PathTraceMaterial* uniform material, +typedef const varying BSDF* uniform (*PathTraceMaterial_GetBSDFFunc)(const uniform PathTraceMaterial* uniform self, uniform ShadingContext* uniform ctx, /*! The point to shade on a surface. */ const DifferentialGeometry& dg, @@ -35,7 +35,7 @@ typedef const varying BSDF* uniform (*PathTraceMaterial_GetBSDFFunc)(const unifo /*! The medium this ray travels inside. */ const Medium& currentMedium); -typedef vec3f (*PathTraceMaterial_GetTransparencyFunc)(const uniform PathTraceMaterial* uniform material, +typedef vec3f (*PathTraceMaterial_GetTransparencyFunc)(const uniform PathTraceMaterial* uniform self, /*! The point to shade on a surface. */ const DifferentialGeometry& dg, /*! The ray arriving at the point to shade. */ @@ -43,8 +43,8 @@ typedef vec3f (*PathTraceMaterial_GetTransparencyFunc)(const uniform PathTraceMa /*! The medium this ray travels inside. */ const Medium& currentMedium); -typedef void (*PathTraceMaterial_SelectNextMediumFunc)(const uniform PathTraceMaterial *uniform self, - varying Medium& currentMedium); +typedef void (*PathTraceMaterial_SelectNextMediumFunc)(const uniform PathTraceMaterial* uniform self, + Medium& currentMedium); struct PathTraceMaterial { @@ -54,7 +54,7 @@ struct PathTraceMaterial PathTraceMaterial_SelectNextMediumFunc selectNextMedium; }; -void PathTraceMaterial_Constructor(uniform PathTraceMaterial *uniform self, +void PathTraceMaterial_Constructor(uniform PathTraceMaterial* uniform self, uniform PathTraceMaterial_GetBSDFFunc getBSDF, uniform PathTraceMaterial_GetTransparencyFunc getTransparency, uniform PathTraceMaterial_SelectNextMediumFunc selectNextMedium); diff --git a/ospray/render/pathtracer/materials/Material.ispc b/ospray/render/pathtracer/materials/Material.ispc index 541ab6ec47..e8df0cbf26 100644 --- a/ospray/render/pathtracer/materials/Material.ispc +++ b/ospray/render/pathtracer/materials/Material.ispc @@ -25,7 +25,7 @@ vec3f PathTraceMaterial_getTransparency(const uniform PathTraceMaterial* uniform } void PathTraceMaterial_selectNextMedium(const uniform PathTraceMaterial* uniform self, - varying Medium& currentMedium) + Medium& currentMedium) { /* do nothing by default */ } void PathTraceMaterial_Constructor(uniform PathTraceMaterial* uniform self, diff --git a/ospray/render/pathtracer/materials/Medium.ih b/ospray/render/pathtracer/materials/Medium.ih index d80d9f669a..427b5e55a5 100644 --- a/ospray/render/pathtracer/materials/Medium.ih +++ b/ospray/render/pathtracer/materials/Medium.ih @@ -30,7 +30,7 @@ inline Medium make_Medium(const vec3f transmission, const float ior) return m; } -inline Medium make_Medium_Vacuum() { +inline Medium make_Medium_vacuum() { return make_Medium(make_vec3f(1.0f),1.0f); } From 66f90eafc05f6f89aea170f3b6dc514c0b2e10b0 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 20 Apr 2016 13:46:46 -0500 Subject: [PATCH 225/310] use 1.0 as default gamma value --- ospray/fb/FrameBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/fb/FrameBuffer.cpp b/ospray/fb/FrameBuffer.cpp index 7d15e38b7c..f89a0430ab 100644 --- a/ospray/fb/FrameBuffer.cpp +++ b/ospray/fb/FrameBuffer.cpp @@ -37,7 +37,7 @@ namespace ospray { void FrameBuffer::commit() { - const float gamma = getParam1f("gamma", 2.2f); + const float gamma = getParam1f("gamma", 1.0f); ispc::FrameBuffer_set_gamma(ispcEquivalent, gamma); } From b58b436570179dc9ee70f3c01b6ddd61f5551860 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 20 Apr 2016 14:26:49 -0500 Subject: [PATCH 226/310] change scivis renderer defaults to more "expected" values, changed in apps --- apps/modelViewer/modelViewer.cpp | 8 ++++++++ apps/qtViewer/sg/common/Integrator.cpp | 10 +++++++++- apps/volumeViewer/VolumeViewer.cpp | 7 +++++++ modules/tachyon/Viewer.cpp | 2 ++ ospray/render/scivis/SciVisRenderer.cpp | 4 ++-- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 2f15a9ecc8..1344ff7e6a 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -690,6 +690,14 @@ namespace ospray { ospModel = ospNewModel(); ospRenderer = ospNewRenderer(rendererType.c_str()); + + // Set renderer defaults (if not using 'aoX' renderers) + if (rendererType[0] != 'a' && rendererType[1] != 'o') + { + ospSet1i(ospRenderer, "aoSamples", 1); + ospSet1i(ospRenderer, "shadowsEnabled", 1); + } + // ospSet1f(ospRenderer, "varianceThreshold", 0.0002); if (!ospRenderer) throw std::runtime_error("could not create ospRenderer '"+rendererType+"'"); diff --git a/apps/qtViewer/sg/common/Integrator.cpp b/apps/qtViewer/sg/common/Integrator.cpp index 055955422e..a1946e2e09 100644 --- a/apps/qtViewer/sg/common/Integrator.cpp +++ b/apps/qtViewer/sg/common/Integrator.cpp @@ -26,7 +26,15 @@ namespace ospray { { if (!ospRenderer) { ospRenderer = ospNewRenderer(type.c_str()); - if (!ospRenderer) + + // Set renderer defaults (if not using 'aoX' renderers) + if (type[0] != 'a' && type[1] != 'o') + { + ospSet1i(ospRenderer, "aoSamples", 1); + ospSet1i(ospRenderer, "shadowsEnabled", 1); + } + + if (!ospRenderer) throw std::runtime_error("#osp:sg:SceneGraph: could not create renderer (of type '"+type+"')"); } if (lastCommitted >= lastModified) return; diff --git a/apps/volumeViewer/VolumeViewer.cpp b/apps/volumeViewer/VolumeViewer.cpp index 347b9895d1..b4a045d24c 100644 --- a/apps/volumeViewer/VolumeViewer.cpp +++ b/apps/volumeViewer/VolumeViewer.cpp @@ -454,6 +454,13 @@ void VolumeViewer::initObjects(const std::string &renderer_type) renderer = ospNewRenderer(renderer_type.c_str()); exitOnCondition(renderer == NULL, "could not create OSPRay renderer object"); + // Set renderer defaults (if not using 'aoX' renderers) + if (renderer_type[0] != 'a' && renderer_type[1] != 'o') + { + ospSet1i(renderer, "aoSamples", 1); + ospSet1i(renderer, "shadowsEnabled", 1); + } + // Create OSPRay ambient and directional lights. GUI elements will modify their parameters. ambientLight = ospNewLight(renderer, "AmbientLight"); exitOnCondition(ambientLight == NULL, "could not create ambient light"); diff --git a/modules/tachyon/Viewer.cpp b/modules/tachyon/Viewer.cpp index 10fa287d73..725a9c0897 100644 --- a/modules/tachyon/Viewer.cpp +++ b/modules/tachyon/Viewer.cpp @@ -198,6 +198,8 @@ namespace ospray { ospCommit(camera); renderer = ospNewRenderer(renderType); + ospSet1i(renderer, "aoSamples", 1); + ospSet1i(renderer, "shadowsEnabled", 1); Assert2(renderer,"could not create renderer"); ospSetObject(renderer,"model",model); diff --git a/ospray/render/scivis/SciVisRenderer.cpp b/ospray/render/scivis/SciVisRenderer.cpp index 81582bc36e..1dcea63d29 100644 --- a/ospray/render/scivis/SciVisRenderer.cpp +++ b/ospray/render/scivis/SciVisRenderer.cpp @@ -43,11 +43,11 @@ namespace ospray { void **lightPtr = lightArray.empty() ? NULL : &lightArray[0]; - const bool shadowsEnabled = bool(getParam1i("shadowsEnabled", 1)); + const bool shadowsEnabled = getParam1i("shadowsEnabled", 0); const int32 maxDepth = getParam1i("maxDepth", 10); - int numAOSamples = getParam1i("aoSamples", 4); + int numAOSamples = getParam1i("aoSamples", 0); float rayLength = getParam1f("aoOcclusionDistance", 1e20f); float aoWeight = getParam1f("aoWeight", 0.25f); From ed2e2f22c66b8638b095695d1a212bd5e690b912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 21 Apr 2016 12:07:29 +0200 Subject: [PATCH 227/310] Simplify cases in MultiBSDF --- ospray/render/pathtracer/bsdfs/MultiBSDF.ih | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih index c45abe55de..be01ec7899 100644 --- a/ospray/render/pathtracer/bsdfs/MultiBSDF.ih +++ b/ospray/render/pathtracer/bsdfs/MultiBSDF.ih @@ -77,7 +77,7 @@ inline BSDF_SampleRes MultiBSDF_sample(const varying BSDF* uniform super, { const varying MultiBSDF* uniform self = (const varying MultiBSDF* uniform)super; - if (self->importanceSum == 0.0f) + if (self->importanceSum == 0.0f) // also handles case self->numBsdfs == 0 return make_BSDF_SampleRes_zero(); if (self->numBsdfs == 1) @@ -85,7 +85,7 @@ inline BSDF_SampleRes MultiBSDF_sample(const varying BSDF* uniform super, const varying BSDF* uniform bsdf = self->bsdfs[0]; return bsdf->sample(bsdf, wo, s, ss); } - else if (self->numBsdfs > 1) + else { // choose which BSDF to sample float x = ss * self->importanceSum; @@ -134,10 +134,6 @@ inline BSDF_SampleRes MultiBSDF_sample(const varying BSDF* uniform super, res.weight = value * rcp(res.pdf); return res; } - else - { - return make_BSDF_SampleRes_zero(); - } } inline void MultiBSDF_Constructor(varying MultiBSDF* uniform self) From e691ec2d93cbed432c97d61de3ed2f9bbaa13f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 22 Apr 2016 11:24:32 +0200 Subject: [PATCH 228/310] Fix transparency of (Thin)Glass, default IoR to 1.5 getTransparency() gets the ray, which has opposite direction of wo that BSDF_sample gets, thus need to flip sign. --- ospray/render/pathtracer/materials/Glass.cpp | 6 ++---- ospray/render/pathtracer/materials/Glass.ispc | 2 +- ospray/render/pathtracer/materials/ThinGlass.cpp | 4 ++-- ospray/render/pathtracer/materials/ThinGlass.ispc | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ospray/render/pathtracer/materials/Glass.cpp b/ospray/render/pathtracer/materials/Glass.cpp index 1d054bc5c6..eecd01d2b9 100644 --- a/ospray/render/pathtracer/materials/Glass.cpp +++ b/ospray/render/pathtracer/materials/Glass.cpp @@ -33,10 +33,8 @@ namespace ospray { const vec3f& transmissionOutside = getParam3f("transmissionOutside",vec3f(1.f)); - const float etaInside - = getParamf("etaInside",getParamf("eta",1.4f)); - const float etaOutside - = getParamf("etaOutside",1.f); + const float etaInside = getParamf("etaInside", getParamf("eta", 1.5f)); + const float etaOutside = getParamf("etaOutside", 1.f); ispcEquivalent = ispc::PathTracer_Glass_create (etaInside, (const ispc::vec3f&)transmissionInside, diff --git a/ospray/render/pathtracer/materials/Glass.ispc b/ospray/render/pathtracer/materials/Glass.ispc index 7ed53e5287..eb070bfae5 100644 --- a/ospray/render/pathtracer/materials/Glass.ispc +++ b/ospray/render/pathtracer/materials/Glass.ispc @@ -52,7 +52,7 @@ vec3f Glass_getTransparency(const uniform PathTraceMaterial* uniform material, float eta = eq(currentMedium, self->mediumOutside) ? self->mediumOutside.ior*rcp(self->mediumInside.ior) : self->mediumInside.ior*rcp(self->mediumOutside.ior); - float cosThetaO = max(dot(ray.dir, dg.Ns), 0.0f); + float cosThetaO = max(-dot(ray.dir, dg.Ns), 0.0f); return make_vec3f(1.0f-fresnelDielectric(cosThetaO, eta)); } diff --git a/ospray/render/pathtracer/materials/ThinGlass.cpp b/ospray/render/pathtracer/materials/ThinGlass.cpp index b0e1cf54d5..abf23b9b9e 100644 --- a/ospray/render/pathtracer/materials/ThinGlass.cpp +++ b/ospray/render/pathtracer/materials/ThinGlass.cpp @@ -29,9 +29,9 @@ namespace ospray { if (getIE() != NULL) return; const vec3f& transmission - = getParam3f("transmission",vec3f(1.f)); //vec3f(0.19,0.45,1.5)); + = getParam3f("transmission", vec3f(1.f)); const float eta - = getParamf("eta",1.4f); //vec3f(.4f,0.f,0.f)); + = getParamf("eta", 1.5f); const float thickness = getParamf("thickness",1.f); diff --git a/ospray/render/pathtracer/materials/ThinGlass.ispc b/ospray/render/pathtracer/materials/ThinGlass.ispc index 91e8e577ff..f6bf8ef2ba 100644 --- a/ospray/render/pathtracer/materials/ThinGlass.ispc +++ b/ospray/render/pathtracer/materials/ThinGlass.ispc @@ -47,8 +47,7 @@ vec3f ThinGlass_getTransparency(const uniform PathTraceMaterial* uniform materia { const uniform ThinGlass* uniform self = (const uniform ThinGlass* uniform)material; - float cosThetaO = max(dot(ray.dir, dg.Ns), 0.0f); - vec3f transmission = self->transmission; + float cosThetaO = max(-dot(ray.dir, dg.Ns), 0.0f); float alpha = self->thickness * rcp(cosThetaO); return powf(self->transmission, alpha) * (1.0f-fresnelDielectric(cosThetaO, self->eta)); } From f73237910d48b881b56decffcf70d26fa5dd8d1b Mon Sep 17 00:00:00 2001 From: atafra Date: Fri, 22 Apr 2016 19:43:38 +0300 Subject: [PATCH 229/310] moved sin2cos/cos2sin to math.ih --- ospray/math/math.ih | 3 +++ ospray/math/sampling.ih | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ospray/math/math.ih b/ospray/math/math.ih index c335e83a1c..2df0696c42 100644 --- a/ospray/math/math.ih +++ b/ospray/math/math.ih @@ -118,6 +118,9 @@ inline varying float deg2rad (const varying float x) { return x * 1.74532925199 inline uniform float rad2deg (const uniform float x) { return x * 5.72957795130823208768e1f; } inline varying float rad2deg (const varying float x) { return x * 5.72957795130823208768e1f; } +inline float cos2sin(const float f) { return sqrt(max(0.f, 1.f - f * f)); } +inline float sin2cos(const float f) { return cos2sin(f); } + inline uniform float nextafter(const uniform float a, const uniform float b) { //! Match the behavior of the C99 math.h function. diff --git a/ospray/math/sampling.ih b/ospray/math/sampling.ih index 843dd25ccb..35371aba1c 100644 --- a/ospray/math/sampling.ih +++ b/ospray/math/sampling.ih @@ -25,9 +25,6 @@ #include "ospray/math/vec.ih" -inline float cos2sin(const float f) { return sqrt(max(0.f, 1.f - f * f)); } -inline float sin2cos(const float f) { return cos2sin(f); } - inline vec3f cartesian(const float phi, const float sinTheta, const float cosTheta) { float sinPhi, cosPhi; From 4cf65090846e8af3dd7ea6c461a9244eb1cf78e7 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 22 Apr 2016 12:59:58 -0500 Subject: [PATCH 230/310] fix ambiguous naming in scivis renderer --- ospray/render/scivis/SciVisRenderer.ispc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index a711b7d4e3..8a8c543619 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -328,7 +328,7 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, { vec3f color = make_vec3f(0.f); float path_opacity = 1.f; - int depth = 0; + int path_depth = 0; float ray_t_depth = 0.f; while (1) { @@ -342,7 +342,7 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, } // Record depth of first hit in z buffer // - if (depth == 0) { + if (path_depth == 0) { ray_t_depth = ray.t; } @@ -365,14 +365,14 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, if (info.local_opacity > 0.01f) { // worth shading? shadeAO(self, sampleID, dg, info, color); - shadeLights(self, ray, dg, info, depth, color); + shadeLights(self, ray, dg, info, ray_t_depth, color); } // Kill path when reached max depth or if remaining contribution too low path_opacity = path_opacity * (1.f - info.d); - depth++; - if (depth >= self->maxDepth | path_opacity < 0.01f ) { - out_color = make_vec4f(color.x, color.y, color.z, 1.f); + path_depth++; + if (path_depth >= self->maxDepth || path_opacity < 0.01f ) { + out_color = make_vec4f(color.x, color.y, color.z, 1.f - path_opacity); ray.t = ray_t_depth; return; } @@ -532,7 +532,7 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, color = color + (1.0f - color.w) * volumeColor; } - } else if (firstHit == geometryRay.t) { + } else {// firstHit == geometryRay.t // Geometry contribution. color = color + (1.0f - color.w) * geometryColor; From bfa90f8e940c9202ad27a1ecfcc4358d326ab979 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 22 Apr 2016 13:07:13 -0500 Subject: [PATCH 231/310] Revert "cleanup unused code paths in scivis renderer" This reverts commit eeb49db65c1329f979ee09f576e32d811b7a1a37. --- ospray/render/scivis/SciVisRenderer.ispc | 110 +++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 8a8c543619..694c69df67 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -326,6 +326,39 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, varying Ray &ray, varying vec4f &out_color) { +#if 0 + //NOTE(jda) - no geometry opacity handled here... + + // We compute intersections on the model and provide the contribution for the + // closest hit. + traceRay(self->super.model, ray); + + // No hit found. + if(ray.geomID < 0) { + ray.t = infinity; + return; + } + + // Calculate material information from DG // + DifferentialGeometry dg; + postIntersect(self->super.model, dg, ray, + DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| + DG_MATERIALID|DG_COLOR|DG_TEXCOORD); + + SciVisShadingInfo info; + initShadingInfo(info); + + shadeMaterials(dg, info); + + info.local_opacity = info.d; + + vec3f color = make_vec3f(0.f); + + shadeAO(self, sampleID, dg, info, color); + shadeLights(self, ray, dg, info, 0/*depth*/, color); + + out_color = make_vec4f(color.x, color.y, color.z, 1.f); +#else vec3f color = make_vec3f(0.f); float path_opacity = 1.f; int path_depth = 0; @@ -384,6 +417,7 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, ray.geomID = -1; ray.instID = -1; } +#endif } /*! Returns the first hit volume for the provided ray and sets the ray bounds t0 and t, @@ -560,10 +594,85 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, // Main shading function // +inline +void SciVisRenderer_shadeRay(const uniform SciVisRenderer *uniform self, + varying ScreenSample &sample) +{ + Ray &ray = sample.ray; + // ISPC issue #703. Switch to 'nice' code once ISPC #703 is fixed. + // print("ray.dir % % %\n",ray.dir.x,ray.dir.y,ray.dir.z); + vec3f color = make_vec3f(0.f); + float path_opacity = 1.f; + int depth = 0; + + while (1) { + + traceRay(self->super.model, ray); + + // Record depth of first hit in z buffer // + if (depth == 0) { + sample.z = ray.t; + } + + // Check if we missed, if so we are done // + if (ray.geomID < 0) { + sample.rgb = self->super.backgroundEnabled ? + color + path_opacity * self->super.bgColor : + color; + sample.alpha = 1.f - path_opacity; + return; + } + + // Start shading // + + // Calculate material information from DG // + DifferentialGeometry dg; + postIntersect(self->super.model, + dg, + ray, + DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| + DG_MATERIALID|DG_COLOR|DG_TEXCOORD); + + SciVisShadingInfo info; + initShadingInfo(info); + + shadeMaterials(dg, info); + + info.local_opacity = path_opacity * info.d; + + if (info.local_opacity > 0.01f) { // worth shading? + shadeAO(self, sample.sampleID, dg, info, color); + shadeLights(self, ray, dg, info, depth, color); + } + + // kill path when reached max depth or if remaining contribution too low + path_opacity = path_opacity * (1.f - info.d); + depth++; + if (depth >= self->maxDepth | path_opacity < 0.01f ) { + sample.rgb = color; + sample.alpha = 1.f - path_opacity; + return; + } + + ray.t0 = ray.t + self->super.epsilon; + ray.t = infinity; + ray.primID = -1; + ray.geomID = -1; + ray.instID = -1; + } +} + void SciVisRenderer_renderSample(uniform Renderer *uniform _self, void *uniform perFrameData, varying ScreenSample &sample) { + //NOTE(jda) - Eliminate #if'd out code path when satisfied with surface only + // scene performance and features +#if 0 + uniform SciVisRenderer *uniform self = + (uniform SciVisRenderer *uniform)_self; + SciVisRenderer_shadeRay(self, sample); +#else SciVisRenderer *uniform renderer = (SciVisRenderer *uniform) _self; @@ -611,6 +720,7 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, sample.rgb.z = color.z; sample.alpha = color.w; sample.z = depth; +#endif } // Exports (called from C++) From 74e7e65f44f7c0e41b056c8b4236ad289936406b Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 22 Apr 2016 13:25:56 -0500 Subject: [PATCH 232/310] correct incorrect usage of shadeLights() fcn in scivis renderer --- ospray/render/scivis/SciVisRenderer.ispc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 694c69df67..b2dd60f4b7 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -223,7 +223,7 @@ inline void shadeLights(const uniform SciVisRenderer *uniform self, const varying Ray &ray, const varying DifferentialGeometry &dg, const varying SciVisShadingInfo &info, - const varying float depth, + const varying int path_depth, varying vec3f &color) { const vec3f R = ray.dir - ((2.f * dot(ray.dir, dg.Ns)) * dg.Ns); @@ -250,7 +250,7 @@ inline void shadeLights(const uniform SciVisRenderer *uniform self, const float light_alpha = lightAlpha(shadowRay, self->super.model, max_contrib, - self->maxDepth - depth, + self->maxDepth - path_depth, self->super.epsilon); color = color + light_alpha * light_contrib; } @@ -398,7 +398,7 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, if (info.local_opacity > 0.01f) { // worth shading? shadeAO(self, sampleID, dg, info, color); - shadeLights(self, ray, dg, info, ray_t_depth, color); + shadeLights(self, ray, dg, info, path_depth, color); } // Kill path when reached max depth or if remaining contribution too low @@ -648,7 +648,7 @@ void SciVisRenderer_shadeRay(const uniform SciVisRenderer *uniform self, // kill path when reached max depth or if remaining contribution too low path_opacity = path_opacity * (1.f - info.d); depth++; - if (depth >= self->maxDepth | path_opacity < 0.01f ) { + if (depth >= self->maxDepth || path_opacity < 0.01f ) { sample.rgb = color; sample.alpha = 1.f - path_opacity; return; @@ -668,7 +668,7 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, { //NOTE(jda) - Eliminate #if'd out code path when satisfied with surface only // scene performance and features -#if 0 +#if 1 uniform SciVisRenderer *uniform self = (uniform SciVisRenderer *uniform)_self; SciVisRenderer_shadeRay(self, sample); From df9ef53500fb356ac4b7f866dce400a17f668270 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 22 Apr 2016 13:31:20 -0500 Subject: [PATCH 233/310] eliminate PassInfo in scivis renderer (DD volumes are not supported yet) --- ospray/render/scivis/SciVisRenderer.ispc | 58 +++++------------------- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index b2dd60f4b7..3bfe3f9a58 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -30,8 +30,7 @@ #define ALPHA_THRESHOLD (.05f) -// Data types -////////////////////////////////////////////////////////////////////////////// +// Data types ///////////////////////////////////////////////////////////////// struct SciVisRenderer { @@ -61,17 +60,7 @@ struct SciVisShadingInfo vec3f geometryColor; }; -struct PassInfo { - // region to integrate over in this pass - varying region1f region; - // block to use in this pass - NULL for 'everything other than blocks' - DDBVolumeBlock *uniform block; - // blend in background color when ray misses - uniform bool useBG; -}; - -// Function definitions -/////////////////////////////////////////////////////////////////////////////// +// Function definitions /////////////////////////////////////////////////////// inline void initShadingInfo(varying SciVisShadingInfo &info) { @@ -426,7 +415,6 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, inline Volume * SciVisRenderer_intersectVolumes(uniform SciVisRenderer *uniform renderer, varying Ray &ray, - const uniform PassInfo &passInfo, const varying float &rayOffset) { // The first intersected volume. @@ -476,19 +464,11 @@ SciVisRenderer_intersectVolumes(uniform SciVisRenderer *uniform renderer, /*! This function intersects the volume and geometries. */ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, varying Ray &ray, - const uniform PassInfo &passInfo, const varying float &rayOffset, const varying vec3i &sampleID, varying vec4f &color, varying float &depth) { - const region1f clipRange = passInfo.region; - - if (clipRange.lower != 0.f) { - ray.t0 = max(ray.t0,clipRange.lower); - ray.t = min(ray.t,clipRange.upper); - } - // Original tMax for ray interval const float tMax = ray.t; @@ -518,8 +498,7 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, geometryRay.instID = -1; // Get first intersected volume for each ray and set the ray bounds. - Volume *volume = SciVisRenderer_intersectVolumes(renderer, ray, - passInfo, rayOffset); + Volume *volume = SciVisRenderer_intersectVolumes(renderer, ray, rayOffset); // Provide ray offset for use with isosurface geometries (this value // ignored elsewhere). @@ -541,8 +520,9 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, // Trace the ray through the volume and geometries. float firstHit; - while ((firstHit = min(ray.t0, geometryRay.t)) < min(tMax,clipRange.upper) - && min(min(color.x, color.y), color.z) < 1.0f && color.w < 0.99f) { + while ((firstHit = min(ray.t0, geometryRay.t)) < tMax + && min(min(color.x, color.y), color.z) < 1.0f + && color.w < 0.99f) { if (firstHit == ray.t0) { // Check to see if we've exited the current volume. @@ -550,8 +530,7 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, ray.t0 = ray.t + epsilon; ray.t = tMax; - volume = SciVisRenderer_intersectVolumes(renderer, ray, - passInfo, rayOffset); + volume = SciVisRenderer_intersectVolumes(renderer, ray, rayOffset); } else { if (any(volume == NULL)) @@ -668,7 +647,7 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, { //NOTE(jda) - Eliminate #if'd out code path when satisfied with surface only // scene performance and features -#if 1 +#if 0 uniform SciVisRenderer *uniform self = (uniform SciVisRenderer *uniform)_self; SciVisRenderer_shadeRay(self, sample); @@ -676,12 +655,6 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, SciVisRenderer *uniform renderer = (SciVisRenderer *uniform) _self; - PassInfo *uniform passInfo - = (PassInfo *uniform)perFrameData; - - // Background color. - const uniform bool useBG = ((passInfo == NULL) || passInfo->useBG); - // Ray offset for this sample, as a fraction of the nominal step size. float rayOffset = precomputedHalton2(sample.sampleID.z); int ix = sample.sampleID.x % 4; @@ -696,20 +669,11 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, vec4f color = make_vec4f(0.0f,0.f,0.f,0.f); float depth = infinity; - if (passInfo != NULL) { - SciVisRenderer_intersect(renderer, sample.ray, *passInfo, - rayOffset, sample.sampleID, color, depth); - } else { - uniform PassInfo dummyPassInfo; - dummyPassInfo.region = make_region1f(0.f,inf); - dummyPassInfo.useBG = true; - dummyPassInfo.block = NULL; - SciVisRenderer_intersect(renderer, sample.ray, dummyPassInfo, - rayOffset, sample.sampleID, color, depth); - } + SciVisRenderer_intersect(renderer, sample.ray, rayOffset, + sample.sampleID, color, depth); // Attenuate the foreground and background colors by the opacity. - if (useBG && renderer->super.backgroundEnabled) { + if (renderer->super.backgroundEnabled) { const vec4f background = make_vec4f(renderer->super.bgColor, 1.f); color = color.w * color + (1.0f - color.w) * background; } From 2d10c44921385191e4edc3f73e24ebc5b4bdbace Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 22 Apr 2016 14:51:47 -0500 Subject: [PATCH 234/310] fix transparency bug (found by vtk test) --- ospray/render/scivis/SciVisRenderer.ispc | 48 +++++------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 3bfe3f9a58..eb77b8f43d 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -315,39 +315,6 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, varying Ray &ray, varying vec4f &out_color) { -#if 0 - //NOTE(jda) - no geometry opacity handled here... - - // We compute intersections on the model and provide the contribution for the - // closest hit. - traceRay(self->super.model, ray); - - // No hit found. - if(ray.geomID < 0) { - ray.t = infinity; - return; - } - - // Calculate material information from DG // - DifferentialGeometry dg; - postIntersect(self->super.model, dg, ray, - DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| - DG_MATERIALID|DG_COLOR|DG_TEXCOORD); - - SciVisShadingInfo info; - initShadingInfo(info); - - shadeMaterials(dg, info); - - info.local_opacity = info.d; - - vec3f color = make_vec3f(0.f); - - shadeAO(self, sampleID, dg, info, color); - shadeLights(self, ray, dg, info, 0/*depth*/, color); - - out_color = make_vec4f(color.x, color.y, color.z, 1.f); -#else vec3f color = make_vec3f(0.f); float path_opacity = 1.f; int path_depth = 0; @@ -359,11 +326,11 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, // Check if we missed, if so we are done // if (ray.geomID < 0) { - ray.t = infinity; + out_color = make_vec4f(color.x, color.y, color.z, 1.f - path_opacity); return; } - // Record depth of first hit in z buffer // + // Record depth of first hit for depth output // if (path_depth == 0) { ray_t_depth = ray.t; } @@ -406,7 +373,6 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, ray.geomID = -1; ray.instID = -1; } -#endif } /*! Returns the first hit volume for the provided ray and sets the ray bounds t0 and t, @@ -520,9 +486,13 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, // Trace the ray through the volume and geometries. float firstHit; + // Geometry contribution. + color = color + (1.0f - color.w) * geometryColor; + while ((firstHit = min(ray.t0, geometryRay.t)) < tMax - && min(min(color.x, color.y), color.z) < 1.0f + /*&& min(min(color.x, color.y), color.z) < 1.0f*///<--why is this here? && color.w < 0.99f) { + if (firstHit == ray.t0) { // Check to see if we've exited the current volume. @@ -531,6 +501,7 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, ray.t0 = ray.t + epsilon; ray.t = tMax; volume = SciVisRenderer_intersectVolumes(renderer, ray, rayOffset); + } else { if (any(volume == NULL)) @@ -545,6 +516,7 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, color = color + (1.0f - color.w) * volumeColor; } + } else {// firstHit == geometryRay.t // Geometry contribution. @@ -666,7 +638,7 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, // Provide the renderer to the intersector as it contains all // volumes, geometries, etc. - vec4f color = make_vec4f(0.0f,0.f,0.f,0.f); + vec4f color = make_vec4f(0.0f); float depth = infinity; SciVisRenderer_intersect(renderer, sample.ray, rayOffset, From 1d4abe7212e8aa80d13100d918b52eea603e8ec7 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 22 Apr 2016 14:57:08 -0500 Subject: [PATCH 235/310] cleanup unused code in scivis renderer --- ospray/render/scivis/SciVisRenderer.ispc | 78 ------------------------ 1 file changed, 78 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index eb77b8f43d..a8313c0e69 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -543,87 +543,10 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, } } -// Main shading function // - -inline -void SciVisRenderer_shadeRay(const uniform SciVisRenderer *uniform self, - varying ScreenSample &sample) -{ - Ray &ray = sample.ray; - // ISPC issue #703. Switch to 'nice' code once ISPC #703 is fixed. - // print("ray.dir % % %\n",ray.dir.x,ray.dir.y,ray.dir.z); - vec3f color = make_vec3f(0.f); - float path_opacity = 1.f; - int depth = 0; - - while (1) { - - traceRay(self->super.model, ray); - - // Record depth of first hit in z buffer // - if (depth == 0) { - sample.z = ray.t; - } - - // Check if we missed, if so we are done // - if (ray.geomID < 0) { - sample.rgb = self->super.backgroundEnabled ? - color + path_opacity * self->super.bgColor : - color; - sample.alpha = 1.f - path_opacity; - return; - } - - // Start shading // - - // Calculate material information from DG // - DifferentialGeometry dg; - postIntersect(self->super.model, - dg, - ray, - DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD| - DG_MATERIALID|DG_COLOR|DG_TEXCOORD); - - SciVisShadingInfo info; - initShadingInfo(info); - - shadeMaterials(dg, info); - - info.local_opacity = path_opacity * info.d; - - if (info.local_opacity > 0.01f) { // worth shading? - shadeAO(self, sample.sampleID, dg, info, color); - shadeLights(self, ray, dg, info, depth, color); - } - - // kill path when reached max depth or if remaining contribution too low - path_opacity = path_opacity * (1.f - info.d); - depth++; - if (depth >= self->maxDepth || path_opacity < 0.01f ) { - sample.rgb = color; - sample.alpha = 1.f - path_opacity; - return; - } - - ray.t0 = ray.t + self->super.epsilon; - ray.t = infinity; - ray.primID = -1; - ray.geomID = -1; - ray.instID = -1; - } -} - void SciVisRenderer_renderSample(uniform Renderer *uniform _self, void *uniform perFrameData, varying ScreenSample &sample) { - //NOTE(jda) - Eliminate #if'd out code path when satisfied with surface only - // scene performance and features -#if 0 - uniform SciVisRenderer *uniform self = - (uniform SciVisRenderer *uniform)_self; - SciVisRenderer_shadeRay(self, sample); -#else SciVisRenderer *uniform renderer = (SciVisRenderer *uniform) _self; @@ -656,7 +579,6 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, sample.rgb.z = color.z; sample.alpha = color.w; sample.z = depth; -#endif } // Exports (called from C++) From ad177ead2d4fbe599c509a490aa309420c7f2205 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Sat, 23 Apr 2016 13:30:28 -0500 Subject: [PATCH 236/310] added clamp() fct for varying vec3fs --- ospray/math/vec.ih | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index fb23d34663..6fb32cdd66 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -723,6 +723,9 @@ inline uniform vec3f powf(const uniform vec3f v, const uniform float f) inline vec3f clamp(const vec3f &a, const uniform vec3f &b, const uniform vec3f &c) { return(make_vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); } +inline vec3f clamp(const vec3f &a, const vec3f &b, const vec3f &c) +{ return(make_vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); } + inline vec3i clamp(const vec3i &a, const uniform vec3i &b, const uniform vec3i &c) { return(make_vec3i(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); } From d1d29660b3d2c390421f9a1c4aa05fc8d9e01931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 22 Apr 2016 15:15:27 +0200 Subject: [PATCH 237/310] API change: rework FrameBuffer to support sRGB format, remove gamma parameter --- apps/modelViewer/modelViewer.cpp | 6 +- apps/ospTutorial.cpp | 2 +- apps/particleViewer/ParticleViewer.cpp | 4 +- apps/qtViewer/sg/common/FrameBuffer.h | 4 +- apps/streamLineViewer/StreamLineViewer.cpp | 4 +- apps/volumeViewer/QOSPRayWindow.cpp | 6 +- ospray/fb/FrameBuffer.cpp | 6 - ospray/fb/FrameBuffer.h | 29 ----- ospray/fb/FrameBuffer.ih | 9 +- ospray/fb/FrameBuffer.ispc | 7 -- ospray/fb/LocalFB.cpp | 22 ++-- ospray/fb/LocalFB.ispc | 120 +++++++------------- ospray/include/ospray/ospray.h | 53 ++++----- ospray/mpi/DistributedFrameBuffer.cpp | 52 +++++---- ospray/mpi/DistributedFrameBuffer.h | 2 + ospray/mpi/DistributedFrameBuffer.ispc | 123 ++++++++++----------- 16 files changed, 181 insertions(+), 268 deletions(-) diff --git a/apps/modelViewer/modelViewer.cpp b/apps/modelViewer/modelViewer.cpp index 1344ff7e6a..80e22f0f79 100644 --- a/apps/modelViewer/modelViewer.cpp +++ b/apps/modelViewer/modelViewer.cpp @@ -162,11 +162,9 @@ namespace ospray { g_windowSize = newSize; if (fb) ospFreeFrameBuffer(fb); fb = ospNewFrameBuffer((const osp::vec2i&)newSize, - OSP_RGBA_I8, + OSP_FB_SRGBA, OSP_FB_COLOR|OSP_FB_DEPTH| OSP_FB_ACCUM|OSP_FB_VARIANCE); - ospSet1f(fb, "gamma", 2.2f); - ospCommit(fb); ospFrameBufferClear(fb,OSP_FB_ACCUM); /*! for now, let's just attach the pixel op to the _main_ frame @@ -176,7 +174,7 @@ namespace ospray { if (displayWall && displayWall->fb != fb) { PRINT(displayWall->size); displayWall->fb = ospNewFrameBuffer((const osp::vec2i&)displayWall->size, - OSP_RGBA_NONE,OSP_FB_COLOR| + OSP_FB_NONE,OSP_FB_COLOR| OSP_FB_DEPTH|OSP_FB_ACCUM); ospFrameBufferClear(displayWall->fb,OSP_FB_ACCUM); if (displayWall->po == NULL) { diff --git a/apps/ospTutorial.cpp b/apps/ospTutorial.cpp index 4afc2b6377..5ac12c82b9 100644 --- a/apps/ospTutorial.cpp +++ b/apps/ospTutorial.cpp @@ -121,7 +121,7 @@ int main(int ac, const char **av) { // create and setup framebuffer - OSPFrameBuffer framebuffer = ospNewFrameBuffer(imgSize, OSP_RGBA_I8, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); + OSPFrameBuffer framebuffer = ospNewFrameBuffer(imgSize, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); ospFrameBufferClear(framebuffer, OSP_FB_COLOR | OSP_FB_ACCUM); // render one frame diff --git a/apps/particleViewer/ParticleViewer.cpp b/apps/particleViewer/ParticleViewer.cpp index 5e46c12aa8..0b9215c4c7 100644 --- a/apps/particleViewer/ParticleViewer.cpp +++ b/apps/particleViewer/ParticleViewer.cpp @@ -91,9 +91,7 @@ namespace ospray { Glut3DWidget::reshape(_newSize); if (fb) ospFreeFrameBuffer(fb); const auto &newSize = reinterpret_cast(_newSize); - fb = ospNewFrameBuffer(newSize,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_ACCUM); - ospSet1f(fb, "gamma", 2.2f); - ospCommit(fb); + fb = ospNewFrameBuffer(newSize, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); ospFrameBufferClear(fb,OSP_FB_ACCUM); accumID = 0; ospSetf(camera,"aspect",viewPort.aspect); diff --git a/apps/qtViewer/sg/common/FrameBuffer.h b/apps/qtViewer/sg/common/FrameBuffer.h index 9f3ee95084..0fa30621ed 100644 --- a/apps/qtViewer/sg/common/FrameBuffer.h +++ b/apps/qtViewer/sg/common/FrameBuffer.h @@ -65,9 +65,7 @@ namespace ospray { inline void FrameBuffer::createFB() { - ospFrameBuffer = ospNewFrameBuffer((const osp::vec2i&)size,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_ACCUM); - ospSet1f(ospFrameBuffer, "gamma", 2.2f); - ospCommit(ospFrameBuffer); + ospFrameBuffer = ospNewFrameBuffer((const osp::vec2i&)size, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); } inline void FrameBuffer::destroyFB() diff --git a/apps/streamLineViewer/StreamLineViewer.cpp b/apps/streamLineViewer/StreamLineViewer.cpp index 1ea260339a..ad10fffd29 100644 --- a/apps/streamLineViewer/StreamLineViewer.cpp +++ b/apps/streamLineViewer/StreamLineViewer.cpp @@ -585,9 +585,7 @@ namespace ospray { { Glut3DWidget::reshape(newSize); if (fb) ospFreeFrameBuffer(fb); - fb = ospNewFrameBuffer((const osp::vec2i&)newSize,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_ACCUM); - ospSet1f(fb, "gamma", 2.2f); - ospCommit(fb); + fb = ospNewFrameBuffer((const osp::vec2i&)newSize, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); ospSetf(camera,"aspect",viewPort.aspect); ospCommit(camera); } diff --git a/apps/volumeViewer/QOSPRayWindow.cpp b/apps/volumeViewer/QOSPRayWindow.cpp index c9b5538b54..3e54c39a7b 100644 --- a/apps/volumeViewer/QOSPRayWindow.cpp +++ b/apps/volumeViewer/QOSPRayWindow.cpp @@ -222,11 +222,7 @@ void QOSPRayWindow::resizeGL(int width, int height) if(frameBuffer) ospFreeFrameBuffer(frameBuffer); - frameBuffer = ospNewFrameBuffer((const osp::vec2i&)windowSize, OSP_RGBA_I8, OSP_FB_COLOR | OSP_FB_ACCUM); - - // set gamma correction - ospSet1f(frameBuffer, "gamma", 1.0f); - ospCommit(frameBuffer); + frameBuffer = ospNewFrameBuffer((const osp::vec2i&)windowSize, OSP_FB_SRGBA, OSP_FB_COLOR | OSP_FB_ACCUM); resetAccumulationBuffer(); diff --git a/ospray/fb/FrameBuffer.cpp b/ospray/fb/FrameBuffer.cpp index f89a0430ab..065eb484cd 100644 --- a/ospray/fb/FrameBuffer.cpp +++ b/ospray/fb/FrameBuffer.cpp @@ -35,12 +35,6 @@ namespace ospray { Assert(size.x > 0 && size.y > 0); } - void FrameBuffer::commit() - { - const float gamma = getParam1f("gamma", 1.0f); - ispc::FrameBuffer_set_gamma(ispcEquivalent, gamma); - } - /*! helper function for debugging. write out given pixels in PPM format */ void writePPM(const std::string &fileName, const vec2i &size, const uint32 *pixels) { diff --git a/ospray/fb/FrameBuffer.h b/ospray/fb/FrameBuffer.h index 4e9844b1c5..15bd154a01 100644 --- a/ospray/fb/FrameBuffer.h +++ b/ospray/fb/FrameBuffer.h @@ -24,33 +24,6 @@ namespace ospray { - /*! helper function to convert float-color into rgba-uint format */ - inline uint32 cvt_uint32(const float f) - { - return (int32)(255.9f * std::max(std::min(f,1.f),0.f)); - } - - /*! helper function to convert float-color into rgba-uint format */ - inline uint32 cvt_uint32(const vec4f &v) - { - return - (cvt_uint32(v.x) << 0) | - (cvt_uint32(v.y) << 8) | - (cvt_uint32(v.z) << 16) | - (cvt_uint32(v.w) << 24); - } - - /*! helper function to convert float-color into rgba-uint format */ - inline uint32 cvt_uint32(const vec3f &v) - { - return - (cvt_uint32(v.x) << 0) | - (cvt_uint32(v.y) << 8) | - (cvt_uint32(v.z) << 16); - } - - - /*! abstract frame buffer class */ struct FrameBuffer : public ManagedObject { /*! app-mappable format of the color buffer. make sure that this @@ -64,8 +37,6 @@ namespace ospray { bool hasAccumBuffer, bool hasVarianceBuffer = false); - virtual void commit(); - virtual const void *mapDepthBuffer() = 0; virtual const void *mapColorBuffer() = 0; diff --git a/ospray/fb/FrameBuffer.ih b/ospray/fb/FrameBuffer.ih index b1548c49ac..ce9781e806 100644 --- a/ospray/fb/FrameBuffer.ih +++ b/ospray/fb/FrameBuffer.ih @@ -37,7 +37,6 @@ struct FrameBuffer { vec2i size; /*!< size (width x height) of frame buffer, in pixels */ vec2f rcpSize; /*! one over size (precomputed) */ - uniform float invGamma; /*! 1/gamma for gamma correction */ FrameBuffer_ColorBufferFormat colorBufferFormat; @@ -71,6 +70,14 @@ inline uint32 cvt_uint32(const vec3f &v) (cvt_uint32(v.z) << 16); } +/*! helper function to convert float-color into srgba format */ +inline uint32 cvt_srgba(const vec4f &v) +{ + // alpha is never gamma-corrected + // approximate sRGB transfer curve with gamma 2.2 + return cvt_uint32(make_vec4f(pow(make_vec3f(v), 1/2.2f), v.w)); +} + void FrameBuffer_Constructor(FrameBuffer *uniform self, void *uniform cClassPtr); diff --git a/ospray/fb/FrameBuffer.ispc b/ospray/fb/FrameBuffer.ispc index 6a321f4722..761e979562 100644 --- a/ospray/fb/FrameBuffer.ispc +++ b/ospray/fb/FrameBuffer.ispc @@ -38,10 +38,3 @@ void FrameBuffer_set(FrameBuffer *uniform self, self->rcpSize.y = 1.f/size_y; self->colorBufferFormat = (uniform FrameBuffer_ColorBufferFormat)colorBufferFormat; } - -export void FrameBuffer_set_gamma(void *uniform _self, - const uniform float gamma) -{ - uniform FrameBuffer *uniform self = (uniform FrameBuffer *uniform)_self; - self->invGamma = 1.0f/gamma; -} diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index a99e131d5e..20a50649c5 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -34,14 +34,15 @@ namespace ospray { if (colorBufferToUse) colorBuffer = colorBufferToUse; else { - switch(colorBufferFormat) { - case OSP_RGBA_NONE: + switch (colorBufferFormat) { + case OSP_FB_NONE: colorBuffer = NULL; break; - case OSP_RGBA_F32: + case OSP_FB_RGBA8: + case OSP_FB_SRGBA: colorBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); break; - case OSP_RGBA_I8: + case OSP_FB_RGBA32F: colorBuffer = (uint32*)alignedMalloc(sizeof(uint32)*size.x*size.y); break; default: @@ -128,12 +129,15 @@ namespace ospray { if (pixelOp) pixelOp->postAccum(tile); if (colorBuffer) { - switch(colorBufferFormat) { - case OSP_RGBA_I8: - ispc::LocalFrameBuffer_writeTile_RGBA_I8(getIE(),(ispc::Tile&)tile); + switch (colorBufferFormat) { + case OSP_FB_RGBA8: + ispc::LocalFrameBuffer_writeTile_RGBA8(getIE(),(ispc::Tile&)tile); break; - case OSP_RGBA_F32: - ispc::LocalFrameBuffer_writeTile_RGBA_F32(getIE(),(ispc::Tile&)tile); + case OSP_FB_SRGBA: + ispc::LocalFrameBuffer_writeTile_SRGBA(getIE(),(ispc::Tile&)tile); + break; + case OSP_FB_RGBA32F: + ispc::LocalFrameBuffer_writeTile_RGBA32F(getIE(),(ispc::Tile&)tile); break; default: NOTIMPLEMENTED; diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index 7d54777e23..e0fd3c294d 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -18,88 +18,50 @@ //! \brief write tile into the given frame buffer's color buffer /*! \detailed this buffer _must_ exist when this fct is called, and it - _must_ have RGBA_I8 format */ -export void LocalFrameBuffer_writeTile_RGBA_I8(void *uniform _fb, - uniform Tile &tile) -{ - uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - uniform uint32 *uniform color = (uniform uint32 *uniform)fb->colorBuffer; - uniform float *uniform depth = (uniform float *uniform)fb->depthBuffer; - if (!color) - // actually, this should never happen ... - return; - - VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; - for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; - - uniform uint32 chunkID = iy*(TILE_SIZE/programCount); - - for (uint32 iix = tile.region.lower.x+programIndex; - iixsuper.size.x+iix; - unmasked { - varying vec4f col = make_vec4f(varyTile->r[chunkID], - varyTile->g[chunkID], - varyTile->b[chunkID], - varyTile->a[chunkID]); - - // NOTE(jda) - no longer hardcoded, but should use pixelops - col = max(col,make_vec4f(0.f)); - // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), fb->super.invGamma), col.w); - - const uint32 asRGBA = cvt_uint32(col); - } - color[pixelID] = asRGBA; - if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; - } - } + _must_ have format 'name' */ +#define template_writeTile(name, type, cvt) \ +export void LocalFrameBuffer_writeTile_##name(void *uniform _fb, \ + uniform Tile &tile) \ +{ \ + uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; \ + uniform type *uniform color = (uniform type *uniform)fb->colorBuffer; \ + uniform float *uniform depth = (uniform float *uniform)fb->depthBuffer; \ + if (!color) \ + /* actually, this should never happen ... */ \ + return; \ + \ + VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; \ + for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; \ + \ + uniform uint32 chunkID = iy*(TILE_SIZE/programCount); \ + \ + for (uint32 iix = tile.region.lower.x+programIndex; \ + iixsuper.size.x+iix; \ + unmasked { \ + varying vec4f col = make_vec4f(varyTile->r[chunkID], \ + varyTile->g[chunkID], \ + varyTile->b[chunkID], \ + varyTile->a[chunkID]); \ + \ + col = max(col,make_vec4f(0.f)); \ + const type cvtCol = cvt(col); \ + } \ + color[pixelID] = cvtCol; \ + if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; \ + } \ + } \ } -//! \brief write tile into the given frame buffer's color buffer -/*! \detailed this buffer _must_ exist when this fct is called, and it - _must_ have RGBA_F32 format */ -export void LocalFrameBuffer_writeTile_RGBA_F32(void *uniform _fb, - uniform Tile &tile) -{ - uniform LocalFB *uniform fb = (uniform LocalFB *uniform)_fb; - uniform vec4f *uniform color = (uniform vec4f *uniform)fb->colorBuffer; - uniform float *uniform depth = (uniform float *uniform)fb->depthBuffer; - if (!color) - // actually, this should never happen ... - return; - - VaryingTile *uniform varyTile = (VaryingTile *uniform)&tile; - for (uniform uint32 iy=0;iy= tile.region.upper.y) continue; - - uniform uint32 chunkID = iy*(TILE_SIZE/programCount); - - for (uint32 iix = tile.region.lower.x+programIndex; - iixsuper.size.x+iix; - unmasked { - varying vec4f col = make_vec4f(varyTile->r[chunkID], - varyTile->g[chunkID], - varyTile->b[chunkID], - varyTile->a[chunkID]); - - // NOTE(jda) - no longer hardcoded, but should use pixelops - col = max(col, make_vec4f(0.f)); - // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), fb->super.invGamma), col.w); - } - color[pixelID] = col; - if (depth) fb->depthBuffer[pixelID] = varyTile->z[chunkID]; - } - } -} +template_writeTile(RGBA8, uint32, cvt_uint32); +template_writeTile(SRGBA, uint32, cvt_srgba); +inline vec4f cvt_nop(const vec4f &v) { return v; }; +template_writeTile(RGBA32F, vec4f, cvt_nop); +#undef template_writeTile //! \brief accumulate tile into BOTH accum buffer AND tile. diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index f7f1eed298..6a634bca07 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -66,20 +66,23 @@ typedef enum { OSP_FB_NONE, //!< framebuffer will not be mapped by application OSP_FB_RGBA8, //!< one dword per pixel: rgb+alpha, each one byte + OSP_FB_SRGBA, //!< one dword per pixel: rgb (in sRGB space) + alpha, each one byte OSP_FB_RGBA32F, //!< one float4 per pixel: rgb+alpha, each one float - /* TODO - OSP_FB_RGB8, //!< three 8-bit unsigned chars per pixel - OSP_FB_RGB32F, ? - OSP_FB_SRGBA, //!< one dword per pixel: rgb (in sRGB space) + alpha, each one byte - OSP_FB_SRGB, //!< three 8-bit unsigned chars (in sRGB space) per pixel - */ - // deprecated names - OSP_RGBA_NONE = OSP_FB_NONE, - OSP_RGBA_I8 = OSP_FB_RGBA8, - OSP_RGBA_F32 = OSP_FB_RGBA32F, - OSP_RGB_I8/* = OSP_FB_RGB8 XXX unsupported! */ +/* TODO + OSP_FB_RGB8, //!< three 8-bit unsigned chars per pixel + OSP_FB_RGB32F, ? + OSP_FB_SRGB, //!< three 8-bit unsigned chars (in sRGB space) per pixel +*/ } OSPFrameBufferFormat; +/*! OSPRay channel constants for Frame Buffer (can be OR'ed together) */ +typedef enum { + OSP_FB_COLOR=(1<<0), + OSP_FB_DEPTH=(1<<1), + OSP_FB_ACCUM=(1<<2), + OSP_FB_VARIANCE=(1<<3) +} OSPFrameBufferChannel; + //! constants for switching the OSPRay MPI Scope between 'per rank' and 'all ranks' /*! \see ospdApiMode */ typedef enum { @@ -132,14 +135,6 @@ typedef enum { OSP_GENERAL_ERROR /*! unspecified error */ } OSPResult; -/*! OSPRay channel constants for Frame Buffer (can be OR'ed together) */ -typedef enum { - OSP_FB_COLOR=(1<<0), - OSP_FB_DEPTH=(1<<1), - OSP_FB_ACCUM=(1<<2), - OSP_FB_VARIANCE=(1<<3) -} OSPFrameBufferChannel; - typedef enum { OSPD_Z_COMPOSITE } OSPDRenderMode; @@ -390,8 +385,8 @@ extern "C" { \param externalFormat describes the format the color buffer has *on the host*, and the format that 'ospMapFrameBuffer' will - eventually return. Valid values are OSP_FB_RBGA_FLOAT, - OSP_FB_RBGA_I8, OSP_FB_RGB_I8, and OSP_FB_NONE (note that + eventually return. Valid values are OSP_FB_SRGBA, OSP_FB_RGBA8, + OSP_FB_RGBA32F, and OSP_FB_NONE (note that OSP_FB_NONE is a perfectly reasonably choice for a framebuffer that will be used only internally, see notes below). The origin of the screen coordinate system is the lower left @@ -425,10 +420,6 @@ extern "C" { format of OSP_FB_NONE the pixels from the path tracing stage will never ever be transferred to the application. */ - // OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, - // const OSPFrameBufferFormat OSP_DEFAULT_VAL(=OSP_RGBA_I8), - // const uint32_t whichChannels OSP_DEFAULT_VAL(=OSP_FB_COLOR)); - OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const int32_t *size /*!< 2 ints: width x height */, const OSPFrameBufferFormat format, const uint32_t whichChannels); @@ -692,7 +683,7 @@ extern "C" { #ifdef __cplusplus extern "C++" { - /*! c++ version with references */ + /*! C++ version with references */ inline void ospPick(OSPPickResult *result, OSPRenderer renderer, const osp::vec2f &screenPos) { ospPick(result,renderer,&screenPos.x); } @@ -702,21 +693,21 @@ extern "C++" { const size_t &count) { ospSampleVolume(&results,volume,(const float *)worldCoordinates,count); } - /*! c++ variant of this function that uses references rather than pointers */ - extern "C++" inline OSPTexture2D ospNewTexture2D(const osp::vec2i &size, + /*! C++ variant of this function that uses references rather than pointers */ + inline OSPTexture2D ospNewTexture2D(const osp::vec2i &size, const OSPTextureFormat format, void *data = NULL, const uint32_t flags = 0) { return ospNewTexture2D(&size.x,format,data,flags); } - /*! c++ variant of ospNewFrameBuffer that can also be called with + /*! C++ variant of ospNewFrameBuffer that can also be called with references rather than with pointers */ inline OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, - const OSPFrameBufferFormat format=OSP_RGBA_I8, + const OSPFrameBufferFormat format=OSP_FB_SRGBA, const uint32_t whichChannels=OSP_FB_COLOR) { return ospNewFrameBuffer(&size.x,format,whichChannels); } - /*! c++ variant that uses refreences rather than pointerts */ + /*! C++ variant that uses refreences rather than pointerts */ inline int ospSetRegion(/*! the object we're writing this block of pixels into */ OSPVolume object, /* points to the first voxel to be copies. The diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index e0758a4336..aa5c409d58 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -82,6 +82,26 @@ namespace ospray { Mutex gMutex; + void DFB::TileData::accumulate(const ospray::Tile &tile) + { + switch(dfb->colorBufferFormat) { + case OSP_FB_RGBA8: + ispc::DFB_accumulate_RGBA8(dfb->ispcEquivalent, + (ispc::VaryingTile *)&tile, + (ispc::VaryingTile*)&this->final, + (ispc::VaryingTile*)&this->accum, + (ispc::VaryingRGBA_I8*)&this->color, + dfb->hasAccumBuffer); + case OSP_FB_SRGBA: + ispc::DFB_accumulate_SRGBA(dfb->ispcEquivalent, + (ispc::VaryingTile *)&tile, + (ispc::VaryingTile*)&this->final, + (ispc::VaryingTile*)&this->accum, + (ispc::VaryingRGBA_I8*)&this->color, + dfb->hasAccumBuffer); + } + } + /*! called exactly once for each ospray::Tile that needs to get written into / composited into this dfb tile */ void DFB::AlphaBlendTile_simple::process(const ospray::Tile &tile) @@ -128,13 +148,7 @@ namespace ospray { this->final.region = tile.region; this->final.fbSize = tile.fbSize; this->final.rcp_fbSize = tile.rcp_fbSize; - ispc::DFB_accumulate(dfb->ispcEquivalent, - (ispc::VaryingTile *)&bufferedTile[0]->tile, - (ispc::VaryingTile *)&this->final, - (ispc::VaryingTile *)&this->accum, - (ispc::VaryingRGBA_I8 *)&this->color, - dfb->hasAccumBuffer); - + accumulate(bufferedTile[0]->tile); dfb->tileIsCompleted(this); for (int i=0;ifinal.region = tile.region; this->final.fbSize = tile.fbSize; this->final.rcp_fbSize = tile.rcp_fbSize; - ispc::DFB_accumulate(dfb->ispcEquivalent, - (ispc::VaryingTile *)&tile, - (ispc::VaryingTile*)&this->final, - (ispc::VaryingTile*)&this->accum, - (ispc::VaryingRGBA_I8*)&this->color, - dfb->hasAccumBuffer); + accumulate(tile); dfb->tileIsCompleted(this); } - void DFB::ZCompositeTile::newFrame() { numPartsComposited = 0; @@ -194,12 +202,7 @@ namespace ospray { } if (done) { - ispc::DFB_accumulate(dfb->ispcEquivalent, - (ispc::VaryingTile*)&this->compositedTileData, - (ispc::VaryingTile*)&this->final, - (ispc::VaryingTile*)&this->accum, - (ispc::VaryingRGBA_I8*)&this->color, - dfb->hasAccumBuffer); + accumulate(this->compositedTileData); dfb->tileIsCompleted(this); } } @@ -311,7 +314,7 @@ namespace ospray { createTiles(); if (comm->group->rank == 0) { - if (colorBufferFormat == OSP_RGBA_NONE) { + if (colorBufferFormat == OSP_FB_NONE) { cout << "#osp:mpi:dfb: we're the master, but framebuffer has 'NONE' " << "format; creating distriubted frame buffer WITHOUT having a " << "mappable copy on the master" << endl; @@ -439,7 +442,7 @@ namespace ospray { } switch(colorBufferFormat) { - case OSP_RGBA_NONE: { + case OSP_FB_NONE: { /* if the master doesn't have a framebufer (i.e., format 'none'), we're only telling it that we're done, but are not sending any pixels */ @@ -448,8 +451,9 @@ namespace ospray { mtm->coords = tile->begin; comm->sendTo(this->master,mtm,sizeof(*mtm)); } break; - case OSP_RGBA_I8: { - /*! if the master has rgba_i8 format, we're sending him a tile + case OSP_FB_RGBA8: + case OSP_FB_SRGBA: { + /*! if the master has RGBA8 or SRGBA format, we're sending him a tile of the proper data */ MasterTileMessage_RGBA_I8 *mtm = new MasterTileMessage_RGBA_I8; mtm->command = MASTER_WRITE_TILE_I8; diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index 278b2c9b1c..60e1ad6e5e 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -114,6 +114,8 @@ namespace ospray { written into / composited into this dfb tile */ virtual void process(const ospray::Tile &tile) = 0; + void accumulate(const ospray::Tile &tile); + ospray::Tile __aligned(64) accum; /* iw: TODO - have to change this. right now, to be able to give the 'postaccum' pixel op a readily normalized tile we have to diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index 106395ef6a..b7aea19270 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -74,71 +74,68 @@ export void DFB_alphaBlendTiles(VaryingTile *uniform prev, } } -export void DFB_accumulate(void *uniform _self, - VaryingTile *uniform tile, - VaryingTile *uniform final, - VaryingTile *uniform accum, - VaryingRGBA_I8 *uniform color, - uniform bool hasAccumBuffer) -{ - DistributedFrameBuffer *uniform self = (DistributedFrameBuffer*)_self; - if (!hasAccumBuffer || tile->accumID < 1) { - for (uniform int i=0;ir[i], - tile->g[i], - tile->b[i], - tile->a[i]); - accum->r[i] = col.x; - accum->g[i] = col.y; - accum->b[i] = col.z; - accum->a[i] = col.w; - final->r[i] = col.x; - final->g[i] = col.y; - final->b[i] = col.z; - final->a[i] = col.w; - - // NOTE(jda) - no longer hardcoded, but should use pixelops - col = max(col,make_vec4f(0.f)); - // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), self->super.invGamma), col.w); - - color->color[i] = cvt_uint32(col); - } - } else { - const uniform float rcpAccumID = 1.f/(tile->accumID+1); - for (uniform int i=0;ir[i], - tile->g[i], - tile->b[i], - tile->a[i]) - + make_vec4f(accum->r[i], - accum->g[i], - accum->b[i], - accum->a[i]); - - accum->r[i] = col.x; - accum->g[i] = col.y; - accum->b[i] = col.z; - accum->a[i] = col.w; - - col = col * rcpAccumID; - - final->r[i] = col.x; - final->g[i] = col.y; - final->b[i] = col.z; - final->a[i] = col.w; - - // NOTE(jda) - no longer hardcoded, but should use pixelops - col = max(col,make_vec4f(0.f)); - // alpha is never gamma-corrected - col = make_vec4f(pow(make_vec3f(col), self->super.invGamma), col.w); - - color->color[i] = cvt_uint32(col); - } - } +#define template_accumulate(name, cvt) \ +export void DFB_accumulate_##name(void *uniform _self, \ + VaryingTile *uniform tile, \ + VaryingTile *uniform final, \ + VaryingTile *uniform accum, \ + VaryingRGBA_I8 *uniform color, \ + uniform bool hasAccumBuffer) \ +{ \ + DistributedFrameBuffer *uniform self = (DistributedFrameBuffer*)_self; \ + if (!hasAccumBuffer || tile->accumID < 1) { \ + for (uniform int i=0;ir[i], \ + tile->g[i], \ + tile->b[i], \ + tile->a[i]); \ + accum->r[i] = col.x; \ + accum->g[i] = col.y; \ + accum->b[i] = col.z; \ + accum->a[i] = col.w; \ + final->r[i] = col.x; \ + final->g[i] = col.y; \ + final->b[i] = col.z; \ + final->a[i] = col.w; \ + \ + col = max(col,make_vec4f(0.f)); \ + color->color[i] = cvt(col); \ + } \ + } else { \ + const uniform float rcpAccumID = 1.f/(tile->accumID+1); \ + for (uniform int i=0;ir[i], \ + tile->g[i], \ + tile->b[i], \ + tile->a[i]) \ + + make_vec4f(accum->r[i], \ + accum->g[i], \ + accum->b[i], \ + accum->a[i]); \ + \ + accum->r[i] = col.x; \ + accum->g[i] = col.y; \ + accum->b[i] = col.z; \ + accum->a[i] = col.w; \ + \ + col = col * rcpAccumID; \ + \ + final->r[i] = col.x; \ + final->g[i] = col.y; \ + final->b[i] = col.z; \ + final->a[i] = col.w; \ + \ + col = max(col,make_vec4f(0.f)); \ + color->color[i] = cvt(col); \ + } \ + } \ } +template_accumulate(RGBA8, cvt_uint32); +template_accumulate(SRGBA, cvt_srgba); +#undef template_accumulate + export void DFB_zComposite(VaryingTile *uniform delta, VaryingTile *uniform current) From 1d79b3a8407c5f6822dba306a51df3eba6d9b116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 25 Apr 2016 16:13:30 +0200 Subject: [PATCH 238/310] Cleanup Optics --- ospray/math/math.ih | 2 +- ospray/math/vec.ih | 1 + ospray/render/pathtracer/bsdfs/Optics.ih | 65 ++++++++++++------------ 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/ospray/math/math.ih b/ospray/math/math.ih index 2df0696c42..47492e4779 100644 --- a/ospray/math/math.ih +++ b/ospray/math/math.ih @@ -118,7 +118,7 @@ inline varying float deg2rad (const varying float x) { return x * 1.74532925199 inline uniform float rad2deg (const uniform float x) { return x * 5.72957795130823208768e1f; } inline varying float rad2deg (const varying float x) { return x * 5.72957795130823208768e1f; } -inline float cos2sin(const float f) { return sqrt(max(0.f, 1.f - f * f)); } +inline float cos2sin(const float f) { return sqrt(max(0.f, 1.f - sqr(f))); } inline float sin2cos(const float f) { return cos2sin(f); } inline uniform float nextafter(const uniform float a, const uniform float b) diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 6fb32cdd66..542060a74c 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -568,6 +568,7 @@ __lift_unary_fct(abs) __lift_unary_fct(rcp) __lift_unary_fct(exp) __lift_unary_fct(frac) +__lift_unary_fct(sqr) #undef __lift_unary_fct diff --git a/ospray/render/pathtracer/bsdfs/Optics.ih b/ospray/render/pathtracer/bsdfs/Optics.ih index ba24d98056..e3d4f2e393 100644 --- a/ospray/render/pathtracer/bsdfs/Optics.ih +++ b/ospray/render/pathtracer/bsdfs/Optics.ih @@ -20,18 +20,23 @@ #include "ospray/math/sampling.ih" #include "ospray/math/LinearSpace.ih" +/*! Reflects a viewing vector I at a normal N. Cosine between I + * and N is given as input. */ +inline vec3f reflect(const vec3f& I, const vec3f& N, float cosI) +{ + return (2.0f*cosI) * N - I; +} + /*! Reflects a viewing vector I at a normal N. */ inline vec3f reflect(const vec3f& I, const vec3f& N) { - float cosI = dot(I,N); - return (2.0f*cosI) * N - I; + return reflect(I, N, dot(I, N)); } -/*! Reflects a viewing vector I at a normal N. Cosine between I - * and N is given as input. */ -inline vec3f reflect(const vec3f& I, const vec3f& N, float cosI) +// helper function which computes cosT^2 from cosI and eta +inline float sqrCosT(const float cosI, const float eta) { - return (2.0f*cosI) * N - I; + return 1.0f - sqr(eta)*(1.0f - sqr(cosI)); } //! \brief Refracts a viewing vector I at a normal N @@ -39,26 +44,24 @@ inline vec3f reflect(const vec3f& I, const vec3f& N, float cosI) * relative refraction index eta. Eta is refraction index of outside * medium (where N points into) divided by refraction index of the * inside medium. The vectors I and N have to point towards the same - * side of the surface. The cosine between I and N is given as input - * and the cosine of -N and transmission ray is computed as - * output. */ -inline vec3f refract(const vec3f& I, const vec3f& N, float cosI, float eta) + * side of the surface. The cosine between I and N, and the cosine of -N and + * the refracted ray is given as input */ +inline vec3f refract(const vec3f& I, const vec3f& N, float cosI, float cosT, float eta) { - const float k = 1.0f-eta*eta*(1.0f-cosI*cosI); - if (k < 0.0f) return make_vec3f(0.f); - const float cosT = sqrtf(k); - return sub(mul(eta,sub(mul(cosI,N),I)),mul(cosT,N)); + return eta*(cosI*N - I) - cosT*N; } -inline vec3f refract(const vec3f& I, const vec3f& N, float cosI, float cosT, float eta) +inline vec3f refract(const vec3f& I, const vec3f& N, float cosI, float eta) { - return sub(mul(eta,sub(mul(cosI,N),I)),mul(cosT,N)); + const float sqrCosT = sqrCosT(cosI, eta); + if (sqrCosT < 0.0f) return make_vec3f(0.f); + return refract(I, N, cosI, sqrt(sqrCosT), eta); } inline float refract(float cosI, float eta) { - float k = 1.0f - eta*eta*(1.0f-cosI*cosI); - return sqrt(max(k, 0.0f)); + const float sqrCosT = sqrCosT(cosI, eta); + return sqrt(max(sqrCosT, 0.0f)); } //! \brief Computes fresnel coefficient for dielectric medium @@ -70,7 +73,7 @@ inline float fresnelDielectric(float cosI, float cosT, float eta) { const float Rper = (eta*cosI - cosT) * rcpf(eta*cosI + cosT); const float Rpar = ( cosI - eta*cosT) * rcpf( cosI + eta*cosT); - return 0.5f*(Rpar*Rpar + Rper*Rper); + return 0.5f*(sqr(Rpar) + sqr(Rper)); } /*! Computes fresnel coefficient for media interface with relative @@ -79,35 +82,33 @@ inline float fresnelDielectric(float cosI, float cosT, float eta) * positive. */ inline float fresnelDielectric(float cosI, float eta) { - const float k = 1.0f-eta*eta*(1.0f-cosI*cosI); - if (k < 0.0f) return 1.0f; - const float cosT = sqrtf(k); - return fresnelDielectric(cosI, cosT, eta); + const float sqrCosT = sqrCosT(cosI, eta); + if (sqrCosT < 0.0f) return 1.0f; + return fresnelDielectric(cosI, sqrt(sqrCosT), eta); } inline float fresnelDielectricEx(float cosI, float& cosT, float eta) { - const float k = 1.0f-eta*eta*(1.0f-cosI*cosI); - if (k < 0.0f) + const float sqrCosT = sqrCosT(cosI, eta); + if (sqrCosT < 0.0f) { cosT = 0.0f; return 1.0f; } - cosT = sqrtf(k); - return fresnelDielectric(cosI, cosT, eta); + return fresnelDielectric(cosI, sqrt(sqrCosT), eta); } /*! Computes fresnel coefficient for conductor medium with complex * refraction index (eta,k). The cosine has to be positive. */ inline vec3f fresnelConductor(float cosI, vec3f eta, vec3f k) { - vec3f tmp = eta*eta + k*k; + vec3f tmp = sqr(eta) + sqr(k); vec3f Rpar - = (tmp * cosI*cosI - 2.0f*eta*cosI + make_vec3f(1.f)) - * rcp(tmp * cosI*cosI + 2.0f*eta*cosI + make_vec3f(1.f)); + = (tmp * sqr(cosI) - 2.0f*eta*cosI + make_vec3f(1.f)) + * rcp(tmp * sqr(cosI) + 2.0f*eta*cosI + make_vec3f(1.f)); vec3f Rper - = (tmp - 2.0f*eta*cosI + make_vec3f(cosI*cosI)) - * rcp(tmp + 2.0f*eta*cosI + make_vec3f(cosI*cosI)); + = (tmp - 2.0f*eta*cosI + make_vec3f(sqr(cosI))) + * rcp(tmp + 2.0f*eta*cosI + make_vec3f(sqr(cosI))); return 0.5f * (Rpar + Rper); } From abc45e266b17912516901168b6c1f650800c2bfb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 25 Apr 2016 11:23:21 -0500 Subject: [PATCH 239/310] add ispc --opt=disable-assertions flag for Release/RelWithDebInfo builds --- cmake/ispc.cmake | 11 ++++++++++- cmake/ospray.cmake | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cmake/ispc.cmake b/cmake/ispc.cmake index 4b73e127fa..41ce36ec1f 100644 --- a/cmake/ispc.cmake +++ b/cmake/ispc.cmake @@ -98,7 +98,12 @@ MACRO (OSPRAY_ISPC_COMPILE) IF (THIS_IS_MIC) SET(ISPC_TARGET_EXT .cpp) SET(ISPC_TARGET_ARGS generic-16) - SET(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --opt=force-aligned-memory --emit-c++ --c++-include-file=${PROJECT_SOURCE_DIR}/ospray/common/ISPC_KNC_Backend.h ) + SET(ISPC_ADDITIONAL_ARGS + ${ISPC_ADDITIONAL_ARGS} + --opt=force-aligned-memory + --emit-c++ + --c++-include-file=${PROJECT_SOURCE_DIR}/ospray/common/ISPC_KNC_Backend.h + ) ELSE() SET(ISPC_TARGET_EXT ${CMAKE_CXX_OUTPUT_EXTENSION}) STRING(REPLACE ";" "," ISPC_TARGET_ARGS "${ISPC_TARGETS}") @@ -128,6 +133,10 @@ MACRO (OSPRAY_ISPC_COMPILE) SET(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --pic) ENDIF() + IF (NOT OSPRAY_DEBUG_BUILD) + SET(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --opt=disable-assertions) + ENDIF() + SET(ISPC_OBJECTS "") FOREACH(src ${ARGN}) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 8269692b36..1d0fa867af 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -61,6 +61,20 @@ ENDMACRO() MACRO(CONFIGURE_OSPRAY) CONFIGURE_TASKING_SYSTEM() + IF("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + SET(OSPRAY_DEBUG_BUILD ON ) + SET(OSPRAY_RELWITHDEBINFO_BUILD OFF) + SET(OSPRAY_RELEASE_BUILD OFF) + ELSEIF("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") + SET(OSPRAY_DEBUG_BUILD OFF) + SET(OSPRAY_RELWITHDEBINFO_BUILD ON ) + SET(OSPRAY_RELEASE_BUILD OFF) + ELSE()# Release + SET(OSPRAY_DEBUG_BUILD OFF) + SET(OSPRAY_RELWITHDEBINFO_BUILD OFF) + SET(OSPRAY_RELEASE_BUILD ON ) + ENDIF() + IF (OSPRAY_TARGET STREQUAL "mic") SET(OSPRAY_EXE_SUFFIX ".mic") SET(OSPRAY_LIB_SUFFIX "_mic") From c071cd178bb8223b290a31fe18ab3cfec6dadebb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 25 Apr 2016 21:14:32 -0500 Subject: [PATCH 240/310] fix some long lines, remove dead code, simplify a parallel_for() --- ospray/mpi/DistributedFrameBuffer.cpp | 9 +--- ospray/mpi/DistributedFrameBuffer.ispc | 48 +++++-------------- ospray/render/LoadBalancer.cpp | 8 ++-- .../render/volume/RaycastVolumeRenderer.cpp | 33 ++++++++----- ospray/volume/BlockBrickedVolume.cpp | 8 ++-- ospray/volume/GhostBlockBrickedVolume.cpp | 8 ++-- 6 files changed, 47 insertions(+), 67 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index e0758a4336..5a533e33ab 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -304,8 +304,7 @@ namespace ospray { { assert(comm); this->ispcEquivalent = ispc::DFB_create(this); - ispc::DFB_set(getIE(),numPixels.x,numPixels.y, - colorBufferFormat); + ispc::DFB_set(getIE(),numPixels.x,numPixels.y, colorBufferFormat); comm->registerObject(this,myID); createTiles(); @@ -515,21 +514,15 @@ namespace ospray { void DFB::closeCurrentFrame() { DBG(printf("rank %i CLOSES frame\n",mpi::world.rank)); - - //NOTE (jda) - Confused here, why lock if ok not to??? - //if (!locked) mutex.lock(); frameIsActive = false; frameIsDone = true; doneCond.notify_all(); - - //if (!locked) mutex.unlock(); } //! write given tile data into the frame buffer, sending to remove owner if //! required void DFB::setTile(ospray::Tile &tile) { - const size_t numPixels = TILE_SIZE*TILE_SIZE; DFB::TileDesc *tileDesc = this->getTileDescFor(tile.region.lower); if (!tileDesc->mine()) { diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index 106395ef6a..073336f225 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -24,17 +24,6 @@ struct DistributedFrameBuffer { struct VaryingRGBA_I8 { varying uint32 color[TILE_SIZE*TILE_SIZE/programCount]; }; -// /*! the ispc equivalent of the c-side -// DistributedFrameBuffer::DFBTileData as it is sent over the -// network */ -// struct DFBTileData { -// VaryingTile accum; -// // varying float accum_r[TILE_SIZE*TILE_SIZE/programCount]; -// // varying float accum_g[TILE_SIZE*TILE_SIZE/programCount]; -// // varying float accum_b[TILE_SIZE*TILE_SIZE/programCount]; -// // varying float accum_a[TILE_SIZE*TILE_SIZE/programCount]; -// varying uint32 color[TILE_SIZE*TILE_SIZE/programCount]; -// }; export void DFB_alphaBlendBackground(VaryingTile *uniform firstTile, const uniform vec4f &bgColor) @@ -56,16 +45,9 @@ export void DFB_alphaBlendBackground(VaryingTile *uniform firstTile, export void DFB_alphaBlendTiles(VaryingTile *uniform prev, VaryingTile *uniform over) { - // print("alpha0 prev % over %\n",prev->a[0],over->a[0]); for (uniform int i=0;ir[i], - prev->g[i], - prev->b[i], - prev->a[i]); - vec4f col_over = make_vec4f(over->r[i], - over->g[i], - over->b[i], - over->a[i]); + vec4f col_prev = make_vec4f(prev->r[i], prev->g[i], prev->b[i], prev->a[i]); + vec4f col_over = make_vec4f(over->r[i], over->g[i], over->b[i], over->a[i]); vec4f col_new = col_over + col_prev * (1.f-col_over.w); prev->r[i] = col_new.x; prev->g[i] = col_new.y; @@ -84,10 +66,7 @@ export void DFB_accumulate(void *uniform _self, DistributedFrameBuffer *uniform self = (DistributedFrameBuffer*)_self; if (!hasAccumBuffer || tile->accumID < 1) { for (uniform int i=0;ir[i], - tile->g[i], - tile->b[i], - tile->a[i]); + vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]); accum->r[i] = col.x; accum->g[i] = col.y; accum->b[i] = col.z; @@ -107,15 +86,8 @@ export void DFB_accumulate(void *uniform _self, } else { const uniform float rcpAccumID = 1.f/(tile->accumID+1); for (uniform int i=0;ir[i], - tile->g[i], - tile->b[i], - tile->a[i]) - + make_vec4f(accum->r[i], - accum->g[i], - accum->b[i], - accum->a[i]); + vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]) + + make_vec4f(accum->r[i], accum->g[i], accum->b[i], accum->a[i]); accum->r[i] = col.x; accum->g[i] = col.y; @@ -156,7 +128,8 @@ export void DFB_zComposite(VaryingTile *uniform delta, export void *uniform DFB_create(void *uniform cClassPtr) { - DistributedFrameBuffer *uniform self = uniform new uniform DistributedFrameBuffer; + DistributedFrameBuffer *uniform self = + uniform new uniform DistributedFrameBuffer; FrameBuffer_Constructor(&self->super,cClassPtr); return self; @@ -171,7 +144,9 @@ export void DFB_set(void *uniform _self, FrameBuffer_set(&self->super,size_x,size_y,colorBufferFormat); } -inline void swapFragments(VaryingTile *uniform t0, VaryingTile *uniform t1, uniform int fragID) +inline void swapFragments(VaryingTile *uniform t0, + VaryingTile *uniform t1, + uniform int fragID) { float r = t0->r[fragID]; t0->r[fragID] = t1->r[fragID]; t1->r[fragID] = r; float g = t0->g[fragID]; t0->g[fragID] = t1->g[fragID]; t1->g[fragID] = g; @@ -220,6 +195,7 @@ inline void sortAndBlendFragments(VaryingTile *uniform *uniform tileArray, } } +#if 0 task void DFB_sortAndBlendFragments_job(VaryingTile *uniform *uniform tileArray, uniform int32 numTiles) { @@ -227,10 +203,12 @@ task void DFB_sortAndBlendFragments_job(VaryingTile *uniform *uniform tileArray, uniform int end = begin + (PIXELS_PER_BLEND_JOB/programCount); sortAndBlendFragments(tileArray,numTiles,begin,end); } +#endif export void DFB_sortAndBlendFragments(VaryingTile *uniform *uniform tileArray, uniform int32 numTiles) { +// NOTE(jda) - I do not know if this should be removed...? #if 1 sortAndBlendFragments(tileArray,numTiles,0,TILE_SIZE*TILE_SIZE/programCount); #else diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index f8b9a62990..db927186e4 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -52,7 +52,7 @@ namespace ospray { const int NTASKS = numTiles_x * numTiles_y; - parallel_for(NTASKS, [&](int taskIndex){ + parallel_for(NTASKS, [&](int taskIndex) { const size_t tile_y = taskIndex / numTiles_x; const size_t tile_x = taskIndex - tile_y*numTiles_x; const vec2i tileID(tile_x, tile_y); @@ -63,7 +63,7 @@ namespace ospray { Tile tile(tileID, fb->size, accumID); - parallel_for(numJobs(renderer->spp, accumID), [&](int taskIndex){ + parallel_for(numJobs(renderer->spp, accumID), [&](int taskIndex) { renderer->renderTile(perFrameData, tile, taskIndex); }); @@ -102,7 +102,7 @@ namespace ospray { const int NTASKS = (numTiles_total / numDevices) + (numTiles_total % numDevices > deviceID); - parallel_for(NTASKS, [&](int taskIndex){ + parallel_for(NTASKS, [&](int taskIndex) { int tileIndex = deviceID + numDevices * taskIndex; const size_t tile_y = tileIndex / numTiles_x; const size_t tile_x = tileIndex - tile_y*numTiles_x; @@ -114,7 +114,7 @@ namespace ospray { Tile tile(tileID, fb->size, accumID); - parallel_for(numJobs(renderer->spp, accumID), [&](int taskIndex){ + parallel_for(numJobs(renderer->spp, accumID), [&](int taskIndex) { renderer->renderTile(perFrameData, tile, taskIndex); }); diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index 6ce1401faa..00ed40114f 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -115,7 +115,7 @@ namespace ospray { DPRenderTask(int workerRank); - void run(size_t taskIndex) const; + void operator()(int taskIndex) const; }; DPRenderTask::DPRenderTask(int workerRank) @@ -123,7 +123,7 @@ namespace ospray { { } - void DPRenderTask::run(size_t taskIndex) const + void DPRenderTask::operator()(int taskIndex) const { const size_t tileID = taskIndex; const size_t tile_y = taskIndex / numTiles_x; @@ -138,9 +138,12 @@ namespace ospray { // for (int i=0;iddBlock[i].bounds); bool *blockWasVisible = (bool*)alloca(numBlocks*sizeof(bool)); + for (int i=0;isetTile(fgTile); - // all other tiles for gen #1 will be set below, no matter whether it's mine or not + // all other tiles for gen #1 will be set below, no matter whether + // it's mine or not } // now, send all block cache tiles that were generated on this @@ -223,10 +228,10 @@ namespace ospray { { int workerRank = ospray::core::getWorkerRank(); - std::vector ddVolumeVec; + using DDBV = DataDistributedBlockedVolume; + std::vector ddVolumeVec; for (int volumeID=0;volumeIDvolume.size();volumeID++) { - const DataDistributedBlockedVolume *ddv - = dynamic_cast(model->volume[volumeID].ptr); + const DDBV *ddv = dynamic_cast(model->volume[volumeID].ptr); if (!ddv) continue; ddVolumeVec.push_back(ddv); } @@ -234,7 +239,8 @@ namespace ospray { if (ddVolumeVec.empty()) { static bool printed = false; if (!printed) { - cout << "no data parallel volumes, rendering in traditional raycast_volume_render mode" << endl; + cout << "no data parallel volumes, rendering in traditional" + << " raycast_volume_render mode" << endl; printed = true; } @@ -252,16 +258,19 @@ namespace ospray { // check if we're even in mpi parallel mode (can't do // data-parallel otherwise) - if (!ospray::core::isMpiParallel()) + if (!ospray::core::isMpiParallel()) { throw std::runtime_error("#dvr: need data-parallel rendering, " "but not running in mpi mode!?"); + } // switch (distributed) frame buffer into compositing mode DistributedFrameBuffer *dfb = dynamic_cast(fb); - if (!dfb) + if (!dfb) { throw std::runtime_error("OSPRay data parallel rendering error. " "this is a data-parallel scene, but we're " "not using the distributed frame buffer!?"); + } + dfb->setFrameMode(DistributedFrameBuffer::ALPHA_BLENDING); @@ -294,7 +303,7 @@ namespace ospray { renderTask.dpv = ddVolumeVec[0]; size_t NTASKS = renderTask.numTiles_x * renderTask.numTiles_y; - parallel_for(NTASKS, [&](int taskIndex){renderTask.run(taskIndex);}); + parallel_for(NTASKS, renderTask); dfb->waitUntilFinished(); Renderer::endFrame(NULL,channelFlags); diff --git a/ospray/volume/BlockBrickedVolume.cpp b/ospray/volume/BlockBrickedVolume.cpp index bc71989a31..d215813308 100644 --- a/ospray/volume/BlockBrickedVolume.cpp +++ b/ospray/volume/BlockBrickedVolume.cpp @@ -99,10 +99,10 @@ namespace ospray { const int NTASKS = regionSize.y * regionSize.z; parallel_for(NTASKS, [&](int taskIndex){ ispc::BlockBrickedVolume_setRegion(ispcEquivalent, - source, - (const ispc::vec3i &) regionCoords, - (const ispc::vec3i &) regionSize, - taskIndex); + source, + (const ispc::vec3i &)regionCoords, + (const ispc::vec3i &)regionSize, + taskIndex); }); return true; diff --git a/ospray/volume/GhostBlockBrickedVolume.cpp b/ospray/volume/GhostBlockBrickedVolume.cpp index a174ff81b3..bd9a1735b0 100644 --- a/ospray/volume/GhostBlockBrickedVolume.cpp +++ b/ospray/volume/GhostBlockBrickedVolume.cpp @@ -98,10 +98,10 @@ namespace ospray { const int NTASKS = regionSize.y * regionSize.z; parallel_for(NTASKS, [&](int taskIndex){ ispc::GBBV_setRegion(ispcEquivalent, - source, - (const ispc::vec3i &) regionCoords, - (const ispc::vec3i &) regionSize, - taskIndex); + source, + (const ispc::vec3i &)regionCoords, + (const ispc::vec3i &)regionSize, + taskIndex); }); return true; From ec6148a927a78f087f2ce92059b943afa28034f3 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 25 Apr 2016 21:15:27 -0500 Subject: [PATCH 241/310] fix data distributed rendering artifacts --- ospray/mpi/DistributedFrameBuffer.cpp | 3 +++ ospray/mpi/DistributedFrameBuffer.ispc | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 5a533e33ab..c9d7ba3fd5 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -133,6 +133,7 @@ namespace ospray { (ispc::VaryingTile *)&this->final, (ispc::VaryingTile *)&this->accum, (ispc::VaryingRGBA_I8 *)&this->color, + dfb->accumId, dfb->hasAccumBuffer); dfb->tileIsCompleted(this); @@ -168,6 +169,7 @@ namespace ospray { (ispc::VaryingTile*)&this->final, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, + dfb->accumId, dfb->hasAccumBuffer); dfb->tileIsCompleted(this); } @@ -199,6 +201,7 @@ namespace ospray { (ispc::VaryingTile*)&this->final, (ispc::VaryingTile*)&this->accum, (ispc::VaryingRGBA_I8*)&this->color, + dfb->accumId, dfb->hasAccumBuffer); dfb->tileIsCompleted(this); } diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index 073336f225..b0cb568bf6 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -61,10 +61,11 @@ export void DFB_accumulate(void *uniform _self, VaryingTile *uniform final, VaryingTile *uniform accum, VaryingRGBA_I8 *uniform color, + uniform int accumID, uniform bool hasAccumBuffer) { DistributedFrameBuffer *uniform self = (DistributedFrameBuffer*)_self; - if (!hasAccumBuffer || tile->accumID < 1) { + if (!hasAccumBuffer || accumID < 1) { for (uniform int i=0;ir[i], tile->g[i], tile->b[i], tile->a[i]); accum->r[i] = col.x; @@ -84,7 +85,7 @@ export void DFB_accumulate(void *uniform _self, color->color[i] = cvt_uint32(col); } } else { - const uniform float rcpAccumID = 1.f/(tile->accumID+1); + const uniform float rcpAccumID = 1.f/(accumID+1); for (uniform int i=0;ir[i], tile->g[i], tile->b[i], tile->a[i]) + make_vec4f(accum->r[i], accum->g[i], accum->b[i], accum->a[i]); From 4b60877a2a4ab254814e5b0dc05decbafdfc8ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 26 Apr 2016 12:07:46 +0200 Subject: [PATCH 242/310] Cleanup sRGB conversion functions --- ospray/common/default.ih | 18 ------- ospray/fb/FrameBuffer.ih | 10 +--- ospray/fb/LocalFB.ispc | 3 +- ospray/math/math.ih | 6 +-- ospray/math/vec.ih | 65 ++++++++++++++++++++++++++ ospray/mpi/DistributedFrameBuffer.ispc | 24 +++------- ospray/texture/Texture2D.ih | 1 - ospray/texture/Texture2D.ispc | 21 ++------- 8 files changed, 81 insertions(+), 67 deletions(-) delete mode 100644 ospray/common/default.ih diff --git a/ospray/common/default.ih b/ospray/common/default.ih deleted file mode 100644 index ac760e11ac..0000000000 --- a/ospray/common/default.ih +++ /dev/null @@ -1,18 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - diff --git a/ospray/fb/FrameBuffer.ih b/ospray/fb/FrameBuffer.ih index ce9781e806..5c75910a2b 100644 --- a/ospray/fb/FrameBuffer.ih +++ b/ospray/fb/FrameBuffer.ih @@ -48,7 +48,7 @@ struct FrameBuffer /*! helper function to convert float-color into rgba-uint format */ inline uint32 cvt_uint32(const float f) { - return (int32)(255.9f * max(min(f,1.f),0.f)); + return (int32)(255.f * clamp(f, 0.f, 1.f)); } /*! helper function to convert float-color into rgba-uint format */ @@ -70,14 +70,6 @@ inline uint32 cvt_uint32(const vec3f &v) (cvt_uint32(v.z) << 16); } -/*! helper function to convert float-color into srgba format */ -inline uint32 cvt_srgba(const vec4f &v) -{ - // alpha is never gamma-corrected - // approximate sRGB transfer curve with gamma 2.2 - return cvt_uint32(make_vec4f(pow(make_vec3f(v), 1/2.2f), v.w)); -} - void FrameBuffer_Constructor(FrameBuffer *uniform self, void *uniform cClassPtr); diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index e0fd3c294d..49308da2b5 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -47,7 +47,6 @@ export void LocalFrameBuffer_writeTile_##name(void *uniform _fb, \ varyTile->b[chunkID], \ varyTile->a[chunkID]); \ \ - col = max(col,make_vec4f(0.f)); \ const type cvtCol = cvt(col); \ } \ color[pixelID] = cvtCol; \ @@ -58,7 +57,7 @@ export void LocalFrameBuffer_writeTile_##name(void *uniform _fb, \ template_writeTile(RGBA8, uint32, cvt_uint32); -template_writeTile(SRGBA, uint32, cvt_srgba); +template_writeTile(SRGBA, uint32, linear_to_srgba8); inline vec4f cvt_nop(const vec4f &v) { return v; }; template_writeTile(RGBA32F, vec4f, cvt_nop); #undef template_writeTile diff --git a/ospray/math/math.ih b/ospray/math/math.ih index 47492e4779..52565fcf95 100644 --- a/ospray/math/math.ih +++ b/ospray/math/math.ih @@ -18,9 +18,9 @@ #include "ospray/common/OSPCommon.ih" -//////////////////////////////////////////////////////////////////////////////// -/// Constants -//////////////////////////////////////////////////////////////////////////////// +// ------------------------------------------------------------------ +// Constants +// ------------------------------------------------------------------ #define inf floatbits(0x7F800000) #define pos_inf floatbits(0x7F800000) diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 542060a74c..5d124f489e 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -794,3 +794,68 @@ inline void set(uniform vec3f &v, const uniform uint32 dim, const uniform float /*! get vector 'v's value in dimension 'd' */ inline float get(const uniform vec3f &v, const uniform uint32 dim) { return (&v.x)[dim]; } + + +// ------------------------------------------------------- +// sRGB conversion functions +// ------------------------------------------------------- +#define APPROXIMATE_SRGB + +inline float linear_to_srgb(const float f) +{ + const float c = max(f, 0.f); +#ifdef APPROXIMATE_SRGB + return pow(c, 1.f/2.2f); +#else + return c <= 0.0031308f ? 12.92f*c : pow(c, 1.f/2.4f)*1.055f - 0.055f; +#endif +} + +inline vec4f linear_to_srgba(const vec4f c) +{ + return make_vec4f(linear_to_srgb(c.x), + linear_to_srgb(c.y), + linear_to_srgb(c.z), + max(c.w, 0f)); // alpha is never gamma-corrected +} + +inline uint32 linear_to_srgba8(const vec4f c) +{ +#if 1 + vec4f l = 255.f * min(linear_to_srgba(c), make_vec4f(1.f)); + return + ((uint32)l.x << 0) | + ((uint32)l.y << 8) | + ((uint32)l.z << 16) | + ((uint32)l.w << 24); +#else +// TODO use ISPC's float_to_srgb8 once it is fixed (issue #1198) + return + (float_to_srgb8(c.x) << 0) | + (float_to_srgb8(c.y) << 8) | + (float_to_srgb8(c.z) << 16) | + ((uint32)clamp(c.w, 0.f, 1.f) << 24); // alpha is never gamma-corrected +#endif +} + +inline float srgb_to_linear(const float f) +{ + const float c = max(f, 0.f); +#ifdef APPROXIMATE_SRGB + return pow(c, 2.2f); +#else + return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f); +#endif +} + +inline vec4f srgba_to_linear(const vec4f c) +{ + return make_vec4f(srgb_to_linear(c.x), + srgb_to_linear(c.y), + srgb_to_linear(c.z), + max(c.w, 0.f)); // alpha is never gamma-corrected +} + +// TODO implement srgba8_to_linear with a 256 entry LUT + +#undef APPROXIMATE_SRGB diff --git a/ospray/mpi/DistributedFrameBuffer.ispc b/ospray/mpi/DistributedFrameBuffer.ispc index 3585c1a2df..6a3ed10ca9 100644 --- a/ospray/mpi/DistributedFrameBuffer.ispc +++ b/ospray/mpi/DistributedFrameBuffer.ispc @@ -62,16 +62,13 @@ export void DFB_accumulate_##name(void *uniform _self, \ VaryingTile *uniform final, \ VaryingTile *uniform accum, \ VaryingRGBA_I8 *uniform color, \ - uniform int accumID, \ - uniform bool hasAccumBuffer) \ + uniform int accumID, \ + uniform bool hasAccumBuffer) \ { \ DistributedFrameBuffer *uniform self = (DistributedFrameBuffer*)_self; \ if (!hasAccumBuffer || accumID < 1) { \ for (uniform int i=0;ir[i], \ - tile->g[i], \ - tile->b[i], \ - tile->a[i]); \ + vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]);\ accum->r[i] = col.x; \ accum->g[i] = col.y; \ accum->b[i] = col.z; \ @@ -81,21 +78,13 @@ export void DFB_accumulate_##name(void *uniform _self, \ final->b[i] = col.z; \ final->a[i] = col.w; \ \ - col = max(col,make_vec4f(0.f)); \ color->color[i] = cvt(col); \ } \ } else { \ const uniform float rcpAccumID = 1.f/(accumID+1); \ for (uniform int i=0;ir[i], \ - tile->g[i], \ - tile->b[i], \ - tile->a[i]) \ - + make_vec4f(accum->r[i], \ - accum->g[i], \ - accum->b[i], \ - accum->a[i]); \ + vec4f col = make_vec4f(tile->r[i], tile->g[i], tile->b[i], tile->a[i]) \ + + make_vec4f(accum->r[i], accum->g[i], accum->b[i], accum->a[i]); \ \ accum->r[i] = col.x; \ accum->g[i] = col.y; \ @@ -109,14 +98,13 @@ export void DFB_accumulate_##name(void *uniform _self, \ final->b[i] = col.z; \ final->a[i] = col.w; \ \ - col = max(col,make_vec4f(0.f)); \ color->color[i] = cvt(col); \ } \ } \ } template_accumulate(RGBA8, cvt_uint32); -template_accumulate(SRGBA, cvt_srgba); +template_accumulate(SRGBA, linear_to_srgba8); #undef template_accumulate diff --git a/ospray/texture/Texture2D.ih b/ospray/texture/Texture2D.ih index 8a564adf6f..e9102755a4 100644 --- a/ospray/texture/Texture2D.ih +++ b/ospray/texture/Texture2D.ih @@ -17,7 +17,6 @@ #pragma once #include "ospray/OSPTexture.h" -#include "ospray/common/default.ih" #include "ospray/math/vec.ih" struct Texture2D; diff --git a/ospray/texture/Texture2D.ispc b/ospray/texture/Texture2D.ispc index 4af84ca998..61e40769ec 100644 --- a/ospray/texture/Texture2D.ispc +++ b/ospray/texture/Texture2D.ispc @@ -26,9 +26,9 @@ inline vec4f getTexel_RGBA8(const uniform Texture2D *uniform self, const vec2i i { assert(self); const uint32 c = ((const uniform uint32 *uniform)self->data)[i.y*self->size.x + i.x]; - const uint32 r = c & 255; - const uint32 g = (c >> 8) & 255; - const uint32 b = (c >> 16) & 255; + const uint32 r = c & 0xff; + const uint32 g = (c >> 8) & 0xff; + const uint32 b = (c >> 16) & 0xff; const uint32 a = c >> 24; return make_vec4f(r, g, b, a)*(1.f/255.f); } @@ -51,25 +51,14 @@ inline vec4f getTexel_R8(const uniform Texture2D *uniform self, const vec2i i) return make_vec4f(c*(1.f/255.f), 0.0f, 0.0f, 1.f); } -inline float srgb(const float c) -{ -// return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f); // exact - return pow(c, 2.2f); // approximate -} - -inline vec4f srgba(const vec4f c) -{ - return make_vec4f(srgb(c.x), srgb(c.y), srgb(c.z), c.w); -} - inline vec4f getTexel_SRGBA(const uniform Texture2D *uniform self, const vec2i i) { - return srgba(getTexel_RGBA8(self, i)); + return srgba_to_linear(getTexel_RGBA8(self, i)); } inline vec4f getTexel_SRGB(const uniform Texture2D *uniform self, const vec2i i) { - return srgba(getTexel_RGB8(self, i)); + return srgba_to_linear(getTexel_RGB8(self, i)); } inline vec4f getTexel_RGBA32F(const uniform Texture2D *uniform self, const vec2i i) From d86fce834aaf884da12cd9735fbded0b95f8ddaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 26 Apr 2016 12:29:13 +0200 Subject: [PATCH 243/310] Adapt module Tachyon to new framebuffer API as well --- modules/tachyon/Viewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tachyon/Viewer.cpp b/modules/tachyon/Viewer.cpp index 725a9c0897..50ad0b3040 100644 --- a/modules/tachyon/Viewer.cpp +++ b/modules/tachyon/Viewer.cpp @@ -281,7 +281,7 @@ namespace ospray { Glut3DWidget::reshape(_newSize); if (fb) ospFreeFrameBuffer(fb); const auto &newSize = reinterpret_cast(_newSize); - fb = ospNewFrameBuffer(newSize,OSP_RGBA_I8,OSP_FB_COLOR|OSP_FB_ACCUM); + fb = ospNewFrameBuffer(newSize, OSP_FB_SRGBA, OSP_FB_COLOR|OSP_FB_ACCUM); ospSetf(camera,"aspect",viewPort.aspect); ospCommit(camera); } From 0839bfa4339204a1eeb86b9e8f5cb2f6d13c1de8 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 26 Apr 2016 09:45:10 -0500 Subject: [PATCH 244/310] change aoWeight default to 1.0 in scivis renderer --- ospray/render/scivis/SciVisRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/render/scivis/SciVisRenderer.cpp b/ospray/render/scivis/SciVisRenderer.cpp index 1dcea63d29..d42a0e4a7d 100644 --- a/ospray/render/scivis/SciVisRenderer.cpp +++ b/ospray/render/scivis/SciVisRenderer.cpp @@ -49,7 +49,7 @@ namespace ospray { int numAOSamples = getParam1i("aoSamples", 0); float rayLength = getParam1f("aoOcclusionDistance", 1e20f); - float aoWeight = getParam1f("aoWeight", 0.25f); + float aoWeight = getParam1f("aoWeight", 1.f); ispc::SciVisRenderer_set(getIE(), shadowsEnabled, From dc5f8158aba30177f06babf12195bb79d5ea4588 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 26 Apr 2016 09:51:45 -0500 Subject: [PATCH 245/310] Revert "change aoWeight default to 1.0 in scivis renderer" This reverts commit 0839bfa4339204a1eeb86b9e8f5cb2f6d13c1de8. --- ospray/render/scivis/SciVisRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/render/scivis/SciVisRenderer.cpp b/ospray/render/scivis/SciVisRenderer.cpp index d42a0e4a7d..1dcea63d29 100644 --- a/ospray/render/scivis/SciVisRenderer.cpp +++ b/ospray/render/scivis/SciVisRenderer.cpp @@ -49,7 +49,7 @@ namespace ospray { int numAOSamples = getParam1i("aoSamples", 0); float rayLength = getParam1f("aoOcclusionDistance", 1e20f); - float aoWeight = getParam1f("aoWeight", 1.f); + float aoWeight = getParam1f("aoWeight", 0.25f); ispc::SciVisRenderer_set(getIE(), shadowsEnabled, From 84e924eda373ecefa82c38f30afaf9bd56834bc5 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 11:06:28 -0500 Subject: [PATCH 246/310] use clearer naming scheme for tasking system in CMake and C++ --- cmake/build_embree.cmake | 2 +- cmake/ospray.cmake | 72 +++++++++++++------ .../ospray_cmake_config/osprayConfig.cmake.in | 8 +-- ospray/CMakeLists.txt | 4 +- ospray/common/tasking/async.h | 10 +-- ospray/common/tasking/parallel_for.h | 10 +-- ospray/render/LoadBalancer.cpp | 2 +- ospray/render/LoadBalancer.h | 4 +- 8 files changed, 70 insertions(+), 42 deletions(-) diff --git a/cmake/build_embree.cmake b/cmake/build_embree.cmake index 0851956bb4..c650962301 100644 --- a/cmake/build_embree.cmake +++ b/cmake/build_embree.cmake @@ -38,7 +38,7 @@ set(RTCORE_ENABLE_RAYSTREAM_LOGGER OFF CACHE INTERNAL "" FORCE) set(RTCORE_IGNORE_INVALID_RAYS OFF CACHE INTERNAL "" FORCE) set(RTCORE_RAY_PACKETS ON CACHE INTERNAL "" FORCE) -if (USE_TBB) +if (OSPRAY_TASKING_TBB) set(RTCORE_TASKING_SYSTEM TBB CACHE INTERNAL "" FORCE) else () set(RTCORE_TASKING_SYSTEM INTERNAL CACHE INTERNAL "" FORCE) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index 1d0fa867af..e7f8bef35d 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -91,13 +91,13 @@ MACRO(CONFIGURE_OSPRAY) SET(OSPRAY_ISPC_SUFFIX ".o") SET(THIS_IS_MIC OFF) SET(__XEON__ ON) - IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + IF (OSPRAY_COMPILER_ICC) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/icc.cmake) - ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + ELSEIF (OSPRAY_COMPILER_GCC) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/gcc.cmake) - ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + ELSEIF (OSPRAY_COMPILER_CLANG) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/clang.cmake) - ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") + ELSEIF (OSPRAY_COMPILER_MSVC) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/msvc.cmake) ELSE() MESSAGE(FATAL_ERROR "Unsupported compiler specified: '${CMAKE_CXX_COMPILER_ID}'") @@ -319,6 +319,31 @@ MACRO(OSPRAY_CONFIGURE_COMPILER) SET(CMAKE_CXX_COMPILER_ID "Clang") ENDIF() ENDIF() + + IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + SET(OSPRAY_COMPILER_ICC ON ) + SET(OSPRAY_COMPILER_GCC OFF) + SET(OSPRAY_COMPILER_CLANG OFF) + SET(OSPRAY_COMPILER_MSVC OFF) + ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + SET(OSPRAY_COMPILER_ICC OFF) + SET(OSPRAY_COMPILER_GCC ON ) + SET(OSPRAY_COMPILER_CLANG OFF) + SET(OSPRAY_COMPILER_MSVC OFF) + ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + SET(OSPRAY_COMPILER_ICC OFF) + SET(OSPRAY_COMPILER_GCC OFF) + SET(OSPRAY_COMPILER_CLANG ON ) + SET(OSPRAY_COMPILER_MSVC OFF) + ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") + SET(OSPRAY_COMPILER_ICC OFF) + SET(OSPRAY_COMPILER_GCC OFF) + SET(OSPRAY_COMPILER_CLANG OFF) + SET(OSPRAY_COMPILER_MSVC ON ) + ELSE() + MESSAGE(FATAL_ERROR + "Unsupported compiler specified: '${CMAKE_CXX_COMPILER_ID}'") + ENDIF() ENDMACRO() ## Tasking system configuration macro ## @@ -350,31 +375,34 @@ MACRO(CONFIGURE_TASKING_SYSTEM) # NOTE(jda) - Make the OSPRAY_TASKING_SYSTEM build option case-insensitive STRING(TOUPPER ${OSPRAY_TASKING_SYSTEM} OSPRAY_TASKING_SYSTEM_ID) - SET(USE_TBB FALSE) - SET(USE_CILK FALSE) - SET(USE_OPENMP FALSE) - SET(USE_INTERNAL FALSE) + SET(OSPRAY_TASKING_TBB FALSE) + SET(OSPRAY_TASKING_CILK FALSE) + SET(OSPRAY_TASKING_OPENMP FALSE) + SET(OSPRAY_TASKING_INTERNAL FALSE) + SET(OSPRAY_TASKING_DEBUG FALSE) IF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "TBB") - SET(USE_TBB TRUE) + SET(OSPRAY_TASKING_TBB TRUE) ELSEIF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "CILK") - SET(USE_CILK TRUE) + SET(OSPRAY_TASKING_CILK TRUE) ELSEIF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "OPENMP") - SET(USE_OPENMP TRUE) + SET(OSPRAY_TASKING_OPENMP TRUE) ELSEIF(${OSPRAY_TASKING_SYSTEM_ID} STREQUAL "INTERNAL") - SET(USE_INTERNAL TRUE) + SET(OSPRAY_TASKING_INTERNAL TRUE) + ELSE() + SET(OSPRAY_TASKING_DEBUG TRUE) ENDIF() UNSET(TASKING_SYSTEM_LIBS) UNSET(TASKING_SYSTEM_LIBS_MIC) - IF(USE_TBB) + IF(OSPRAY_TASKING_TBB) FIND_PACKAGE(TBB REQUIRED) - ADD_DEFINITIONS(-DOSPRAY_USE_TBB) + ADD_DEFINITIONS(-DOSPRAY_TASKING_TBB) INCLUDE_DIRECTORIES(${TBB_INCLUDE_DIRS}) SET(TASKING_SYSTEM_LIBS ${TBB_LIBRARIES}) SET(TASKING_SYSTEM_LIBS_MIC ${TBB_LIBRARIES_MIC}) - ELSE(USE_TBB) + ELSE(OSPRAY_TASKING_TBB) UNSET(TBB_INCLUDE_DIR CACHE) UNSET(TBB_LIBRARY CACHE) UNSET(TBB_LIBRARY_DEBUG CACHE) @@ -383,21 +411,21 @@ MACRO(CONFIGURE_TASKING_SYSTEM) UNSET(TBB_INCLUDE_DIR_MIC CACHE) UNSET(TBB_LIBRARY_MIC CACHE) UNSET(TBB_LIBRARY_MALLOC_MIC CACHE) - IF(USE_OPENMP) + IF(OSPRAY_TASKING_OPENMP) FIND_PACKAGE(OpenMP) IF (OPENMP_FOUND) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") - ADD_DEFINITIONS(-DOSPRAY_USE_OMP) + ADD_DEFINITIONS(-DOSPRAY_TASKING_OMP) ENDIF() - ELSEIF(USE_CILK) - ADD_DEFINITIONS(-DOSPRAY_USE_CILK) - ELSEIF(USE_INTERNAL) - ADD_DEFINITIONS(-DOSPRAY_USE_INTERNAL_TASKING) + ELSEIF(OSPRAY_TASKING_CILK) + ADD_DEFINITIONS(-DOSPRAY_TASKING_CILK) + ELSEIF(OSPRAY_TASKING_INTERNAL) + ADD_DEFINITIONS(-DOSPRAY_TASKING_INTERNAL) ELSE()#Debug # Do nothing, will fall back to scalar code (useful for debugging) ENDIF() - ENDIF(USE_TBB) + ENDIF(OSPRAY_TASKING_TBB) ENDMACRO() diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index 37afb87f67..85cd84988e 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -113,7 +113,7 @@ set(OSPRAY_CURRENT_ROOT_INSTALL_DIR ${CURRENT_ROOT_INSTALL_DIR}) # any ospray dependencies. A list of libs should be constructed # and added to the OSPRAY_LIBRARIES variable below. -if (@USE_TBB@) +if (@OSPRAY_TASKING_TBB@) # Find tbb find_package(TBB) if(":${TBB_LIBRARY}" STREQUAL ":") @@ -123,12 +123,12 @@ if (@USE_TBB@) message(STATUS "Found required OSPRay dependency: TBB in ${TBB_INCLUDE_DIRS}") endif() - add_definitions(-DOSPRAY_USE_TBB) + add_definitions(-DOSPRAY_TASKING_TBB) list(APPEND OSPRAY_DEPENDENCIES ${TBB_LIBRARIES}) endif() -if (@USE_CILK@) - add_definitions(-DOSPRAY_USE_CILK) +if (@OSPRAY_TASKING_CILK@) + add_definitions(-DOSPRAY_TASKING_CILK) endif() if(@OSPRAY_USE_EXTERNAL_EMBREE@) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index a49d673ce6..31d8c3c973 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -74,8 +74,8 @@ ELSE() ENDIF() # Build Embree included in the OSPRay tree - # NOTE(jda) - Embree assumes that USE_TBB will be defined correctly in - # CONFIGURE_OSPRAY().CONFIGURE_TASKING_SYSTEM() + # NOTE(jda) - Embree assumes that OSPRAY_TASKING_TBB will be defined correctly + # in CONFIGURE_OSPRAY().CONFIGURE_TASKING_SYSTEM() # NOTE(jda) - Only do the Embree include once (Xeon), it will build both # Xeon and MIC code if both are enabled. IF (NOT THIS_IS_MIC) diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index acbf34ebca..bf92fdfb17 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -16,11 +16,11 @@ #pragma once -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB # include #elif defined(OSPRAY_USE_CILK) # include -#elif defined(OSPRAY_USE_INTERNAL_TASKING) +#elif defined(OSPRAY_TASKING_INTERNAL) # include "ospray/common/tasking/TaskSys.h" #endif @@ -36,7 +36,7 @@ namespace ospray { template inline void async(const TASK_T& fcn) { -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB struct LocalTBBTask : public tbb::task { TASK_T func; @@ -50,9 +50,9 @@ inline void async(const TASK_T& fcn) }; tbb::task::enqueue(*new(tbb::task::allocate_root())LocalTBBTask(fcn)); -#elif defined(OSPRAY_USE_CILK) +#elif defined(OSPRAY_TASKING_CILK) cilk_spawn fcn(); -#elif defined(OSPRAY_USE_INTERNAL_TASKING) +#elif defined(OSPRAY_TASKING_INTERNAL) struct LocalTask : public Task { TASK_T t; LocalTask(const TASK_T& fcn) : Task("LocalTask"), t(std::move(fcn)) {} diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index c4779b1c05..193918c3d6 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -16,11 +16,11 @@ #pragma once -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB # include #elif defined(OSPRAY_USE_CILK) # include -#elif defined(OSPRAY_USE_INTERNAL_TASKING) +#elif defined(OSPRAY_TASKING_INTERNAL) # include "ospray/common/tasking/TaskSys.h" #endif @@ -31,18 +31,18 @@ namespace ospray { template inline void parallel_for(int nTasks, const TASK_T& fcn) { -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB tbb::parallel_for(0, nTasks, 1, fcn); #elif defined(OSPRAY_USE_CILK) cilk_for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); } -#elif defined(OSPRAY_USE_OMP) +#elif defined(OSPRAY_TASKING_OMP) # pragma omp parallel for schedule(dynamic) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); } -#elif defined(OSPRAY_USE_INTERNAL_TASKING) +#elif defined(OSPRAY_TASKING_INTERNAL) struct LocalTask : public Task { const TASK_T &t; LocalTask(const TASK_T& fcn) : Task("LocalTask"), t(fcn) {} diff --git a/ospray/render/LoadBalancer.cpp b/ospray/render/LoadBalancer.cpp index db927186e4..30642c92c9 100644 --- a/ospray/render/LoadBalancer.cpp +++ b/ospray/render/LoadBalancer.cpp @@ -31,7 +31,7 @@ namespace ospray { TiledLoadBalancer *TiledLoadBalancer::instance = NULL; LocalTiledLoadBalancer::LocalTiledLoadBalancer() -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB : tbb_init(numThreads) #endif { diff --git a/ospray/render/LoadBalancer.h b/ospray/render/LoadBalancer.h index b96f705ddb..a314bd1dfe 100644 --- a/ospray/render/LoadBalancer.h +++ b/ospray/render/LoadBalancer.h @@ -24,7 +24,7 @@ #include "ospray/render/Renderer.h" // tbb -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB # include #endif @@ -63,7 +63,7 @@ namespace ospray { std::string toString() const override; -#ifdef OSPRAY_USE_TBB +#ifdef OSPRAY_TASKING_TBB tbb::task_scheduler_init tbb_init; #endif }; From 8147dea3340a6c53cb6cb974463940540c36dce1 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 11:16:48 -0500 Subject: [PATCH 247/310] CMake macro naming consistency, use OSPRAY_COMPILER_* appropriately --- apps/CMakeLists.txt | 2 +- cmake/ospray.cmake | 10 +++++----- cmake/package.cmake | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 0df71eabeb..1ba1c8e506 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -44,7 +44,7 @@ IF(NOT THIS_IS_MIC) # NOTE(jda) - Disable Qt based viewers when on OS X using ICC due to # unresolved issues # qt-based viewer for geometry (and soon volumes) - IF(NOT (APPLE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel"))) + IF(NOT (APPLE AND OSPRAY_COMPILER_ICC)) OPTION(OSPRAY_APPS_QTVIEWER "Build ospQtViewer (Qt-based model viewer)" ON) IF (OSPRAY_APPS_QTVIEWER) ADD_SUBDIRECTORY(qtViewer) diff --git a/cmake/ospray.cmake b/cmake/ospray.cmake index e7f8bef35d..33ab05e8bc 100644 --- a/cmake/ospray.cmake +++ b/cmake/ospray.cmake @@ -59,7 +59,7 @@ ENDMACRO() # ".mic"-suffix trick, so we'll put libraries into separate # directories (names 'intel64' and 'mic', respectively) MACRO(CONFIGURE_OSPRAY) - CONFIGURE_TASKING_SYSTEM() + OSPRAY_CONFIGURE_TASKING_SYSTEM() IF("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") SET(OSPRAY_DEBUG_BUILD ON ) @@ -99,8 +99,6 @@ MACRO(CONFIGURE_OSPRAY) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/clang.cmake) ELSEIF (OSPRAY_COMPILER_MSVC) INCLUDE(${PROJECT_SOURCE_DIR}/cmake/msvc.cmake) - ELSE() - MESSAGE(FATAL_ERROR "Unsupported compiler specified: '${CMAKE_CXX_COMPILER_ID}'") ENDIF() SET(OSPRAY_EMBREE_ENABLE_AVX512 false) @@ -348,12 +346,14 @@ ENDMACRO() ## Tasking system configuration macro ## -MACRO(CONFIGURE_TASKING_SYSTEM) +MACRO(OSPRAY_CONFIGURE_TASKING_SYSTEM) # ------------------------------------------------------- # Setup tasking system build configuration # ------------------------------------------------------- - IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") + # NOTE(jda) - Notice that this implies that OSPRAY_CONFIGURE_COMPILER() has + # been called before this macro! + IF(OSPRAY_COMPILER_ICC) SET(CILK_STRING "Cilk") ENDIF() diff --git a/cmake/package.cmake b/cmake/package.cmake index 1069a18c10..09d8d66385 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -162,7 +162,7 @@ ELSE() SET(CPACK_GENERATOR TGZ) SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.linux") ELSE() - CONFIGURE_TASKING_SYSTEM()# NOTE(jda) - OSPRAY_TASKING_SYSTEM wasn't visible + OSPRAY_CONFIGURE_TASKING_SYSTEM()# NOTE(jda) - OSPRAY_TASKING_SYSTEM wasn't visible IF(${OSPRAY_TASKING_SYSTEM} STREQUAL "TBB") SET(TBB_REQ "tbb >= 3.0") ENDIF() From c95902fe3cb42f6f6ca9eb44caa59d668241020b Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 11:25:26 -0500 Subject: [PATCH 248/310] cleanup and enhance find_package() config with build config variables [ci skip] --- .../ospray_cmake_config/osprayConfig.cmake.in | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/cmake/ospray_cmake_config/osprayConfig.cmake.in b/cmake/ospray_cmake_config/osprayConfig.cmake.in index 85cd84988e..75e96c1652 100644 --- a/cmake/ospray_cmake_config/osprayConfig.cmake.in +++ b/cmake/ospray_cmake_config/osprayConfig.cmake.in @@ -96,11 +96,21 @@ endif(NOT EXISTS ${OSPRAY_INCLUDE_DIR}/ospray/version.h) set(OSPRAY_INCLUDE_DIRS ${OSPRAY_INCLUDE_DIR} ${OSPRAY_INCLUDE_DIR}/ospray - ${OSPRAY_INCLUDE_DIR}/ospray/embree-v2.7.1 - ${OSPRAY_INCLUDE_DIR}/ospray/embree-v2.7.1/common ) +############################################################################### +# ospray build configuration + + +SET(OSPRAY_COMPILER_ICC @OSPRAY_COMPILER_ICC@ ) +SET(OSPRAY_COMPILER_GCC @OSPRAY_COMPILER_GCC@ ) +SET(OSPRAY_COMPILER_CLANG @OSPRAY_COMPILER_CLANG@) +SET(OSPRAY_COMPILER_MSVC @OSPRAY_COMPILER_MSVC@ ) + +SET(OSPRAY_USE_EXTERNAL_EMBREE @OSPRAY_USE_EXTERNAL_EMBREE@) + + ############################################################################### # ospray dependencies @@ -113,7 +123,7 @@ set(OSPRAY_CURRENT_ROOT_INSTALL_DIR ${CURRENT_ROOT_INSTALL_DIR}) # any ospray dependencies. A list of libs should be constructed # and added to the OSPRAY_LIBRARIES variable below. -if (@OSPRAY_TASKING_TBB@) +if (OSPRAY_TASKING_TBB) # Find tbb find_package(TBB) if(":${TBB_LIBRARY}" STREQUAL ":") @@ -127,11 +137,11 @@ if (@OSPRAY_TASKING_TBB@) list(APPEND OSPRAY_DEPENDENCIES ${TBB_LIBRARIES}) endif() -if (@OSPRAY_TASKING_CILK@) +if (OSPRAY_TASKING_CILK) add_definitions(-DOSPRAY_TASKING_CILK) endif() -if(@OSPRAY_USE_EXTERNAL_EMBREE@) +if(OSPRAY_USE_EXTERNAL_EMBREE) # Find existing Embree on the machine find_package(embree @REQUIRED_MINIMUM_EMBREE@ REQUIRED) else() From a218f6c4fc84b5b7857fa4a1f5867caf598cdef9 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 11:50:51 -0500 Subject: [PATCH 249/310] make GLUT CMake error more helpful, remove dead CMake code --- apps/qtViewer/CMakeLists.txt | 3 --- cmake/glut.cmake | 15 +++++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/qtViewer/CMakeLists.txt b/apps/qtViewer/CMakeLists.txt index 5590f88ef7..0ad957c3d9 100644 --- a/apps/qtViewer/CMakeLists.txt +++ b/apps/qtViewer/CMakeLists.txt @@ -16,9 +16,6 @@ CONFIGURE_OSPRAY() -#MESSAGE("EXTERNAL_EMBREE_DIR ${EXTERNAL_EMBREE_DIR}") -#MESSAGE("OSPRAY_EMBREE_SOURCE_DIR ${OSPRAY_EMBREE_SOURCE_DIR}") - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ospray/include) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/cmake/glut.cmake b/cmake/glut.cmake index c572b451d0..ef27e4bb90 100644 --- a/cmake/glut.cmake +++ b/cmake/glut.cmake @@ -56,9 +56,7 @@ ELSEIF (WIN32) ENDIF() ELSE() FIND_PACKAGE(GLUT) - IF (GLUT_FOUND) - SET(GLUT_LIBRARIES glut GLU m) - ELSE() + IF (NOT GLUT_FOUND) FIND_PATH(GLUT_INCLUDE_DIR GL/glut.h $ENV{TACC_FREEGLUT_INC} ) @@ -67,7 +65,16 @@ ELSE() ) FIND_LIBRARY(GLUT_LIBRARIES NAMES libglut.so PATHS $ENV{TACC_FREEGLUT_LIB}) IF (NOT GLUT_LIBRARIES) - MESSAGE(FATAL_ERROR "Could not find GLUT library, even after trying additional search dirs") + MESSAGE(FATAL_ERROR "Could not find GLUT library, even after trying" + " additional search dirs." + " Please disable the following to build without GLUT:" + "\n" + " OSPRAY_APPS_MODELVIEWER," + " OSPRAY_APPS_PARTICLEVIEWER," + " OSPRAY_APPS_QTVIEWER," + " OSPRAY_APPS_STREAMLINEVIEWER," + " OSPRAY_MODULE_TACHYON" + "\n") ELSE() SET(GLUT_FOUND ON) ENDIF() From d9be5233c7491d4df0b6b0272be99bc6ff257d14 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 11:56:10 -0500 Subject: [PATCH 250/310] revert CMake bug introduced by a218f6c4 --- cmake/glut.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/glut.cmake b/cmake/glut.cmake index ef27e4bb90..fed7e4b1b6 100644 --- a/cmake/glut.cmake +++ b/cmake/glut.cmake @@ -56,7 +56,9 @@ ELSEIF (WIN32) ENDIF() ELSE() FIND_PACKAGE(GLUT) - IF (NOT GLUT_FOUND) + IF (GLUT_FOUND) + SET(GLUT_LIBRARIES glut GLU m) + ELSE() FIND_PATH(GLUT_INCLUDE_DIR GL/glut.h $ENV{TACC_FREEGLUT_INC} ) From 1d515e63fae6037ba9cce02d15e8d0ed21fbdef8 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 12:58:12 -0500 Subject: [PATCH 251/310] add missing device/ files to OSPRAY_SOURCES for IDEs (i.e. QtCreator) --- ospray/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 31d8c3c973..7d714aa6e9 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -105,6 +105,8 @@ SET(OSPRAY_SOURCES include/ospray/OSPDataType.h include/ospray/OSPTexture.h + device/buffers.cpp + device/command.h device/nwlayer.cpp math/box.ispc From ca2fdf3f1d9f4bfb305f5a6168ff5795276da32c Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Wed, 27 Apr 2016 19:25:32 -0500 Subject: [PATCH 252/310] fix for COI device --- ospray/api/COIDeviceHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/api/COIDeviceHost.cpp b/ospray/api/COIDeviceHost.cpp index b5c2e70911..956576ac62 100644 --- a/ospray/api/COIDeviceHost.cpp +++ b/ospray/api/COIDeviceHost.cpp @@ -1021,7 +1021,7 @@ namespace ospray { args.write((uint32)mode); args.write(channels); - Assert(mode == OSP_RGBA_I8); + Assert(mode == OSP_FB_RGBA8); COIFrameBuffer *fb = new COIFrameBuffer; fbList[handle] = fb; fb->hostMem = new int32[size.x*size.y]; From bec167d74276241041c25b4f1b60cc9279716ca7 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 28 Apr 2016 13:33:28 -0500 Subject: [PATCH 253/310] fix name change typo which caused a Cilk tasking performance bug --- ospray/common/tasking/async.h | 2 +- ospray/common/tasking/parallel_for.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index bf92fdfb17..294b1b85a8 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -18,7 +18,7 @@ #ifdef OSPRAY_TASKING_TBB # include -#elif defined(OSPRAY_USE_CILK) +#elif defined(OSPRAY_TASKING_CILK) # include #elif defined(OSPRAY_TASKING_INTERNAL) # include "ospray/common/tasking/TaskSys.h" diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index 193918c3d6..67da411083 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -18,7 +18,7 @@ #ifdef OSPRAY_TASKING_TBB # include -#elif defined(OSPRAY_USE_CILK) +#elif defined(OSPRAY_TASKING_CILK) # include #elif defined(OSPRAY_TASKING_INTERNAL) # include "ospray/common/tasking/TaskSys.h" @@ -33,7 +33,7 @@ inline void parallel_for(int nTasks, const TASK_T& fcn) { #ifdef OSPRAY_TASKING_TBB tbb::parallel_for(0, nTasks, 1, fcn); -#elif defined(OSPRAY_USE_CILK) +#elif defined(OSPRAY_TASKING_CILK) cilk_for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); } From b0983ed3270c519cd4ca8bbd43b86917ffea5348 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 28 Apr 2016 14:37:31 -0500 Subject: [PATCH 254/310] tweaks to linux release script --- .gitignore | 2 ++ scripts/release_linux.sh | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index caa003364c..b9c0bc157c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ tags *.gz *.rpm *.zip +tbb +ospray-doc diff --git a/scripts/release_linux.sh b/scripts/release_linux.sh index 92456eeb77..272734e8e7 100755 --- a/scripts/release_linux.sh +++ b/scripts/release_linux.sh @@ -16,11 +16,13 @@ #!/bin/bash +export ROOT_DIR=$PWD + # to make sure we do not include nor link against wrong TBB export CPATH= export LIBRARY_PATH= export LD_LIBRARY_PATH= -TBB_PATH_LOCAL=$PWD/tbb +TBB_PATH_LOCAL=$ROOT_DIR/tbb # check version of symbols function check_symbols @@ -54,21 +56,21 @@ cmake \ -D CMAKE_C_COMPILER:FILEPATH=icc \ -D CMAKE_CXX_COMPILER:FILEPATH=icpc \ -D OSPRAY_BUILD_ISA=ALL \ --D OSPRAY_BUILD_MIC_SUPPORT=ON \ --D OSPRAY_BUILD_COI_DEVICE=ON \ --D OSPRAY_BUILD_MPI_DEVICE=ON \ +-D OSPRAY_BUILD_MIC_SUPPORT=OFF \ +-D OSPRAY_BUILD_COI_DEVICE=OFF \ +-D OSPRAY_BUILD_MPI_DEVICE=OFF \ -D USE_IMAGE_MAGICK=OFF \ -D OSPRAY_ZIP_MODE=OFF \ --D CMAKE_INSTALL_PREFIX=/usr \ +-D CMAKE_INSTALL_PREFIX=$ROOT_DIR/install \ -D TBB_ROOT=$TBB_PATH_LOCAL \ .. # create RPM files make -j `nproc` preinstall -check_symbols libospray.so GLIBC 2 4 +check_symbols libospray.so GLIBC 2 4 check_symbols libospray.so GLIBCXX 3 4 -check_symbols libospray.so CXXABI 1 3 +check_symbols libospray.so CXXABI 1 3 make package # read OSPRay version @@ -94,4 +96,4 @@ cmake \ # create tar.gz files make -j `nproc` package -cd .. +cd $ROOT_DIR From ea8406dda64b7d76618e676d9edd525226cd8a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 29 Apr 2016 15:03:04 +0200 Subject: [PATCH 255/310] Initialize tileAccumID even without ACCUM buffer, because renderers rely on it --- ospray/fb/LocalFB.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 20a50649c5..73d32249ed 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -63,6 +63,7 @@ namespace ospray { tilesx = divRoundUp(size.x, TILE_SIZE); tiles = tilesx * divRoundUp(size.y, TILE_SIZE); tileAccumID = new int32[tiles]; + memset(tileAccumID, 0, tiles*sizeof(int32)); if (hasVarianceBuffer) { varianceBuffer = (vec4f*)alignedMalloc(sizeof(vec4f)*size.x*size.y); @@ -105,8 +106,7 @@ namespace ospray { // it is only necessary to reset the accumID, // LocalFrameBuffer_accumulateTile takes care of clearing the // accumulation buffers - for (int i = 0; i < tiles; i++) - tileAccumID[i] = 0; + memset(tileAccumID, 0, tiles*sizeof(int32)); // always also clear error buffer (if present) if (hasVarianceBuffer) { From b72c931254590e588b8df547bbcf4a2eea50fe90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 29 Apr 2016 15:17:32 +0200 Subject: [PATCH 256/310] Initialize accumId, because renderers rely on it --- ospray/mpi/DistributedFrameBuffer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ospray/mpi/DistributedFrameBuffer.cpp b/ospray/mpi/DistributedFrameBuffer.cpp index 22b185d7e5..b7449631cc 100644 --- a/ospray/mpi/DistributedFrameBuffer.cpp +++ b/ospray/mpi/DistributedFrameBuffer.cpp @@ -305,6 +305,7 @@ namespace ospray { numTiles((numPixels.x+TILE_SIZE-1)/TILE_SIZE, (numPixels.y+TILE_SIZE-1)/TILE_SIZE), frameIsActive(false), frameIsDone(false), localFBonMaster(NULL), + accumId(0), frameMode(WRITE_ONCE) { assert(comm); @@ -581,7 +582,7 @@ namespace ospray { } }); - if (fbChannelFlags & OSP_FB_ACCUM) + if (hasAccumBuffer && (fbChannelFlags & OSP_FB_ACCUM)) accumId = -1; // we increment at the start of the frame } } From 21c3f5bb7c6552618e6cff49ed6e5ea722a83e5b Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 29 Apr 2016 10:14:02 -0500 Subject: [PATCH 257/310] initial v0.10.0 changelog update --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b6a012777..caf1a3e28b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,37 @@ Version History --------------- +### Changes in v0.10.0: + +- OSPRay can now use a newer, pre-installed Embree enabled by + the new 'OSPRAY_USE_EXTERNAL_EMBREE' CMake option +- New 'ospcommon' library used to separately provide math types + and OS abstractions for both OSPRay and sample apps + - Removes extra dependencies on internal Embree math types and + utility functions + - 'ospray.h' header is now C99 compatible +- Replaced old OSPRay framebuffer types with new ones: OSP_FB_NONE, + OSP_FB_RGBA8, OSP_FB_SRGBA, and OSP_FB_RGBA32F +- New support for adaptive accumulation + - Enable detection of frame variance +- Added new tasking options: 'Cilk', 'Internal', and 'Debug' + - Provides more ways for OSPRay to interact with calling application + tasking systems + 'Cilk': Use Intel® Cilkâ„¢PLus language extensions (ICC only) + 'Internal': Use hand written OSPRay tasking system + 'Debug': All tasks are run in serial (useful for debugging) + - In most cases, TBB remains the fastest option +- New 'scivis' renderer parameter defaults + - All shading (AO + shadows) must be expicitly enabled +- Removed loaders module, functionality remains inside of ospVolumeViewer +- Many miscellaneous cleanups, bugfixes, and improvements: + - Fixed data distributed volume rendering bugs when using + less blocks than workers + - Fixes to CMake find_package() config + - Fix bug in GhostBlockBrickVolume when using doubles + - Various robustness changes made in CMake to make it easier to + compile OSPRay + ### Changes in v0.9.1: - Volume rendering now integrated into the "scivis" renderer From a4ffa28dccbefaf4484ac86d681621e6973ac624 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 29 Apr 2016 10:21:04 -0500 Subject: [PATCH 258/310] update formatting to changelog [ci skip] --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index caf1a3e28b..efa5c919ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,9 +17,9 @@ Version History - Added new tasking options: 'Cilk', 'Internal', and 'Debug' - Provides more ways for OSPRay to interact with calling application tasking systems - 'Cilk': Use Intel® Cilkâ„¢PLus language extensions (ICC only) - 'Internal': Use hand written OSPRay tasking system - 'Debug': All tasks are run in serial (useful for debugging) + - 'Cilk' : Use Intel® Cilkâ„¢PLus language extensions (ICC only) + - 'Internal': Use hand written OSPRay tasking system + - 'Debug' : All tasks are run in serial (useful for debugging) - In most cases, TBB remains the fastest option - New 'scivis' renderer parameter defaults - All shading (AO + shadows) must be expicitly enabled From 0a6a35c1b883f9753b32000f7f7f88188ff9570e Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 29 Apr 2016 12:58:03 -0500 Subject: [PATCH 259/310] fix startup crash when using 'Internal' tasking system --- ospray/common/OSPCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index a81d703b03..578673794d 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -127,7 +127,7 @@ namespace ospray { } } -#ifdef OSPRAY_USE_INTERNAL_TASKING +#ifdef OSPRAY_TASKING_INTERNAL try { ospray::Task::initTaskSystem(debugMode ? 0 : numThreads); } catch (const std::runtime_error &e) { From 5814ca9ac0fec91867aaa2525fa6942f0c5bdc92 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 29 Apr 2016 18:01:56 -0500 Subject: [PATCH 260/310] minor cleanupus in MPI/DFB --- ospray/mpi/DistributedFrameBuffer.h | 14 ++--- ospray/mpi/MPICommon.h | 2 +- ospray/mpi/MPIDevice.cpp | 12 ++-- .../render/volume/RaycastVolumeRenderer.cpp | 56 +++++++++---------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/ospray/mpi/DistributedFrameBuffer.h b/ospray/mpi/DistributedFrameBuffer.h index 60e1ad6e5e..5163fc0558 100644 --- a/ospray/mpi/DistributedFrameBuffer.h +++ b/ospray/mpi/DistributedFrameBuffer.h @@ -31,21 +31,21 @@ namespace ospray { public virtual FrameBuffer { //! get number of pixels per tile, in x and y direction - vec2i getTileSize() const { return vec2i(TILE_SIZE); }; + vec2i getTileSize() const { return vec2i(TILE_SIZE); } //! return number of tiles in x and y direction - vec2i getNumTiles() const { return numTiles; }; + vec2i getNumTiles() const { return numTiles; } //! get number of pixels in x and y diretion vec2i getNumPixels() const { return size; } //! number of tiles that "I" own - size_t numMyTiles() const { return myTiles.size(); }; + size_t numMyTiles() const { return myTiles.size(); } int accumId; int32 accumID(const vec2i &) override { return accumId; } float tileError(const vec2i &) override { return inf; } - float endFrame(const float) override { return inf; }; + float endFrame(const float) override { return inf; } /*! color buffer and depth buffer on master */ @@ -99,9 +99,9 @@ namespace ospray { the DFB tile itself */ struct TileData : public TileDesc { TileData(DistributedFrameBuffer *dfb, - const vec2i &begin, - size_t tileID, - size_t ownerID); + const vec2i &begin, + size_t tileID, + size_t ownerID); /*! called exactly once at the beginning of each frame */ virtual void newFrame() = 0; diff --git a/ospray/mpi/MPICommon.h b/ospray/mpi/MPICommon.h index 69449cdef4..0c58c1624c 100644 --- a/ospray/mpi/MPICommon.h +++ b/ospray/mpi/MPICommon.h @@ -83,6 +83,6 @@ namespace ospray { group */ void init(int *ac, const char **av); - }; + } } // ::ospray diff --git a/ospray/mpi/MPIDevice.cpp b/ospray/mpi/MPIDevice.cpp index c44c4cac45..0b0df119c7 100644 --- a/ospray/mpi/MPIDevice.cpp +++ b/ospray/mpi/MPIDevice.cpp @@ -185,7 +185,6 @@ namespace ospray { cout << "=======================================================" << endl; } int rc; - MPI_Status status; app.comm = world.comm; app.makeIntraComm(); @@ -250,7 +249,6 @@ namespace ospray { const char *launchCommand) { int rc; - MPI_Status status; ospray::init(ac,&av); mpi::init(ac,av); @@ -382,7 +380,6 @@ namespace ospray { OSPFrameBufferChannel channel) { int rc; - MPI_Status status; ObjectHandle handle = (const ObjectHandle &)_fb; FrameBuffer *fb = (FrameBuffer *)handle.lookup(); @@ -509,7 +506,8 @@ namespace ospray { int numFails = 0; MPI_Status status; - int rc = MPI_Recv(&numFails,1,MPI_INT,0,MPI_ANY_TAG,mpi::worker.comm,&status); + int rc = MPI_Recv(&numFails,1,MPI_INT, + 0,MPI_ANY_TAG,mpi::worker.comm,&status); Assert(rc == MPI_SUCCESS); @@ -941,7 +939,8 @@ namespace ospray { int numFails = 0; MPI_Status status; - int rc = MPI_Recv(&numFails,1,MPI_INT,0,MPI_ANY_TAG,mpi::worker.comm,&status); + int rc = MPI_Recv(&numFails,1,MPI_INT, + 0,MPI_ANY_TAG,mpi::worker.comm,&status); if (numFails == 0) return (OSPMaterial)(int64)handle; else { @@ -984,7 +983,8 @@ namespace ospray { // int MPI_Allreduce(void* , void*, int, MPI_Datatype, MPI_Op, MPI_Comm); int numFails = 0; MPI_Status status; - int rc = MPI_Recv(&numFails,1,MPI_INT,0,MPI_ANY_TAG,mpi::worker.comm,&status); + int rc = MPI_Recv(&numFails,1,MPI_INT, + 0,MPI_ANY_TAG,mpi::worker.comm,&status); if (numFails==0) return (OSPLight)(int64)handle; else { diff --git a/ospray/render/volume/RaycastVolumeRenderer.cpp b/ospray/render/volume/RaycastVolumeRenderer.cpp index 00ed40114f..35056d5f6f 100644 --- a/ospray/render/volume/RaycastVolumeRenderer.cpp +++ b/ospray/render/volume/RaycastVolumeRenderer.cpp @@ -46,24 +46,26 @@ namespace ospray { CacheForBlockTiles(size_t numBlocks) : numBlocks(numBlocks), blockTile(new Tile *[numBlocks]) { - for (int i=0;i::infinity(); Tile *tile = new Tile; - for (int i=0;ir[i] = 0.f; - for (int i=0;ig[i] = 0.f; - for (int i=0;ib[i] = 0.f; - for (int i=0;ia[i] = 0.f; - for (int i=0;iz[i] = std::numeric_limits::infinity(); + for (int i = 0; i < TILE_SIZE*TILE_SIZE; i++) tile->r[i] = 0.f; + for (int i = 0; i < TILE_SIZE*TILE_SIZE; i++) tile->g[i] = 0.f; + for (int i = 0; i < TILE_SIZE*TILE_SIZE; i++) tile->b[i] = 0.f; + for (int i = 0; i < TILE_SIZE*TILE_SIZE; i++) tile->a[i] = 0.f; + for (int i = 0; i < TILE_SIZE*TILE_SIZE; i++) tile->z[i] = infinity; return tile; } @@ -72,17 +74,17 @@ namespace ospray { #if TILE_CACHE_SAFE_MUTEX mutex.lock(); Tile *tile = blockTile[blockID]; - if (tile == NULL) { + if (tile == nullptr) { blockTile[blockID] = tile = allocTile(); } mutex.unlock(); return tile; #else Tile *tile = blockTile[blockID]; - if (tile != NULL) return tile; + if (tile != nullptr) return tile; mutex.lock(); tile = blockTile[blockID]; - if (tile == NULL) { + if (tile == nullptr) { blockTile[blockID] = tile = allocTile(); } mutex.unlock(); @@ -139,7 +141,7 @@ namespace ospray { // PRINT(dpv->ddBlock[i].bounds); bool *blockWasVisible = (bool*)alloca(numBlocks*sizeof(bool)); - for (int i=0;iregion = bgTile.region; tile->fbSize = bgTile.fbSize; tile->rcp_fbSize = bgTile.rcp_fbSize; tile->generation = 1; tile->children = 0; //nextGenTile-1; - // for (int i=0;ir[i] = float((blockID*3*7) % 11) / 11.f; - fb->setTile(*tile); } } /*! try if we are running in data-parallel mode, and if data-parallel is even required. if not (eg, if there's no - data-parallel volumes in the scene) return NULL and render only + data-parallel volumes in the scene) return nullptr and render only in regular mode; otherwise, compute some precomputations and return pointer to that (which'll switch the main renderframe fct to render data parallel) */ @@ -229,9 +230,9 @@ namespace ospray { int workerRank = ospray::core::getWorkerRank(); using DDBV = DataDistributedBlockedVolume; - std::vector ddVolumeVec; - for (int volumeID=0;volumeIDvolume.size();volumeID++) { - const DDBV *ddv = dynamic_cast(model->volume[volumeID].ptr); + std::vector ddVolumeVec; + for (int volumeID = 0; volumeID < model->volume.size(); volumeID++) { + const DDBV* ddv = dynamic_cast(model->volume[volumeID].ptr); if (!ddv) continue; ddVolumeVec.push_back(ddv); } @@ -273,7 +274,6 @@ namespace ospray { dfb->setFrameMode(DistributedFrameBuffer::ALPHA_BLENDING); - // note: we can NEVER be the master, since the master doesn't even // have an instance of this renderer class - assert(workerRank >= 0); @@ -297,8 +297,8 @@ namespace ospray { DPRenderTask renderTask(workerRank); renderTask.fb = fb; renderTask.renderer = this; - renderTask.numTiles_x = divRoundUp(dfb->size.x,TILE_SIZE); - renderTask.numTiles_y = divRoundUp(dfb->size.y,TILE_SIZE); + renderTask.numTiles_x = divRoundUp(dfb->size.x, TILE_SIZE); + renderTask.numTiles_y = divRoundUp(dfb->size.y, TILE_SIZE); renderTask.channelFlags = channelFlags; renderTask.dpv = ddVolumeVec[0]; @@ -306,7 +306,7 @@ namespace ospray { parallel_for(NTASKS, renderTask); dfb->waitUntilFinished(); - Renderer::endFrame(NULL,channelFlags); + Renderer::endFrame(nullptr, channelFlags); return fb->endFrame(0.f); } @@ -315,12 +315,12 @@ namespace ospray { void RaycastVolumeRenderer::commit() { // Create the equivalent ISPC RaycastVolumeRenderer object. - if (ispcEquivalent == NULL) { + if (ispcEquivalent == nullptr) { ispcEquivalent = ispc::RaycastVolumeRenderer_createInstance(); } // Set the lights if any. - Data *lightsData = (Data *)getParamData("lights", NULL); + Data *lightsData = (Data *)getParamData("lights", nullptr); lights.clear(); @@ -330,7 +330,7 @@ namespace ospray { } ispc::RaycastVolumeRenderer_setLights(ispcEquivalent, - lights.empty() ? NULL : &lights[0], + lights.empty() ? nullptr : &lights[0], lights.size()); // Initialize state in the parent class, must be called after the ISPC From 7f3c8d4f1f5ca9a264125cd408c99b9b60473af2 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 29 Apr 2016 18:29:22 -0500 Subject: [PATCH 261/310] alleviate 'Internal' perf issue caused by forcing init thread to be tid=0 --- ospray/common/tasking/TaskSys.cpp | 5 +---- ospray/fb/LocalFB.cpp | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/ospray/common/tasking/TaskSys.cpp b/ospray/common/tasking/TaskSys.cpp index 858cb9b69a..ba71864d81 100644 --- a/ospray/common/tasking/TaskSys.cpp +++ b/ospray/common/tasking/TaskSys.cpp @@ -193,6 +193,7 @@ namespace ospray { { if (initialized) throw std::runtime_error("#osp: task system initialized twice!"); + initialized = true; running = true; @@ -211,9 +212,5 @@ namespace ospray { threads.push_back(createThread((thread_func)TaskSys::threadStub, (void*)-1,4*1024*1024,-1)); } - -#if ~defined(__MIC__) - setAffinity(0); -#endif } }//namespace ospray diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index 73d32249ed..0342019f25 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -17,7 +17,6 @@ //ospray #include "LocalFB.h" #include "LocalFB_ispc.h" -#include "ospray/common/tasking/parallel_for.h" namespace ospray { From be6674b5ec5568e7ef595c7b627c463116459917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Sat, 30 Apr 2016 01:16:24 +0200 Subject: [PATCH 262/310] Update CHANGELOG and README based on ospray-doc --- CHANGELOG.md | 64 ++++++++++++++++++++++++++++++---------------------- README.md | 2 +- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efa5c919ed..483fd24fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,32 +3,42 @@ Version History ### Changes in v0.10.0: -- OSPRay can now use a newer, pre-installed Embree enabled by - the new 'OSPRAY_USE_EXTERNAL_EMBREE' CMake option -- New 'ospcommon' library used to separately provide math types - and OS abstractions for both OSPRay and sample apps +- Added new tasking options: `Cilk`, `Internal`, and `Debug` + - Provides more ways for OSPRay to interact with calling + application tasking systems + - `Cilk`: Use Intel® Cilkâ„¢ Plus language extensions (ICC only) + - `Internal`: Use hand written OSPRay tasking system + - `Debug`: All tasks are run in serial (useful for debugging) + - In most cases, `TBB` remains the fastest option +- Added support for adaptive accumulation and stopping + - `ospRenderFrame` now returns an estimation of the variance in + the rendered image if the framebuffer was created with the + `OSP_FB_VARIANCE` channel + - If the renderer parameter `varianceThreshold` is set, + progressive refinement concentrates on regions of the image with + a variance higher than this threshold +- `OSPTexture2D` now supports sRGB formats -- actually most images are + stored in sRGB. As a consequence the API call `ospNewTexture2D()` + needed to change to accept the new `OSPTextureFormat` parameter. +- Similarly, OSPRay's framebuffer types now also distinguishes between + linear and sRGB 8-bit formats. The new types are `OSP_FB_NONE`, + `OSP_FB_RGBA8`, `OSP_FB_SRGBA`, and `OSP_FB_RGBA32F` +- Changed "scivis" renderer parameter defaults + - All shading (AO + shadows) must be explicitly enabled +- OSPRay can now use a newer, pre-installed Embree enabled by the new + `OSPRAY_USE_EXTERNAL_EMBREE` CMake option +- New `ospcommon` library used to separately provide math types and OS + abstractions for both OSPRay and sample apps - Removes extra dependencies on internal Embree math types and utility functions - - 'ospray.h' header is now C99 compatible -- Replaced old OSPRay framebuffer types with new ones: OSP_FB_NONE, - OSP_FB_RGBA8, OSP_FB_SRGBA, and OSP_FB_RGBA32F -- New support for adaptive accumulation - - Enable detection of frame variance -- Added new tasking options: 'Cilk', 'Internal', and 'Debug' - - Provides more ways for OSPRay to interact with calling application - tasking systems - - 'Cilk' : Use Intel® Cilkâ„¢PLus language extensions (ICC only) - - 'Internal': Use hand written OSPRay tasking system - - 'Debug' : All tasks are run in serial (useful for debugging) - - In most cases, TBB remains the fastest option -- New 'scivis' renderer parameter defaults - - All shading (AO + shadows) must be expicitly enabled -- Removed loaders module, functionality remains inside of ospVolumeViewer + - `ospray.h` header is now C99 compatible +- Removed loaders module, functionality remains inside of + `ospVolumeViewer` - Many miscellaneous cleanups, bugfixes, and improvements: - - Fixed data distributed volume rendering bugs when using - less blocks than workers - - Fixes to CMake find_package() config - - Fix bug in GhostBlockBrickVolume when using doubles + - Fixed data distributed volume rendering bugs when using less + blocks than workers + - Fixes to CMake `find_package()` config + - Fix bug in `GhostBlockBrickVolume` when using `double`s - Various robustness changes made in CMake to make it easier to compile OSPRay @@ -43,10 +53,10 @@ Version History infrastructure restored (volume rendering is known to still be broken) - New support for CPack built OSPRay binary redistributable packages -- Add support for HDRI lighting in path tracer -- Add `ospRemoveVolume()` API call -- Add ability to render a subsection of the full view into the entire - framebuffer in the perspective camera +- Added support for HDRI lighting in path tracer +- Added `ospRemoveVolume()` API call +- Added ability to render a subsection of the full view into the + entire framebuffer in the perspective camera - Many miscellaneous cleanups, bugfixes, and improvements: - The depthbuffer is now correctly populated by in the "scivis" renderer diff --git a/README.md b/README.md index 9d4ece609b..5b70b40815 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ OSPRay ====== -This is release v0.9.1 of OSPRay. For changes and new features see the +This is release v0.10.0 of OSPRay. For changes and new features see the [changelog](CHANGELOG.md). Also visit http://www.ospray.org for more information. From bf49229db0c4a50a8929c9fc56ce431901c61283 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 2 May 2016 13:49:32 -0500 Subject: [PATCH 263/310] cleanups --- ospray/volume/BlockBrickedVolume.cpp | 2 -- ospray/volume/GhostBlockBrickedVolume.cpp | 20 ++++++------ ospray/volume/SharedStructuredVolume.cpp | 38 +++++++++++------------ ospray/volume/SharedStructuredVolume.h | 13 +++++--- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/ospray/volume/BlockBrickedVolume.cpp b/ospray/volume/BlockBrickedVolume.cpp index d215813308..38cc6f7135 100644 --- a/ospray/volume/BlockBrickedVolume.cpp +++ b/ospray/volume/BlockBrickedVolume.cpp @@ -18,8 +18,6 @@ #include "ospray/volume/BlockBrickedVolume.h" #include "ospray/common/tasking/parallel_for.h" #include "BlockBrickedVolume_ispc.h" -// std -#include namespace ospray { diff --git a/ospray/volume/GhostBlockBrickedVolume.cpp b/ospray/volume/GhostBlockBrickedVolume.cpp index bd9a1735b0..6a14d4c11f 100644 --- a/ospray/volume/GhostBlockBrickedVolume.cpp +++ b/ospray/volume/GhostBlockBrickedVolume.cpp @@ -18,10 +18,6 @@ #include "ospray/volume/GhostBlockBrickedVolume.h" #include "ospray/common/tasking/parallel_for.h" #include "GhostBlockBrickedVolume_ispc.h" -// std -#include - -bool g_dbg = 0; namespace ospray { @@ -90,8 +86,10 @@ namespace ospray { computeVoxelRange((float *)source, numVoxelsInRegion); else if (voxelType == "double") computeVoxelRange((double *) source, numVoxelsInRegion); - else - throw std::runtime_error("invalid voxelType in GhostBlockBrickedVolume::setRegion()"); + else { + throw std::runtime_error("invalid voxelType in " + "GhostBlockBrickedVolume::setRegion()"); + } } #endif // Copy voxel data into the volume. @@ -112,18 +110,20 @@ namespace ospray { // Get the voxel type. voxelType = getParamString("voxelType", "unspecified"); exitOnCondition(getVoxelType() == OSP_UNKNOWN, - "unrecognized voxel type (must be set before calling ospSetRegion())"); + "unrecognized voxel type (must be set before calling " + "ospSetRegion())"); // Get the volume dimensions. this->dimensions = getParam3i("dimensions", vec3i(0)); exitOnCondition(reduce_min(this->dimensions) <= 0, - "invalid volume dimensions (must be set before calling ospSetRegion())"); + "invalid volume dimensions (must be set before calling " + "ospSetRegion())"); // Create an ISPC GhostBlockBrickedVolume object and assign type-specific // function pointers. ispcEquivalent = ispc::GBBV_createInstance(this, - (int)getVoxelType(), - (const ispc::vec3i &)this->dimensions); + (int)getVoxelType(), + (const ispc::vec3i &)this->dimensions); } #ifdef EXP_NEW_BB_VOLUME_KERNELS diff --git a/ospray/volume/SharedStructuredVolume.cpp b/ospray/volume/SharedStructuredVolume.cpp index 0bb50da881..fce5cd956f 100644 --- a/ospray/volume/SharedStructuredVolume.cpp +++ b/ospray/volume/SharedStructuredVolume.cpp @@ -19,12 +19,10 @@ #include "SharedStructuredVolume_ispc.h" #include "StructuredVolume_ispc.h" #include "ospray/common/Data.h" -// std -#include namespace ospray { -SharedStructuredVolume::SharedStructuredVolume() : voxelData(NULL) {} +SharedStructuredVolume::SharedStructuredVolume() : voxelData(nullptr) {} SharedStructuredVolume::~SharedStructuredVolume() { @@ -40,7 +38,7 @@ SharedStructuredVolume::~SharedStructuredVolume() void SharedStructuredVolume::commit() { // Create the equivalent ISPC volume container. - if (ispcEquivalent == NULL) createEquivalentISPC(); + if (ispcEquivalent == nullptr) createEquivalentISPC(); // StructuredVolume commit actions. StructuredVolume::commit(); @@ -50,7 +48,7 @@ SharedStructuredVolume::~SharedStructuredVolume() const vec3i &index, const vec3i &count) { - if (getIE() == NULL) + if (getIE() == nullptr) createEquivalentISPC(); switch (getVoxelType()) { case OSP_UCHAR: @@ -70,10 +68,9 @@ SharedStructuredVolume::~SharedStructuredVolume() break; default: throw std::runtime_error("SharedStructuredVolume::setRegion() not " - "support for volumes of voxel type '"+voxelType+"'"); + "support for volumes of voxel type '" + + voxelType + "'"); } - // exitOnCondition(true, "setRegion() not allowed on this volume type; " - // "volume data must be provided via the voxelData parameter"); return 0; } @@ -89,20 +86,22 @@ SharedStructuredVolume::~SharedStructuredVolume() exitOnCondition(reduce_min(dimensions) <= 0, "invalid volume dimensions"); // Get the voxel data. - voxelData = (Data *)getParamObject("voxelData", NULL); + voxelData = (Data *)getParamObject("voxelData", nullptr); - // exitOnCondition(voxelData == NULL, "no voxel data provided"); - if (voxelData) + if (voxelData) { warnOnCondition(!(voxelData->flags & OSP_DATA_SHARED_BUFFER), - "the voxel data buffer was not created with the OSP_DATA_SHARED_BUFFER flag; " - "use another volume type (e.g. BlockBrickedVolume) for better performance"); + "The voxel data buffer was not created with the " + "OSP_DATA_SHARED_BUFFER flag; " + "Use another volume type (e.g. BlockBrickedVolume) for " + "better performance"); + } // The voxel count. - size_t voxelCount = (size_t)dimensions.x * (size_t)dimensions.y * (size_t)dimensions.z; - allocatedVoxelData - = (voxelData == NULL) - ? malloc(voxelCount*sizeOf(ospVoxelType)) - : NULL; + size_t voxelCount = (size_t)dimensions.x * + (size_t)dimensions.y * + (size_t)dimensions.z; + allocatedVoxelData = (voxelData == nullptr) ? + malloc(voxelCount*sizeOf(ospVoxelType)) : nullptr; // Create an ISPC SharedStructuredVolume object and assign // type-specific function pointers. @@ -123,7 +122,8 @@ SharedStructuredVolume::~SharedStructuredVolume() StructuredVolume::buildAccelerator(); } - // A volume type with XYZ storage order. The voxel data is provided by the application via a shared data buffer. + // A volume type with XYZ storage order. The voxel data is provided by the + // application via a shared data buffer. OSP_REGISTER_VOLUME(SharedStructuredVolume, shared_structured_volume); } // ::ospray diff --git a/ospray/volume/SharedStructuredVolume.h b/ospray/volume/SharedStructuredVolume.h index f6d92be19b..7b6afa3cd3 100644 --- a/ospray/volume/SharedStructuredVolume.h +++ b/ospray/volume/SharedStructuredVolume.h @@ -34,19 +34,21 @@ namespace ospray { ~SharedStructuredVolume(); //! A string description of this class. - std::string toString() const; + std::string toString() const override; //! Allocate storage and populate the volume, called through the OSPRay API. - void commit(); + void commit() override; //! Copy voxels into the volume at the given index; not allowed on //! SharedStructuredVolume. - int setRegion(const void *source, const vec3i &index, const vec3i &count); + int setRegion(const void *source, + const vec3i &index, + const vec3i &count) override; private: //! Create the equivalent ISPC volume container. - void createEquivalentISPC(); + void createEquivalentISPC() override; //! Called when a dependency of this object changes. void dependencyGotChanged(ManagedObject *object); @@ -54,7 +56,8 @@ namespace ospray { //! The voxelData object upon commit(). Data *voxelData; - //! the pointer to allocated data if the user did _not_ specify a shared buffer + //! the pointer to allocated data if the user did _not_ specify a shared + //! buffer void *allocatedVoxelData; }; From fc44f076079cbecf59e6a6268c61c1ce347b1e10 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 2 May 2016 14:02:38 -0500 Subject: [PATCH 264/310] remove unnecessary dynamic allocation in ospray::parallel_for() --- ospray/common/tasking/parallel_for.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index 67da411083..861100b309 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -49,8 +49,8 @@ inline void parallel_for(int nTasks, const TASK_T& fcn) void run(size_t taskIndex) override { t(taskIndex); } }; - Ref task = new LocalTask(fcn); - task->scheduleAndWait(nTasks); + LocalTask task(fcn); + task.scheduleAndWait(nTasks); #else // Debug (no tasking system) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); From ae4350f5ee4c06a845b9f9fb1a3b2a3f9ba0b2eb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 2 May 2016 14:20:50 -0500 Subject: [PATCH 265/310] cleanups --- ospray/common/tasking/async.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index 294b1b85a8..cfbb34390b 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -40,12 +40,7 @@ inline void async(const TASK_T& fcn) struct LocalTBBTask : public tbb::task { TASK_T func; - tbb::task* execute() override - { - func(); - return nullptr; - } - + tbb::task* execute() override { func(); return nullptr; } LocalTBBTask( const TASK_T& f ) : func(f) {} }; From aa94148028bbd061c2c789e07bc83faeef4bb5cb Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 2 May 2016 21:02:31 -0500 Subject: [PATCH 266/310] changes to enable warning if trying to build MIC support w/o icc --- CMakeLists.txt | 55 +++++++++++++++++++++++--------------- cmake/mpi.cmake | 71 +++++++++++++++++++++---------------------------- 2 files changed, 64 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f7b0a01a4..7f779c94e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,11 +37,6 @@ SET(OSPRAY_VERSION ) SET(OSPRAY_SOVERSION 0) - -OPTION(OSPRAY_USE_EXTERNAL_EMBREE - "Use a pre-built Embree instead of the internally built version" OFF) - - SET(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") IF (WIN32) IF (NOT OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET) @@ -59,17 +54,46 @@ SET(OSPRAY_BINARY_DIR ${PROJECT_BINARY_DIR}) SET(LIBRARY_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) +############################################################## +# CMake modules and macro files +############################################################## + +INCLUDE(cmake/ospray.cmake) +INCLUDE(cmake/ispc.cmake) + +SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) + +INCLUDE(cmake/mpi.cmake) + +IF(NOT WIN32) + INCLUDE(cmake/doxygen.cmake) +ENDIF() + +OSPRAY_CONFIGURE_COMPILER() + +############################################################## +# OSPRay specific build options and configuration selection +############################################################## + +OPTION(OSPRAY_USE_EXTERNAL_EMBREE + "Use a pre-built Embree instead of the internally built version" OFF) + # add experimental KNL/AVX512 build option - not fully supported, yet, so keep it hidden OPTION(OSPRAY_BUILD_ENABLE_KNL "Enable experimental 'Knights Landing' build?") MARK_AS_ADVANCED(OSPRAY_BUILD_ENABLE_KNL) -OPTION(OSPRAY_VOLUME_VOXELRANGE_IN_APP "Move 'voxelrange' computations to app?" OFF) +OPTION(OSPRAY_VOLUME_VOXELRANGE_IN_APP + "Move 'voxelrange' computations to app?" OFF) MARK_AS_ADVANCED(OSPRAY_VOLUME_VOXELRANGE_IN_APP) IF (WIN32) - SET(OSPRAY_BUILD_MIC_SUPPORT OFF CACHE INTERNAL "OSPRay with KNC not supported on Windows.") + SET(OSPRAY_BUILD_MIC_SUPPORT OFF CACHE INTERNAL + "OSPRay with KNC not supported on Windows.") ELSE() OPTION(OSPRAY_BUILD_MIC_SUPPORT "Build OSPRay with KNC Support?") + IF (OSPRAY_BUILD_MIC_SUPPORT AND NOT OSPRAY_COMPILER_ICC) + MESSAGE(FATAL_ERROR "To build with MIC support, you must use ICC!") + ENDIF() ENDIF() OPTION(OSPRAY_BUILD_MPI_DEVICE "Add MPI Remote/Distributed rendering support?") @@ -88,23 +112,10 @@ STRING(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) SET(OSPRAY_MPI ${OSPRAY_BUILD_MPI_DEVICE}) -############################################################## -# CMake modules and macro files -############################################################## - -INCLUDE(cmake/ospray.cmake) -INCLUDE(cmake/ispc.cmake) - -SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) - -INCLUDE(cmake/mpi.cmake) - -IF(NOT WIN32) - INCLUDE(cmake/doxygen.cmake) +IF (OSPRAY_MPI) + SET(OSPRAY_MPI_DISTRIBUTED ON) # sets this define in OSPConfig.h ENDIF() -OSPRAY_CONFIGURE_COMPILER() - ############################################################## # create binary packages; before any INSTALL() invocation/definition ############################################################## diff --git a/cmake/mpi.cmake b/cmake/mpi.cmake index 3aecbe6a0f..26eaaf164e 100644 --- a/cmake/mpi.cmake +++ b/cmake/mpi.cmake @@ -14,54 +14,45 @@ ## limitations under the License. ## ## ======================================================================== ## -IF (OSPRAY_MPI) - SET(OSPRAY_MPI_DISTRIBUTED ON) # sets this define in OSPConfig.h +MACRO(CONFIGURE_MPI) - MACRO(CONFIGURE_MPI) + IF (WIN32) # FindMPI does not find Intel MPI on Windows, we need to help here + FIND_PACKAGE(MPI) - IF (WIN32) # FindMPI does not find Intel MPI on Windows, we need to help here - FIND_PACKAGE(MPI) - - # need to strip quotes, otherwise CMake treats it as relative path - STRING(REGEX REPLACE "^\"|\"$" "" MPI_CXX_INCLUDE_PATH ${MPI_CXX_INCLUDE_PATH}) + # need to strip quotes, otherwise CMake treats it as relative path + STRING(REGEX REPLACE "^\"|\"$" "" MPI_CXX_INCLUDE_PATH ${MPI_CXX_INCLUDE_PATH}) - IF (NOT MPI_CXX_FOUND) - # try again, hinting the compiler wrappers - SET(MPI_CXX_COMPILER mpicxx.bat) - SET(MPI_C_COMPILER mpicc.bat) - FIND_PACKAGE(MPI) + IF (NOT MPI_CXX_FOUND) + # try again, hinting the compiler wrappers + SET(MPI_CXX_COMPILER mpicxx.bat) + SET(MPI_C_COMPILER mpicc.bat) + FIND_PACKAGE(MPI) - IF (NOT MPI_CXX_LIBRARIES) - SET(MPI_LIB_PATH ${MPI_CXX_INCLUDE_PATH}\\..\\lib) + IF (NOT MPI_CXX_LIBRARIES) + SET(MPI_LIB_PATH ${MPI_CXX_INCLUDE_PATH}\\..\\lib) - SET(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE) - FIND_LIBRARY(MPI_LIB NAMES impi HINTS ${MPI_LIB_PATH}) - SET(MPI_C_LIB ${MPI_LIB}) - SET(MPI_C_LIBRARIES ${MPI_LIB} CACHE STRING "MPI C libraries to link against" FORCE) + SET(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE) + FIND_LIBRARY(MPI_LIB NAMES impi HINTS ${MPI_LIB_PATH}) + SET(MPI_C_LIB ${MPI_LIB}) + SET(MPI_C_LIBRARIES ${MPI_LIB} CACHE STRING "MPI C libraries to link against" FORCE) - SET(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE) - FIND_LIBRARY(MPI_LIB NAMES impicxx HINTS ${MPI_LIB_PATH}) - SET(MPI_CXX_LIBRARIES ${MPI_C_LIB} ${MPI_LIB} CACHE STRING "MPI CXX libraries to link against" FORCE) - SET(MPI_LIB "MPI_LIB-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI lib detection" FORCE) - ENDIF() - ENDIF() - ELSE() - FIND_PACKAGE(MPI REQUIRED) - IF(MPI_CXX_FOUND) - GET_FILENAME_COMPONENT(DIR ${MPI_LIBRARY} PATH) - SET(MPI_LIBRARY_MIC ${DIR}/../../mic/lib/libmpi.so CACHE FILEPATH "") + SET(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE) + FIND_LIBRARY(MPI_LIB NAMES impicxx HINTS ${MPI_LIB_PATH}) + SET(MPI_CXX_LIBRARIES ${MPI_C_LIB} ${MPI_LIB} CACHE STRING "MPI CXX libraries to link against" FORCE) + SET(MPI_LIB "MPI_LIB-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI lib detection" FORCE) ENDIF() ENDIF() + ELSE() + FIND_PACKAGE(MPI REQUIRED) + IF(MPI_CXX_FOUND) + GET_FILENAME_COMPONENT(DIR ${MPI_LIBRARY} PATH) + SET(MPI_LIBRARY_MIC ${DIR}/../../mic/lib/libmpi.so CACHE FILEPATH "") + ENDIF() + ENDIF() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MPI_CXX_COMPILE_FLAGS}") - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_CXX_LINK_FLAGS}") - - INCLUDE_DIRECTORIES(SYSTEM ${MPI_CXX_INCLUDE_PATH}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MPI_CXX_COMPILE_FLAGS}") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_CXX_LINK_FLAGS}") - ENDMACRO() + INCLUDE_DIRECTORIES(SYSTEM ${MPI_CXX_INCLUDE_PATH}) -ELSE() - MACRO(CONFIGURE_MPI) - # nothing to do w/o mpi mode - ENDMACRO() -ENDIF() +ENDMACRO() From 58582db5a2d249243b65cabc91f5932cc7c2abf6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 2 May 2016 21:12:47 -0500 Subject: [PATCH 267/310] CMake cleanups --- CMakeLists.txt | 13 ++++--------- ospray/CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f779c94e6..f3779af749 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,9 +60,6 @@ SET(EXECUTABLE_OUTPUT_PATH ${OSPRAY_BINARY_DIR}) INCLUDE(cmake/ospray.cmake) INCLUDE(cmake/ispc.cmake) - -SET(OSPRAY_EMBREE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ospray/embree-v2.7.1) - INCLUDE(cmake/mpi.cmake) IF(NOT WIN32) @@ -76,14 +73,12 @@ OSPRAY_CONFIGURE_COMPILER() ############################################################## OPTION(OSPRAY_USE_EXTERNAL_EMBREE - "Use a pre-built Embree instead of the internally built version" OFF) + "Use a pre-built Embree instead of the internally built version") -# add experimental KNL/AVX512 build option - not fully supported, yet, so keep it hidden OPTION(OSPRAY_BUILD_ENABLE_KNL "Enable experimental 'Knights Landing' build?") MARK_AS_ADVANCED(OSPRAY_BUILD_ENABLE_KNL) -OPTION(OSPRAY_VOLUME_VOXELRANGE_IN_APP - "Move 'voxelrange' computations to app?" OFF) +OPTION(OSPRAY_VOLUME_VOXELRANGE_IN_APP "Move 'voxelrange' computations to app?") MARK_AS_ADVANCED(OSPRAY_VOLUME_VOXELRANGE_IN_APP) IF (WIN32) @@ -92,7 +87,7 @@ IF (WIN32) ELSE() OPTION(OSPRAY_BUILD_MIC_SUPPORT "Build OSPRay with KNC Support?") IF (OSPRAY_BUILD_MIC_SUPPORT AND NOT OSPRAY_COMPILER_ICC) - MESSAGE(FATAL_ERROR "To build with MIC support, you must use ICC!") + MESSAGE(FATAL_ERROR "MIC support requires the Intel Compiler.") ENDIF() ENDIF() @@ -106,7 +101,7 @@ ELSE() SET_PROPERTY(CACHE OSPRAY_BUILD_ISA PROPERTY STRINGS ALL SSE AVX AVX2) ENDIF() -# make ospray target and compiler uppercase - we need this in some other parts of the build system +# make ISA target case-insensitive, used in configure_ospray() macro STRING(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 7d714aa6e9..160e371cbc 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -81,7 +81,7 @@ ELSE() IF (NOT THIS_IS_MIC) INCLUDE(../cmake/build_embree.cmake) ENDIF() - SET(EMBREE_INCLUDE_DIRS ${OSPRAY_EMBREE_SOURCE_DIR}/include) + SET(EMBREE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/ospray/embree-v2.7.1/include) SET(EMBREE_LIBRARY embree) SET(EMBREE_LIBRARIES ${EMBREE_LIBRARY}) SET(EMBREE_LIBRARY_XEONPHI embree_xeonphi) From a4c2d7117efd2ee181385ca9d30b213219b875fa Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 2 May 2016 21:16:22 -0500 Subject: [PATCH 268/310] Revert "remove unnecessary dynamic allocation in ospray::parallel_for()" NOTE: Broke local rendering on dual Ivy Bridge Xeon workstation This reverts commit fc44f076079cbecf59e6a6268c61c1ce347b1e10. --- ospray/common/tasking/parallel_for.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index 861100b309..67da411083 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -49,8 +49,8 @@ inline void parallel_for(int nTasks, const TASK_T& fcn) void run(size_t taskIndex) override { t(taskIndex); } }; - LocalTask task(fcn); - task.scheduleAndWait(nTasks); + Ref task = new LocalTask(fcn); + task->scheduleAndWait(nTasks); #else // Debug (no tasking system) for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); From ae50d92cd4a34f47695cfbf313d7fd4b1c832b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 3 May 2016 10:03:49 +0200 Subject: [PATCH 269/310] Support 16-bit integer (ushort) volumes --- apps/volumeViewer/loaders/RawVolumeFile.cpp | 7 + ospray/common/OSPCommon.cpp | 2 + ospray/include/ospray/OSPDataType.h | 2 + ospray/volume/BlockBrickedVolume.cpp | 2 + ospray/volume/BlockBrickedVolume.ispc | 291 +++------ ospray/volume/GhostBlockBrickedVolume.cpp | 2 + ospray/volume/GhostBlockBrickedVolume.ispc | 14 + ospray/volume/SharedStructuredVolume.cpp | 5 + ospray/volume/SharedStructuredVolume.ispc | 617 +++++++++----------- ospray/volume/StructuredVolume.cpp | 4 + 10 files changed, 372 insertions(+), 574 deletions(-) diff --git a/apps/volumeViewer/loaders/RawVolumeFile.cpp b/apps/volumeViewer/loaders/RawVolumeFile.cpp index 85a41c7414..b17dd3a360 100644 --- a/apps/volumeViewer/loaders/RawVolumeFile.cpp +++ b/apps/volumeViewer/loaders/RawVolumeFile.cpp @@ -59,6 +59,8 @@ OSPVolume RawVolumeFile::importVolume(OSPVolume volume) if (strcmp(voxelType, "uchar") == 0) voxelSize = sizeof(unsigned char); + else if (strcmp(voxelType, "ushort") == 0) + voxelSize = sizeof(uint16_t); else if (strcmp(voxelType, "float") == 0) voxelSize = sizeof(float); else if (strcmp(voxelType, "double") == 0) @@ -158,6 +160,11 @@ ospcommon::vec2f voxelRange(+std::numeric_limits::infinity(), (unsigned char *)voxelData, volumeDimensions.x*volumeDimensions.y); } + else if (strcmp(voxelType, "ushort") == 0) { + extendVoxelRange(voxelRange, + (uint16_t *)voxelData, + volumeDimensions.x*volumeDimensions.y); + } else if (strcmp(voxelType, "float") == 0) { extendVoxelRange(voxelRange, (float *)voxelData, diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 578673794d..19e1481f38 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -165,6 +165,7 @@ namespace ospray { case OSP_UCHAR2: return sizeof(vec2uc); case OSP_UCHAR3: return sizeof(vec3uc); case OSP_UCHAR4: return sizeof(vec4uc); + case OSP_USHORT: return sizeof(uint16); case OSP_INT: return sizeof(int32); case OSP_INT2: return sizeof(vec2i); case OSP_INT3: return sizeof(vec3i); @@ -211,6 +212,7 @@ namespace ospray { if (strcmp(string, "uchar2") == 0) return(OSP_UCHAR2); if (strcmp(string, "uchar3") == 0) return(OSP_UCHAR3); if (strcmp(string, "uchar4") == 0) return(OSP_UCHAR4); + if (strcmp(string, "ushort") == 0) return(OSP_USHORT); if (strcmp(string, "uint" ) == 0) return(OSP_UINT); if (strcmp(string, "uint2" ) == 0) return(OSP_UINT2); if (strcmp(string, "uint3" ) == 0) return(OSP_UINT3); diff --git a/ospray/include/ospray/OSPDataType.h b/ospray/include/ospray/OSPDataType.h index 8044ab1544..6c95935188 100644 --- a/ospray/include/ospray/OSPDataType.h +++ b/ospray/include/ospray/OSPDataType.h @@ -49,6 +49,8 @@ typedef enum { //! Unsigned character scalar and vector types. OSP_UCHAR =110, OSP_UCHAR2, OSP_UCHAR3, OSP_UCHAR4, + OSP_USHORT =115, + //! Signed integer scalar and vector types. OSP_INT =120, OSP_INT2, OSP_INT3, OSP_INT4, diff --git a/ospray/volume/BlockBrickedVolume.cpp b/ospray/volume/BlockBrickedVolume.cpp index 38cc6f7135..391257cab9 100644 --- a/ospray/volume/BlockBrickedVolume.cpp +++ b/ospray/volume/BlockBrickedVolume.cpp @@ -82,6 +82,8 @@ namespace ospray { + (size_t)regionSize.z; if (voxelType == "uchar") computeVoxelRange((unsigned char *)source, numVoxelsInRegion); + else if (voxelType == "ushort") + computeVoxelRange((unsigned short *)source, numVoxelsInRegion); else if (voxelType == "float") computeVoxelRange((float *)source, numVoxelsInRegion); else if (voxelType == "double") diff --git a/ospray/volume/BlockBrickedVolume.ispc b/ospray/volume/BlockBrickedVolume.ispc index a688a759af..ddba87a98b 100644 --- a/ospray/volume/BlockBrickedVolume.ispc +++ b/ospray/volume/BlockBrickedVolume.ispc @@ -82,68 +82,35 @@ inline void BlockBrickedVolume_getVoxelAddress(BlockBrickedVolume *uniform volum | voxelOffset.x; } -inline void BlockBrickedVolumeUChar_getVoxel(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - BlockBrickedVolume *uniform volume = (BlockBrickedVolume *uniform) _volume; - - // Cast to the actual voxel type. - uint8 *uniform blockMem = (uint8 *uniform) volume->blockMem; - // Compute the 1D address of the block in the volume and the voxel in the block. - Address address; - BlockBrickedVolume_getVoxelAddress(volume, index, address); - // The voxel value at the 1D address. - foreach_unique(blockID in address.block) { - uint8 *uniform blockPtr = blockMem + (BLOCK_VOXEL_COUNT * (uint64)blockID); - value = blockPtr[address.voxel]; - } +#define template_getVoxel(type) \ +inline void BlockBrickedVolume_getVoxel_##type(void *uniform _self, \ + const varying vec3i &index, \ + varying float &value) \ +{ \ + /* Cast to the actual volume subtype. */ \ + BlockBrickedVolume *uniform self = (BlockBrickedVolume *uniform)_self; \ + \ + /* Compute the 1D address of the block in the volume \ + and the voxel in the block. */ \ + Address address; \ + BlockBrickedVolume_getVoxelAddress(self, index, address); \ + \ + /* The voxel value at the 1D address. */ \ + foreach_unique(blockID in address.block) { \ + type *uniform blockPtr = (type *uniform)self->blockMem + \ + (BLOCK_VOXEL_COUNT * (uint64)blockID); \ + value = blockPtr[address.voxel]; \ + } \ } -inline void BlockBrickedVolumeFloat_getVoxel(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - BlockBrickedVolume *uniform volume = (BlockBrickedVolume *uniform) _volume; - - // Cast to the actual voxel type. - float *uniform blockMem = (float *uniform) volume->blockMem; - - // Compute the 1D address of the block in the volume and the voxel in the block. - Address address; - BlockBrickedVolume_getVoxelAddress(volume, index, address); +template_getVoxel(uint8); +template_getVoxel(uint16); +template_getVoxel(float); +template_getVoxel(double); +#undef template_getVoxel - // The voxel value at the 1D address. - foreach_unique(blockID in address.block) { - float *uniform blockPtr = blockMem + (BLOCK_VOXEL_COUNT * (uint64)blockID); - value = blockPtr[address.voxel]; - } -} - -inline void BlockBrickedVolumeDouble_getVoxel(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - BlockBrickedVolume *uniform volume = (BlockBrickedVolume *uniform) _volume; - - // Cast to the actual voxel type. - double *uniform blockMem = (double *uniform) volume->blockMem; - - // Compute the 1D address of the block in the volume and the voxel in the block. - Address address; - BlockBrickedVolume_getVoxelAddress(volume, index, address); - - // The voxel value at the 1D address. - foreach_unique(blockID in address.block) { - double *uniform blockPtr = blockMem + (BLOCK_VOXEL_COUNT * (uint64)blockID); - value = blockPtr[address.voxel]; - } -} inline void BlockBrickedVolume_allocateMemory(BlockBrickedVolume *uniform volume) { @@ -168,109 +135,46 @@ inline void BlockBrickedVolume_allocateMemory(BlockBrickedVolume *uniform volume /*! copy given block of voxels into the volume, where source[0] will be written to volume[targetCoord000] */ -void BlockBrickedVolumeUChar_setRegion(BlockBrickedVolume *uniform self, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize, - const uniform int taskIndex) -{ - const uint8 *uniform source = (const uint8 *uniform)_source; - const uniform uint32 region_y = taskIndex % regionSize.y; - const uniform uint32 region_z = taskIndex / regionSize.y; - const uniform uint64 runOfs = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); - const uint8 *uniform run = source + runOfs; - vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); - foreach (x = 0 ... regionSize.x) { - Address address; - coord.x = targetCoord000.x + x; - if (coord.x < 0 || - coord.y < 0 || - coord.z < 0 || - coord.x >= self->super.dimensions.x || - coord.y >= self->super.dimensions.y || - coord.z >= self->super.dimensions.z - ) - continue; - BlockBrickedVolume_getVoxelAddress(self, coord, address); - foreach_unique(blockID in address.block) { - uint8 *uniform blockPtr - = ((uint8*uniform)self->blockMem) - + blockID * (uint64)BLOCK_VOXEL_COUNT; - blockPtr[address.voxel] = run[x]; - } - } +#define template_setRegion(type) \ +void BlockBrickedVolume_setRegion_##type(BlockBrickedVolume *uniform self, \ + const void *uniform _source, \ + const uniform vec3i &targetCoord000, \ + const uniform vec3i ®ionSize, \ + const uniform int taskIndex) \ +{ \ + const uniform uint32 region_y = taskIndex % regionSize.y; \ + const uniform uint32 region_z = taskIndex / regionSize.y; \ + const uniform uint64 runOfs = (uint64)regionSize.x * \ + (region_y + (uint64)regionSize.y * region_z); \ + const type *uniform run = (const type *uniform)_source + runOfs; \ + vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); \ + foreach (x = 0 ... regionSize.x) { \ + Address address; \ + coord.x = targetCoord000.x + x; \ + if (coord.x < 0 || \ + coord.y < 0 || \ + coord.z < 0 || \ + coord.x >= self->super.dimensions.x || \ + coord.y >= self->super.dimensions.y || \ + coord.z >= self->super.dimensions.z \ + ) \ + continue; \ + \ + BlockBrickedVolume_getVoxelAddress(self, coord, address); \ + foreach_unique(blockID in address.block) { \ + type *uniform blockPtr = ((type *uniform)self->blockMem) \ + + blockID * (uint64)BLOCK_VOXEL_COUNT; \ + blockPtr[address.voxel] = run[x]; \ + } \ + } \ } -/*! copy given block of voxels into the volume, where source[0] will - be written to volume[targetCoord000] */ -void BlockBrickedVolumeFloat_setRegion(BlockBrickedVolume *uniform self, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize, - const uniform int taskIndex) -{ - const float *uniform source = (const float *uniform)_source; - const uniform uint32 region_y = taskIndex % regionSize.y; - const uniform uint32 region_z = taskIndex / regionSize.y; - const uniform uint64 runOfs = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); - const float *uniform run = source + runOfs; - vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); - foreach (x = 0 ... regionSize.x) { - Address address; - coord.x = targetCoord000.x + x; - if (coord.x < 0 || - coord.y < 0 || - coord.z < 0 || - coord.x >= self->super.dimensions.x || - coord.y >= self->super.dimensions.y || - coord.z >= self->super.dimensions.z - ) - continue; - - BlockBrickedVolume_getVoxelAddress(self, coord, address); - foreach_unique(blockID in address.block) { - float *uniform blockPtr - = ((float*uniform)self->blockMem) - + blockID * (uint64)BLOCK_VOXEL_COUNT; - blockPtr[address.voxel] = run[x]; - } - } -} +template_setRegion(uint8); +template_setRegion(uint16); +template_setRegion(float); +template_setRegion(double); +#undef template_setRegion -/*! copy given block of voxels into the volume, where source[0] will - be written to volume[targetCoord000] */ -void BlockBrickedVolumeDouble_setRegion(BlockBrickedVolume *uniform self, - const void *uniform _source, - const uniform vec3i &targetCoord000, - const uniform vec3i ®ionSize, - const uniform int taskIndex) -{ - const double *uniform source = (const double *uniform)_source; - const uniform uint32 region_y = taskIndex % regionSize.y; - const uniform uint32 region_z = taskIndex / regionSize.y; - const uniform uint64 runOfs = (uint64)regionSize.x * (region_y + (uint64)regionSize.y * region_z); - const double *uniform run = source + runOfs; - vec3i coord = targetCoord000 + make_vec3i(0,region_y,region_z); - foreach (x = 0 ... regionSize.x) { - Address address; - coord.x = targetCoord000.x + x; - if (coord.x < 0 || - coord.y < 0 || - coord.z < 0 || - coord.x >= self->super.dimensions.x || - coord.y >= self->super.dimensions.y || - coord.z >= self->super.dimensions.z - ) - continue; - BlockBrickedVolume_getVoxelAddress(self, coord, address); - foreach_unique(blockID in address.block) { - double *uniform blockPtr - = ((double*uniform)self->blockMem) - + blockID * (uint64)BLOCK_VOXEL_COUNT; - blockPtr[address.voxel] = run[x]; - } - } -} void BlockBrickedVolume_Constructor(BlockBrickedVolume *uniform volume, /*! pointer to the c++-equivalent class of this entity */ @@ -285,18 +189,23 @@ void BlockBrickedVolume_Constructor(BlockBrickedVolume *uniform volume, if (volume->voxelType == OSP_UCHAR) { volume->voxelSize = sizeof(uniform uint8); - volume->super.getVoxel = BlockBrickedVolumeUChar_getVoxel; - volume->setRegion = &BlockBrickedVolumeUChar_setRegion; + volume->super.getVoxel = BlockBrickedVolume_getVoxel_uint8; + volume->setRegion = &BlockBrickedVolume_setRegion_uint8; + } + else if (volume->voxelType == OSP_USHORT) { + volume->voxelSize = sizeof(uniform uint16); + volume->super.getVoxel = BlockBrickedVolume_getVoxel_uint16; + volume->setRegion = &BlockBrickedVolume_setRegion_uint16; } else if (volume->voxelType == OSP_FLOAT) { volume->voxelSize = sizeof(uniform float); - volume->super.getVoxel = BlockBrickedVolumeFloat_getVoxel; - volume->setRegion = &BlockBrickedVolumeFloat_setRegion; + volume->super.getVoxel = BlockBrickedVolume_getVoxel_float; + volume->setRegion = &BlockBrickedVolume_setRegion_float; } else if (volume->voxelType == OSP_DOUBLE) { volume->voxelSize = sizeof(uniform double); - volume->super.getVoxel = BlockBrickedVolumeDouble_getVoxel; - volume->setRegion = &BlockBrickedVolumeDouble_setRegion; + volume->super.getVoxel = BlockBrickedVolume_getVoxel_double; + volume->setRegion = &BlockBrickedVolume_setRegion_double; } else { print("#osp:block_bricked_volume: unknown voxel type\n"); @@ -307,56 +216,6 @@ void BlockBrickedVolume_Constructor(BlockBrickedVolume *uniform volume, BlockBrickedVolume_allocateMemory(volume); } -inline varying float BlockBrickedVolumeFloat_computeSample(void *uniform _volume, const varying vec3f &worldCoordinates) -{ - // Cast to the actual Volume subtype. - StructuredVolume *uniform volume = (StructuredVolume *uniform) _volume; - - // Transform the sample location into the local coordinate system. - vec3f localCoordinates; - volume->transformWorldToLocal(volume, worldCoordinates, localCoordinates); - - // Coordinates outside the volume are clamped to the volume bounds. - const vec3f clampedLocalCoordinates = clamp(localCoordinates, make_vec3f(0.0f), - volume->localCoordinatesUpperBound); - - // Lower and upper corners of the box straddling the voxels to be interpolated. - const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); - const vec3i voxelIndex_1 = voxelIndex_0 + 1; - - // Fractional coordinates within the lower corner voxel used during interpolation. - const vec3f fractionalLocalCoordinates = clampedLocalCoordinates - float_cast(voxelIndex_0); - - // Look up the voxel values to be interpolated. - float voxelValue_000; - float voxelValue_001; - float voxelValue_010; - float voxelValue_011; - float voxelValue_100; - float voxelValue_101; - float voxelValue_110; - float voxelValue_111; - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_0.x, voxelIndex_0.y, voxelIndex_0.z), voxelValue_000); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_1.x, voxelIndex_0.y, voxelIndex_0.z), voxelValue_001); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_0.x, voxelIndex_1.y, voxelIndex_0.z), voxelValue_010); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_1.x, voxelIndex_1.y, voxelIndex_0.z), voxelValue_011); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_0.x, voxelIndex_0.y, voxelIndex_1.z), voxelValue_100); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_1.x, voxelIndex_0.y, voxelIndex_1.z), voxelValue_101); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_0.x, voxelIndex_1.y, voxelIndex_1.z), voxelValue_110); - BlockBrickedVolumeFloat_getVoxel(volume, make_vec3i(voxelIndex_1.x, voxelIndex_1.y, voxelIndex_1.z), voxelValue_111); - - // Interpolate the voxel values. - const float voxelValue_00 = voxelValue_000 + fractionalLocalCoordinates.x * (voxelValue_001 - voxelValue_000); - const float voxelValue_01 = voxelValue_010 + fractionalLocalCoordinates.x * (voxelValue_011 - voxelValue_010); - const float voxelValue_10 = voxelValue_100 + fractionalLocalCoordinates.x * (voxelValue_101 - voxelValue_100); - const float voxelValue_11 = voxelValue_110 + fractionalLocalCoordinates.x * (voxelValue_111 - voxelValue_110); - const float voxelValue_0 = voxelValue_00 + fractionalLocalCoordinates.y * (voxelValue_01 - voxelValue_00 ); - const float voxelValue_1 = voxelValue_10 + fractionalLocalCoordinates.y * (voxelValue_11 - voxelValue_10 ); - const float volumeSample = voxelValue_0 + fractionalLocalCoordinates.z * (voxelValue_1 - voxelValue_0 ); - - return volumeSample; -} - export void *uniform BlockBrickedVolume_createInstance(void *uniform cppEquivalent, const uniform int voxelType, @@ -364,12 +223,8 @@ export void *uniform BlockBrickedVolume_createInstance(void *uniform cppEquivale { // The volume container. BlockBrickedVolume *uniform volume = uniform new uniform BlockBrickedVolume; - BlockBrickedVolume_Constructor(volume, cppEquivalent, voxelType, dimensions); - // if (voxelType == OSP_FLOAT) { - // print("using hand-inlined computesample fct for block-bricked\n"); - // volume->super.super.computeSample = BlockBrickedVolumeFloat_computeSample; - // } + return volume; } diff --git a/ospray/volume/GhostBlockBrickedVolume.cpp b/ospray/volume/GhostBlockBrickedVolume.cpp index 6a14d4c11f..66b8247fa0 100644 --- a/ospray/volume/GhostBlockBrickedVolume.cpp +++ b/ospray/volume/GhostBlockBrickedVolume.cpp @@ -82,6 +82,8 @@ namespace ospray { + (size_t)regionSize.z; if (voxelType == "uchar") computeVoxelRange((unsigned char *)source, numVoxelsInRegion); + else if (voxelType == "ushort") + computeVoxelRange((unsigned short *)source, numVoxelsInRegion); else if (voxelType == "float") computeVoxelRange((float *)source, numVoxelsInRegion); else if (voxelType == "double") diff --git a/ospray/volume/GhostBlockBrickedVolume.ispc b/ospray/volume/GhostBlockBrickedVolume.ispc index d88e16302e..34a7dacab4 100644 --- a/ospray/volume/GhostBlockBrickedVolume.ispc +++ b/ospray/volume/GhostBlockBrickedVolume.ispc @@ -60,6 +60,7 @@ /*! @{ number of bits we have to SHIFT addresses for given type */ #define shift_per_uint8 0 +#define shift_per_uint16 1 #define shift_per_float 2 #define shift_per_double 3 /*! @} */ @@ -67,6 +68,7 @@ /*! @{ number of bits we have to MULTIPLY offsets with for given type */ #define scale_per_uint8 1 +#define scale_per_uint16 2 #define scale_per_float 4 #define scale_per_double 8 /*! @} */ @@ -155,6 +157,7 @@ inline int intDiv(float x) } template_brickTranslation(uint8); +template_brickTranslation(uint16); template_brickTranslation(float); template_brickTranslation(double); @@ -222,6 +225,7 @@ template_brickTranslation(double); } template_getAddress(uint8); +template_getAddress(uint16); template_getAddress(float); template_getAddress(double); @@ -315,6 +319,7 @@ inline bool GBBV_getGhostIndices(GBBV *uniform volume, } \ template_accessArray(uint8); +template_accessArray(uint16); template_accessArray(float); template_accessArray(double); #undef template_accessArray @@ -347,6 +352,7 @@ template_accessArray(double); } template_getVoxel(uint8) +template_getVoxel(uint16) template_getVoxel(float) template_getVoxel(double) #undef template_getVoxel @@ -402,6 +408,7 @@ void GBBV_setRegionTask_##type(GBBV *uniform self, } template_setRegion(uint8) +template_setRegion(uint16) template_setRegion(float) template_setRegion(double) #undef template_setRegion @@ -491,6 +498,7 @@ template_setRegion(double) } template_computeSample(uint8) +template_computeSample(uint16) template_computeSample(float) template_computeSample(double) #undef template_computeSample @@ -534,6 +542,12 @@ void GBBV_Constructor(GBBV *uniform volume, volume->setRegion = &GBBV_setRegionTask_uint8; volume->super.super.computeSample = GBBV_computeSample_uint8; } + else if (volume->voxelType == OSP_USHORT) { + volume->voxelSize = sizeof(uniform uint16); + volume->super.getVoxel = GBBV_getVoxel_uint16; + volume->setRegion = &GBBV_setRegionTask_uint16; + volume->super.super.computeSample = GBBV_computeSample_uint16; + } else if (volume->voxelType == OSP_FLOAT) { volume->voxelSize = sizeof(uniform float); volume->super.getVoxel = GBBV_getVoxel_float; diff --git a/ospray/volume/SharedStructuredVolume.cpp b/ospray/volume/SharedStructuredVolume.cpp index fce5cd956f..c198c88b53 100644 --- a/ospray/volume/SharedStructuredVolume.cpp +++ b/ospray/volume/SharedStructuredVolume.cpp @@ -56,6 +56,11 @@ SharedStructuredVolume::~SharedStructuredVolume() (const ispc::vec3i&)index, (const ispc::vec3i&)count); break; + case OSP_USHORT: + ispc::SharedStructuredVolume_setRegion_uint16(getIE(),source, + (const ispc::vec3i&)index, + (const ispc::vec3i&)count); + break; case OSP_FLOAT: ispc::SharedStructuredVolume_setRegion_float(getIE(),source, (const ispc::vec3i&)index, diff --git a/ospray/volume/SharedStructuredVolume.ispc b/ospray/volume/SharedStructuredVolume.ispc index 11e8273ba5..a9b6ea2e15 100644 --- a/ospray/volume/SharedStructuredVolume.ispc +++ b/ospray/volume/SharedStructuredVolume.ispc @@ -16,186 +16,81 @@ #include "ospray/volume/SharedStructuredVolume.ih" -// ----------------------------------------------------------------------------- -// versions for pure 32-bit addressing. volume *MUST* be smaller than 2G -// ----------------------------------------------------------------------------- - -/*! get a voxel from given volume type, assuming we can use 32-bit addressing */ -inline void SharedStructuredVolumeUChar_getVoxel_32(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - // Cast to the actual voxel type. - const uint8 *uniform voxelData = (const uint8 *uniform) volume->voxelData; - - // The voxel value at the given index. - value = voxelData[index.x + volume->super.dimensions.x * (index.y + volume->super.dimensions.y * index.z)]; -} - -/*! get a voxel from given volume type, assuming we can use 32-bit addressing */ -inline void SharedStructuredVolumeFloat_getVoxel_32(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - // Cast to the actual voxel type. - const float *uniform voxelData = (const float *uniform) volume->voxelData; - const uint32 addr = index.x + volume->super.dimensions.x * (index.y + volume->super.dimensions.y * index.z); - - // The voxel value at the given index. - value = voxelData[addr]; -} - -/*! get a voxel from given volume type, assuming we can use 32-bit addressing */ -inline void SharedStructuredVolumeDouble_getVoxel_32(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - // Cast to the actual voxel type. - const double *uniform voxelData = (const double *uniform) volume->voxelData; - const uint32 addr = index.x + volume->super.dimensions.x * (index.y + volume->super.dimensions.y * index.z); - - // The voxel value at the given index. - value = voxelData[addr]; -} - - -// ----------------------------------------------------------------------------- -// versions for 64/32-bit addressing. volume itself can be larger than -// 2G, but each slice must be within the 2G limit. -// ----------------------------------------------------------------------------- - -/*! get a voxel from given volume type, assuming we need proper 64-bit addressing */ -inline void SharedStructuredVolumeUChar_getVoxel_64_32(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - - const uniform uint8 *uniform basePtr = (const uniform uint8 *uniform)volume->voxelData; - - // iterate over slices, then do 32-bit gather in slice - const uint32 ofs = index.x + volume->super.dimensions.x * index.y; - foreach_unique (z in index.z) { - const uniform uint64 byteOffset = z * volume->bytesPerSlice; - const uniform uint8 *uniform sliceData - = (const uniform uint8 *uniform )(basePtr + byteOffset); - value = sliceData[ofs]; - } -} - -/*! get a voxel from given volume type, assuming we need proper 64-bit addressing */ -inline void SharedStructuredVolumeFloat_getVoxel_64_32(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - const uniform uint8 *uniform basePtr = (const uniform uint8 *uniform)volume->voxelData; - - // iterate over slices, then do 32-bit gather in slice - const uint32 ofs = index.x + volume->super.dimensions.x * index.y; - foreach_unique (z in index.z) { - const uniform uint64 byteOffset = z * volume->bytesPerSlice; - const uniform float *uniform sliceData - = (const uniform float *uniform )(basePtr + byteOffset); - value = sliceData[ofs]; - } -} - -/*! get a voxel from given volume type, assuming we need proper 64-bit addressing */ -inline void SharedStructuredVolumeDouble_getVoxel_64_32(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - const uniform uint8 *uniform basePtr = (const uniform uint8 *uniform)volume->voxelData; - - // iterate over slices, then do 32-bit gather in slice - const uint32 ofs = index.x + volume->super.dimensions.x * index.y; - foreach_unique (z in index.z) { - const uniform uint64 byteOffset = z * volume->bytesPerSlice; - const uniform double *uniform sliceData - = (const uniform double *uniform )(basePtr + byteOffset); - value = sliceData[ofs]; - } -} - - -// ----------------------------------------------------------------------------- -// versions for full 64-bit addressing, no matter what the dimensions or slice size -// ----------------------------------------------------------------------------- - -/*! get a voxel from given volume type, assuming we need proper 64-bit addressing */ -inline void SharedStructuredVolumeUChar_getVoxel_64(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - const uint64 index64 = - (uint64)index.x + volume->super.dimensions.x * ((int64)index.y + volume->super.dimensions.y * ((uint64)index.z)); - const uint32 hi28 = index64 >> 28; - const uint32 lo28 = index64 & ((1<<28)-1); - - foreach_unique (hi in hi28) { - const uniform uint64 hi64 = hi; - const uint8 *uniform base = ((const uint8 *)volume->voxelData) + (hi64<<28); - value = base[lo28]; - } -} - -/*! get a voxel from given volume type, assuming we need proper 64-bit addressing */ -inline void SharedStructuredVolumeFloat_getVoxel_64(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - const uint64 index64 = (uint64)index.x + volume->super.dimensions.x * ((int64)index.y + volume->super.dimensions.y * ((uint64)index.z)); - const uint32 hi28 = index64 >> 28; - const uint32 lo28 = index64 & ((1<<28)-1); - - foreach_unique (hi in hi28) { - const uniform uint64 hi64 = hi; - const float *uniform base = ((const float *)volume->voxelData) + (hi64<<28); - value = base[lo28]; - } +/*! get a voxel from given volume type */ + +#define template_getVoxel(type) \ +/* --------------------------------------------------------------------------\ +// versions for pure 32-bit addressing. volume *MUST* be smaller than 2G \ +// ------------------------------------------------------------------------*/\ +inline void SSV_getVoxel_##type##_32(void *uniform _self, \ + const varying vec3i &index, \ + varying float &value) \ +{ \ + /* Cast to the actual Volume subtype. */ \ + SharedStructuredVolume *uniform self \ + = (SharedStructuredVolume *uniform)_self; \ + \ + /* Cast to the actual voxel type. */ \ + const type *uniform voxelData = (const type *uniform)self->voxelData; \ + const uint32 addr = index.x + \ + self->super.dimensions.x*(index.y + self->super.dimensions.y*index.z); \ + \ + /* The voxel value at the given index. */ \ + value = voxelData[addr]; \ +} \ +/* --------------------------------------------------------------------------\ +// versions for 64/32-bit addressing. volume itself can be larger than \ +// 2G, but each slice must be within the 2G limit. \ +// ------------------------------------------------------------------------*/\ +inline void SSV_getVoxel_##type##_64_32(void *uniform _self, \ + const varying vec3i &index, \ + varying float &value) \ +{ \ + /* Cast to the actual Volume subtype. */ \ + SharedStructuredVolume *uniform self \ + = (SharedStructuredVolume *uniform)_self; \ + \ + const uniform uint8 *uniform basePtr = \ + (const uniform uint8 *uniform)self->voxelData; \ + \ + /* iterate over slices, then do 32-bit gather in slice */ \ + const uint32 ofs = index.x + self->super.dimensions.x * index.y; \ + foreach_unique (z in index.z) { \ + const uniform uint64 byteOffset = z * self->bytesPerSlice; \ + const uniform type *uniform sliceData \ + = (const uniform type *uniform )(basePtr + byteOffset); \ + value = sliceData[ofs]; \ + } \ +} \ +/* --------------------------------------------------------------------------\ +// versions for full 64-bit addressing, for all dimensions or slice size \ +// ------------------------------------------------------------------------*/\ +inline void SSV_getVoxel_##type##_64(void *uniform _self, \ + const varying vec3i &index, \ + varying float &value) \ +{ \ + /* Cast to the actual Volume subtype. */ \ + SharedStructuredVolume *uniform self \ + = (SharedStructuredVolume *uniform)_self; \ + \ + const uint64 index64 = (uint64)index.x + self->super.dimensions.x * \ + ((int64)index.y + self->super.dimensions.y * ((uint64)index.z)); \ + const uint32 hi28 = index64 >> 28; \ + const uint32 lo28 = index64 & ((1<<28)-1); \ + \ + foreach_unique (hi in hi28) { \ + const uniform uint64 hi64 = hi; \ + const type *uniform base = ((const type *)self->voxelData) + (hi64<<28); \ + value = base[lo28]; \ + } \ } -/*! get a voxel from given volume type, assuming we need proper 64-bit addressing */ -inline void SharedStructuredVolumeDouble_getVoxel_64(void *uniform _volume, - const varying vec3i &index, - varying float &value) -{ - // Cast to the actual Volume subtype. - SharedStructuredVolume *uniform volume = (SharedStructuredVolume *uniform) _volume; - - const uint64 index64 = (uint64)index.x + volume->super.dimensions.x * ((int64)index.y + volume->super.dimensions.y * ((uint64)index.z)); - const uint32 hi28 = index64 >> 28; - const uint32 lo28 = index64 & ((1<<28)-1); +template_getVoxel(uint8); +template_getVoxel(uint16); +template_getVoxel(float); +template_getVoxel(double); +#undef template_getVoxel - foreach_unique (hi in hi28) { - const uniform uint64 hi64 = hi; - const double *uniform base = ((const double *)volume->voxelData) + (hi64<<28); - value = base[lo28]; - } -} /*! read a _typed_ value from an address that's given by an *BYTE*-offset relative to a base array. note that even though we @@ -203,23 +98,23 @@ inline void SharedStructuredVolumeDouble_getVoxel_64(void *uniform _volume, the width of the array data type), the the base pointer must *STILL* be of the proper type for this macro to figure out the type of data it's reading from this address */ -#define template_accessArray(type) \ - inline float accessArrayWithOffset(const type *uniform basePtr, \ - const varying uint32 offset) \ - { \ - uniform uint8 *uniform base = (uniform uint8 *uniform)basePtr; \ - return *((uniform type *)(base+offset)); \ - } \ - inline float accessArrayWithOffset(const type *uniform basePtr, \ - const uniform uint64 baseOfs, \ - const varying uint32 offset) \ - { \ - uniform uint8 *uniform base \ - = (uniform uint8 *uniform)(basePtr); \ - return *((uniform type *)((base+baseOfs)+offset)); \ - } \ +#define template_accessArray(type) \ +inline float accessArrayWithOffset(const type *uniform basePtr, \ + const varying uint32 offset) \ +{ \ + uniform uint8 *uniform base = (uniform uint8 *uniform)basePtr; \ + return *((uniform type *)(base+offset)); \ +} \ +inline float accessArrayWithOffset(const type *uniform basePtr, \ + const uniform uint64 baseOfs, \ + const varying uint32 offset) \ +{ \ + uniform uint8 *uniform base = (uniform uint8 *uniform)(basePtr); \ + return *((uniform type *)((base+baseOfs)+offset)); \ +} \ template_accessArray(uint8); +template_accessArray(uint16); template_accessArray(float); template_accessArray(double); #undef template_accessArray @@ -231,136 +126,135 @@ template_accessArray(double); function will directly do all the addressing for the getSample (inlined), and thus be about 50% faster (wall-time, meaning even much faster in pure sample speed) */ -#define template_computeSample(type) \ - inline float SSV_computeSample_##type##_32(void *uniform _self, \ - const vec3f &worldCoordinates) \ - { \ - /* Cast to the actual Volume subtype. */ \ - SharedStructuredVolume *uniform self \ - = (SharedStructuredVolume *uniform) _self; \ - \ - /* Transform the sample location into the local coordinate system. */ \ - vec3f localCoordinates; \ - self->super.transformWorldToLocal(&self->super, \ - worldCoordinates, \ - localCoordinates); \ - \ - /* Coordinates outside the volume are clamped to the volume bounds. */ \ - const vec3f clampedLocalCoordinates \ - = clamp(localCoordinates, make_vec3f(0.0f), \ - self->super.localCoordinatesUpperBound); \ - \ - /* Lower and upper corners of the box straddling the voxels to be interpolated. */ \ - const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); \ - \ - /* Fractional coordinates within the lower corner voxel used during interpolation. */ \ - const vec3f frac = clampedLocalCoordinates - float_cast(voxelIndex_0); \ - \ - const uint32 voxelOfs \ - = voxelIndex_0.x * self->voxelOfs_dx \ - + voxelIndex_0.y * self->voxelOfs_dy \ - + voxelIndex_0.z * self->voxelOfs_dz; \ - const type *uniform voxelData \ - = (const type *uniform)self->voxelData; \ - const uniform uint64 ofs000 = 0; \ - const uniform uint64 ofs001 = self->bytesPerVoxel; \ - const float val000 = accessArrayWithOffset(voxelData,ofs000,voxelOfs); \ - const float val001 = accessArrayWithOffset(voxelData,ofs001,voxelOfs); \ - const float val00 = val000 + frac.x * (val001 - val000); \ - \ - const uniform uint64 ofs010 = self->bytesPerLine; \ - const uniform uint64 ofs011 = self->bytesPerLine+self->bytesPerVoxel; \ - const float val010 = accessArrayWithOffset(voxelData,ofs010,voxelOfs); \ - const float val011 = accessArrayWithOffset(voxelData,ofs011,voxelOfs); \ - const float val01 = val010 + frac.x * (val011 - val010); \ - \ - const uniform uint64 ofs100 = self->bytesPerSlice; \ - const uniform uint64 ofs101 = ofs100 + ofs001; \ - const float val100 = accessArrayWithOffset(voxelData,ofs100,voxelOfs); \ - const float val101 = accessArrayWithOffset(voxelData,ofs101,voxelOfs); \ - const float val10 = val100 + frac.x * (val101 - val100); \ - \ - const uniform uint64 ofs110 = ofs100 + ofs010; \ - const uniform uint64 ofs111 = ofs100 + ofs011; \ - const float val110 = accessArrayWithOffset(voxelData,ofs110,voxelOfs); \ - const float val111 = accessArrayWithOffset(voxelData,ofs111,voxelOfs); \ - const float val11 = val110 + frac.x * (val111 - val110); \ - \ - /* Interpolate the voxel values. */ \ - const float val0 = val00 + frac.y * (val01 - val00 ); \ - const float val1 = val10 + frac.y * (val11 - val10 ); \ - const float val = val0 + frac.z * (val1 - val0 ); \ - \ - return val; \ - } \ - \ - inline float SSV_computeSample_##type##_64_32(void *uniform _self, \ - const vec3f &worldCoordinates) \ - { \ - /* Cast to the actual Volume subtype. */ \ - SharedStructuredVolume *uniform self \ - = (SharedStructuredVolume *uniform) _self; \ - \ - /* Transform the sample location into the local coordinate system. */ \ - vec3f localCoordinates; \ - self->super.transformWorldToLocal(&self->super, \ - worldCoordinates, \ - localCoordinates); \ - \ - /* Coordinates outside the volume are clamped to the volume bounds. */ \ - const vec3f clampedLocalCoordinates \ - = clamp(localCoordinates, make_vec3f(0.0f), \ - self->super.localCoordinatesUpperBound); \ - \ - /* Lower and upper corners of the box straddling the voxels to be interpolated. */ \ - const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); \ - \ - /* Fractional coordinates within the lower corner voxel used during interpolation. */ \ - const vec3f frac = clampedLocalCoordinates - float_cast(voxelIndex_0); \ - \ - varying float ret = 0.f; \ - foreach_unique (sliceID in voxelIndex_0.z) { \ - const uint32 voxelOfs \ - = voxelIndex_0.x * self->voxelOfs_dx \ - + voxelIndex_0.y * self->voxelOfs_dy; \ - const type *uniform voxelData \ - = (const type *uniform)((uniform uint8*uniform)self->voxelData \ - +sliceID*self->bytesPerSlice); \ - const uniform uint64 ofs000 = 0; \ - const uniform uint64 ofs001 = self->bytesPerVoxel; \ - const float val000 = accessArrayWithOffset(voxelData,ofs000,voxelOfs); \ - const float val001 = accessArrayWithOffset(voxelData,ofs001,voxelOfs); \ - const float val00 = val000 + frac.x * (val001 - val000); \ - \ - const uniform uint64 ofs010 = self->bytesPerLine; \ - const uniform uint64 ofs011 = self->bytesPerLine+self->bytesPerVoxel; \ - const float val010 = accessArrayWithOffset(voxelData,ofs010,voxelOfs); \ - const float val011 = accessArrayWithOffset(voxelData,ofs011,voxelOfs); \ - const float val01 = val010 + frac.x * (val011 - val010); \ - \ - const uniform uint64 ofs100 = self->bytesPerSlice; \ - const uniform uint64 ofs101 = ofs100 + ofs001; \ - const float val100 = accessArrayWithOffset(voxelData,ofs100,voxelOfs); \ - const float val101 = accessArrayWithOffset(voxelData,ofs101,voxelOfs); \ - const float val10 = val100 + frac.x * (val101 - val100); \ - \ - const uniform uint64 ofs110 = ofs100 + ofs010; \ - const uniform uint64 ofs111 = ofs100 + ofs011; \ - const float val110 = accessArrayWithOffset(voxelData,ofs110,voxelOfs); \ - const float val111 = accessArrayWithOffset(voxelData,ofs111,voxelOfs); \ - const float val11 = val110 + frac.x * (val111 - val110); \ - \ - /* Interpolate the voxel values. */ \ - const float val0 = val00 + frac.y * (val01 - val00 ); \ - const float val1 = val10 + frac.y * (val11 - val10 ); \ - const float val = val0 + frac.z * (val1 - val0 ); \ - ret = val; \ - } \ - return ret; \ - } - +#define template_computeSample(type) \ +inline float SSV_computeSample_##type##_32(void *uniform _self, \ + const vec3f &worldCoordinates) \ +{ \ + /* Cast to the actual Volume subtype. */ \ + SharedStructuredVolume *uniform self \ + = (SharedStructuredVolume *uniform)_self; \ + \ + /* Transform the sample location into the local coordinate system. */ \ + vec3f localCoordinates; \ + self->super.transformWorldToLocal(&self->super, \ + worldCoordinates, \ + localCoordinates); \ + \ + /* Coordinates outside the volume are clamped to the volume bounds. */ \ + const vec3f clampedLocalCoordinates \ + = clamp(localCoordinates, make_vec3f(0.0f), \ + self->super.localCoordinatesUpperBound); \ + \ + /* Lower and upper corners of the box straddling the voxels to be interpolated. */\ + const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); \ + \ + /* Fractional coordinates within the lower corner voxel used during interpolation. */\ + const vec3f frac = clampedLocalCoordinates - float_cast(voxelIndex_0); \ + \ + const uint32 voxelOfs \ + = voxelIndex_0.x * self->voxelOfs_dx \ + + voxelIndex_0.y * self->voxelOfs_dy \ + + voxelIndex_0.z * self->voxelOfs_dz; \ + const type *uniform voxelData = (const type *uniform)self->voxelData; \ + const uniform uint64 ofs000 = 0; \ + const uniform uint64 ofs001 = self->bytesPerVoxel; \ + const float val000 = accessArrayWithOffset(voxelData,ofs000,voxelOfs); \ + const float val001 = accessArrayWithOffset(voxelData,ofs001,voxelOfs); \ + const float val00 = val000 + frac.x * (val001 - val000); \ + \ + const uniform uint64 ofs010 = self->bytesPerLine; \ + const uniform uint64 ofs011 = self->bytesPerLine+self->bytesPerVoxel; \ + const float val010 = accessArrayWithOffset(voxelData,ofs010,voxelOfs); \ + const float val011 = accessArrayWithOffset(voxelData,ofs011,voxelOfs); \ + const float val01 = val010 + frac.x * (val011 - val010); \ + \ + const uniform uint64 ofs100 = self->bytesPerSlice; \ + const uniform uint64 ofs101 = ofs100 + ofs001; \ + const float val100 = accessArrayWithOffset(voxelData,ofs100,voxelOfs); \ + const float val101 = accessArrayWithOffset(voxelData,ofs101,voxelOfs); \ + const float val10 = val100 + frac.x * (val101 - val100); \ + \ + const uniform uint64 ofs110 = ofs100 + ofs010; \ + const uniform uint64 ofs111 = ofs100 + ofs011; \ + const float val110 = accessArrayWithOffset(voxelData,ofs110,voxelOfs); \ + const float val111 = accessArrayWithOffset(voxelData,ofs111,voxelOfs); \ + const float val11 = val110 + frac.x * (val111 - val110); \ + \ + /* Interpolate the voxel values. */ \ + const float val0 = val00 + frac.y * (val01 - val00); \ + const float val1 = val10 + frac.y * (val11 - val10); \ + const float val = val0 + frac.z * (val1 - val0 ); \ + \ + return val; \ +} \ + \ +inline float SSV_computeSample_##type##_64_32(void *uniform _self, \ + const vec3f &worldCoordinates) \ +{ \ + /* Cast to the actual Volume subtype. */ \ + SharedStructuredVolume *uniform self \ + = (SharedStructuredVolume *uniform)_self; \ + \ + /* Transform the sample location into the local coordinate system. */ \ + vec3f localCoordinates; \ + self->super.transformWorldToLocal(&self->super, \ + worldCoordinates, \ + localCoordinates); \ + \ + /* Coordinates outside the volume are clamped to the volume bounds. */ \ + const vec3f clampedLocalCoordinates \ + = clamp(localCoordinates, make_vec3f(0.0f), \ + self->super.localCoordinatesUpperBound); \ + \ + /* Lower and upper corners of the box straddling the voxels to be interpolated. */\ + const vec3i voxelIndex_0 = integer_cast(clampedLocalCoordinates); \ + \ + /* Fractional coordinates within the lower corner voxel used during interpolation. */\ + const vec3f frac = clampedLocalCoordinates - float_cast(voxelIndex_0); \ + \ + varying float ret = 0.f; \ + foreach_unique (sliceID in voxelIndex_0.z) { \ + const uint32 voxelOfs \ + = voxelIndex_0.x * self->voxelOfs_dx \ + + voxelIndex_0.y * self->voxelOfs_dy; \ + const type *uniform voxelData \ + = (const type *uniform)((uniform uint8*uniform)self->voxelData \ + +sliceID*self->bytesPerSlice); \ + const uniform uint64 ofs000 = 0; \ + const uniform uint64 ofs001 = self->bytesPerVoxel; \ + const float val000 = accessArrayWithOffset(voxelData,ofs000,voxelOfs); \ + const float val001 = accessArrayWithOffset(voxelData,ofs001,voxelOfs); \ + const float val00 = val000 + frac.x * (val001 - val000); \ + \ + const uniform uint64 ofs010 = self->bytesPerLine; \ + const uniform uint64 ofs011 = self->bytesPerLine+self->bytesPerVoxel; \ + const float val010 = accessArrayWithOffset(voxelData,ofs010,voxelOfs); \ + const float val011 = accessArrayWithOffset(voxelData,ofs011,voxelOfs); \ + const float val01 = val010 + frac.x * (val011 - val010); \ + \ + const uniform uint64 ofs100 = self->bytesPerSlice; \ + const uniform uint64 ofs101 = ofs100 + ofs001; \ + const float val100 = accessArrayWithOffset(voxelData,ofs100,voxelOfs); \ + const float val101 = accessArrayWithOffset(voxelData,ofs101,voxelOfs); \ + const float val10 = val100 + frac.x * (val101 - val100); \ + \ + const uniform uint64 ofs110 = ofs100 + ofs010; \ + const uniform uint64 ofs111 = ofs100 + ofs011; \ + const float val110 = accessArrayWithOffset(voxelData,ofs110,voxelOfs); \ + const float val111 = accessArrayWithOffset(voxelData,ofs111,voxelOfs); \ + const float val11 = val110 + frac.x * (val111 - val110); \ + \ + /* Interpolate the voxel values. */ \ + const float val0 = val00 + frac.y * (val01 - val00); \ + const float val1 = val10 + frac.y * (val11 - val10); \ + const float val = val0 + frac.z * (val1 - val0 ); \ + ret = val; \ + } \ + return ret; \ +} template_computeSample(uint8) +template_computeSample(uint16) template_computeSample(float) template_computeSample(double) #undef template_computeSample @@ -378,6 +272,8 @@ void SharedStructuredVolume_Constructor(SharedStructuredVolume *uniform self, if (voxelType == OSP_UCHAR) bytesPerVoxel = sizeof(uniform uint8); + if (voxelType == OSP_USHORT) + bytesPerVoxel = sizeof(uniform uint16); else if (voxelType == OSP_FLOAT) bytesPerVoxel = sizeof(uniform float); else if (voxelType == OSP_DOUBLE) @@ -405,13 +301,16 @@ void SharedStructuredVolume_Constructor(SharedStructuredVolume *uniform self, // in this case, we know ALL addressing can be 32-bit. if (voxelType == OSP_UCHAR) { - self->super.getVoxel = SharedStructuredVolumeUChar_getVoxel_32; + self->super.getVoxel = SSV_getVoxel_uint8_32; self->super.super.computeSample = SSV_computeSample_uint8_32; + } else if (voxelType == OSP_USHORT) { + self->super.getVoxel = SSV_getVoxel_uint16_32; + self->super.super.computeSample = SSV_computeSample_float_32; } else if (voxelType == OSP_FLOAT) { - self->super.getVoxel = SharedStructuredVolumeFloat_getVoxel_32; + self->super.getVoxel = SSV_getVoxel_float_32; self->super.super.computeSample = SSV_computeSample_float_32; } else if (voxelType == OSP_DOUBLE) { - self->super.getVoxel = SharedStructuredVolumeDouble_getVoxel_32; + self->super.getVoxel = SSV_getVoxel_double_32; self->super.super.computeSample = SSV_computeSample_double_32; } @@ -421,13 +320,16 @@ void SharedStructuredVolume_Constructor(SharedStructuredVolume *uniform self, // slice, but need 64-bit arithmetic to get slice begins if (voxelType == OSP_UCHAR) { - self->super.getVoxel = SharedStructuredVolumeUChar_getVoxel_64_32; + self->super.getVoxel = SSV_getVoxel_uint8_64_32; self->super.super.computeSample = SSV_computeSample_uint8_64_32; + } else if (voxelType == OSP_USHORT) { + self->super.getVoxel = SSV_getVoxel_uint16_64_32; + self->super.super.computeSample = SSV_computeSample_uint16_64_32; } else if (voxelType == OSP_FLOAT) { - self->super.getVoxel = SharedStructuredVolumeFloat_getVoxel_64_32; + self->super.getVoxel = SSV_getVoxel_float_64_32; self->super.super.computeSample = SSV_computeSample_float_64_32; } else if (voxelType == OSP_DOUBLE) { - self->super.getVoxel = SharedStructuredVolumeDouble_getVoxel_64_32; + self->super.getVoxel = SSV_getVoxel_double_64_32; self->super.super.computeSample = SSV_computeSample_double_64_32; } } else { @@ -436,12 +338,13 @@ void SharedStructuredVolume_Constructor(SharedStructuredVolume *uniform self, // addressing, and we have to do 64-bit throughout if (voxelType == OSP_UCHAR) - self->super.getVoxel = SharedStructuredVolumeUChar_getVoxel_64; + self->super.getVoxel = SSV_getVoxel_uint8_64; + else if (voxelType == OSP_USHORT) + self->super.getVoxel = SSV_getVoxel_uint16_64; else if (voxelType == OSP_FLOAT) - self->super.getVoxel = SharedStructuredVolumeFloat_getVoxel_64; + self->super.getVoxel = SSV_getVoxel_float_64; else if (voxelType == OSP_DOUBLE) - self->super.getVoxel = SharedStructuredVolumeDouble_getVoxel_64; - + self->super.getVoxel = SSV_getVoxel_double_64; } } @@ -460,33 +363,35 @@ export void *uniform SharedStructuredVolume_createInstance(void *uniform cppEqui /*! this is a very simple implementation that does not yet use either vectors OR threads ... should be fixed */ -#define template_setRegion(type) \ - export void SharedStructuredVolume_setRegion_##type \ - (void *uniform _self, \ - const void *uniform source, \ - const uniform vec3i &index, \ - const uniform vec3i &count) \ - { \ - SharedStructuredVolume *uniform self \ - = (SharedStructuredVolume *uniform)_self; \ - uniform type *uniform ptr_out = (uniform type *)self->voxelData; \ - const uniform type *uniform ptr_in = (const uniform type *)source; \ - for (uniform int iz=0;izsuper.dimensions.x \ - * (iiy+self->super.dimensions.y*iiz); \ - *(ptr_out+ofs_out) = ptr_in[ofs_in]; \ - } \ - } \ - } +#define template_setRegion(type) \ +export void SharedStructuredVolume_setRegion_##type \ +(void *uniform _self, \ + const void *uniform source, \ + const uniform vec3i &index, \ + const uniform vec3i &count) \ +{ \ + SharedStructuredVolume *uniform self \ + = (SharedStructuredVolume *uniform)_self; \ + uniform type *uniform ptr_out = (uniform type *)self->voxelData; \ + const uniform type *uniform ptr_in = (const uniform type *)source; \ + for (uniform int iz=0;izsuper.dimensions.x \ + * (iiy+self->super.dimensions.y*iiz); \ + *(ptr_out+ofs_out) = ptr_in[ofs_in]; \ + } \ + } \ +} template_setRegion(uint8); +template_setRegion(uint16); template_setRegion(float); template_setRegion(double); +#undef template_setRegion diff --git a/ospray/volume/StructuredVolume.cpp b/ospray/volume/StructuredVolume.cpp index 954f7c2ad6..1a957a76ef 100644 --- a/ospray/volume/StructuredVolume.cpp +++ b/ospray/volume/StructuredVolume.cpp @@ -114,6 +114,10 @@ namespace ospray { if (!strcmp(kind, "uchar") && width == 1) res = OSP_UCHAR; + // Unsigned 16-bit scalar integer. + if (!strcmp(kind, "ushort") && width == 1) + res = OSP_USHORT; + // Single precision scalar floating point. if (!strcmp(kind, "float") && width == 1) res = OSP_FLOAT; From 7885a8ac0ecbd5182035a45f9d1d9532adde5e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Thu, 28 Apr 2016 15:30:20 +0200 Subject: [PATCH 270/310] Normalize BRDFs in SciVis to match PT OBJ material --- ospray/render/pathtracer/bsdfs/Specular.ih | 4 ++-- ospray/render/scivis/SciVisRenderer.ispc | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ospray/render/pathtracer/bsdfs/Specular.ih b/ospray/render/pathtracer/bsdfs/Specular.ih index e794f53545..f33906081e 100644 --- a/ospray/render/pathtracer/bsdfs/Specular.ih +++ b/ospray/render/pathtracer/bsdfs/Specular.ih @@ -41,7 +41,7 @@ inline BSDF_EvalRes Specular_eval(const varying BSDF* uniform super, const vec3f refl = reflect(wo, getN(super)); if (dot(refl,wi) < 0.0f) return make_BSDF_EvalRes_zero(); res.pdf = powerCosineSampleHemispherePDF(dot(refl,wi), self->exp); - res.value = mul(self->R, (self->exp+2) * one_over_two_pi * pow(dot(refl,wi),self->exp) * clamp(dot(wi, getN(super)))); + res.value = self->R * ((self->exp+2.f) * one_over_two_pi * pow(dot(refl,wi),self->exp) * clamp(dot(wi, getN(super)))); return res; } @@ -56,7 +56,7 @@ inline BSDF_SampleRes Specular_sample(const varying BSDF* uniform super, res.wi = frame(refl) * localDir; res.pdf = powerCosineSampleHemispherePDF(localDir, self->exp); res.type = BSDF_GLOSSY_REFLECTION; - res.weight = mul(self->R, (self->exp+2) * rcp(self->exp+1) * clamp(dot(res.wi, getN(super)))); + res.weight = self->R * ((self->exp+2.f) * rcp(self->exp+1.f) * clamp(dot(res.wi, getN(super)))); return res; } diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index a8313c0e69..a0888a8e9b 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -107,6 +107,9 @@ inline void shadeMaterials(const varying DifferentialGeometry &dg, } } } + // BRDF normalization + info.Kd = info.Kd * one_over_pi; + info.Ks = info.Ks * ((info.Ns + 2.f) * one_over_two_pi); } // AO functions // @@ -139,6 +142,7 @@ inline float calculateAO(const uniform SciVisRenderer *uniform self, hits++; } + // the cosTheta of cosineSampleHemispherePDF and dot(dg.Ns, ao_dir) cancel return 1.0f - (float)hits/self->aoSamples; } @@ -600,7 +604,10 @@ export void SciVisRenderer_set(void *uniform _self, self->maxDepth = maxDepth; self->aoSamples = aoSamples; self->aoRayLength = aoRayLength; - self->aoWeight = aoWeight; + + // already factor in parts of cosineSampleHemispherePDF + self->aoWeight = aoWeight * pi; + self->lights = (const uniform Light *uniform *uniform)lights; self->numLights = numLights; } @@ -610,7 +617,7 @@ export void *uniform SciVisRenderer_create(void *uniform cppE) uniform SciVisRenderer *uniform self = uniform new uniform SciVisRenderer; Renderer_Constructor(&self->super,cppE); self->super.renderSample = SciVisRenderer_renderSample; - SciVisRenderer_set(self, true, 10, 4, infinity, 1.f, NULL, 0); + SciVisRenderer_set(self, true, 10, 4, infinity, 0.25f, NULL, 0); return self; } From 7dc65b37d84fccb03b0b6a4b2ac44331a623b5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 3 May 2016 10:17:32 +0200 Subject: [PATCH 271/310] More CMake cleanup --- CMakeLists.txt | 4 ---- ospray/common/OSPConfig.h.in | 1 - ospray/mpi/testing/TestDistributedApp.cpp | 5 ----- 3 files changed, 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3779af749..bbb595f5e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,10 +107,6 @@ STRING(TOUPPER ${OSPRAY_BUILD_ISA} OSPRAY_BUILD_ISA) SET(OSPRAY_MIC ${OSPRAY_BUILD_MIC_SUPPORT}) SET(OSPRAY_MPI ${OSPRAY_BUILD_MPI_DEVICE}) -IF (OSPRAY_MPI) - SET(OSPRAY_MPI_DISTRIBUTED ON) # sets this define in OSPConfig.h -ENDIF() - ############################################################## # create binary packages; before any INSTALL() invocation/definition ############################################################## diff --git a/ospray/common/OSPConfig.h.in b/ospray/common/OSPConfig.h.in index 01f6a4ee15..f6b4a8c556 100644 --- a/ospray/common/OSPConfig.h.in +++ b/ospray/common/OSPConfig.h.in @@ -36,7 +36,6 @@ #cmakedefine OSPRAY_EXP_IMAGE_COMPOSITING #cmakedefine OSPRAY_EXP_DISTRIBUTED_VOLUME #cmakedefine OSPRAY_EXP_ALPHA_BLENDING -#cmakedefine OSPRAY_MPI_DISTRIBUTED #endif #cmakedefine OSPRAY_VOLUME_VOXELRANGE_IN_APP #cmakedefine OSPRAY_PIN_ASYNC diff --git a/ospray/mpi/testing/TestDistributedApp.cpp b/ospray/mpi/testing/TestDistributedApp.cpp index 934001ceb4..6655dbaf9d 100644 --- a/ospray/mpi/testing/TestDistributedApp.cpp +++ b/ospray/mpi/testing/TestDistributedApp.cpp @@ -16,11 +16,6 @@ // ======================================================================== // -// enable the "mpi distributed" part of the ospray api -#ifndef OSPRAY_MPI_DISTRIBUTED -# define OSPRAY_MPI_DISTRIBUTED -#endif - #include #include From fd1de8d4adca12e76a5895f402ad9daa2deea5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 3 May 2016 14:22:20 +0200 Subject: [PATCH 272/310] Always have both MIS samples with more consistent max bounces behavior Do max_depth check after evaluation of lights and before next surface interaction. --- ospray/render/pathtracer/PathTracer.ispc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 682cd0efeb..7ae21ce5c9 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -143,7 +143,9 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, if (noHit(ray)) break; - + // terminate after evaluation of lights and before next shading to always have both samples for MIS + if (depth >= self->maxDepth) + break; //////////////////////////////////// // handle next surface interaction @@ -202,9 +204,6 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, } } - if (depth >= self->maxDepth) - break; - // sample BSDF vec2f s = RandomTEA__getFloats(rng); vec2f ss = RandomTEA__getFloats(rng); // FIXME: should be only one component From 5327af46bbe4d9f29c41f518d1c1eb194d064f4c Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 3 May 2016 13:09:16 -0500 Subject: [PATCH 273/310] warning fix --- ospray/volume/SharedStructuredVolume.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/volume/SharedStructuredVolume.h b/ospray/volume/SharedStructuredVolume.h index 7b6afa3cd3..e28ec635b0 100644 --- a/ospray/volume/SharedStructuredVolume.h +++ b/ospray/volume/SharedStructuredVolume.h @@ -51,7 +51,7 @@ namespace ospray { void createEquivalentISPC() override; //! Called when a dependency of this object changes. - void dependencyGotChanged(ManagedObject *object); + void dependencyGotChanged(ManagedObject *object) override; //! The voxelData object upon commit(). Data *voxelData; From d707c856e2ea99e33bf002300e712ff1d39a320d Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 3 May 2016 13:14:27 -0500 Subject: [PATCH 274/310] initial implementation of checking parallel_for() TASK_T with type traits --- ospray/CMakeLists.txt | 1 + ospray/common/tasking/TaskingTypeTraits.h | 56 +++++++++++++++++++++++ ospray/common/tasking/parallel_for.h | 7 +++ 3 files changed, 64 insertions(+) create mode 100644 ospray/common/tasking/TaskingTypeTraits.h diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 160e371cbc..b0c6ebb149 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -128,6 +128,7 @@ SET(OSPRAY_SOURCES common/tasking/parallel_for.h common/tasking/async.h + common/tasking/TaskingTypeTraits.h common/tasking/TaskSys.cpp fb/FrameBuffer.ispc diff --git a/ospray/common/tasking/TaskingTypeTraits.h b/ospray/common/tasking/TaskingTypeTraits.h new file mode 100644 index 0000000000..41ef131c42 --- /dev/null +++ b/ospray/common/tasking/TaskingTypeTraits.h @@ -0,0 +1,56 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include +#include + +namespace ospray { + + +//NOTE(jda) - This checks if T implements void T::operator(P taskIndex), where +// P is an integral type (must be short, int, uint, or size_t) +template +struct has_operator_method_integral_param +{ + template class checker; + + using T_SHORT_PARAM = void(T::*)(short) const; + using T_INT_PARAM = void(T::*)(int) const; + using T_UNSIGNED_PARAM = void(T::*)(unsigned int) const; + using T_SIZET_PARAM = void(T::*)(size_t) const; + + using IS_SHORT = std::is_same; + using IS_INT = std::is_same; + using IS_UNSIGNED = std::is_same; + using IS_SIZET = std::is_same; + + template + static std::true_type test(checker *); + + template + static std::false_type test(...); + + using type = decltype(test(nullptr)); + static constexpr bool value = std::is_same::value && + (IS_SHORT::value + || IS_INT::value + || IS_UNSIGNED::value + || IS_SIZET::value); +}; + +}//namespace ospray diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index 67da411083..248692c157 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -16,6 +16,8 @@ #pragma once +#include + #ifdef OSPRAY_TASKING_TBB # include #elif defined(OSPRAY_TASKING_CILK) @@ -31,6 +33,11 @@ namespace ospray { template inline void parallel_for(int nTasks, const TASK_T& fcn) { + static_assert(has_operator_method_integral_param::value, + "ospray::parallel_for() requires the implementation of method " + "'void TASK_T::operator(P taskIndex), where P is of type " + "short, int, uint, or size_t."); + #ifdef OSPRAY_TASKING_TBB tbb::parallel_for(0, nTasks, 1, fcn); #elif defined(OSPRAY_TASKING_CILK) From 87286967c79709c694f07e7f43598865a3d3f132 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 3 May 2016 13:25:24 -0500 Subject: [PATCH 275/310] add checking async() TASK_T with type traits --- ospray/common/tasking/TaskingTypeTraits.h | 51 ++++++++++++++--------- ospray/common/tasking/async.h | 6 +++ ospray/common/tasking/parallel_for.h | 2 +- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/ospray/common/tasking/TaskingTypeTraits.h b/ospray/common/tasking/TaskingTypeTraits.h index 41ef131c42..fcb0ad24c0 100644 --- a/ospray/common/tasking/TaskingTypeTraits.h +++ b/ospray/common/tasking/TaskingTypeTraits.h @@ -21,24 +21,13 @@ namespace ospray { - -//NOTE(jda) - This checks if T implements void T::operator(P taskIndex), where -// P is an integral type (must be short, int, uint, or size_t) +//NOTE(jda) - This checks at compile time if T implements the method +// 'void T::operator()'. template -struct has_operator_method_integral_param +struct has_operator_method { template class checker; - using T_SHORT_PARAM = void(T::*)(short) const; - using T_INT_PARAM = void(T::*)(int) const; - using T_UNSIGNED_PARAM = void(T::*)(unsigned int) const; - using T_SIZET_PARAM = void(T::*)(size_t) const; - - using IS_SHORT = std::is_same; - using IS_INT = std::is_same; - using IS_UNSIGNED = std::is_same; - using IS_SIZET = std::is_same; - template static std::true_type test(checker *); @@ -46,11 +35,35 @@ struct has_operator_method_integral_param static std::false_type test(...); using type = decltype(test(nullptr)); - static constexpr bool value = std::is_same::value && - (IS_SHORT::value - || IS_INT::value - || IS_UNSIGNED::value - || IS_SIZET::value); + static constexpr bool value = std::is_same::value; +}; + +//NOTE(jda) - This checks at compile time if T implements the method +// 'void T::operator(P taskIndex)', where P is an integral type +// (must be short, int, uint, or size_t) at compile-time. To be used +// inside a static_assert(). +template +struct has_operator_method_with_integral_param +{ + using T_SHORT_PARAM = void(T::*)(short) const; + using T_INT_PARAM = void(T::*)(int) const; + using T_UNSIGNED_PARAM = void(T::*)(unsigned int) const; + using T_SIZET_PARAM = void(T::*)(size_t) const; + + using PARAM_IS_SHORT = std::is_same; + using PARAM_IS_INT = std::is_same; + using PARAM_IS_UNSIGNED = std::is_same; + using PARAM_IS_SIZET = std::is_same; + + static constexpr bool value = has_operator_method::value && + (PARAM_IS_SHORT::value + || PARAM_IS_INT::value + || PARAM_IS_UNSIGNED::value + || PARAM_IS_SIZET::value); }; }//namespace ospray diff --git a/ospray/common/tasking/async.h b/ospray/common/tasking/async.h index cfbb34390b..b208602dc2 100644 --- a/ospray/common/tasking/async.h +++ b/ospray/common/tasking/async.h @@ -16,6 +16,8 @@ #pragma once +#include + #ifdef OSPRAY_TASKING_TBB # include #elif defined(OSPRAY_TASKING_CILK) @@ -36,6 +38,10 @@ namespace ospray { template inline void async(const TASK_T& fcn) { + static_assert(has_operator_method::value, + "ospray::async() requires the implementation of method " + "'void TASK_T::operator()'."); + #ifdef OSPRAY_TASKING_TBB struct LocalTBBTask : public tbb::task { diff --git a/ospray/common/tasking/parallel_for.h b/ospray/common/tasking/parallel_for.h index 248692c157..41e5caf8fb 100644 --- a/ospray/common/tasking/parallel_for.h +++ b/ospray/common/tasking/parallel_for.h @@ -33,7 +33,7 @@ namespace ospray { template inline void parallel_for(int nTasks, const TASK_T& fcn) { - static_assert(has_operator_method_integral_param::value, + static_assert(has_operator_method_with_integral_param::value, "ospray::parallel_for() requires the implementation of method " "'void TASK_T::operator(P taskIndex), where P is of type " "short, int, uint, or size_t."); From 98219c099e4674f78a879403df6a5ae9dd0b7c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 4 May 2016 13:03:13 +0200 Subject: [PATCH 276/310] Cleanup and fixes for C99 part of ospray.h OSPRay defines a C99 API with some additional C++ signatures where appropriate for convenience. Aliasing pointers in C99 and references in C++11 mode works with all compilers supported by OSPRay. --- apps/volumeViewer/ProbeWidget.cpp | 4 +- apps/volumeViewer/ProbeWidget.h | 2 +- ospray/api/API.cpp | 46 ++-- ospray/include/ospray/ospray.h | 419 ++++++++++++++---------------- 4 files changed, 214 insertions(+), 257 deletions(-) diff --git a/apps/volumeViewer/ProbeWidget.cpp b/apps/volumeViewer/ProbeWidget.cpp index 8aa0daef7e..341c97f771 100644 --- a/apps/volumeViewer/ProbeWidget.cpp +++ b/apps/volumeViewer/ProbeWidget.cpp @@ -132,12 +132,12 @@ void ProbeWidget::updateProbe() return; } - coordinate = ospcommon::vec3f(probeCoordinateWidgets[0]->getValue(), probeCoordinateWidgets[1]->getValue(), probeCoordinateWidgets[2]->getValue()); + coordinate = osp::vec3f{probeCoordinateWidgets[0]->getValue(), probeCoordinateWidgets[1]->getValue(), probeCoordinateWidgets[2]->getValue()}; if (volume) { float *results = NULL; - ospSampleVolume(results, volume, (osp::vec3f*)&coordinate, 1); + ospSampleVolume(&results, volume, coordinate, 1); if (!results) std::cout << "error calling ospSampleVolume()" << std::endl; diff --git a/apps/volumeViewer/ProbeWidget.h b/apps/volumeViewer/ProbeWidget.h index 3d7d6745d3..f5e550abb3 100644 --- a/apps/volumeViewer/ProbeWidget.h +++ b/apps/volumeViewer/ProbeWidget.h @@ -89,7 +89,7 @@ public slots: bool isEnabled; //! The probe coordinate. - ospcommon::vec3f coordinate; + osp::vec3f coordinate; // UI elements. std::vector probeCoordinateWidgets; diff --git a/ospray/api/API.cpp b/ospray/api/API.cpp index 26edb3f0e7..1541d053d2 100644 --- a/ospray/api/API.cpp +++ b/ospray/api/API.cpp @@ -189,12 +189,12 @@ extern "C" void ospFreeFrameBuffer(OSPFrameBuffer fb) ospray::api::Device::current->release(fb); } -extern "C" OSPFrameBuffer ospNewFrameBuffer(const int *size, +extern "C" OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, const OSPFrameBufferFormat mode, const uint32_t channels) { ASSERT_DEVICE(); - return ospray::api::Device::current->frameBufferCreate(*(const vec2i*)size,mode,channels); + return ospray::api::Device::current->frameBufferCreate((vec2i&)size, mode, channels); } //! load module \ from shard lib libospray_module_\.so, or @@ -390,17 +390,17 @@ extern "C" OSPCamera ospNewCamera(const char *type) return camera; } -extern "C" OSPTexture2D ospNewTexture2D(const int32_t *size, +extern "C" OSPTexture2D ospNewTexture2D(const osp::vec2i &size, const OSPTextureFormat type, void *data, const uint32_t flags) { ASSERT_DEVICE(); assert(size != NULL); - Assert2(size[0] > 0, "Width must be greater than 0 in ospNewTexture2D"); - Assert2(size[1] > 0, "Height must be greater than 0 in ospNewTexture2D"); - LOG("ospNewTexture2D( (" << size[0] << ", " << size[1] << "), " << type << ", " << data << ", " << flags << ")"); - return ospray::api::Device::current->newTexture2D(*(const vec2i*)size, type, data, flags); + Assert2(size.x > 0, "Width must be greater than 0 in ospNewTexture2D"); + Assert2(size.y > 0, "Height must be greater than 0 in ospNewTexture2D"); + LOG("ospNewTexture2D( (" << size.x << ", " << size.y << "), " << type << ", " << data << ", " << flags << ")"); + return ospray::api::Device::current->newTexture2D((vec2i&)size, type, data, flags); } /*! \brief create a new volume of given type, return 'NULL' if that type is not known */ @@ -513,12 +513,12 @@ extern "C" void ospSeti(OSPObject _object, const char *id, int x) /*! Copy data into the given volume. */ extern "C" int ospSetRegion(OSPVolume object, void *source, - const int *index, const int *count) + const osp::vec3i &index, const osp::vec3i &count) { ASSERT_DEVICE(); return(ospray::api::Device::current->setRegion(object, source, - *(const vec3i*)index, - *(const vec3i*)count)); + (vec3i&)index, + (vec3i&)count)); } /*! add a vec2f parameter to an object */ @@ -733,10 +733,9 @@ extern "C" int ospGetVec3i(OSPObject object, const char *name, osp::vec3i *value model. the resulting geometry still has to be added to another model via ospAddGeometry */ extern "C" OSPGeometry ospNewInstance(OSPModel modelToInstantiate, - const float *_xfm) //const osp::affine3f &xfm) + const osp::affine3f &xfm) { ASSERT_DEVICE(); - const osp::affine3f xfm = *(const osp::affine3f *)_xfm; // return ospray::api::Device::current->newInstance(modelToInstantiate,xfm); OSPGeometry geom = ospNewGeometry("instance"); ospSet3fv(geom,"xfm.l.vx",&xfm.l.vx.x); @@ -749,12 +748,12 @@ extern "C" OSPGeometry ospNewInstance(OSPModel modelToInstantiate, extern "C" void ospPick(OSPPickResult *result, OSPRenderer renderer, - const float *screenPos) + const osp::vec2f &screenPos) { ASSERT_DEVICE(); Assert2(renderer, "NULL renderer passed to ospPick"); if (!result) return; - *result = ospray::api::Device::current->pick(renderer, *(const vec2f *)screenPos); + *result = ospray::api::Device::current->pick(renderer, (const vec2f&)screenPos); } //! \brief allows for switching the MPI scope from "per rank" to "all ranks" @@ -783,24 +782,9 @@ extern "C" void ospdMpiShutdown() } #endif -// extern "C" OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos) -// { -// static bool warned = false; -// if (!warned) { -// std::cout << "'ospUnproject()' has been deprecated. Please use the new function 'ospPick()' instead" << std::endl; -// warned = true; -// } -// ASSERT_DEVICE(); -// Assert2(renderer, "NULL renderer passed to ospUnproject"); -// vec2f flippedScreenPos = vec2f(screenPos.x, 1.0f - screenPos.y); -// OSPPickResult pick = ospray::api::Device::current->pick(renderer, flippedScreenPos); -// OSPPickData res = { pick.hit, pick.position.x, pick.position.y, pick.position.z }; -// return res; -// } - extern "C" void ospSampleVolume(float **results, OSPVolume volume, - const float *worldCoordinates, + const osp::vec3f &worldCoordinates, const size_t count) { ASSERT_DEVICE(); @@ -813,6 +797,6 @@ extern "C" void ospSampleVolume(float **results, Assert2(worldCoordinates, "NULL worldCoordinates passed to ospSampleVolume"); - ospray::api::Device::current->sampleVolume(results, volume, (const vec3f *)worldCoordinates, count); + ospray::api::Device::current->sampleVolume(results, volume, (vec3f*)&worldCoordinates, count); } diff --git a/ospray/include/ospray/ospray.h b/ospray/include/ospray/ospray.h index 6a634bca07..31673bd20b 100644 --- a/ospray/include/ospray/ospray.h +++ b/ospray/include/ospray/ospray.h @@ -20,7 +20,7 @@ \ingroup ospray - \brief Defines the public API for the OSPRay core + \brief Defines the public API for the OSPRay core \{ */ @@ -36,7 +36,7 @@ #endif // ------------------------------------------------------- -// include common components +// include common components // ------------------------------------------------------- #include #include @@ -46,12 +46,12 @@ #ifdef _WIN32 # ifdef ospray_EXPORTS -# define OSPRAY_INTERFACE __declspec(dllexport) +# define OSPRAY_INTERFACE __declspec(dllexport) # else -# define OSPRAY_INTERFACE __declspec(dllimport) +# define OSPRAY_INTERFACE __declspec(dllimport) # endif #else -# define OSPRAY_INTERFACE +# define OSPRAY_INTERFACE #endif #ifdef __GNUC__ @@ -131,11 +131,6 @@ typedef enum { } OSPDataCreationFlags; typedef enum { - OSP_OK=0, /*! no error; any value other than zero means 'some kind of error' */ - OSP_GENERAL_ERROR /*! unspecified error */ -} OSPResult; - -typedef enum { OSPD_Z_COMPOSITE } OSPDRenderMode; @@ -207,36 +202,45 @@ typedef osp::Texture2D *OSPTexture2D; typedef osp::ManagedObject *OSPObject; typedef osp::PixelOp *OSPPixelOp; -/* c++ DOES support default initializers */ +/* C++ DOES support default initializers */ #define OSP_DEFAULT_VAL(a) a #else -/*! std-C99 versions. This version doesn't need the vector classes - because c99 doesn't have references, anyway */ - -/*! abstract object types. in c99, those are all the same because c99 +typedef struct { float x, y; } osp_vec2f; +typedef struct { int x, y; } osp_vec2i; +typedef struct { float x, y, z; } osp_vec3f; +typedef struct { float x, y, z; + union { int a; unsigned u; float w; }; } osp_vec3fa; +typedef struct { int x, y, z; } osp_vec3i; +typedef struct { float x, y, z, w; } osp_vec4f; +typedef struct { osp_vec2i lower, upper; } osp_box2i; +typedef struct { osp_vec3f lower, upper; } osp_box3f; +typedef struct { osp_vec3f vx, vy, vz; } osp_linear3f; +typedef struct { osp_linear3f l; osp_vec3f p; } osp_affine3f; + +/*! abstract object types. in C99, those are all the same because C99 doesn't know inheritance, and we want to make sure that a OSPGeometry can still be passed to a function that expects a OSPObject, etc */ -typedef struct _OSPManagedObject *OSPManagedObject, - *OSPRenderer, - *OSPCamera, +typedef struct _OSPManagedObject *OSPManagedObject, + *OSPRenderer, + *OSPCamera, *OSPFrameBuffer, - *OSPModel, - *OSPData, - *OSPGeometry, - *OSPMaterial, - *OSPLight, - *OSPVolume, - *OSPTransferFunction, - *OSPTexture2D, - *OSPObject, + *OSPModel, + *OSPData, + *OSPGeometry, + *OSPMaterial, + *OSPLight, + *OSPVolume, + *OSPTransferFunction, + *OSPTexture2D, + *OSPObject, *OSPPixelOp; -/* c99 does NOT support default initializers, so we use this macro +/* C99 does NOT support default initializers, so we use this macro to define them away */ -#define OSP_DEFAULT_VAL(a) /* no default arguments on c99 */ +#define OSP_DEFAULT_VAL(a) /* no default arguments on C99 */ #endif @@ -244,57 +248,55 @@ typedef struct _OSPManagedObject *OSPManagedObject, extern "C" { #endif - //! initialize the ospray engine (for single-node user application) + //! initialize the ospray engine (for single-node user application) OSPRAY_INTERFACE void ospInit(int *ac, const char **av); - + //! \brief allows for switching the MPI mode btween collaborative, mastered, and independent - OSPRAY_INTERFACE - void ospdApiMode(OSPDApiMode mode); + OSPRAY_INTERFACE void ospdApiMode(OSPDApiMode); //! the 'lid to the pot' of ospdMpiInit(). /*! does both an osp shutdown and an mpi shutdown for the mpi group created with ospdMpiInit */ OSPRAY_INTERFACE - void ospdMpiInit(int *ac, char ***av, OSPDRenderMode renderMode=OSPD_Z_COMPOSITE); + void ospdMpiInit(int *ac, char ***av, OSPDRenderMode mode OSP_DEFAULT_VAL(=OSPD_Z_COMPOSITE)); /*! the 'lid to the pot' of ospdMpiInit(). shuts down both ospray *and* the MPI layer created with ospdMpiInit */ - OSPRAY_INTERFACE - void ospdMpiShutdown(); + OSPRAY_INTERFACE void ospdMpiShutdown(); //! load plugin 'name' from shard lib libospray_module_.so /*! returns 0 if the module could be loaded, else it returns an error code > 0 */ OSPRAY_INTERFACE int32_t ospLoadModule(const char *pluginName); - //! use renderer to render a frame. + //! use renderer to render a frame. /*! What input to use for rendering the frame is encoded in the renderer's parameters, typically in "world". return estimate of variance if framebuffer has VARIANCE buffer */ - OSPRAY_INTERFACE float ospRenderFrame(OSPFrameBuffer fb, - OSPRenderer renderer, - const uint32_t whichChannels OSP_DEFAULT_VAL(=OSP_FB_COLOR)); + OSPRAY_INTERFACE float ospRenderFrame(OSPFrameBuffer, + OSPRenderer, + const uint32_t frameBufferChannels OSP_DEFAULT_VAL(=OSP_FB_COLOR)); - //! create a new renderer of given type + //! create a new renderer of given type /*! return 'NULL' if that type is not known */ OSPRAY_INTERFACE OSPRenderer ospNewRenderer(const char *type); - - //! create a new pixel op of given type + + //! create a new pixel op of given type /*! return 'NULL' if that type is not known */ OSPRAY_INTERFACE OSPPixelOp ospNewPixelOp(const char *type); - + //! set a frame buffer's pixel op */ - OSPRAY_INTERFACE void ospSetPixelOp(OSPFrameBuffer fb, OSPPixelOp op); + OSPRAY_INTERFACE void ospSetPixelOp(OSPFrameBuffer, OSPPixelOp); - //! create a new geometry of given type + //! create a new geometry of given type /*! return 'NULL' if that type is not known */ OSPRAY_INTERFACE OSPGeometry ospNewGeometry(const char *type); //! let given renderer create a new material of given type - OSPRAY_INTERFACE OSPMaterial ospNewMaterial(OSPRenderer renderer, const char *type); + OSPRAY_INTERFACE OSPMaterial ospNewMaterial(OSPRenderer, const char *type); //! let given renderer create a new light of given type - OSPRAY_INTERFACE OSPLight ospNewLight(OSPRenderer renderer, const char *type); - + OSPRAY_INTERFACE OSPLight ospNewLight(OSPRenderer, const char *type); + //! release (i.e., reduce refcount of) given object /*! note that all objects in ospray are refcounted, so one cannot explicitly "delete" any object. instead, each object is created @@ -305,22 +307,22 @@ extern "C" { create a new material, assign it to a geometry, and immediately after this assignation release its refcount; the material will stay 'alive' as long as the given geometry requires it. */ - OSPRAY_INTERFACE void ospRelease(OSPObject obj); - + OSPRAY_INTERFACE void ospRelease(OSPObject); + //! assign given material to given geometry - OSPRAY_INTERFACE void ospSetMaterial(OSPGeometry geometry, OSPMaterial material); + OSPRAY_INTERFACE void ospSetMaterial(OSPGeometry, OSPMaterial); - //! \brief create a new camera of given type + //! \brief create a new camera of given type /*! \detailed The default camera type supported in all ospray versions is "perspective" (\ref perspective_camera). For a list of supported camera type in this version of ospray, see \ref ospray_supported_cameras - + \returns 'NULL' if that type is not known, else a handle to the created camera */ OSPRAY_INTERFACE OSPCamera ospNewCamera(const char *type); - //! \brief create a new volume of given type + //! \brief create a new volume of given type /*! \detailed return 'NULL' if that type is not known */ OSPRAY_INTERFACE OSPVolume ospNewVolume(const char *type); @@ -333,13 +335,20 @@ extern "C" { //! \brief create a new transfer function of given type /*! \detailed return 'NULL' if that type is not known */ OSPRAY_INTERFACE OSPTransferFunction ospNewTransferFunction(const char * type); - + //! \brief create a new Texture2D with the given parameters /*! \detailed return 'NULL' if the texture could not be created with the given parameters */ - OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(const int32_t *size, - const OSPTextureFormat format, - void *data, - const uint32_t flags); +#ifdef __cplusplus + OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(const osp::vec2i &size, + const OSPTextureFormat, + void *source = NULL, + const uint32_t textureCreationFlags = 0); +#else + OSPRAY_INTERFACE OSPTexture2D ospNewTexture2D(const osp_vec2i *size, + const OSPTextureFormat, + void *source, + const uint32_t textureCreationFlags); +#endif //! \brief clears the specified channel(s) of the frame buffer /*! \detailed clear the specified channel(s) of the frame buffer specified in 'whichChannels' @@ -347,39 +356,39 @@ extern "C" { if whichChannels & OSP_FB_DEPTH != 0, clear the depth buffer to +inf if whichChannels & OSP_FB_ACCUM != 0, clear the accum buffer to 0,0,0,0, and reset accumID */ - OSPRAY_INTERFACE void ospFrameBufferClear(OSPFrameBuffer, const uint32_t whichChannels); + OSPRAY_INTERFACE void ospFrameBufferClear(OSPFrameBuffer, const uint32_t frameBufferChannels); // ------------------------------------------------------- - /*! \defgroup ospray_data Data Buffer Handling + /*! \defgroup ospray_data Data Buffer Handling \ingroup ospray_api - \{ + \{ */ - /*! create a new data buffer, with optional init data and control flags + /*! create a new data buffer, with optional init data and control flags Valid flags that can be OR'ed together into the flags value: - OSP_DATA_SHARED_BUFFER: indicates that the buffer can be shared with the app. In this case the calling program guarantees that the 'init' pointer will remain valid for the duration that this data array is being used. */ - OSPRAY_INTERFACE OSPData ospNewData(size_t numItems, - OSPDataType format, - const void *init OSP_DEFAULT_VAL(=NULL), + OSPRAY_INTERFACE OSPData ospNewData(size_t numItems, + OSPDataType, + const void *source OSP_DEFAULT_VAL(=NULL), const uint32_t dataCreationFlags OSP_DEFAULT_VAL(=0)); /*! \} */ // ------------------------------------------------------- - /*! \defgroup ospray_framebuffer Frame Buffer Manipulation + /*! \defgroup ospray_framebuffer Frame Buffer Manipulation + + \ingroup ospray_api - \ingroup ospray_api - - \{ + \{ */ - /*! \brief create a new framebuffer (actual format is internal to ospray) + /*! \brief create a new framebuffer (actual format is internal to ospray) Creates a new frame buffer of given size, externalFormat, and channel type(s). @@ -397,7 +406,7 @@ extern "C" { OSP_FB_DEPTH, and/or OSP_FB_ACCUM. If a certain buffer value is _not_ specified, the given buffer will not be present (see notes below). - + \param size size (in pixels) of frame buffer. Note that ospray makes a very clear distinction between the @@ -420,9 +429,15 @@ extern "C" { format of OSP_FB_NONE the pixels from the path tracing stage will never ever be transferred to the application. */ - OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const int32_t *size /*!< 2 ints: width x height */, - const OSPFrameBufferFormat format, - const uint32_t whichChannels); +#ifdef __cplusplus + OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, + const OSPFrameBufferFormat format = OSP_FB_SRGBA, + const uint32_t frameBufferChannels = OSP_FB_COLOR); +#else + OSPRAY_INTERFACE OSPFrameBuffer ospNewFrameBuffer(const osp_vec2i *size, + const OSPFrameBufferFormat, + const uint32_t frameBufferChannels); +#endif // \brief Set a given region of the volume to a given set of voxels /*! \detailed Given a block of voxels (of dimensions 'blockDim', @@ -430,34 +445,41 @@ extern "C" { given voxels into volume, at the region of addresses [regionCoords...regionCoord+regionSize]. */ +#ifdef __cplusplus OSPRAY_INTERFACE int ospSetRegion(/*! the object we're writing this block of pixels into */ - OSPVolume object, + OSPVolume, /* points to the first voxel to be copies. The voxels at 'source' MUST have dimensions 'regionSize', must be organized in 3D-array order, and must have the same voxel type as the volume.*/ - void *source, + void *source, /*! coordinates of the lower, left, front corner of the target region.*/ - const int32_t *regionCoords, + const osp::vec3i ®ionCoords, /*! size of the region that we're writing to; MUST be the same as the dimensions of source[][][] */ - const int32_t *regionSize); + const osp::vec3i ®ionSize); +#else + OSPRAY_INTERFACE int ospSetRegion(OSPVolume, + void *source, + const osp_vec3i *regionCoords, + const osp_vec3i *regionSize); +#endif + - - /*! \brief free a framebuffer + /*! \brief free a framebuffer - due to refcounting the frame buffer may not immeidately be deleted + due to refcounting the frame buffer may not immediately be deleted at this time */ - OSPRAY_INTERFACE void ospFreeFrameBuffer(OSPFrameBuffer fb); + OSPRAY_INTERFACE void ospFreeFrameBuffer(OSPFrameBuffer); /*! \brief map app-side content of a framebuffer (see \ref frame_buffer_handling) */ - OSPRAY_INTERFACE const void *ospMapFrameBuffer(OSPFrameBuffer fb, + OSPRAY_INTERFACE const void *ospMapFrameBuffer(OSPFrameBuffer, const OSPFrameBufferChannel OSP_DEFAULT_VAL(=OSP_FB_COLOR)); /*! \brief unmap a previously mapped frame buffer (see \ref frame_buffer_handling) */ - OSPRAY_INTERFACE void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer fb); + OSPRAY_INTERFACE void ospUnmapFrameBuffer(const void *mapped, OSPFrameBuffer); /*! \} */ @@ -467,66 +489,66 @@ extern "C" { \ingroup ospray_api - @{ + @{ */ /*! add a c-string (zero-terminated char *) parameter to another object */ - OSPRAY_INTERFACE void ospSetString(OSPObject _object, const char *id, const char *s); + OSPRAY_INTERFACE void ospSetString(OSPObject, const char *id, const char *s); + + /*! add a object-typed parameter to another object - /*! add a object-typed parameter to another object - \warning this call has been superseded by ospSetObject, and will eventually get removed */ - OSP_DEPRECATED OSPRAY_INTERFACE void ospSetParam(OSPObject _object, const char *id, OSPObject object); + OSP_DEPRECATED OSPRAY_INTERFACE void ospSetParam(OSPObject, const char *id, OSPObject other); /*! add a object-typed parameter to another object */ - OSPRAY_INTERFACE void ospSetObject(OSPObject _object, const char *id, OSPObject object); + OSPRAY_INTERFACE void ospSetObject(OSPObject, const char *id, OSPObject other); /*! add a data array to another object */ - OSPRAY_INTERFACE void ospSetData(OSPObject _object, const char *id, OSPData data); + OSPRAY_INTERFACE void ospSetData(OSPObject, const char *id, OSPData); /*! add 1-float parameter to given object */ - OSPRAY_INTERFACE void ospSetf(OSPObject _object, const char *id, float x); + OSPRAY_INTERFACE void ospSetf(OSPObject, const char *id, float x); /*! add 1-float parameter to given object */ - OSPRAY_INTERFACE void ospSet1f(OSPObject _object, const char *id, float x); + OSPRAY_INTERFACE void ospSet1f(OSPObject, const char *id, float x); /*! add 1-int parameter to given object */ - OSPRAY_INTERFACE void ospSet1i(OSPObject _object, const char *id, int32_t x); + OSPRAY_INTERFACE void ospSet1i(OSPObject, const char *id, int32_t x); /*! add a 2-float parameter to a given object */ - OSPRAY_INTERFACE void ospSet2f(OSPObject _object, const char *id, float x, float y); + OSPRAY_INTERFACE void ospSet2f(OSPObject, const char *id, float x, float y); /*! add 2-float parameter to given object */ - OSPRAY_INTERFACE void ospSet2fv(OSPObject _object, const char *id, const float *xy); + OSPRAY_INTERFACE void ospSet2fv(OSPObject, const char *id, const float *xy); /*! add a 2-int parameter to a given object */ - OSPRAY_INTERFACE void ospSet2i(OSPObject _object, const char *id, int x, int y); + OSPRAY_INTERFACE void ospSet2i(OSPObject, const char *id, int x, int y); /*! add 2-int parameter to given object */ - OSPRAY_INTERFACE void ospSet2iv(OSPObject _object, const char *id, const int *xy); + OSPRAY_INTERFACE void ospSet2iv(OSPObject, const char *id, const int *xy); /*! add 3-float parameter to given object */ - OSPRAY_INTERFACE void ospSet3f(OSPObject _object, const char *id, float x, float y, float z); + OSPRAY_INTERFACE void ospSet3f(OSPObject, const char *id, float x, float y, float z); /*! add 3-float parameter to given object */ - OSPRAY_INTERFACE void ospSet3fv(OSPObject _object, const char *id, const float *xyz); - - /*! add 4-float parameter to given object */ - OSPRAY_INTERFACE void ospSet4f(OSPObject _object, const char *id, float x, float y, float z, float w); - - /*! add 4-float parameter to given object */ - OSPRAY_INTERFACE void ospSet4fv(OSPObject _object, const char *id, const float *xyzw); + OSPRAY_INTERFACE void ospSet3fv(OSPObject, const char *id, const float *xyz); /*! add 3-int parameter to given object */ - OSPRAY_INTERFACE void ospSet3i(OSPObject _object, const char *id, int x, int y, int z); + OSPRAY_INTERFACE void ospSet3i(OSPObject, const char *id, int x, int y, int z); /*! add 3-int parameter to given object */ - OSPRAY_INTERFACE void ospSet3iv(OSPObject _object, const char *id, const int *xyz); + OSPRAY_INTERFACE void ospSet3iv(OSPObject, const char *id, const int *xyz); + + /*! add 4-float parameter to given object */ + OSPRAY_INTERFACE void ospSet4f(OSPObject, const char *id, float x, float y, float z, float w); + + /*! add 4-float parameter to given object */ + OSPRAY_INTERFACE void ospSet4fv(OSPObject, const char *id, const float *xyzw); /*! add untyped void pointer to object - this will *ONLY* work in local rendering! */ - OSPRAY_INTERFACE void ospSetVoidPtr(OSPObject _object, const char *id, void *v); + OSPRAY_INTERFACE void ospSetVoidPtr(OSPObject, const char *id, void *v); #ifdef __cplusplus - /*! \brief Object and parameter introspection. */ + /*! \brief Object and parameter introspection. These are all DEPRECATED. */ /*! */ /*! These functions are used to retrieve the type or handle of an object, */ /*! or the name, type, or value of a parameter associated with an object. */ @@ -543,9 +565,9 @@ extern "C" { /*! \brief Get a copy of the data in an array (the application is responsible for freeing this pointer). */ /*! \warning this call has been deprecated and will eventually be removed */ - OSP_DEPRECATED OSPRAY_INTERFACE int ospGetDataValues(OSPData object, - void **pointer, - size_t *count, + OSP_DEPRECATED OSPRAY_INTERFACE int ospGetDataValues(OSPData object, + void **pointer, + size_t *count, OSPDataType *type); /*! \brief Get the named scalar floating point value associated with an object. */ @@ -587,33 +609,54 @@ extern "C" { /*! \brief Get the named 3-vector integer value associated with an object. */ /*! \warning this call has been deprecated and will eventually be removed */ OSP_DEPRECATED OSPRAY_INTERFACE int ospGetVec3i(OSPObject object, const char *name, osp::vec3i *value); + + // probably want to deprecate those as well: + + /*! add 2-float parameter to given object */ + OSPRAY_INTERFACE void ospSetVec2f(OSPObject, const char *id, const osp::vec2f &v); + + /*! add 2-int parameter to given object */ + OSPRAY_INTERFACE void ospSetVec2i(OSPObject, const char *id, const osp::vec2i &v); + + /*! add 3-float parameter to given object */ + OSPRAY_INTERFACE void ospSetVec3f(OSPObject, const char *id, const osp::vec3f &v); + + /*! add 3-int parameter to given object */ + OSPRAY_INTERFACE void ospSetVec3i(OSPObject, const char *id, const osp::vec3i &v); + + /*! add 4-float parameter to given object */ + OSPRAY_INTERFACE void ospSetVec4f(OSPObject, const char *id, const osp::vec4f &v); #endif /*! @} end of ospray_params */ // ------------------------------------------------------- - /*! \defgroup ospray_geometry Geometry Handling + /*! \defgroup ospray_geometry Geometry Handling \ingroup ospray_api - - \{ + + \{ */ /*! add an already created geometry to a model */ - OSPRAY_INTERFACE void ospAddGeometry(OSPModel model, OSPGeometry mesh); + OSPRAY_INTERFACE void ospAddGeometry(OSPModel, OSPGeometry); /*! \} end of ospray_trianglemesh */ /*! \brief remove an existing geometry from a model */ - OSPRAY_INTERFACE void ospRemoveGeometry(OSPModel model, OSPGeometry mesh); - - + OSPRAY_INTERFACE void ospRemoveGeometry(OSPModel, OSPGeometry); + + /*! \brief create a new instance geometry that instantiates another model. the resulting geometry still has to be added to another model via ospAddGeometry */ +#ifdef __cplusplus OSPRAY_INTERFACE OSPGeometry ospNewInstance(OSPModel modelToInstantiate, - /*! affine3f transform matrix, to 4x3 floats */ - const float *affine3f_xfm); + const osp::affine3f &transform); +#else + OSPRAY_INTERFACE OSPGeometry ospNewInstance(OSPModel modelToInstantiate, + const osp_affine3f *transform); +#endif // ------------------------------------------------------- - /*! \defgroup ospray_model OSPRay Model Handling + /*! \defgroup ospray_model OSPRay Model Handling \ingroup ospray_api models are the equivalent of 'scenes' in embree (ie, @@ -622,44 +665,37 @@ extern "C" { contain more than just embree triangle meshes - they can also contain cameras, materials, volume data, etc, as well as references to (and instances of) other models. - - \{ + + \{ */ /*! \brief create a new ospray model. */ OSPRAY_INTERFACE OSPModel ospNewModel(); /*! \} */ - + /*! \brief commit changes to an object */ - OSPRAY_INTERFACE void ospCommit(OSPObject object); + OSPRAY_INTERFACE void ospCommit(OSPObject); + +#ifdef __cplusplus /*! \brief represents the result returned by an ospPick operation */ typedef struct { -#ifdef __cplusplus osp::vec3f position; //< the position of the hit point (in world-space) bool hit; //< whether or not a hit actually occured -#else - float position[3]; //< the position of the hit point (in world-space) - unsigned char hit; //< whether or not a hit actually occured -#endif } OSPPickResult; - + /*! \brief returns the world-space position of the geometry seen at [0-1] normalized screen-space pixel coordinates (if any) */ - OSPRAY_INTERFACE void ospPick(OSPPickResult *result, OSPRenderer renderer, const float *screenPos); - - // typedef struct { - // bool hit; - // float world_x, world_y, world_z; - // } OSPPickData; - - // /*! \warning this call has been superseded by ospPick, and will eventually get removed */ - // OSP_DEPRECATED OSPRAY_INTERFACE OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos); - // #ifdef __cplusplus - // /*! c++ version with references */ - // inline OSPPickData ospUnproject(OSPRenderer renderer, const osp::vec2f &screenPos) - // { OSPPickData res; ospUnproject(&res,renderer,&screenPos.x); } - // #endif + OSPRAY_INTERFACE void ospPick(OSPPickResult*, OSPRenderer, const osp::vec2f &screenPos); +#else + typedef struct { + osp_vec3f position; //< the position of the hit point (in world-space) + int hit; //< whether or not a hit actually occured + } OSPPickResult; + + OSPRAY_INTERFACE void ospPick(OSPPickResult*, OSPRenderer, const osp_vec2f *screenPos); +#endif + /*! \brief Samples the given volume at the provided world-space coordinates. @@ -672,83 +708,20 @@ extern "C" { as needed for data probes, etc. in applications. It is not intended for large-scale sampling of volumes. */ - OSPRAY_INTERFACE void ospSampleVolume(float **results, - OSPVolume volume, - const float *worldCoordinates, - const size_t count); #ifdef __cplusplus -} // extern "C" + OSPRAY_INTERFACE void ospSampleVolume(float **results, + OSPVolume, + const osp::vec3f &worldCoordinates, + const size_t count); +#else + OSPRAY_INTERFACE void ospSampleVolume(float **results, + OSPVolume, + const osp_vec3f *worldCoordinates, + const size_t count); #endif - #ifdef __cplusplus -extern "C++" { - /*! C++ version with references */ - inline void ospPick(OSPPickResult *result, OSPRenderer renderer, const osp::vec2f &screenPos) - { ospPick(result,renderer,&screenPos.x); } - - inline void ospSampleVolume(float *&results, - OSPVolume volume, - const osp::vec3f *worldCoordinates, - const size_t &count) - { ospSampleVolume(&results,volume,(const float *)worldCoordinates,count); } - - /*! C++ variant of this function that uses references rather than pointers */ - inline OSPTexture2D ospNewTexture2D(const osp::vec2i &size, - const OSPTextureFormat format, - void *data = NULL, - const uint32_t flags = 0) - { return ospNewTexture2D(&size.x,format,data,flags); } - - /*! C++ variant of ospNewFrameBuffer that can also be called with - references rather than with pointers */ - inline OSPFrameBuffer ospNewFrameBuffer(const osp::vec2i &size, - const OSPFrameBufferFormat format=OSP_FB_SRGBA, - const uint32_t whichChannels=OSP_FB_COLOR) - { return ospNewFrameBuffer(&size.x,format,whichChannels); } - - /*! C++ variant that uses refreences rather than pointerts */ - inline int ospSetRegion(/*! the object we're writing this block of pixels into */ - OSPVolume object, - /* points to the first voxel to be copies. The - voxels at 'source' MUST have dimensions - 'regionSize', must be organized in 3D-array - order, and must have the same voxel type as the - volume.*/ - void *source, - /*! coordinates of the lower, left, front corner of - the target region.*/ - const osp::vec3i ®ionCoords, - /*! size of the region that we're writing to; MUST - be the same as the dimensions of source[][][] */ - const osp::vec3i ®ionSize) - { return ospSetRegion(object,source,®ionCoords.x,®ionSize.x); } - - inline OSPGeometry ospNewInstance(OSPModel modelToInstantiate, - const osp::affine3f &xfm) - { return ospNewInstance(modelToInstantiate,(const float *)&xfm); } - -} // extern C++ - -extern "C" { - // probably want to deprecate those, or make c++ linkage. - - /*! add 2-float parameter to given object */ - OSPRAY_INTERFACE void ospSetVec2f(OSPObject _object, const char *id, const osp::vec2f &v); - - /*! add 2-int parameter to given object */ - OSPRAY_INTERFACE void ospSetVec2i(OSPObject _object, const char *id, const osp::vec2i &v); - - /*! add 3-float parameter to given object */ - OSPRAY_INTERFACE void ospSetVec3f(OSPObject _object, const char *id, const osp::vec3f &v); - - /*! add 4-float parameter to given object */ - OSPRAY_INTERFACE void ospSetVec4f(OSPObject _object, const char *id, const osp::vec4f &v); - - /*! add 3-int parameter to given object */ - OSPRAY_INTERFACE void ospSetVec3i(OSPObject _object, const char *id, const osp::vec3i &v); -} // extern C - -#endif // __cplusplus +} // extern "C" +#endif /*! \} */ From 00b222841b3c75909f99f9d9b57d394c419749c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 4 May 2016 13:07:26 +0200 Subject: [PATCH 277/310] Add C99 version of ospTutorial --- apps/ospTutorial.c | 145 ++++++++++++++++++++++++++++++++++++++++++ cmake/clang.cmake | 1 + cmake/gcc.cmake | 1 + cmake/icc.cmake | 1 + ospray/CMakeLists.txt | 5 +- 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 apps/ospTutorial.c diff --git a/apps/ospTutorial.c b/apps/ospTutorial.c new file mode 100644 index 0000000000..58efae2f7e --- /dev/null +++ b/apps/ospTutorial.c @@ -0,0 +1,145 @@ +// ======================================================================== // +// Copyright 2009-2016 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + + +/* This is a small example tutorial how to use OSPRay in an application. + * + * On Linux build it in the build_directory with + * gcc -std=c99 ../apps/ospTutorial.c -I ../ospray/include -I .. -I ../ospray/embree/common ./libospray.so -Wl,-rpath,. -o ospTutorialC + * On Windows build it in the build_directory\$Configuration with + * cl ..\..\apps\ospTutorial.c /EHsc -I ..\..\ospray\include -I ..\.. -I ..\..\ospray\embree\common ospray.lib + */ + +#include +#include +#ifdef _WIN32 +# include +#else +# include +#endif +#include "ospray/ospray.h" + +// helper function to write the rendered image as PPM file +void writePPM(const char *fileName, + const osp_vec2i *size, + const uint32_t *pixel) +{ + FILE *file = fopen(fileName, "wb"); + fprintf(file, "P6\n%i %i\n255\n", size->x, size->y); + unsigned char *out = (unsigned char *)alloca(3*size->x); + for (int y = 0; y < size->y; y++) { + const unsigned char *in = (const unsigned char *)&pixel[(size->y-1-y)*size->x]; + for (int x = 0; x < size->x; x++) { + out[3*x + 0] = in[4*x + 0]; + out[3*x + 1] = in[4*x + 1]; + out[3*x + 2] = in[4*x +2 ]; + } + fwrite(out, 3*size->x, sizeof(char), file); + } + fprintf(file, "\n"); + fclose(file); +} + + +int main(int ac, const char **av) { + // image size + osp_vec2i imgSize; + imgSize.x = 1024; // width + imgSize.y = 768; // height + + // camera + float cam_pos[] = {0.f, 0.f, 0.f}; + float cam_up [] = {0.f, 1.f, 0.f}; + float cam_view [] = {0.1f, 0.f, 1.f}; + + // triangle mesh data + float vertex[] = { -1.0f, -1.0f, 3.0f, 0.f, + -1.0f, 1.0f, 3.0f, 0.f, + 1.0f, -1.0f, 3.0f, 0.f, + 0.1f, 0.1f, 0.3f, 0.f }; + float color[] = { 0.9f, 0.5f, 0.5f, 1.0f, + 0.8f, 0.8f, 0.8f, 1.0f, + 0.8f, 0.8f, 0.8f, 1.0f, + 0.5f, 0.9f, 0.5f, 1.0f }; + int32_t index[] = { 0, 1, 2, + 1, 2, 3 }; + + + // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, e.g. "--osp:debug" + ospInit(&ac, av); + + // create and setup camera + OSPCamera camera = ospNewCamera("perspective"); + ospSetf(camera, "aspect", imgSize.x/(float)imgSize.y); + ospSet3fv(camera, "pos", cam_pos); + ospSet3fv(camera, "dir", cam_view); + ospSet3fv(camera, "up", cam_up); + ospCommit(camera); // commit each object to indicate modifications are done + + + // create and setup model and mesh + OSPGeometry mesh = ospNewGeometry("triangles"); + OSPData data = ospNewData(4, OSP_FLOAT3A, vertex, 0); // OSP_FLOAT3 format is also supported for vertex positions (currently not on MIC) + ospCommit(data); + ospSetData(mesh, "vertex", data); + + data = ospNewData(4, OSP_FLOAT4, color, 0); + ospCommit(data); + ospSetData(mesh, "vertex.color", data); + + data = ospNewData(2, OSP_INT3, index, 0); // OSP_INT4 format is also supported for triangle indices + ospCommit(data); + ospSetData(mesh, "index", data); + + ospCommit(mesh); + + + OSPModel world = ospNewModel(); + ospAddGeometry(world, mesh); + ospCommit(world); + + + // create and setup renderer + OSPRenderer renderer = ospNewRenderer("scivis"); // choose Scientific Visualization renderer + ospSet1f(renderer, "aoWeight", 1.0f); // with full Ambient Occlusion + ospSetObject(renderer, "model", world); + ospSetObject(renderer, "camera", camera); + ospCommit(renderer); + + + // create and setup framebuffer + OSPFrameBuffer framebuffer = ospNewFrameBuffer(&imgSize, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); + ospFrameBufferClear(framebuffer, OSP_FB_COLOR | OSP_FB_ACCUM); + + // render one frame + ospRenderFrame(framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM); + + // access framebuffer and write its content as PPM file + const uint32_t * fb = (uint32_t*)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); + writePPM("firstFrameC.ppm", &imgSize, fb); + ospUnmapFrameBuffer(fb, framebuffer); + + + // render 10 more frames, which are accumulated to result in a better converged image + for (int frames = 0; frames < 10; frames++) + ospRenderFrame(framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM); + + fb = (uint32_t*)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); + writePPM("accumulatedFrameC.ppm", &imgSize, fb); + ospUnmapFrameBuffer(fb, framebuffer); + + return 0; +} diff --git a/cmake/clang.cmake b/cmake/clang.cmake index fed2c4e297..40eb261e56 100644 --- a/cmake/clang.cmake +++ b/cmake/clang.cmake @@ -18,6 +18,7 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fno-strict-aliasing -Wno-narrowin SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -g -O0 -Wstrict-aliasing=1") SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -Wstrict-aliasing=1") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -g -O3 -Wstrict-aliasing=1") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") IF (APPLE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # we only use MacOSX 10.7 features diff --git a/cmake/gcc.cmake b/cmake/gcc.cmake index d5a9b8669b..3db539b7e7 100644 --- a/cmake/gcc.cmake +++ b/cmake/gcc.cmake @@ -18,6 +18,7 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fno-strict-aliasing -std=c++11 - SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -g -Wstrict-aliasing=1") SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -Wstrict-aliasing=1 -ffast-math ") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -g -O3 -Wstrict-aliasing=1 -ffast-math ") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") IF (APPLE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # we only use MacOSX 10.7 features diff --git a/cmake/icc.cmake b/cmake/icc.cmake index fc319530da..a92eb9ed15 100644 --- a/cmake/icc.cmake +++ b/cmake/icc.cmake @@ -19,6 +19,7 @@ SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -g") SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3") #SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -no-ansi-alias -restrict -fp-model fast -fimf-precision=low -no-prec-div -no-prec-sqrt -fma -no-inline-max-total-size -inline-factor=200 ") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -g -O3 -no-ansi-alias -restrict -fp-model fast -fimf-precision=low -no-prec-div -no-prec-sqrt -fma -no-inline-max-total-size -inline-factor=200") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") IF (APPLE) SET (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS_INIT} -dynamiclib) diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index b0c6ebb149..fc8aceed8c 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -357,8 +357,11 @@ OSPRAY_INSTALL_LIBRARY(ospray) IF(NOT THIS_IS_MIC) # build ospTutorial, for testing - ADD_EXECUTABLE(ospTutorial ../apps/ospTutorial) + ADD_EXECUTABLE(ospTutorial ../apps/ospTutorial.cpp) OSPRAY_EXE_LINK_LIBRARIES(ospTutorial ospray ospray_common) + # C version + ADD_EXECUTABLE(ospTutorialC ../apps/ospTutorial.c) + OSPRAY_EXE_LINK_LIBRARIES(ospTutorialC ospray ospray_common) ENDIF() From 2e935d75a63af5b72fa714d94cd07efd279611b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Wed, 4 May 2016 13:25:50 +0200 Subject: [PATCH 278/310] Fix tutorials (re-activate AO due to changed defaults in SciVis) --- apps/ospTutorial.c | 1 + apps/ospTutorial.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/ospTutorial.c b/apps/ospTutorial.c index 58efae2f7e..506c960e4d 100644 --- a/apps/ospTutorial.c +++ b/apps/ospTutorial.c @@ -115,6 +115,7 @@ int main(int ac, const char **av) { // create and setup renderer OSPRenderer renderer = ospNewRenderer("scivis"); // choose Scientific Visualization renderer ospSet1f(renderer, "aoWeight", 1.0f); // with full Ambient Occlusion + ospSet1i(renderer, "aoSamples", 1); ospSetObject(renderer, "model", world); ospSetObject(renderer, "camera", camera); ospCommit(renderer); diff --git a/apps/ospTutorial.cpp b/apps/ospTutorial.cpp index 5ac12c82b9..f9c7111ec0 100644 --- a/apps/ospTutorial.cpp +++ b/apps/ospTutorial.cpp @@ -115,6 +115,7 @@ int main(int ac, const char **av) { // create and setup renderer OSPRenderer renderer = ospNewRenderer("scivis"); // choose Scientific Visualization renderer ospSet1f(renderer, "aoWeight", 1.0f); // with full Ambient Occlusion + ospSet1i(renderer, "aoSamples", 1); ospSetObject(renderer, "model", world); ospSetObject(renderer, "camera", camera); ospCommit(renderer); From 7917b175e13461706383eed30565504b5855dc3b Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 5 May 2016 11:40:10 -0500 Subject: [PATCH 279/310] fix long lines in FB code --- ospray/fb/FrameBuffer.cpp | 9 +++++++-- ospray/fb/FrameBuffer.h | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ospray/fb/FrameBuffer.cpp b/ospray/fb/FrameBuffer.cpp index 065eb484cd..a563111c06 100644 --- a/ospray/fb/FrameBuffer.cpp +++ b/ospray/fb/FrameBuffer.cpp @@ -36,7 +36,9 @@ namespace ospray { } /*! helper function for debugging. write out given pixels in PPM format */ - void writePPM(const std::string &fileName, const vec2i &size, const uint32 *pixels) + void writePPM(const std::string &fileName, + const vec2i &size, + const uint32 *pixels) { FILE *file = fopen(fileName.c_str(),"w"); if (!file) { @@ -52,7 +54,10 @@ namespace ospray { } // helper function to write a (float) image as (flipped) PFM file - void writePFM(const std::string &fileName, const vec2i &size, const int channel, const float *pixel) + void writePFM(const std::string &fileName, + const vec2i &size, + const int channel, + const float *pixel) { FILE *file = fopen(fileName.c_str(),"w"); if (!file) { diff --git a/ospray/fb/FrameBuffer.h b/ospray/fb/FrameBuffer.h index 15bd154a01..d5b9a5706b 100644 --- a/ospray/fb/FrameBuffer.h +++ b/ospray/fb/FrameBuffer.h @@ -68,7 +68,9 @@ namespace ospray { changes that requires clearing the accumulation buffer. */ virtual int32 accumID(const vec2i &tile) = 0; virtual float tileError(const vec2i &tile) = 0; - virtual float endFrame(const float errorThreshold) = 0; // returns error of frame + + //! returns error of frame + virtual float endFrame(const float errorThreshold) = 0; Ref pixelOp; }; @@ -78,6 +80,7 @@ namespace ospray { void writePPM(const std::string &fileName, const vec2i &size, uint32 *pixels); //! helper function to write a (float) image as (flipped) PFM file - void writePFM(const std::string &fileName, const vec2i &size, const int channel, const float *pixels); + void writePFM(const std::string &fileName, const vec2i &size, + const int channel, const float *pixels); } // ::ospray From 9f6eea04d25600769a46ab1dbcf507de6b850d25 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 5 May 2016 11:42:39 -0500 Subject: [PATCH 280/310] remove 'obj' renderer, use 'obj' as alias for 'scivis' renderer now --- ospray/CMakeLists.txt | 4 - ospray/render/obj/OBJMaterial.cpp | 56 ------ ospray/render/obj/OBJMaterial.h | 44 ----- ospray/render/obj/OBJMaterial.ih | 37 ---- ospray/render/obj/OBJMaterial.ispc | 47 ----- ospray/render/obj/OBJRenderer.cpp | 71 ------- ospray/render/obj/OBJRenderer.h | 65 ------- ospray/render/obj/OBJRenderer.ispc | 246 ------------------------ ospray/render/scivis/SciVisMaterial.cpp | 1 + ospray/render/scivis/SciVisRenderer.cpp | 2 + 10 files changed, 3 insertions(+), 570 deletions(-) delete mode 100644 ospray/render/obj/OBJMaterial.cpp delete mode 100644 ospray/render/obj/OBJMaterial.h delete mode 100644 ospray/render/obj/OBJMaterial.ih delete mode 100644 ospray/render/obj/OBJMaterial.ispc delete mode 100644 ospray/render/obj/OBJRenderer.cpp delete mode 100644 ospray/render/obj/OBJRenderer.h delete mode 100644 ospray/render/obj/OBJRenderer.ispc diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index fc8aceed8c..3283c59e57 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -211,10 +211,6 @@ SET(OSPRAY_SOURCES render/simpleAO/SimpleAOMaterial.cpp render/simpleAO/SimpleAOMaterial.ih render/simpleAO/SimpleAOMaterial.ispc - render/obj/OBJRenderer.ispc - render/obj/OBJMaterial.ispc - render/obj/OBJRenderer.cpp - render/obj/OBJMaterial.cpp render/scivis/SciVisRenderer.ispc render/scivis/SciVisMaterial.ispc render/scivis/SciVisMaterial.ih diff --git a/ospray/render/obj/OBJMaterial.cpp b/ospray/render/obj/OBJMaterial.cpp deleted file mode 100644 index 2f2b4ce8cc..0000000000 --- a/ospray/render/obj/OBJMaterial.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#include "OBJMaterial.h" -#include "OBJMaterial_ispc.h" -#include "ospray/common/Data.h" - -namespace ospray { - namespace obj { - - //! \brief commit the material's parameters - void OBJMaterial::commit() - { - if (ispcEquivalent == NULL) - ispcEquivalent = ispc::OBJMaterial_create(this); - - map_d = (Texture2D*)getParamObject("map_d", NULL); - map_Kd = (Texture2D*)getParamObject("map_Kd", getParamObject("map_kd", NULL)); - map_Ks = (Texture2D*)getParamObject("map_Ks", getParamObject("map_ks", NULL)); - map_Ns = (Texture2D*)getParamObject("map_Ns", getParamObject("map_ns", NULL)); - map_Bump = (Texture2D*)getParamObject("map_Bump", getParamObject("map_bump", NULL)); - - d = getParam1f("d", 1.f); - Kd = getParam3f("kd", getParam3f("Kd", vec3f(.8f))); - Ks = getParam3f("ks", getParam3f("Ks", vec3f(0.f))); - Ns = getParam1f("ns", getParam1f("Ns", 10.f)); - - ispc::OBJMaterial_set(getIE(), - map_d ? map_d->getIE() : NULL, - d, - map_Kd ? map_Kd->getIE() : NULL, - (ispc::vec3f&)Kd, - map_Ks ? map_Ks->getIE() : NULL, - (ispc::vec3f&)Ks, - map_Ns ? map_Ns->getIE() : NULL, - Ns, - map_Bump != NULL ? map_Bump->getIE() : NULL ); - } - - OSP_REGISTER_MATERIAL(OBJMaterial,OBJMaterial); - - } // ::ospray::obj -} // ::ospray diff --git a/ospray/render/obj/OBJMaterial.h b/ospray/render/obj/OBJMaterial.h deleted file mode 100644 index 77527c6865..0000000000 --- a/ospray/render/obj/OBJMaterial.h +++ /dev/null @@ -1,44 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - -#include "ospray/common/Material.h" -#include "ospray/texture/Texture2D.h" - -namespace ospray { - namespace obj { - - typedef vec3f Color; - - /*! implements the Material used by the \ref ospray_render_obj */ - struct OBJMaterial : public Material { - Texture2D *map_d; float d; /*! opacity: 0 (transparent), 1 (opaque) */ - Texture2D *map_Kd; Color Kd; /*! diffuse reflectance: 0 (none), 1 (full) */ - Texture2D *map_Ks; Color Ks; /*! specular reflectance: 0 (none), 1 (full) */ - Texture2D *map_Ns; float Ns; /*! specular exponent: 0 (diffuse), infinity (specular) */ - Texture2D *map_Bump; /*! bump map */ - - //! \brief common function to help printf-debugging - /*! Every derived class should overrride this! */ - virtual std::string toString() const { return "ospray::objrenderer::OBJMaterial"; } - - //! \brief commit the material's parameters - virtual void commit(); - }; - - } // ::ospray::obj -} // ::ospray diff --git a/ospray/render/obj/OBJMaterial.ih b/ospray/render/obj/OBJMaterial.ih deleted file mode 100644 index 074af645b4..0000000000 --- a/ospray/render/obj/OBJMaterial.ih +++ /dev/null @@ -1,37 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - -#include "ospray/math/vec.ih" -#include "ospray/common/Material.ih" -#include "ospray/texture/Texture2D.ih" - -//! ispc-equivalent of ospray::obj::OBJMaterial -struct OBJMaterial -{ - uniform Material super; //!< inherited material properties - const uniform Texture2D *map_d; - float d; - const uniform Texture2D *map_Kd; - vec3f Kd; - const uniform Texture2D *map_Ks; - vec3f Ks; - const uniform Texture2D *map_Ns; - float Ns; - const uniform Texture2D *map_Bump; -}; - diff --git a/ospray/render/obj/OBJMaterial.ispc b/ospray/render/obj/OBJMaterial.ispc deleted file mode 100644 index 6583367b31..0000000000 --- a/ospray/render/obj/OBJMaterial.ispc +++ /dev/null @@ -1,47 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#include "OBJMaterial.ih" - -export void *uniform OBJMaterial_create(void *uniform cppE) -{ - uniform OBJMaterial *uniform mat = uniform new uniform OBJMaterial; - mat->super.cppEquivalent = cppE; - return mat; -} - -export void OBJMaterial_set(void *uniform _mat, - const void *uniform map_d, - const uniform float &d, - const void *uniform map_Kd, - const uniform vec3f &Kd, - const void *uniform map_Ks, - const uniform vec3f &Ks, - const void *uniform map_Ns, - const uniform float &Ns, - const void *uniform map_Bump) -{ - uniform OBJMaterial *uniform self = (uniform OBJMaterial *uniform)_mat; - self->map_d = (uniform Texture2D *uniform)map_d; - self->d = d; - self->map_Kd = (uniform Texture2D *uniform)map_Kd; - self->Kd = Kd; - self->map_Ks = (uniform Texture2D *uniform)map_Ks; - self->Ks = Ks; - self->map_Ns = (uniform Texture2D *uniform)map_Ns; - self->Ns = Ns; - self->map_Bump = (uniform Texture2D *uniform)map_Bump; -} diff --git a/ospray/render/obj/OBJRenderer.cpp b/ospray/render/obj/OBJRenderer.cpp deleted file mode 100644 index edad8307b7..0000000000 --- a/ospray/render/obj/OBJRenderer.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -// obj -#include "OBJRenderer.h" -#include "OBJMaterial.h" -// ospray -#include "ospray/common/Data.h" -#include "ospray/lights/Light.h" -//sys -#include -// ispc exports -#include "OBJRenderer_ispc.h" - -namespace ospray { - namespace obj { - - void OBJRenderer::commit() - { - Renderer::commit(); - - lightData = (Data*)getParamData("lights"); - - lightArray.clear(); - - if (lightData) - for (int i = 0; i < lightData->size(); i++) - lightArray.push_back(((Light**)lightData->data)[i]->getIE()); - - void **lightPtr = lightArray.empty() ? NULL : &lightArray[0]; - - vec3f bgColor; - bgColor = getParam3f("bgColor", vec3f(1.f)); - - const bool shadowsEnabled = bool(getParam1i("shadowsEnabled", 1)); - - ispc::OBJRenderer_set(getIE(), - (ispc::vec3f&)bgColor, - shadowsEnabled, - lightPtr, lightArray.size()); - } - - OBJRenderer::OBJRenderer() - { - ispcEquivalent = ispc::OBJRenderer_create(this); - } - - /*! \brief create a material of given type */ - Material *OBJRenderer::createMaterial(const char *type) - { - Material *mat = new OBJMaterial; - return mat; - } - - OSP_REGISTER_RENDERER(OBJRenderer,OBJ); - OSP_REGISTER_RENDERER(OBJRenderer,obj); - } // ::ospray::obj -} // ::ospray diff --git a/ospray/render/obj/OBJRenderer.h b/ospray/render/obj/OBJRenderer.h deleted file mode 100644 index 71e6ba9fd4..0000000000 --- a/ospray/render/obj/OBJRenderer.h +++ /dev/null @@ -1,65 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - -/*! \defgroup ospray_render_obj "Wavefront OBJ" Material-based Renderer - - \brief Implements the Wavefront OBJ Material Model - - \ingroup ospray_supported_renderers - - This renderer implementes a shading model roughly based on the - Wavefront OBJ material format. In particular, this renderer - implements the Material model as implemented in \ref - ospray::OBJMaterial, and implements a recursive ray tracer on top of - this mateiral model. - - Note that this renderer is NOT fully compatible with the Wavefront - OBJ specifications - in particular, we do not support the different - illumination models as specified in the 'illum' field, and always - perform full ray tracing with the given material parameters. - -*/ - -// ospray -#include "ospray/render/Renderer.h" -#include "ospray/common/Material.h" - -// system -#include - -namespace ospray { - - namespace obj { - - /*! \brief Renderer for the OBJ Wavefront Material/Lighting format - - See \ref ospray_render_obj - */ - struct OBJRenderer : public Renderer { - OBJRenderer(); - virtual std::string toString() const { return "ospray::OBJRenderer"; } - virtual void commit(); - virtual Material *createMaterial(const char *type); - - std::vector lightArray; // the 'IE's of the XXXLights - Data *lightData; - }; - - } // ::ospray::api -} // ::ospray - diff --git a/ospray/render/obj/OBJRenderer.ispc b/ospray/render/obj/OBJRenderer.ispc deleted file mode 100644 index f3362ade3c..0000000000 --- a/ospray/render/obj/OBJRenderer.ispc +++ /dev/null @@ -1,246 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -// ospray -#include "ospray/fb/FrameBuffer.ih" -#include "ospray/render/util.ih" -#include "ospray/common/Model.ih" -#include "ospray/texture/Texture2D.ih" -#include "ospray/lights/Light.ih" -#include "ospray/render/Renderer.ih" -// obj renderer -#include "OBJMaterial.ih" - -#define ALPHA_THRESHOLD (.05f) - -struct OBJRenderer { - Renderer super; - - const uniform Light *uniform *uniform lights; - uint32 numLights; - - vec3f bgColor; - bool shadowsEnabled; -}; - -inline float lightAlpha(Ray &ray, uniform Model *uniform model, const float weight, const uniform float epsilon) -{ - float alpha = 1.f; - int max_depth = 8; - const float org_t_max = ray.t; - - while (1) { - traceRay(model,ray); - - if (ray.geomID < 0) return alpha; - - DifferentialGeometry dg; - postIntersect(model, dg, ray, DG_MATERIALID | DG_TEXCOORD | DG_COLOR); - - uniform OBJMaterial *objMaterial = (uniform OBJMaterial *)dg.material; - - float material_opacity = 1.f; - - if(objMaterial == NULL) { - material_opacity = dg.color.w; - } else { - foreach_unique( mat in objMaterial ) { - material_opacity = mat->d * get1f(mat->map_d, dg.st, 1.f); - if (mat->map_Kd) { - vec4f Kd_from_map = get4f(mat->map_Kd,dg.st); - material_opacity *= Kd_from_map.w; - } - } - } - - alpha = alpha * (1.f - material_opacity); - - if (alpha * weight < ALPHA_THRESHOLD) return alpha; - - if (--max_depth <= 0) - return 0.f; - - ray.t0 = ray.t + epsilon; - ray.t = org_t_max; - ray.primID = -1; - ray.geomID = -1; - ray.instID = -1; - } -} - -inline void OBJRenderer_shadeRay(const uniform OBJRenderer *uniform self, varying ScreenSample &sample) -{ - Ray &ray = sample.ray; - // ISPC issue #703. Switch to 'nice' code once ISPC #703 is fixed. - // print("ray.dir % % %\n",ray.dir.x,ray.dir.y,ray.dir.z); - vec3f color = make_vec3f(0.f); - float path_opacity = 1.f; - int max_depth = 10; - uniform int depth = 0; - bool depthGotSet = 0; - - sample.z = infinity; - while (1) { - traceRay(self->super.model,ray); - - if (ray.geomID < 0) { - sample.rgb = self->super.backgroundEnabled ? color + path_opacity * self->bgColor : color; - sample.alpha = self->super.backgroundEnabled ? 1.f : 1.f - path_opacity; - sample.z = 1; - return; - } - - vec3f local_shade_color = make_vec3f(0.f); - - DifferentialGeometry dg; - postIntersect(self->super.model, - dg, - ray, - DG_NG|DG_NS|DG_NORMALIZE|DG_FACEFORWARD|DG_MATERIALID|DG_COLOR|DG_TEXCOORD); - - uniform Material *material = dg.material; - uniform OBJMaterial *objMaterial = (uniform OBJMaterial *)material; - - float d = 1.f; - float Ns = 0.f; - vec3f Kd = make_vec3f(0.f,1.f,0.f); - vec3f Ks = make_vec3f(0.f); -// vec3f bump = make_vec3f(0.f); // not yet supported - - if (!objMaterial) { - //color = color + path_opacity * make_vec3f(dg.color); - //return color; - d = dg.color.w; - Kd = make_vec3f(dg.color); - } else { - foreach_unique (mat in objMaterial) { - // textures modify (mul) values, see http://paulbourke.net/dataformats/mtl/ - d = mat->d * get1f(mat->map_d, dg.st, 1.f); - Kd = mat->Kd * make_vec3f(dg.color); - if (mat->map_Kd) { - vec4f Kd_from_map = get4f(mat->map_Kd,dg.st); - Kd = Kd * make_vec3f(Kd_from_map); - d *= Kd_from_map.w; - } - Ks = mat->Ks * get3f(mat->map_Ks, dg.st, make_vec3f(1.f)); - Ns = mat->Ns * get1f(mat->map_Ns, dg.st, 1.f); -// bump = get3f(mat->map_Bump, dg.st, make_vec3f(0.f)); - } - } - - if (d >= .5 && !depthGotSet) { - sample.z = ray.t; - depthGotSet = true; - } - - const float local_opacity = path_opacity * d; - - max_depth -= 1; - if (max_depth <= 0) { - sample.rgb = color; - sample.alpha = 1.f - path_opacity; - return; - } - - if (local_opacity > 0.01f) { // worth shading? - const vec3f R = ray.dir - (2.f * dot(ray.dir, dg.Ns))*dg.Ns; - const vec3f P = dg.P + self->super.epsilon * dg.Ng; - - //Some fake hard coded ambient light - color = color + local_opacity * Kd * .05; - - //calculate shading for all lights - for (uniform int i = 0; self->lights && i < self->numLights; i++) { - const uniform Light *uniform l = self->lights[i]; - const vec2f s = make_vec2f(0.f); - const Light_SampleRes light = l->sample(l, dg, s); - - if (reduce_max(light.weight) > 0.f) { // any potential contribution? - const float cosNL = abs(dot(light.dir, dg.Ns)); - const float cosLR = max(0.f, dot(light.dir, R)); - const vec3f unshaded_light_contrib = local_opacity * (Kd * cosNL + Ks * powf(cosLR, Ns)) * light.weight; - - if (self->shadowsEnabled) { - const float max_contrib = reduce_max(unshaded_light_contrib); - if (max_contrib > .01f) { - Ray shadowRay; - setRay(shadowRay, P, light.dir); - const float light_alpha = lightAlpha(shadowRay, self->super.model, max_contrib, self->super.epsilon); - local_shade_color = local_shade_color + light_alpha * unshaded_light_contrib; - } - } else - local_shade_color = local_shade_color + unshaded_light_contrib; - } - } - - color = color + local_shade_color; - } - - path_opacity = path_opacity * (1.f - d); - if (path_opacity < 0.01f) { - //remaining contribution too low kill path - sample.rgb = color; - sample.alpha = 1.f - path_opacity; - return; - } - - ray.t0 = ray.t + self->super.epsilon; - ray.t = infinity; - ray.primID = -1; - ray.geomID = -1; - ray.instID = -1; - } - - sample.rgb = color; - sample.alpha = 1.f - path_opacity; - return; -} - -void OBJRenderer_renderSample(uniform Renderer *uniform _self, - void *uniform perFrameData, - varying ScreenSample &sample) -{ - uniform OBJRenderer *uniform self = (uniform OBJRenderer *uniform)_self; - OBJRenderer_shadeRay(self, sample); -} - - -// Exports (called from C++) -////////////////////////////////////////////////////////////////////////////// - -export void OBJRenderer_set(void *uniform _self, - const uniform vec3f &bgColor, - const uniform bool shadowsEnabled, - void **uniform lights, - const uniform uint32 numLights) -{ - uniform OBJRenderer *uniform self = (uniform OBJRenderer *uniform)_self; - - self->bgColor = bgColor; - self->shadowsEnabled = shadowsEnabled; - self->lights = (const uniform Light *uniform *uniform)lights; - self->numLights = numLights; -} - -export void *uniform OBJRenderer_create(void *uniform cppE) -{ - uniform OBJRenderer *uniform self = uniform new uniform OBJRenderer; - Renderer_Constructor(&self->super,cppE); - self->super.renderSample = OBJRenderer_renderSample; - OBJRenderer_set(self, make_vec3f(1.f), true, NULL, 0); - - return self; -} diff --git a/ospray/render/scivis/SciVisMaterial.cpp b/ospray/render/scivis/SciVisMaterial.cpp index f0a7958438..2a5100ed64 100644 --- a/ospray/render/scivis/SciVisMaterial.cpp +++ b/ospray/render/scivis/SciVisMaterial.cpp @@ -58,6 +58,7 @@ namespace ospray { } OSP_REGISTER_MATERIAL(SciVisMaterial, SciVisMaterial); + OSP_REGISTER_MATERIAL(SciVisMaterial, OBJMaterial); } // ::ospray::scivis } // ::ospray diff --git a/ospray/render/scivis/SciVisRenderer.cpp b/ospray/render/scivis/SciVisRenderer.cpp index 1dcea63d29..26b6078bfa 100644 --- a/ospray/render/scivis/SciVisRenderer.cpp +++ b/ospray/render/scivis/SciVisRenderer.cpp @@ -76,6 +76,8 @@ namespace ospray { OSP_REGISTER_RENDERER(SciVisRenderer, rt); OSP_REGISTER_RENDERER(SciVisRenderer, scivis); OSP_REGISTER_RENDERER(SciVisRenderer, sv); + OSP_REGISTER_RENDERER(SciVisRenderer, obj); + OSP_REGISTER_RENDERER(SciVisRenderer, OBJ); } // ::ospray::scivis } // ::ospray From 40bbb85e272dd614fc0cb805e092a276cd5e11ab Mon Sep 17 00:00:00 2001 From: Sven Woop Date: Fri, 6 May 2016 11:46:13 +0200 Subject: [PATCH 281/310] fixed compile warning --- ospray/lights/PointLight.ispc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 7a5241a78b..152e644b8f 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -53,7 +53,7 @@ Light_SampleRes PointLight_sample(const uniform Light* uniform super, res.weight = self->power * sqr(invdist); const float sinTheta = self->radius * invdist; - if (self->radius > 0.f & sinTheta > 0.005f) { + if ((self->radius > 0.f) & (sinTheta > 0.005f)) { // res surface of sphere as seen by hit point -> cone of directions // for very small cones treat as point light, because float precision is not good enough if (sinTheta < 1.f) { From 408eb7364494b8b2cbecb66a356bff3f7ab1124c Mon Sep 17 00:00:00 2001 From: Sven Woop Date: Fri, 6 May 2016 13:41:54 +0200 Subject: [PATCH 282/310] some fixes to share ospray lights with Embree --- ospray/lights/AmbientLight.ispc | 1 + ospray/lights/DirectionalLight.ispc | 1 + ospray/lights/HDRILight.ispc | 1 + ospray/lights/PointLight.ispc | 1 + ospray/lights/QuadLight.ispc | 1 + ospray/lights/SpotLight.ispc | 1 + ospray/math/sampling.ih | 2 +- 7 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 379acb4be9..84ca7f8147 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -20,6 +20,7 @@ struct AmbientLight { + //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f radiance; //!< RGB color and intensity of light diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 2c516312d7..e7205aa113 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -20,6 +20,7 @@ struct DirectionalLight { + //ALIGNED_STRUCT Light super; //!< inherited light fields linear3f frame; //!< coordinate frame, with vz == direction *towards* the light source diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index e15d43621a..f2ee50a04a 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -22,6 +22,7 @@ struct HDRILight { + //ALIGNED_STRUCT Light super; //!< inherited light fields linear3f light2world; //!< Transformation from light space into world space diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 152e644b8f..10fc9871c8 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -20,6 +20,7 @@ struct PointLight { + //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f position; //!< light position diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index 20b9b8f06c..c733a6246c 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -18,6 +18,7 @@ struct QuadLight { + //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f position; //!< world-space corner position of the light diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 10a249930a..53ef3170ff 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -20,6 +20,7 @@ struct SpotLight { + //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f position; //!< Position of the SpotLight diff --git a/ospray/math/sampling.ih b/ospray/math/sampling.ih index 35371aba1c..45f6f257e9 100644 --- a/ospray/math/sampling.ih +++ b/ospray/math/sampling.ih @@ -77,7 +77,7 @@ inline float powerCosineSampleHemispherePDF(const float cosTheta, const float n) return (n + 1.0f) * (0.5f / M_PI) * pow(cosTheta, n); } -inline float powerCosineSampleHemispherePDF(const vec3f dir, const float n) // TODO: order of arguments +inline float powerCosineSampleHemispherePDF(const vec3f& dir, const float n) // TODO: order of arguments { return (n + 1.0f) * (0.5f / M_PI) * pow(dir.z, n); } From a5139a713194c0086dbd303bc5bd9a13abf5736e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 6 May 2016 14:44:37 +0200 Subject: [PATCH 283/310] Updates to changes and readme --- CHANGELOG.md | 2 ++ README.md | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 483fd24fac..899ea57a57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ Version History - If the renderer parameter `varianceThreshold` is set, progressive refinement concentrates on regions of the image with a variance higher than this threshold +- Added support for volumes with voxelType `ushort` (16-bit unsigned + integers) - `OSPTexture2D` now supports sRGB formats -- actually most images are stored in sRGB. As a consequence the API call `ospNewTexture2D()` needed to change to accept the new `OSPTextureFormat` parameter. diff --git a/README.md b/README.md index 5b70b40815..b900753ea3 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,8 @@ Tutorial -------- A minimal working example demonstrating how to use OSPRay can be found -at `apps/ospTutorial.cpp`. On Linux build it in the build_directory with +at `apps/ospTutorial.cpp`^[A C99 version is available at +`apps/ospTutorial.c`.]. On Linux build it in the build_directory with g++ ../apps/ospTutorial.cpp -I ../ospray/include -I .. -I ../ospray/embree/common \ ./libospray.so -Wl,-rpath,. -o ospTutorial From 604d3826b9468c668345dcf43898d7886f6506b2 Mon Sep 17 00:00:00 2001 From: atafra Date: Fri, 6 May 2016 18:21:53 +0300 Subject: [PATCH 284/310] minor change --- ospray/math/sampling.ih | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/math/sampling.ih b/ospray/math/sampling.ih index 35371aba1c..45f6f257e9 100644 --- a/ospray/math/sampling.ih +++ b/ospray/math/sampling.ih @@ -77,7 +77,7 @@ inline float powerCosineSampleHemispherePDF(const float cosTheta, const float n) return (n + 1.0f) * (0.5f / M_PI) * pow(cosTheta, n); } -inline float powerCosineSampleHemispherePDF(const vec3f dir, const float n) // TODO: order of arguments +inline float powerCosineSampleHemispherePDF(const vec3f& dir, const float n) // TODO: order of arguments { return (n + 1.0f) * (0.5f / M_PI) * pow(dir.z, n); } From 40247b932015f93d58242d0b26dd7bc07e21e216 Mon Sep 17 00:00:00 2001 From: Ingo Wald Date: Fri, 6 May 2016 12:29:40 -0500 Subject: [PATCH 285/310] fixed compile errors aroudn assertions --- apps/qtViewer/sg/geometry/Spheres.cpp | 5 +- ospray/api/API.cpp | 3 - ospray/geometry/Spheres.cpp | 7 +- ospray/geometry/Spheres.h | 12 +++- ospray/geometry/Spheres.ispc | 94 +++++++++++++++------------ 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/apps/qtViewer/sg/geometry/Spheres.cpp b/apps/qtViewer/sg/geometry/Spheres.cpp index f5eb6e3c90..fbaf4b0083 100644 --- a/apps/qtViewer/sg/geometry/Spheres.cpp +++ b/apps/qtViewer/sg/geometry/Spheres.cpp @@ -65,6 +65,7 @@ namespace ospray { size_t num = node->getPropl("num"); size_t ofs = node->getPropl("ofs"); float rad = atof(node->getProp("radius").c_str()); + PRINT(num); PRINT(rad); Spheres::Sphere s(vec3f(0.f),rad,0); @@ -78,9 +79,9 @@ namespace ospray { sphere.push_back(s); } } else { + const vec3f *in = (const vec3f*)(binBasePtr+ofs); for (int i=0;i 0, "Width must be greater than 0 in ospNewTexture2D"); Assert2(size.y > 0, "Height must be greater than 0 in ospNewTexture2D"); LOG("ospNewTexture2D( (" << size.x << ", " << size.y << "), " << type << ", " << data << ", " << flags << ")"); @@ -795,8 +794,6 @@ extern "C" void ospSampleVolume(float **results, return; } - Assert2(worldCoordinates, "NULL worldCoordinates passed to ospSampleVolume"); - ospray::api::Device::current->sampleVolume(results, volume, (vec3f*)&worldCoordinates, count); } diff --git a/ospray/geometry/Spheres.cpp b/ospray/geometry/Spheres.cpp index f8ed7b2b16..25642bbd6e 100644 --- a/ospray/geometry/Spheres.cpp +++ b/ospray/geometry/Spheres.cpp @@ -51,7 +51,9 @@ namespace ospray { sphereData = getParamData("spheres"); materialList = getParamData("materialList"); colorData = getParamData("color"); - + colorOffset = getParam1i("color_offset",0); + colorStride = getParam1i("color_stride",4*sizeof(float)); + if (sphereData.ptr == NULL) { throw std::runtime_error("#ospray:geometry/spheres: no 'spheres' data " "specified"); @@ -88,7 +90,8 @@ namespace ospray { ispc::SpheresGeometry_set(getIE(),model->getIE(), sphereData->data,_materialList, - colorData?(ispc::vec4f*)colorData->data:NULL, + colorData?(unsigned char*)colorData->data:NULL, + colorOffset, colorStride, numSpheres,bytesPerSphere, radius,materialID, offset_center,offset_radius, diff --git a/ospray/geometry/Spheres.h b/ospray/geometry/Spheres.h index e8ba9be5d8..876b99ba86 100644 --- a/ospray/geometry/Spheres.h +++ b/ospray/geometry/Spheres.h @@ -74,7 +74,17 @@ namespace ospray { Ref sphereData; Ref materialList; void *_materialList; - Ref colorData; /*!< sphere color array (vec3fa) */ + /*! data array from which we read the per-sphere color data; if + NULL we do not have per-sphere data */ + Ref colorData; + /*! stride in colorData array for accessing i'th sphere's + color. color of sphere i will be read as 3 floats from + 'colorOffset+i*colorStride */ + size_t colorStride; + /*! offset in colorData array for accessing i'th sphere's + color. color of sphere i will be read as 3 floats from + 'colorOffset+i*colorStride */ + size_t colorOffset; Spheres(); ~Spheres(); diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index 6fb99d4192..3a0f533250 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -26,11 +26,10 @@ #include "embree2/rtcore_geometry_user.isph" struct Spheres { - uniform Geometry geometry; //!< inherited geometry fields + uniform Geometry super; //!< inherited geometry fields uniform uint8 *uniform data; uniform Material *uniform *materialList; - uniform vec4f *uniform color; float radius; int materialID; @@ -38,6 +37,12 @@ struct Spheres { int offset_radius; int offset_materialID; int offset_colorID; + + uint8 *color_data; + int color_stride; + int color_offset; + // uniform vec4f *uniform color; + int32 numSpheres; int32 bytesPerSphere; }; @@ -54,16 +59,18 @@ static void Spheres_postIntersect(uniform Geometry *uniform geometry, dg.Ng = dg.Ns = ray.Ng; - if ((flags & DG_COLOR) && self->color) { + if ((flags & DG_COLOR) && self->color_data) { + uint32 colorID = 0; if (self->offset_colorID >= 0) { uniform uint8 *varying spherePtr = self->data + self->bytesPerSphere*ray.primID; - uint32 colorID = *((uniform uint32 *varying)(spherePtr+self->offset_colorID)); - dg.color = self->color[colorID]; + colorID = *((uniform uint32 *varying)(spherePtr+self->offset_colorID)); } else { - dg.color = self->color[ray.primID]; + colorID = ray.primID; } + uint32 colorAddr = self->color_offset+colorID*self->color_stride; + dg.color = make_vec4f(*((vec3f *)(self->color_data+colorAddr))); } - + if ((flags & DG_MATERIALID) && (self->offset_materialID >= 0)) { const uniform int32 primsPerPage = (1024*1024*64); if (any(ray.primID >= primsPerPage )) { @@ -87,27 +94,28 @@ static void Spheres_postIntersect(uniform Geometry *uniform geometry, } } -unmasked void Spheres_bounds(uniform Spheres *uniform geometry, +unmasked void Spheres_bounds(uniform Spheres *uniform self, uniform size_t primID, uniform box3fa &bbox) { - uniform uint8 *uniform spherePtr = geometry->data + geometry->bytesPerSphere*((uniform int64)primID); - uniform bool offr = geometry->offset_radius >= 0; - uniform float radius = offr ? *((uniform float *uniform)(spherePtr+geometry->offset_radius)) : geometry->radius; - uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+geometry->offset_center)); + uniform uint8 *uniform spherePtr = self->data + self->bytesPerSphere*((uniform int64)primID); + uniform bool offr = self->offset_radius >= 0; + uniform float radius = offr ? *((uniform float *uniform)(spherePtr+self->offset_radius)) : self->radius; + uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+self->offset_center)); bbox = make_box3fa(center-make_vec3f(radius),center+make_vec3f(radius)); } -void Spheres_intersect(uniform Spheres *uniform geometry, +void Spheres_intersect(uniform Spheres *uniform self, varying Ray &ray, uniform size_t primID) { - uniform uint8 *uniform spherePtr = geometry->data + geometry->bytesPerSphere*((uniform int64)primID); - uniform float radius = geometry->radius; - if (geometry->offset_radius >= 0) { - radius = *((uniform float *uniform)(spherePtr+geometry->offset_radius)); + uniform uint8 *uniform spherePtr = self->data + self->bytesPerSphere*((uniform int64)primID); + float *uniform spp = (float *)spherePtr; + uniform float radius = self->radius; + if (self->offset_radius >= 0) { + radius = *((uniform float *uniform)(spherePtr+self->offset_radius)); } - uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+geometry->offset_center)); + uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+self->offset_center)); const vec3f A = center - ray.org; const float a = dot(ray.dir,ray.dir); @@ -132,7 +140,7 @@ void Spheres_intersect(uniform Spheres *uniform geometry, } if (hit) { ray.primID = primID; - ray.geomID = geometry->geometry.geomID; + ray.geomID = self->super.geomID; ray.instID = -1; // cannot easily be moved to postIntersect // we need hit in object space, in postIntersect it is in world-space @@ -143,18 +151,20 @@ void Spheres_intersect(uniform Spheres *uniform geometry, export void *uniform Spheres_create(void *uniform cppEquivalent) { - uniform Spheres *uniform geom = uniform new uniform Spheres; - Geometry_Constructor(&geom->geometry,cppEquivalent, + uniform Spheres *uniform self = uniform new uniform Spheres; + Geometry_Constructor(&self->super,cppEquivalent, Spheres_postIntersect, NULL,0,NULL); - return geom; + return self; } -export void SpheresGeometry_set(void *uniform _geom, +export void SpheresGeometry_set(void *uniform _self, void *uniform _model, void *uniform data, void *uniform materialList, - uniform vec4f *uniform color, + uint8 *uniform color_data, + int uniform color_offset, + int uniform color_stride, int uniform numSpheres, int uniform bytesPerSphere, float uniform radius, @@ -164,27 +174,29 @@ export void SpheresGeometry_set(void *uniform _geom, int uniform offset_materialID, int uniform offset_colorID) { - uniform Spheres *uniform geom = (uniform Spheres *uniform)_geom; + uniform Spheres *uniform self = (uniform Spheres *uniform)_self; uniform Model *uniform model = (uniform Model *uniform)_model; uniform uint32 geomID = rtcNewUserGeometry(model->embreeSceneHandle,numSpheres); - geom->geometry.model = model; - geom->geometry.geomID = geomID; - geom->materialList = (Material **)materialList; - geom->color = color; - geom->numSpheres = numSpheres; - geom->radius = radius; - geom->data = (uniform uint8 *uniform)data; - geom->materialID = materialID; - geom->bytesPerSphere = bytesPerSphere; - - geom->offset_center = offset_center; - geom->offset_radius = offset_radius; - geom->offset_materialID = offset_materialID; - geom->offset_colorID = offset_colorID; - - rtcSetUserData(model->embreeSceneHandle,geomID,geom); + self->super.model = model; + self->super.geomID = geomID; + self->materialList = (Material **)materialList; + self->color_data = color_data; + self->color_stride = color_stride; + self->color_offset = color_offset; + self->numSpheres = numSpheres; + self->radius = radius; + self->data = (uniform uint8 *uniform)data; + self->materialID = materialID; + self->bytesPerSphere = bytesPerSphere; + + self->offset_center = offset_center; + self->offset_radius = offset_radius; + self->offset_materialID = offset_materialID; + self->offset_colorID = offset_colorID; + + rtcSetUserData(model->embreeSceneHandle,geomID,self); rtcSetBoundsFunction(model->embreeSceneHandle,geomID, (uniform RTCBoundsFunc)&Spheres_bounds); rtcSetIntersectFunction(model->embreeSceneHandle,geomID, From 5937a3b3e647b92e98dc9e64d4d6311aa8c65c82 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 6 May 2016 13:21:04 -0500 Subject: [PATCH 286/310] long line cleanups in Renderer.ispc --- ospray/render/Renderer.ispc | 63 +++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/ospray/render/Renderer.ispc b/ospray/render/Renderer.ispc index b8130d201a..6e16e50253 100644 --- a/ospray/render/Renderer.ispc +++ b/ospray/render/Renderer.ispc @@ -26,14 +26,14 @@ void Renderer_default_renderSample(uniform Renderer *uniform self, { sample.z = inf; sample.alpha = 1.f; - sample.rgb = make_random_color((sample.sampleID.x<<0)+ + sample.rgb = make_random_color((sample.sampleID.x<<0 )+ (sample.sampleID.y<<14)+ - (sample.sampleID.z<<28) - ); + (sample.sampleID.z<<28)); } -static unmasked void *uniform Renderer_default_beginFrame(uniform Renderer *uniform self, - uniform FrameBuffer *uniform fb) +static unmasked void *uniform +Renderer_default_beginFrame(uniform Renderer *uniform self, + uniform FrameBuffer *uniform fb) { self->fb = fb; if (self->camera == NULL) @@ -44,16 +44,15 @@ static unmasked void *uniform Renderer_default_beginFrame(uniform Renderer *unif } static unmasked void Renderer_default_endFrame(uniform Renderer *uniform self, - void *uniform perFrameData) + void *uniform perFrameData) { - if (self->fb) - self->fb = NULL; + if (self->fb) self->fb = NULL; } -unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, - void *uniform perFrameData, - uniform Tile &tile, - uniform int taskIndex) +unmasked void Renderer_default_renderTile(uniform Renderer *uniform self, + void *uniform perFrameData, + uniform Tile &tile, + uniform int taskIndex) { uniform FrameBuffer *uniform fb = self->fb; uniform Camera *uniform camera = self->camera; @@ -75,7 +74,7 @@ unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, const uniform int end = begin + RENDERTILE_PIXELS_PER_JOB; const uniform int startSampleID = max(tile.accumID, 0)*spp; - for (uniform uint32 i=begin;imaxDepthTexture) { // always sample center of pixel vec2f depthTexCoord; @@ -96,13 +96,15 @@ unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, } vec3f col = make_vec3f(0.f); const uint32 pixel = z_order.xs[index] + (z_order.ys[index] * TILE_SIZE); - for (uniform uint32 s = 0; srcpSize.x; - cameraSample.screen.y = (screenSample.sampleID.y + pixel_dv) * fb->rcpSize.y; + cameraSample.screen.x = (screenSample.sampleID.x + pixel_du) + * fb->rcpSize.x; + cameraSample.screen.y = (screenSample.sampleID.y + pixel_dv) + * fb->rcpSize.y; // TODO: fix correlations / better RNG cameraSample.lens.x = precomputedHalton3(startSampleID+s); @@ -130,25 +132,31 @@ unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, CameraSample cameraSample; - const uniform int blocks = tile.accumID > 0 || spp > 0 ? 1 : min(1 << -2 * spp, TILE_SIZE*TILE_SIZE); + const uniform int blocks = tile.accumID > 0 + || spp > 0 ? 1 : min(1 << -2 * spp, + TILE_SIZE*TILE_SIZE); const uniform int begin = taskIndex * RENDERTILE_PIXELS_PER_JOB; - const uniform int end = min(begin + RENDERTILE_PIXELS_PER_JOB, TILE_SIZE*TILE_SIZE/blocks); + const uniform int end = min(begin + RENDERTILE_PIXELS_PER_JOB, + TILE_SIZE*TILE_SIZE/blocks); - for (uint32 i=begin+programIndex;i= fb->size.x) | (screenSample.sampleID.y >= fb->size.y)) { continue; } - cameraSample.screen.x = (screenSample.sampleID.x + pixel_du) * fb->rcpSize.x; - cameraSample.screen.y = (screenSample.sampleID.y + pixel_dv) * fb->rcpSize.y; + cameraSample.screen.x = (screenSample.sampleID.x + pixel_du) + * fb->rcpSize.x; + cameraSample.screen.y = (screenSample.sampleID.y + pixel_dv) + * fb->rcpSize.y; camera->initRay(camera,screenSample.ray,cameraSample); - // set ray t value for early ray termination if we have a maximum depth texture + // set ray t value for early ray termination if we have a maximum depth + // texture if (self->maxDepthTexture) { // always sample center of pixel vec2f depthTexCoord; @@ -161,7 +169,8 @@ unmasked void Renderer_default_renderTileJob(uniform Renderer *uniform self, self->renderSample(self,perFrameData,screenSample); for (uniform int p = 0; p < blocks; p++) { - const uint32 pixel = z_order.xs[i*blocks+p] + (z_order.ys[i*blocks+p] * TILE_SIZE); + const uint32 pixel = z_order.xs[i*blocks+p] + + (z_order.ys[i*blocks+p] * TILE_SIZE); assert(pixel < TILE_SIZE*TILE_SIZE); setRGBAZ(tile,pixel,screenSample.rgb,screenSample.alpha,screenSample.z); } @@ -180,7 +189,7 @@ void Renderer_Constructor(uniform Renderer *uniform self, self->backgroundEnabled = true; self->maxDepthTexture = NULL; self->renderSample = Renderer_default_renderSample; - self->renderTile = Renderer_default_renderTileJob; + self->renderTile = Renderer_default_renderTile; self->beginFrame = Renderer_default_beginFrame; self->endFrame = Renderer_default_endFrame; self->toneMap = NULL; From 7c3fd4c3424a334ae96b3614400867b61ff65aa4 Mon Sep 17 00:00:00 2001 From: atafra Date: Sun, 8 May 2016 15:18:17 +0300 Subject: [PATCH 287/310] removed unnecessary ALIGNED_STRUCT from lights --- ospray/lights/AmbientLight.ispc | 1 - ospray/lights/DirectionalLight.ispc | 1 - ospray/lights/HDRILight.ispc | 1 - ospray/lights/PointLight.ispc | 1 - ospray/lights/QuadLight.ispc | 1 - ospray/lights/SpotLight.ispc | 1 - 6 files changed, 6 deletions(-) diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 84ca7f8147..379acb4be9 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -20,7 +20,6 @@ struct AmbientLight { - //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f radiance; //!< RGB color and intensity of light diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index e7205aa113..2c516312d7 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -20,7 +20,6 @@ struct DirectionalLight { - //ALIGNED_STRUCT Light super; //!< inherited light fields linear3f frame; //!< coordinate frame, with vz == direction *towards* the light source diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index f2ee50a04a..e15d43621a 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -22,7 +22,6 @@ struct HDRILight { - //ALIGNED_STRUCT Light super; //!< inherited light fields linear3f light2world; //!< Transformation from light space into world space diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 10fc9871c8..152e644b8f 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -20,7 +20,6 @@ struct PointLight { - //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f position; //!< light position diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index c733a6246c..20b9b8f06c 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -18,7 +18,6 @@ struct QuadLight { - //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f position; //!< world-space corner position of the light diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 53ef3170ff..10a249930a 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -20,7 +20,6 @@ struct SpotLight { - //ALIGNED_STRUCT Light super; //!< inherited light fields vec3f position; //!< Position of the SpotLight From e4a5700d9f76ba16f656bf813d7c68a77a1accc4 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 9 May 2016 14:32:31 -0500 Subject: [PATCH 288/310] updates to linux release script --- .gitignore | 3 +++ scripts/release_linux.sh | 56 ++++++++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index b9c0bc157c..7c0e2d76fc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ bin *.user* build +build_release *.sw? tags .ycm_extra_conf.pyc @@ -10,5 +11,7 @@ tags *.gz *.rpm *.zip +deps tbb +embree ospray-doc diff --git a/scripts/release_linux.sh b/scripts/release_linux.sh index 272734e8e7..d06f4d6b38 100755 --- a/scripts/release_linux.sh +++ b/scripts/release_linux.sh @@ -16,13 +16,7 @@ #!/bin/bash -export ROOT_DIR=$PWD - -# to make sure we do not include nor link against wrong TBB -export CPATH= -export LIBRARY_PATH= -export LD_LIBRARY_PATH= -TBB_PATH_LOCAL=$ROOT_DIR/tbb +#### Helper functions #### # check version of symbols function check_symbols @@ -45,6 +39,48 @@ function check_symbols done } +#### Set variables for script #### + +export ROOT_DIR=$PWD + +DEP_LOCATION=http://sdvis.org/~jdamstut/deps +TBB_TARBALL=embree-2.9.0.x86_64.linux.tar.gz +EMBREE_TARBALL=tbb44_20160413oss_lin.tgz + +# set compiler +export CC=gcc +export CXX=g++ + +# to make sure we do not include nor link against wrong TBB +unset CPATH +unset LIBRARY_PATH +unset LD_LIBRARY_PATH + +#### Fetch dependencies (TBB+Embree) #### + +mkdir deps +rm -rf deps/* +cd deps + +# TBB +wget $DEP_LOCATION/$TBB_TARBALL +tar -xaf $TBB_TARBALL +rm $TBB_TARBALL + +# Embree +wget $DEP_LOCATION/$EMBREE_TARBALL +tar -xaf $EMBREE_TARBALL +rm $EMBREE_TARBALL + +cd $ROOT_DIR +ln -snf deps/tbb* tbb +ln -snf deps/embree* embree + +TBB_PATH_LOCAL=$ROOT_DIR/tbb +export embree_DIR=$ROOT_DIR/embree + +#### Build OSPRay #### + mkdir -p build_release cd build_release # make sure to use default settings @@ -53,12 +89,11 @@ rm -f ospray/version.h # set release and RPM settings cmake \ --D CMAKE_C_COMPILER:FILEPATH=icc \ --D CMAKE_CXX_COMPILER:FILEPATH=icpc \ -D OSPRAY_BUILD_ISA=ALL \ -D OSPRAY_BUILD_MIC_SUPPORT=OFF \ -D OSPRAY_BUILD_COI_DEVICE=OFF \ -D OSPRAY_BUILD_MPI_DEVICE=OFF \ +-D OSPRAY_USE_EXTERNAL_EMBREE=ON \ -D USE_IMAGE_MAGICK=OFF \ -D OSPRAY_ZIP_MODE=OFF \ -D CMAKE_INSTALL_PREFIX=$ROOT_DIR/install \ @@ -71,7 +106,7 @@ make -j `nproc` preinstall check_symbols libospray.so GLIBC 2 4 check_symbols libospray.so GLIBCXX 3 4 check_symbols libospray.so CXXABI 1 3 -make package +make -j `nproc` package # read OSPRay version OSPRAY_VERSION=`sed -n 's/#define OSPRAY_VERSION "\(.*\)"/\1/p' ospray/version.h` @@ -96,4 +131,3 @@ cmake \ # create tar.gz files make -j `nproc` package -cd $ROOT_DIR From 480afcaffd9b039d80c089fceb3e561e53df3fea Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 9 May 2016 21:34:24 -0500 Subject: [PATCH 289/310] fix spheres broken in VTK --- ospray/geometry/Spheres.ispc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index 3a0f533250..8a445de495 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -68,7 +68,7 @@ static void Spheres_postIntersect(uniform Geometry *uniform geometry, colorID = ray.primID; } uint32 colorAddr = self->color_offset+colorID*self->color_stride; - dg.color = make_vec4f(*((vec3f *)(self->color_data+colorAddr))); + dg.color = *((vec4f *)(self->color_data+colorAddr)); } if ((flags & DG_MATERIALID) && (self->offset_materialID >= 0)) { From 2c7c8f40215c2868c7e81f4d545ef32249bc07d9 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Mon, 9 May 2016 21:34:37 -0500 Subject: [PATCH 290/310] fix long lines in Spheres.ispc --- ospray/geometry/Spheres.ispc | 68 +++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index 8a445de495..a38d3eaef6 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -41,7 +41,6 @@ struct Spheres { uint8 *color_data; int color_stride; int color_offset; - // uniform vec4f *uniform color; int32 numSpheres; int32 bytesPerSphere; @@ -62,7 +61,8 @@ static void Spheres_postIntersect(uniform Geometry *uniform geometry, if ((flags & DG_COLOR) && self->color_data) { uint32 colorID = 0; if (self->offset_colorID >= 0) { - uniform uint8 *varying spherePtr = self->data + self->bytesPerSphere*ray.primID; + uniform uint8 *varying spherePtr = + self->data + self->bytesPerSphere*ray.primID; colorID = *((uniform uint32 *varying)(spherePtr+self->offset_colorID)); } else { colorID = ray.primID; @@ -77,16 +77,23 @@ static void Spheres_postIntersect(uniform Geometry *uniform geometry, const int primPageID = ray.primID / primsPerPage; const int localPrimID = ray.primID % primsPerPage; foreach_unique(primPage in primPageID) { - uniform uint8 *uniform pagePtr = self->data + (((int64)primPage) * primsPerPage * self->bytesPerSphere); - uniform uint8 *varying spherePtr = pagePtr + self->bytesPerSphere*localPrimID; - dg.materialID = *((uniform uint32 *varying)(spherePtr+self->offset_materialID)); + uniform uint8 *uniform pagePtr = self->data + + (((int64)primPage) + * primsPerPage + * self->bytesPerSphere); + uniform uint8 *varying spherePtr = pagePtr + + self->bytesPerSphere*localPrimID; + dg.materialID = + *((uniform uint32 *varying)(spherePtr+self->offset_materialID)); if (self->materialList) { dg.material = self->materialList[dg.materialID]; } } } else { - uniform uint8 *varying spherePtr = self->data + self->bytesPerSphere*ray.primID; - dg.materialID = *((uniform uint32 *varying)(spherePtr+self->offset_materialID)); + uniform uint8 *varying spherePtr = self->data + + self->bytesPerSphere*ray.primID; + dg.materialID = + *((uniform uint32 *varying)(spherePtr+self->offset_materialID)); if (self->materialList) { dg.material = self->materialList[dg.materialID]; } @@ -98,10 +105,14 @@ unmasked void Spheres_bounds(uniform Spheres *uniform self, uniform size_t primID, uniform box3fa &bbox) { - uniform uint8 *uniform spherePtr = self->data + self->bytesPerSphere*((uniform int64)primID); + uniform uint8 *uniform spherePtr = self->data + + self->bytesPerSphere*((uniform int64)primID); uniform bool offr = self->offset_radius >= 0; - uniform float radius = offr ? *((uniform float *uniform)(spherePtr+self->offset_radius)) : self->radius; - uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+self->offset_center)); + uniform float radius = + offr ? *((uniform float *uniform)(spherePtr+self->offset_radius)) : + self->radius; + uniform vec3f center = + *((uniform vec3f*uniform)(spherePtr+self->offset_center)); bbox = make_box3fa(center-make_vec3f(radius),center+make_vec3f(radius)); } @@ -109,13 +120,14 @@ void Spheres_intersect(uniform Spheres *uniform self, varying Ray &ray, uniform size_t primID) { - uniform uint8 *uniform spherePtr = self->data + self->bytesPerSphere*((uniform int64)primID); - float *uniform spp = (float *)spherePtr; + uniform uint8 *uniform spherePtr = + self->data + self->bytesPerSphere*((uniform int64)primID); uniform float radius = self->radius; if (self->offset_radius >= 0) { radius = *((uniform float *uniform)(spherePtr+self->offset_radius)); } - uniform vec3f center = *((uniform vec3f*uniform)(spherePtr+self->offset_center)); + uniform vec3f center = + *((uniform vec3f*uniform)(spherePtr+self->offset_center)); const vec3f A = center - ray.org; const float a = dot(ray.dir,ray.dir); @@ -158,21 +170,21 @@ export void *uniform Spheres_create(void *uniform cppEquivalent) return self; } -export void SpheresGeometry_set(void *uniform _self, - void *uniform _model, - void *uniform data, - void *uniform materialList, - uint8 *uniform color_data, - int uniform color_offset, - int uniform color_stride, - int uniform numSpheres, - int uniform bytesPerSphere, - float uniform radius, - int uniform materialID, - int uniform offset_center, - int uniform offset_radius, - int uniform offset_materialID, - int uniform offset_colorID) +export void SpheresGeometry_set(void *uniform _self, + void *uniform _model, + void *uniform data, + void *uniform materialList, + uint8 *uniform color_data, + int uniform color_offset, + int uniform color_stride, + int uniform numSpheres, + int uniform bytesPerSphere, + float uniform radius, + int uniform materialID, + int uniform offset_center, + int uniform offset_radius, + int uniform offset_materialID, + int uniform offset_colorID) { uniform Spheres *uniform self = (uniform Spheres *uniform)_self; uniform Model *uniform model = (uniform Model *uniform)_model; From 6a7d29a9ee07ad7fc603bdb95813e45d1ba70c22 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 10 May 2016 19:59:31 -0500 Subject: [PATCH 291/310] fix some long lines in scivis renderer --- ospray/render/scivis/SciVisRenderer.ispc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index a0888a8e9b..251f76f0b6 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -287,7 +287,8 @@ inline void SciVisRenderer_computeVolumeSample(SciVisRenderer *uniform renderer, const vec2f s = make_vec2f(0.5f); for (uniform uint32 i=0; inumLights; i++) { - const Light_SampleRes light = renderer->lights[i]->sample(renderer->lights[i], dg, s); + const Light_SampleRes light = + renderer->lights[i]->sample(renderer->lights[i], dg, s); const float cosNL = (gradient.x == 0.f && gradient.y == 0.f && gradient.z == 0.f) ? @@ -379,9 +380,11 @@ void SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, } } -/*! Returns the first hit volume for the provided ray and sets the ray bounds t0 and t, - considering the provided ray offset and any clipping. If no volume is found, the - returned volume is NULL and ray.t0 will be set to infinity. */ +/*! Returns the first hit volume for the provided ray and sets the ray bounds + * t0 and t, considering the provided ray offset and any clipping. If no + * volume is found, the returned volume is NULL and ray.t0 will be set to + * infinity. + */ inline Volume * SciVisRenderer_intersectVolumes(uniform SciVisRenderer *uniform renderer, varying Ray &ray, @@ -403,7 +406,8 @@ SciVisRenderer_intersectVolumes(uniform SciVisRenderer *uniform renderer, intersectBox(ray, volume_i->boundingBox, t0, t1); // Clip against volume clipping box (if specified). - if(ne(volume_i->volumeClippingBox.lower, volume_i->volumeClippingBox.upper)) { + if(ne(volume_i->volumeClippingBox.lower, + volume_i->volumeClippingBox.upper)) { float tClip0, tClip1; intersectBox(ray, volume_i->volumeClippingBox, tClip0, tClip1); From 4e8504417882760f610cde550ad7fd1f7a2a62c2 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Tue, 10 May 2016 20:29:54 -0500 Subject: [PATCH 292/310] fix scivis renderer bug where volumes would always be on top of volumes --- ospray/render/scivis/SciVisRenderer.ispc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 251f76f0b6..01f03017a6 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -494,8 +494,10 @@ void SciVisRenderer_intersect(uniform SciVisRenderer *uniform renderer, // Trace the ray through the volume and geometries. float firstHit; - // Geometry contribution. - color = color + (1.0f - color.w) * geometryColor; + if(geometryRay.t < ray.t0 || volume == NULL) { + // Geometry contribution. + color = color + (1.0f - color.w) * geometryColor; + } while ((firstHit = min(ray.t0, geometryRay.t)) < tMax /*&& min(min(color.x, color.y), color.z) < 1.0f*///<--why is this here? From 7754c7347e308ee404d459b0647009412e72b611 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 12 May 2016 13:49:32 -0500 Subject: [PATCH 293/310] remove unused files, move remaining MPI specific files to mpi/ directory --- common/CMakeLists.txt | 2 - common/mpi.h | 62 ------ common/network.cpp | 332 ------------------------------- common/network.h | 86 -------- ospray/CMakeLists.txt | 7 +- ospray/device/buffers.cpp | 22 -- ospray/device/nwlayer.cpp | 45 ----- ospray/device/nwlayer.h | 101 ---------- ospray/mpi/MPIDevice.h | 2 +- ospray/{device => mpi}/buffers.h | 0 ospray/{device => mpi}/command.h | 2 +- 11 files changed, 5 insertions(+), 656 deletions(-) delete mode 100644 common/mpi.h delete mode 100644 common/network.cpp delete mode 100644 common/network.h delete mode 100644 ospray/device/buffers.cpp delete mode 100644 ospray/device/nwlayer.cpp delete mode 100644 ospray/device/nwlayer.h rename ospray/{device => mpi}/buffers.h (100%) rename ospray/{device => mpi}/command.h (98%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index b8f6decdc2..40db5afebe 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -27,7 +27,6 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED library.cpp thread.cpp vec.cpp - network.cpp AffineSpace.h box.h @@ -35,7 +34,6 @@ OSPRAY_ADD_LIBRARY(ospray_common SHARED intrinsics.h LinearSpace.h math.h - mpi.h platform.h Quaternion.h RefCount.h diff --git a/common/mpi.h b/common/mpi.h deleted file mode 100644 index 2fa5c7a6a9..0000000000 --- a/common/mpi.h +++ /dev/null @@ -1,62 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#include -#include - -#define MPI_CALL(cmd) { int rc = MPI_##cmd; if (rc != MPI_SUCCESS) throw std::runtime_error("mpi error"); } - -#define error(msg) throw std::runtime_error(msg) - - -namespace ospcommon { - - struct MPIComm { - MPI_Comm comm; - int size, rank, isInterComm; - - void setTo(MPI_Comm comm); - void dupFrom(MPI_Comm comm); - void setSizeAndRank(); - }; - - inline void MPIComm::setSizeAndRank() - { - MPI_CALL(Comm_test_inter(comm,&isInterComm)); - if (isInterComm) { - MPI_CALL(Comm_remote_size(comm,&size)); - rank = -1; - } else { - MPI_CALL(Comm_size(comm,&size)); - MPI_CALL(Comm_rank(comm,&rank)); - } - } - - inline void MPIComm::setTo(MPI_Comm comm) - { - this->comm = comm; - setSizeAndRank(); - } - - inline void MPIComm::dupFrom(MPI_Comm comm) - { - MPI_CALL(Comm_dup(comm,&this->comm)); - setSizeAndRank(); - } - -} // ::ospcommon - - diff --git a/common/network.cpp b/common/network.cpp deleted file mode 100644 index f63129bbe9..0000000000 --- a/common/network.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#include "network.h" -#include "string.h" - -//////////////////////////////////////////////////////////////////////////////// -/// Platforms supporting Socket interface -//////////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -#include -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#include -//#include -typedef int socklen_t; -#define SHUT_RDWR 0x2 -#else -#include -#include -#include -#include -#include -#include -#include -#define SOCKET int -#define INVALID_SOCKET -1 -#define closesocket close -#endif - -/*! ignore if not supported */ -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif - -#define BUFFERING 1 - -namespace ospcommon -{ - namespace network - { - __forceinline void initialize() { -#ifdef _WIN32 - static bool initialized = false; - static std::mutex initMutex; - std::lock_guard lock(initMutex); - WSADATA wsaData; - short version = MAKEWORD(1,1); - if (WSAStartup(version,&wsaData) != 0) - THROW_RUNTIME_ERROR("Winsock initialization failed"); - initialized = true; -#endif - } - - struct buffered_socket_t - { - buffered_socket_t (SOCKET fd, size_t isize = 64*1024, size_t osize = 64*1024) - : fd(fd), - ibuf(new char[isize]), isize(isize), istart(0), iend(0), - obuf(new char[osize]), osize(osize), oend(0) { - } - - ~buffered_socket_t () { - delete[] ibuf; ibuf = nullptr; - delete[] obuf; obuf = nullptr; - } - - SOCKET fd; //!< file descriptor of the socket - char* ibuf; - size_t isize; - size_t istart,iend; - char* obuf; - size_t osize; - size_t oend; - }; - - socket_t connect(const char* host, unsigned short port) - { - initialize(); - - /*! create a new socket */ - SOCKET sockfd = ::socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot create socket"); - - /*! perform DNS lookup */ - struct hostent* server = ::gethostbyname(host); - if (server == nullptr) THROW_RUNTIME_ERROR("server "+std::string(host)+" not found"); - - /*! perform connection */ - struct sockaddr_in serv_addr; - memset((char*)&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = (unsigned short) htons(port); - memcpy((char*)&serv_addr.sin_addr.s_addr, (char*)server->h_addr, server->h_length); - - if (::connect(sockfd,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0) - THROW_RUNTIME_ERROR("connection to "+std::string(host)+":"+std::to_string((long long)port)+" failed"); - - /*! enable TCP_NODELAY */ -#ifdef TCP_NODELAY - { int flag = 1; ::setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(int)); } -#endif - - /*! we do not want SIGPIPE to be thrown */ -#ifdef SO_NOSIGPIPE - { int flag = 1; setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (const char*) &flag, sizeof(int)); } -#endif - - return (socket_t) new buffered_socket_t(sockfd); - } - - socket_t bind(unsigned short port) - { - initialize(); - - /*! create a new socket */ - SOCKET sockfd = ::socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot create socket"); - - /* When the server completes, the server socket enters a time-wait state during which the local - address and port used by the socket are believed to be in use by the OS. The wait state may - last several minutes. This socket option allows bind() to reuse the port immediately. */ -#ifdef SO_REUSEADDR - { int flag = true; ::setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(int)); } -#endif - - /*! bind socket to port */ - struct sockaddr_in serv_addr; - memset((char *) &serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = (unsigned short) htons(port); - serv_addr.sin_addr.s_addr = INADDR_ANY; - - if (::bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) { - THROW_RUNTIME_ERROR("binding to port "+std::to_string((long long)port)+" failed"); - } - - /*! listen to port, up to 5 pending connections */ - if (::listen(sockfd,5) < 0) - THROW_RUNTIME_ERROR("listening on socket failed"); - - return (socket_t) new buffered_socket_t(sockfd); - } - - socket_t listen(socket_t hsock) - { - SOCKET sockfd = ((buffered_socket_t*) hsock)->fd; - - /*! accept incoming connection */ - struct sockaddr_in addr; - socklen_t len = sizeof(addr); - SOCKET fd = ::accept(sockfd, (struct sockaddr *) &addr, &len); - if (fd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot accept connection"); - - /*! enable TCP_NODELAY */ -#ifdef TCP_NODELAY - { int flag = 1; ::setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char*)&flag,sizeof(int)); } -#endif - - /*! we do not want SIGPIPE to be thrown */ -#ifdef SO_NOSIGPIPE - { int flag = 1; setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&flag, sizeof(int)); } -#endif - - return (socket_t) new buffered_socket_t(fd); - } - - void read(socket_t hsock_i, void* data_i, size_t bytes) - { -#if BUFFERING - char* data = (char*)data_i; - buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; - while (bytes) { - if (hsock->istart == hsock->iend) { - ssize_t n = ::recv(hsock->fd,hsock->ibuf,hsock->isize,MSG_NOSIGNAL); - if (n == 0) throw Disconnect(); - else if (n < 0) THROW_RUNTIME_ERROR("error reading from socket"); - hsock->istart = 0; - hsock->iend = n; - } - size_t bsize = hsock->iend-hsock->istart; - if (bytes < bsize) bsize = bytes; - memcpy(data,hsock->ibuf+hsock->istart,bsize); - data += bsize; - hsock->istart += bsize; - bytes -= bsize; - } -#else - char* data = (char*) data_i; - buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; - while (bytes) { - ssize_t n = ::read(hsock->fd,data,bytes); - if (n == 0) throw Disconnect(); - else if (n < 0) THROW_RUNTIME_ERROR("error reading from socket"); - data+=n; - bytes-=n; - } -#endif - } - - void write(socket_t hsock_i, const void* data_i, size_t bytes) - { -#if BUFFERING - const char* data = (const char*) data_i; - buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; - while (bytes) { - if (hsock->oend == hsock->osize) flush(hsock_i); - size_t bsize = hsock->osize-hsock->oend; - if (bytes < bsize) bsize = bytes; - memcpy(hsock->obuf+hsock->oend,data,bsize); - data += bsize; - hsock->oend += bsize; - bytes -= bsize; - } -#else - const char* data = (const char*) data_i; - buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; - while (bytes) { - ssize_t n = ::write(hsock->fd,data,bytes); - if (n < 0) THROW_RUNTIME_ERROR("error writing to socket"); - data+=n; - bytes-=n; - } -#endif - } - - void flush(socket_t hsock_i) - { -#if BUFFERING - buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; - char* data = hsock->obuf; - size_t bytes = hsock->oend; - while (bytes > 0) { - ssize_t n = ::send(hsock->fd,data,(int)bytes,MSG_NOSIGNAL); - if (n < 0) THROW_RUNTIME_ERROR("error writing to socket"); - bytes -= n; - data += n; - } - hsock->oend = 0; -#endif - } - - void close(socket_t hsock_i) { - buffered_socket_t* hsock = (buffered_socket_t*) hsock_i; - ::shutdown(hsock->fd,SHUT_RDWR); - delete hsock; - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -/// All Platforms -//////////////////////////////////////////////////////////////////////////////// - -namespace ospcommon -{ - namespace network - { - bool read_bool(socket_t socket) - { - bool value = 0; - read(socket,&value,sizeof(bool)); - return value; - } - - char read_char(socket_t socket) - { - char value = 0; - read(socket,&value,sizeof(char)); - return value; - } - - int read_int(socket_t socket) - { - int value = 0; - read(socket,&value,sizeof(int)); - return value; - } - - float read_float(socket_t socket) - { - float value = 0.0f; - read(socket,&value,sizeof(float)); - return value; - } - - std::string read_string(socket_t socket) - { - int bytes = read_int(socket); - char* str = new char[bytes+1]; - read(socket,str,bytes); - str[bytes] = 0x00; - std::string s(str); - delete[] str; - return s; - } - - void write(socket_t socket, bool value) { - write(socket,&value,sizeof(bool)); - } - - void write(socket_t socket, char value) { - write(socket,&value,sizeof(char)); - } - - void write(socket_t socket, int value) { - write(socket,&value,sizeof(int)); - } - - void write(socket_t socket, float value) { - write(socket,&value,sizeof(float)); - } - - void write(socket_t socket, const std::string& str) { - write(socket,(int)str.size()); - write(socket,str.c_str(),str.size()); - } - } -} diff --git a/common/network.h b/common/network.h deleted file mode 100644 index 83c6b18ab1..0000000000 --- a/common/network.h +++ /dev/null @@ -1,86 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - -#include "platform.h" - -namespace ospcommon -{ - namespace network - { - /*! type for a socket */ - typedef struct opaque_socket_t* socket_t; - - /*! exception thrown when other side disconnects */ - struct Disconnect : public std::exception { - virtual const char* what() const throw() { - return "network disconnect"; - } - }; - - /*! creates a socket bound to a port */ - socket_t bind(unsigned short port); - - /*! listens for an incoming connection and accepts that connection */ - socket_t listen(socket_t sockfd); - - /*! initiates a connection */ - socket_t connect(const char* host, unsigned short port); - - /*! read data from the socket */ - void read(socket_t socket, void* data, size_t bytes); - - /*! write data to the socket */ - void write(socket_t socket, const void* data, size_t bytes); - - /*! flushes the write buffer */ - void flush(socket_t socket); - - /*! close a socket */ - void close(socket_t socket); - - /*! reads a bool from the socket */ - bool read_bool(socket_t socket); - - /*! reads a character from the socket */ - char read_char(socket_t socket); - - /*! reads an integer from the socket */ - int read_int(socket_t socket); - - /*! reads a float from the socket */ - float read_float(socket_t socket); - - /*! reads a string from the socket */ - std::string read_string(socket_t socket); - - /*! writes a bool to the socket */ - void write(socket_t socket, bool value); - - /*! writes a character to the socket */ - void write(socket_t socket, char value); - - /*! writes an integer to the socket */ - void write(socket_t socket, int value); - - /*! writes a float to the socket */ - void write(socket_t socket, float value); - - /*! writes a string to the socket */ - void write(socket_t socket, const std::string& str); - } -} diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index 3283c59e57..9f4cf4c65d 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -105,10 +105,6 @@ SET(OSPRAY_SOURCES include/ospray/OSPDataType.h include/ospray/OSPTexture.h - device/buffers.cpp - device/command.h - device/nwlayer.cpp - math/box.ispc math/Distribution2D.ispc @@ -256,6 +252,9 @@ IF (OSPRAY_MPI) CONFIGURE_MPI() SET(OSPRAY_SOURCES ${OSPRAY_SOURCES} + mpi/buffers.h + mpi/command.h + mpi/MPIDevice.cpp mpi/MPICommon.cpp mpi/MPILoadBalancer.cpp diff --git a/ospray/device/buffers.cpp b/ospray/device/buffers.cpp deleted file mode 100644 index 35a669bc58..0000000000 --- a/ospray/device/buffers.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#include "buffers.h" - -namespace ospray { - namespace nwlayer { - } -} diff --git a/ospray/device/nwlayer.cpp b/ospray/device/nwlayer.cpp deleted file mode 100644 index 24ecffd3f2..0000000000 --- a/ospray/device/nwlayer.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#include "nwlayer.h" - -namespace ospray { - namespace nwlayer { - - inline std::string toString(long l) - { std::stringstream ss; ss << l; return ss.str(); } - - void RemoteWorker::handleCommand(const CommandTag cmd, ReadBuffer &args) - { - throw std::runtime_error("unknown command "+toString(cmd)); - } - - void RemoteWorker::executeCommands() - { - assert(comm); - assert(device); - CommandTag cmd; - ReadBuffer args; - while (1) { - PING; - comm->recv(cmd,args); - PRINT(cmd); - handleCommand(cmd,args); - } - } - - } // ::ospray::nwlayer -} // ::ospray diff --git a/ospray/device/nwlayer.h b/ospray/device/nwlayer.h deleted file mode 100644 index 070e523588..0000000000 --- a/ospray/device/nwlayer.h +++ /dev/null @@ -1,101 +0,0 @@ -// ======================================================================== // -// Copyright 2009-2016 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // - -#pragma once - -/*! \file ospray/device/nwlayer.h \brief Defines the basic network layer abstraction */ - -// ospray -#include "ospray/device/buffers.h" -#include "ospray/device/command.h" -#include "ospray/api/Device.h" -// embree -#include "common/network.h" - -namespace ospray { - namespace nwlayer { - - /*! a "communicator" is the abstraction for the class that can - send messages/commands to remote clients */ - struct Communicator { - /* receive from *master* to *all* clients */ - virtual void bcast(const WriteBuffer &args) = 0; - virtual void sendTo(const uint32 clientID, - const WriteBuffer &args) = 0; - /*! flush the send queue, making sure that the last command was - properly executed. this may introduce (quite) some delay, so - be wary of this call */ - virtual void flushSendQueue() = 0; - /* receive from *master* */ - virtual void recv(CommandTag &cmd, ReadBuffer &args) = 0; - }; - - struct MPICommunicator : public Communicator { - }; - struct TCPCommunicator : public Communicator { - std::vector remote; - }; - - - /*! a network "worker" is the instance that handles a device's API - calls on a remote node */ - struct RemoteWorker { - /*! communicator through which we receive commands */ - Communicator *comm; - /*! device which we use by default to execute the commands we received */ - ospray::api::Device *device; - virtual void handleCommand(const CommandTag cmd, ReadBuffer &args) = 0; - virtual void executeCommands(); - }; - - /*! base class for all kinds of devices in which API calls get - packed up as command streams that then get sent (or broadcast) - to different workers */ - struct RemoteDevice : public ospray::api::Device { - }; - - /*! the remote rendering device simply forwards all calls to the - remote worker (which may use a device of its choice to compute - the pixels), and returns a (possibly compressed) image back */ - struct RemoteRenderingDevice : public RemoteDevice { - }; - - /*! the MPI *group* device has a set of N nodes that are all in - the same MPI group and communiate with each other through a - common intracommunicator. Rank 0 acts as a master and does the - control/load balancing of the other ranks, but by itself - doesn't do anything else (if the same node is to also render - pixels it should simply be added twice; once as rank0, and - once as rank1. */ - struct MPIGroupDevice { - struct DeviceInterface : public RemoteDevice - { - }; - struct Worker : public RemoteWorker - { - }; - }; - - /*! the MPI *cluster* device has a dedicated master node for - control and load balancing, has all workers running in a - different MPI group, and has master and workers communicate - through a MPI-*inter*-communicator (the workers also have a - intracommunicator among themselves */ - struct MPIClusterDevice { - }; - - } // ::ospray::nwlayer -} // ::ospray diff --git a/ospray/mpi/MPIDevice.h b/ospray/mpi/MPIDevice.h index 6f3aec954c..38dd596172 100644 --- a/ospray/mpi/MPIDevice.h +++ b/ospray/mpi/MPIDevice.h @@ -18,7 +18,7 @@ #include "MPICommon.h" #include "ospray/api/Device.h" -#include "ospray/device/command.h" +#include "ospray/mpi/command.h" #include "CommandStream.h" #include "ospray/common/Managed.h" diff --git a/ospray/device/buffers.h b/ospray/mpi/buffers.h similarity index 100% rename from ospray/device/buffers.h rename to ospray/mpi/buffers.h diff --git a/ospray/device/command.h b/ospray/mpi/command.h similarity index 98% rename from ospray/device/command.h rename to ospray/mpi/command.h index cc5524ed2e..d3c4df8a06 100644 --- a/ospray/device/command.h +++ b/ospray/mpi/command.h @@ -19,7 +19,7 @@ /*! \file ospray/device/nwlayer.h \brief Defines the basic network layer abstraction */ #include "ospray/include/ospray/ospray.h" -#include "ospray/device/buffers.h" +#include "ospray/mpi/buffers.h" namespace ospray { // namespace nwlayer { From 723389410d6687b51e85c4233217e7fc359b3eaa Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 12 May 2016 14:41:57 -0500 Subject: [PATCH 294/310] reorganize release scripts, make linux.sh script more compiler flexible --- .../{release_linux.sh => release/linux.sh} | 50 ++++++++++--------- .../{release_macosx.sh => release/macosx.sh} | 0 scripts/{release_win.bat => release/win.bat} | 0 scripts/{release_win.sh => release/win.sh} | 0 4 files changed, 27 insertions(+), 23 deletions(-) rename scripts/{release_linux.sh => release/linux.sh} (86%) rename scripts/{release_macosx.sh => release/macosx.sh} (100%) rename scripts/{release_win.bat => release/win.bat} (100%) rename scripts/{release_win.sh => release/win.sh} (100%) diff --git a/scripts/release_linux.sh b/scripts/release/linux.sh similarity index 86% rename from scripts/release_linux.sh rename to scripts/release/linux.sh index d06f4d6b38..817ea6cfbe 100755 --- a/scripts/release_linux.sh +++ b/scripts/release/linux.sh @@ -47,9 +47,11 @@ DEP_LOCATION=http://sdvis.org/~jdamstut/deps TBB_TARBALL=embree-2.9.0.x86_64.linux.tar.gz EMBREE_TARBALL=tbb44_20160413oss_lin.tgz -# set compiler -export CC=gcc -export CXX=g++ +# set compiler if the user hasn't explicitly set CC and CXX +if [ -z $CC ]; then + export CC=icc + export CXX=icpc +fi # to make sure we do not include nor link against wrong TBB unset CPATH @@ -58,23 +60,25 @@ unset LD_LIBRARY_PATH #### Fetch dependencies (TBB+Embree) #### -mkdir deps -rm -rf deps/* -cd deps - -# TBB -wget $DEP_LOCATION/$TBB_TARBALL -tar -xaf $TBB_TARBALL -rm $TBB_TARBALL - -# Embree -wget $DEP_LOCATION/$EMBREE_TARBALL -tar -xaf $EMBREE_TARBALL -rm $EMBREE_TARBALL - -cd $ROOT_DIR -ln -snf deps/tbb* tbb -ln -snf deps/embree* embree +if [ ! -d deps ]; then + mkdir deps + rm -rf deps/* + cd deps + + # TBB + wget $DEP_LOCATION/$TBB_TARBALL + tar -xaf $TBB_TARBALL + rm $TBB_TARBALL + + # Embree + wget $DEP_LOCATION/$EMBREE_TARBALL + tar -xaf $EMBREE_TARBALL + rm $EMBREE_TARBALL + + cd $ROOT_DIR + ln -snf deps/tbb* tbb + ln -snf deps/embree* embree +fi TBB_PATH_LOCAL=$ROOT_DIR/tbb export embree_DIR=$ROOT_DIR/embree @@ -83,9 +87,9 @@ export embree_DIR=$ROOT_DIR/embree mkdir -p build_release cd build_release -# make sure to use default settings -rm -f CMakeCache.txt -rm -f ospray/version.h + +# Clean out build directory to be sure we are doing a fresh build +rm -rf * # set release and RPM settings cmake \ diff --git a/scripts/release_macosx.sh b/scripts/release/macosx.sh similarity index 100% rename from scripts/release_macosx.sh rename to scripts/release/macosx.sh diff --git a/scripts/release_win.bat b/scripts/release/win.bat similarity index 100% rename from scripts/release_win.bat rename to scripts/release/win.bat diff --git a/scripts/release_win.sh b/scripts/release/win.sh similarity index 100% rename from scripts/release_win.sh rename to scripts/release/win.sh From 32beeff491cc536ee5070506681bae98c97144e4 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 12 May 2016 21:08:48 -0500 Subject: [PATCH 295/310] test to see if gitlab can make a linux binary --- .gitignore | 1 + .gitlab-ci.yml | 23 +++++++++++++++++++++++ scripts/release/linux.sh | 22 +++++++++++++++++++--- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7c0e2d76fc..8eb2a3180e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ tags deps tbb embree +ispc ospray-doc diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9957eb185d..591c377bd3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ stages: - build + - deploy build-centos6-gcc: type: build @@ -8,6 +9,7 @@ build-centos6-gcc: tags: - centos6 - gcc + - build build-centos7-gcc: type: build @@ -16,6 +18,7 @@ build-centos7-gcc: tags: - centos7 - gcc + - build build-fedora-gcc: type: build @@ -24,6 +27,7 @@ build-fedora-gcc: tags: - fedora - gcc + - build build-ubuntu-gcc: type: build @@ -32,6 +36,7 @@ build-ubuntu-gcc: tags: - ubuntu - gcc + - build #build-ubuntu-clang: # type: build @@ -50,6 +55,7 @@ build-sles-gcc: tags: - sles - gcc + - build build-osx-clang: type: build @@ -58,3 +64,20 @@ build-osx-clang: tags: - osx - clang + - build + +release-test: + type: deploy + script: + - export CC=gcc + - export CXX=g++ + - export OSPRAY_RELEASE_NO_VERIFY=1 + - scripts/release/linux.sh + tags: + - icc + - release + only: + - jda/release_test + artifacts: + paths: + - build_release/*.gz diff --git a/scripts/release/linux.sh b/scripts/release/linux.sh index 817ea6cfbe..3ae30a65c9 100755 --- a/scripts/release/linux.sh +++ b/scripts/release/linux.sh @@ -46,9 +46,13 @@ export ROOT_DIR=$PWD DEP_LOCATION=http://sdvis.org/~jdamstut/deps TBB_TARBALL=embree-2.9.0.x86_64.linux.tar.gz EMBREE_TARBALL=tbb44_20160413oss_lin.tgz +ISPC_TARBALL=ispc-v1.9.0-linux.tar.gz # set compiler if the user hasn't explicitly set CC and CXX if [ -z $CC ]; then + echo "***NOTE: Defaulting to use icc/icpc!" + echo -n " Please set env variables 'CC' and 'CXX' to" + echo " a different supported compiler (gcc/clang) if desired." export CC=icc export CXX=icpc fi @@ -75,13 +79,20 @@ if [ ! -d deps ]; then tar -xaf $EMBREE_TARBALL rm $EMBREE_TARBALL + # ISPC + wget $DEP_LOCATION/$ISPC_TARBALL + tar -xaf $ISPC_TARBALL + rm $ISPC_TARBALL + cd $ROOT_DIR ln -snf deps/tbb* tbb ln -snf deps/embree* embree + ln -snf deps/ispc* ispc fi TBB_PATH_LOCAL=$ROOT_DIR/tbb export embree_DIR=$ROOT_DIR/embree +export PATH=$ROOT_DIR/ispc:$PATH #### Build OSPRay #### @@ -107,9 +118,14 @@ cmake \ # create RPM files make -j `nproc` preinstall -check_symbols libospray.so GLIBC 2 4 -check_symbols libospray.so GLIBCXX 3 4 -check_symbols libospray.so CXXABI 1 3 +# if we define 'OSPRAY_RELEASE_NO_VERIFY' to anything, then we +# don't verify link dependencies for CentOS6 +if [ -z $OSPRAY_RELEASE_NO_VERIFY ]; then + check_symbols libospray.so GLIBC 2 4 + check_symbols libospray.so GLIBCXX 3 4 + check_symbols libospray.so CXXABI 1 3 +fi + make -j `nproc` package # read OSPRay version From 2f7b3adc08d2877894d266c9745e0bbcfd486a5d Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Thu, 12 May 2016 21:22:29 -0500 Subject: [PATCH 296/310] change gitlab config to build binaries on updates to 'devel' and 'master' --- .gitlab-ci.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 591c377bd3..e15f57d910 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,8 @@ stages: - build - deploy +### BUILD JOBS ### + build-centos6-gcc: type: build script: @@ -66,18 +68,23 @@ build-osx-clang: - clang - build -release-test: +### RELEASE JOBS ### + +release-linux: type: deploy script: - - export CC=gcc - - export CXX=g++ - - export OSPRAY_RELEASE_NO_VERIFY=1 + - module load intel + - export CC=icc + - export CXX=icpc - scripts/release/linux.sh tags: - icc - release only: - - jda/release_test + - devel + - master artifacts: paths: - build_release/*.gz + +#TODO: add OS X and Windows release jobs From b2abae46c02150f9a8a824812e7a6ddaa81e16d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 13 May 2016 12:35:23 +0200 Subject: [PATCH 297/310] Include Windows in GitLab builds --- .gitlab-ci.yml | 24 +++++++++++++++++++++++- scripts/build_gitlab/linux.sh | 22 ++++++++++++++++++++-- scripts/build_gitlab/win.sh | 31 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100755 scripts/build_gitlab/win.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e15f57d910..6cf99d5f05 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,6 +68,14 @@ build-osx-clang: - clang - build +build-windows-msvc: + type: build + script: + - scripts/build_gitlab/win.sh + tags: + - msvc + - build + ### RELEASE JOBS ### release-linux: @@ -87,4 +95,18 @@ release-linux: paths: - build_release/*.gz -#TODO: add OS X and Windows release jobs +release-windows: + type: deploy + script: + - scripts/release/win.sh + tags: + - msvc + - release + only: + - devel + - master + artifacts: + paths: + - build_release/*.gz + +#TODO: add OS X release jobs diff --git a/scripts/build_gitlab/linux.sh b/scripts/build_gitlab/linux.sh index a4bfaefcce..f683b94f53 100755 --- a/scripts/build_gitlab/linux.sh +++ b/scripts/build_gitlab/linux.sh @@ -1,11 +1,29 @@ -#/bin/sh +## ======================================================================== ## +## Copyright 2015-2016 Intel Corporation ## +## ## +## Licensed under the Apache License, Version 2.0 (the "License"); ## +## you may not use this file except in compliance with the License. ## +## You may obtain a copy of the License at ## +## ## +## http://www.apache.org/licenses/LICENSE-2.0 ## +## ## +## Unless required by applicable law or agreed to in writing, software ## +## distributed under the License is distributed on an "AS IS" BASIS, ## +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ## +## See the License for the specific language governing permissions and ## +## limitations under the License. ## +## ======================================================================== ## +#!/bin/sh + +rm -rf build mkdir build cd build -rm -rf * + cmake \ -D OSPRAY_BUILD_ISA=ALL \ -D OSPRAY_APPS_PARTICLEVIEWER=ON \ -D OSPRAY_MODULE_TACHYON=ON \ .. + make -j`nproc` diff --git a/scripts/build_gitlab/win.sh b/scripts/build_gitlab/win.sh new file mode 100755 index 0000000000..4f59dbf8e0 --- /dev/null +++ b/scripts/build_gitlab/win.sh @@ -0,0 +1,31 @@ +## ======================================================================== ## +## Copyright 2015-2016 Intel Corporation ## +## ## +## Licensed under the Apache License, Version 2.0 (the "License"); ## +## you may not use this file except in compliance with the License. ## +## You may obtain a copy of the License at ## +## ## +## http://www.apache.org/licenses/LICENSE-2.0 ## +## ## +## Unless required by applicable law or agreed to in writing, software ## +## distributed under the License is distributed on an "AS IS" BASIS, ## +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ## +## See the License for the specific language governing permissions and ## +## limitations under the License. ## +## ======================================================================== ## + +#!/bin/sh + +rm -rf build +mkdir build +cd build + +cmake -L \ +-G "Visual Studio 12 2013 Win64" \ +-T "Intel C++ Compiler 16.0" \ +-D OSPRAY_BUILD_ISA=ALL \ +-D OSPRAY_BUILD_MIC_SUPPORT=OFF \ +-D USE_IMAGE_MAGICK=OFF \ +.. + +cmake --build . --config Release --target PACKAGE -- -m -nologo From 89af65d7ca6b7b7c3e51978b45b470a7cfb19828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 13 May 2016 13:58:57 +0200 Subject: [PATCH 298/310] Build is already removed by GitLab scripts --- scripts/build_gitlab/linux.sh | 1 - scripts/build_gitlab/win.sh | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/build_gitlab/linux.sh b/scripts/build_gitlab/linux.sh index f683b94f53..86d4d92ed4 100755 --- a/scripts/build_gitlab/linux.sh +++ b/scripts/build_gitlab/linux.sh @@ -16,7 +16,6 @@ #!/bin/sh -rm -rf build mkdir build cd build diff --git a/scripts/build_gitlab/win.sh b/scripts/build_gitlab/win.sh index 4f59dbf8e0..215c4613b4 100755 --- a/scripts/build_gitlab/win.sh +++ b/scripts/build_gitlab/win.sh @@ -16,7 +16,6 @@ #!/bin/sh -rm -rf build mkdir build cd build From c1dee4c4278e65978f385f02c763a17d366a56b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 13 May 2016 13:59:35 +0200 Subject: [PATCH 299/310] Also look for TBB in sibling folder on Windows --- cmake/FindTBB.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake index 2798b867db..4c716ae743 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake @@ -50,6 +50,7 @@ IF (WIN32) HINTS ${TBB_ROOT} PATHS ${PROJECT_SOURCE_DIR}/tbb + ${PROJECT_SOURCE_DIR}/../tbb "${PROGRAMFILES32}/IntelSWTools/compilers_and_libraries/windows/tbb" "${PROGRAMFILES32}/Intel/Composer XE/tbb" "${PROGRAMFILES32}/Intel/compilers_and_libraries/windows/tbb" From 97481efb3a3e3d1f9d180e112eeac62ea268fd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 13 May 2016 14:49:23 +0200 Subject: [PATCH 300/310] Tweaks to scripts --- .gitlab-ci.yml | 3 ++- scripts/build_gitlab/win.sh | 4 +++- scripts/release/linux.sh | 2 +- scripts/release/win.sh | 5 ++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6cf99d5f05..56c4010e1d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -107,6 +107,7 @@ release-windows: - master artifacts: paths: - - build_release/*.gz + - build_release/ospray*.zip + - build_release/ospray*.exe #TODO: add OS X release jobs diff --git a/scripts/build_gitlab/win.sh b/scripts/build_gitlab/win.sh index 215c4613b4..9b5781bd18 100755 --- a/scripts/build_gitlab/win.sh +++ b/scripts/build_gitlab/win.sh @@ -24,7 +24,9 @@ cmake -L \ -T "Intel C++ Compiler 16.0" \ -D OSPRAY_BUILD_ISA=ALL \ -D OSPRAY_BUILD_MIC_SUPPORT=OFF \ +-D OSPRAY_USE_EXTERNAL_EMBREE=ON \ +-D embree_DIR=../../embree/lib/cmake/embree-2.9.0 \ -D USE_IMAGE_MAGICK=OFF \ .. -cmake --build . --config Release --target PACKAGE -- -m -nologo +cmake --build . --config Release --target ALL_BUILD -- -m -nologo diff --git a/scripts/release/linux.sh b/scripts/release/linux.sh index 3ae30a65c9..c37032645b 100755 --- a/scripts/release/linux.sh +++ b/scripts/release/linux.sh @@ -111,7 +111,7 @@ cmake \ -D OSPRAY_USE_EXTERNAL_EMBREE=ON \ -D USE_IMAGE_MAGICK=OFF \ -D OSPRAY_ZIP_MODE=OFF \ --D CMAKE_INSTALL_PREFIX=$ROOT_DIR/install \ +-D CMAKE_INSTALL_PREFIX=/usr \ -D TBB_ROOT=$TBB_PATH_LOCAL \ .. diff --git a/scripts/release/win.sh b/scripts/release/win.sh index 146270c825..0d27a32f42 100755 --- a/scripts/release/win.sh +++ b/scripts/release/win.sh @@ -22,11 +22,8 @@ export LIBRARY_PATH= export LD_LIBRARY_PATH= #TBB_PATH_LOCAL=$PWD/tbb -#rm -rf build_release mkdir -p build_release cd build_release -rm -f CMakeCache.txt -rm -f ospray/version.h # set release settings cmake -L \ @@ -35,6 +32,8 @@ cmake -L \ -D OSPRAY_ZIP_MODE=OFF \ -D OSPRAY_BUILD_ISA=ALL \ -D OSPRAY_BUILD_MIC_SUPPORT=OFF \ +-D OSPRAY_USE_EXTERNAL_EMBREE=ON \ +-D embree_DIR=../../embree/lib/cmake/embree-2.9.0 \ -D USE_IMAGE_MAGICK=OFF \ -D CMAKE_INSTALL_INCLUDEDIR=include \ -D CMAKE_INSTALL_LIBDIR=lib \ From 72cc03def6dd8d3c8b24da11d6fe6fb5ecc7744f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 13 May 2016 15:38:28 +0200 Subject: [PATCH 301/310] Fix Windows build: "constexpr" is not supported --- ospray/common/tasking/TaskingTypeTraits.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ospray/common/tasking/TaskingTypeTraits.h b/ospray/common/tasking/TaskingTypeTraits.h index fcb0ad24c0..026cd57f37 100644 --- a/ospray/common/tasking/TaskingTypeTraits.h +++ b/ospray/common/tasking/TaskingTypeTraits.h @@ -35,7 +35,7 @@ struct has_operator_method static std::false_type test(...); using type = decltype(test(nullptr)); - static constexpr bool value = std::is_same::value; + static const bool value = std::is_same::value; }; //NOTE(jda) - This checks at compile time if T implements the method @@ -59,7 +59,7 @@ struct has_operator_method_with_integral_param using PARAM_IS_SIZET = std::is_same; - static constexpr bool value = has_operator_method::value && + static const bool value = has_operator_method::value && (PARAM_IS_SHORT::value || PARAM_IS_INT::value || PARAM_IS_UNSIGNED::value From 1069e05f53b5ed5dfe5ec7847905465ecdaf8a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 13 May 2016 16:06:38 +0200 Subject: [PATCH 302/310] Tweaks to release scripts --- .gitlab-ci.yml | 22 +++++++++++++++++---- scripts/build_gitlab/win.bat | 37 ++++++++++++++++++++++++++++++++++++ scripts/release/win.bat | 4 ++-- 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100755 scripts/build_gitlab/win.bat diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 56c4010e1d..862ef3ef87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,7 +71,7 @@ build-osx-clang: build-windows-msvc: type: build script: - - scripts/build_gitlab/win.sh + - call scripts\build_gitlab\win.bat tags: - msvc - build @@ -79,6 +79,20 @@ build-windows-msvc: ### RELEASE JOBS ### release-linux: + type: deploy + script: + - scripts/release/linux.sh + tags: + - gcc + - release + only: + - devel + - master + artifacts: + paths: + - build_release/*.gz + +release-linux-icc: type: deploy script: - module load intel @@ -98,7 +112,7 @@ release-linux: release-windows: type: deploy script: - - scripts/release/win.sh + - call scripts\release\win.bat tags: - msvc - release @@ -107,7 +121,7 @@ release-windows: - master artifacts: paths: - - build_release/ospray*.zip - - build_release/ospray*.exe + - build_release\ospray*.zip + - build_release\ospray*.exe #TODO: add OS X release jobs diff --git a/scripts/build_gitlab/win.bat b/scripts/build_gitlab/win.bat new file mode 100755 index 0000000000..e7ccf0a98b --- /dev/null +++ b/scripts/build_gitlab/win.bat @@ -0,0 +1,37 @@ +@echo off +rem ======================================================================== rem +rem Copyright 2015-2016 Intel Corporation rem +rem rem +rem Licensed under the Apache License, Version 2.0 (the "License"); rem +rem you may not use this file except in compliance with the License. rem +rem You may obtain a copy of the License at rem +rem rem +rem http://www.apache.org/licenses/LICENSE-2.0 rem +rem rem +rem Unless required by applicable law or agreed to in writing, software rem +rem distributed under the License is distributed on an "AS IS" BASIS, rem +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem +rem See the License for the specific language governing permissions and rem +rem limitations under the License. rem +rem ======================================================================== rem + +setlocal + +md build +cd build + +cmake -L ^ +-G "Visual Studio 12 2013 Win64" ^ +-T "Intel C++ Compiler 16.0" ^ +-D OSPRAY_BUILD_ISA=ALL ^ +-D OSPRAY_BUILD_MIC_SUPPORT=OFF ^ +-D OSPRAY_USE_EXTERNAL_EMBREE=ON ^ +-D embree_DIR=..\..\embree\lib\cmake\embree-2.9.0 ^ +-D USE_IMAGE_MAGICK=OFF ^ +.. + +cmake --build . --config Release --target ALL_BUILD -- /m /nologo + +:abort +endlocal +:end diff --git a/scripts/release/win.bat b/scripts/release/win.bat index a4931bdc31..b729ee414e 100755 --- a/scripts/release/win.bat +++ b/scripts/release/win.bat @@ -20,8 +20,6 @@ rem set TBB_PATH_LOCAL=%cd%\tbb md build_release cd build_release -del CMakeCache.txt -del ospray\version.h rem set release settings cmake -L ^ @@ -30,6 +28,8 @@ cmake -L ^ -D OSPRAY_ZIP_MODE=OFF ^ -D OSPRAY_BUILD_ISA=ALL ^ -D OSPRAY_BUILD_MIC_SUPPORT=OFF ^ +-D OSPRAY_USE_EXTERNAL_EMBREE=ON ^ +-D embree_DIR=..\..\embree\lib\cmake\embree-2.9.0 ^ -D USE_IMAGE_MAGICK=OFF ^ -D CMAKE_INSTALL_INCLUDEDIR=include ^ -D CMAKE_INSTALL_LIBDIR=lib ^ From 3762287e70f1abc2b3b1d3fc42f2ffa86f9cd054 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 10:13:38 -0500 Subject: [PATCH 303/310] tweak to gitlab config --- .gitlab-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 862ef3ef87..2675cc99d8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -78,9 +78,12 @@ build-windows-msvc: ### RELEASE JOBS ### -release-linux: +release-linux-gcc: type: deploy script: + - module load gcc + - export CC=gcc + - export CXX=g++ - scripts/release/linux.sh tags: - gcc From 3f29395ebe241bd6ee8f39bcaef09f45a8be6c9f Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 10:27:18 -0500 Subject: [PATCH 304/310] don't verify linking behavior for gcc releases (can't use CentOS6 defaults) --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2675cc99d8..28ba26dd79 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -84,6 +84,7 @@ release-linux-gcc: - module load gcc - export CC=gcc - export CXX=g++ + - export OSPRAY_RELEASE_NO_VERIFY=1 - scripts/release/linux.sh tags: - gcc From 2086806b5e7e4cdd78e7e085cb91a229132f4d1d Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 10:38:44 -0500 Subject: [PATCH 305/310] another tweak to release script --- scripts/release/linux.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/release/linux.sh b/scripts/release/linux.sh index c37032645b..23dbb7375c 100755 --- a/scripts/release/linux.sh +++ b/scripts/release/linux.sh @@ -58,9 +58,13 @@ if [ -z $CC ]; then fi # to make sure we do not include nor link against wrong TBB -unset CPATH -unset LIBRARY_PATH -unset LD_LIBRARY_PATH +# NOTE: if we are not verifying CentOS6 defaults, we are likely using +# a different compiler which requires LD_LIBRARY_PATH! +if [ -n $OSPRAY_RELEASE_NO_VERIFY ]; then + unset CPATH + unset LIBRARY_PATH + unset LD_LIBRARY_PATH +fi #### Fetch dependencies (TBB+Embree) #### From eb6682cb5fb40d0876e571dbe3584d20eeb25882 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 13:13:25 -0500 Subject: [PATCH 306/310] disable release-linux-gcc, tweak macosx release script to mirror linux --- .gitlab-ci.yml | 47 +++++++++++++++++-------- scripts/release/linux.sh | 4 +-- scripts/release/macosx.sh | 72 ++++++++++++++++++++++++++++++++------- 3 files changed, 95 insertions(+), 28 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 28ba26dd79..abd331c902 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -75,20 +75,40 @@ build-windows-msvc: tags: - msvc - build + - win7 ### RELEASE JOBS ### -release-linux-gcc: +#release-linux-gcc: +# type: deploy +# script: +# - module load gcc +# - export CC=gcc +# - export CXX=g++ +# - export OSPRAY_RELEASE_NO_VERIFY=1 +# - scripts/release/linux.sh +# tags: +# - gcc +# - release +# - centos6 +# only: +# - devel +# - master +# artifacts: +# paths: +# - build_release/*.gz + +release-linux-icc: type: deploy script: - - module load gcc - - export CC=gcc - - export CXX=g++ - - export OSPRAY_RELEASE_NO_VERIFY=1 + - module load intel + - export CC=icc + - export CXX=icpc - scripts/release/linux.sh tags: - - gcc + - icc - release + - centos6 only: - devel - master @@ -96,16 +116,16 @@ release-linux-gcc: paths: - build_release/*.gz -release-linux-icc: +release-osx-clang: type: deploy script: - - module load intel - - export CC=icc - - export CXX=icpc - - scripts/release/linux.sh + - export CC=clang + - export CXX=clang++ + - scripts/release/macosx.sh tags: - - icc + - clang - release + - osx only: - devel - master @@ -120,6 +140,7 @@ release-windows: tags: - msvc - release + - win7 only: - devel - master @@ -127,5 +148,3 @@ release-windows: paths: - build_release\ospray*.zip - build_release\ospray*.exe - -#TODO: add OS X release jobs diff --git a/scripts/release/linux.sh b/scripts/release/linux.sh index 23dbb7375c..60232a5cbe 100755 --- a/scripts/release/linux.sh +++ b/scripts/release/linux.sh @@ -43,7 +43,7 @@ function check_symbols export ROOT_DIR=$PWD -DEP_LOCATION=http://sdvis.org/~jdamstut/deps +DEP_LOCATION=http://sdvis.org/~jdamstut/ospray_deps/linux TBB_TARBALL=embree-2.9.0.x86_64.linux.tar.gz EMBREE_TARBALL=tbb44_20160413oss_lin.tgz ISPC_TARBALL=ispc-v1.9.0-linux.tar.gz @@ -66,7 +66,7 @@ if [ -n $OSPRAY_RELEASE_NO_VERIFY ]; then unset LD_LIBRARY_PATH fi -#### Fetch dependencies (TBB+Embree) #### +#### Fetch dependencies (TBB+Embree+ISPC) #### if [ ! -d deps ]; then mkdir deps diff --git a/scripts/release/macosx.sh b/scripts/release/macosx.sh index 65779b9606..5cca1cdd90 100755 --- a/scripts/release/macosx.sh +++ b/scripts/release/macosx.sh @@ -16,11 +16,7 @@ #!/bin/bash -# to make sure we do not include nor link against wrong TBB -export CPATH= -export LIBRARY_PATH= -export DYLD_LIBRARY_PATH= -TBB_PATH_LOCAL=$PWD/tbb +#### Helper functions #### umask=`umask` function onexit { @@ -29,6 +25,62 @@ function onexit { trap onexit EXIT umask 002 +#### Set variables for script #### + +export ROOT_DIR=$PWD + +DEP_LOCATION=http://sdvis.org/~jdamstut/ospray_deps/osx +TBB_TARBALL=embree-2.9.0.x86_64.osx.tar.gz +EMBREE_TARBALL=tbb44_20160413oss_osx.tgz +ISPC_TARBALL=ispc-v1.9.0-osx.tar.gz + +# set compiler if the user hasn't explicitly set CC and CXX +if [ -z $CC ]; then + echo "***NOTE: Defaulting to use clang!" + echo -n " Please set env variables 'CC' and 'CXX' to" + echo " a different supported compiler (gcc/icc) if desired." + export CC=clang + export CXX=clang++ +fi + +# to make sure we do not include nor link against wrong TBB +export CPATH= +export LIBRARY_PATH= +export DYLD_LIBRARY_PATH= +TBB_PATH_LOCAL=$PWD/tbb + +#### Fetch dependencies (TBB+Embree+ISPC) #### + +if [ ! -d deps ]; then + mkdir deps + rm -rf deps/* + cd deps + + # TBB + wget $DEP_LOCATION/$TBB_TARBALL + tar -xaf $TBB_TARBALL + rm $TBB_TARBALL + + # Embree + wget $DEP_LOCATION/$EMBREE_TARBALL + tar -xaf $EMBREE_TARBALL + rm $EMBREE_TARBALL + + # ISPC + wget $DEP_LOCATION/$ISPC_TARBALL + tar -xaf $ISPC_TARBALL + rm $ISPC_TARBALL + + cd $ROOT_DIR + ln -snf deps/tbb* tbb + ln -snf deps/embree* embree + ln -snf deps/ispc* ispc +fi + +TBB_PATH_LOCAL=$ROOT_DIR/tbb +export embree_DIR=$ROOT_DIR/embree +export PATH=$ROOT_DIR/ispc:$PATH + mkdir -p build_release cd build_release # make sure to use default settings @@ -37,12 +89,10 @@ rm -f ospray/version.h # set release and installer settings cmake \ --D CMAKE_C_COMPILER:FILEPATH=icc \ --D CMAKE_CXX_COMPILER:FILEPATH=icpc \ -D OSPRAY_BUILD_ISA=ALL \ --D OSPRAY_BUILD_MIC_SUPPORT=ON \ --D OSPRAY_BUILD_COI_DEVICE=ON \ --D OSPRAY_BUILD_MPI_DEVICE=ON \ +-D OSPRAY_BUILD_MIC_SUPPORT=OFF \ +-D OSPRAY_BUILD_COI_DEVICE=OFF \ +-D OSPRAY_BUILD_MPI_DEVICE=OFF \ -D USE_IMAGE_MAGICK=OFF \ -D OSPRAY_ZIP_MODE=OFF \ -D CMAKE_INSTALL_PREFIX=/opt/local \ @@ -51,7 +101,6 @@ cmake \ -D CMAKE_INSTALL_DOCDIR=../../Applications/OSPRay/doc \ -D CMAKE_INSTALL_BINDIR=../../Applications/OSPRay/bin \ .. -#-D TBB_ROOT=/opt/local \ # create installers make -j 4 package @@ -69,4 +118,3 @@ cmake \ # create ZIP files make -j 4 package -cd .. From 6c8c8da1d550c3c9db266e3786afd998b5e0a0c6 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 13:19:14 -0500 Subject: [PATCH 307/310] fix release script typos --- scripts/release/linux.sh | 16 ++++++++-------- scripts/release/macosx.sh | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/scripts/release/linux.sh b/scripts/release/linux.sh index 60232a5cbe..7e9440c6ca 100755 --- a/scripts/release/linux.sh +++ b/scripts/release/linux.sh @@ -44,9 +44,9 @@ function check_symbols export ROOT_DIR=$PWD DEP_LOCATION=http://sdvis.org/~jdamstut/ospray_deps/linux -TBB_TARBALL=embree-2.9.0.x86_64.linux.tar.gz -EMBREE_TARBALL=tbb44_20160413oss_lin.tgz +EMBREE_TARBALL=embree-2.9.0.x86_64.linux.tar.gz ISPC_TARBALL=ispc-v1.9.0-linux.tar.gz +TBB_TARBALL=tbb44_20160413oss_lin.tgz # set compiler if the user hasn't explicitly set CC and CXX if [ -z $CC ]; then @@ -73,11 +73,6 @@ if [ ! -d deps ]; then rm -rf deps/* cd deps - # TBB - wget $DEP_LOCATION/$TBB_TARBALL - tar -xaf $TBB_TARBALL - rm $TBB_TARBALL - # Embree wget $DEP_LOCATION/$EMBREE_TARBALL tar -xaf $EMBREE_TARBALL @@ -88,10 +83,15 @@ if [ ! -d deps ]; then tar -xaf $ISPC_TARBALL rm $ISPC_TARBALL + # TBB + wget $DEP_LOCATION/$TBB_TARBALL + tar -xaf $TBB_TARBALL + rm $TBB_TARBALL + cd $ROOT_DIR - ln -snf deps/tbb* tbb ln -snf deps/embree* embree ln -snf deps/ispc* ispc + ln -snf deps/tbb* tbb fi TBB_PATH_LOCAL=$ROOT_DIR/tbb diff --git a/scripts/release/macosx.sh b/scripts/release/macosx.sh index 5cca1cdd90..66822c8e53 100755 --- a/scripts/release/macosx.sh +++ b/scripts/release/macosx.sh @@ -30,9 +30,9 @@ umask 002 export ROOT_DIR=$PWD DEP_LOCATION=http://sdvis.org/~jdamstut/ospray_deps/osx -TBB_TARBALL=embree-2.9.0.x86_64.osx.tar.gz -EMBREE_TARBALL=tbb44_20160413oss_osx.tgz +EMBREE_TARBALL=embree-2.9.0.x86_64.macosx.tar.gz ISPC_TARBALL=ispc-v1.9.0-osx.tar.gz +TBB_TARBALL=tbb44_20160413oss_osx.tgz # set compiler if the user hasn't explicitly set CC and CXX if [ -z $CC ]; then @@ -56,11 +56,6 @@ if [ ! -d deps ]; then rm -rf deps/* cd deps - # TBB - wget $DEP_LOCATION/$TBB_TARBALL - tar -xaf $TBB_TARBALL - rm $TBB_TARBALL - # Embree wget $DEP_LOCATION/$EMBREE_TARBALL tar -xaf $EMBREE_TARBALL @@ -71,10 +66,15 @@ if [ ! -d deps ]; then tar -xaf $ISPC_TARBALL rm $ISPC_TARBALL + # TBB + wget $DEP_LOCATION/$TBB_TARBALL + tar -xaf $TBB_TARBALL + rm $TBB_TARBALL + cd $ROOT_DIR - ln -snf deps/tbb* tbb ln -snf deps/embree* embree ln -snf deps/ispc* ispc + ln -snf deps/tbb* tbb fi TBB_PATH_LOCAL=$ROOT_DIR/tbb From cb9635609a177cfc3adbc69e132aa62dcaa9c74c Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 13:30:41 -0500 Subject: [PATCH 308/310] bug fixes to macosx release script --- scripts/release/macosx.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/release/macosx.sh b/scripts/release/macosx.sh index 66822c8e53..65a2359239 100755 --- a/scripts/release/macosx.sh +++ b/scripts/release/macosx.sh @@ -58,17 +58,17 @@ if [ ! -d deps ]; then # Embree wget $DEP_LOCATION/$EMBREE_TARBALL - tar -xaf $EMBREE_TARBALL + tar -xf $EMBREE_TARBALL rm $EMBREE_TARBALL # ISPC wget $DEP_LOCATION/$ISPC_TARBALL - tar -xaf $ISPC_TARBALL + tar -xf $ISPC_TARBALL rm $ISPC_TARBALL # TBB wget $DEP_LOCATION/$TBB_TARBALL - tar -xaf $TBB_TARBALL + tar -xf $TBB_TARBALL rm $TBB_TARBALL cd $ROOT_DIR @@ -81,11 +81,13 @@ TBB_PATH_LOCAL=$ROOT_DIR/tbb export embree_DIR=$ROOT_DIR/embree export PATH=$ROOT_DIR/ispc:$PATH +#### Build OSPRay #### + mkdir -p build_release cd build_release -# make sure to use default settings -rm -f CMakeCache.txt -rm -f ospray/version.h + +# Clean out build directory to be sure we are doing a fresh build +rm -rf * # set release and installer settings cmake \ @@ -100,6 +102,7 @@ cmake \ -D CMAKE_INSTALL_LIBDIR=lib \ -D CMAKE_INSTALL_DOCDIR=../../Applications/OSPRay/doc \ -D CMAKE_INSTALL_BINDIR=../../Applications/OSPRay/bin \ +-D TBB_ROOT=$TBB_PATH_LOCAL \ .. # create installers From 59b3c707a72463485fd611357ef17ee627f41f42 Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 13:37:44 -0500 Subject: [PATCH 309/310] update osx build script to use hardcoded -j value (alias doesn't work) [ci skip] --- scripts/build_gitlab/osx.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/build_gitlab/osx.sh b/scripts/build_gitlab/osx.sh index d1b7d496b6..8881e493d3 100755 --- a/scripts/build_gitlab/osx.sh +++ b/scripts/build_gitlab/osx.sh @@ -1,7 +1,5 @@ #/bin/sh -alias nproc='sysctrl -n hw.ncpu' - mkdir build cd build rm -rf * @@ -11,4 +9,4 @@ cmake \ -D OSPRAY_TASKING_SYSTEM=Internal \ .. -make -j`nproc` +make -j 4 From 4d69c6172b04677c1487a4e1e26ec86476e7525f Mon Sep 17 00:00:00 2001 From: Jefferson Amstutz Date: Fri, 13 May 2016 13:49:59 -0500 Subject: [PATCH 310/310] add dmg package to gitlab artifacts on macosx deploy stage [ci skip] --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index abd331c902..92ca363043 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -132,6 +132,7 @@ release-osx-clang: artifacts: paths: - build_release/*.gz + - build_release/*.dmg release-windows: type: deploy