Skip to content

Commit

Permalink
Blacklist MSAA for GPU Raster on Intel GPUs
Browse files Browse the repository at this point in the history
Intel GPUs have unacceptable performance for GPU raster when MSAA is
enabled. This has been tested on recent Intel GPUs on CrOS, Mac, and
Windows. Given this we’re adding a workaround for Intel GPUs which will
disable MSAA for GPU raster.

We don’t want to impact WebGL, so this workaround specifically targets
non-WebGL contexts.

I’ve updated FeatureInfo’s Initialize function to accept the context
type, which allows us to customize features based on webgl/non-webgl.

I’ve also changed the secondary version of Initialize, which takes no
arguments, to be InitializeForTesting, as this function is only called
in tests.

BUG=527565
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

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

Cr-Commit-Position: refs/heads/master@{#351904}
  • Loading branch information
ericrk authored and Commit bot committed Oct 1, 2015
1 parent 58ceda2 commit ed27437
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 70 deletions.
2 changes: 1 addition & 1 deletion gpu/command_buffer/service/buffer_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class BufferManagerTestBase : public GpuServiceTest {
GpuServiceTest::SetUp();
if (feature_info) {
TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), extensions);
feature_info->Initialize();
feature_info->InitializeForTesting();
}
error_state_.reset(new MockErrorState());
manager_.reset(new BufferManager(memory_tracker, feature_info));
Expand Down
26 changes: 11 additions & 15 deletions gpu/command_buffer/service/context_group.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ ContextGroup::ContextGroup(
const scoped_refptr<SubscriptionRefSet>& subscription_ref_set,
const scoped_refptr<ValueStateMap>& pending_valuebuffer_state,
bool bind_generates_resource)
: context_type_(CONTEXT_TYPE_OPENGLES2),
mailbox_manager_(mailbox_manager),
: mailbox_manager_(mailbox_manager),
memory_tracker_(memory_tracker),
shader_translator_cache_(shader_translator_cache),
#if defined(OS_MACOSX)
Expand Down Expand Up @@ -92,21 +91,18 @@ static void GetIntegerv(GLenum pname, uint32* var) {
bool ContextGroup::Initialize(GLES2Decoder* decoder,
ContextType context_type,
const DisallowedFeatures& disallowed_features) {
if (!HaveContexts()) {
context_type_ = context_type;
} else if (context_type_ != context_type) {
LOG(ERROR) << "ContextGroup::Initialize failed because the type of "
<< "the context does not fit with the group.";
return false;
}

// If we've already initialized the group just add the context.
if (HaveContexts()) {
if (context_type != feature_info_->context_type()) {
LOG(ERROR) << "ContextGroup::Initialize failed because the type of "
<< "the context does not fit with the group.";
return false;
}
// If we've already initialized the group just add the context.
decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder));
return true;
}

if (!feature_info_->Initialize(disallowed_features)) {
if (!feature_info_->Initialize(context_type, disallowed_features)) {
LOG(ERROR) << "ContextGroup::Initialize failed because FeatureInfo "
<< "initialization failed.";
return false;
Expand Down Expand Up @@ -146,9 +142,9 @@ bool ContextGroup::Initialize(GLES2Decoder* decoder,

buffer_manager_.reset(
new BufferManager(memory_tracker_.get(), feature_info_.get()));
framebuffer_manager_.reset(
new FramebufferManager(max_draw_buffers_, max_color_attachments_,
context_type, framebuffer_completeness_cache_));
framebuffer_manager_.reset(new FramebufferManager(
max_draw_buffers_, max_color_attachments_, feature_info_->context_type(),
framebuffer_completeness_cache_));
renderbuffer_manager_.reset(new RenderbufferManager(
memory_tracker_.get(), max_renderbuffer_size, max_samples,
feature_info_.get()));
Expand Down
4 changes: 0 additions & 4 deletions gpu/command_buffer/service/context_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
bool QueryGLFeatureU(GLenum pname, GLint min_required, uint32* v);
bool HaveContexts();

ContextType context_type_;

scoped_refptr<MailboxManager> mailbox_manager_;
scoped_refptr<MemoryTracker> memory_tracker_;
scoped_refptr<ShaderTranslatorCache> shader_translator_cache_;
Expand Down Expand Up @@ -308,5 +306,3 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
} // namespace gpu

#endif // GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_


43 changes: 35 additions & 8 deletions gpu/command_buffer/service/feature_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -231,20 +231,23 @@ void FeatureInfo::InitializeBasicState(const base::CommandLine* command_line) {
command_line->HasSwitch(switches::kDisableGLSLTranslator);

unsafe_es3_apis_enabled_ = false;
}

bool FeatureInfo::Initialize() {
disallowed_features_ = DisallowedFeatures();
InitializeFeatures();
return true;
// Default context_type_ to a GLES2 Context.
context_type_ = CONTEXT_TYPE_OPENGLES2;
}

bool FeatureInfo::Initialize(const DisallowedFeatures& disallowed_features) {
bool FeatureInfo::Initialize(ContextType context_type,
const DisallowedFeatures& disallowed_features) {
disallowed_features_ = disallowed_features;
context_type_ = context_type;
InitializeFeatures();
return true;
}

bool FeatureInfo::InitializeForTesting() {
return Initialize(CONTEXT_TYPE_OPENGLES2, DisallowedFeatures());
}

bool IsGL_REDSupportedOnFBOs() {
// Skia uses GL_RED with frame buffers, unfortunately, Mesa claims to support
// GL_EXT_texture_rg, but it doesn't support it on frame buffers. To fix
Expand Down Expand Up @@ -698,7 +701,15 @@ void FeatureInfo::InitializeFeatures() {
}

// Check for multisample support
if (!workarounds_.disable_chromium_framebuffer_multisample) {

// crbug.com/527565 - On some GPUs, MSAA does not perform acceptably for
// rasterization. We disable it on non-WebGL contexts. For WebGL contexts
// we leave it up to the site to decide whether to enable MSAA.
bool disable_all_multisample =
workarounds_.disable_msaa_on_non_webgl_contexts && !IsWebGLContext();

if (!disable_all_multisample &&
!workarounds_.disable_chromium_framebuffer_multisample) {
bool ext_has_multisample =
extensions.Contains("GL_EXT_framebuffer_multisample") ||
gl_version_info_->is_es3 ||
Expand All @@ -720,7 +731,8 @@ void FeatureInfo::InitializeFeatures() {
}
}

if (!workarounds_.disable_multisampled_render_to_texture) {
if (!disable_all_multisample &&
!workarounds_.disable_multisampled_render_to_texture) {
if (extensions.Contains("GL_EXT_multisampled_render_to_texture")) {
feature_flags_.multisampled_render_to_texture = true;
} else if (extensions.Contains("GL_IMG_multisampled_render_to_texture")) {
Expand Down Expand Up @@ -1193,6 +1205,21 @@ void FeatureInfo::EnableES3Validators() {
unsafe_es3_apis_enabled_ = true;
}

bool FeatureInfo::IsWebGLContext() const {
// Switch statement to cause a compile-time error if we miss a case.
switch (context_type_) {
case CONTEXT_TYPE_WEBGL1:
case CONTEXT_TYPE_WEBGL2:
return true;
case CONTEXT_TYPE_OPENGLES2:
case CONTEXT_TYPE_OPENGLES3:
return false;
}

NOTREACHED();
return false;
}

void FeatureInfo::AddExtensionString(const char* s) {
std::string str(s);
size_t pos = extensions_.find(str);
Expand Down
13 changes: 11 additions & 2 deletions gpu/command_buffer/service/feature_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,18 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
FeatureInfo(const base::CommandLine& command_line);

// Initializes the feature information. Needs a current GL context.
bool Initialize();
bool Initialize(const DisallowedFeatures& disallowed_features);
bool Initialize(ContextType context_type,
const DisallowedFeatures& disallowed_features);

// Helper that defaults to no disallowed features and a GLES2 context.
bool InitializeForTesting();

const Validators* validators() const {
return &validators_;
}

ContextType context_type() const { return context_type_; }

const std::string& extensions() const {
return extensions_;
}
Expand Down Expand Up @@ -148,6 +153,8 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
workarounds_.use_virtualized_gl_contexts;
}

bool IsWebGLContext() const;

private:
friend class base::RefCounted<FeatureInfo>;
friend class BufferManagerClientSideArraysTest;
Expand All @@ -162,6 +169,8 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {

DisallowedFeatures disallowed_features_;

ContextType context_type_;

// The extensions string returned by glGetString(GL_EXTENSIONS);
std::string extensions_;

Expand Down
43 changes: 40 additions & 3 deletions gpu/command_buffer/service/feature_info_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class FeatureInfoTest
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
gl_.get(), extensions, renderer, version);
info_ = new FeatureInfo();
info_->Initialize();
info_->InitializeForTesting();
}

void SetupInitExpectationsWithGLVersionAndCommandLine(
Expand All @@ -88,7 +88,20 @@ class FeatureInfoTest
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
gl_.get(), extensions, renderer, version);
info_ = new FeatureInfo(command_line);
info_->Initialize();
info_->InitializeForTesting();
}

void SetupInitExpectationsWithGLVersionAndContextTypeAndCommandLine(
const char* extensions,
const char* renderer,
const char* version,
ContextType context_type,
const base::CommandLine& command_line) {
GpuServiceTest::SetUpWithGLVersion(version, extensions);
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
gl_.get(), extensions, renderer, version);
info_ = new FeatureInfo(command_line);
info_->Initialize(context_type, DisallowedFeatures());
}

void SetupWithCommandLine(const base::CommandLine& command_line) {
Expand All @@ -103,7 +116,7 @@ class FeatureInfoTest
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
gl_.get(), extensions, "", "");
info_ = new FeatureInfo(command_line);
info_->Initialize();
info_->InitializeForTesting();
}

void SetupWithoutInit() {
Expand Down Expand Up @@ -1369,5 +1382,29 @@ TEST_P(FeatureInfoTest, InitializeCHROMIUM_ycbcr_422_imageTrue) {
EXPECT_TRUE(info_->feature_flags().chromium_image_ycbcr_422);
}

TEST_P(FeatureInfoTest, DisableMsaaOnNonWebGLContexts) {
base::CommandLine command_line(0, NULL);
command_line.AppendSwitchASCII(
switches::kGpuDriverBugWorkarounds,
base::IntToString(gpu::DISABLE_MSAA_ON_NON_WEBGL_CONTEXTS));
SetupInitExpectationsWithGLVersionAndContextTypeAndCommandLine(
"GL_EXT_multisampled_render_to_texture GL_EXT_framebuffer_multisample",
"", "", CONTEXT_TYPE_OPENGLES2, command_line);
EXPECT_FALSE(info_->feature_flags().multisampled_render_to_texture);
EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample);
}

TEST_P(FeatureInfoTest, DontDisableMsaaOnWebGLContexts) {
base::CommandLine command_line(0, NULL);
command_line.AppendSwitchASCII(
switches::kGpuDriverBugWorkarounds,
base::IntToString(gpu::DISABLE_MSAA_ON_NON_WEBGL_CONTEXTS));
SetupInitExpectationsWithGLVersionAndContextTypeAndCommandLine(
"GL_EXT_multisampled_render_to_texture GL_EXT_framebuffer_multisample",
"", "", CONTEXT_TYPE_WEBGL1, command_line);
EXPECT_TRUE(info_->feature_flags().multisampled_render_to_texture);
EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample);
}

} // namespace gles2
} // namespace gpu
2 changes: 1 addition & 1 deletion gpu/command_buffer/service/framebuffer_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class FramebufferInfoTestBase : public GpuServiceTest {
GpuServiceTest::SetUpWithGLVersion(gl_version, extensions);
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(),
extensions, "", gl_version);
feature_info_->Initialize();
feature_info_->InitializeForTesting();
manager_.CreateFramebuffer(kClient1Id, kService1Id);
error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
framebuffer_ = manager_.GetFramebuffer(kClient1Id);
Expand Down
30 changes: 12 additions & 18 deletions gpu/command_buffer/service/gles2_cmd_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -841,11 +841,6 @@ class GLES2DecoderImpl : public GLES2Decoder,
return true;
}

bool IsWebGLContext() const {
return context_type_ == CONTEXT_TYPE_WEBGL1 ||
context_type_ == CONTEXT_TYPE_WEBGL2;
}

bool IsOffscreenBufferMultisampled() const {
return offscreen_target_samples_ > 1;
}
Expand Down Expand Up @@ -2623,8 +2618,6 @@ bool GLES2DecoderImpl::Initialize(
if (!attrib_parser.Parse(attribs))
return false;

context_type_ = attrib_parser.context_type;

surfaceless_ = surface->IsSurfaceless() && !offscreen;

set_initialized();
Expand Down Expand Up @@ -2674,18 +2667,19 @@ bool GLES2DecoderImpl::Initialize(
}

disallowed_features_ = disallowed_features;
if (context_type_ == CONTEXT_TYPE_WEBGL1) {
if (attrib_parser.context_type == CONTEXT_TYPE_WEBGL1) {
disallowed_features_.npot_support = true;
}

if (!group_->Initialize(this, context_type_, disallowed_features_)) {
if (!group_->Initialize(this, attrib_parser.context_type,
disallowed_features_)) {
group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
Destroy(true);
return false;
}
CHECK_GL_ERROR();
if (context_type_ == CONTEXT_TYPE_WEBGL2 ||
context_type_ == CONTEXT_TYPE_OPENGLES3) {
if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL2 ||
feature_info_->context_type() == CONTEXT_TYPE_OPENGLES3) {
if (!feature_info_->IsES3Capable()) {
LOG(ERROR) << "Underlying driver does not support ES3.";
Destroy(true);
Expand Down Expand Up @@ -3226,7 +3220,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
resources.FragmentPrecisionHigh =
PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);

if (IsWebGLContext()) {
if (feature_info_->IsWebGLContext()) {
resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
Expand All @@ -3253,7 +3247,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
}

ShShaderSpec shader_spec;
switch (context_type_) {
switch (feature_info_->context_type()) {
case CONTEXT_TYPE_WEBGL1:
shader_spec = SH_WEBGL_SPEC;
break;
Expand Down Expand Up @@ -9006,7 +9000,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
}
break;
}
if (!IsWebGLContext()) {
if (!feature_info_->IsWebGLContext()) {
accepted_formats.push_back(GL_BGRA_EXT);
accepted_types.push_back(GL_UNSIGNED_BYTE);
}
Expand Down Expand Up @@ -9507,7 +9501,7 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
case GL_VENDOR:
// Return the unmasked VENDOR/RENDERER string for WebGL contexts.
// They are used by WEBGL_debug_renderer_info.
if (!IsWebGLContext())
if (!feature_info_->IsWebGLContext())
str = "Chromium";
else
str = reinterpret_cast<const char*>(glGetString(name));
Expand All @@ -9516,7 +9510,7 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
{
// For WebGL contexts, strip out the OES derivatives and
// EXT frag depth extensions if they have not been enabled.
if (IsWebGLContext()) {
if (feature_info_->IsWebGLContext()) {
extensions = feature_info_->extensions();
if (!derivatives_explicitly_enabled_) {
size_t offset = extensions.find(kOESDerivativeExtension);
Expand Down Expand Up @@ -11963,7 +11957,7 @@ error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
cmd_data);
Bucket* bucket = CreateBucket(c.bucket_id);
scoped_refptr<FeatureInfo> info(new FeatureInfo());
info->Initialize(disallowed_features_);
info->Initialize(feature_info_->context_type(), disallowed_features_);
bucket->SetFromString(info->extensions().c_str());
return error::kNoError;
}
Expand All @@ -11986,7 +11980,7 @@ error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
bool desire_frag_depth = false;
bool desire_draw_buffers = false;
bool desire_shader_texture_lod = false;
if (IsWebGLContext()) {
if (feature_info_->IsWebGLContext()) {
desire_standard_derivatives =
feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
desire_frag_depth =
Expand Down

0 comments on commit ed27437

Please sign in to comment.