Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions codegen/wgpu_native_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def write_mappings():
("NativeFeature", True),
("PipelineStatisticName", True),
("Dx12Compiler", False),
("PolygonMode", False),
):
pylines.append(f' "{name}":' + " {")
for key, val in hp.enums[name].items():
Expand Down
70 changes: 70 additions & 0 deletions examples/compute_int64.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
simple example of using the int64 shader feature
"""

import wgpu

adapter = wgpu.gpu.request_adapter_sync(power_preference="high-performance")
device = adapter.request_device_sync(required_features=["shader-int64"])

add_shader = """
@group(0) @binding(0)
var<storage, read_write> data: array<i64>;
@compute
@workgroup_size(1)
fn main(@builtin(global_invocation_id) index: vec3<u32>) {
let i: u32 = index.x;
let a_idx = i * 3u;
let b_idx = a_idx + 1u;
let c_idx = a_idx + 2u;
data[c_idx] = data[a_idx] + data[b_idx];
}
"""
a = 0x1234567890
b = 0x9876543210
data = memoryview(bytearray(6 * 8)).cast("q") # signed long long >= 64 bits
data[0] = a
data[1] = b
data[3] = -a
data[4] = -b

buffer = device.create_buffer_with_data(
data=data,
usage=wgpu.BufferUsage.STORAGE
| wgpu.BufferUsage.COPY_SRC
| wgpu.BufferUsage.COPY_DST,
)
pipeline = device.create_compute_pipeline(
layout="auto",
compute={
"module": device.create_shader_module(code=add_shader),
"entry_point": "main",
},
)

bind_group = device.create_bind_group(
layout=pipeline.get_bind_group_layout(0),
entries=[
{
"binding": 0,
"resource": {"buffer": buffer, "offset": 0, "size": buffer.size},
}
],
)

command_encoder = device.create_command_encoder()
compute_pass = command_encoder.begin_compute_pass()
compute_pass.set_pipeline(pipeline)
compute_pass.set_bind_group(0, bind_group)
compute_pass.dispatch_workgroups(2) # we do two calculations
compute_pass.end()
device.queue.submit([command_encoder.finish()])
result = device.queue.read_buffer(buffer)
res = result.cast("q").tolist()
c = a + b
assert res[2] == c, f"expected {c}, got {res[2]}"
print(f"{a:#x} + {b:#x} = {c:#x}")
d = -a + -b
assert res[5] == d, f"expected {d}, got {res[5]}"
print(f"{-a:#x} + {-b:#x} = {d:#x}")
2 changes: 1 addition & 1 deletion examples/imgui_cmap_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def update_gui():
# add the items for the picker
for cmap_name, tex_ref in cmap_data.items():
# text part of each item
clicked, enabled = imgui.menu_item(
_clicked, enabled = imgui.menu_item(
cmap_name, "", p_selected=current_cmap == cmap_name
)
imgui.same_line()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_set_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def test_render_bundle_push_constants():


def test_bad_set_push_constants():
device, pipeline, render_pass_descriptor = setup_pipeline()
device, _pipeline, render_pass_descriptor = setup_pipeline()
encoder = device.create_command_encoder()
this_pass = encoder.begin_render_pass(**render_pass_descriptor)

Expand Down
8 changes: 3 additions & 5 deletions tests/test_wgpu_native_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,8 @@ def are_features_wgpu_legal(features):
def test_features_are_legal():
# A standard feature. Probably exists
assert are_features_wgpu_legal(["shader-f16"])
# Two common extension features
assert are_features_wgpu_legal(["multi-draw-indirect", "vertex-writable-storage"])
# A common extension feature
assert are_features_wgpu_legal(["vertex-writable-storage"])
# An uncommon extension feature. Certainly not on a mac.
assert are_features_wgpu_legal(["pipeline-statistics-query"])
assert are_features_wgpu_legal(
Expand All @@ -429,9 +429,7 @@ def test_features_are_legal():

def test_features_are_illegal():
# writable is misspelled
assert not are_features_wgpu_legal(
["multi-draw-indirect", "vertex-writeable-storage"]
)
assert not are_features_wgpu_legal(["vertex-writeable-storage"])
assert not are_features_wgpu_legal(["my-made-up-feature"])


Expand Down
29 changes: 9 additions & 20 deletions tests/test_wgpu_native_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from testutils import run_tests
from pytest import raises


dedent = lambda s: s.replace("\n ", "\n").strip()


Expand Down Expand Up @@ -36,9 +35,6 @@ def test_parse_shader_error1(caplog):
9 │ out.invalid_attr = vec4<f32>(0.0, 0.0, 1.0);
│ ^^^^^^^^^^^^ invalid accessor


invalid field accessor `invalid_attr`
"""

code = dedent(code)
Expand All @@ -47,6 +43,7 @@ def test_parse_shader_error1(caplog):
device.create_shader_module(code=code)

error = err.value.message
error = error.rstrip("\n")
assert error == expected, f"Expected:\n\n{expected}"


Expand All @@ -72,9 +69,6 @@ def test_parse_shader_error2(caplog):
2 │ @location(0) texcoord : vec2<f32>;
│ ^ expected `,`


expected `,`, found ";"
"""

code = dedent(code)
Expand All @@ -83,6 +77,7 @@ def test_parse_shader_error2(caplog):
device.create_shader_module(code=code)

error = err.value.message
error = error.rstrip("\n")
assert error == expected, f"Expected:\n\n{expected}"


Expand All @@ -108,9 +103,6 @@ def test_parse_shader_error3(caplog):
3 │ @builtin(position) position: vec4<f3>,
│ ^^ unknown type


unknown type: `f3`
"""

code = dedent(code)
Expand All @@ -119,6 +111,7 @@ def test_parse_shader_error3(caplog):
device.create_shader_module(code=code)

error = err.value.message
error = error.rstrip("\n")
assert error == expected, f"Expected:\n\n{expected}"


Expand All @@ -140,9 +133,6 @@ def test_parse_shader_error4(caplog):
In wgpuDeviceCreateShaderModule

Shader '' parsing error: Index 4 is out of bounds for expression [10]


Index 4 is out of bounds for expression [10]
"""

code = dedent(code)
Expand All @@ -151,6 +141,7 @@ def test_parse_shader_error4(caplog):
device.create_shader_module(code=code)

error = err.value.message
error = error.rstrip("\n") # seems to have tailing newlines sometimes?
assert error == expected, f"Expected:\n\n{expected}"


Expand Down Expand Up @@ -191,9 +182,8 @@ def test_validate_shader_error1(caplog):
= Operation Multiply can't work with [4] (of type Matrix { columns: Quad, rows: Quad, scalar: Scalar { kind: Float, width: 4 } }) and [6] (of type Vector { size: Tri, scalar: Scalar { kind: Float, width: 4 } })


Entry point vs_main at Vertex is invalid
Expression [7] is invalid
Operation Multiply can't work with [4] (of type Matrix { columns: Quad, rows: Quad, scalar: Scalar { kind: Float, width: 4 } }) and [6] (of type Vector { size: Tri, scalar: Scalar { kind: Float, width: 4 } })
Expression [7] is invalid
Operation Multiply can't work with [4] (of type Matrix { columns: Quad, rows: Quad, scalar: Scalar { kind: Float, width: 4 } }) and [6] (of type Vector { size: Tri, scalar: Scalar { kind: Float, width: 4 } })
"""

code = dedent(code)
Expand Down Expand Up @@ -227,7 +217,7 @@ def test_validate_shader_error2(caplog):
}
"""

expected1 = """Returning Some(Vector { size: Tri, scalar: Scalar { kind: Float, width: 4 } }) where Some(Vector { size: Quad, scalar: Scalar { kind: Float, width: 4 } }) is expected"""
expected1 = """Returning Some(Handle([3])) where Some([0]) is expected"""
expected2 = """
Validation Error

Expand All @@ -240,11 +230,10 @@ def test_validate_shader_error2(caplog):
9 │ return vec3<f32>(1.0, 0.0, 1.0);
│ ^^^^^^^^^^^^^^^^^^^^^^^^ naga::ir::Expression [8]
= The `return` value Some([8]) does not match the function return value
= The `return` expression Some([8]) does not match the declared return type Some([0])


Entry point fs_main at Vertex is invalid
The `return` value Some([8]) does not match the function return value
The `return` expression Some([8]) does not match the declared return type Some([0])
"""

code = dedent(code)
Expand Down
8 changes: 1 addition & 7 deletions tests/test_wgpu_vertex_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

class Runner:
REQUIRED_FEATURES = ["indirect-first-instance"]
OPTIONAL_FEATURES = ["multi-draw-indirect", "multi-draw-indirect-count"]
OPTIONAL_FEATURES = ["multi-draw-indirect-count"]

@classmethod
def is_usable(cls):
Expand Down Expand Up @@ -263,9 +263,6 @@ def draw(encoder):


def test_multi_draw_indirect(runner):
if "multi-draw-indirect" not in runner.device.features:
pytest.skip("Must have 'multi-draw-indirect' to run")

def draw(encoder):
multi_draw_indirect(encoder, runner.draw_data_buffer, offset=8, count=2)

Expand Down Expand Up @@ -329,9 +326,6 @@ def draw(encoder):


def test_multi_draw_indexed_indirect(runner):
if "multi-draw-indirect" not in runner.device.features:
pytest.skip("Must have 'multi-draw-indirect' to run")

def draw(encoder):
multi_draw_indexed_indirect(
encoder, runner.draw_data_buffer_indexed, offset=8, count=2
Expand Down
4 changes: 2 additions & 2 deletions wgpu/backends/wgpu_native/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@


# The wgpu-native version that we target/expect
__version__ = "25.0.2.1"
__commit_sha__ = "af9074edf144efe4f1432b2e42c477429c4964c1"
__version__ = "27.0.2.0"
__commit_sha__ = "74f8c24c903b6352d09f1928c56962ce06f77a4d"
version_info = tuple(map(int, __version__.split("."))) # noqa: RUF048
_check_expected_version(version_info) # produces a warning on mismatch

Expand Down
21 changes: 20 additions & 1 deletion wgpu/backends/wgpu_native/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,10 @@ def _create_render_pipeline_descriptor(
depth_stencil = depth_stencil or {}
multisample = multisample or {}
primitive = primitive or {}
# remove the extras so the struct can still be checked
primitive_extras = {}
primitive_extras["polygon_mode"] = primitive.pop("polygon_mode", "Fill")
primitive_extras["conservative"] = primitive.pop("conservative", False)
check_struct("VertexState", vertex)
check_struct("DepthStencilState", depth_stencil)
check_struct("MultisampleState", multisample)
Expand All @@ -2053,10 +2057,25 @@ def _create_render_pipeline_descriptor(
buffers=c_vertex_buffer_descriptors_array,
)

# explanations for extras: https://docs.rs/wgpu/latest/wgpu/struct.PrimitiveState.html
polygon_mode = enum_str2int["PolygonMode"].get(
primitive_extras.get("polygon_mode"), enum_str2int["PolygonMode"]["Fill"]
)

# H: chain: WGPUChainedStruct, polygonMode: WGPUPolygonMode, conservative: WGPUBool/int
c_primitive_state_extras = new_struct_p(
"WGPUPrimitiveStateExtras *",
# not used: chain
polygonMode=polygon_mode,
conservative=primitive_extras.get("conservative", False),
)
c_primitive_state_extras.chain.sType = lib.WGPUSType_PrimitiveStateExtras
next_in_chain = ffi.cast("WGPUChainedStruct *", c_primitive_state_extras)

# H: nextInChain: WGPUChainedStruct *, topology: WGPUPrimitiveTopology, stripIndexFormat: WGPUIndexFormat, frontFace: WGPUFrontFace, cullMode: WGPUCullMode, unclippedDepth: WGPUBool/int
c_primitive_state = new_struct(
"WGPUPrimitiveState",
# not used: nextInChain
nextInChain=next_in_chain,
topology=primitive.get("topology", "triangle-list"),
stripIndexFormat=primitive.get("strip_index_format", 0),
frontFace=primitive.get("front_face", "ccw"),
Expand Down
11 changes: 9 additions & 2 deletions wgpu/backends/wgpu_native/_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,6 @@
"NativeFeature": {
"push-constants": 196609,
"texture-adapter-specific-format-features": 196610,
"multi-draw-indirect": 196611,
"multi-draw-indirect-count": 196612,
"vertex-writable-storage": 196613,
"texture-binding-array": 196614,
Expand All @@ -343,10 +342,12 @@
"mappable-primary-buffers": 196622,
"buffer-binding-array": 196623,
"uniform-buffer-and-storage-texture-array-non-uniform-indexing": 196624,
"polygon-mode-line": 196627,
"polygon-mode-point": 196628,
"conservative-rasterization": 196629,
"spirv-shader-passthrough": 196631,
"vertex-attribute64bit": 196633,
"texture-format-nv12": 196634,
"ray-tracing-acceleration-structure": 196635,
"ray-query": 196636,
"shader-f64": 196637,
"shader-i16": 196638,
Expand All @@ -357,6 +358,7 @@
"subgroup-barrier": 196643,
"timestamp-query-inside-encoders": 196644,
"timestamp-query-inside-passes": 196645,
"shader-int64": 196646,
},
"PipelineStatisticName": {
"vertex-shader-invocations": 0,
Expand All @@ -370,6 +372,11 @@
"Fxc": 1,
"Dxc": 2,
},
"PolygonMode": {
"Fill": 0,
"Line": 1,
"Point": 2,
},
}

enum_int2str = {
Expand Down
Loading