Skip to content

Commit

Permalink
Make canvas arg in request_adapter() optional (#415)
Browse files Browse the repository at this point in the history
* Make canvas arg in request_adapter optional

* Update examples and tests
  • Loading branch information
almarklein authored Nov 15, 2023
1 parent f701760 commit a88bd70
Show file tree
Hide file tree
Showing 11 changed files with 26 additions and 43 deletions.
2 changes: 1 addition & 1 deletion docs/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ you can obtain a device.

.. code-block:: py
adapter = wgpu.gpu.request_adapter(canvas=canvas, power_preference="high-performance")
adapter = wgpu.gpu.request_adapter(power_preference="high-performance")
device = adapter.request_device()
The ``wgpu.gpu`` object is the API entrypoint (:class:`wgpu.GPU`). It contains just a handful of functions,
Expand Down
2 changes: 1 addition & 1 deletion examples/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
canvas = WgpuCanvas(title="wgpu cube")

# Create a wgpu device
adapter = wgpu.gpu.request_adapter(canvas=canvas, power_preference="high-performance")
adapter = wgpu.gpu.request_adapter(power_preference="high-performance")
device = adapter.request_device()

# Prepare present context
Expand Down
8 changes: 2 additions & 6 deletions examples/triangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,14 @@

def main(canvas, power_preference="high-performance", limits=None):
"""Regular function to setup a viz on the given canvas."""
# Note: passing the canvas here can (oddly enough) prevent the
# adapter from being found. Seen with wx/Linux.
adapter = wgpu.gpu.request_adapter(canvas=None, power_preference=power_preference)
adapter = wgpu.gpu.request_adapter(power_preference=power_preference)
device = adapter.request_device(required_limits=limits)
return _main(canvas, device)


async def main_async(canvas):
"""Async function to setup a viz on the given canvas."""
adapter = await wgpu.gpu.request_adapter_async(
canvas=canvas, power_preference="high-performance"
)
adapter = await wgpu.gpu.request_adapter_async(power_preference="high-performance")
device = await adapter.request_device_async(required_limits={})
return _main(canvas, device)

Expand Down
8 changes: 2 additions & 6 deletions examples/triangle_glsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,14 @@

def main(canvas, power_preference="high-performance", limits=None):
"""Regular function to setup a viz on the given canvas."""
# Note: passing the canvas here can (oddly enough) prevent the
# adapter from being found. Seen with wx/Linux.
adapter = wgpu.gpu.request_adapter(canvas=None, power_preference=power_preference)
adapter = wgpu.gpu.request_adapter(power_preference=power_preference)
device = adapter.request_device(required_limits=limits)
return _main(canvas, device)


async def main_async(canvas):
"""Async function to setup a viz on the given canvas."""
adapter = await wgpu.gpu.request_adapter_async(
canvas=canvas, power_preference="high-performance"
)
adapter = await wgpu.gpu.request_adapter_async(power_preference="high-performance")
device = await adapter.request_device_async(required_limits={})
return _main(canvas, device)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def test_base_wgpu_api():
@mark.skipif(not can_use_wgpu_lib, reason="Needs wgpu lib")
def test_backend_is_selected_automatically():
# Test this in a subprocess to have a clean wgpu with no backend imported yet
code = "import wgpu; print(wgpu.gpu.request_adapter(canvas=None))"
code = "import wgpu; print(wgpu.gpu.request_adapter())"
result = subprocess.run(
[sys.executable, "-c", code],
stdout=subprocess.PIPE,
Expand Down
7 changes: 2 additions & 5 deletions tests/test_gui_glfw.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,7 @@ def test_glfw_canvas_render():

canvas = WgpuCanvas(max_fps=9999)

# wgpu.utils.get_default_device()
adapter = wgpu.gpu.request_adapter(
canvas=canvas, power_preference="high-performance"
)
device = adapter.request_device()
device = wgpu.utils.get_default_device()
draw_frame1 = _get_draw_function(device, canvas)

frame_counter = 0
Expand Down Expand Up @@ -203,6 +199,7 @@ def get_context(self):

canvas = CustomCanvas()

# Also pass canvas here, to touch that code somewhere
adapter = wgpu.gpu.request_adapter(
canvas=canvas, power_preference="high-performance"
)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_wgpu_native_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def test_shader_module_creation_spirv():

@mark.skipif(not can_use_wgpu_lib, reason="Needs wgpu lib")
def test_adapter_destroy():
adapter = wgpu.gpu.request_adapter(canvas=None, power_preference="high-performance")
adapter = wgpu.gpu.request_adapter(power_preference="high-performance")
assert adapter._internal is not None
adapter.__del__()
assert adapter._internal is None
Expand Down
2 changes: 1 addition & 1 deletion tests_mem/test_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
def test_release_adapter(n):
yield {}
for i in range(n):
yield wgpu.gpu.request_adapter(canvas=None, power_preference="high-performance")
yield wgpu.gpu.request_adapter(power_preference="high-performance")


@create_and_release
Expand Down
18 changes: 8 additions & 10 deletions wgpu/backends/wgpu_native/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,19 @@ def check_struct(struct_name, d):

class GPU(base.GPU):
def request_adapter(
self, *, canvas, power_preference=None, force_fallback_adapter=False
self, *, power_preference=None, force_fallback_adapter=False, canvas=None
):
"""Create a `GPUAdapter`, the object that represents an abstract wgpu
implementation, from which one can request a `GPUDevice`.
This is the implementation based on the Rust wgpu-native library.
This is the implementation based on wgpu-native.
Arguments:
canvas (WgpuCanvas): The canvas that the adapter should be able to
render to (to create a swap chain for, to be precise). Can be None
if you're not rendering to screen (or if you're confident that the
returned adapter will work just fine).
power_preference(PowerPreference): "high-performance" or "low-power".
power_preference (PowerPreference): "high-performance" or "low-power".
force_fallback_adapter (bool): whether to use a (probably CPU-based)
fallback adapter.
canvas (WgpuCanvasInterface): The canvas that the adapter should
be able to render to. This can typically be left to None.
"""

# ----- Surface ID
Expand Down Expand Up @@ -335,15 +333,15 @@ def to_py_str(key):
return GPUAdapter(adapter_id, features, limits, adapter_info)

async def request_adapter_async(
self, *, canvas, power_preference=None, force_fallback_adapter=False
self, *, power_preference=None, force_fallback_adapter=False, canvas=None
):
"""Async version of ``request_adapter()``.
This function uses the Rust WGPU library.
This is the implementation based on wgpu-native.
"""
return self.request_adapter(
canvas=canvas,
power_preference=power_preference,
force_fallback_adapter=force_fallback_adapter,
canvas=canvas,
) # no-cover


Expand Down
14 changes: 6 additions & 8 deletions wgpu/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,39 +82,37 @@ class GPU:
# IDL: Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
@apidiff.change("arguments include a canvas object")
def request_adapter(
self, *, canvas, power_preference=None, force_fallback_adapter=False
self, *, power_preference=None, force_fallback_adapter=False, canvas=None
):
"""Create a `GPUAdapter`, the object that represents an abstract wgpu
implementation, from which one can request a `GPUDevice`.
Arguments:
canvas (WgpuCanvasInterface): The canvas that the adapter should
be able to render to (to create a swap chain for, to be precise).
Can be None if you're not rendering to screen (or if you're
confident that the returned adapter will work just fine).
power_preference (PowerPreference): "high-performance" or "low-power".
force_fallback_adapter (bool): whether to use a (probably CPU-based)
fallback adapter.
canvas (WgpuCanvasInterface): The canvas that the adapter should
be able to render to. This can typically be left to None.
"""
# If this method gets called, no backend has been loaded yet, let's do that now!
from .backends.auto import gpu # noqa

return gpu.request_adapter(
canvas=canvas,
power_preference=power_preference,
force_fallback_adapter=force_fallback_adapter,
canvas=canvas,
)

# IDL: Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
@apidiff.change("arguments include a canvas object")
async def request_adapter_async(
self, *, canvas, power_preference=None, force_fallback_adapter=False
self, *, power_preference=None, force_fallback_adapter=False, canvas=None
):
"""Async version of `request_adapter()`."""
return self.request_adapter(
canvas=canvas,
power_preference=power_preference,
force_fallback_adapter=force_fallback_adapter,
canvas=canvas,
)

# IDL: GPUTextureFormat getPreferredCanvasFormat();
Expand Down
4 changes: 1 addition & 3 deletions wgpu/utils/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ def get_default_device():
if _default_device is None:
import wgpu.backends.auto # noqa

adapter = wgpu.gpu.request_adapter(
canvas=None, power_preference="high-performance"
)
adapter = wgpu.gpu.request_adapter(power_preference="high-performance")
_default_device = adapter.request_device()
return _default_device

0 comments on commit a88bd70

Please sign in to comment.