Skip to content

Commit

Permalink
command_buffer: Use GLSL core version that matches the OpenGL version
Browse files Browse the repository at this point in the history
Use GLSL core version that matches OpenGL version as specified in the
corresponding OpenGL specification.

This makes it simpler to support GL extensions that depend on specific
GLSL feature and are specified to be supported on contexts implementing
the GLSL language version.

Using the specified version as opposed to a hand-picked specific version
should minimize the kind of regressions caused by forcing a specific
core GLSL version in the past.

The idea is that when implementing a client-side feature that requires
a specific service-side GLSL feature, the feature_info can just check
the corresponding GL context version. Typically context version of an
extension is selected so that GLSL features match.

Needed in implementing EXT_blend_func_extended in the client. The
service side will be implemented with ARB_blend_func_extended, which
uses custom outputs. Using compatibility output from ANGLE would result
in gl_ built-ins as well as custom outputs, which is not allowed.

BUG=471960

Review URL: https://codereview.chromium.org/1273693002

Cr-Commit-Position: refs/heads/master@{#343172}
  • Loading branch information
kkinnunen authored and Commit bot committed Aug 13, 2015
1 parent 0dea3c1 commit 4885420
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 96 deletions.
18 changes: 7 additions & 11 deletions gpu/command_buffer/service/gles2_cmd_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3273,9 +3273,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
resources.HashFunction = &CityHash64;
else
resources.HashFunction = NULL;
ShaderTranslatorInterface::GlslImplementationType implementation_type =
gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;

int driver_bug_workarounds = 0;
if (workarounds().needs_glsl_built_in_function_emulation)
driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
Expand All @@ -3299,11 +3297,12 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
switches::kEmulateShaderPrecision))
resources.WEBGL_debug_shader_precision = true;

ShShaderOutput shader_output_language =
ShaderTranslator::GetShaderOutputLanguageForContext(
feature_info_->gl_version_info());

vertex_translator_ = shader_translator_cache()->GetTranslator(
GL_VERTEX_SHADER,
shader_spec,
&resources,
implementation_type,
GL_VERTEX_SHADER, shader_spec, &resources, shader_output_language,
static_cast<ShCompileOptions>(driver_bug_workarounds));
if (!vertex_translator_.get()) {
LOG(ERROR) << "Could not initialize vertex shader translator.";
Expand All @@ -3312,10 +3311,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
}

fragment_translator_ = shader_translator_cache()->GetTranslator(
GL_FRAGMENT_SHADER,
shader_spec,
&resources,
implementation_type,
GL_FRAGMENT_SHADER, shader_spec, &resources, shader_output_language,
static_cast<ShCompileOptions>(driver_bug_workarounds));
if (!fragment_translator_.get()) {
LOG(ERROR) << "Could not initialize fragment shader translator.";
Expand Down
12 changes: 6 additions & 6 deletions gpu/command_buffer/service/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ class MockShaderTranslator : public ShaderTranslatorInterface {
public:
MockShaderTranslator();

MOCK_METHOD5(Init, bool(
sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
GlslImplementationType glsl_implementation_type,
ShCompileOptions driver_bug_workarounds));
MOCK_METHOD5(Init,
bool(sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds));
MOCK_CONST_METHOD8(Translate, bool(
const std::string& shader_source,
std::string* info_log,
Expand Down
76 changes: 52 additions & 24 deletions gpu/command_buffer/service/shader_translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_version_info.h"

namespace gpu {
namespace gles2 {
Expand Down Expand Up @@ -90,6 +91,50 @@ void GetNameHashingInfo(ShHandle compiler, NameMap* name_map) {

} // namespace

ShShaderOutput ShaderTranslator::GetShaderOutputLanguageForContext(
const gfx::GLVersionInfo& version_info) {
if (version_info.is_es) {
return SH_ESSL_OUTPUT;
}

// Determine the GLSL version based on OpenGL specification.

unsigned context_version =
version_info.major_version * 100 + version_info.minor_version * 10;
if (context_version >= 450) {
// OpenGL specs from 4.2 on specify that the core profile is "also
// guaranteed to support all previous versions of the OpenGL Shading
// Language back to version 1.40". For simplicity, we assume future
// specs do not unspecify this. If they did, they could unspecify
// glGetStringi(GL_SHADING_LANGUAGE_VERSION, k), too.
// Since current context >= 4.5, use GLSL 4.50 core.
return SH_GLSL_450_CORE_OUTPUT;
} else if (context_version == 440) {
return SH_GLSL_440_CORE_OUTPUT;
} else if (context_version == 430) {
return SH_GLSL_430_CORE_OUTPUT;
} else if (context_version == 420) {
return SH_GLSL_420_CORE_OUTPUT;
} else if (context_version == 410) {
return SH_GLSL_410_CORE_OUTPUT;
} else if (context_version == 400) {
return SH_GLSL_400_CORE_OUTPUT;
} else if (context_version == 330) {
return SH_GLSL_330_CORE_OUTPUT;
} else if (context_version == 320) {
return SH_GLSL_150_CORE_OUTPUT;
} else if (context_version == 310) {
return SH_GLSL_140_OUTPUT;
} else if (context_version == 300) {
return SH_GLSL_130_OUTPUT;
}

// Before OpenGL 3.0 we use compatibility profile. Also for future
// specs between OpenGL 3.3 and OpenGL 4.0, at the time of writing,
// we use compatibility profile.
return SH_GLSL_COMPATIBILITY_OUTPUT;
}

ShaderTranslator::DestructionObserver::DestructionObserver() {
}

Expand All @@ -98,16 +143,14 @@ ShaderTranslator::DestructionObserver::~DestructionObserver() {

ShaderTranslator::ShaderTranslator()
: compiler_(NULL),
implementation_is_glsl_es_(false),
driver_bug_workarounds_(static_cast<ShCompileOptions>(0)) {
}

bool ShaderTranslator::Init(
GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
ShaderTranslatorInterface::GlslImplementationType glsl_implementation_type,
ShCompileOptions driver_bug_workarounds) {
bool ShaderTranslator::Init(GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds) {
// Make sure Init is called only once.
DCHECK(compiler_ == NULL);
DCHECK(shader_type == GL_FRAGMENT_SHADER || shader_type == GL_VERTEX_SHADER);
Expand All @@ -117,27 +160,12 @@ bool ShaderTranslator::Init(

g_translator_initializer.Get();

ShShaderOutput shader_output;
if (glsl_implementation_type == kGlslES) {
shader_output = SH_ESSL_OUTPUT;
} else {
// TODO(kbr): clean up the tests of shader_spec and
// gfx::GetGLImplementation(). crbug.com/471960
if (shader_spec == SH_WEBGL2_SPEC ||
gfx::GetGLImplementation() ==
gfx::kGLImplementationDesktopGLCoreProfile) {
shader_output = SH_GLSL_410_CORE_OUTPUT;
} else {
shader_output = SH_GLSL_COMPATIBILITY_OUTPUT;
}
}

{
TRACE_EVENT0("gpu", "ShConstructCompiler");
compiler_ = ShConstructCompiler(
shader_type, shader_spec, shader_output, resources);
compiler_ = ShConstructCompiler(shader_type, shader_spec,
shader_output_language, resources);
}
implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES);
driver_bug_workarounds_ = driver_bug_workarounds;
return compiler_ != NULL;
}
Expand Down
26 changes: 14 additions & 12 deletions gpu/command_buffer/service/shader_translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "gpu/gpu_export.h"
#include "third_party/angle/include/GLSLANG/ShaderLang.h"

namespace gfx {
struct GLVersionInfo;
}

namespace gpu {
namespace gles2 {

Expand All @@ -31,19 +35,14 @@ class ShaderTranslatorInterface
: public base::RefCounted<ShaderTranslatorInterface> {
public:
ShaderTranslatorInterface() {}
enum GlslImplementationType {
kGlsl,
kGlslES
};

// Initializes the translator.
// Must be called once before using the translator object.
virtual bool Init(
sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
GlslImplementationType glsl_implementation_type,
ShCompileOptions driver_bug_workarounds) = 0;
virtual bool Init(sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds) = 0;

// Translates the given shader source.
// Returns true if translation is successful, false otherwise.
Expand Down Expand Up @@ -88,11 +87,15 @@ class GPU_EXPORT ShaderTranslator

ShaderTranslator();

// Return shader output lanaguage type based on the context version.
static ShShaderOutput GetShaderOutputLanguageForContext(
const gfx::GLVersionInfo& context_version);

// Overridden from ShaderTranslatorInterface.
bool Init(sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
GlslImplementationType glsl_implementation_type,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds) override;

// Overridden from ShaderTranslatorInterface.
Expand All @@ -116,7 +119,6 @@ class GPU_EXPORT ShaderTranslator
int GetCompileOptions() const;

ShHandle compiler_;
bool implementation_is_glsl_es_;
ShCompileOptions driver_bug_workarounds_;
base::ObserverList<DestructionObserver> destruction_observers_;
};
Expand Down
12 changes: 4 additions & 8 deletions gpu/command_buffer/service/shader_translator_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@ scoped_refptr<ShaderTranslator> ShaderTranslatorCache::GetTranslator(
sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
ShaderTranslatorInterface::GlslImplementationType
glsl_implementation_type,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds) {
ShaderTranslatorInitParams params(shader_type,
shader_spec,
*resources,
glsl_implementation_type,
ShaderTranslatorInitParams params(shader_type, shader_spec, *resources,
shader_output_language,
driver_bug_workarounds);

Cache::iterator it = cache_.find(params);
Expand All @@ -46,8 +43,7 @@ scoped_refptr<ShaderTranslator> ShaderTranslatorCache::GetTranslator(

ShaderTranslator* translator = new ShaderTranslator();
if (translator->Init(shader_type, shader_spec, resources,
glsl_implementation_type,
driver_bug_workarounds)) {
shader_output_language, driver_bug_workarounds)) {
cache_[params] = translator;
translator->AddDestructionObserver(this);
return translator;
Expand Down
11 changes: 4 additions & 7 deletions gpu/command_buffer/service/shader_translator_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ class GPU_EXPORT ShaderTranslatorCache
sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources* resources,
ShaderTranslatorInterface::GlslImplementationType
glsl_implementation_type,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds);

private:
Expand All @@ -49,21 +48,19 @@ class GPU_EXPORT ShaderTranslatorCache
sh::GLenum shader_type;
ShShaderSpec shader_spec;
ShBuiltInResources resources;
ShaderTranslatorInterface::GlslImplementationType
glsl_implementation_type;
ShShaderOutput shader_output_language;
ShCompileOptions driver_bug_workarounds;

ShaderTranslatorInitParams(sh::GLenum shader_type,
ShShaderSpec shader_spec,
const ShBuiltInResources& resources,
ShaderTranslatorInterface::GlslImplementationType
glsl_implementation_type,
ShShaderOutput shader_output_language,
ShCompileOptions driver_bug_workarounds) {
memset(this, 0, sizeof(*this));
this->shader_type = shader_type;
this->shader_spec = shader_spec;
this->resources = resources;
this->glsl_implementation_type = glsl_implementation_type;
this->shader_output_language = shader_output_language;
this->driver_bug_workarounds = driver_bug_workarounds;
}

Expand Down
10 changes: 2 additions & 8 deletions gpu/command_buffer/service/shader_translator_cache_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,11 @@ TEST(ShaderTranslatorCacheTest, InitParamComparable) {
memset(a_storage, 55, sizeof(a_storage));
ShaderTranslatorCache::ShaderTranslatorInitParams* a =
new (&a_storage) ShaderTranslatorCache::ShaderTranslatorInitParams(
GL_VERTEX_SHADER,
SH_GLES2_SPEC,
a_resources,
ShaderTranslatorInterface::kGlslES,
GL_VERTEX_SHADER, SH_GLES2_SPEC, a_resources, SH_ESSL_OUTPUT,
driver_bug_workarounds);

ShaderTranslatorCache::ShaderTranslatorInitParams b(
GL_VERTEX_SHADER,
SH_GLES2_SPEC,
b_resources,
ShaderTranslatorInterface::kGlslES,
GL_VERTEX_SHADER, SH_GLES2_SPEC, b_resources, SH_ESSL_OUTPUT,
driver_bug_workarounds);

EXPECT_TRUE(*a == b);
Expand Down
Loading

0 comments on commit 4885420

Please sign in to comment.