1 #ifndef _ESEXTCTEXTUREBUFFERTEXTUREBUFFERRANGE_HPP
2 #define _ESEXTCTEXTUREBUFFERTEXTUREBUFFERRANGE_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2014-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
23  * \brief
24  */ /*-------------------------------------------------------------------*/
25 
26 /*!
27  * \file  esextcTextureBufferTextureBufferRange.hpp
28  * \brief Texture Buffer Range Test (Test 3)
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "../esextcTestCaseBase.hpp"
32 #include "glwEnums.hpp"
33 #include <map>
34 
35 namespace glcts
36 {
37 
38 /**  Implementation of (Test 3) from CTS_EXT_texture_buffer. Description follows
39  *
40  *   Test whether using the function TexBufferRangeEXT sub-ranges of
41  *   the buffer's object data store can be correctly attached to
42  *   texture buffers. The test should take into account that the offset value
43  *   should be an integer multiple of TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT value.
44  *
45  *   Category: API, Functional Test.
46  *
47  *   The test should create a texture object and bind it to TEXTURE_BUFFER_EXT
48  *   texture target at texture unit 0.
49  *
50  *   It should create a buffer object and bind it to TEXTURE_BUFFER_EXT target.
51  *
52  *   It should then query for the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT
53  *   using GetIntegerv function.
54  *
55  *   The test should allocate a memory block of the size equal to the sum of
56  *   aligned texel sizes calculated for each format supported by texture buffer
57  *   listed in table texbo.1
58  *
59  *   Texel size for each format supported by texture buffer should be aligned
60  *   taking into consideration the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT.
61  *
62  *   The memory block should then be filled with values up to its size.
63  *
64  *   Use glBufferData to initialize a buffer object's data store.
65  *   glBufferData should be given a pointer to allocated memory that will be
66  *   copied into the data store for initialization.
67  *
68  *   The test should iterate over all formats supported by texture buffer and
69  *   use the buffer object as texture buffer's data store by calling
70  *
71  *   TexBufferRangeEXT(TEXTURE_BUFFER_EXT, format_name, buffer_id, offset,
72  *       not_aligned_texel_size_for_format );
73  *
74  *   offset += aligned_texel_size_for_format;
75  *
76  *   Write a vertex shader that defines texture sampler of the type compatible
77  *   with used format. Bind the sampler location to texture unit 0.
78  *
79  *   The vertex shader should also define an output variable outValue of the type
80  *   compatible with used format and int outTextureSize output variable.
81  *   Configure transform feedback to capture the value of outValue and
82  *   outTextureSize.
83  *
84  *   In the shader execute:
85  *
86  *   outValue        = texelFetch( sampler_buffer, 0 );
87  *   outTextureSize  = textureSize( sampler_buffer );
88  *
89  *   Create a program from the above vertex shader and a boilerplate fragment
90  *   shader and use it.
91  *
92  *   Execute a draw call and copy captured outValue and outTextureSize from the
93  *   buffer objects bound to transform feedback binding points to client's
94  *   address space.
95  *
96  *   This phase of the test is successful if for each format supported by texture
97  *   buffer outValue is equal to the value stored originally in the
98  *   buffer object that is being used as texture buffer's data store and
99  *   the value of outTextureSize is equal to 1.
100  *
101  *   Write a compute shader that defines image sampler of the type compatible
102  *   with used format. Bind the texture buffer to image unit 0.
103  *
104  *   Work group size should be equal to 1 x 1 x 1.
105  *
106  *   The shader should also define shader storage buffer objects
107  *
108  *   layout(binding = 0) buffer ComputeSSBOSize
109  *   {
110  *       int outImageSize;
111  *   } computeSSBOSize;
112  *
113  *   layout(binding = 1) buffer ComputeSSBOValue
114  *   {
115  *       compatible_type outValue;
116  *   } computeSSBOValue;
117 
118  *   Initialize two buffer objects to be assigned as ssbos' data stores.
119  *
120  *   In the compute shader execute:
121  *
122  *   computeSSBOSize.outImageSize   = imageSize( image_buffer );
123  *   computeSSBOValue.outValue      = imageLoad( image_buffer, 0 );
124  *
125  *   Call:
126  *
127  *   glDispatchCompute(1, 1, 1);
128  *   glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
129  *
130  *   Map the ssbos' buffer objects' data stores to client's address space and
131  *   fetch the values of outImageSize and outValue.
132  *
133  *   This phase of the test is successful if for each format supported by texture
134  *   buffer outValue is equal to the value stored originally in the
135  *   buffer object that is being used as texture buffer's data store and
136  *   the value of outImageSize is equal to 1.
137  */
138 
139 /* Helper class containing test configuration for specific internal format */
140 class FormatInfo
141 {
142 public:
143 	/* Public methods */
144 	FormatInfo();
145 	FormatInfo(glw::GLenum internalFormat, glw::GLuint offsetAlignment);
146 
get_aligned_size()147 	glw::GLuint get_aligned_size()
148 	{
149 		return m_aligned_size;
150 	}
get_not_aligned_size()151 	glw::GLuint get_not_aligned_size()
152 	{
153 		return m_not_aligned_size;
154 	}
get_ssbo_value_size()155 	glw::GLuint get_ssbo_value_size()
156 	{
157 		return m_ssbo_value_size;
158 	}
get_internal_format()159 	glw::GLenum get_internal_format()
160 	{
161 		return m_internal_format;
162 	}
get_n_components()163 	glw::GLuint get_n_components()
164 	{
165 		return m_n_components;
166 	}
get_input_type()167 	glw::GLenum get_input_type()
168 	{
169 		return m_input_type;
170 	}
get_output_type()171 	glw::GLenum get_output_type()
172 	{
173 		return m_output_type;
174 	}
get_is_image_supported()175 	glw::GLboolean get_is_image_supported()
176 	{
177 		return m_is_image_supported;
178 	}
get_image_format_name()179 	std::string get_image_format_name()
180 	{
181 		return m_image_format_name;
182 	}
get_image_type_name()183 	std::string get_image_type_name()
184 	{
185 		return m_image_type_name;
186 	}
get_sampler_type_name()187 	std::string get_sampler_type_name()
188 	{
189 		return m_sampler_type_name;
190 	}
get_output_type_name()191 	std::string get_output_type_name()
192 	{
193 		return m_output_type_name;
194 	}
get_value_selector()195 	std::string get_value_selector()
196 	{
197 		return m_value_selector;
198 	}
199 
200 private:
201 	/* Private methods */
202 	glw::GLuint countAlignedSize(glw::GLuint offsetAlignment, glw::GLuint totalSize);
203 	void configure(void);
204 
205 	/* Private Variables */
206 	glw::GLuint	m_aligned_size;
207 	glw::GLuint	m_not_aligned_size;
208 	glw::GLuint	m_ssbo_value_size;
209 	glw::GLenum	m_internal_format;
210 	glw::GLuint	m_offset_alignment;
211 	glw::GLuint	m_n_components;
212 	glw::GLenum	m_input_type;
213 	glw::GLenum	m_output_type;
214 	glw::GLboolean m_is_image_supported;
215 	std::string	m_image_format_name;
216 	std::string	m_image_type_name;
217 	std::string	m_sampler_type_name;
218 	std::string	m_output_type_name;
219 	std::string	m_value_selector;
220 };
221 
222 /* Test Case Class */
223 class TextureBufferTextureBufferRange : public TestCaseBase
224 {
225 public:
226 	/* Public methods */
227 	TextureBufferTextureBufferRange(Context& context, const ExtParameters& extParams, const char* name,
228 									const char* description);
229 
~TextureBufferTextureBufferRange()230 	virtual ~TextureBufferTextureBufferRange()
231 	{
232 	}
233 
234 	virtual void		  deinit(void);
235 	virtual IterateResult iterate(void);
236 
237 private:
238 	/* Private methods */
239 	virtual void initTest(void);
240 	std::string getComputeShaderCode(FormatInfo& info) const;
241 	std::string getFragmentShaderCode(FormatInfo& info) const;
242 	std::string getVertexShaderCode(FormatInfo& info) const;
243 
244 	void fillInputData(glw::GLubyte* buffer, glw::GLuint offset, FormatInfo& info);
245 	void fillOutputData(glw::GLubyte* buffer, FormatInfo& info);
246 	void cleanIteration();
247 
248 	bool checkResult(FormatInfo& info, const char* phase, bool transformFeedback);
249 	void logError(const char* phase, const char* internalFormat, glw::GLuint component, const char* exptectedValue,
250 				  const char* resultValue);
251 
252 	/* Variables for general usage */
253 	glw::GLuint m_cs_id;
254 	glw::GLuint m_cs_po_id;
255 	glw::GLuint m_ssbo_size_id;
256 	glw::GLuint m_ssbo_value_id;
257 	glw::GLuint m_tbo_id;
258 	glw::GLuint m_tbo_tex_id;
259 	glw::GLint  m_texture_buffer_offset_alignment;
260 	glw::GLuint m_vao_id;
261 
262 	glw::GLuint m_vs_id;
263 	glw::GLuint m_fs_id;
264 	glw::GLuint m_vsfs_po_id;
265 	glw::GLuint m_tf_size_buffer_id;
266 	glw::GLuint m_tf_value_buffer_id;
267 
268 	std::map<glw::GLenum, FormatInfo> m_configurations;
269 	glw::GLuint m_buffer_total_size;
270 };
271 
272 } // namespace glcts
273 
274 #endif // _ESEXTCTEXTUREBUFFERTEXTUREBUFFERRANGE_HPP
275