summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authorzmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-20 00:59:12 +0000
committerzmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-20 00:59:12 +0000
commita2a0fe765475d7434d453bcab9ae01fe5600c63c (patch)
tree3003223b1b927104fc020808b59e0e3c643f4419 /gpu/command_buffer
parent95604b9ee186f5d8d082477bdde2c11276a9a5cf (diff)
downloadchromium_src-a2a0fe765475d7434d453bcab9ae01fe5600c63c.zip
chromium_src-a2a0fe765475d7434d453bcab9ae01fe5600c63c.tar.gz
chromium_src-a2a0fe765475d7434d453bcab9ae01fe5600c63c.tar.bz2
Turn on glsl built-in function emulation in ANGLE shader translator.
At the moment we need to turn it on for ATI/Mac and also Windows/D3D. Also, added the switch to turn of driver bug workaround, although this CL doesn't hook it up with all workarounds yet. BUG=96293 TEST=failing webgl glsl feature tests passing, with the switch, these tests fail. Review URL: http://codereview.chromium.org/7923002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101880 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc34
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h6
-rw-r--r--gpu/command_buffer/service/mocks.h5
-rw-r--r--gpu/command_buffer/service/shader_translator.cc22
-rw-r--r--gpu/command_buffer/service/shader_translator.h17
-rw-r--r--gpu/command_buffer/service/shader_translator_unittest.cc28
6 files changed, 89 insertions, 23 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 530342b..4a8b59f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1322,6 +1322,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
GLenum reset_status_;
bool needs_mac_nvidia_driver_workaround_;
+ bool needs_glsl_built_in_function_emulation_;
DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
};
@@ -1682,7 +1683,8 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
frame_number_(0),
has_arb_robustness_(false),
reset_status_(GL_NO_ERROR),
- needs_mac_nvidia_driver_workaround_(false) {
+ needs_mac_nvidia_driver_workaround_(false),
+ needs_glsl_built_in_function_emulation_(false) {
DCHECK(group);
attrib_0_value_.v[0] = 0.0f;
@@ -1936,12 +1938,19 @@ bool GLES2DecoderImpl::Initialize(
has_arb_robustness_ = context->HasExtension("GL_ARB_robustness");
+ if (!disallowed_extensions_.driver_bug_workarounds) {
#if defined(OS_MACOSX)
- const char* vendor_str = reinterpret_cast<const char*>(
- glGetString(GL_VENDOR));
- needs_mac_nvidia_driver_workaround_ =
- vendor_str && strstr(vendor_str, "NVIDIA");
+ const char* vendor_str = reinterpret_cast<const char*>(
+ glGetString(GL_VENDOR));
+ needs_mac_nvidia_driver_workaround_ =
+ vendor_str && strstr(vendor_str, "NVIDIA");
+ needs_glsl_built_in_function_emulation_ =
+ vendor_str && (strstr(vendor_str, "ATI") || strstr(vendor_str, "AMD"));
+#elif defined(OS_WIN)
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
+ needs_glsl_built_in_function_emulation_ = true;
#endif
+ }
if (!InitializeShaderTranslator()) {
return false;
@@ -1985,17 +1994,24 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
vertex_translator_.reset(new ShaderTranslator);
ShShaderSpec shader_spec = feature_info_->feature_flags().chromium_webglsl ?
SH_WEBGL_SPEC : SH_GLES2_SPEC;
- bool is_glsl_es =
- gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
+ ShaderTranslatorInterface::GlslImplementationType implementation_type =
+ gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
+ ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
+ ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
+ needs_glsl_built_in_function_emulation_ ?
+ ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
+ ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
if (!vertex_translator_->Init(
- SH_VERTEX_SHADER, shader_spec, &resources, is_glsl_es)) {
+ SH_VERTEX_SHADER, shader_spec, &resources,
+ implementation_type, function_behavior)) {
LOG(ERROR) << "Could not initialize vertex shader translator.";
Destroy();
return false;
}
fragment_translator_.reset(new ShaderTranslator);
if (!fragment_translator_->Init(
- SH_FRAGMENT_SHADER, shader_spec, &resources, is_glsl_es)) {
+ SH_FRAGMENT_SHADER, shader_spec, &resources,
+ implementation_type, function_behavior)) {
LOG(ERROR) << "Could not initialize fragment shader translator.";
Destroy();
return false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 35ad67d..0d83c23 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -30,9 +30,13 @@ class ContextGroup;
class GLES2Util;
struct DisallowedExtensions {
- DisallowedExtensions() : multisampling(false) {}
+ DisallowedExtensions()
+ : multisampling(false),
+ driver_bug_workarounds(false) {
+ }
bool multisampling;
+ bool driver_bug_workarounds;
};
// This class implements the AsyncAPIInterface interface, decoding GLES2
diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h
index 0d341bd..01dcbd8 100644
--- a/gpu/command_buffer/service/mocks.h
+++ b/gpu/command_buffer/service/mocks.h
@@ -76,11 +76,12 @@ class MockShaderTranslator : public ShaderTranslatorInterface {
MockShaderTranslator();
virtual ~MockShaderTranslator();
- MOCK_METHOD4(Init, bool(
+ MOCK_METHOD5(Init, bool(
ShShaderType shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
- bool implementation_is_glsl_es));
+ GlslImplementationType glsl_implementation_type,
+ GlslBuiltInFunctionBehavior glsl_built_in_function_behavior));
MOCK_METHOD1(Translate, bool(const char* shader));
MOCK_CONST_METHOD0(translated_shader, const char*());
MOCK_CONST_METHOD0(info_log, const char*());
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index c46d995..6c1269f 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -70,7 +70,8 @@ namespace gles2 {
ShaderTranslator::ShaderTranslator()
: compiler_(NULL),
- implementation_is_glsl_es_(false) {
+ implementation_is_glsl_es_(false),
+ needs_built_in_function_emulation_(false) {
}
ShaderTranslator::~ShaderTranslator() {
@@ -78,10 +79,13 @@ ShaderTranslator::~ShaderTranslator() {
ShDestruct(compiler_);
}
-bool ShaderTranslator::Init(ShShaderType shader_type,
- ShShaderSpec shader_spec,
- const ShBuiltInResources* resources,
- bool implementation_is_glsl_es) {
+bool ShaderTranslator::Init(
+ ShShaderType shader_type,
+ ShShaderSpec shader_spec,
+ const ShBuiltInResources* resources,
+ ShaderTranslatorInterface::GlslImplementationType glsl_implementation_type,
+ ShaderTranslatorInterface::GlslBuiltInFunctionBehavior
+ glsl_built_in_function_behavior) {
// Make sure Init is called only once.
DCHECK(compiler_ == NULL);
DCHECK(shader_type == SH_FRAGMENT_SHADER || shader_type == SH_VERTEX_SHADER);
@@ -92,11 +96,13 @@ bool ShaderTranslator::Init(ShShaderType shader_type,
return false;
ShShaderOutput shader_output =
- implementation_is_glsl_es ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT;
+ (glsl_implementation_type == kGlslES ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT);
compiler_ = ShConstructCompiler(
shader_type, shader_spec, shader_output, resources);
- implementation_is_glsl_es_ = implementation_is_glsl_es;
+ implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES);
+ needs_built_in_function_emulation_ =
+ (glsl_built_in_function_behavior == kGlslBuiltInFunctionEmulated);
return compiler_ != NULL;
}
@@ -109,6 +115,8 @@ bool ShaderTranslator::Translate(const char* shader) {
bool success = false;
int compile_options =
SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS | SH_MAP_LONG_VARIABLE_NAMES;
+ if (needs_built_in_function_emulation_)
+ compile_options |= SH_EMULATE_BUILT_IN_FUNCTIONS;
if (ShCompile(compiler_, &shader, 1, compile_options)) {
success = true;
// Get translated shader.
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index cca5aa6..9f5e766 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -19,6 +19,16 @@ namespace gles2 {
// validates GLSL ES 2.0 shaders on a true GLSL ES implementation.
class ShaderTranslatorInterface {
public:
+ enum GlslImplementationType {
+ kGlsl,
+ kGlslES
+ };
+
+ enum GlslBuiltInFunctionBehavior {
+ kGlslBuiltInFunctionOriginal,
+ kGlslBuiltInFunctionEmulated
+ };
+
virtual ~ShaderTranslatorInterface() { }
// Initializes the translator.
@@ -27,7 +37,8 @@ class ShaderTranslatorInterface {
ShShaderType shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
- bool implementation_is_glsl_es) = 0;
+ GlslImplementationType glsl_implementation_type,
+ GlslBuiltInFunctionBehavior glsl_built_in_function_behavior) = 0;
// Translates the given shader source.
// Returns true if translation is successful, false otherwise.
@@ -71,7 +82,8 @@ class ShaderTranslator : public ShaderTranslatorInterface {
ShShaderType shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
- bool implementation_is_glsl_es);
+ GlslImplementationType glsl_implementation_type,
+ GlslBuiltInFunctionBehavior glsl_built_in_function_behavior);
// Overridden from ShaderTranslatorInterface.
virtual bool Translate(const char* shader);
@@ -93,6 +105,7 @@ class ShaderTranslator : public ShaderTranslatorInterface {
VariableMap attrib_map_;
VariableMap uniform_map_;
bool implementation_is_glsl_es_;
+ bool needs_built_in_function_emulation_;
DISALLOW_COPY_AND_ASSIGN(ShaderTranslator);
};
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc
index f7468d7..9718cf4 100644
--- a/gpu/command_buffer/service/shader_translator_unittest.cc
+++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -22,9 +22,13 @@ class ShaderTranslatorTest : public testing::Test {
ShInitBuiltInResources(&resources);
ASSERT_TRUE(vertex_translator_.Init(
- SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, false));
+ SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
+ ShaderTranslatorInterface::kGlsl,
+ ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated));
ASSERT_TRUE(fragment_translator_.Init(
- SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources, false));
+ SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
+ ShaderTranslatorInterface::kGlsl,
+ ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal));
// Post-init the results must be empty.
// Vertex translator results.
EXPECT_TRUE(vertex_translator_.translated_shader() == NULL);
@@ -190,6 +194,26 @@ TEST_F(ShaderTranslatorTest, GetUniforms) {
EXPECT_EQ("bar[1].foo.color[0]", iter->second.name);
}
+#if defined(OS_MACOSX)
+TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) {
+ // This test might become invalid in the future when ANGLE Translator is no
+ // longer emulate dot(float, float) in Mac, or the emulated function name is
+ // no longer webgl_dot_emu.
+ const char* shader =
+ "void main() {\n"
+ " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\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_TRUE(strstr(vertex_translator_.translated_shader(),
+ "webgl_dot_emu") != NULL);
+}
+#endif
+
} // namespace gles2
} // namespace gpu