diff options
author | zmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-20 00:59:12 +0000 |
---|---|---|
committer | zmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-20 00:59:12 +0000 |
commit | a2a0fe765475d7434d453bcab9ae01fe5600c63c (patch) | |
tree | 3003223b1b927104fc020808b59e0e3c643f4419 /gpu/command_buffer | |
parent | 95604b9ee186f5d8d082477bdde2c11276a9a5cf (diff) | |
download | chromium_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.cc | 34 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/mocks.h | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_translator.cc | 22 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_translator.h | 17 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_translator_unittest.cc | 28 |
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 |