• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP
2 #define _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2016 The Khronos Group Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */ /*!
22  * \file  glcRobustBufferAccessBehaviorTests.hpp
23  * \brief Declares test classes for "Robust Buffer Access Behavior" functionality.
24  */ /*-------------------------------------------------------------------*/
25 
26 #include "glcRobustnessTests.hpp"
27 #include "glcTestCase.hpp"
28 #include "glwDefs.hpp"
29 #include "glwEnums.hpp"
30 
31 #include <map>
32 
33 namespace glcts
34 {
35 namespace RobustBufferAccessBehavior
36 {
37 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
38  **/
39 void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, std::string& string);
40 
41 /** Represents buffer instance
42  * Provides basic buffer functionality
43  **/
44 class Buffer
45 {
46 public:
47 	/* Public methods */
48 	/* Ctr & Dtr */
49 	Buffer(const glw::Functions& gl);
50 	~Buffer();
51 
52 	/* Init & Release */
53 	void InitData(glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, const glw::GLvoid* data);
54 	void Release();
55 
56 	/* Functionality */
57 	void Bind() const;
58 	void BindBase(glw::GLuint index) const;
59 
60 	/* Public static routines */
61 	/* Functionality */
62 	static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target);
63 	static void BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index);
64 	static void Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size,
65 					 const glw::GLvoid* data);
66 	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
67 	static void SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size,
68 						glw::GLvoid* data);
69 
70 	/* Public fields */
71 	glw::GLuint m_id;
72 
73 	/* Public constants */
74 	static const glw::GLuint m_invalid_id;
75 	static const glw::GLuint m_n_targets = 13;
76 	static const glw::GLenum m_targets[m_n_targets];
77 
78 private:
79 	/* Private enums */
80 
81 	/* Private fields */
82 	const glw::Functions& m_gl;
83 	glw::GLenum	m_target;
84 };
85 
86 /** Represents framebuffer
87  * Provides basic functionality
88  **/
89 class Framebuffer
90 {
91 public:
92 	/* Public methods */
93 	/* Ctr & Dtr */
94 	Framebuffer(const glw::Functions& gl);
95 	~Framebuffer();
96 
97 	/* Init & Release */
98 	void Release();
99 
100 	/* Public static routines */
101 	static void AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment,
102 							  glw::GLuint texture_id, glw::GLint level, glw::GLuint width, glw::GLuint height);
103 
104 	static void Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id);
105 	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
106 
107 	/* Public fields */
108 	glw::GLuint m_id;
109 
110 	/* Public constants */
111 	static const glw::GLuint m_invalid_id;
112 
113 private:
114 	/* Private fields */
115 	const glw::Functions& m_gl;
116 };
117 
118 /** Represents shader instance.
119  * Provides basic functionality for shaders.
120  **/
121 class Shader
122 {
123 public:
124 	/* Public methods */
125 	/* Ctr & Dtr */
126 	Shader(const glw::Functions& gl);
127 	~Shader();
128 
129 	/* Init & Realese */
130 	void Init(glw::GLenum stage, const std::string& source);
131 	void Release();
132 
133 	/* Public static routines */
134 	/* Functionality */
135 	static void Compile(const glw::Functions& gl, glw::GLuint id);
136 	static void Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id);
137 	static void Source(const glw::Functions& gl, glw::GLuint id, const std::string& source);
138 
139 	/* Public fields */
140 	glw::GLuint m_id;
141 
142 	/* Public constants */
143 	static const glw::GLuint m_invalid_id;
144 
145 private:
146 	/* Private fields */
147 	const glw::Functions& m_gl;
148 };
149 
150 /** Represents program instance.
151  * Provides basic functionality
152  **/
153 class Program
154 {
155 public:
156 	/* Public methods */
157 	/* Ctr & Dtr */
158 	Program(const glw::Functions& gl);
159 	~Program();
160 
161 	/* Init & Release */
162 	void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader,
163 			  const std::string& tesselation_control_shader, const std::string& tesselation_evaluation_shader,
164 			  const std::string& vertex_shader);
165 
166 	void Release();
167 
168 	/* Functionality */
169 	void Use() const;
170 
171 	/* Public static routines */
172 	/* Functionality */
173 	static void Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id);
174 	static void Create(const glw::Functions& gl, glw::GLuint& out_id);
175 	static void Link(const glw::Functions& gl, glw::GLuint id);
176 	static void Use(const glw::Functions& gl, glw::GLuint id);
177 
178 	/* Public fields */
179 	glw::GLuint m_id;
180 
181 	Shader m_compute;
182 	Shader m_fragment;
183 	Shader m_geometry;
184 	Shader m_tess_ctrl;
185 	Shader m_tess_eval;
186 	Shader m_vertex;
187 
188 	/* Public constants */
189 	static const glw::GLuint m_invalid_id;
190 
191 private:
192 	/* Private fields */
193 	const glw::Functions& m_gl;
194 };
195 
196 /** Represents texture instance
197  **/
198 class Texture
199 {
200 public:
201 	/* Public methods */
202 	/* Ctr & Dtr */
203 	Texture(const glw::Functions& gl);
204 	~Texture();
205 
206 	/* Init & Release */
207 	void Release();
208 
209 	/* Public static routines */
210 	/* Functionality */
211 	static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target);
212 
213 	static void CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level,
214 								glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth,
215 								glw::GLsizei image_size, const glw::GLvoid* data);
216 
217 	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
218 
219 	static void GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format,
220 						glw::GLenum type, glw::GLvoid* out_data);
221 
222 	static void GetData(const glw::Functions& gl, glw::GLuint id, glw::GLint level, glw::GLuint width,
223 						glw::GLuint height, glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data);
224 
225 	static void GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname,
226 								  glw::GLint* param);
227 
228 	static void Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format,
229 					  glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type,
230 					  const glw::GLvoid* data);
231 
232 	static void Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format,
233 						glw::GLuint width, glw::GLuint height, glw::GLuint depth);
234 
235 	static void SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y,
236 						 glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format,
237 						 glw::GLenum type, const glw::GLvoid* pixels);
238 
239 	/* Public fields */
240 	glw::GLuint m_id;
241 
242 	/* Public constants */
243 	static const glw::GLuint m_invalid_id;
244 
245 private:
246 	/* Private fields */
247 	const glw::Functions& m_gl;
248 };
249 
250 /** Represents Vertex array object
251  * Provides basic functionality
252  **/
253 class VertexArray
254 {
255 public:
256 	/* Public methods */
257 	/* Ctr & Dtr */
258 	VertexArray(const glw::Functions& gl);
259 	~VertexArray();
260 
261 	/* Init & Release */
262 	void Release();
263 
264 	/* Public static methods */
265 	static void Bind(const glw::Functions& gl, glw::GLuint id);
266 	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
267 
268 	/* Public fields */
269 	glw::GLuint m_id;
270 
271 	/* Public constants */
272 	static const glw::GLuint m_invalid_id;
273 
274 private:
275 	/* Private fields */
276 	const glw::Functions& m_gl;
277 };
278 
279 class RobustnessBase : public tcu::TestCase
280 {
281 public:
282 	RobustnessBase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType);
283 
284 	glu::RenderContext* createRobustContext(
285 		glu::ResetNotificationStrategy reset = glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION);
286 
287 protected:
288 	glu::ApiType m_api_type;
289 	bool		 m_context_is_es;
290 	bool		 m_has_khr_robust_buffer_access;
291 
292 	std::map<std::string, std::string> m_specializationMap;
293 };
294 
295 /** Implementation of test VertexBufferObjects. Description follows:
296  *
297  * This test verifies that any "out-of-bound" read from vertex buffer result with abnormal program exit
298  *
299  * Steps:
300  * - prepare vertex buffer with the following vertices:
301  *   * 0 - [ 0,  0, 0],
302  *   * 1 - [-1,  0, 0],
303  *   * 2 - [-1,  1, 0],
304  *   * 3 - [ 0,  1, 0],
305  *   * 4 - [ 1,  1, 0],
306  *   * 5 - [ 1,  0, 0],
307  *   * 6 - [ 1, -1, 0],
308  *   * 7 - [ 0, -1, 0],
309  *   * 8 - [-1, -1, 0];
310  * - prepare element buffer:
311  *   * valid:
312  *     0, 1, 2,
313  *     0, 2, 3,
314  *     0, 3, 4,
315  *     0, 4, 5,
316  *     0, 5, 6,
317  *     0, 6, 7,
318  *     0, 7, 8,
319  *     0, 8, 1;
320  *   * invalid:
321  *      9, 1, 2,
322  *     10, 2, 3,
323  *     11, 3, 4,
324  *     12, 4, 5,
325  *     13, 5, 6,
326  *     14, 6, 7,
327  *     15, 7, 8,
328  *     16, 8, 1;
329  * - prepare program consisting of vertex and fragment shader that will output
330  * value 1;
331  * - prepare framebuffer with R8UI texture attached as color 0, filled with
332  * value 128;
333  * - execute draw call with invalid element buffer;
334  * - inspect contents of framebuffer, it is expected that it is filled with
335  * value 1;
336  * - clean framebuffer to value 128;
337  * - execute draw call with valid element buffer;
338  * - inspect contents of framebuffer, it is expected that it is filled with
339  * value 1.
340  **/
341 class VertexBufferObjectsTest : public RobustnessBase
342 {
343 public:
344 	/* Public methods */
345 	VertexBufferObjectsTest(tcu::TestContext& testCtx, glu::ApiType apiType);
~VertexBufferObjectsTest()346 	virtual ~VertexBufferObjectsTest()
347 	{
348 	}
349 
350 	/* Public methods inherited from TestCase */
351 	virtual tcu::TestNode::IterateResult iterate(void);
352 
353 protected:
354 	/* Protected methods */
355 	std::string getFragmentShader();
356 	std::string getVertexShader();
357 	void cleanTexture(const glw::Functions& gl, glw::GLuint texture_id);
358 	bool verifyInvalidResults(const glw::Functions& gl, glw::GLuint texture_id);
359 	bool verifyValidResults(const glw::Functions& gl, glw::GLuint texture_id);
360 	bool verifyResults(const glw::Functions& gl, glw::GLuint texture_id);
361 };
362 
363 /** Implementation of test TexelFetch. Description follows:
364  *
365  * This test verifies that any "out-of-bound" fetch from texture result in
366  * "zero".
367  *
368  * Steps:
369  * - prepare program consisting of vertex, geometry and fragment shader that
370  * will output full-screen quad; Each fragment should receive value of
371  * corresponding texel from source texture; Use texelFetch function;
372  * - prepare 16x16 2D R8UI source texture filled with unique values;
373  * - prepare framebuffer with 16x16 R8UI texture as color attachment, filled
374  * with value 0;
375  * - execute draw call;
376  * - inspect contents of framebuffer, it is expected to match source texture;
377  * - modify program so it will fetch invalid texels;
378  * - execute draw call;
379  * - inspect contents of framebuffer, it is expected that it will be filled
380  * with value 0 for RGB channels and with 0, 1 or the biggest representable
381  * integral number for alpha channel.
382  *
383  * Repeat steps for:
384  * - R8 texture;
385  * - RG8_SNORM texture;
386  * - RGBA32F texture;
387  * - mipmap at level 1;
388  * - a texture with 4 samples.
389  **/
390 class TexelFetchTest : public RobustnessBase
391 {
392 public:
393 	/* Public methods */
394 	TexelFetchTest(tcu::TestContext& testCtx, glu::ApiType apiType);
395 	TexelFetchTest(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType);
~TexelFetchTest()396 	virtual ~TexelFetchTest()
397 	{
398 	}
399 
400 	/* Public methods inherited from TestCase */
401 	virtual tcu::TestNode::IterateResult iterate(void);
402 
403 protected:
404 	/* Protected enums */
405 	enum TEST_CASES
406 	{
407 		R8,
408 		RG8_SNORM,
409 		R32UI_MULTISAMPLE,
410 		RGBA32F,
411 		R32UI_MIPMAP,
412 		/* */
413 		LAST
414 	};
415 
416 	enum VERSION
417 	{
418 		VALID,
419 		SOURCE_INVALID,
420 		DESTINATION_INVALID,
421 	};
422 
423 	/* Protected methods */
424 	const glw::GLchar* getTestCaseName() const;
425 	void prepareTexture(const glw::Functions& gl, bool is_source, glw::GLuint texture_id);
426 
427 	/* Protected fields */
428 	TEST_CASES m_test_case;
429 
430 protected:
431 	/* Protected methods */
432 	std::string getFragmentShader(const glu::ContextType& contextType, bool is_case_valid,
433 								  glw::GLuint fetch_offset = 0);
434 	std::string  getGeometryShader();
435 	std::string  getVertexShader();
436 	virtual bool verifyInvalidResults(const glw::Functions& gl, glw::GLuint texture_id);
437 	virtual bool verifyValidResults(const glw::Functions& gl, glw::GLuint texture_id);
438 };
439 
440 /** Implementation of test ImageLoadStore. Description follows:
441  *
442  * This test verifies that any "out-of-bound" access to image result in "zero"
443  * or is discarded.
444  *
445  * Modify TexelFetch test in the following aspects:
446  * - use compute shader instead of "draw" pipeline;
447  * - use imageLoad instead of texelFetch;
448  * - use destination image instead of framebuffer; Store texel with imageStore;
449  * - for each case from TexelFetch verify:
450  *   * valid coordinates for source and destination images;
451  *   * invalid coordinates for destination and valid ones for source image;
452  *   * valid coordinates for destination and invalid ones for source image.
453  **/
454 class ImageLoadStoreTest : public TexelFetchTest
455 {
456 public:
457 	/* Public methods */
458 	ImageLoadStoreTest(tcu::TestContext& testCtx, glu::ApiType apiType);
~ImageLoadStoreTest()459 	virtual ~ImageLoadStoreTest()
460 	{
461 	}
462 
463 	/* Public methods inherited from TestCase */
464 	virtual tcu::TestNode::IterateResult iterate(void);
465 
466 protected:
467 	/* Protected methods */
468 	std::string getComputeShader(VERSION version, glw::GLuint coord_offset = 0, glw::GLuint sample_offset = 0);
469 	void setTextures(const glw::Functions& gl, glw::GLuint id_destination, glw::GLuint id_source);
470 	bool verifyInvalidResults(const glw::Functions& gl, glw::GLuint texture_id);
471 	bool verifyValidResults(const glw::Functions& gl, glw::GLuint texture_id);
472 };
473 
474 /** Implementation of test StorageBuffer. Description follows:
475  *
476  * This test verifies that any "out-of-bound" access to buffer result in zero
477  * or is discarded.
478  *
479  * Steps:
480  * - prepare compute shader based on the following code snippet:
481  *
482  *     uint dst_index         = gl_LocalInvocationID.x;
483  *     uint src_index         = gl_LocalInvocationID.x;
484  *     destination[dst_index] = source[src_index];
485  *
486  * where source and destination are storage buffers, defined as unsized arrays
487  * of floats;
488  * - prepare two buffers of 4 floats:
489  *   * destination filled with value 1;
490  *   * source filled with unique values;
491  * - dispatch program to copy all 4 values;
492  * - inspect program to verify that contents of source buffer were copied to
493  * destination;
494  * - repeat steps for the following cases:
495  *   * value of dst_index is equal to gl_LocalInvocationID.x + 16; It is
496  *   expected that destination buffer will not be modified;
497  *   * value of src_index is equal to gl_LocalInvocationID.x + 16; It is
498  *   expected that destination buffer will be filled with value 0.
499  **/
500 class StorageBufferTest : public RobustnessBase
501 {
502 public:
503 	/* Public methods */
504 	StorageBufferTest(tcu::TestContext& testCtx, glu::ApiType apiType);
~StorageBufferTest()505 	virtual ~StorageBufferTest()
506 	{
507 	}
508 
509 	/* Public methods inherited from TestCase */
510 	virtual tcu::TestNode::IterateResult iterate(void);
511 
512 protected:
513 	/* Protected enums */
514 	enum VERSION
515 	{
516 		VALID,
517 		SOURCE_INVALID,
518 		DESTINATION_INVALID,
519 		/* */
520 		LAST
521 	};
522 
523 	/* Private methods */
524 	std::string getComputeShader(glw::GLuint offset);
525 	bool verifyResults(glw::GLfloat* buffer_data);
526 
527 	/* Protected fields */
528 	VERSION m_test_case;
529 
530 	/* Protected constants */
531 	static const glw::GLfloat m_destination_data[4];
532 	static const glw::GLfloat m_source_data[4];
533 };
534 
535 /** Implementation of test UniformBuffer. Description follows:
536  *
537  * This test verifies that any "out-of-bound" read from uniform buffer result
538  * in zero;
539  *
540  * Modify StorageBuffer test in the following aspects:
541  * - use uniform buffer for source instead of storage buffer;
542  * - ignore the case with invalid value of dst_index.
543  **/
544 class UniformBufferTest : public RobustnessBase
545 {
546 public:
547 	/* Public methods */
548 	UniformBufferTest(tcu::TestContext& testCtx, glu::ApiType apiType);
~UniformBufferTest()549 	virtual ~UniformBufferTest()
550 	{
551 	}
552 
553 	/* Public methods inherited from TestCase */
554 	virtual tcu::TestNode::IterateResult iterate(void);
555 
556 protected:
557 	/* Protected enums */
558 	enum VERSION
559 	{
560 		VALID,
561 		SOURCE_INVALID,
562 		/* */
563 		LAST
564 	};
565 
566 	/* Protected methods */
567 	std::string getComputeShader(glw::GLuint offset);
568 	bool verifyResults(glw::GLfloat* buffer_data);
569 
570 	/* Protected fields */
571 	VERSION m_test_case;
572 };
573 } /* RobustBufferAccessBehavior */
574 
575 /** Group class for multi bind conformance tests */
576 class RobustBufferAccessBehaviorTests : public tcu::TestCaseGroup
577 {
578 public:
579 	/* Public methods */
580 	RobustBufferAccessBehaviorTests(tcu::TestContext& testCtx, glu::ApiType apiType);
~RobustBufferAccessBehaviorTests(void)581 	virtual ~RobustBufferAccessBehaviorTests(void)
582 	{
583 	}
584 
585 	virtual void init(void);
586 
587 private:
588 	/* Private methods */
589 	RobustBufferAccessBehaviorTests(const RobustBufferAccessBehaviorTests& other);
590 	RobustBufferAccessBehaviorTests& operator=(const RobustBufferAccessBehaviorTests& other);
591 
592 	glu::ApiType m_ApiType;
593 };
594 
595 } /* glcts */
596 
597 #endif // _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP
598