• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 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 // ContextNoErrorTest:
7 //   Tests pertaining to GL_KHR_no_error
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include "common/platform.h"
13 #include "test_utils/ANGLETest.h"
14 #include "test_utils/gl_raii.h"
15 
16 using namespace angle;
17 
18 class ContextNoErrorTest : public ANGLETest
19 {
20   protected:
ContextNoErrorTest()21     ContextNoErrorTest() : mNaughtyTexture(0) { setNoErrorEnabled(true); }
22 
testTearDown()23     void testTearDown() override
24     {
25         if (mNaughtyTexture != 0)
26         {
27             glDeleteTextures(1, &mNaughtyTexture);
28         }
29     }
30 
bindNaughtyTexture()31     void bindNaughtyTexture()
32     {
33         glGenTextures(1, &mNaughtyTexture);
34         ASSERT_GL_NO_ERROR();
35         glBindTexture(GL_TEXTURE_CUBE_MAP, mNaughtyTexture);
36         ASSERT_GL_NO_ERROR();
37 
38         // mNaughtyTexture should now be a GL_TEXTURE_CUBE_MAP texture, so rebinding it to
39         // GL_TEXTURE_2D is an error
40         glBindTexture(GL_TEXTURE_2D, mNaughtyTexture);
41     }
42 
43     GLuint mNaughtyTexture;
44 };
45 
46 class ContextNoErrorTest31 : public ContextNoErrorTest
47 {
48   protected:
~ContextNoErrorTest31()49     ~ContextNoErrorTest31()
50     {
51         glDeleteProgram(mVertProg);
52         glDeleteProgram(mFragProg);
53         glDeleteProgramPipelines(1, &mPipeline);
54     }
55 
56     void bindProgramPipeline(const GLchar *vertString, const GLchar *fragString);
57     void drawQuadWithPPO(const std::string &positionAttribName,
58                          const GLfloat positionAttribZ,
59                          const GLfloat positionAttribXYScale);
60 
61     GLuint mVertProg;
62     GLuint mFragProg;
63     GLuint mPipeline;
64 };
65 
bindProgramPipeline(const GLchar * vertString,const GLchar * fragString)66 void ContextNoErrorTest31::bindProgramPipeline(const GLchar *vertString, const GLchar *fragString)
67 {
68     mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
69     ASSERT_NE(mVertProg, 0u);
70     mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
71     ASSERT_NE(mFragProg, 0u);
72 
73     // Generate a program pipeline and attach the programs to their respective stages
74     glGenProgramPipelines(1, &mPipeline);
75     EXPECT_GL_NO_ERROR();
76     glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
77     EXPECT_GL_NO_ERROR();
78     glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
79     EXPECT_GL_NO_ERROR();
80     glBindProgramPipeline(mPipeline);
81     EXPECT_GL_NO_ERROR();
82 }
83 
drawQuadWithPPO(const std::string & positionAttribName,const GLfloat positionAttribZ,const GLfloat positionAttribXYScale)84 void ContextNoErrorTest31::drawQuadWithPPO(const std::string &positionAttribName,
85                                            const GLfloat positionAttribZ,
86                                            const GLfloat positionAttribXYScale)
87 {
88     glUseProgram(0);
89 
90     std::array<Vector3, 6> quadVertices = ANGLETestBase::GetQuadVertices();
91 
92     for (Vector3 &vertex : quadVertices)
93     {
94         vertex.x() *= positionAttribXYScale;
95         vertex.y() *= positionAttribXYScale;
96         vertex.z() = positionAttribZ;
97     }
98 
99     GLint positionLocation = glGetAttribLocation(mVertProg, positionAttribName.c_str());
100 
101     glBindBuffer(GL_ARRAY_BUFFER, 0);
102     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
103     glEnableVertexAttribArray(positionLocation);
104 
105     glDrawArrays(GL_TRIANGLES, 0, 6);
106 
107     glDisableVertexAttribArray(positionLocation);
108     glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
109 }
110 
111 // Tests that error reporting is suppressed when GL_KHR_no_error is enabled
TEST_P(ContextNoErrorTest,NoError)112 TEST_P(ContextNoErrorTest, NoError)
113 {
114     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_no_error"));
115 
116     bindNaughtyTexture();
117     EXPECT_GL_NO_ERROR();
118 }
119 
120 // Test glDetachShader to make sure it resolves linking with a no error context and doesn't assert
TEST_P(ContextNoErrorTest,DetachAfterLink)121 TEST_P(ContextNoErrorTest, DetachAfterLink)
122 {
123     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_no_error"));
124 
125     GLuint vs      = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
126     GLuint fs      = CompileShader(GL_FRAGMENT_SHADER, essl1_shaders::fs::Red());
127     GLuint program = glCreateProgram();
128     glAttachShader(program, vs);
129     glAttachShader(program, fs);
130     glLinkProgram(program);
131 
132     glDetachShader(program, vs);
133     glDetachShader(program, fs);
134 
135     glDeleteShader(vs);
136     glDeleteShader(fs);
137     glDeleteProgram(program);
138     EXPECT_GL_NO_ERROR();
139 }
140 
141 // Tests that we can draw with a program pipeline when GL_KHR_no_error is enabled.
TEST_P(ContextNoErrorTest31,DrawWithPPO)142 TEST_P(ContextNoErrorTest31, DrawWithPPO)
143 {
144     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_no_error"));
145 
146     // Only the Vulkan backend supports PPOs
147     ANGLE_SKIP_TEST_IF(!IsVulkan());
148 
149     // TODO(http://anglebug.com/5102): Linking PPOs is currently done during draw call validation,
150     // so drawing with a PPO fails without validation enabled.
151     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_KHR_no_error"));
152 
153     // Create two separable program objects from a
154     // single source string respectively (vertSrc and fragSrc)
155     const GLchar *vertString = essl31_shaders::vs::Simple();
156     const GLchar *fragString = essl31_shaders::fs::Red();
157 
158     bindProgramPipeline(vertString, fragString);
159 
160     drawQuadWithPPO("a_position", 0.5f, 1.0f);
161     ASSERT_GL_NO_ERROR();
162     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
163 }
164 
165 // Tests that an incorrect enum to GetInteger does not cause an application crash.
TEST_P(ContextNoErrorTest,InvalidGetIntegerDoesNotCrash)166 TEST_P(ContextNoErrorTest, InvalidGetIntegerDoesNotCrash)
167 {
168     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_no_error"));
169 
170     GLint value = 1;
171     glGetIntegerv(GL_TEXTURE_2D, &value);
172     EXPECT_GL_NO_ERROR();
173     EXPECT_EQ(value, 1);
174 }
175 
176 // Test that we ignore an invalid texture type when EGL_KHR_create_context_no_error is enabled.
TEST_P(ContextNoErrorTest,InvalidTextureType)177 TEST_P(ContextNoErrorTest, InvalidTextureType)
178 {
179     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_no_error"));
180 
181     GLTexture texture;
182     constexpr GLenum kInvalidTextureType = 0;
183 
184     glBindTexture(kInvalidTextureType, texture);
185     ASSERT_GL_NO_ERROR();
186 
187     glTexParameteri(kInvalidTextureType, GL_TEXTURE_BASE_LEVEL, 0);
188     ASSERT_GL_NO_ERROR();
189 }
190 
191 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ContextNoErrorTest);
192 
193 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContextNoErrorTest31);
194 ANGLE_INSTANTIATE_TEST_ES31(ContextNoErrorTest31);
195