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
8 changes: 8 additions & 0 deletions iris-hostgl/src/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2416,9 +2416,11 @@ pub fn run(x: &mut Exec, op: usize, c: &[u8]) -> Option<u64> {
let c1 = get_count(a0 as u32);
let n1 = x.count(c1)?;
let mut o1 = vec![0 as u8; n1.max(1) + 16];
if !x.color_matrix_query(a0, &mut o1) {
let f = x.func(151)?;
let g: extern "C" fn(u32, *mut u8) = unsafe { std::mem::transmute(f) };
g(a0, o1.as_mut_ptr());
}
x.get_limit(a0, &mut o1);
x.put::<u8>(a1, &o1[..n1])?;
x.image_done();
Expand Down Expand Up @@ -2620,9 +2622,11 @@ pub fn run(x: &mut Exec, op: usize, c: &[u8]) -> Option<u64> {
let c1 = get_count(a0 as u32);
let n1 = x.count(c1)?;
let mut o1 = vec![0 as f64; n1.max(1) + 16];
if !x.color_matrix_query(a0, &mut o1) {
let f = x.func(166)?;
let g: extern "C" fn(u32, *mut f64) = unsafe { std::mem::transmute(f) };
g(a0, o1.as_mut_ptr());
}
x.get_limit(a0, &mut o1);
x.put::<f64>(a1, &o1[..n1])?;
x.image_done();
Expand All @@ -2637,9 +2641,11 @@ pub fn run(x: &mut Exec, op: usize, c: &[u8]) -> Option<u64> {
let c1 = get_count(a0 as u32);
let n1 = x.count(c1)?;
let mut o1 = vec![0 as f32; n1.max(1) + 16];
if !x.color_matrix_query(a0, &mut o1) {
let f = x.func(168)?;
let g: extern "C" fn(u32, *mut f32) = unsafe { std::mem::transmute(f) };
g(a0, o1.as_mut_ptr());
}
x.get_limit(a0, &mut o1);
x.put::<f32>(a1, &o1[..n1])?;
x.image_done();
Expand Down Expand Up @@ -2742,9 +2748,11 @@ pub fn run(x: &mut Exec, op: usize, c: &[u8]) -> Option<u64> {
let c1 = get_count(a0 as u32);
let n1 = x.count(c1)?;
let mut o1 = vec![0 as i32; n1.max(1) + 16];
if !x.color_matrix_query(a0, &mut o1) {
let f = x.func(176)?;
let g: extern "C" fn(u32, *mut i32) = unsafe { std::mem::transmute(f) };
g(a0, o1.as_mut_ptr());
}
x.get_limit(a0, &mut o1);
x.put::<i32>(a1, &o1[..n1])?;
x.image_done();
Expand Down
37 changes: 37 additions & 0 deletions iris-hostgl/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,43 @@ impl<'a> Exec<'a> {
/// fixed-function emulation (`emul`) is written for the units we exercise;
/// 8 is far above what IRIX-era software asks for (Quake III wants 2), and
/// a ceiling is easier to raise later than a wrong answer is to find.
/// SGI_color_matrix's state, answered here when the host GL has no
/// colour matrix: Mesa's compatibility profile has no ARB_imaging, so it
/// refused these queries with GL_INVALID_ENUM and left the answer 0.
/// SGI's IRIS GL (IGLOO) asks for GL_MAX_COLOR_MATRIX_STACK_DEPTH when it
/// sets up a window, sizes a stack from it, and crashed on 0: on a Linux
/// host every IRIS GL program that asked for a stencil buffer died in
/// gconfig(). The answers are IMPACT's -- a stack of 2, 1 deep, holding
/// the identity -- and no error is raised. True when answered here.
pub fn color_matrix_query<T: GetValue>(&mut self, pname: u32, out: &mut [T]) -> bool {
const GL_COLOR_MATRIX: u32 = 0x80B1;
const GL_COLOR_MATRIX_STACK_DEPTH: u32 = 0x80B2;
const GL_MAX_COLOR_MATRIX_STACK_DEPTH: u32 = 0x80B3;
if !(GL_COLOR_MATRIX..=GL_MAX_COLOR_MATRIX_STACK_DEPTH).contains(&pname)
|| !self.backend.lookup("glColorTable").is_null()
{
return false;
}
match pname {
GL_COLOR_MATRIX => {
for (i, v) in out.iter_mut().take(16).enumerate() {
*v = T::from_i64((i % 5 == 0) as i64);
}
}
GL_COLOR_MATRIX_STACK_DEPTH => {
if let Some(v) = out.first_mut() {
*v = T::from_i64(1);
}
}
_ => {
if let Some(v) = out.first_mut() {
*v = T::from_i64(2);
}
}
}
true
}

pub fn get_limit<T: GetValue>(&mut self, pname: u32, out: &mut [T]) {
// The accumulation buffer is this library's (accum.rs), not the
// host's, which has none to report.
Expand Down
18 changes: 18 additions & 0 deletions iris-hostgl/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1734,3 +1734,21 @@ fn texture_internal_format_is_answered_as_the_program_gave_it() {
assert_eq!(v(0), 0x1908, "the proxy: GL_RGBA, as asked");
assert_eq!(v(4), 3, "the texture: 3, as given");
}

/// SGI_color_matrix's limits answer as IMPACT's do on any host, and asking
/// raises no error: on a host without a colour matrix (Mesa) the answer was
/// 0 with GL_INVALID_ENUM, and SGI's IRIS GL crashed sizing its stack from it.
#[test]
fn color_matrix_limits_are_answered_and_raise_no_error() {
let mut g = Guest::new(512);
g.context(0x0040_000f, 16, 16);
let out = g.mem.alloc(16 * 4, 0);
let mut e = Enc::default();
e.cmd("glGetIntegerv", &[V::I(0x80B3), V::A(out)]) // GL_MAX_COLOR_MATRIX_STACK_DEPTH
.cmd("glGetIntegerv", &[V::I(0x80B2), V::A(out + 4)]) // GL_COLOR_MATRIX_STACK_DEPTH
.cmd("glGetError", &[]);
assert_eq!(g.batch(&e.take()), Reply::Ok(0, 0), "no GL error from the queries");
let v = |i: u64| i32::from_be_bytes(g.mem.get(out + i, 4).try_into().unwrap());
assert!(v(0) >= 2, "a colour matrix stack of at least 2, as IMPACT's: {}", v(0));
assert_eq!(v(4), 1, "one deep");
}
7 changes: 7 additions & 0 deletions iris-hostgl/tools/glshim.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,13 @@ def gen_rust(api):
"glFogf": "x.fog(a0, &[a1])",
"glFogi": "x.fog(a0, &[a1 as f32])",
"glFogfv": "x.fog(a0, &v1)",
# SGI_color_matrix's state on a host without a colour matrix (Mesa's
# compatibility profile has no ARB_imaging): answered here, as IMPACT
# answers it, rather than refused (Exec::color_matrix_query).
"glGetBooleanv": "x.color_matrix_query(a0, &mut o1)",
"glGetIntegerv": "x.color_matrix_query(a0, &mut o1)",
"glGetFloatv": "x.color_matrix_query(a0, &mut o1)",
"glGetDoublev": "x.color_matrix_query(a0, &mut o1)",
}

# Calls that read the framebuffer: a multisampled drawable is resolved first.
Expand Down
Loading