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