blob: 8808b1d8cbfeaf47c33a0b62b538847c0fcff828 [file] [log] [blame]
csmartdalton0d28e572016-07-06 09:59:43 -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
8#include "SkTypes.h"
9#include "SkPoint.h"
10#include "Test.h"
11#include <vector>
12
13#if SK_SUPPORT_GPU
14
Brian Salomon652ecb52017-01-17 12:39:53 -050015#include "GrAppliedClip.h"
16#include "GrPipelineBuilder.h"
csmartdaltonc633abb2016-11-01 08:55:55 -070017#include "GrRenderTargetContext.h"
csmartdalton0d28e572016-07-06 09:59:43 -070018#include "GrRenderTargetPriv.h"
Brian Salomon0e8fc8b2016-12-09 15:10:07 -050019#include "GrTypesPriv.h"
csmartdalton0d28e572016-07-06 09:59:43 -070020#include "gl/GrGLGpu.h"
21#include "gl/debug/DebugGLTestContext.h"
22
23typedef std::vector<SkPoint> SamplePattern;
24
25static const SamplePattern kTestPatterns[] = {
26 SamplePattern{ // Intel on mac, msaa8, offscreen.
27 {0.562500, 0.312500},
28 {0.437500, 0.687500},
29 {0.812500, 0.562500},
30 {0.312500, 0.187500},
31 {0.187500, 0.812500},
32 {0.062500, 0.437500},
33 {0.687500, 0.937500},
34 {0.937500, 0.062500}
35 },
36
37 SamplePattern{ // Intel on mac, msaa8, on-screen.
38 {0.562500, 0.687500},
39 {0.437500, 0.312500},
40 {0.812500, 0.437500},
41 {0.312500, 0.812500},
42 {0.187500, 0.187500},
43 {0.062500, 0.562500},
44 {0.687500, 0.062500},
45 {0.937500, 0.937500}
46 },
47
48 SamplePattern{ // NVIDIA, msaa16.
49 {0.062500, 0.000000},
50 {0.250000, 0.125000},
51 {0.187500, 0.375000},
52 {0.437500, 0.312500},
53 {0.500000, 0.062500},
54 {0.687500, 0.187500},
55 {0.750000, 0.437500},
56 {0.937500, 0.250000},
57 {0.000000, 0.500000},
58 {0.312500, 0.625000},
59 {0.125000, 0.750000},
60 {0.375000, 0.875000},
61 {0.562500, 0.562500},
62 {0.812500, 0.687500},
63 {0.625000, 0.812500},
64 {0.875000, 0.937500}
65 },
66
67 SamplePattern{ // NVIDIA, mixed samples, 16:1.
68 {0.250000, 0.125000},
69 {0.625000, 0.812500},
70 {0.500000, 0.062500},
71 {0.812500, 0.687500},
72 {0.187500, 0.375000},
73 {0.875000, 0.937500},
74 {0.125000, 0.750000},
75 {0.750000, 0.437500},
76 {0.937500, 0.250000},
77 {0.312500, 0.625000},
78 {0.437500, 0.312500},
79 {0.000000, 0.500000},
80 {0.375000, 0.875000},
81 {0.687500, 0.187500},
82 {0.062500, 0.000000},
83 {0.562500, 0.562500}
84 }
85};
86constexpr int numTestPatterns = SK_ARRAY_COUNT(kTestPatterns);
87
88class TestSampleLocationsInterface : public SkNoncopyable {
89public:
90 virtual void overrideSamplePattern(const SamplePattern&) = 0;
91 virtual ~TestSampleLocationsInterface() {}
92};
93
Brian Salomonb5cb6832017-02-24 11:01:15 -050094static void construct_dummy_pipeline(GrRenderTargetContext* dc, GrPipeline* pipeline) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -050095 GrPipelineBuilder dummyBuilder(GrPaint(), GrAAType::kNone);
csmartdaltonc633abb2016-11-01 08:55:55 -070096 GrScissorState dummyScissor;
97 GrWindowRectsState dummyWindows;
csmartdaltonc633abb2016-11-01 08:55:55 -070098
Brian Salomonc48af932017-03-16 19:51:42 +000099 GrAppliedClip dummyAppliedClip;
Brian Salomon5298dc82017-02-22 11:52:03 -0500100 GrProcessorSet::FragmentProcessorAnalysis analysis;
Brian Salomonb5cb6832017-02-24 11:01:15 -0500101 GrPipeline::InitArgs args;
102 dummyBuilder.getPipelineInitArgs(&args);
Brian Salomonb16e8ac2017-02-22 11:52:36 -0500103 args.fRenderTarget = dc->accessRenderTarget();
Brian Salomon5298dc82017-02-22 11:52:03 -0500104 args.fAnalysis = &analysis;
csmartdaltonc633abb2016-11-01 08:55:55 -0700105 args.fCaps = dc->caps();
Brian Salomonc48af932017-03-16 19:51:42 +0000106 args.fAppliedClip = &dummyAppliedClip;
csmartdaltonc633abb2016-11-01 08:55:55 -0700107 args.fDstTexture = GrXferProcessor::DstTexture();
Brian Salomonb5cb6832017-02-24 11:01:15 -0500108 pipeline->init(args);
csmartdalton0d28e572016-07-06 09:59:43 -0700109}
110
111void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
112 const GrGpu::MultisampleSpecs& specs, bool flipY) {
113 GrAlwaysAssert(specs.fSampleLocations);
114 if ((int)pattern.size() != specs.fEffectiveSampleCnt) {
csmartdaltonc633abb2016-11-01 08:55:55 -0700115 REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong number of samples."));
csmartdalton0d28e572016-07-06 09:59:43 -0700116 return;
117 }
118 for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) {
119 SkPoint expectedLocation = specs.fSampleLocations[i];
120 if (flipY) {
121 expectedLocation.fY = 1 - expectedLocation.fY;
122 }
123 if (pattern[i] != expectedLocation) {
csmartdaltonc633abb2016-11-01 08:55:55 -0700124 REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong sample location."));
csmartdalton0d28e572016-07-06 09:59:43 -0700125 return;
126 }
127 }
128}
129
130void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInterface* testInterface,
131 GrContext* ctx) {
132 SkRandom rand;
csmartdaltonc633abb2016-11-01 08:55:55 -0700133 sk_sp<GrRenderTargetContext> bottomUps[numTestPatterns];
134 sk_sp<GrRenderTargetContext> topDowns[numTestPatterns];
csmartdalton0d28e572016-07-06 09:59:43 -0700135 for (int i = 0; i < numTestPatterns; ++i) {
136 int numSamples = (int)kTestPatterns[i].size();
137 GrAlwaysAssert(numSamples > 1 && SkIsPow2(numSamples));
csmartdaltonc633abb2016-11-01 08:55:55 -0700138 bottomUps[i] = ctx->makeRenderTargetContextWithFallback(
139 SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
140 rand.nextRangeU(1 + numSamples / 2, numSamples),
141 kBottomLeft_GrSurfaceOrigin);
142 topDowns[i] = ctx->makeRenderTargetContextWithFallback(
143 SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
144 rand.nextRangeU(1 + numSamples / 2, numSamples),
145 kTopLeft_GrSurfaceOrigin);
csmartdalton0d28e572016-07-06 09:59:43 -0700146 }
147
148 // Ensure all sample locations get queried and/or cached properly.
csmartdalton0d28e572016-07-06 09:59:43 -0700149 for (int repeat = 0; repeat < 2; ++repeat) {
150 for (int i = 0; i < numTestPatterns; ++i) {
151 testInterface->overrideSamplePattern(kTestPatterns[i]);
csmartdaltonc633abb2016-11-01 08:55:55 -0700152 for (GrRenderTargetContext* dc : {bottomUps[i].get(), topDowns[i].get()}) {
Brian Salomonb5cb6832017-02-24 11:01:15 -0500153 GrPipeline dummyPipeline;
154 construct_dummy_pipeline(dc, &dummyPipeline);
csmartdaltonc633abb2016-11-01 08:55:55 -0700155 GrRenderTarget* rt = dc->accessRenderTarget();
156 assert_equal(reporter, kTestPatterns[i],
Brian Salomonb5cb6832017-02-24 11:01:15 -0500157 rt->renderTargetPriv().getMultisampleSpecs(dummyPipeline),
csmartdaltonc633abb2016-11-01 08:55:55 -0700158 kBottomLeft_GrSurfaceOrigin == rt->origin());
csmartdaltonc633abb2016-11-01 08:55:55 -0700159 }
csmartdalton0d28e572016-07-06 09:59:43 -0700160 }
161 }
csmartdaltonc633abb2016-11-01 08:55:55 -0700162
csmartdalton0d28e572016-07-06 09:59:43 -0700163}
164
165////////////////////////////////////////////////////////////////////////////////////////////////////
166
167class GLTestSampleLocationsInterface : public TestSampleLocationsInterface, public GrGLInterface {
168public:
169 GLTestSampleLocationsInterface() : fTestContext(sk_gpu_test::CreateDebugGLTestContext()) {
170 fStandard = fTestContext->gl()->fStandard;
171 fExtensions = fTestContext->gl()->fExtensions;
172 fFunctions = fTestContext->gl()->fFunctions;
173
174 fFunctions.fGetIntegerv = [&](GrGLenum pname, GrGLint* params) {
175 GrAlwaysAssert(GR_GL_EFFECTIVE_RASTER_SAMPLES != pname);
176 if (GR_GL_SAMPLES == pname) {
177 GrAlwaysAssert(!fSamplePattern.empty());
178 *params = (int)fSamplePattern.size();
179 } else {
180 fTestContext->gl()->fFunctions.fGetIntegerv(pname, params);
181 }
182 };
183
184 fFunctions.fGetMultisamplefv = [&](GrGLenum pname, GrGLuint index, GrGLfloat* val) {
185 GrAlwaysAssert(GR_GL_SAMPLE_POSITION == pname);
186 val[0] = fSamplePattern[index].fX;
187 val[1] = fSamplePattern[index].fY;
188 };
189 }
190
191 operator GrBackendContext() {
192 return reinterpret_cast<GrBackendContext>(static_cast<GrGLInterface*>(this));
193 }
194
195 void overrideSamplePattern(const SamplePattern& newPattern) override {
196 fSamplePattern = newPattern;
197 }
198
199private:
Ben Wagner145dbcd2016-11-03 14:40:50 -0400200 std::unique_ptr<sk_gpu_test::GLTestContext> fTestContext;
csmartdalton0d28e572016-07-06 09:59:43 -0700201 SamplePattern fSamplePattern;
202};
203
204DEF_GPUTEST(GLSampleLocations, reporter, /*factory*/) {
205 GLTestSampleLocationsInterface testInterface;
Hal Canary342b7ac2016-11-04 11:49:42 -0400206 sk_sp<GrContext> ctx(GrContext::Create(kOpenGL_GrBackend, testInterface));
207 test_sampleLocations(reporter, &testInterface, ctx.get());
csmartdalton0d28e572016-07-06 09:59:43 -0700208}
209
210#endif