Move clear-as-draw caps into GrCaps

Bug: skia:
Change-Id: Ib029f337f5e61366e2550e77dc99310b44d03f84
Reviewed-on: https://skia-review.googlesource.com/c/182970
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Michael Ludwig 2019-01-11 15:26:22 -05:00 committed by Skia Commit-Bot
parent 69802c4704
commit a21d196602
9 changed files with 67 additions and 51 deletions

View File

@ -140,10 +140,9 @@ struct GrContextOptions {
bool fSharpenMipmappedTextures = false;
/**
* Enables driver workaround to use draws instead of glClear. This only applies to
* GrBackendApi::kOpenGL.
* Enables driver workaround to use draws instead of HW clears, e.g. glClear on the GL backend.
*/
Enable fUseDrawInsteadOfGLClear = Enable::kDefault;
Enable fUseDrawInsteadOfClear = Enable::kDefault;
/**
* Allow Ganesh to explicitly allocate resources at flush time rather than incrementally while

View File

@ -38,6 +38,9 @@ GrCaps::GrCaps(const GrContextOptions& options) {
fCrossContextTextureSupport = false;
fHalfFloatVertexAttributeSupport = false;
fDynamicStateArrayGeometryProcessorTextureSupport = false;
fPerformPartialClearsAsDraws = false;
fPerformColorClearsAsDraws = false;
fPerformStencilClearsAsDraws = false;
fBlendEquationSupport = kBasic_BlendEquationSupport;
fAdvBlendEqBlacklist = 0;
@ -86,6 +89,17 @@ void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
// SkASSERT(!fBlacklistCoverageCounting);
SkASSERT(!fAvoidStencilBuffers);
SkASSERT(!fAdvBlendEqBlacklist);
SkASSERT(!fPerformColorClearsAsDraws);
SkASSERT(!fPerformStencilClearsAsDraws);
// Don't check the partial-clear workaround, since that is a backend limitation, not a
// driver workaround (it just so happens the fallbacks are the same).
}
if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfClear) {
fPerformColorClearsAsDraws = false;
fPerformStencilClearsAsDraws = false;
} else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfClear) {
fPerformColorClearsAsDraws = true;
fPerformStencilClearsAsDraws = true;
}
fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride);
@ -186,6 +200,10 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
writer->appendBool("Half float vertex attribute support", fHalfFloatVertexAttributeSupport);
writer->appendBool("Specify GeometryProcessor textures as a dynamic state array",
fDynamicStateArrayGeometryProcessorTextureSupport);
writer->appendBool("Use draws for partial clears", fPerformPartialClearsAsDraws);
writer->appendBool("Use draws for color clears", fPerformColorClearsAsDraws);
writer->appendBool("Use draws for stencil clip clears", fPerformStencilClearsAsDraws);
writer->appendBool("Clamp-to-border", fClampToBorderSupport);
writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
fBlacklistCoverageCounting);

View File

@ -251,8 +251,23 @@ public:
return fDynamicStateArrayGeometryProcessorTextureSupport;
}
virtual bool performPartialClearsAsDraws() const {
return false;
// Not all backends support clearing with a scissor test (e.g. Metal).
// FIXME(michaelludwig): This should always return true if performColorClearsAsDraws() returns
// true, but the current partial-clear code doesn't handle transparent clear colors correctly
bool performPartialClearsAsDraws() const {
return fPerformPartialClearsAsDraws;
}
// Many drivers have issues with color clears.
bool performColorClearsAsDraws() const {
return fPerformColorClearsAsDraws;
}
/// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
/// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
/// op instead of using glClear seems to resolve the issue.
bool performStencilClearsAsDraws() const {
return fPerformStencilClearsAsDraws;
}
/**
@ -331,6 +346,9 @@ protected:
bool fSupportsAHardwareBufferImages : 1;
bool fHalfFloatVertexAttributeSupport : 1;
bool fClampToBorderSupport : 1;
bool fPerformPartialClearsAsDraws : 1;
bool fPerformColorClearsAsDraws : 1;
bool fPerformStencilClearsAsDraws : 1;
// Driver workaround
bool fBlacklistCoverageCounting : 1;

View File

@ -61,8 +61,6 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
fClearToBoundaryValuesIsBroken = false;
fClearTextureSupport = false;
fDrawArraysBaseVertexIsBroken = false;
fUseDrawToClearColor = false;
fUseDrawToClearStencilClip = false;
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
fUseDrawInsteadOfAllRenderTargetWrites = false;
fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
@ -1155,8 +1153,7 @@ void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
writer->appendBool("BGRA to RGBA readback conversions are slow",
fRGBAToBGRAReadbackConversionsAreSlow);
writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
writer->appendBool("Draw To clear color", fUseDrawToClearColor);
writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
@ -2428,14 +2425,14 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
(kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
ctxInfo.driver() != kChromium_GrGLDriver)) {
fUseDrawToClearColor = true;
fPerformColorClearsAsDraws = true;
}
#endif
// A lot of GPUs have trouble with full screen clears (skbug.com/7195)
if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
fUseDrawToClearColor = true;
fPerformColorClearsAsDraws = true;
}
#ifdef SK_BUILD_FOR_MAC
@ -2447,7 +2444,7 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
// Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
if (kIntel_GrGLVendor == ctxInfo.vendor() &&
ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
fUseDrawToClearColor = true;
fPerformColorClearsAsDraws = true;
}
#endif
@ -2456,21 +2453,21 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
// See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
// but only for D3D11 ANGLE.
if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
fUseDrawToClearColor = true;
fPerformColorClearsAsDraws = true;
}
if (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||
kAdreno4xx_other_GrGLRenderer == ctxInfo.renderer()) {
// This is known to be fixed sometime between driver 145.0 and 219.0
if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
fUseDrawToClearStencilClip = true;
fPerformStencilClearsAsDraws = true;
}
fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
}
if (fDriverBugWorkarounds.gl_clear_broken) {
fUseDrawToClearColor = true;
fUseDrawToClearStencilClip = true;
fPerformColorClearsAsDraws = true;
fPerformStencilClearsAsDraws = true;
}
// This was reproduced on the following configurations:
@ -2755,18 +2752,11 @@ void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
SkASSERT(!fClearToBoundaryValuesIsBroken);
SkASSERT(0 == fMaxInstancesPerDrawWithoutCrashing);
SkASSERT(!fDrawArraysBaseVertexIsBroken);
SkASSERT(!fUseDrawToClearColor);
SkASSERT(!fUseDrawToClearStencilClip);
SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
SkASSERT(!fDetachStencilFromMSAABuffersBeforeReadPixels);
}
if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
fUseDrawToClearColor = false;
} else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
fUseDrawToClearColor = true;
}
if (options.fDoManualMipmapping) {
fDoManualMipmapping = true;
}

View File

@ -355,14 +355,6 @@ public:
// https://bugs.chromium.org/p/skia/issues/detail?id=6650
bool drawArraysBaseVertexIsBroken() const { return fDrawArraysBaseVertexIsBroken; }
// Many drivers have issues with color clears.
bool useDrawToClearColor() const { return fUseDrawToClearColor; }
/// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
/// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
/// op instead of using glClear seems to resolve the issue.
bool useDrawToClearStencilClip() const { return fUseDrawToClearStencilClip; }
// If true then we must use an intermediate surface to perform partial updates to unorm textures
// that have ever been bound to a FBO.
bool disallowTexSubImageForUnormConfigTexturesEverBoundToFBO() const {
@ -513,8 +505,6 @@ private:
bool fDoManualMipmapping : 1;
bool fClearToBoundaryValuesIsBroken : 1;
bool fDrawArraysBaseVertexIsBroken : 1;
bool fUseDrawToClearColor : 1;
bool fUseDrawToClearStencilClip : 1;
bool fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO : 1;
bool fUseDrawInsteadOfAllRenderTargetWrites : 1;
bool fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines : 1;

View File

@ -2009,7 +2009,7 @@ void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color,
this->handleDirtyContext();
if (this->glCaps().useDrawToClearColor()) {
if (this->caps()->performColorClearsAsDraws()) {
this->clearColorAsDraw(clip, color, target, origin);
return;
}
@ -2070,7 +2070,7 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
SkASSERT(target);
this->handleDirtyContext();
if (this->glCaps().useDrawToClearStencilClip()) {
if (this->caps()->performStencilClearsAsDraws()) {
this->clearStencilClipAsDraw(clip, insideStencilMask, target, origin);
return;
}

View File

@ -78,10 +78,6 @@ public:
GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
GrSRGBEncoded srgbEncoded) const override;
bool performPartialClearsAsDraws() const override {
return true;
}
private:
void initFeatureSet(MTLFeatureSet featureSet);

View File

@ -195,6 +195,9 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
// Max vertex attribs is the same on all devices
fMaxVertexAttributes = 31;
// Metal does not support scissor + clear
fPerformPartialClearsAsDraws = true;
// RenderTarget and Texture size
if (this->isMac()) {
fMaxRenderTargetSize = 16384;

View File

@ -225,13 +225,14 @@ static void clear_op_test(skiatest::Reporter* reporter, GrContext* context) {
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ClearOp, reporter, ctxInfo) {
// Regular clear
clear_op_test(reporter, ctxInfo.grContext());
if (ctxInfo.backend() == GrBackendApi::kOpenGL) {
GrContextOptions options(ctxInfo.options());
options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
sk_gpu_test::GrContextFactory workaroundFactory(options);
clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
}
// Force drawing for clears
GrContextOptions options(ctxInfo.options());
options.fUseDrawInsteadOfClear = GrContextOptions::Enable::kYes;
sk_gpu_test::GrContextFactory workaroundFactory(options);
clear_op_test(reporter, workaroundFactory.get(ctxInfo.type()));
}
void fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrContext* context) {
@ -290,11 +291,12 @@ void fullscreen_clear_with_layer_test(skiatest::Reporter* reporter, GrContext* c
}
// From crbug.com/768134
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FullScreenClearWithLayers, reporter, ctxInfo) {
// Regular clear
fullscreen_clear_with_layer_test(reporter, ctxInfo.grContext());
if (ctxInfo.backend() == GrBackendApi::kOpenGL) {
GrContextOptions options(ctxInfo.options());
options.fUseDrawInsteadOfGLClear = GrContextOptions::Enable::kYes;
sk_gpu_test::GrContextFactory workaroundFactory(options);
fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
}
// Use draws for clears
GrContextOptions options(ctxInfo.options());
options.fUseDrawInsteadOfClear = GrContextOptions::Enable::kYes;
sk_gpu_test::GrContextFactory workaroundFactory(options);
fullscreen_clear_with_layer_test(reporter, workaroundFactory.get(ctxInfo.type()));
}