aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/PrimitiveProcessorTest.cpp
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-03-23 11:50:26 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-23 11:50:26 -0700
commit1d417a8738304c115f3547ecc34dda7a7d75b97a (patch)
treedcd9b55ade66a51972f352244da1e2aa5bf521c3 /tests/PrimitiveProcessorTest.cpp
parentf799706656f2581c5bf5510d94df3fa17cce1607 (diff)
Add unit test for vertex attribute count.
Diffstat (limited to 'tests/PrimitiveProcessorTest.cpp')
-rw-r--r--tests/PrimitiveProcessorTest.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
new file mode 100644
index 0000000000..922b4fd892
--- /dev/null
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -0,0 +1,155 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// This is a GPU-backend specific test. It relies on static intializers to work
+
+#include "SkTypes.h"
+#include "Test.h"
+
+#if SK_SUPPORT_GPU
+#include "GrBatchFlushState.h"
+#include "GrDrawContext.h"
+#include "GrDrawContextPriv.h"
+#include "GrContext.h"
+#include "GrGeometryProcessor.h"
+#include "GrGpu.h"
+#include "GrTextureProvider.h"
+#include "glsl/GrGLSLGeometryProcessor.h"
+#include "glsl/GrGLSLVarying.h"
+#include "batches/GrVertexBatch.h"
+#include "SkString.h"
+
+namespace {
+class Batch : public GrVertexBatch {
+public:
+ DEFINE_BATCH_CLASS_ID
+
+ const char* name() const override { return "Dummy Batch"; }
+ void computePipelineOptimizations(GrInitInvariantOutput* color,
+ GrInitInvariantOutput* coverage,
+ GrBatchToXPOverrides* overrides) const override {
+ color->setUnknownFourComponents();
+ coverage->setUnknownSingleComponent();
+ }
+
+ void initBatchTracker(const GrXPOverridesForBatch& overrides) override {}
+
+ Batch(int numAttribs)
+ : INHERITED(ClassID())
+ , fNumAttribs(numAttribs) {
+ this->setBounds(SkRect::MakeWH(1.f, 1.f));
+ }
+
+private:
+ bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; }
+ void onPrepareDraws(Target* target) const override {
+ class GP : public GrGeometryProcessor {
+ public:
+ GP(int numAttribs) {
+ this->initClassID<GP>();
+ SkASSERT(numAttribs > 1);
+ for (auto i = 0; i < numAttribs; ++i) {
+ fAttribNames.push_back().printf("attr%d", i);
+ }
+ for (auto i = 0; i < numAttribs; ++i) {
+ Attribute attribute;
+ attribute.fType = kVec2f_GrVertexAttribType;
+ attribute.fName = fAttribNames[i].c_str();
+ attribute.fOffset = 2 * sizeof(float) * i;
+ attribute.fPrecision = kDefault_GrSLPrecision;
+ this->addVertexAttrib(attribute);
+ }
+ };
+ const char* name() const override { return "Dummy GP"; }
+
+ GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override {
+ class GLSLGP : public GrGLSLGeometryProcessor {
+ public:
+ void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
+ const GP& gp = args.fGP.cast<GP>();
+ args.fVaryingHandler->emitAttributes(gp);
+ this->setupPosition(args.fVertBuilder, gpArgs, gp.fAttribs[0].fName);
+ }
+ void setData(const GrGLSLProgramDataManager& pdman,
+ const GrPrimitiveProcessor& primProc) override {}
+ };
+ return new GLSLGP();
+ }
+ void getGLSLProcessorKey(const GrGLSLCaps&,
+ GrProcessorKeyBuilder* builder) const override {
+ builder->add32(this->numAttribs());
+ }
+
+ private:
+ SkTArray<SkString> fAttribNames;
+ };
+ SkAutoTUnref<GrGeometryProcessor> gp(new GP(fNumAttribs));
+ target->initDraw(gp);
+ QuadHelper helper;
+ size_t vertexStride = gp->getVertexStride();
+ SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
+ vertices->setRectFan(0.f, 0.f, 1.f, 1.f, vertexStride);
+ helper.recordDraw(target);
+ }
+
+ int fNumAttribs;
+
+ typedef GrVertexBatch INHERITED;
+};
+}
+
+DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, context) {
+ GrTextureDesc desc;
+ desc.fHeight = 1;
+ desc.fWidth = 1;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
+ desc.fConfig = kRGBA_8888_GrPixelConfig;
+ SkAutoTUnref<GrTexture> target(context->textureProvider()->createTexture(desc,
+ SkBudgeted::kYes));
+ if (!target) {
+ ERRORF(reporter, "Could not create render target.");
+ return;
+ }
+ SkAutoTUnref<GrDrawContext> dc(context->drawContext(target->asRenderTarget()));
+ if (!dc) {
+ ERRORF(reporter, "Could not create draw context.");
+ return;
+ }
+ int attribCnt = context->caps()->maxVertexAttributes();
+ if (!attribCnt) {
+ ERRORF(reporter, "No attributes allowed?!");
+ return;
+ }
+ context->flush();
+ context->resetGpuStats();
+#if GR_GPU_STATS
+ REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
+ REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
+#endif
+ SkAutoTUnref<GrDrawBatch> batch;
+ GrPipelineBuilder pb;
+ pb.setRenderTarget(target->asRenderTarget());
+ // This one should succeed.
+ batch.reset(new Batch(attribCnt));
+ dc->drawContextPriv().testingOnly_drawBatch(pb, batch);
+ context->flush();
+#if GR_GPU_STATS
+ REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
+ REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
+#endif
+ context->resetGpuStats();
+ // This one should fail.
+ batch.reset(new Batch(attribCnt+1));
+ dc->drawContextPriv().testingOnly_drawBatch(pb, batch);
+ context->flush();
+#if GR_GPU_STATS
+ REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
+ REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
+#endif
+}
+#endif