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 +}