blob: 37284266e5634cbdb1f815541432ed9e4191d5f5 [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"
Brian Salomon201cdbb2019-08-14 17:00:30 -040018#include "src/gpu/GrRenderTarget.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/gpu/GrRenderTargetPriv.h"
Chris Dalton4ece96d2019-08-30 11:26:39 -060020#include "src/gpu/GrTexturePriv.h"
egdaniel9cb63402016-06-23 08:37:05 -070021
Greg Daniel2d41d0d2019-08-26 11:08:51 -040022void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
Robert Phillips4912d902018-04-27 12:09:35 -040023 SkASSERT(fRenderTarget);
Michael Ludwigc39d0c82019-01-15 10:03:43 -050024 // A clear at this level will always be a true clear, so make sure clears were not supposed to
25 // be redirected to draws instead
26 SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws());
27 SkASSERT(!clip.scissorEnabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
Robert Phillips19e51dc2017-08-09 09:30:51 -040028 this->onClear(clip, color);
egdaniel9cb63402016-06-23 08:37:05 -070029}
30
Greg Daniel2d41d0d2019-08-26 11:08:51 -040031void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Michael Ludwigc39d0c82019-01-15 10:03:43 -050032 // As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings
33 SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws());
Robert Phillips19e51dc2017-08-09 09:30:51 -040034 this->onClearStencilClip(clip, insideStencilMask);
egdaniel9cb63402016-06-23 08:37:05 -070035}
36
Chris Dalton4ece96d2019-08-30 11:26:39 -060037#ifdef SK_DEBUG
38static void assert_msaa_and_mips_are_resolved(
39 const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
40 const GrPipeline::FixedDynamicState* fixedDynamicState,
41 const GrPipeline::DynamicStateArrays* dynamicStateArrays, int meshCount) {
42 auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) {
43 SkASSERT(tex);
44
Chris Dalton4ece96d2019-08-30 11:26:39 -060045 // Ensure mipmaps were all resolved ahead of time by the DAG.
46 if (GrSamplerState::Filter::kMipMap == sampler.filter() &&
47 (tex->width() != 1 || tex->height() != 1)) {
48 // There are some cases where we might be given a non-mipmapped texture with a mipmap
49 // filter. See skbug.com/7094.
50 SkASSERT(tex->texturePriv().mipMapped() != GrMipMapped::kYes ||
51 !tex->texturePriv().mipMapsAreDirty());
52 }
53 };
54
55 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
56 for (int m = 0, i = 0; m < meshCount; ++m) {
57 for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
58 auto* tex = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
59 assertResolved(tex, primProc.textureSampler(s).samplerState());
60 }
61 }
62 } else {
63 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
64 auto* tex = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
65 assertResolved(tex, primProc.textureSampler(i).samplerState());
66 }
67 }
68
69 GrFragmentProcessor::Iter iter(pipeline);
70 while (const GrFragmentProcessor* fp = iter.next()) {
71 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
72 const auto& textureSampler = fp->textureSampler(i);
73 assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
74 }
75 }
76}
77#endif
78
Greg Daniel2d41d0d2019-08-26 11:08:51 -040079bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
80 const GrPipeline::FixedDynamicState* fixedDynamicState,
81 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
82 const GrMesh meshes[], int meshCount, const SkRect& bounds) {
Chris Daltonbca46e22017-05-15 11:03:26 -060083#ifdef SK_DEBUG
Brian Salomon92be2f72018-06-19 14:33:47 -040084 SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
Chris Daltonbca46e22017-05-15 11:03:26 -060085 for (int i = 0; i < meshCount; ++i) {
Brian Salomon92be2f72018-06-19 14:33:47 -040086 SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
Chris Dalton906430d2019-02-27 18:16:59 -070087 SkASSERT(primProc.hasInstanceAttributes() == meshes[i].hasInstanceData());
Chris Daltonbca46e22017-05-15 11:03:26 -060088 }
Chris Dalton4ece96d2019-08-30 11:26:39 -060089
Brian Salomond818ebf2018-07-02 14:08:49 +000090 SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
Brian Salomon49348902018-06-26 09:12:38 -040091 (dynamicStateArrays && dynamicStateArrays->fScissorRects));
92
Robert Phillips82774f82019-06-20 14:38:27 -040093 SkASSERT(!pipeline.isBad());
94
Brian Salomonf7232642018-09-19 08:58:08 -040095 if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
Robert Phillips7eeb74f2019-03-29 07:26:46 -040096 GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
Brian Salomonf7232642018-09-19 08:58:08 -040097 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
Robert Phillips12c46292019-04-23 07:36:17 -040098 SkASSERT(processorProxies[i]->isInstantiated());
Brian Salomonf7232642018-09-19 08:58:08 -040099 }
100 }
101 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
102 int n = primProc.numTextureSamplers() * meshCount;
103 const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
104 for (int i = 0; i < n; ++i) {
Robert Phillips12c46292019-04-23 07:36:17 -0400105 SkASSERT(textures[i]->isInstantiated());
Brian Salomon7eae3e02018-08-07 14:02:38 +0000106 }
Greg Daniel9a51a862018-11-30 10:18:14 -0500107 SkASSERT(meshCount >= 1);
108 const GrTextureProxy* const* primProcProxies =
109 dynamicStateArrays->fPrimitiveProcessorTextures;
110 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
111 const GrBackendFormat& format = primProcProxies[i]->backendFormat();
112 GrTextureType type = primProcProxies[i]->textureType();
113 GrPixelConfig config = primProcProxies[i]->config();
114 for (int j = 1; j < meshCount; ++j) {
115 const GrTextureProxy* testProxy =
116 primProcProxies[j*primProc.numTextureSamplers() + i];
117 SkASSERT(testProxy->backendFormat() == format);
118 SkASSERT(testProxy->textureType() == type);
119 SkASSERT(testProxy->config() == config);
120 }
121 }
Brian Salomon7eae3e02018-08-07 14:02:38 +0000122 }
Chris Dalton4ece96d2019-08-30 11:26:39 -0600123
124 assert_msaa_and_mips_are_resolved(
125 primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount);
Robert Phillips12c46292019-04-23 07:36:17 -0400126#endif
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400127
Brian Salomon92be2f72018-06-19 14:33:47 -0400128 if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
egdaniel9cb63402016-06-23 08:37:05 -0700129 this->gpu()->stats()->incNumFailedDraws();
130 return false;
131 }
Brian Salomon49348902018-06-26 09:12:38 -0400132 this->onDraw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshes, meshCount,
133 bounds);
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600134#ifdef SK_DEBUG
135 GrProcessor::CustomFeatures processorFeatures = primProc.requestedFeatures();
136 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
137 processorFeatures |= pipeline.getFragmentProcessor(i).requestedFeatures();
138 }
139 processorFeatures |= pipeline.getXferProcessor().requestedFeatures();
140 if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) {
141 // Verify we always have the same sample pattern key, regardless of graphics state.
142 SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
143 == fRenderTarget->renderTargetPriv().getSamplePatternKey());
144 }
145#endif
egdaniel9cb63402016-06-23 08:37:05 -0700146 return true;
147}