From bf1b4ec2bbdf052444cbd5608dd60ec03bb09437 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 17:30:04 +0100 Subject: [PATCH 1/6] add ComputeDispatch class revoke glDispatch in PCProgram::useProgram update example --- .../osgcomputeshaders/osgcomputeshaders.cpp | 6 +-- include/osg/ComputeDispatch | 48 +++++++++++++++++++ src/osg/CMakeLists.txt | 2 + src/osg/ComputeDispatch.cpp | 12 +++++ src/osg/Program.cpp | 4 -- .../serializers/osg/ComputeDispatch.cpp | 36 ++++++++++++++ 6 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 include/osg/ComputeDispatch create mode 100644 src/osg/ComputeDispatch.cpp create mode 100644 src/osgWrappers/serializers/osg/ComputeDispatch.cpp diff --git a/examples/osgcomputeshaders/osgcomputeshaders.cpp b/examples/osgcomputeshaders/osgcomputeshaders.cpp index 87073cfe5..7d87a7472 100644 --- a/examples/osgcomputeshaders/osgcomputeshaders.cpp +++ b/examples/osgcomputeshaders/osgcomputeshaders.cpp @@ -20,7 +20,7 @@ // This example can work only if GL version is 4.3 or greater #include -#include +#include #include #include #include @@ -57,14 +57,12 @@ int main( int argc, char** argv ) // The compute shader can't work with other kinds of shaders // It also requires the work group numbers. Setting them to 0 will disable the compute shader osg::ref_ptr computeProg = new osg::Program; - computeProg->setComputeGroups( 512/16, 512/16, 1 ); computeProg->addShader( new osg::Shader(osg::Shader::COMPUTE, computeSrc) ); // Create a node for outputting to the texture. // It is OK to have just an empty node here, but seems inbuilt uniforms like osg_FrameTime won't work then. // TODO: maybe we can have a custom drawable which also will implement glMemoryBarrier? - osg::ref_ptr sourceNode = osgDB::readRefNodeFile("axes.osgt"); - if ( !sourceNode ) sourceNode = new osg::Node; + osg::ref_ptr sourceNode = new osg::ComputeDispatch(512/16, 512/16, 1 ); sourceNode->setDataVariance( osg::Object::DYNAMIC ); sourceNode->getOrCreateStateSet()->setAttributeAndModes( computeProg.get() ); sourceNode->getOrCreateStateSet()->addUniform( new osg::Uniform("targetTex", (int)0) ); diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch new file mode 100644 index 000000000..605011060 --- /dev/null +++ b/include/osg/ComputeDispatch @@ -0,0 +1,48 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield + * Copyright (C) 2017 Julien Valentin + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_COMPUTEDISPATCH +#define OSG_COMPUTEDISPATCH 1 + +#include + +#include + +namespace osg{ + class OSG_EXPORT ComputeDispatch : public osg::Drawable + { + public: + ComputeDispatch(GLint numGroupsX=0, GLint numGroupsY=0, GLint numGroupsZ=0 ): + Drawable(), + _numGroupsX(numGroupsX), + _numGroupsY(numGroupsY), + _numGroupsZ(numGroupsZ) + {} + + ComputeDispatch(const ComputeDispatch&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Node(osg, ComputeDispatch); + + + virtual void drawImplementation(RenderInfo& renderInfo) const; + /** Set/get compute shader work groups */ + void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX,_numGroupsY=numGroupsY, _numGroupsZ=numGroupsZ; } + void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const{ numGroupsX=_numGroupsX; numGroupsY=_numGroupsY; numGroupsZ=_numGroupsZ; } + protected: + GLint _numGroupsX, _numGroupsY, _numGroupsZ; + + }; +} +#endif + diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 845306551..5fc119403 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -55,6 +55,7 @@ SET(TARGET_H ${HEADER_PATH}/ColorMaski ${HEADER_PATH}/ColorMatrix ${HEADER_PATH}/ComputeBoundsVisitor + ${HEADER_PATH}/ComputeDispatch ${HEADER_PATH}/ContextData ${HEADER_PATH}/ConvexPlanarOccluder ${HEADER_PATH}/ConvexPlanarPolygon @@ -267,6 +268,7 @@ SET(TARGET_SRC ColorMaski.cpp ColorMatrix.cpp ComputeBoundsVisitor.cpp + ComputeDispatch.cpp ContextData.cpp ConvexPlanarOccluder.cpp ConvexPlanarPolygon.cpp diff --git a/src/osg/ComputeDispatch.cpp b/src/osg/ComputeDispatch.cpp new file mode 100644 index 000000000..75791b68f --- /dev/null +++ b/src/osg/ComputeDispatch.cpp @@ -0,0 +1,12 @@ +#include +using namespace osg; + + +ComputeDispatch::ComputeDispatch(const ComputeDispatch&o,const osg::CopyOp& copyop): Drawable(o,copyop), _numGroupsX(o._numGroupsX), _numGroupsY(o._numGroupsY), _numGroupsZ(o._numGroupsZ) +{ + +} + +void ComputeDispatch::drawImplementation(RenderInfo& renderInfo) const{ + renderInfo.getState()->get()->glDispatchCompute(_numGroupsX, _numGroupsY, _numGroupsZ); +} diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 68fadaf0c..f42fe3826 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -1108,8 +1108,4 @@ Program::ProgramBinary* Program::PerContextProgram::compileProgramBinary(osg::St void Program::PerContextProgram::useProgram() const { _extensions->glUseProgram( _glProgramHandle ); - if ( _program->_numGroupsX>0 && _program->_numGroupsY>0 && _program->_numGroupsZ>0 ) - { - _extensions->glDispatchCompute( _program->_numGroupsX, _program->_numGroupsY, _program->_numGroupsZ ); - } } diff --git a/src/osgWrappers/serializers/osg/ComputeDispatch.cpp b/src/osgWrappers/serializers/osg/ComputeDispatch.cpp new file mode 100644 index 000000000..d77533a5d --- /dev/null +++ b/src/osgWrappers/serializers/osg/ComputeDispatch.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +// _numGroupsX/Y/Z +static bool checkComputeGroups( const osg::ComputeDispatch& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + attr.getComputeGroups( numX, numY, numZ ); + return numX>0 && numY>0 && numZ>0; +} + +static bool readComputeGroups( osgDB::InputStream& is, osg::ComputeDispatch& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + is >> numX >> numY >> numZ; + attr.setComputeGroups( numX, numY, numZ ); + return true; +} + +static bool writeComputeGroups( osgDB::OutputStream& os, const osg::ComputeDispatch& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + attr.getComputeGroups( numX, numY, numZ ); + os << numX << numY << numZ << std::endl; + return true; +} + +REGISTER_OBJECT_WRAPPER( ComputeDispatch, + new osg::ComputeDispatch, + osg::ComputeDispatch, + "osg::Object osg::Node osg::Drawable osg::ComputeDispatch" ) +{ + ADD_USER_SERIALIZER( ComputeGroups ); // _numGroupsX/Y/Z +} From 195df4f811d774286644ccda58c202fb5a8f7b3d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 17:39:32 +0100 Subject: [PATCH 2/6] numgroup removed but introduce a reto compatibility bug in Program serializer hope nobody use it --- include/osg/Program | 10 ------- src/osg/Program.cpp | 30 +-------------------- src/osgWrappers/serializers/osg/Program.cpp | 28 ------------------- 3 files changed, 1 insertion(+), 67 deletions(-) diff --git a/include/osg/Program b/include/osg/Program index 36aa7ed2f..e9e26829f 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -103,10 +103,6 @@ class OSG_EXPORT Program : public osg::StateAttribute void setParameter( GLenum pname, GLint value ); GLint getParameter( GLenum pname ) const; - /** Set/get compute shader work groups */ - void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ); - void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const; - /** Add an attribute location binding. */ void addBindAttribLocation( const std::string& name, GLuint index ); @@ -439,12 +435,6 @@ class OSG_EXPORT Program : public osg::StateAttribute GLint _geometryInputType; GLint _geometryOutputType; - - /** Parameter maintained with glDispatchCompute */ - GLint _numGroupsX; - GLint _numGroupsY; - GLint _numGroupsZ; - /**TransformFeedBack**/ GLenum _feedbackmode; std::vector _feedbackout; diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index f42fe3826..b41d27b81 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -92,8 +92,7 @@ void Program::ProgramBinary::assign(unsigned int size, const unsigned char* data Program::Program() : _geometryVerticesOut(1), _geometryInputType(GL_TRIANGLES), - _geometryOutputType(GL_TRIANGLE_STRIP), - _numGroupsX(0), _numGroupsY(0), _numGroupsZ(0), _feedbackmode(GL_SEPARATE_ATTRIBS) + _geometryOutputType(GL_TRIANGLE_STRIP), _feedbackmode(GL_SEPARATE_ATTRIBS) { } @@ -133,10 +132,6 @@ Program::Program(const Program& rhs, const osg::CopyOp& copyop): _geometryInputType = rhs._geometryInputType; _geometryOutputType = rhs._geometryOutputType; - _numGroupsX = rhs._numGroupsX; - _numGroupsY = rhs._numGroupsY; - _numGroupsZ = rhs._numGroupsZ; - _feedbackmode=rhs._feedbackmode; _feedbackout=rhs._feedbackout; } @@ -173,15 +168,6 @@ int Program::compare(const osg::StateAttribute& sa) const if( _geometryOutputType < rhs._geometryOutputType ) return -1; if( rhs._geometryOutputType < _geometryOutputType ) return 1; - if( _numGroupsX < rhs._numGroupsX ) return -1; - if( rhs._numGroupsX < _numGroupsX ) return 1; - - if( _numGroupsY < rhs._numGroupsY ) return -1; - if( rhs._numGroupsY < _numGroupsY ) return 1; - - if( _numGroupsZ < rhs._numGroupsZ ) return -1; - if( rhs._numGroupsZ < _numGroupsZ ) return 1; - if(_feedbackout0 && numY>0 && numZ>0; -} - -static bool readComputeGroups( osgDB::InputStream& is, osg::Program& attr ) -{ - GLint numX = 0, numY = 0, numZ = 0; - is >> numX >> numY >> numZ; - attr.setComputeGroups( numX, numY, numZ ); - return true; -} - -static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& attr ) -{ - GLint numX = 0, numY = 0, numZ = 0; - attr.getComputeGroups( numX, numY, numZ ); - os << numX << numY << numZ << std::endl; - return true; -} static bool checkBindUniformBlock( const osg::Program& node ) { @@ -190,11 +167,6 @@ REGISTER_OBJECT_WRAPPER( Program, ADD_USER_SERIALIZER( GeometryInputType ); // _geometryInputType ADD_USER_SERIALIZER( GeometryOutputType ); // _geometryOutputType - { - UPDATE_TO_VERSION_SCOPED( 95 ) - ADD_USER_SERIALIZER( ComputeGroups ); // _numGroupsX/Y/Z - } - { UPDATE_TO_VERSION_SCOPED( 116 ) ADD_USER_SERIALIZER( FeedBackVaryingsName ); From 994c38c0c77d16f7403298a615fa4742dd38500d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 20:03:40 +0100 Subject: [PATCH 3/6] adapt SSBO example for ComputeDispatch but have strange runtime errors: 0(100) : error C7623: implicit narrowing of type from "vec3" to "float" 0(108) : error C7623: implicit narrowing of type from "vec3" to "float" --- examples/osgSSBO/osgSSBO.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index 637f466bc..5ce2ec07c 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -167,6 +167,7 @@ class ComputeNode : public osg::PositionAttitudeTransform public: + osg::ref_ptr _computeDispatch; osg::ref_ptr _computeProgram; osg::ref_ptr _computeShader; //compute and write position data in SSBO @@ -204,6 +205,8 @@ public: _vertexShaderSourcePath = "shaders/osgssboVertexShader.vs"; _geometryShaderSourcePath = "shaders/osgssboGeometryShader.gs"; _fragmentShaderSourcePath = "shaders/osgssboFragmentShader.fs"; + _computeDispatch=new osg::ComputeDispatch(); + addChild(_computeDispatch); } }; @@ -622,7 +625,7 @@ void ComputeNode::initComputingSetup() { _computeProgram = new osg::Program; - _computeProgram->setComputeGroups((NUM_ELEMENTS_X / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_X / WORK_GROUP_SIZE), (NUM_ELEMENTS_Y / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_Y / WORK_GROUP_SIZE), 1); + _computeDispatch->setComputeGroups((NUM_ELEMENTS_X / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_X / WORK_GROUP_SIZE), (NUM_ELEMENTS_Y / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_Y / WORK_GROUP_SIZE), 1); _computeShader = osgDB::readRefShaderFile(osg::Shader::COMPUTE, _computeShaderSourcePath); _computeProgram->addShader(_computeShader.get()); From 739303b3d968811fac206123e5f1707ca0861218 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 20:31:09 +0100 Subject: [PATCH 4/6] override compile and createVAS in order to do nothing --- include/osg/ComputeDispatch | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch index 605011060..2a3725bc1 100644 --- a/include/osg/ComputeDispatch +++ b/include/osg/ComputeDispatch @@ -34,11 +34,16 @@ namespace osg{ META_Node(osg, ComputeDispatch); + virtual void compileGLObjects(RenderInfo& renderInfo) const {return;} + + virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const { return 0; } virtual void drawImplementation(RenderInfo& renderInfo) const; + /** Set/get compute shader work groups */ void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX,_numGroupsY=numGroupsY, _numGroupsZ=numGroupsZ; } void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const{ numGroupsX=_numGroupsX; numGroupsY=_numGroupsY; numGroupsZ=_numGroupsZ; } + protected: GLint _numGroupsX, _numGroupsY, _numGroupsZ; From 021dca0072c2372ee8b09a707b8ec0db727e2ade Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Wed, 29 Nov 2017 08:14:44 +0000 Subject: [PATCH 5/6] Cleaned up code layout --- include/osg/ComputeDispatch | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch index 2a3725bc1..411d8de32 100644 --- a/include/osg/ComputeDispatch +++ b/include/osg/ComputeDispatch @@ -23,7 +23,7 @@ namespace osg{ class OSG_EXPORT ComputeDispatch : public osg::Drawable { public: - ComputeDispatch(GLint numGroupsX=0, GLint numGroupsY=0, GLint numGroupsZ=0 ): + ComputeDispatch(GLint numGroupsX=0, GLint numGroupsY=0, GLint numGroupsZ=0): Drawable(), _numGroupsX(numGroupsX), _numGroupsY(numGroupsY), @@ -34,14 +34,16 @@ namespace osg{ META_Node(osg, ComputeDispatch); - virtual void compileGLObjects(RenderInfo& renderInfo) const {return;} + virtual void compileGLObjects(RenderInfo& renderInfo) const {} virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const { return 0; } virtual void drawImplementation(RenderInfo& renderInfo) const; - /** Set/get compute shader work groups */ - void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX,_numGroupsY=numGroupsY, _numGroupsZ=numGroupsZ; } + /** Set compute shader work groups */ + void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX; _numGroupsY=numGroupsY; _numGroupsZ=numGroupsZ; } + + /** Get compute shader work groups */ void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const{ numGroupsX=_numGroupsX; numGroupsY=_numGroupsY; numGroupsZ=_numGroupsZ; } protected: From cd0744ddfa9025cc0721b03b205b997969a9d079 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Wed, 29 Nov 2017 08:16:53 +0000 Subject: [PATCH 6/6] Cleaned up code layout --- src/osg/ComputeDispatch.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/osg/ComputeDispatch.cpp b/src/osg/ComputeDispatch.cpp index 75791b68f..c689bd95b 100644 --- a/src/osg/ComputeDispatch.cpp +++ b/src/osg/ComputeDispatch.cpp @@ -1,12 +1,16 @@ #include + using namespace osg; - -ComputeDispatch::ComputeDispatch(const ComputeDispatch&o,const osg::CopyOp& copyop): Drawable(o,copyop), _numGroupsX(o._numGroupsX), _numGroupsY(o._numGroupsY), _numGroupsZ(o._numGroupsZ) +ComputeDispatch::ComputeDispatch(const ComputeDispatch&o,const osg::CopyOp& copyop): + Drawable(o,copyop), + _numGroupsX(o._numGroupsX), + _numGroupsY(o._numGroupsY), + _numGroupsZ(o._numGroupsZ) { - } -void ComputeDispatch::drawImplementation(RenderInfo& renderInfo) const{ +void ComputeDispatch::drawImplementation(RenderInfo& renderInfo) const +{ renderInfo.getState()->get()->glDispatchCompute(_numGroupsX, _numGroupsY, _numGroupsZ); }