1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker // This is a GPU-backend specific test.
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextOptions.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/KeyBuilder.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrAutoLocaleSetter.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDrawOpTest.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDrawingManager.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPaint.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessorUnitTest.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/effects/GrBlendFragmentProcessor.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
45*c8dee2aaSAndroid Build Coastguard Worker
46*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
47*c8dee2aaSAndroid Build Coastguard Worker #include <array>
48*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
49*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
50*c8dee2aaSAndroid Build Coastguard Worker #include <tuple>
51*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker class GrRecordingContext;
54*c8dee2aaSAndroid Build Coastguard Worker struct GrShaderCaps;
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
57*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h"
58*c8dee2aaSAndroid Build Coastguard Worker #endif
59*c8dee2aaSAndroid Build Coastguard Worker
60*c8dee2aaSAndroid Build Coastguard Worker /*
61*c8dee2aaSAndroid Build Coastguard Worker * A simple processor which just tries to insert a massive key and verify that it can retrieve the
62*c8dee2aaSAndroid Build Coastguard Worker * whole thing correctly
63*c8dee2aaSAndroid Build Coastguard Worker */
64*c8dee2aaSAndroid Build Coastguard Worker static const uint32_t kMaxKeySize = 1024;
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker namespace {
67*c8dee2aaSAndroid Build Coastguard Worker class BigKeyProcessor : public GrFragmentProcessor {
68*c8dee2aaSAndroid Build Coastguard Worker public:
Make()69*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<GrFragmentProcessor> Make() {
70*c8dee2aaSAndroid Build Coastguard Worker return std::unique_ptr<GrFragmentProcessor>(new BigKeyProcessor);
71*c8dee2aaSAndroid Build Coastguard Worker }
72*c8dee2aaSAndroid Build Coastguard Worker
name() const73*c8dee2aaSAndroid Build Coastguard Worker const char* name() const override { return "Big_Ole_Key"; }
74*c8dee2aaSAndroid Build Coastguard Worker
onMakeProgramImpl() const75*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
76*c8dee2aaSAndroid Build Coastguard Worker class Impl : public ProgramImpl {
77*c8dee2aaSAndroid Build Coastguard Worker public:
78*c8dee2aaSAndroid Build Coastguard Worker void emitCode(EmitArgs& args) override {
79*c8dee2aaSAndroid Build Coastguard Worker args.fFragBuilder->codeAppendf("return half4(1);\n");
80*c8dee2aaSAndroid Build Coastguard Worker }
81*c8dee2aaSAndroid Build Coastguard Worker };
82*c8dee2aaSAndroid Build Coastguard Worker
83*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<Impl>();
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker
clone() const86*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }
87*c8dee2aaSAndroid Build Coastguard Worker
88*c8dee2aaSAndroid Build Coastguard Worker private:
BigKeyProcessor()89*c8dee2aaSAndroid Build Coastguard Worker BigKeyProcessor() : INHERITED(kBigKeyProcessor_ClassID, kNone_OptimizationFlags) {}
onAddToKey(const GrShaderCaps & caps,skgpu::KeyBuilder * b) const90*c8dee2aaSAndroid Build Coastguard Worker void onAddToKey(const GrShaderCaps& caps, skgpu::KeyBuilder* b) const override {
91*c8dee2aaSAndroid Build Coastguard Worker for (uint32_t i = 0; i < kMaxKeySize; i++) {
92*c8dee2aaSAndroid Build Coastguard Worker b->add32(i);
93*c8dee2aaSAndroid Build Coastguard Worker }
94*c8dee2aaSAndroid Build Coastguard Worker }
onIsEqual(const GrFragmentProcessor &) const95*c8dee2aaSAndroid Build Coastguard Worker bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
96*c8dee2aaSAndroid Build Coastguard Worker
97*c8dee2aaSAndroid Build Coastguard Worker GR_DECLARE_FRAGMENT_PROCESSOR_TEST
98*c8dee2aaSAndroid Build Coastguard Worker
99*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GrFragmentProcessor;
100*c8dee2aaSAndroid Build Coastguard Worker };
101*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
102*c8dee2aaSAndroid Build Coastguard Worker
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor)103*c8dee2aaSAndroid Build Coastguard Worker GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor)
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
106*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> BigKeyProcessor::TestCreate(GrProcessorTestData*) {
107*c8dee2aaSAndroid Build Coastguard Worker return BigKeyProcessor::Make();
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker #endif
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker class BlockInputFragmentProcessor : public GrFragmentProcessor {
114*c8dee2aaSAndroid Build Coastguard Worker public:
Make(std::unique_ptr<GrFragmentProcessor> fp)115*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
116*c8dee2aaSAndroid Build Coastguard Worker return std::unique_ptr<GrFragmentProcessor>(new BlockInputFragmentProcessor(std::move(fp)));
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker
name() const119*c8dee2aaSAndroid Build Coastguard Worker const char* name() const override { return "Block_Input"; }
120*c8dee2aaSAndroid Build Coastguard Worker
onMakeProgramImpl() const121*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
122*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<GLFP>();
123*c8dee2aaSAndroid Build Coastguard Worker }
124*c8dee2aaSAndroid Build Coastguard Worker
clone() const125*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> clone() const override {
126*c8dee2aaSAndroid Build Coastguard Worker return Make(this->childProcessor(0)->clone());
127*c8dee2aaSAndroid Build Coastguard Worker }
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker private:
130*c8dee2aaSAndroid Build Coastguard Worker class GLFP : public ProgramImpl {
131*c8dee2aaSAndroid Build Coastguard Worker public:
emitCode(EmitArgs & args)132*c8dee2aaSAndroid Build Coastguard Worker void emitCode(EmitArgs& args) override {
133*c8dee2aaSAndroid Build Coastguard Worker SkString temp = this->invokeChild(0, args);
134*c8dee2aaSAndroid Build Coastguard Worker args.fFragBuilder->codeAppendf("return %s;", temp.c_str());
135*c8dee2aaSAndroid Build Coastguard Worker }
136*c8dee2aaSAndroid Build Coastguard Worker
137*c8dee2aaSAndroid Build Coastguard Worker private:
138*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = ProgramImpl;
139*c8dee2aaSAndroid Build Coastguard Worker };
140*c8dee2aaSAndroid Build Coastguard Worker
BlockInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child)141*c8dee2aaSAndroid Build Coastguard Worker BlockInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child)
142*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(kBlockInputFragmentProcessor_ClassID, kNone_OptimizationFlags) {
143*c8dee2aaSAndroid Build Coastguard Worker this->registerChild(std::move(child));
144*c8dee2aaSAndroid Build Coastguard Worker }
145*c8dee2aaSAndroid Build Coastguard Worker
onAddToKey(const GrShaderCaps &,skgpu::KeyBuilder *) const146*c8dee2aaSAndroid Build Coastguard Worker void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}
147*c8dee2aaSAndroid Build Coastguard Worker
onIsEqual(const GrFragmentProcessor &) const148*c8dee2aaSAndroid Build Coastguard Worker bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
149*c8dee2aaSAndroid Build Coastguard Worker
150*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GrFragmentProcessor;
151*c8dee2aaSAndroid Build Coastguard Worker };
152*c8dee2aaSAndroid Build Coastguard Worker
153*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker /*
156*c8dee2aaSAndroid Build Coastguard Worker * Begin test code
157*c8dee2aaSAndroid Build Coastguard Worker */
158*c8dee2aaSAndroid Build Coastguard Worker static const int kRenderTargetHeight = 1;
159*c8dee2aaSAndroid Build Coastguard Worker static const int kRenderTargetWidth = 1;
160*c8dee2aaSAndroid Build Coastguard Worker
random_surface_draw_context(GrRecordingContext * rContext,SkRandom * random,const GrCaps * caps)161*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<skgpu::ganesh::SurfaceDrawContext> random_surface_draw_context(
162*c8dee2aaSAndroid Build Coastguard Worker GrRecordingContext* rContext, SkRandom* random, const GrCaps* caps) {
163*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
164*c8dee2aaSAndroid Build Coastguard Worker : kBottomLeft_GrSurfaceOrigin;
165*c8dee2aaSAndroid Build Coastguard Worker
166*c8dee2aaSAndroid Build Coastguard Worker GrColorType ct = GrColorType::kRGBA_8888;
167*c8dee2aaSAndroid Build Coastguard Worker const GrBackendFormat format = caps->getDefaultBackendFormat(ct, GrRenderable::kYes);
168*c8dee2aaSAndroid Build Coastguard Worker
169*c8dee2aaSAndroid Build Coastguard Worker int sampleCnt = random->nextBool() ? caps->getRenderTargetSampleCount(2, format) : 1;
170*c8dee2aaSAndroid Build Coastguard Worker // Above could be 0 if msaa isn't supported.
171*c8dee2aaSAndroid Build Coastguard Worker sampleCnt = std::max(1, sampleCnt);
172*c8dee2aaSAndroid Build Coastguard Worker
173*c8dee2aaSAndroid Build Coastguard Worker return skgpu::ganesh::SurfaceDrawContext::Make(rContext,
174*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
175*c8dee2aaSAndroid Build Coastguard Worker nullptr,
176*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
177*c8dee2aaSAndroid Build Coastguard Worker {kRenderTargetWidth, kRenderTargetHeight},
178*c8dee2aaSAndroid Build Coastguard Worker SkSurfaceProps(),
179*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{},
180*c8dee2aaSAndroid Build Coastguard Worker sampleCnt,
181*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kNo,
182*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo,
183*c8dee2aaSAndroid Build Coastguard Worker origin);
184*c8dee2aaSAndroid Build Coastguard Worker }
185*c8dee2aaSAndroid Build Coastguard Worker
186*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
set_random_xpf(GrPaint * paint,GrProcessorTestData * d)187*c8dee2aaSAndroid Build Coastguard Worker static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) {
188*c8dee2aaSAndroid Build Coastguard Worker paint->setXPFactory(GrXPFactoryTestFactory::Get(d));
189*c8dee2aaSAndroid Build Coastguard Worker }
190*c8dee2aaSAndroid Build Coastguard Worker
create_random_proc_tree(GrProcessorTestData * d,int minLevels,int maxLevels)191*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d,
192*c8dee2aaSAndroid Build Coastguard Worker int minLevels, int maxLevels) {
193*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(1 <= minLevels);
194*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(minLevels <= maxLevels);
195*c8dee2aaSAndroid Build Coastguard Worker
196*c8dee2aaSAndroid Build Coastguard Worker // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
197*c8dee2aaSAndroid Build Coastguard Worker // If returning a leaf node, make sure that it doesn't have children (e.g. another
198*c8dee2aaSAndroid Build Coastguard Worker // GrComposeEffect)
199*c8dee2aaSAndroid Build Coastguard Worker const float terminateProbability = 0.3f;
200*c8dee2aaSAndroid Build Coastguard Worker if (1 == minLevels) {
201*c8dee2aaSAndroid Build Coastguard Worker bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
202*c8dee2aaSAndroid Build Coastguard Worker if (terminate) {
203*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> fp;
204*c8dee2aaSAndroid Build Coastguard Worker while (true) {
205*c8dee2aaSAndroid Build Coastguard Worker fp = GrFragmentProcessorTestFactory::Make(d);
206*c8dee2aaSAndroid Build Coastguard Worker if (!fp) {
207*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
208*c8dee2aaSAndroid Build Coastguard Worker }
209*c8dee2aaSAndroid Build Coastguard Worker if (0 == fp->numNonNullChildProcessors()) {
210*c8dee2aaSAndroid Build Coastguard Worker break;
211*c8dee2aaSAndroid Build Coastguard Worker }
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker return fp;
214*c8dee2aaSAndroid Build Coastguard Worker }
215*c8dee2aaSAndroid Build Coastguard Worker }
216*c8dee2aaSAndroid Build Coastguard Worker // If we didn't terminate, choose either the left or right subtree to fulfill
217*c8dee2aaSAndroid Build Coastguard Worker // the minLevels requirement of this tree; the other child can have as few levels as it wants.
218*c8dee2aaSAndroid Build Coastguard Worker // Also choose a random xfer mode.
219*c8dee2aaSAndroid Build Coastguard Worker if (minLevels > 1) {
220*c8dee2aaSAndroid Build Coastguard Worker --minLevels;
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker auto minLevelsChild = create_random_proc_tree(d, minLevels, maxLevels - 1);
223*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1));
224*c8dee2aaSAndroid Build Coastguard Worker if (!minLevelsChild || !otherChild) {
225*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
226*c8dee2aaSAndroid Build Coastguard Worker }
227*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0,
228*c8dee2aaSAndroid Build Coastguard Worker (int)SkBlendMode::kLastMode));
229*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> fp;
230*c8dee2aaSAndroid Build Coastguard Worker if (d->fRandom->nextF() < 0.5f) {
231*c8dee2aaSAndroid Build Coastguard Worker fp = GrBlendFragmentProcessor::Make(std::move(minLevelsChild), std::move(otherChild), mode);
232*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fp);
233*c8dee2aaSAndroid Build Coastguard Worker } else {
234*c8dee2aaSAndroid Build Coastguard Worker fp = GrBlendFragmentProcessor::Make(std::move(otherChild), std::move(minLevelsChild), mode);
235*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fp);
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker return fp;
238*c8dee2aaSAndroid Build Coastguard Worker }
239*c8dee2aaSAndroid Build Coastguard Worker
set_random_color_coverage_stages(GrPaint * paint,GrProcessorTestData * d,int maxStages,int maxTreeLevels)240*c8dee2aaSAndroid Build Coastguard Worker static void set_random_color_coverage_stages(GrPaint* paint,
241*c8dee2aaSAndroid Build Coastguard Worker GrProcessorTestData* d,
242*c8dee2aaSAndroid Build Coastguard Worker int maxStages,
243*c8dee2aaSAndroid Build Coastguard Worker int maxTreeLevels) {
244*c8dee2aaSAndroid Build Coastguard Worker // Randomly choose to either create a linear pipeline of procs or create one proc tree
245*c8dee2aaSAndroid Build Coastguard Worker const float procTreeProbability = 0.5f;
246*c8dee2aaSAndroid Build Coastguard Worker if (d->fRandom->nextF() < procTreeProbability) {
247*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels));
248*c8dee2aaSAndroid Build Coastguard Worker if (fp) {
249*c8dee2aaSAndroid Build Coastguard Worker paint->setColorFragmentProcessor(std::move(fp));
250*c8dee2aaSAndroid Build Coastguard Worker }
251*c8dee2aaSAndroid Build Coastguard Worker } else {
252*c8dee2aaSAndroid Build Coastguard Worker if (maxStages >= 1) {
253*c8dee2aaSAndroid Build Coastguard Worker if (std::unique_ptr<GrFragmentProcessor> fp = GrFragmentProcessorTestFactory::Make(d)) {
254*c8dee2aaSAndroid Build Coastguard Worker paint->setColorFragmentProcessor(std::move(fp));
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker if (maxStages >= 2) {
258*c8dee2aaSAndroid Build Coastguard Worker if (std::unique_ptr<GrFragmentProcessor> fp = GrFragmentProcessorTestFactory::Make(d)) {
259*c8dee2aaSAndroid Build Coastguard Worker paint->setCoverageFragmentProcessor(std::move(fp));
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker }
262*c8dee2aaSAndroid Build Coastguard Worker }
263*c8dee2aaSAndroid Build Coastguard Worker }
264*c8dee2aaSAndroid Build Coastguard Worker
265*c8dee2aaSAndroid Build Coastguard Worker #endif
266*c8dee2aaSAndroid Build Coastguard Worker
267*c8dee2aaSAndroid Build Coastguard Worker #if !defined(GPU_TEST_UTILS)
ProgramUnitTest(GrDirectContext *,int)268*c8dee2aaSAndroid Build Coastguard Worker bool GrDrawingManager::ProgramUnitTest(GrDirectContext*, int) { return true; }
269*c8dee2aaSAndroid Build Coastguard Worker #else
ProgramUnitTest(GrDirectContext * direct,int maxStages,int maxLevels)270*c8dee2aaSAndroid Build Coastguard Worker bool GrDrawingManager::ProgramUnitTest(GrDirectContext* direct, int maxStages, int maxLevels) {
271*c8dee2aaSAndroid Build Coastguard Worker GrProxyProvider* proxyProvider = direct->priv().proxyProvider();
272*c8dee2aaSAndroid Build Coastguard Worker const GrCaps* caps = direct->priv().caps();
273*c8dee2aaSAndroid Build Coastguard Worker
274*c8dee2aaSAndroid Build Coastguard Worker GrProcessorTestData::ViewInfo views[2];
275*c8dee2aaSAndroid Build Coastguard Worker
276*c8dee2aaSAndroid Build Coastguard Worker // setup arbitrary textures
277*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped mipmapped = skgpu::Mipmapped(caps->mipmapSupport());
278*c8dee2aaSAndroid Build Coastguard Worker {
279*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkISize kDims = {34, 18};
280*c8dee2aaSAndroid Build Coastguard Worker const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888,
281*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes);
282*c8dee2aaSAndroid Build Coastguard Worker auto proxy = proxyProvider->createProxy(format,
283*c8dee2aaSAndroid Build Coastguard Worker kDims,
284*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
285*c8dee2aaSAndroid Build Coastguard Worker 1,
286*c8dee2aaSAndroid Build Coastguard Worker mipmapped,
287*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
288*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo,
289*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo,
290*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{},
291*c8dee2aaSAndroid Build Coastguard Worker GrInternalSurfaceFlags::kNone);
292*c8dee2aaSAndroid Build Coastguard Worker skgpu::Swizzle swizzle = caps->getReadSwizzle(format, GrColorType::kRGBA_8888);
293*c8dee2aaSAndroid Build Coastguard Worker views[0] = {{std::move(proxy), kBottomLeft_GrSurfaceOrigin, swizzle},
294*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888, kPremul_SkAlphaType};
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker {
297*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkISize kDims = {16, 22};
298*c8dee2aaSAndroid Build Coastguard Worker const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
299*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kNo);
300*c8dee2aaSAndroid Build Coastguard Worker auto proxy = proxyProvider->createProxy(format,
301*c8dee2aaSAndroid Build Coastguard Worker kDims,
302*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kNo,
303*c8dee2aaSAndroid Build Coastguard Worker 1,
304*c8dee2aaSAndroid Build Coastguard Worker mipmapped,
305*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
306*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo,
307*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo,
308*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{},
309*c8dee2aaSAndroid Build Coastguard Worker GrInternalSurfaceFlags::kNone);
310*c8dee2aaSAndroid Build Coastguard Worker skgpu::Swizzle swizzle = caps->getReadSwizzle(format, GrColorType::kAlpha_8);
311*c8dee2aaSAndroid Build Coastguard Worker views[1] = {{std::move(proxy), kTopLeft_GrSurfaceOrigin, swizzle},
312*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kAlpha_8, kPremul_SkAlphaType};
313*c8dee2aaSAndroid Build Coastguard Worker }
314*c8dee2aaSAndroid Build Coastguard Worker
315*c8dee2aaSAndroid Build Coastguard Worker if (!std::get<0>(views[0]) || !std::get<0>(views[1])) {
316*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not allocate textures for test");
317*c8dee2aaSAndroid Build Coastguard Worker return false;
318*c8dee2aaSAndroid Build Coastguard Worker }
319*c8dee2aaSAndroid Build Coastguard Worker
320*c8dee2aaSAndroid Build Coastguard Worker SkRandom random;
321*c8dee2aaSAndroid Build Coastguard Worker static const int NUM_TESTS = 1024;
322*c8dee2aaSAndroid Build Coastguard Worker for (int t = 0; t < NUM_TESTS; t++) {
323*c8dee2aaSAndroid Build Coastguard Worker // setup random render target(can fail)
324*c8dee2aaSAndroid Build Coastguard Worker auto surfaceDrawContext = random_surface_draw_context(direct, &random, caps);
325*c8dee2aaSAndroid Build Coastguard Worker if (!surfaceDrawContext) {
326*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not allocate surfaceDrawContext");
327*c8dee2aaSAndroid Build Coastguard Worker return false;
328*c8dee2aaSAndroid Build Coastguard Worker }
329*c8dee2aaSAndroid Build Coastguard Worker
330*c8dee2aaSAndroid Build Coastguard Worker GrPaint paint;
331*c8dee2aaSAndroid Build Coastguard Worker GrProcessorTestData ptd(&random, direct, /*maxTreeDepth=*/1, std::size(views), views);
332*c8dee2aaSAndroid Build Coastguard Worker set_random_color_coverage_stages(&paint, &ptd, maxStages, maxLevels);
333*c8dee2aaSAndroid Build Coastguard Worker set_random_xpf(&paint, &ptd);
334*c8dee2aaSAndroid Build Coastguard Worker GrDrawRandomOp(&random, surfaceDrawContext.get(), std::move(paint));
335*c8dee2aaSAndroid Build Coastguard Worker }
336*c8dee2aaSAndroid Build Coastguard Worker // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
337*c8dee2aaSAndroid Build Coastguard Worker direct->flush(GrFlushInfo());
338*c8dee2aaSAndroid Build Coastguard Worker direct->submit(GrSyncCpu::kNo);
339*c8dee2aaSAndroid Build Coastguard Worker
340*c8dee2aaSAndroid Build Coastguard Worker // Validate that GrFPs work correctly without an input.
341*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(direct,
342*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
343*c8dee2aaSAndroid Build Coastguard Worker nullptr,
344*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
345*c8dee2aaSAndroid Build Coastguard Worker {kRenderTargetWidth, kRenderTargetHeight},
346*c8dee2aaSAndroid Build Coastguard Worker SkSurfaceProps(),
347*c8dee2aaSAndroid Build Coastguard Worker /*label=*/{});
348*c8dee2aaSAndroid Build Coastguard Worker if (!sdc) {
349*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not allocate a surfaceDrawContext");
350*c8dee2aaSAndroid Build Coastguard Worker return false;
351*c8dee2aaSAndroid Build Coastguard Worker }
352*c8dee2aaSAndroid Build Coastguard Worker
353*c8dee2aaSAndroid Build Coastguard Worker int fpFactoryCnt = GrFragmentProcessorTestFactory::Count();
354*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fpFactoryCnt; ++i) {
355*c8dee2aaSAndroid Build Coastguard Worker // Since FP factories internally randomize, call each 10 times.
356*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < 10; ++j) {
357*c8dee2aaSAndroid Build Coastguard Worker GrProcessorTestData ptd(&random, direct, /*maxTreeDepth=*/1, std::size(views),
358*c8dee2aaSAndroid Build Coastguard Worker views);
359*c8dee2aaSAndroid Build Coastguard Worker
360*c8dee2aaSAndroid Build Coastguard Worker GrPaint paint;
361*c8dee2aaSAndroid Build Coastguard Worker paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
362*c8dee2aaSAndroid Build Coastguard Worker auto fp = GrFragmentProcessorTestFactory::MakeIdx(i, &ptd);
363*c8dee2aaSAndroid Build Coastguard Worker auto blockFP = BlockInputFragmentProcessor::Make(std::move(fp));
364*c8dee2aaSAndroid Build Coastguard Worker paint.setColorFragmentProcessor(std::move(blockFP));
365*c8dee2aaSAndroid Build Coastguard Worker GrDrawRandomOp(&random, sdc.get(), std::move(paint));
366*c8dee2aaSAndroid Build Coastguard Worker
367*c8dee2aaSAndroid Build Coastguard Worker direct->flush(GrFlushInfo());
368*c8dee2aaSAndroid Build Coastguard Worker direct->submit(GrSyncCpu::kNo);
369*c8dee2aaSAndroid Build Coastguard Worker }
370*c8dee2aaSAndroid Build Coastguard Worker }
371*c8dee2aaSAndroid Build Coastguard Worker
372*c8dee2aaSAndroid Build Coastguard Worker return true;
373*c8dee2aaSAndroid Build Coastguard Worker }
374*c8dee2aaSAndroid Build Coastguard Worker #endif
375*c8dee2aaSAndroid Build Coastguard Worker
get_programs_max_stages(const sk_gpu_test::ContextInfo & ctxInfo)376*c8dee2aaSAndroid Build Coastguard Worker static int get_programs_max_stages(const sk_gpu_test::ContextInfo& ctxInfo) {
377*c8dee2aaSAndroid Build Coastguard Worker int maxStages = 6;
378*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
379*c8dee2aaSAndroid Build Coastguard Worker auto context = ctxInfo.directContext();
380*c8dee2aaSAndroid Build Coastguard Worker if (skiatest::IsGLContextType(ctxInfo.type())) {
381*c8dee2aaSAndroid Build Coastguard Worker GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
382*c8dee2aaSAndroid Build Coastguard Worker if (kGLES_GrGLStandard == gpu->glStandard()) {
383*c8dee2aaSAndroid Build Coastguard Worker // We've had issues with driver crashes and HW limits being exceeded with many effects on
384*c8dee2aaSAndroid Build Coastguard Worker // Android devices. We have passes on ARM devices with the default number of stages.
385*c8dee2aaSAndroid Build Coastguard Worker // TODO When we run ES 3.00 GLSL in more places, test again
386*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_ANDROID
387*c8dee2aaSAndroid Build Coastguard Worker if (gpu->ctxInfo().vendor() != GrGLVendor::kARM) {
388*c8dee2aaSAndroid Build Coastguard Worker maxStages = 1;
389*c8dee2aaSAndroid Build Coastguard Worker }
390*c8dee2aaSAndroid Build Coastguard Worker #endif
391*c8dee2aaSAndroid Build Coastguard Worker // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
392*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_IOS
393*c8dee2aaSAndroid Build Coastguard Worker maxStages = 3;
394*c8dee2aaSAndroid Build Coastguard Worker #endif
395*c8dee2aaSAndroid Build Coastguard Worker }
396*c8dee2aaSAndroid Build Coastguard Worker // On Angle D3D we will hit a limit of out variables if we use too many stages. This is
397*c8dee2aaSAndroid Build Coastguard Worker // particularly true on D3D9 with a low limit on varyings and the fact that every varying is
398*c8dee2aaSAndroid Build Coastguard Worker // packed as though it has 4 components.
399*c8dee2aaSAndroid Build Coastguard Worker if (ctxInfo.type() == skgpu::ContextType::kANGLE_D3D9_ES2) {
400*c8dee2aaSAndroid Build Coastguard Worker maxStages = 2;
401*c8dee2aaSAndroid Build Coastguard Worker } else if (ctxInfo.type() == skgpu::ContextType::kANGLE_D3D11_ES2) {
402*c8dee2aaSAndroid Build Coastguard Worker maxStages = 3;
403*c8dee2aaSAndroid Build Coastguard Worker }
404*c8dee2aaSAndroid Build Coastguard Worker }
405*c8dee2aaSAndroid Build Coastguard Worker #endif
406*c8dee2aaSAndroid Build Coastguard Worker return maxStages;
407*c8dee2aaSAndroid Build Coastguard Worker }
408*c8dee2aaSAndroid Build Coastguard Worker
get_programs_max_levels(const sk_gpu_test::ContextInfo & ctxInfo)409*c8dee2aaSAndroid Build Coastguard Worker static int get_programs_max_levels(const sk_gpu_test::ContextInfo& ctxInfo) {
410*c8dee2aaSAndroid Build Coastguard Worker // A full tree with 5 levels (31 nodes) may cause a program that exceeds shader limits
411*c8dee2aaSAndroid Build Coastguard Worker // (e.g. uniform or varying limits); maxTreeLevels should be a number from 1 to 4 inclusive.
412*c8dee2aaSAndroid Build Coastguard Worker int maxTreeLevels = 4;
413*c8dee2aaSAndroid Build Coastguard Worker if (skiatest::IsGLContextType(ctxInfo.type())) {
414*c8dee2aaSAndroid Build Coastguard Worker // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
415*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_IOS
416*c8dee2aaSAndroid Build Coastguard Worker maxTreeLevels = 2;
417*c8dee2aaSAndroid Build Coastguard Worker #endif
418*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_BUILD_FOR_ANDROID) && defined(SK_GL)
419*c8dee2aaSAndroid Build Coastguard Worker GrGLGpu* gpu = static_cast<GrGLGpu*>(ctxInfo.directContext()->priv().getGpu());
420*c8dee2aaSAndroid Build Coastguard Worker // Tecno Spark 3 Pro with Power VR Rogue GE8300 will fail shader compiles with
421*c8dee2aaSAndroid Build Coastguard Worker // no message if the shader is particularly long.
422*c8dee2aaSAndroid Build Coastguard Worker if (gpu->ctxInfo().vendor() == GrGLVendor::kImagination) {
423*c8dee2aaSAndroid Build Coastguard Worker maxTreeLevels = 3;
424*c8dee2aaSAndroid Build Coastguard Worker }
425*c8dee2aaSAndroid Build Coastguard Worker #endif
426*c8dee2aaSAndroid Build Coastguard Worker if (ctxInfo.type() == skgpu::ContextType::kANGLE_D3D9_ES2 ||
427*c8dee2aaSAndroid Build Coastguard Worker ctxInfo.type() == skgpu::ContextType::kANGLE_D3D11_ES2) {
428*c8dee2aaSAndroid Build Coastguard Worker // On Angle D3D we will hit a limit of out variables if we use too many stages.
429*c8dee2aaSAndroid Build Coastguard Worker maxTreeLevels = 2;
430*c8dee2aaSAndroid Build Coastguard Worker }
431*c8dee2aaSAndroid Build Coastguard Worker }
432*c8dee2aaSAndroid Build Coastguard Worker return maxTreeLevels;
433*c8dee2aaSAndroid Build Coastguard Worker }
434*c8dee2aaSAndroid Build Coastguard Worker
test_programs(skiatest::Reporter * reporter,const sk_gpu_test::ContextInfo & ctxInfo)435*c8dee2aaSAndroid Build Coastguard Worker static void test_programs(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo) {
436*c8dee2aaSAndroid Build Coastguard Worker int maxStages = get_programs_max_stages(ctxInfo);
437*c8dee2aaSAndroid Build Coastguard Worker if (maxStages == 0) {
438*c8dee2aaSAndroid Build Coastguard Worker return;
439*c8dee2aaSAndroid Build Coastguard Worker }
440*c8dee2aaSAndroid Build Coastguard Worker int maxLevels = get_programs_max_levels(ctxInfo);
441*c8dee2aaSAndroid Build Coastguard Worker if (maxLevels == 0) {
442*c8dee2aaSAndroid Build Coastguard Worker return;
443*c8dee2aaSAndroid Build Coastguard Worker }
444*c8dee2aaSAndroid Build Coastguard Worker
445*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(ctxInfo.directContext(), maxStages,
446*c8dee2aaSAndroid Build Coastguard Worker maxLevels));
447*c8dee2aaSAndroid Build Coastguard Worker }
448*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(Programs,reporter,options,CtsEnforcement::kNever)449*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(Programs, reporter, options, CtsEnforcement::kNever) {
450*c8dee2aaSAndroid Build Coastguard Worker // Set a locale that would cause shader compilation to fail because of , as decimal separator.
451*c8dee2aaSAndroid Build Coastguard Worker // skbug 3330
452*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_WIN
453*c8dee2aaSAndroid Build Coastguard Worker GrAutoLocaleSetter als("sv-SE");
454*c8dee2aaSAndroid Build Coastguard Worker #else
455*c8dee2aaSAndroid Build Coastguard Worker GrAutoLocaleSetter als("sv_SE.UTF-8");
456*c8dee2aaSAndroid Build Coastguard Worker #endif
457*c8dee2aaSAndroid Build Coastguard Worker
458*c8dee2aaSAndroid Build Coastguard Worker // We suppress prints to avoid spew
459*c8dee2aaSAndroid Build Coastguard Worker GrContextOptions opts = options;
460*c8dee2aaSAndroid Build Coastguard Worker opts.fSuppressPrints = true;
461*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::GrContextFactory debugFactory(opts);
462*c8dee2aaSAndroid Build Coastguard Worker skiatest::RunWithGaneshTestContexts(test_programs, &skgpu::IsRenderingContext, reporter, opts);
463*c8dee2aaSAndroid Build Coastguard Worker }
464