Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
/xgpuPublic

WebGPU (webgpu.h) Python bindings

License

NotificationsYou must be signed in to change notification settings

PyryM/xgpu

Repository files navigation

xgpu is an aggressively typed, red-squiggle-free Python bindingofwgpu-native, autogenerated fromthe upstream C headers.

Not 'production ready'.

Install

Wheels are built for Mac (x86 only), Windows, and Linux for Python 3.7+:

pip install xgpu

Motivation

Whyanother webgpu/wgpu_native binding whenwgpu-pyalready exists and is semi-mature?

  • Typing:xgpu takes full advantage of Python type annotations, enabling quality of lifefeatures like IDE autocomplete for enum values
  • Up to date:xgpu is 99% autogenerated from the headers, and aims to always be in sync withthe latestwgpu-native release
  • Performance:xgpu is substantially faster thanwgpu

Conventions/Philosophy

xgpu is a mostly 1-to-1 binding ofwebgpu.h (+wgpu.h fromwgpu-native).

General name conventions

xgpu largely tries to maintain the names fromwebgpu.h rather than localizingthem into Python's conventions.

  • Names keep their formatting fromwebgpu.h but loseWGPU prefixes:WGPUTextureSampleType ->TextureSampleType
  • Fields:WGPUAdapterProperties.vendorName ->AdapterProperties.vendorName
  • Member functions:wgpuDeviceHasFeature ->Device.hasFeature
  • Enum values:WGPUTextureUsage_CopySrc ->TextureUsage.CopySrc
    • Names invalid in Python are prefixed with "_":WGPUBufferUsage_None ->BufferUsage._None,WGPUTextureDimension_2D ->TextureDimension._2D

Struct constructors

webgpu.h requires constructing various structs, for exampleWGPUExtent3D. These can be created in two ways:

# Recommended: create explicit initialized struct (note lowercase name)extents=xgpu.extent3D(width=100,height=100,depthOrArrayLayers=1)# Alternative: create 0-initialized struct and then mutate valuesextents=xgpu.Extent3D()extents.width=100extents.height=100extents.depthOrArrayLayers=1

Member functions

As a C API,webgpu.h follows typical C convention for member functions, which is to definethem like:

uint32_twgpuTextureGetHeight(WGPUTexturetexture)

Inxgpu these become genuine member functions, e.g.,

classTexture:defgetHeight(self)->int

Array arguments / fields

Somewebgpu.h functions and structs take arrays using the convention of passing firstthe array item count, and then the array pointer, e.g.,

voidwgpuQueueSubmit(WGPUQueuequeue,size_tcommandCount,WGPUCommandBufferconst*commands)typedefstructWGPUPipelineLayoutDescriptor {// ...size_tbindGroupLayoutCount;WGPUBindGroupLayoutconst*bindGroupLayouts;}WGPUPipelineLayoutDescriptor;

These are translated to take lists:

classQueue:defsubmit(self,commands:List[CommandBuffer]])defpipelineLayoutDescriptor(*,bindGroupLayouts:List["BindGroupLayout"])

Enums and Flags

Enums are translated intoIntEnums:

mode=xgpu.AddressMode.MirrorRepeatprint(int(mode))# 2print(mode.name)# "MirrorRepeat"mode=xgpu.AddressMode(2)print(mode.name)# "ClampToEdge"

Some enums are meant to be ORed together into bitflags. These can be combinedin the natural way:

usage=xgpu.BufferUsage.MapRead|xgpu.BufferUsage.CopyDstprint(usage)# prints: 9

This works becauseIntEnums inherit all the int methods include bitwiseoperations; however, this discards the type information.A slightly more annoying but type-safer way is:

usage=xgpu.BufferUsage.MapRead.asflag()|xgpu.BufferUsage.CopyDstprint(usage)# prints: BufferUsage.MapRead | BufferUsage.CopyDst

You can also create typed flags from bare ints:

usage=xgpu.BufferUsageFlags(0b1001)print(usage)# prints: BufferUsage.MapRead | BufferUsage.CopyDst

You can test for a particular flag with the pythonin operator:

has_map_read=xgpu.BufferUsage.MapReadinmybuffer.getUsage()

Callbacks

Callbacks must be explicitly wrapped in the appropriate callback type:

defmy_adapter_cb(status:xgpu.RequestAdapterStatus,gotten:xgpu.Adapter,msg:str):print(f"Got adapter with msg:'{msg}', status:{status.name}")cb=xgpu.RequestAdapterCallback(my_adapter_cb)

Chained structs

Thewebgpu.h structure chaining convention is represented byChainedStruct, whoseconstructor takes a list ofChainable and automatically creates the linked chain.

shader_source="""..."""shader=device.createShaderModule(nextInChain=xgpu.ChainedStruct(      [xgpu.shaderModuleWGSLDescriptor(code=shader_source)]    ),hints=[],)

Byte buffers, void pointers

xgpu has two translations forvoid *:VoidPtr represents a pointer toopaque data (e.g., a window handle) whileDataPtr represents a pointerto asized data structure (e.g., texture data you want to upload).

For example,

# Note use of VoidPtr.NULL and VoidPtr.raw_castsurf_desc=xgpu.surfaceDescriptorFromWindowsHWND(hinstance=xgpu.VoidPtr.NULL,hwnd=xgpu.VoidPtr.raw_cast(self.window_handle),)# DataPtr.wrap can wrap anything supporting the 'buffer' interfacebytedata=bytearray(100)wrapped=xgpu.DataPtr.wrap(bytedata)queue.writeBuffer(buffer=some_buffer,bufferOffset=0,data=wrapped)# This includes numpy arraysmy_array=np.ones(100,dtype=np.float32)wrapped=xgpu.DataPtr.wrap(my_array)

Codegen/Local Build

You will needbun to run the codegen. Denomightwork but just go ahead and install bun. You will also need to haveruff and cffi installed in python (pip install ruff cffi).

Then:

python codegen/fetch_wgpu_bins.pybun codegen/generate.tscd xgpupython _build_ext.pycd ..pip install .

About

WebGPU (webgpu.h) Python bindings

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp