Hi,
I have modified one of the osgCompute examples to try to learn a bit about
osgCompute/CUDA... I am trying to take 3 float textures, and use a CUDA kernel
to create a 4 texture which is a combination of the the 3 input textures. This
works if I create 3 GL_RGBA/GL_UNSIGNED_BYTE textures, btu when I try to use
float textures, using GL_RGBA32F_ARB/GL_FLOAT, I get the following errors:
alloc srcTexture0:unable to register image object
(cudaGraphicsGLRegisterImage()). Not all GL formats are supported.invalid
argument.
unmap srcTexture0: error during device memory synchronization (map()).
alloc srcTexture1:unable to register image object
(cudaGraphicsGLRegisterImage()). Not all GL formats are supported.invalid
argument.
unmap srcTexture1: error during device memory synchronization (map()).
alloc srcTexture2:unable to register image object
(cudaGraphicsGLRegisterImage()). Not all GL formats are supported.invalid
argument.
unmap srcTexture2: error during device memory synchronization (map()).
alloc trgBuffer:unable to register image object
(cudaGraphicsGLRegisterImage()). Not all GL formats are supported.invalid
argument.
unmap trgBuffer: error during device memory synchronization (map()).
Can someone help me out and tell me what i am doing wrong here?
This is my code:
/* osgCompute - Copyright (C) 2008-2009 SVT Group
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* 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
* GNU Lesse General Public License for more details.
*
* The full license is in LICENSE file included with this distribution.
*/
#include <iostream>
#include <sstream>
#include <osg/ArgumentParser>
#include <osg/Texture2D>
#include <osg/Vec4ub>
#include <osg/BlendFunc>
#include <osg/Geometry>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgViewer/CompositeViewer>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgCompute/Computation>
#include <osgCompute/Callback>
#include <osgCuda/Buffer>
#include <osgCuda/Texture>
#include <osgCuda/Computation>
#include <osgCudaStats/Stats>
#include <osgCudaInit/Init>
extern "C" void mix( unsigned int numPixelsX,
unsigned int numPixelsY,
void* trgBuffer,
void* srcBuffer0,
float srcBuffer0Fract,
void* srcBuffer1,
float srcBuffer1Fract,
void* srcBuffer2,
float srcBuffer2Fract,
unsigned int srcBufferSize );
///////////////////////////////////////////////////////////////////////////////////////////
//
//
//
///////////////////////////////////////////////////////////////////////////////////////////
class TexFilter : public osgCompute::Program
{
public:
//------------------------------------------------------------------------------
virtual void launch()
{
if( !_trgBuffer.valid() || !_srcBuffer0.valid() || !_srcBuffer1.valid()
|| !_srcBuffer2.valid())
return;
if( !_timer.valid() )
{
_timer = new osgCuda::Timer;
_timer->setName( "TexFilter");
}
_timer->start();
mix( _trgBuffer->getDimension(0),
_trgBuffer->getDimension(1),
_trgBuffer->map( osgCompute::MAP_DEVICE_TARGET ),
_srcBuffer0->map( osgCompute::MAP_DEVICE_SOURCE ),
_srcBuffer0Fract,
_srcBuffer1->map( osgCompute::MAP_DEVICE_SOURCE ),
_srcBuffer1Fract,
_srcBuffer2->map( osgCompute::MAP_DEVICE_SOURCE ),
_srcBuffer2Fract,
_srcBuffer0->getByteSize( osgCompute::MAP_DEVICE ) );
_timer->stop();
}
//------------------------------------------------------------------------------
virtual void acceptResource( osgCompute::Resource& resource )
{
if( resource.isIdentifiedBy("TRG_BUFFER") )
_trgBuffer = dynamic_cast<osgCompute::Memory*>( &resource );
if( resource.isIdentifiedBy("SRC_BUFFER0") )
_srcBuffer0 = dynamic_cast<osgCompute::Memory*>( &resource );
if( resource.isIdentifiedBy("SRC_BUFFER1") )
_srcBuffer1 = dynamic_cast<osgCompute::Memory*>( &resource );
if( resource.isIdentifiedBy("SRC_BUFFER2") )
_srcBuffer2 = dynamic_cast<osgCompute::Memory*>( &resource );
}
public:
void setSrcBufferFractions(float srcBuffer0Fract, float srcBuffer1Fract,
float srcBuffer2Fract)
{
_srcBuffer0Fract = srcBuffer0Fract;
_srcBuffer1Fract = srcBuffer1Fract;
_srcBuffer2Fract = srcBuffer2Fract;
}
private:
osg::ref_ptr<osgCompute::Memory> _srcBuffer0;
osg::ref_ptr<osgCompute::Memory> _srcBuffer1;
osg::ref_ptr<osgCompute::Memory> _srcBuffer2;
osg::ref_ptr<osgCompute::Memory> _trgBuffer;
osg::ref_ptr<osgCuda::Timer> _timer;
float _srcBuffer0Fract;
float _srcBuffer1Fract;
float _srcBuffer2Fract;
};
///////////////////////////////////////////////////////////////////////////////////////////
//
//
//
///////////////////////////////////////////////////////////////////////////////////////////
osg::ref_ptr<osg::Node> setupScene()
{
// CREATE TEXTURE RESOURCES //
int textureWidth = 512;
int textureHeight = 512;
int size = textureWidth * textureHeight * 4;
///////////////////////////////////////////////////////////////////////////////////////////
// create RED Texture and display quad
///////////////////////////////////////////////////////////////////////////////////////////
osg::ref_ptr< osgCuda::Texture2D > srcTexture0 = new osgCuda::Texture2D;
{
srcTexture0->setTextureSize(512, 512);
srcTexture0->setInternalFormat(GL_RGBA32F_ARB);
srcTexture0->setSourceType( GL_FLOAT );
srcTexture0->setName( "srcTexture0" );
srcTexture0->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
srcTexture0->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
srcTexture0->addIdentifier("SRC_BUFFER0");
osg::Image* sourceImage = new osg::Image;
if(sourceImage)
{
sourceImage->allocateImage(textureWidth, textureHeight, 1,
GL_RGBA32F_ARB, GL_FLOAT);
GLfloat* dataPtr = (GLfloat*)sourceImage->data();
if(dataPtr)
{
for(int row = 0; row < textureHeight; row++)
{
float value = 0;
for(int col = 0; col < textureHeight; col++)
{
int idx = row * textureWidth + col;
int i = 4 * idx;
dataPtr[i + 0] = 1.0f;
dataPtr[i + 1] = 0.0f;
dataPtr[i + 2] = 0.0f;
dataPtr[i + 3] = 1.0f;
}
}
srcTexture0->setImage(sourceImage);
}
}
}
osg::ref_ptr<osg::Geode> sourceQuad0 = new osg::Geode;
{
sourceQuad0->setDataVariance( osg::Object::DYNAMIC );
sourceQuad0->addDrawable( osg::createTexturedQuadGeometry(
osg::Vec3(-1.1, 0, 0.1), osg::Vec3(1,0,0), osg::Vec3(0,0,1) ) );
sourceQuad0->getOrCreateStateSet()->setTextureAttributeAndModes( 0,
srcTexture0.get(), osg::StateAttribute::ON );
}
///////////////////////////////////////////////////////////////////////////////////////////
// create GREEN Texture and display quad
///////////////////////////////////////////////////////////////////////////////////////////
osg::ref_ptr< osgCuda::Texture2D > srcTexture1 = new osgCuda::Texture2D;
{
srcTexture1->setTextureSize(512, 512);
srcTexture1->setInternalFormat(GL_RGBA32F_ARB);
srcTexture1->setSourceType( GL_FLOAT );
srcTexture1->setName( "srcTexture1" );
srcTexture1->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
srcTexture1->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
srcTexture1->addIdentifier("SRC_BUFFER1");
osg::Image* sourceImage = new osg::Image;
if(sourceImage)
{
sourceImage->allocateImage(textureWidth, textureHeight, 1,
GL_RGBA32F_ARB, GL_FLOAT);
GLfloat* dataPtr = (GLfloat*)sourceImage->data();
if(dataPtr)
{
for(int row = 0; row < textureHeight; row++)
{
float value = 0;
for(int col = 0; col < textureHeight; col++)
{
int idx = row * textureWidth + col;
int i = 4 * idx;
dataPtr[i + 0] = 0.0f;
dataPtr[i + 1] = 1.0f;
dataPtr[i + 2] = 0.0f;
dataPtr[i + 3] = 1.0f;
}
}
srcTexture1->setImage(sourceImage);
}
}
}
osg::ref_ptr<osg::Geode> sourceQuad1 = new osg::Geode;
{
sourceQuad1->setDataVariance( osg::Object::DYNAMIC );
sourceQuad1->addDrawable( osg::createTexturedQuadGeometry(
osg::Vec3(0.1, 0, 0.1), osg::Vec3(1,0,0), osg::Vec3(0,0,1) ) );
sourceQuad1->getOrCreateStateSet()->setTextureAttributeAndModes( 0,
srcTexture1.get(), osg::StateAttribute::ON );
}
///////////////////////////////////////////////////////////////////////////////////////////
// create BLUE Texture and display quad
///////////////////////////////////////////////////////////////////////////////////////////
osg::ref_ptr< osgCuda::Texture2D > srcTexture2 = new osgCuda::Texture2D;
{
srcTexture2->setTextureSize(512, 512);
srcTexture2->setInternalFormat(GL_RGBA32F_ARB);
srcTexture2->setSourceType( GL_FLOAT );
srcTexture2->setName( "srcTexture2" );
srcTexture2->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
srcTexture2->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
srcTexture2->addIdentifier("SRC_BUFFER2");
osg::Image* sourceImage = new osg::Image;
if(sourceImage)
{
sourceImage->allocateImage(textureWidth, textureHeight, 1,
GL_RGBA32F_ARB, GL_FLOAT);
GLfloat* dataPtr = (GLfloat*)sourceImage->data();
if(dataPtr)
{
for(int row = 0; row < textureHeight; row++)
{
float value = 0;
for(int col = 0; col < textureHeight; col++)
{
int idx = row * textureWidth + col;
int i = 4 * idx;
dataPtr[i + 0] = 0.0f;
dataPtr[i + 1] = 0.0f;
dataPtr[i + 2] = 1.0f;
dataPtr[i + 3] = 1.0f;
}
}
srcTexture2->setImage(sourceImage);
}
}
}
osg::ref_ptr<osg::Geode> sourceQuad2 = new osg::Geode;
{
sourceQuad2->setDataVariance( osg::Object::DYNAMIC );
sourceQuad2->addDrawable( osg::createTexturedQuadGeometry(
osg::Vec3(-1.1, 0, -1.1), osg::Vec3(1,0,0), osg::Vec3(0,0,1) ) );
sourceQuad2->getOrCreateStateSet()->setTextureAttributeAndModes( 0,
srcTexture2.get(), osg::StateAttribute::ON );
}
///////////////////////////////////////////////////////////////////////////////////////////
// create TARGET Texture and Quad
///////////////////////////////////////////////////////////////////////////////////////////
osg::ref_ptr< osgCuda::Texture2D > targetTexture = new osgCuda::Texture2D;
{
targetTexture->setTextureSize(512, 512);
targetTexture->setInternalFormat(GL_RGBA32F_ARB);
targetTexture->setSourceType( GL_FLOAT );
targetTexture->setName( "trgBuffer" );
targetTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
targetTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
targetTexture->addIdentifier("TRG_BUFFER");
}
osg::ref_ptr<osg::Geode> resultQuad = new osg::Geode;
{
resultQuad->setDataVariance( osg::Object::DYNAMIC );
resultQuad->addDrawable( osg::createTexturedQuadGeometry(
osg::Vec3(0.1,0,-1.1), osg::Vec3(1,0,0), osg::Vec3(0,0,1) ) );
resultQuad->getOrCreateStateSet()->setTextureAttributeAndModes( 0,
targetTexture.get(), osg::StateAttribute::ON );
}
///////////////////////////////////////////////////////////////////////////////////////////
// Create Computation
///////////////////////////////////////////////////////////////////////////////////////////
osg::ref_ptr<osgCuda::Computation> computation = new osgCuda::Computation;
{
osg::ref_ptr<TexFilter> texFilter = new TexFilter;
texFilter->setSrcBufferFractions(1.0f, 1.0f, 1.0f);
computation->addProgram( *texFilter );
computation->setComputeOrder( osgCompute::Computation::PRE_RENDER );
computation->addResource( *(srcTexture0->getMemory()) );
computation->addResource( *(srcTexture1->getMemory()) );
computation->addResource( *(srcTexture2->getMemory()) );
computation->addResource( *(targetTexture->getMemory()) );
}
osg::ref_ptr<osg::Group> scene = new osg::Group;
{
scene->addChild( sourceQuad0 );
scene->addChild( sourceQuad1 );
scene->addChild( sourceQuad2 );
scene->addChild( resultQuad );
scene->addChild( computation );
}
return scene;
}
//------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
osg::setNotifyLevel( osg::INFO );
////////////////////////////////////////////////////////////////////////////
osg::GraphicsContext::WindowingSystemInterface* wsi =
osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
{
osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available,
cannot create windows."<<std::endl;
return 1;
}
unsigned int windowWidth = 512;
unsigned int windowHeight = 512;
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new
osg::GraphicsContext::Traits;
traits->x = 10;
traits->y = 10;
traits->width = windowWidth;
traits->height = windowHeight;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
osg::ref_ptr<osg::GraphicsContext> graphicsContext =
osg::GraphicsContext::createGraphicsContext(traits.get());
if (graphicsContext.valid())
{
osg::notify(osg::INFO)<<" GraphicsWindow has been created
successfully."<<std::endl;
graphicsContext->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
graphicsContext->setClearMask(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
}
else
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created
successfully."<<std::endl;
}
osgViewer::CompositeViewer viewer;
viewer.setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
viewer.setReleaseContextAtEndOfFrameHint(false);
osg::ref_ptr<osgViewer::View> mainView = new osgViewer::View;
mainView->setName("Main View");
mainView->getCamera()->setGraphicsContext(graphicsContext);
mainView->getCamera()->setViewport(0, 0, windowWidth, windowHeight);
mainView->setCameraManipulator(new osgGA::TrackballManipulator);
mainView->addEventHandler(new osgViewer::StatsHandler);
mainView->addEventHandler(new osgCuda::StatsHandler);
viewer.addView(mainView);
///////////////////////
// LINK CUDA AND OSG //
///////////////////////
// setupOsgCudaAndViewer() creates the OpenGL context
// and binds it to the CUDA context of the thread.
osgCuda::setupOsgCudaAndViewer( viewer );
/////////////////
// SETUP SCENE //
/////////////////
mainView->setSceneData( setupScene() );
viewer.realize();
while (!viewer.done())
{
viewer.advance();
viewer.eventTraversal();
viewer.updateTraversal();
viewer.renderingTraversals();
}
}
...
Thank you!
Cheers,
Conan
Code:
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=59232#59232
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org