blob: 21788d2382a43097455767cbfbfc31f031bfc007 [file] [log] [blame]
jchen1082af6202018-06-22 10:59:52 +08001//
2// Copyright 2018 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// ParallelShaderCompileTest.cpp : Tests of the GL_KHR_parallel_shader_compile extension.
8
9#include "test_utils/ANGLETest.h"
10
jchen107ae70d82018-07-06 13:47:01 +080011#include "random_utils.h"
12
jchen1082af6202018-06-22 10:59:52 +080013using namespace angle;
14
15namespace
16{
17
18class ParallelShaderCompileTest : public ANGLETest
19{
20 protected:
21 ParallelShaderCompileTest()
22 {
23 setWindowWidth(128);
24 setWindowHeight(128);
25 setConfigRedBits(8);
26 setConfigGreenBits(8);
27 setConfigBlueBits(8);
28 setConfigAlphaBits(8);
29 }
30
31 void SetUp() override { ANGLETest::SetUp(); }
32
33 void TearDown() override { ANGLETest::TearDown(); }
34
35 bool ensureParallelShaderCompileExtensionAvailable()
36 {
37 if (extensionRequestable("GL_KHR_parallel_shader_compile"))
38 {
39 glRequestExtensionANGLE("GL_KHR_parallel_shader_compile");
40 }
41
42 if (!extensionEnabled("GL_KHR_parallel_shader_compile"))
43 {
44 return false;
45 }
46 return true;
47 }
jchen107ae70d82018-07-06 13:47:01 +080048
49 class ClearColorWithDraw
50 {
51 public:
52 ClearColorWithDraw(GLubyte color) : mColor(color, color, color, 255) {}
53
54 bool compileAndLink()
55 {
56 mProgram =
57 CompileProgramParallel(insertRandomString(essl1_shaders::vs::Simple()),
58 insertRandomString(essl1_shaders::fs::UniformColor()));
59 return (mProgram != 0);
60 }
61
62 bool isLinkCompleted()
63 {
64 GLint status;
65 glGetProgramiv(mProgram, GL_COMPLETION_STATUS_KHR, &status);
66 return (status == GL_TRUE);
67 }
68
69 void drawAndVerify(ParallelShaderCompileTest *test)
70 {
71 glClearColor(0, 0, 0, 0);
72 glClear(GL_COLOR_BUFFER_BIT);
73 glDisable(GL_DEPTH_TEST);
74 glUseProgram(mProgram);
75 ASSERT_GL_NO_ERROR();
76 GLint colorUniformLocation =
77 glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
78 ASSERT_NE(colorUniformLocation, -1);
79 auto normalizeColor = mColor.toNormalizedVector();
80 glUniform4fv(colorUniformLocation, 1, normalizeColor.data());
81 test->drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
82 EXPECT_PIXEL_COLOR_EQ(test->getWindowWidth() / 2, test->getWindowHeight() / 2, mColor);
83 glUseProgram(0);
84 glDeleteProgram(mProgram);
85 ASSERT_GL_NO_ERROR();
86 }
87
88 private:
89 std::string insertRandomString(const std::string &source)
90 {
91 RNG rng;
92 std::ostringstream ostream;
93 ostream << "// Random string to fool program cache: " << rng.randomInt() << "\n"
94 << source;
95 return ostream.str();
96 }
97
98 GLColor mColor;
99 GLuint mProgram;
100 };
jchen1082af6202018-06-22 10:59:52 +0800101};
102
103// Test basic functionality of GL_KHR_parallel_shader_compile
104TEST_P(ParallelShaderCompileTest, Basic)
105{
106 ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
107
108 GLint count = 0;
109 glMaxShaderCompilerThreadsKHR(8);
110 EXPECT_GL_NO_ERROR();
111 glGetIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &count);
112 EXPECT_GL_NO_ERROR();
113 EXPECT_EQ(8, count);
114}
115
jchen107ae70d82018-07-06 13:47:01 +0800116// Test to compile and link many programs in parallel.
117TEST_P(ParallelShaderCompileTest, LinkAndDrawManyPrograms)
118{
119 ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
120
121 std::vector<std::unique_ptr<ClearColorWithDraw>> tasks;
122 constexpr int kTaskCount = 32;
123 for (int i = 0; i < kTaskCount; ++i)
124 {
125 std::unique_ptr<ClearColorWithDraw> task(new ClearColorWithDraw(i * 255 / kTaskCount));
126 bool isLinking = task->compileAndLink();
127 ASSERT_TRUE(isLinking);
128 tasks.push_back(std::move(task));
129 }
130 constexpr unsigned int kPollInterval = 100;
131 while (!tasks.empty())
132 {
133 for (unsigned int i = 0; i < tasks.size();)
134 {
135 auto &task = tasks[i];
136 if (task->isLinkCompleted())
137 {
138 task->drawAndVerify(this);
139 tasks.erase(tasks.begin() + i);
140 continue;
141 }
142 ++i;
143 }
144 Sleep(kPollInterval);
145 }
146}
147
jchen1082af6202018-06-22 10:59:52 +0800148ANGLE_INSTANTIATE_TEST(ParallelShaderCompileTest,
149 ES2_D3D9(),
150 ES2_D3D11(),
151 ES2_D3D11_FL9_3(),
152 ES2_OPENGL(),
153 ES2_OPENGLES(),
154 ES2_VULKAN());
155
156} // namespace