Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ This code is distributed under the 2-clause BSD license.
* Install devtools using `pip install -e .[dev]`.
* Using `pip install -e .` will also download the upstream wgpu-native
binaries.
* You can use `python tools/download_wgpu_native.py` when needed.
* You can use `python tools/download_wgpu_native.py` when needed. And run `python codegen` once to obtain the combined headerfile.
* Or point the `WGPU_LIB_PATH` environment variable to a custom build of `wgpu-native`.
* Use `ruff format` to apply autoformatting.
* Use `ruff check` to check for linting errors.
Expand Down
2 changes: 1 addition & 1 deletion codegen/wgpu_native_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def write_mappings():
if native_name in hp.enums:
for key, val in hp.enums[native_name].items():
key = key.lower()
if key in hp_enum:
if key in hp_enum and val != hp_enum.get(key):
print(f"Enum field {name}.{key} overridden by wgpu.h")
hp_enum[key] = val
for ikey in idl.enums[name].values():
Expand Down
45 changes: 44 additions & 1 deletion tests/test_wgpu_native_texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np

from testutils import run_tests, can_use_wgpu_lib, iters_equal
from pytest import mark, raises
from pytest import mark, raises, skip


@mark.skipif(not can_use_wgpu_lib, reason="Needs wgpu lib")
Expand Down Expand Up @@ -281,5 +281,48 @@ def test_write_texture2():
assert iters_equal(data0, data2)


def test_16bit_norm():
"""
Test creating, writing and making a view wiht a 16bit norm texture formats, if the native only feature is available.
"""
# can't use the default device because this need an additional feature
feature_16bit_norm = "texture-format16bit-norm" # in the future it will be tier1
adapter = wgpu.gpu.request_adapter_sync()
if feature_16bit_norm not in adapter.features:
skip(
f"{adapter.summary} does not support {feature_16bit_norm}, skipping test for 16bit norm textures"
)
device = adapter.request_device_sync(required_features=[feature_16bit_norm])

shape = (64, 64, 1) # 1 channel should do it

data = np.empty(
shape=shape, dtype=np.uint16
) # TODO: maybe use actual data or rand ints?

texture = device.create_texture(
label="test 16bit norm texture",
size=shape,
format=wgpu.enums.TextureFormat.r16unorm,
usage=wgpu.flags.TextureUsage.COPY_DST, # not yet possible: wgpu.TextureUsage.RENDER_ATTACHMENT
)

device.queue.write_texture(
destination=wgpu.structs.TexelCopyTextureInfo(
texture=texture,
),
data=data,
data_layout=wgpu.structs.TexelCopyBufferLayout(
bytes_per_row=shape[0] * 2,
rows_per_image=shape[1],
),
size=shape,
)

texture_view = texture.create_view(format=wgpu.enums.TextureFormat.r16unorm)
assert texture_view
assert "r16unorm" in texture.format


if __name__ == "__main__":
run_tests(globals())
2 changes: 1 addition & 1 deletion tools/download_wgpu_native.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def main(version=None, os_string=None, arch=None, upstream=None):
current_version = get_current_version()
if version != current_version:
print(
f"Version changed, updating {VERSION_FILE}, diff: https://github.com/{upstream}/compare/v{current_version}...v{version}"
f"Version changed, updating {VERSION_FILE}, diff: https://github.com/{upstream}/compare/v{current_version}...v{version}\nPlese run codegen to obtain the combined headerfile"
)
filename = "commit-sha"
url = f"https://github.com/{upstream}/releases/download/v{version}/{filename}"
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__ = "29.0.0.0"
__commit_sha__ = "d2e3330ade4ae1bb238d76b485926f067e7ee64c"
__version__ = "29.0.1.1"
__commit_sha__ = "6aed50955d934ac36049ba8d002034841633ae02"
version_info = tuple(map(int, __version__.split("."))) # noqa: RUF048
_check_expected_version(version_info) # produces a warning on mismatch

Expand Down
43 changes: 13 additions & 30 deletions wgpu/backends/wgpu_native/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ def _get_limits(id: int, device: bool = False, adapter: bool = False):
"""Gets the limits for a device or an adapter"""
assert device + adapter == 1 # exactly one is set

# NOTE: this will get even simpler in the near future: https://github.com/gfx-rs/wgpu-native/pull/575 as maxImmediateSize shouldn't exist in both

# H: chain: WGPUChainedStruct, maxImmediateSize: int, maxNonSamplerBindings: int, maxBindingArrayElementsPerShaderStage: int
# H: chain: WGPUChainedStruct, maxNonSamplerBindings: int, maxBindingArrayElementsPerShaderStage: int, maxBindingArraySamplerElementsPerShaderStage: int, maxMultiviewViewCount: int
c_limits_native = new_struct(
"WGPUNativeLimits",
# H: next: WGPUChainedStruct *, sType: WGPUSType
Expand All @@ -334,9 +332,10 @@ def _get_limits(id: int, device: bool = False, adapter: bool = False):
# not used: next
sType=lib.WGPUSType_NativeLimits,
),
# not used: maxImmediateSize
# not used: maxNonSamplerBindings
# not used: maxBindingArrayElementsPerShaderStage
# not used: maxBindingArraySamplerElementsPerShaderStage
# not used: maxMultiviewViewCount
)

# Note that the object returned by ffi.cast() does not own the memory, so we must keep a ref to the uncast object, until wgpu-native has consumed it.
Expand Down Expand Up @@ -1229,7 +1228,6 @@ def canonicalize_limit_name(name):
# Skip the pointers
if snake_key in (
"next-in-chain",
"max-immediate-size",
"max-non-sampler-bindings",
):
# Skip the chain and the native limits as they are handled in their own
Expand All @@ -1241,18 +1239,18 @@ def canonicalize_limit_name(name):
value = self._limits[snake_key]
setattr(c_required_limits, key, value)

# TODO: handle new native limits, or find a programmatic solution for it
# the native only limits are passed in via the next-in-chain struct
# H: chain: WGPUChainedStruct, maxImmediateSize: int, maxNonSamplerBindings: int, maxBindingArrayElementsPerShaderStage: int
# H: chain: WGPUChainedStruct, maxNonSamplerBindings: int, maxBindingArrayElementsPerShaderStage: int, maxBindingArraySamplerElementsPerShaderStage: int, maxMultiviewViewCount: int
c_required_limits_native = new_struct_p(
"WGPUNativeLimits *",
maxImmediateSize=required_limits.get(
"max-immediate-size", self._limits["max-immediate-size"]
),
maxNonSamplerBindings=required_limits.get(
"max-non-sampler-bindings", self._limits["max-non-sampler-bindings"]
),
# not used: chain
# not used: maxBindingArrayElementsPerShaderStage
# not used: maxBindingArraySamplerElementsPerShaderStage
# not used: maxMultiviewViewCount
)
c_required_limits_native.chain.next = ffi.NULL
c_required_limits_native.chain.sType = lib.WGPUSType_NativeLimits
Expand Down Expand Up @@ -1805,29 +1803,14 @@ def create_pipeline_layout(
bind_group_layouts_ids = [x._internal for x in bind_group_layouts]
c_layout_array = new_array("WGPUBindGroupLayout[]", bind_group_layouts_ids)

c_pipeline_layout_next_in_chain = ffi.NULL
if immediate_size:
# H: chain: WGPUChainedStruct, immediateDataSize: int
c_pipeline_layout_extras = new_struct_p(
"WGPUPipelineLayoutExtras *",
# not used: chain
immediateDataSize=immediate_size,
)
c_pipeline_layout_extras.chain.sType = lib.WGPUSType_PipelineLayoutExtras
# Note that the object returned by ffi.cast() does not own the memory, so we must keep a ref to the uncast object, until wgpu-native has consumed it.
c_pipeline_layout_next_in_chain = ffi.cast(
"WGPUChainedStruct *", c_pipeline_layout_extras
)

# TODO: there is an immediateSize field in this struct too. so do we even need the extras?
# H: nextInChain: WGPUChainedStruct *, label: WGPUStringView, bindGroupLayoutCount: int, bindGroupLayouts: WGPUBindGroupLayout *, immediateSize: int
struct = new_struct_p(
"WGPUPipelineLayoutDescriptor *",
nextInChain=c_pipeline_layout_next_in_chain,
label=to_c_string_view(label),
bindGroupLayouts=c_layout_array,
bindGroupLayoutCount=len(bind_group_layouts),
# not used: immediateSize
immediateSize=immediate_size,
# not used: nextInChain
)

# H: WGPUPipelineLayout f(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor)
Expand Down Expand Up @@ -2990,13 +2973,13 @@ def set_immediates(
raise ValueError("data_size + data_offset is too large")

c_data = ffi.cast("void *", address) # do we want to add data_offset?
# H: void wgpuComputePassEncoderSetImmediates(WGPUComputePassEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const *data)
# H: void wgpuRenderPassEncoderSetImmediates(WGPURenderPassEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const *data)
# H: void wgpuRenderBundleEncoderSetImmediates(WGPURenderBundleEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const *data)
# H: void wgpuComputePassEncoderSetImmediates(WGPUComputePassEncoder computePassEncoder, uint32_t offset, void const * data, size_t size)
# H: void wgpuRenderPassEncoderSetImmediates(WGPURenderPassEncoder renderPassEncoder, uint32_t offset, void const * data, size_t size)
# H: void wgpuRenderBundleEncoderSetImmediates(WGPURenderBundleEncoder renderBundleEncoder, uint32_t offset, void const * data, size_t size)
function = type(self)._set_immediates_function
if function is None:
self._not_implemented("set_immediates")
function(self._internal, range_offset, size, c_data + data_offset)
function(self._internal, range_offset, c_data + data_offset, size)


class GPUDebugCommandsMixin(classes.GPUDebugCommandsMixin):
Expand Down
38 changes: 29 additions & 9 deletions wgpu/backends/wgpu_native/_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@
"TextureFormat.etc2-rgba8unorm-srgb": 69,
"TextureFormat.r16float": 9,
"TextureFormat.r16sint": 8,
"TextureFormat.r16snorm": 196610,
"TextureFormat.r16snorm": 6,
"TextureFormat.r16uint": 7,
"TextureFormat.r16unorm": 196609,
"TextureFormat.r16unorm": 5,
"TextureFormat.r32float": 14,
"TextureFormat.r32sint": 16,
"TextureFormat.r32uint": 15,
Expand All @@ -193,9 +193,9 @@
"TextureFormat.rg11b10ufloat": 31,
"TextureFormat.rg16float": 21,
"TextureFormat.rg16sint": 20,
"TextureFormat.rg16snorm": 196612,
"TextureFormat.rg16snorm": 18,
"TextureFormat.rg16uint": 19,
"TextureFormat.rg16unorm": 196611,
"TextureFormat.rg16unorm": 17,
"TextureFormat.rg32float": 33,
"TextureFormat.rg32sint": 35,
"TextureFormat.rg32uint": 34,
Expand All @@ -208,9 +208,9 @@
"TextureFormat.rgb9e5ufloat": 32,
"TextureFormat.rgba16float": 40,
"TextureFormat.rgba16sint": 39,
"TextureFormat.rgba16snorm": 196614,
"TextureFormat.rgba16snorm": 37,
"TextureFormat.rgba16uint": 38,
"TextureFormat.rgba16unorm": 196613,
"TextureFormat.rgba16unorm": 36,
"TextureFormat.rgba32float": 41,
"TextureFormat.rgba32sint": 43,
"TextureFormat.rgba32uint": 42,
Expand Down Expand Up @@ -275,7 +275,7 @@
"VertexStepMode.vertex": 1,
}

# There are 48 struct-field enum mappings
# There are 49 struct-field enum mappings

cstructfield2enum = {
"BlendComponent.dstFactor": "BlendFactor",
Expand All @@ -286,6 +286,7 @@
"CompilationMessage.type": "CompilationMessageType",
"DepthStencilState.depthCompare": "CompareFunction",
"DepthStencilState.format": "TextureFormat",
"ImageSubresourceRange.aspect": "TextureAspect",
"PrimitiveState.cullMode": "CullMode",
"PrimitiveState.frontFace": "FrontFace",
"PrimitiveState.stripIndexFormat": "IndexFormat",
Expand Down Expand Up @@ -354,11 +355,14 @@
"texture-compression-astc-hdr": 196620,
"mappable-primary-buffers": 196622,
"buffer-binding-array": 196623,
"uniform-buffer-and-storage-texture-array-non-uniform-indexing": 196624,
"storage-texture-array-non-uniform-indexing": 196624,
"address-mode-clamp-to-zero": 196625,
"address-mode-clamp-to-border": 196626,
"polygon-mode-line": 196627,
"polygon-mode-point": 196628,
"conservative-rasterization": 196629,
"spirv-shader-passthrough": 196631,
"clear-texture": 196630,
"multiview": 196632,
"vertex-attribute64bit": 196633,
"texture-format-nv12": 196634,
"ray-query": 196636,
Expand All @@ -371,6 +375,22 @@
"timestamp-query-inside-encoders": 196644,
"timestamp-query-inside-passes": 196645,
"shader-int64": 196646,
"shader-float32-atomic": 196647,
"texture-atomic": 196648,
"texture-format-p010": 196649,
"pipeline-cache": 196651,
"shader-int64-atomic-min-max": 196652,
"shader-int64-atomic-all-ops": 196653,
"texture-int64-atomic": 196656,
"shader-barycentrics": 196663,
"selective-multiview": 196664,
"multisample-array": 196666,
"cooperative-matrix": 196667,
"shader-per-vertex": 196668,
"shader-draw-index": 196669,
"acceleration-structure-binding-array": 196670,
"memory-decoration-coherent": 196671,
"memory-decoration-volatile": 196672,
},
"PipelineStatisticName": {
"vertex-shader-invocations": 0,
Expand Down
17 changes: 5 additions & 12 deletions wgpu/resources/codegen_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
## Preparing
* The webgpu.idl defines 37 classes with 77 functions
* The webgpu.idl defines 5 flags, 34 enums, 60 structs
* webgpu.h/wgpu.h define 226 functions
* webgpu.h/wgpu.h define 7 flags, 68 enums, 114 structs
* webgpu.h/wgpu.h define 228 functions
* webgpu.h/wgpu.h define 8 flags, 70 enums, 115 structs
## Updating API
* Wrote 5 flags to flags.py
* Wrote 34 enums to enums.py
Expand All @@ -24,19 +24,12 @@
### Patching API for backends/wgpu_native/_api.py
* Validated 38 classes, 116 methods, 0 properties
## Validating backends/wgpu_native/_api.py
* Enum field TextureFormat.r16unorm overridden by wgpu.h
* Enum field TextureFormat.r16snorm overridden by wgpu.h
* Enum field TextureFormat.rg16unorm overridden by wgpu.h
* Enum field TextureFormat.rg16snorm overridden by wgpu.h
* Enum field TextureFormat.rgba16unorm overridden by wgpu.h
* Enum field TextureFormat.rgba16snorm overridden by wgpu.h
* Enum PipelineErrorReason missing in webgpu.h
* Enum AutoLayoutMode missing in webgpu.h
* Enum field VertexFormat.unorm10-10-10-2 missing in webgpu.h
* Enum field QueryType.force32 overridden by wgpu.h
* Enum CanvasAlphaMode missing in webgpu.h
* Enum CanvasToneMappingMode missing in webgpu.h
* Wrote 267 enum mappings and 48 struct-field mappings to wgpu_native/_mappings.py
* Wrote 267 enum mappings and 49 struct-field mappings to wgpu_native/_mappings.py
* Validated 154 C function calls
* Not using 83 C functions
* Validated 97 C structs
* Not using 85 C functions
* Validated 96 C structs
Loading
Loading