• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2022-2022 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20 
21 /*!
22  * \file  esextcFragmentShadingRateErrors.hpp
23  * \brief FragmentShadingRateEXT errors
24  */ /*-------------------------------------------------------------------*/
25 
26 #include "esextcFragmentShadingRateErrors.hpp"
27 #include "gluContextInfo.hpp"
28 #include "gluDefs.hpp"
29 #include "glwEnums.hpp"
30 #include "glwFunctions.hpp"
31 #include "tcuTestLog.hpp"
32 #include <cstddef>
33 
34 namespace glcts
35 {
36 
37 /// Constructor
38 ///
39 /// @param context     Test context
40 /// @param name        Test case's name
41 /// @param description Test case's description
FragmentShadingRateErrors(Context & context,const ExtParameters & extParams,const char * name,const char * description)42 FragmentShadingRateErrors::FragmentShadingRateErrors(Context& context, const ExtParameters& extParams, const char* name,
43 													 const char* description)
44 	: TestCaseBase(context, extParams, name, description)
45 {
46 }
47 
48 /// Initialize the test.
init(void)49 void FragmentShadingRateErrors::init(void)
50 {
51 	TestCaseBase::init();
52 
53 	// Skip if required extensions are not supported.
54 	if (!m_is_fragment_shading_rate_supported)
55 	{
56 		throw tcu::NotSupportedError(FRAGMENT_SHADING_RATE_NOT_SUPPORTED, "", __FILE__, __LINE__);
57 	}
58 }
59 
60 /// Deinitializes all GLES objects created for the test.
deinit(void)61 void FragmentShadingRateErrors::deinit(void)
62 {
63 	// Deinitialize base class
64 	TestCaseBase::deinit();
65 }
66 
67 /// Test if the error code returned by glGetError is the same as expected.
68 ///  If the error is different from expected description is logged.
69 ///
70 /// @param expected_error    GLenum error which is expected
71 /// @param description       Log message in the case of failure.
72 ///
73 /// @return true if error is equal to expected, false otherwise.
verifyError(const glw::GLenum expected_error,const char * description) const74 glw::GLboolean FragmentShadingRateErrors::verifyError(const glw::GLenum expected_error, const char* description) const
75 {
76 	/* Retrieve GLES entry points. */
77 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
78 
79 	glw::GLboolean test_passed = true;
80 	glw::GLenum	   error_code  = gl.getError();
81 
82 	if (error_code != expected_error)
83 	{
84 		test_passed = false;
85 
86 		m_testCtx.getLog() << tcu::TestLog::Message << description << tcu::TestLog::EndMessage;
87 	}
88 
89 	return test_passed;
90 }
91 
92 /// Executes the test.
93 /// Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
94 /// Note the function throws exception should an error occur!
95 ///
96 ///  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
iterate(void)97 tcu::TestNode::IterateResult FragmentShadingRateErrors::iterate(void)
98 {
99 	bool testPassed = true;
100 
101 	/* Retrieve GLES entry points. */
102 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
103 
104 	// Shading Rate                   Size
105 	// ----------------------------   -----
106 	// SHADING_RATE_1X1_PIXELS_EXT    1x1
107 	// SHADING_RATE_1X2_PIXELS_EXT    1x2
108 	// SHADING_RATE_1X4_PIXELS_EXT    1x4
109 	// SHADING_RATE_2X1_PIXELS_EXT    2x1
110 	// SHADING_RATE_2X2_PIXELS_EXT    2x2
111 	// SHADING_RATE_2X4_PIXELS_EXT    2x4
112 	// SHADING_RATE_4X1_PIXELS_EXT    4x1
113 	// SHADING_RATE_4X2_PIXELS_EXT    4x2
114 	// SHADING_RATE_4X4_PIXELS_EXT    4x4
115 	// INVALID_ENUM is generated by ShadingRateEXT if <rate> is not a valid shading rate from table
116 	gl.shadingRateEXT(GL_SAMPLE_SHADING);
117 	testPassed = testPassed && verifyError(GL_INVALID_ENUM, "glShadingRateEXT <rate> is not valid");
118 
119 	if (m_is_fragment_shading_rate_attachment_supported)
120 	{
121 		// void FramebufferShadingRateEXT(enum target, enum attachment, uint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight);
122 		constexpr deUint32 kBaseLayer	  = 0;
123 		constexpr deUint32 kNumLayer	  = 1;
124 		constexpr deUint32 kTextureWidth  = 256;
125 		constexpr deUint32 kTextureHeight = 256;
126 		constexpr deUint32 kTexelWidth	  = 16;
127 		constexpr deUint32 kTexelHeight	  = 16;
128 
129 		glw::GLuint fbo_id;
130 		/* Generate framebuffer objects */
131 		gl.genFramebuffers(1, &fbo_id);
132 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up framebuffer objects");
133 
134 		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
135 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!");
136 
137 		glw::GLuint to_id;
138 		glw::GLuint mutable_to_id;
139 		/* Generate texture objects */
140 		gl.genTextures(1, &to_id);
141 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture objects");
142 
143 		gl.genTextures(1, &mutable_to_id);
144 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture objects");
145 
146 		gl.bindTexture(GL_TEXTURE_2D, to_id);
147 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
148 		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8UI, kTextureWidth, kTextureHeight);
149 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object!");
150 
151 		gl.bindTexture(GL_TEXTURE_2D, mutable_to_id);
152 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
153 		gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, kTextureWidth, kTextureHeight, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
154 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object!");
155 
156 		glw::GLint minTexelWidth		= 0;
157 		glw::GLint maxTexelWidth		= 0;
158 		glw::GLint minTexelHeight		= 0;
159 		glw::GLint maxTexelHeight		= 0;
160 		glw::GLint maxAttachAspectRatio = 0;
161 		glw::GLint maxAttachLayerCount	= 0;
162 		gl.getIntegerv(GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT, &minTexelWidth);
163 		GLU_EXPECT_NO_ERROR(gl.getError(),
164 							"Error getIntegerv GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT!");
165 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT, &maxTexelWidth);
166 		GLU_EXPECT_NO_ERROR(gl.getError(),
167 							"Error getIntegerv GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT!");
168 		gl.getIntegerv(GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT, &minTexelHeight);
169 		GLU_EXPECT_NO_ERROR(gl.getError(),
170 							"Error getIntegerv GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT!");
171 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT, &maxTexelHeight);
172 		GLU_EXPECT_NO_ERROR(gl.getError(),
173 							"Error getIntegerv GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT!");
174 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT, &maxAttachAspectRatio);
175 		GLU_EXPECT_NO_ERROR(gl.getError(),
176 							"Error getIntegerv GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT!");
177 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT, &maxAttachLayerCount);
178 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getIntegerv GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT!");
179 
180 		// An INVALID_ENUM error is generated if <target> is not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER, or FRAMEBUFFER.
181 		gl.framebufferShadingRateEXT(GL_RENDERBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, to_id, kBaseLayer, kNumLayer,
182 									 kTexelWidth, kTexelHeight);
183 		testPassed = testPassed && verifyError(GL_INVALID_ENUM, "framebufferShadingRateEXT <target> is not valid");
184 
185 		// An INVALID_ENUM error is generated if <attachment> is not SHADING_RATE_ATTACHMENT_EXT.
186 		gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id, kBaseLayer, kNumLayer, kTexelWidth,
187 									 kTexelHeight);
188 		testPassed = testPassed && verifyError(GL_INVALID_ENUM, "framebufferShadingRateEXT <attachment> is not valid");
189 
190 		// An INVALID_VALUE error is generated if <texture> is not zero and is not the name of an immutable texture object.
191 		gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, mutable_to_id, kBaseLayer,
192 									 kNumLayer, kTexelWidth, kTexelHeight);
193 		testPassed = testPassed && verifyError(GL_INVALID_VALUE, "framebufferShadingRateEXT <texture> is not valid");
194 
195 		// An INVALID_VALUE error is generated if <baseLayer> is greater than or equal to the value of MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT.
196 		gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, to_id,
197 									 GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT, kNumLayer, kTexelWidth,
198 									 kTexelHeight);
199 		testPassed = testPassed && verifyError(GL_INVALID_VALUE, "framebufferShadingRateEXT <baseLayer> is not valid");
200 
201 		// An INVALID_VALUE error is generated if <numLayers> is greater than the value of MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT.
202 		gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, to_id, 0,
203 									 GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT + 1, kTexelWidth, kTexelHeight);
204 		testPassed = testPassed && verifyError(GL_INVALID_VALUE, "framebufferShadingRateEXT <numLayers> is not valid");
205 
206 		// An INVALID_VALUE error is generated if <texelWidth> / <texelHeight> is larger than MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT.
207 		gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, to_id, 0,
208 									 GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT + 1, minTexelWidth,
209 									 (minTexelWidth * GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT)
210 										 << 1);
211 		testPassed = testPassed &&
212 					 verifyError(GL_INVALID_VALUE, "framebufferShadingRateEXT <texelWidth, texelHeight> is not valid");
213 
214 		// An INVALID_VALUE error is generated if <texelHeight> / <texelWidth> is larger than MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT.
215 		gl.framebufferShadingRateEXT(
216 			GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, to_id, 0,
217 			GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT + 1,
218 			(minTexelHeight * GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT) << 1, minTexelHeight);
219 		testPassed = testPassed &&
220 					 verifyError(GL_INVALID_VALUE, "framebufferShadingRateEXT <texelWidth, texelHeight> is not valid");
221 
222 		gl.deleteFramebuffers(1, &fbo_id);
223 		gl.deleteFramebuffers(1, &to_id);
224 		gl.deleteFramebuffers(1, &mutable_to_id);
225 	}
226 
227 	// void ShadingRateCombinerOpsEXT(enum combinerOp0, enum combinerOp1)
228 	//
229 	// An INVALID_ENUM error is generated if <combinerOp0> is not
230 	// An INVALID_ENUM error is generated if <combinerOp1> is not
231 	// FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT,
232 	// FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT,
233 	// FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT,
234 	// FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT, or
235 	// FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT
236 	gl.shadingRateCombinerOpsEXT(GL_SHADING_RATE_EXT, GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT);
237 	testPassed = testPassed && verifyError(GL_INVALID_ENUM, "shadingRateCombinerOpsEXT <combinerOp0> is not valid");
238 	gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT,
239 								 GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT);
240 	testPassed = testPassed && verifyError(GL_INVALID_ENUM, "shadingRateCombinerOpsEXT <combinerOp1> is not valid");
241 
242 	glw::GLboolean supportNonTrivialCombiner = false;
243 	gl.getBooleanv(GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT, &supportNonTrivialCombiner);
244 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getBooleanv non trivial combiner");
245 
246 	// An INVALID_OPERATION error is generated if the value of FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT
247 	// is FALSE and <combinerOp0> is not
248 	// FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT or FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT
249 	// is FALSE and <combinerOp1> is not
250 	// FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT or FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT
251 	if (!supportNonTrivialCombiner)
252 	{
253 		gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT,
254 									 GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT);
255 		testPassed = testPassed && verifyError(GL_INVALID_OPERATION, "<combinerOp0> combiner is non trivial combiner");
256 
257 		gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT,
258 									 GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT);
259 		testPassed = testPassed && verifyError(GL_INVALID_OPERATION, "<combinerOp1> combiner is non trivial combiner");
260 	}
261 	// [[If GL_EXT_fragment_shading_rate_primitive is not supported]]
262 	// An INVALID_OPERATION error is generated if <combinerOp0> is not
263 	// FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT
264 	if (!m_is_fragment_shading_rate_primitive_supported)
265 	{
266 		gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT,
267 									 GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT);
268 		testPassed = testPassed && verifyError(GL_INVALID_ENUM, "shadingRateCombinerOpsEXT <combinerOp0> is not valid");
269 	}
270 
271 	// [[If GL_EXT_fragment_shading_rate_attachment is not supported]]
272 	// An INVALID_OPERATION error is generated if <combinerOp1> is not
273 	// FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT
274 	if (!m_is_fragment_shading_rate_attachment_supported)
275 	{
276 		gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT,
277 									 GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT);
278 		testPassed = testPassed && verifyError(GL_INVALID_ENUM, "shadingRateCombinerOpsEXT <combinerOp0> is not valid");
279 	}
280 
281 	/* All done */
282 	if (testPassed)
283 	{
284 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
285 	}
286 	else
287 	{
288 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
289 	}
290 
291 	return STOP;
292 }
293 
294 } // namespace glcts
295