add ComputeDispatch class

revoke glDispatch in PCProgram::useProgram
update example
This commit is contained in:
Julien Valentin 2017-11-28 17:30:04 +01:00
parent 117045170d
commit bf1b4ec2bb
6 changed files with 100 additions and 8 deletions

View File

@ -20,7 +20,7 @@
// This example can work only if GL version is 4.3 or greater
#include <osg/Texture2D>
#include <osg/Geometry>
#include <osg/ComputeDispatch>
#include <osg/Geode>
#include <osgDB/ReadFile>
#include <osgGA/StateSetManipulator>
@ -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<osg::Program> 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<osg::Node> sourceNode = osgDB::readRefNodeFile("axes.osgt");
if ( !sourceNode ) sourceNode = new osg::Node;
osg::ref_ptr<osg::Node> 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) );

View File

@ -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 <osg/Export>
#include <osg/Geometry>
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

View File

@ -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

View File

@ -0,0 +1,12 @@
#include <osg/ComputeDispatch>
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<GLExtensions>()->glDispatchCompute(_numGroupsX, _numGroupsY, _numGroupsZ);
}

View File

@ -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 );
}
}

View File

@ -0,0 +1,36 @@
#include <osg/ComputeDispatch>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _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
}