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 ¤t_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 ¤t_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 ¤t_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 ¤t_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 **)¤t_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 ¤t_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 ¤t_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