[Piglit] [PATCH v3 3/4] generators: Add a minimum version helper.
Dylan Baker
baker.dylan.c at gmail.com
Wed Apr 13 00:20:06 UTC 2016
This adds another GLSL related helper, a factory for getting minimum
versions based on stages. This is able to sort all of the stages for
both OpenGL and OpenGL ES.
Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
generated_tests/modules/glsl.py | 126 +++++++++++++++++++++++++++
unittests/generators/test_glsl.py | 174 ++++++++++++++++++++++++++++++++++++++
2 files changed, 300 insertions(+)
diff --git a/generated_tests/modules/glsl.py b/generated_tests/modules/glsl.py
index 85de920..f42bec4 100644
--- a/generated_tests/modules/glsl.py
+++ b/generated_tests/modules/glsl.py
@@ -209,3 +209,129 @@ class GLSLESVersion(object):
return '{:.2f}'.format(float(self))
else:
return '{:.2f} es'.format(float(self))
+
+
+class _MinVersion(object):
+ """A factory class for sorting GLSL and GLSLES versions.
+
+ This stores the minimum version required for various operations (currently
+ only for_stage and for_stage_with_ext).
+
+ This class is not meant to be reinitialized, instead use the provided
+ MinVersion constant.
+
+ """
+ __gl_stage_min = {
+ 'frag': Version('110'),
+ 'vert': Version('110'),
+ 'geom': Version('150'),
+ 'tesc': Version('400'),
+ 'tese': Version('400'),
+ 'comp': Version('430'),
+ }
+ # Only versions that actaly change are here, the function will return the
+ # values from __gl_stage_min if they're not here
+ __gl_stage_min_ext = {
+ # geometry_shader4 is not included here intentionally. It is
+ # significantly different than the geometry shaders in OpenGL 3.2
+ 'tesc': (Version('140'), 'GL_ARB_tesselation_shader'),
+ 'tese': (Version('140'), 'GL_ARB_tesselation_shader'),
+ 'comp': (Version('140'), 'GL_ARB_compute_shader'),
+ }
+ __gles_stage_min = {
+ 'frag': Version('100'),
+ 'vert': Version('100'),
+ 'comp': Version('310 es'),
+ 'geom': Version('320 es'),
+ 'tesc': Version('320 es'),
+ 'tese': Version('320 es'),
+ }
+ # Only versions that actaly change are here, the function will return the
+ # values from __gles_stage_min if they're not here
+ __gles_stage_min_ext = {
+ 'geom': (Version('310 es'), 'GL_OES_geometry_shader'),
+ 'tesc': (Version('310 es'), 'GL_OES_tesselation_shader'),
+ 'tese': (Version('310 es'), 'GL_OES_tesselation_shader'),
+ }
+
+ def for_stage(self, stage, version):
+ """Return max(stage minimum version, requested version).
+
+ When provided a stage and a version, it will return the greater of the
+ provided version and the minimum version of that stage without an
+ extension. For example, in OpenGL teselation is available in GLSL
+ 4.00+, or in 1.40+ with ARB_tesselation_shader. Given Version('150')
+ and 'tesc' this method returns Version('400').
+
+ Arguments:
+ stage -- A stage named by the extensions glslparsertest uses (frag,
+ vert, geom, tesc, tese, comp)
+ version -- A version as returned by the Version function.
+
+ >>> m = _MinVersion()
+ >>> m.for_stage('geom', Version('300 es'))
+ Version('320 es')
+ >>> m.for_stage('frag', Version('130'))
+ Version('130')
+
+ """
+ assert isinstance(version, (GLSLVersion, GLSLESVersion))
+ if isinstance(version, GLSLVersion):
+ _stage = self.__gl_stage_min[stage]
+ elif isinstance(version, GLSLESVersion):
+ _stage = self.__gles_stage_min[stage]
+
+ return _stage if _stage > version else version
+
+ def for_stage_with_ext(self, stage, version):
+ """Return the earliest GLSL version that a stage is supported in with
+ an extension.
+
+ When provided a stage and a version, it will return the greater of the
+ provided version and the minimum version of that stage with an
+ extension, and if necissary the extension as a string. For example, in
+ OpenGL teselation is available in GLSL 4.00+, or in 1.40+ with
+ ARB_tesselation_shader. Given Version('150') and 'tesc' this method
+ returns (Version('150'), 'GL_ARB_tesselation_shader'); but given
+ Version('400') and 'tesc' it returns (Version('400'), None)
+
+ If there is no extension (like with fragment and vertex) then None will
+ be returned as the secon value. It is up to the caller to handle this
+ appropriately. It will also return None for the extension when the GLSL
+ version is high enough to not require an extension.
+
+ Takes the same arguments as for_stage.
+
+ >>> m = _MinVersion()
+ >>> m.for_stage_with_ext('geom', Version('300 es'))
+ (Version('310 es'), 'GL_OES_geometry_shader')
+ >>> m.for_stage_with_ext('frag', Version('130'))
+ (Version('130'), None)
+
+ """
+ assert isinstance(version, (GLSLVersion, GLSLESVersion))
+ if isinstance(version, GLSLVersion):
+ try:
+ _stage, ext = self.__gl_stage_min_ext[stage]
+ except KeyError:
+ _stage, ext = self.__gl_stage_min[stage], None
+ elif isinstance(version, GLSLESVersion):
+ try:
+ _stage, ext = self.__gles_stage_min_ext[stage]
+ except KeyError:
+ _stage, ext = self.__gles_stage_min[stage], None
+
+ # If the version queried is less than the required, return the require
+ # and the ext
+ if _stage > version:
+ return (_stage, ext)
+ # If the requested version is greater or equal to the version that the
+ # feature became core in, return the version and None
+ elif self.for_stage(stage, version) <= version:
+ return (version, None)
+ # Otherwise the requested version and the extension are returned
+ else:
+ return (version, ext)
+
+
+MinVersion = _MinVersion() # pylint: disable=invalid-name
diff --git a/unittests/generators/test_glsl.py b/unittests/generators/test_glsl.py
index eabb600..c587997 100644
--- a/unittests/generators/test_glsl.py
+++ b/unittests/generators/test_glsl.py
@@ -297,3 +297,177 @@ def test_GLSLESVersion_print_float():
def test_GLSLESVersion_print_float_es():
"""generated_tests.modules.glsl.GLSLESVersion: print_float() (es version)"""
nt.eq_(glsl.Version('300 es').print_float(), '3.00 es')
+
+
+class TestMinVersion_for_stage(object):
+ """Tests for generated_tests.modules.glsl.MinVersion.for_stage.
+
+ Each test covers the requested < required and requested == required. If
+ it's possible it also covers requested > required.
+
+ """
+ def _test(self, stage, version, expected):
+ nt.eq_(glsl.MinVersion.for_stage(stage, version), expected,
+ msg='(actual) {} != (expected) {}'.format(
+ str(version), str(expected)))
+
+ def test_opengl_frag(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: FS (OpenGL)"""
+ self._test('frag', glsl.Version('150'), glsl.Version('150'))
+ self._test('frag', glsl.Version('110'), glsl.Version('110'))
+
+ def test_opengl_vert(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: VS (OpenGL)"""
+ self._test('vert', glsl.Version('150'), glsl.Version('150'))
+ self._test('vert', glsl.Version('110'), glsl.Version('110'))
+
+ def test_opengl_geom(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: GS (OpenGL)"""
+ self._test('geom', glsl.Version('330'), glsl.Version('330'))
+ self._test('geom', glsl.Version('110'), glsl.Version('150'))
+ self._test('geom', glsl.Version('150'), glsl.Version('150'))
+
+ def test_opengl_tesc(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: TCS (OpenGL)"""
+ self._test('tesc', glsl.Version('410'), glsl.Version('410'))
+ self._test('tesc', glsl.Version('400'), glsl.Version('400'))
+ self._test('tesc', glsl.Version('140'), glsl.Version('400'))
+
+ def test_opengl_tese(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: TES (OpenGL)"""
+ self._test('tese', glsl.Version('410'), glsl.Version('410'))
+ self._test('tese', glsl.Version('400'), glsl.Version('400'))
+ self._test('tese', glsl.Version('140'), glsl.Version('400'))
+
+ def test_opengl_comp(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: CS (OpenGL)"""
+ self._test('comp', glsl.Version('440'), glsl.Version('440'))
+ self._test('comp', glsl.Version('430'), glsl.Version('430'))
+ self._test('comp', glsl.Version('140'), glsl.Version('430'))
+
+ def test_opengles_frag(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: FS (OpenGL ES)"""
+ self._test('frag', glsl.Version('300 es'), glsl.Version('300 es'))
+ self._test('frag', glsl.Version('100'), glsl.Version('100'))
+
+ def test_opengles_vert(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: VS (OpenGL ES)"""
+ self._test('vert', glsl.Version('320 es'), glsl.Version('320 es'))
+ self._test('vert', glsl.Version('100'), glsl.Version('100'))
+
+ def test_opengles_geom(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: GS (OpenGL ES)"""
+ self._test('geom', glsl.Version('100'), glsl.Version('320 es'))
+ self._test('geom', glsl.Version('320 es'), glsl.Version('320 es'))
+
+ def test_opengles_tesc(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: TCS (OpenGL ES)"""
+ self._test('tesc', glsl.Version('320 es'), glsl.Version('320 es'))
+ self._test('tesc', glsl.Version('100'), glsl.Version('320 es'))
+
+ def test_opengles_tese(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: TES (OpenGL ES)"""
+ self._test('tese', glsl.Version('320 es'), glsl.Version('320 es'))
+ self._test('tese', glsl.Version('100'), glsl.Version('320 es'))
+
+ def test_opengles_comp(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage: TES (OpenGL ES)"""
+ self._test('comp', glsl.Version('320 es'), glsl.Version('320 es'))
+ self._test('comp', glsl.Version('100'), glsl.Version('310 es'))
+ self._test('comp', glsl.Version('310 es'), glsl.Version('310 es'))
+
+
+class TestMinVersion_for_stage_with_ext(object):
+ """Tests for generated_tests.modules.glsl.MinVersion.for_stage_with_ext."""
+ def _test(self, stage, version, expected):
+ ver, ext = glsl.MinVersion.for_stage_with_ext(stage, version)
+ nt.eq_((ver, ext), expected,
+ msg='(actual) ({}, {}) != (expected) ({}, {})'.format(
+ str(ver), ext, str(expected[0]), expected[1]))
+
+ def test_opengl_frag(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: FS (OpenGL)"""
+ self._test('frag', glsl.Version('150'), (glsl.Version('150'), None))
+ self._test('frag', glsl.Version('110'), (glsl.Version('110'), None))
+
+ def test_opengl_vert(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: VS (OpenGL)"""
+ self._test('vert', glsl.Version('150'), (glsl.Version('150'), None))
+ self._test('vert', glsl.Version('110'), (glsl.Version('110'), None))
+
+ def test_opengl_geom(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: GS (OpenGL)"""
+ self._test('geom', glsl.Version('330'), (glsl.Version('330'), None))
+ self._test('geom', glsl.Version('110'), (glsl.Version('150'), None))
+ self._test('geom', glsl.Version('150'), (glsl.Version('150'), None))
+
+ def test_opengl_tesc(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: TCS (OpenGL)"""
+ self._test('tesc', glsl.Version('410'), (glsl.Version('410'), None))
+ self._test('tesc', glsl.Version('140'),
+ (glsl.Version('140'), 'GL_ARB_tesselation_shader'))
+ self._test('tesc', glsl.Version('110'),
+ (glsl.Version('140'), 'GL_ARB_tesselation_shader'))
+
+ def test_opengl_tese(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: TES (OpenGL)"""
+ self._test('tese', glsl.Version('410'), (glsl.Version('410'), None))
+ self._test('tese', glsl.Version('140'),
+ (glsl.Version('140'), 'GL_ARB_tesselation_shader'))
+ self._test('tese', glsl.Version('110'),
+ (glsl.Version('140'), 'GL_ARB_tesselation_shader'))
+
+ def test_opengl_comp(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: CS (OpenGL)"""
+ self._test('comp', glsl.Version('430'), (glsl.Version('430'), None))
+ self._test('comp', glsl.Version('140'),
+ (glsl.Version('140'), 'GL_ARB_compute_shader'))
+ self._test('comp', glsl.Version('110'),
+ (glsl.Version('140'), 'GL_ARB_compute_shader'))
+
+ def test_opengles_frag(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: FS (OpenGL ES)"""
+ self._test('frag', glsl.Version('300 es'),
+ (glsl.Version('300 es'), None))
+ self._test('frag', glsl.Version('100'), (glsl.Version('100'), None))
+
+ def test_opengles_vert(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: VS (OpenGL ES)"""
+ self._test('vert', glsl.Version('300 es'),
+ (glsl.Version('300 es'), None))
+ self._test('vert', glsl.Version('100'), (glsl.Version('100'), None))
+
+ def test_opengles_geom(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: GS (OpenGL ES)"""
+ self._test('geom', glsl.Version('100'),
+ (glsl.Version('310 es'), 'GL_OES_geometry_shader'))
+ self._test('geom', glsl.Version('310 es'),
+ (glsl.Version('310 es'), 'GL_OES_geometry_shader'))
+ self._test('geom', glsl.Version('320 es'),
+ (glsl.Version('320 es'), None))
+
+ def test_opengles_tesc(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: TCS (OpenGL ES)"""
+ self._test('tesc', glsl.Version('320 es'),
+ (glsl.Version('320 es'), None))
+ self._test('tesc', glsl.Version('310 es'),
+ (glsl.Version('310 es'), 'GL_OES_tesselation_shader'))
+ self._test('tesc', glsl.Version('100'),
+ (glsl.Version('310 es'), 'GL_OES_tesselation_shader'))
+
+ def test_opengles_tese(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: TES (OpenGL ES)"""
+ self._test('tese', glsl.Version('320 es'),
+ (glsl.Version('320 es'), None))
+ self._test('tese', glsl.Version('310 es'),
+ (glsl.Version('310 es'), 'GL_OES_tesselation_shader'))
+ self._test('tese', glsl.Version('100'),
+ (glsl.Version('310 es'), 'GL_OES_tesselation_shader'))
+
+ def test_opengles_comp(self):
+ """generated_tests.modules.glsl.MinVersion.for_stage_with_ext: TES (OpenGL ES)"""
+ self._test('comp', glsl.Version('320 es'),
+ (glsl.Version('320 es'), None))
+ self._test('comp', glsl.Version('100'), (glsl.Version('310 es'), None))
+ self._test('comp', glsl.Version('310 es'),
+ (glsl.Version('310 es'), None))
--
2.8.0
More information about the Piglit
mailing list