implements PLN-0076 render capability split
This commit is contained in:
parent
c3396f5a61
commit
7c35edcb84
@ -286,6 +286,9 @@ pub enum Capability {
|
|||||||
None,
|
None,
|
||||||
System,
|
System,
|
||||||
Gfx,
|
Gfx,
|
||||||
|
Composer,
|
||||||
|
Gfx2d,
|
||||||
|
Gfxui,
|
||||||
Audio,
|
Audio,
|
||||||
Fs,
|
Fs,
|
||||||
Log,
|
Log,
|
||||||
|
|||||||
@ -117,6 +117,9 @@ fn normalize_capabilities(capabilities: &[Capability]) -> Result<CapFlags, Cartr
|
|||||||
Capability::None => caps::NONE,
|
Capability::None => caps::NONE,
|
||||||
Capability::System => caps::SYSTEM,
|
Capability::System => caps::SYSTEM,
|
||||||
Capability::Gfx => caps::GFX,
|
Capability::Gfx => caps::GFX,
|
||||||
|
Capability::Composer => caps::COMPOSER,
|
||||||
|
Capability::Gfx2d => caps::GFX2D,
|
||||||
|
Capability::Gfxui => caps::GFXUI,
|
||||||
Capability::Audio => caps::AUDIO,
|
Capability::Audio => caps::AUDIO,
|
||||||
Capability::Fs => caps::FS,
|
Capability::Fs => caps::FS,
|
||||||
Capability::Log => caps::LOG,
|
Capability::Log => caps::LOG,
|
||||||
|
|||||||
@ -18,7 +18,7 @@ pub use resolver::{
|
|||||||
///
|
///
|
||||||
/// Each Syscall has a unique 32-bit ID. The IDs are grouped by category:
|
/// Each Syscall has a unique 32-bit ID. The IDs are grouped by category:
|
||||||
/// - **0x0xxx**: System & OS Control
|
/// - **0x0xxx**: System & OS Control
|
||||||
/// - **0x1xxx**: Graphics (GFX)
|
/// - **0x1xxx**: Game 2D primitives (`gfx2d`) and Shell UI primitives (`gfxui`)
|
||||||
/// - **0x11xx**: Frame Composer orchestration
|
/// - **0x11xx**: Frame Composer orchestration
|
||||||
/// - **0x2xxx**: Reserved for legacy input syscalls (disabled for v1 VM-owned input)
|
/// - **0x2xxx**: Reserved for legacy input syscalls (disabled for v1 VM-owned input)
|
||||||
/// - **0x3xxx**: Audio (PCM & Mixing)
|
/// - **0x3xxx**: Audio (PCM & Mixing)
|
||||||
@ -37,6 +37,13 @@ pub enum Syscall {
|
|||||||
GfxDrawDisc = 0x1005,
|
GfxDrawDisc = 0x1005,
|
||||||
GfxDrawSquare = 0x1006,
|
GfxDrawSquare = 0x1006,
|
||||||
GfxDrawText = 0x1008,
|
GfxDrawText = 0x1008,
|
||||||
|
GfxUiClear = 0x1201,
|
||||||
|
GfxUiFillRect = 0x1202,
|
||||||
|
GfxUiDrawLine = 0x1203,
|
||||||
|
GfxUiDrawCircle = 0x1204,
|
||||||
|
GfxUiDrawDisc = 0x1205,
|
||||||
|
GfxUiDrawSquare = 0x1206,
|
||||||
|
GfxUiDrawText = 0x1208,
|
||||||
ComposerBindScene = 0x1101,
|
ComposerBindScene = 0x1101,
|
||||||
ComposerUnbindScene = 0x1102,
|
ComposerUnbindScene = 0x1102,
|
||||||
ComposerSetCamera = 0x1103,
|
ComposerSetCamera = 0x1103,
|
||||||
|
|||||||
@ -2,10 +2,13 @@ use super::CapFlags;
|
|||||||
|
|
||||||
pub const NONE: CapFlags = 0;
|
pub const NONE: CapFlags = 0;
|
||||||
pub const SYSTEM: CapFlags = 1 << 0;
|
pub const SYSTEM: CapFlags = 1 << 0;
|
||||||
pub const GFX: CapFlags = 1 << 1;
|
pub const COMPOSER: CapFlags = 1 << 1;
|
||||||
pub const AUDIO: CapFlags = 1 << 2;
|
pub const AUDIO: CapFlags = 1 << 2;
|
||||||
pub const FS: CapFlags = 1 << 3;
|
pub const FS: CapFlags = 1 << 3;
|
||||||
pub const LOG: CapFlags = 1 << 4;
|
pub const LOG: CapFlags = 1 << 4;
|
||||||
pub const ASSET: CapFlags = 1 << 5;
|
pub const ASSET: CapFlags = 1 << 5;
|
||||||
pub const BANK: CapFlags = 1 << 6;
|
pub const BANK: CapFlags = 1 << 6;
|
||||||
pub const ALL: CapFlags = SYSTEM | GFX | AUDIO | FS | LOG | ASSET | BANK;
|
pub const GFX2D: CapFlags = 1 << 7;
|
||||||
|
pub const GFXUI: CapFlags = 1 << 8;
|
||||||
|
pub const GFX: CapFlags = COMPOSER | GFX2D;
|
||||||
|
pub const ALL: CapFlags = SYSTEM | COMPOSER | AUDIO | FS | LOG | ASSET | BANK | GFX2D | GFXUI;
|
||||||
|
|||||||
@ -4,19 +4,19 @@ pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
|
|||||||
SyscallRegistryEntry::builder(Syscall::ComposerBindScene, "composer", "bind_scene")
|
SyscallRegistryEntry::builder(Syscall::ComposerBindScene, "composer", "bind_scene")
|
||||||
.args(1)
|
.args(1)
|
||||||
.rets(1)
|
.rets(1)
|
||||||
.caps(caps::GFX)
|
.caps(caps::COMPOSER)
|
||||||
.cost(5),
|
.cost(5),
|
||||||
SyscallRegistryEntry::builder(Syscall::ComposerUnbindScene, "composer", "unbind_scene")
|
SyscallRegistryEntry::builder(Syscall::ComposerUnbindScene, "composer", "unbind_scene")
|
||||||
.rets(1)
|
.rets(1)
|
||||||
.caps(caps::GFX)
|
.caps(caps::COMPOSER)
|
||||||
.cost(2),
|
.cost(2),
|
||||||
SyscallRegistryEntry::builder(Syscall::ComposerSetCamera, "composer", "set_camera")
|
SyscallRegistryEntry::builder(Syscall::ComposerSetCamera, "composer", "set_camera")
|
||||||
.args(2)
|
.args(2)
|
||||||
.caps(caps::GFX)
|
.caps(caps::COMPOSER)
|
||||||
.cost(2),
|
.cost(2),
|
||||||
SyscallRegistryEntry::builder(Syscall::ComposerEmitSprite, "composer", "emit_sprite")
|
SyscallRegistryEntry::builder(Syscall::ComposerEmitSprite, "composer", "emit_sprite")
|
||||||
.args(9)
|
.args(9)
|
||||||
.rets(1)
|
.rets(1)
|
||||||
.caps(caps::GFX)
|
.caps(caps::COMPOSER)
|
||||||
.cost(5),
|
.cost(5),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,32 +1,32 @@
|
|||||||
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
|
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
|
||||||
|
|
||||||
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
|
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxClear, "gfx", "clear")
|
SyscallRegistryEntry::builder(Syscall::GfxClear, "gfx2d", "clear")
|
||||||
.args(1)
|
.args(1)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(20),
|
.cost(20),
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxFillRect, "gfx", "fill_rect")
|
SyscallRegistryEntry::builder(Syscall::GfxFillRect, "gfx2d", "fill_rect")
|
||||||
.args(5)
|
.args(5)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(20),
|
.cost(20),
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxDrawLine, "gfx", "draw_line")
|
SyscallRegistryEntry::builder(Syscall::GfxDrawLine, "gfx2d", "draw_line")
|
||||||
.args(5)
|
.args(5)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(5),
|
.cost(5),
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxDrawCircle, "gfx", "draw_circle")
|
SyscallRegistryEntry::builder(Syscall::GfxDrawCircle, "gfx2d", "draw_circle")
|
||||||
.args(4)
|
.args(4)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(5),
|
.cost(5),
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxDrawDisc, "gfx", "draw_disc")
|
SyscallRegistryEntry::builder(Syscall::GfxDrawDisc, "gfx2d", "draw_disc")
|
||||||
.args(5)
|
.args(5)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(5),
|
.cost(5),
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxDrawSquare, "gfx", "draw_square")
|
SyscallRegistryEntry::builder(Syscall::GfxDrawSquare, "gfx2d", "draw_square")
|
||||||
.args(6)
|
.args(6)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(5),
|
.cost(5),
|
||||||
SyscallRegistryEntry::builder(Syscall::GfxDrawText, "gfx", "draw_text")
|
SyscallRegistryEntry::builder(Syscall::GfxDrawText, "gfx2d", "draw_text")
|
||||||
.args(4)
|
.args(4)
|
||||||
.caps(caps::GFX)
|
.caps(caps::GFX2D)
|
||||||
.cost(20),
|
.cost(20),
|
||||||
];
|
];
|
||||||
|
|||||||
32
crates/console/prometeu-hal/src/syscalls/domains/gfxui.rs
Normal file
32
crates/console/prometeu-hal/src/syscalls/domains/gfxui.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
|
||||||
|
|
||||||
|
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiClear, "gfxui", "clear")
|
||||||
|
.args(1)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(20),
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiFillRect, "gfxui", "fill_rect")
|
||||||
|
.args(5)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(20),
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiDrawLine, "gfxui", "draw_line")
|
||||||
|
.args(5)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(5),
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiDrawCircle, "gfxui", "draw_circle")
|
||||||
|
.args(4)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(5),
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiDrawDisc, "gfxui", "draw_disc")
|
||||||
|
.args(5)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(5),
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiDrawSquare, "gfxui", "draw_square")
|
||||||
|
.args(6)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(5),
|
||||||
|
SyscallRegistryEntry::builder(Syscall::GfxUiDrawText, "gfxui", "draw_text")
|
||||||
|
.args(4)
|
||||||
|
.caps(caps::GFXUI)
|
||||||
|
.cost(20),
|
||||||
|
];
|
||||||
@ -4,6 +4,7 @@ mod bank;
|
|||||||
mod composer;
|
mod composer;
|
||||||
mod fs;
|
mod fs;
|
||||||
mod gfx;
|
mod gfx;
|
||||||
|
mod gfxui;
|
||||||
mod log;
|
mod log;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ pub(crate) fn all_entries() -> impl Iterator<Item = &'static SyscallRegistryEntr
|
|||||||
system::ENTRIES
|
system::ENTRIES
|
||||||
.iter()
|
.iter()
|
||||||
.chain(gfx::ENTRIES.iter())
|
.chain(gfx::ENTRIES.iter())
|
||||||
|
.chain(gfxui::ENTRIES.iter())
|
||||||
.chain(composer::ENTRIES.iter())
|
.chain(composer::ENTRIES.iter())
|
||||||
.chain(audio::ENTRIES.iter())
|
.chain(audio::ENTRIES.iter())
|
||||||
.chain(fs::ENTRIES.iter())
|
.chain(fs::ENTRIES.iter())
|
||||||
|
|||||||
@ -21,6 +21,13 @@ impl Syscall {
|
|||||||
0x1005 => Some(Self::GfxDrawDisc),
|
0x1005 => Some(Self::GfxDrawDisc),
|
||||||
0x1006 => Some(Self::GfxDrawSquare),
|
0x1006 => Some(Self::GfxDrawSquare),
|
||||||
0x1008 => Some(Self::GfxDrawText),
|
0x1008 => Some(Self::GfxDrawText),
|
||||||
|
0x1201 => Some(Self::GfxUiClear),
|
||||||
|
0x1202 => Some(Self::GfxUiFillRect),
|
||||||
|
0x1203 => Some(Self::GfxUiDrawLine),
|
||||||
|
0x1204 => Some(Self::GfxUiDrawCircle),
|
||||||
|
0x1205 => Some(Self::GfxUiDrawDisc),
|
||||||
|
0x1206 => Some(Self::GfxUiDrawSquare),
|
||||||
|
0x1208 => Some(Self::GfxUiDrawText),
|
||||||
0x1101 => Some(Self::ComposerBindScene),
|
0x1101 => Some(Self::ComposerBindScene),
|
||||||
0x1102 => Some(Self::ComposerUnbindScene),
|
0x1102 => Some(Self::ComposerUnbindScene),
|
||||||
0x1103 => Some(Self::ComposerSetCamera),
|
0x1103 => Some(Self::ComposerSetCamera),
|
||||||
@ -70,6 +77,13 @@ impl Syscall {
|
|||||||
Self::GfxDrawDisc => "GfxDrawDisc",
|
Self::GfxDrawDisc => "GfxDrawDisc",
|
||||||
Self::GfxDrawSquare => "GfxDrawSquare",
|
Self::GfxDrawSquare => "GfxDrawSquare",
|
||||||
Self::GfxDrawText => "GfxDrawText",
|
Self::GfxDrawText => "GfxDrawText",
|
||||||
|
Self::GfxUiClear => "GfxUiClear",
|
||||||
|
Self::GfxUiFillRect => "GfxUiFillRect",
|
||||||
|
Self::GfxUiDrawLine => "GfxUiDrawLine",
|
||||||
|
Self::GfxUiDrawCircle => "GfxUiDrawCircle",
|
||||||
|
Self::GfxUiDrawDisc => "GfxUiDrawDisc",
|
||||||
|
Self::GfxUiDrawSquare => "GfxUiDrawSquare",
|
||||||
|
Self::GfxUiDrawText => "GfxUiDrawText",
|
||||||
Self::ComposerBindScene => "ComposerBindScene",
|
Self::ComposerBindScene => "ComposerBindScene",
|
||||||
Self::ComposerUnbindScene => "ComposerUnbindScene",
|
Self::ComposerUnbindScene => "ComposerUnbindScene",
|
||||||
Self::ComposerSetCamera => "ComposerSetCamera",
|
Self::ComposerSetCamera => "ComposerSetCamera",
|
||||||
|
|||||||
@ -39,23 +39,23 @@ fn every_syscall_has_metadata() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resolver_returns_expected_id_for_known_identity() {
|
fn resolver_returns_expected_id_for_known_identity() {
|
||||||
let id = resolve_syscall("gfx", "clear", 1).expect("known identity must resolve");
|
let id = resolve_syscall("gfx2d", "clear", 1).expect("known identity must resolve");
|
||||||
assert_eq!(id.id, 0x1001);
|
assert_eq!(id.id, 0x1001);
|
||||||
assert_eq!(id.meta.module, "gfx");
|
assert_eq!(id.meta.module, "gfx2d");
|
||||||
assert_eq!(id.meta.name, "clear");
|
assert_eq!(id.meta.name, "clear");
|
||||||
assert_eq!(id.meta.version, 1);
|
assert_eq!(id.meta.version, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resolver_rejects_unknown_identity() {
|
fn resolver_rejects_unknown_identity() {
|
||||||
let res = resolve_syscall("gfx", "nonexistent", 1);
|
let res = resolve_syscall("gfx2d", "nonexistent", 1);
|
||||||
assert!(res.is_none());
|
assert!(res.is_none());
|
||||||
|
|
||||||
let requested = [SyscallIdentity { module: "gfx", name: "nonexistent", version: 1 }];
|
let requested = [SyscallIdentity { module: "gfx2d", name: "nonexistent", version: 1 }];
|
||||||
let err = resolve_program_syscalls(&requested, 0).unwrap_err();
|
let err = resolve_program_syscalls(&requested, 0).unwrap_err();
|
||||||
match err {
|
match err {
|
||||||
LoadError::UnknownSyscall { module, name, version } => {
|
LoadError::UnknownSyscall { module, name, version } => {
|
||||||
assert_eq!(module, "gfx");
|
assert_eq!(module, "gfx2d");
|
||||||
assert_eq!(name, "nonexistent");
|
assert_eq!(name, "nonexistent");
|
||||||
assert_eq!(version, 1);
|
assert_eq!(version, 1);
|
||||||
}
|
}
|
||||||
@ -65,23 +65,23 @@ fn resolver_rejects_unknown_identity() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resolver_rejects_removed_legacy_gfx_set_sprite_identity() {
|
fn resolver_rejects_removed_legacy_gfx_set_sprite_identity() {
|
||||||
assert!(resolve_syscall("gfx", "set_sprite", 1).is_none());
|
assert!(resolve_syscall("gfx2d", "set_sprite", 1).is_none());
|
||||||
|
|
||||||
let requested = [SyscallIdentity { module: "gfx", name: "set_sprite", version: 1 }];
|
let requested = [SyscallIdentity { module: "gfx2d", name: "set_sprite", version: 1 }];
|
||||||
let err = resolve_program_syscalls(&requested, caps::ALL).unwrap_err();
|
let err = resolve_program_syscalls(&requested, caps::ALL).unwrap_err();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err,
|
err,
|
||||||
LoadError::UnknownSyscall { module: "gfx".into(), name: "set_sprite".into(), version: 1 }
|
LoadError::UnknownSyscall { module: "gfx2d".into(), name: "set_sprite".into(), version: 1 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resolver_enforces_capabilities() {
|
fn resolver_enforces_capabilities() {
|
||||||
let requested = [SyscallIdentity { module: "gfx", name: "clear", version: 1 }];
|
let requested = [SyscallIdentity { module: "gfx2d", name: "clear", version: 1 }];
|
||||||
let err = resolve_program_syscalls(&requested, 0).unwrap_err();
|
let err = resolve_program_syscalls(&requested, 0).unwrap_err();
|
||||||
match err {
|
match err {
|
||||||
LoadError::MissingCapability { required, provided, module, name, version } => {
|
LoadError::MissingCapability { required, provided, module, name, version } => {
|
||||||
assert_eq!(module, "gfx");
|
assert_eq!(module, "gfx2d");
|
||||||
assert_eq!(name, "clear");
|
assert_eq!(name, "clear");
|
||||||
assert_eq!(version, 1);
|
assert_eq!(version, 1);
|
||||||
assert_ne!(required, 0);
|
assert_ne!(required, 0);
|
||||||
@ -90,15 +90,30 @@ fn resolver_enforces_capabilities() {
|
|||||||
_ => panic!("expected MissingCapability error"),
|
_ => panic!("expected MissingCapability error"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let ok = resolve_program_syscalls(&requested, caps::GFX).expect("must resolve with caps");
|
let ok = resolve_program_syscalls(&requested, caps::GFX2D).expect("must resolve with caps");
|
||||||
assert_eq!(ok.len(), 1);
|
assert_eq!(ok.len(), 1);
|
||||||
assert_eq!(ok[0].id, 0x1001);
|
assert_eq!(ok[0].id, 0x1001);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resolver_exposes_split_render_capabilities() {
|
||||||
|
let composer = resolve_syscall("composer", "bind_scene", 1).expect("composer resolves");
|
||||||
|
assert_eq!(composer.meta.caps, caps::COMPOSER);
|
||||||
|
|
||||||
|
let gfx2d = resolve_syscall("gfx2d", "clear", 1).expect("gfx2d resolves");
|
||||||
|
assert_eq!(gfx2d.meta.caps, caps::GFX2D);
|
||||||
|
|
||||||
|
let gfxui = resolve_syscall("gfxui", "clear", 1).expect("gfxui resolves");
|
||||||
|
assert_eq!(gfxui.id, 0x1201);
|
||||||
|
assert_eq!(gfxui.meta.caps, caps::GFXUI);
|
||||||
|
|
||||||
|
assert!(resolve_syscall("gfx", "clear", 1).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn declared_resolver_returns_expected_id_for_known_identity() {
|
fn declared_resolver_returns_expected_id_for_known_identity() {
|
||||||
let declared = [prometeu_bytecode::SyscallDecl {
|
let declared = [prometeu_bytecode::SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -106,7 +121,7 @@ fn declared_resolver_returns_expected_id_for_known_identity() {
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
let ok =
|
let ok =
|
||||||
resolve_declared_program_syscalls(&declared, caps::GFX).expect("must resolve with ABI");
|
resolve_declared_program_syscalls(&declared, caps::GFX2D).expect("must resolve with ABI");
|
||||||
assert_eq!(ok.len(), 1);
|
assert_eq!(ok.len(), 1);
|
||||||
assert_eq!(ok[0].id, 0x1001);
|
assert_eq!(ok[0].id, 0x1001);
|
||||||
}
|
}
|
||||||
@ -114,18 +129,18 @@ fn declared_resolver_returns_expected_id_for_known_identity() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn declared_resolver_rejects_unknown_identity() {
|
fn declared_resolver_rejects_unknown_identity() {
|
||||||
let declared = [prometeu_bytecode::SyscallDecl {
|
let declared = [prometeu_bytecode::SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "nonexistent".into(),
|
name: "nonexistent".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
ret_slots: 0,
|
ret_slots: 0,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let err = resolve_declared_program_syscalls(&declared, caps::GFX).unwrap_err();
|
let err = resolve_declared_program_syscalls(&declared, caps::GFX2D).unwrap_err();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err,
|
err,
|
||||||
DeclaredLoadError::UnknownSyscall {
|
DeclaredLoadError::UnknownSyscall {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "nonexistent".into(),
|
name: "nonexistent".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
}
|
}
|
||||||
@ -135,7 +150,7 @@ fn declared_resolver_rejects_unknown_identity() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn declared_resolver_rejects_missing_capability() {
|
fn declared_resolver_rejects_missing_capability() {
|
||||||
let declared = [prometeu_bytecode::SyscallDecl {
|
let declared = [prometeu_bytecode::SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -146,9 +161,9 @@ fn declared_resolver_rejects_missing_capability() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
err,
|
err,
|
||||||
DeclaredLoadError::MissingCapability {
|
DeclaredLoadError::MissingCapability {
|
||||||
required: caps::GFX,
|
required: caps::GFX2D,
|
||||||
provided: caps::NONE,
|
provided: caps::NONE,
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
}
|
}
|
||||||
@ -158,18 +173,18 @@ fn declared_resolver_rejects_missing_capability() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn declared_resolver_rejects_abi_mismatch() {
|
fn declared_resolver_rejects_abi_mismatch() {
|
||||||
let declared = [prometeu_bytecode::SyscallDecl {
|
let declared = [prometeu_bytecode::SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_line".into(),
|
name: "draw_line".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 4,
|
arg_slots: 4,
|
||||||
ret_slots: 0,
|
ret_slots: 0,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let err = resolve_declared_program_syscalls(&declared, caps::GFX).unwrap_err();
|
let err = resolve_declared_program_syscalls(&declared, caps::GFX2D).unwrap_err();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err,
|
err,
|
||||||
DeclaredLoadError::AbiMismatch {
|
DeclaredLoadError::AbiMismatch {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_line".into(),
|
name: "draw_line".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
declared_arg_slots: 4,
|
declared_arg_slots: 4,
|
||||||
@ -386,7 +401,7 @@ fn declared_resolver_accepts_mixed_status_first_surface_as_a_single_module() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let resolved =
|
let resolved =
|
||||||
resolve_declared_program_syscalls(&declared, caps::GFX | caps::AUDIO | caps::ASSET)
|
resolve_declared_program_syscalls(&declared, caps::COMPOSER | caps::AUDIO | caps::ASSET)
|
||||||
.expect("mixed status-first surface must resolve together");
|
.expect("mixed status-first surface must resolve together");
|
||||||
|
|
||||||
assert_eq!(resolved.len(), declared.len());
|
assert_eq!(resolved.len(), declared.len());
|
||||||
|
|||||||
@ -188,6 +188,17 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().clear(color);
|
hw.gfx_mut().clear(color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiClear => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let color = self.get_color(expect_int(args, 0)?)?;
|
||||||
|
hw.gfx_mut().clear(color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::GfxFillRect => {
|
Syscall::GfxFillRect => {
|
||||||
let x = expect_int(args, 0)? as i32;
|
let x = expect_int(args, 0)? as i32;
|
||||||
let y = expect_int(args, 1)? as i32;
|
let y = expect_int(args, 1)? as i32;
|
||||||
@ -197,6 +208,21 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().fill_rect(x, y, w, h, color);
|
hw.gfx_mut().fill_rect(x, y, w, h, color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiFillRect => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let x = expect_int(args, 0)? as i32;
|
||||||
|
let y = expect_int(args, 1)? as i32;
|
||||||
|
let w = expect_int(args, 2)? as i32;
|
||||||
|
let h = expect_int(args, 3)? as i32;
|
||||||
|
let color = self.get_color(expect_int(args, 4)?)?;
|
||||||
|
hw.gfx_mut().fill_rect(x, y, w, h, color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::GfxDrawLine => {
|
Syscall::GfxDrawLine => {
|
||||||
let x1 = expect_int(args, 0)? as i32;
|
let x1 = expect_int(args, 0)? as i32;
|
||||||
let y1 = expect_int(args, 1)? as i32;
|
let y1 = expect_int(args, 1)? as i32;
|
||||||
@ -206,6 +232,21 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().draw_line(x1, y1, x2, y2, color);
|
hw.gfx_mut().draw_line(x1, y1, x2, y2, color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiDrawLine => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let x1 = expect_int(args, 0)? as i32;
|
||||||
|
let y1 = expect_int(args, 1)? as i32;
|
||||||
|
let x2 = expect_int(args, 2)? as i32;
|
||||||
|
let y2 = expect_int(args, 3)? as i32;
|
||||||
|
let color = self.get_color(expect_int(args, 4)?)?;
|
||||||
|
hw.gfx_mut().draw_line(x1, y1, x2, y2, color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::GfxDrawCircle => {
|
Syscall::GfxDrawCircle => {
|
||||||
let x = expect_int(args, 0)? as i32;
|
let x = expect_int(args, 0)? as i32;
|
||||||
let y = expect_int(args, 1)? as i32;
|
let y = expect_int(args, 1)? as i32;
|
||||||
@ -214,6 +255,20 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().draw_circle(x, y, r, color);
|
hw.gfx_mut().draw_circle(x, y, r, color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiDrawCircle => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let x = expect_int(args, 0)? as i32;
|
||||||
|
let y = expect_int(args, 1)? as i32;
|
||||||
|
let r = expect_int(args, 2)? as i32;
|
||||||
|
let color = self.get_color(expect_int(args, 3)?)?;
|
||||||
|
hw.gfx_mut().draw_circle(x, y, r, color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::GfxDrawDisc => {
|
Syscall::GfxDrawDisc => {
|
||||||
let x = expect_int(args, 0)? as i32;
|
let x = expect_int(args, 0)? as i32;
|
||||||
let y = expect_int(args, 1)? as i32;
|
let y = expect_int(args, 1)? as i32;
|
||||||
@ -223,6 +278,21 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().draw_disc(x, y, r, border_color, fill_color);
|
hw.gfx_mut().draw_disc(x, y, r, border_color, fill_color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiDrawDisc => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let x = expect_int(args, 0)? as i32;
|
||||||
|
let y = expect_int(args, 1)? as i32;
|
||||||
|
let r = expect_int(args, 2)? as i32;
|
||||||
|
let border_color = self.get_color(expect_int(args, 3)?)?;
|
||||||
|
let fill_color = self.get_color(expect_int(args, 4)?)?;
|
||||||
|
hw.gfx_mut().draw_disc(x, y, r, border_color, fill_color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::GfxDrawSquare => {
|
Syscall::GfxDrawSquare => {
|
||||||
let x = expect_int(args, 0)? as i32;
|
let x = expect_int(args, 0)? as i32;
|
||||||
let y = expect_int(args, 1)? as i32;
|
let y = expect_int(args, 1)? as i32;
|
||||||
@ -233,6 +303,22 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().draw_square(x, y, w, h, border_color, fill_color);
|
hw.gfx_mut().draw_square(x, y, w, h, border_color, fill_color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiDrawSquare => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let x = expect_int(args, 0)? as i32;
|
||||||
|
let y = expect_int(args, 1)? as i32;
|
||||||
|
let w = expect_int(args, 2)? as i32;
|
||||||
|
let h = expect_int(args, 3)? as i32;
|
||||||
|
let border_color = self.get_color(expect_int(args, 4)?)?;
|
||||||
|
let fill_color = self.get_color(expect_int(args, 5)?)?;
|
||||||
|
hw.gfx_mut().draw_square(x, y, w, h, border_color, fill_color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::GfxDrawText => {
|
Syscall::GfxDrawText => {
|
||||||
let x = expect_int(args, 0)? as i32;
|
let x = expect_int(args, 0)? as i32;
|
||||||
let y = expect_int(args, 1)? as i32;
|
let y = expect_int(args, 1)? as i32;
|
||||||
@ -241,6 +327,20 @@ impl NativeInterface for VmRuntimeHost<'_> {
|
|||||||
hw.gfx_mut().draw_text(x, y, &msg, color);
|
hw.gfx_mut().draw_text(x, y, &msg, color);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Syscall::GfxUiDrawText => {
|
||||||
|
if self.current_cartridge_app_mode != AppMode::Shell {
|
||||||
|
return Err(VmFault::Trap(
|
||||||
|
TRAP_INVALID_SYSCALL,
|
||||||
|
format!("{} is only available to the Shell profile", syscall.name()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let x = expect_int(args, 0)? as i32;
|
||||||
|
let y = expect_int(args, 1)? as i32;
|
||||||
|
let msg = expect_string(args, 2, "message")?;
|
||||||
|
let color = self.get_color(expect_int(args, 3)?)?;
|
||||||
|
hw.gfx_mut().draw_text(x, y, &msg, color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Syscall::ComposerBindScene => {
|
Syscall::ComposerBindScene => {
|
||||||
let scene_bank_id = match Self::int_arg_to_usize_status(expect_int(args, 0)?) {
|
let scene_bank_id = match Self::int_arg_to_usize_status(expect_int(args, 0)?) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
|
|||||||
@ -195,7 +195,7 @@ fn initialize_vm_applies_cartridge_capabilities_before_loader_resolution() {
|
|||||||
let program = serialized_single_function_module(
|
let program = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -221,7 +221,7 @@ fn initialize_vm_succeeds_when_cartridge_capabilities_cover_hostcalls() {
|
|||||||
let program = serialized_single_function_module(
|
let program = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -253,7 +253,7 @@ fn tick_returns_error_when_vm_ends_slice_with_trap() {
|
|||||||
let program = serialized_single_function_module(
|
let program = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -304,7 +304,7 @@ fn tick_system_profile_rejects_gfx_game_surface() {
|
|||||||
let program = serialized_single_function_module(
|
let program = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -388,6 +388,55 @@ fn tick_system_profile_rejects_composer_game_surface() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tick_game_profile_rejects_gfxui_shell_surface() {
|
||||||
|
let mut runtime = VirtualMachineRuntime::new(None);
|
||||||
|
let mut log_service = LogService::new(4096);
|
||||||
|
let mut fs = VirtualFS::new();
|
||||||
|
let mut fs_state = FsState::Unmounted;
|
||||||
|
let mut memcard = MemcardService::new();
|
||||||
|
let mut open_files: HashMap<u32, String> = HashMap::new();
|
||||||
|
let mut next_handle = 1;
|
||||||
|
let mut vm = VirtualMachine::default();
|
||||||
|
let mut hardware = Hardware::new();
|
||||||
|
let signals = InputSignals::default();
|
||||||
|
let code = assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
|
||||||
|
let program = serialized_single_function_module(
|
||||||
|
code,
|
||||||
|
vec![SyscallDecl {
|
||||||
|
module: "gfxui".into(),
|
||||||
|
name: "clear".into(),
|
||||||
|
version: 1,
|
||||||
|
arg_slots: 1,
|
||||||
|
ret_slots: 0,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
let cartridge = cartridge_with_program_and_mode(program, caps::GFXUI, AppMode::Game);
|
||||||
|
|
||||||
|
runtime.initialize_vm(&mut log_service, &mut vm, &cartridge).expect("runtime must initialize");
|
||||||
|
let report = runtime
|
||||||
|
.tick(
|
||||||
|
&mut log_service,
|
||||||
|
&mut fs,
|
||||||
|
&mut fs_state,
|
||||||
|
&mut memcard,
|
||||||
|
&mut open_files,
|
||||||
|
&mut next_handle,
|
||||||
|
&mut vm,
|
||||||
|
&signals,
|
||||||
|
&mut hardware,
|
||||||
|
)
|
||||||
|
.expect("game gfxui call must trap");
|
||||||
|
|
||||||
|
match report {
|
||||||
|
CrashReport::VmTrap { trap } => {
|
||||||
|
assert_eq!(trap.code, prometeu_bytecode::TRAP_INVALID_SYSCALL);
|
||||||
|
assert!(trap.message.contains("GfxUiClear is only available to the Shell profile"));
|
||||||
|
}
|
||||||
|
other => panic!("expected VmTrap crash report, got {:?}", other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tick_system_profile_rejects_bank_game_surface() {
|
fn tick_system_profile_rejects_bank_game_surface() {
|
||||||
let mut runtime = VirtualMachineRuntime::new(None);
|
let mut runtime = VirtualMachineRuntime::new(None);
|
||||||
@ -655,7 +704,7 @@ fn tick_draw_text_survives_no_scene_frame_path() {
|
|||||||
code,
|
code,
|
||||||
vec![ConstantPoolEntry::String("I".into())],
|
vec![ConstantPoolEntry::String("I".into())],
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_text".into(),
|
name: "draw_text".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 4,
|
arg_slots: 4,
|
||||||
@ -696,7 +745,7 @@ fn initialize_vm_success_clears_previous_crash_report() {
|
|||||||
let program = serialized_single_function_module(
|
let program = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -856,7 +905,7 @@ fn initialize_vm_failure_clears_previous_identity_and_handles() {
|
|||||||
let good_program = serialized_single_function_module(
|
let good_program = serialized_single_function_module(
|
||||||
assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble"),
|
assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble"),
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -878,7 +927,7 @@ fn initialize_vm_failure_clears_previous_identity_and_handles() {
|
|||||||
let bad_program = serialized_single_function_module(
|
let bad_program = serialized_single_function_module(
|
||||||
assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble"),
|
assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble"),
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
|
|||||||
@ -2707,7 +2707,7 @@ mod tests {
|
|||||||
let bytes = serialized_single_function_module(
|
let bytes = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -2733,7 +2733,7 @@ mod tests {
|
|||||||
let bytes = serialized_single_function_module(
|
let bytes = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -2765,14 +2765,14 @@ mod tests {
|
|||||||
code,
|
code,
|
||||||
vec![
|
vec![
|
||||||
SyscallDecl {
|
SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
ret_slots: 0,
|
ret_slots: 0,
|
||||||
},
|
},
|
||||||
SyscallDecl {
|
SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_text".into(),
|
name: "draw_text".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 4,
|
arg_slots: 4,
|
||||||
@ -2788,7 +2788,7 @@ mod tests {
|
|||||||
Err(VmInitError::LoaderPatchFailed(
|
Err(VmInitError::LoaderPatchFailed(
|
||||||
crate::vm_init_error::LoaderPatchError::UnusedSyscallDecl {
|
crate::vm_init_error::LoaderPatchError::UnusedSyscallDecl {
|
||||||
sysc_index: 1,
|
sysc_index: 1,
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_text".into(),
|
name: "draw_text".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
},
|
},
|
||||||
@ -2805,7 +2805,7 @@ mod tests {
|
|||||||
let bytes = serialized_single_function_module(
|
let bytes = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -2835,7 +2835,7 @@ mod tests {
|
|||||||
let bytes = serialized_single_function_module(
|
let bytes = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "missing".into(),
|
name: "missing".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 0,
|
arg_slots: 0,
|
||||||
@ -2850,7 +2850,7 @@ mod tests {
|
|||||||
Err(VmInitError::LoaderPatchFailed(
|
Err(VmInitError::LoaderPatchFailed(
|
||||||
crate::vm_init_error::LoaderPatchError::ResolveFailed(
|
crate::vm_init_error::LoaderPatchError::ResolveFailed(
|
||||||
prometeu_hal::syscalls::DeclaredLoadError::UnknownSyscall {
|
prometeu_hal::syscalls::DeclaredLoadError::UnknownSyscall {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "missing".into(),
|
name: "missing".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
},
|
},
|
||||||
@ -2868,7 +2868,7 @@ mod tests {
|
|||||||
let bytes = serialized_single_function_module(
|
let bytes = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
@ -2883,9 +2883,9 @@ mod tests {
|
|||||||
Err(VmInitError::LoaderPatchFailed(
|
Err(VmInitError::LoaderPatchFailed(
|
||||||
crate::vm_init_error::LoaderPatchError::ResolveFailed(
|
crate::vm_init_error::LoaderPatchError::ResolveFailed(
|
||||||
prometeu_hal::syscalls::DeclaredLoadError::MissingCapability {
|
prometeu_hal::syscalls::DeclaredLoadError::MissingCapability {
|
||||||
required: prometeu_hal::syscalls::caps::GFX,
|
required: prometeu_hal::syscalls::caps::GFX2D,
|
||||||
provided: prometeu_hal::syscalls::caps::NONE,
|
provided: prometeu_hal::syscalls::caps::NONE,
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
},
|
},
|
||||||
@ -2903,7 +2903,7 @@ mod tests {
|
|||||||
let bytes = serialized_single_function_module(
|
let bytes = serialized_single_function_module(
|
||||||
code,
|
code,
|
||||||
vec![SyscallDecl {
|
vec![SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_line".into(),
|
name: "draw_line".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 4,
|
arg_slots: 4,
|
||||||
@ -2918,7 +2918,7 @@ mod tests {
|
|||||||
Err(VmInitError::LoaderPatchFailed(
|
Err(VmInitError::LoaderPatchFailed(
|
||||||
crate::vm_init_error::LoaderPatchError::ResolveFailed(
|
crate::vm_init_error::LoaderPatchError::ResolveFailed(
|
||||||
prometeu_hal::syscalls::DeclaredLoadError::AbiMismatch {
|
prometeu_hal::syscalls::DeclaredLoadError::AbiMismatch {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_line".into(),
|
name: "draw_line".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
declared_arg_slots: 4,
|
declared_arg_slots: 4,
|
||||||
|
|||||||
@ -42,14 +42,14 @@ pub fn generate() -> Result<()> {
|
|||||||
let mut rom: Vec<u8> = Vec::new();
|
let mut rom: Vec<u8> = Vec::new();
|
||||||
let syscalls = vec![
|
let syscalls = vec![
|
||||||
SyscallDecl {
|
SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "clear".into(),
|
name: "clear".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 1,
|
arg_slots: 1,
|
||||||
ret_slots: 0,
|
ret_slots: 0,
|
||||||
},
|
},
|
||||||
SyscallDecl {
|
SyscallDecl {
|
||||||
module: "gfx".into(),
|
module: "gfx2d".into(),
|
||||||
name: "draw_text".into(),
|
name: "draw_text".into(),
|
||||||
version: 1,
|
version: 1,
|
||||||
arg_slots: 4,
|
arg_slots: 4,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":39,"AGD":39,"DEC":31,"PLN":87,"LSN":47,"CLSN":1}}
|
||||||
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
{"type":"discussion","id":"DSC-0038","status":"in_progress","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-05-25","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[{"id":"AGD-0038","file":"AGD-0038-renderframepacket-boundary-for-classic-2d-renderer.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25"}],"decisions":[{"id":"DEC-0030","file":"DEC-0030-logical-render-pipeline-command-boundary.md","status":"accepted","created_at":"2026-05-25","updated_at":"2026-05-25","ref_agenda":"AGD-0038"}],"plans":[{"id":"PLN-0073","file":"PLN-0073-render-contract-specs.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0074","file":"PLN-0074-hal-render-submission-types.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0075","file":"PLN-0075-rendermanager-core.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0076","file":"PLN-0076-capabilities-and-abi-domain-split.md","status":"done","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0077","file":"PLN-0077-composer-buffer-and-game2d-packet.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0078","file":"PLN-0078-classic2d-game-renderer-consumer.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0079","file":"PLN-0079-gfx2d-primitive-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0080","file":"PLN-0080-shell-ui-packet-and-gfxui-domain.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0081","file":"PLN-0081-shell-hub-migration.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0082","file":"PLN-0082-frame-publication-and-present-boundary.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0083","file":"PLN-0083-fade-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0084","file":"PLN-0084-host-debug-overlay-removal.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0085","file":"PLN-0085-pbs-stdlib-and-syscall-declarations.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]},{"id":"PLN-0086","file":"PLN-0086-end-to-end-render-boundary-validation.md","status":"open","created_at":"2026-05-25","updated_at":"2026-05-25","ref_decisions":["DEC-0030"]}],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"discussion/lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
id: PLN-0076
|
id: PLN-0076
|
||||||
ticket: render-frame-packet-boundary
|
ticket: render-frame-packet-boundary
|
||||||
title: Capabilities and ABI Domain Split
|
title: Capabilities and ABI Domain Split
|
||||||
status: open
|
status: done
|
||||||
created: 2026-05-25
|
created: 2026-05-25
|
||||||
ref_decisions: [DEC-0030]
|
ref_decisions: [DEC-0030]
|
||||||
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
tags: [gfx, renderer, runtime, frame-composer, architecture, ui, pipeline]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user