Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc

Issue 1309743005: command_buffer: Implement EXT_blend_func_extended (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new-05-path-fragment-input-gen
Patch Set: rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/test_helper.cc ('k') | gpu/gpu.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <GLES2/gl2.h>
6 #include <GLES2/gl2ext.h>
7 #include <GLES2/gl2extchromium.h>
8 #include <GLES3/gl3.h>
9
10 #include "base/command_line.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "gpu/command_buffer/service/gpu_switches.h"
13 #include "gpu/command_buffer/tests/gl_manager.h"
14 #include "gpu/command_buffer/tests/gl_test_utils.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/gl/gl_switches.h"
18
19 #define SHADER(Src) #Src
20 #define BFE_SHADER(Src) "#extension GL_EXT_blend_func_extended : require\n" #Src
21
22 namespace {
23 // Partial implementation of weight function for GLES 2 blend equation that
24 // is dual-source aware.
25 template <int factor, int index>
26 float Weight(float /*dst*/[4], float src[4], float src1[4]) {
27 if (factor == GL_SRC_COLOR)
28 return src[index];
29 if (factor == GL_SRC_ALPHA)
30 return src[3];
31 if (factor == GL_SRC1_COLOR_EXT)
32 return src1[index];
33 if (factor == GL_SRC1_ALPHA_EXT)
34 return src1[3];
35 if (factor == GL_ONE_MINUS_SRC1_COLOR_EXT)
36 return 1.0f - src1[index];
37 if (factor == GL_ONE_MINUS_SRC1_ALPHA_EXT)
38 return 1.0f - src1[3];
39 return 0.0f;
40 }
41
42 // Implementation of GLES 2 blend equation that is dual-source aware.
43 template <int RGBs, int RGBd, int As, int Ad>
44 void BlendEquationFuncAdd(float dst[4],
45 float src[4],
46 float src1[4],
47 uint8 result[4]) {
48 float r[4];
49 r[0] = src[0] * Weight<RGBs, 0>(dst, src, src1) +
50 dst[0] * Weight<RGBd, 0>(dst, src, src1);
51 r[1] = src[1] * Weight<RGBs, 1>(dst, src, src1) +
52 dst[1] * Weight<RGBd, 1>(dst, src, src1);
53 r[2] = src[2] * Weight<RGBs, 2>(dst, src, src1) +
54 dst[2] * Weight<RGBd, 2>(dst, src, src1);
55 r[3] = src[3] * Weight<As, 3>(dst, src, src1) +
56 dst[3] * Weight<Ad, 3>(dst, src, src1);
57 for (int i = 0; i < 4; ++i) {
58 result[i] = static_cast<uint8>(
59 std::floor(std::max(0.0f, std::min(1.0f, r[i])) * 255.0f));
60 }
61 }
62
63 } // namespace
64
65 namespace gpu {
66
67 class EXTBlendFuncExtendedTest : public testing::Test {
68 public:
69 protected:
70 void SetUp() override { gl_.Initialize(GLManager::Options()); }
71
72 void TearDown() override { gl_.Destroy(); }
73 bool IsApplicable() const {
74 return GLTestHelper::HasExtension("GL_EXT_blend_func_extended");
75 }
76 GLManager gl_;
77 };
78
79 TEST_F(EXTBlendFuncExtendedTest, TestMaxDualSourceDrawBuffers) {
80 if (!IsApplicable())
81 return;
82
83 GLint maxDualSourceDrawBuffers = 0;
84 glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, &maxDualSourceDrawBuffers);
85 EXPECT_GT(maxDualSourceDrawBuffers, 0);
86 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
87 }
88
89 class EXTBlendFuncExtendedDrawTest : public testing::TestWithParam<bool> {
90 public:
91 static const GLsizei kWidth = 100;
92 static const GLsizei kHeight = 100;
93 EXTBlendFuncExtendedDrawTest() : program_(0) {}
94
95 protected:
96 void SetUp() override {
97 GLManager::Options options;
98 options.size = gfx::Size(kWidth, kHeight);
99 options.force_shader_name_hashing = GetParam();
100 base::CommandLine command_line(*base::CommandLine::ForCurrentProcess());
101 gl_.InitializeWithCommandLine(options, &command_line);
102 }
103
104 bool IsApplicable() const {
105 return GLTestHelper::HasExtension("GL_EXT_blend_func_extended");
106 }
107
108 virtual const char* GetVertexShader() {
109 // clang-format off
110 static const char* kVertexShader =
111 SHADER(
112 attribute vec4 position;
113 void main() {
114 gl_Position = position;
115 });
116 // clang-format on
117 return kVertexShader;
118 }
119
120 void CreateProgramWithFragmentShader(const char* fragment_shader_str) {
121 GLuint vertex_shader =
122 GLTestHelper::LoadShader(GL_VERTEX_SHADER, GetVertexShader());
123 GLuint fragment_shader =
124 GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, fragment_shader_str);
125 ASSERT_NE(0u, vertex_shader);
126 ASSERT_NE(0u, fragment_shader);
127 program_ = glCreateProgram();
128 ASSERT_NE(0u, program_);
129 glAttachShader(program_, vertex_shader);
130 glAttachShader(program_, fragment_shader);
131 glDeleteShader(vertex_shader);
132 glDeleteShader(fragment_shader);
133 }
134
135 testing::AssertionResult LinkProgram() {
136 glLinkProgram(program_);
137 GLint linked = 0;
138 glGetProgramiv(program_, GL_LINK_STATUS, &linked);
139 if (linked == 0) {
140 char buffer[1024];
141 GLsizei length = 0;
142 glGetProgramInfoLog(program_, sizeof(buffer), &length, buffer);
143 std::string log(buffer, length);
144 return testing::AssertionFailure() << "Error linking program: " << log;
145 }
146 glUseProgram(program_);
147 position_loc_ = glGetAttribLocation(program_, "position");
148 src_loc_ = glGetUniformLocation(program_, "src");
149 src1_loc_ = glGetUniformLocation(program_, "src1");
150 return testing::AssertionSuccess();
151 }
152
153 void TearDown() override {
154 if (program_ != 0)
155 glDeleteProgram(program_);
156 gl_.Destroy();
157 }
158
159 void DrawAndVerify() {
160 float kDst[4] = {0.5f, 0.5f, 0.5f, 0.5f};
161 float kSrc[4] = {1.0f, 1.0f, 1.0f, 1.0f};
162 float kSrc1[4] = {0.3f, 0.6f, 0.9f, 0.7f};
163
164 glUniform4f(src_loc_, kSrc[0], kSrc[1], kSrc[2], kSrc[3]);
165 glUniform4f(src1_loc_, kSrc1[0], kSrc1[1], kSrc1[2], kSrc1[3]);
166
167 GLTestHelper::SetupUnitQuad(position_loc_);
168
169 glEnable(GL_BLEND);
170 glBlendEquation(GL_FUNC_ADD);
171 glBlendFuncSeparate(GL_SRC1_COLOR_EXT, GL_SRC_ALPHA,
172 GL_ONE_MINUS_SRC1_COLOR_EXT,
173 GL_ONE_MINUS_SRC1_ALPHA_EXT);
174 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
175
176 // Draw one triangle (bottom left half).
177 glViewport(0, 0, kWidth, kHeight);
178 glClearColor(kDst[0], kDst[1], kDst[2], kDst[3]);
179 glClear(GL_COLOR_BUFFER_BIT);
180 glDrawArrays(GL_TRIANGLES, 0, 6);
181 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
182 // Verify.
183 uint8 color[4];
184 BlendEquationFuncAdd<GL_SRC1_COLOR_EXT, GL_SRC_ALPHA,
185 GL_ONE_MINUS_SRC1_COLOR_EXT,
186 GL_ONE_MINUS_SRC1_ALPHA_EXT>(kDst, kSrc, kSrc1, color);
187
188 EXPECT_TRUE(GLTestHelper::CheckPixels(kWidth / 4, (3 * kHeight) / 4, 1, 1,
189 1, color));
190 EXPECT_TRUE(GLTestHelper::CheckPixels(kWidth - 1, 0, 1, 1, 1, color));
191 }
192
193 protected:
194 GLuint program_;
195 GLuint position_loc_;
196 GLuint src_loc_;
197 GLuint src1_loc_;
198 GLManager gl_;
199 };
200
201 TEST_P(EXTBlendFuncExtendedDrawTest, ESSL1FragColor) {
202 if (!IsApplicable())
203 return;
204 // clang-format off
205 static const char* kFragColorShader =
206 BFE_SHADER(
207 precision mediump float;
208 uniform vec4 src;
209 uniform vec4 src1;
210 void main() {
211 gl_FragColor = src;
212 gl_SecondaryFragColorEXT = src1;
213 });
214 // clang-format on
215 CreateProgramWithFragmentShader(kFragColorShader);
216 LinkProgram();
217 DrawAndVerify();
218 }
219
220 TEST_P(EXTBlendFuncExtendedDrawTest, ESSL1FragData) {
221 if (!IsApplicable())
222 return;
223 // clang-format off
224 static const char* kFragDataShader =
225 BFE_SHADER(
226 precision mediump float;
227 uniform vec4 src;
228 uniform vec4 src1;
229 void main() {
230 gl_FragData[0] = src;
231 gl_SecondaryFragDataEXT[0] = src1;
232 });
233 // clang-format on
234 CreateProgramWithFragmentShader(kFragDataShader);
235 LinkProgram();
236 DrawAndVerify();
237 }
238
239 class EXTBlendFuncExtendedES3DrawTest : public EXTBlendFuncExtendedDrawTest {
240 protected:
241 void SetUp() override {
242 GLManager::Options options;
243 options.size = gfx::Size(kWidth, kHeight);
244 options.context_type = gles2::CONTEXT_TYPE_OPENGLES3;
245 options.force_shader_name_hashing = GetParam();
246 base::CommandLine command_line(*base::CommandLine::ForCurrentProcess());
247 command_line.AppendSwitch(switches::kEnableUnsafeES3APIs);
248 gl_.InitializeWithCommandLine(options, &command_line);
249 }
250 bool IsApplicable() const {
251 return gl_.IsInitialized() && EXTBlendFuncExtendedDrawTest::IsApplicable();
252 }
253 const char* GetVertexShader() override {
254 // clang-format off
255 static const char* kVertexShader =
256 "#version 300 es\n"
257 SHADER(
258 in vec4 position;
259 void main() {
260 gl_Position = position;
261 });
262 // clang-format on
263 return kVertexShader;
264 }
265 };
266
267 TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3Var) {
268 if (!IsApplicable())
269 return;
270 // clang-format off
271 static const char* kFragColorShader =
272 "#version 300 es\n"
273 BFE_SHADER(
274 precision mediump float;
275 uniform vec4 src;
276 uniform vec4 src1;
277 out vec4 FragColor;
278 out vec4 SecondaryFragColor;
279 void main() {
280 FragColor = src;
281 SecondaryFragColor = src1;
282 });
283 // clang-format on
284 CreateProgramWithFragmentShader(kFragColorShader);
285 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragColor");
286 LinkProgram();
287 DrawAndVerify();
288 }
289
290 TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3BindArrayWithSimpleName) {
291 if (!IsApplicable())
292 return;
293 // clang-format off
294 static const char* kFragDataShader =
295 "#version 300 es\n"
296 BFE_SHADER(
297 precision mediump float;
298 uniform vec4 src;
299 uniform vec4 src1;
300 out vec4 FragData[1];
301 out vec4 SecondaryFragData[1];
302 void main() {
303 FragData[0] = src;
304 SecondaryFragData[0] = src1;
305 });
306 // clang-format on
307 CreateProgramWithFragmentShader(kFragDataShader);
308 glBindFragDataLocationEXT(program_, 0, "FragData");
309 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData");
310 LinkProgram();
311 DrawAndVerify();
312 }
313
314 TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3BindSimpleVarAsArrayNoBind) {
315 if (!IsApplicable())
316 return;
317 // clang-format off
318 static const char* kFragDataShader =
319 "#version 300 es\n"
320 BFE_SHADER(
321 precision mediump float;
322 uniform vec4 src;
323 uniform vec4 src1;
324 out vec4 FragData;
325 out vec4 SecondaryFragData;
326 void main() {
327 FragData = src;
328 SecondaryFragData = src1;
329 });
330 // clang-format on
331 CreateProgramWithFragmentShader(kFragDataShader);
332 glBindFragDataLocationEXT(program_, 0, "FragData[0]");
333 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData[0]");
334 // Does not fail, since FragData[0] and SecondaryFragData[0] do not exist.
335 EXPECT_TRUE(LinkProgram());
336
337 EXPECT_EQ(-1, glGetFragDataLocation(program_, "FragData[0]"));
338 EXPECT_EQ(0, glGetFragDataLocation(program_, "FragData"));
339 EXPECT_EQ(1, glGetFragDataLocation(program_, "SecondaryFragData"));
340 // Did not bind index.
341 EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "SecondaryFragData"));
342
343 glBindFragDataLocationEXT(program_, 0, "FragData");
344 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData");
345 EXPECT_TRUE(LinkProgram());
346 DrawAndVerify();
347 }
348
349 TEST_P(EXTBlendFuncExtendedES3DrawTest, ESSL3BindArrayAsArray) {
350 if (!IsApplicable())
351 return;
352 // clang-format off
353 static const char* kFragDataShader =
354 "#version 300 es\n"
355 BFE_SHADER(
356 precision mediump float;
357 uniform vec4 src;
358 uniform vec4 src1;
359 out vec4 FragData[1];
360 out vec4 SecondaryFragData[1];
361 void main() {
362 FragData[0] = src;
363 SecondaryFragData[0] = src1;
364 });
365 // clang-format on
366 CreateProgramWithFragmentShader(kFragDataShader);
367 glBindFragDataLocationEXT(program_, 0, "FragData[0]");
368 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragData[0]");
369 LinkProgram();
370 DrawAndVerify();
371 }
372
373 TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3Getters) {
374 if (!IsApplicable())
375 return;
376 // clang-format off
377 static const char* kFragColorShader =
378 "#version 300 es\n"
379 BFE_SHADER(
380 precision mediump float;
381 uniform vec4 src;
382 uniform vec4 src1;
383 out vec4 FragColor;
384 out vec4 SecondaryFragColor;
385 void main() {
386 FragColor = src;
387 SecondaryFragColor = src1;
388 });
389 // clang-format on
390 CreateProgramWithFragmentShader(kFragColorShader);
391 glBindFragDataLocationEXT(program_, 0, "FragColor");
392 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragColor");
393
394 // Getters return GL error before linking.
395 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
396 GLint location = glGetFragDataLocation(program_, "FragColor");
397 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
398 GLint index = glGetFragDataIndexEXT(program_, "FragColor");
399 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
400 location = glGetFragDataLocation(program_, "SecondaryFragColor");
401 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
402 index = glGetFragDataIndexEXT(program_, "SecondaryFragColor");
403 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
404 LinkProgram();
405
406 // Getters return location and index after linking. Run twice to confirm that
407 // setters do not affect the getters until next link.
408 for (int i = 0; i < 2; ++i) {
409 SCOPED_TRACE(testing::Message() << "Testing getters after link, iteration "
410 << i);
411
412 location = glGetFragDataLocation(program_, "FragColor");
413 EXPECT_EQ(0, location);
414 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
415 index = glGetFragDataIndexEXT(program_, "FragColor");
416 EXPECT_EQ(0, index);
417 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
418 location = glGetFragDataLocation(program_, "SecondaryFragColor");
419 EXPECT_EQ(0, location);
420 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
421 index = glGetFragDataIndexEXT(program_, "SecondaryFragColor");
422 EXPECT_EQ(1, index);
423 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
424
425 // The calls should not affect the getters until re-linking.
426 glBindFragDataLocationEXT(program_, 0, "SecondaryFragColor");
427 glBindFragDataLocationIndexedEXT(program_, 0, 1, "FragColor");
428 }
429
430 LinkProgram();
431
432 location = glGetFragDataLocation(program_, "FragColor");
433 EXPECT_EQ(0, location);
434 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
435 index = glGetFragDataIndexEXT(program_, "FragColor");
436 EXPECT_EQ(1, index);
437 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
438 location = glGetFragDataLocation(program_, "SecondaryFragColor");
439 EXPECT_EQ(0, location);
440 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
441 index = glGetFragDataIndexEXT(program_, "SecondaryFragColor");
442 EXPECT_EQ(0, index);
443 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
444
445 // Unknown colors return location -1, index -1.
446 location = glGetFragDataLocation(program_, "UnknownColor");
447 EXPECT_EQ(-1, location);
448 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
449 index = glGetFragDataIndexEXT(program_, "UnknownColor");
450 EXPECT_EQ(-1, index);
451
452 // Reset the settings and verify that the driver gets them correct.
453 glBindFragDataLocationEXT(program_, 0, "FragColor");
454 glBindFragDataLocationIndexedEXT(program_, 0, 1, "SecondaryFragColor");
455 LinkProgram();
456 DrawAndVerify();
457 }
458
459 // Test that tests glBindFragDataLocationEXT, glBindFragDataLocationIndexedEXT,
460 // glGetFragDataLocation, glGetFragDataIndexEXT work correctly with
461 // GLSL array output variables. The output variable can be bound by
462 // referring to the variable name with or without the first element array
463 // accessor. The getters can query location of the individual elements in
464 // the array. The test does not actually use the base test drawing,
465 // since the drivers at the time of writing do not support multiple
466 // buffers and dual source blending.
467 TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3GettersArray) {
468 if (!IsApplicable())
469 return;
470 const GLint kTestArraySize = 2;
471 const GLint kFragData0Location = 2;
472 const GLint kFragData1Location = 1;
473 const GLint kUnusedLocation = 5;
474
475 // The test binds kTestArraySize -sized array to location 1 for test purposes.
476 // The GL_MAX_DRAW_BUFFERS must be > kTestArraySize, since an
477 // array will be bound to continuous locations, starting from the first
478 // location.
479 GLint maxDrawBuffers = 0;
480 glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
481 EXPECT_LT(kTestArraySize, maxDrawBuffers);
482
483 // clang-format off
484 static const char* kFragColorShader =
485 "#version 300 es\n"
486 BFE_SHADER(
487 precision mediump float;
488 uniform vec4 src;
489 uniform vec4 src1;
490 out vec4 FragData[2];
491 void main() {
492 FragData[0] = src;
493 FragData[1] = src1;
494 });
495 // clang-format on
496 CreateProgramWithFragmentShader(kFragColorShader);
497
498 for (int testcase = 0; testcase < 4; ++testcase) {
499 if (testcase == 0) {
500 glBindFragDataLocationEXT(program_, kUnusedLocation, "FragData[0]");
501 glBindFragDataLocationEXT(program_, kFragData0Location, "FragData");
502 glBindFragDataLocationEXT(program_, kFragData1Location, "FragData[1]");
503 } else if (testcase == 1) {
504 glBindFragDataLocationEXT(program_, kUnusedLocation, "FragData");
505 glBindFragDataLocationEXT(program_, kFragData0Location, "FragData[0]");
506 glBindFragDataLocationEXT(program_, kFragData1Location, "FragData[1]");
507 } else if (testcase == 2) {
508 glBindFragDataLocationIndexedEXT(program_, kUnusedLocation, 0,
509 "FragData[0]");
510 glBindFragDataLocationIndexedEXT(program_, kFragData0Location, 0,
511 "FragData");
512 glBindFragDataLocationIndexedEXT(program_, kFragData1Location, 0,
513 "FragData[1]");
514 } else if (testcase == 3) {
515 glBindFragDataLocationIndexedEXT(program_, kUnusedLocation, 0,
516 "FragData");
517 glBindFragDataLocationIndexedEXT(program_, kFragData0Location, 0,
518 "FragData[0]");
519 glBindFragDataLocationIndexedEXT(program_, kFragData1Location, 0,
520 "FragData[1]");
521 }
522
523 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
524 LinkProgram();
525 EXPECT_EQ(kFragData0Location, glGetFragDataLocation(program_, "FragData"));
526 EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "FragData"));
527 EXPECT_EQ(kFragData0Location,
528 glGetFragDataLocation(program_, "FragData[0]"));
529 EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "FragData[0]"));
530 EXPECT_EQ(kFragData1Location,
531 glGetFragDataLocation(program_, "FragData[1]"));
532 EXPECT_EQ(0, glGetFragDataIndexEXT(program_, "FragData[1]"));
533
534 // Index bigger than the GLSL variable array length does not find anything.
535 EXPECT_EQ(-1, glGetFragDataLocation(program_, "FragData[3]"));
536 }
537 }
538
539 // Test that tests glBindFragDataLocationEXT, glBindFragDataLocationIndexedEXT
540 // conflicts
541 // with GLSL output variables.
542 TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3Conflicts) {
543 if (!IsApplicable())
544 return;
545 const GLint kTestArraySize = 2;
546 const GLint kColorName0Location = 0;
547 const GLint kColorName1Location = 1;
548 GLint maxDrawBuffers = 0;
549 glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
550 EXPECT_LT(kTestArraySize, maxDrawBuffers);
551
552 // clang-format off
553 static const char* kFragColorShader =
554 "#version 300 es\n"
555 BFE_SHADER(
556 precision mediump float;
557 uniform vec4 src;
558 uniform vec4 src1;
559 out vec4 FragData0;
560 out vec4 FragData1;
561 void main() {
562 FragData0 = src;
563 FragData1 = src1;
564 });
565 // clang-format on
566 CreateProgramWithFragmentShader(kFragColorShader);
567
568 glBindFragDataLocationEXT(program_, kColorName0Location, "FragData0");
569 glBindFragDataLocationEXT(program_, kColorName0Location, "FragData1");
570 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
571 EXPECT_FALSE(LinkProgram());
572
573 glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 0,
574 "FragData0");
575 glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 0,
576 "FragData1");
577 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
578 EXPECT_FALSE(LinkProgram());
579
580 glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 1,
581 "FragData0");
582 glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 1,
583 "FragData1");
584 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
585 EXPECT_FALSE(LinkProgram());
586
587 // Test that correct binding actually works.
588 glBindFragDataLocationEXT(program_, kColorName0Location, "FragData0");
589 glBindFragDataLocationEXT(program_, kColorName1Location, "FragData1");
590 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
591 EXPECT_TRUE(LinkProgram());
592
593 glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 0,
594 "FragData0");
595 glBindFragDataLocationIndexedEXT(program_, kColorName0Location, 1,
596 "FragData1");
597 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
598 EXPECT_TRUE(LinkProgram());
599 }
600
601 // Test that tests glBindFragDataLocationEXT conflicts
602 // with GLSL array output variables.
603 TEST_P(EXTBlendFuncExtendedES3DrawTest, ES3ConflictsArray) {
604 if (!IsApplicable())
605 return;
606 const GLint kTestArraySize = 2;
607 const GLint kColorName0Location = 0;
608 const GLint kColorName1Location = 1;
609 const GLint kUnusedLocation = 5;
610 GLint maxDrawBuffers = 0;
611 glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
612 EXPECT_LT(kTestArraySize, maxDrawBuffers);
613
614 // clang-format off
615 static const char* kFragColorShader =
616 "#version 300 es\n"
617 BFE_SHADER(
618 precision mediump float;
619 uniform vec4 src;
620 uniform vec4 src1;
621 out vec4 FragData[2];
622 void main() {
623 FragData[0] = src;
624 FragData[1] = src1;
625 });
626 // clang-format on
627 CreateProgramWithFragmentShader(kFragColorShader);
628
629 glBindFragDataLocationEXT(program_, kColorName1Location, "FragData");
630 glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[1]");
631 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
632 EXPECT_FALSE(LinkProgram());
633 glBindFragDataLocationEXT(program_, kUnusedLocation, "FragData");
634 glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[0]");
635 glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[1]");
636 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
637 EXPECT_FALSE(LinkProgram());
638 // Test that binding actually works.
639 glBindFragDataLocationEXT(program_, kColorName0Location, "FragData[0]");
640 glBindFragDataLocationEXT(program_, kColorName1Location, "FragData[1]");
641 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
642 EXPECT_TRUE(LinkProgram());
643 }
644
645 INSTANTIATE_TEST_CASE_P(TranslatorVariants,
646 EXTBlendFuncExtendedDrawTest,
647 ::testing::Bool());
648
649 INSTANTIATE_TEST_CASE_P(TranslatorVariants,
650 EXTBlendFuncExtendedES3DrawTest,
651 ::testing::Bool());
652
653 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/test_helper.cc ('k') | gpu/gpu.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698