Merge branch 'ComputeDispatch' of https://github.com/mp3butcher/OpenSceneGraph into mp3butcher-ComputeDispatch
This commit is contained in:
commit
9f6eb74d28
@ -10,7 +10,7 @@
|
|||||||
#include <osg/StateAttributeCallback>
|
#include <osg/StateAttributeCallback>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osg/Geometry>
|
#include <osg/Geometry>
|
||||||
#include <osg/Geode>
|
#include <osg/ComputeDispatch>
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
#include <osgGA/StateSetManipulator>
|
#include <osgGA/StateSetManipulator>
|
||||||
#include <osgViewer/Viewer>
|
#include <osgViewer/Viewer>
|
||||||
@ -167,6 +167,7 @@ class ComputeNode : public osg::PositionAttitudeTransform
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::ComputeDispatch> _computeDispatch;
|
||||||
osg::ref_ptr<osg::Program> _computeProgram;
|
osg::ref_ptr<osg::Program> _computeProgram;
|
||||||
osg::ref_ptr<osg::Shader> _computeShader; //compute and write position data in SSBO
|
osg::ref_ptr<osg::Shader> _computeShader; //compute and write position data in SSBO
|
||||||
|
|
||||||
@ -204,6 +205,8 @@ public:
|
|||||||
_vertexShaderSourcePath = "shaders/osgssboVertexShader.vs";
|
_vertexShaderSourcePath = "shaders/osgssboVertexShader.vs";
|
||||||
_geometryShaderSourcePath = "shaders/osgssboGeometryShader.gs";
|
_geometryShaderSourcePath = "shaders/osgssboGeometryShader.gs";
|
||||||
_fragmentShaderSourcePath = "shaders/osgssboFragmentShader.fs";
|
_fragmentShaderSourcePath = "shaders/osgssboFragmentShader.fs";
|
||||||
|
_computeDispatch=new osg::ComputeDispatch();
|
||||||
|
addChild(_computeDispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -622,7 +625,7 @@ void ComputeNode::initComputingSetup()
|
|||||||
{
|
{
|
||||||
|
|
||||||
_computeProgram = new osg::Program;
|
_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);
|
_computeShader = osgDB::readRefShaderFile(osg::Shader::COMPUTE, _computeShaderSourcePath);
|
||||||
_computeProgram->addShader(_computeShader.get());
|
_computeProgram->addShader(_computeShader.get());
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
// This example can work only if GL version is 4.3 or greater
|
// This example can work only if GL version is 4.3 or greater
|
||||||
|
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osg/Geometry>
|
#include <osg/ComputeDispatch>
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
#include <osgGA/StateSetManipulator>
|
#include <osgGA/StateSetManipulator>
|
||||||
@ -57,14 +57,12 @@ int main( int argc, char** argv )
|
|||||||
// The compute shader can't work with other kinds of shaders
|
// 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
|
// 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;
|
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) );
|
computeProg->addShader( new osg::Shader(osg::Shader::COMPUTE, computeSrc) );
|
||||||
|
|
||||||
// Create a node for outputting to the texture.
|
// 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.
|
// 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?
|
// TODO: maybe we can have a custom drawable which also will implement glMemoryBarrier?
|
||||||
osg::ref_ptr<osg::Node> sourceNode = osgDB::readRefNodeFile("axes.osgt");
|
osg::ref_ptr<osg::Node> sourceNode = new osg::ComputeDispatch(512/16, 512/16, 1 );
|
||||||
if ( !sourceNode ) sourceNode = new osg::Node;
|
|
||||||
sourceNode->setDataVariance( osg::Object::DYNAMIC );
|
sourceNode->setDataVariance( osg::Object::DYNAMIC );
|
||||||
sourceNode->getOrCreateStateSet()->setAttributeAndModes( computeProg.get() );
|
sourceNode->getOrCreateStateSet()->setAttributeAndModes( computeProg.get() );
|
||||||
sourceNode->getOrCreateStateSet()->addUniform( new osg::Uniform("targetTex", (int)0) );
|
sourceNode->getOrCreateStateSet()->addUniform( new osg::Uniform("targetTex", (int)0) );
|
||||||
|
55
include/osg/ComputeDispatch
Normal file
55
include/osg/ComputeDispatch
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* -*-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 compileGLObjects(RenderInfo& renderInfo) const {}
|
||||||
|
|
||||||
|
virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const { return 0; }
|
||||||
|
|
||||||
|
virtual void drawImplementation(RenderInfo& renderInfo) const;
|
||||||
|
|
||||||
|
/** 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:
|
||||||
|
GLint _numGroupsX, _numGroupsY, _numGroupsZ;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -103,10 +103,6 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
|||||||
void setParameter( GLenum pname, GLint value );
|
void setParameter( GLenum pname, GLint value );
|
||||||
GLint getParameter( GLenum pname ) const;
|
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. */
|
/** Add an attribute location binding. */
|
||||||
void addBindAttribLocation( const std::string& name, GLuint index );
|
void addBindAttribLocation( const std::string& name, GLuint index );
|
||||||
|
|
||||||
@ -439,12 +435,6 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
|||||||
GLint _geometryInputType;
|
GLint _geometryInputType;
|
||||||
GLint _geometryOutputType;
|
GLint _geometryOutputType;
|
||||||
|
|
||||||
|
|
||||||
/** Parameter maintained with glDispatchCompute */
|
|
||||||
GLint _numGroupsX;
|
|
||||||
GLint _numGroupsY;
|
|
||||||
GLint _numGroupsZ;
|
|
||||||
|
|
||||||
/**TransformFeedBack**/
|
/**TransformFeedBack**/
|
||||||
GLenum _feedbackmode;
|
GLenum _feedbackmode;
|
||||||
std::vector<std::string> _feedbackout;
|
std::vector<std::string> _feedbackout;
|
||||||
|
@ -55,6 +55,7 @@ SET(TARGET_H
|
|||||||
${HEADER_PATH}/ColorMaski
|
${HEADER_PATH}/ColorMaski
|
||||||
${HEADER_PATH}/ColorMatrix
|
${HEADER_PATH}/ColorMatrix
|
||||||
${HEADER_PATH}/ComputeBoundsVisitor
|
${HEADER_PATH}/ComputeBoundsVisitor
|
||||||
|
${HEADER_PATH}/ComputeDispatch
|
||||||
${HEADER_PATH}/ContextData
|
${HEADER_PATH}/ContextData
|
||||||
${HEADER_PATH}/ConvexPlanarOccluder
|
${HEADER_PATH}/ConvexPlanarOccluder
|
||||||
${HEADER_PATH}/ConvexPlanarPolygon
|
${HEADER_PATH}/ConvexPlanarPolygon
|
||||||
@ -267,6 +268,7 @@ SET(TARGET_SRC
|
|||||||
ColorMaski.cpp
|
ColorMaski.cpp
|
||||||
ColorMatrix.cpp
|
ColorMatrix.cpp
|
||||||
ComputeBoundsVisitor.cpp
|
ComputeBoundsVisitor.cpp
|
||||||
|
ComputeDispatch.cpp
|
||||||
ContextData.cpp
|
ContextData.cpp
|
||||||
ConvexPlanarOccluder.cpp
|
ConvexPlanarOccluder.cpp
|
||||||
ConvexPlanarPolygon.cpp
|
ConvexPlanarPolygon.cpp
|
||||||
|
16
src/osg/ComputeDispatch.cpp
Normal file
16
src/osg/ComputeDispatch.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#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);
|
||||||
|
}
|
@ -92,8 +92,7 @@ void Program::ProgramBinary::assign(unsigned int size, const unsigned char* data
|
|||||||
|
|
||||||
Program::Program() :
|
Program::Program() :
|
||||||
_geometryVerticesOut(1), _geometryInputType(GL_TRIANGLES),
|
_geometryVerticesOut(1), _geometryInputType(GL_TRIANGLES),
|
||||||
_geometryOutputType(GL_TRIANGLE_STRIP),
|
_geometryOutputType(GL_TRIANGLE_STRIP), _feedbackmode(GL_SEPARATE_ATTRIBS)
|
||||||
_numGroupsX(0), _numGroupsY(0), _numGroupsZ(0), _feedbackmode(GL_SEPARATE_ATTRIBS)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,10 +132,6 @@ Program::Program(const Program& rhs, const osg::CopyOp& copyop):
|
|||||||
_geometryInputType = rhs._geometryInputType;
|
_geometryInputType = rhs._geometryInputType;
|
||||||
_geometryOutputType = rhs._geometryOutputType;
|
_geometryOutputType = rhs._geometryOutputType;
|
||||||
|
|
||||||
_numGroupsX = rhs._numGroupsX;
|
|
||||||
_numGroupsY = rhs._numGroupsY;
|
|
||||||
_numGroupsZ = rhs._numGroupsZ;
|
|
||||||
|
|
||||||
_feedbackmode=rhs._feedbackmode;
|
_feedbackmode=rhs._feedbackmode;
|
||||||
_feedbackout=rhs._feedbackout;
|
_feedbackout=rhs._feedbackout;
|
||||||
}
|
}
|
||||||
@ -173,15 +168,6 @@ int Program::compare(const osg::StateAttribute& sa) const
|
|||||||
if( _geometryOutputType < rhs._geometryOutputType ) return -1;
|
if( _geometryOutputType < rhs._geometryOutputType ) return -1;
|
||||||
if( rhs._geometryOutputType < _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(_feedbackout<rhs._feedbackout) return -1;
|
if(_feedbackout<rhs._feedbackout) return -1;
|
||||||
if(_feedbackmode<rhs._feedbackmode) return -1;
|
if(_feedbackmode<rhs._feedbackmode) return -1;
|
||||||
|
|
||||||
@ -386,20 +372,6 @@ GLint Program::getParameter( GLenum pname ) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ )
|
|
||||||
{
|
|
||||||
_numGroupsX = numGroupsX;
|
|
||||||
_numGroupsY = numGroupsY;
|
|
||||||
_numGroupsZ = numGroupsZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Program::getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const
|
|
||||||
{
|
|
||||||
numGroupsX = _numGroupsX;
|
|
||||||
numGroupsY = _numGroupsY;
|
|
||||||
numGroupsZ = _numGroupsZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Program::addBindAttribLocation( const std::string& name, GLuint index )
|
void Program::addBindAttribLocation( const std::string& name, GLuint index )
|
||||||
{
|
{
|
||||||
_attribBindingList[name] = index;
|
_attribBindingList[name] = index;
|
||||||
@ -1108,8 +1080,4 @@ Program::ProgramBinary* Program::PerContextProgram::compileProgramBinary(osg::St
|
|||||||
void Program::PerContextProgram::useProgram() const
|
void Program::PerContextProgram::useProgram() const
|
||||||
{
|
{
|
||||||
_extensions->glUseProgram( _glProgramHandle );
|
_extensions->glUseProgram( _glProgramHandle );
|
||||||
if ( _program->_numGroupsX>0 && _program->_numGroupsY>0 && _program->_numGroupsZ>0 )
|
|
||||||
{
|
|
||||||
_extensions->glDispatchCompute( _program->_numGroupsX, _program->_numGroupsY, _program->_numGroupsZ );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
36
src/osgWrappers/serializers/osg/ComputeDispatch.cpp
Normal file
36
src/osgWrappers/serializers/osg/ComputeDispatch.cpp
Normal 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
|
||||||
|
}
|
@ -121,29 +121,6 @@ static bool writeFeedBackMode( osgDB::OutputStream& os, const osg::Program& attr
|
|||||||
os << attr.getTransformFeedBackMode()<< std::endl;
|
os << attr.getTransformFeedBackMode()<< std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// _numGroupsX/Y/Z
|
|
||||||
static bool checkComputeGroups( const osg::Program& 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::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 )
|
static bool checkBindUniformBlock( const osg::Program& node )
|
||||||
{
|
{
|
||||||
@ -190,11 +167,6 @@ REGISTER_OBJECT_WRAPPER( Program,
|
|||||||
ADD_USER_SERIALIZER( GeometryInputType ); // _geometryInputType
|
ADD_USER_SERIALIZER( GeometryInputType ); // _geometryInputType
|
||||||
ADD_USER_SERIALIZER( GeometryOutputType ); // _geometryOutputType
|
ADD_USER_SERIALIZER( GeometryOutputType ); // _geometryOutputType
|
||||||
|
|
||||||
{
|
|
||||||
UPDATE_TO_VERSION_SCOPED( 95 )
|
|
||||||
ADD_USER_SERIALIZER( ComputeGroups ); // _numGroupsX/Y/Z
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
UPDATE_TO_VERSION_SCOPED( 116 )
|
UPDATE_TO_VERSION_SCOPED( 116 )
|
||||||
ADD_USER_SERIALIZER( FeedBackVaryingsName );
|
ADD_USER_SERIALIZER( FeedBackVaryingsName );
|
||||||
|
Loading…
Reference in New Issue
Block a user