Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build a tiny RISC virtual machine which can interpret and execute GDExtensions #10071

Open
fire opened this issue Jun 29, 2024 · 10 comments
Open

Comments

@fire
Copy link
Member

fire commented Jun 29, 2024

Describe the project you are working on

V-Sekai is a self-hostable MIT open source software stack built with Godot Engine 4. This project aims to provide a robust and flexible platform for game development.

Describe the problem or limitation you are having in your project

The main challenge we're facing is the inefficiency of compiling gdextension for multiple platform variants. Running a custom engine isn't feasible due to lack of adoption. We want more efficient and flexible ways to handle gdextension binaries. Additionally, we're interested in exploring the possibility of players distributing riscv binaries as user-generated scripts inside of godot scenes. As part of our future work, we plan to convert gdscript bytecode via string templating the bytecode as c and compile it with the TCC c compiler.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

To address these issues, we propose building a tiny RISC virtual machine capable of interpreting and executing GDExtensions. The entire gdextension API would be wrapped and compiled as RISCV binaries. These binaries would function like shared libraries via librisc emulation, either as an interpreter or a register machine. An interpreter would allow us to maintain the fast developer iteration times that Godot Engine is known for, while an ahead-of-time compiled riscv binary would offer greater efficiency. We have already implemented instruction count limits.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Our approach involves using libriscv's vmcall to call into the riscv gdextension binary and exchange data. Here are some resources that will aid in this process:

  1. libriscv VM Call Documentation - Detailed documentation on making function calls into the VM guest.
  2. tcc
  3. Godot Orchestrator
  4. @shakesoda has provided an implementation of riscv processors in Godot Engine via zig language as a reference.

If this enhancement will not be used often, can it be worked around with a few lines of script?

The alternative to using compiled code is slower gdscript or utilizing the godot orchestrator. However, these options may not provide the same level of efficiency and flexibility that our proposed solution offers.

Is there a reason why this should be core and not an add-on in the asset library?

While this could potentially be developed as an addon, we are currently tracking the proposal in godot-proposals for better visibility and collaboration. More information can be found at godot-riscv.

@fire fire changed the title Load gdextension modules as RISCV binaries on the full set of Godot Engine platforms. Load gdextension modules as RISCV binaries on all platforms. Jun 29, 2024
@fire
Copy link
Member Author

fire commented Jun 29, 2024

Thanks @fwsGonzo for assisting me with my questions.

@octanejohn
Copy link

1 doesnt web need wasm output anyway and most langs support wasm, gdscript could target it too instead building two paths

2 i know wasm doesnt work with how godot operates on non-web but with libgodot and hacking the wamr runtime separating scripting from inside godot it could work?
example gdscript(any lang)>wamr<>libgodot>gd extention game instead of gdscript>godot game>wamr

3 is libriscv an ir like mlir llvm, what is its goal?

@fire
Copy link
Member Author

fire commented Jun 29, 2024

  1. @octanejohn My conversation from my friend who worked on scripting for https://github.com/matrix-org/thirdroom mentioned they used a wasm quickjs to execute user scripts due to browser security.

If we've already got gdscript in wasm, we can already use it. Like there's no benefit.

If we can compile gdscript (feature doesn't exist) then we can also compile that to riscv (feature doesn't exist for basically the cost of a gcc compiler invoke).

  1. We spent years trying to get wasm wamr to work and it was too difficult.

  2. riscv is an instruction set standard like amd64 or arm64.

@octanejohn
Copy link

2 the wasm to godot i seen it wasnt with libgodot but if its easier and works with consoles no problem
3 so riscv isa is used like a low level intermediate representation, cool

@fire
Copy link
Member Author

fire commented Jun 30, 2024

fwsGonzo/libriscv#174

Adds support for embedded sandboxed code. This would allow platforms without support for dynamic linking to ship with full binary translation performance. Essentially, this means that the code can be executed directly without needing to be linked at runtime, which can improve performance.

This could potentially be beneficial for loading gdextension modules as it could speed up their execution.

@fire
Copy link
Member Author

fire commented Jun 30, 2024

fwsGonzo/godot-riscv#1

We discussed creating a proof-of-concept plan to validate the general idea.

  1. Implement shared object loading, verify able to fetch address of dynamically loaded functions
  2. Verify shared object works with binary translation
  3. Output embeddable C code for shared object
  4. Verify embeddable C code works. Eg. run it on Windows.

Edited:

So 3 and 4 relates to fwsGonzo/libriscv#174

Edited:

1 and 2 are also completed.

Edited:

Shared executables are implemented, but not loading a specific symbol

Edited:

Shared libraries are implemented, but crashing on a jump to a garbage location.

@fire
Copy link
Member Author

fire commented Jun 30, 2024

Since we can now load shared executables the next step is to load and execute a hello world function call with a shared object.

fwsGonzo/libriscv#175 (comment)

@JosephCatrambone
Copy link

There may be a few folks who, like me, misread this ticket slightly. I was thinking initially, "This is adding RISCV as a compile target for Godot extensions. If that is the case, why not add WASM as a target VM?"

This proposal is not that.

This proposal is, "Let us build a very tiny RISC virtual machine which can interpret and execute GDExtensions not targeted for it."
That's a much more interesting prospect in my mind, especially if it's safe and performant. I very much like the idea that it might eventually become a bytecode for GDScript, too.

@fire fire changed the title Load gdextension modules as RISCV binaries on all platforms. Build a tiny RISC virtual machine which can interpret and execute GDExtensions not targeted for it Jun 30, 2024
@fire fire changed the title Build a tiny RISC virtual machine which can interpret and execute GDExtensions not targeted for it Build a tiny RISC virtual machine which can interpret and execute GDExtensions targeted for it instead of the native platform Jun 30, 2024
@fire fire changed the title Build a tiny RISC virtual machine which can interpret and execute GDExtensions targeted for it instead of the native platform Build a tiny RISC virtual machine which can interpret and execute GDExtensions Jun 30, 2024
@fire
Copy link
Member Author

fire commented Jun 30, 2024

We're working in @fwsGonzo 's discord https://discord.gg/ExhqfFMCDz feel free to join or discuss building a tiny RISC virtual machine which can interpret and execute GDExtensions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants