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
865 << ";\n"
866 "\n"
867 "uniform "
868 << samplerType
869 << " test_sampler;\n"
870 "in "
871 << coordType
872 << " texture_coords_out;\n"
873 "layout(location = 0) out "
874 << outType
875 << " color;\n"
876 "\n"
877 "void main()\n"
878 "{\n"
879 " color = "
880 << outCommand
881 << ";\n"
882 "}\n";
883
884 return result.str();
885 }
886
887 /** Create vertex shader code
888 *
889 * @return string with vertex shader code
890 */
891 template <typename InputType, typename OutputType>
getVertexShaderCode(void)892 std::string TextureBorderClampSamplingTexture<InputType, OutputType>::getVertexShaderCode(void)
893 {
894 std::stringstream result;
895 std::string coordType;
896 std::string coordAssignment;
897
898 /* Check input texture target and prepare approperiate coordinate type and coordinate assignment method */
899 switch (m_test_configuration.get_target())
900 {
901 case GL_TEXTURE_2D:
902 coordType = "vec2";
903 coordAssignment = "texture_coords_in";
904 break;
905
906 case GL_TEXTURE_2D_ARRAY:
907 case GL_TEXTURE_3D:
908 coordType = "vec3";
909 coordAssignment = "vec3(texture_coords_in, layer)";
910 break;
911
912 default:
913 throw tcu::TestError("Not allowed texture target!", "", __FILE__, __LINE__);
914 }
915
916 result << "${VERSION}\n"
917 "\n"
918 "precision highp float;\n"
919 "\n"
920 "layout (location = 0) in vec4 vertex_position_in;\n"
921 "layout (location = 1) in vec2 texture_coords_in;\n"
922 "out "
923 << coordType
924 << " texture_coords_out;\n"
925 "uniform float layer;\n"
926 "\n"
927 "void main()\n"
928 "{\n"
929 " gl_Position = vertex_position_in;\n"
930 " texture_coords_out = "
931 << coordAssignment
932 << ";\n"
933 "}\n";
934
935 return result.str();
936 }
937
938 /** Check if result data is the same as expected data when GL_NEAREST filtering is set
939 * @param buffer reference to the buffer with result data
940 * @param expectedValue it is the value which should be read from texture if coordinates are inside of [0,1]
941 * @param expectedBorderColor it is the value which should be read from texture if coordinates are outside of [0,1]
942 * @return returns true if result data is as expected, otherwise returns false
943 */
944 template <typename InputType, typename OutputType>
checkNearest(std::vector<OutputType> & buffer,OutputType expectedValue,OutputType expectedBorderColor,glw::GLint layer)945 bool TextureBorderClampSamplingTexture<InputType, OutputType>::checkNearest(std::vector<OutputType> &buffer,
946 OutputType expectedValue,
947 OutputType expectedBorderColor,
948 glw::GLint layer)
949 {
950 glw::GLuint width = m_test_configuration.get_width();
951 glw::GLuint height = m_test_configuration.get_height();
952 glw::GLuint in_components = m_test_configuration.get_n_in_components();
953 glw::GLuint out_components = m_test_configuration.get_n_out_components();
954 glw::GLuint outRowWidth = m_test_configuration.get_width() * out_components;
955 glw::GLuint index = 0;
956
957 /* Check if center point is equal to expectedValue */
958 std::pair<glw::GLuint, glw::GLuint> centerPoint(width / 2, height / 2);
959
960 for (glw::GLuint i = 0; i < deMinu32(out_components, in_components); ++i)
961 {
962 index = centerPoint.second * outRowWidth + centerPoint.first * out_components + i;
963 if (buffer[index] != expectedValue)
964 {
965 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong value for layer (" << layer << ") at point (x,y) = ("
966 << centerPoint.first << "," << centerPoint.second << ") , component (" << i << ")\n"
967 << "Expected value [" << (glw::GLint)expectedValue << "]\n"
968 << "Result value [" << (glw::GLint)buffer[index] << "]\n"
969 << tcu::TestLog::EndMessage;
970 return false;
971 }
972 }
973
974 /* Check if following points (marked as BC) contain values equal border color
975 *
976 * (-1, -1) (0, -1) (1, -1) (2, -1)
977 * *-------+-------+-------*
978 * | | | |
979 * | BC | BC | BC |
980 * | | | |
981 * (-1, 0) +-------+-------+-------+ (2, 0)
982 * | | | |
983 * | BC | 0 | BC |
984 * | | | |
985 * (-1, 1) +-------+-------+-------+ (2, 1)
986 * | | | |
987 * | BC | BC | BC |
988 * | | | |
989 * *-------+-------+-------*
990 * (-1, 2) (0, 2) (1, 2) (2, 2)
991 */
992
993 std::vector<std::pair<glw::GLuint, glw::GLuint>> borderPoints;
994
995 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 6, height / 6));
996 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 2, height / 6));
997 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>((glw::GLuint)(width / 6.0 * 5), height / 6));
998 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 6, height / 2));
999 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>((glw::GLuint)(width / 6.0 * 5), height / 2));
1000 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 6, (glw::GLuint)(height / 6.0 * 5)));
1001 borderPoints.push_back(std::pair<glw::GLuint, glw::GLuint>(width / 2, (glw::GLuint)(height / 6.0 * 5)));
1002 borderPoints.push_back(
1003 std::pair<glw::GLuint, glw::GLuint>((glw::GLuint)(width / 6.0 * 5), (glw::GLuint)(height / 6.0 * 5)));
1004
1005 for (glw::GLuint j = 0; j < borderPoints.size(); ++j)
1006 {
1007 for (glw::GLuint i = 0; i < deMinu32(out_components, in_components); ++i)
1008 {
1009 index = borderPoints[j].second * outRowWidth + borderPoints[j].first * out_components + i;
1010 if (buffer[index] != expectedBorderColor)
1011 {
1012 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong value for layer (" << layer
1013 << ") at point (x,y) = (" << borderPoints[j].first << "," << borderPoints[j].second
1014 << ") , component (" << i << ")\n"
1015 << "Expected value [" << (glw::GLint)expectedBorderColor << "]\n"
1016 << "Result value [" << (glw::GLint)buffer[index] << "]\n"
1017 << tcu::TestLog::EndMessage;
1018 return false;
1019 }
1020 }
1021 }
1022
1023 return true;
1024 }
1025
1026 /** Check if result data is as expected when GL_LINEAR filtering is set
1027 *
1028 * @param buffer reference to the buffer with result data
1029 * @return returns true if result data is as expected, otherwise return false
1030 */
1031 template <typename InputType, typename OutputType>
checkLinear(std::vector<OutputType> & buffer,glw::GLint layer)1032 bool TextureBorderClampSamplingTexture<InputType, OutputType>::checkLinear(std::vector<OutputType> &buffer,
1033 glw::GLint layer)
1034 {
1035 glw::GLuint w = m_test_configuration.get_width();
1036 glw::GLuint h = m_test_configuration.get_height();
1037 glw::GLuint centerX = w / 2;
1038 glw::GLuint centerY = h / 2;
1039 glw::GLuint stepX = w / 3;
1040 glw::GLuint stepY = h / 3;
1041
1042 glw::GLuint index = 0;
1043
1044 glw::GLuint in_components = m_test_configuration.get_n_in_components();
1045 glw::GLuint out_components = m_test_configuration.get_n_out_components();
1046 glw::GLuint outRowWidth = w * out_components;
1047
1048 /* Check that some points well within the texture are 0. Not applicable for
1049 * 3D, where some slices are blended with border along the depth coordinate.
1050 */
1051 if (m_test_configuration.get_target() != GL_TEXTURE_3D)
1052 {
1053 glw::GLuint texture_samples[4][2] = {
1054 {centerX + w / 6, centerY},
1055 {centerX - w / 6, centerY},
1056 {centerX, centerY + h / 6},
1057 {centerX, centerY - h / 6},
1058 };
1059 for (glw::GLuint i = 0; i < 4; i++)
1060 {
1061 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1062 {
1063 if (buffer[texture_samples[i][1] * outRowWidth + texture_samples[i][0] * out_components + c] != 0)
1064 {
1065 m_testCtx.getLog() << tcu::TestLog::Message << "Texture sample at (x, y) = ("
1066 << texture_samples[i][0] << "," << texture_samples[i][1] << ") not black\n"
1067 << tcu::TestLog::EndMessage;
1068 return false;
1069 }
1070 }
1071 }
1072 }
1073
1074 /* Check values from center to the bottom */
1075 for (glw::GLuint y = centerY; y < centerY + stepY; ++y)
1076 {
1077 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1078 {
1079 index = y * outRowWidth + centerX * out_components + c;
1080 if (buffer[index + outRowWidth] - buffer[index] < 0)
1081 {
1082 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1083 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1084 << ") to the bottom\n"
1085 << "at point (x, y) = (" << centerX << "," << y
1086 << ") - texel values stopped to be monotonically increasing\n"
1087 << tcu::TestLog::EndMessage;
1088 return false;
1089 }
1090 }
1091 }
1092
1093 /* Check values from center to the top */
1094 for (glw::GLuint y = centerY; y > centerY - stepY; --y)
1095 {
1096 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1097 {
1098 index = y * outRowWidth + centerX * out_components + c;
1099 if (buffer[index - outRowWidth] - buffer[index] < 0)
1100 {
1101 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1102 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1103 << ") to the top\n"
1104 << "at point (x, y) = (" << centerX << "," << y
1105 << ")- texel values stopped to be monotonically increasing\n"
1106 << tcu::TestLog::EndMessage;
1107 return false;
1108 }
1109 }
1110 }
1111
1112 /* Check values from center to the right */
1113 for (glw::GLuint x = centerX; x < centerX + stepX; ++x)
1114 {
1115 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1116 {
1117 index = centerY + x * out_components + c;
1118 if (buffer[index + out_components] - buffer[index] < 0)
1119 {
1120 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1121 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1122 << ") to the right\n"
1123 << "at point (x, y) = (" << x << "," << centerY
1124 << ")- texel values stopped to be monotonically increasing\n"
1125 << tcu::TestLog::EndMessage;
1126 return false;
1127 }
1128 }
1129 }
1130
1131 /* Check values from center to the left */
1132 for (glw::GLuint x = centerY; x > centerX - stepX; --x)
1133 {
1134 for (glw::GLuint c = 0; c < deMinu32(out_components, in_components); ++c)
1135 {
1136 index = centerY + x * out_components + c;
1137 if (buffer[index - out_components] - buffer[index] < 0)
1138 {
1139 m_testCtx.getLog() << tcu::TestLog::Message << "For layer (" << layer
1140 << ") when moving from center point (x, y) = (" << centerX << "," << centerY
1141 << ") to the left\n"
1142 << "at point (x, y) = (" << x << "," << centerY
1143 << ")- texel values stopped to be monotonically increasing\n"
1144 << tcu::TestLog::EndMessage;
1145 return false;
1146 }
1147 }
1148 }
1149
1150 return true;
1151 }
1152
1153 /** Returns start layer index
1154 *
1155 * @return returns start layer index (0 for GL_TEXTURE_2D target , otherwise -1)
1156 */
1157 template <typename InputType, typename OutputType>
getStartingLayerIndex()1158 glw::GLint TextureBorderClampSamplingTexture<InputType, OutputType>::getStartingLayerIndex()
1159 {
1160 switch (m_test_configuration.get_target())
1161 {
1162 case GL_TEXTURE_2D:
1163 case GL_TEXTURE_2D_ARRAY:
1164 return 0;
1165
1166 case GL_TEXTURE_3D:
1167 return -1;
1168
1169 default:
1170 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
1171 }
1172 }
1173
1174 /** Returns last layer index
1175 *
1176 * @return returns last layer index (1 for GL_TEXTURE_2D target , otherwise depth + 1)
1177 */
1178 template <typename InputType, typename OutputType>
getLastLayerIndex()1179 glw::GLint TextureBorderClampSamplingTexture<InputType, OutputType>::getLastLayerIndex()
1180 {
1181 switch (m_test_configuration.get_target())
1182 {
1183 case GL_TEXTURE_2D:
1184 case GL_TEXTURE_2D_ARRAY:
1185 return m_test_configuration.get_depth();
1186
1187 case GL_TEXTURE_3D:
1188 return m_test_configuration.get_depth() + 1;
1189
1190 default:
1191 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
1192 }
1193 }
1194
1195 /** Returns third texture coordinate to access a particular layer in a texture
1196 *
1197 * @return returns third texture coordinate
1198 */
1199 template <typename InputType, typename OutputType>
getCoordinateValue(glw::GLint index)1200 glw::GLfloat TextureBorderClampSamplingTexture<InputType, OutputType>::getCoordinateValue(glw::GLint index)
1201 {
1202 switch (m_test_configuration.get_target())
1203 {
1204 case GL_TEXTURE_2D:
1205 return 0.0f;
1206 break;
1207
1208 case GL_TEXTURE_2D_ARRAY:
1209 return (glw::GLfloat)index;
1210
1211 case GL_TEXTURE_3D:
1212 return static_cast<glw::GLfloat>(index) / static_cast<glw::GLfloat>(m_test_configuration.get_depth());
1213
1214 default:
1215 TCU_FAIL("Not allowed texture target - should be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D");
1216 }
1217 }
1218
1219 } // namespace glcts
1220