Initiate MSAA resolves during DAG generation
Adds an "fIsMSAADirty" flag to GrRenderTargetProxy and switches to
resolving MSAA in GrTextureResolveRenderTask. This completes our push
to resolve textures outside of render passes.
For the time being, we only store a dirty flag on the proxy and still
rely on the GrRenderTarget itself to track the actual dirty rect. This
will be followed by a CL that moves the dirty rect out of
GrRenderTarget and into the proxy.
Bug: skia:
Change-Id: I21219a58028bdb4590940210e565133093cd34b3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235672
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp
index 3876a42..dcc53b6 100644
--- a/src/gpu/GrOpsRenderPass.cpp
+++ b/src/gpu/GrOpsRenderPass.cpp
@@ -17,6 +17,7 @@
#include "src/gpu/GrPrimitiveProcessor.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrRenderTargetPriv.h"
+#include "src/gpu/GrTexturePriv.h"
void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
SkASSERT(fRenderTarget);
@@ -33,6 +34,51 @@
this->onClearStencilClip(clip, insideStencilMask);
}
+#ifdef SK_DEBUG
+static void assert_msaa_and_mips_are_resolved(
+ const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays, int meshCount) {
+ auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) {
+ SkASSERT(tex);
+
+ // Ensure msaa was resolved ahead of time by the DAG.
+ SkASSERT(!tex->asRenderTarget() || !tex->asRenderTarget()->needsResolve());
+
+ // Ensure mipmaps were all resolved ahead of time by the DAG.
+ if (GrSamplerState::Filter::kMipMap == sampler.filter() &&
+ (tex->width() != 1 || tex->height() != 1)) {
+ // There are some cases where we might be given a non-mipmapped texture with a mipmap
+ // filter. See skbug.com/7094.
+ SkASSERT(tex->texturePriv().mipMapped() != GrMipMapped::kYes ||
+ !tex->texturePriv().mipMapsAreDirty());
+ }
+ };
+
+ if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
+ for (int m = 0, i = 0; m < meshCount; ++m) {
+ for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
+ auto* tex = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
+ assertResolved(tex, primProc.textureSampler(s).samplerState());
+ }
+ }
+ } else {
+ for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
+ auto* tex = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
+ assertResolved(tex, primProc.textureSampler(i).samplerState());
+ }
+ }
+
+ GrFragmentProcessor::Iter iter(pipeline);
+ while (const GrFragmentProcessor* fp = iter.next()) {
+ for (int i = 0; i < fp->numTextureSamplers(); ++i) {
+ const auto& textureSampler = fp->textureSampler(i);
+ assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
+ }
+ }
+}
+#endif
+
bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
@@ -45,13 +91,12 @@
SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
SkASSERT(primProc.hasInstanceAttributes() == meshes[i].hasInstanceData());
}
-#endif
+
SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
(dynamicStateArrays && dynamicStateArrays->fScissorRects));
SkASSERT(!pipeline.isBad());
-#ifdef SK_DEBUG
if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
@@ -80,6 +125,9 @@
}
}
}
+
+ assert_msaa_and_mips_are_resolved(
+ primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount);
#endif
if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {