fix the spelling in whole piglit
[piglit.git] / generated_tests / modules / glsl.py
blobca52987f94bbd364c800e6aec62b53adcde97554
1 # encoding=utf-8
2 # Copyright © 2016 Intel Corporation
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
11 # The above copyright notice and this permission notice shall be included in
12 # all copies or substantial portions of the Software.
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 # SOFTWARE.
22 """Provides helper classes for representing glsl data."""
24 import functools
26 __all__ = [
27 'GLSLESVersion',
28 'GLSLVersion',
29 'Version',
33 class _Version(object):
34 """Factory class for glsl versions.
36 provides an object cache to reduce duplication of objects. This object
37 should not be initialized more than once, to avoid that use the Version
38 constant provided by the module.
40 It would provide either a GLSLVersion or a GLSLESVersion.
42 """
43 _es_versions = [
44 '100',
45 '300 es',
46 '310 es',
47 '320 es',
50 _versions = [
51 '110',
52 '120',
53 '130',
54 '140',
55 '150',
56 '330',
57 '400',
58 '410',
59 '420',
60 '430',
61 '440',
62 '450',
65 def __init__(self):
66 self.__cache = {}
68 def __call__(self, ver):
69 """Make a Version object, or provide one from the cache."""
70 assert isinstance(ver, str)
72 # Try to get an object from the cache, if that fails create a new one
73 # and add it to the cache before returning it.
74 try:
75 return self.__cache[ver]
76 except KeyError:
77 if ver in self._es_versions:
78 obj = GLSLESVersion(ver)
79 elif ver in self._versions:
80 obj = GLSLVersion(ver)
81 else:
82 raise Exception('Undefined version {}'.format(ver))
84 self.__cache[ver] = obj
85 return obj
88 Version = _Version() # pylint: disable=invalid-name
91 @functools.total_ordering
92 class GLSLVersion(object):
93 """A Representation of an OpenGL Shading Language version.
95 This object provides a bunch of the niceties that one would want. It's
96 orderable (can be sorted, and can be compared with the standard ==, !=, <,
97 etc), can be called with str() (which provides the integer version, like
98 120), and a method to print the decimal version (1.20).
100 Do not initialize this directly.
103 def __init__(self, ver):
104 assert ver in ['110', '120', '130', '140', '150', '330', '400', '410',
105 '420', '430', '440', '450']
106 self._internal = ver
107 self.is_es = False
109 def __str__(self):
110 return self._internal
112 def __int__(self):
113 return int(self._internal)
115 def __float__(self):
116 return float(int(self) / 100)
118 def __eq__(self, other):
119 # If the other version is ES then we know they're not equal
120 if isinstance(other, GLSLESVersion):
121 return False
122 elif isinstance(other, (GLSLVersion, int)):
123 return int(self) == int(other)
124 elif isinstance(other, float):
125 return float(self) == float(other)
126 else:
127 return NotImplemented
129 def __ne__(self, other):
130 return not self == other
132 def __lt__(self, other):
133 if isinstance(other, GLSLESVersion):
134 raise TypeError('Unorderable types GLSLVersion and GLSLESVersion')
135 elif isinstance(other, (GLSLVersion, int)):
136 return int(self) < int(other)
137 elif isinstance(other, float):
138 return float(self) < other
139 else:
140 return NotImplemented
142 def print_float(self):
143 """A version suitable to print as a decimal with two trailing digits."""
144 return '{:.2f}'.format(float(self))
147 @functools.total_ordering
148 class GLSLESVersion(object):
149 """Represents a GLSL ES version.
151 Do not initialize this directly.
154 def __init__(self, ver):
155 if ver == '100':
156 self._internal = ver
157 else:
158 self._internal = ver[:-3] # drop " es"
159 self.is_es = True
161 def __str__(self):
162 if self._internal == '100':
163 return self._internal
164 else:
165 return self._internal + " es"
167 def __int__(self):
168 return int(self._internal)
170 def __float__(self):
171 return float(int(self) / 100)
173 def __eq__(self, other):
174 # If the other version is ES then we know they're not equal
175 if isinstance(other, GLSLVersion):
176 return False
177 elif isinstance(other, (GLSLESVersion, int)):
178 return int(self) == int(other)
179 elif isinstance(other, float):
180 return float(self) == float(other)
181 else:
182 return NotImplemented
184 def __ne__(self, other):
185 return not self == other
187 def __lt__(self, other):
188 if isinstance(other, GLSLVersion):
189 raise TypeError('Unorderable types GLSLESVersion and GLSLVersion')
190 elif isinstance(other, (GLSLESVersion, int)):
191 return int(self) < int(other)
192 elif isinstance(other, float):
193 return float(self) < other
194 else:
195 return NotImplemented
197 def print_float(self):
198 """A version suitable to print as a decimal with two trailing digits."""
199 if self._internal == '100':
200 return '{:.2f}'.format(float(self))
201 else:
202 return '{:.2f} es'.format(float(self))
205 class _MinVersion(object):
206 """A factory class for sorting GLSL and GLSLES versions.
208 This stores the minimum version required for various operations (currently
209 only for_stage and for_stage_with_ext).
211 This class is not meant to be reinitialized, instead use the provided
212 MinVersion constant.
215 __gl_stage_min = {
216 'frag': Version('110'),
217 'vert': Version('110'),
218 'geom': Version('150'),
219 'tesc': Version('400'),
220 'tese': Version('400'),
221 'comp': Version('430'),
223 # Only versions that actaly change are here, the function will return the
224 # values from __gl_stage_min if they're not here
225 __gl_stage_min_ext = {
226 # geometry_shader4 is not included here intentionally. It is
227 # significantly different than the geometry shaders in OpenGL 3.2
228 'tesc': (Version('140'), 'GL_ARB_tessellation_shader'),
229 'tese': (Version('140'), 'GL_ARB_tessellation_shader'),
230 'comp': (Version('140'), 'GL_ARB_compute_shader'),
232 __gles_stage_min = {
233 'frag': Version('100'),
234 'vert': Version('100'),
235 'comp': Version('310 es'),
236 'geom': Version('320 es'),
237 'tesc': Version('320 es'),
238 'tese': Version('320 es'),
240 # Only versions that actaly change are here, the function will return the
241 # values from __gles_stage_min if they're not here
242 __gles_stage_min_ext = {
243 'geom': (Version('310 es'), 'GL_OES_geometry_shader'),
244 'tesc': (Version('310 es'), 'GL_OES_tessellation_shader'),
245 'tese': (Version('310 es'), 'GL_OES_tessellation_shader'),
248 def for_stage(self, stage, version):
249 """Return max(stage minimum version, requested version).
251 When provided a stage and a version, it will return the greater of the
252 provided version and the minimum version of that stage without an
253 extension. For example, in OpenGL teselation is available in GLSL
254 4.00+, or in 1.40+ with ARB_tessellation_shader. Given Version('150')
255 and 'tesc' this method returns Version('400').
257 Arguments:
258 stage -- A stage named by the extensions glslparsertest uses (frag,
259 vert, geom, tesc, tese, comp)
260 version -- A version as returned by the Version function.
262 >>> m = _MinVersion()
263 >>> m.for_stage('geom', Version('300 es'))
264 Version('320 es')
265 >>> m.for_stage('frag', Version('130'))
266 Version('130')
269 assert isinstance(version, (GLSLVersion, GLSLESVersion))
270 if isinstance(version, GLSLVersion):
271 _stage = self.__gl_stage_min[stage]
272 elif isinstance(version, GLSLESVersion):
273 _stage = self.__gles_stage_min[stage]
275 return _stage if _stage > version else version
277 def for_stage_with_ext(self, stage, version):
278 """Return the earliest GLSL version that a stage is supported in with
279 an extension.
281 When provided a stage and a version, it will return the greater of the
282 provided version and the minimum version of that stage with an
283 extension, and if necissary the extension as a string. For example, in
284 OpenGL teselation is available in GLSL 4.00+, or in 1.40+ with
285 ARB_tessellation_shader. Given Version('150') and 'tesc' this method
286 returns (Version('150'), 'GL_ARB_tessellation_shader'); but given
287 Version('400') and 'tesc' it returns (Version('400'), None)
289 If there is no extension (like with fragment and vertex) then None will
290 be returned as the secon value. It is up to the caller to handle this
291 appropriately. It will also return None for the extension when the GLSL
292 version is high enough to not require an extension.
294 Takes the same arguments as for_stage.
296 >>> m = _MinVersion()
297 >>> m.for_stage_with_ext('geom', Version('300 es'))
298 (Version('310 es'), 'GL_OES_geometry_shader')
299 >>> m.for_stage_with_ext('frag', Version('130'))
300 (Version('130'), None)
303 assert isinstance(version, (GLSLVersion, GLSLESVersion))
304 if isinstance(version, GLSLVersion):
305 try:
306 _stage, ext = self.__gl_stage_min_ext[stage]
307 except KeyError:
308 _stage, ext = self.__gl_stage_min[stage], None
309 elif isinstance(version, GLSLESVersion):
310 try:
311 _stage, ext = self.__gles_stage_min_ext[stage]
312 except KeyError:
313 _stage, ext = self.__gles_stage_min[stage], None
315 # If the version queried is less than the required, return the require
316 # and the ext
317 if _stage > version:
318 return (_stage, ext)
319 # If the requested version is greater or equal to the version that the
320 # feature became core in, return the version and None
321 elif self.for_stage(stage, version) <= version:
322 return (version, None)
323 # Otherwise the requested version and the extension are returned
324 else:
325 return (version, ext)
328 MinVersion = _MinVersion() # pylint: disable=invalid-name