1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2017 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 * \file glcPolygonOffsetClampTests.cpp
21 * \brief Conformance tests for the EXT_polygon_offset_clamp functionality.
22 */ /*-------------------------------------------------------------------*/
23
24 #include "glcPolygonOffsetClampTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "glwEnums.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "tcuTestLog.hpp"
30
31 #include <stdio.h>
32
33 using namespace glw;
34 using namespace glu;
35
36 namespace glcts
37 {
38
39 const char* poc_shader_version_450core = "#version 450 core\n\n";
40 const char* poc_shader_version_310es = "#version 310 es\n\n";
41
42 const char* poc_vertexColor = "in highp vec3 vertex;\n"
43 "\n"
44 "void main()\n"
45 "{\n"
46 " gl_Position = vec4(vertex, 1);\n"
47 "}\n";
48
49 const char* poc_fragmentColor = "out highp vec4 fragColor;\n"
50 "\n"
51 "void main()\n"
52 "{\n"
53 " fragColor = vec4(1, 1, 1, 1);\n"
54 "}\n";
55
56 const char* poc_vertexTexture = "in highp vec3 vertex;\n"
57 "in highp vec2 texCoord;\n"
58 "out highp vec2 varyingtexCoord;\n"
59 "\n"
60 "void main()\n"
61 "{\n"
62 " gl_Position = vec4(vertex, 1);\n"
63 " varyingtexCoord = texCoord;\n"
64 "}\n";
65
66 const char* poc_fragmentTexture = "in highp vec2 varyingtexCoord;\n"
67 "out highp vec4 fragColor;\n"
68 "\n"
69 "layout (location = 0) uniform highp sampler2D tex;\n"
70 "\n"
71 "void main()\n"
72 "{\n"
73 " highp vec4 v = texture(tex, varyingtexCoord);\n"
74 " int r = int(v.r * 65536.0) % 256;\n"
75 " int g = int(v.r * 65536.0) / 256;\n"
76 " fragColor = vec4(float(r) / 255.0, float(g) / 255.0, 0.0, 1.0);\n"
77 "}\n";
78
79 /** Constructor.
80 *
81 * @param context Rendering context
82 * @param name Test name
83 * @param description Test description
84 */
PolygonOffsetClampTestCaseBase(deqp::Context & context,const char * name,const char * description)85 PolygonOffsetClampTestCaseBase::PolygonOffsetClampTestCaseBase(deqp::Context& context, const char* name,
86 const char* description)
87 : TestCase(context, name, description)
88 {
89 glu::ContextType contextType = m_context.getRenderContext().getType();
90 m_extensionSupported = glu::contextSupports(contextType, glu::ApiType::core(4, 6));
91 m_extensionSupported |= context.getContextInfo().isExtensionSupported("GL_EXT_polygon_offset_clamp");
92 m_extensionSupported |= context.getContextInfo().isExtensionSupported("GL_ARB_polygon_offset_clamp");
93 }
94
iterate()95 tcu::TestNode::IterateResult PolygonOffsetClampTestCaseBase::iterate()
96 {
97 if (!m_extensionSupported)
98 {
99 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
100 return STOP;
101 }
102
103 test(m_context.getRenderContext().getFunctions());
104
105 return STOP;
106 }
107
108 /** Constructor.
109 *
110 * @param context Rendering context
111 */
PolygonOffsetClampAvailabilityTestCase(deqp::Context & context)112 PolygonOffsetClampAvailabilityTestCase::PolygonOffsetClampAvailabilityTestCase(deqp::Context& context)
113 : PolygonOffsetClampTestCaseBase(context, "PolygonOffsetClampAvailability",
114 "Verifies if queries for GL_EXT_polygon_offset_clamp extension works properly")
115 {
116 }
117
test(const glw::Functions & gl)118 void PolygonOffsetClampAvailabilityTestCase::test(const glw::Functions& gl)
119 {
120 {
121 glw::GLboolean data;
122 gl.getBooleanv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
123 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
124 }
125 {
126 glw::GLint data;
127 gl.getIntegerv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
128 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
129 }
130 {
131 glw::GLint64 data;
132 gl.getInteger64v(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
133 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
134 }
135 {
136 glw::GLfloat data;
137 gl.getFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
138 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
139 }
140
141 // OpenGL ES does not support getDoublev query
142 if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
143 {
144 glw::GLdouble data;
145 gl.getDoublev(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
146 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
147 }
148
149 gl.polygonOffsetClamp(1.0f, 1.0f, 0.5f);
150 GLU_EXPECT_NO_ERROR(gl.getError(), "polygonOffsetClamp error occurred");
151
152 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
153 }
154
155 /** Constructor.
156 *
157 * @param context Rendering context
158 */
PolygonOffsetClampValueTestCaseBase(deqp::Context & context,const char * name,const char * description)159 PolygonOffsetClampValueTestCaseBase::PolygonOffsetClampValueTestCaseBase(deqp::Context& context, const char* name,
160 const char* description)
161 : PolygonOffsetClampTestCaseBase(context, name, description)
162 , m_fbo(0)
163 , m_depthBuf(0)
164 , m_colorBuf(0)
165 , m_fboReadback(0)
166 , m_colorBufReadback(0)
167 {
168 }
169
170 /** Initialization method that creates framebuffer with depth attachment
171 */
init()172 void PolygonOffsetClampValueTestCaseBase::init()
173 {
174 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
175
176 gl.genTextures(1, &m_depthBuf);
177 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
178 gl.bindTexture(GL_TEXTURE_2D, m_depthBuf);
179 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
180 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 64, 64);
181 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
182 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
183 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
184 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
185 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
186
187 gl.genTextures(1, &m_colorBuf);
188 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
189 gl.bindTexture(GL_TEXTURE_2D, m_colorBuf);
190 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
191 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
192 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
193 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
194 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
195 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
196 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
197
198 gl.genFramebuffers(1, &m_fbo);
199 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
200 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
201 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
202 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuf, 0);
203 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
204 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuf, 0);
205 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
206
207 if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
208 {
209 gl.genTextures(1, &m_colorBufReadback);
210 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
211 gl.bindTexture(GL_TEXTURE_2D, m_colorBufReadback);
212 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
213 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
214 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
215 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
216 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
217 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
218 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
219
220 gl.genFramebuffers(1, &m_fboReadback);
221 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
222 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback);
223 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
224 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBufReadback, 0);
225 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
226 }
227
228 gl.viewport(0, 0, 64, 64);
229 }
230
231 /** De-Initialization method that releases
232 */
deinit()233 void PolygonOffsetClampValueTestCaseBase::deinit()
234 {
235 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
236
237 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
238 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
239
240 if (m_fbo)
241 gl.deleteFramebuffers(1, &m_fbo);
242 if (m_depthBuf)
243 gl.deleteTextures(1, &m_depthBuf);
244 if (m_colorBuf)
245 gl.deleteTextures(1, &m_colorBuf);
246
247 if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
248 {
249 if (m_colorBufReadback)
250 gl.deleteTextures(1, &m_colorBufReadback);
251 if (m_fboReadback)
252 gl.deleteFramebuffers(1, &m_fboReadback);
253 }
254 }
255
256 /** Testing method that verifies if depth values generated after polygon offset clamp are as expected.
257 *
258 * @param gl Function bindings
259 */
test(const glw::Functions & gl)260 void PolygonOffsetClampValueTestCaseBase::test(const glw::Functions& gl)
261 {
262 const GLfloat vertices[] = { -1.0f, -1.0f, 0.5f, -1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, 1.0f, 1.0f, 0.5f };
263
264 // Prepare shader program
265 std::string vertexColor;
266 std::string fragmentColor;
267 if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
268 vertexColor = std::string(poc_shader_version_450core);
269 else
270 vertexColor = std::string(poc_shader_version_310es);
271 fragmentColor = vertexColor;
272
273 vertexColor = vertexColor + poc_vertexColor;
274 fragmentColor = fragmentColor + poc_fragmentColor;
275
276 ProgramSources testSources = makeVtxFragSources(vertexColor, fragmentColor);
277 ShaderProgram testProgram(gl, testSources);
278
279 if (!testProgram.isOk())
280 {
281 m_testCtx.getLog() << tcu::TestLog::Message << "TestProgram build failed.\n"
282 << "Vertex: " << testProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
283 << "Fragment: " << testProgram.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
284 << "Program: " << testProgram.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
285
286 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
287 return;
288 }
289
290 ShaderProgram* readDepthProgram = DE_NULL;
291 GLuint readDepthProgramId = 0;
292
293 // Prepare shader program for reading depth buffer indirectly
294 if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
295 {
296 std::string vertexTexture = std::string(poc_shader_version_310es) + poc_vertexTexture;
297 std::string fragmentTexture = std::string(poc_shader_version_310es) + poc_fragmentTexture;
298
299 ProgramSources readDepthSources = makeVtxFragSources(vertexTexture, fragmentTexture);
300
301 readDepthProgram = new ShaderProgram(gl, readDepthSources);
302
303 if (!readDepthProgram->isOk())
304 {
305 m_testCtx.getLog() << tcu::TestLog::Message << "ReadDepthProgram build failed.\n"
306 << "Vertex: " << readDepthProgram->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
307 << "Fragment: " << readDepthProgram->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
308 << "Program: " << readDepthProgram->getProgramInfo().infoLog << tcu::TestLog::EndMessage;
309
310 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
311 return;
312 }
313
314 readDepthProgramId = readDepthProgram->getProgram();
315 }
316
317 gl.useProgram(testProgram.getProgram());
318 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
319
320 GLuint vao;
321 GLuint arrayBuffer;
322
323 // Setup depth testing
324 gl.enable(GL_DEPTH_TEST);
325 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
326
327 gl.depthFunc(GL_ALWAYS);
328 GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc");
329
330 // Generate vertex array object
331 gl.genVertexArrays(1, &vao);
332 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
333
334 gl.bindVertexArray(vao);
335 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
336
337 // Setup vertex array buffer
338 gl.genBuffers(1, &arrayBuffer);
339 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
340
341 gl.bindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
342 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
343
344 gl.bufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
345 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
346
347 // Setup vertex attrib pointer
348 gl.enableVertexAttribArray(0);
349 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
350
351 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
352 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
353
354 // Bind framebuffer for drawing
355 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
356 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
357
358 /* Calculate number of depth units from depth bits. */
359 GLint depth_bits = 0;
360 gl.getIntegerv(GL_DEPTH_BITS, &depth_bits);
361 float num_units = (float)(1 << depth_bits);
362 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
363
364 bool result = true;
365 for (GLuint i = 0; i < m_testValues.size(); ++i)
366 {
367 // Prepare verification variables
368 GLfloat depthValue = 0.0f;
369 GLfloat depthValueOffset = 0.0f;
370 GLfloat depthValueOffsetClamp = 0.0f;
371
372 // Draw reference polygon
373 gl.disable(GL_POLYGON_OFFSET_FILL);
374 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
375
376 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
377 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
378
379 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
380 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
381
382 // Get reference depth value
383 depthValue = readDepthValue(gl, readDepthProgramId);
384
385 // Draw polygon with depth offset
386 gl.enable(GL_POLYGON_OFFSET_FILL);
387 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
388
389 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
390 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
391
392 gl.polygonOffset(m_testValues[i].factor, m_testValues[i].units * num_units);
393 GLU_EXPECT_NO_ERROR(gl.getError(), "glPolygonOffset");
394
395 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
396 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
397
398 depthValueOffset = readDepthValue(gl, readDepthProgramId);
399
400 // Draw reference polygon
401 gl.disable(GL_POLYGON_OFFSET_FILL);
402 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
403
404 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
405 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
406
407 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
408 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
409
410 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
411 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
412
413 // Draw polygon with depth offset
414 gl.enable(GL_POLYGON_OFFSET_FILL);
415 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
416
417 gl.polygonOffsetClamp(m_testValues[i].factor, m_testValues[i].units * num_units, m_testValues[i].clamp);
418 GLU_EXPECT_NO_ERROR(gl.getError(), "glPolygonOffsetClamp");
419
420 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
421 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
422
423 depthValueOffsetClamp = readDepthValue(gl, readDepthProgramId);
424
425 // Verify results
426 result = result && verify(i, depthValue, depthValueOffset, depthValueOffsetClamp);
427 }
428
429 // Cleanup
430 gl.disableVertexAttribArray(0);
431 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
432
433 gl.deleteVertexArrays(1, &arrayBuffer);
434 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
435
436 gl.deleteVertexArrays(1, &vao);
437 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
438
439 gl.disable(GL_POLYGON_OFFSET_FILL);
440 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
441
442 if (readDepthProgram)
443 delete readDepthProgram;
444
445 if (result)
446 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
447 else
448 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
449 }
450
451 /** Method .
452 *
453 * @param gl Function bindings
454 */
readDepthValue(const glw::Functions & gl,const GLuint readDepthProgramId)455 float PolygonOffsetClampValueTestCaseBase::readDepthValue(const glw::Functions& gl, const GLuint readDepthProgramId)
456 {
457 GLfloat depthValue = 0.0f;
458
459 if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
460 {
461 gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthValue);
462 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
463 }
464 // OpenGL ES does not support reading pixels directly from depth buffer
465 else
466 {
467 // Bind framebuffer for readback
468 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback);
469 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
470
471 gl.disable(GL_DEPTH_TEST);
472 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
473
474 gl.useProgram(readDepthProgramId);
475 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
476
477 gl.activeTexture(GL_TEXTURE0);
478 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
479 gl.bindTexture(GL_TEXTURE_2D, m_depthBuf);
480 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
481 gl.uniform1i(0, 0);
482 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
483
484 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
485 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
486
487 GLubyte pixels[4];
488 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
489 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
490
491 gl.enable(GL_DEPTH_TEST);
492 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
493
494 // Convert read depth value to GLfloat normalized
495 depthValue = (GLfloat)(pixels[0] + pixels[1] * 256) / 0xFFFF;
496
497 // Bind framebuffer for drawing
498 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
499 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
500 }
501
502 return depthValue;
503 }
504
505 /** Constructor.
506 *
507 * @param context Rendering context
508 */
PolygonOffsetClampMinMaxTestCase(deqp::Context & context)509 PolygonOffsetClampMinMaxTestCase::PolygonOffsetClampMinMaxTestCase(deqp::Context& context)
510 : PolygonOffsetClampValueTestCaseBase(
511 context, "PolygonOffsetClampMinMax",
512 "Verifies if polygon offset clamp works as expected for non-zero, finite clamp values")
513 {
514 }
515
516 /** Initialization method that fills polygonOffset* testing values
517 */
init()518 void PolygonOffsetClampMinMaxTestCase::init()
519 {
520 PolygonOffsetClampValueTestCaseBase::init();
521
522 m_testValues.clear();
523 m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f / 65536.0f, -0.0001f)); // Min offset case
524 m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f / 65536.0f, 0.0001f)); // Max offset case
525 }
526
527 /** Verification method that determines if depth values are as expected
528 *
529 * @param caseNo Case iteration number
530 * @param depth Reference depth value
531 * @param offsetDepth Case iteration number
532 * @param offsetClampDepth Case iteration number
533 */
verify(GLuint caseNo,GLfloat depth,GLfloat offsetDepth,GLfloat offsetClampDepth)534 bool PolygonOffsetClampMinMaxTestCase::verify(GLuint caseNo, GLfloat depth, GLfloat offsetDepth,
535 GLfloat offsetClampDepth)
536 {
537 // Min offset case
538 if (caseNo == 0)
539 {
540 if (depth <= offsetDepth || depth <= offsetClampDepth || offsetDepth >= offsetClampDepth)
541 {
542 m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MIN offset test.\n"
543 << "Expected result: "
544 << "refDepth[" << depth << "] > "
545 << "offsetClampDepth[" << offsetClampDepth << "] > "
546 << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage;
547
548 return false;
549 }
550 }
551 // Max offset case
552 else if (caseNo == 1)
553 {
554 if (depth >= offsetDepth || depth >= offsetClampDepth || offsetDepth <= offsetClampDepth)
555 {
556 m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MAX offset test.\n"
557 << "Expected result: "
558 << "refDepth[" << depth << "] < "
559 << "offsetClampDepth[" << offsetClampDepth << "] < "
560 << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage;
561
562 return false;
563 }
564 }
565 // Undefined case
566 else
567 return false;
568
569 return true;
570 }
571
572 /** Constructor.
573 *
574 * @param context Rendering context
575 */
PolygonOffsetClampZeroInfinityTestCase(deqp::Context & context)576 PolygonOffsetClampZeroInfinityTestCase::PolygonOffsetClampZeroInfinityTestCase(deqp::Context& context)
577 : PolygonOffsetClampValueTestCaseBase(
578 context, "PolygonOffsetClampZeroInfinity",
579 "Verifies if polygon offset clamp works as expected for zero and infinite clamp values")
580 {
581 }
582
583 /** Initialization method that fills polygonOffset* testing values
584 */
init()585 void PolygonOffsetClampZeroInfinityTestCase::init()
586 {
587 PolygonOffsetClampValueTestCaseBase::init();
588
589 m_testValues.clear();
590 m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f / 65536.0f, 0.0f)); // Min offset, zero clamp case
591 m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f / 65536.0f, -INFINITY)); // Min Offset, infinity clamp case
592 m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f / 65536.0f, 0.0f)); // Max offset, zero clamp case
593 m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f / 65536.0f, INFINITY)); // Max Offset, infinity clamp case
594 }
595
verify(GLuint caseNo,GLfloat depth,GLfloat offsetDepth,GLfloat offsetClampDepth)596 bool PolygonOffsetClampZeroInfinityTestCase::verify(GLuint caseNo, GLfloat depth, GLfloat offsetDepth,
597 GLfloat offsetClampDepth)
598 {
599 DE_UNREF(caseNo);
600
601 if (depth == offsetDepth || depth == offsetClampDepth || offsetDepth != offsetClampDepth)
602 {
603 m_testCtx.getLog() << tcu::TestLog::Message
604 << "PolygonOffsetClampEXT failed at Zero/Infinity offset clamp test.\n"
605 << "Expected result: "
606 << "refDepth[" << depth << "] != "
607 << "(offsetClampDepth[" << offsetClampDepth << "] == "
608 << "offsetDepth[" << offsetDepth << "])" << tcu::TestLog::EndMessage;
609
610 return false;
611 }
612
613 return true;
614 }
615
616 /** Constructor.
617 *
618 * @param context Rendering context.
619 */
PolygonOffsetClamp(deqp::Context & context)620 PolygonOffsetClamp::PolygonOffsetClamp(deqp::Context& context)
621 : TestCaseGroup(context, "polygon_offset_clamp",
622 "Verify conformance of CTS_EXT_polygon_offset_clamp implementation")
623 {
624 }
625
626 /** Initializes the test group contents. */
init()627 void PolygonOffsetClamp::init()
628 {
629 addChild(new PolygonOffsetClampAvailabilityTestCase(m_context));
630 addChild(new PolygonOffsetClampMinMaxTestCase(m_context));
631 addChild(new PolygonOffsetClampZeroInfinityTestCase(m_context));
632 }
633 } /* glcts namespace */
634