On Mali-TXXX driver version <= 1.26 rebind color target after

glCheckFramebufferStatus.

Bug: skia:12640

Change-Id: If51a62bbe6d512aae2af51437871fe99fe0e24b7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470462
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2021-11-12 15:06:34 -05:00 committed by SkCQ
parent 6388f0e8ef
commit babbec12ff
6 changed files with 82 additions and 10 deletions

View File

@ -61,6 +61,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
fDisallowDynamicMSAA = false;
fMustResetBlendFuncBetweenDualSourceAndDisable = false;
fBindTexture0WhenChangingTextureFBOMultisampleCount = false;
fRebindColorAttachmentAfterCheckFramebufferStatus = false;
fProgramBinarySupport = false;
fProgramParameterSupport = false;
fSamplerObjectSupport = false;
@ -4258,23 +4259,23 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
// non-MSAA we get corruption in the texture contents. Binding texture 0 and then rebinding the
// original texture avoids this.
// This was found on Nexus 5, Android 6.0.1, build M4B30Z
// GL_VENDOR: "Qualcomm"
// GL_VENDOR : "Qualcomm"
// GL_RENDERER: "Adreno (TM) 330"
// GL_VERSION: "OpenGL ES 3.0 V@127.0 AU@ (GIT@I96aee987eb)"
// GL_VERSION : "OpenGL ES 3.0 V@127.0 AU@ (GIT@I96aee987eb)"
//
// We also so alpha blending issues on these GMs skbug_9819, p3_ovals, p3 on Mali-Gxx devices
// The GM issues were observed on a Galaxy S9 running Android 10:
// GL_VERSION: "OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###"
// GL_VERSION : "OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###"
// GL_RENDERER: "Mali-G72"
// GL_VENDOR: "ARM"
// GL_VENDOR : "ARM"
// and a P30 running Android 9:
// GL_VERSION: "OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5"
// GL_VERSION : "OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5"
// GL_RENDERER: "Mali-G76"
// GL_VENDOR: "ARM"
// GL_VENDOR : "ARM"
// but *not* a Galaxy S20 running Android 10:
// GL_VERSION: "OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###"
// GL_VERSION : "OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###"
// GL_RENDERER: "Mali-G77"
// GL_VENDOR: "ARM"
// GL_VENDOR : "ARM"
// It's unclear if the difference is driver version or Bifrost vs Valhall. The workaround is
// fairly trivial so just applying to all Bifrost and Valhall.
if ((ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
@ -4282,6 +4283,25 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
(ctxInfo.renderer() == GrGLRenderer::kMaliG)) {
fBindTexture0WhenChangingTextureFBOMultisampleCount = true;
}
// skbug.com/12640
// We found that on the Galaxy S7 the TransferPixelsTo test would fail after adding
// glCheckFramebufferStatus() checks when making new FBOs. Note that the returned status was
// GL_FRAMEBUFFER_COMPLETE. Switching the color binding to ID 0 and back to the original
// afterwards works around the issue.
// GL_VENDOR : "ARM"
// GL_RENDERER: "Mali-T880"
// GL_VERSION : "OpenGL ES 3.2 v1.r22p0-01rel0.f294e54ceb2cb2d81039204fa4b0402e"
//
// This *didn't* reproduce on a Kevin ChromeOS device:
// GL_VENDOR : "ARM"
// GL_RENDERER: "Mali-T860"
// GL_VERSION : "OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3"
if (ctxInfo.renderer() == GrGLRenderer::kMaliT &&
ctxInfo.driver() == GrGLDriver::kARM &&
ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 26, 0)) {
fRebindColorAttachmentAfterCheckFramebufferStatus = true;
}
}
void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {

View File

@ -417,6 +417,12 @@ public:
return fBindTexture0WhenChangingTextureFBOMultisampleCount;
}
// After using glCheckFramebufferStatus() bind 0 to the color attachment and then rebind the
// original color attachment.
bool rebindColorAttachmentAfterCheckFramebufferStatus() const {
return fRebindColorAttachmentAfterCheckFramebufferStatus;
}
// Returns the observed maximum number of instances the driver can handle in a single draw call
// without crashing, or 'pendingInstanceCount' if this workaround is not necessary.
// NOTE: the return value may be larger than pendingInstanceCount.
@ -592,6 +598,7 @@ private:
bool fDisallowDynamicMSAA : 1;
bool fMustResetBlendFuncBetweenDualSourceAndDisable : 1;
bool fBindTexture0WhenChangingTextureFBOMultisampleCount : 1;
bool fRebindColorAttachmentAfterCheckFramebufferStatus : 1;
int fMaxInstancesPerDrawWithoutCrashing = 0;
uint32_t fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;

View File

@ -1265,6 +1265,16 @@ bool GrGLGpu::createRenderTargetObjects(const GrGLTexture::Desc& desc,
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
return false;
}
if (this->glCaps().rebindColorAttachmentAfterCheckFramebufferStatus()) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
GR_GL_RENDERBUFFER,
0));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
GR_GL_RENDERBUFFER,
rtIDs->fMSColorRenderbufferID));
}
}
rtIDs->fTotalMemorySamplesPerPixel += sampleCount;
}
@ -1281,6 +1291,18 @@ bool GrGLGpu::createRenderTargetObjects(const GrGLTexture::Desc& desc,
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
return false;
}
if (this->glCaps().rebindColorAttachmentAfterCheckFramebufferStatus()) {
GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
desc.fTarget,
0,
0));
GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
desc.fTarget,
desc.fID,
0));
}
}
++rtIDs->fTotalMemorySamplesPerPixel;
@ -2231,7 +2253,9 @@ void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target, bool useM
// lots of repeated command buffer flushes when the compositor is
// rendering with Ganesh, which is really slow; even too slow for
// Debug mode.
if (!this->glCaps().skipErrorChecks()) {
// Also don't do this when we know glCheckFramebufferStatus() may have side effects.
if (!this->glCaps().skipErrorChecks() &&
!this->glCaps().rebindColorAttachmentAfterCheckFramebufferStatus()) {
GrGLenum status;
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {

View File

@ -247,7 +247,8 @@ void GrGLRenderTarget::bindInternal(GrGLenum fboTarget, bool useMultisampleFBO)
0));
}
#ifdef SK_DEBUG
if (!this->getGLGpu()->glCaps().skipErrorChecks()) {
if (!this->getGLGpu()->glCaps().skipErrorChecks() &&
!this->getGLGpu()->glCaps().rebindColorAttachmentAfterCheckFramebufferStatus()) {
GrGLenum status;
GL_CALL_RET(status, CheckFramebufferStatus(fboTarget));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {

View File

@ -519,6 +519,25 @@ static std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStan
// doesn't fit into the 'patch' bits, so omit it until we need it.
driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
}
} else if (vendor == GrGLVendor::kARM) {
// Example:
// OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3
// It's unclear how to interpret what comes between "p" and "rel". Every string we've
// seen so far has "0-01" there. We ignore it for now.
int ignored0;
int ignored1;
int n = sscanf(versionString,
"OpenGL ES %d.%d v%d.r%dp%d-%drel",
&major,
&minor,
&driverMajor,
&driverMinor,
&ignored0,
&ignored1);
if (n == 6) {
driver = GrGLDriver::kARM;
driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
}
} else {
static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {

View File

@ -214,6 +214,7 @@ enum class GrGLDriver {
kFreedreno,
kAndroidEmulator,
kImagination,
kARM,
kUnknown
};