Notice: If you are member of any public project or group, please make sure that your GitLab username is not the same as the LRZ identifier/Kennung (see https://gitlab.lrz.de/profile/account). Please change your username if necessary. For more information see the section "Public projects / Öffentliche Projekte" at https://doku.lrz.de/display/PUBLIC/GitLab . Thank you!

Commit 445c22ba authored by Jakob Weiss's avatar Jakob Weiss

Improvements to the CS support interface

* CSHelper ns contains methods to simplify boilerplate code
* some changes to the cgt::Texture interface
* Shader code now dumped to console when compilation fails (could still use some reworking, i.e. like line numbers)
* updated MedianFilter code
parent 2a6bc7a6
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2015, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
// (c) 2016 Jakob Weiss <jakob.weiss@tum.de>
#include "cshelper.h"
#include <sstream>
#include <cgt/texture.h>
#include <cgt/imageunit.h>
#include <cgt/gltextureformattraits.h>
namespace campvis {
namespace CSHelper {
//const std::string loggerCat_ = "CAMPVis.core.tools.CSHelper";
CAMPVIS_CORE_API std::string generateGLSLImageDefinition(const cgt::Texture & tex, const std::string& uniformName, const cgt::ImageUnit& imgUnit)
{
std::stringstream ss;
auto fmtTraits = cgt::GLTextureFormatTraits::get(tex.getInternalFormat());
ss << "layout(" << fmtTraits.glslFormatQualifier() << ", binding = " << imgUnit.getUnitNumber() << ") uniform "; // "layout( (r8|r16|rgba16|...) uniform"
ss << (fmtTraits.isIntegerFormat() ? (fmtTraits.isSignedFormat() ? "iimage" : "uimage") : "image"); // "(i|u|_)image"
ss << ( (tex.getType() == GL_TEXTURE_1D) ? 1 : ( (tex.getType() == GL_TEXTURE_2D) ? 2 : 3) ) << "D "; // "(1|2|3)D"
ss << uniformName << ";" << std::endl;
return ss.str();
}
}
}
\ No newline at end of file
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2015, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
// (c) 2016 Jakob Weiss <jakob.weiss@tum.de>
#ifndef CSHELPER_H__
#define CSHELPER_H__
#include <string>
#include "core/coreapi.h"
namespace cgt {
class Texture;
class ImageUnit;
}
namespace campvis {
/**
* CSHelper namespace
* Collection of various helper classes and functions to simplify using Compute Shaders for various applications
*/
namespace CSHelper {
/// Loggin category for the LDEBUG macros
//const std::string loggerCat_;
/**
* Generates a glsl image definition that matches the texture type and layout
*/
CAMPVIS_CORE_API std::string generateGLSLImageDefinition(const cgt::Texture& tex, const std::string& uniformName, const cgt::ImageUnit& imgUnit);
}
}
#endif // CSHELPER_H__
......@@ -176,7 +176,7 @@ namespace campvis {
}
// read back stuff
GLenum readBackFormat = cgt::Texture::calcMatchingFormat(outputTex->getInternalFormat());
GLenum readBackFormat = cgt::Texture::calcMatchingPixelFormat(outputTex->getInternalFormat());
size_t channels = outputTex->getNumChannels();
toReturn.resize(channels);
glReadBuffer(GL_COLOR_ATTACHMENT0);
......
......@@ -29,7 +29,6 @@ SET(CGT_SOURCES
frustum.cpp
glcanvas.cpp
glcontextmanager.cpp
gltextureformattraits.cpp
gpucapabilities.cpp
gpucapabilitieswindows.cpp
imageunit.cpp
......
This diff is collapsed.
This diff is collapsed.
......@@ -630,7 +630,8 @@ void Shader::loadSeparate(const string& vert_filename, const string& geom_filena
if (!vert->compileShader()) {
LERROR("Failed to compile vertex shader " << vert_filename);
LERROR("Compiler Log: \n" << vert->getCompilerLog());
LERROR("************* Compiler Log *************" << std::endl << vert->getCompilerLog());
LDEBUG("************* Vertex Shader Code *************" << std::endl << vert->getParsedSource());
delete vert;
throw Exception("Failed to compile vertex shader: " + vert_filename);
}
......@@ -659,7 +660,8 @@ void Shader::loadSeparate(const string& vert_filename, const string& geom_filena
geom->uploadSource();
if (!geom->compileShader()) {
LERROR("Failed to compile geometry shader " << geom_filename);
LERROR("Compiler Log: \n" << geom->getCompilerLog());
LERROR("************* Compiler Log *************" << std::endl << geom->getCompilerLog());
LDEBUG("************* Geometry Shader Code *************" << std::endl << geom->getParsedSource());
delete vert;
delete geom;
throw Exception("Failed to compile geometry shader: " + geom_filename);
......@@ -694,7 +696,8 @@ void Shader::loadSeparate(const string& vert_filename, const string& geom_filena
if (!frag->compileShader()) {
LERROR("Failed to compile fragment shader " << frag_filename);
LERROR("Compiler Log: \n" << frag->getCompilerLog());
LERROR("************* Compiler Log ************* \n" << frag->getCompilerLog());
LDEBUG("************* Fragment Shader Code *************" << std::endl << frag->getParsedSource());
delete vert;
delete geom;
delete frag;
......@@ -736,14 +739,18 @@ void Shader::loadSeparate(const string& vert_filename, const string& geom_filena
if (vert && vert->getCompilerLog().size() > 1) {
LDEBUG("Vertex shader compiler log for file '" << vert_filename
<< "': \n" << vert->getCompilerLog());
LDEBUG("************* Vertex Shader Code *************" << std::endl << vert->getParsedSource());
}
if (geom && geom->getCompilerLog().size() > 1) {
LDEBUG("Geometry shader compiler log for file '" << geom_filename
<< "': \n" << geom->getCompilerLog());
LDEBUG("************* Geometry Shader Code *************" << std::endl << geom->getParsedSource());
}
if (frag && frag->getCompilerLog().size() > 1) {
LDEBUG("Fragment shader compiler log for file '" << frag_filename
<< "': \n" << frag->getCompilerLog());
LDEBUG("************* Fragment Shader Code *************" << std::endl << frag->getParsedSource());
}
if (getLinkerLog().size() > 1) {
......@@ -784,7 +791,8 @@ void Shader::loadCompute(const string& compFilename, const string& customHeader,
if (!comp->compileShader()) {
LERROR("Failed to compile Compute shader " << compFilename);
LERROR("Compiler Log: \n" << comp->getCompilerLog());
LERROR("************* Compiler Log *************" << std::endl << comp->getCompilerLog());
LDEBUG("************* Compute Shader Code *************" << std::endl << comp->getParsedSource());
delete comp;
throw Exception("Failed to compile vertex shader: " + compFilename);
}
......@@ -799,7 +807,8 @@ void Shader::loadCompute(const string& compFilename, const string& customHeader,
LERROR(comp->filename_ << " Compute shader compiler log: \n" << comp->getCompilerLog());
detachObject(comp);
LERROR("Linker Log: \n" << getLinkerLog());
LERROR("************* Linker Log *************\n" << getLinkerLog());
LDEBUG("************* Compute Shader Code *************" << std::endl << comp->getParsedSource());
throw Exception("Failed to link shader (" + compFilename + ")");
}
......
......@@ -127,7 +127,9 @@ public:
source_ = source;
unparsedSource_ = source;
}
const std::string getSource() { return unparsedSource_; }
const std::string getSource() const { return unparsedSource_; }
const std::string getParsedSource() const { return source_; };
/**
* Set geometry shader input type. For this change to take effect call setDirectives() and
......
......@@ -33,6 +33,8 @@
// #define MEDIAN_WINDOW_Y
// #define MEDIAN_WINDOW_Z
// Size of the Median filter kernel in every dimension. All values to 1 performs results in a 3x3x3 filter window
// uniform _outputImage
// dynamically defined (i|u)image(1|2|3)D uniform to allow imageStore operation of the output
// The work group size can be overridden by dynamic defines
#ifndef WORK_GROUP_SIZE_X
......@@ -50,7 +52,6 @@
uniform sampler3D _texture;
uniform TextureParameters3D _textureParams;
layout(OUTPUT_TEXTURE_FORMAT, binding = 0) uniform image3D _outputImage;
layout(local_size_x = WORK_GROUP_SIZE_X, local_size_y = WORK_GROUP_SIZE_Y, local_size_z = WORK_GROUP_SIZE_Z) in;
#define KERNEL_X (MEDIAN_WINDOW_X*2 + 1)
......
......@@ -39,7 +39,7 @@ namespace campvis {
: AutoEvaluationPipeline(dc, getId())
, _lsp()
, _imageReader()
, _resampler(&_canvasSize)
, _resampler()
, _ve(&_canvasSize)
{
addProcessor(&_lsp);
......
......@@ -30,7 +30,7 @@
#include "modules/modulesapi.h"
#include "modules/base/processors/lightsourceprovider.h"
#include "modules/io/processors/mhdimagereader.h"
#include "modules/preprocessing/processors/glimageresampler.h"
#include "modules/preprocessing/processors/medianfilter.h"
#include "modules/vis/processors/volumeexplorer.h"
namespace campvis {
......@@ -58,7 +58,7 @@ namespace campvis {
protected:
LightSourceProvider _lsp;
MhdImageReader _imageReader;
GlImageResampler _resampler;
MedianFilter _resampler;
VolumeExplorer _ve;
};
}
......
......@@ -35,6 +35,7 @@
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/renderdata.h"
#include "core/tools/cshelper.h"
#include "core/tools/quadrenderer.h"
#include "core/tools/stringutils.h"
......@@ -79,7 +80,8 @@ namespace campvis {
if (img != 0) {
if (img->getParent()->getDimensionality() > 1) {
generateShader(img);
cgt::ImageUnit outputUnit;
generateShader(img, outputUnit);
if (_shader) {
cgt::ivec3 size = img->getSize();
......@@ -89,7 +91,7 @@ namespace campvis {
cgt::TextureUnit inputUnit;
inputUnit.activate();
cgt::ImageUnit outputUnit;
_shader->activate();
......@@ -102,8 +104,6 @@ namespace campvis {
_shader->setUniform("_outputImage", outputUnit.getUnitNumber());
LGL_ERROR;
LGL_ERROR;
glDispatchCompute(groups.x, groups.y, groups.z);
LGL_ERROR;
......@@ -130,7 +130,7 @@ namespace campvis {
}
}
void MedianFilter::generateShader(const ImageRepresentationGL::ScopedRepresentation & img)
void MedianFilter::generateShader(const ImageRepresentationGL::ScopedRepresentation& img, const cgt::ImageUnit& imgUnit)
{
auto wnd = p_windowSize.getValue();
auto wg = p_workgroupSize.getValue();
......@@ -142,6 +142,7 @@ namespace campvis {
ss << "#define WORK_GROUP_SIZE_Y " << wg.y << std::endl;
ss << "#define WORK_GROUP_SIZE_Z " << wg.z << std::endl;
ss << "#define OUTPUT_TEXTURE_FORMAT " << cgt::Texture::calcMatchingWriteFormat(img->getTexture()->getInternalFormat()) << std::endl;
ss << CSHelper::generateGLSLImageDefinition(*(img->getTexture()), "_outputImage", imgUnit) << std::endl;
// very simple caching to eliminate the glsl compiler as a bottleneck
static std::string headers;
......
......@@ -70,7 +70,7 @@ namespace campvis {
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Performs a median filtering on the input image using OpenGL Compute Shaders."; };
virtual const std::string getDescription() const { return "Performs a median filtering on the first channel of the input image using OpenGL Compute Shaders."; };
/// \see AbstractProcessor::getAuthor()
virtual const std::string getAuthor() const { return "Jakob Weiss <jakob.weiss@tum.de>"; };
/// \see AbstractProcessor::getProcessorState()
......@@ -79,14 +79,18 @@ namespace campvis {
DataNameProperty p_inputImage; ///< ID for input volume
DataNameProperty p_outputImage; ///< ID for output gradient volume
IVec3Property p_windowSize; ///< Size for specifying filtering window
IVec3Property p_workgroupSize; ///< Size of the workgroup
IVec3Property p_windowSize; ///< Size for specifying filtering window
IVec3Property p_workgroupSize; ///< Size of the workgroup
protected:
/// \see AbstractProcessor::updateResult
virtual void updateResult(DataContainer& dataContainer) override;
void generateShader(const ImageRepresentationGL::ScopedRepresentation& img);
/**
* Generates the shader tailored for the current input image. Simple caching is applied so as not to re-compile the shader
* on every image update if the image metadata does not change
*/
void generateShader(const ImageRepresentationGL::ScopedRepresentation& img, const cgt::ImageUnit& imgUnit);
cgt::Shader* _shader; ///< Shader for performing median filtering
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment