added glad generator and a glad runtime
This commit is contained in:
parent
2017f6195e
commit
ac18a84a9c
62 changed files with 32373 additions and 10 deletions
tools/glad-0.1.14a0/glad/lang/nim
530
tools/glad-0.1.14a0/glad/lang/nim/generator.py
Normal file
530
tools/glad-0.1.14a0/glad/lang/nim/generator.py
Normal file
|
@ -0,0 +1,530 @@
|
|||
from itertools import chain
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
from glad.lang.common.generator import Generator
|
||||
from glad.lang.common.util import makefiledir
|
||||
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
from io import StringIO
|
||||
basestring = str
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
|
||||
|
||||
def _gl_types(gen, f):
|
||||
f.write('''
|
||||
GLdebugProc* = proc (
|
||||
source: GLenum,
|
||||
typ: GLenum,
|
||||
id: GLuint,
|
||||
severity: GLenum,
|
||||
length: GLsizei,
|
||||
message: ptr GLchar,
|
||||
userParam: pointer) {.stdcall.}
|
||||
|
||||
GLdebugProcArb* = proc (
|
||||
source: GLenum,
|
||||
typ: GLenum,
|
||||
id: GLuint,
|
||||
severity: GLenum,
|
||||
len: GLsizei,
|
||||
message: ptr GLchar,
|
||||
userParam: pointer) {.stdcall.}
|
||||
|
||||
GLdebugProcAmd* = proc (
|
||||
id: GLuint,
|
||||
category: GLenum,
|
||||
severity: GLenum,
|
||||
len: GLsizei,
|
||||
message: ptr GLchar,
|
||||
userParam: pointer) {.stdcall.}
|
||||
|
||||
GLdebugProcKhr* = proc (
|
||||
source, typ: GLenum,
|
||||
id: GLuint,
|
||||
severity: GLenum,
|
||||
length: GLsizei,
|
||||
message: ptr GLchar,
|
||||
userParam: pointer) {.stdcall.}
|
||||
''')
|
||||
|
||||
|
||||
# TODO finish converting the egl, glx & wgl loaders to Nim
|
||||
|
||||
# def _egl_types(gen, f):
|
||||
# def _glx_types(gen, f):
|
||||
# def _wgl_types(gen, f):
|
||||
|
||||
NIMTYPES = {
|
||||
'__other': {
|
||||
'gl': _gl_types
|
||||
# 'egl': _egl_types,
|
||||
# 'glx': _glx_types,
|
||||
# 'wgl': _wgl_types
|
||||
},
|
||||
|
||||
'gl': {
|
||||
'GLbitfield': 'uint32',
|
||||
'GLboolean': 'bool',
|
||||
'GLbyte': 'int8',
|
||||
'GLchar': 'char',
|
||||
'GLcharARB': 'byte',
|
||||
'GLclampd': 'float64',
|
||||
'GLclampf': 'float32',
|
||||
'GLclampx': 'int32',
|
||||
'GLdouble': 'float64',
|
||||
'GLeglImageOES': 'distinct pointer',
|
||||
'GLenum': 'uint32',
|
||||
'GLfixed': 'int32',
|
||||
'GLfloat': 'float32',
|
||||
'GLhalf': 'uint16',
|
||||
'GLhalfARB': 'uint16',
|
||||
'GLhalfNV': 'uint16',
|
||||
'GLhandleARB': 'uint32',
|
||||
'GLint': 'int32',
|
||||
'GLint64': 'int64',
|
||||
'GLint64EXT': 'int64',
|
||||
'GLintptr': 'int32',
|
||||
'GLintptrARB': 'int32',
|
||||
'GLshort': 'int16',
|
||||
'GLsizei': 'int32',
|
||||
'GLsizeiptr': 'int32',
|
||||
'GLsizeiptrARB': 'int32',
|
||||
'GLubyte': 'uint8',
|
||||
'GLuint': 'uint32',
|
||||
'GLuint64': 'uint64',
|
||||
'GLuint64EXT': 'uint64',
|
||||
'GLushort': 'uint16',
|
||||
'GLvdpauSurfaceNV': 'int32',
|
||||
'GLvoid': 'pointer',
|
||||
'GLsync': 'distinct pointer',
|
||||
'ClContext': 'distinct pointer',
|
||||
'ClEvent': 'distinct pointer'
|
||||
},
|
||||
'egl': {
|
||||
'EGLAttrib': 'int32',
|
||||
'EGLAttribKHR': 'int32',
|
||||
'EGLBoolean': 'bool',
|
||||
'EGLClientBuffer': 'distinct pointer',
|
||||
'EGLConfig': 'distinct pointer',
|
||||
'EGLContext': 'distinct pointer',
|
||||
'EGLDeviceEXT': 'distinct pointer',
|
||||
'EGLDisplay': 'distinct pointer',
|
||||
'EGLImage': 'distinct pointer',
|
||||
'EGLImageKHR': 'distinct pointer',
|
||||
'EGLNativeFileDescriptorKHR': 'int32',
|
||||
'EGLOutputLayerEXT': 'distinct pointer',
|
||||
'EGLOutputPortEXT': 'distinct pointer',
|
||||
'EGLStreamKHR': 'distinct pointer',
|
||||
'EGLSurface': 'distinct pointer',
|
||||
'EGLSync': 'distinct pointer',
|
||||
'EGLSyncKHR': 'distinct pointer',
|
||||
'EGLSyncNV': 'distinct pointer',
|
||||
'EGLTimeKHR': 'uint64',
|
||||
'EGLTime': 'uint64',
|
||||
'EGLTimeNV': 'uint64',
|
||||
'EGLenum': 'uint32',
|
||||
'EGLint': 'int32',
|
||||
'EGLsizeiANDROID': 'distinct pointer',
|
||||
'EGLuint64KHR': 'uint64',
|
||||
'EGLuint64MESA': 'uint64',
|
||||
'EGLuint64NV': 'uint64',
|
||||
# '__eglMustCastToProperFunctionPointerType': 'void function()'
|
||||
},
|
||||
'glx': {
|
||||
'GLbitfield': 'uint32',
|
||||
'GLboolean': 'uint8',
|
||||
'GLenum': 'uint32',
|
||||
'GLfloat': 'float32',
|
||||
'GLint': 'int32',
|
||||
'GLintptr': 'int32',
|
||||
'GLsizei': 'int32',
|
||||
'GLsizeiptr': 'int32',
|
||||
'GLubyte': 'uint8',
|
||||
'GLuint': 'uint32'
|
||||
},
|
||||
'wgl': {
|
||||
'GLbitfield': 'uint32',
|
||||
'GLboolean': 'uint8',
|
||||
'GLenum': 'uint32',
|
||||
'GLfloat': 'float32',
|
||||
'GLint': 'int32',
|
||||
'GLsizei': 'int32',
|
||||
'GLuint': 'uint32',
|
||||
'GLushort': 'uint16',
|
||||
'INT32': 'int32',
|
||||
'INT64': 'int64'
|
||||
},
|
||||
|
||||
'SpecialNumbers': {
|
||||
'gl': [
|
||||
('GL_FALSE', '0', None),
|
||||
('GL_INVALID_INDEX', '0xFFFFFFFF', 'uint32'),
|
||||
('GL_NONE', '0', None),
|
||||
('GL_NONE_OES', '0', None),
|
||||
('GL_NO_ERROR', '0', None),
|
||||
('GL_ONE', '1', None),
|
||||
('GL_TIMEOUT_IGNORED', '0xFFFFFFFFFFFFFFFF', 'uint64'),
|
||||
('GL_TIMEOUT_IGNORED_APPLE', '0xFFFFFFFFFFFFFFFF', 'uint64'),
|
||||
('GL_TRUE', '1', None),
|
||||
('GL_VERSION_ES_CL_1_0', '1', None),
|
||||
('GL_VERSION_ES_CL_1_1', '1', None),
|
||||
('GL_VERSION_ES_CM_1_1', '1', None),
|
||||
('GL_ZERO', '0', None),
|
||||
],
|
||||
'egl': [
|
||||
# ('EGL_DONT_CARE', '-1', 'int'), ('EGL_UNKNOWN', '-1', 'int'),
|
||||
# ('EGL_NO_NATIVE_FENCE_FD_ANDROID', '-1', 'uint'),
|
||||
# ('EGL_DEPTH_ENCODING_NONE_NV', '0', 'uint'),
|
||||
# ('EGL_NO_CONTEXT', 'cast(EGLContext)0', 'EGLContext'),
|
||||
# ('EGL_NO_DEVICE_EXT', 'cast(EGLDeviceEXT)0', 'EGLDeviceEXT'),
|
||||
# ('EGL_NO_DISPLAY', 'cast(EGLDisplay)0', 'EGLDisplay'),
|
||||
# ('EGL_NO_IMAGE', 'cast(EGLImage)0', 'EGLImage'),
|
||||
# ('EGL_NO_IMAGE_KHR', 'cast(EGLImageKHR)0', 'EGLImageKHR'),
|
||||
# ('EGL_DEFAULT_DISPLAY', 'cast(EGLNativeDisplayType)0', 'EGLNativeDisplayType'),
|
||||
# ('EGL_NO_FILE_DESCRIPTOR_KHR', 'cast(EGLNativeFileDescriptorKHR)-1', 'EGLNativeFileDescriptorKHR'),
|
||||
# ('EGL_NO_OUTPUT_LAYER_EXT', 'cast(EGLOutputLayerEXT)0', 'EGLOutputLayerEXT'),
|
||||
# ('EGL_NO_OUTPUT_PORT_EXT', 'cast(EGLOutputPortEXT)0', 'EGLOutputPortEXT'),
|
||||
# ('EGL_NO_STREAM_KHR', 'cast(EGLStreamKHR)0', 'EGLStreamKHR'),
|
||||
# ('EGL_NO_SURFACE', 'cast(EGLSurface)0', 'EGLSurface'),
|
||||
# ('EGL_NO_SYNC', 'cast(EGLSync)0', 'EGLSync'),
|
||||
# ('EGL_NO_SYNC_KHR', 'cast(EGLSyncKHR)0', 'EGLSyncKHR'),
|
||||
# ('EGL_NO_SYNC_NV', 'cast(EGLSyncNV)0', 'EGLSyncNV'),
|
||||
# ('EGL_DISPLAY_SCALING', '10000', 'uint'),
|
||||
# ('EGL_FOREVER', '0xFFFFFFFFFFFFFFFF', 'ulong'),
|
||||
# ('EGL_FOREVER_KHR', '0xFFFFFFFFFFFFFFFF', 'ulong'),
|
||||
# ('EGL_FOREVER_NV', '0xFFFFFFFFFFFFFFFF', 'ulong')
|
||||
],
|
||||
'glx': [
|
||||
# ('GLX_DONT_CARE', '0xFFFFFFFF', 'uint'),
|
||||
# ('GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB', '0', 'uint')
|
||||
],
|
||||
'wgl': [
|
||||
# ('WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB', '0', 'uint'),
|
||||
# ('WGL_FONT_LINES', '0', 'uint'),
|
||||
# ('WGL_FONT_POLYGONS', 1, 'uint')
|
||||
]
|
||||
},
|
||||
|
||||
'SpecialEnumNames': {
|
||||
'gl': {
|
||||
'GL_BYTE': 'cGL_BYTE',
|
||||
'GL_SHORT': 'cGL_SHORT',
|
||||
'GL_INT': 'cGL_INT',
|
||||
'GL_FLOAT': 'cGL_FLOAT',
|
||||
'GL_DOUBLE': 'cGL_DOUBLE',
|
||||
'GL_FIXED': 'cGL_FIXED'
|
||||
},
|
||||
'egl': {},
|
||||
'glx': {},
|
||||
'wgl': {}
|
||||
},
|
||||
|
||||
'SpecialFuncNames': {
|
||||
'gl': {
|
||||
'glGetTransformFeedbacki_v': 'glGetTransformFeedbacki_v2'
|
||||
},
|
||||
'egl': {},
|
||||
'glx': {},
|
||||
'wgl': {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class NimGenerator(Generator):
|
||||
NAME = 'nim'
|
||||
NAME_LONG = 'Nim'
|
||||
|
||||
MODULE = 'glad'
|
||||
FILE_EXTENSION = '.nim'
|
||||
TYPE_DICT = NIMTYPES
|
||||
|
||||
LOAD_GL_PREFIX = 'glad'
|
||||
EXT_PREFIX = 'GLAD_'
|
||||
|
||||
def open(self):
|
||||
self._f_gl = open(self.make_path(self.spec.NAME), 'w')
|
||||
|
||||
def close(self):
|
||||
self._f_gl.close()
|
||||
|
||||
def generate_header(self):
|
||||
self._f_gl.write('#[')
|
||||
self._f_gl.write(self.header)
|
||||
self._f_gl.write(']#\n\n')
|
||||
self._f_gl.write('import strutils\n\n')
|
||||
self._f_gl.write('var glVersionMajor, glVersionMinor: int\n\n')
|
||||
|
||||
def generate_loader(self, features, extensions):
|
||||
f = self._f_gl
|
||||
|
||||
rfeatures = features
|
||||
if self.spec.NAME in ('egl', 'wgl'):
|
||||
features = {'egl': [], 'wgl': []}
|
||||
|
||||
self.loader.write(f)
|
||||
self.loader.write_has_ext(f, self.get_version())
|
||||
|
||||
written = set()
|
||||
for api, version in self.api.items():
|
||||
# core load procs
|
||||
for feature in features[api]:
|
||||
f.write('proc load_{}(load: proc) =\n'
|
||||
.format(feature.name))
|
||||
if self.spec.NAME == 'gl':
|
||||
f.write(' if not {}{}: return\n\n'.format(self.EXT_PREFIX,
|
||||
feature.name))
|
||||
for func in feature.functions:
|
||||
self.write_func_definition(f, func)
|
||||
f.write('\n\n')
|
||||
|
||||
# extension load procs
|
||||
for ext in extensions[api]:
|
||||
if len(list(ext.functions)) == 0 or ext.name in written:
|
||||
continue
|
||||
|
||||
f.write('proc load_{}(load: proc) =\n'
|
||||
.format(ext.name))
|
||||
if self.spec.NAME == 'gl':
|
||||
f.write(' if not {}{}: return\n'.format(self.EXT_PREFIX,
|
||||
ext.name))
|
||||
for func in ext.functions:
|
||||
# even if they were in written we need to load it
|
||||
self.write_func_definition(f, func)
|
||||
|
||||
f.write('\n\n')
|
||||
|
||||
written.add(ext.name)
|
||||
|
||||
# findExtensions proc
|
||||
f.write('proc findExtensions{}() =\n'.format(api.upper()))
|
||||
if self.spec.NAME == 'gl':
|
||||
for ext in extensions[api]:
|
||||
f.write(' {0}{1} = hasExt("{1}")\n'.format(self.EXT_PREFIX,
|
||||
ext.name))
|
||||
f.write('\n\n')
|
||||
|
||||
# findCore proc
|
||||
f.write('proc findCore{}(glVersion: string) =\n'.format(api.upper()))
|
||||
self.loader.write_find_core(f)
|
||||
if self.spec.NAME == 'gl':
|
||||
for feature in features[api]:
|
||||
f.write(' {}{} = (major == {num[0]} and minor >= {num[1]}) or'
|
||||
' major > {num[0]}\n'.format(self.EXT_PREFIX, feature.name,
|
||||
num=feature.number))
|
||||
f.write('\n\n')
|
||||
|
||||
# main loader proc
|
||||
loadername = 'Load' if self.LOAD_GL_PREFIX else 'load'
|
||||
f.write('proc {}{}{}*(load: proc): bool =\n'
|
||||
.format(self.LOAD_GL_PREFIX, loadername, api.upper()))
|
||||
self.loader.write_begin_load(f)
|
||||
|
||||
f.write(' findCore{}($glVersion)\n\n'.format(api.upper()))
|
||||
for feature in features[api]:
|
||||
f.write(' load_{}(load)\n'.format(feature.name))
|
||||
f.write('\n findExtensions{}()\n\n'.format(api.upper()))
|
||||
for ext in extensions[api]:
|
||||
if len(list(ext.functions)) == 0:
|
||||
continue
|
||||
f.write(' load_{}(load);\n'.format(ext.name))
|
||||
self.loader.write_end_load(f)
|
||||
f.write('\n')
|
||||
|
||||
|
||||
def write_func_definition(self, fobj, func):
|
||||
func_name = self.map_func_name(func)
|
||||
fobj.write(' {} = cast['.format(func_name))
|
||||
self.write_function_declaration(fobj, func)
|
||||
fobj.write('](load("{}"))\n'.format(func_name))
|
||||
|
||||
|
||||
def map_func_name(self, func):
|
||||
name = func.proto.name
|
||||
m = self.TYPE_DICT['SpecialFuncNames'][self.spec.NAME]
|
||||
return m[name] if name in m else name
|
||||
|
||||
|
||||
def generate_types(self, types):
|
||||
f = self._f_gl
|
||||
|
||||
f.write('# Types\ntype\n')
|
||||
for ogl, d in sorted(self.TYPE_DICT[self.spec.NAME].items()):
|
||||
f.write(' {}* = {}\n'.format(ogl, d))
|
||||
self.TYPE_DICT['__other'][self.spec.NAME](self, f)
|
||||
f.write('\n')
|
||||
|
||||
|
||||
def generate_features(self, features):
|
||||
self.write_enums(features)
|
||||
self.write_funcs(features)
|
||||
|
||||
|
||||
def write_enums(self, features):
|
||||
f = self._f_gl
|
||||
|
||||
f.write('\n# Enums\nconst\n')
|
||||
for v in sorted(self.TYPE_DICT['SpecialNumbers'][self.spec.NAME]):
|
||||
self.write_enum(f, *v)
|
||||
f.write('\n')
|
||||
|
||||
written = set()
|
||||
for feature in features:
|
||||
for enum in feature.enums:
|
||||
if enum.group == 'SpecialNumbers':
|
||||
written.add(enum)
|
||||
continue
|
||||
if not enum in written:
|
||||
self.write_enum(f, enum.name, enum.value)
|
||||
written.add(enum)
|
||||
f.write('\n')
|
||||
|
||||
|
||||
def write_funcs(self, features):
|
||||
f = self._f_gl
|
||||
|
||||
f.write('\n# Functions\nvar\n')
|
||||
if self.spec.NAME == 'gl':
|
||||
for feature in features:
|
||||
self.write_boolean(f, feature.name)
|
||||
f.write('\n')
|
||||
|
||||
# TODO
|
||||
if self.spec.NAME in ('egl', 'wgl'):
|
||||
for feature in features:
|
||||
for func in feature.functions:
|
||||
self.write_function_def(f, func) # TODO
|
||||
f.write('\n')
|
||||
else:
|
||||
self.write_functions(f, set(), set(), features)
|
||||
f.write('\n\n')
|
||||
|
||||
|
||||
# TODO
|
||||
def write_function_def(self, fobj, func):
|
||||
fobj.write('{} {}('.format(func.proto.ret.to_nim(), self.map_func_name(func)))
|
||||
fobj.write(', '.join(param.type.to_nim() for param in func.params))
|
||||
fobj.write(');\n')
|
||||
|
||||
|
||||
def generate_extensions(self, extensions, enums, functions):
|
||||
f = self._f_gl
|
||||
|
||||
write = set()
|
||||
written = set(enum.name for enum in enums) | \
|
||||
set(function.proto.name for function in functions)
|
||||
|
||||
f.write('# Extensions\nvar\n')
|
||||
for ext in extensions:
|
||||
if self.spec.NAME == 'gl' and not ext.name in written:
|
||||
self.write_boolean(f, ext.name)
|
||||
|
||||
for enum in ext.enums:
|
||||
if not enum.name in written and not enum.group == 'SpecialNumbers':
|
||||
type = (None if enum.group == 'TransformFeedbackTokenNV'
|
||||
else 'GLenum')
|
||||
self.write_enum(f, enum.name, enum.value, type)
|
||||
written.add(enum.name)
|
||||
written.add(ext.name)
|
||||
f.write('\n')
|
||||
|
||||
self.write_functions(f, write, written, extensions)
|
||||
f.write('\n\n')
|
||||
|
||||
|
||||
def write_functions(self, f, write, written, extensions):
|
||||
for ext in extensions:
|
||||
for func in ext.functions:
|
||||
if not func.proto.name in written:
|
||||
self.write_function_var(f, func)
|
||||
write.add(func)
|
||||
written.add(func.proto.name)
|
||||
|
||||
|
||||
def write_function_var(self, fobj, func):
|
||||
fobj.write(' {}*: '.format(self.map_func_name(func)))
|
||||
self.write_function_declaration(fobj, func)
|
||||
fobj.write('\n')
|
||||
|
||||
|
||||
def write_function_declaration(self, fobj, func):
|
||||
fobj.write('proc ('.format(self.map_func_name(func)))
|
||||
fobj.write(', '.join('{}: {}'.format(self.to_nim_param_name(param.name),
|
||||
param.type.to_nim())
|
||||
for param in func.params))
|
||||
fobj.write(')')
|
||||
|
||||
ret = func.proto.ret.to_nim()
|
||||
if (ret != 'void'):
|
||||
fobj.write(': {}'.format(ret))
|
||||
|
||||
fobj.write(' {.cdecl.}')
|
||||
|
||||
# TODO
|
||||
# def write_function_var(self, fobj, func):
|
||||
# fobj.write(' {} = cast[proc ('.format(func.proto.name))
|
||||
# fobj.write(', '.join('{}: {}'.format(self.to_nim_param_name(param.name),
|
||||
# param.type.to_nim())
|
||||
# for param in func.params))
|
||||
# fobj.write(')')
|
||||
#
|
||||
# ret = func.proto.ret.to_nim()
|
||||
# if (ret != 'void'):
|
||||
# fobj.write(': {}'.format(ret))
|
||||
#
|
||||
# fobj.write(' {.cdecl.}]')
|
||||
# fobj.write(' (getProcAddress("{}"))\n'.format(func.proto.name))
|
||||
|
||||
|
||||
NIM_KEYWORDS = [ # as of Nim 0.13.0
|
||||
'addr', 'and', 'as', 'asm', 'atomic',
|
||||
'bind', 'block', 'break',
|
||||
'case', 'cast', 'concept', 'const', 'continue', 'converter',
|
||||
'defer', 'discard', 'distinct', 'div', 'do',
|
||||
'elif', 'else', 'end', 'enum', 'except', 'export',
|
||||
'finally', 'for', 'from', 'func',
|
||||
'generic',
|
||||
'if', 'import', 'in', 'include', 'interface', 'is', 'isnot', 'iterator',
|
||||
'let',
|
||||
'macro', 'method', 'mixin', 'mod',
|
||||
'nil', 'not', 'notin',
|
||||
'object', 'of', 'or', 'out',
|
||||
'proc', 'ptr',
|
||||
'raise', 'ref', 'return',
|
||||
'shl', 'shr', 'static',
|
||||
'template', 'try', 'tuple', 'type',
|
||||
'using',
|
||||
'var',
|
||||
'when', 'while', 'with', 'without',
|
||||
'xor',
|
||||
'yield'
|
||||
]
|
||||
|
||||
def to_nim_param_name(self, name):
|
||||
return '`{}`'.format(name) if name in self.NIM_KEYWORDS else name
|
||||
|
||||
def make_path(self, name):
|
||||
path = os.path.join(self.path, self.MODULE.split('.')[-1],
|
||||
name.split('.')[-1] + self.FILE_EXTENSION)
|
||||
makefiledir(path)
|
||||
return path
|
||||
|
||||
def write_boolean(self, fobj, name):
|
||||
fobj.write(' {}{}*: bool\n'.format(self.EXT_PREFIX, name))
|
||||
|
||||
def write_enum(self, fobj, name, value, type='GLenum'):
|
||||
fobj.write(' {}*'.format(self.map_enum_name(name)))
|
||||
if type:
|
||||
fobj.write(': {0} = {0}({1})'.format(type, value))
|
||||
else:
|
||||
fobj.write(' = {}'.format(value))
|
||||
fobj.write('\n')
|
||||
|
||||
def map_enum_name(self, name):
|
||||
m = self.TYPE_DICT['SpecialEnumNames'][self.spec.NAME]
|
||||
return m[name] if name in m else name
|
||||
|
||||
def get_version(self):
|
||||
return self.api[self.spec.NAME]
|
Loading…
Add table
Add a link
Reference in a new issue