blob: 7fbb84dde115904ec3ad94f6a75e96b119fc2efa [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Jamie Madillfa05f602015-05-07 13:47:11 -04008
Brandon Jones993d08d2014-10-10 14:32:57 -07009#include <memory>
10#include <stdint.h>
Jamie Madill7a29e4a2014-05-02 10:41:48 -040011
Austin Kinross137b1512015-06-17 16:14:53 -070012#include "EGLWindow.h"
13#include "OSWindow.h"
14#include "test_utils/angle_test_configs.h"
15
Jamie Madillfa05f602015-05-07 13:47:11 -040016using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070017
Jamie Madill7a29e4a2014-05-02 10:41:48 -040018class ProgramBinaryTest : public ANGLETest
19{
Geoff Lang0d3683c2014-10-23 11:08:16 -040020 protected:
Jamie Madillfa05f602015-05-07 13:47:11 -040021 ProgramBinaryTest()
Jamie Madill7a29e4a2014-05-02 10:41:48 -040022 {
23 setWindowWidth(128);
24 setWindowHeight(128);
25 setConfigRedBits(8);
26 setConfigGreenBits(8);
27 setConfigBlueBits(8);
28 setConfigAlphaBits(8);
29 }
30
Corentin Wallez42e9e592015-10-29 14:09:25 -040031 void SetUp() override
Jamie Madill7a29e4a2014-05-02 10:41:48 -040032 {
33 ANGLETest::SetUp();
34
35 const std::string vertexShaderSource = SHADER_SOURCE
36 (
37 attribute vec4 inputAttribute;
38 void main()
39 {
40 gl_Position = inputAttribute;
41 }
42 );
43
44 const std::string fragmentShaderSource = SHADER_SOURCE
45 (
46 void main()
47 {
48 gl_FragColor = vec4(1,0,0,1);
49 }
50 );
51
Jamie Madill5599c8f2014-08-26 13:16:39 -040052 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill7a29e4a2014-05-02 10:41:48 -040053 if (mProgram == 0)
54 {
55 FAIL() << "shader compilation failed.";
56 }
57
58 glGenBuffers(1, &mBuffer);
59 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
60 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_STATIC_DRAW);
61 glBindBuffer(GL_ARRAY_BUFFER, 0);
62
63 ASSERT_GL_NO_ERROR();
64 }
65
Corentin Wallez42e9e592015-10-29 14:09:25 -040066 void TearDown() override
Jamie Madill7a29e4a2014-05-02 10:41:48 -040067 {
68 glDeleteProgram(mProgram);
69 glDeleteBuffers(1, &mBuffer);
70
71 ANGLETest::TearDown();
72 }
73
Geoff Lang90208e92015-10-05 15:40:36 -040074 GLint getAvailableProgramBinaryFormatCount() const
75 {
76 GLint formatCount;
77 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &formatCount);
78 return formatCount;
79 }
80
Jamie Madill7a29e4a2014-05-02 10:41:48 -040081 GLuint mProgram;
82 GLuint mBuffer;
83};
84
85// This tests the assumption that float attribs of different size
86// should not internally cause a vertex shader recompile (for conversion).
Jamie Madillfa05f602015-05-07 13:47:11 -040087TEST_P(ProgramBinaryTest, FloatDynamicShaderSize)
Jamie Madill7a29e4a2014-05-02 10:41:48 -040088{
Geoff Lang90208e92015-10-05 15:40:36 -040089 if (!extensionEnabled("GL_OES_get_program_binary"))
90 {
91 std::cout << "Test skipped because GL_OES_get_program_binary is not available."
92 << std::endl;
93 return;
94 }
95
96 if (getAvailableProgramBinaryFormatCount() == 0)
97 {
98 std::cout << "Test skipped because no program binary formats are available." << std::endl;
99 return;
100 }
101
Jamie Madill7a29e4a2014-05-02 10:41:48 -0400102 glUseProgram(mProgram);
103 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
104
105 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8, NULL);
106 glEnableVertexAttribArray(0);
107 glDrawArrays(GL_POINTS, 0, 1);
108
109 GLint programLength;
110 glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &programLength);
111
112 EXPECT_GL_NO_ERROR();
113
114 for (GLsizei size = 1; size <= 3; size++)
115 {
116 glVertexAttribPointer(0, size, GL_FLOAT, GL_FALSE, 8, NULL);
117 glEnableVertexAttribArray(0);
118 glDrawArrays(GL_POINTS, 0, 1);
119
120 GLint newProgramLength;
121 glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &newProgramLength);
122 EXPECT_GL_NO_ERROR();
123 EXPECT_EQ(programLength, newProgramLength);
124 }
125}
Brandon Jones993d08d2014-10-10 14:32:57 -0700126
Jamie Madillbdec2f42016-03-02 16:35:32 -0500127// Tests that switching between signed and unsigned un-normalized data doesn't trigger a bug
128// in the D3D11 back-end.
129TEST_P(ProgramBinaryTest, DynamicShadersSignatureBug)
130{
131 glUseProgram(mProgram);
132 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
133
134 GLint attribLocation = glGetAttribLocation(mProgram, "inputAttribute");
135 ASSERT_NE(-1, attribLocation);
136 glEnableVertexAttribArray(attribLocation);
137
138 glVertexAttribPointer(attribLocation, 2, GL_BYTE, GL_FALSE, 0, nullptr);
139 glDrawArrays(GL_POINTS, 0, 1);
140
141 glVertexAttribPointer(attribLocation, 2, GL_UNSIGNED_BYTE, GL_FALSE, 0, nullptr);
142 glDrawArrays(GL_POINTS, 0, 1);
143}
144
Brandon Jones993d08d2014-10-10 14:32:57 -0700145// This tests the ability to successfully save and load a program binary.
Jamie Madillfa05f602015-05-07 13:47:11 -0400146TEST_P(ProgramBinaryTest, SaveAndLoadBinary)
Brandon Jones993d08d2014-10-10 14:32:57 -0700147{
Geoff Lang90208e92015-10-05 15:40:36 -0400148 if (!extensionEnabled("GL_OES_get_program_binary"))
149 {
150 std::cout << "Test skipped because GL_OES_get_program_binary is not available."
151 << std::endl;
152 return;
153 }
154
155 if (getAvailableProgramBinaryFormatCount() == 0)
156 {
157 std::cout << "Test skipped because no program binary formats are available." << std::endl;
158 return;
159 }
160
Brandon Jones993d08d2014-10-10 14:32:57 -0700161 GLint programLength = 0;
162 GLint writtenLength = 0;
163 GLenum binaryFormat = 0;
164
165 glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &programLength);
166 EXPECT_GL_NO_ERROR();
167
168 std::vector<uint8_t> binary(programLength);
169 glGetProgramBinaryOES(mProgram, programLength, &writtenLength, &binaryFormat, binary.data());
170 EXPECT_GL_NO_ERROR();
171
172 // The lengths reported by glGetProgramiv and glGetProgramBinaryOES should match
173 EXPECT_EQ(programLength, writtenLength);
174
175 if (writtenLength)
176 {
177 GLuint program2 = glCreateProgram();
178 glProgramBinaryOES(program2, binaryFormat, binary.data(), writtenLength);
179
180 EXPECT_GL_NO_ERROR();
181
182 GLint linkStatus;
183 glGetProgramiv(program2, GL_LINK_STATUS, &linkStatus);
184 if (linkStatus == 0)
185 {
186 GLint infoLogLength;
187 glGetProgramiv(program2, GL_INFO_LOG_LENGTH, &infoLogLength);
188
Geoff Lang981afd72014-11-05 16:30:36 -0500189 if (infoLogLength > 0)
190 {
191 std::vector<GLchar> infoLog(infoLogLength);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700192 glGetProgramInfoLog(program2, static_cast<GLsizei>(infoLog.size()), NULL,
193 &infoLog[0]);
Geoff Lang981afd72014-11-05 16:30:36 -0500194 FAIL() << "program link failed: " << &infoLog[0];
195 }
196 else
197 {
198 FAIL() << "program link failed.";
199 }
Brandon Jones993d08d2014-10-10 14:32:57 -0700200 }
201 else
202 {
203 glUseProgram(program2);
204 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
205
206 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8, NULL);
207 glEnableVertexAttribArray(0);
208 glDrawArrays(GL_POINTS, 0, 1);
209
210 EXPECT_GL_NO_ERROR();
211 }
212
213 glDeleteProgram(program2);
214 }
215}
Jamie Madillfa05f602015-05-07 13:47:11 -0400216
217// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang90208e92015-10-05 15:40:36 -0400218ANGLE_INSTANTIATE_TEST(ProgramBinaryTest,
219 ES2_D3D9(),
220 ES2_D3D11(),
221 ES3_D3D11(),
222 ES2_OPENGL(),
223 ES3_OPENGL());
Austin Kinross137b1512015-06-17 16:14:53 -0700224
Brandon Jones1048ea72015-10-06 15:34:52 -0700225class ProgramBinaryTransformFeedbackTest : public ANGLETest
226{
227 protected:
228 ProgramBinaryTransformFeedbackTest()
229 {
230 setWindowWidth(128);
231 setWindowHeight(128);
232 setConfigRedBits(8);
233 setConfigGreenBits(8);
234 setConfigBlueBits(8);
235 setConfigAlphaBits(8);
236 }
237
238 void SetUp() override
239 {
240 ANGLETest::SetUp();
241
242 const std::string vertexShaderSource = SHADER_SOURCE
243 ( #version 300 es\n
244 in vec4 inputAttribute;
245 out vec4 outputVarying;
246 void main()
247 {
248 outputVarying = inputAttribute;
249 }
250 );
251
252 const std::string fragmentShaderSource = SHADER_SOURCE
253 ( #version 300 es\n
254 precision highp float;
255 out vec4 outputColor;
256 void main()
257 {
258 outputColor = vec4(1,0,0,1);
259 }
260 );
261
262 std::vector<std::string> transformFeedbackVaryings;
263 transformFeedbackVaryings.push_back("outputVarying");
264
265 mProgram = CompileProgramWithTransformFeedback(
266 vertexShaderSource, fragmentShaderSource, transformFeedbackVaryings,
267 GL_SEPARATE_ATTRIBS);
268 if (mProgram == 0)
269 {
270 FAIL() << "shader compilation failed.";
271 }
272
273 ASSERT_GL_NO_ERROR();
274 }
275
Corentin Wallez42e9e592015-10-29 14:09:25 -0400276 void TearDown() override
Brandon Jones1048ea72015-10-06 15:34:52 -0700277 {
278 glDeleteProgram(mProgram);
279
280 ANGLETest::TearDown();
281 }
282
283 GLint getAvailableProgramBinaryFormatCount() const
284 {
285 GLint formatCount;
286 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &formatCount);
287 return formatCount;
288 }
289
290 GLuint mProgram;
291};
292
293// This tests the assumption that float attribs of different size
294// should not internally cause a vertex shader recompile (for conversion).
295TEST_P(ProgramBinaryTransformFeedbackTest, GetTransformFeedbackVarying)
296{
297 if (!extensionEnabled("GL_OES_get_program_binary"))
298 {
299 std::cout << "Test skipped because GL_OES_get_program_binary is not available."
300 << std::endl;
301 return;
302 }
303
304 if (getAvailableProgramBinaryFormatCount() == 0)
305 {
306 std::cout << "Test skipped because no program binary formats are available." << std::endl;
307 return;
308 }
309
310 std::vector<uint8_t> binary(0);
311 GLint programLength = 0;
312 GLint writtenLength = 0;
313 GLenum binaryFormat = 0;
314
315 // Save the program binary out
316 glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &programLength);
317 ASSERT_GL_NO_ERROR();
318 binary.resize(programLength);
319 glGetProgramBinaryOES(mProgram, programLength, &writtenLength, &binaryFormat, binary.data());
320 ASSERT_GL_NO_ERROR();
321
322 glDeleteProgram(mProgram);
323
324 // Load program binary
325 mProgram = glCreateProgram();
326 glProgramBinaryOES(mProgram, binaryFormat, binary.data(), writtenLength);
327
328 // Ensure the loaded binary is linked
329 GLint linkStatus;
330 glGetProgramiv(mProgram, GL_LINK_STATUS, &linkStatus);
331 EXPECT_TRUE(linkStatus != 0);
332
333 // Query information about the transform feedback varying
334 char varyingName[64];
335 GLsizei varyingSize = 0;
336 GLenum varyingType = GL_NONE;
337
338 glGetTransformFeedbackVarying(mProgram, 0, 64, &writtenLength, &varyingSize, &varyingType, varyingName);
339 EXPECT_GL_NO_ERROR();
340
341 EXPECT_EQ(13, writtenLength);
342 EXPECT_STREQ("outputVarying", varyingName);
343 EXPECT_EQ(1, varyingSize);
344 EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, varyingType);
345
346 EXPECT_GL_NO_ERROR();
347}
348
349// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
350ANGLE_INSTANTIATE_TEST(ProgramBinaryTransformFeedbackTest,
351 ES3_D3D11(),
352 ES3_OPENGL());
353
Austin Kinross137b1512015-06-17 16:14:53 -0700354// For the ProgramBinariesAcrossPlatforms tests, we need two sets of params:
355// - a set to save the program binary
356// - a set to load the program binary
357// We combine these into one struct extending PlatformParameters so we can reuse existing ANGLE test macros
358struct PlatformsWithLinkResult : PlatformParameters
359{
360 PlatformsWithLinkResult(PlatformParameters saveParams, PlatformParameters loadParamsIn, bool expectedLinkResultIn)
361 {
362 majorVersion = saveParams.majorVersion;
363 minorVersion = saveParams.minorVersion;
364 eglParameters = saveParams.eglParameters;
365 loadParams = loadParamsIn;
366 expectedLinkResult = expectedLinkResultIn;
367 }
368
369 PlatformParameters loadParams;
370 bool expectedLinkResult;
371};
372
Corentin Wallez33585c72015-09-03 14:41:23 -0400373// Provide a custom gtest parameter name function for PlatformsWithLinkResult
374// to avoid returning the same parameter name twice. Such a conflict would happen
375// between ES2_D3D11_to_ES2D3D11 and ES2_D3D11_to_ES3D3D11 as they were both
376// named ES2_D3D11
377std::ostream &operator<<(std::ostream& stream, const PlatformsWithLinkResult &platform)
378{
379 const PlatformParameters &platform1 = platform;
380 const PlatformParameters &platform2 = platform.loadParams;
381 stream << platform1 << "_to_" << platform2;
382 return stream;
383}
384
Austin Kinross137b1512015-06-17 16:14:53 -0700385class ProgramBinariesAcrossPlatforms : public testing::TestWithParam<PlatformsWithLinkResult>
386{
387 public:
388 void SetUp() override
389 {
390 mOSWindow = CreateOSWindow();
391 bool result = mOSWindow->initialize("ProgramBinariesAcrossRenderersTests", 100, 100);
392
393 if (result == false)
394 {
395 FAIL() << "Failed to create OS window";
396 }
397 }
398
399 EGLWindow *createAndInitEGLWindow(angle::PlatformParameters &param)
400 {
Geoff Lang5ade8452015-09-02 11:00:30 -0400401 EGLWindow *eglWindow =
402 new EGLWindow(param.majorVersion, param.minorVersion, param.eglParameters);
Austin Kinross137b1512015-06-17 16:14:53 -0700403 bool result = eglWindow->initializeGL(mOSWindow);
404 if (result == false)
405 {
406 SafeDelete(eglWindow);
407 eglWindow = nullptr;
408 }
409
410 return eglWindow;
411 }
412
413 void destroyEGLWindow(EGLWindow **eglWindow)
414 {
Jamie Madille1faacb2016-12-13 12:42:14 -0500415 ASSERT_NE(nullptr, *eglWindow);
Austin Kinross137b1512015-06-17 16:14:53 -0700416 (*eglWindow)->destroyGL();
417 SafeDelete(*eglWindow);
418 *eglWindow = nullptr;
419 }
420
421 GLuint createES2ProgramFromSource()
422 {
423 const std::string testVertexShaderSource = SHADER_SOURCE
424 (
425 attribute highp vec4 position;
426
427 void main(void)
428 {
429 gl_Position = position;
430 }
431 );
432
433 const std::string testFragmentShaderSource = SHADER_SOURCE
434 (
435 void main(void)
436 {
437 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
438 }
439 );
440
441 return CompileProgram(testVertexShaderSource, testFragmentShaderSource);
442 }
443
444 GLuint createES3ProgramFromSource()
445 {
446 const std::string testVertexShaderSource = SHADER_SOURCE
447 ( #version 300 es\n
448 precision highp float;
449 in highp vec4 position;
450
451 void main(void)
452 {
453 gl_Position = position;
454 }
455 );
456
457 const std::string testFragmentShaderSource = SHADER_SOURCE
458 ( #version 300 es \n
459 precision highp float;
460 out vec4 out_FragColor;
461
462 void main(void)
463 {
464 out_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
465 }
466 );
467
468 return CompileProgram(testVertexShaderSource, testFragmentShaderSource);
469 }
470
471 void drawWithProgram(GLuint program)
472 {
473 glClearColor(0, 0, 0, 1);
474 glClear(GL_COLOR_BUFFER_BIT);
475
476 GLint positionLocation = glGetAttribLocation(program, "position");
477
478 glUseProgram(program);
479
480 const GLfloat vertices[] =
481 {
482 -1.0f, 1.0f, 0.5f,
483 -1.0f, -1.0f, 0.5f,
484 1.0f, -1.0f, 0.5f,
485
486 -1.0f, 1.0f, 0.5f,
487 1.0f, -1.0f, 0.5f,
488 1.0f, 1.0f, 0.5f,
489 };
490
491 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
492 glEnableVertexAttribArray(positionLocation);
493
494 glDrawArrays(GL_TRIANGLES, 0, 6);
495
496 glDisableVertexAttribArray(positionLocation);
497 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
498
499 EXPECT_PIXEL_EQ(mOSWindow->getWidth() / 2, mOSWindow->getHeight() / 2, 255, 0, 0, 255);
500 }
501
502 void TearDown() override
503 {
504 mOSWindow->destroy();
505 SafeDelete(mOSWindow);
506 }
507
508 OSWindow *mOSWindow;
509};
510
511// Tries to create a program binary using one set of platform params, then load it using a different sent of params
512TEST_P(ProgramBinariesAcrossPlatforms, CreateAndReloadBinary)
513{
514 angle::PlatformParameters firstRenderer = GetParam();
515 angle::PlatformParameters secondRenderer = GetParam().loadParams;
516 bool expectedLinkResult = GetParam().expectedLinkResult;
517
518 if (!(IsPlatformAvailable(firstRenderer)))
519 {
520 std::cout << "First renderer not supported, skipping test";
521 return;
522 }
523
524 if (!(IsPlatformAvailable(secondRenderer)))
525 {
526 std::cout << "Second renderer not supported, skipping test";
527 return;
528 }
529
530 EGLWindow *eglWindow = nullptr;
531 std::vector<uint8_t> binary(0);
532 GLuint program = 0;
533
534 GLint programLength = 0;
535 GLint writtenLength = 0;
536 GLenum binaryFormat = 0;
537
538 // Create a EGL window with the first renderer
539 eglWindow = createAndInitEGLWindow(firstRenderer);
540 if (eglWindow == nullptr)
541 {
542 FAIL() << "Failed to create EGL window";
543 return;
544 }
545
546 // If the test is trying to use both the default GPU and WARP, but the default GPU *IS* WARP,
547 // then our expectations for the test results will be invalid.
548 if (firstRenderer.eglParameters.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE &&
549 secondRenderer.eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE)
550 {
551 std::string rendererString = std::string(reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
552 std::transform(rendererString.begin(), rendererString.end(), rendererString.begin(), ::tolower);
553
554 auto basicRenderPos = rendererString.find(std::string("microsoft basic render"));
555 auto softwareAdapterPos = rendererString.find(std::string("software adapter"));
556
557 if (basicRenderPos != std::string::npos || softwareAdapterPos != std::string::npos)
558 {
559 // The first renderer is using WARP, even though we didn't explictly request it
560 // We should skip this test
561 std::cout << "Test skipped on when default GPU is WARP." << std::endl;
562 return;
563 }
564 }
565
566 // Create a program
567 if (firstRenderer.majorVersion == 3)
568 {
569 program = createES3ProgramFromSource();
570 }
571 else
572 {
573 program = createES2ProgramFromSource();
574 }
575
576 if (program == 0)
577 {
Austin Kinross137b1512015-06-17 16:14:53 -0700578 destroyEGLWindow(&eglWindow);
Corentin Wallezefb6ac62015-09-02 08:10:09 -0700579 FAIL() << "Failed to create program from source";
Austin Kinross137b1512015-06-17 16:14:53 -0700580 }
581
582 // Draw using the program to ensure it works as expected
583 drawWithProgram(program);
584 EXPECT_GL_NO_ERROR();
585
586 // Save the program binary out from this renderer
587 glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &programLength);
588 EXPECT_GL_NO_ERROR();
589 binary.resize(programLength);
590 glGetProgramBinaryOES(program, programLength, &writtenLength, &binaryFormat, binary.data());
591 EXPECT_GL_NO_ERROR();
592
593 // Destroy the first renderer
594 glDeleteProgram(program);
595 destroyEGLWindow(&eglWindow);
596
597 // Create an EGL window with the second renderer
598 eglWindow = createAndInitEGLWindow(secondRenderer);
599 if (eglWindow == nullptr)
600 {
601 FAIL() << "Failed to create EGL window";
602 return;
603 }
604
605 program = glCreateProgram();
606 glProgramBinaryOES(program, binaryFormat, binary.data(), writtenLength);
607
608 GLint linkStatus;
609 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
610 EXPECT_EQ(expectedLinkResult, (linkStatus != 0));
611
612 if (linkStatus != 0)
613 {
614 // If the link was successful, then we should try to draw using the program to ensure it works as expected
615 drawWithProgram(program);
616 EXPECT_GL_NO_ERROR();
617 }
618
619 // Destroy the second renderer
620 glDeleteProgram(program);
621 destroyEGLWindow(&eglWindow);
622}
623
Jamie Madilla2c74982016-12-12 11:20:42 -0500624// clang-format off
Austin Kinross137b1512015-06-17 16:14:53 -0700625ANGLE_INSTANTIATE_TEST(ProgramBinariesAcrossPlatforms,
626 // | Save the program | Load the program | Expected
627 // | using these params | using these params | link result
628 PlatformsWithLinkResult(ES2_D3D11(), ES2_D3D11(), true ), // Loading + reloading binary should work
629 PlatformsWithLinkResult(ES3_D3D11(), ES3_D3D11(), true ), // Loading + reloading binary should work
630 PlatformsWithLinkResult(ES2_D3D11_FL11_0(), ES2_D3D11_FL9_3(), false ), // Switching feature level shouldn't work
631 PlatformsWithLinkResult(ES2_D3D11(), ES2_D3D11_WARP(), false ), // Switching from hardware to software shouldn't work
632 PlatformsWithLinkResult(ES2_D3D11_FL9_3(), ES2_D3D11_FL9_3_WARP(), false ), // Switching from hardware to software shouldn't work for FL9 either
633 PlatformsWithLinkResult(ES2_D3D11(), ES2_D3D9(), false ), // Switching from D3D11 to D3D9 shouldn't work
634 PlatformsWithLinkResult(ES2_D3D9(), ES2_D3D11(), false ), // Switching from D3D9 to D3D11 shouldn't work
Jamie Madilla2c74982016-12-12 11:20:42 -0500635 PlatformsWithLinkResult(ES2_D3D11(), ES3_D3D11(), false ), // Switching to newer client version shouldn't work
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400636 );
Jamie Madilla2c74982016-12-12 11:20:42 -0500637// clang-format on