1
2 /*-------------------------------------------------------------------------
3 * OpenGL Conformance Test Suite
4 * -----------------------------
5 *
6 * Copyright (c) 2014-2016 The Khronos Group Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */ /*!
21 * \file
22 * \brief
23 */ /*-------------------------------------------------------------------*/
24
25 /*!
26 * \file esextcTextureBorderClampSamplingTexture.cpp
27 * \brief Verify that sampling a texture with GL_CLAMP_TO_BORDER_EXT
28 * wrap mode enabled gives correct results (Test 7)
29 */ /*-------------------------------------------------------------------*/
30
31 #include "esextcTextureBorderClampSamplingTexture.hpp"
32 #include "esextcTextureBorderClampCompressedResources.hpp"
33 #include "gluDefs.hpp"
34 #include "gluTextureUtil.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
38
39 namespace glcts
40 {
41
42 template <typename InputType, typename OutputType>
43 const glw::GLuint TextureBorderClampSamplingTexture<InputType, OutputType>::m_texture_unit = 0;
44
45 /** Constructor
46 *
47 * @param nComponents number of components
48 * @param target texture target
49 * @param inputInternalFormat input texture internal format
50 * @param outputInternalFormat output texture internal format
51 * @param filtering contains parameters for GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER - in our case can be GL_NEAREST or GL_LINEAR
52 * @param inputFormat input texture format
53 * @param outputFormat output texture format
54 * @param width texture/viewport width
55 * @param height texture/viewport height
56 * @param initValue value used for input texture to fill all texels with
57 * @param initBorderColor value of border color for input texture
58 * @param expectedValue expected value for texture texels for points taken from inside of input texture
59 * @param expectedBorderColor expected value for texture texels for points taken from outside of input texture
60 * @param inputType enum representing data type for input texture
61 * @param outputType enum representing data type for output texture
62 **/
63 template <typename InputType, typename OutputType>
TestConfiguration(glw::GLsizei nInComponents,glw::GLsizei nOutComponents,glw::GLenum target,glw::GLenum inputInternalFormat,glw::GLenum outputInternalFormat,glw::GLenum filtering,glw::GLenum inputFormat,glw::GLenum outputFormat,glw::GLuint width,glw::GLuint height,glw::GLuint depth,InputType initValue,InputType initBorderColor,OutputType expectedValue,OutputType expectedBorderColor,glw::GLenum inputType,glw::GLenum outputType)64 TestConfiguration<InputType, OutputType>::TestConfiguration(
65 glw::GLsizei nInComponents, glw::GLsizei nOutComponents, glw::GLenum target, glw::GLenum inputInternalFormat,
66 glw::GLenum outputInternalFormat, glw::GLenum filtering, glw::GLenum inputFormat, glw::GLenum outputFormat,
67 glw::GLuint width, glw::GLuint height, glw::GLuint depth, InputType initValue, InputType initBorderColor,
68 OutputType expectedValue, OutputType expectedBorderColor, glw::GLenum inputType, glw::GLenum outputType)
69 : m_n_in_components(nInComponents)
70 , m_n_out_components(nOutComponents)
71 , m_target(target)
72 , m_input_internal_format(inputInternalFormat)
73 , m_output_internal_format(outputInternalFormat)
74 , m_filtering(filtering)
75 , m_input_format(inputFormat)
76 , m_output_format(outputFormat)
77 , m_width(width)
78 , m_height(height)
79 , m_depth(depth)
80 , m_init_value(initValue)
81 , m_init_border_color(initBorderColor)
82 , m_expected_value(expectedValue)
83 , m_expected_border_color(expectedBorderColor)
84 , m_input_type(inputType)
85 , m_output_type(outputType)
86 {
87 /* Nothing to be done here */
88 }
89
90 /** Copy Contructor
91 *
92 * @param configuration const reference to the configuration which will be copied
93 */
94 template <typename InputType, typename OutputType>
TestConfiguration(const TestConfiguration & configuration)95 TestConfiguration<InputType, OutputType>::TestConfiguration(const TestConfiguration& configuration)
96 {
97 m_n_in_components = configuration.get_n_in_components();
98 m_n_out_components = configuration.get_n_out_components();
99 m_target = configuration.get_target();
100 m_input_internal_format = configuration.get_input_internal_format();
101 m_output_internal_format = configuration.get_output_internal_format();
102 m_filtering = configuration.get_filtering();
103 m_input_format = configuration.get_input_format();
104 m_output_format = configuration.get_output_format();
105 m_width = configuration.get_width();
106 m_height = configuration.get_height();
107 m_depth = configuration.get_depth();
108 m_init_value = configuration.get_init_value();
109 m_init_border_color = configuration.get_init_border_color();
110 m_expected_value = configuration.get_expected_value();
111 m_expected_border_color = configuration.get_expected_border_color();
112 m_input_type = configuration.get_input_type();
113 m_output_type = configuration.get_output_type();
114 }
115
116 /** Constructor
117 *
118 * @param context Test context
119 * @param name Test case's name
120 * @param description Test case's description
121 **/
122 template <typename InputType, typename OutputType>
TextureBorderClampSamplingTexture(Context & context,const ExtParameters & extParams,const char * name,const char * description,const TestConfiguration<InputType,OutputType> & configuration)123 TextureBorderClampSamplingTexture<InputType, OutputType>::TextureBorderClampSamplingTexture(
124 Context& context, const ExtParameters& extParams, const char* name, const char* description,
125 const TestConfiguration<InputType, OutputType>& configuration)
126 : TestCaseBase(context, extParams, name, description)
127 , m_attr_position_location(-1)
128 , m_attr_texcoord_location(-1)
129 , m_fbo_id(0)
130 , m_fs_id(0)
131 , m_po_id(0)
132 , m_sampler_id(0)
133 , m_test_configuration(configuration)
134 , m_input_to_id(0)
135 , m_output_to_id(0)
136 , m_position_vbo_id(0)
137 , m_text_coord_vbo_id(0)
138 , m_vs_id(0)
139 , m_vao_id(0)
140 {
141 /* Nothing to be done here */
142 }
143
144 /** Initializes GLES objects used during the test.
145 *
146 **/
147 template <typename InputType, typename OutputType>
initTest(void)148 void TextureBorderClampSamplingTexture<InputType, OutputType>::initTest(void)
149 {
150 if (!m_is_texture_border_clamp_supported)
151 {
152 throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
153 }
154
155 if (!m_is_texture_float_linear_supported && m_test_configuration.get_filtering() == GL_LINEAR &&
156 (m_test_configuration.get_input_internal_format() == GL_RGBA32F ||
157 m_test_configuration.get_input_internal_format() == GL_DEPTH_COMPONENT32F))
158 {
159 throw tcu::NotSupportedError(TEXTURE_FLOAT_LINEAR_NOT_SUPPORTED, "", __FILE__, __LINE__);
160 }
161
162 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
163
164 /* Generate and bind VAO */
165 gl.genVertexArrays(1, &m_vao_id);
166 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");
167 gl.bindVertexArray(m_vao_id);
168 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");
169
170 /* Generate sampler object */
171 gl.genSamplers(1, &m_sampler_id);
172 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating sampler object!");
173
174 /* Create framebuffer object */
175 gl.genFramebuffers(1, &m_fbo_id);
176 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating framebuffer object!");
177
178 /* Set up clear color */
179 gl.clearColor(0.5 /* red */, 0.5 /* green */, 0.5 /* blue */, 1 /* alpha */);
180 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting clear color value!");
181
182 /* Input attributes for vertex shader */
183
184 /* Full screen quad */
185 glw::GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
186 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };
187
188 /* Texture coords */
189 glw::GLfloat coords[] = {
190 -1.0f, -1.0f, /* for bottom-left corner of the viewport */
191 -1.0f, 2.0f, /* for top-left corner of the viewport */
192 2.0f, -1.0f, /* for bottom-right corner of the viewport */
193 2.0f, 2.0f /* for top-right corner of the viewport */
194 };
195
196 /* Generate buffer object */
197 gl.genBuffers(1, &m_position_vbo_id);
198 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
199
200 /* Bind buffer object */
201 gl.bindBuffer(GL_ARRAY_BUFFER, m_position_vbo_id);
202 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
203
204 /* Set data for buffer object */
205 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
206 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting data for buffer object!");
207
208 /* Generate buffer object */
209 gl.genBuffers(1, &m_text_coord_vbo_id);
210 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
211
212 /* Bind buffer object */
213 gl.bindBuffer(GL_ARRAY_BUFFER, m_text_coord_vbo_id);
214 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
215
216 /* Set data for buffer object */
217 gl.bufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW);
218 GLU_EXPECT_NO_ERROR(gl.getError(), "Error seting data for buffer object!");
219
220 /* Create program object */
221 m_po_id = gl.createProgram();
222
223 /* Create shader objects */
224 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
225 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
226
227 /* Get vertex shader code */
228 std::string vsCode = getVertexShaderCode();
229 const char* vsCodePtr = (const char*)vsCode.c_str();
230
231 /* Get fragment shader code */
232 std::string fshaderCode = getFragmentShaderCode();
233 const char* fshaderCodePtr = (const char*)fshaderCode.c_str();
234
235 /* Build program */
236 if (!buildProgram(m_po_id, m_fs_id, 1, &fshaderCodePtr, m_vs_id, 1, &vsCodePtr))
237 {
238 TCU_FAIL("Program could not have been created sucessfully from a valid vertex/fragment shader!");
239 }
240
241 createTextures();
242 }
243
244 /** Set data for input texture
245 *
246 * @param buffer reference to buffer where initial data will be stored
247 */
248 template <typename InputType, typename OutputType>
setInitData(std::vector<InputType> & buffer)249 void TextureBorderClampSamplingTexture<InputType, OutputType>::setInitData(std::vector<InputType>& buffer)
250 {
251 const InputType initDataTexel = m_test_configuration.get_init_value();
252
253 glw::GLuint size = m_test_configuration.get_width() * m_test_configuration.get_height() *
254 m_test_configuration.get_depth() * m_test_configuration.get_n_in_components();
255
256 for (glw::GLuint i = 0; i < size; ++i)
257 {
258 buffer[i] = initDataTexel;
259 }
260 }
261
262 /** Create input and output textures
263 *
264 */
265 template <typename InputType, typename OutputType>
createTextures(void)266 void TextureBorderClampSamplingTexture<InputType, OutputType>::createTextures(void)
267 {
268 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
269
270 /* Generate input texture */
271 gl.genTextures(1, &m_input_to_id);
272 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
273
274 /* Bind input texture */
275 gl.bindTexture(m_test_configuration.get_target(), m_input_to_id);
276 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
277
278 glw::GLsizei components = m_test_configuration.get_n_in_components();
279 glw::GLsizei texelsNumber =
280 m_test_configuration.get_width() * m_test_configuration.get_height() * m_test_configuration.get_depth();
281
282 /* Allocate storage for input texture and fill it with data */
283 {
284 switch (m_test_configuration.get_target())
285 {
286 case GL_TEXTURE_2D:
287 {
288 gl.texStorage2D(m_test_configuration.get_target(), /* target */
289 1, /* levels */
290 m_test_configuration.get_input_internal_format(), /* internalformat */
291 m_test_configuration.get_width(), /* width */
292 m_test_configuration.get_height()); /* height */
293 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!");
294
295 if (m_test_configuration.get_input_internal_format() == GL_COMPRESSED_RGBA8_ETC2_EAC)
296 {
297 gl.compressedTexSubImage2D(m_test_configuration.get_target(), /* target */
298 0, /* level */
299 0, /* xoffset */
300 0, /* yoffset */
301 m_test_configuration.get_width(), /* width */
302 m_test_configuration.get_height(), /* height */
303 m_test_configuration.get_input_internal_format(), /* internalformat */
304 sizeof(compressed_image_data_2D), /* image size */
305 compressed_image_data_2D); /* data */
306 GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture with compressed data!");
307 }
308 else
309 {
310 std::vector<InputType> inputData(components * texelsNumber);
311 setInitData(inputData);
312
313 gl.texSubImage2D(m_test_configuration.get_target(), /* target */
314 0, /* level */
315 0, /* xoffset */
316 0, /* yoffset */
317 m_test_configuration.get_width(), /* width */
318 m_test_configuration.get_height(), /* height */
319 m_test_configuration.get_input_format(), /* format */
320 m_test_configuration.get_input_type(), /* type */
321 &inputData[0]); /* data */
322 GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture with data!");
323 }
324 break;
325 }
326 case GL_TEXTURE_2D_ARRAY:
327 case GL_TEXTURE_3D:
328 {
329 gl.texStorage3D(m_test_configuration.get_target(), /* target */
330 1, /* levels */
331 m_test_configuration.get_input_internal_format(), /* internalformat*/
332 m_test_configuration.get_width(), /* width */
333 m_test_configuration.get_height(), /* height */
334 m_test_configuration.get_depth()); /* depth */
335 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!");
336
337 if (m_test_configuration.get_input_internal_format() == GL_COMPRESSED_RGBA8_ETC2_EAC)
338 {
339 gl.compressedTexSubImage3D(m_test_configuration.get_target(), /* target */
340 0, /* level */
341 0, /* xoffset */
342 0, /* yoffset */
343 0, /* zoffset */
344 m_test_configuration.get_width(), /* width */
345 m_test_configuration.get_height(), /* height */
346 m_test_configuration.get_depth(), /* depth */
347 m_test_configuration.get_input_internal_format(), /* internalformat */
348 sizeof(compressed_image_data_2D_array), /* image size */
349 compressed_image_data_2D_array); /* data */
350 GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture with compressed data!");
351 }
352 else
353 {
354 std::vector<InputType> inputData(components * texelsNumber);
355 setInitData(inputData);
356
357 gl.texSubImage3D(m_test_configuration.get_target(), /* target */
358 0, /* level */
359 0, /* xoffset */
360 0, /* yoffset */
361 0, /* zoffset */
362 m_test_configuration.get_width(), /* width */
363 m_test_configuration.get_height(), /* height */
364 m_test_configuration.get_depth(), /* depth */
365 m_test_configuration.get_input_format(), /* format */
366 m_test_configuration.get_input_type(), /* type */
367 &inputData[0]); /* data */
368 GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture with data!");
369 }
370 break;
371 }
372 default:
373 TCU_FAIL("Test parameters can contain only following targets: GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, "
374 "GL_TEXTURE_3D!");
375 }
376 }
377
378 /* Generate output texture */
379 gl.genTextures(1, &m_output_to_id);
380 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
381
382 /* Bind output texture */
383 gl.bindTexture(GL_TEXTURE_2D, m_output_to_id);
384 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
385
386 /* Allocate storage for output texture */
387 gl.texStorage2D(GL_TEXTURE_2D, 1, m_test_configuration.get_output_internal_format(),
388 m_test_configuration.get_width(), m_test_configuration.get_height());
389 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!");
390 }
391
392 /** Executes the test.
393 *
394 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
395 *
396 * Note the function throws exception should an error occur!
397 *
398 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
399 **/
400 template <typename InputType, typename OutputType>
iterate(void)401 tcu::TestNode::IterateResult TextureBorderClampSamplingTexture<InputType, OutputType>::iterate(void)
402 {
403 /* Initialize test case */
404 initTest();
405
406 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
407
408 bool testResult = true;
409
410 gl.useProgram(m_po_id);
411 GLU_EXPECT_NO_ERROR(gl.getError(), "Error using program!");
412
413 /* Configure vertices position attribute */
414 gl.bindBuffer(GL_ARRAY_BUFFER, m_position_vbo_id);
415 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
416
417 m_attr_position_location = gl.getAttribLocation(m_po_id, "vertex_position_in");
418 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get attribute location!");
419
420 gl.vertexAttribPointer(m_attr_position_location, 4, GL_FLOAT, GL_FALSE, 0, 0);
421 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set vertex attribute pointer!");
422
423 gl.enableVertexAttribArray(m_attr_position_location);
424 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not enable vertex attribute array!");
425
426 /* Configure texture coordinates attribute */
427 gl.bindBuffer(GL_ARRAY_BUFFER, m_text_coord_vbo_id);
428 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
429
430 m_attr_texcoord_location = gl.getAttribLocation(m_po_id, "texture_coords_in");
431 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get attribute location!");
432
433 gl.vertexAttribPointer(m_attr_texcoord_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
434 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set vertex attribute pointer!");
435
436 gl.enableVertexAttribArray(m_attr_texcoord_location);
437 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not enable vertex attribute array!");
438
439 /* Configure and bind sampler to texture unit */
440 gl.activeTexture(GL_TEXTURE0);
441 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active texture unit!");
442
443 gl.bindTexture(m_test_configuration.get_target(), m_input_to_id);
444 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture!");
445
446 glw::GLint samplerLocation = gl.getUniformLocation(m_po_id, "test_sampler");
447 GLU_EXPECT_NO_ERROR(gl.getError(), "Erros getting sampler location!");
448
449 gl.uniform1i(samplerLocation, m_texture_unit);
450 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind sampler location to texture unit!");
451
452 gl.bindSampler(m_texture_unit, m_sampler_id);
453 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind sampler object to texture unit!");
454
455 /* Set GL_TEXTURE_BORDER_COLOR_EXT for sampler object */
456 switch (m_test_configuration.get_input_internal_format())
457 {
458 case GL_RGBA32F:
459 case GL_RGBA8:
460 case GL_DEPTH_COMPONENT32F:
461 case GL_DEPTH_COMPONENT16:
462 case GL_COMPRESSED_RGBA8_ETC2_EAC:
463 {
464 glw::GLfloat val = (glw::GLfloat)m_test_configuration.get_init_border_color();
465 glw::GLfloat border_color[] = { val, val, val, val };
466 gl.samplerParameterfv(m_sampler_id, m_glExtTokens.TEXTURE_BORDER_COLOR, border_color);
467 break;
468 }
469 case GL_R32UI:
470 {
471 glw::GLuint val = (glw::GLuint)m_test_configuration.get_init_border_color();
472 glw::GLuint border_color[] = { val, val, val, val };
473 gl.samplerParameterIuiv(m_sampler_id, m_glExtTokens.TEXTURE_BORDER_COLOR, border_color);
474 break;
475 }
476 case GL_R32I:
477 {
478 glw::GLint val = (glw::GLint)m_test_configuration.get_init_border_color();
479 glw::GLint border_color[] = { val, val, val, val };
480 gl.samplerParameterIiv(m_sampler_id, m_glExtTokens.TEXTURE_BORDER_COLOR, border_color);
481 break;
482 }
483
484 default:
485 throw tcu::TestError("Unsupported sized internal format. Should never happen!", "", __FILE__, __LINE__);
486 break;
487 }
488 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting border color parameter!");
489
490 /* Set sampler's GL_TEXTURE_WRAP_* parameters values to GL_CLAMP_TO_BORDER_EXT */
491 gl.samplerParameteri(m_sampler_id, GL_TEXTURE_WRAP_S, m_glExtTokens.CLAMP_TO_BORDER);
492 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_TEXTURE_WRAP_S parameter!");
493 gl.samplerParameteri(m_sampler_id, GL_TEXTURE_WRAP_R, m_glExtTokens.CLAMP_TO_BORDER);
494 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_TEXTURE_WRAP_R parameter!");
495 gl.samplerParameteri(m_sampler_id, GL_TEXTURE_WRAP_T, m_glExtTokens.CLAMP_TO_BORDER);
496 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_TEXTURE_WRAP_T parameter!");
497
498 /* Set GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER parameters values */
499 gl.samplerParameteri(m_sampler_id, GL_TEXTURE_MAG_FILTER, m_test_configuration.get_filtering());
500 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for GL_TEXTURE_MAG_FILTER parameter!");
501 gl.samplerParameteri(m_sampler_id, GL_TEXTURE_MIN_FILTER, m_test_configuration.get_filtering());
502 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for GL_TEXTURE_MIN_FILTER parameter!");
503
504 for (glw::GLint i = getStartingLayerIndex(); i < getLastLayerIndex(); ++i)
505 {
506 /* Configure layer (third texture coordinate) */
507 glw::GLint layerLocation = gl.getUniformLocation(m_po_id, "layer");
508 GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting layer uniform location!");
509
510 gl.uniform1f(layerLocation, getCoordinateValue(i));
511 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting layer uniform variable!");
512
513 /* Bind framebuffer object */
514 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
515 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object!");
516
517 /* Set view port */
518 gl.viewport(0, /* x */
519 0, /* y */
520 m_test_configuration.get_width(), /* width */
521 m_test_configuration.get_height()); /* height */
522 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting view port!");
523
524 /* Attach texture to framebuffer */
525 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, /* target */
526 GL_COLOR_ATTACHMENT0, /* attachment */
527 GL_TEXTURE_2D, /* textarget */
528 m_output_to_id, /* texture */
529 0); /* level */
530 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not attach texture object to GL_COLOR_ATTACHMENT0!");
531
532 /* Check framebuffer status */
533 checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
534
535 /* Clear the color buffer with (0.5, 0.5, 0.5, 1) color */
536 gl.clear(GL_COLOR_BUFFER_BIT);
537 GLU_EXPECT_NO_ERROR(gl.getError(), "Error clearing color buffer");
538
539 /* Render */
540 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
541 GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
542
543 /* Get data from framebuffer's color attachment and compare with expected values.
544 * For GL_NEAREST filtering and GL_TEXTURE_3D texture target and Layer equal to
545 * -1 or Depth the whole texture is expected to be filled with border color
546 */
547 OutputType expectedColor;
548
549 switch (m_test_configuration.get_target())
550 {
551 case GL_TEXTURE_2D:
552 case GL_TEXTURE_2D_ARRAY:
553 expectedColor = m_test_configuration.get_expected_value();
554 break;
555
556 case GL_TEXTURE_3D:
557 if (i > -1 && i < (glw::GLint)m_test_configuration.get_depth())
558 expectedColor = m_test_configuration.get_expected_value();
559 else
560 expectedColor = m_test_configuration.get_expected_border_color();
561 break;
562 default:
563 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
564 }
565
566 if (!checkResult(expectedColor, m_test_configuration.get_expected_border_color(), i))
567 {
568 testResult = false;
569 }
570 }
571
572 if (testResult)
573 {
574 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
575 }
576 else
577 {
578 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
579 }
580 return STOP;
581 }
582
583 /** Deinitializes GLES objects created during the test.
584 *
585 */
586 template <typename InputType, typename OutputType>
deinit(void)587 void TextureBorderClampSamplingTexture<InputType, OutputType>::deinit(void)
588 {
589 /* Get GL entry points */
590 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
591
592 /* Reset Gl state */
593 gl.bindTexture(GL_TEXTURE_2D, 0);
594 gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
595 gl.bindTexture(GL_TEXTURE_3D, 0);
596 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
597 gl.bindSampler(m_texture_unit, 0);
598 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
599 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
600 gl.bindVertexArray(0);
601
602 if (m_attr_position_location != -1)
603 {
604 gl.disableVertexAttribArray(m_attr_position_location);
605 m_attr_position_location = -1;
606 }
607
608 if (m_attr_texcoord_location != -1)
609 {
610 gl.disableVertexAttribArray(m_attr_texcoord_location);
611 m_attr_texcoord_location = -1;
612 }
613
614 gl.useProgram(0);
615
616 /* Delete Gl objects */
617 if (m_fbo_id != 0)
618 {
619 gl.deleteFramebuffers(1, &m_fbo_id);
620 m_fbo_id = 0;
621 }
622
623 if (m_po_id != 0)
624 {
625 gl.deleteProgram(m_po_id);
626 m_po_id = 0;
627 }
628
629 if (m_fs_id != 0)
630 {
631 gl.deleteShader(m_fs_id);
632 m_fs_id = 0;
633 }
634
635 if (m_vs_id != 0)
636 {
637 gl.deleteShader(m_vs_id);
638 m_vs_id = 0;
639 }
640
641 if (m_input_to_id != 0)
642 {
643 gl.deleteTextures(1, &m_input_to_id);
644 m_input_to_id = 0;
645 }
646
647 if (m_output_to_id != 0)
648 {
649 gl.deleteTextures(1, &m_output_to_id);
650 m_output_to_id = 0;
651 }
652
653 if (m_sampler_id != 0)
654 {
655 gl.deleteSamplers(1, &m_sampler_id);
656 m_sampler_id = 0;
657 }
658
659 if (m_position_vbo_id != 0)
660 {
661 gl.deleteBuffers(1, &m_position_vbo_id);
662 m_position_vbo_id = 0;
663 }
664
665 if (m_text_coord_vbo_id != 0)
666 {
667 gl.deleteBuffers(1, &m_text_coord_vbo_id);
668 m_text_coord_vbo_id = 0;
669 }
670
671 if (m_vao_id != 0)
672 {
673 gl.deleteVertexArrays(1, &m_vao_id);
674 m_vao_id = 0;
675 }
676
677 /* Deinitialize base class */
678 TestCaseBase::deinit();
679 }
680
681 /** Check Framebuffer Status - throw exception if status is different than GL_FRAMEBUFFER_COMPLETE
682 *
683 * @param framebuffer - GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER
684 *
685 */
686 template <typename InputType, typename OutputType>
checkFramebufferStatus(glw::GLenum framebuffer)687 void TextureBorderClampSamplingTexture<InputType, OutputType>::checkFramebufferStatus(glw::GLenum framebuffer)
688 {
689 /* Get GL entry points */
690 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
691
692 /* Check framebuffer status */
693 glw::GLenum framebufferStatus = gl.checkFramebufferStatus(framebuffer);
694
695 if (GL_FRAMEBUFFER_COMPLETE != framebufferStatus)
696 {
697 switch (framebufferStatus)
698 {
699 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
700 {
701 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
702 }
703
704 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
705 {
706 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
707 }
708
709 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
710 {
711 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
712 }
713
714 case GL_FRAMEBUFFER_UNSUPPORTED:
715 {
716 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_UNSUPPORTED");
717 }
718
719 default:
720 {
721 TCU_FAIL("Framebuffer incomplete, status not recognized");
722 }
723 }
724
725 } /* if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) */
726 }
727
728 /** Get result data and check if it is as expected
729 *
730 * @return returns true if result data is as expected, otherwise returns false
731 */
732 template <typename InputType, typename OutputType>
checkResult(OutputType expectedValue,OutputType expectedBorderColor,glw::GLint layer)733 bool TextureBorderClampSamplingTexture<InputType, OutputType>::checkResult(OutputType expectedValue,
734 OutputType expectedBorderColor,
735 glw::GLint layer)
736 {
737 /* Get GL entry points */
738 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
739
740 /* Bind draw framebuffer to read framebuffer */
741 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
742 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object!");
743
744 std::vector<OutputType> resultData(m_test_configuration.get_width() * m_test_configuration.get_height() *
745 m_test_configuration.get_n_out_components());
746
747 /* Read data from framebuffer */
748 gl.readPixels(0, /* x */
749 0, /* y */
750 m_test_configuration.get_width(), /* width */
751 m_test_configuration.get_height(), /* height */
752 m_test_configuration.get_output_format(), /* format */
753 m_test_configuration.get_output_type(), /* type */
754 &resultData[0]); /* data */
755 GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels from color buffer");
756
757 tcu::TextureFormat tcuFormat =
758 glu::mapGLTransferFormat(m_test_configuration.get_output_format(), m_test_configuration.get_output_type());
759 m_testCtx.getLog() << tcu::TestLog::Image("Result", "Rendered result image",
760 tcu::ConstPixelBufferAccess(tcuFormat, m_test_configuration.get_width(),
761 m_test_configuration.get_height(), 1,
762 &resultData[0]));
763
764 /* Choose comparision method depending on filtering mode */
765 if (m_test_configuration.get_filtering() == GL_NEAREST)
766 {
767 return checkNearest(resultData, expectedValue, expectedBorderColor, layer);
768 }
769 else
770 {
771 return checkLinear(resultData, layer);
772 }
773 }
774
775 /** Create fragment shader code
776 *
777 * @return string with fragment shader code
778 */
779 template <typename InputType, typename OutputType>
getFragmentShaderCode(void)780 std::string TextureBorderClampSamplingTexture<InputType, OutputType>::getFragmentShaderCode(void)
781 {
782 std::stringstream result;
783 std::string coordType;
784 std::string samplerType;
785 std::string outType;
786 std::string outCommand;
787
788 /* Check input texture format and prepare sampler prefix */
789 switch (m_test_configuration.get_input_internal_format())
790 {
791 case GL_RGBA32F:
792 case GL_RGBA8:
793 case GL_DEPTH_COMPONENT32F:
794 case GL_DEPTH_COMPONENT16:
795 case GL_COMPRESSED_RGBA8_ETC2_EAC:
796 samplerType = "";
797 break;
798
799 case GL_R32UI:
800 samplerType = "u";
801 break;
802
803 case GL_R32I:
804 samplerType = "i";
805 break;
806
807 default:
808 throw tcu::TestError("Not allowed internal format", "", __FILE__, __LINE__);
809 }
810
811 /* Check input texture target and prepare approperiate texture coordinate type and sampler type */
812 switch (m_test_configuration.get_target())
813 {
814 case GL_TEXTURE_2D:
815 coordType = "vec2";
816 samplerType += "sampler2D";
817 break;
818
819 case GL_TEXTURE_2D_ARRAY:
820 coordType = "vec3";
821 samplerType += "sampler2DArray";
822 break;
823
824 case GL_TEXTURE_3D:
825 coordType = "vec3";
826 samplerType += "sampler3D";
827 break;
828
829 default:
830 throw tcu::TestError("Not allowed texture target!", "", __FILE__, __LINE__);
831 }
832
833 /* Check output texture format and prepare approperiate texel fetching method and output type */
834 switch (m_test_configuration.get_output_internal_format())
835 {
836 case GL_RGBA8:
837 outType = "vec4";
838 outCommand = "texture(test_sampler, texture_coords_out)";
839 break;
840
841 case GL_R8:
842 outType = "float";
843 outCommand = "texture(test_sampler, texture_coords_out).x";
844 break;
845
846 case GL_R32UI:
847 outType = "uint";
848 outCommand = "uint(texture(test_sampler, texture_coords_out).x)";
849 break;
850
851 case GL_R32I:
852 outType = "int";
853 outCommand = "int(texture(test_sampler, texture_coords_out).x)";
854 break;
855
856 default:
857 throw tcu::TestError("Not allowed internal format!", "", __FILE__, __LINE__);
858 }
859
860 result << "${VERSION}\n"
861 "\n"
862 "precision highp float;\n"
863 "precision highp "
864 << samplerType << ";\n"
865 "\n"
866 "uniform "
867 << samplerType << " test_sampler;\n"
868 "in "
869 << coordType << " texture_coords_out;\n"
870 "layout(location = 0) out "
871 << outType << " color;\n"
872 "\n"
873 "void main()\n"
874 "{\n"
875 " color = "
876 << outCommand << ";\n"
877 "}\n";
878
879 return result.str();
880 }
881
882 /** Create vertex shader code
883 *
884 * @return string with vertex shader code
885 */
886 template <typename InputType, typename OutputType>
getVertexShaderCode(void)887 std::string TextureBorderClampSamplingTexture<InputType, OutputType>::getVertexShaderCode(void)
888 {
889 std::stringstream result;
890 std::string coordType;
891 std::string coordAssignment;
892
893 /* Check input texture target and prepare approperiate coordinate type and coordinate assignment method */
894 switch (m_test_configuration.get_target())
895 {
896 case GL_TEXTURE_2D:
897 coordType = "vec2";
898 coordAssignment = "texture_coords_in";
899 break;
900
901 case GL_TEXTURE_2D_ARRAY:
902 case GL_TEXTURE_3D:
903 coordType = "vec3";
904 coordAssignment = "vec3(texture_coords_in, layer)";
905 break;
906
907 default:
908 throw tcu::TestError("Not allowed texture target!", "", __FILE__, __LINE__);
909 }
910
911 result << "${VERSION}\n"
912 "\n"
913 "precision highp float;\n"
914 "\n"
915 "layout (location = 0) in vec4 vertex_position_in;\n"
916 "layout (location = 1) in vec2 texture_coords_in;\n"
917 "out "
918 << coordType << " texture_coords_out;\n"
919 "uniform float layer;\n"
920 "\n"
921 "void main()\n"
922 "{\n"
923 " gl_Position = vertex_position_in;\n"
924 " texture_coords_out = "
925 << coordAssignment << ";\n"
926 "}\n";
927
928 return result.str();
929 }
930
931 /** Check if result data is the same as expected data when GL_NEAREST filtering is set
932 * @param buffer reference to the buffer with result data
933 * @param expectedValue it is the value which should be read from texture if coordinates are inside of [0,1]
934 * @param expectedBorderColor it is the value which should be read from texture if coordinates are outside of [0,1]
935 * @return returns true if result data is as expected, otherwise returns false
936 */
937 template <typename InputType, typename OutputType>
checkNearest(std::vector<OutputType> & buffer,OutputType expectedValue,OutputType expectedBorderColor,glw::GLint layer)938 bool TextureBorderClampSamplingTexture<InputType, OutputType>::checkNearest(std::vector<OutputType>& buffer,
939 OutputType expectedValue,
940 OutputType expectedBorderColor,
941 glw::GLint layer)
942 {
943 glw::GLuint width = m_test_configuration.get_width();
944 glw::GLuint height = m_test_configuration.get_height();
945 glw::GLuint in_components = m_test_configuration.get_n_in_components();
946 glw::GLuint out_components = m_test_configuration.get_n_out_components();
947 glw::GLuint outRowWidth = m_test_configuration.get_width() * out_components;
948 glw::GLuint index = 0;
949
950 /* Check if center point is equal to expectedValue */
951 std::pair<glw::GLuint, glw::GLuint> centerPoint(width / 2, height / 2);
952
953 for (glw::GLuint i = 0; i < deMinu32(out_components, in_components); ++i)
954 {
955 index = centerPoint.second * outRowWidth + centerPoint.first * out_components + i;
956 if (buffer[index] != expectedValue)
957 {
958 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong value for layer (" << layer << ") at point (x,y) = ("
959 << centerPoint.first << "," << centerPoint.second << ") , component (" << i << ")\n"
960 << "Expected value [" << (glw::GLint)expectedValue << "]\n"
961 << "Result value [" << (glw::GLint)buffer[index] << "]\n"
962 << tcu::TestLog::EndMessage;
963 return false;
964 }
965 }
966
967 /* Check if following points (marked as BC) contain values equal border color
968 *
969 * (-1, -1) (0, -1) (1, -1) (2, -1)
970 * *-------+-------+-------*
971 * | | | |
972 * | BC | BC | BC |
973 * | | | |
974 * (-1, 0) +-------+-------+-------+ (2, 0)
975 * | | | |
976 * | BC | 0 | BC |
977 * | | | |
978 * (-1, 1) +-------+-------+-------+ (2, 1)
979 * | | | |
980 * | BC | BC | BC |
981 * | | | |
982 * *-------+-------+-------*
983 * (-1, 2) (0, 2) (1, 2) (2, 2)
984 */
985
986 std::vector<std::pair<glw::GLuint, glw::GLuint> > borderPoints;
987
988 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 6, height / 6));
989 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 2, height / 6));
990 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>((glw::GLuint)(width / 6.0 * 5), height / 6));
991 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 6, height / 2));
992 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>((glw::GLuint)(width / 6.0 * 5), height / 2));
993 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 6, (glw::GLuint)(height / 6.0 * 5)));
994 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 2, (glw::GLuint)(height / 6.0 * 5)));
995 borderPoints.push_back(
996 std::pair<glw::GLuint, glw::GLuint>((glw::GLuint)(width / 6.0 * 5), (glw::GLuint)(height / 6.0 * 5)));
997
998 for (glw::GLuint j = 0; j < borderPoints.size(); ++j)
999 {
1000 for (glw::GLuint i = 0; i < deMinu32(out_components, in_components); ++i)
1001 {
1002 index = borderPoints[j].second * outRowWidth + borderPoints[j].first * out_components + i;
1003 if (buffer[index] != expectedBorderColor)
1004 {
1005 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong value for layer (" << layer
1006 << ") at point (x,y) = (" << borderPoints[j].first << "," << borderPoints[j].second
1007 << ") , component (" << i << ")\n"
1008 << "Expected value [" << (glw::GLint)expectedBorderColor << "]\n"
1009 << "Result value [" << (glw::GLint)buffer[index] << "]\n"
1010 << tcu::TestLog::EndMessage;
1011 return false;
1012 }
1013 }
1014 }
1015
1016 return true;
1017 }
1018
1019 /** Check if result data is as expected when GL_LINEAR filtering is set
1020 *
1021 * @param buffer reference to the buffer with result data
1022 * @return returns true if result data is as expected, otherwise return false
1023 */
1024 template <typename InputType, typename OutputType>
checkLinear(std::vector<OutputType> & buffer,glw::GLint layer)1025 bool TextureBorderClampSamplingTexture<InputType, OutputType>::checkLinear(std::vector<OutputType>& buffer,
1026 glw::GLint layer)
1027 {
1028 glw::GLuint w = m_test_configuration.get_width();
1029 glw::GLuint h = m_test_configuration.get_height();
1030 glw::GLuint centerX = w / 2;
1031 glw::GLuint centerY = h / 2;
1032 glw::GLuint stepX = w / 3;
1033 glw::GLuint stepY = h / 3;
1034
1035 glw::GLuint index = 0;
1036
1037 glw::GLuint in_components = m_test_configuration.get_n_in_components();
1038 glw::GLuint out_components = m_test_configuration.get_n_out_components();
1039 glw::GLuint outRowWidth = w * out_components;
1040
1041 /* Check that some points well within the texture are 0. Not applicable for
1042 * 3D, where some slices are blended with border along the depth coordinate.
1043 */
1044 if (m_test_configuration.get_target() != GL_TEXTURE_3D)
1045 {
1046 glw::GLuint texture_samples[4][2] = {
1047 { centerX + w / 6, centerY },
1048 { centerX - w / 6, centerY },
1049 { centerX, centerY + h / 6 },
1050 { centerX, centerY - h / 6 },
1051 };
1052 for (glw::GLuint i = 0; i < 4; i++)
1053 {
1054 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1055 {
1056 if (buffer[texture_samples[i][1] * outRowWidth + texture_samples[i][0] * out_components + c] != 0)
1057 {
1058 m_testCtx.getLog() << tcu::TestLog::Message << "Texture sample at (x, y) = ("
1059 << texture_samples[i][0] << "," << texture_samples[i][1] << ") not black\n"
1060 << tcu::TestLog::EndMessage;
1061 return false;
1062 }
1063 }
1064 }
1065 }
1066
1067 /* Check values from center to the bottom */
1068 for (glw::GLuint y = centerY; y < centerY + stepY; ++y)
1069 {
1070 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1071 {
1072 index = y * outRowWidth + centerX * out_components + c;
1073 if (buffer[index + outRowWidth] - buffer[index] < 0)
1074 {
1075 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1076 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1077 << ") to the bottom\n"
1078 << "at point (x, y) = (" << centerX << "," << y
1079 << ") - texel values stopped to be monotonically increasing\n"
1080 << tcu::TestLog::EndMessage;
1081 return false;
1082 }
1083 }
1084 }
1085
1086 /* Check values from center to the top */
1087 for (glw::GLuint y = centerY; y > centerY - stepY; --y)
1088 {
1089 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1090 {
1091 index = y * outRowWidth + centerX * out_components + c;
1092 if (buffer[index - outRowWidth] - buffer[index] < 0)
1093 {
1094 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1095 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1096 << ") to the top\n"
1097 << "at point (x, y) = (" << centerX << "," << y
1098 << ")- texel values stopped to be monotonically increasing\n"
1099 << tcu::TestLog::EndMessage;
1100 return false;
1101 }
1102 }
1103 }
1104
1105 /* Check values from center to the right */
1106 for (glw::GLuint x = centerX; x < centerX + stepX; ++x)
1107 {
1108 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1109 {
1110 index = centerY + x * out_components + c;
1111 if (buffer[index + out_components] - buffer[index] < 0)
1112 {
1113 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1114 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1115 << ") to the right\n"
1116 << "at point (x, y) = (" << x << "," << centerY
1117 << ")- texel values stopped to be monotonically increasing\n"
1118 << tcu::TestLog::EndMessage;
1119 return false;
1120 }
1121 }
1122 }
1123
1124 /* Check values from center to the left */
1125 for (glw::GLuint x = centerY; x > centerX - stepX; --x)
1126 {
1127 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1128 {
1129 index = centerY + x * out_components + c;
1130 if (buffer[index - out_components] - buffer[index] < 0)
1131 {
1132 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1133 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1134 << ") to the left\n"
1135 << "at point (x, y) = (" << x << "," << centerY
1136 << ")- texel values stopped to be monotonically increasing\n"
1137 << tcu::TestLog::EndMessage;
1138 return false;
1139 }
1140 }
1141 }
1142
1143 return true;
1144 }
1145
1146 /** Returns start layer index
1147 *
1148 * @return returns start layer index (0 for GL_TEXTURE_2D target , otherwise -1)
1149 */
1150 template <typename InputType, typename OutputType>
getStartingLayerIndex()1151 glw::GLint TextureBorderClampSamplingTexture<InputType, OutputType>::getStartingLayerIndex()
1152 {
1153 switch (m_test_configuration.get_target())
1154 {
1155 case GL_TEXTURE_2D:
1156 case GL_TEXTURE_2D_ARRAY:
1157 return 0;
1158
1159 case GL_TEXTURE_3D:
1160 return -1;
1161
1162 default:
1163 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
1164 }
1165 }
1166
1167 /** Returns last layer index
1168 *
1169 * @return returns last layer index (1 for GL_TEXTURE_2D target , otherwise depth + 1)
1170 */
1171 template <typename InputType, typename OutputType>
getLastLayerIndex()1172 glw::GLint TextureBorderClampSamplingTexture<InputType, OutputType>::getLastLayerIndex()
1173 {
1174 switch (m_test_configuration.get_target())
1175 {
1176 case GL_TEXTURE_2D:
1177 case GL_TEXTURE_2D_ARRAY:
1178 return m_test_configuration.get_depth();
1179
1180 case GL_TEXTURE_3D:
1181 return m_test_configuration.get_depth() + 1;
1182
1183 default:
1184 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
1185 }
1186 }
1187
1188 /** Returns third texture coordinate to access a particular layer in a texture
1189 *
1190 * @return returns third texture coordinate
1191 */
1192 template <typename InputType, typename OutputType>
getCoordinateValue(glw::GLint index)1193 glw::GLfloat TextureBorderClampSamplingTexture<InputType, OutputType>::getCoordinateValue(glw::GLint index)
1194 {
1195 switch (m_test_configuration.get_target())
1196 {
1197 case GL_TEXTURE_2D:
1198 return 0.0f;
1199 break;
1200
1201 case GL_TEXTURE_2D_ARRAY:
1202 return (glw::GLfloat)index;
1203
1204 case GL_TEXTURE_3D:
1205 return static_cast<glw::GLfloat>(index) / static_cast<glw::GLfloat>(m_test_configuration.get_depth());
1206
1207 default:
1208 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
1209 }
1210 }
1211
1212 } // namespace glcts
1213