Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / framework / opengl / gluContextInfo.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
3  * ------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Context Info Class.
22  *//*--------------------------------------------------------------------*/
23
24 #include "gluContextInfo.hpp"
25 #include "gluRenderContext.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "glwFunctions.hpp"
28 #include "glwEnums.hpp"
29
30 #include <iterator>
31 #include <algorithm>
32
33 using std::vector;
34 using std::string;
35 using std::set;
36
37 namespace glu
38 {
39
40 class TryCompileProgram
41 {
42 public:
43         // \note Assumes that shader pointer can be stored as is (eg. it is static data)
44         TryCompileProgram (const char* vertexSource, const char* fragmentSource)
45                 : m_vertexSource        (vertexSource)
46                 , m_fragmentSource      (fragmentSource)
47         {
48         }
49
50         bool operator() (const RenderContext& context) const
51         {
52                 ShaderProgram program(context,
53                         ProgramSources() << VertexSource(m_vertexSource)
54                                                          << FragmentSource(m_fragmentSource));
55                 return program.isOk();
56         }
57
58 private:
59         const char*     m_vertexSource;
60         const char*     m_fragmentSource;
61 };
62
63 typedef CachedValue<bool, TryCompileProgram> IsProgramSupported;
64
65 bool IsES3Compatible(const glw::Functions& gl)
66 {
67         // Detect compatible GLES context by querying GL_MAJOR_VERSION.
68         // This query does not exist on GLES2 so succeeding query implies GLES3+ context.
69         glw::GLint majorVersion = 0;
70         gl.getError();
71         gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
72
73         return (gl.getError() == GL_NO_ERROR);
74 }
75
76 // ES2-specific context info
77 class ES2ContextInfo : public ContextInfo
78 {
79 public:
80                                                                                 ES2ContextInfo                                          (const RenderContext& context);
81                                                                                 ~ES2ContextInfo                                         (void) {}
82
83         bool                                                            isVertexUniformLoopSupported            (void) const    { return m_vertexUniformLoopsSupported.getValue(m_context);             }
84         bool                                                            isVertexDynamicLoopSupported            (void) const    { return m_vertexDynamicLoopsSupported.getValue(m_context);             }
85         bool                                                            isFragmentHighPrecisionSupported        (void) const    { return m_fragmentHighPrecisionSupported.getValue(m_context);  }
86         bool                                                            isFragmentUniformLoopSupported          (void) const    { return m_fragmentUniformLoopsSupported.getValue(m_context);   }
87         bool                                                            isFragmentDynamicLoopSupported          (void) const    { return m_fragmentDynamicLoopsSupported.getValue(m_context);   }
88
89 private:
90         IsProgramSupported                                      m_vertexUniformLoopsSupported;
91         IsProgramSupported                                      m_vertexDynamicLoopsSupported;
92
93         IsProgramSupported                                      m_fragmentHighPrecisionSupported;
94         IsProgramSupported                                      m_fragmentUniformLoopsSupported;
95         IsProgramSupported                                      m_fragmentDynamicLoopsSupported;
96 };
97
98 static const char* s_defaultVertexShader =
99         "attribute highp vec4 a_position;\n"
100         "void main (void) {\n"
101         "       gl_Position = a_position;\n"
102         "}\n";
103 static const char* s_defaultFragmentShader =
104         "void main (void) {\n"
105         "       gl_FragColor = vec4(1.0);\n"
106         "}\n";
107
108 static const char* s_vertexUniformLoopsSupported =
109         "attribute highp vec4   a_position;\n"
110         "uniform int                    u_numIters;\n"
111         "void main (void) {\n"
112         "       gl_Position = a_position;\n"
113         "       for (int i = 0; i < u_numIters; i++)\n"
114         "               gl_Position += vec4(0.1);\n"
115         "}\n";
116 static const char* s_vertexDynamicLoopsSupported =
117         "attribute highp vec4   a_position;\n"
118         "uniform mediump float  a, b;\n"
119         "void main (void) {\n"
120         "       gl_Position = a_position;\n"
121         "       int numIters = a < b ? int(3.0*b) : int(a_position.x);\n"
122         "       for (int i = 0; i < numIters; i++)\n"
123         "               gl_Position += vec4(0.1);\n"
124         "}\n";
125
126 static const char* s_fragmentHighPrecisionSupported =
127         "varying highp vec4             v_color;\n"
128         "void main (void) {\n"
129         "       highp float tmp = v_color.r;\n"
130         "       gl_FragColor = v_color;\n"
131         "}\n";
132 static const char* s_fragmentUniformLoopsSupported =
133         "varying mediump vec4   v_color;\n"
134         "uniform int                    u_numIters;\n"
135         "void main (void) {\n"
136         "       gl_FragColor = v_color;\n"
137         "       for (int i = 0; i < u_numIters; i++)\n"
138         "               gl_FragColor += vec4(0.1);\n"
139         "}\n";
140 static const char* s_fragmentDynamicLoopsSupported =
141         "varying mediump vec4   v_color;\n"
142         "uniform mediump float  a, b;\n"
143         "void main (void) {\n"
144         "       gl_FragColor = v_color;\n"
145         "       int numIters = a < b ? int(3.0*b) : int(v_color.x);\n"
146         "       for (int i = 0; i < numIters; i++)\n"
147         "               gl_FragColor += vec4(0.1);\n"
148         "}\n";
149
150 ES2ContextInfo::ES2ContextInfo (const RenderContext& context)
151         : glu::ContextInfo                                      (context)
152         , m_vertexUniformLoopsSupported         (TryCompileProgram(s_vertexUniformLoopsSupported, s_defaultFragmentShader))
153         , m_vertexDynamicLoopsSupported         (TryCompileProgram(s_vertexDynamicLoopsSupported, s_defaultFragmentShader))
154         , m_fragmentHighPrecisionSupported      (TryCompileProgram(s_defaultVertexShader, s_fragmentHighPrecisionSupported))
155         , m_fragmentUniformLoopsSupported       (TryCompileProgram(s_defaultVertexShader, s_fragmentUniformLoopsSupported))
156         , m_fragmentDynamicLoopsSupported       (TryCompileProgram(s_defaultVertexShader, s_fragmentDynamicLoopsSupported))
157 {
158 }
159
160 static void split (vector<string>& dst, const string& src)
161 {
162         size_t start = 0;
163         size_t end       = string::npos;
164
165         while ((end = src.find(' ', start)) != string::npos)
166         {
167                 dst.push_back(src.substr(start, end-start));
168                 start = end+1;
169         }
170
171         if (start < end)
172                 dst.push_back(src.substr(start, end-start));
173 }
174
175 set<int> GetCompressedTextureFormats::operator() (const RenderContext& context) const
176 {
177         const glw::Functions& gl = context.getFunctions();
178
179         int numFormats = 0;
180         gl.getIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
181
182         vector<int> formats(numFormats);
183         if (numFormats > 0)
184                 gl.getIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, &formats[0]);
185
186         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS) failed");
187
188         set<int> formatSet;
189         std::copy(formats.begin(), formats.end(), std::inserter(formatSet, formatSet.begin()));
190
191         return formatSet;
192 }
193
194 // ContextInfo
195
196 ContextInfo::ContextInfo (const RenderContext& context)
197         : m_context(context)
198 {
199         const glw::Functions& gl = context.getFunctions();
200
201         if (context.getType().getAPI() == ApiType::es(2,0))
202         {
203                 const char* result = (const char*)gl.getString(GL_EXTENSIONS);
204                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetString(GL_EXTENSIONS) failed");
205
206                 split(m_extensions, string(result));
207         }
208         else
209         {
210                 int                             numExtensions   = 0;
211
212                 gl.getIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
213                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_NUM_EXTENSIONS) failed");
214
215                 m_extensions.resize(numExtensions);
216                 for (int ndx = 0; ndx < numExtensions; ndx++)
217                         m_extensions[ndx] = (const char*)gl.getStringi(GL_EXTENSIONS, ndx);
218                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetStringi(GL_EXTENSIONS, ndx) failed");
219         }
220 }
221
222 ContextInfo::~ContextInfo (void)
223 {
224 }
225
226 int ContextInfo::getInt (int param) const
227 {
228         int val = -1;
229         m_context.getFunctions().getIntegerv(param, &val);
230         GLU_EXPECT_NO_ERROR(m_context.getFunctions().getError(), "glGetIntegerv() failed");
231         return val;
232 }
233
234 bool ContextInfo::getBool (int param) const
235 {
236         glw::GLboolean val = GL_FALSE;
237         m_context.getFunctions().getBooleanv(param, &val);
238         GLU_EXPECT_NO_ERROR(m_context.getFunctions().getError(), "glGetBooleanv() failed");
239         return val != GL_FALSE;
240 }
241
242 const char* ContextInfo::getString (int param) const
243 {
244         const char* str = (const char*)m_context.getFunctions().getString(param);
245         GLU_EXPECT_NO_ERROR(m_context.getFunctions().getError(), "glGetString() failed");
246         return str;
247 }
248
249 bool ContextInfo::isCompressedTextureFormatSupported (int format) const
250 {
251         const set<int>& formats = m_compressedTextureFormats.getValue(m_context);
252         return formats.find(format) != formats.end();
253 }
254
255 bool ContextInfo::isExtensionSupported (const char* name) const
256 {
257         const std::vector<std::string>& extensions = getExtensions();
258         return std::find(extensions.begin(), extensions.end(), name) != extensions.end();
259 }
260
261 bool ContextInfo::isES3Compatible() const
262 {
263    return IsES3Compatible(m_context.getFunctions());
264 }
265
266 ContextInfo* ContextInfo::create (const RenderContext& context)
267 {
268         // ES2 uses special variant that checks support for various shader features
269         // by trying to compile shader programs.
270         if (context.getType().getAPI() == ApiType::es(2,0))
271                 return new ES2ContextInfo(context);
272
273         return new ContextInfo(context);
274 }
275
276 } // glu