Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion iris-hostgl/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
// calls are the same as a core or ARB call it has, and the ones emulated in
// emul.rs. (Checked against SGI's own libGL list and the Mac's; carried over
// as generated, not regenerated here.)
pub const EXTENSIONS: &str = "GL_ARB_multitexture GL_EXT_abgr GL_EXT_blend_color GL_EXT_blend_logic_op GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_convolution GL_EXT_copy_texture GL_EXT_histogram GL_EXT_packed_pixels GL_EXT_polygon_offset GL_EXT_subtexture GL_EXT_texture GL_EXT_texture3D GL_EXT_texture_object GL_EXT_vertex_array GL_SGIS_detail_texture GL_SGIS_fog_function GL_SGIS_generate_mipmap GL_SGIS_multisample GL_SGIS_multitexture GL_SGIS_point_parameters GL_SGIS_sharpen_texture GL_SGIS_texture4D GL_SGIS_texture_edge_clamp GL_SGIS_texture_filter4 GL_SGIS_texture_lod GL_SGIS_texture_select GL_SGIX_clipmap GL_SGIX_flush_raster GL_SGIX_fog_offset GL_SGIX_interlace GL_SGIX_pixel_texture GL_SGIX_reference_plane GL_SGIX_shadow GL_SGIX_sprite GL_SGIX_texture_add_env GL_SGIX_texture_scale_bias GL_SGI_color_matrix GL_SGI_color_table GL_SGI_texture_color_table";
// Of IMPACT's own list (IMPACT/2/2/4, 6.5.22), all are here but
// GL_SGIX_list_priority (glListParameter*, which this library does not
// have): GL_SGIS_texture_border_clamp's GL_CLAMP_TO_BORDER_SGIS is core
// GL_CLAMP_TO_BORDER, and GL_SGIX_texture_multi_buffer is a hint the guest
// library takes (its glHint keeps GL_TEXTURE_MULTI_BUFFER_HINT_SGIX itself).
pub const EXTENSIONS: &str = "GL_ARB_multitexture GL_EXT_abgr GL_EXT_blend_color GL_EXT_blend_logic_op GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_convolution GL_EXT_copy_texture GL_EXT_histogram GL_EXT_packed_pixels GL_EXT_polygon_offset GL_EXT_subtexture GL_EXT_texture GL_EXT_texture3D GL_EXT_texture_object GL_EXT_vertex_array GL_SGIS_detail_texture GL_SGIS_fog_function GL_SGIS_generate_mipmap GL_SGIS_multisample GL_SGIS_multitexture GL_SGIS_point_parameters GL_SGIS_sharpen_texture GL_SGIS_texture4D GL_SGIS_texture_border_clamp GL_SGIS_texture_edge_clamp GL_SGIS_texture_filter4 GL_SGIS_texture_lod GL_SGIS_texture_select GL_SGIX_clipmap GL_SGIX_flush_raster GL_SGIX_fog_offset GL_SGIX_interlace GL_SGIX_pixel_texture GL_SGIX_reference_plane GL_SGIX_shadow GL_SGIX_sprite GL_SGIX_texture_add_env GL_SGIX_texture_multi_buffer GL_SGIX_texture_scale_bias GL_SGI_color_matrix GL_SGI_color_table GL_SGI_texture_color_table";

/*
* What a guest program is told it is talking to.
Expand Down
75 changes: 75 additions & 0 deletions iris-hostgl/tools/glshim.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,90 @@
"glEnable": "if (hgl_index_mode && cap == GL_LOGIC_OP) cap = GL_COLOR_LOGIC_OP;",
"glDisable": "if (hgl_index_mode && cap == GL_LOGIC_OP) cap = GL_COLOR_LOGIC_OP;",
"glIsEnabled": "if (hgl_index_mode && cap == GL_LOGIC_OP) cap = GL_COLOR_LOGIC_OP;",
# GL_TEXTURE_MULTI_BUFFER_HINT_SGIX (GL_SGIX_texture_multi_buffer): a
# hint about IMPACT's texture memory, which the host has no use for and
# would refuse; taken here.
"glHint": "if (target == 0x812E) return;",
# Drawing indices: the host's RGBA GL turns them into colours through its
# pixel maps (all 0), so they are encoded here as an index context draws.
"glDrawPixels": "if (hgl_index_mode && format == GL_COLOR_INDEX) { hgl_draw_index(width, height, type, pixels); return; }",
# Reading indices back: the host has only the RGBA they were drawn as.
"glReadPixels": "if (hgl_index_mode && format == GL_COLOR_INDEX) { hgl_read_index(x, y, width, height, type, pixels); return; }",
}

# lmcolor(LMC_COLOR) for SGI's IRIS GL (hgl_lmc in the guest's glshim_rt.c):
# the program's GL_LIGHTING, and a glBegin held until its first vertex while
# the mode is on. Which of a colour and a normal came last, IGLOO says itself.
GUEST_HOOKS.update({
**{f"glVertex{n}{t}{v}": "if (hgl_lmc_pending) hgl_lmc_vertex();"
for n in ("2", "3", "4") for t in ("d", "f", "i", "s") for v in ("", "v")},
"glBegin": "if (hgl_lmc && hgl_lmc_begin(mode)) return;",
"glEnd": "if (hgl_lmc_pending && hgl_lmc_end()) return;",
"glEnable": "hgl_lmc_lighting(cap, 1);",
"glDisable": "hgl_lmc_lighting(cap, 0);",
})

# swaptmesh for SGI's IRIS GL (hgl_tm in the guest's glshim_rt.c): inside one
# of its triangle meshes, each vertex and the normal, colour and texture
# coordinate it was sent with are kept, so that a swap can send the older of
# the last two again. Values as floats: an integer colour or normal is
# normalized as OpenGL does it.
_TM_NORM = {"b": "127.0", "s": "32767.0", "i": "2147483647.0"}
_TM_UNORM = {"ub": "255.0", "us": "65535.0", "ui": "4294967295.0"}


def _tm_args(names, n, t, v, norm):
"""C expressions for n values of type t, scalar names or v[i], as doubles."""
vals = [f"v[{i}]" if v else names[i] for i in range(n)]
if norm and t in _TM_NORM:
# OpenGL 1.1: (2c + 1) / (2^b - 1)
return [f"(2.0 * {x} + 1.0) / (2.0 * {_TM_NORM[t]} + 1.0)" for x in vals]
if norm and t in _TM_UNORM:
return [f"{x} / {_TM_UNORM[t]}" for x in vals]
return [f"(double){x}" for x in vals]


def _tm_hook(kind, names, n, t, v, norm, fill):
a = _tm_args(names, n, t, v, norm) + fill[n:]
return f"if (hgl_tm && !hgl_tm_internal) hgl_tm_attr({kind}, {', '.join(a)});"


def _add_hook(name, code, first=False):
old = GUEST_HOOKS.get(name)
GUEST_HOOKS[name] = code if old is None else (f"{code} {old}" if first else f"{old} {code}")


for n in ("3", "4"):
for t in ("b", "d", "f", "i", "s", "ub", "ui", "us"):
for v in ("", "v"):
_add_hook(f"glColor{n}{t}{v}", _tm_hook("HGL_TM_COLOUR", ["red", "green", "blue", "alpha"], int(n), t, v, True,
["0", "0", "0", "1.0"]))
for t in ("b", "d", "f", "i", "s"):
for v in ("", "v"):
_add_hook(f"glNormal3{t}{v}", _tm_hook("HGL_TM_NORMAL", ["nx", "ny", "nz"], 3, t, v, True, ["0", "0", "0", "0"]))
for n in ("1", "2", "3", "4"):
for t in ("d", "f", "i", "s"):
for v in ("", "v"):
_add_hook(f"glTexCoord{n}{t}{v}", _tm_hook("HGL_TM_TEXCOORD", ["s", "t", "r", "q"], int(n), t, v, False,
["0", "0", "0", "1.0"]))
for n in ("2", "3", "4"):
for t in ("d", "f", "i", "s"):
for v in ("", "v"):
# After lmcolor's: the vertex is sent after its held glBegin.
_add_hook(f"glVertex{n}{t}{v}", _tm_hook("HGL_TM_VERTEX", ["x", "y", "z", "w"], int(n), t, v, False,
["0", "0", "0", "1.0"]))
# Before lmcolor's, which may return: a new strip starts with no vertices kept.
_add_hook("glBegin", "if (hgl_tm) hgl_tm_begin();", first=True)

# ... and these after a state query has its answer: an index context answers
# for its index state, which the host does not have.
GUEST_AFTER = {
"glGetBooleanv": "if (hgl_index_mode) hgl_index_getb(pname, data);",
"glGetIntegerv": "if (hgl_index_mode) hgl_index_geti(pname, data);",
"glGetFloatv": "if (hgl_index_mode) hgl_index_getf(pname, data);",
"glGetDoublev": "if (hgl_index_mode) hgl_index_getd(pname, data);",
# The program's lighting back on after a primitive drawn unlit (hgl_lmc).
"glEnd": "if (hgl_lmc_off) hgl_lmc_after_end();",
}

# The encoders also report what memory the host will read: hgl_ref for a
Expand Down
Loading