blob: fd4345b5b3601e003f975bb4cf82bdbbf917e032 [file] [log] [blame]
egdaniel9cb63402016-06-23 08:37:05 -07001/*
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 Daniel2d41d0d2019-08-26 11:08:51 -04008#include "src/gpu/GrOpsRenderPass.h"
egdaniel9cb63402016-06-23 08:37:05 -07009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkRect.h"
11#include "include/gpu/GrContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#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 Phillips901aff02019-10-08 12:32:56 -040018#include "src/gpu/GrProgramInfo.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040019#include "src/gpu/GrRenderTarget.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "src/gpu/GrRenderTargetPriv.h"
Chris Dalton4ece96d2019-08-30 11:26:39 -060021#include "src/gpu/GrTexturePriv.h"
egdaniel9cb63402016-06-23 08:37:05 -070022
Greg Daniel2d41d0d2019-08-26 11:08:51 -040023void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
Robert Phillips4912d902018-04-27 12:09:35 -040024 SkASSERT(fRenderTarget);
Michael Ludwigc39d0c82019-01-15 10:03:43 -050025 // 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 Phillips19e51dc2017-08-09 09:30:51 -040029 this->onClear(clip, color);
egdaniel9cb63402016-06-23 08:37:05 -070030}
31
Greg Daniel2d41d0d2019-08-26 11:08:51 -040032void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Michael Ludwigc39d0c82019-01-15 10:03:43 -050033 // 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 Phillips19e51dc2017-08-09 09:30:51 -040035 this->onClearStencilClip(clip, insideStencilMask);
egdaniel9cb63402016-06-23 08:37:05 -070036}
37
Chris Dalton4ece96d2019-08-30 11:26:39 -060038#ifdef SK_DEBUG
Robert Phillips901aff02019-10-08 12:32:56 -040039static void assert_msaa_and_mips_are_resolved(const GrProgramInfo& programInfo, int meshCount) {
Chris Dalton4ece96d2019-08-30 11:26:39 -060040 auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) {
41 SkASSERT(tex);
42
Chris Dalton4ece96d2019-08-30 11:26:39 -060043 // 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 Phillips901aff02019-10-08 12:32:56 -040053 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 Dalton4ece96d2019-08-30 11:26:39 -060060 }
61 }
Robert Phillips901aff02019-10-08 12:32:56 -040062 } 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 Dalton4ece96d2019-08-30 11:26:39 -060068 }
69 }
70
Robert Phillips901aff02019-10-08 12:32:56 -040071 GrFragmentProcessor::Iter iter(programInfo.pipeline());
Chris Dalton4ece96d2019-08-30 11:26:39 -060072 while (const GrFragmentProcessor* fp = iter.next()) {
Robert Phillips901aff02019-10-08 12:32:56 -040073 for (int s = 0; s < fp->numTextureSamplers(); ++s) {
74 const auto& textureSampler = fp->textureSampler(s);
Chris Dalton4ece96d2019-08-30 11:26:39 -060075 assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
76 }
77 }
78}
79#endif
80
Robert Phillips901aff02019-10-08 12:32:56 -040081bool GrOpsRenderPass::draw(const GrProgramInfo& programInfo,
Greg Daniel2d41d0d2019-08-26 11:08:51 -040082 const GrMesh meshes[], int meshCount, const SkRect& bounds) {
Robert Phillips901aff02019-10-08 12:32:56 -040083 if (!meshCount) {
84 return true;
85 }
86
Chris Daltonbca46e22017-05-15 11:03:26 -060087#ifdef SK_DEBUG
Robert Phillips901aff02019-10-08 12:32:56 -040088 SkASSERT(!programInfo.primProc().hasInstanceAttributes() ||
89 this->gpu()->caps()->instanceAttribSupport());
Chris Daltonbca46e22017-05-15 11:03:26 -060090 for (int i = 0; i < meshCount; ++i) {
Robert Phillips901aff02019-10-08 12:32:56 -040091 SkASSERT(programInfo.primProc().hasVertexAttributes() == meshes[i].hasVertexData());
92 SkASSERT(programInfo.primProc().hasInstanceAttributes() == meshes[i].hasInstanceData());
Chris Daltonbca46e22017-05-15 11:03:26 -060093 }
Chris Dalton4ece96d2019-08-30 11:26:39 -060094
Robert Phillips901aff02019-10-08 12:32:56 -040095 SkASSERT(!programInfo.pipeline().isScissorEnabled() || programInfo.fixedDynamicState() ||
96 (programInfo.dynamicStateArrays() && programInfo.dynamicStateArrays()->fScissorRects));
Brian Salomon49348902018-06-26 09:12:38 -040097
Robert Phillips901aff02019-10-08 12:32:56 -040098 SkASSERT(!programInfo.pipeline().isBad());
Robert Phillips82774f82019-06-20 14:38:27 -040099
Robert Phillips901aff02019-10-08 12:32:56 -0400100 if (programInfo.hasFixedPrimProcTextures()) {
101 auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
102 for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
103 SkASSERT(fixedPrimProcTextures[s]->isInstantiated());
Brian Salomonf7232642018-09-19 08:58:08 -0400104 }
105 }
Robert Phillips901aff02019-10-08 12:32:56 -0400106
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 Salomon7eae3e02018-08-07 14:02:38 +0000113 }
Robert Phillips901aff02019-10-08 12:32:56 -0400114
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 Daniel9a51a862018-11-30 10:18:14 -0500128 SkASSERT(testProxy->backendFormat() == format);
129 SkASSERT(testProxy->textureType() == type);
130 SkASSERT(testProxy->config() == config);
131 }
132 }
Brian Salomon7eae3e02018-08-07 14:02:38 +0000133 }
Chris Dalton4ece96d2019-08-30 11:26:39 -0600134
Robert Phillips901aff02019-10-08 12:32:56 -0400135 assert_msaa_and_mips_are_resolved(programInfo, meshCount);
Robert Phillips12c46292019-04-23 07:36:17 -0400136#endif
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400137
Robert Phillips901aff02019-10-08 12:32:56 -0400138 if (programInfo.primProc().numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
egdaniel9cb63402016-06-23 08:37:05 -0700139 this->gpu()->stats()->incNumFailedDraws();
140 return false;
141 }
Robert Phillips901aff02019-10-08 12:32:56 -0400142 this->onDraw(programInfo, meshes, meshCount, bounds);
143
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600144#ifdef SK_DEBUG
Robert Phillips901aff02019-10-08 12:32:56 -0400145 GrProcessor::CustomFeatures processorFeatures = programInfo.requestedFeatures();
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600146 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
egdaniel9cb63402016-06-23 08:37:05 -0700152 return true;
153}