egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
Greg Daniel | 2d41d0d | 2019-08-26 11:08:51 -0400 | [diff] [blame] | 8 | #include "src/gpu/GrOpsRenderPass.h" |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 9 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 10 | #include "include/core/SkRect.h" |
| 11 | #include "include/gpu/GrContext.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 12 | #include "src/gpu/GrCaps.h" |
| 13 | #include "src/gpu/GrContextPriv.h" |
| 14 | #include "src/gpu/GrFixedClip.h" |
| 15 | #include "src/gpu/GrGpu.h" |
| 16 | #include "src/gpu/GrMesh.h" |
| 17 | #include "src/gpu/GrPrimitiveProcessor.h" |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 18 | #include "src/gpu/GrProgramInfo.h" |
Brian Salomon | 201cdbb | 2019-08-14 17:00:30 -0400 | [diff] [blame] | 19 | #include "src/gpu/GrRenderTarget.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 20 | #include "src/gpu/GrRenderTargetPriv.h" |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 21 | #include "src/gpu/GrTexturePriv.h" |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 22 | |
Greg Daniel | 2d41d0d | 2019-08-26 11:08:51 -0400 | [diff] [blame] | 23 | void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) { |
Robert Phillips | 4912d90 | 2018-04-27 12:09:35 -0400 | [diff] [blame] | 24 | SkASSERT(fRenderTarget); |
Michael Ludwig | c39d0c8 | 2019-01-15 10:03:43 -0500 | [diff] [blame] | 25 | // A clear at this level will always be a true clear, so make sure clears were not supposed to |
| 26 | // be redirected to draws instead |
| 27 | SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws()); |
| 28 | SkASSERT(!clip.scissorEnabled() || !this->gpu()->caps()->performPartialClearsAsDraws()); |
Robert Phillips | 19e51dc | 2017-08-09 09:30:51 -0400 | [diff] [blame] | 29 | this->onClear(clip, color); |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 30 | } |
| 31 | |
Greg Daniel | 2d41d0d | 2019-08-26 11:08:51 -0400 | [diff] [blame] | 32 | void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { |
Michael Ludwig | c39d0c8 | 2019-01-15 10:03:43 -0500 | [diff] [blame] | 33 | // As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings |
| 34 | SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws()); |
Robert Phillips | 19e51dc | 2017-08-09 09:30:51 -0400 | [diff] [blame] | 35 | this->onClearStencilClip(clip, insideStencilMask); |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 36 | } |
| 37 | |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 38 | #ifdef SK_DEBUG |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 39 | static void assert_msaa_and_mips_are_resolved(const GrProgramInfo& programInfo, int meshCount) { |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 40 | auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) { |
| 41 | SkASSERT(tex); |
| 42 | |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 43 | // Ensure mipmaps were all resolved ahead of time by the DAG. |
| 44 | if (GrSamplerState::Filter::kMipMap == sampler.filter() && |
| 45 | (tex->width() != 1 || tex->height() != 1)) { |
| 46 | // There are some cases where we might be given a non-mipmapped texture with a mipmap |
| 47 | // filter. See skbug.com/7094. |
| 48 | SkASSERT(tex->texturePriv().mipMapped() != GrMipMapped::kYes || |
| 49 | !tex->texturePriv().mipMapsAreDirty()); |
| 50 | } |
| 51 | }; |
| 52 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 53 | if (programInfo.hasDynamicPrimProcTextures()) { |
| 54 | for (int m = 0; m < meshCount; ++m) { |
| 55 | auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m); |
| 56 | |
| 57 | for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) { |
| 58 | auto* tex = dynamicPrimProcTextures[s]->peekTexture(); |
| 59 | assertResolved(tex, programInfo.primProc().textureSampler(s).samplerState()); |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 60 | } |
| 61 | } |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 62 | } else if (programInfo.hasFixedPrimProcTextures()) { |
| 63 | auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures(); |
| 64 | |
| 65 | for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) { |
| 66 | auto* tex = fixedPrimProcTextures[s]->peekTexture(); |
| 67 | assertResolved(tex, programInfo.primProc().textureSampler(s).samplerState()); |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 68 | } |
| 69 | } |
| 70 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 71 | GrFragmentProcessor::Iter iter(programInfo.pipeline()); |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 72 | while (const GrFragmentProcessor* fp = iter.next()) { |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 73 | for (int s = 0; s < fp->numTextureSamplers(); ++s) { |
| 74 | const auto& textureSampler = fp->textureSampler(s); |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 75 | assertResolved(textureSampler.peekTexture(), textureSampler.samplerState()); |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | #endif |
| 80 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 81 | bool GrOpsRenderPass::draw(const GrProgramInfo& programInfo, |
Greg Daniel | 2d41d0d | 2019-08-26 11:08:51 -0400 | [diff] [blame] | 82 | const GrMesh meshes[], int meshCount, const SkRect& bounds) { |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 83 | if (!meshCount) { |
| 84 | return true; |
| 85 | } |
| 86 | |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 87 | #ifdef SK_DEBUG |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 88 | SkASSERT(!programInfo.primProc().hasInstanceAttributes() || |
| 89 | this->gpu()->caps()->instanceAttribSupport()); |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 90 | for (int i = 0; i < meshCount; ++i) { |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 91 | SkASSERT(programInfo.primProc().hasVertexAttributes() == meshes[i].hasVertexData()); |
| 92 | SkASSERT(programInfo.primProc().hasInstanceAttributes() == meshes[i].hasInstanceData()); |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 93 | } |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 94 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 95 | SkASSERT(!programInfo.pipeline().isScissorEnabled() || programInfo.fixedDynamicState() || |
| 96 | (programInfo.dynamicStateArrays() && programInfo.dynamicStateArrays()->fScissorRects)); |
Brian Salomon | 4934890 | 2018-06-26 09:12:38 -0400 | [diff] [blame] | 97 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 98 | SkASSERT(!programInfo.pipeline().isBad()); |
Robert Phillips | 82774f8 | 2019-06-20 14:38:27 -0400 | [diff] [blame] | 99 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 100 | if (programInfo.hasFixedPrimProcTextures()) { |
| 101 | auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures(); |
| 102 | for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) { |
| 103 | SkASSERT(fixedPrimProcTextures[s]->isInstantiated()); |
Brian Salomon | f723264 | 2018-09-19 08:58:08 -0400 | [diff] [blame] | 104 | } |
| 105 | } |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 106 | |
| 107 | if (programInfo.hasDynamicPrimProcTextures()) { |
| 108 | for (int m = 0; m < meshCount; ++m) { |
| 109 | auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m); |
| 110 | for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) { |
| 111 | SkASSERT(dynamicPrimProcTextures[s]->isInstantiated()); |
| 112 | } |
Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 113 | } |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 114 | |
| 115 | // Check that, for a given sampler, the properties of the dynamic textures remain |
| 116 | // the same for all the meshes |
| 117 | for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) { |
| 118 | auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(0); |
| 119 | |
| 120 | const GrBackendFormat& format = dynamicPrimProcTextures[s]->backendFormat(); |
| 121 | GrTextureType type = dynamicPrimProcTextures[s]->textureType(); |
| 122 | GrPixelConfig config = dynamicPrimProcTextures[s]->config(); |
| 123 | |
| 124 | for (int m = 1; m < meshCount; ++m) { |
| 125 | dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m); |
| 126 | |
| 127 | auto testProxy = dynamicPrimProcTextures[s]; |
Greg Daniel | 9a51a86 | 2018-11-30 10:18:14 -0500 | [diff] [blame] | 128 | SkASSERT(testProxy->backendFormat() == format); |
| 129 | SkASSERT(testProxy->textureType() == type); |
| 130 | SkASSERT(testProxy->config() == config); |
| 131 | } |
| 132 | } |
Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 133 | } |
Chris Dalton | 4ece96d | 2019-08-30 11:26:39 -0600 | [diff] [blame] | 134 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 135 | assert_msaa_and_mips_are_resolved(programInfo, meshCount); |
Robert Phillips | 12c4629 | 2019-04-23 07:36:17 -0400 | [diff] [blame] | 136 | #endif |
Robert Phillips | a91e0b7 | 2017-05-01 13:12:20 -0400 | [diff] [blame] | 137 | |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 138 | if (programInfo.primProc().numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) { |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 139 | this->gpu()->stats()->incNumFailedDraws(); |
| 140 | return false; |
| 141 | } |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 142 | this->onDraw(programInfo, meshes, meshCount, bounds); |
| 143 | |
Chris Dalton | 8c4cafd | 2019-04-15 19:14:36 -0600 | [diff] [blame] | 144 | #ifdef SK_DEBUG |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame^] | 145 | GrProcessor::CustomFeatures processorFeatures = programInfo.requestedFeatures(); |
Chris Dalton | 8c4cafd | 2019-04-15 19:14:36 -0600 | [diff] [blame] | 146 | if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) { |
| 147 | // Verify we always have the same sample pattern key, regardless of graphics state. |
| 148 | SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget) |
| 149 | == fRenderTarget->renderTargetPriv().getSamplePatternKey()); |
| 150 | } |
| 151 | #endif |
egdaniel | 9cb6340 | 2016-06-23 08:37:05 -0700 | [diff] [blame] | 152 | return true; |
| 153 | } |