~vladh/glad

2b5d178be0e33ef109f61421433f0231b594d725 — Conrad Hoffmann a month ago a505e1d
Update to work with latest Hare stdlib and Jinja

Changes include mostly:
 - *void -> *opaque
 - char -> types::c::char
 - jinja::contextfilter -> jinja::pass_context
 - avoid duplicate values (due to aliases) in switch statements

Disclaimer: I have no idea what I am doing :) but I did get the
vulkan-hello-world example to work and also the starfield GL example.
M glad/generator/hare/__init__.py => glad/generator/hare/__init__.py +10 -7
@@ 14,7 14,7 @@ from glad.sink import LoggingSink

_HARE_TYPE_MAPPING = {
    'void': 'void',
    # 'char': 'i8',
    'char': 'c::char',
    'uchar': 'u8',
    'float': 'f32',
    'double': 'f64',


@@ 60,8 60,8 @@ _HARE_TYPE_MAPPING = {
    'GLfixed': 'i32',
    'GLhandleARB': 'uint',
    'GLhalfNV': 'u16',
    'GLeglImageOES': '*const void',
    'GLeglClientBufferEXT': '*void',
    'GLeglImageOES': '*const opaque',
    'GLeglClientBufferEXT': '*opaque',
    '_cl_context': 'void', # opaque struct
    '_cl_event': 'void', # opaque struct
}


@@ 166,6 166,9 @@ def to_hare_type(type_):

    type_ = _HARE_TYPE_MAPPING.get(parsed_type.type.strip(), parsed_type.type.strip())

    if type_ == 'void' and parsed_type.is_pointer:
        type_ = 'opaque'

    if parsed_type.is_array > 0:
        type_ = '[{}]{}'.format(parsed_type.is_array, type_)



@@ 247,13 250,13 @@ class HareGenerator(JinjaGenerator):

        self.environment.filters.update(
            feature=lambda x: 'feature = "{}"'.format(x),
            enum_type=jinja2.contextfilter(lambda ctx, enum: enum_type(enum, ctx['feature_set'])),
            enum_value=jinja2.contextfilter(lambda ctx, enum: enum_value(enum, ctx['feature_set'])),
            enum_type=jinja2.pass_context(lambda ctx, enum: enum_type(enum, ctx['feature_set'])),
            enum_value=jinja2.pass_context(lambda ctx, enum: enum_value(enum, ctx['feature_set'])),
            type=to_hare_type,
            params=to_hare_params,
            identifier=identifier,
            no_prefix=jinja2.contextfilter(lambda ctx, value: strip_specification_prefix(value, ctx['spec'])),
            is_descendant=jinja2.contextfilter(lambda ctx, type_, target, ignoretypes = None: is_descendant(type_, target, ignoretypes, ctx['spec'])),
            no_prefix=jinja2.pass_context(lambda ctx, value: strip_specification_prefix(value, ctx['spec'])),
            is_descendant=jinja2.pass_context(lambda ctx, type_, target, ignoretypes = None: is_descendant(type_, target, ignoretypes, ctx['spec'])),
            alias_to_value=alias_to_value,
        )


M glad/generator/hare/templates/gl.ha => glad/generator/hare/templates/gl.ha +7 -6
@@ 1,11 1,12 @@
{% set ctx_name = feature_set.name | capitalize %}
use types;
use types::c;

// Built-in loader
@symbol("eglGetProcAddress") fn eglGetProcAddress(procName: *const char) *void;
@symbol("eglGetProcAddress") fn eglGetProcAddress(procName: *const c::char) *opaque;

fn get_proc_address(proc_name: str) *void = {
	let cstr = ((&proc_name): *types::string).data: *const char;
fn get_proc_address(proc_name: str) *opaque = {
	let cstr = c::nulstr(proc_name);
	return eglGetProcAddress(cstr);
};



@@ 36,10 37,10 @@ export fn load() void = {
};

// Function loading with user loader
export type fp_get_proc_address = fn(procName: *const char) *void;
export type fp_get_proc_address = fn(procName: *const c::char) *opaque;

fn call_user_get_proc_address(user_get_proc_address: *fp_get_proc_address, proc_name: str) *void = {
	let cstr = ((&proc_name): *types::string).data: *const char;
fn call_user_get_proc_address(user_get_proc_address: *fp_get_proc_address, proc_name: str) *opaque = {
	let cstr = c::nulstr(proc_name);
	return user_get_proc_address(cstr);
};


M glad/generator/hare/templates/types/gl.ha => glad/generator/hare/templates/types/gl.ha +8 -8
@@ 7,8 7,8 @@ export type GLDEBUGPROC = nullable *fn(
	id: uint,
	severity: gl_enum,
	length: i32,
	message: nullable *const char,
	userParam: nullable *void
	message: nullable *const c::char,
	userParam: nullable *opaque
) void;
export type GLDEBUGPROCARB = nullable *fn(
	source: gl_enum,


@@ 16,8 16,8 @@ export type GLDEBUGPROCARB = nullable *fn(
	id: uint,
	severity: gl_enum,
	length: i32,
	message: nullable *const char,
	userParam: nullable *void
	message: nullable *const c::char,
	userParam: nullable *opaque
) void;
export type GLDEBUGPROCKHR = nullable *fn(
	source: gl_enum,


@@ 25,15 25,15 @@ export type GLDEBUGPROCKHR = nullable *fn(
	id: uint,
	severity: gl_enum,
	length: i32,
	message: nullable *const char,
	userParam: nullable *void
	message: nullable *const c::char,
	userParam: nullable *opaque
) void;
export type GLDEBUGPROCAMD = nullable *fn(
	id: uint,
	category: gl_enum,
	severity: gl_enum,
	length: i32,
	message: nullable *const char,
	userParam: nullable *void
	message: nullable *const c::char,
	userParam: nullable *opaque
) void;
export type GLVULKANPROCNV = nullable *fn() void;

M glad/generator/hare/templates/types/vk.ha => glad/generator/hare/templates/types/vk.ha +22 -18
@@ 1,26 1,26 @@
{% import 'template_utils.ha' as template_utils with context %}

// XCB
export type xcb_connection_t = nullable *void;
export type xcb_connection_t = nullable *opaque;
export type xcb_window_t = u32;
export type xcb_visualid_t = u32;
export type zx_handle_t = u32;

// Android (somehow already defined)
// export type ANativeWindow = nullable *void;
// export type AHardwareBuffer = nullable *void;
// export type ANativeWindow = nullable *opaque;
// export type AHardwareBuffer = nullable *opaque;

// iOS / macOS (some are somehow already defined)
// export type CAMetalLayer = nullable *void;
// export type CAMetalLayer = nullable *opaque;
export type GgpFrameToken = u32;
export type GgpStreamDescriptor = u32;

// DirectFB
export type IDirectFB = nullable *void;
export type IDirectFBSurface = nullable *void;
export type IDirectFB = nullable *opaque;
export type IDirectFBSurface = nullable *opaque;

// xlib (_xrandr)
export type Display = nullable *void;
export type Display = nullable *opaque;
export type RROutput = u32;
export type Window = u32;
export type VisualID = u32;


@@ 28,13 28,13 @@ export type VisualID = u32;
// Win32
export type BOOL = i32;
export type DWORD = u32;
export type LPVOID = nullable *void;
export type HANDLE = nullable *void;
export type HMONITOR = nullable *void;
export type LPVOID = nullable *opaque;
export type HANDLE = nullable *opaque;
export type HMONITOR = nullable *opaque;
export type WCHAR = u16;
export type LPCWSTR = *const void; // hare doesn't have wide chars
export type HINSTANCE = nullable *void;
export type HWND = nullable *void;
export type LPCWSTR = *const opaque; // hare doesn't have wide chars
export type HINSTANCE = nullable *opaque;
export type HWND = nullable *opaque;
export type SECURITY_ATTRIBUTES = struct {
    nLength: DWORD,
    lpSecurityDescriptor: LPVOID,


@@ 42,12 42,12 @@ export type SECURITY_ATTRIBUTES = struct {
};

// Wayland
export type wl_display = nullable *void;
export type wl_surface = nullable *void;
export type wl_display = nullable *opaque;
export type wl_surface = nullable *opaque;

// Mir
export type MirConnection = nullable *void;
export type MirSurface = nullable *void;
export type MirConnection = nullable *opaque;
export type MirSurface = nullable *opaque;

export fn VK_MAKE_VERSION(major: uint, minor: uint, patch: uint) uint = {
	return (major << 22) | (minor << 12) | patch;


@@ 77,7 77,7 @@ export type {{ type.name }} = {{ type.alias }};
{% elif type.category == 'basetype' %}
export type {{ type.name }} = {{ type.type|type }};
{% elif type.category == 'handle' %}
export type {{ type.name }} = nullable *void;
export type {{ type.name }} = nullable *opaque;
{% elif type.category == 'enum' %}
{% set members = type.enums_for(feature_set) %}
{% if members %}


@@ 94,9 94,13 @@ export type {{ type.name }} = enum u{{ type.bitwidth or 32 }} {
{% endcall %}
export fn Str{{ type.name }}(value: {{ type.name }}) str = {
	switch (value) {
	{% set values = { None: 1 } %}
	{% for member in members %}
	{% if not member.value in values %}
	{% set x=values.__setitem__(member.value, 1) %}
	case {{ type.name }}::{{ member.name }} =>
		return "{{ member.name }}";
	{% endif %}
	{% endfor %}
	};
};

M glad/generator/hare/templates/vk.ha => glad/generator/hare/templates/vk.ha +7 -6
@@ 1,15 1,16 @@
use types;
use types::c;

// Built-in loader
@symbol("vkGetInstanceProcAddr") fn _vkGetInstanceProcAddr(instance: nullable *void, procName: *const char) *void;
@symbol("vkGetDeviceProcAddr") fn _vkGetDeviceProcAddr(device: nullable *void, procName: *const char) *void;
@symbol("vkGetInstanceProcAddr") fn _vkGetInstanceProcAddr(instance: nullable *opaque, procName: *const c::char) *opaque;
@symbol("vkGetDeviceProcAddr") fn _vkGetDeviceProcAddr(device: nullable *opaque, procName: *const c::char) *opaque;

fn get_instance_proc_address(instance: nullable *void, proc_name: *const char) *void = {
	let cstr = ((proc_name): *types::string).data: *const char;
fn get_instance_proc_address(instance: nullable *opaque, proc_name: const str) *opaque = {
	const cstr = c::nulstr(proc_name);
	return _vkGetInstanceProcAddr(instance, cstr);
};
fn get_device_proc_address(device: nullable *void, proc_name: *const char) *void = {
	let cstr = ((proc_name): *types::string).data: *const char;
fn get_device_proc_address(device: nullable *opaque, proc_name: const str) *opaque = {
	const cstr = c::nulstr(proc_name);
	return _vkGetDeviceProcAddr(device, cstr);
};