From 71a72e94ed5b6441928e8ed5bb7f55e0124682c1 Mon Sep 17 00:00:00 2001 From: atomchild411 <143453386+atomchild411@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:09:20 -0800 Subject: [PATCH 1/4] iris-hostgl: IMPACT's border clamp and multi-buffer extensions; glshim hooks for SGI's IRIS GL GL_SGIS_texture_border_clamp (its GL_CLAMP_TO_BORDER_SGIS is core GL_CLAMP_TO_BORDER) and GL_SGIX_texture_multi_buffer (a hint the guest library takes) join the extension list, so every extension IMPACT names is there but GL_SGIX_list_priority. The generator's guest hooks gain glReadPixels(GL_COLOR_INDEX) in index contexts, the multi-buffer hint, and lmcolor(LMC_COLOR) for SGI's IRIS GL (colour/normal last, a glBegin held to its first vertex, lighting back at glEnd). Encoders and the decoder are otherwise unchanged. Co-Authored-By: Claude Opus 5.5 --- iris-hostgl/src/ext.rs | 7 ++++++- iris-hostgl/tools/glshim.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/iris-hostgl/src/ext.rs b/iris-hostgl/src/ext.rs index 54f09f084..d48e7bffb 100644 --- a/iris-hostgl/src/ext.rs +++ b/iris-hostgl/src/ext.rs @@ -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. diff --git a/iris-hostgl/tools/glshim.py b/iris-hostgl/tools/glshim.py index 291800a53..4426f8482 100644 --- a/iris-hostgl/tools/glshim.py +++ b/iris-hostgl/tools/glshim.py @@ -103,8 +103,30 @@ "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;", + # 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): +# which of a colour and a normal came last, the program's GL_LIGHTING, and a +# glBegin held until its first vertex while the mode is on. +GUEST_HOOKS.update({ + **{f"glColor{n}{t}{v}": "hgl_lmc_colour_last = 1;" + for n in ("3", "4") for t in ("b", "d", "f", "i", "s", "ub", "ui", "us") for v in ("", "v")}, + **{f"glNormal3{t}{v}": "hgl_lmc_colour_last = 0;" + for t in ("b", "d", "f", "i", "s") for v in ("", "v")}, + **{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);", +}) + # ... 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 = { @@ -112,6 +134,8 @@ "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 From 50834c90220198906ba9490b00bb532762ede699 Mon Sep 17 00:00:00 2001 From: atomchild411 <143453386+atomchild411@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:47:15 -0800 Subject: [PATCH 2/4] iris-hostgl: glshim hook for glDrawPixels(GL_COLOR_INDEX) in colour-index contexts The guest library encodes an index image itself (hgl_draw_index); the host's RGBA GL would turn it into index 0 through its pixel maps. Co-Authored-By: Claude Opus 5.5 --- iris-hostgl/tools/glshim.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iris-hostgl/tools/glshim.py b/iris-hostgl/tools/glshim.py index 4426f8482..31d7fce75 100644 --- a/iris-hostgl/tools/glshim.py +++ b/iris-hostgl/tools/glshim.py @@ -107,6 +107,9 @@ # 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; }", } From 66f936ec699333e906e5d1691bc2d79a3ee03d0d Mon Sep 17 00:00:00 2001 From: atomchild411 <143453386+atomchild411@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:34:19 -0800 Subject: [PATCH 3/4] iris-hostgl: glshim hooks for IRIS GL's swaptmesh in the guest library SGI's IRIS GL (IGLOO) draws a triangle mesh as a GL_TRIANGLE_STRIP and asks SGI's libGL for each swaptmesh through glIglooInterfaceSGIX. The guest library does the swap by sending the older of the last two vertices again (hgl_tm in its glshim_rt.c); these hooks keep, inside a mesh, each vertex with the normal, colour and texture coordinate it was sent with, integers normalized as OpenGL does, and start each strip empty. Co-Authored-By: Claude Opus 5.5 --- iris-hostgl/tools/glshim.py | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/iris-hostgl/tools/glshim.py b/iris-hostgl/tools/glshim.py index 31d7fce75..d7561b662 100644 --- a/iris-hostgl/tools/glshim.py +++ b/iris-hostgl/tools/glshim.py @@ -130,6 +130,58 @@ "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 = { From ee565a497cc4755785863cee414aec8c2cc321db Mon Sep 17 00:00:00 2001 From: atomchild411 <143453386+atomchild411@users.noreply.github.com> Date: Fri, 16 Oct 2026 23:05:37 -0800 Subject: [PATCH 4/4] iris-hostgl: lmcolor's colour-or-normal comes from IGLOO, not glColor/glNormal hooks SGI's IRIS GL says itself which of a colour and a normal came last (glIglooInterfaceSGIX 0x81A1, COLORNORMAL), and IMPACT's libGL switches its lighting mode on that flag alone. The guest library now does the same, so the hooks that watched every glColor and glNormal go; IGLOO's own glColor calls (it sends the colour again when lmcolor changes) no longer count as the program's. Co-Authored-By: Claude Opus 5.5 --- iris-hostgl/tools/glshim.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/iris-hostgl/tools/glshim.py b/iris-hostgl/tools/glshim.py index d7561b662..c5bf10f72 100644 --- a/iris-hostgl/tools/glshim.py +++ b/iris-hostgl/tools/glshim.py @@ -115,13 +115,9 @@ } # lmcolor(LMC_COLOR) for SGI's IRIS GL (hgl_lmc in the guest's glshim_rt.c): -# which of a colour and a normal came last, the program's GL_LIGHTING, and a -# glBegin held until its first vertex while the mode is on. +# 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"glColor{n}{t}{v}": "hgl_lmc_colour_last = 1;" - for n in ("3", "4") for t in ("b", "d", "f", "i", "s", "ub", "ui", "us") for v in ("", "v")}, - **{f"glNormal3{t}{v}": "hgl_lmc_colour_last = 0;" - for t in ("b", "d", "f", "i", "s") for v in ("", "v")}, **{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;",