PrimitiveProcessorTest.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  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. // This is a GPU-backend specific test. It relies on static intializers to work
  8. #include "include/core/SkTypes.h"
  9. #include "tests/Test.h"
  10. #include "include/core/SkString.h"
  11. #include "include/gpu/GrContext.h"
  12. #include "src/core/SkPointPriv.h"
  13. #include "src/gpu/GrContextPriv.h"
  14. #include "src/gpu/GrGeometryProcessor.h"
  15. #include "src/gpu/GrGpu.h"
  16. #include "src/gpu/GrMemoryPool.h"
  17. #include "src/gpu/GrOpFlushState.h"
  18. #include "src/gpu/GrRenderTargetContext.h"
  19. #include "src/gpu/GrRenderTargetContextPriv.h"
  20. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  21. #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
  22. #include "src/gpu/glsl/GrGLSLVarying.h"
  23. #include "src/gpu/ops/GrMeshDrawOp.h"
  24. namespace {
  25. class Op : public GrMeshDrawOp {
  26. public:
  27. DEFINE_OP_CLASS_ID
  28. const char* name() const override { return "Dummy Op"; }
  29. static std::unique_ptr<GrDrawOp> Make(GrContext* context, int numAttribs) {
  30. GrOpMemoryPool* pool = context->priv().opMemoryPool();
  31. return pool->allocate<Op>(numAttribs);
  32. }
  33. FixedFunctionFlags fixedFunctionFlags() const override {
  34. return FixedFunctionFlags::kNone;
  35. }
  36. GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
  37. bool hasMixedSampledCoverage, GrClampType) override {
  38. return GrProcessorSet::EmptySetAnalysis();
  39. }
  40. private:
  41. friend class ::GrOpMemoryPool;
  42. Op(int numAttribs) : INHERITED(ClassID()), fNumAttribs(numAttribs) {
  43. this->setBounds(SkRect::MakeWH(1.f, 1.f), HasAABloat::kNo, IsZeroArea::kNo);
  44. }
  45. void onPrepareDraws(Target* target) override {
  46. class GP : public GrGeometryProcessor {
  47. public:
  48. GP(int numAttribs) : INHERITED(kGP_ClassID), fNumAttribs(numAttribs) {
  49. SkASSERT(numAttribs > 1);
  50. fAttribNames.reset(new SkString[numAttribs]);
  51. fAttributes.reset(new Attribute[numAttribs]);
  52. for (auto i = 0; i < numAttribs; ++i) {
  53. fAttribNames[i].printf("attr%d", i);
  54. // This gives us more of a mix of attribute types, and allows the
  55. // component count to fit within the limits for iOS Metal.
  56. if (i & 0x1) {
  57. fAttributes[i] = {fAttribNames[i].c_str(), kFloat_GrVertexAttribType,
  58. kFloat_GrSLType};
  59. } else {
  60. fAttributes[i] = {fAttribNames[i].c_str(), kFloat2_GrVertexAttribType,
  61. kFloat2_GrSLType};
  62. }
  63. }
  64. this->setVertexAttributes(fAttributes.get(), numAttribs);
  65. }
  66. const char* name() const override { return "Dummy GP"; }
  67. GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
  68. class GLSLGP : public GrGLSLGeometryProcessor {
  69. public:
  70. void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
  71. const GP& gp = args.fGP.cast<GP>();
  72. args.fVaryingHandler->emitAttributes(gp);
  73. this->writeOutputPosition(args.fVertBuilder, gpArgs,
  74. gp.fAttributes[0].name());
  75. GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
  76. fragBuilder->codeAppendf("%s = half4(1);", args.fOutputColor);
  77. fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
  78. }
  79. void setData(const GrGLSLProgramDataManager& pdman,
  80. const GrPrimitiveProcessor& primProc,
  81. FPCoordTransformIter&&) override {}
  82. };
  83. return new GLSLGP();
  84. }
  85. void getGLSLProcessorKey(const GrShaderCaps&,
  86. GrProcessorKeyBuilder* builder) const override {
  87. builder->add32(fNumAttribs);
  88. }
  89. private:
  90. int fNumAttribs;
  91. std::unique_ptr<SkString[]> fAttribNames;
  92. std::unique_ptr<Attribute[]> fAttributes;
  93. typedef GrGeometryProcessor INHERITED;
  94. };
  95. sk_sp<GrGeometryProcessor> gp(new GP(fNumAttribs));
  96. size_t vertexStride = gp->vertexStride();
  97. QuadHelper helper(target, vertexStride, 1);
  98. SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.vertices());
  99. SkPointPriv::SetRectTriStrip(vertices, 0.f, 0.f, 1.f, 1.f, vertexStride);
  100. helper.recordDraw(target, std::move(gp));
  101. }
  102. void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
  103. flushState->executeDrawsAndUploadsForMeshDrawOp(
  104. this, chainBounds, GrProcessorSet::MakeEmptySet());
  105. }
  106. int fNumAttribs;
  107. typedef GrMeshDrawOp INHERITED;
  108. };
  109. }
  110. DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
  111. GrContext* context = ctxInfo.grContext();
  112. #if GR_GPU_STATS
  113. GrGpu* gpu = context->priv().getGpu();
  114. #endif
  115. sk_sp<GrRenderTargetContext> renderTargetContext(
  116. context->priv().makeDeferredRenderTargetContext(SkBackingFit::kApprox, 1, 1,
  117. GrColorType::kRGBA_8888, nullptr));
  118. if (!renderTargetContext) {
  119. ERRORF(reporter, "Could not create render target context.");
  120. return;
  121. }
  122. int attribCnt = context->priv().caps()->maxVertexAttributes();
  123. if (!attribCnt) {
  124. ERRORF(reporter, "No attributes allowed?!");
  125. return;
  126. }
  127. context->flush();
  128. context->priv().resetGpuStats();
  129. #if GR_GPU_STATS
  130. REPORTER_ASSERT(reporter, gpu->stats()->numDraws() == 0);
  131. REPORTER_ASSERT(reporter, gpu->stats()->numFailedDraws() == 0);
  132. #endif
  133. // Adding discard to appease vulkan validation warning about loading uninitialized data on draw
  134. renderTargetContext->discard();
  135. GrPaint grPaint;
  136. // This one should succeed.
  137. renderTargetContext->priv().testingOnly_addDrawOp(Op::Make(context, attribCnt));
  138. context->flush();
  139. #if GR_GPU_STATS
  140. REPORTER_ASSERT(reporter, gpu->stats()->numDraws() == 1);
  141. REPORTER_ASSERT(reporter, gpu->stats()->numFailedDraws() == 0);
  142. #endif
  143. context->priv().resetGpuStats();
  144. renderTargetContext->priv().testingOnly_addDrawOp(Op::Make(context, attribCnt + 1));
  145. context->flush();
  146. #if GR_GPU_STATS
  147. REPORTER_ASSERT(reporter, gpu->stats()->numDraws() == 0);
  148. REPORTER_ASSERT(reporter, gpu->stats()->numFailedDraws() == 1);
  149. #endif
  150. }