From patchwork Tue Dec 6 16:35:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 5519 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id CBC7423E0C for ; Tue, 6 Dec 2011 16:35:18 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id B0EC8A18A62 for ; Tue, 6 Dec 2011 16:35:18 +0000 (UTC) Received: by eaac11 with SMTP id c11so6824372eaa.11 for ; Tue, 06 Dec 2011 08:35:18 -0800 (PST) Received: by 10.213.35.75 with SMTP id o11mr2633711ebd.108.1323189318349; Tue, 06 Dec 2011 08:35:18 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.129.2 with SMTP id hg2cs47309bkc; Tue, 6 Dec 2011 08:35:18 -0800 (PST) Received: by 10.180.105.131 with SMTP id gm3mr2178355wib.50.1323189316752; Tue, 06 Dec 2011 08:35:16 -0800 (PST) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id eu12si1304616wbb.48.2011.12.06.08.35.16 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Dec 2011 08:35:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1RXxz9-000721-Rj for ; Tue, 06 Dec 2011 16:35:15 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id C4079E043A for ; Tue, 6 Dec 2011 16:35:15 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glcompbench X-Launchpad-Branch: ~glcompbench-dev/glcompbench/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 67 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glcompbench-dev/glcompbench/trunk] Rev 67: Merge the shader-source branch. This adds the ShaderSource and ancillary objects Message-Id: <20111206163515.16365.96746.launchpad@ackee.canonical.com> Date: Tue, 06 Dec 2011 16:35:15 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14435"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: b1202200c14a87d5da68a059ee5f6bc0e21cf197 Merge authors: Jesse Barker (jesse-barker) Related merge proposals: https://code.launchpad.net/~jesse-barker/glcompbench/shader-source/+merge/84520 proposed by: Jesse Barker (jesse-barker) review: Approve - Alexandros Frantzis (afrantzis) ------------------------------------------------------------ revno: 67 [merge] committer: Jesse Barker branch nick: trunk timestamp: Tue 2011-12-06 08:29:56 -0800 message: Merge the shader-source branch. This adds the ShaderSource and ancillary objects from the glmark2 project for managing shaders. The changes also incorporates those objects into the GL-based scenarios; a by-product of this is that the fragment shader for the fade effect goes away since it can now be generated from the shader for the default scenario. removed: data/fade.frag added: src/shader-source.cc src/shader-source.h src/util.cc src/util.h modified: data/brick.frag data/brick.vert data/default.frag data/default.vert src/composite-test-simple-base.cc src/composite-test-simple-default.cc src/composite-test-simple-fade.cc src/composite-test.h --- lp:glcompbench https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk You are subscribed to branch lp:glcompbench. To unsubscribe from this branch go to https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk/+edit-subscription === modified file 'data/brick.frag' --- data/brick.frag 2011-07-29 20:28:24 +0000 +++ data/brick.frag 2011-12-05 19:01:24 +0000 @@ -1,6 +1,3 @@ -#ifdef GL_ES -precision mediump float; -#endif uniform vec2 BrickSize; uniform vec2 BrickPct; === modified file 'data/brick.vert' --- data/brick.vert 2011-07-29 20:28:24 +0000 +++ data/brick.vert 2011-12-05 19:01:24 +0000 @@ -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' --- data/default.frag 2011-07-18 17:14:16 +0000 +++ data/default.frag 2011-12-05 19:01:24 +0000 @@ -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' --- data/default.vert 2011-07-18 17:14:16 +0000 +++ data/default.vert 2011-12-05 19:01:24 +0000 @@ -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' --- data/fade.frag 2011-10-13 22:48:52 +0000 +++ data/fade.frag 1970-01-01 00:00:00 +0000 @@ -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' --- src/composite-test-simple-base.cc 2011-09-05 15:23:11 +0000 +++ src/composite-test-simple-base.cc 2011-12-05 19:01:24 +0000 @@ -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' --- src/composite-test-simple-default.cc 2011-09-05 15:23:11 +0000 +++ src/composite-test-simple-default.cc 2011-12-05 19:01:24 +0000 @@ -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 &window_list) { === modified file 'src/composite-test-simple-fade.cc' --- src/composite-test-simple-fade.cc 2011-10-14 12:41:30 +0000 +++ src/composite-test-simple-fade.cc 2011-12-05 19:01:24 +0000 @@ -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' --- src/composite-test.h 2011-10-14 02:09:08 +0000 +++ src/composite-test.h 2011-12-05 18:14:07 +0000 @@ -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 &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 &window_list); + virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg); }; #endif // COMPOSITE_TEST_H_ === added file 'src/shader-source.cc' --- src/shader-source.cc 1970-01-01 00:00:00 +0000 +++ src/shader-source.cc 2011-12-02 21:54:50 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis (glmark2) + */ + +#include +#include + +#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::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 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 &array, + const std::string &function) +{ + std::stringstream ss; + + ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed; + for(std::vector::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 &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::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: + * ",,," + * + * 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 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' --- src/shader-source.h 1970-01-01 00:00:00 +0000 +++ src/shader-source.h 2011-12-02 21:54:50 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis (glmark2) + */ + +#include +#include +#include +#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 &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 &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 default_precision_; +}; === added file 'src/util.cc' --- src/util.cc 1970-01-01 00:00:00 +0000 +++ src/util.cc 2011-12-02 21:54:50 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include +#include +#include + +#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 &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(tv.tv_sec) * 1000000 + + static_cast(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(ifs); +} + +void +Util::list_files(const std::string& dirName, std::vector& 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' --- src/util.h 1970-01-01 00:00:00 +0000 +++ src/util.h 2011-12-02 21:54:50 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#ifndef UTIL_H_ +#define UTIL_H_ + +#include +#include +#include +#include +#include + +struct Util { + static void split(const std::string &s, char delim, std::vector &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& fileVec); + template static void dispose_pointer_vector(std::vector &vec) + { + for (typename std::vector::const_iterator iter = vec.begin(); + iter != vec.end(); + iter++) + { + delete *iter; + } + + vec.clear(); + } + template + static T + fromString(const std::string& asString) + { + std::stringstream ss(asString); + T retVal; + ss >> retVal; + return retVal; + } + + template + static std::string + toString(const T t) + { + std::stringstream ss; + ss << t; + return ss.str(); + } +}; + +#endif /* UTIL_H */