GLProgramsTest.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /*
  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. // This is a GPU-backend specific test.
  8. #include "include/core/SkTypes.h"
  9. #include "include/private/SkChecksum.h"
  10. #include "include/utils/SkRandom.h"
  11. #include "src/gpu/GrAutoLocaleSetter.h"
  12. #include "src/gpu/GrContextPriv.h"
  13. #include "src/gpu/GrDrawOpTest.h"
  14. #include "src/gpu/GrDrawingManager.h"
  15. #include "src/gpu/GrPipeline.h"
  16. #include "src/gpu/GrRenderTargetContextPriv.h"
  17. #include "src/gpu/GrXferProcessor.h"
  18. #include "tests/Test.h"
  19. #include "tools/gpu/GrContextFactory.h"
  20. #include "src/gpu/ops/GrDrawOp.h"
  21. #include "src/gpu/effects/GrPorterDuffXferProcessor.h"
  22. #include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
  23. #include "src/gpu/effects/generated/GrConfigConversionEffect.h"
  24. #include "src/gpu/gl/GrGLGpu.h"
  25. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  26. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  27. #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
  28. /*
  29. * A dummy processor which just tries to insert a massive key and verify that it can retrieve the
  30. * whole thing correctly
  31. */
  32. static const uint32_t kMaxKeySize = 1024;
  33. class GLBigKeyProcessor : public GrGLSLFragmentProcessor {
  34. public:
  35. void emitCode(EmitArgs& args) override {
  36. // pass through
  37. GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
  38. if (args.fInputColor) {
  39. fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
  40. } else {
  41. fragBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
  42. }
  43. }
  44. static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
  45. for (uint32_t i = 0; i < kMaxKeySize; i++) {
  46. b->add32(i);
  47. }
  48. }
  49. private:
  50. typedef GrGLSLFragmentProcessor INHERITED;
  51. };
  52. class BigKeyProcessor : public GrFragmentProcessor {
  53. public:
  54. static std::unique_ptr<GrFragmentProcessor> Make() {
  55. return std::unique_ptr<GrFragmentProcessor>(new BigKeyProcessor);
  56. }
  57. const char* name() const override { return "Big Ole Key"; }
  58. GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
  59. return new GLBigKeyProcessor;
  60. }
  61. std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }
  62. private:
  63. BigKeyProcessor() : INHERITED(kBigKeyProcessor_ClassID, kNone_OptimizationFlags) { }
  64. virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
  65. GrProcessorKeyBuilder* b) const override {
  66. GLBigKeyProcessor::GenKey(*this, caps, b);
  67. }
  68. bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
  69. GR_DECLARE_FRAGMENT_PROCESSOR_TEST
  70. typedef GrFragmentProcessor INHERITED;
  71. };
  72. GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor);
  73. #if GR_TEST_UTILS
  74. std::unique_ptr<GrFragmentProcessor> BigKeyProcessor::TestCreate(GrProcessorTestData*) {
  75. return BigKeyProcessor::Make();
  76. }
  77. #endif
  78. //////////////////////////////////////////////////////////////////////////////
  79. class BlockInputFragmentProcessor : public GrFragmentProcessor {
  80. public:
  81. static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
  82. return std::unique_ptr<GrFragmentProcessor>(new BlockInputFragmentProcessor(std::move(fp)));
  83. }
  84. const char* name() const override { return "Block Input"; }
  85. GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLFP; }
  86. std::unique_ptr<GrFragmentProcessor> clone() const override {
  87. return Make(this->childProcessor(0).clone());
  88. }
  89. private:
  90. class GLFP : public GrGLSLFragmentProcessor {
  91. public:
  92. void emitCode(EmitArgs& args) override {
  93. this->emitChild(0, args);
  94. }
  95. private:
  96. typedef GrGLSLFragmentProcessor INHERITED;
  97. };
  98. BlockInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child)
  99. : INHERITED(kBlockInputFragmentProcessor_ClassID, kNone_OptimizationFlags) {
  100. this->registerChildProcessor(std::move(child));
  101. }
  102. void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {}
  103. bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
  104. typedef GrFragmentProcessor INHERITED;
  105. };
  106. //////////////////////////////////////////////////////////////////////////////
  107. /*
  108. * Begin test code
  109. */
  110. static const int kRenderTargetHeight = 1;
  111. static const int kRenderTargetWidth = 1;
  112. static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* context,
  113. SkRandom* random,
  114. const GrCaps* caps) {
  115. GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
  116. : kBottomLeft_GrSurfaceOrigin;
  117. GrColorType ct = GrColorType::kRGBA_8888;
  118. const GrBackendFormat format = caps->getBackendFormatFromColorType(ct);
  119. int sampleCnt = random->nextBool() ? caps->getRenderTargetSampleCount(2, ct, format) : 1;
  120. // Above could be 0 if msaa isn't supported.
  121. sampleCnt = SkTMax(1, sampleCnt);
  122. sk_sp<GrRenderTargetContext> renderTargetContext(
  123. context->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
  124. kRenderTargetWidth,
  125. kRenderTargetHeight,
  126. GrColorType::kRGBA_8888,
  127. nullptr,
  128. sampleCnt,
  129. GrMipMapped::kNo,
  130. origin));
  131. return renderTargetContext;
  132. }
  133. #if GR_TEST_UTILS
  134. static void set_random_xpf(GrPaint* paint, GrProcessorTestData* d) {
  135. paint->setXPFactory(GrXPFactoryTestFactory::Get(d));
  136. }
  137. static std::unique_ptr<GrFragmentProcessor> create_random_proc_tree(GrProcessorTestData* d,
  138. int minLevels, int maxLevels) {
  139. SkASSERT(1 <= minLevels);
  140. SkASSERT(minLevels <= maxLevels);
  141. // Return a leaf node if maxLevels is 1 or if we randomly chose to terminate.
  142. // If returning a leaf node, make sure that it doesn't have children (e.g. another
  143. // GrComposeEffect)
  144. const float terminateProbability = 0.3f;
  145. if (1 == minLevels) {
  146. bool terminate = (1 == maxLevels) || (d->fRandom->nextF() < terminateProbability);
  147. if (terminate) {
  148. std::unique_ptr<GrFragmentProcessor> fp;
  149. while (true) {
  150. fp = GrFragmentProcessorTestFactory::Make(d);
  151. if (!fp) {
  152. return nullptr;
  153. }
  154. if (0 == fp->numChildProcessors()) {
  155. break;
  156. }
  157. }
  158. return fp;
  159. }
  160. }
  161. // If we didn't terminate, choose either the left or right subtree to fulfill
  162. // the minLevels requirement of this tree; the other child can have as few levels as it wants.
  163. // Also choose a random xfer mode.
  164. if (minLevels > 1) {
  165. --minLevels;
  166. }
  167. auto minLevelsChild = create_random_proc_tree(d, minLevels, maxLevels - 1);
  168. std::unique_ptr<GrFragmentProcessor> otherChild(create_random_proc_tree(d, 1, maxLevels - 1));
  169. if (!minLevelsChild || !otherChild) {
  170. return nullptr;
  171. }
  172. SkBlendMode mode = static_cast<SkBlendMode>(d->fRandom->nextRangeU(0,
  173. (int)SkBlendMode::kLastMode));
  174. std::unique_ptr<GrFragmentProcessor> fp;
  175. if (d->fRandom->nextF() < 0.5f) {
  176. fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(minLevelsChild),
  177. std::move(otherChild), mode);
  178. SkASSERT(fp);
  179. } else {
  180. fp = GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(otherChild),
  181. std::move(minLevelsChild), mode);
  182. SkASSERT(fp);
  183. }
  184. return fp;
  185. }
  186. static void set_random_color_coverage_stages(GrPaint* paint,
  187. GrProcessorTestData* d,
  188. int maxStages,
  189. int maxTreeLevels) {
  190. // Randomly choose to either create a linear pipeline of procs or create one proc tree
  191. const float procTreeProbability = 0.5f;
  192. if (d->fRandom->nextF() < procTreeProbability) {
  193. std::unique_ptr<GrFragmentProcessor> fp(create_random_proc_tree(d, 2, maxTreeLevels));
  194. if (fp) {
  195. paint->addColorFragmentProcessor(std::move(fp));
  196. }
  197. } else {
  198. int numProcs = d->fRandom->nextULessThan(maxStages + 1);
  199. int numColorProcs = d->fRandom->nextULessThan(numProcs + 1);
  200. for (int s = 0; s < numProcs; ++s) {
  201. std::unique_ptr<GrFragmentProcessor> fp(GrFragmentProcessorTestFactory::Make(d));
  202. if (!fp) {
  203. continue;
  204. }
  205. // finally add the stage to the correct pipeline in the drawstate
  206. if (s < numColorProcs) {
  207. paint->addColorFragmentProcessor(std::move(fp));
  208. } else {
  209. paint->addCoverageFragmentProcessor(std::move(fp));
  210. }
  211. }
  212. }
  213. }
  214. #endif
  215. #if !GR_TEST_UTILS
  216. bool GrDrawingManager::ProgramUnitTest(GrContext*, int) { return true; }
  217. #else
  218. bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int maxLevels) {
  219. GrDrawingManager* drawingManager = context->priv().drawingManager();
  220. GrProxyProvider* proxyProvider = context->priv().proxyProvider();
  221. sk_sp<GrTextureProxy> proxies[2];
  222. // setup dummy textures
  223. GrMipMapped mipMapped = GrMipMapped(context->priv().caps()->mipMapSupport());
  224. {
  225. GrSurfaceDesc dummyDesc;
  226. dummyDesc.fWidth = 34;
  227. dummyDesc.fHeight = 18;
  228. dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
  229. const GrBackendFormat format =
  230. context->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
  231. proxies[0] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kYes, 1,
  232. kBottomLeft_GrSurfaceOrigin, mipMapped,
  233. SkBackingFit::kExact, SkBudgeted::kNo,
  234. GrProtected::kNo, GrInternalSurfaceFlags::kNone);
  235. }
  236. {
  237. GrSurfaceDesc dummyDesc;
  238. dummyDesc.fWidth = 16;
  239. dummyDesc.fHeight = 22;
  240. dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
  241. const GrBackendFormat format =
  242. context->priv().caps()->getBackendFormatFromColorType(GrColorType::kAlpha_8);
  243. proxies[1] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kNo, 1,
  244. kTopLeft_GrSurfaceOrigin, mipMapped,
  245. SkBackingFit::kExact, SkBudgeted::kNo,
  246. GrProtected::kNo, GrInternalSurfaceFlags::kNone);
  247. }
  248. if (!proxies[0] || !proxies[1]) {
  249. SkDebugf("Could not allocate dummy textures");
  250. return false;
  251. }
  252. // dummy scissor state
  253. GrScissorState scissor;
  254. SkRandom random;
  255. static const int NUM_TESTS = 1024;
  256. for (int t = 0; t < NUM_TESTS; t++) {
  257. // setup random render target(can fail)
  258. sk_sp<GrRenderTargetContext> renderTargetContext(
  259. random_render_target_context(context, &random, context->priv().caps()));
  260. if (!renderTargetContext) {
  261. SkDebugf("Could not allocate renderTargetContext");
  262. return false;
  263. }
  264. GrPaint paint;
  265. GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
  266. set_random_color_coverage_stages(&paint, &ptd, maxStages, maxLevels);
  267. set_random_xpf(&paint, &ptd);
  268. GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
  269. }
  270. // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
  271. drawingManager->flush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, GrFlushInfo(),
  272. GrPrepareForExternalIORequests());
  273. // Validate that GrFPs work correctly without an input.
  274. sk_sp<GrRenderTargetContext> renderTargetContext(
  275. context->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
  276. kRenderTargetWidth,
  277. kRenderTargetHeight,
  278. GrColorType::kRGBA_8888,
  279. nullptr));
  280. if (!renderTargetContext) {
  281. SkDebugf("Could not allocate a renderTargetContext");
  282. return false;
  283. }
  284. int fpFactoryCnt = GrFragmentProcessorTestFactory::Count();
  285. for (int i = 0; i < fpFactoryCnt; ++i) {
  286. // Since FP factories internally randomize, call each 10 times.
  287. for (int j = 0; j < 10; ++j) {
  288. GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
  289. GrPaint paint;
  290. paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
  291. auto fp = GrFragmentProcessorTestFactory::MakeIdx(i, &ptd);
  292. auto blockFP = BlockInputFragmentProcessor::Make(std::move(fp));
  293. paint.addColorFragmentProcessor(std::move(blockFP));
  294. GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
  295. drawingManager->flush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess,
  296. GrFlushInfo(), GrPrepareForExternalIORequests());
  297. }
  298. }
  299. return true;
  300. }
  301. #endif
  302. static int get_glprograms_max_stages(const sk_gpu_test::ContextInfo& ctxInfo) {
  303. GrContext* context = ctxInfo.grContext();
  304. GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
  305. int maxStages = 6;
  306. if (kGLES_GrGLStandard == gpu->glStandard()) {
  307. // We've had issues with driver crashes and HW limits being exceeded with many effects on
  308. // Android devices. We have passes on ARM devices with the default number of stages.
  309. // TODO When we run ES 3.00 GLSL in more places, test again
  310. #ifdef SK_BUILD_FOR_ANDROID
  311. if (kARM_GrGLVendor != gpu->ctxInfo().vendor()) {
  312. maxStages = 1;
  313. }
  314. #endif
  315. // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
  316. #ifdef SK_BUILD_FOR_IOS
  317. maxStages = 3;
  318. #endif
  319. }
  320. if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
  321. ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
  322. // On Angle D3D we will hit a limit of out variables if we use too many stages.
  323. maxStages = 3;
  324. }
  325. return maxStages;
  326. }
  327. static int get_glprograms_max_levels(const sk_gpu_test::ContextInfo& ctxInfo) {
  328. // A full tree with 5 levels (31 nodes) may cause a program that exceeds shader limits
  329. // (e.g. uniform or varying limits); maxTreeLevels should be a number from 1 to 4 inclusive.
  330. int maxTreeLevels = 4;
  331. // On iOS we can exceed the maximum number of varyings. http://skbug.com/6627.
  332. #ifdef SK_BUILD_FOR_IOS
  333. maxTreeLevels = 2;
  334. #endif
  335. if (ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D9_ES2_ContextType ||
  336. ctxInfo.type() == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES2_ContextType) {
  337. // On Angle D3D we will hit a limit of out variables if we use too many stages.
  338. maxTreeLevels = 2;
  339. }
  340. return maxTreeLevels;
  341. }
  342. static void test_glprograms(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& ctxInfo) {
  343. int maxStages = get_glprograms_max_stages(ctxInfo);
  344. if (maxStages == 0) {
  345. return;
  346. }
  347. int maxLevels = get_glprograms_max_levels(ctxInfo);
  348. if (maxLevels == 0) {
  349. return;
  350. }
  351. REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(ctxInfo.grContext(), maxStages,
  352. maxLevels));
  353. }
  354. DEF_GPUTEST(GLPrograms, reporter, options) {
  355. // Set a locale that would cause shader compilation to fail because of , as decimal separator.
  356. // skbug 3330
  357. #ifdef SK_BUILD_FOR_WIN
  358. GrAutoLocaleSetter als("sv-SE");
  359. #else
  360. GrAutoLocaleSetter als("sv_SE.UTF-8");
  361. #endif
  362. // We suppress prints to avoid spew
  363. GrContextOptions opts = options;
  364. opts.fSuppressPrints = true;
  365. sk_gpu_test::GrContextFactory debugFactory(opts);
  366. skiatest::RunWithGPUTestContexts(test_glprograms, &skiatest::IsRenderingGLContextType, reporter,
  367. opts);
  368. }