Skip to content

Conversation

Vipitis
Copy link
Contributor

@Vipitis Vipitis commented Sep 27, 2025

new weekend, new project...

I think there is two options to get wgpu-py into the browser: compile wgpu-native for wasm and package that, or call the js backend directly. I run into compilation errors with the rust code, so gave up there... but:

basically autocompleted my way through errors to see what kind of patterns are needed... everything around moving data requires more effort. While pyodide provides some functions, they feel buggy and unpredictable.
It is likely possible to codegen the vast majority of this and then fix up all the api diff - might get to that over the next few days.
structs have potential to make this easier.

I changed some of the examples to auto layout since I couldn't get .create_bindgroup_layout() to work - and you don't need it with auto layout.

works with pygfx/rendercanvas#115
couldn't get the cube example to work just yet, but triangle does - so the potential is there
image

more to come

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 29, 2025

there are were many headaches around the type conversion which aren't well documented... but I got to the cube in the end.
Haven't looked at any code gen approach as there is quite a few specialties like when it's okay to use keywords when calling the js function. For exmaple:

self._internal.getMappedRange(offset=js_offset, size=data.nbytes)

vs

self._internal.getMappedRange(0, size)

And the error you get is about not of type unsigned long long because these function parameters are GPUSize64 which lead me down a rabbit hole of using BigInt - and now I am not sure if that is required anymore.
Or when your dict contains the key "type" it accesses dict on the js side, not the value...
For anyone else giving this a try or making their branch from here - the comments will be all over the place and likely contradict themselves.

browser_cube.mp4

I will hopefully find some more time this coming week to continue and maybe get some more interesting examples to run (pygfx?/fastplotlib?).

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 29, 2025

super exciting to get imgui working with a few tweaks

imgui_example.mp4

cc @pthom thanks a lot for your article I read a few weeks ago, that motivated me to give it a try here!

@pthom
Copy link
Contributor

pthom commented Sep 29, 2025

@Vipitis : many thanks for the info, that looks very promising. Please keep me in the loop!

@almarklein
Copy link
Member

I was expecting codegen to come a long way here. The codegen knows when the arguments of a function were actually wrapped in a dict in IDL, so we can generate the code to reconstruct the dict before passing it to the JS WebGPU API call.

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 29, 2025

I also think that codegen can do a lot, I just need to give it a try. The to_js method has a few more arguments to make use of, for example dict_converter which sounds like solves some problems. The custom accessor currently has two functions: access the ._internal object and replace dict/struct keys with camelCase. However it overwrites the default dict conversion.
It can likely also do the data conversion and more. So the whole API might look like the following which should be trivial to codegen.

def some_function(self, *args, **kwargs):
    js_args = to_js(args, eager_converter=js_acccessor)
    js_kwrags = to_js(kwargs, eager_converter=js_accessor, dict_converter=Object.from_entries)
    self._internal.someFunction(*js_args, js_kwargs)

@almarklein
Copy link
Member

Whatever way this goes, what I care most about, is that when the IDL changes for a certain method, it will place some FIXME comment in the code for the JS backend, so that we won't forget to update that method there.

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

Successfully merging this pull request may close these issues.

3 participants