Commit ac1f382d authored by Chad Versace's avatar Chad Versace

dispatch: Generate piglit-dispatch from Khronos XML

Khronos now generates its headers from XML and no longer maintains the
old, crufty *.spec files. Piglit should do the same. Otherwise,
piglit-dispatch won't be able to pick up new extension functions.

As a really really big bonus, after Piglit starts generating its GL
dispatch code from gl.xml, it will be a small step to start generating
EGL and GLX dispatch from egl.xml and glx.xml.

This patch imports 'gl.xml' into a new toplevel "registry" directory, to
follow the precedent of libepoxy.

This patch follows the precedent of libepoxy by importing "gl.xml" into
a new toplevel "registry" directory.

I did *not* try to redesign piglit-dispatch in this patch. To the
contrary, I attempted to keep the newly generated dispatch code to be as
similar as possible as the old generated code. Despite wanting to clean
up piglit-dispatch's design, I refrained because "a patch should do one
thing, and do it well".

I strove to keep separate concerns in separate files. File
"registry/gl.py" parses "registry/gl.xml". File
"tests/util/gen_dispatch.py" generates code from the that parsed result.
This decision kept gen_dispatch.py small and focused.

I hope everyone finds the rewritten gen_dispatch.py more maintainable
and easy to read.

The generated code has changed as following:

  - It now contains the GLES1 API, because gl.xml contains information
    on all OpenGL APIs.

  - The comment block for each function alias set now contains more
    information. For each function in the set, it now lists the
    complete set of providers.

    For example:
      /* glActiveTexture (GL_VERSION_1_3) (GL_VERSION_ES_CM_1_0) (GL_ES_VERSION_2_0) */
      /* glActiveTextureARB (GL_ARB_multitexture) */
      extern PFNGLACTIVETEXTUREPROC piglit_dispatch_glActiveTexture;
      #define glActiveTexture piglit_dispatch_glActiveTexture
      #define glActiveTextureARB piglit_dispatch_glActiveTexture

  - Enums are sorted by group then by value. Old dispatch sorted only by
    value.

    For example:
      /* Enum Group MapBufferUsageMask */
      #define GL_MAP_READ_BIT 0x0001
      #define GL_MAP_READ_BIT_EXT 0x0001
      #define GL_MAP_WRITE_BIT 0x0002
      #define GL_MAP_WRITE_BIT_EXT 0x0002
      ...

Tested for regressions with:
    piglit run -p x11_egl -x glx -x glean
    Mesa 10.2.1
    Intel Ivybridge
    Fedora 20

v3, for Dylan:
  - Replace ElementTree with cElementTree, for speed.
  - Each method $foo in KeyedOrderedSet that returns
    a generator, rename it to iter${foo} to follow Python2 (not 3)
    naming conventions.
  - Python 2.6 lacks OrderedDict, so don't use it.
  - Remove unused import 'dedent'.
  - Python 2.6 does not recognize the syntax for set literals, so
    replace each set literal with a list literal or generator literal.
  - Replace sys.stderr.write with print(file=sys.stderr).
  - Remove hand-coded OrderedKeyedSet.copy and instead use copy module.
  - Prefer the 'lxml' module (it uses libxml2) over Python's builtin 'xml' module.
  - Replace methods ``def foo(x, y):`` with ``def foo(self, other):``.
  - Replace lists with generators in methods Command.c_*_param_list.
  - PEP8: Separate all toplevel items with 2 newlines.
  - PEP8: Fix minor whitespace issues.
  - PEP8: Replace some ``== None`` with ``is None``.
  - Replace None-check for --out-dir with add_argument(..., required=True)
  - Remove 'prog' assignment when calling ArgumentParser(prog=PROG_NAME).
    Instead, use default value
Signed-off-by: default avatarChad Versace <chad.versace@linux.intel.com>
parent def993a7
......@@ -19,6 +19,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
set(piglit_dispatch_gen_script ${CMAKE_SOURCE_DIR}/tests/util/gen_dispatch.py)
set(piglit_dispatch_gen_output_dir ${CMAKE_BINARY_DIR}/tests/util)
file(MAKE_DIRECTORY ${piglit_dispatch_gen_output_dir})
......@@ -28,15 +29,19 @@ set(piglit_dispatch_gen_outputs
${piglit_dispatch_gen_output_dir}/piglit-dispatch-gen.h
)
set(piglit_dispatch_gen_inputs
set(piglit_dispatch_gen_depends
${CMAKE_SOURCE_DIR}/registry/__init__.py
${CMAKE_SOURCE_DIR}/registry/gl.py
${CMAKE_SOURCE_DIR}/registry/gl.xml
${CMAKE_SOURCE_DIR}/tests/util/gen_dispatch.py
${CMAKE_BINARY_DIR}/glapi/glapi.json
${CMAKE_SOURCE_DIR}/tests/util/piglit-dispatch-gen.c.mako
${CMAKE_SOURCE_DIR}/tests/util/piglit-dispatch-gen.h.mako
)
add_custom_command(
OUTPUT ${piglit_dispatch_gen_outputs}
DEPENDS ${piglit_dispatch_gen_inputs}
COMMAND ${python} ${piglit_dispatch_gen_inputs} ${piglit_dispatch_gen_outputs}
DEPENDS ${piglit_dispatch_gen_depends}
COMMAND ${python} ${piglit_dispatch_gen_script} --out-dir ${piglit_dispatch_gen_output_dir}
)
add_custom_target(piglit_dispatch_gen
......
This diff is collapsed.
config.h
piglit-dispatch-gen.c
piglit-dispatch-gen.h
piglit-dispatch-gen.[ch]
This diff is collapsed.
This diff is collapsed.
/**
* ${warning}
*
* Copyright 2014 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.
*/
<%block filter='fake_whitespace'>\
% for alias_set in gl_registry.command_alias_map:
<% f0 = alias_set.primary_command %>\
static void*
resolve_${f0.name}(void)
{
% for req in alias_set.requirements:
>-------/* ${req.command.name} (${req.provider.name}) */
% for api in sorted(set(dispatch.APIS[x] for x in req.apis)):
% if loop.first:
>-------if ((
% else:
>------- .
% endif
.............(dispatch_api == ${api.c_piglit_token}
% if req.has_feature and req.feature.version_int > api.base_version_int:
................................................... && check_version(${req.feature.version_int})
% endif
................................................................................................)
% if not loop.last:
................................................................................................. ||
% endif
% endfor
....................................................................................................)
% if req.has_extension:
>------- && check_extension("${req.extension.name}")
% endif
...............................................................) {
% if req.has_feature:
>------->-------return get_core_proc("${req.command.name}", ${api.base_version_int});
% elif req.has_extension:
>------->-------return get_ext_proc("${req.command.name}");
% endif
>-------}
% endfor
>-------unsupported("${f0.name}");
>-------return piglit_dispatch_${f0.name};
}
static ${f0.c_return_type} APIENTRY
stub_${f0.name}(${f0.c_named_param_list})
{
>-------check_initialized();
>-------piglit_dispatch_${f0.name} = resolve_${f0.name}();
>-------
% if f0.c_return_type != 'void':
........return .
% endif
...............piglit_dispatch_${f0.name}(${f0.c_untyped_param_list});
}
PFN${f0.name.upper()}PROC piglit_dispatch_${f0.name} = stub_${f0.name};
% endfor
static void reset_dispatch_pointers(void)
{
% for alias_set in gl_registry.command_alias_map:
<% f0 = alias_set.primary_command %>\
>-------piglit_dispatch_${f0.name} = stub_${f0.name};
% endfor
}
static const char * function_names[] = {
% for command in gl_registry.commands:
>-------"${command.name}",
% endfor
};
static void* (*const function_resolvers[])(void) = {
% for alias_set in gl_registry.command_alias_map:
<% f0 = alias_set.primary_command %>\
>-------resolve_${f0.name},
% endfor
};
</%block>\
/**
* ${warning}
*
* Copyright 2014 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.
*/
<%block filter='fake_whitespace'>\
#pragma once
#ifndef __PIGLIT_DISPATCH_GEN_H__
#define __PIGLIT_DISPATCH_GEN_H__
##
## Define function pointer typedefs, such as PFNGLACCUMPROC.
##
% for f in sorted(gl_registry.commands):
typedef ${f.c_return_type} (APIENTRY *PFN${f.name.upper()}PROC)(${f.c_named_param_list});
% endfor
##
## Emit macro wrapper for each dispatch function. For example,
##
## #define glAttachObjectARB piglit_dispatch_glAttachShader
##
% for alias_set in gl_registry.command_alias_map:
<% f0 = alias_set.primary_command %>\
% for command in alias_set:
/* ${command.name}
% for requirement in command.requirements:
.................. (${requirement.provider.name})
% endfor
................................................. */
% endfor
extern PFN${f0.name.upper()}PROC piglit_dispatch_${f0.name};
% for command in alias_set:
#define ${command.name} piglit_dispatch_${f0.name}
% endfor
% endfor
##
## Define enums.
##
% for enum_group in gl_registry.enum_groups:
% if len(enum_group.enums) > 0:
/* Enum Group ${enum_group.name} */
% for enum in enum_group.enums:
#define ${enum.name} ${enum.c_num_literal}
% endfor
% endif
% endfor
/* Extensions */
% for extension in gl_registry.extensions:
#define ${extension.name} 1
% endfor
/* Versions */
% for feature in gl_registry.features:
#define ${feature.name} 1
% endfor
#endif /* __PIGLIT_DISPATCH_GEN_H__ */
</%block>\
......@@ -96,6 +96,7 @@ typedef float GLfloat;
typedef float GLclampf;
typedef double GLdouble;
typedef double GLclampd;
typedef int32_t GLclampx;
typedef void GLvoid;
typedef int64_t GLint64EXT;
typedef uint64_t GLuint64EXT;
......@@ -136,8 +137,6 @@ typedef piglit_dispatch_function_ptr (*piglit_get_core_proc_address_function_ptr
typedef piglit_dispatch_function_ptr (*piglit_get_ext_proc_address_function_ptr)(const char *);
typedef piglit_dispatch_function_ptr (*piglit_dispatch_resolver_ptr)();
typedef void (*piglit_error_function_ptr)(const char *);
typedef enum {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment