=== modified file 'data/brick.frag'
@@ -1,6 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
uniform vec2 BrickSize;
uniform vec2 BrickPct;
=== modified file 'data/brick.vert'
@@ -1,6 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
uniform mat4 modelview;
uniform mat4 projection;
uniform vec4 LightPosition;
=== modified file 'data/default.frag'
@@ -1,12 +1,9 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
uniform sampler2D Texture0;
varying vec2 TextureCoord;
void main(void)
{
+ float alpha = 1.0 - alpha_bias;
vec4 texel = texture2D(Texture0, TextureCoord);
- gl_FragColor = vec4(texel.xyz, 0.5);
+ gl_FragColor = vec4(texel.xyz, alpha);
}
=== modified file 'data/default.vert'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
attribute vec3 position;
attribute vec2 texcoord;
uniform mat4 projection;
=== removed file 'data/fade.frag'
@@ -1,14 +0,0 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
-uniform float alpha_bias;
-uniform sampler2D Texture0;
-varying vec2 TextureCoord;
-
-void main(void)
-{
- float alpha = 1.0 - alpha_bias;
- vec4 texel = texture2D(Texture0, TextureCoord);
- gl_FragColor = vec4(texel.xyz, alpha);
-}
=== modified file 'src/composite-test-simple-base.cc'
@@ -45,6 +45,26 @@
"Whether to use VBOs for rendering [true,false]");
}
+bool
+CompositeTestSimpleBase::init_shaders(ShaderSource& vtx, ShaderSource& frg)
+{
+ if (vtx.type() == ShaderSource::ShaderTypeUnknown)
+ {
+ return false;
+ }
+ if (frg.type() == ShaderSource::ShaderTypeUnknown)
+ {
+ return false;
+ }
+
+ static const string precisionString("default,default,default,default");
+ static const ShaderSource::Precision precision(precisionString);
+ vtx.precision(precision);
+ frg.precision(precision);
+
+ return true;
+}
+
void
CompositeTestSimpleBase::init()
{
@@ -52,16 +72,11 @@
return;
// Initialize shader sources from input files
- if (!gotSource(vs_filename_, vertex_shader_))
- {
- Log::error("Failed to get vertex shader source for test\n");
- return;
- }
- if (!gotSource(fs_filename_, fragment_shader_))
- {
- Log::error("Failed to get fragment shader source for test\n");
- return;
- }
+ ShaderSource vtx_source(vs_filename_);
+ ShaderSource frg_source(fs_filename_);
+ init_shaders(vtx_source, frg_source);
+ vertex_shader_ = vtx_source.str();
+ fragment_shader_ = frg_source.str();
program_.init();
if (!program_.valid())
=== modified file 'src/composite-test-simple-default.cc'
@@ -29,6 +29,18 @@
using std::string;
using std::map;
+bool
+CompositeTestSimpleDefault::init_shaders(ShaderSource& vtx, ShaderSource& frg)
+{
+ static const string precisionString("default,default,default,default");
+ static const ShaderSource::Precision precision(precisionString);
+ vtx.precision(precision);
+ frg.precision(precision);
+ static const float alpha_bias(0.5);
+ frg.add_const("alpha_bias", alpha_bias);
+
+ return true;
+}
void
CompositeTestSimpleDefault::draw(std::list<CompositeWindow *> &window_list)
{
=== modified file 'src/composite-test-simple-fade.cc'
@@ -31,6 +31,18 @@
const string CompositeTestSimpleFade::fade_bias_name_("alpha_bias");
+bool
+CompositeTestSimpleFade::init_shaders(ShaderSource& vtx, ShaderSource& frg)
+{
+ static const string precisionString("default,default,default,default");
+ static const ShaderSource::Precision precision(precisionString);
+ vtx.precision(precision);
+ frg.precision(precision);
+ static const string uniform("uniform float alpha_bias;");
+ frg.add(uniform);
+ return true;
+}
+
// We want to fade smoothly across the test duration, so take a timestamp
// at the beginning of the test (beginning of the first draw), and take one
// each time we'll update the fade bias to see if we should. We know based
=== modified file 'src/composite-test.h'
@@ -34,6 +34,7 @@
#include "program.h"
#include "composite-window.h"
#include "vbo.h"
+#include "shader-source.h"
class CompositeCanvas;
@@ -141,7 +142,7 @@
LibMatrix::Stack4 projection_matrix;
LibMatrix::Stack4 model_view_matrix;
-
+ virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg);
};
class CompositeTestSimpleDefault : public CompositeTestSimpleBase
@@ -154,6 +155,7 @@
{}
virtual void draw(std::list<CompositeWindow*> &window_list);
+ virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg);
};
class CompositeTestSimpleBrick : public CompositeTestSimpleBase
@@ -216,10 +218,11 @@
CompositeTestSimpleFade() :
CompositeTestSimpleBase("fade",
GLCOMPBENCH_DATA_PATH"/default.vert",
- GLCOMPBENCH_DATA_PATH"/fade.frag")
+ GLCOMPBENCH_DATA_PATH"/default.frag")
{}
virtual void draw(std::list<CompositeWindow*> &window_list);
+ virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg);
};
#endif // COMPOSITE_TEST_H_
=== added file 'src/shader-source.cc'
@@ -0,0 +1,622 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+
+#include <istream>
+#include <memory>
+
+#include "shader-source.h"
+#include "log.h"
+#include "vec.h"
+#include "util.h"
+
+/**
+ * Holds default precision values for all shader types
+ * (even the unknown type, which is hardwired to default precision values)
+ */
+std::vector<ShaderSource::Precision>
+ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1);
+
+/**
+ * Loads the contents of a file into a string.
+ *
+ * @param filename the name of the file
+ * @param str the string to put the contents of the file into
+ */
+bool
+ShaderSource::load_file(const std::string& filename, std::string& str)
+{
+ std::auto_ptr<std::istream> is_ptr(Util::get_resource(filename));
+ std::istream& inputFile(*is_ptr);
+
+ if (!inputFile)
+ {
+ Log::error("Failed to open \"%s\"\n", filename.c_str());
+ return false;
+ }
+
+ std::string curLine;
+ while (getline(inputFile, curLine))
+ {
+ str += curLine;
+ str += '\n';
+ }
+
+ return true;
+}
+
+
+/**
+ * Appends a string to the shader source.
+ *
+ * @param str the string to append
+ */
+void
+ShaderSource::append(const std::string &str)
+{
+ source_ << str;
+}
+
+/**
+ * Appends the contents of a file to the shader source.
+ *
+ * @param filename the name of the file to append
+ */
+void
+ShaderSource::append_file(const std::string &filename)
+{
+ std::string source;
+ if (load_file(filename, source))
+ source_ << source;
+}
+
+/**
+ * Replaces a string in the source with another string.
+ *
+ * @param remove the string to replace
+ * @param insert the string to replace with
+ */
+void
+ShaderSource::replace(const std::string &remove, const std::string &insert)
+{
+ std::string::size_type pos = 0;
+ std::string str(source_.str());
+
+ while ((pos = str.find(remove, pos)) != std::string::npos) {
+ str.replace(pos, remove.size(), insert);
+ pos++;
+ }
+
+ source_.clear();
+ source_.str(str);
+}
+
+/**
+ * Replaces a string in the source with the contents of a file.
+ *
+ * @param remove the string to replace
+ * @param filename the name of the file to read from
+ */
+void
+ShaderSource::replace_with_file(const std::string &remove, const std::string &filename)
+{
+ std::string source;
+ if (load_file(filename, source))
+ replace(remove, source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) at
+ * global (per shader) scope.
+ *
+ * The string is placed after any default precision qualifiers.
+ *
+ * @param str the string to add
+ */
+void
+ShaderSource::add_global(const std::string &str)
+{
+ std::string::size_type pos = 0;
+ std::string source(source_.str());
+
+ /* Find the last precision qualifier */
+ pos = source.rfind("precision");
+
+ if (pos != std::string::npos) {
+ /*
+ * Find the next #endif line of a preprocessor block that contains
+ * the precision qualifier.
+ */
+ std::string::size_type pos_if = source.find("#if", pos);
+ std::string::size_type pos_endif = source.find("#endif", pos);
+
+ if (pos_endif != std::string::npos && pos_endif < pos_if)
+ pos = pos_endif;
+
+ /* Go to the next line */
+ pos = source.find("\n", pos);
+ if (pos != std::string::npos)
+ pos++;
+ }
+ else
+ pos = 0;
+
+ source.insert(pos, str);
+
+ source_.clear();
+ source_.str(source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) at
+ * global (per shader) scope.
+ *
+ * The string is placed after any default precision qualifiers.
+ *
+ * @param function the function to add the string into
+ * @param str the string to add
+ */
+void
+ShaderSource::add_local(const std::string &str, const std::string &function)
+{
+ std::string::size_type pos = 0;
+ std::string source(source_.str());
+
+ /* Find the function */
+ pos = source.find(function);
+ pos = source.find('{', pos);
+
+ /* Go to the next line */
+ pos = source.find("\n", pos);
+ if (pos != std::string::npos)
+ pos++;
+
+ source.insert(pos, str);
+
+ source_.clear();
+ source_.str(source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) to a shader source
+ *
+ * If the function parameter is empty, the string will be added to global
+ * scope, after any precision definitions.
+ *
+ * @param str the string to add
+ * @param function if not empty, the function to add the string into
+ */
+void
+ShaderSource::add(const std::string &str, const std::string &function)
+{
+ if (!function.empty())
+ add_local(str, function);
+ else
+ add_global(str);
+}
+
+/**
+ * Adds a float constant definition.
+ *
+ * @param name the name of the constant
+ * @param f the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, float f,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const float " << name << " = " << std::fixed << f << ";" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a float array constant definition.
+ *
+ * Note that various GLSL versions (including ES) don't support
+ * array constants.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, std::vector<float> &array,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed;
+ for(std::vector<float>::const_iterator iter = array.begin();
+ iter != array.end();
+ iter++)
+ {
+ ss << *iter;
+ if (iter + 1 != array.end())
+ ss << ", " << std::endl;
+ }
+
+ ss << "};" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a vec2 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const vec2 " << name << " = vec2(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a vec3 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec3 &v,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const vec3 " << name << " = vec3(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a vec4 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec4 &v,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const vec4 " << name << " = vec4(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a mat3 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::mat3 &m,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const mat3 " << name << " = mat3(" << std::fixed;
+ ss << m[0][0] << ", " << m[1][0] << ", " << m[2][0] << "," << std::endl;
+ ss << m[0][1] << ", " << m[1][1] << ", " << m[2][1] << "," << std::endl;
+ ss << m[0][2] << ", " << m[1][2] << ", " << m[2][2] << std::endl;
+ ss << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a float array declaration and initialization.
+ *
+ * @param name the name of the array
+ * @param array the array values
+ * @param init_function the function to put the initialization in
+ * @param decl_function if not empty, the function to put the declaration in
+ */
+void
+ShaderSource::add_array(const std::string &name, std::vector<float> &array,
+ const std::string &init_function,
+ const std::string &decl_function)
+{
+ if (init_function.empty() || name.empty())
+ return;
+
+ std::stringstream ss;
+ ss << "float " << name << "[" << array.size() << "];" << std::endl;
+
+ std::string decl(ss.str());
+
+ ss.clear();
+ ss.str("");
+ ss << std::fixed;
+
+ for(std::vector<float>::const_iterator iter = array.begin();
+ iter != array.end();
+ iter++)
+ {
+ ss << name << "[" << iter - array.begin() << "] = " << *iter << ";" << std::endl;
+ }
+
+ add(ss.str(), init_function);
+
+ add(decl, decl_function);
+}
+
+/**
+ * Gets the ShaderType for this ShaderSource.
+ *
+ * If the ShaderType is unknown, an attempt is made to infer
+ * the type from the shader source contents.
+ *
+ * @return the ShaderType
+ */
+ShaderSource::ShaderType
+ShaderSource::type()
+{
+ /* Try to infer the type from the source contents */
+ if (type_ == ShaderSource::ShaderTypeUnknown) {
+ std::string source(source_.str());
+
+ if (source.find("gl_FragColor") != std::string::npos)
+ type_ = ShaderSource::ShaderTypeFragment;
+ else if (source.find("gl_Position") != std::string::npos)
+ type_ = ShaderSource::ShaderTypeVertex;
+ else
+ Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n");
+ }
+
+ return type_;
+}
+
+/**
+ * Helper function that emits a precision statement.
+ *
+ * @param ss the stringstream to add the statement to
+ * @param val the precision value
+ * @param type_str the variable type to apply the precision value to
+ */
+void
+ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
+ const std::string& type_str)
+{
+ static const char *precision_map[] = {
+ "lowp", "mediump", "highp", NULL
+ };
+
+ if (val == ShaderSource::PrecisionValueHigh) {
+ if (type_ == ShaderSource::ShaderTypeFragment)
+ ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl;
+
+ ss << "precision highp " << type_str << ";" << std::endl;
+
+ if (type_ == ShaderSource::ShaderTypeFragment) {
+ ss << "#else" << std::endl;
+ ss << "precision mediump " << type_str << ";" << std::endl;
+ ss << "#endif" << std::endl;
+ }
+ }
+ else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) {
+ ss << "precision " << precision_map[val] << " ";
+ ss << type_str << ";" << std::endl;
+ }
+
+ /* There is no default precision in the fragment shader, so set it to mediump */
+ if (val == ShaderSource::PrecisionValueDefault
+ && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment)
+ {
+ ss << "precision mediump float;" << std::endl;
+ }
+}
+
+/**
+ * Gets a string containing the complete shader source.
+ *
+ * Precision statements are applied at this point.
+ *
+ * @return the shader source
+ */
+std::string
+ShaderSource::str()
+{
+ /* Decide which precision values to use */
+ ShaderSource::Precision precision;
+
+ if (precision_has_been_set_)
+ precision = precision_;
+ else
+ precision = default_precision(type());
+
+ /* Create the precision statements */
+ std::stringstream ss;
+
+ emit_precision(ss, precision.int_precision, "int");
+ emit_precision(ss, precision.float_precision, "float");
+ emit_precision(ss, precision.sampler2d_precision, "sampler2D");
+ emit_precision(ss, precision.samplercube_precision, "samplerCube");
+
+ std::string precision_str(ss.str());
+ if (!precision_str.empty()) {
+ precision_str.insert(0, "#ifdef GL_ES\n");
+ precision_str.insert(precision_str.size(), "#endif\n");
+ }
+
+ return precision_str + source_.str();
+}
+
+/**
+ * Sets the precision that will be used for this shader.
+ *
+ * This overrides any default values set with ShaderSource::default_*_precision().
+ *
+ * @param precision the precision to set
+ */
+void
+ShaderSource::precision(const ShaderSource::Precision& precision)
+{
+ precision_ = precision;
+ precision_has_been_set_ = true;
+}
+
+/**
+ * Gets the precision that will be used for this shader.
+ *
+ * @return the precision
+ */
+const ShaderSource::Precision&
+ShaderSource::precision()
+{
+ return precision_;
+}
+
+/**
+ * Sets the default precision that will be used for a shaders type.
+ *
+ * If type is ShaderTypeUnknown the supplied precision is used for all
+ * shader types.
+ *
+ * This can be overriden per ShaderSource object by using ::precision().
+ *
+ * @param precision the default precision to set
+ * @param type the ShaderType to use the precision for
+ */
+void
+ShaderSource::default_precision(const ShaderSource::Precision& precision,
+ ShaderSource::ShaderType type)
+{
+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
+ type = ShaderSource::ShaderTypeUnknown;
+
+ if (type == ShaderSource::ShaderTypeUnknown) {
+ for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++)
+ default_precision_[i] = precision;
+ }
+ else {
+ default_precision_[type] = precision;
+ }
+}
+
+/**
+ * Gets the default precision that will be used for a shader type.
+ *
+ * It is valid to use a type of ShaderTypeUnknown. This will always
+ * return a Precision with default values.
+ *
+ * @param type the ShaderType to get the precision of
+ *
+ * @return the precision
+ */
+const ShaderSource::Precision&
+ShaderSource::default_precision(ShaderSource::ShaderType type)
+{
+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
+ type = ShaderSource::ShaderTypeUnknown;
+
+ return default_precision_[type];
+}
+
+/****************************************
+ * ShaderSource::Precision constructors *
+ ****************************************/
+
+/**
+ * Creates a ShaderSource::Precision with default precision values.
+ */
+ShaderSource::Precision::Precision() :
+ int_precision(ShaderSource::PrecisionValueDefault),
+ float_precision(ShaderSource::PrecisionValueDefault),
+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
+ samplercube_precision(ShaderSource::PrecisionValueDefault)
+{
+}
+
+/**
+ * Creates a ShaderSource::Precision using the supplied precision values.
+ */
+ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p,
+ ShaderSource::PrecisionValue float_p,
+ ShaderSource::PrecisionValue sampler2d_p,
+ ShaderSource::PrecisionValue samplercube_p) :
+ int_precision(int_p), float_precision(float_p),
+ sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p)
+{
+}
+
+/**
+ * Creates a ShaderSource::Precision from a string representation of
+ * precision values.
+ *
+ * The string format is:
+ * "<int>,<float>,<sampler2d>,<samplercube>"
+ *
+ * Each precision value is one of "high", "medium", "low" or "default".
+ *
+ * @param precision_values the string representation of the precision values
+ */
+ShaderSource::Precision::Precision(const std::string& precision_values) :
+ int_precision(ShaderSource::PrecisionValueDefault),
+ float_precision(ShaderSource::PrecisionValueDefault),
+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
+ samplercube_precision(ShaderSource::PrecisionValueDefault)
+{
+ std::vector<std::string> elems;
+
+ Util::split(precision_values, ',', elems);
+
+ for (size_t i = 0; i < elems.size() && i < 4; i++) {
+ const std::string& pstr(elems[i]);
+ ShaderSource::PrecisionValue pval;
+
+ if (pstr == "high")
+ pval = ShaderSource::PrecisionValueHigh;
+ else if (pstr == "medium")
+ pval = ShaderSource::PrecisionValueMedium;
+ else if (pstr == "low")
+ pval = ShaderSource::PrecisionValueLow;
+ else
+ pval = ShaderSource::PrecisionValueDefault;
+
+ switch(i) {
+ case 0: int_precision = pval; break;
+ case 1: float_precision = pval; break;
+ case 2: sampler2d_precision = pval; break;
+ case 3: samplercube_precision = pval; break;
+ default: break;
+ }
+ }
+}
=== added file 'src/shader-source.h'
@@ -0,0 +1,113 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include "vec.h"
+#include "mat.h"
+
+/**
+ * Helper class for loading and manipulating shader sources.
+ */
+class ShaderSource
+{
+public:
+ enum ShaderType {
+ ShaderTypeVertex,
+ ShaderTypeFragment,
+ ShaderTypeUnknown
+ };
+
+ ShaderSource(ShaderType type = ShaderTypeUnknown) :
+ precision_has_been_set_(false), type_(type) {}
+ ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) :
+ precision_has_been_set_(false), type_(type) { append_file(filename); }
+
+ void append(const std::string &str);
+ void append_file(const std::string &filename);
+
+ void replace(const std::string &remove, const std::string &insert);
+ void replace_with_file(const std::string &remove, const std::string &filename);
+
+ void add(const std::string &str, const std::string &function = "");
+
+ void add_const(const std::string &name, float f,
+ const std::string &function = "");
+ void add_const(const std::string &name, std::vector<float> &f,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::vec2 &v,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::vec3 &v,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::vec4 &v,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::mat3 &m,
+ const std::string &function = "");
+
+ void add_array(const std::string &name, std::vector<float> &array,
+ const std::string &init_function,
+ const std::string &decl_function = "");
+
+ ShaderType type();
+ std::string str();
+
+ enum PrecisionValue {
+ PrecisionValueLow,
+ PrecisionValueMedium,
+ PrecisionValueHigh,
+ PrecisionValueDefault,
+ };
+
+ struct Precision {
+ Precision();
+ Precision(PrecisionValue int_p, PrecisionValue float_p,
+ PrecisionValue sampler2d_p, PrecisionValue samplercube_p);
+ Precision(const std::string& list);
+
+ PrecisionValue int_precision;
+ PrecisionValue float_precision;
+ PrecisionValue sampler2d_precision;
+ PrecisionValue samplercube_precision;
+ };
+
+ void precision(const Precision& precision);
+ const Precision& precision();
+
+ static void default_precision(const Precision& precision,
+ ShaderType type = ShaderTypeUnknown);
+ static const Precision& default_precision(ShaderType type);
+
+private:
+ void add_global(const std::string &str);
+ void add_local(const std::string &str, const std::string &function);
+ bool load_file(const std::string& filename, std::string& str);
+ void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
+ const std::string& type_str);
+
+ std::stringstream source_;
+ Precision precision_;
+ bool precision_has_been_set_;
+ ShaderType type_;
+
+ static std::vector<Precision> default_precision_;
+};
=== added file 'src/util.cc'
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <sstream>
+#include <fstream>
+#include <sys/time.h>
+#include <dirent.h>
+
+#include "log.h"
+#include "util.h"
+
+/**
+ * Splits a string using a delimiter
+ *
+ * @param s the string to split
+ * @param delim the delimitir to use
+ * @param elems the string vector to populate
+ */
+void
+Util::split(const std::string &s, char delim, std::vector<std::string> &elems)
+{
+ std::stringstream ss(s);
+
+ std::string item;
+ while(std::getline(ss, item, delim))
+ elems.push_back(item);
+}
+
+uint64_t
+Util::get_timestamp_us()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ uint64_t now = static_cast<uint64_t>(tv.tv_sec) * 1000000 +
+ static_cast<double>(tv.tv_usec);
+ return now;
+}
+
+std::istream *
+Util::get_resource(const std::string &path)
+{
+ std::ifstream *ifs = new std::ifstream(path.c_str());
+
+ return static_cast<std::istream *>(ifs);
+}
+
+void
+Util::list_files(const std::string& dirName, std::vector<std::string>& fileVec)
+{
+ DIR* dir = opendir(dirName.c_str());
+ if (!dir)
+ {
+ Log::error("Failed to open models directory '%s'\n", dirName.c_str());
+ return;
+ }
+
+ struct dirent* entry = readdir(dir);
+ while (entry)
+ {
+ std::string pathname(dirName + "/");
+ pathname += std::string(entry->d_name);
+ // Skip '.' and '..'
+ if (entry->d_name[0] != '.')
+ {
+ fileVec.push_back(pathname);
+ }
+ entry = readdir(dir);
+ }
+ closedir(dir);
+}
=== added file 'src/util.h'
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <string>
+#include <vector>
+#include <istream>
+#include <sstream>
+#include <stdint.h>
+
+struct Util {
+ static void split(const std::string &s, char delim, std::vector<std::string> &elems);
+ static uint64_t get_timestamp_us();
+ static std::istream *get_resource(const std::string &path);
+ static void list_files(const std::string& dirName, std::vector<std::string>& fileVec);
+ template <class T> static void dispose_pointer_vector(std::vector<T*> &vec)
+ {
+ for (typename std::vector<T*>::const_iterator iter = vec.begin();
+ iter != vec.end();
+ iter++)
+ {
+ delete *iter;
+ }
+
+ vec.clear();
+ }
+ template<typename T>
+ static T
+ fromString(const std::string& asString)
+ {
+ std::stringstream ss(asString);
+ T retVal;
+ ss >> retVal;
+ return retVal;
+ }
+
+ template<typename T>
+ static std::string
+ toString(const T t)
+ {
+ std::stringstream ss;
+ ss << t;
+ return ss.str();
+ }
+};
+
+#endif /* UTIL_H */