glapi: Store exec table version info outside the XML
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 19 May 2015 18:24:26 +0000 (11:24 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 28 May 2015 23:56:32 +0000 (16:56 -0700)
Currently on the functions that are exclusive to core-profile are
implemented.  The remainder continue to live in the XML.  Additional
functions can be moved later.

The functions for GL_ARB_draw_indirect and GL_ARB_multi_draw_indirect
are put in the dispatch table inside the VBO module, so they do not need
to be moved over.

The diff of src/mesa/main/api_exec.c before and after this patch is as
expected.  All of the functions listed in apiexec.py moved out of a 'if
(_mesa_is_desktop(ctx))' block into a new 'if (ctx->API ==
API_OPENGL_CORE)' block.

v2: Remove stray shebang line in apiexec.py.  Suggested by Ilia.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Dylan Baker <baker.dylan.c@gmail.com>
Cc: "10.6" <mesa-stable@lists.freedesktop.org>
src/mapi/glapi/gen/Makefile.am
src/mapi/glapi/gen/apiexec.py [new file with mode: 0644]
src/mapi/glapi/gen/gl_genexec.py

index d7742f7b9d4a31b61921fa951c4cfa8ad36c9327..34602579c8a0ffddb7de07b971927ce017ba9c82 100644 (file)
@@ -61,6 +61,7 @@ EXTRA_DIST= \
        $(MESA_GLAPI_DIR)/glapi_x86-64.S \
        $(MESA_GLAPI_DIR)/glapi_sparc.S \
        $(COMMON_GLX) \
+       apiexec.py \
        gl_apitemp.py \
        gl_enums.py \
        gl_genexec.py \
@@ -267,7 +268,7 @@ $(MESA_GLAPI_DIR)/glapi_sparc.S: gl_SPARC_asm.py $(COMMON)
 $(MESA_DIR)/main/enums.c: gl_enums.py $(COMMON)
        $(PYTHON_GEN) $< -f $(srcdir)/gl_and_es_API.xml > $@
 
-$(MESA_DIR)/main/api_exec.c: gl_genexec.py $(COMMON)
+$(MESA_DIR)/main/api_exec.c: gl_genexec.py apiexec.py $(COMMON)
        $(PYTHON_GEN) $< -f $(srcdir)/gl_and_es_API.xml > $@
 
 $(MESA_DIR)/main/dispatch.h: gl_table.py $(COMMON)
diff --git a/src/mapi/glapi/gen/apiexec.py b/src/mapi/glapi/gen/apiexec.py
new file mode 100644 (file)
index 0000000..4f16a0b
--- /dev/null
@@ -0,0 +1,140 @@
+# Copyright (C) 2015 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+class exec_info():
+    """Information relating GL APIs to a function.
+
+    Each of the four attributes of this class, compatibility, core, es1, and
+    es2, specify the minimum API version where a function can possibly exist
+    in Mesa.  The version is specified as an integer of (real GL version *
+    10).  For example, glCreateProgram was added in OpenGL 2.0, so
+    compatibility=20 and core=31.
+
+    If the attribute is None, then it cannot be supported by that
+    API.  For example, glNewList was removed from core profiles, so
+    compatibility=10 and core=None.
+
+    Each of the attributes that is not None must have a valid value.  The
+    valid ranges are:
+
+        compatiblity: [10, 30]
+        core: [31, )
+        es1: [10, 11]
+        es2: [20, )
+
+    These ranges are enforced by the constructor.
+    """
+    def __init__(self, compatibility=None, core=None, es1=None, es2=None):
+        if compatibility is not None:
+            assert isinstance(compatibility, int)
+            assert compatibility >= 10
+            assert compatibility <= 30
+
+        if core is not None:
+            assert isinstance(core, int)
+            assert core >= 31
+
+        if es1 is not None:
+            assert isinstance(es1, int)
+            assert es1 == 10 or es1 == 11
+
+        if es2 is not None:
+            assert isinstance(es2, int)
+            assert es2 >= 20
+
+        self.compatibility = compatibility
+        self.core = core
+        self.es1 = es1
+        self.es2 = es2
+
+functions = {
+    # OpenGL 3.1 / GL_ARB_texture_buffer_object.  Mesa only exposes this
+    # extension with core profile.
+    "TexBuffer": exec_info(core=31),
+
+    # OpenGL 3.2 / GL_ARB_geometry_shader4.  Mesa does not support
+    # GL_ARB_geometry_shader4, so OpenGL 3.2 is required.
+    "FramebufferTexture": exec_info(core=32),
+
+    # OpenGL 4.0 / GL_ARB_gpu_shader_fp64.  The extension spec says:
+    #
+    #     "OpenGL 3.2 and GLSL 1.50 are required."
+    "Uniform1d": exec_info(core=32),
+    "Uniform2d": exec_info(core=32),
+    "Uniform3d": exec_info(core=32),
+    "Uniform4d": exec_info(core=32),
+    "Uniform1dv": exec_info(core=32),
+    "Uniform2dv": exec_info(core=32),
+    "Uniform3dv": exec_info(core=32),
+    "Uniform4dv": exec_info(core=32),
+    "UniformMatrix2dv": exec_info(core=32),
+    "UniformMatrix3dv": exec_info(core=32),
+    "UniformMatrix4dv": exec_info(core=32),
+    "UniformMatrix2x3dv": exec_info(core=32),
+    "UniformMatrix2x4dv": exec_info(core=32),
+    "UniformMatrix3x2dv": exec_info(core=32),
+    "UniformMatrix3x4dv": exec_info(core=32),
+    "UniformMatrix4x2dv": exec_info(core=32),
+    "UniformMatrix4x3dv": exec_info(core=32),
+    "GetUniformdv": exec_info(core=32),
+
+    # OpenGL 4.1 / GL_ARB_vertex_attrib_64bit.  The extension spec says:
+    #
+    #     "OpenGL 3.0 and GLSL 1.30 are required.
+    #
+    #     ARB_gpu_shader_fp64 (or equivalent functionality) is required."
+    #
+    # For Mesa this effectively means OpenGL 3.2 is required.  It seems
+    # unlikely that Mesa will ever get support for any of the NV extensions
+    # that add "equivalent functionality."
+    "VertexAttribL1d": exec_info(core=32),
+    "VertexAttribL2d": exec_info(core=32),
+    "VertexAttribL3d": exec_info(core=32),
+    "VertexAttribL4d": exec_info(core=32),
+    "VertexAttribL1dv": exec_info(core=32),
+    "VertexAttribL2dv": exec_info(core=32),
+    "VertexAttribL3dv": exec_info(core=32),
+    "VertexAttribL4dv": exec_info(core=32),
+    "VertexAttribLPointer": exec_info(core=32),
+    "GetVertexAttribLdv": exec_info(core=32),
+
+    # OpenGL 4.1 / GL_ARB_viewport_array.  The extension spec says:
+    #
+    #     "OpenGL 3.2 or the EXT_geometry_shader4 or ARB_geometry_shader4
+    #     extensions are required."
+    #
+    # Mesa does not support either of the geometry shader extensions, so
+    # OpenGL 3.2 is required.
+    "ViewportArrayv": exec_info(core=32),
+    "ViewportIndexedf": exec_info(core=32),
+    "ViewportIndexedfv": exec_info(core=32),
+    "ScissorArrayv": exec_info(core=32),
+    "ScissorIndexed": exec_info(core=32),
+    "ScissorIndexedv": exec_info(core=32),
+    "DepthRangeArrayv": exec_info(core=32),
+    "DepthRangeIndexed": exec_info(core=32),
+    # GetFloati_v also GL_ARB_shader_atomic_counters
+    # GetDoublei_v also GL_ARB_shader_atomic_counters
+
+    # OpenGL 4.3 / GL_ARB_texture_buffer_range.  Mesa can expose the extension
+    # with OpenGL 3.1.
+    "TexBufferRange": exec_info(core=31),
+}
index 0d58a8a2914be64926721c29d8a0fb1e309e9a62..26d8e7bfb3a881a8475fc2da6a1138c1ad5bb7e2 100644 (file)
@@ -30,6 +30,7 @@ import collections
 import license
 import gl_XML
 import sys
+import apiexec
 
 
 exec_flavor_map = {
@@ -176,18 +177,49 @@ class PrintCode(gl_XML.gl_print_base):
                 raise Exception(
                     'Unrecognized exec flavor {0!r}'.format(f.exec_flavor))
             condition_parts = []
-            if f.desktop:
-                if f.deprecated:
+            if f.name in apiexec.functions:
+                ex = apiexec.functions[f.name]
+                unconditional_count = 0
+
+                if ex.compatibility is not None:
                     condition_parts.append('ctx->API == API_OPENGL_COMPAT')
-                else:
-                    condition_parts.append('_mesa_is_desktop_gl(ctx)')
-            if 'es1' in f.api_map:
-                condition_parts.append('ctx->API == API_OPENGLES')
-            if 'es2' in f.api_map:
-                if f.api_map['es2'] > 2.0:
-                    condition_parts.append('(ctx->API == API_OPENGLES2 && ctx->Version >= {0})'.format(int(f.api_map['es2'] * 10)))
-                else:
-                    condition_parts.append('ctx->API == API_OPENGLES2')
+                    unconditional_count += 1
+
+                if ex.core is not None:
+                    condition_parts.append('ctx->API == API_OPENGL_CORE')
+                    unconditional_count += 1
+
+                if ex.es1 is not None:
+                    condition_parts.append('ctx->API == API_OPENGLES')
+                    unconditional_count += 1
+
+                if ex.es2 is not None:
+                    if ex.es2 > 20:
+                        condition_parts.append('(ctx->API == API_OPENGLES2 && ctx->Version >= {0})'.format(ex.es2))
+                    else:
+                        condition_parts.append('ctx->API == API_OPENGLES2')
+                        unconditional_count += 1
+
+                # If the function is unconditionally available in all four
+                # APIs, then it is always available.  Replace the complex
+                # tautology condition with "true" and let GCC do the right
+                # thing.
+                if unconditional_count == 4:
+                    condition_parts = ['true']
+            else:
+                if f.desktop:
+                    if f.deprecated:
+                        condition_parts.append('ctx->API == API_OPENGL_COMPAT')
+                    else:
+                        condition_parts.append('_mesa_is_desktop_gl(ctx)')
+                if 'es1' in f.api_map:
+                    condition_parts.append('ctx->API == API_OPENGLES')
+                if 'es2' in f.api_map:
+                    if f.api_map['es2'] > 2.0:
+                        condition_parts.append('(ctx->API == API_OPENGLES2 && ctx->Version >= {0})'.format(int(f.api_map['es2'] * 10)))
+                    else:
+                        condition_parts.append('ctx->API == API_OPENGLES2')
+
             if not condition_parts:
                 # This function does not exist in any API.
                 continue