[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