blob: dcc53b644efd7d967820654ae30ecbe18be9bc2d [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
45 // Ensure msaa was resolved ahead of time by the DAG.
46 SkASSERT(!tex->asRenderTarget() || !tex->asRenderTarget()->needsResolve());
47
48 // Ensure mipmaps were all resolved ahead of time by the DAG.
49 if (GrSamplerState::Filter::kMipMap == sampler.filter() &&
50 (tex->width() != 1 || tex->height() != 1)) {
51 // There are some cases where we might be given a non-mipmapped texture with a mipmap
52 // filter. See skbug.com/7094.
53 SkASSERT(tex->texturePriv().mipMapped() != GrMipMapped::kYes ||
54 !tex->texturePriv().mipMapsAreDirty());
55 }
56 };
57
58 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
59 for (int m = 0, i = 0; m < meshCount; ++m) {
60 for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
61 auto* tex = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
62 assertResolved(tex, primProc.textureSampler(s).samplerState());
63 }
64 }
65 } else {
66 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
67 auto* tex = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
68 assertResolved(tex, primProc.textureSampler(i).samplerState());
69 }
70 }
71
72 GrFragmentProcessor::Iter iter(pipeline);
73 while (const GrFragmentProcessor* fp = iter.next()) {
74 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
75 const auto& textureSampler = fp->textureSampler(i);
76 assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
77 }
78 }
79}
80#endif
81
Greg Daniel2d41d0d2019-08-26 11:08:51 -040082bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
83 const GrPipeline::FixedDynamicState* fixedDynamicState,
84 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
85 const GrMesh meshes[], int meshCount, const SkRect& bounds) {
Chris Daltonbca46e22017-05-15 11:03:26 -060086#ifdef SK_DEBUG
Brian Salomon92be2f72018-06-19 14:33:47 -040087 SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
Chris Daltonbca46e22017-05-15 11:03:26 -060088 for (int i = 0; i < meshCount; ++i) {
Chris Daltonb894c2b2017-06-14 12:39:19 -060089 SkASSERT(!GrPrimTypeRequiresGeometryShaderSupport(meshes[i].primitiveType()) ||
Chris Dalton3809bab2017-06-13 10:55:06 -060090 this->gpu()->caps()->shaderCaps()->geometryShaderSupport());
Brian Salomon92be2f72018-06-19 14:33:47 -040091 SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
Chris Dalton906430d2019-02-27 18:16:59 -070092 SkASSERT(primProc.hasInstanceAttributes() == meshes[i].hasInstanceData());
Chris Daltonbca46e22017-05-15 11:03:26 -060093 }
Chris Dalton4ece96d2019-08-30 11:26:39 -060094
Brian Salomond818ebf2018-07-02 14:08:49 +000095 SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
Brian Salomon49348902018-06-26 09:12:38 -040096 (dynamicStateArrays && dynamicStateArrays->fScissorRects));
97
Robert Phillips82774f82019-06-20 14:38:27 -040098 SkASSERT(!pipeline.isBad());
99
Brian Salomonf7232642018-09-19 08:58:08 -0400100 if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
Robert Phillips7eeb74f2019-03-29 07:26:46 -0400101 GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
Brian Salomonf7232642018-09-19 08:58:08 -0400102 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
Robert Phillips12c46292019-04-23 07:36:17 -0400103 SkASSERT(processorProxies[i]->isInstantiated());
Brian Salomonf7232642018-09-19 08:58:08 -0400104 }
105 }
106 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
107 int n = primProc.numTextureSamplers() * meshCount;
108 const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
109 for (int i = 0; i < n; ++i) {
Robert Phillips12c46292019-04-23 07:36:17 -0400110 SkASSERT(textures[i]->isInstantiated());
Brian Salomon7eae3e02018-08-07 14:02:38 +0000111 }
Greg Daniel9a51a862018-11-30 10:18:14 -0500112 SkASSERT(meshCount >= 1);
113 const GrTextureProxy* const* primProcProxies =
114 dynamicStateArrays->fPrimitiveProcessorTextures;
115 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
116 const GrBackendFormat& format = primProcProxies[i]->backendFormat();
117 GrTextureType type = primProcProxies[i]->textureType();
118 GrPixelConfig config = primProcProxies[i]->config();
119 for (int j = 1; j < meshCount; ++j) {
120 const GrTextureProxy* testProxy =
121 primProcProxies[j*primProc.numTextureSamplers() + i];
122 SkASSERT(testProxy->backendFormat() == format);
123 SkASSERT(testProxy->textureType() == type);
124 SkASSERT(testProxy->config() == config);
125 }
126 }
Brian Salomon7eae3e02018-08-07 14:02:38 +0000127 }
Chris Dalton4ece96d2019-08-30 11:26:39 -0600128
129 assert_msaa_and_mips_are_resolved(
130 primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount);
Robert Phillips12c46292019-04-23 07:36:17 -0400131#endif
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400132
Brian Salomon92be2f72018-06-19 14:33:47 -0400133 if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
egdaniel9cb63402016-06-23 08:37:05 -0700134 this->gpu()->stats()->incNumFailedDraws();
135 return false;
136 }
Brian Salomon49348902018-06-26 09:12:38 -0400137 this->onDraw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshes, meshCount,
138 bounds);
Chris Dalton8c4cafd2019-04-15 19:14:36 -0600139#ifdef SK_DEBUG
140 GrProcessor::CustomFeatures processorFeatures = primProc.requestedFeatures();
141 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
142 processorFeatures |= pipeline.getFragmentProcessor(i).requestedFeatures();
143 }
144 processorFeatures |= pipeline.getXferProcessor().requestedFeatures();
145 if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) {
146 // Verify we always have the same sample pattern key, regardless of graphics state.
147 SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
148 == fRenderTarget->renderTargetPriv().getSamplePatternKey());
149 }
150#endif
egdaniel9cb63402016-06-23 08:37:05 -0700151 return true;
152}