xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl3cCullDistanceTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * OpenGL Conformance Test Suite
3*35238bceSAndroid Build Coastguard Worker  * -----------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright (c) 2015-2016 The Khronos Group Inc.
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  */ /*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief
22*35238bceSAndroid Build Coastguard Worker  */ /*-------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker /**
25*35238bceSAndroid Build Coastguard Worker  */ /*!
26*35238bceSAndroid Build Coastguard Worker  * \file  gl3cCullDistanceTests.cpp
27*35238bceSAndroid Build Coastguard Worker  * \brief Cull Distance Test Suite Implementation
28*35238bceSAndroid Build Coastguard Worker  */ /*-------------------------------------------------------------------*/
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker #include "gl3cCullDistanceTests.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluDefs.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker #include <cmath>
40*35238bceSAndroid Build Coastguard Worker #include <sstream>
41*35238bceSAndroid Build Coastguard Worker #include <string>
42*35238bceSAndroid Build Coastguard Worker #include <vector>
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker #ifndef GL_MAX_CULL_DISTANCES
45*35238bceSAndroid Build Coastguard Worker #define GL_MAX_CULL_DISTANCES (0x82F9)
46*35238bceSAndroid Build Coastguard Worker #endif
47*35238bceSAndroid Build Coastguard Worker #ifndef GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES
48*35238bceSAndroid Build Coastguard Worker #define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES (0x82FA)
49*35238bceSAndroid Build Coastguard Worker #endif
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker namespace glcts
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker /** @brief Build OpenGL program
54*35238bceSAndroid Build Coastguard Worker  *
55*35238bceSAndroid Build Coastguard Worker  *  @param [in]  gl             OpenGL function bindings
56*35238bceSAndroid Build Coastguard Worker  *  @param [in]  testCtx        Context
57*35238bceSAndroid Build Coastguard Worker  *  @param [in]  cs_body        Compute shader source code
58*35238bceSAndroid Build Coastguard Worker  *  @param [in]  fs_body        Fragment shader source code
59*35238bceSAndroid Build Coastguard Worker  *  @param [in]  gs_body        Geometric shader source code
60*35238bceSAndroid Build Coastguard Worker  *  @param [in]  tc_body        Tessellation control shader source code
61*35238bceSAndroid Build Coastguard Worker  *  @param [in]  te_body        Tessellation evaluation shader source code
62*35238bceSAndroid Build Coastguard Worker  *  @param [in]  vs_body        Vertex shader source code
63*35238bceSAndroid Build Coastguard Worker  *  @param [in]  n_tf_varyings  Number of transform feedback varyings
64*35238bceSAndroid Build Coastguard Worker  *  @param [in]  tf_varyings    Transform feedback varyings names
65*35238bceSAndroid Build Coastguard Worker  *
66*35238bceSAndroid Build Coastguard Worker  *  @param [out] out_program    If succeeded output program GL handle, 0 otherwise.
67*35238bceSAndroid Build Coastguard Worker  */
buildProgram(const glw::Functions & gl,tcu::TestContext & testCtx,const glw::GLchar * cs_body,const glw::GLchar * fs_body,const glw::GLchar * gs_body,const glw::GLchar * tc_body,const glw::GLchar * te_body,const glw::GLchar * vs_body,const glw::GLuint & n_tf_varyings,const glw::GLchar ** tf_varyings,glw::GLuint * out_program)68*35238bceSAndroid Build Coastguard Worker void CullDistance::Utilities::buildProgram(const glw::Functions &gl, tcu::TestContext &testCtx,
69*35238bceSAndroid Build Coastguard Worker                                            const glw::GLchar *cs_body, const glw::GLchar *fs_body,
70*35238bceSAndroid Build Coastguard Worker                                            const glw::GLchar *gs_body, const glw::GLchar *tc_body,
71*35238bceSAndroid Build Coastguard Worker                                            const glw::GLchar *te_body, const glw::GLchar *vs_body,
72*35238bceSAndroid Build Coastguard Worker                                            const glw::GLuint &n_tf_varyings, const glw::GLchar **tf_varyings,
73*35238bceSAndroid Build Coastguard Worker                                            glw::GLuint *out_program)
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker     glw::GLuint po_id = 0;
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker     struct _shaders_configuration
78*35238bceSAndroid Build Coastguard Worker     {
79*35238bceSAndroid Build Coastguard Worker         glw::GLenum type;
80*35238bceSAndroid Build Coastguard Worker         const glw::GLchar *body;
81*35238bceSAndroid Build Coastguard Worker         glw::GLuint id;
82*35238bceSAndroid Build Coastguard Worker     } shaders_configuration[] = {{GL_COMPUTE_SHADER, cs_body, 0},         {GL_FRAGMENT_SHADER, fs_body, 0},
83*35238bceSAndroid Build Coastguard Worker                                  {GL_GEOMETRY_SHADER, gs_body, 0},        {GL_TESS_CONTROL_SHADER, tc_body, 0},
84*35238bceSAndroid Build Coastguard Worker                                  {GL_TESS_EVALUATION_SHADER, te_body, 0}, {GL_VERTEX_SHADER, vs_body, 0}};
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_shaders_configuration = sizeof(shaders_configuration) / sizeof(shaders_configuration[0]);
87*35238bceSAndroid Build Coastguard Worker 
88*35238bceSAndroid Build Coastguard Worker     /* Guard allocated OpenGL resources */
89*35238bceSAndroid Build Coastguard Worker     try
90*35238bceSAndroid Build Coastguard Worker     {
91*35238bceSAndroid Build Coastguard Worker         /* Create needed programs */
92*35238bceSAndroid Build Coastguard Worker         po_id = gl.createProgram();
93*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
94*35238bceSAndroid Build Coastguard Worker 
95*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint n_shader_index = 0; n_shader_index < n_shaders_configuration; n_shader_index++)
96*35238bceSAndroid Build Coastguard Worker         {
97*35238bceSAndroid Build Coastguard Worker             if (shaders_configuration[n_shader_index].body != DE_NULL)
98*35238bceSAndroid Build Coastguard Worker             {
99*35238bceSAndroid Build Coastguard Worker                 /* Generate shader object */
100*35238bceSAndroid Build Coastguard Worker                 shaders_configuration[n_shader_index].id = gl.createShader(shaders_configuration[n_shader_index].type);
101*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed");
102*35238bceSAndroid Build Coastguard Worker 
103*35238bceSAndroid Build Coastguard Worker                 glw::GLint compile_status = GL_FALSE;
104*35238bceSAndroid Build Coastguard Worker                 const glw::GLuint so_id   = shaders_configuration[n_shader_index].id;
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker                 /* Assign shader source code */
107*35238bceSAndroid Build Coastguard Worker                 gl.shaderSource(shaders_configuration[n_shader_index].id, 1,           /* count */
108*35238bceSAndroid Build Coastguard Worker                                 &shaders_configuration[n_shader_index].body, DE_NULL); /* length */
109*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
110*35238bceSAndroid Build Coastguard Worker 
111*35238bceSAndroid Build Coastguard Worker                 gl.compileShader(so_id);
112*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker                 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
115*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
116*35238bceSAndroid Build Coastguard Worker 
117*35238bceSAndroid Build Coastguard Worker                 if (compile_status == GL_FALSE)
118*35238bceSAndroid Build Coastguard Worker                 {
119*35238bceSAndroid Build Coastguard Worker                     std::vector<glw::GLchar> log_array(1);
120*35238bceSAndroid Build Coastguard Worker                     glw::GLint log_length = 0;
121*35238bceSAndroid Build Coastguard Worker                     std::string log_string("Failed to retrieve log");
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker                     /* Retrive compilation log length */
124*35238bceSAndroid Build Coastguard Worker                     gl.getShaderiv(so_id, GL_INFO_LOG_LENGTH, &log_length);
125*35238bceSAndroid Build Coastguard Worker                     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker                     log_array.resize(log_length + 1, 0);
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker                     gl.getShaderInfoLog(so_id, log_length, DE_NULL, &log_array[0]);
130*35238bceSAndroid Build Coastguard Worker                     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog() call failed.");
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker                     log_string = std::string(&log_array[0]);
133*35238bceSAndroid Build Coastguard Worker 
134*35238bceSAndroid Build Coastguard Worker                     testCtx.getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
135*35238bceSAndroid Build Coastguard Worker                                      << "Shader type: " << shaders_configuration[n_shader_index].type << "\n"
136*35238bceSAndroid Build Coastguard Worker                                      << "Shader compilation error log:\n"
137*35238bceSAndroid Build Coastguard Worker                                      << log_string << "\n"
138*35238bceSAndroid Build Coastguard Worker                                      << "Shader source code:\n"
139*35238bceSAndroid Build Coastguard Worker                                      << shaders_configuration[n_shader_index].body << "\n"
140*35238bceSAndroid Build Coastguard Worker                                      << tcu::TestLog::EndMessage;
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Shader compilation has failed.");
143*35238bceSAndroid Build Coastguard Worker                 }
144*35238bceSAndroid Build Coastguard Worker 
145*35238bceSAndroid Build Coastguard Worker                 /* Also attach the shader to the corresponding program object */
146*35238bceSAndroid Build Coastguard Worker                 gl.attachShader(po_id, so_id);
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed");
149*35238bceSAndroid Build Coastguard Worker             } /* if (shaders_configuration[n_shader_index].body != DE_NULL) */
150*35238bceSAndroid Build Coastguard Worker         }     /* for (all shader object IDs) */
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker         /* Set transform feedback if requested */
153*35238bceSAndroid Build Coastguard Worker         if (n_tf_varyings > 0)
154*35238bceSAndroid Build Coastguard Worker         {
155*35238bceSAndroid Build Coastguard Worker             gl.transformFeedbackVaryings(po_id, n_tf_varyings, tf_varyings, GL_INTERLEAVED_ATTRIBS);
156*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed");
157*35238bceSAndroid Build Coastguard Worker         }
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker         /* Try to link the program objects */
160*35238bceSAndroid Build Coastguard Worker         if (po_id != 0)
161*35238bceSAndroid Build Coastguard Worker         {
162*35238bceSAndroid Build Coastguard Worker             glw::GLint link_status = GL_FALSE;
163*35238bceSAndroid Build Coastguard Worker 
164*35238bceSAndroid Build Coastguard Worker             gl.linkProgram(po_id);
165*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed");
166*35238bceSAndroid Build Coastguard Worker 
167*35238bceSAndroid Build Coastguard Worker             gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
168*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
169*35238bceSAndroid Build Coastguard Worker 
170*35238bceSAndroid Build Coastguard Worker             if (link_status == GL_FALSE)
171*35238bceSAndroid Build Coastguard Worker             {
172*35238bceSAndroid Build Coastguard Worker                 std::vector<glw::GLchar> log_array(1);
173*35238bceSAndroid Build Coastguard Worker                 glw::GLsizei log_length = 0;
174*35238bceSAndroid Build Coastguard Worker                 std::string log_string;
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker                 /* Retreive compilation log length */
177*35238bceSAndroid Build Coastguard Worker                 gl.getProgramiv(po_id, GL_INFO_LOG_LENGTH, &log_length);
178*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
179*35238bceSAndroid Build Coastguard Worker 
180*35238bceSAndroid Build Coastguard Worker                 log_array.resize(log_length + 1, 0);
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker                 /* Retreive compilation log */
183*35238bceSAndroid Build Coastguard Worker                 gl.getProgramInfoLog(po_id, log_length, DE_NULL, &log_array[0]);
184*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog() call failed.");
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker                 log_string = std::string(&log_array[0]);
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker                 /* Log linking error message */
189*35238bceSAndroid Build Coastguard Worker                 testCtx.getLog() << tcu::TestLog::Message << "Program linking has failed.\n"
190*35238bceSAndroid Build Coastguard Worker                                  << "Linking error log:\n"
191*35238bceSAndroid Build Coastguard Worker                                  << log_string << "\n"
192*35238bceSAndroid Build Coastguard Worker                                  << tcu::TestLog::EndMessage;
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker                 /* Log shader source code of shaders involved */
195*35238bceSAndroid Build Coastguard Worker                 for (glw::GLuint n_shader_index = 0; n_shader_index < n_shaders_configuration; n_shader_index++)
196*35238bceSAndroid Build Coastguard Worker                 {
197*35238bceSAndroid Build Coastguard Worker                     if (shaders_configuration[n_shader_index].body != DE_NULL)
198*35238bceSAndroid Build Coastguard Worker                     {
199*35238bceSAndroid Build Coastguard Worker                         testCtx.getLog() << tcu::TestLog::Message << "Shader source code of type "
200*35238bceSAndroid Build Coastguard Worker                                          << shaders_configuration[n_shader_index].type << " follows:\n"
201*35238bceSAndroid Build Coastguard Worker                                          << shaders_configuration[n_shader_index].body << "\n"
202*35238bceSAndroid Build Coastguard Worker                                          << tcu::TestLog::EndMessage;
203*35238bceSAndroid Build Coastguard Worker                     }
204*35238bceSAndroid Build Coastguard Worker                 }
205*35238bceSAndroid Build Coastguard Worker 
206*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Program linking failed");
207*35238bceSAndroid Build Coastguard Worker             }
208*35238bceSAndroid Build Coastguard Worker         } /* if (po_id != 0) */
209*35238bceSAndroid Build Coastguard Worker 
210*35238bceSAndroid Build Coastguard Worker         /* Delete all shaders we've created */
211*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint n_shader_index = 0; n_shader_index < n_shaders_configuration; n_shader_index++)
212*35238bceSAndroid Build Coastguard Worker         {
213*35238bceSAndroid Build Coastguard Worker             const glw::GLuint so_id = shaders_configuration[n_shader_index].id;
214*35238bceSAndroid Build Coastguard Worker 
215*35238bceSAndroid Build Coastguard Worker             if (so_id != 0)
216*35238bceSAndroid Build Coastguard Worker             {
217*35238bceSAndroid Build Coastguard Worker                 gl.deleteShader(so_id);
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker                 shaders_configuration[n_shader_index].id = 0;
220*35238bceSAndroid Build Coastguard Worker 
221*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
222*35238bceSAndroid Build Coastguard Worker             }
223*35238bceSAndroid Build Coastguard Worker         }
224*35238bceSAndroid Build Coastguard Worker 
225*35238bceSAndroid Build Coastguard Worker         /* Store the result progrtam IDs */
226*35238bceSAndroid Build Coastguard Worker         *out_program = po_id;
227*35238bceSAndroid Build Coastguard Worker     }
228*35238bceSAndroid Build Coastguard Worker     catch (...)
229*35238bceSAndroid Build Coastguard Worker     {
230*35238bceSAndroid Build Coastguard Worker         /* Delete all shaders we've created */
231*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint n_shader_index = 0; n_shader_index < n_shaders_configuration; n_shader_index++)
232*35238bceSAndroid Build Coastguard Worker         {
233*35238bceSAndroid Build Coastguard Worker             const glw::GLuint so_id = shaders_configuration[n_shader_index].id;
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker             if (so_id != 0)
236*35238bceSAndroid Build Coastguard Worker             {
237*35238bceSAndroid Build Coastguard Worker                 gl.deleteShader(so_id);
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker                 shaders_configuration[n_shader_index].id = 0;
240*35238bceSAndroid Build Coastguard Worker             }
241*35238bceSAndroid Build Coastguard Worker         }
242*35238bceSAndroid Build Coastguard Worker 
243*35238bceSAndroid Build Coastguard Worker         /* Delete the program object */
244*35238bceSAndroid Build Coastguard Worker         if (po_id != 0)
245*35238bceSAndroid Build Coastguard Worker         {
246*35238bceSAndroid Build Coastguard Worker             gl.deleteProgram(po_id);
247*35238bceSAndroid Build Coastguard Worker 
248*35238bceSAndroid Build Coastguard Worker             po_id = 0;
249*35238bceSAndroid Build Coastguard Worker         }
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker         /* Rethrow */
252*35238bceSAndroid Build Coastguard Worker         throw;
253*35238bceSAndroid Build Coastguard Worker     }
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker /** @brief Replace all occurences of a substring in a string by a substring
257*35238bceSAndroid Build Coastguard Worker  *
258*35238bceSAndroid Build Coastguard Worker  *  @param [in,out] str    string to be edited
259*35238bceSAndroid Build Coastguard Worker  *  @param [in]     from   substring to be replaced
260*35238bceSAndroid Build Coastguard Worker  *  @param [out]    to     new substring
261*35238bceSAndroid Build Coastguard Worker  */
replaceAll(std::string & str,const std::string & from,const std::string & to)262*35238bceSAndroid Build Coastguard Worker void CullDistance::Utilities::replaceAll(std::string &str, const std::string &from, const std::string &to)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker     for (size_t start_pos = str.find(from, 0); start_pos != std::string::npos; start_pos = str.find(from, start_pos))
265*35238bceSAndroid Build Coastguard Worker     {
266*35238bceSAndroid Build Coastguard Worker         str.replace(start_pos, from.length(), to);
267*35238bceSAndroid Build Coastguard Worker 
268*35238bceSAndroid Build Coastguard Worker         start_pos += to.length();
269*35238bceSAndroid Build Coastguard Worker     }
270*35238bceSAndroid Build Coastguard Worker 
271*35238bceSAndroid Build Coastguard Worker     return;
272*35238bceSAndroid Build Coastguard Worker }
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker /** @brief Convert integer to string representation
275*35238bceSAndroid Build Coastguard Worker  *
276*35238bceSAndroid Build Coastguard Worker  *  @param [in] integer     input integer to be converted
277*35238bceSAndroid Build Coastguard Worker  *
278*35238bceSAndroid Build Coastguard Worker  *  @return String representation of integer
279*35238bceSAndroid Build Coastguard Worker  */
intToString(glw::GLint integer)280*35238bceSAndroid Build Coastguard Worker std::string CullDistance::Utilities::intToString(glw::GLint integer)
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker     std::stringstream temp_sstream;
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker     temp_sstream << integer;
285*35238bceSAndroid Build Coastguard Worker 
286*35238bceSAndroid Build Coastguard Worker     return temp_sstream.str();
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker /** Constructor.
290*35238bceSAndroid Build Coastguard Worker  *
291*35238bceSAndroid Build Coastguard Worker  *  @param context Rendering context handle.
292*35238bceSAndroid Build Coastguard Worker  **/
APICoverageTest(deqp::Context & context)293*35238bceSAndroid Build Coastguard Worker CullDistance::APICoverageTest::APICoverageTest(deqp::Context &context)
294*35238bceSAndroid Build Coastguard Worker     : TestCase(context, "coverage", "Cull Distance API Coverage Test")
295*35238bceSAndroid Build Coastguard Worker     , m_bo_id(0)
296*35238bceSAndroid Build Coastguard Worker     , m_cs_id(0)
297*35238bceSAndroid Build Coastguard Worker     , m_cs_to_id(0)
298*35238bceSAndroid Build Coastguard Worker     , m_fbo_draw_id(0)
299*35238bceSAndroid Build Coastguard Worker     , m_fbo_draw_to_id(0)
300*35238bceSAndroid Build Coastguard Worker     , m_fbo_read_id(0)
301*35238bceSAndroid Build Coastguard Worker     , m_fs_id(0)
302*35238bceSAndroid Build Coastguard Worker     , m_gs_id(0)
303*35238bceSAndroid Build Coastguard Worker     , m_po_id(0)
304*35238bceSAndroid Build Coastguard Worker     , m_tc_id(0)
305*35238bceSAndroid Build Coastguard Worker     , m_te_id(0)
306*35238bceSAndroid Build Coastguard Worker     , m_vao_id(0)
307*35238bceSAndroid Build Coastguard Worker     , m_vs_id(0)
308*35238bceSAndroid Build Coastguard Worker {
309*35238bceSAndroid Build Coastguard Worker     /* Left blank on purpose */
310*35238bceSAndroid Build Coastguard Worker }
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker /** @brief Cull Distance API Coverage Test deinitialization */
deinit()313*35238bceSAndroid Build Coastguard Worker void CullDistance::APICoverageTest::deinit()
314*35238bceSAndroid Build Coastguard Worker {
315*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker     if (m_bo_id != 0)
318*35238bceSAndroid Build Coastguard Worker     {
319*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_bo_id);
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker         m_bo_id = 0;
322*35238bceSAndroid Build Coastguard Worker     }
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker     if (m_cs_id != 0)
325*35238bceSAndroid Build Coastguard Worker     {
326*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_cs_id);
327*35238bceSAndroid Build Coastguard Worker 
328*35238bceSAndroid Build Coastguard Worker         m_cs_id = 0;
329*35238bceSAndroid Build Coastguard Worker     }
330*35238bceSAndroid Build Coastguard Worker 
331*35238bceSAndroid Build Coastguard Worker     if (m_cs_to_id != 0)
332*35238bceSAndroid Build Coastguard Worker     {
333*35238bceSAndroid Build Coastguard Worker         gl.deleteTextures(1, &m_cs_to_id);
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker         m_cs_to_id = 0;
336*35238bceSAndroid Build Coastguard Worker     }
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker     if (m_fbo_draw_id != 0)
339*35238bceSAndroid Build Coastguard Worker     {
340*35238bceSAndroid Build Coastguard Worker         gl.deleteFramebuffers(1, &m_fbo_draw_id);
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker         m_fbo_draw_id = 0;
343*35238bceSAndroid Build Coastguard Worker     }
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker     if (m_fbo_draw_to_id != 0)
346*35238bceSAndroid Build Coastguard Worker     {
347*35238bceSAndroid Build Coastguard Worker         gl.deleteTextures(1, &m_fbo_draw_to_id);
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker         m_fbo_draw_to_id = 0;
350*35238bceSAndroid Build Coastguard Worker     }
351*35238bceSAndroid Build Coastguard Worker 
352*35238bceSAndroid Build Coastguard Worker     if (m_fbo_read_id != 0)
353*35238bceSAndroid Build Coastguard Worker     {
354*35238bceSAndroid Build Coastguard Worker         gl.deleteFramebuffers(1, &m_fbo_read_id);
355*35238bceSAndroid Build Coastguard Worker 
356*35238bceSAndroid Build Coastguard Worker         m_fbo_read_id = 0;
357*35238bceSAndroid Build Coastguard Worker     }
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker     if (m_fs_id != 0)
360*35238bceSAndroid Build Coastguard Worker     {
361*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_fs_id);
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker         m_fs_id = 0;
364*35238bceSAndroid Build Coastguard Worker     }
365*35238bceSAndroid Build Coastguard Worker 
366*35238bceSAndroid Build Coastguard Worker     if (m_gs_id != 0)
367*35238bceSAndroid Build Coastguard Worker     {
368*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_gs_id);
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker         m_gs_id = 0;
371*35238bceSAndroid Build Coastguard Worker     }
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker     if (m_po_id != 0)
374*35238bceSAndroid Build Coastguard Worker     {
375*35238bceSAndroid Build Coastguard Worker         gl.deleteProgram(m_po_id);
376*35238bceSAndroid Build Coastguard Worker 
377*35238bceSAndroid Build Coastguard Worker         m_po_id = 0;
378*35238bceSAndroid Build Coastguard Worker     }
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker     if (m_tc_id != 0)
381*35238bceSAndroid Build Coastguard Worker     {
382*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_tc_id);
383*35238bceSAndroid Build Coastguard Worker 
384*35238bceSAndroid Build Coastguard Worker         m_tc_id = 0;
385*35238bceSAndroid Build Coastguard Worker     }
386*35238bceSAndroid Build Coastguard Worker 
387*35238bceSAndroid Build Coastguard Worker     if (m_te_id != 0)
388*35238bceSAndroid Build Coastguard Worker     {
389*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_te_id);
390*35238bceSAndroid Build Coastguard Worker 
391*35238bceSAndroid Build Coastguard Worker         m_te_id = 0;
392*35238bceSAndroid Build Coastguard Worker     }
393*35238bceSAndroid Build Coastguard Worker 
394*35238bceSAndroid Build Coastguard Worker     if (m_vao_id != 0)
395*35238bceSAndroid Build Coastguard Worker     {
396*35238bceSAndroid Build Coastguard Worker         gl.deleteVertexArrays(1, &m_vao_id);
397*35238bceSAndroid Build Coastguard Worker 
398*35238bceSAndroid Build Coastguard Worker         m_vao_id = 0;
399*35238bceSAndroid Build Coastguard Worker     }
400*35238bceSAndroid Build Coastguard Worker 
401*35238bceSAndroid Build Coastguard Worker     if (m_vs_id != 0)
402*35238bceSAndroid Build Coastguard Worker     {
403*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_vs_id);
404*35238bceSAndroid Build Coastguard Worker 
405*35238bceSAndroid Build Coastguard Worker         m_vs_id = 0;
406*35238bceSAndroid Build Coastguard Worker     }
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker     /* Restore default pack alignment value */
409*35238bceSAndroid Build Coastguard Worker     gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
410*35238bceSAndroid Build Coastguard Worker }
411*35238bceSAndroid Build Coastguard Worker 
412*35238bceSAndroid Build Coastguard Worker /** Executes test iteration.
413*35238bceSAndroid Build Coastguard Worker  *
414*35238bceSAndroid Build Coastguard Worker  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
415*35238bceSAndroid Build Coastguard Worker  */
iterate()416*35238bceSAndroid Build Coastguard Worker tcu::TestNode::IterateResult CullDistance::APICoverageTest::iterate()
417*35238bceSAndroid Build Coastguard Worker {
418*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
419*35238bceSAndroid Build Coastguard Worker 
420*35238bceSAndroid Build Coastguard Worker     /* This test should only be executed if ARB_cull_distance is supported, or if
421*35238bceSAndroid Build Coastguard Worker      * we're running a GL4.5 context
422*35238bceSAndroid Build Coastguard Worker      */
423*35238bceSAndroid Build Coastguard Worker     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_cull_distance") &&
424*35238bceSAndroid Build Coastguard Worker         !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
425*35238bceSAndroid Build Coastguard Worker     {
426*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("GL_ARB_cull_distance is not supported");
427*35238bceSAndroid Build Coastguard Worker     }
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker     /* Check that calling GetIntegerv with MAX_CULL_DISTANCES doesn't generate
430*35238bceSAndroid Build Coastguard Worker      * any errors and returns a value at least 8.
431*35238bceSAndroid Build Coastguard Worker      *
432*35238bceSAndroid Build Coastguard Worker      * Check that calling GetIntegerv with MAX_COMBINED_CLIP_AND_CULL_DISTANCES
433*35238bceSAndroid Build Coastguard Worker      * doesn't generate any errors and returns a value at least 8.
434*35238bceSAndroid Build Coastguard Worker      *
435*35238bceSAndroid Build Coastguard Worker      */
436*35238bceSAndroid Build Coastguard Worker     glw::GLint error_code                                    = GL_NO_ERROR;
437*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_cull_distances_value                   = 0;
438*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_combined_clip_and_cull_distances_value = 0;
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_CULL_DISTANCES, &gl_max_cull_distances_value);
441*35238bceSAndroid Build Coastguard Worker 
442*35238bceSAndroid Build Coastguard Worker     error_code = gl.getError();
443*35238bceSAndroid Build Coastguard Worker     if (error_code != GL_NO_ERROR)
444*35238bceSAndroid Build Coastguard Worker     {
445*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv() returned error code "
446*35238bceSAndroid Build Coastguard Worker                            << "[" << glu::getErrorStr(error_code)
447*35238bceSAndroid Build Coastguard Worker                            << "] for GL_MAX_CULL_DISTANCES"
448*35238bceSAndroid Build Coastguard Worker                               " query instead of GL_NO_ERROR"
449*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
450*35238bceSAndroid Build Coastguard Worker 
451*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
452*35238bceSAndroid Build Coastguard Worker 
453*35238bceSAndroid Build Coastguard Worker         return STOP;
454*35238bceSAndroid Build Coastguard Worker     }
455*35238bceSAndroid Build Coastguard Worker 
456*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES, &gl_max_combined_clip_and_cull_distances_value);
457*35238bceSAndroid Build Coastguard Worker 
458*35238bceSAndroid Build Coastguard Worker     error_code = gl.getError();
459*35238bceSAndroid Build Coastguard Worker     if (error_code != GL_NO_ERROR)
460*35238bceSAndroid Build Coastguard Worker     {
461*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv() returned error code "
462*35238bceSAndroid Build Coastguard Worker                            << "[" << glu::getErrorStr(error_code)
463*35238bceSAndroid Build Coastguard Worker                            << "] for "
464*35238bceSAndroid Build Coastguard Worker                               "GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES query "
465*35238bceSAndroid Build Coastguard Worker                               "instead of GL_NO_ERROR"
466*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
467*35238bceSAndroid Build Coastguard Worker 
468*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
469*35238bceSAndroid Build Coastguard Worker 
470*35238bceSAndroid Build Coastguard Worker         return STOP;
471*35238bceSAndroid Build Coastguard Worker     }
472*35238bceSAndroid Build Coastguard Worker 
473*35238bceSAndroid Build Coastguard Worker     /* Before we proceed with the two other tests, initialize a buffer & a texture
474*35238bceSAndroid Build Coastguard Worker      * object we will need to capture data from the programs */
475*35238bceSAndroid Build Coastguard Worker     static const glw::GLuint bo_size = sizeof(int) * 4 /* components */ * 4 /* result points */;
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_bo_id);
478*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker     gl.genFramebuffers(1, &m_fbo_draw_id);
481*35238bceSAndroid Build Coastguard Worker     gl.genFramebuffers(1, &m_fbo_read_id);
482*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call(s) failed.");
483*35238bceSAndroid Build Coastguard Worker 
484*35238bceSAndroid Build Coastguard Worker     gl.genTextures(1, &m_cs_to_id);
485*35238bceSAndroid Build Coastguard Worker     gl.genTextures(1, &m_fbo_draw_to_id);
486*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &m_vao_id);
489*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(m_vao_id);
492*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
493*35238bceSAndroid Build Coastguard Worker 
494*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
495*35238bceSAndroid Build Coastguard Worker     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */
496*35238bceSAndroid Build Coastguard Worker                       m_bo_id);
497*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() or glBindBufferBase() call(s) failed.");
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, GL_STATIC_DRAW);
500*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
501*35238bceSAndroid Build Coastguard Worker 
502*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_to_id = 0; n_to_id < 2; /* CS, FBO */ ++n_to_id)
503*35238bceSAndroid Build Coastguard Worker     {
504*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, (n_to_id == 0) ? m_cs_to_id : m_fbo_draw_to_id);
505*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
506*35238bceSAndroid Build Coastguard Worker 
507*35238bceSAndroid Build Coastguard Worker         gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
508*35238bceSAndroid Build Coastguard Worker                         GL_R32I, 1,       /* width */
509*35238bceSAndroid Build Coastguard Worker                         1);               /* height */
510*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
511*35238bceSAndroid Build Coastguard Worker     }
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker     if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 3)) ||
514*35238bceSAndroid Build Coastguard Worker         m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
515*35238bceSAndroid Build Coastguard Worker     {
516*35238bceSAndroid Build Coastguard Worker         gl.bindImageTexture(0,             /* unit */
517*35238bceSAndroid Build Coastguard Worker                             m_cs_to_id, 0, /* level */
518*35238bceSAndroid Build Coastguard Worker                             GL_FALSE,      /* layered */
519*35238bceSAndroid Build Coastguard Worker                             0,             /* layer */
520*35238bceSAndroid Build Coastguard Worker                             GL_WRITE_ONLY, GL_R32I);
521*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed.");
522*35238bceSAndroid Build Coastguard Worker     }
523*35238bceSAndroid Build Coastguard Worker 
524*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_draw_id);
525*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
526*35238bceSAndroid Build Coastguard Worker 
527*35238bceSAndroid Build Coastguard Worker     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fbo_draw_to_id, 0); /* level */
528*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
529*35238bceSAndroid Build Coastguard Worker 
530*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read_id);
531*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
532*35238bceSAndroid Build Coastguard Worker 
533*35238bceSAndroid Build Coastguard Worker     gl.viewport(0,  /* x */
534*35238bceSAndroid Build Coastguard Worker                 0,  /* y */
535*35238bceSAndroid Build Coastguard Worker                 1,  /* width */
536*35238bceSAndroid Build Coastguard Worker                 1); /* height */
537*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
538*35238bceSAndroid Build Coastguard Worker 
539*35238bceSAndroid Build Coastguard Worker     gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
540*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed.");
541*35238bceSAndroid Build Coastguard Worker 
542*35238bceSAndroid Build Coastguard Worker     /* There are two new GL constants, where value we need to verify */
543*35238bceSAndroid Build Coastguard Worker     struct _run
544*35238bceSAndroid Build Coastguard Worker     {
545*35238bceSAndroid Build Coastguard Worker         const glw::GLchar *essl_token_value;
546*35238bceSAndroid Build Coastguard Worker         glw::GLenum gl_enum;
547*35238bceSAndroid Build Coastguard Worker         glw::GLint gl_value;
548*35238bceSAndroid Build Coastguard Worker         glw::GLint min_value;
549*35238bceSAndroid Build Coastguard Worker         const glw::GLchar *name;
550*35238bceSAndroid Build Coastguard Worker     } runs[] = {{"gl_MaxCullDistances", GL_MAX_CULL_DISTANCES, gl_max_cull_distances_value, 8 /*minimum required */,
551*35238bceSAndroid Build Coastguard Worker                  "GL_MAX_CULL_DISTANCES"},
552*35238bceSAndroid Build Coastguard Worker                 {"gl_MaxCombinedClipAndCullDistances", GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES,
553*35238bceSAndroid Build Coastguard Worker                  gl_max_combined_clip_and_cull_distances_value, 8 /*minimum required */,
554*35238bceSAndroid Build Coastguard Worker                  "GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES"}};
555*35238bceSAndroid Build Coastguard Worker 
556*35238bceSAndroid Build Coastguard Worker     static const glw::GLuint n_runs = sizeof(runs) / sizeof(runs[0]);
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_run = 0; n_run < n_runs; ++n_run)
559*35238bceSAndroid Build Coastguard Worker     {
560*35238bceSAndroid Build Coastguard Worker         _run &current_run = runs[n_run];
561*35238bceSAndroid Build Coastguard Worker 
562*35238bceSAndroid Build Coastguard Worker         static const struct _stage
563*35238bceSAndroid Build Coastguard Worker         {
564*35238bceSAndroid Build Coastguard Worker             bool use_cs;
565*35238bceSAndroid Build Coastguard Worker             bool use_fs;
566*35238bceSAndroid Build Coastguard Worker             bool use_gs;
567*35238bceSAndroid Build Coastguard Worker             bool use_tc;
568*35238bceSAndroid Build Coastguard Worker             bool use_te;
569*35238bceSAndroid Build Coastguard Worker             bool use_vs;
570*35238bceSAndroid Build Coastguard Worker 
571*35238bceSAndroid Build Coastguard Worker             const glw::GLchar *fs_input;
572*35238bceSAndroid Build Coastguard Worker             const glw::GLchar *gs_input;
573*35238bceSAndroid Build Coastguard Worker             const glw::GLchar *tc_input;
574*35238bceSAndroid Build Coastguard Worker             const glw::GLchar *te_input;
575*35238bceSAndroid Build Coastguard Worker 
576*35238bceSAndroid Build Coastguard Worker             const glw::GLchar *tf_output_name;
577*35238bceSAndroid Build Coastguard Worker             const glw::GLenum tf_mode;
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker             glw::GLenum draw_call_mode;
580*35238bceSAndroid Build Coastguard Worker             glw::GLuint n_draw_call_vertices;
581*35238bceSAndroid Build Coastguard Worker         } stages[]                 = {/* CS only test */
582*35238bceSAndroid Build Coastguard Worker                       {
583*35238bceSAndroid Build Coastguard Worker                           /* use_cs|use_fs|use_gs|use_tc|use_te|use_vs */
584*35238bceSAndroid Build Coastguard Worker                           true, false, false, false, false, false,
585*35238bceSAndroid Build Coastguard Worker 
586*35238bceSAndroid Build Coastguard Worker                           NULL,    /* fs_input             */
587*35238bceSAndroid Build Coastguard Worker                           NULL,    /* gs_input             */
588*35238bceSAndroid Build Coastguard Worker                           NULL,    /* tc_input             */
589*35238bceSAndroid Build Coastguard Worker                           NULL,    /* te_input             */
590*35238bceSAndroid Build Coastguard Worker                           NULL,    /* tf_output_name       */
591*35238bceSAndroid Build Coastguard Worker                           GL_NONE, /* tf_mode              */
592*35238bceSAndroid Build Coastguard Worker                           GL_NONE, /* draw_call_mode       */
593*35238bceSAndroid Build Coastguard Worker                           0,       /* n_draw_call_vertices */
594*35238bceSAndroid Build Coastguard Worker                       },
595*35238bceSAndroid Build Coastguard Worker                       /* VS+GS+TC+TE+FS test */
596*35238bceSAndroid Build Coastguard Worker                       {
597*35238bceSAndroid Build Coastguard Worker                           /* use_cs|use_fs|use_gs|use_tc|use_te|use_vs */
598*35238bceSAndroid Build Coastguard Worker                           false, true, true, true, true, true,
599*35238bceSAndroid Build Coastguard Worker 
600*35238bceSAndroid Build Coastguard Worker                           "out_gs",     /* fs_input             */
601*35238bceSAndroid Build Coastguard Worker                           "out_te",     /* gs_input             */
602*35238bceSAndroid Build Coastguard Worker                           "out_vs",     /* tc_input             */
603*35238bceSAndroid Build Coastguard Worker                           "out_tc",     /* te_input             */
604*35238bceSAndroid Build Coastguard Worker                           "out_gs",     /* tf_output_name       */
605*35238bceSAndroid Build Coastguard Worker                           GL_TRIANGLES, /* tf_mode              */
606*35238bceSAndroid Build Coastguard Worker                           GL_PATCHES,   /* draw_call_mode       */
607*35238bceSAndroid Build Coastguard Worker                           3,            /* n_draw_call_vertices */
608*35238bceSAndroid Build Coastguard Worker                       },
609*35238bceSAndroid Build Coastguard Worker                       /* VS+GS+FS test */
610*35238bceSAndroid Build Coastguard Worker                       {
611*35238bceSAndroid Build Coastguard Worker                           /* use_cs|use_fs|use_gs|use_tc|use_te|use_vs */
612*35238bceSAndroid Build Coastguard Worker                           false, true, true, false, false, true,
613*35238bceSAndroid Build Coastguard Worker 
614*35238bceSAndroid Build Coastguard Worker                           "out_gs",     /* fs_input             */
615*35238bceSAndroid Build Coastguard Worker                           "out_vs",     /* gs_input             */
616*35238bceSAndroid Build Coastguard Worker                           NULL,         /* tc_input             */
617*35238bceSAndroid Build Coastguard Worker                           NULL,         /* te_input             */
618*35238bceSAndroid Build Coastguard Worker                           "out_gs",     /* tf_output_name       */
619*35238bceSAndroid Build Coastguard Worker                           GL_TRIANGLES, /* tf_mode              */
620*35238bceSAndroid Build Coastguard Worker                           GL_POINTS,    /* draw_call_mode       */
621*35238bceSAndroid Build Coastguard Worker                           1,            /* n_draw_call_vertices */
622*35238bceSAndroid Build Coastguard Worker                       },
623*35238bceSAndroid Build Coastguard Worker                       /* VS+TC+TE+FS test */
624*35238bceSAndroid Build Coastguard Worker                       {
625*35238bceSAndroid Build Coastguard Worker                           /* use_cs|use_fs|use_gs|use_tc|use_te|use_vs */
626*35238bceSAndroid Build Coastguard Worker                           false, true, false, true, true, true,
627*35238bceSAndroid Build Coastguard Worker 
628*35238bceSAndroid Build Coastguard Worker                           "out_te",   /* fs_input             */
629*35238bceSAndroid Build Coastguard Worker                           NULL,       /* gs_input             */
630*35238bceSAndroid Build Coastguard Worker                           "out_vs",   /* tc_input             */
631*35238bceSAndroid Build Coastguard Worker                           "out_tc",   /* te_input             */
632*35238bceSAndroid Build Coastguard Worker                           "out_te",   /* tf_output_name       */
633*35238bceSAndroid Build Coastguard Worker                           GL_POINTS,  /* tf_mode              */
634*35238bceSAndroid Build Coastguard Worker                           GL_PATCHES, /* draw_call_mode       */
635*35238bceSAndroid Build Coastguard Worker                           3           /* n_draw_call_vertices */
636*35238bceSAndroid Build Coastguard Worker                       },
637*35238bceSAndroid Build Coastguard Worker                       /* VS test */
638*35238bceSAndroid Build Coastguard Worker                       {
639*35238bceSAndroid Build Coastguard Worker                           /* use_cs|use_fs|use_gs|use_tc|use_te|use_vs */
640*35238bceSAndroid Build Coastguard Worker                           false, false, false, false, false, true,
641*35238bceSAndroid Build Coastguard Worker 
642*35238bceSAndroid Build Coastguard Worker                           "out_vs",  /* fs_input             */
643*35238bceSAndroid Build Coastguard Worker                           NULL,      /* gs_input             */
644*35238bceSAndroid Build Coastguard Worker                           NULL,      /* tc_input             */
645*35238bceSAndroid Build Coastguard Worker                           NULL,      /* te_input             */
646*35238bceSAndroid Build Coastguard Worker                           "out_vs",  /* tf_output_name       */
647*35238bceSAndroid Build Coastguard Worker                           GL_POINTS, /* tf_mode              */
648*35238bceSAndroid Build Coastguard Worker                           GL_POINTS, /* draw_call_mode       */
649*35238bceSAndroid Build Coastguard Worker                           1          /* n_draw_call_vertices */
650*35238bceSAndroid Build Coastguard Worker                       }};
651*35238bceSAndroid Build Coastguard Worker                         const glw::GLuint n_stages = sizeof(stages) / sizeof(stages[0]);
652*35238bceSAndroid Build Coastguard Worker 
653*35238bceSAndroid Build Coastguard Worker         /* Run through all test stages */
654*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint n_stage = 0; n_stage < n_stages; ++n_stage)
655*35238bceSAndroid Build Coastguard Worker         {
656*35238bceSAndroid Build Coastguard Worker             /* Check for OpenGL feature support */
657*35238bceSAndroid Build Coastguard Worker             if (stages[n_stage].use_cs)
658*35238bceSAndroid Build Coastguard Worker             {
659*35238bceSAndroid Build Coastguard Worker                 if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 3)) &&
660*35238bceSAndroid Build Coastguard Worker                     !m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
661*35238bceSAndroid Build Coastguard Worker                 {
662*35238bceSAndroid Build Coastguard Worker                     continue; // no compute shader support
663*35238bceSAndroid Build Coastguard Worker                 }
664*35238bceSAndroid Build Coastguard Worker             }
665*35238bceSAndroid Build Coastguard Worker             if (stages[n_stage].use_tc || stages[n_stage].use_te)
666*35238bceSAndroid Build Coastguard Worker             {
667*35238bceSAndroid Build Coastguard Worker                 if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)) &&
668*35238bceSAndroid Build Coastguard Worker                     !m_context.getContextInfo().isExtensionSupported("GL_ARB_tessellation_shader"))
669*35238bceSAndroid Build Coastguard Worker                 {
670*35238bceSAndroid Build Coastguard Worker                     continue; // no tessellation shader support
671*35238bceSAndroid Build Coastguard Worker                 }
672*35238bceSAndroid Build Coastguard Worker             }
673*35238bceSAndroid Build Coastguard Worker 
674*35238bceSAndroid Build Coastguard Worker             /* Check that use of the GLSL built-in constant gl_MaxCullDistance in any
675*35238bceSAndroid Build Coastguard Worker              * shader stage (including compute shader) does not affect the shader
676*35238bceSAndroid Build Coastguard Worker              * compilation & program linking process.
677*35238bceSAndroid Build Coastguard Worker              */
678*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *cs_body_template =
679*35238bceSAndroid Build Coastguard Worker                 "#version 420 core\n"
680*35238bceSAndroid Build Coastguard Worker                 "\n"
681*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_compute_shader          : require\n"
682*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_cull_distance           : require\n"
683*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_shader_image_load_store : require\n"
684*35238bceSAndroid Build Coastguard Worker                 "\n"
685*35238bceSAndroid Build Coastguard Worker                 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
686*35238bceSAndroid Build Coastguard Worker                 "\n"
687*35238bceSAndroid Build Coastguard Worker                 "layout(r32i) uniform writeonly iimage2D result;\n"
688*35238bceSAndroid Build Coastguard Worker                 "\n"
689*35238bceSAndroid Build Coastguard Worker                 "void main()\n"
690*35238bceSAndroid Build Coastguard Worker                 "{\n"
691*35238bceSAndroid Build Coastguard Worker                 "    imageStore(result, ivec2(0),ivec4(TOKEN) );\n"
692*35238bceSAndroid Build Coastguard Worker                 "}\n";
693*35238bceSAndroid Build Coastguard Worker             std::string cs_body = cs_body_template;
694*35238bceSAndroid Build Coastguard Worker 
695*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *fs_body_template = "#version 150\n"
696*35238bceSAndroid Build Coastguard Worker                                                          "\n"
697*35238bceSAndroid Build Coastguard Worker                                                          "#extension GL_ARB_cull_distance : require\n"
698*35238bceSAndroid Build Coastguard Worker                                                          "\n"
699*35238bceSAndroid Build Coastguard Worker                                                          "flat in  int INPUT_FS_NAME;\n"
700*35238bceSAndroid Build Coastguard Worker                                                          "out int out_fs;\n"
701*35238bceSAndroid Build Coastguard Worker                                                          "\n"
702*35238bceSAndroid Build Coastguard Worker                                                          "void main()\n"
703*35238bceSAndroid Build Coastguard Worker                                                          "{\n"
704*35238bceSAndroid Build Coastguard Worker                                                          "    if (INPUT_FS_NAME == TOKEN)\n"
705*35238bceSAndroid Build Coastguard Worker                                                          "    {\n"
706*35238bceSAndroid Build Coastguard Worker                                                          "        out_fs = TOKEN;\n"
707*35238bceSAndroid Build Coastguard Worker                                                          "    }\n"
708*35238bceSAndroid Build Coastguard Worker                                                          "    else\n"
709*35238bceSAndroid Build Coastguard Worker                                                          "    {\n"
710*35238bceSAndroid Build Coastguard Worker                                                          "        out_fs = -1;\n"
711*35238bceSAndroid Build Coastguard Worker                                                          "    }\n"
712*35238bceSAndroid Build Coastguard Worker                                                          "}\n";
713*35238bceSAndroid Build Coastguard Worker             std::string fs_body                        = fs_body_template;
714*35238bceSAndroid Build Coastguard Worker 
715*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *gs_body_template =
716*35238bceSAndroid Build Coastguard Worker                 "#version 150\n"
717*35238bceSAndroid Build Coastguard Worker                 "\n"
718*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_cull_distance : require\n"
719*35238bceSAndroid Build Coastguard Worker                 "\n"
720*35238bceSAndroid Build Coastguard Worker                 "flat in  int INPUT_GS_NAME[];\n"
721*35238bceSAndroid Build Coastguard Worker                 "flat out int out_gs;\n"
722*35238bceSAndroid Build Coastguard Worker                 "\n"
723*35238bceSAndroid Build Coastguard Worker                 "layout(points)                           in;\n"
724*35238bceSAndroid Build Coastguard Worker                 "layout(triangle_strip, max_vertices = 4) out;\n"
725*35238bceSAndroid Build Coastguard Worker                 "\n"
726*35238bceSAndroid Build Coastguard Worker                 "void main()\n"
727*35238bceSAndroid Build Coastguard Worker                 "{\n"
728*35238bceSAndroid Build Coastguard Worker                 "    int result_value = (INPUT_GS_NAME[0] == TOKEN) ? TOKEN : -1;\n"
729*35238bceSAndroid Build Coastguard Worker                 "\n"
730*35238bceSAndroid Build Coastguard Worker                 /* Draw a full-screen quad */
731*35238bceSAndroid Build Coastguard Worker                 "    gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
732*35238bceSAndroid Build Coastguard Worker                 "    out_gs      = result_value;\n"
733*35238bceSAndroid Build Coastguard Worker                 "    EmitVertex();\n"
734*35238bceSAndroid Build Coastguard Worker                 "\n"
735*35238bceSAndroid Build Coastguard Worker                 "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
736*35238bceSAndroid Build Coastguard Worker                 "    out_gs      = result_value;\n"
737*35238bceSAndroid Build Coastguard Worker                 "    EmitVertex();\n"
738*35238bceSAndroid Build Coastguard Worker                 "\n"
739*35238bceSAndroid Build Coastguard Worker                 "    gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\n"
740*35238bceSAndroid Build Coastguard Worker                 "    out_gs      = result_value;\n"
741*35238bceSAndroid Build Coastguard Worker                 "    EmitVertex();\n"
742*35238bceSAndroid Build Coastguard Worker                 "\n"
743*35238bceSAndroid Build Coastguard Worker                 "    gl_Position = vec4(1.0, -1.0, 0.0, 1.0);\n"
744*35238bceSAndroid Build Coastguard Worker                 "    out_gs      = result_value;\n"
745*35238bceSAndroid Build Coastguard Worker                 "    EmitVertex();\n"
746*35238bceSAndroid Build Coastguard Worker                 "    EndPrimitive();\n"
747*35238bceSAndroid Build Coastguard Worker                 "}\n";
748*35238bceSAndroid Build Coastguard Worker             std::string gs_body = gs_body_template;
749*35238bceSAndroid Build Coastguard Worker 
750*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *tc_body_template =
751*35238bceSAndroid Build Coastguard Worker                 "#version 150\n"
752*35238bceSAndroid Build Coastguard Worker                 "\n"
753*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_cull_distance : require\n"
754*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_tessellation_shader : require\n"
755*35238bceSAndroid Build Coastguard Worker                 "\n"
756*35238bceSAndroid Build Coastguard Worker                 "layout(vertices = 1) out;\n"
757*35238bceSAndroid Build Coastguard Worker                 "\n"
758*35238bceSAndroid Build Coastguard Worker                 "flat in  int INPUT_TC_NAME[];\n"
759*35238bceSAndroid Build Coastguard Worker                 "flat out int out_tc       [];\n"
760*35238bceSAndroid Build Coastguard Worker                 "\n"
761*35238bceSAndroid Build Coastguard Worker                 "void main()\n"
762*35238bceSAndroid Build Coastguard Worker                 "{\n"
763*35238bceSAndroid Build Coastguard Worker                 "    int result_value = (INPUT_TC_NAME[0] == TOKEN) ? TOKEN : -1;\n"
764*35238bceSAndroid Build Coastguard Worker                 "\n"
765*35238bceSAndroid Build Coastguard Worker                 "    out_tc[gl_InvocationID]             = result_value;\n"
766*35238bceSAndroid Build Coastguard Worker                 "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
767*35238bceSAndroid Build Coastguard Worker                 "    gl_TessLevelInner[0]                = 1.0;\n"
768*35238bceSAndroid Build Coastguard Worker                 "    gl_TessLevelInner[1]                = 1.0;\n"
769*35238bceSAndroid Build Coastguard Worker                 "    gl_TessLevelOuter[0]                = 1.0;\n"
770*35238bceSAndroid Build Coastguard Worker                 "    gl_TessLevelOuter[1]                = 1.0;\n"
771*35238bceSAndroid Build Coastguard Worker                 "    gl_TessLevelOuter[2]                = 1.0;\n"
772*35238bceSAndroid Build Coastguard Worker                 "    gl_TessLevelOuter[3]                = 1.0;\n"
773*35238bceSAndroid Build Coastguard Worker                 "}\n";
774*35238bceSAndroid Build Coastguard Worker             std::string tc_body = tc_body_template;
775*35238bceSAndroid Build Coastguard Worker 
776*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *te_body_template =
777*35238bceSAndroid Build Coastguard Worker                 "#version 150\n"
778*35238bceSAndroid Build Coastguard Worker                 "\n"
779*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_cull_distance : require\n"
780*35238bceSAndroid Build Coastguard Worker                 "#extension GL_ARB_tessellation_shader : require\n"
781*35238bceSAndroid Build Coastguard Worker                 "\n"
782*35238bceSAndroid Build Coastguard Worker                 "flat in  int INPUT_TE_NAME[];\n"
783*35238bceSAndroid Build Coastguard Worker                 "flat out int out_te;\n"
784*35238bceSAndroid Build Coastguard Worker                 "\n"
785*35238bceSAndroid Build Coastguard Worker                 "layout(isolines, point_mode) in;\n"
786*35238bceSAndroid Build Coastguard Worker                 "\n"
787*35238bceSAndroid Build Coastguard Worker                 "void main()\n"
788*35238bceSAndroid Build Coastguard Worker                 "{\n"
789*35238bceSAndroid Build Coastguard Worker                 "    int result_value = (INPUT_TE_NAME[0] == TOKEN) ? TOKEN : 0;\n"
790*35238bceSAndroid Build Coastguard Worker                 "\n"
791*35238bceSAndroid Build Coastguard Worker                 "    out_te = result_value;\n"
792*35238bceSAndroid Build Coastguard Worker                 "\n"
793*35238bceSAndroid Build Coastguard Worker                 "    gl_Position = vec4(0.0, 0.0, 0.0, 1.);\n"
794*35238bceSAndroid Build Coastguard Worker                 "}\n";
795*35238bceSAndroid Build Coastguard Worker             std::string te_body = te_body_template;
796*35238bceSAndroid Build Coastguard Worker 
797*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *vs_body_template = "#version 150\n"
798*35238bceSAndroid Build Coastguard Worker                                                          "\n"
799*35238bceSAndroid Build Coastguard Worker                                                          "#extension GL_ARB_cull_distance : require\n"
800*35238bceSAndroid Build Coastguard Worker                                                          "\n"
801*35238bceSAndroid Build Coastguard Worker                                                          "flat out int out_vs;\n"
802*35238bceSAndroid Build Coastguard Worker                                                          "\n"
803*35238bceSAndroid Build Coastguard Worker                                                          "void main()\n"
804*35238bceSAndroid Build Coastguard Worker                                                          "{\n"
805*35238bceSAndroid Build Coastguard Worker                                                          "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
806*35238bceSAndroid Build Coastguard Worker                                                          "    out_vs      = TOKEN;\n"
807*35238bceSAndroid Build Coastguard Worker                                                          "}\n";
808*35238bceSAndroid Build Coastguard Worker             std::string vs_body                        = vs_body_template;
809*35238bceSAndroid Build Coastguard Worker 
810*35238bceSAndroid Build Coastguard Worker             const _stage &current_stage = stages[n_stage];
811*35238bceSAndroid Build Coastguard Worker 
812*35238bceSAndroid Build Coastguard Worker             /* Build shader bodies */
813*35238bceSAndroid Build Coastguard Worker             struct _shader_body
814*35238bceSAndroid Build Coastguard Worker             {
815*35238bceSAndroid Build Coastguard Worker                 std::string *body_ptr;
816*35238bceSAndroid Build Coastguard Worker                 glw::GLenum gl_type;
817*35238bceSAndroid Build Coastguard Worker             } shader_bodies[] = {{&cs_body, GL_COMPUTE_SHADER},         {&fs_body, GL_FRAGMENT_SHADER},
818*35238bceSAndroid Build Coastguard Worker                                  {&gs_body, GL_GEOMETRY_SHADER},        {&tc_body, GL_TESS_CONTROL_SHADER},
819*35238bceSAndroid Build Coastguard Worker                                  {&te_body, GL_TESS_EVALUATION_SHADER}, {&vs_body, GL_VERTEX_SHADER}};
820*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *input_fs_token_string = "INPUT_FS_NAME";
821*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *input_gs_token_string = "INPUT_GS_NAME";
822*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *input_te_token_string = "INPUT_TE_NAME";
823*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *input_tc_token_string = "INPUT_TC_NAME";
824*35238bceSAndroid Build Coastguard Worker             static const glw::GLuint n_shader_bodies        = sizeof(shader_bodies) / sizeof(shader_bodies[0]);
825*35238bceSAndroid Build Coastguard Worker 
826*35238bceSAndroid Build Coastguard Worker             std::size_t token_position             = std::string::npos;
827*35238bceSAndroid Build Coastguard Worker             static const glw::GLchar *token_string = "TOKEN";
828*35238bceSAndroid Build Coastguard Worker 
829*35238bceSAndroid Build Coastguard Worker             for (glw::GLuint n_shader_body = 0; n_shader_body < n_shader_bodies; ++n_shader_body)
830*35238bceSAndroid Build Coastguard Worker             {
831*35238bceSAndroid Build Coastguard Worker                 _shader_body &current_body = shader_bodies[n_shader_body];
832*35238bceSAndroid Build Coastguard Worker 
833*35238bceSAndroid Build Coastguard Worker                 /* Is this stage actually used? */
834*35238bceSAndroid Build Coastguard Worker                 if (((current_body.gl_type == GL_COMPUTE_SHADER) && (!current_stage.use_cs)) ||
835*35238bceSAndroid Build Coastguard Worker                     ((current_body.gl_type == GL_FRAGMENT_SHADER) && (!current_stage.use_fs)) ||
836*35238bceSAndroid Build Coastguard Worker                     ((current_body.gl_type == GL_TESS_CONTROL_SHADER) && (!current_stage.use_tc)) ||
837*35238bceSAndroid Build Coastguard Worker                     ((current_body.gl_type == GL_TESS_EVALUATION_SHADER) && (!current_stage.use_te)) ||
838*35238bceSAndroid Build Coastguard Worker                     ((current_body.gl_type == GL_VERTEX_SHADER) && (!current_stage.use_vs)))
839*35238bceSAndroid Build Coastguard Worker                 {
840*35238bceSAndroid Build Coastguard Worker                     /* Skip the iteration. */
841*35238bceSAndroid Build Coastguard Worker                     continue;
842*35238bceSAndroid Build Coastguard Worker                 }
843*35238bceSAndroid Build Coastguard Worker 
844*35238bceSAndroid Build Coastguard Worker                 /* Iterate over all token and replace them with stage-specific values */
845*35238bceSAndroid Build Coastguard Worker                 struct _token_value_pair
846*35238bceSAndroid Build Coastguard Worker                 {
847*35238bceSAndroid Build Coastguard Worker                     const glw::GLchar *token;
848*35238bceSAndroid Build Coastguard Worker                     const glw::GLchar *value;
849*35238bceSAndroid Build Coastguard Worker                 } token_value_pairs[] = {
850*35238bceSAndroid Build Coastguard Worker                     /* NOTE: The last entry is filled by the switch() block below */
851*35238bceSAndroid Build Coastguard Worker                     {token_string, current_run.essl_token_value},
852*35238bceSAndroid Build Coastguard Worker                     {NULL, NULL},
853*35238bceSAndroid Build Coastguard Worker                 };
854*35238bceSAndroid Build Coastguard Worker 
855*35238bceSAndroid Build Coastguard Worker                 const size_t n_token_value_pairs = sizeof(token_value_pairs) / sizeof(token_value_pairs[0]);
856*35238bceSAndroid Build Coastguard Worker 
857*35238bceSAndroid Build Coastguard Worker                 switch (current_body.gl_type)
858*35238bceSAndroid Build Coastguard Worker                 {
859*35238bceSAndroid Build Coastguard Worker                 case GL_COMPUTE_SHADER:
860*35238bceSAndroid Build Coastguard Worker                 case GL_VERTEX_SHADER:
861*35238bceSAndroid Build Coastguard Worker                     break;
862*35238bceSAndroid Build Coastguard Worker 
863*35238bceSAndroid Build Coastguard Worker                 case GL_FRAGMENT_SHADER:
864*35238bceSAndroid Build Coastguard Worker                 {
865*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].token = input_fs_token_string;
866*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].value = current_stage.fs_input;
867*35238bceSAndroid Build Coastguard Worker 
868*35238bceSAndroid Build Coastguard Worker                     break;
869*35238bceSAndroid Build Coastguard Worker                 }
870*35238bceSAndroid Build Coastguard Worker 
871*35238bceSAndroid Build Coastguard Worker                 case GL_GEOMETRY_SHADER:
872*35238bceSAndroid Build Coastguard Worker                 {
873*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].token = input_gs_token_string;
874*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].value = current_stage.gs_input;
875*35238bceSAndroid Build Coastguard Worker 
876*35238bceSAndroid Build Coastguard Worker                     break;
877*35238bceSAndroid Build Coastguard Worker                 }
878*35238bceSAndroid Build Coastguard Worker 
879*35238bceSAndroid Build Coastguard Worker                 case GL_TESS_CONTROL_SHADER:
880*35238bceSAndroid Build Coastguard Worker                 {
881*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].token = input_tc_token_string;
882*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].value = current_stage.tc_input;
883*35238bceSAndroid Build Coastguard Worker 
884*35238bceSAndroid Build Coastguard Worker                     break;
885*35238bceSAndroid Build Coastguard Worker                 }
886*35238bceSAndroid Build Coastguard Worker 
887*35238bceSAndroid Build Coastguard Worker                 case GL_TESS_EVALUATION_SHADER:
888*35238bceSAndroid Build Coastguard Worker                 {
889*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].token = input_te_token_string;
890*35238bceSAndroid Build Coastguard Worker                     token_value_pairs[1].value = current_stage.te_input;
891*35238bceSAndroid Build Coastguard Worker 
892*35238bceSAndroid Build Coastguard Worker                     break;
893*35238bceSAndroid Build Coastguard Worker                 }
894*35238bceSAndroid Build Coastguard Worker 
895*35238bceSAndroid Build Coastguard Worker                 default:
896*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Unrecognized shader body type");
897*35238bceSAndroid Build Coastguard Worker                 }
898*35238bceSAndroid Build Coastguard Worker 
899*35238bceSAndroid Build Coastguard Worker                 for (glw::GLuint n_pair = 0; n_pair < n_token_value_pairs; ++n_pair)
900*35238bceSAndroid Build Coastguard Worker                 {
901*35238bceSAndroid Build Coastguard Worker                     const _token_value_pair &current_pair = token_value_pairs[n_pair];
902*35238bceSAndroid Build Coastguard Worker 
903*35238bceSAndroid Build Coastguard Worker                     if (current_pair.token == NULL || current_pair.value == NULL)
904*35238bceSAndroid Build Coastguard Worker                     {
905*35238bceSAndroid Build Coastguard Worker                         continue;
906*35238bceSAndroid Build Coastguard Worker                     }
907*35238bceSAndroid Build Coastguard Worker 
908*35238bceSAndroid Build Coastguard Worker                     while ((token_position = current_body.body_ptr->find(current_pair.token)) != std::string::npos)
909*35238bceSAndroid Build Coastguard Worker                     {
910*35238bceSAndroid Build Coastguard Worker                         current_body.body_ptr->replace(token_position, strlen(current_pair.token), current_pair.value);
911*35238bceSAndroid Build Coastguard Worker                     }
912*35238bceSAndroid Build Coastguard Worker                 } /* for (all token+value pairs) */
913*35238bceSAndroid Build Coastguard Worker             }     /* for (all sader bodies) */
914*35238bceSAndroid Build Coastguard Worker 
915*35238bceSAndroid Build Coastguard Worker             /* Build the test program */
916*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::buildProgram(
917*35238bceSAndroid Build Coastguard Worker                 gl, m_testCtx, current_stage.use_cs ? cs_body.c_str() : DE_NULL,
918*35238bceSAndroid Build Coastguard Worker                 current_stage.use_fs ? fs_body.c_str() : DE_NULL, current_stage.use_gs ? gs_body.c_str() : DE_NULL,
919*35238bceSAndroid Build Coastguard Worker                 current_stage.use_tc ? tc_body.c_str() : DE_NULL, current_stage.use_te ? te_body.c_str() : DE_NULL,
920*35238bceSAndroid Build Coastguard Worker                 current_stage.use_vs ? vs_body.c_str() : DE_NULL, (current_stage.tf_output_name != NULL) ? 1 : 0,
921*35238bceSAndroid Build Coastguard Worker                 (const glw::GLchar **)&current_stage.tf_output_name, &m_po_id);
922*35238bceSAndroid Build Coastguard Worker 
923*35238bceSAndroid Build Coastguard Worker             /* Bind the test program */
924*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(m_po_id != 0);
925*35238bceSAndroid Build Coastguard Worker 
926*35238bceSAndroid Build Coastguard Worker             gl.useProgram(m_po_id);
927*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
928*35238bceSAndroid Build Coastguard Worker 
929*35238bceSAndroid Build Coastguard Worker             /* Execute the draw call. Transform Feed-back should be enabled for all iterations
930*35238bceSAndroid Build Coastguard Worker              * par the CS one, since we use a different tool to capture the result data in the
931*35238bceSAndroid Build Coastguard Worker              * latter case.
932*35238bceSAndroid Build Coastguard Worker              */
933*35238bceSAndroid Build Coastguard Worker             if (!current_stage.use_cs)
934*35238bceSAndroid Build Coastguard Worker             {
935*35238bceSAndroid Build Coastguard Worker                 gl.beginTransformFeedback(current_stage.tf_mode);
936*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
937*35238bceSAndroid Build Coastguard Worker 
938*35238bceSAndroid Build Coastguard Worker                 gl.drawArrays(current_stage.draw_call_mode, 0,     /* first */
939*35238bceSAndroid Build Coastguard Worker                               current_stage.n_draw_call_vertices); /* count */
940*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
941*35238bceSAndroid Build Coastguard Worker 
942*35238bceSAndroid Build Coastguard Worker                 gl.endTransformFeedback();
943*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
944*35238bceSAndroid Build Coastguard Worker             } /* if (uses_tf) */
945*35238bceSAndroid Build Coastguard Worker             else
946*35238bceSAndroid Build Coastguard Worker             {
947*35238bceSAndroid Build Coastguard Worker                 gl.dispatchCompute(1,  /* num_groups_x */
948*35238bceSAndroid Build Coastguard Worker                                    1,  /* num_groups_y */
949*35238bceSAndroid Build Coastguard Worker                                    1); /* num_groups_z */
950*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute() call failed.");
951*35238bceSAndroid Build Coastguard Worker             }
952*35238bceSAndroid Build Coastguard Worker 
953*35238bceSAndroid Build Coastguard Worker             /* Verify the result values */
954*35238bceSAndroid Build Coastguard Worker             if (!current_stage.use_cs)
955*35238bceSAndroid Build Coastguard Worker             {
956*35238bceSAndroid Build Coastguard Worker                 glw::GLint *result_data_ptr = DE_NULL;
957*35238bceSAndroid Build Coastguard Worker 
958*35238bceSAndroid Build Coastguard Worker                 /* Retrieve the data captured by Transform Feedback */
959*35238bceSAndroid Build Coastguard Worker                 result_data_ptr = (glw::GLint *)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* offset */
960*35238bceSAndroid Build Coastguard Worker                                                                   sizeof(unsigned int) * 1, GL_MAP_READ_BIT);
961*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
962*35238bceSAndroid Build Coastguard Worker 
963*35238bceSAndroid Build Coastguard Worker                 if (*result_data_ptr != current_run.gl_value)
964*35238bceSAndroid Build Coastguard Worker                 {
965*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << current_run.name
966*35238bceSAndroid Build Coastguard Worker                                        << " value "
967*35238bceSAndroid Build Coastguard Worker                                           "["
968*35238bceSAndroid Build Coastguard Worker                                        << *result_data_ptr
969*35238bceSAndroid Build Coastguard Worker                                        << "]"
970*35238bceSAndroid Build Coastguard Worker                                           " does not match the one reported by glGetIntegerv() "
971*35238bceSAndroid Build Coastguard Worker                                           "["
972*35238bceSAndroid Build Coastguard Worker                                        << current_run.gl_value << "]" << tcu::TestLog::EndMessage;
973*35238bceSAndroid Build Coastguard Worker 
974*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("GL constant value does not match the ES SL equivalent");
975*35238bceSAndroid Build Coastguard Worker                 }
976*35238bceSAndroid Build Coastguard Worker 
977*35238bceSAndroid Build Coastguard Worker                 if (*result_data_ptr < current_run.min_value)
978*35238bceSAndroid Build Coastguard Worker                 {
979*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << current_run.name
980*35238bceSAndroid Build Coastguard Worker                                        << " value "
981*35238bceSAndroid Build Coastguard Worker                                           "["
982*35238bceSAndroid Build Coastguard Worker                                        << *result_data_ptr
983*35238bceSAndroid Build Coastguard Worker                                        << "]"
984*35238bceSAndroid Build Coastguard Worker                                           " does not meet the minimum specification requirements "
985*35238bceSAndroid Build Coastguard Worker                                           "["
986*35238bceSAndroid Build Coastguard Worker                                        << current_run.min_value << "]" << tcu::TestLog::EndMessage;
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("GL constant value does not meet minimum specification requirements");
989*35238bceSAndroid Build Coastguard Worker                 }
990*35238bceSAndroid Build Coastguard Worker 
991*35238bceSAndroid Build Coastguard Worker                 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
992*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
993*35238bceSAndroid Build Coastguard Worker             }
994*35238bceSAndroid Build Coastguard Worker 
995*35238bceSAndroid Build Coastguard Worker             for (glw::GLuint n_stage_internal = 0; n_stage_internal < 2; /* CS, FS write to separate textures */
996*35238bceSAndroid Build Coastguard Worker                  ++n_stage_internal)
997*35238bceSAndroid Build Coastguard Worker             {
998*35238bceSAndroid Build Coastguard Worker                 glw::GLuint to_id = (n_stage_internal == 0) ? m_cs_to_id : m_fbo_draw_to_id;
999*35238bceSAndroid Build Coastguard Worker 
1000*35238bceSAndroid Build Coastguard Worker                 if (((n_stage_internal == 0) && (!current_stage.use_cs)) ||
1001*35238bceSAndroid Build Coastguard Worker                     ((n_stage_internal == 1) && (!current_stage.use_fs)))
1002*35238bceSAndroid Build Coastguard Worker                 {
1003*35238bceSAndroid Build Coastguard Worker                     /* Skip the iteration */
1004*35238bceSAndroid Build Coastguard Worker                     continue;
1005*35238bceSAndroid Build Coastguard Worker                 }
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker                 /* Check the image data the test CS / FS should have written */
1008*35238bceSAndroid Build Coastguard Worker                 glw::GLint result_value = 0;
1009*35238bceSAndroid Build Coastguard Worker 
1010*35238bceSAndroid Build Coastguard Worker                 gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, to_id, 0); /* level */
1011*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker                 /* NOTE: We're using our custom read framebuffer here, so we'll be reading
1014*35238bceSAndroid Build Coastguard Worker                  *       from the texture, that the writes have been issued to earlier. */
1015*35238bceSAndroid Build Coastguard Worker                 gl.finish();
1016*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier() call failed.");
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker                 gl.readPixels(0, /* x */
1019*35238bceSAndroid Build Coastguard Worker                               0, /* y */
1020*35238bceSAndroid Build Coastguard Worker                               1, /* width */
1021*35238bceSAndroid Build Coastguard Worker                               1, /* height */
1022*35238bceSAndroid Build Coastguard Worker                               GL_RED_INTEGER, GL_INT, &result_value);
1023*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
1024*35238bceSAndroid Build Coastguard Worker 
1025*35238bceSAndroid Build Coastguard Worker                 if (result_value != current_run.gl_value)
1026*35238bceSAndroid Build Coastguard Worker                 {
1027*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << current_run.name
1028*35238bceSAndroid Build Coastguard Worker                                        << " value accessible to the compute / fragment shader "
1029*35238bceSAndroid Build Coastguard Worker                                           "["
1030*35238bceSAndroid Build Coastguard Worker                                        << result_value
1031*35238bceSAndroid Build Coastguard Worker                                        << "]"
1032*35238bceSAndroid Build Coastguard Worker                                           " does not match the one reported by glGetIntegerv() "
1033*35238bceSAndroid Build Coastguard Worker                                           "["
1034*35238bceSAndroid Build Coastguard Worker                                        << current_run.gl_value << "]" << tcu::TestLog::EndMessage;
1035*35238bceSAndroid Build Coastguard Worker 
1036*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("GL constant value does not match the ES SL equivalent");
1037*35238bceSAndroid Build Coastguard Worker                 }
1038*35238bceSAndroid Build Coastguard Worker 
1039*35238bceSAndroid Build Coastguard Worker                 if (result_value < current_run.min_value)
1040*35238bceSAndroid Build Coastguard Worker                 {
1041*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << current_run.name
1042*35238bceSAndroid Build Coastguard Worker                                        << " value accessible to the compute / fragment shader "
1043*35238bceSAndroid Build Coastguard Worker                                           "["
1044*35238bceSAndroid Build Coastguard Worker                                        << result_value
1045*35238bceSAndroid Build Coastguard Worker                                        << "]"
1046*35238bceSAndroid Build Coastguard Worker                                           " does not meet the minimum specification requirements "
1047*35238bceSAndroid Build Coastguard Worker                                           "["
1048*35238bceSAndroid Build Coastguard Worker                                        << current_run.min_value << "]" << tcu::TestLog::EndMessage;
1049*35238bceSAndroid Build Coastguard Worker 
1050*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("GL constant value does not meet minimum specification requirements");
1051*35238bceSAndroid Build Coastguard Worker                 }
1052*35238bceSAndroid Build Coastguard Worker             }
1053*35238bceSAndroid Build Coastguard Worker 
1054*35238bceSAndroid Build Coastguard Worker             /* Clear the data buffer before we continue */
1055*35238bceSAndroid Build Coastguard Worker             static const glw::GLubyte bo_clear_data[bo_size] = {0};
1056*35238bceSAndroid Build Coastguard Worker 
1057*35238bceSAndroid Build Coastguard Worker             gl.bufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* offset */
1058*35238bceSAndroid Build Coastguard Worker                              bo_size, bo_clear_data);
1059*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
1060*35238bceSAndroid Build Coastguard Worker 
1061*35238bceSAndroid Build Coastguard Worker             /* Clear the texture mip-map before we continue */
1062*35238bceSAndroid Build Coastguard Worker             glw::GLint clear_values[4] = {0, 0, 0, 0};
1063*35238bceSAndroid Build Coastguard Worker 
1064*35238bceSAndroid Build Coastguard Worker             gl.clearBufferiv(GL_COLOR, 0, /* drawbuffer */
1065*35238bceSAndroid Build Coastguard Worker                              clear_values);
1066*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferiv() call failed.");
1067*35238bceSAndroid Build Coastguard Worker 
1068*35238bceSAndroid Build Coastguard Worker             /* Release program before we move on to the next iteration */
1069*35238bceSAndroid Build Coastguard Worker             if (m_po_id != 0)
1070*35238bceSAndroid Build Coastguard Worker             {
1071*35238bceSAndroid Build Coastguard Worker                 gl.deleteProgram(m_po_id);
1072*35238bceSAndroid Build Coastguard Worker 
1073*35238bceSAndroid Build Coastguard Worker                 m_po_id = 0;
1074*35238bceSAndroid Build Coastguard Worker             }
1075*35238bceSAndroid Build Coastguard Worker         } /* for (all stages) */
1076*35238bceSAndroid Build Coastguard Worker     }     /* for (both runs) */
1077*35238bceSAndroid Build Coastguard Worker 
1078*35238bceSAndroid Build Coastguard Worker     /* All done */
1079*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1080*35238bceSAndroid Build Coastguard Worker 
1081*35238bceSAndroid Build Coastguard Worker     return STOP;
1082*35238bceSAndroid Build Coastguard Worker }
1083*35238bceSAndroid Build Coastguard Worker 
1084*35238bceSAndroid Build Coastguard Worker /** Constructor.
1085*35238bceSAndroid Build Coastguard Worker  *
1086*35238bceSAndroid Build Coastguard Worker  *  @param context Rendering context handle.
1087*35238bceSAndroid Build Coastguard Worker  **/
FunctionalTest(deqp::Context & context)1088*35238bceSAndroid Build Coastguard Worker CullDistance::FunctionalTest::FunctionalTest(deqp::Context &context)
1089*35238bceSAndroid Build Coastguard Worker     : TestCase(context, "functional", "Cull Distance Functional Test")
1090*35238bceSAndroid Build Coastguard Worker     , m_bo_data()
1091*35238bceSAndroid Build Coastguard Worker     , m_bo_id(0)
1092*35238bceSAndroid Build Coastguard Worker     , m_fbo_id(0)
1093*35238bceSAndroid Build Coastguard Worker     , m_po_id(0)
1094*35238bceSAndroid Build Coastguard Worker     , m_render_primitives(0)
1095*35238bceSAndroid Build Coastguard Worker     , m_render_vertices(0)
1096*35238bceSAndroid Build Coastguard Worker     , m_sub_grid_cell_size(0)
1097*35238bceSAndroid Build Coastguard Worker     , m_to_id(0)
1098*35238bceSAndroid Build Coastguard Worker     , m_vao_id(0)
1099*35238bceSAndroid Build Coastguard Worker     , m_to_height(512)
1100*35238bceSAndroid Build Coastguard Worker     , m_to_width(512)
1101*35238bceSAndroid Build Coastguard Worker     , m_to_pixel_data_cache()
1102*35238bceSAndroid Build Coastguard Worker {
1103*35238bceSAndroid Build Coastguard Worker     /* Left blank on purpose */
1104*35238bceSAndroid Build Coastguard Worker }
1105*35238bceSAndroid Build Coastguard Worker 
1106*35238bceSAndroid Build Coastguard Worker /** @brief Build OpenGL program for functional tests
1107*35238bceSAndroid Build Coastguard Worker  *
1108*35238bceSAndroid Build Coastguard Worker  *  @param [in]  clipdistances_array_size   use size of gl_ClipDistance array
1109*35238bceSAndroid Build Coastguard Worker  *  @param [in]  culldistances_array_size   use size of gl_CullDistance array
1110*35238bceSAndroid Build Coastguard Worker  *  @param [in]  dynamic_index_writes       use dunamic indexing for setting  the gl_ClipDistance and gl_CullDistance arrays
1111*35238bceSAndroid Build Coastguard Worker  *  @param [in]  primitive_mode             primitive_mode will be used for rendering
1112*35238bceSAndroid Build Coastguard Worker  *  @param [in]  redeclare_clipdistances    redeclare gl_ClipDistance
1113*35238bceSAndroid Build Coastguard Worker  *  @param [in]  redeclare_culldistances    redeclare gl_CullDistance
1114*35238bceSAndroid Build Coastguard Worker  *  @param [in]  use_core_functionality     use core OpenGL functionality
1115*35238bceSAndroid Build Coastguard Worker  *  @param [in]  use_gs                     use geometry shader
1116*35238bceSAndroid Build Coastguard Worker  *  @param [in]  use_ts                     use tessellation shader
1117*35238bceSAndroid Build Coastguard Worker  *  @param [in]  fetch_culldistance_from_fs fetch check sum of gl_ClipDistance and gl_CullDistance from fragment shader
1118*35238bceSAndroid Build Coastguard Worker  */
buildPO(glw::GLuint clipdistances_array_size,glw::GLuint culldistances_array_size,bool dynamic_index_writes,_primitive_mode primitive_mode,bool redeclare_clipdistances,bool redeclare_culldistances,bool use_core_functionality,bool use_gs,bool use_ts,bool fetch_culldistance_from_fs)1119*35238bceSAndroid Build Coastguard Worker void CullDistance::FunctionalTest::buildPO(glw::GLuint clipdistances_array_size, glw::GLuint culldistances_array_size,
1120*35238bceSAndroid Build Coastguard Worker                                            bool dynamic_index_writes, _primitive_mode primitive_mode,
1121*35238bceSAndroid Build Coastguard Worker                                            bool redeclare_clipdistances, bool redeclare_culldistances,
1122*35238bceSAndroid Build Coastguard Worker                                            bool use_core_functionality, bool use_gs, bool use_ts,
1123*35238bceSAndroid Build Coastguard Worker                                            bool fetch_culldistance_from_fs)
1124*35238bceSAndroid Build Coastguard Worker {
1125*35238bceSAndroid Build Coastguard Worker     deinitPO();
1126*35238bceSAndroid Build Coastguard Worker 
1127*35238bceSAndroid Build Coastguard Worker     /* Form the vertex shader */
1128*35238bceSAndroid Build Coastguard Worker     glw::GLuint clipdistances_input_size =
1129*35238bceSAndroid Build Coastguard Worker         clipdistances_array_size > 0 ? clipdistances_array_size : 1; /* Avoid zero-sized array compilation error */
1130*35238bceSAndroid Build Coastguard Worker     glw::GLuint culldistances_input_size =
1131*35238bceSAndroid Build Coastguard Worker         culldistances_array_size > 0 ? culldistances_array_size : 1; /* Avoid zero-sized array compilation error */
1132*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *dynamic_array_setters =
1133*35238bceSAndroid Build Coastguard Worker         "\n"
1134*35238bceSAndroid Build Coastguard Worker         "#if TEMPLATE_N_GL_CLIPDISTANCE_ENTRIES\n"
1135*35238bceSAndroid Build Coastguard Worker         "     for (int n_clipdistance_entry = 0;\n"
1136*35238bceSAndroid Build Coastguard Worker         "          n_clipdistance_entry < TEMPLATE_N_GL_CLIPDISTANCE_ENTRIES;\n"
1137*35238bceSAndroid Build Coastguard Worker         "        ++n_clipdistance_entry)\n"
1138*35238bceSAndroid Build Coastguard Worker         "     {\n"
1139*35238bceSAndroid Build Coastguard Worker         "         ASSIGN_CLIP_DISTANCE(n_clipdistance_entry);\n"
1140*35238bceSAndroid Build Coastguard Worker         "     }\n"
1141*35238bceSAndroid Build Coastguard Worker         "#endif"
1142*35238bceSAndroid Build Coastguard Worker         "\n"
1143*35238bceSAndroid Build Coastguard Worker         "#if TEMPLATE_N_GL_CULLDISTANCE_ENTRIES \n"
1144*35238bceSAndroid Build Coastguard Worker         "     for (int n_culldistance_entry = 0;\n"
1145*35238bceSAndroid Build Coastguard Worker         "          n_culldistance_entry < TEMPLATE_N_GL_CULLDISTANCE_ENTRIES;\n"
1146*35238bceSAndroid Build Coastguard Worker         "        ++n_culldistance_entry)\n"
1147*35238bceSAndroid Build Coastguard Worker         "     {\n"
1148*35238bceSAndroid Build Coastguard Worker         "         ASSIGN_CULL_DISTANCE(n_culldistance_entry);\n"
1149*35238bceSAndroid Build Coastguard Worker         "     }\n"
1150*35238bceSAndroid Build Coastguard Worker         "#endif\n";
1151*35238bceSAndroid Build Coastguard Worker 
1152*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *core_functionality = "#version 450\n";
1153*35238bceSAndroid Build Coastguard Worker 
1154*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *extention_functionality = "#version 150\n"
1155*35238bceSAndroid Build Coastguard Worker                                                         "\n"
1156*35238bceSAndroid Build Coastguard Worker                                                         "#extension GL_ARB_cull_distance : require\n"
1157*35238bceSAndroid Build Coastguard Worker                                                         "TEMPLATE_EXTENSIONS\n"
1158*35238bceSAndroid Build Coastguard Worker                                                         "\n"
1159*35238bceSAndroid Build Coastguard Worker                                                         "#ifndef GL_ARB_cull_distance\n"
1160*35238bceSAndroid Build Coastguard Worker                                                         "    #error GL_ARB_cull_distance is undefined\n"
1161*35238bceSAndroid Build Coastguard Worker                                                         "#endif\n";
1162*35238bceSAndroid Build Coastguard Worker 
1163*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *fetch_function = "highp float fetch()\n"
1164*35238bceSAndroid Build Coastguard Worker                                                "{\n"
1165*35238bceSAndroid Build Coastguard Worker                                                "    highp float sum = 0.0;\n"
1166*35238bceSAndroid Build Coastguard Worker                                                "\n"
1167*35238bceSAndroid Build Coastguard Worker                                                "TEMPLATE_SUM_SETTER"
1168*35238bceSAndroid Build Coastguard Worker                                                "\n"
1169*35238bceSAndroid Build Coastguard Worker                                                "    return sum / TEMPLATE_SUM_DIVIDER;\n"
1170*35238bceSAndroid Build Coastguard Worker                                                "}\n"
1171*35238bceSAndroid Build Coastguard Worker                                                "\n"
1172*35238bceSAndroid Build Coastguard Worker                                                "#define ASSIGN_RETURN_VALUE fetch()";
1173*35238bceSAndroid Build Coastguard Worker 
1174*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *fs_template = "TEMPLATE_HEADER_DECLARATION\n"
1175*35238bceSAndroid Build Coastguard Worker                                             "\n"
1176*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_CLIPDISTANCE\n"
1177*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_CULLDISTANCE\n"
1178*35238bceSAndroid Build Coastguard Worker                                             "\n"
1179*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_ASSIGN_RETURN_VALUE\n"
1180*35238bceSAndroid Build Coastguard Worker                                             "\n"
1181*35238bceSAndroid Build Coastguard Worker                                             "out vec4 out_fs;\n"
1182*35238bceSAndroid Build Coastguard Worker                                             "\n"
1183*35238bceSAndroid Build Coastguard Worker                                             "/* Fragment shader main function */\n"
1184*35238bceSAndroid Build Coastguard Worker                                             "void main()\n"
1185*35238bceSAndroid Build Coastguard Worker                                             "{\n"
1186*35238bceSAndroid Build Coastguard Worker                                             "    out_fs = vec4(ASSIGN_RETURN_VALUE, 1.0, 1.0, 1.0);\n"
1187*35238bceSAndroid Build Coastguard Worker                                             "}\n";
1188*35238bceSAndroid Build Coastguard Worker 
1189*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *gs_template = "TEMPLATE_HEADER_DECLARATION\n"
1190*35238bceSAndroid Build Coastguard Worker                                             "\n"
1191*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_LAYOUT_IN\n"
1192*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_LAYOUT_OUT\n"
1193*35238bceSAndroid Build Coastguard Worker                                             "\n"
1194*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_CLIPDISTANCE\n"
1195*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_CULLDISTANCE\n"
1196*35238bceSAndroid Build Coastguard Worker                                             "\n"
1197*35238bceSAndroid Build Coastguard Worker                                             "#define ASSIGN_CLIP_DISTANCE(IDX) TEMPLATE_ASSIGN_CLIP_DISTANCE\n"
1198*35238bceSAndroid Build Coastguard Worker                                             "#define ASSIGN_CULL_DISTANCE(IDX) TEMPLATE_ASSIGN_CULL_DISTANCE\n"
1199*35238bceSAndroid Build Coastguard Worker                                             "\n"
1200*35238bceSAndroid Build Coastguard Worker                                             "/* Geometry shader (passthrough) main function */\n"
1201*35238bceSAndroid Build Coastguard Worker                                             "void main()\n"
1202*35238bceSAndroid Build Coastguard Worker                                             "{\n"
1203*35238bceSAndroid Build Coastguard Worker                                             "    for (int n_vertex_index = 0;\n"
1204*35238bceSAndroid Build Coastguard Worker                                             "             n_vertex_index < gl_in.length();\n"
1205*35238bceSAndroid Build Coastguard Worker                                             "             n_vertex_index ++)\n"
1206*35238bceSAndroid Build Coastguard Worker                                             "    {\n"
1207*35238bceSAndroid Build Coastguard Worker                                             "        gl_Position = gl_in[n_vertex_index].gl_Position;\n"
1208*35238bceSAndroid Build Coastguard Worker                                             "\n"
1209*35238bceSAndroid Build Coastguard Worker                                             "        TEMPLATE_ARRAY_SETTERS\n"
1210*35238bceSAndroid Build Coastguard Worker                                             "\n"
1211*35238bceSAndroid Build Coastguard Worker                                             "        EmitVertex();\n"
1212*35238bceSAndroid Build Coastguard Worker                                             "    }\n"
1213*35238bceSAndroid Build Coastguard Worker                                             "\n"
1214*35238bceSAndroid Build Coastguard Worker                                             "    EndPrimitive();\n"
1215*35238bceSAndroid Build Coastguard Worker                                             "}\n";
1216*35238bceSAndroid Build Coastguard Worker 
1217*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *tc_template =
1218*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_HEADER_DECLARATION\n"
1219*35238bceSAndroid Build Coastguard Worker         "\n"
1220*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_LAYOUT_OUT\n"
1221*35238bceSAndroid Build Coastguard Worker         "\n"
1222*35238bceSAndroid Build Coastguard Worker         "out gl_PerVertex {\n"
1223*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_REDECLARE_CLIPDISTANCE\n"
1224*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_REDECLARE_CULLDISTANCE\n"
1225*35238bceSAndroid Build Coastguard Worker         "vec4 gl_Position;\n"
1226*35238bceSAndroid Build Coastguard Worker         "} gl_out[];\n"
1227*35238bceSAndroid Build Coastguard Worker         "\n"
1228*35238bceSAndroid Build Coastguard Worker         "#define ASSIGN_CLIP_DISTANCE(IDX) TEMPLATE_ASSIGN_CLIP_DISTANCE\n"
1229*35238bceSAndroid Build Coastguard Worker         "#define ASSIGN_CULL_DISTANCE(IDX) TEMPLATE_ASSIGN_CULL_DISTANCE\n"
1230*35238bceSAndroid Build Coastguard Worker         "\n"
1231*35238bceSAndroid Build Coastguard Worker         "/* Tesselation control shader main function */\n"
1232*35238bceSAndroid Build Coastguard Worker         "void main()\n"
1233*35238bceSAndroid Build Coastguard Worker         "{\n"
1234*35238bceSAndroid Build Coastguard Worker         "    gl_TessLevelInner[0] = 1.0;\n"
1235*35238bceSAndroid Build Coastguard Worker         "    gl_TessLevelInner[1] = 1.0;\n"
1236*35238bceSAndroid Build Coastguard Worker         "    gl_TessLevelOuter[0] = 1.0;\n"
1237*35238bceSAndroid Build Coastguard Worker         "    gl_TessLevelOuter[1] = 1.0;\n"
1238*35238bceSAndroid Build Coastguard Worker         "    gl_TessLevelOuter[2] = 1.0;\n"
1239*35238bceSAndroid Build Coastguard Worker         "    gl_TessLevelOuter[3] = 1.0;\n"
1240*35238bceSAndroid Build Coastguard Worker         "    /* Clipdistance and culldistance array setters */\n"
1241*35238bceSAndroid Build Coastguard Worker         "    {\n"
1242*35238bceSAndroid Build Coastguard Worker         "        TEMPLATE_ARRAY_SETTERS\n"
1243*35238bceSAndroid Build Coastguard Worker         "    }\n"
1244*35238bceSAndroid Build Coastguard Worker         "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1245*35238bceSAndroid Build Coastguard Worker         "}\n";
1246*35238bceSAndroid Build Coastguard Worker 
1247*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *te_template = "TEMPLATE_HEADER_DECLARATION\n"
1248*35238bceSAndroid Build Coastguard Worker                                             "\n"
1249*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_LAYOUT_IN\n"
1250*35238bceSAndroid Build Coastguard Worker                                             "\n"
1251*35238bceSAndroid Build Coastguard Worker                                             "in gl_PerVertex {\n"
1252*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_IN_CLIPDISTANCE\n"
1253*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_IN_CULLDISTANCE\n"
1254*35238bceSAndroid Build Coastguard Worker                                             "vec4 gl_Position;\n"
1255*35238bceSAndroid Build Coastguard Worker                                             "} gl_in[];\n"
1256*35238bceSAndroid Build Coastguard Worker                                             "\n"
1257*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_CLIPDISTANCE\n"
1258*35238bceSAndroid Build Coastguard Worker                                             "TEMPLATE_REDECLARE_CULLDISTANCE\n"
1259*35238bceSAndroid Build Coastguard Worker                                             "\n"
1260*35238bceSAndroid Build Coastguard Worker                                             "#define ASSIGN_CLIP_DISTANCE(IDX) TEMPLATE_ASSIGN_CLIP_DISTANCE\n"
1261*35238bceSAndroid Build Coastguard Worker                                             "#define ASSIGN_CULL_DISTANCE(IDX) TEMPLATE_ASSIGN_CULL_DISTANCE\n"
1262*35238bceSAndroid Build Coastguard Worker                                             "\n"
1263*35238bceSAndroid Build Coastguard Worker                                             "/* Tesselation evaluation shader main function */\n"
1264*35238bceSAndroid Build Coastguard Worker                                             "void main()\n"
1265*35238bceSAndroid Build Coastguard Worker                                             "{\n"
1266*35238bceSAndroid Build Coastguard Worker                                             "    /* Clipdistance and culldistance array setters */\n"
1267*35238bceSAndroid Build Coastguard Worker                                             "    {\n"
1268*35238bceSAndroid Build Coastguard Worker                                             "        TEMPLATE_ARRAY_SETTERS\n"
1269*35238bceSAndroid Build Coastguard Worker                                             "    }\n"
1270*35238bceSAndroid Build Coastguard Worker                                             "    gl_Position = TEMPLATE_OUT_FORMULA;\n"
1271*35238bceSAndroid Build Coastguard Worker                                             "}\n";
1272*35238bceSAndroid Build Coastguard Worker 
1273*35238bceSAndroid Build Coastguard Worker     static const glw::GLchar *vs_template =
1274*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_HEADER_DECLARATION\n"
1275*35238bceSAndroid Build Coastguard Worker         "\n"
1276*35238bceSAndroid Build Coastguard Worker         "in float clipdistance_data[TEMPLATE_CLIPDISTANCE_INPUT_SIZE];\n"
1277*35238bceSAndroid Build Coastguard Worker         "in float culldistance_data[TEMPLATE_CULLDISTANCE_INPUT_SIZE];\n"
1278*35238bceSAndroid Build Coastguard Worker         "in vec2  position;\n"
1279*35238bceSAndroid Build Coastguard Worker         "\n"
1280*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_REDECLARE_CLIPDISTANCE\n"
1281*35238bceSAndroid Build Coastguard Worker         "TEMPLATE_REDECLARE_CULLDISTANCE\n"
1282*35238bceSAndroid Build Coastguard Worker         "\n"
1283*35238bceSAndroid Build Coastguard Worker         "#define ASSIGN_CLIP_DISTANCE(IDX) TEMPLATE_ASSIGN_CLIP_DISTANCE\n"
1284*35238bceSAndroid Build Coastguard Worker         "#define ASSIGN_CULL_DISTANCE(IDX) TEMPLATE_ASSIGN_CULL_DISTANCE\n"
1285*35238bceSAndroid Build Coastguard Worker         "\n"
1286*35238bceSAndroid Build Coastguard Worker         "/* Vertex shader main function */\n"
1287*35238bceSAndroid Build Coastguard Worker         "void main()\n"
1288*35238bceSAndroid Build Coastguard Worker         "{\n"
1289*35238bceSAndroid Build Coastguard Worker         "    /* Clipdistance and culldistance array setters */\n"
1290*35238bceSAndroid Build Coastguard Worker         "    {\n"
1291*35238bceSAndroid Build Coastguard Worker         "        TEMPLATE_ARRAY_SETTERS\n"
1292*35238bceSAndroid Build Coastguard Worker         "    }\n"
1293*35238bceSAndroid Build Coastguard Worker         "    gl_Position = vec4(2.0 * position.x - 1.0, 2.0 * position.y - 1.0, 0.0, 1.0);\n"
1294*35238bceSAndroid Build Coastguard Worker         "}\n";
1295*35238bceSAndroid Build Coastguard Worker 
1296*35238bceSAndroid Build Coastguard Worker     std::string *shader_body_string_fs    = DE_NULL;
1297*35238bceSAndroid Build Coastguard Worker     std::string *shader_body_string_gs    = DE_NULL;
1298*35238bceSAndroid Build Coastguard Worker     std::string *shader_body_string_tc    = DE_NULL;
1299*35238bceSAndroid Build Coastguard Worker     std::string *shader_body_string_te    = DE_NULL;
1300*35238bceSAndroid Build Coastguard Worker     std::string *shader_body_string_vs    = DE_NULL;
1301*35238bceSAndroid Build Coastguard Worker     std::string shader_header_declaration = use_core_functionality ? core_functionality : extention_functionality;
1302*35238bceSAndroid Build Coastguard Worker 
1303*35238bceSAndroid Build Coastguard Worker     struct _shaders_configuration
1304*35238bceSAndroid Build Coastguard Worker     {
1305*35238bceSAndroid Build Coastguard Worker         glw::GLenum type;
1306*35238bceSAndroid Build Coastguard Worker         const glw::GLchar *shader_template;
1307*35238bceSAndroid Build Coastguard Worker         std::string body;
1308*35238bceSAndroid Build Coastguard Worker         const bool use;
1309*35238bceSAndroid Build Coastguard Worker     } shaders_configuration[] = {{
1310*35238bceSAndroid Build Coastguard Worker                                      GL_FRAGMENT_SHADER,
1311*35238bceSAndroid Build Coastguard Worker                                      fs_template,
1312*35238bceSAndroid Build Coastguard Worker                                      std::string(),
1313*35238bceSAndroid Build Coastguard Worker                                      true,
1314*35238bceSAndroid Build Coastguard Worker                                  },
1315*35238bceSAndroid Build Coastguard Worker                                  {
1316*35238bceSAndroid Build Coastguard Worker                                      GL_GEOMETRY_SHADER,
1317*35238bceSAndroid Build Coastguard Worker                                      gs_template,
1318*35238bceSAndroid Build Coastguard Worker                                      std::string(),
1319*35238bceSAndroid Build Coastguard Worker                                      use_gs,
1320*35238bceSAndroid Build Coastguard Worker                                  },
1321*35238bceSAndroid Build Coastguard Worker                                  {
1322*35238bceSAndroid Build Coastguard Worker                                      GL_TESS_CONTROL_SHADER,
1323*35238bceSAndroid Build Coastguard Worker                                      tc_template,
1324*35238bceSAndroid Build Coastguard Worker                                      std::string(),
1325*35238bceSAndroid Build Coastguard Worker                                      use_ts,
1326*35238bceSAndroid Build Coastguard Worker                                  },
1327*35238bceSAndroid Build Coastguard Worker                                  {
1328*35238bceSAndroid Build Coastguard Worker                                      GL_TESS_EVALUATION_SHADER,
1329*35238bceSAndroid Build Coastguard Worker                                      te_template,
1330*35238bceSAndroid Build Coastguard Worker                                      std::string(),
1331*35238bceSAndroid Build Coastguard Worker                                      use_ts,
1332*35238bceSAndroid Build Coastguard Worker                                  },
1333*35238bceSAndroid Build Coastguard Worker                                  {
1334*35238bceSAndroid Build Coastguard Worker                                      GL_VERTEX_SHADER,
1335*35238bceSAndroid Build Coastguard Worker                                      vs_template,
1336*35238bceSAndroid Build Coastguard Worker                                      std::string(),
1337*35238bceSAndroid Build Coastguard Worker                                      true,
1338*35238bceSAndroid Build Coastguard Worker                                  }};
1339*35238bceSAndroid Build Coastguard Worker 
1340*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_shaders_configuration = sizeof(shaders_configuration) / sizeof(shaders_configuration[0]);
1341*35238bceSAndroid Build Coastguard Worker 
1342*35238bceSAndroid Build Coastguard Worker     /* Construct shader bodies out of templates */
1343*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_shader_index = 0; n_shader_index < n_shaders_configuration; n_shader_index++)
1344*35238bceSAndroid Build Coastguard Worker     {
1345*35238bceSAndroid Build Coastguard Worker         if (shaders_configuration[n_shader_index].use)
1346*35238bceSAndroid Build Coastguard Worker         {
1347*35238bceSAndroid Build Coastguard Worker             std::string array_setters;
1348*35238bceSAndroid Build Coastguard Worker             std::string clipdistance_array_declaration;
1349*35238bceSAndroid Build Coastguard Worker             std::string culldistance_array_declaration;
1350*35238bceSAndroid Build Coastguard Worker             std::string clipdistance_in_array_declaration;
1351*35238bceSAndroid Build Coastguard Worker             std::string culldistance_in_array_declaration;
1352*35238bceSAndroid Build Coastguard Worker             std::string &shader_source = shaders_configuration[n_shader_index].body;
1353*35238bceSAndroid Build Coastguard Worker 
1354*35238bceSAndroid Build Coastguard Worker             /* Copy template into shader body source */
1355*35238bceSAndroid Build Coastguard Worker             shader_source = shaders_configuration[n_shader_index].shader_template;
1356*35238bceSAndroid Build Coastguard Worker 
1357*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_HEADER_DECLARATION"),
1358*35238bceSAndroid Build Coastguard Worker                                                 shader_header_declaration);
1359*35238bceSAndroid Build Coastguard Worker 
1360*35238bceSAndroid Build Coastguard Worker             /* Shader-specific actions */
1361*35238bceSAndroid Build Coastguard Worker             switch (shaders_configuration[n_shader_index].type)
1362*35238bceSAndroid Build Coastguard Worker             {
1363*35238bceSAndroid Build Coastguard Worker             case GL_FRAGMENT_SHADER:
1364*35238bceSAndroid Build Coastguard Worker             {
1365*35238bceSAndroid Build Coastguard Worker                 shader_body_string_fs = &shaders_configuration[n_shader_index].body;
1366*35238bceSAndroid Build Coastguard Worker 
1367*35238bceSAndroid Build Coastguard Worker                 if (fetch_culldistance_from_fs)
1368*35238bceSAndroid Build Coastguard Worker                 {
1369*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_ASSIGN_RETURN_VALUE"),
1370*35238bceSAndroid Build Coastguard Worker                                                         std::string(fetch_function));
1371*35238bceSAndroid Build Coastguard Worker 
1372*35238bceSAndroid Build Coastguard Worker                     std::string fetch_sum_setters = "";
1373*35238bceSAndroid Build Coastguard Worker                     for (glw::GLuint i = 0; i < clipdistances_array_size; ++i)
1374*35238bceSAndroid Build Coastguard Worker                     {
1375*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append("    sum += abs(gl_ClipDistance[");
1376*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append(CullDistance::Utilities::intToString(i));
1377*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append("]) * ");
1378*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append(CullDistance::Utilities::intToString(i + 1));
1379*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append(".0;\n");
1380*35238bceSAndroid Build Coastguard Worker                     }
1381*35238bceSAndroid Build Coastguard Worker 
1382*35238bceSAndroid Build Coastguard Worker                     fetch_sum_setters.append("\n");
1383*35238bceSAndroid Build Coastguard Worker 
1384*35238bceSAndroid Build Coastguard Worker                     for (glw::GLuint i = 0; i < culldistances_array_size; ++i)
1385*35238bceSAndroid Build Coastguard Worker                     {
1386*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append("    sum += abs(gl_CullDistance[");
1387*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append(CullDistance::Utilities::intToString(i));
1388*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append("]) * ");
1389*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append(
1390*35238bceSAndroid Build Coastguard Worker                             CullDistance::Utilities::intToString(i + 1 + clipdistances_array_size));
1391*35238bceSAndroid Build Coastguard Worker                         fetch_sum_setters.append(".0;\n");
1392*35238bceSAndroid Build Coastguard Worker                     }
1393*35238bceSAndroid Build Coastguard Worker 
1394*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_SUM_SETTER"),
1395*35238bceSAndroid Build Coastguard Worker                                                         std::string(fetch_sum_setters));
1396*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1397*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_SUM_DIVIDER"),
1398*35238bceSAndroid Build Coastguard Worker                         std::string(CullDistance::Utilities::intToString(
1399*35238bceSAndroid Build Coastguard Worker                                         (clipdistances_array_size + culldistances_array_size) *
1400*35238bceSAndroid Build Coastguard Worker                                         ((clipdistances_array_size + culldistances_array_size + 1))))
1401*35238bceSAndroid Build Coastguard Worker                             .append(".0"));
1402*35238bceSAndroid Build Coastguard Worker                 }
1403*35238bceSAndroid Build Coastguard Worker                 else
1404*35238bceSAndroid Build Coastguard Worker                 {
1405*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_ASSIGN_RETURN_VALUE"),
1406*35238bceSAndroid Build Coastguard Worker                                                         std::string("#define ASSIGN_RETURN_VALUE 1.0"));
1407*35238bceSAndroid Build Coastguard Worker                 }
1408*35238bceSAndroid Build Coastguard Worker 
1409*35238bceSAndroid Build Coastguard Worker                 break;
1410*35238bceSAndroid Build Coastguard Worker             }
1411*35238bceSAndroid Build Coastguard Worker 
1412*35238bceSAndroid Build Coastguard Worker             case GL_GEOMETRY_SHADER:
1413*35238bceSAndroid Build Coastguard Worker             {
1414*35238bceSAndroid Build Coastguard Worker                 shader_body_string_gs = &shaders_configuration[n_shader_index].body;
1415*35238bceSAndroid Build Coastguard Worker 
1416*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(
1417*35238bceSAndroid Build Coastguard Worker                     shader_source, std::string("TEMPLATE_ASSIGN_CLIP_DISTANCE"),
1418*35238bceSAndroid Build Coastguard Worker                     std::string("gl_ClipDistance[IDX] = gl_in[n_vertex_index].gl_ClipDistance[IDX]"));
1419*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(
1420*35238bceSAndroid Build Coastguard Worker                     shader_source, std::string("TEMPLATE_ASSIGN_CULL_DISTANCE"),
1421*35238bceSAndroid Build Coastguard Worker                     std::string("gl_CullDistance[IDX] = gl_in[n_vertex_index].gl_CullDistance[IDX]"));
1422*35238bceSAndroid Build Coastguard Worker 
1423*35238bceSAndroid Build Coastguard Worker                 switch (primitive_mode)
1424*35238bceSAndroid Build Coastguard Worker                 {
1425*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_LINES:
1426*35238bceSAndroid Build Coastguard Worker                 {
1427*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_IN"),
1428*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(lines)                        in;"));
1429*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_OUT"),
1430*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(line_strip, max_vertices = 2) out;"));
1431*35238bceSAndroid Build Coastguard Worker 
1432*35238bceSAndroid Build Coastguard Worker                     break;
1433*35238bceSAndroid Build Coastguard Worker                 }
1434*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_POINTS:
1435*35238bceSAndroid Build Coastguard Worker                 {
1436*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_IN"),
1437*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(points)                   in;"));
1438*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_OUT"),
1439*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(points, max_vertices = 1) out;"));
1440*35238bceSAndroid Build Coastguard Worker 
1441*35238bceSAndroid Build Coastguard Worker                     break;
1442*35238bceSAndroid Build Coastguard Worker                 }
1443*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_TRIANGLES:
1444*35238bceSAndroid Build Coastguard Worker                 {
1445*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_IN"),
1446*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(triangles)                        in;"));
1447*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_OUT"),
1448*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(triangle_strip, max_vertices = 3) out;"));
1449*35238bceSAndroid Build Coastguard Worker 
1450*35238bceSAndroid Build Coastguard Worker                     break;
1451*35238bceSAndroid Build Coastguard Worker                 }
1452*35238bceSAndroid Build Coastguard Worker                 default:
1453*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Unknown primitive mode");
1454*35238bceSAndroid Build Coastguard Worker                 }
1455*35238bceSAndroid Build Coastguard Worker 
1456*35238bceSAndroid Build Coastguard Worker                 break;
1457*35238bceSAndroid Build Coastguard Worker             }
1458*35238bceSAndroid Build Coastguard Worker 
1459*35238bceSAndroid Build Coastguard Worker             case GL_TESS_CONTROL_SHADER:
1460*35238bceSAndroid Build Coastguard Worker             {
1461*35238bceSAndroid Build Coastguard Worker                 shader_body_string_tc = &shaders_configuration[n_shader_index].body;
1462*35238bceSAndroid Build Coastguard Worker 
1463*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(
1464*35238bceSAndroid Build Coastguard Worker                     shader_source, std::string("TEMPLATE_ASSIGN_CLIP_DISTANCE"),
1465*35238bceSAndroid Build Coastguard Worker                     std::string(
1466*35238bceSAndroid Build Coastguard Worker                         "gl_out[gl_InvocationID].gl_ClipDistance[IDX] = gl_in[gl_InvocationID].gl_ClipDistance[IDX]"));
1467*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(
1468*35238bceSAndroid Build Coastguard Worker                     shader_source, std::string("TEMPLATE_ASSIGN_CULL_DISTANCE"),
1469*35238bceSAndroid Build Coastguard Worker                     std::string(
1470*35238bceSAndroid Build Coastguard Worker                         "gl_out[gl_InvocationID].gl_CullDistance[IDX] = gl_in[gl_InvocationID].gl_CullDistance[IDX]"));
1471*35238bceSAndroid Build Coastguard Worker 
1472*35238bceSAndroid Build Coastguard Worker                 switch (primitive_mode)
1473*35238bceSAndroid Build Coastguard Worker                 {
1474*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_LINES:
1475*35238bceSAndroid Build Coastguard Worker                 {
1476*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_OUT"),
1477*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(vertices = 2) out;"));
1478*35238bceSAndroid Build Coastguard Worker 
1479*35238bceSAndroid Build Coastguard Worker                     break;
1480*35238bceSAndroid Build Coastguard Worker                 }
1481*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_POINTS:
1482*35238bceSAndroid Build Coastguard Worker                 {
1483*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_OUT"),
1484*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(vertices = 1) out;"));
1485*35238bceSAndroid Build Coastguard Worker 
1486*35238bceSAndroid Build Coastguard Worker                     break;
1487*35238bceSAndroid Build Coastguard Worker                 }
1488*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_TRIANGLES:
1489*35238bceSAndroid Build Coastguard Worker                 {
1490*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_OUT"),
1491*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(vertices = 3) out;"));
1492*35238bceSAndroid Build Coastguard Worker 
1493*35238bceSAndroid Build Coastguard Worker                     break;
1494*35238bceSAndroid Build Coastguard Worker                 }
1495*35238bceSAndroid Build Coastguard Worker                 default:
1496*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Unknown primitive mode");
1497*35238bceSAndroid Build Coastguard Worker                 }
1498*35238bceSAndroid Build Coastguard Worker 
1499*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_EXTENSIONS"),
1500*35238bceSAndroid Build Coastguard Worker                                                     std::string("#extension GL_ARB_tessellation_shader: require"));
1501*35238bceSAndroid Build Coastguard Worker                 break;
1502*35238bceSAndroid Build Coastguard Worker             }
1503*35238bceSAndroid Build Coastguard Worker 
1504*35238bceSAndroid Build Coastguard Worker             case GL_TESS_EVALUATION_SHADER:
1505*35238bceSAndroid Build Coastguard Worker             {
1506*35238bceSAndroid Build Coastguard Worker                 shader_body_string_te = &shaders_configuration[n_shader_index].body;
1507*35238bceSAndroid Build Coastguard Worker 
1508*35238bceSAndroid Build Coastguard Worker                 switch (primitive_mode)
1509*35238bceSAndroid Build Coastguard Worker                 {
1510*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_LINES:
1511*35238bceSAndroid Build Coastguard Worker                 {
1512*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_IN"),
1513*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(isolines) in;"));
1514*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1515*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_OUT_FORMULA"),
1516*35238bceSAndroid Build Coastguard Worker                         std::string("mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x)"));
1517*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1518*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_ASSIGN_CLIP_DISTANCE"),
1519*35238bceSAndroid Build Coastguard Worker                         std::string("gl_ClipDistance[IDX] = mix(gl_in[0].gl_ClipDistance[IDX], "
1520*35238bceSAndroid Build Coastguard Worker                                     "gl_in[1].gl_ClipDistance[IDX], gl_TessCoord.x)"));
1521*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1522*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_ASSIGN_CULL_DISTANCE"),
1523*35238bceSAndroid Build Coastguard Worker                         std::string("gl_CullDistance[IDX] = mix(gl_in[0].gl_CullDistance[IDX], "
1524*35238bceSAndroid Build Coastguard Worker                                     "gl_in[1].gl_CullDistance[IDX], gl_TessCoord.x)"));
1525*35238bceSAndroid Build Coastguard Worker 
1526*35238bceSAndroid Build Coastguard Worker                     break;
1527*35238bceSAndroid Build Coastguard Worker                 }
1528*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_POINTS:
1529*35238bceSAndroid Build Coastguard Worker                 {
1530*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_IN"),
1531*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(isolines, point_mode) in;"));
1532*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_OUT_FORMULA"),
1533*35238bceSAndroid Build Coastguard Worker                                                         std::string("gl_in[0].gl_Position"));
1534*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1535*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_ASSIGN_CLIP_DISTANCE"),
1536*35238bceSAndroid Build Coastguard Worker                         std::string("gl_ClipDistance[IDX] = gl_in[0].gl_ClipDistance[IDX]"));
1537*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1538*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_ASSIGN_CULL_DISTANCE"),
1539*35238bceSAndroid Build Coastguard Worker                         std::string("gl_CullDistance[IDX] = gl_in[0].gl_CullDistance[IDX]"));
1540*35238bceSAndroid Build Coastguard Worker 
1541*35238bceSAndroid Build Coastguard Worker                     break;
1542*35238bceSAndroid Build Coastguard Worker                 }
1543*35238bceSAndroid Build Coastguard Worker                 case PRIMITIVE_MODE_TRIANGLES:
1544*35238bceSAndroid Build Coastguard Worker                 {
1545*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_LAYOUT_IN"),
1546*35238bceSAndroid Build Coastguard Worker                                                         std::string("layout(triangles) in;"));
1547*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1548*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_OUT_FORMULA"),
1549*35238bceSAndroid Build Coastguard Worker                         std::string("vec4(mat3(gl_in[0].gl_Position.xyz, gl_in[1].gl_Position.xyz, "
1550*35238bceSAndroid Build Coastguard Worker                                     "gl_in[2].gl_Position.xyz) * gl_TessCoord, 1.0)"));
1551*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1552*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_ASSIGN_CLIP_DISTANCE"),
1553*35238bceSAndroid Build Coastguard Worker                         std::string("gl_ClipDistance[IDX] = dot(vec3(gl_in[0].gl_ClipDistance[IDX], "
1554*35238bceSAndroid Build Coastguard Worker                                     "gl_in[1].gl_ClipDistance[IDX], gl_in[2].gl_ClipDistance[IDX]), gl_TessCoord)"));
1555*35238bceSAndroid Build Coastguard Worker                     CullDistance::Utilities::replaceAll(
1556*35238bceSAndroid Build Coastguard Worker                         shader_source, std::string("TEMPLATE_ASSIGN_CULL_DISTANCE"),
1557*35238bceSAndroid Build Coastguard Worker                         std::string("gl_CullDistance[IDX] = dot(vec3(gl_in[0].gl_CullDistance[IDX], "
1558*35238bceSAndroid Build Coastguard Worker                                     "gl_in[1].gl_CullDistance[IDX], gl_in[2].gl_CullDistance[IDX]), gl_TessCoord)"));
1559*35238bceSAndroid Build Coastguard Worker 
1560*35238bceSAndroid Build Coastguard Worker                     break;
1561*35238bceSAndroid Build Coastguard Worker                 }
1562*35238bceSAndroid Build Coastguard Worker                 default:
1563*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Unknown primitive mode");
1564*35238bceSAndroid Build Coastguard Worker                 }
1565*35238bceSAndroid Build Coastguard Worker 
1566*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_EXTENSIONS"),
1567*35238bceSAndroid Build Coastguard Worker                                                     std::string("#extension GL_ARB_tessellation_shader: require"));
1568*35238bceSAndroid Build Coastguard Worker                 break;
1569*35238bceSAndroid Build Coastguard Worker             }
1570*35238bceSAndroid Build Coastguard Worker 
1571*35238bceSAndroid Build Coastguard Worker             case GL_VERTEX_SHADER:
1572*35238bceSAndroid Build Coastguard Worker             {
1573*35238bceSAndroid Build Coastguard Worker                 shader_body_string_vs = &shaders_configuration[n_shader_index].body;
1574*35238bceSAndroid Build Coastguard Worker 
1575*35238bceSAndroid Build Coastguard Worker                 /* Specify input data size for clipdistances data */
1576*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_CLIPDISTANCE_INPUT_SIZE"),
1577*35238bceSAndroid Build Coastguard Worker                                                     CullDistance::Utilities::intToString(clipdistances_input_size));
1578*35238bceSAndroid Build Coastguard Worker 
1579*35238bceSAndroid Build Coastguard Worker                 /* Specify input data size for culldistances data */
1580*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_CULLDISTANCE_INPUT_SIZE"),
1581*35238bceSAndroid Build Coastguard Worker                                                     CullDistance::Utilities::intToString(culldistances_input_size));
1582*35238bceSAndroid Build Coastguard Worker 
1583*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_ASSIGN_CLIP_DISTANCE"),
1584*35238bceSAndroid Build Coastguard Worker                                                     std::string("gl_ClipDistance[IDX] = clipdistance_data[IDX]"));
1585*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_ASSIGN_CULL_DISTANCE"),
1586*35238bceSAndroid Build Coastguard Worker                                                     std::string("gl_CullDistance[IDX] = culldistance_data[IDX]"));
1587*35238bceSAndroid Build Coastguard Worker 
1588*35238bceSAndroid Build Coastguard Worker                 break;
1589*35238bceSAndroid Build Coastguard Worker             }
1590*35238bceSAndroid Build Coastguard Worker 
1591*35238bceSAndroid Build Coastguard Worker             default:
1592*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Unknown shader type");
1593*35238bceSAndroid Build Coastguard Worker             }
1594*35238bceSAndroid Build Coastguard Worker 
1595*35238bceSAndroid Build Coastguard Worker             /* Clear out in case no specific exts were needed */
1596*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_EXTENSIONS"), std::string(""));
1597*35238bceSAndroid Build Coastguard Worker 
1598*35238bceSAndroid Build Coastguard Worker             /* Adjust clipdistances declaration */
1599*35238bceSAndroid Build Coastguard Worker             if (redeclare_clipdistances && clipdistances_array_size > 0)
1600*35238bceSAndroid Build Coastguard Worker             {
1601*35238bceSAndroid Build Coastguard Worker                 if (shaders_configuration[n_shader_index].type == GL_FRAGMENT_SHADER)
1602*35238bceSAndroid Build Coastguard Worker                 {
1603*35238bceSAndroid Build Coastguard Worker                     if (fetch_culldistance_from_fs)
1604*35238bceSAndroid Build Coastguard Worker                     {
1605*35238bceSAndroid Build Coastguard Worker                         clipdistance_array_declaration =
1606*35238bceSAndroid Build Coastguard Worker                             std::string("in float gl_ClipDistance[") +
1607*35238bceSAndroid Build Coastguard Worker                             CullDistance::Utilities::intToString(clipdistances_array_size) + std::string("];");
1608*35238bceSAndroid Build Coastguard Worker                     }
1609*35238bceSAndroid Build Coastguard Worker                 }
1610*35238bceSAndroid Build Coastguard Worker                 else if (shaders_configuration[n_shader_index].type == GL_TESS_CONTROL_SHADER)
1611*35238bceSAndroid Build Coastguard Worker                 {
1612*35238bceSAndroid Build Coastguard Worker                     clipdistance_array_declaration = std::string("float gl_ClipDistance[") +
1613*35238bceSAndroid Build Coastguard Worker                                                      CullDistance::Utilities::intToString(clipdistances_array_size) +
1614*35238bceSAndroid Build Coastguard Worker                                                      std::string("];");
1615*35238bceSAndroid Build Coastguard Worker                 }
1616*35238bceSAndroid Build Coastguard Worker                 else
1617*35238bceSAndroid Build Coastguard Worker                 {
1618*35238bceSAndroid Build Coastguard Worker                     clipdistance_array_declaration = std::string("out float gl_ClipDistance[") +
1619*35238bceSAndroid Build Coastguard Worker                                                      CullDistance::Utilities::intToString(clipdistances_array_size) +
1620*35238bceSAndroid Build Coastguard Worker                                                      std::string("];");
1621*35238bceSAndroid Build Coastguard Worker                     clipdistance_in_array_declaration = std::string("in float gl_ClipDistance[") +
1622*35238bceSAndroid Build Coastguard Worker                                                         CullDistance::Utilities::intToString(clipdistances_array_size) +
1623*35238bceSAndroid Build Coastguard Worker                                                         std::string("];");
1624*35238bceSAndroid Build Coastguard Worker                 }
1625*35238bceSAndroid Build Coastguard Worker             }
1626*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_REDECLARE_CLIPDISTANCE"),
1627*35238bceSAndroid Build Coastguard Worker                                                 clipdistance_array_declaration);
1628*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_REDECLARE_IN_CLIPDISTANCE"),
1629*35238bceSAndroid Build Coastguard Worker                                                 clipdistance_in_array_declaration);
1630*35238bceSAndroid Build Coastguard Worker 
1631*35238bceSAndroid Build Coastguard Worker             /* Adjust culldistances declaration */
1632*35238bceSAndroid Build Coastguard Worker             if (redeclare_culldistances && culldistances_array_size > 0)
1633*35238bceSAndroid Build Coastguard Worker             {
1634*35238bceSAndroid Build Coastguard Worker                 if (shaders_configuration[n_shader_index].type == GL_FRAGMENT_SHADER)
1635*35238bceSAndroid Build Coastguard Worker                 {
1636*35238bceSAndroid Build Coastguard Worker                     if (fetch_culldistance_from_fs)
1637*35238bceSAndroid Build Coastguard Worker                     {
1638*35238bceSAndroid Build Coastguard Worker                         culldistance_array_declaration =
1639*35238bceSAndroid Build Coastguard Worker                             std::string("in float gl_CullDistance[") +
1640*35238bceSAndroid Build Coastguard Worker                             CullDistance::Utilities::intToString(culldistances_array_size) + std::string("];");
1641*35238bceSAndroid Build Coastguard Worker                     }
1642*35238bceSAndroid Build Coastguard Worker                 }
1643*35238bceSAndroid Build Coastguard Worker                 else if (shaders_configuration[n_shader_index].type == GL_TESS_CONTROL_SHADER)
1644*35238bceSAndroid Build Coastguard Worker                 {
1645*35238bceSAndroid Build Coastguard Worker                     culldistance_array_declaration = std::string("float gl_CullDistance[") +
1646*35238bceSAndroid Build Coastguard Worker                                                      CullDistance::Utilities::intToString(culldistances_array_size) +
1647*35238bceSAndroid Build Coastguard Worker                                                      std::string("];");
1648*35238bceSAndroid Build Coastguard Worker                 }
1649*35238bceSAndroid Build Coastguard Worker                 else
1650*35238bceSAndroid Build Coastguard Worker                 {
1651*35238bceSAndroid Build Coastguard Worker                     culldistance_array_declaration = std::string("out float gl_CullDistance[") +
1652*35238bceSAndroid Build Coastguard Worker                                                      CullDistance::Utilities::intToString(culldistances_array_size) +
1653*35238bceSAndroid Build Coastguard Worker                                                      std::string("];");
1654*35238bceSAndroid Build Coastguard Worker                     culldistance_in_array_declaration = std::string("in float gl_CullDistance[") +
1655*35238bceSAndroid Build Coastguard Worker                                                         CullDistance::Utilities::intToString(culldistances_array_size) +
1656*35238bceSAndroid Build Coastguard Worker                                                         std::string("];");
1657*35238bceSAndroid Build Coastguard Worker                 }
1658*35238bceSAndroid Build Coastguard Worker             }
1659*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_REDECLARE_CULLDISTANCE"),
1660*35238bceSAndroid Build Coastguard Worker                                                 culldistance_array_declaration);
1661*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_REDECLARE_IN_CULLDISTANCE"),
1662*35238bceSAndroid Build Coastguard Worker                                                 culldistance_in_array_declaration);
1663*35238bceSAndroid Build Coastguard Worker 
1664*35238bceSAndroid Build Coastguard Worker             /* Adjust clip/cull distances setters */
1665*35238bceSAndroid Build Coastguard Worker             if (dynamic_index_writes)
1666*35238bceSAndroid Build Coastguard Worker             {
1667*35238bceSAndroid Build Coastguard Worker                 array_setters = dynamic_array_setters;
1668*35238bceSAndroid Build Coastguard Worker 
1669*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(array_setters, std::string("TEMPLATE_N_GL_CLIPDISTANCE_ENTRIES"),
1670*35238bceSAndroid Build Coastguard Worker                                                     CullDistance::Utilities::intToString(clipdistances_array_size));
1671*35238bceSAndroid Build Coastguard Worker                 CullDistance::Utilities::replaceAll(array_setters, std::string("TEMPLATE_N_GL_CULLDISTANCE_ENTRIES"),
1672*35238bceSAndroid Build Coastguard Worker                                                     CullDistance::Utilities::intToString(culldistances_array_size));
1673*35238bceSAndroid Build Coastguard Worker             }
1674*35238bceSAndroid Build Coastguard Worker             else
1675*35238bceSAndroid Build Coastguard Worker             {
1676*35238bceSAndroid Build Coastguard Worker                 std::stringstream static_array_setters_sstream;
1677*35238bceSAndroid Build Coastguard Worker 
1678*35238bceSAndroid Build Coastguard Worker                 static_array_setters_sstream << "\n";
1679*35238bceSAndroid Build Coastguard Worker 
1680*35238bceSAndroid Build Coastguard Worker                 for (glw::GLuint clipdistances_array_entry = 0; clipdistances_array_entry < clipdistances_array_size;
1681*35238bceSAndroid Build Coastguard Worker                      ++clipdistances_array_entry)
1682*35238bceSAndroid Build Coastguard Worker                 {
1683*35238bceSAndroid Build Coastguard Worker                     static_array_setters_sstream << "        ASSIGN_CLIP_DISTANCE(" << clipdistances_array_entry
1684*35238bceSAndroid Build Coastguard Worker                                                  << ");\n";
1685*35238bceSAndroid Build Coastguard Worker                 }
1686*35238bceSAndroid Build Coastguard Worker 
1687*35238bceSAndroid Build Coastguard Worker                 static_array_setters_sstream << "\n";
1688*35238bceSAndroid Build Coastguard Worker 
1689*35238bceSAndroid Build Coastguard Worker                 for (glw::GLuint culldistances_array_entry = 0; culldistances_array_entry < culldistances_array_size;
1690*35238bceSAndroid Build Coastguard Worker                      ++culldistances_array_entry)
1691*35238bceSAndroid Build Coastguard Worker                 {
1692*35238bceSAndroid Build Coastguard Worker                     static_array_setters_sstream << "        ASSIGN_CULL_DISTANCE(" << culldistances_array_entry
1693*35238bceSAndroid Build Coastguard Worker                                                  << ");\n";
1694*35238bceSAndroid Build Coastguard Worker                 }
1695*35238bceSAndroid Build Coastguard Worker 
1696*35238bceSAndroid Build Coastguard Worker                 array_setters = static_array_setters_sstream.str();
1697*35238bceSAndroid Build Coastguard Worker             }
1698*35238bceSAndroid Build Coastguard Worker 
1699*35238bceSAndroid Build Coastguard Worker             CullDistance::Utilities::replaceAll(shader_source, std::string("TEMPLATE_ARRAY_SETTERS"), array_setters);
1700*35238bceSAndroid Build Coastguard Worker         }
1701*35238bceSAndroid Build Coastguard Worker     }
1702*35238bceSAndroid Build Coastguard Worker 
1703*35238bceSAndroid Build Coastguard Worker     /* Build the geometry shader */
1704*35238bceSAndroid Build Coastguard Worker     CullDistance::Utilities::buildProgram(
1705*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions(), m_testCtx, DE_NULL, /* Compute shader                    */
1706*35238bceSAndroid Build Coastguard Worker         shader_body_string_fs != DE_NULL ? shader_body_string_fs->c_str() :
1707*35238bceSAndroid Build Coastguard Worker                                            DE_NULL, /* Fragment shader                   */
1708*35238bceSAndroid Build Coastguard Worker         shader_body_string_gs != DE_NULL ? shader_body_string_gs->c_str() :
1709*35238bceSAndroid Build Coastguard Worker                                            DE_NULL, /* Geometry shader                   */
1710*35238bceSAndroid Build Coastguard Worker         shader_body_string_tc != DE_NULL ? shader_body_string_tc->c_str() :
1711*35238bceSAndroid Build Coastguard Worker                                            DE_NULL, /* Tesselation control shader        */
1712*35238bceSAndroid Build Coastguard Worker         shader_body_string_te != DE_NULL ? shader_body_string_te->c_str() :
1713*35238bceSAndroid Build Coastguard Worker                                            DE_NULL, /* Tesselation evaluation shader     */
1714*35238bceSAndroid Build Coastguard Worker         shader_body_string_vs != DE_NULL ? shader_body_string_vs->c_str() :
1715*35238bceSAndroid Build Coastguard Worker                                            DE_NULL, /* Vertex shader                     */
1716*35238bceSAndroid Build Coastguard Worker         0,                                          /* Transform feedback varyings count */
1717*35238bceSAndroid Build Coastguard Worker         DE_NULL,                                    /* Transform feedback varyings       */
1718*35238bceSAndroid Build Coastguard Worker         &m_po_id                                    /* Program object id                 */
1719*35238bceSAndroid Build Coastguard Worker     );
1720*35238bceSAndroid Build Coastguard Worker }
1721*35238bceSAndroid Build Coastguard Worker 
1722*35238bceSAndroid Build Coastguard Worker /** Generates primitive data required to test a case with specified
1723*35238bceSAndroid Build Coastguard Worker  *  gl_ClipDistance and glCullDistance array sizes for specified
1724*35238bceSAndroid Build Coastguard Worker  *  primitive mode. Generated primitive data is stored in m_bo_data
1725*35238bceSAndroid Build Coastguard Worker  *  as well uploaded into buffer specified in m_bo_id buffer.
1726*35238bceSAndroid Build Coastguard Worker  *  Also the procedure binds vertex attribute locations to
1727*35238bceSAndroid Build Coastguard Worker  *  program object m_po_id.
1728*35238bceSAndroid Build Coastguard Worker  *
1729*35238bceSAndroid Build Coastguard Worker  *  @param clipdistances_array_size gl_ClipDistance array size. Can be 0.
1730*35238bceSAndroid Build Coastguard Worker  *  @param culldistances_array_size gl_CullDistance array size. Can be 0.
1731*35238bceSAndroid Build Coastguard Worker  *  @param _primitive_mode          Primitives to be generated. Can be:
1732*35238bceSAndroid Build Coastguard Worker  *                                  PRIMITIVE_MODE_POINTS,
1733*35238bceSAndroid Build Coastguard Worker  *                                  PRIMITIVE_MODE_LINES,
1734*35238bceSAndroid Build Coastguard Worker  *                                  PRIMITIVE_MODE_TRIANGLES.
1735*35238bceSAndroid Build Coastguard Worker  */
configureVAO(glw::GLuint clipdistances_array_size,glw::GLuint culldistances_array_size,_primitive_mode primitive_mode)1736*35238bceSAndroid Build Coastguard Worker void CullDistance::FunctionalTest::configureVAO(glw::GLuint clipdistances_array_size,
1737*35238bceSAndroid Build Coastguard Worker                                                 glw::GLuint culldistances_array_size, _primitive_mode primitive_mode)
1738*35238bceSAndroid Build Coastguard Worker {
1739*35238bceSAndroid Build Coastguard Worker     /* Detailed test description.
1740*35238bceSAndroid Build Coastguard Worker      *
1741*35238bceSAndroid Build Coastguard Worker      * configureVAO() generates primitives layouted in grid. Primitve
1742*35238bceSAndroid Build Coastguard Worker      * consists of up to 3 vertices and each vertex is accompanied by:
1743*35238bceSAndroid Build Coastguard Worker      * - array of clipdistances (clipdistances_array_size floats);
1744*35238bceSAndroid Build Coastguard Worker      * - array of culldistances (culldistances_array_size floats);
1745*35238bceSAndroid Build Coastguard Worker      * - rendering position coordinates (x and y);
1746*35238bceSAndroid Build Coastguard Worker      * - check position coordinates (x and y).
1747*35238bceSAndroid Build Coastguard Worker      *
1748*35238bceSAndroid Build Coastguard Worker      * The grid has following layout:
1749*35238bceSAndroid Build Coastguard Worker      *
1750*35238bceSAndroid Build Coastguard Worker      *     Grid                       |         gl_CullDistance[x]         |
1751*35238bceSAndroid Build Coastguard Worker      *                                |  0 .. culldistances_array_size - 1 |
1752*35238bceSAndroid Build Coastguard Worker      *                                |  0th  |  1st  |  2nd  | .......... |
1753*35238bceSAndroid Build Coastguard Worker      *     ---------------------------+-------+-------+-------+------------+
1754*35238bceSAndroid Build Coastguard Worker      *     0th  gl_ClipDistance       |Subgrid|Subgrid|Subgrid| .......... |
1755*35238bceSAndroid Build Coastguard Worker      *     1st  gl_ClipDistance       |Subgrid|Subgrid|Subgrid| .......... |
1756*35238bceSAndroid Build Coastguard Worker      *     ...                        |  ...  |  ...  |  ...  | .......... |
1757*35238bceSAndroid Build Coastguard Worker      *     y-th gl_ClipDistance       |Subgrid|Subgrid|Subgrid| .......... |
1758*35238bceSAndroid Build Coastguard Worker      *     ...                        |  ...  |  ...  |  ...  | .......... |
1759*35238bceSAndroid Build Coastguard Worker      *     clipdistances_array_size-1 |Subgrid|Subgrid|Subgrid| .......... |
1760*35238bceSAndroid Build Coastguard Worker      *
1761*35238bceSAndroid Build Coastguard Worker      * Each grid cell contains subgrid of 3*3 items in size with following
1762*35238bceSAndroid Build Coastguard Worker      * structure:
1763*35238bceSAndroid Build Coastguard Worker      *
1764*35238bceSAndroid Build Coastguard Worker      *     Subgrid        |        x-th gl_CullDistance test           |
1765*35238bceSAndroid Build Coastguard Worker      *                    |                                            |
1766*35238bceSAndroid Build Coastguard Worker      *     y-th           | all vertices | 0th vertex   | all vertices |
1767*35238bceSAndroid Build Coastguard Worker      *     gl_ClipDistance| in primitive | in primitive | in primitive |
1768*35238bceSAndroid Build Coastguard Worker      *     tests          | dist[x] > 0  | dist[x] < 0  | dist[x] < 0  |
1769*35238bceSAndroid Build Coastguard Worker      *     ---------------+--------------+--------------+--------------+
1770*35238bceSAndroid Build Coastguard Worker      *        all vertices| primitive #0 | primitive #1 | primitive #2 |
1771*35238bceSAndroid Build Coastguard Worker      *        in primitive|              |              |              |
1772*35238bceSAndroid Build Coastguard Worker      *        dist[y] > 0 |   visible    |   visible    |    culled    |
1773*35238bceSAndroid Build Coastguard Worker      *     ---------------+--------------+--------------+--------------+
1774*35238bceSAndroid Build Coastguard Worker      *        0th vertex  | primitive #3 | primitive #4 | primitive #5 |
1775*35238bceSAndroid Build Coastguard Worker      *        in primitive|  0th vertex  |  0th vertex  |              |
1776*35238bceSAndroid Build Coastguard Worker      *        dist[y] < 0 |   clipped    |   clipped    |    culled    |
1777*35238bceSAndroid Build Coastguard Worker      *     ---------------+--------------+--------------+--------------+
1778*35238bceSAndroid Build Coastguard Worker      *        all vertices| primitive #6 | primitive #7 | primitive #8 |
1779*35238bceSAndroid Build Coastguard Worker      *        in primitive|              |              |              |
1780*35238bceSAndroid Build Coastguard Worker      *        dist[y] < 0 |   clipped    |   clipped    |    culled    |
1781*35238bceSAndroid Build Coastguard Worker      *     ---------------+--------------+--------------+--------------+
1782*35238bceSAndroid Build Coastguard Worker      *
1783*35238bceSAndroid Build Coastguard Worker      * Expected rendering result is specified in cell bottom.
1784*35238bceSAndroid Build Coastguard Worker      * It can be one of the following:
1785*35238bceSAndroid Build Coastguard Worker      * - "visible" means the primitive is not affected neither by gl_CullDistance
1786*35238bceSAndroid Build Coastguard Worker      *             nor by gl_ClipDistance and rendered as a whole;
1787*35238bceSAndroid Build Coastguard Worker      * - "clipped" for the vertex means the vertex is not rendered, while other
1788*35238bceSAndroid Build Coastguard Worker      *             primitive vertices and some filling fragments are rendered;
1789*35238bceSAndroid Build Coastguard Worker      * - "clipped" for primitive means none of primitive vertices and fragments
1790*35238bceSAndroid Build Coastguard Worker      *             are rendered and thus primitive is not rendered and is invisible;
1791*35238bceSAndroid Build Coastguard Worker      * - "culled"  means, that neither primitive vertices, nor primitive filling
1792*35238bceSAndroid Build Coastguard Worker      *             fragments are rendered (primitive is invisible).
1793*35238bceSAndroid Build Coastguard Worker      *
1794*35238bceSAndroid Build Coastguard Worker      * All subgrid items contain same primitive rendered. Depending on
1795*35238bceSAndroid Build Coastguard Worker      * test case running it would be either triangle, or line, or point:
1796*35238bceSAndroid Build Coastguard Worker      *
1797*35238bceSAndroid Build Coastguard Worker      *     triangle    line        point
1798*35238bceSAndroid Build Coastguard Worker      *     8x8 box     8x8 box     3x3 box
1799*35238bceSAndroid Build Coastguard Worker      *     ........    ........    ...
1800*35238bceSAndroid Build Coastguard Worker      *     .0----2.    .0......    .0.
1801*35238bceSAndroid Build Coastguard Worker      *     ..\@@@|.    ..\.....    ...
1802*35238bceSAndroid Build Coastguard Worker      *     ...\@@|.    ...\....
1803*35238bceSAndroid Build Coastguard Worker      *     ....\@|.    ....\...
1804*35238bceSAndroid Build Coastguard Worker      *     .....\|.    .....\..
1805*35238bceSAndroid Build Coastguard Worker      *     ......1.    ......1.
1806*35238bceSAndroid Build Coastguard Worker      *     ........    ........
1807*35238bceSAndroid Build Coastguard Worker      *
1808*35238bceSAndroid Build Coastguard Worker      *     where 0 - is a 0th vertex primitive
1809*35238bceSAndroid Build Coastguard Worker      *           1 - is a 1st vertex primitive
1810*35238bceSAndroid Build Coastguard Worker      *           2 - is a 2nd vertex primitive
1811*35238bceSAndroid Build Coastguard Worker      *
1812*35238bceSAndroid Build Coastguard Worker      * The culldistances_array_size can be 0. In that case, grid height
1813*35238bceSAndroid Build Coastguard Worker      * is assumed equal to 1, but 0 glCullDistances is specified.
1814*35238bceSAndroid Build Coastguard Worker      * Similar handled clipdistances_array_size.
1815*35238bceSAndroid Build Coastguard Worker      *
1816*35238bceSAndroid Build Coastguard Worker      * The data generated is used and checked in executeRenderTest().
1817*35238bceSAndroid Build Coastguard Worker      * After rendering each primitive vertex is tested:
1818*35238bceSAndroid Build Coastguard Worker      * - if it is rendered, if it have to be rendered (according distance);
1819*35238bceSAndroid Build Coastguard Worker      * - if it is not rendered, if it have to be not rendered (according distance).
1820*35238bceSAndroid Build Coastguard Worker      * Due to "top-left" rasterization rule check position is
1821*35238bceSAndroid Build Coastguard Worker      * different from rendering vertex position.
1822*35238bceSAndroid Build Coastguard Worker      *
1823*35238bceSAndroid Build Coastguard Worker      * Also one pixel width guarding box is checked to be clear.
1824*35238bceSAndroid Build Coastguard Worker      */
1825*35238bceSAndroid Build Coastguard Worker 
1826*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1827*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_sub_grid_cells = 3; /* Tested distance is positive for all vertices in the primitive;
1828*35238bceSAndroid Build Coastguard Worker                                              * Tested distance is negative for 0th vertex in the primitive;
1829*35238bceSAndroid Build Coastguard Worker                                              * Tested distance is negative for all vertices in the primitive;
1830*35238bceSAndroid Build Coastguard Worker                                              */
1831*35238bceSAndroid Build Coastguard Worker     const glw::GLuint sub_grid_cell_size = ((primitive_mode == PRIMITIVE_MODE_LINES)  ? 8 :
1832*35238bceSAndroid Build Coastguard Worker                                             (primitive_mode == PRIMITIVE_MODE_POINTS) ? 3 :
1833*35238bceSAndroid Build Coastguard Worker                                                                                         8);
1834*35238bceSAndroid Build Coastguard Worker 
1835*35238bceSAndroid Build Coastguard Worker     const glw::GLuint grid_cell_size       = n_sub_grid_cells * sub_grid_cell_size;
1836*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_primitive_vertices = ((primitive_mode == PRIMITIVE_MODE_LINES)  ? 2 :
1837*35238bceSAndroid Build Coastguard Worker                                               (primitive_mode == PRIMITIVE_MODE_POINTS) ? 1 :
1838*35238bceSAndroid Build Coastguard Worker                                                                                           3);
1839*35238bceSAndroid Build Coastguard Worker 
1840*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_grid_cells_x               = culldistances_array_size != 0 ? culldistances_array_size : 1;
1841*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_grid_cells_y               = clipdistances_array_size != 0 ? clipdistances_array_size : 1;
1842*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_pervertex_float_attributes = clipdistances_array_size + culldistances_array_size +
1843*35238bceSAndroid Build Coastguard Worker                                                      2 /* vertex' draw x, y */ + 2 /* vertex' checkpoint x, y */;
1844*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_primitives_total     = n_grid_cells_x * n_sub_grid_cells * n_grid_cells_y * n_sub_grid_cells;
1845*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_vertices_total       = n_primitives_total * n_primitive_vertices;
1846*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_line_draw_x[2] = {
1847*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 1}; /* vertex x offsets to subgrid cell origin for line primitive     */
1848*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_line_draw_y[2] = {
1849*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 1}; /* vertex y offsets to subgrid cell origin for line primitive     */
1850*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_line_checkpoint_x[2] = {
1851*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 2}; /* pixel x offsets to subgrid cell origin for line primitive      */
1852*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_line_checkpoint_y[2] = {
1853*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 2}; /* pixel y offsets to subgrid cell origin for line primitive      */
1854*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_point_draw_x[1] = {
1855*35238bceSAndroid Build Coastguard Worker         1}; /* vertex x offsets to subgrid cell origin for point primitive    */
1856*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_point_draw_y[1] = {
1857*35238bceSAndroid Build Coastguard Worker         1}; /* vertex y offsets to subgrid cell origin for point primitive    */
1858*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_point_checkpoint_x[1] = {
1859*35238bceSAndroid Build Coastguard Worker         1}; /* pixel x offsets to subgrid cell origin for point primitive     */
1860*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_point_checkpoint_y[1] = {
1861*35238bceSAndroid Build Coastguard Worker         1}; /* pixel y offsets to subgrid cell origin for point primitive     */
1862*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_triangle_draw_x[3] = {
1863*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 1,
1864*35238bceSAndroid Build Coastguard Worker         sub_grid_cell_size - 1}; /* vertex x offsets to subgrid cell origin for triangle primitive */
1865*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_triangle_draw_y[3] = {
1866*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 1, 1}; /* vertex y offsets to subgrid cell origin for triangle primitive */
1867*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_triangle_checkpoint_x[3] = {
1868*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 2,
1869*35238bceSAndroid Build Coastguard Worker         sub_grid_cell_size - 2}; /* pixel x offsets to subgrid cell origin for triangle primitive  */
1870*35238bceSAndroid Build Coastguard Worker     const glw::GLuint offsets_triangle_checkpoint_y[3] = {
1871*35238bceSAndroid Build Coastguard Worker         1, sub_grid_cell_size - 2, 1}; /* pixel y offsets to subgrid cell origin for triangle primitive  */
1872*35238bceSAndroid Build Coastguard Worker     const glw::GLfloat offsets_pixel_center_x = (primitive_mode == PRIMITIVE_MODE_POINTS) ? 0.5f : 0;
1873*35238bceSAndroid Build Coastguard Worker     const glw::GLfloat offsets_pixel_center_y = (primitive_mode == PRIMITIVE_MODE_POINTS) ? 0.5f : 0;
1874*35238bceSAndroid Build Coastguard Worker     /* Clear data left from previous tests. */
1875*35238bceSAndroid Build Coastguard Worker     m_bo_data.clear();
1876*35238bceSAndroid Build Coastguard Worker 
1877*35238bceSAndroid Build Coastguard Worker     /* No data to render */
1878*35238bceSAndroid Build Coastguard Worker     m_render_primitives = 0;
1879*35238bceSAndroid Build Coastguard Worker     m_render_vertices   = 0;
1880*35238bceSAndroid Build Coastguard Worker 
1881*35238bceSAndroid Build Coastguard Worker     /* Preallocate space for bo_points_count */
1882*35238bceSAndroid Build Coastguard Worker     m_bo_data.reserve(n_vertices_total * n_pervertex_float_attributes);
1883*35238bceSAndroid Build Coastguard Worker 
1884*35238bceSAndroid Build Coastguard Worker     /* Generate test data for cell_y-th clip distance */
1885*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint cell_y = 0; cell_y < n_grid_cells_y; cell_y++)
1886*35238bceSAndroid Build Coastguard Worker     {
1887*35238bceSAndroid Build Coastguard Worker         /* Generate test data for cell_x-th cull distance */
1888*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint cell_x = 0; cell_x < n_grid_cells_x; cell_x++)
1889*35238bceSAndroid Build Coastguard Worker         {
1890*35238bceSAndroid Build Coastguard Worker             /* Check clip distance sub cases:
1891*35238bceSAndroid Build Coastguard Worker              * 0. Tested distance is positive for all vertices in the primitive;
1892*35238bceSAndroid Build Coastguard Worker              * 1. Tested distance is negative for 0th vertex in the primitive;
1893*35238bceSAndroid Build Coastguard Worker              * 2. Tested distance is negative for all vertices in the primitive;
1894*35238bceSAndroid Build Coastguard Worker              */
1895*35238bceSAndroid Build Coastguard Worker             for (glw::GLuint n_sub_cell_y = 0; n_sub_cell_y < n_sub_grid_cells; n_sub_cell_y++)
1896*35238bceSAndroid Build Coastguard Worker             {
1897*35238bceSAndroid Build Coastguard Worker                 /* Check cull distance sub cases:
1898*35238bceSAndroid Build Coastguard Worker                  * 0. Tested distance is positive for all vertices in the primitive;
1899*35238bceSAndroid Build Coastguard Worker                  * 1. Tested distance is negative for 0th vertex in the primitive;
1900*35238bceSAndroid Build Coastguard Worker                  * 2. Tested distance is negative for all vertices in the primitive;
1901*35238bceSAndroid Build Coastguard Worker                  */
1902*35238bceSAndroid Build Coastguard Worker                 for (glw::GLuint n_sub_cell_x = 0; n_sub_cell_x < n_sub_grid_cells; n_sub_cell_x++)
1903*35238bceSAndroid Build Coastguard Worker                 {
1904*35238bceSAndroid Build Coastguard Worker                     /* Generate vertices in primitive */
1905*35238bceSAndroid Build Coastguard Worker                     for (glw::GLuint n_primitive_vertex = 0; n_primitive_vertex < n_primitive_vertices;
1906*35238bceSAndroid Build Coastguard Worker                          n_primitive_vertex++)
1907*35238bceSAndroid Build Coastguard Worker                     {
1908*35238bceSAndroid Build Coastguard Worker                         /* Fill in clipdistance array for the n_primitive_vertex vertex in primitive */
1909*35238bceSAndroid Build Coastguard Worker                         for (glw::GLuint n_clipdistance_entry = 0; n_clipdistance_entry < clipdistances_array_size;
1910*35238bceSAndroid Build Coastguard Worker                              n_clipdistance_entry++)
1911*35238bceSAndroid Build Coastguard Worker                         {
1912*35238bceSAndroid Build Coastguard Worker                             glw::GLfloat distance_value = 0.0f;
1913*35238bceSAndroid Build Coastguard Worker                             bool negative               = true;
1914*35238bceSAndroid Build Coastguard Worker 
1915*35238bceSAndroid Build Coastguard Worker                             /* Special approach to tested clipdistance entry. */
1916*35238bceSAndroid Build Coastguard Worker                             if (n_clipdistance_entry == cell_y)
1917*35238bceSAndroid Build Coastguard Worker                             {
1918*35238bceSAndroid Build Coastguard Worker                                 /* The primitive vertex should be affected by the clip distance */
1919*35238bceSAndroid Build Coastguard Worker                                 switch (n_sub_cell_y)
1920*35238bceSAndroid Build Coastguard Worker                                 {
1921*35238bceSAndroid Build Coastguard Worker                                 case 0:
1922*35238bceSAndroid Build Coastguard Worker                                 {
1923*35238bceSAndroid Build Coastguard Worker                                     /* subgrid row 0: all primitive vertices have tested distance value positive */
1924*35238bceSAndroid Build Coastguard Worker                                     negative = false;
1925*35238bceSAndroid Build Coastguard Worker 
1926*35238bceSAndroid Build Coastguard Worker                                     break;
1927*35238bceSAndroid Build Coastguard Worker                                 }
1928*35238bceSAndroid Build Coastguard Worker                                 case 1:
1929*35238bceSAndroid Build Coastguard Worker                                 {
1930*35238bceSAndroid Build Coastguard Worker                                     /* subgrid row 1: tested distance value for 0th primitive vertex is negative,
1931*35238bceSAndroid Build Coastguard Worker                                      all other primitive vertices have tested distance value positive */
1932*35238bceSAndroid Build Coastguard Worker                                     negative = (n_primitive_vertex == 0) ? true : false;
1933*35238bceSAndroid Build Coastguard Worker 
1934*35238bceSAndroid Build Coastguard Worker                                     break;
1935*35238bceSAndroid Build Coastguard Worker                                 }
1936*35238bceSAndroid Build Coastguard Worker                                 case 2:
1937*35238bceSAndroid Build Coastguard Worker                                 {
1938*35238bceSAndroid Build Coastguard Worker                                     /* subgrid row 2: tested distance value is negative for all primitive vertices */
1939*35238bceSAndroid Build Coastguard Worker                                     negative = true;
1940*35238bceSAndroid Build Coastguard Worker 
1941*35238bceSAndroid Build Coastguard Worker                                     break;
1942*35238bceSAndroid Build Coastguard Worker                                 }
1943*35238bceSAndroid Build Coastguard Worker                                 default:
1944*35238bceSAndroid Build Coastguard Worker                                     TCU_FAIL("Invalid subgrid cell index");
1945*35238bceSAndroid Build Coastguard Worker                                 }
1946*35238bceSAndroid Build Coastguard Worker 
1947*35238bceSAndroid Build Coastguard Worker                                 distance_value = (negative ? -1.0f : 1.0f) * glw::GLfloat(n_clipdistance_entry + 1);
1948*35238bceSAndroid Build Coastguard Worker                             }
1949*35238bceSAndroid Build Coastguard Worker                             else
1950*35238bceSAndroid Build Coastguard Worker                             {
1951*35238bceSAndroid Build Coastguard Worker                                 /* For clip distances other than tested: assign positive value to avoid its influence. */
1952*35238bceSAndroid Build Coastguard Worker                                 distance_value = glw::GLfloat(clipdistances_array_size + n_clipdistance_entry + 1);
1953*35238bceSAndroid Build Coastguard Worker                             }
1954*35238bceSAndroid Build Coastguard Worker 
1955*35238bceSAndroid Build Coastguard Worker                             m_bo_data.push_back(distance_value / glw::GLfloat(clipdistances_array_size));
1956*35238bceSAndroid Build Coastguard Worker                         } /* for (all gl_ClipDistance[] array values) */
1957*35238bceSAndroid Build Coastguard Worker 
1958*35238bceSAndroid Build Coastguard Worker                         /* Fill in culldistance array for the n_primitive_vertex vertex in primitive */
1959*35238bceSAndroid Build Coastguard Worker                         for (glw::GLuint n_culldistance_entry = 0; n_culldistance_entry < culldistances_array_size;
1960*35238bceSAndroid Build Coastguard Worker                              n_culldistance_entry++)
1961*35238bceSAndroid Build Coastguard Worker                         {
1962*35238bceSAndroid Build Coastguard Worker                             glw::GLfloat distance_value = 0.0f;
1963*35238bceSAndroid Build Coastguard Worker                             bool negative               = true;
1964*35238bceSAndroid Build Coastguard Worker 
1965*35238bceSAndroid Build Coastguard Worker                             /* Special approach to tested culldistance entry. */
1966*35238bceSAndroid Build Coastguard Worker                             if (n_culldistance_entry == cell_x)
1967*35238bceSAndroid Build Coastguard Worker                             {
1968*35238bceSAndroid Build Coastguard Worker                                 /* The primitive vertex should be affected by the cull distance */
1969*35238bceSAndroid Build Coastguard Worker                                 switch (n_sub_cell_x)
1970*35238bceSAndroid Build Coastguard Worker                                 {
1971*35238bceSAndroid Build Coastguard Worker                                 case 0:
1972*35238bceSAndroid Build Coastguard Worker                                 {
1973*35238bceSAndroid Build Coastguard Worker                                     /* subgrid column 0: all primitive vertices have tested distance value positive */
1974*35238bceSAndroid Build Coastguard Worker                                     negative = false;
1975*35238bceSAndroid Build Coastguard Worker 
1976*35238bceSAndroid Build Coastguard Worker                                     break;
1977*35238bceSAndroid Build Coastguard Worker                                 }
1978*35238bceSAndroid Build Coastguard Worker                                 case 1:
1979*35238bceSAndroid Build Coastguard Worker                                 {
1980*35238bceSAndroid Build Coastguard Worker                                     /* subgrid column 1: tested distance value for 0th primitive vertex is negative,
1981*35238bceSAndroid Build Coastguard Worker                                      all other primitive vertices have tested distance value positive */
1982*35238bceSAndroid Build Coastguard Worker                                     negative = (n_primitive_vertex == 0) ? true : false;
1983*35238bceSAndroid Build Coastguard Worker 
1984*35238bceSAndroid Build Coastguard Worker                                     break;
1985*35238bceSAndroid Build Coastguard Worker                                 }
1986*35238bceSAndroid Build Coastguard Worker                                 case 2:
1987*35238bceSAndroid Build Coastguard Worker                                 {
1988*35238bceSAndroid Build Coastguard Worker                                     /* subgrid column 2: tested distance value is negative for all primitive vertices */
1989*35238bceSAndroid Build Coastguard Worker                                     negative = true;
1990*35238bceSAndroid Build Coastguard Worker 
1991*35238bceSAndroid Build Coastguard Worker                                     break;
1992*35238bceSAndroid Build Coastguard Worker                                 }
1993*35238bceSAndroid Build Coastguard Worker                                 default:
1994*35238bceSAndroid Build Coastguard Worker                                     TCU_FAIL("Invalid subgrid cell index");
1995*35238bceSAndroid Build Coastguard Worker                                 }
1996*35238bceSAndroid Build Coastguard Worker 
1997*35238bceSAndroid Build Coastguard Worker                                 distance_value = (negative ? -1.0f : 1.0f) * glw::GLfloat(n_culldistance_entry + 1);
1998*35238bceSAndroid Build Coastguard Worker                             }
1999*35238bceSAndroid Build Coastguard Worker                             else
2000*35238bceSAndroid Build Coastguard Worker                             {
2001*35238bceSAndroid Build Coastguard Worker                                 /* For cull distances other than tested: assign 0th vertex negative value,
2002*35238bceSAndroid Build Coastguard Worker                                  to check absence of between-distances influence. */
2003*35238bceSAndroid Build Coastguard Worker                                 if (n_primitive_vertices > 1 && n_primitive_vertex == 0)
2004*35238bceSAndroid Build Coastguard Worker                                 {
2005*35238bceSAndroid Build Coastguard Worker                                     distance_value = -glw::GLfloat(culldistances_array_size + n_culldistance_entry + 1);
2006*35238bceSAndroid Build Coastguard Worker                                 }
2007*35238bceSAndroid Build Coastguard Worker                                 else
2008*35238bceSAndroid Build Coastguard Worker                                 {
2009*35238bceSAndroid Build Coastguard Worker                                     /* This culldistance is out of interest: assign positive value. */
2010*35238bceSAndroid Build Coastguard Worker                                     distance_value = glw::GLfloat(culldistances_array_size + n_culldistance_entry + 1);
2011*35238bceSAndroid Build Coastguard Worker                                 }
2012*35238bceSAndroid Build Coastguard Worker                             }
2013*35238bceSAndroid Build Coastguard Worker 
2014*35238bceSAndroid Build Coastguard Worker                             m_bo_data.push_back(distance_value / glw::GLfloat(culldistances_array_size));
2015*35238bceSAndroid Build Coastguard Worker                         } /* for (all gl_CullDistance[] array values) */
2016*35238bceSAndroid Build Coastguard Worker 
2017*35238bceSAndroid Build Coastguard Worker                         /* Generate primitve vertex draw and checkpoint coordinates */
2018*35238bceSAndroid Build Coastguard Worker                         glw::GLint vertex_draw_pixel_offset_x       = 0;
2019*35238bceSAndroid Build Coastguard Worker                         glw::GLint vertex_draw_pixel_offset_y       = 0;
2020*35238bceSAndroid Build Coastguard Worker                         glw::GLint vertex_checkpoint_pixel_offset_x = 0;
2021*35238bceSAndroid Build Coastguard Worker                         glw::GLint vertex_checkpoint_pixel_offset_y = 0;
2022*35238bceSAndroid Build Coastguard Worker 
2023*35238bceSAndroid Build Coastguard Worker                         switch (primitive_mode)
2024*35238bceSAndroid Build Coastguard Worker                         {
2025*35238bceSAndroid Build Coastguard Worker                         case PRIMITIVE_MODE_LINES:
2026*35238bceSAndroid Build Coastguard Worker                         {
2027*35238bceSAndroid Build Coastguard Worker                             vertex_draw_pixel_offset_x       = offsets_line_draw_x[n_primitive_vertex];
2028*35238bceSAndroid Build Coastguard Worker                             vertex_draw_pixel_offset_y       = offsets_line_draw_y[n_primitive_vertex];
2029*35238bceSAndroid Build Coastguard Worker                             vertex_checkpoint_pixel_offset_x = offsets_line_checkpoint_x[n_primitive_vertex];
2030*35238bceSAndroid Build Coastguard Worker                             vertex_checkpoint_pixel_offset_y = offsets_line_checkpoint_y[n_primitive_vertex];
2031*35238bceSAndroid Build Coastguard Worker 
2032*35238bceSAndroid Build Coastguard Worker                             break;
2033*35238bceSAndroid Build Coastguard Worker                         }
2034*35238bceSAndroid Build Coastguard Worker 
2035*35238bceSAndroid Build Coastguard Worker                         case PRIMITIVE_MODE_POINTS:
2036*35238bceSAndroid Build Coastguard Worker                         {
2037*35238bceSAndroid Build Coastguard Worker                             vertex_draw_pixel_offset_x       = offsets_point_draw_x[n_primitive_vertex];
2038*35238bceSAndroid Build Coastguard Worker                             vertex_draw_pixel_offset_y       = offsets_point_draw_y[n_primitive_vertex];
2039*35238bceSAndroid Build Coastguard Worker                             vertex_checkpoint_pixel_offset_x = offsets_point_checkpoint_x[n_primitive_vertex];
2040*35238bceSAndroid Build Coastguard Worker                             vertex_checkpoint_pixel_offset_y = offsets_point_checkpoint_y[n_primitive_vertex];
2041*35238bceSAndroid Build Coastguard Worker 
2042*35238bceSAndroid Build Coastguard Worker                             break;
2043*35238bceSAndroid Build Coastguard Worker                         }
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker                         case PRIMITIVE_MODE_TRIANGLES:
2046*35238bceSAndroid Build Coastguard Worker                         {
2047*35238bceSAndroid Build Coastguard Worker                             vertex_draw_pixel_offset_x       = offsets_triangle_draw_x[n_primitive_vertex];
2048*35238bceSAndroid Build Coastguard Worker                             vertex_draw_pixel_offset_y       = offsets_triangle_draw_y[n_primitive_vertex];
2049*35238bceSAndroid Build Coastguard Worker                             vertex_checkpoint_pixel_offset_x = offsets_triangle_checkpoint_x[n_primitive_vertex];
2050*35238bceSAndroid Build Coastguard Worker                             vertex_checkpoint_pixel_offset_y = offsets_triangle_checkpoint_y[n_primitive_vertex];
2051*35238bceSAndroid Build Coastguard Worker 
2052*35238bceSAndroid Build Coastguard Worker                             break;
2053*35238bceSAndroid Build Coastguard Worker                         }
2054*35238bceSAndroid Build Coastguard Worker 
2055*35238bceSAndroid Build Coastguard Worker                         default:
2056*35238bceSAndroid Build Coastguard Worker                             TCU_FAIL("Unknown primitive mode");
2057*35238bceSAndroid Build Coastguard Worker                         }
2058*35238bceSAndroid Build Coastguard Worker 
2059*35238bceSAndroid Build Coastguard Worker                         /* Origin of sub_cell */
2060*35238bceSAndroid Build Coastguard Worker                         glw::GLint sub_cell_origin_x = cell_x * grid_cell_size + n_sub_cell_x * sub_grid_cell_size;
2061*35238bceSAndroid Build Coastguard Worker                         glw::GLint sub_cell_origin_y = cell_y * grid_cell_size + n_sub_cell_y * sub_grid_cell_size;
2062*35238bceSAndroid Build Coastguard Worker                         /* Normalized texture coordinates of vertex draw position. */
2063*35238bceSAndroid Build Coastguard Worker                         glw::GLfloat x =
2064*35238bceSAndroid Build Coastguard Worker                             (glw::GLfloat(sub_cell_origin_x + vertex_draw_pixel_offset_x) + offsets_pixel_center_x) /
2065*35238bceSAndroid Build Coastguard Worker                             glw::GLfloat(m_to_width);
2066*35238bceSAndroid Build Coastguard Worker                         glw::GLfloat y =
2067*35238bceSAndroid Build Coastguard Worker                             (glw::GLfloat(sub_cell_origin_y + vertex_draw_pixel_offset_y) + offsets_pixel_center_y) /
2068*35238bceSAndroid Build Coastguard Worker                             glw::GLfloat(m_to_height);
2069*35238bceSAndroid Build Coastguard Worker                         /* Normalized texture coordinates of vertex checkpoint position. */
2070*35238bceSAndroid Build Coastguard Worker                         glw::GLfloat checkpoint_x = glw::GLfloat(sub_cell_origin_x + vertex_checkpoint_pixel_offset_x) /
2071*35238bceSAndroid Build Coastguard Worker                                                     glw::GLfloat(m_to_width);
2072*35238bceSAndroid Build Coastguard Worker                         glw::GLfloat checkpoint_y = glw::GLfloat(sub_cell_origin_y + vertex_checkpoint_pixel_offset_y) /
2073*35238bceSAndroid Build Coastguard Worker                                                     glw::GLfloat(m_to_height);
2074*35238bceSAndroid Build Coastguard Worker 
2075*35238bceSAndroid Build Coastguard Worker                         /* Add vertex draw coordinates into buffer. */
2076*35238bceSAndroid Build Coastguard Worker                         m_bo_data.push_back(x);
2077*35238bceSAndroid Build Coastguard Worker                         m_bo_data.push_back(y);
2078*35238bceSAndroid Build Coastguard Worker 
2079*35238bceSAndroid Build Coastguard Worker                         /* Add vertex checkpoint coordinates into buffer. */
2080*35238bceSAndroid Build Coastguard Worker                         m_bo_data.push_back(checkpoint_x);
2081*35238bceSAndroid Build Coastguard Worker                         m_bo_data.push_back(checkpoint_y);
2082*35238bceSAndroid Build Coastguard Worker                     } /* for (all vertices in primitive) */
2083*35238bceSAndroid Build Coastguard Worker                 }     /* for (all horizontal sub cells) */
2084*35238bceSAndroid Build Coastguard Worker             }         /* for (all vertical sub cells) */
2085*35238bceSAndroid Build Coastguard Worker         }             /* for (all horizontal cells) */
2086*35238bceSAndroid Build Coastguard Worker     }                 /* for (all vertical cells) */
2087*35238bceSAndroid Build Coastguard Worker 
2088*35238bceSAndroid Build Coastguard Worker     /* Quick check: make sure we pushed required amount of data */
2089*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_bo_data.size() == n_vertices_total * n_pervertex_float_attributes);
2090*35238bceSAndroid Build Coastguard Worker 
2091*35238bceSAndroid Build Coastguard Worker     /* Save number of primitives to render */
2092*35238bceSAndroid Build Coastguard Worker     m_render_primitives  = n_primitives_total;
2093*35238bceSAndroid Build Coastguard Worker     m_render_vertices    = n_vertices_total;
2094*35238bceSAndroid Build Coastguard Worker     m_sub_grid_cell_size = sub_grid_cell_size;
2095*35238bceSAndroid Build Coastguard Worker 
2096*35238bceSAndroid Build Coastguard Worker     /* Copy the data to the buffer object */
2097*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
2098*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
2099*35238bceSAndroid Build Coastguard Worker 
2100*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ARRAY_BUFFER, m_bo_data.size() * sizeof(glw::GLfloat), &m_bo_data[0], GL_STATIC_DRAW);
2101*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2102*35238bceSAndroid Build Coastguard Worker 
2103*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_po_id != 0);
2104*35238bceSAndroid Build Coastguard Worker 
2105*35238bceSAndroid Build Coastguard Worker     /* Bind VAO data to program */
2106*35238bceSAndroid Build Coastguard Worker     glw::GLint po_clipdistance_array_location = -1;
2107*35238bceSAndroid Build Coastguard Worker     glw::GLint po_culldistance_array_location = -1;
2108*35238bceSAndroid Build Coastguard Worker     glw::GLint po_position_location           = -1;
2109*35238bceSAndroid Build Coastguard Worker 
2110*35238bceSAndroid Build Coastguard Worker     /* Retrieve clipdistance and culldistance attribute locations */
2111*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(m_vao_id);
2112*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2113*35238bceSAndroid Build Coastguard Worker 
2114*35238bceSAndroid Build Coastguard Worker     po_clipdistance_array_location = gl.getAttribLocation(m_po_id, "clipdistance_data[0]");
2115*35238bceSAndroid Build Coastguard Worker     po_culldistance_array_location = gl.getAttribLocation(m_po_id, "culldistance_data[0]");
2116*35238bceSAndroid Build Coastguard Worker     po_position_location           = gl.getAttribLocation(m_po_id, "position");
2117*35238bceSAndroid Build Coastguard Worker 
2118*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() call(s) failed.");
2119*35238bceSAndroid Build Coastguard Worker 
2120*35238bceSAndroid Build Coastguard Worker     if (clipdistances_array_size > 0)
2121*35238bceSAndroid Build Coastguard Worker     {
2122*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(po_clipdistance_array_location != -1);
2123*35238bceSAndroid Build Coastguard Worker     }
2124*35238bceSAndroid Build Coastguard Worker 
2125*35238bceSAndroid Build Coastguard Worker     if (culldistances_array_size > 0)
2126*35238bceSAndroid Build Coastguard Worker     {
2127*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(po_culldistance_array_location != -1);
2128*35238bceSAndroid Build Coastguard Worker     }
2129*35238bceSAndroid Build Coastguard Worker 
2130*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(po_position_location != -1);
2131*35238bceSAndroid Build Coastguard Worker 
2132*35238bceSAndroid Build Coastguard Worker     glw::GLintptr current_offset = 0;
2133*35238bceSAndroid Build Coastguard Worker     const glw::GLint stride      = static_cast<glw::GLint>(n_pervertex_float_attributes * sizeof(glw::GLfloat));
2134*35238bceSAndroid Build Coastguard Worker 
2135*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(m_vao_id);
2136*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2137*35238bceSAndroid Build Coastguard Worker 
2138*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_clipdistance_entry = 0; n_clipdistance_entry < clipdistances_array_size; ++n_clipdistance_entry)
2139*35238bceSAndroid Build Coastguard Worker     {
2140*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(po_clipdistance_array_location + n_clipdistance_entry, 1, /* size */
2141*35238bceSAndroid Build Coastguard Worker                                GL_FLOAT, GL_FALSE,                                       /* normalized */
2142*35238bceSAndroid Build Coastguard Worker                                stride, (const glw::GLvoid *)current_offset);
2143*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");
2144*35238bceSAndroid Build Coastguard Worker 
2145*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(po_clipdistance_array_location + n_clipdistance_entry);
2146*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed.");
2147*35238bceSAndroid Build Coastguard Worker 
2148*35238bceSAndroid Build Coastguard Worker         current_offset += sizeof(glw::GLfloat);
2149*35238bceSAndroid Build Coastguard Worker     } /* for (all clip distance array value attributes) */
2150*35238bceSAndroid Build Coastguard Worker 
2151*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_culldistance_entry = 0; n_culldistance_entry < culldistances_array_size; ++n_culldistance_entry)
2152*35238bceSAndroid Build Coastguard Worker     {
2153*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(po_culldistance_array_location + n_culldistance_entry, 1, /* size */
2154*35238bceSAndroid Build Coastguard Worker                                GL_FLOAT, GL_FALSE,                                       /* normalized */
2155*35238bceSAndroid Build Coastguard Worker                                stride, (const glw::GLvoid *)current_offset);
2156*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");
2157*35238bceSAndroid Build Coastguard Worker 
2158*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(po_culldistance_array_location + n_culldistance_entry);
2159*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed.");
2160*35238bceSAndroid Build Coastguard Worker 
2161*35238bceSAndroid Build Coastguard Worker         current_offset += sizeof(glw::GLfloat);
2162*35238bceSAndroid Build Coastguard Worker     } /* for (all cull distance array value attributes) */
2163*35238bceSAndroid Build Coastguard Worker 
2164*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(po_position_location, 2, /* size */
2165*35238bceSAndroid Build Coastguard Worker                            GL_FLOAT, GL_FALSE,      /* normalized */
2166*35238bceSAndroid Build Coastguard Worker                            stride, (const glw::GLvoid *)current_offset);
2167*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed");
2168*35238bceSAndroid Build Coastguard Worker 
2169*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(po_position_location);
2170*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed");
2171*35238bceSAndroid Build Coastguard Worker }
2172*35238bceSAndroid Build Coastguard Worker 
2173*35238bceSAndroid Build Coastguard Worker /** @brief Cull Distance Functional Test deinitialization */
deinit()2174*35238bceSAndroid Build Coastguard Worker void CullDistance::FunctionalTest::deinit()
2175*35238bceSAndroid Build Coastguard Worker {
2176*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2177*35238bceSAndroid Build Coastguard Worker 
2178*35238bceSAndroid Build Coastguard Worker     if (m_fbo_id != 0)
2179*35238bceSAndroid Build Coastguard Worker     {
2180*35238bceSAndroid Build Coastguard Worker         gl.deleteFramebuffers(1, &m_fbo_id);
2181*35238bceSAndroid Build Coastguard Worker 
2182*35238bceSAndroid Build Coastguard Worker         m_fbo_id = 0;
2183*35238bceSAndroid Build Coastguard Worker     }
2184*35238bceSAndroid Build Coastguard Worker 
2185*35238bceSAndroid Build Coastguard Worker     if (m_to_id != 0)
2186*35238bceSAndroid Build Coastguard Worker     {
2187*35238bceSAndroid Build Coastguard Worker         gl.deleteTextures(1, &m_to_id);
2188*35238bceSAndroid Build Coastguard Worker 
2189*35238bceSAndroid Build Coastguard Worker         m_to_id = 0;
2190*35238bceSAndroid Build Coastguard Worker     }
2191*35238bceSAndroid Build Coastguard Worker 
2192*35238bceSAndroid Build Coastguard Worker     if (m_vao_id != 0)
2193*35238bceSAndroid Build Coastguard Worker     {
2194*35238bceSAndroid Build Coastguard Worker         gl.deleteVertexArrays(1, &m_vao_id);
2195*35238bceSAndroid Build Coastguard Worker 
2196*35238bceSAndroid Build Coastguard Worker         m_vao_id = 0;
2197*35238bceSAndroid Build Coastguard Worker     }
2198*35238bceSAndroid Build Coastguard Worker 
2199*35238bceSAndroid Build Coastguard Worker     deinitPO();
2200*35238bceSAndroid Build Coastguard Worker }
2201*35238bceSAndroid Build Coastguard Worker 
2202*35238bceSAndroid Build Coastguard Worker /** @brief Cull Distance Functional Test deinitialization of OpenGL programs */
deinitPO()2203*35238bceSAndroid Build Coastguard Worker void CullDistance::FunctionalTest::deinitPO()
2204*35238bceSAndroid Build Coastguard Worker {
2205*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2206*35238bceSAndroid Build Coastguard Worker 
2207*35238bceSAndroid Build Coastguard Worker     if (m_po_id != 0)
2208*35238bceSAndroid Build Coastguard Worker     {
2209*35238bceSAndroid Build Coastguard Worker         gl.deleteProgram(m_po_id);
2210*35238bceSAndroid Build Coastguard Worker 
2211*35238bceSAndroid Build Coastguard Worker         m_po_id = 0;
2212*35238bceSAndroid Build Coastguard Worker     }
2213*35238bceSAndroid Build Coastguard Worker }
2214*35238bceSAndroid Build Coastguard Worker 
2215*35238bceSAndroid Build Coastguard Worker /** @brief Executes single render test case
2216*35238bceSAndroid Build Coastguard Worker  *
2217*35238bceSAndroid Build Coastguard Worker  * @param [in]  clipdistances_array_size    Size of gl_ClipDistance[] array
2218*35238bceSAndroid Build Coastguard Worker  * @param [in]  culldistances_array_size    Size of gl_CullDistance[] array
2219*35238bceSAndroid Build Coastguard Worker  * @param [in]  primitive_mode              Type of primitives to be rendered (see enum _primitive_mode)
2220*35238bceSAndroid Build Coastguard Worker  * @param [in]  use_tesselation             Indicate whether to use tessellation shader
2221*35238bceSAndroid Build Coastguard Worker  * @param [in]  fetch_culldistance_from_fs  Indicate whether to fetch gl_CullDistance and gl_ClipDistance values from the fragment shader
2222*35238bceSAndroid Build Coastguard Worker  */
executeRenderTest(glw::GLuint clipdistances_array_size,glw::GLuint culldistances_array_size,_primitive_mode primitive_mode,bool use_tesselation,bool fetch_culldistance_from_fs)2223*35238bceSAndroid Build Coastguard Worker void CullDistance::FunctionalTest::executeRenderTest(glw::GLuint clipdistances_array_size,
2224*35238bceSAndroid Build Coastguard Worker                                                      glw::GLuint culldistances_array_size,
2225*35238bceSAndroid Build Coastguard Worker                                                      _primitive_mode primitive_mode, bool use_tesselation,
2226*35238bceSAndroid Build Coastguard Worker                                                      bool fetch_culldistance_from_fs)
2227*35238bceSAndroid Build Coastguard Worker {
2228*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl                   = m_context.getRenderContext().getFunctions();
2229*35238bceSAndroid Build Coastguard Worker     glw::GLenum mode                           = GL_NONE;
2230*35238bceSAndroid Build Coastguard Worker     glw::GLuint n_clipped_vertices_real        = 0;
2231*35238bceSAndroid Build Coastguard Worker     glw::GLuint n_culled_primitives_real       = 0;
2232*35238bceSAndroid Build Coastguard Worker     const glw::GLuint primitive_vertices_count = ((primitive_mode == PRIMITIVE_MODE_LINES)  ? 2 :
2233*35238bceSAndroid Build Coastguard Worker                                                   (primitive_mode == PRIMITIVE_MODE_POINTS) ? 1 :
2234*35238bceSAndroid Build Coastguard Worker                                                                                               3);
2235*35238bceSAndroid Build Coastguard Worker     const glw::GLuint stride_in_floats =
2236*35238bceSAndroid Build Coastguard Worker         clipdistances_array_size + culldistances_array_size + 2 /* position's x, y*/ + 2 /* checkpoint x,y */;
2237*35238bceSAndroid Build Coastguard Worker 
2238*35238bceSAndroid Build Coastguard Worker     // Release build does not use them
2239*35238bceSAndroid Build Coastguard Worker     DE_UNREF(n_clipped_vertices_real);
2240*35238bceSAndroid Build Coastguard Worker     DE_UNREF(n_culled_primitives_real);
2241*35238bceSAndroid Build Coastguard Worker 
2242*35238bceSAndroid Build Coastguard Worker     switch (primitive_mode)
2243*35238bceSAndroid Build Coastguard Worker     {
2244*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_MODE_LINES:
2245*35238bceSAndroid Build Coastguard Worker     {
2246*35238bceSAndroid Build Coastguard Worker         mode = GL_LINES;
2247*35238bceSAndroid Build Coastguard Worker 
2248*35238bceSAndroid Build Coastguard Worker         break;
2249*35238bceSAndroid Build Coastguard Worker     }
2250*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_MODE_POINTS:
2251*35238bceSAndroid Build Coastguard Worker     {
2252*35238bceSAndroid Build Coastguard Worker         mode = GL_POINTS;
2253*35238bceSAndroid Build Coastguard Worker 
2254*35238bceSAndroid Build Coastguard Worker         break;
2255*35238bceSAndroid Build Coastguard Worker     }
2256*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_MODE_TRIANGLES:
2257*35238bceSAndroid Build Coastguard Worker     {
2258*35238bceSAndroid Build Coastguard Worker         mode = GL_TRIANGLES;
2259*35238bceSAndroid Build Coastguard Worker 
2260*35238bceSAndroid Build Coastguard Worker         break;
2261*35238bceSAndroid Build Coastguard Worker     }
2262*35238bceSAndroid Build Coastguard Worker     default:
2263*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unknown primitive mode");
2264*35238bceSAndroid Build Coastguard Worker     }
2265*35238bceSAndroid Build Coastguard Worker 
2266*35238bceSAndroid Build Coastguard Worker     if (use_tesselation)
2267*35238bceSAndroid Build Coastguard Worker     {
2268*35238bceSAndroid Build Coastguard Worker         mode = GL_PATCHES;
2269*35238bceSAndroid Build Coastguard Worker 
2270*35238bceSAndroid Build Coastguard Worker         gl.patchParameteri(GL_PATCH_VERTICES, primitive_vertices_count);
2271*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
2272*35238bceSAndroid Build Coastguard Worker     }
2273*35238bceSAndroid Build Coastguard Worker 
2274*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
2275*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
2276*35238bceSAndroid Build Coastguard Worker 
2277*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_po_id);
2278*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2279*35238bceSAndroid Build Coastguard Worker 
2280*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_clipdistance_entry = 0; n_clipdistance_entry < clipdistances_array_size; n_clipdistance_entry++)
2281*35238bceSAndroid Build Coastguard Worker     {
2282*35238bceSAndroid Build Coastguard Worker         gl.enable(GL_CLIP_DISTANCE0 + n_clipdistance_entry);
2283*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gl.enable(GL_CLIP_DISTANCE)() call failed.");
2284*35238bceSAndroid Build Coastguard Worker     } /* for (all clip distance array value attributes) */
2285*35238bceSAndroid Build Coastguard Worker 
2286*35238bceSAndroid Build Coastguard Worker     gl.drawArrays(mode, 0, m_render_vertices);
2287*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray() call(s) failed.");
2288*35238bceSAndroid Build Coastguard Worker 
2289*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_clipdistance_entry = 0; n_clipdistance_entry < clipdistances_array_size; n_clipdistance_entry++)
2290*35238bceSAndroid Build Coastguard Worker     {
2291*35238bceSAndroid Build Coastguard Worker         gl.disable(GL_CLIP_DISTANCE0 + n_clipdistance_entry);
2292*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "gl.disable(GL_CLIP_DISTANCE)() call failed.");
2293*35238bceSAndroid Build Coastguard Worker     } /* for (all clip distance array value attributes) */
2294*35238bceSAndroid Build Coastguard Worker 
2295*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
2296*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2297*35238bceSAndroid Build Coastguard Worker 
2298*35238bceSAndroid Build Coastguard Worker     /* Read generated texture into m_to_pixel_data_cache */
2299*35238bceSAndroid Build Coastguard Worker     readTexturePixels();
2300*35238bceSAndroid Build Coastguard Worker 
2301*35238bceSAndroid Build Coastguard Worker     for (glw::GLint n_primitive_index = 0; n_primitive_index < m_render_primitives; n_primitive_index++)
2302*35238bceSAndroid Build Coastguard Worker     {
2303*35238bceSAndroid Build Coastguard Worker         glw::GLuint base_index_of_primitive     = n_primitive_index * primitive_vertices_count * stride_in_floats;
2304*35238bceSAndroid Build Coastguard Worker         bool primitive_culled                   = false;
2305*35238bceSAndroid Build Coastguard Worker         glw::GLint primitive_culled_by_distance = -1;
2306*35238bceSAndroid Build Coastguard Worker 
2307*35238bceSAndroid Build Coastguard Worker         /* Check the bounding box is clear */
2308*35238bceSAndroid Build Coastguard Worker         glw::GLuint base_index_of_vertex      = base_index_of_primitive;
2309*35238bceSAndroid Build Coastguard Worker         glw::GLuint checkpoint_position_index = base_index_of_vertex + clipdistances_array_size +
2310*35238bceSAndroid Build Coastguard Worker                                                 culldistances_array_size + 2 /* ignore vertex coordinates */;
2311*35238bceSAndroid Build Coastguard Worker         glw::GLint checkpoint_x = glw::GLint(glw::GLfloat(m_to_width) * m_bo_data[checkpoint_position_index]);
2312*35238bceSAndroid Build Coastguard Worker         glw::GLint checkpoint_y = glw::GLint(glw::GLfloat(m_to_height) * m_bo_data[checkpoint_position_index + 1]);
2313*35238bceSAndroid Build Coastguard Worker         glw::GLint origin_x     = checkpoint_x - 1;
2314*35238bceSAndroid Build Coastguard Worker         glw::GLint origin_y     = checkpoint_y - 1;
2315*35238bceSAndroid Build Coastguard Worker         for (glw::GLint pixel_offset = 0; pixel_offset < m_sub_grid_cell_size; pixel_offset++)
2316*35238bceSAndroid Build Coastguard Worker         {
2317*35238bceSAndroid Build Coastguard Worker             if (readRedPixelValue(origin_x + pixel_offset, origin_y) != 0)
2318*35238bceSAndroid Build Coastguard Worker             {
2319*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Top edge of bounding box is overwritten");
2320*35238bceSAndroid Build Coastguard Worker             }
2321*35238bceSAndroid Build Coastguard Worker 
2322*35238bceSAndroid Build Coastguard Worker             if (readRedPixelValue(origin_x + m_sub_grid_cell_size - 1, origin_y + pixel_offset) != 0)
2323*35238bceSAndroid Build Coastguard Worker             {
2324*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Right edge of bounding box is overwritten");
2325*35238bceSAndroid Build Coastguard Worker             }
2326*35238bceSAndroid Build Coastguard Worker 
2327*35238bceSAndroid Build Coastguard Worker             if (readRedPixelValue(origin_x + m_sub_grid_cell_size - 1 - pixel_offset,
2328*35238bceSAndroid Build Coastguard Worker                                   origin_y + m_sub_grid_cell_size - 1) != 0)
2329*35238bceSAndroid Build Coastguard Worker             {
2330*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Bottom edge of bounding box is overwritten");
2331*35238bceSAndroid Build Coastguard Worker             }
2332*35238bceSAndroid Build Coastguard Worker 
2333*35238bceSAndroid Build Coastguard Worker             if (readRedPixelValue(origin_x, origin_y + m_sub_grid_cell_size - 1 - pixel_offset) != 0)
2334*35238bceSAndroid Build Coastguard Worker             {
2335*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Left edge of bounding box is overwritten");
2336*35238bceSAndroid Build Coastguard Worker             }
2337*35238bceSAndroid Build Coastguard Worker         }
2338*35238bceSAndroid Build Coastguard Worker 
2339*35238bceSAndroid Build Coastguard Worker         /* Determine if primitive has been culled */
2340*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint n_culldistance_entry = 0; n_culldistance_entry < culldistances_array_size;
2341*35238bceSAndroid Build Coastguard Worker              n_culldistance_entry++)
2342*35238bceSAndroid Build Coastguard Worker         {
2343*35238bceSAndroid Build Coastguard Worker             bool distance_negative_in_all_primitive_vertices = true;
2344*35238bceSAndroid Build Coastguard Worker 
2345*35238bceSAndroid Build Coastguard Worker             for (glw::GLuint n_primitive_vertex = 0; n_primitive_vertex < primitive_vertices_count;
2346*35238bceSAndroid Build Coastguard Worker                  n_primitive_vertex++)
2347*35238bceSAndroid Build Coastguard Worker             {
2348*35238bceSAndroid Build Coastguard Worker                 glw::GLint base_index_of_vertex_internal =
2349*35238bceSAndroid Build Coastguard Worker                     base_index_of_primitive + n_primitive_vertex * stride_in_floats;
2350*35238bceSAndroid Build Coastguard Worker                 glw::GLint culldistance_array_offset    = base_index_of_vertex_internal + clipdistances_array_size;
2351*35238bceSAndroid Build Coastguard Worker                 glw::GLfloat *vertex_culldistance_array = &m_bo_data[culldistance_array_offset];
2352*35238bceSAndroid Build Coastguard Worker 
2353*35238bceSAndroid Build Coastguard Worker                 if (vertex_culldistance_array[n_culldistance_entry] >= 0)
2354*35238bceSAndroid Build Coastguard Worker                 {
2355*35238bceSAndroid Build Coastguard Worker                     /* Primitive is not culled, due to one of its distances is not negative */
2356*35238bceSAndroid Build Coastguard Worker                     distance_negative_in_all_primitive_vertices = false;
2357*35238bceSAndroid Build Coastguard Worker 
2358*35238bceSAndroid Build Coastguard Worker                     /* Skip left vertices for this distance */
2359*35238bceSAndroid Build Coastguard Worker                     break;
2360*35238bceSAndroid Build Coastguard Worker                 }
2361*35238bceSAndroid Build Coastguard Worker             }
2362*35238bceSAndroid Build Coastguard Worker 
2363*35238bceSAndroid Build Coastguard Worker             /* The distance is negative in all primitive vertices, so this distance culls the primitive */
2364*35238bceSAndroid Build Coastguard Worker             if (distance_negative_in_all_primitive_vertices)
2365*35238bceSAndroid Build Coastguard Worker             {
2366*35238bceSAndroid Build Coastguard Worker                 primitive_culled             = true;
2367*35238bceSAndroid Build Coastguard Worker                 primitive_culled_by_distance = n_culldistance_entry;
2368*35238bceSAndroid Build Coastguard Worker 
2369*35238bceSAndroid Build Coastguard Worker                 n_culled_primitives_real++;
2370*35238bceSAndroid Build Coastguard Worker 
2371*35238bceSAndroid Build Coastguard Worker                 /* Skip left distances from check */
2372*35238bceSAndroid Build Coastguard Worker                 break;
2373*35238bceSAndroid Build Coastguard Worker             }
2374*35238bceSAndroid Build Coastguard Worker         }
2375*35238bceSAndroid Build Coastguard Worker 
2376*35238bceSAndroid Build Coastguard Worker         /* Validate culling */
2377*35238bceSAndroid Build Coastguard Worker         if (primitive_culled)
2378*35238bceSAndroid Build Coastguard Worker         {
2379*35238bceSAndroid Build Coastguard Worker             /* Check whether primitive was culled and all its vertices are invisible */
2380*35238bceSAndroid Build Coastguard Worker             for (glw::GLuint n_primitive_vertex = 0; n_primitive_vertex < primitive_vertices_count;
2381*35238bceSAndroid Build Coastguard Worker                  n_primitive_vertex++)
2382*35238bceSAndroid Build Coastguard Worker             {
2383*35238bceSAndroid Build Coastguard Worker                 glw::GLint base_index_of_vertex_internal =
2384*35238bceSAndroid Build Coastguard Worker                     base_index_of_primitive + n_primitive_vertex * stride_in_floats;
2385*35238bceSAndroid Build Coastguard Worker                 glw::GLint checkpoint_position_index_internal = base_index_of_vertex_internal +
2386*35238bceSAndroid Build Coastguard Worker                                                                 clipdistances_array_size + culldistances_array_size +
2387*35238bceSAndroid Build Coastguard Worker                                                                 2 /* ignore vertex coordinates */;
2388*35238bceSAndroid Build Coastguard Worker                 glw::GLint checkpoint_x_internal =
2389*35238bceSAndroid Build Coastguard Worker                     glw::GLint(glw::GLfloat(m_to_width) * m_bo_data[checkpoint_position_index_internal]);
2390*35238bceSAndroid Build Coastguard Worker                 glw::GLint checkpoint_y_internal =
2391*35238bceSAndroid Build Coastguard Worker                     glw::GLint(glw::GLfloat(m_to_height) * m_bo_data[checkpoint_position_index_internal + 1]);
2392*35238bceSAndroid Build Coastguard Worker                 glw::GLint vertex_color_red_value = readRedPixelValue(checkpoint_x_internal, checkpoint_y_internal);
2393*35238bceSAndroid Build Coastguard Worker 
2394*35238bceSAndroid Build Coastguard Worker                 /* Make sure vertex is invisible */
2395*35238bceSAndroid Build Coastguard Worker                 if (vertex_color_red_value != 0)
2396*35238bceSAndroid Build Coastguard Worker                 {
2397*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "Primitive number [" << n_primitive_index << "] "
2398*35238bceSAndroid Build Coastguard Worker                                        << "should be culled by distance [" << primitive_culled_by_distance << "]"
2399*35238bceSAndroid Build Coastguard Worker                                        << "but primitive vertex at (" << checkpoint_x << "," << checkpoint_y
2400*35238bceSAndroid Build Coastguard Worker                                        << ") is visible." << tcu::TestLog::EndMessage;
2401*35238bceSAndroid Build Coastguard Worker 
2402*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Primitive is expected to be culled, but one of its vertices is visible.");
2403*35238bceSAndroid Build Coastguard Worker                 }
2404*35238bceSAndroid Build Coastguard Worker             }
2405*35238bceSAndroid Build Coastguard Worker 
2406*35238bceSAndroid Build Coastguard Worker             /* Primitive is culled, no reason to check clipping */
2407*35238bceSAndroid Build Coastguard Worker             continue;
2408*35238bceSAndroid Build Coastguard Worker         }
2409*35238bceSAndroid Build Coastguard Worker 
2410*35238bceSAndroid Build Coastguard Worker         bool all_vertices_are_clipped = true;
2411*35238bceSAndroid Build Coastguard Worker 
2412*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint n_primitive_vertex = 0; n_primitive_vertex < primitive_vertices_count; n_primitive_vertex++)
2413*35238bceSAndroid Build Coastguard Worker         {
2414*35238bceSAndroid Build Coastguard Worker             glw::GLuint base_index_of_vertex_internal = base_index_of_primitive + n_primitive_vertex * stride_in_floats;
2415*35238bceSAndroid Build Coastguard Worker             glw::GLuint clipdistance_array_index      = base_index_of_vertex_internal;
2416*35238bceSAndroid Build Coastguard Worker             glw::GLuint checkpoint_position_index_internal = base_index_of_vertex_internal + clipdistances_array_size +
2417*35238bceSAndroid Build Coastguard Worker                                                              culldistances_array_size +
2418*35238bceSAndroid Build Coastguard Worker                                                              2 /* ignore vertex coordinates */;
2419*35238bceSAndroid Build Coastguard Worker             glw::GLint checkpoint_x_internal =
2420*35238bceSAndroid Build Coastguard Worker                 glw::GLint(glw::GLfloat(m_to_width) * m_bo_data[checkpoint_position_index_internal]);
2421*35238bceSAndroid Build Coastguard Worker             glw::GLint checkpoint_y_internal =
2422*35238bceSAndroid Build Coastguard Worker                 glw::GLint(glw::GLfloat(m_to_height) * m_bo_data[checkpoint_position_index_internal + 1]);
2423*35238bceSAndroid Build Coastguard Worker             glw::GLfloat *vertex_clipdistance_array = &m_bo_data[clipdistance_array_index];
2424*35238bceSAndroid Build Coastguard Worker             bool vertex_clipped                     = false;
2425*35238bceSAndroid Build Coastguard Worker             glw::GLint vertex_clipped_by_distance   = 0;
2426*35238bceSAndroid Build Coastguard Worker             glw::GLint vertex_color_red_value       = readRedPixelValue(checkpoint_x_internal, checkpoint_y_internal);
2427*35238bceSAndroid Build Coastguard Worker 
2428*35238bceSAndroid Build Coastguard Worker             /* Check whether pixel should be clipped */
2429*35238bceSAndroid Build Coastguard Worker             for (glw::GLuint n_clipdistance_entry = 0; n_clipdistance_entry < clipdistances_array_size;
2430*35238bceSAndroid Build Coastguard Worker                  n_clipdistance_entry++)
2431*35238bceSAndroid Build Coastguard Worker             {
2432*35238bceSAndroid Build Coastguard Worker                 if (vertex_clipdistance_array[n_clipdistance_entry] < 0)
2433*35238bceSAndroid Build Coastguard Worker                 {
2434*35238bceSAndroid Build Coastguard Worker                     vertex_clipped             = true;
2435*35238bceSAndroid Build Coastguard Worker                     vertex_clipped_by_distance = n_clipdistance_entry;
2436*35238bceSAndroid Build Coastguard Worker 
2437*35238bceSAndroid Build Coastguard Worker                     break;
2438*35238bceSAndroid Build Coastguard Worker                 }
2439*35238bceSAndroid Build Coastguard Worker             }
2440*35238bceSAndroid Build Coastguard Worker 
2441*35238bceSAndroid Build Coastguard Worker             all_vertices_are_clipped &= vertex_clipped;
2442*35238bceSAndroid Build Coastguard Worker 
2443*35238bceSAndroid Build Coastguard Worker             /* Validate whether real data same as expected */
2444*35238bceSAndroid Build Coastguard Worker             if (vertex_clipped)
2445*35238bceSAndroid Build Coastguard Worker             {
2446*35238bceSAndroid Build Coastguard Worker                 if (vertex_color_red_value != 0)
2447*35238bceSAndroid Build Coastguard Worker                 {
2448*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "In primitive number [" << n_primitive_index << "] "
2449*35238bceSAndroid Build Coastguard Worker                                        << "vertex at (" << checkpoint_x << "," << checkpoint_y << ") "
2450*35238bceSAndroid Build Coastguard Worker                                        << "should be clipped by distance [" << vertex_clipped_by_distance << "] "
2451*35238bceSAndroid Build Coastguard Worker                                        << "(distance value [" << vertex_clipdistance_array[vertex_clipped_by_distance]
2452*35238bceSAndroid Build Coastguard Worker                                        << "])" << tcu::TestLog::EndMessage;
2453*35238bceSAndroid Build Coastguard Worker 
2454*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Vertex is expected to be clipped and invisible, while it is visible.");
2455*35238bceSAndroid Build Coastguard Worker                 }
2456*35238bceSAndroid Build Coastguard Worker                 else
2457*35238bceSAndroid Build Coastguard Worker                 {
2458*35238bceSAndroid Build Coastguard Worker                     n_clipped_vertices_real++;
2459*35238bceSAndroid Build Coastguard Worker                 }
2460*35238bceSAndroid Build Coastguard Worker             }
2461*35238bceSAndroid Build Coastguard Worker             else
2462*35238bceSAndroid Build Coastguard Worker             {
2463*35238bceSAndroid Build Coastguard Worker                 if (vertex_color_red_value == 0)
2464*35238bceSAndroid Build Coastguard Worker                 {
2465*35238bceSAndroid Build Coastguard Worker                     m_testCtx.getLog() << tcu::TestLog::Message << "In primitive number [" << n_primitive_index << "] "
2466*35238bceSAndroid Build Coastguard Worker                                        << "vertex at (" << checkpoint_x << "," << checkpoint_y << ") "
2467*35238bceSAndroid Build Coastguard Worker                                        << "should not be clipped." << tcu::TestLog::EndMessage;
2468*35238bceSAndroid Build Coastguard Worker 
2469*35238bceSAndroid Build Coastguard Worker                     TCU_FAIL("Vertex is unexpectedly clipped or invisible");
2470*35238bceSAndroid Build Coastguard Worker                 }
2471*35238bceSAndroid Build Coastguard Worker             }
2472*35238bceSAndroid Build Coastguard Worker         }
2473*35238bceSAndroid Build Coastguard Worker 
2474*35238bceSAndroid Build Coastguard Worker         if (!all_vertices_are_clipped)
2475*35238bceSAndroid Build Coastguard Worker         {
2476*35238bceSAndroid Build Coastguard Worker             /* Check fetched values from the shader (Point 2 of Basic Outline : "Use program that...") */
2477*35238bceSAndroid Build Coastguard Worker             if (fetch_culldistance_from_fs)
2478*35238bceSAndroid Build Coastguard Worker             {
2479*35238bceSAndroid Build Coastguard Worker                 for (glw::GLuint n_primitive_vertex = 0; n_primitive_vertex < primitive_vertices_count;
2480*35238bceSAndroid Build Coastguard Worker                      n_primitive_vertex++)
2481*35238bceSAndroid Build Coastguard Worker                 {
2482*35238bceSAndroid Build Coastguard Worker                     /* Get shader output value */
2483*35238bceSAndroid Build Coastguard Worker                     glw::GLuint base_index_of_vertex_internal =
2484*35238bceSAndroid Build Coastguard Worker                         base_index_of_primitive + n_primitive_vertex * stride_in_floats;
2485*35238bceSAndroid Build Coastguard Worker                     glw::GLuint checkpoint_position_index_internal =
2486*35238bceSAndroid Build Coastguard Worker                         base_index_of_vertex_internal + clipdistances_array_size + culldistances_array_size +
2487*35238bceSAndroid Build Coastguard Worker                         2 /* ignore vertex coordinates */;
2488*35238bceSAndroid Build Coastguard Worker                     glw::GLuint culldistances_index = base_index_of_vertex_internal + clipdistances_array_size;
2489*35238bceSAndroid Build Coastguard Worker                     glw::GLint checkpoint_x_internal =
2490*35238bceSAndroid Build Coastguard Worker                         glw::GLint(glw::GLfloat(m_to_width) * m_bo_data[checkpoint_position_index_internal]);
2491*35238bceSAndroid Build Coastguard Worker                     glw::GLint checkpoint_y_internal =
2492*35238bceSAndroid Build Coastguard Worker                         glw::GLint(glw::GLfloat(m_to_height) * m_bo_data[checkpoint_position_index_internal + 1]);
2493*35238bceSAndroid Build Coastguard Worker                     glw::GLint vertex_color_red_value = readRedPixelValue(checkpoint_x_internal, checkpoint_y_internal);
2494*35238bceSAndroid Build Coastguard Worker 
2495*35238bceSAndroid Build Coastguard Worker                     /* Calculate culldistances check sum hash */
2496*35238bceSAndroid Build Coastguard Worker                     float sum = 0.f;
2497*35238bceSAndroid Build Coastguard Worker 
2498*35238bceSAndroid Build Coastguard Worker                     for (glw::GLuint n_clipdistance_entry = 0; n_clipdistance_entry < clipdistances_array_size;
2499*35238bceSAndroid Build Coastguard Worker                          ++n_clipdistance_entry)
2500*35238bceSAndroid Build Coastguard Worker                     {
2501*35238bceSAndroid Build Coastguard Worker                         sum += de::abs(m_bo_data[base_index_of_vertex_internal + n_clipdistance_entry]) *
2502*35238bceSAndroid Build Coastguard Worker                                float(n_clipdistance_entry + 1);
2503*35238bceSAndroid Build Coastguard Worker                     }
2504*35238bceSAndroid Build Coastguard Worker 
2505*35238bceSAndroid Build Coastguard Worker                     for (glw::GLuint n_culldistance_entry = 0; n_culldistance_entry < culldistances_array_size;
2506*35238bceSAndroid Build Coastguard Worker                          ++n_culldistance_entry)
2507*35238bceSAndroid Build Coastguard Worker                     {
2508*35238bceSAndroid Build Coastguard Worker                         sum += de::abs(m_bo_data[culldistances_index + n_culldistance_entry]) *
2509*35238bceSAndroid Build Coastguard Worker                                float(n_culldistance_entry + 1 + clipdistances_array_size);
2510*35238bceSAndroid Build Coastguard Worker                     }
2511*35238bceSAndroid Build Coastguard Worker 
2512*35238bceSAndroid Build Coastguard Worker                     /* limit sum and return */
2513*35238bceSAndroid Build Coastguard Worker                     glw::GLint sum_hash =
2514*35238bceSAndroid Build Coastguard Worker                         glw::GLint(sum /
2515*35238bceSAndroid Build Coastguard Worker                                    glw::GLfloat((clipdistances_array_size + culldistances_array_size) *
2516*35238bceSAndroid Build Coastguard Worker                                                 (clipdistances_array_size + culldistances_array_size + 1)) *
2517*35238bceSAndroid Build Coastguard Worker                                    65535.f /* normalizing to short */);
2518*35238bceSAndroid Build Coastguard Worker                     sum_hash = (sum_hash < 65536) ? sum_hash : 65535; /* clamping to short */
2519*35238bceSAndroid Build Coastguard Worker 
2520*35238bceSAndroid Build Coastguard Worker                     /* Compare against setup value */
2521*35238bceSAndroid Build Coastguard Worker                     if (std::abs(vertex_color_red_value - sum_hash) > 4 /* precision 4/65536 */)
2522*35238bceSAndroid Build Coastguard Worker                     {
2523*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog()
2524*35238bceSAndroid Build Coastguard Worker                             << tcu::TestLog::Message << "Primitive number [" << n_primitive_index << "] "
2525*35238bceSAndroid Build Coastguard Worker                             << "should have culldistance hash sum " << sum_hash << "but primitive vertex at ("
2526*35238bceSAndroid Build Coastguard Worker                             << checkpoint_x << "," << checkpoint_y << ") has sum hash equal to "
2527*35238bceSAndroid Build Coastguard Worker                             << vertex_color_red_value << tcu::TestLog::EndMessage;
2528*35238bceSAndroid Build Coastguard Worker 
2529*35238bceSAndroid Build Coastguard Worker                         TCU_FAIL("Culled distances returned from fragment shader dose not match expected values.");
2530*35238bceSAndroid Build Coastguard Worker                     }
2531*35238bceSAndroid Build Coastguard Worker                 }
2532*35238bceSAndroid Build Coastguard Worker             }
2533*35238bceSAndroid Build Coastguard Worker         }
2534*35238bceSAndroid Build Coastguard Worker     }
2535*35238bceSAndroid Build Coastguard Worker 
2536*35238bceSAndroid Build Coastguard Worker     /* sub_grid cell size is 3*3 */
2537*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_render_primitives % 9 == 0);
2538*35238bceSAndroid Build Coastguard Worker 
2539*35238bceSAndroid Build Coastguard Worker     /* Quick check */
2540*35238bceSAndroid Build Coastguard Worker     switch (primitive_mode)
2541*35238bceSAndroid Build Coastguard Worker     {
2542*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_MODE_LINES:
2543*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_MODE_TRIANGLES:
2544*35238bceSAndroid Build Coastguard Worker     {
2545*35238bceSAndroid Build Coastguard Worker         /* Validate culled primitives */
2546*35238bceSAndroid Build Coastguard Worker         if (culldistances_array_size == 0)
2547*35238bceSAndroid Build Coastguard Worker         {
2548*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(n_culled_primitives_real == 0);
2549*35238bceSAndroid Build Coastguard Worker         }
2550*35238bceSAndroid Build Coastguard Worker         else
2551*35238bceSAndroid Build Coastguard Worker         {
2552*35238bceSAndroid Build Coastguard Worker             /* Each 3rd line or triangle should be culled by test design */
2553*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(glw::GLsizei(n_culled_primitives_real) == m_render_primitives / 3);
2554*35238bceSAndroid Build Coastguard Worker         }
2555*35238bceSAndroid Build Coastguard Worker 
2556*35238bceSAndroid Build Coastguard Worker         /* Validate clipped vertices */
2557*35238bceSAndroid Build Coastguard Worker         if (clipdistances_array_size == 0)
2558*35238bceSAndroid Build Coastguard Worker         {
2559*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(n_clipped_vertices_real == 0);
2560*35238bceSAndroid Build Coastguard Worker         }
2561*35238bceSAndroid Build Coastguard Worker         else
2562*35238bceSAndroid Build Coastguard Worker         {
2563*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG) && !defined(DE_COVERAGE_BUILD)
2564*35238bceSAndroid Build Coastguard Worker             glw::GLint one_third_of_rendered_primitives = (m_render_primitives - n_culled_primitives_real) / 3;
2565*35238bceSAndroid Build Coastguard Worker             glw::GLint n_clipped_vertices_expected      = /* One third of primitives has 0th vertex clipped */
2566*35238bceSAndroid Build Coastguard Worker                 one_third_of_rendered_primitives +
2567*35238bceSAndroid Build Coastguard Worker                 /* One third of primitives clipped completely     */
2568*35238bceSAndroid Build Coastguard Worker                 one_third_of_rendered_primitives * primitive_vertices_count;
2569*35238bceSAndroid Build Coastguard Worker 
2570*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(glw::GLint(n_clipped_vertices_real) == n_clipped_vertices_expected);
2571*35238bceSAndroid Build Coastguard Worker #endif
2572*35238bceSAndroid Build Coastguard Worker         }
2573*35238bceSAndroid Build Coastguard Worker         break;
2574*35238bceSAndroid Build Coastguard Worker     }
2575*35238bceSAndroid Build Coastguard Worker 
2576*35238bceSAndroid Build Coastguard Worker     case PRIMITIVE_MODE_POINTS:
2577*35238bceSAndroid Build Coastguard Worker     {
2578*35238bceSAndroid Build Coastguard Worker         /* Validate culled primitives */
2579*35238bceSAndroid Build Coastguard Worker         if (culldistances_array_size == 0)
2580*35238bceSAndroid Build Coastguard Worker         {
2581*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(n_culled_primitives_real == 0);
2582*35238bceSAndroid Build Coastguard Worker         }
2583*35238bceSAndroid Build Coastguard Worker         else
2584*35238bceSAndroid Build Coastguard Worker         {
2585*35238bceSAndroid Build Coastguard Worker             /* 2/3 points should be culled by test design */
2586*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(glw::GLsizei(n_culled_primitives_real) == m_render_primitives * 2 / 3);
2587*35238bceSAndroid Build Coastguard Worker         }
2588*35238bceSAndroid Build Coastguard Worker 
2589*35238bceSAndroid Build Coastguard Worker         /* Validate clipped vertices */
2590*35238bceSAndroid Build Coastguard Worker         if (clipdistances_array_size == 0)
2591*35238bceSAndroid Build Coastguard Worker         {
2592*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(n_clipped_vertices_real == 0);
2593*35238bceSAndroid Build Coastguard Worker         }
2594*35238bceSAndroid Build Coastguard Worker         else
2595*35238bceSAndroid Build Coastguard Worker         {
2596*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG) && !defined(DE_COVERAGE_BUILD)
2597*35238bceSAndroid Build Coastguard Worker             glw::GLint one_third_of_rendered_primitives = (m_render_primitives - n_culled_primitives_real) / 3;
2598*35238bceSAndroid Build Coastguard Worker 
2599*35238bceSAndroid Build Coastguard Worker             /* 2/3 of rendered points should be clipped by test design */
2600*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(glw::GLint(n_clipped_vertices_real) == 2 * one_third_of_rendered_primitives);
2601*35238bceSAndroid Build Coastguard Worker #endif
2602*35238bceSAndroid Build Coastguard Worker         }
2603*35238bceSAndroid Build Coastguard Worker 
2604*35238bceSAndroid Build Coastguard Worker         break;
2605*35238bceSAndroid Build Coastguard Worker     }
2606*35238bceSAndroid Build Coastguard Worker     default:
2607*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unknown primitive mode");
2608*35238bceSAndroid Build Coastguard Worker     }
2609*35238bceSAndroid Build Coastguard Worker }
2610*35238bceSAndroid Build Coastguard Worker 
2611*35238bceSAndroid Build Coastguard Worker /** Executes test iteration.
2612*35238bceSAndroid Build Coastguard Worker  *
2613*35238bceSAndroid Build Coastguard Worker  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2614*35238bceSAndroid Build Coastguard Worker  */
iterate()2615*35238bceSAndroid Build Coastguard Worker tcu::TestNode::IterateResult CullDistance::FunctionalTest::iterate()
2616*35238bceSAndroid Build Coastguard Worker {
2617*35238bceSAndroid Build Coastguard Worker     /* This test should only be executed if ARB_cull_distance is supported, or if
2618*35238bceSAndroid Build Coastguard Worker      * we're running a GL4.5 context
2619*35238bceSAndroid Build Coastguard Worker      */
2620*35238bceSAndroid Build Coastguard Worker     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_cull_distance") &&
2621*35238bceSAndroid Build Coastguard Worker         !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
2622*35238bceSAndroid Build Coastguard Worker     {
2623*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("GL_ARB_cull_distance is not supported");
2624*35238bceSAndroid Build Coastguard Worker     }
2625*35238bceSAndroid Build Coastguard Worker 
2626*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2627*35238bceSAndroid Build Coastguard Worker     bool has_succeeded       = true;
2628*35238bceSAndroid Build Coastguard Worker     bool is_core             = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
2629*35238bceSAndroid Build Coastguard Worker 
2630*35238bceSAndroid Build Coastguard Worker     /* Retrieve important GL constant values */
2631*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_clip_distances_value                   = 0;
2632*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_combined_clip_and_cull_distances_value = 0;
2633*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_cull_distances_value                   = 0;
2634*35238bceSAndroid Build Coastguard Worker 
2635*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max_clip_distances_value);
2636*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES, &gl_max_combined_clip_and_cull_distances_value);
2637*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_CULL_DISTANCES, &gl_max_cull_distances_value);
2638*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call(s) failed.");
2639*35238bceSAndroid Build Coastguard Worker 
2640*35238bceSAndroid Build Coastguard Worker     gl.genTextures(1, &m_to_id);
2641*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
2642*35238bceSAndroid Build Coastguard Worker 
2643*35238bceSAndroid Build Coastguard Worker     gl.bindTexture(GL_TEXTURE_2D, m_to_id);
2644*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
2645*35238bceSAndroid Build Coastguard Worker 
2646*35238bceSAndroid Build Coastguard Worker     gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
2647*35238bceSAndroid Build Coastguard Worker                     GL_R32F, m_to_width, m_to_height);
2648*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
2649*35238bceSAndroid Build Coastguard Worker 
2650*35238bceSAndroid Build Coastguard Worker     /* Set up the draw/read FBO */
2651*35238bceSAndroid Build Coastguard Worker     gl.genFramebuffers(1, &m_fbo_id);
2652*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
2653*35238bceSAndroid Build Coastguard Worker 
2654*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
2655*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
2656*35238bceSAndroid Build Coastguard Worker 
2657*35238bceSAndroid Build Coastguard Worker     gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0); /* level */
2658*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
2659*35238bceSAndroid Build Coastguard Worker 
2660*35238bceSAndroid Build Coastguard Worker     /* Prepare a buffer object */
2661*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_bo_id);
2662*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2663*35238bceSAndroid Build Coastguard Worker 
2664*35238bceSAndroid Build Coastguard Worker     /* Prepare a VAO. We will configure separately for each iteration. */
2665*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &m_vao_id);
2666*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2667*35238bceSAndroid Build Coastguard Worker 
2668*35238bceSAndroid Build Coastguard Worker     /* Iterate over all functional tests */
2669*35238bceSAndroid Build Coastguard Worker     struct _test_item
2670*35238bceSAndroid Build Coastguard Worker     {
2671*35238bceSAndroid Build Coastguard Worker         bool redeclare_clipdistances_array;
2672*35238bceSAndroid Build Coastguard Worker         bool redeclare_culldistances_array;
2673*35238bceSAndroid Build Coastguard Worker         bool dynamic_index_writes;
2674*35238bceSAndroid Build Coastguard Worker         bool use_passthrough_gs;
2675*35238bceSAndroid Build Coastguard Worker         bool use_passthrough_ts;
2676*35238bceSAndroid Build Coastguard Worker         bool use_core_functionality;
2677*35238bceSAndroid Build Coastguard Worker         bool fetch_culldistances;
2678*35238bceSAndroid Build Coastguard Worker     } test_items[]                 = {/* Use the basic outline to test the basic functionality of cull distances. */
2679*35238bceSAndroid Build Coastguard Worker                       {
2680*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_clipdistances_array */
2681*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_culldistances_array */
2682*35238bceSAndroid Build Coastguard Worker                           false,   /* dynamic_index_writes          */
2683*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_gs            */
2684*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_ts            */
2685*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality        */
2686*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances           */
2687*35238bceSAndroid Build Coastguard Worker                       },
2688*35238bceSAndroid Build Coastguard Worker                       /* Use the basic outline but don't redeclare gl_ClipDistance with a size. */
2689*35238bceSAndroid Build Coastguard Worker                       {
2690*35238bceSAndroid Build Coastguard Worker                           false,   /* redeclare_clipdistances_array */
2691*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_culldistances_array */
2692*35238bceSAndroid Build Coastguard Worker                           false,   /* dynamic_index_writes          */
2693*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_gs            */
2694*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_ts            */
2695*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality        */
2696*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances           */
2697*35238bceSAndroid Build Coastguard Worker                       },
2698*35238bceSAndroid Build Coastguard Worker                       /* Use the basic outline but don't redeclare gl_CullDistance with a size. */
2699*35238bceSAndroid Build Coastguard Worker                       {
2700*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_clipdistances_array  */
2701*35238bceSAndroid Build Coastguard Worker                           false,   /* redeclare_culldistances_array  */
2702*35238bceSAndroid Build Coastguard Worker                           false,   /* dynamic_index_writes           */
2703*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_gs             */
2704*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_ts             */
2705*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality         */
2706*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances            */
2707*35238bceSAndroid Build Coastguard Worker                       },
2708*35238bceSAndroid Build Coastguard Worker                       /* Use the basic outline but don't redeclare either gl_ClipDistance or
2709*35238bceSAndroid Build Coastguard Worker                        * gl_CullDistance with a size.
2710*35238bceSAndroid Build Coastguard Worker                        */
2711*35238bceSAndroid Build Coastguard Worker                       {
2712*35238bceSAndroid Build Coastguard Worker                           false,   /* redeclare_clipdistances_array */
2713*35238bceSAndroid Build Coastguard Worker                           false,   /* redeclare_culldistances_array */
2714*35238bceSAndroid Build Coastguard Worker                           false,   /* dynamic_index_writes          */
2715*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_gs            */
2716*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_ts            */
2717*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality        */
2718*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances           */
2719*35238bceSAndroid Build Coastguard Worker                       },
2720*35238bceSAndroid Build Coastguard Worker                       /* Use the basic outline but use dynamic indexing when writing the elements
2721*35238bceSAndroid Build Coastguard Worker                        * of the gl_ClipDistance and gl_CullDistance arrays.
2722*35238bceSAndroid Build Coastguard Worker                        */
2723*35238bceSAndroid Build Coastguard Worker                       {
2724*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_clipdistances_array */
2725*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_culldistances_array */
2726*35238bceSAndroid Build Coastguard Worker                           true,    /* dynamic_index_writes          */
2727*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_gs            */
2728*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_ts            */
2729*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality        */
2730*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances           */
2731*35238bceSAndroid Build Coastguard Worker                       },
2732*35238bceSAndroid Build Coastguard Worker                       /* Use the basic outline but add a geometry shader to the program that
2733*35238bceSAndroid Build Coastguard Worker                        * simply passes through all written clip and cull distances.
2734*35238bceSAndroid Build Coastguard Worker                        */
2735*35238bceSAndroid Build Coastguard Worker                       {
2736*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_clipdistances_array */
2737*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_culldistances_array */
2738*35238bceSAndroid Build Coastguard Worker                           false,   /* dynamic_index_writes          */
2739*35238bceSAndroid Build Coastguard Worker                           true,    /* use_passthrough_gs            */
2740*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_ts            */
2741*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality        */
2742*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances           */
2743*35238bceSAndroid Build Coastguard Worker                       },
2744*35238bceSAndroid Build Coastguard Worker                       /* Use the basic outline but add a tessellation control and tessellation
2745*35238bceSAndroid Build Coastguard Worker                        * evaluation shader to the program which simply pass through all written
2746*35238bceSAndroid Build Coastguard Worker                        * clip and cull distances.
2747*35238bceSAndroid Build Coastguard Worker                        */
2748*35238bceSAndroid Build Coastguard Worker                       {
2749*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_clipdistances_array */
2750*35238bceSAndroid Build Coastguard Worker                           true,    /* redeclare_culldistances_array */
2751*35238bceSAndroid Build Coastguard Worker                           false,   /* dynamic_index_writes          */
2752*35238bceSAndroid Build Coastguard Worker                           false,   /* use_passthrough_gs            */
2753*35238bceSAndroid Build Coastguard Worker                           true,    /* use_passthrough_ts            */
2754*35238bceSAndroid Build Coastguard Worker                           is_core, /* use_core_functionality        */
2755*35238bceSAndroid Build Coastguard Worker                           false    /* fetch_culldistances           */
2756*35238bceSAndroid Build Coastguard Worker                       },
2757*35238bceSAndroid Build Coastguard Worker                       /* Test that using #extension with GL_ARB_cull_distance allows using the
2758*35238bceSAndroid Build Coastguard Worker                        * feature even with an earlier version of GLSL. Also test that the
2759*35238bceSAndroid Build Coastguard Worker                        * extension name is available as preprocessor #define.
2760*35238bceSAndroid Build Coastguard Worker                        */
2761*35238bceSAndroid Build Coastguard Worker                       {
2762*35238bceSAndroid Build Coastguard Worker                           true,  /* redeclare_clipdistances_array */
2763*35238bceSAndroid Build Coastguard Worker                           true,  /* redeclare_culldistances_array */
2764*35238bceSAndroid Build Coastguard Worker                           false, /* dynamic_index_writes          */
2765*35238bceSAndroid Build Coastguard Worker                           false, /* use_passthrough_gs            */
2766*35238bceSAndroid Build Coastguard Worker                           false, /* use_passthrough_ts            */
2767*35238bceSAndroid Build Coastguard Worker                           false, /* use_core_functionality        */
2768*35238bceSAndroid Build Coastguard Worker                           false  /* fetch_culldistances           */
2769*35238bceSAndroid Build Coastguard Worker                       },
2770*35238bceSAndroid Build Coastguard Worker                       /* Use a program that has only a vertex shader and a fragment shader.
2771*35238bceSAndroid Build Coastguard Worker                        * The vertex shader should redeclare gl_ClipDistance with a size that
2772*35238bceSAndroid Build Coastguard Worker                        * fits all enabled cull distances. Also redeclare gl_CullDistance with a
2773*35238bceSAndroid Build Coastguard Worker                        * size. The sum of the two sizes should not be more than MAX_COMBINED_-
2774*35238bceSAndroid Build Coastguard Worker                        * CLIP_AND_CULL_DISTANCES. The fragment shader should output the cull
2775*35238bceSAndroid Build Coastguard Worker                        * distances written by the vertex shader by reading them from the built-in
2776*35238bceSAndroid Build Coastguard Worker                        * array gl_CullDistance.
2777*35238bceSAndroid Build Coastguard Worker                        */
2778*35238bceSAndroid Build Coastguard Worker                       {
2779*35238bceSAndroid Build Coastguard Worker                           true,  /* redeclare_clipdistances_array */
2780*35238bceSAndroid Build Coastguard Worker                           true,  /* redeclare_culldistances_array */
2781*35238bceSAndroid Build Coastguard Worker                           false, /* dynamic_index_writes          */
2782*35238bceSAndroid Build Coastguard Worker                           false, /* use_passthrough_gs            */
2783*35238bceSAndroid Build Coastguard Worker                           false, /* use_passthrough_ts            */
2784*35238bceSAndroid Build Coastguard Worker                           false, /* use_core_functionality        */
2785*35238bceSAndroid Build Coastguard Worker                           true   /* fetch_culldistances           */
2786*35238bceSAndroid Build Coastguard Worker                       }};
2787*35238bceSAndroid Build Coastguard Worker     const glw::GLuint n_test_items = sizeof(test_items) / sizeof(test_items[0]);
2788*35238bceSAndroid Build Coastguard Worker 
2789*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, m_to_width, m_to_height);
2790*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
2791*35238bceSAndroid Build Coastguard Worker 
2792*35238bceSAndroid Build Coastguard Worker     gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
2793*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
2794*35238bceSAndroid Build Coastguard Worker 
2795*35238bceSAndroid Build Coastguard Worker     for (glw::GLuint n_test_item = 0; n_test_item < n_test_items; ++n_test_item)
2796*35238bceSAndroid Build Coastguard Worker     {
2797*35238bceSAndroid Build Coastguard Worker         /* Check for OpenGL feature support */
2798*35238bceSAndroid Build Coastguard Worker         if (test_items[n_test_item].use_passthrough_ts)
2799*35238bceSAndroid Build Coastguard Worker         {
2800*35238bceSAndroid Build Coastguard Worker             if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)) &&
2801*35238bceSAndroid Build Coastguard Worker                 !m_context.getContextInfo().isExtensionSupported("GL_ARB_tessellation_shader"))
2802*35238bceSAndroid Build Coastguard Worker             {
2803*35238bceSAndroid Build Coastguard Worker                 continue; // no tessellation shader support
2804*35238bceSAndroid Build Coastguard Worker             }
2805*35238bceSAndroid Build Coastguard Worker         }
2806*35238bceSAndroid Build Coastguard Worker 
2807*35238bceSAndroid Build Coastguard Worker         const _test_item &current_test_item                         = test_items[n_test_item];
2808*35238bceSAndroid Build Coastguard Worker         const _primitive_mode primitive_modes[PRIMITIVE_MODE_COUNT] = {PRIMITIVE_MODE_LINES, PRIMITIVE_MODE_POINTS,
2809*35238bceSAndroid Build Coastguard Worker                                                                        PRIMITIVE_MODE_TRIANGLES};
2810*35238bceSAndroid Build Coastguard Worker 
2811*35238bceSAndroid Build Coastguard Worker         for (glw::GLuint primitive_mode_index = 0; primitive_mode_index < PRIMITIVE_MODE_COUNT; ++primitive_mode_index)
2812*35238bceSAndroid Build Coastguard Worker         {
2813*35238bceSAndroid Build Coastguard Worker             _primitive_mode primitive_mode = primitive_modes[primitive_mode_index];
2814*35238bceSAndroid Build Coastguard Worker 
2815*35238bceSAndroid Build Coastguard Worker             /* Iterate over a set of gl_ClipDistances[] and gl_CullDistances[] array sizes */
2816*35238bceSAndroid Build Coastguard Worker             for (glw::GLint n_iteration = 0; n_iteration <= gl_max_combined_clip_and_cull_distances_value;
2817*35238bceSAndroid Build Coastguard Worker                  ++n_iteration)
2818*35238bceSAndroid Build Coastguard Worker             {
2819*35238bceSAndroid Build Coastguard Worker                 glw::GLuint clipdistances_array_size = 0;
2820*35238bceSAndroid Build Coastguard Worker                 glw::GLuint culldistances_array_size = 0;
2821*35238bceSAndroid Build Coastguard Worker 
2822*35238bceSAndroid Build Coastguard Worker                 if (n_iteration != 0 && n_iteration <= gl_max_clip_distances_value)
2823*35238bceSAndroid Build Coastguard Worker                 {
2824*35238bceSAndroid Build Coastguard Worker                     clipdistances_array_size = n_iteration;
2825*35238bceSAndroid Build Coastguard Worker                 }
2826*35238bceSAndroid Build Coastguard Worker 
2827*35238bceSAndroid Build Coastguard Worker                 if ((gl_max_combined_clip_and_cull_distances_value - n_iteration) < gl_max_cull_distances_value)
2828*35238bceSAndroid Build Coastguard Worker                 {
2829*35238bceSAndroid Build Coastguard Worker                     culldistances_array_size = gl_max_combined_clip_and_cull_distances_value - n_iteration;
2830*35238bceSAndroid Build Coastguard Worker                 }
2831*35238bceSAndroid Build Coastguard Worker                 else
2832*35238bceSAndroid Build Coastguard Worker                 {
2833*35238bceSAndroid Build Coastguard Worker                     culldistances_array_size = gl_max_cull_distances_value;
2834*35238bceSAndroid Build Coastguard Worker                 }
2835*35238bceSAndroid Build Coastguard Worker 
2836*35238bceSAndroid Build Coastguard Worker                 if (clipdistances_array_size == 0 && culldistances_array_size == 0)
2837*35238bceSAndroid Build Coastguard Worker                 {
2838*35238bceSAndroid Build Coastguard Worker                     /* Skip the empty iteration */
2839*35238bceSAndroid Build Coastguard Worker                     continue;
2840*35238bceSAndroid Build Coastguard Worker                 }
2841*35238bceSAndroid Build Coastguard Worker 
2842*35238bceSAndroid Build Coastguard Worker                 if (current_test_item.fetch_culldistances && (primitive_mode != PRIMITIVE_MODE_POINTS))
2843*35238bceSAndroid Build Coastguard Worker                 {
2844*35238bceSAndroid Build Coastguard Worker                     continue;
2845*35238bceSAndroid Build Coastguard Worker                 }
2846*35238bceSAndroid Build Coastguard Worker 
2847*35238bceSAndroid Build Coastguard Worker                 /* Create a program to run */
2848*35238bceSAndroid Build Coastguard Worker                 buildPO(clipdistances_array_size, culldistances_array_size, current_test_item.dynamic_index_writes,
2849*35238bceSAndroid Build Coastguard Worker                         primitive_mode, current_test_item.redeclare_clipdistances_array,
2850*35238bceSAndroid Build Coastguard Worker                         current_test_item.redeclare_culldistances_array, current_test_item.use_core_functionality,
2851*35238bceSAndroid Build Coastguard Worker                         current_test_item.use_passthrough_gs, current_test_item.use_passthrough_ts,
2852*35238bceSAndroid Build Coastguard Worker                         current_test_item.fetch_culldistances);
2853*35238bceSAndroid Build Coastguard Worker 
2854*35238bceSAndroid Build Coastguard Worker                 /* Initialize VAO data */
2855*35238bceSAndroid Build Coastguard Worker                 configureVAO(clipdistances_array_size, culldistances_array_size, primitive_mode);
2856*35238bceSAndroid Build Coastguard Worker 
2857*35238bceSAndroid Build Coastguard Worker                 /* Run GLSL program and check results */
2858*35238bceSAndroid Build Coastguard Worker                 executeRenderTest(clipdistances_array_size, culldistances_array_size, primitive_mode,
2859*35238bceSAndroid Build Coastguard Worker                                   current_test_item.use_passthrough_ts, current_test_item.fetch_culldistances);
2860*35238bceSAndroid Build Coastguard Worker 
2861*35238bceSAndroid Build Coastguard Worker             } /* for (all iterations) */
2862*35238bceSAndroid Build Coastguard Worker         }     /* for (all test modes) */
2863*35238bceSAndroid Build Coastguard Worker     }         /* for (all test items) */
2864*35238bceSAndroid Build Coastguard Worker 
2865*35238bceSAndroid Build Coastguard Worker     /* All done */
2866*35238bceSAndroid Build Coastguard Worker     if (has_succeeded)
2867*35238bceSAndroid Build Coastguard Worker     {
2868*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2869*35238bceSAndroid Build Coastguard Worker     }
2870*35238bceSAndroid Build Coastguard Worker     else
2871*35238bceSAndroid Build Coastguard Worker     {
2872*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2873*35238bceSAndroid Build Coastguard Worker     }
2874*35238bceSAndroid Build Coastguard Worker 
2875*35238bceSAndroid Build Coastguard Worker     return STOP;
2876*35238bceSAndroid Build Coastguard Worker }
2877*35238bceSAndroid Build Coastguard Worker 
2878*35238bceSAndroid Build Coastguard Worker /** Returns pixel red component read from texture at position x, y.
2879*35238bceSAndroid Build Coastguard Worker  *
2880*35238bceSAndroid Build Coastguard Worker  *  @param x x-coordinate to read pixel color component from
2881*35238bceSAndroid Build Coastguard Worker  *  @param y y-coordinate to read pixel color component from
2882*35238bceSAndroid Build Coastguard Worker  **/
readRedPixelValue(glw::GLint x,glw::GLint y)2883*35238bceSAndroid Build Coastguard Worker glw::GLint CullDistance::FunctionalTest::readRedPixelValue(glw::GLint x, glw::GLint y)
2884*35238bceSAndroid Build Coastguard Worker {
2885*35238bceSAndroid Build Coastguard Worker     glw::GLint result = -1;
2886*35238bceSAndroid Build Coastguard Worker 
2887*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(x >= 0 && (glw::GLuint)x < m_to_width);
2888*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y >= 0 && (glw::GLuint)y < m_to_height);
2889*35238bceSAndroid Build Coastguard Worker 
2890*35238bceSAndroid Build Coastguard Worker     result = m_to_pixel_data_cache[(m_to_width * y + x) * m_to_pixel_data_cache_color_components];
2891*35238bceSAndroid Build Coastguard Worker 
2892*35238bceSAndroid Build Coastguard Worker     return result;
2893*35238bceSAndroid Build Coastguard Worker }
2894*35238bceSAndroid Build Coastguard Worker 
2895*35238bceSAndroid Build Coastguard Worker /** Reads texture into m_to_pixel_data_cache.
2896*35238bceSAndroid Build Coastguard Worker  *  Texture size determined by fields m_to_width, m_to_height
2897*35238bceSAndroid Build Coastguard Worker  **/
readTexturePixels()2898*35238bceSAndroid Build Coastguard Worker void CullDistance::FunctionalTest::readTexturePixels()
2899*35238bceSAndroid Build Coastguard Worker {
2900*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2901*35238bceSAndroid Build Coastguard Worker 
2902*35238bceSAndroid Build Coastguard Worker     m_to_pixel_data_cache.clear();
2903*35238bceSAndroid Build Coastguard Worker 
2904*35238bceSAndroid Build Coastguard Worker     m_to_pixel_data_cache.resize(m_to_width * m_to_height * m_to_pixel_data_cache_color_components);
2905*35238bceSAndroid Build Coastguard Worker 
2906*35238bceSAndroid Build Coastguard Worker     /* Read vertex from texture */
2907*35238bceSAndroid Build Coastguard Worker     gl.readPixels(0,           /* x      */
2908*35238bceSAndroid Build Coastguard Worker                   0,           /* y      */
2909*35238bceSAndroid Build Coastguard Worker                   m_to_width,  /* width  */
2910*35238bceSAndroid Build Coastguard Worker                   m_to_height, /* height */
2911*35238bceSAndroid Build Coastguard Worker                   GL_RGBA, GL_UNSIGNED_SHORT, &m_to_pixel_data_cache[0]);
2912*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
2913*35238bceSAndroid Build Coastguard Worker }
2914*35238bceSAndroid Build Coastguard Worker 
2915*35238bceSAndroid Build Coastguard Worker /** Constructor.
2916*35238bceSAndroid Build Coastguard Worker  *
2917*35238bceSAndroid Build Coastguard Worker  *  @param context Rendering context handle.
2918*35238bceSAndroid Build Coastguard Worker  **/
NegativeTest(deqp::Context & context)2919*35238bceSAndroid Build Coastguard Worker CullDistance::NegativeTest::NegativeTest(deqp::Context &context)
2920*35238bceSAndroid Build Coastguard Worker     : TestCase(context, "negative", "Cull Distance Negative Test")
2921*35238bceSAndroid Build Coastguard Worker     , m_fs_id(0)
2922*35238bceSAndroid Build Coastguard Worker     , m_po_id(0)
2923*35238bceSAndroid Build Coastguard Worker     , m_temp_buffer(DE_NULL)
2924*35238bceSAndroid Build Coastguard Worker     , m_vs_id(0)
2925*35238bceSAndroid Build Coastguard Worker {
2926*35238bceSAndroid Build Coastguard Worker     /* Left blank on purpose */
2927*35238bceSAndroid Build Coastguard Worker }
2928*35238bceSAndroid Build Coastguard Worker 
2929*35238bceSAndroid Build Coastguard Worker /** @brief Cull Distance Negative Test deinitialization */
deinit()2930*35238bceSAndroid Build Coastguard Worker void CullDistance::NegativeTest::deinit()
2931*35238bceSAndroid Build Coastguard Worker {
2932*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2933*35238bceSAndroid Build Coastguard Worker 
2934*35238bceSAndroid Build Coastguard Worker     if (m_fs_id != 0)
2935*35238bceSAndroid Build Coastguard Worker     {
2936*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_fs_id);
2937*35238bceSAndroid Build Coastguard Worker 
2938*35238bceSAndroid Build Coastguard Worker         m_fs_id = 0;
2939*35238bceSAndroid Build Coastguard Worker     }
2940*35238bceSAndroid Build Coastguard Worker 
2941*35238bceSAndroid Build Coastguard Worker     if (m_po_id != 0)
2942*35238bceSAndroid Build Coastguard Worker     {
2943*35238bceSAndroid Build Coastguard Worker         gl.deleteProgram(m_po_id);
2944*35238bceSAndroid Build Coastguard Worker 
2945*35238bceSAndroid Build Coastguard Worker         m_po_id = 0;
2946*35238bceSAndroid Build Coastguard Worker     }
2947*35238bceSAndroid Build Coastguard Worker 
2948*35238bceSAndroid Build Coastguard Worker     if (m_vs_id != 0)
2949*35238bceSAndroid Build Coastguard Worker     {
2950*35238bceSAndroid Build Coastguard Worker         gl.deleteShader(m_vs_id);
2951*35238bceSAndroid Build Coastguard Worker 
2952*35238bceSAndroid Build Coastguard Worker         m_vs_id = 0;
2953*35238bceSAndroid Build Coastguard Worker     }
2954*35238bceSAndroid Build Coastguard Worker 
2955*35238bceSAndroid Build Coastguard Worker     if (m_temp_buffer != DE_NULL)
2956*35238bceSAndroid Build Coastguard Worker     {
2957*35238bceSAndroid Build Coastguard Worker         delete[] m_temp_buffer;
2958*35238bceSAndroid Build Coastguard Worker 
2959*35238bceSAndroid Build Coastguard Worker         m_temp_buffer = DE_NULL;
2960*35238bceSAndroid Build Coastguard Worker     }
2961*35238bceSAndroid Build Coastguard Worker }
2962*35238bceSAndroid Build Coastguard Worker 
2963*35238bceSAndroid Build Coastguard Worker /** @brief Get string description of test with given parameters
2964*35238bceSAndroid Build Coastguard Worker  *
2965*35238bceSAndroid Build Coastguard Worker  *  @param [in] n_test_iteration                    Test iteration number
2966*35238bceSAndroid Build Coastguard Worker  *  @param [in] should_redeclare_output_variables   Indicate whether test redeclared gl_ClipDistance and gl_CullDistance
2967*35238bceSAndroid Build Coastguard Worker  *  @param [in] use_dynamic_index_based_writes      Indicate whether test used dynamic index-based setters
2968*35238bceSAndroid Build Coastguard Worker  *
2969*35238bceSAndroid Build Coastguard Worker  *  @return String containing description.
2970*35238bceSAndroid Build Coastguard Worker  */
getTestDescription(int n_test_iteration,bool should_redeclare_output_variables,bool use_dynamic_index_based_writes)2971*35238bceSAndroid Build Coastguard Worker std::string CullDistance::NegativeTest::getTestDescription(int n_test_iteration, bool should_redeclare_output_variables,
2972*35238bceSAndroid Build Coastguard Worker                                                            bool use_dynamic_index_based_writes)
2973*35238bceSAndroid Build Coastguard Worker {
2974*35238bceSAndroid Build Coastguard Worker     std::stringstream stream;
2975*35238bceSAndroid Build Coastguard Worker 
2976*35238bceSAndroid Build Coastguard Worker     stream << "Test iteration [" << n_test_iteration << "] which uses a vertex shader that:\n\n"
2977*35238bceSAndroid Build Coastguard Worker            << ((should_redeclare_output_variables) ?
2978*35238bceSAndroid Build Coastguard Worker                    "* redeclares gl_ClipDistance and gl_CullDistance arrays\n" :
2979*35238bceSAndroid Build Coastguard Worker                    "* does not redeclare gl_ClipDistance and gl_CullDistance arrays\n")
2980*35238bceSAndroid Build Coastguard Worker            << ((use_dynamic_index_based_writes) ? "* uses dynamic index-based writes\n" : "* uses static writes\n");
2981*35238bceSAndroid Build Coastguard Worker 
2982*35238bceSAndroid Build Coastguard Worker     return stream.str();
2983*35238bceSAndroid Build Coastguard Worker }
2984*35238bceSAndroid Build Coastguard Worker 
2985*35238bceSAndroid Build Coastguard Worker /** Executes test iteration.
2986*35238bceSAndroid Build Coastguard Worker  *
2987*35238bceSAndroid Build Coastguard Worker  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2988*35238bceSAndroid Build Coastguard Worker  */
iterate()2989*35238bceSAndroid Build Coastguard Worker tcu::TestNode::IterateResult CullDistance::NegativeTest::iterate()
2990*35238bceSAndroid Build Coastguard Worker {
2991*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2992*35238bceSAndroid Build Coastguard Worker 
2993*35238bceSAndroid Build Coastguard Worker     /* Build the test shaders. */
2994*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *token_dynamic_index_based_writes = "DYNAMIC_INDEX_BASED_WRITES";
2995*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *token_insert_static_writes       = "INSERT_STATIC_WRITES";
2996*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *token_n_gl_clipdistance_entries  = "N_GL_CLIPDISTANCE_ENTRIES";
2997*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *token_n_gl_culldistance_entries  = "N_GL_CULLDISTANCE_ENTRIES";
2998*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *token_redeclare_output_variables = "REDECLARE_OUTPUT_VARIABLES";
2999*35238bceSAndroid Build Coastguard Worker 
3000*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *fs_body = "#version 130\n"
3001*35238bceSAndroid Build Coastguard Worker                                  "\n"
3002*35238bceSAndroid Build Coastguard Worker                                  "void main()\n"
3003*35238bceSAndroid Build Coastguard Worker                                  "{\n"
3004*35238bceSAndroid Build Coastguard Worker                                  "}\n";
3005*35238bceSAndroid Build Coastguard Worker 
3006*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *vs_body_preamble = "#version 130\n"
3007*35238bceSAndroid Build Coastguard Worker                                           "\n"
3008*35238bceSAndroid Build Coastguard Worker                                           "    #extension GL_ARB_cull_distance : require\n"
3009*35238bceSAndroid Build Coastguard Worker                                           "\n";
3010*35238bceSAndroid Build Coastguard Worker 
3011*35238bceSAndroid Build Coastguard Worker     const glw::GLchar *vs_body_main = "#ifdef REDECLARE_OUTPUT_VARIABLES\n"
3012*35238bceSAndroid Build Coastguard Worker                                       "    out float gl_ClipDistance[N_GL_CLIPDISTANCE_ENTRIES];\n"
3013*35238bceSAndroid Build Coastguard Worker                                       "    out float gl_CullDistance[N_GL_CULLDISTANCE_ENTRIES];\n"
3014*35238bceSAndroid Build Coastguard Worker                                       "#endif\n"
3015*35238bceSAndroid Build Coastguard Worker                                       "\n"
3016*35238bceSAndroid Build Coastguard Worker                                       "void main()\n"
3017*35238bceSAndroid Build Coastguard Worker                                       "{\n"
3018*35238bceSAndroid Build Coastguard Worker                                       "#ifdef DYNAMIC_INDEX_BASED_WRITES\n"
3019*35238bceSAndroid Build Coastguard Worker                                       "    for (int n_clipdistance_entry = 0;\n"
3020*35238bceSAndroid Build Coastguard Worker                                       "             n_clipdistance_entry < N_GL_CLIPDISTANCE_ENTRIES;\n"
3021*35238bceSAndroid Build Coastguard Worker                                       "           ++n_clipdistance_entry)\n"
3022*35238bceSAndroid Build Coastguard Worker                                       "    {\n"
3023*35238bceSAndroid Build Coastguard Worker                                       "        gl_ClipDistance[n_clipdistance_entry] = float(n_clipdistance_entry) / "
3024*35238bceSAndroid Build Coastguard Worker                                       "float(N_GL_CLIPDISTANCE_ENTRIES);\n"
3025*35238bceSAndroid Build Coastguard Worker                                       "    }\n"
3026*35238bceSAndroid Build Coastguard Worker                                       "\n"
3027*35238bceSAndroid Build Coastguard Worker                                       "    for (int n_culldistance_entry = 0;\n"
3028*35238bceSAndroid Build Coastguard Worker                                       "             n_culldistance_entry < N_GL_CULLDISTANCE_ENTRIES;\n"
3029*35238bceSAndroid Build Coastguard Worker                                       "           ++n_culldistance_entry)\n"
3030*35238bceSAndroid Build Coastguard Worker                                       "    {\n"
3031*35238bceSAndroid Build Coastguard Worker                                       "        gl_CullDistance[n_culldistance_entry] = float(n_culldistance_entry) / "
3032*35238bceSAndroid Build Coastguard Worker                                       "float(N_GL_CULLDISTANCE_ENTRIES);\n"
3033*35238bceSAndroid Build Coastguard Worker                                       "    }\n"
3034*35238bceSAndroid Build Coastguard Worker                                       "#else\n"
3035*35238bceSAndroid Build Coastguard Worker                                       "    INSERT_STATIC_WRITES\n"
3036*35238bceSAndroid Build Coastguard Worker                                       "#endif\n"
3037*35238bceSAndroid Build Coastguard Worker                                       "}\n";
3038*35238bceSAndroid Build Coastguard Worker 
3039*35238bceSAndroid Build Coastguard Worker     /* This test should only be executed if ARB_cull_distance is supported, or if
3040*35238bceSAndroid Build Coastguard Worker      * we're running a GL4.5 context
3041*35238bceSAndroid Build Coastguard Worker      */
3042*35238bceSAndroid Build Coastguard Worker     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_cull_distance") &&
3043*35238bceSAndroid Build Coastguard Worker         !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
3044*35238bceSAndroid Build Coastguard Worker     {
3045*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("GL_ARB_cull_distance is not supported");
3046*35238bceSAndroid Build Coastguard Worker     }
3047*35238bceSAndroid Build Coastguard Worker 
3048*35238bceSAndroid Build Coastguard Worker     /* It only makes sense to run this test if GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES
3049*35238bceSAndroid Build Coastguard Worker      * is lower than a sum of GL_MAX_CLIP_DISTANCES and GL_MAX_CLIP_CULL_DISTANCES.
3050*35238bceSAndroid Build Coastguard Worker      */
3051*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_clip_distances_value                   = 0;
3052*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_combined_clip_and_cull_distances_value = 0;
3053*35238bceSAndroid Build Coastguard Worker     glw::GLint gl_max_cull_distances_value                   = 0;
3054*35238bceSAndroid Build Coastguard Worker     glw::GLuint n_gl_clipdistance_array_items                = 0;
3055*35238bceSAndroid Build Coastguard Worker     std::string n_gl_clipdistance_array_items_string;
3056*35238bceSAndroid Build Coastguard Worker     glw::GLuint n_gl_culldistance_array_items = 0;
3057*35238bceSAndroid Build Coastguard Worker     std::string n_gl_culldistance_array_items_string;
3058*35238bceSAndroid Build Coastguard Worker     std::string static_write_shader_body_part;
3059*35238bceSAndroid Build Coastguard Worker 
3060*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max_clip_distances_value);
3061*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES, &gl_max_combined_clip_and_cull_distances_value);
3062*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_MAX_CULL_DISTANCES, &gl_max_cull_distances_value);
3063*35238bceSAndroid Build Coastguard Worker 
3064*35238bceSAndroid Build Coastguard Worker     if (gl_max_clip_distances_value + gl_max_cull_distances_value < gl_max_combined_clip_and_cull_distances_value)
3065*35238bceSAndroid Build Coastguard Worker     {
3066*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
3067*35238bceSAndroid Build Coastguard Worker                            << "GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES is larger than or equal to "
3068*35238bceSAndroid Build Coastguard Worker                               "the sum of GL_MAX_CLIP_DISTANCES and GL_MAX_CULL_DISTANCES. Skipping."
3069*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
3070*35238bceSAndroid Build Coastguard Worker 
3071*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3072*35238bceSAndroid Build Coastguard Worker 
3073*35238bceSAndroid Build Coastguard Worker         return STOP;
3074*35238bceSAndroid Build Coastguard Worker     }
3075*35238bceSAndroid Build Coastguard Worker 
3076*35238bceSAndroid Build Coastguard Worker     n_gl_clipdistance_array_items = gl_max_clip_distances_value;
3077*35238bceSAndroid Build Coastguard Worker     n_gl_culldistance_array_items = gl_max_combined_clip_and_cull_distances_value - gl_max_clip_distances_value + 1;
3078*35238bceSAndroid Build Coastguard Worker 
3079*35238bceSAndroid Build Coastguard Worker     /* Determine the number of items we will want the gl_ClipDistance and gl_CullDistance arrays
3080*35238bceSAndroid Build Coastguard Worker      * to hold for test iterations that will re-declare the built-in output variables.
3081*35238bceSAndroid Build Coastguard Worker      */
3082*35238bceSAndroid Build Coastguard Worker     {
3083*35238bceSAndroid Build Coastguard Worker         std::stringstream temp_sstream;
3084*35238bceSAndroid Build Coastguard Worker 
3085*35238bceSAndroid Build Coastguard Worker         temp_sstream << n_gl_clipdistance_array_items;
3086*35238bceSAndroid Build Coastguard Worker 
3087*35238bceSAndroid Build Coastguard Worker         n_gl_clipdistance_array_items_string = temp_sstream.str();
3088*35238bceSAndroid Build Coastguard Worker     }
3089*35238bceSAndroid Build Coastguard Worker 
3090*35238bceSAndroid Build Coastguard Worker     {
3091*35238bceSAndroid Build Coastguard Worker         std::stringstream temp_sstream;
3092*35238bceSAndroid Build Coastguard Worker 
3093*35238bceSAndroid Build Coastguard Worker         temp_sstream << n_gl_culldistance_array_items;
3094*35238bceSAndroid Build Coastguard Worker 
3095*35238bceSAndroid Build Coastguard Worker         n_gl_culldistance_array_items_string = temp_sstream.str();
3096*35238bceSAndroid Build Coastguard Worker     }
3097*35238bceSAndroid Build Coastguard Worker 
3098*35238bceSAndroid Build Coastguard Worker     /* Form the "static write" shader body part. */
3099*35238bceSAndroid Build Coastguard Worker     {
3100*35238bceSAndroid Build Coastguard Worker         std::stringstream temp_sstream;
3101*35238bceSAndroid Build Coastguard Worker 
3102*35238bceSAndroid Build Coastguard Worker         temp_sstream << "gl_ClipDistance[" << n_gl_clipdistance_array_items_string.c_str() << "] = 0.0f;\n"
3103*35238bceSAndroid Build Coastguard Worker                      << "gl_CullDistance[" << n_gl_culldistance_array_items_string.c_str() << "] = 0.0f;\n";
3104*35238bceSAndroid Build Coastguard Worker 
3105*35238bceSAndroid Build Coastguard Worker         static_write_shader_body_part = temp_sstream.str();
3106*35238bceSAndroid Build Coastguard Worker     }
3107*35238bceSAndroid Build Coastguard Worker 
3108*35238bceSAndroid Build Coastguard Worker     /* Prepare GL objects before we continue */
3109*35238bceSAndroid Build Coastguard Worker     glw::GLint compile_status = GL_FALSE;
3110*35238bceSAndroid Build Coastguard Worker 
3111*35238bceSAndroid Build Coastguard Worker     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
3112*35238bceSAndroid Build Coastguard Worker     m_po_id = gl.createProgram();
3113*35238bceSAndroid Build Coastguard Worker     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3114*35238bceSAndroid Build Coastguard Worker 
3115*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() / glCreateShader() calls failed.");
3116*35238bceSAndroid Build Coastguard Worker 
3117*35238bceSAndroid Build Coastguard Worker     gl.attachShader(m_po_id, m_fs_id);
3118*35238bceSAndroid Build Coastguard Worker     gl.attachShader(m_po_id, m_vs_id);
3119*35238bceSAndroid Build Coastguard Worker 
3120*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
3121*35238bceSAndroid Build Coastguard Worker 
3122*35238bceSAndroid Build Coastguard Worker     gl.shaderSource(m_fs_id, 1,         /* count */
3123*35238bceSAndroid Build Coastguard Worker                     &fs_body, DE_NULL); /* length */
3124*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
3125*35238bceSAndroid Build Coastguard Worker 
3126*35238bceSAndroid Build Coastguard Worker     gl.compileShader(m_fs_id);
3127*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
3128*35238bceSAndroid Build Coastguard Worker 
3129*35238bceSAndroid Build Coastguard Worker     gl.getShaderiv(m_fs_id, GL_COMPILE_STATUS, &compile_status);
3130*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
3131*35238bceSAndroid Build Coastguard Worker 
3132*35238bceSAndroid Build Coastguard Worker     if (compile_status == GL_FALSE)
3133*35238bceSAndroid Build Coastguard Worker     {
3134*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Fragment shader failed to compile.");
3135*35238bceSAndroid Build Coastguard Worker     }
3136*35238bceSAndroid Build Coastguard Worker 
3137*35238bceSAndroid Build Coastguard Worker     /* Run three separate test iterations. */
3138*35238bceSAndroid Build Coastguard Worker     struct _test_item
3139*35238bceSAndroid Build Coastguard Worker     {
3140*35238bceSAndroid Build Coastguard Worker         bool should_redeclare_output_variables;
3141*35238bceSAndroid Build Coastguard Worker         bool use_dynamic_index_based_writes;
3142*35238bceSAndroid Build Coastguard Worker     } test_items[]                  = {/* Negative Test 1 */
3143*35238bceSAndroid Build Coastguard Worker                       {true, false},
3144*35238bceSAndroid Build Coastguard Worker 
3145*35238bceSAndroid Build Coastguard Worker                       /* Negative Test 2 */
3146*35238bceSAndroid Build Coastguard Worker                       {false, false},
3147*35238bceSAndroid Build Coastguard Worker 
3148*35238bceSAndroid Build Coastguard Worker                       /* Negative Test 3 */
3149*35238bceSAndroid Build Coastguard Worker                       {false, true}};
3150*35238bceSAndroid Build Coastguard Worker     const unsigned int n_test_items = sizeof(test_items) / sizeof(test_items[0]);
3151*35238bceSAndroid Build Coastguard Worker 
3152*35238bceSAndroid Build Coastguard Worker     for (unsigned int n_test_item = 0; n_test_item < n_test_items; ++n_test_item)
3153*35238bceSAndroid Build Coastguard Worker     {
3154*35238bceSAndroid Build Coastguard Worker         const _test_item &current_test_item = test_items[n_test_item];
3155*35238bceSAndroid Build Coastguard Worker 
3156*35238bceSAndroid Build Coastguard Worker         /* Prepare vertex shader body */
3157*35238bceSAndroid Build Coastguard Worker         std::size_t token_position = std::string::npos;
3158*35238bceSAndroid Build Coastguard Worker         std::stringstream vs_body_sstream;
3159*35238bceSAndroid Build Coastguard Worker         std::string vs_body_string;
3160*35238bceSAndroid Build Coastguard Worker 
3161*35238bceSAndroid Build Coastguard Worker         vs_body_sstream << vs_body_preamble << "\n";
3162*35238bceSAndroid Build Coastguard Worker 
3163*35238bceSAndroid Build Coastguard Worker         if (current_test_item.should_redeclare_output_variables)
3164*35238bceSAndroid Build Coastguard Worker         {
3165*35238bceSAndroid Build Coastguard Worker             vs_body_sstream << "#define " << token_redeclare_output_variables << "\n";
3166*35238bceSAndroid Build Coastguard Worker         }
3167*35238bceSAndroid Build Coastguard Worker 
3168*35238bceSAndroid Build Coastguard Worker         if (current_test_item.use_dynamic_index_based_writes)
3169*35238bceSAndroid Build Coastguard Worker         {
3170*35238bceSAndroid Build Coastguard Worker             vs_body_sstream << "#define " << token_dynamic_index_based_writes << "\n";
3171*35238bceSAndroid Build Coastguard Worker         }
3172*35238bceSAndroid Build Coastguard Worker 
3173*35238bceSAndroid Build Coastguard Worker         vs_body_sstream << vs_body_main;
3174*35238bceSAndroid Build Coastguard Worker 
3175*35238bceSAndroid Build Coastguard Worker         /* Replace tokens with meaningful values */
3176*35238bceSAndroid Build Coastguard Worker         vs_body_string = vs_body_sstream.str();
3177*35238bceSAndroid Build Coastguard Worker 
3178*35238bceSAndroid Build Coastguard Worker         while ((token_position = vs_body_string.find(token_n_gl_clipdistance_entries)) != std::string::npos)
3179*35238bceSAndroid Build Coastguard Worker         {
3180*35238bceSAndroid Build Coastguard Worker             vs_body_string = vs_body_string.replace(token_position, strlen(token_n_gl_clipdistance_entries),
3181*35238bceSAndroid Build Coastguard Worker                                                     n_gl_clipdistance_array_items_string);
3182*35238bceSAndroid Build Coastguard Worker         }
3183*35238bceSAndroid Build Coastguard Worker 
3184*35238bceSAndroid Build Coastguard Worker         while ((token_position = vs_body_string.find(token_n_gl_culldistance_entries)) != std::string::npos)
3185*35238bceSAndroid Build Coastguard Worker         {
3186*35238bceSAndroid Build Coastguard Worker             vs_body_string = vs_body_string.replace(token_position, strlen(token_n_gl_clipdistance_entries),
3187*35238bceSAndroid Build Coastguard Worker                                                     n_gl_culldistance_array_items_string);
3188*35238bceSAndroid Build Coastguard Worker         }
3189*35238bceSAndroid Build Coastguard Worker 
3190*35238bceSAndroid Build Coastguard Worker         while ((token_position = vs_body_string.find(token_insert_static_writes)) != std::string::npos)
3191*35238bceSAndroid Build Coastguard Worker         {
3192*35238bceSAndroid Build Coastguard Worker             vs_body_string = vs_body_string.replace(token_position, strlen(token_insert_static_writes),
3193*35238bceSAndroid Build Coastguard Worker                                                     static_write_shader_body_part);
3194*35238bceSAndroid Build Coastguard Worker         }
3195*35238bceSAndroid Build Coastguard Worker 
3196*35238bceSAndroid Build Coastguard Worker         /* Try to compile the vertex shader */
3197*35238bceSAndroid Build Coastguard Worker         glw::GLint compile_status_internal = GL_FALSE;
3198*35238bceSAndroid Build Coastguard Worker         const char *vs_body_raw_ptr        = vs_body_string.c_str();
3199*35238bceSAndroid Build Coastguard Worker 
3200*35238bceSAndroid Build Coastguard Worker         gl.shaderSource(m_vs_id, 1,                 /* count */
3201*35238bceSAndroid Build Coastguard Worker                         &vs_body_raw_ptr, DE_NULL); /* length */
3202*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
3203*35238bceSAndroid Build Coastguard Worker 
3204*35238bceSAndroid Build Coastguard Worker         gl.compileShader(m_vs_id);
3205*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
3206*35238bceSAndroid Build Coastguard Worker 
3207*35238bceSAndroid Build Coastguard Worker         gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status_internal);
3208*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
3209*35238bceSAndroid Build Coastguard Worker 
3210*35238bceSAndroid Build Coastguard Worker         if (compile_status_internal == GL_FALSE)
3211*35238bceSAndroid Build Coastguard Worker         {
3212*35238bceSAndroid Build Coastguard Worker             glw::GLint buffer_size = 0;
3213*35238bceSAndroid Build Coastguard Worker 
3214*35238bceSAndroid Build Coastguard Worker             /* Log the compilation error */
3215*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
3216*35238bceSAndroid Build Coastguard Worker                                << getTestDescription(n_test_item, current_test_item.should_redeclare_output_variables,
3217*35238bceSAndroid Build Coastguard Worker                                                      current_test_item.use_dynamic_index_based_writes)
3218*35238bceSAndroid Build Coastguard Worker                                << "has failed (as expected) to compile with the following info log:\n\n"
3219*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
3220*35238bceSAndroid Build Coastguard Worker 
3221*35238bceSAndroid Build Coastguard Worker             gl.getShaderiv(m_vs_id, GL_INFO_LOG_LENGTH, &buffer_size);
3222*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
3223*35238bceSAndroid Build Coastguard Worker 
3224*35238bceSAndroid Build Coastguard Worker             m_temp_buffer = new glw::GLchar[buffer_size + 1];
3225*35238bceSAndroid Build Coastguard Worker 
3226*35238bceSAndroid Build Coastguard Worker             memset(m_temp_buffer, 0, buffer_size + 1);
3227*35238bceSAndroid Build Coastguard Worker 
3228*35238bceSAndroid Build Coastguard Worker             gl.getShaderInfoLog(m_vs_id, buffer_size, DE_NULL, /* length */
3229*35238bceSAndroid Build Coastguard Worker                                 m_temp_buffer);
3230*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog() call failed.");
3231*35238bceSAndroid Build Coastguard Worker 
3232*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << m_temp_buffer << tcu::TestLog::EndMessage;
3233*35238bceSAndroid Build Coastguard Worker 
3234*35238bceSAndroid Build Coastguard Worker             delete[] m_temp_buffer;
3235*35238bceSAndroid Build Coastguard Worker             m_temp_buffer = DE_NULL;
3236*35238bceSAndroid Build Coastguard Worker 
3237*35238bceSAndroid Build Coastguard Worker             /* Move on to the next iteration */
3238*35238bceSAndroid Build Coastguard Worker             continue;
3239*35238bceSAndroid Build Coastguard Worker         }
3240*35238bceSAndroid Build Coastguard Worker 
3241*35238bceSAndroid Build Coastguard Worker         /* Try to link the program object */
3242*35238bceSAndroid Build Coastguard Worker         glw::GLint link_status = GL_FALSE;
3243*35238bceSAndroid Build Coastguard Worker 
3244*35238bceSAndroid Build Coastguard Worker         gl.linkProgram(m_po_id);
3245*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
3246*35238bceSAndroid Build Coastguard Worker 
3247*35238bceSAndroid Build Coastguard Worker         gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
3248*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
3249*35238bceSAndroid Build Coastguard Worker 
3250*35238bceSAndroid Build Coastguard Worker         if (link_status == GL_TRUE)
3251*35238bceSAndroid Build Coastguard Worker         {
3252*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
3253*35238bceSAndroid Build Coastguard Worker                                << getTestDescription(n_test_item, current_test_item.should_redeclare_output_variables,
3254*35238bceSAndroid Build Coastguard Worker                                                      current_test_item.use_dynamic_index_based_writes)
3255*35238bceSAndroid Build Coastguard Worker                                << "has linked successfully which is invalid!" << tcu::TestLog::EndMessage;
3256*35238bceSAndroid Build Coastguard Worker 
3257*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Program object has linked successfully, even though the process should have failed.");
3258*35238bceSAndroid Build Coastguard Worker         }
3259*35238bceSAndroid Build Coastguard Worker         else
3260*35238bceSAndroid Build Coastguard Worker         {
3261*35238bceSAndroid Build Coastguard Worker             glw::GLint buffer_size = 0;
3262*35238bceSAndroid Build Coastguard Worker 
3263*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
3264*35238bceSAndroid Build Coastguard Worker                                << getTestDescription(n_test_item, current_test_item.should_redeclare_output_variables,
3265*35238bceSAndroid Build Coastguard Worker                                                      current_test_item.use_dynamic_index_based_writes)
3266*35238bceSAndroid Build Coastguard Worker                                << "has failed (as expected) to link with the following info log:\n\n"
3267*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
3268*35238bceSAndroid Build Coastguard Worker 
3269*35238bceSAndroid Build Coastguard Worker             gl.getProgramiv(m_po_id, GL_INFO_LOG_LENGTH, &buffer_size);
3270*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
3271*35238bceSAndroid Build Coastguard Worker 
3272*35238bceSAndroid Build Coastguard Worker             m_temp_buffer = new glw::GLchar[buffer_size + 1];
3273*35238bceSAndroid Build Coastguard Worker 
3274*35238bceSAndroid Build Coastguard Worker             memset(m_temp_buffer, 0, buffer_size + 1);
3275*35238bceSAndroid Build Coastguard Worker 
3276*35238bceSAndroid Build Coastguard Worker             gl.getProgramInfoLog(m_po_id, buffer_size, DE_NULL, /* length */
3277*35238bceSAndroid Build Coastguard Worker                                  m_temp_buffer);
3278*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog() call failed.");
3279*35238bceSAndroid Build Coastguard Worker 
3280*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << m_temp_buffer << tcu::TestLog::EndMessage;
3281*35238bceSAndroid Build Coastguard Worker 
3282*35238bceSAndroid Build Coastguard Worker             delete[] m_temp_buffer;
3283*35238bceSAndroid Build Coastguard Worker             m_temp_buffer = DE_NULL;
3284*35238bceSAndroid Build Coastguard Worker         }
3285*35238bceSAndroid Build Coastguard Worker     } /* for (all test items) */
3286*35238bceSAndroid Build Coastguard Worker 
3287*35238bceSAndroid Build Coastguard Worker     /* All done */
3288*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3289*35238bceSAndroid Build Coastguard Worker 
3290*35238bceSAndroid Build Coastguard Worker     return STOP;
3291*35238bceSAndroid Build Coastguard Worker }
3292*35238bceSAndroid Build Coastguard Worker 
3293*35238bceSAndroid Build Coastguard Worker /** Constructor.
3294*35238bceSAndroid Build Coastguard Worker  *
3295*35238bceSAndroid Build Coastguard Worker  *  @param context Rendering context.
3296*35238bceSAndroid Build Coastguard Worker  */
Tests(deqp::Context & context)3297*35238bceSAndroid Build Coastguard Worker CullDistance::Tests::Tests(deqp::Context &context) : TestCaseGroup(context, "cull_distance", "Cull Distance Test Suite")
3298*35238bceSAndroid Build Coastguard Worker {
3299*35238bceSAndroid Build Coastguard Worker }
3300*35238bceSAndroid Build Coastguard Worker 
3301*35238bceSAndroid Build Coastguard Worker /** Initializes the test group contents. */
init()3302*35238bceSAndroid Build Coastguard Worker void CullDistance::Tests::init()
3303*35238bceSAndroid Build Coastguard Worker {
3304*35238bceSAndroid Build Coastguard Worker     addChild(new CullDistance::APICoverageTest(m_context));
3305*35238bceSAndroid Build Coastguard Worker     addChild(new CullDistance::FunctionalTest(m_context));
3306*35238bceSAndroid Build Coastguard Worker     addChild(new CullDistance::NegativeTest(m_context));
3307*35238bceSAndroid Build Coastguard Worker }
3308*35238bceSAndroid Build Coastguard Worker } // namespace glcts
3309