summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authoralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-29 16:49:24 +0000
committeralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-29 16:49:24 +0000
commitff9e2a07893e137627884f74550ccf0cce132f8d (patch)
tree1303167913125fb9793c25ef20c600f295ab545a /gpu/command_buffer
parentcd5d0b1ca6b112db4f58c8d606f47c6bee2cf1a7 (diff)
downloadchromium_src-ff9e2a07893e137627884f74550ccf0cce132f8d.zip
chromium_src-ff9e2a07893e137627884f74550ccf0cce132f8d.tar.gz
chromium_src-ff9e2a07893e137627884f74550ccf0cce132f8d.tar.bz2
Hooked up functionality for getting info for attribs and uniforms.
Review URL: http://codereview.chromium.org/3436030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60951 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rw-r--r--gpu/command_buffer/service/shader_translator.cc62
-rw-r--r--gpu/command_buffer/service/shader_translator.h14
-rw-r--r--gpu/command_buffer/service/shader_translator_unittest.cc180
3 files changed, 247 insertions, 9 deletions
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index dd3ea24..f64fd58 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -20,6 +20,45 @@ bool InitializeShaderTranslator() {
}
return initialized;
}
+
+using gpu::gles2::ShaderTranslator;
+void GetVariableInfo(ShHandle compiler, EShInfo var_type,
+ ShaderTranslator::VariableMap* var_map) {
+ int name_len = 0;
+ switch (var_type) {
+ case SH_ACTIVE_ATTRIBUTES:
+ ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &name_len);
+ break;
+ case SH_ACTIVE_UNIFORMS:
+ ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &name_len);
+ break;
+ default: NOTREACHED();
+ }
+ if (name_len <= 1) return;
+ scoped_array<char> name(new char[name_len]);
+
+ int num_vars = 0;
+ ShGetInfo(compiler, var_type, &num_vars);
+ for (int i = 0; i < num_vars; ++i) {
+ int size = 0;
+ EShDataType type = SH_NONE;
+
+ switch (var_type) {
+ case SH_ACTIVE_ATTRIBUTES:
+ ShGetActiveAttrib(compiler, i, NULL, &size, &type, name.get());
+ break;
+ case SH_ACTIVE_UNIFORMS:
+ ShGetActiveUniform(compiler, i, NULL, &size, &type, name.get());
+ break;
+ default: NOTREACHED();
+ }
+
+ ShaderTranslator::VariableInfo info = {0};
+ info.type = type;
+ info.size = size;
+ (*var_map)[name.get()] = info;
+ }
+}
} // namespace
namespace gpu {
@@ -54,23 +93,28 @@ bool ShaderTranslator::Translate(const char* shader) {
ClearResults();
bool success = false;
- int compile_options = EShOptObjectCode;
+ int compile_options = EShOptObjectCode | EShOptAttribsUniforms;
if (ShCompile(compiler_, &shader, 1, compile_options)) {
+ success = true;
// Get translated shader.
int obj_code_len = 0;
ShGetInfo(compiler_, SH_OBJECT_CODE_LENGTH, &obj_code_len);
- translated_shader_.reset(new char[obj_code_len]);
- ShGetObjectCode(compiler_, translated_shader_.get());
-
- // TODO(alokp): Get attribs and uniforms.
- success = true;
+ if (obj_code_len > 1) {
+ translated_shader_.reset(new char[obj_code_len]);
+ ShGetObjectCode(compiler_, translated_shader_.get());
+ }
+ // Get info for attribs and uniforms.
+ GetVariableInfo(compiler_, SH_ACTIVE_ATTRIBUTES, &attrib_map_);
+ GetVariableInfo(compiler_, SH_ACTIVE_UNIFORMS, &uniform_map_);
}
// Get info log.
int info_log_len = 0;
ShGetInfo(compiler_, SH_INFO_LOG_LENGTH, &info_log_len);
- info_log_.reset(new char[info_log_len]);
- ShGetInfoLog(compiler_, info_log_.get());
+ if (info_log_len > 1) {
+ info_log_.reset(new char[info_log_len]);
+ ShGetInfoLog(compiler_, info_log_.get());
+ }
return success;
}
@@ -78,6 +122,8 @@ bool ShaderTranslator::Translate(const char* shader) {
void ShaderTranslator::ClearResults() {
translated_shader_.reset();
info_log_.reset();
+ attrib_map_.clear();
+ uniform_map_.clear();
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index 3dc0a05..26e8dc6 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -5,6 +5,9 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_SHADER_TRANSLATOR_H_
#define GPU_COMMAND_BUFFER_SERVICE_SHADER_TRANSLATOR_H_
+#include <map>
+#include <string>
+
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "third_party/angle/include/GLSLANG/ShaderLang.h"
@@ -32,7 +35,14 @@ class ShaderTranslator {
const char* translated_shader() { return translated_shader_.get(); }
const char* info_log() { return info_log_.get(); }
- // TODO(alokp): Add functions for returning attribs and uniforms.
+ struct VariableInfo {
+ int type;
+ int size;
+ };
+ // Mapping between variable name and info.
+ typedef std::map<std::string, VariableInfo> VariableMap;
+ const VariableMap& attrib_map() { return attrib_map_; }
+ const VariableMap& uniform_map() { return uniform_map_; }
private:
void ClearResults();
@@ -41,6 +51,8 @@ class ShaderTranslator {
ShHandle compiler_;
scoped_array<char> translated_shader_;
scoped_array<char> info_log_;
+ VariableMap attrib_map_;
+ VariableMap uniform_map_;
};
} // namespace gles2
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc
new file mode 100644
index 0000000..251b95c
--- /dev/null
+++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -0,0 +1,180 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/shader_translator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gpu {
+namespace gles2 {
+
+class ShaderTranslatorTest : public testing::Test {
+ public:
+ ShaderTranslatorTest() {
+ }
+
+ ~ShaderTranslatorTest() {
+ }
+
+ protected:
+ virtual void SetUp() {
+ TBuiltInResource resources;
+ ShInitBuiltInResource(&resources);
+
+ ASSERT_TRUE(vertex_translator_.Init(EShLangVertex, &resources));
+ ASSERT_TRUE(fragment_translator_.Init(EShLangFragment, &resources));
+ // Post-init the results must be empty.
+ // Vertex translator results.
+ EXPECT_TRUE(vertex_translator_.translated_shader() == NULL);
+ EXPECT_TRUE(vertex_translator_.info_log() == NULL);
+ EXPECT_TRUE(vertex_translator_.attrib_map().empty());
+ EXPECT_TRUE(vertex_translator_.uniform_map().empty());
+ // Fragment translator results.
+ EXPECT_TRUE(fragment_translator_.translated_shader() == NULL);
+ EXPECT_TRUE(fragment_translator_.info_log() == NULL);
+ EXPECT_TRUE(fragment_translator_.attrib_map().empty());
+ EXPECT_TRUE(fragment_translator_.uniform_map().empty());
+ }
+ virtual void TearDown() {}
+
+ ShaderTranslator vertex_translator_;
+ ShaderTranslator fragment_translator_;
+};
+
+TEST_F(ShaderTranslatorTest, ValidVertexShader) {
+ const char* shader =
+ "void main() {\n"
+ " gl_Position = vec4(1.0);\n"
+ "}";
+
+ // A valid shader should be successfully translated.
+ EXPECT_TRUE(vertex_translator_.Translate(shader));
+ // Info log must be NULL.
+ EXPECT_TRUE(vertex_translator_.info_log() == NULL);
+ // Translated shader must be valid and non-empty.
+ EXPECT_TRUE(vertex_translator_.translated_shader() != NULL);
+ EXPECT_GT(strlen(vertex_translator_.translated_shader()), 0u);
+ // There should be no attributes or uniforms.
+ EXPECT_TRUE(vertex_translator_.attrib_map().empty());
+ EXPECT_TRUE(vertex_translator_.uniform_map().empty());
+}
+
+TEST_F(ShaderTranslatorTest, InvalidVertexShader) {
+ const char* shader = "foo-bar";
+
+ // An invalid shader should fail.
+ EXPECT_FALSE(vertex_translator_.Translate(shader));
+ // Info log must be valid and non-empty.
+ EXPECT_TRUE(vertex_translator_.info_log() != NULL);
+ EXPECT_GT(strlen(vertex_translator_.info_log()), 0u);
+ // Translated shader must be NULL.
+ EXPECT_TRUE(vertex_translator_.translated_shader() == NULL);
+ // There should be no attributes or uniforms.
+ EXPECT_TRUE(vertex_translator_.attrib_map().empty());
+ EXPECT_TRUE(vertex_translator_.uniform_map().empty());
+}
+
+TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
+ const char* shader =
+ "void main() {\n"
+ " gl_FragColor = vec4(1.0);\n"
+ "}";
+
+ // A valid shader should be successfully translated.
+ EXPECT_TRUE(fragment_translator_.Translate(shader));
+ // Info log must be NULL.
+ EXPECT_TRUE(fragment_translator_.info_log() == NULL);
+ // Translated shader must be valid and non-empty.
+ EXPECT_TRUE(fragment_translator_.translated_shader() != NULL);
+ EXPECT_GT(strlen(fragment_translator_.translated_shader()), 0u);
+ // There should be no attributes or uniforms.
+ EXPECT_TRUE(fragment_translator_.attrib_map().empty());
+ EXPECT_TRUE(fragment_translator_.uniform_map().empty());
+}
+
+TEST_F(ShaderTranslatorTest, InvalidFragmentShader) {
+ const char* shader = "foo-bar";
+
+ // An invalid shader should fail.
+ EXPECT_FALSE(fragment_translator_.Translate(shader));
+ // Info log must be valid and non-empty.
+ EXPECT_TRUE(fragment_translator_.info_log() != NULL);
+ EXPECT_GT(strlen(fragment_translator_.info_log()), 0u);
+ // Translated shader must be NULL.
+ EXPECT_TRUE(fragment_translator_.translated_shader() == NULL);
+ // There should be no attributes or uniforms.
+ EXPECT_TRUE(fragment_translator_.attrib_map().empty());
+ EXPECT_TRUE(fragment_translator_.uniform_map().empty());
+}
+
+TEST_F(ShaderTranslatorTest, GetAttributes) {
+ const char* shader =
+ "attribute vec4 vPosition;\n"
+ "void main() {\n"
+ " gl_Position = vPosition;\n"
+ "}";
+
+ EXPECT_TRUE(vertex_translator_.Translate(shader));
+ // Info log must be NULL.
+ EXPECT_TRUE(vertex_translator_.info_log() == NULL);
+ // Translated shader must be valid and non-empty.
+ EXPECT_TRUE(vertex_translator_.translated_shader() != NULL);
+ EXPECT_GT(strlen(vertex_translator_.translated_shader()), 0u);
+ // There should be no uniforms.
+ EXPECT_TRUE(vertex_translator_.uniform_map().empty());
+ // There should be one attribute with following characteristics:
+ // name:vPosition type:SH_FLOAT_VEC4 size:1.
+ const ShaderTranslator::VariableMap& attrib_map =
+ vertex_translator_.attrib_map();
+ EXPECT_EQ(1u, attrib_map.size());
+ ShaderTranslator::VariableMap::const_iterator iter =
+ attrib_map.find("vPosition");
+ EXPECT_TRUE(iter != attrib_map.end());
+ EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
+ EXPECT_EQ(1, iter->second.size);
+}
+
+TEST_F(ShaderTranslatorTest, GetUniforms) {
+ const char* shader =
+ "precision mediump float;\n"
+ "struct Foo {\n"
+ " vec4 color[1];\n"
+ "};\n"
+ "struct Bar {\n"
+ " Foo foo;\n"
+ "};\n"
+ "uniform Bar bar[2];\n"
+ "void main() {\n"
+ " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
+ "}";
+
+ EXPECT_TRUE(fragment_translator_.Translate(shader));
+ // Info log must be NULL.
+ EXPECT_TRUE(fragment_translator_.info_log() == NULL);
+ // Translated shader must be valid and non-empty.
+ EXPECT_TRUE(fragment_translator_.translated_shader() != NULL);
+ EXPECT_GT(strlen(fragment_translator_.translated_shader()), 0u);
+ // There should be no attributes.
+ EXPECT_TRUE(fragment_translator_.attrib_map().empty());
+ // There should be two uniforms with following characteristics:
+ // 1. name:bar[0].foo.color[0] type:SH_FLOAT_VEC4 size:1
+ // 2. name:bar[1].foo.color[0] type:SH_FLOAT_VEC4 size:1
+ const ShaderTranslator::VariableMap& uniform_map =
+ fragment_translator_.uniform_map();
+ EXPECT_EQ(2u, uniform_map.size());
+ // First uniform.
+ ShaderTranslator::VariableMap::const_iterator iter =
+ uniform_map.find("bar[0].foo.color[0]");
+ EXPECT_TRUE(iter != uniform_map.end());
+ EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
+ EXPECT_EQ(1, iter->second.size);
+ // Second uniform.
+ iter = uniform_map.find("bar[1].foo.color[0]");
+ EXPECT_TRUE(iter != uniform_map.end());
+ EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
+ EXPECT_EQ(1, iter->second.size);
+}
+
+} // namespace gles2
+} // namespace gpu
+