blob: 35184af92acbd79c77f640e0bb1f19bb3543b021 [file] [log] [blame]
bsalomon@google.coma8e686e2011-08-16 15:45:58 +00001/*
2 * Copyright 2011 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
Ben Wagnerf1344ac2019-05-10 15:01:53 -04008// This is a GPU-backend specific test.
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +00009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkTypes.h"
bsalomon@google.com2a48c3a2012-08-03 14:54:45 +000011
Robert Phillips6d344c32020-07-06 10:56:46 -040012#include "include/gpu/GrDirectContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/private/SkChecksum.h"
14#include "include/utils/SkRandom.h"
15#include "src/gpu/GrAutoLocaleSetter.h"
16#include "src/gpu/GrContextPriv.h"
17#include "src/gpu/GrDrawOpTest.h"
18#include "src/gpu/GrDrawingManager.h"
19#include "src/gpu/GrPipeline.h"
Robert Phillipse19babf2020-04-06 13:57:30 -040020#include "src/gpu/GrProxyProvider.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "src/gpu/GrRenderTargetContextPriv.h"
22#include "src/gpu/GrXferProcessor.h"
John Stilesf743d4e2020-07-23 11:35:08 -040023#include "src/gpu/effects/GrBlendFragmentProcessor.h"
Brian Salomon1171d312020-03-19 08:47:44 -040024#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Brian Salomon1171d312020-03-19 08:47:44 -040025#include "src/gpu/effects/generated/GrConfigConversionEffect.h"
Brian Salomon1171d312020-03-19 08:47:44 -040026#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
27#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
28#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
Brian Salomonf4ba4ec2020-03-19 15:54:28 -040029#include "src/gpu/ops/GrDrawOp.h"
30#include "tests/Test.h"
31#include "tools/gpu/GrContextFactory.h"
32
33#ifdef SK_GL
34#include "src/gpu/gl/GrGLGpu.h"
35#endif
bsalomon@google.comc3841b92012-08-02 18:11:43 +000036
joshualitt65171342014-10-09 07:25:36 -070037/*
bsalomon98b33eb2014-10-15 11:05:26 -070038 * A dummy processor which just tries to insert a massive key and verify that it can retrieve the
joshualitt65171342014-10-09 07:25:36 -070039 * whole thing correctly
40 */
41static const uint32_t kMaxKeySize = 1024;
42
egdaniel64c47282015-11-13 06:54:19 -080043class GLBigKeyProcessor : public GrGLSLFragmentProcessor {
joshualitt65171342014-10-09 07:25:36 -070044public:
robertphillips9cdb9922016-02-03 12:25:40 -080045 void emitCode(EmitArgs& args) override {
joshualitt6c891102015-05-13 08:51:49 -070046 // pass through
Brian Salomonffd15ea2020-07-01 16:48:20 -040047 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonb5b60322015-09-14 12:26:33 -070048 if (args.fInputColor) {
egdaniel4ca2e602015-11-18 08:01:26 -080049 fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
bsalomonb5b60322015-09-14 12:26:33 -070050 } else {
egdaniel4ca2e602015-11-18 08:01:26 -080051 fragBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
bsalomonb5b60322015-09-14 12:26:33 -070052 }
joshualitt6c891102015-05-13 08:51:49 -070053 }
joshualitt65171342014-10-09 07:25:36 -070054
Brian Salomon94efbf52016-11-29 13:43:05 -050055 static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
joshualitt65171342014-10-09 07:25:36 -070056 for (uint32_t i = 0; i < kMaxKeySize; i++) {
57 b->add32(i);
joshualittd9097592014-10-07 08:37:36 -070058 }
joshualittd9097592014-10-07 08:37:36 -070059 }
60
joshualitt65171342014-10-09 07:25:36 -070061private:
egdaniel64c47282015-11-13 06:54:19 -080062 typedef GrGLSLFragmentProcessor INHERITED;
joshualitt65171342014-10-09 07:25:36 -070063};
64
joshualitteb2a6762014-12-04 11:35:33 -080065class BigKeyProcessor : public GrFragmentProcessor {
66public:
Brian Salomonaff329b2017-08-11 09:40:37 -040067 static std::unique_ptr<GrFragmentProcessor> Make() {
68 return std::unique_ptr<GrFragmentProcessor>(new BigKeyProcessor);
joshualitteb2a6762014-12-04 11:35:33 -080069 }
70
Ethan Nicholas7c752262020-04-01 14:18:28 -040071 const char* name() const override { return "Big_Ole_Key"; }
joshualitteb2a6762014-12-04 11:35:33 -080072
egdaniel57d3b032015-11-13 11:57:27 -080073 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
robertphillips9cdb9922016-02-03 12:25:40 -080074 return new GLBigKeyProcessor;
joshualitteb2a6762014-12-04 11:35:33 -080075 }
76
Brian Salomonaff329b2017-08-11 09:40:37 -040077 std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }
Brian Salomonb17e6392017-07-28 13:41:51 -040078
joshualitteb2a6762014-12-04 11:35:33 -080079private:
Ethan Nicholasabff9562017-10-09 10:54:08 -040080 BigKeyProcessor() : INHERITED(kBigKeyProcessor_ClassID, kNone_OptimizationFlags) { }
Brian Salomon94efbf52016-11-29 13:43:05 -050081 virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -080082 GrProcessorKeyBuilder* b) const override {
wangyix4b3050b2015-08-04 07:59:37 -070083 GLBigKeyProcessor::GenKey(*this, caps, b);
84 }
mtklein36352bf2015-03-25 18:17:31 -070085 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
joshualitteb2a6762014-12-04 11:35:33 -080086
Brian Salomon0c26a9d2017-07-06 10:09:38 -040087 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
joshualitteb2a6762014-12-04 11:35:33 -080088
89 typedef GrFragmentProcessor INHERITED;
90};
91
92GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor);
93
Hal Canary6f6961e2017-01-31 13:50:44 -050094#if GR_TEST_UTILS
Brian Salomonaff329b2017-08-11 09:40:37 -040095std::unique_ptr<GrFragmentProcessor> BigKeyProcessor::TestCreate(GrProcessorTestData*) {
bungeman06ca8ec2016-06-09 08:01:03 -070096 return BigKeyProcessor::Make();
joshualitteb2a6762014-12-04 11:35:33 -080097}
Hal Canary6f6961e2017-01-31 13:50:44 -050098#endif
joshualitteb2a6762014-12-04 11:35:33 -080099
bsalomonb5b60322015-09-14 12:26:33 -0700100//////////////////////////////////////////////////////////////////////////////
101
102class BlockInputFragmentProcessor : public GrFragmentProcessor {
103public:
Brian Salomonaff329b2017-08-11 09:40:37 -0400104 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
105 return std::unique_ptr<GrFragmentProcessor>(new BlockInputFragmentProcessor(std::move(fp)));
bsalomonb5b60322015-09-14 12:26:33 -0700106 }
107
Brian Salomonf49debf2020-04-17 10:35:38 -0400108 const char* name() const override { return "Block_Input"; }
bsalomonb5b60322015-09-14 12:26:33 -0700109
egdaniel57d3b032015-11-13 11:57:27 -0800110 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLFP; }
bsalomonb5b60322015-09-14 12:26:33 -0700111
Brian Salomonaff329b2017-08-11 09:40:37 -0400112 std::unique_ptr<GrFragmentProcessor> clone() const override {
Brian Osman12c5d292020-07-13 16:11:35 -0400113 return Make(this->childProcessor(0)->clone());
Brian Salomonb17e6392017-07-28 13:41:51 -0400114 }
115
bsalomonb5b60322015-09-14 12:26:33 -0700116private:
egdaniel64c47282015-11-13 06:54:19 -0800117 class GLFP : public GrGLSLFragmentProcessor {
bsalomonb5b60322015-09-14 12:26:33 -0700118 public:
119 void emitCode(EmitArgs& args) override {
Brian Osman978693c2020-01-24 14:52:10 -0500120 SkString temp = this->invokeChild(0, args);
Brian Osmancddfc5e2020-01-24 10:24:27 -0500121 args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, temp.c_str());
bsalomonb5b60322015-09-14 12:26:33 -0700122 }
123
124 private:
egdaniel64c47282015-11-13 06:54:19 -0800125 typedef GrGLSLFragmentProcessor INHERITED;
bsalomonb5b60322015-09-14 12:26:33 -0700126 };
127
Brian Salomonaff329b2017-08-11 09:40:37 -0400128 BlockInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400129 : INHERITED(kBlockInputFragmentProcessor_ClassID, kNone_OptimizationFlags) {
Michael Ludwig9aba6252020-06-22 14:46:36 -0400130 this->registerChild(std::move(child));
bsalomonb5b60322015-09-14 12:26:33 -0700131 }
132
Brian Salomon94efbf52016-11-29 13:43:05 -0500133 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {}
bsalomonb5b60322015-09-14 12:26:33 -0700134
135 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
136
bsalomonb5b60322015-09-14 12:26:33 -0700137 typedef GrFragmentProcessor INHERITED;
138};
139
140//////////////////////////////////////////////////////////////////////////////
141
joshualitt65171342014-10-09 07:25:36 -0700142/*
143 * Begin test code
144 */
145static const int kRenderTargetHeight = 1;
146static const int kRenderTargetWidth = 1;
147
Robert Phillips58adb342020-07-23 09:41:57 -0400148static std::unique_ptr<GrRenderTargetContext> random_render_target_context(
149 GrRecordingContext* rContext,
150 SkRandom* random,
151 const GrCaps* caps) {
robertphillips82ec6e52016-05-19 14:01:05 -0700152 GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
153 : kBottomLeft_GrSurfaceOrigin;
joshualitt6c891102015-05-13 08:51:49 -0700154
Greg Daniel5c96db82019-07-09 14:06:58 -0400155 GrColorType ct = GrColorType::kRGBA_8888;
Robert Phillips0a15cc62019-07-30 12:49:10 -0400156 const GrBackendFormat format = caps->getDefaultBackendFormat(ct, GrRenderable::kYes);
Greg Daniel4065d452018-11-16 15:43:41 -0500157
Greg Daniel6fa62e22019-08-07 15:52:37 -0400158 int sampleCnt = random->nextBool() ? caps->getRenderTargetSampleCount(2, format) : 1;
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400159 // Above could be 0 if msaa isn't supported.
Brian Osman788b9162020-02-07 10:36:46 -0500160 sampleCnt = std::max(1, sampleCnt);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400161
Greg Daniele20fcad2020-01-08 11:52:34 -0500162 return GrRenderTargetContext::Make(
Robert Phillips58adb342020-07-23 09:41:57 -0400163 rContext, GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400164 {kRenderTargetWidth, kRenderTargetHeight}, sampleCnt, GrMipmapped::kNo,
Greg Daniele20fcad2020-01-08 11:52:34 -0500165 GrProtected::kNo, origin);
bsalomon@google.com91207482013-02-12 21:45:24 +0000166}
167
Hal Canary6f6961e2017-01-31 13:50:44 -0500168#if GR_TEST_UTILS
robertphillips28a838e2016-06-23 14:07:00 -0700169static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) {
Brian Salomona1633922017-01-09 11:46:10 -0500170 paint->setXPFactory(GrXPFactoryTestFactory::Get(d));
egdanielc2304142014-12-11 13:15:13 -0800171}
172
Brian Salomonaff329b2017-08-11 09:40:37 -0400173static std::unique_ptr<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d,
174 int minLevels, int maxLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700175 SkASSERT(1 <= minLevels);
176 SkASSERT(minLevels <= maxLevels);
177
178 // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
179 // If returning a leaf node, make sure that it doesn't have children (e.g. another
180 // GrComposeEffect)
181 const float terminateProbability = 0.3f;
182 if (1 == minLevels) {
183 bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
184 if (terminate) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400185 std::unique_ptr<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700186 while (true) {
Brian Salomon1c053642017-07-24 10:16:19 -0400187 fp = GrFragmentProcessorTestFactory::Make(d);
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400188 if (!fp) {
189 return nullptr;
190 }
Brian Osman12c5d292020-07-13 16:11:35 -0400191 if (0 == fp->numNonNullChildProcessors()) {
wangyix059dffa2015-09-10 06:57:05 -0700192 break;
193 }
wangyix059dffa2015-09-10 06:57:05 -0700194 }
195 return fp;
196 }
197 }
198 // If we didn't terminate, choose either the left or right subtree to fulfill
199 // the minLevels requirement of this tree; the other child can have as few levels as it wants.
Brian Salomona12c1532017-02-13 12:41:44 -0500200 // Also choose a random xfer mode.
wangyix059dffa2015-09-10 06:57:05 -0700201 if (minLevels > 1) {
202 --minLevels;
203 }
Brian Salomonaff329b2017-08-11 09:40:37 -0400204 auto minLevelsChild = create_random_proc_tree(d, minLevels, maxLevels - 1);
205 std::unique_ptr<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1));
Ben Wagnerf1344ac2019-05-10 15:01:53 -0400206 if (!minLevelsChild || !otherChild) {
207 return nullptr;
208 }
Mike Reed7d954ad2016-10-28 15:42:34 -0400209 SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0,
Brian Salomona12c1532017-02-13 12:41:44 -0500210 (int)SkBlendMode::kLastMode));
Brian Salomonaff329b2017-08-11 09:40:37 -0400211 std::unique_ptr<GrFragmentProcessor> fp;
wangyix059dffa2015-09-10 06:57:05 -0700212 if (d->fRandom->nextF() < 0.5f) {
John Stilesf743d4e2020-07-23 11:35:08 -0400213 fp = GrBlendFragmentProcessor::Make(std::move(minLevelsChild), std::move(otherChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700214 SkASSERT(fp);
215 } else {
John Stilesf743d4e2020-07-23 11:35:08 -0400216 fp = GrBlendFragmentProcessor::Make(std::move(otherChild), std::move(minLevelsChild), mode);
wangyix059dffa2015-09-10 06:57:05 -0700217 SkASSERT(fp);
218 }
219 return fp;
220}
221
robertphillips28a838e2016-06-23 14:07:00 -0700222static void set_random_color_coverage_stages(GrPaint* paint,
223 GrProcessorTestData* d,
Greg Daniel78325c12017-06-19 16:39:13 -0400224 int maxStages,
225 int maxTreeLevels) {
wangyix059dffa2015-09-10 06:57:05 -0700226 // Randomly choose to either create a linear pipeline of procs or create one proc tree
227 const float procTreeProbability = 0.5f;
228 if (d->fRandom->nextF() < procTreeProbability) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400229 std::unique_ptr<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels));
Robert Phillips1c9686b2017-06-30 08:40:28 -0400230 if (fp) {
John Stiles5933d7d2020-07-21 12:28:35 -0400231 paint->setColorFragmentProcessor(std::move(fp));
Robert Phillips1c9686b2017-06-30 08:40:28 -0400232 }
wangyix059dffa2015-09-10 06:57:05 -0700233 } else {
John Stiles41d91b62020-07-21 14:39:40 -0400234 if (maxStages >= 1) {
235 if (std::unique_ptr<GrFragmentProcessor> fp = GrFragmentProcessorTestFactory::Make(d)) {
John Stiles5933d7d2020-07-21 12:28:35 -0400236 paint->setColorFragmentProcessor(std::move(fp));
John Stiles41d91b62020-07-21 14:39:40 -0400237 }
238 }
239 if (maxStages >= 2) {
240 if (std::unique_ptr<GrFragmentProcessor> fp = GrFragmentProcessorTestFactory::Make(d)) {
241 paint->setCoverageFragmentProcessor(std::move(fp));
wangyix059dffa2015-09-10 06:57:05 -0700242 }
joshualitt65171342014-10-09 07:25:36 -0700243 }
joshualitt65171342014-10-09 07:25:36 -0700244 }
245}
246
Hal Canary6f6961e2017-01-31 13:50:44 -0500247#endif
joshualitt249af152014-09-15 11:41:13 -0700248
Hal Canary6f6961e2017-01-31 13:50:44 -0500249#if !GR_TEST_UTILS
Robert Phillips4e105e22020-07-16 09:18:50 -0400250bool GrDrawingManager::ProgramUnitTest(GrDirectContext*, int) { return true; }
Hal Canary6f6961e2017-01-31 13:50:44 -0500251#else
Robert Phillips4e105e22020-07-16 09:18:50 -0400252bool GrDrawingManager::ProgramUnitTest(GrDirectContext* direct, int maxStages, int maxLevels) {
253 GrProxyProvider* proxyProvider = direct->priv().proxyProvider();
254 const GrCaps* caps = direct->priv().caps();
robertphillipsa13e2022015-11-11 12:01:09 -0800255
Greg Daniel026a60c2020-02-12 10:53:51 -0500256 GrProcessorTestData::ViewInfo views[2];
Robert Phillipse78b7252017-04-06 07:59:41 -0400257
joshualitt65171342014-10-09 07:25:36 -0700258 // setup dummy textures
Brian Salomon69100f02020-07-21 10:49:25 -0400259 GrMipmapped mipMapped = GrMipmapped(caps->mipmapSupport());
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500260 {
Brian Salomona56a7462020-02-07 14:17:25 -0500261 static constexpr SkISize kDummyDims = {34, 18};
Robert Phillips4e105e22020-07-16 09:18:50 -0400262 const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888,
263 GrRenderable::kYes);
Brian Salomondf1bd6d2020-03-26 20:37:01 -0400264 auto proxy = proxyProvider->createProxy(format, kDummyDims, GrRenderable::kYes, 1,
Greg Daniel3a365112020-02-14 10:47:18 -0500265 mipMapped, SkBackingFit::kExact, SkBudgeted::kNo,
Greg Daniel026a60c2020-02-12 10:53:51 -0500266 GrProtected::kNo, GrInternalSurfaceFlags::kNone);
Robert Phillips4e105e22020-07-16 09:18:50 -0400267 GrSwizzle swizzle = caps->getReadSwizzle(format, GrColorType::kRGBA_8888);
Greg Daniel026a60c2020-02-12 10:53:51 -0500268 views[0] = {{std::move(proxy), kBottomLeft_GrSurfaceOrigin, swizzle},
269 GrColorType::kRGBA_8888, kPremul_SkAlphaType};
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500270 }
271 {
Brian Salomona56a7462020-02-07 14:17:25 -0500272 static constexpr SkISize kDummyDims = {16, 22};
Robert Phillips4e105e22020-07-16 09:18:50 -0400273 const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
274 GrRenderable::kNo);
Brian Salomondf1bd6d2020-03-26 20:37:01 -0400275 auto proxy = proxyProvider->createProxy(format, kDummyDims, GrRenderable::kNo, 1, mipMapped,
276 SkBackingFit::kExact, SkBudgeted::kNo,
Greg Daniel026a60c2020-02-12 10:53:51 -0500277 GrProtected::kNo, GrInternalSurfaceFlags::kNone);
Robert Phillips4e105e22020-07-16 09:18:50 -0400278 GrSwizzle swizzle = caps->getReadSwizzle(format, GrColorType::kAlpha_8);
Greg Daniel026a60c2020-02-12 10:53:51 -0500279 views[1] = {{std::move(proxy), kTopLeft_GrSurfaceOrigin, swizzle},
Brian Salomona56a7462020-02-07 14:17:25 -0500280 GrColorType::kAlpha_8, kPremul_SkAlphaType};
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500281 }
bsalomon@google.comd4726202012-08-03 14:34:46 +0000282
Greg Daniel026a60c2020-02-12 10:53:51 -0500283 if (!std::get<0>(views[0]) || !std::get<0>(views[1])) {
joshualitt65171342014-10-09 07:25:36 -0700284 SkDebugf("Could not allocate dummy textures");
bsalomone904c092014-07-17 10:50:59 -0700285 return false;
286 }
287
Brian Osman9f772a42017-07-10 13:03:50 -0400288 SkRandom random;
bsalomonf3261af2016-04-05 10:57:13 -0700289 static const int NUM_TESTS = 1024;
joshualitt6c891102015-05-13 08:51:49 -0700290 for (int t = 0; t < NUM_TESTS; t++) {
joshualitt65171342014-10-09 07:25:36 -0700291 // setup random render target(can fail)
Robert Phillips4e105e22020-07-16 09:18:50 -0400292 auto renderTargetContext = random_render_target_context(direct, &random, caps);
Brian Osman11052242016-10-27 14:47:55 -0400293 if (!renderTargetContext) {
294 SkDebugf("Could not allocate renderTargetContext");
joshualittf5883a62016-01-13 07:47:38 -0800295 return false;
296 }
robertphillips0dfa62c2015-11-16 06:23:31 -0800297
Brian Salomon17726632017-05-12 14:09:46 -0400298 GrPaint paint;
John Stiles87d0a2f2020-08-10 13:12:41 -0400299 GrProcessorTestData ptd(&random, direct, /*maxTreeDepth=*/1, SK_ARRAY_COUNT(views), views);
Greg Daniel78325c12017-06-19 16:39:13 -0400300 set_random_color_coverage_stages(&paint, &ptd, maxStages, maxLevels);
Brian Salomon17726632017-05-12 14:09:46 -0400301 set_random_xpf(&paint, &ptd);
Brian Salomon17726632017-05-12 14:09:46 -0400302 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000303 }
joshualitt6c891102015-05-13 08:51:49 -0700304 // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
Robert Phillips4e105e22020-07-16 09:18:50 -0400305 direct->flush(GrFlushInfo());
306 direct->submit(false);
bsalomonb5b60322015-09-14 12:26:33 -0700307
308 // Validate that GrFPs work correctly without an input.
Greg Daniele20fcad2020-01-08 11:52:34 -0500309 auto renderTargetContext = GrRenderTargetContext::Make(
Robert Phillips4e105e22020-07-16 09:18:50 -0400310 direct, GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact,
Greg Daniele20fcad2020-01-08 11:52:34 -0500311 {kRenderTargetWidth, kRenderTargetHeight});
Brian Osman11052242016-10-27 14:47:55 -0400312 if (!renderTargetContext) {
313 SkDebugf("Could not allocate a renderTargetContext");
robertphillips82ec6e52016-05-19 14:01:05 -0700314 return false;
315 }
316
Brian Salomon1c053642017-07-24 10:16:19 -0400317 int fpFactoryCnt = GrFragmentProcessorTestFactory::Count();
bsalomonb5b60322015-09-14 12:26:33 -0700318 for (int i = 0; i < fpFactoryCnt; ++i) {
319 // Since FP factories internally randomize, call each 10 times.
320 for (int j = 0; j < 10; ++j) {
John Stiles87d0a2f2020-08-10 13:12:41 -0400321 GrProcessorTestData ptd(&random, direct, /*maxTreeDepth=*/1, SK_ARRAY_COUNT(views),
322 views);
bsalomonb5b60322015-09-14 12:26:33 -0700323
Brian Salomon17726632017-05-12 14:09:46 -0400324 GrPaint paint;
325 paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Brian Salomonaff329b2017-08-11 09:40:37 -0400326 auto fp = GrFragmentProcessorTestFactory::MakeIdx(i, &ptd);
327 auto blockFP = BlockInputFragmentProcessor::Make(std::move(fp));
John Stiles5933d7d2020-07-21 12:28:35 -0400328 paint.setColorFragmentProcessor(std::move(blockFP));
Brian Salomon17726632017-05-12 14:09:46 -0400329 GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
Robert Phillips4e105e22020-07-16 09:18:50 -0400330
331 direct->flush(GrFlushInfo());
332 direct->submit(false);
bsalomonb5b60322015-09-14 12:26:33 -0700333 }
334 }
335
bsalomon@google.comc3841b92012-08-02 18:11:43 +0000336 return true;
337}
Hal Canary6f6961e2017-01-31 13:50:44 -0500338#endif
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000339
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400340static int get_programs_max_stages(const sk_gpu_test::ContextInfo& ctxInfo) {
Brian Salomon1171d312020-03-19 08:47:44 -0400341 int maxStages = 6;
Brian Salomonf4ba4ec2020-03-19 15:54:28 -0400342#ifdef SK_GL
Robert Phillips6d344c32020-07-06 10:56:46 -0400343 auto context = ctxInfo.directContext();
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400344 if (skiatest::IsGLContextType(ctxInfo.type())) {
345 GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
346 if (kGLES_GrGLStandard == gpu->glStandard()) {
347 // We've had issues with driver crashes and HW limits being exceeded with many effects on
348 // Android devices. We have passes on ARM devices with the default number of stages.
349 // TODO When we run ES 3.00 GLSL in more places, test again
Brian Salomone334c592017-05-15 11:00:58 -0400350#ifdef SK_BUILD_FOR_ANDROID
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400351 if (kARM_GrGLVendor != gpu->ctxInfo().vendor()) {
352 maxStages = 1;
353 }
kkinnunen3e980c32015-12-23 01:33:00 -0800354#endif
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400355 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
Brian Osman4e1868c2017-05-26 15:56:32 -0400356#ifdef SK_BUILD_FOR_IOS
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400357 maxStages = 3;
Brian Salomone334c592017-05-15 11:00:58 -0400358#endif
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400359 }
Brian Salomonb0aab2c2020-04-16 16:01:25 -0400360 // On Angle D3D we will hit a limit of out variables if we use too many stages. This is
361 // particularly true on D3D9 with a low limit on varyings and the fact that every varying is
362 // packed as though it has 4 components.
363 if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType) {
364 maxStages = 2;
365 } else if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400366 maxStages = 3;
367 }
Greg Danield895ca62017-06-19 14:39:43 -0400368 }
Brian Salomonf4ba4ec2020-03-19 15:54:28 -0400369#endif
Brian Salomone334c592017-05-15 11:00:58 -0400370 return maxStages;
371}
372
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400373static int get_programs_max_levels(const sk_gpu_test::ContextInfo& ctxInfo) {
Greg Daniel78325c12017-06-19 16:39:13 -0400374 // A full tree with 5 levels (31 nodes) may cause a program that exceeds shader limits
375 // (e.g. uniform or varying limits); maxTreeLevels should be a number from 1 to 4 inclusive.
376 int maxTreeLevels = 4;
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400377 if (skiatest::IsGLContextType(ctxInfo.type())) {
378 // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
Greg Daniel78325c12017-06-19 16:39:13 -0400379#ifdef SK_BUILD_FOR_IOS
Michael Ludwig6387dc12019-10-22 15:39:41 +0000380 maxTreeLevels = 2;
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400381#endif
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500382#ifdef SK_BUILD_FOR_ANDROID
Robert Phillips6d344c32020-07-06 10:56:46 -0400383 GrGLGpu* gpu = static_cast<GrGLGpu*>(ctxInfo.directContext()->priv().getGpu());
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500384 // Tecno Spark 3 Pro with Power VR Rogue GE8300 will fail shader compiles with
385 // no message if the shader is particularly long.
386 if (gpu->ctxInfo().vendor() == kImagination_GrGLVendor) {
387 maxTreeLevels = 3;
388 }
389#endif
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400390 if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
391 ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
392 // On Angle D3D we will hit a limit of out variables if we use too many stages.
393 maxTreeLevels = 2;
394 }
Greg Daniel78325c12017-06-19 16:39:13 -0400395 }
396 return maxTreeLevels;
397}
398
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400399static void test_programs(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo) {
400 int maxStages = get_programs_max_stages(ctxInfo);
kkinnunen3e980c32015-12-23 01:33:00 -0800401 if (maxStages == 0) {
402 return;
403 }
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400404 int maxLevels = get_programs_max_levels(ctxInfo);
Greg Daniel78325c12017-06-19 16:39:13 -0400405 if (maxLevels == 0) {
406 return;
407 }
Brian Osman9f772a42017-07-10 13:03:50 -0400408
Robert Phillips6d344c32020-07-06 10:56:46 -0400409 REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(ctxInfo.directContext(), maxStages,
Greg Daniel78325c12017-06-19 16:39:13 -0400410 maxLevels));
kkinnunen3e980c32015-12-23 01:33:00 -0800411}
412
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400413DEF_GPUTEST(Programs, reporter, options) {
bsalomon3318ee72015-03-16 11:56:29 -0700414 // Set a locale that would cause shader compilation to fail because of , as decimal separator.
415 // skbug 3330
416#ifdef SK_BUILD_FOR_WIN
417 GrAutoLocaleSetter als("sv-SE");
418#else
419 GrAutoLocaleSetter als("sv_SE.UTF-8");
420#endif
421
joshualitt6c891102015-05-13 08:51:49 -0700422 // We suppress prints to avoid spew
Brian Salomondcfca432017-11-15 15:48:03 -0500423 GrContextOptions opts = options;
joshualitt6c891102015-05-13 08:51:49 -0700424 opts.fSuppressPrints = true;
bsalomon3724e572016-03-30 18:56:19 -0700425 sk_gpu_test::GrContextFactory debugFactory(opts);
Jim Van Verth5a8f3e42019-10-24 10:23:26 -0400426 skiatest::RunWithGPUTestContexts(test_programs, &skiatest::IsRenderingGLOrMetalContextType,
427 reporter, opts);
bsalomon@google.coma8e686e2011-08-16 15:45:58 +0000428}