Skip to content

Commit 6ff9fd9

Browse files
authored
Update to wgpu-native 0.8.0.2 (#167)
* update to latest wgpu-native * make codegen make some extra mappings for rs * fix API deviation * re-codegen, force vulkan, request more-texture-features, obtain adapter properties * add notes on some restrictions
1 parent c6da8e6 commit 6ff9fd9

File tree

7 files changed

+163
-54
lines changed

7 files changed

+163
-54
lines changed

codegen/rspatcher.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,28 @@ def write_mappings():
109109
pylines.append(f' "{key}": {cstructfield2enum[key]!r},')
110110
pylines.append("}\n")
111111

112+
# Write a few native-only mappings: key => int
113+
pylines.append("enum_str2int = {")
114+
for name in ["BackendType"]:
115+
pylines.append(f' "{name}":' + " {")
116+
for key, val in hp.enums[name].items():
117+
if key == "Force32":
118+
continue
119+
pylines.append(f' "{key}": {val},')
120+
pylines.append(" }")
121+
pylines.append("}")
122+
123+
# Write a few native-only mappings: int => key
124+
pylines.append("enum_int2str = {")
125+
for name in ["BackendType", "AdapterType"]:
126+
pylines.append(f' "{name}":' + " {")
127+
for key, val in hp.enums[name].items():
128+
if key == "Force32":
129+
continue
130+
pylines.append(f' {val}: "{key}",')
131+
pylines.append(" },")
132+
pylines.append("}")
133+
112134
# Wrap up
113135
code = blacken("\n".join(pylines)) # just in case; code is already black
114136
with open(os.path.join(lib_dir, "backends", "rs_mappings.py"), "wb") as f:

tests/test_rs_render_tex.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,11 @@ def render_textured_square(fragment_shader, texture_format, texture_size, textur
492492
# Determine sampler type.
493493
# Note that integer texture types cannot even use a sampler.
494494
sampler_type = wgpu.SamplerBindingType.filtering
495-
if "32float" in texture_format:
496-
sampler_type = wgpu.SamplerBindingType.non_filtering
497-
texture_sample_type = wgpu.TextureSampleType.unfilterable_float
495+
# On Vanilla wgpu, float32 textures cannot use a filtering
496+
# (interpolating) texture, but we request a feature so that we can.
497+
# if "32float" in texture_format:
498+
# sampler_type = wgpu.SamplerBindingType.non_filtering
499+
# texture_sample_type = wgpu.TextureSampleType.unfilterable_float
498500

499501
# Bindings and layout
500502
bindings = [

wgpu/backends/rs.py

Lines changed: 71 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
from .._coreutils import ApiDiff
4242

4343
from .rs_ffi import ffi, lib, check_expected_version
44-
from .rs_mappings import cstructfield2enum, enummap
44+
from .rs_mappings import cstructfield2enum, enummap, enum_str2int, enum_int2str
4545
from .rs_helpers import (
4646
get_surface_id_from_canvas,
4747
get_memoryview_from_address,
@@ -53,8 +53,8 @@
5353
apidiff = ApiDiff()
5454

5555
# The wgpu-native version that we target/expect
56-
__version__ = "0.8.0.1"
57-
__commit_sha__ = "691468c9817b51a81530fb277a9b30fcc4a71ea7"
56+
__version__ = "0.8.0.2"
57+
__commit_sha__ = "66a4139579f2499a67b7ade1a6c3bcb414046c64"
5858
version_info = tuple(map(int, __version__.split(".")))
5959
check_expected_version(version_info) # produces a warning on mismatch
6060

@@ -212,12 +212,27 @@ def request_adapter(self, *, canvas, power_preference=None):
212212
else:
213213
surface_id = get_surface_id_from_canvas(canvas)
214214

215+
# Force Vulkan on Windows, to avoid DX12 which seems to ignore
216+
# the NVidia control panel settings. I guess Vulkan is more
217+
# mature than Metal too, so let's just force that for now.
218+
# See https://github.com/gfx-rs/wgpu/issues/1416
219+
# force_backend = lib.WGPUBackendType_Vulkan
220+
force_backend = enum_str2int["BackendType"]["Vulkan"]
221+
222+
# H: chain: WGPUChainedStruct, backend: WGPUBackendType
223+
extras = new_struct_p(
224+
"WGPUAdapterExtras *",
225+
backend=force_backend,
226+
# not used: chain
227+
)
228+
extras.chain.sType = lib.WGPUSType_AdapterExtras
229+
215230
# Convert the descriptor
216231
# H: nextInChain: WGPUChainedStruct *, compatibleSurface: WGPUSurface
217232
struct = new_struct_p(
218233
"WGPURequestAdapterOptions *",
219234
compatibleSurface=surface_id,
220-
# not used: nextInChain
235+
nextInChain=ffi.cast("WGPUChainedStruct * ", extras),
221236
)
222237

223238
# Do the API call and get the adapter id
@@ -251,16 +266,19 @@ def callback(received, userdata):
251266
# not used: backendType
252267
)
253268

254-
# todo: This function exists in the headerfile but not in the lib (yet)
255269
# H: void f(WGPUAdapter adapter, WGPUAdapterProperties * properties)
256-
# lib.wgpuAdapterGetProperties(adapter_id, c_properties)
270+
lib.wgpuAdapterGetProperties(adapter_id, c_properties)
257271
properties = {
258272
"name": "",
259273
"vendorID": c_properties.vendorID,
260274
"deviceID": c_properties.deviceID,
261275
"driverDescription": "",
262-
"adapterType": c_properties.adapterType,
263-
"backendType": c_properties.backendType,
276+
"adapterType": enum_int2str["AdapterType"].get(
277+
c_properties.adapterType, "unknown"
278+
),
279+
"backendType": enum_int2str["BackendType"].get(
280+
c_properties.backendType, "unknown"
281+
),
264282
}
265283
if c_properties.name:
266284
properties["name"] = ffi.string(c_properties.name).decode(errors="ignore")
@@ -335,13 +353,26 @@ def _request_device(self, label, features, limits, trace_path):
335353
limits2 = base.DEFAULT_ADAPTER_LIMITS.copy()
336354
limits2.update(limits or {})
337355

338-
# H: chain: WGPUChainedStruct, maxBindGroups: int, label: char*, tracePath: char*
356+
# Vanilla WGPU does not support interpolating samplers for float32 textures,
357+
# which is sad for scientific data in particular. We can enable it
358+
# (on the hardware were wgpu-py likely runs) using the feature:
359+
# WGPUNativeFeature_TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
360+
361+
# H: chain: WGPUChainedStruct, maxTextureDimension1D: int, maxTextureDimension2D: int, maxTextureDimension3D: int, maxTextureArrayLayers: int, maxBindGroups: int, maxDynamicStorageBuffersPerPipelineLayout: int, maxStorageBuffersPerShaderStage: int, maxStorageBufferBindingSize: int, nativeFeatures: WGPUNativeFeature, label: char*, tracePath: char*
339362
extras = new_struct_p(
340363
"WGPUDeviceExtras *",
341364
label=to_c_label(label),
342365
maxBindGroups=limits2["max_bind_groups"],
366+
maxStorageBuffersPerShaderStage=6,
343367
tracePath=c_trace_path,
368+
nativeFeatures=lib.WGPUNativeFeature_TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
344369
# not used: chain
370+
# not used: maxTextureDimension1D
371+
# not used: maxTextureDimension2D
372+
# not used: maxTextureDimension3D
373+
# not used: maxTextureArrayLayers
374+
# not used: maxDynamicStorageBuffersPerPipelineLayout
375+
# not used: maxStorageBufferBindingSize
345376
)
346377
extras.chain.sType = lib.WGPUSType_DeviceExtras
347378

@@ -917,34 +948,37 @@ def create_render_pipeline(
917948
if fragment is not None:
918949
c_color_targets_list = []
919950
for target in fragment["targets"]:
920-
alpha_blend = _tuple_from_tuple_or_dict(
921-
target["blend"]["alpha"],
922-
("src_factor", "dst_factor", "operation"),
923-
)
924-
# H: srcFactor: WGPUBlendFactor, dstFactor: WGPUBlendFactor, operation: WGPUBlendOperation
925-
c_alpha_blend = new_struct(
926-
"WGPUBlendComponent",
927-
srcFactor=alpha_blend[0],
928-
dstFactor=alpha_blend[1],
929-
operation=alpha_blend[2],
930-
)
931-
color_blend = _tuple_from_tuple_or_dict(
932-
target["blend"]["color"],
933-
("src_factor", "dst_factor", "operation"),
934-
)
935-
# H: srcFactor: WGPUBlendFactor, dstFactor: WGPUBlendFactor, operation: WGPUBlendOperation
936-
c_color_blend = new_struct(
937-
"WGPUBlendComponent",
938-
srcFactor=color_blend[0],
939-
dstFactor=color_blend[1],
940-
operation=color_blend[2],
941-
)
942-
# H: color: WGPUBlendComponent, alpha: WGPUBlendComponent
943-
c_blend = new_struct_p(
944-
"WGPUBlendState *",
945-
color=c_color_blend,
946-
alpha=c_alpha_blend,
947-
)
951+
if not target.get("blend", None):
952+
c_blend = ffi.NULL
953+
else:
954+
alpha_blend = _tuple_from_tuple_or_dict(
955+
target["blend"]["alpha"],
956+
("src_factor", "dst_factor", "operation"),
957+
)
958+
# H: srcFactor: WGPUBlendFactor, dstFactor: WGPUBlendFactor, operation: WGPUBlendOperation
959+
c_alpha_blend = new_struct(
960+
"WGPUBlendComponent",
961+
srcFactor=alpha_blend[0],
962+
dstFactor=alpha_blend[1],
963+
operation=alpha_blend[2],
964+
)
965+
color_blend = _tuple_from_tuple_or_dict(
966+
target["blend"]["color"],
967+
("src_factor", "dst_factor", "operation"),
968+
)
969+
# H: srcFactor: WGPUBlendFactor, dstFactor: WGPUBlendFactor, operation: WGPUBlendOperation
970+
c_color_blend = new_struct(
971+
"WGPUBlendComponent",
972+
srcFactor=color_blend[0],
973+
dstFactor=color_blend[1],
974+
operation=color_blend[2],
975+
)
976+
# H: color: WGPUBlendComponent, alpha: WGPUBlendComponent
977+
c_blend = new_struct_p(
978+
"WGPUBlendState *",
979+
color=c_color_blend,
980+
alpha=c_alpha_blend,
981+
)
948982
# H: nextInChain: WGPUChainedStruct *, format: WGPUTextureFormat, blend: WGPUBlendState *, writeMask: WGPUColorWriteMaskFlags/int
949983
c_color_state = new_struct(
950984
"WGPUColorTargetState",

wgpu/backends/rs_mappings.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,32 @@
227227
"VertexAttribute.format": "VertexFormat",
228228
"VertexBufferLayout.stepMode": "InputStepMode",
229229
}
230+
231+
enum_str2int = {
232+
"BackendType": {
233+
"Null": 0,
234+
"D3D11": 1,
235+
"D3D12": 2,
236+
"Metal": 3,
237+
"Vulkan": 4,
238+
"OpenGL": 5,
239+
"OpenGLES": 6,
240+
}
241+
}
242+
enum_int2str = {
243+
"BackendType": {
244+
0: "Null",
245+
1: "D3D11",
246+
2: "D3D12",
247+
3: "Metal",
248+
4: "Vulkan",
249+
5: "OpenGL",
250+
6: "OpenGLES",
251+
},
252+
"AdapterType": {
253+
0: "DiscreteGPU",
254+
1: "IntegratedGPU",
255+
2: "CPU",
256+
3: "Unknown",
257+
},
258+
}

wgpu/base.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,13 +661,13 @@ def create_render_pipeline(
661661
"format": wgpu.TextureFormat.depth24plus_stencil8,
662662
"depth_write_enabled": False, # optional
663663
"depth_compare": wgpu.CompareFunction.always, # optional
664-
"front": { # optional
664+
"stencil_front": { # optional
665665
"compare": wgpu.CompareFunction.equal,
666666
"fail_op": wgpu.StencilOperation.keep,
667667
"depth_fail_op": wgpu.StencilOperation.keep,
668668
"pass_op": wgpu.StencilOperation.keep,
669669
},
670-
"back": { # optional
670+
"stencil_back": { # optional
671671
"compare": wgpu.CompareFunction.equal,
672672
"fail_op": wgpu.StencilOperation.keep,
673673
"depth_fail_op": wgpu.StencilOperation.keep,
@@ -690,7 +690,8 @@ def create_render_pipeline(
690690
"alpha_to_coverage_enabled": False # optional
691691
}
692692
693-
Example fragment (FragmentState) dict:
693+
Example fragment (FragmentState) dict. The `blend` parameter can be None
694+
to disable blending (not all texture formats support blending).
694695
695696
.. code-block:: py
696697

wgpu/resources/codegen_report.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* The webgpu.idl defines 34 classes with 82 functions
44
* The webgpu.idl defines 5 flags, 31 enums, 52 structs
55
* The wgpu.h defines 106 functions
6-
* The wgpu.h defines 5 flags, 36 enums, 58 structs
6+
* The wgpu.h defines 5 flags, 37 enums, 59 structs
77
## Updating API
88
* Wrote 5 flags to flags.py
99
* Wrote 31 enums to enums.py
@@ -41,4 +41,4 @@
4141
* Wrote 169 enum mappings and 45 struct-field mappings to rs_mappings.py
4242
* Validated 65 C function calls
4343
* Not using 46 C functions
44-
* Validated 65 C structs
44+
* Validated 66 C structs

wgpu/resources/wgpu.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
#ifndef WGPU_H_
22
#define WGPU_H_
33

4-
#include "webgpu-headers/webgpu.h"
4+
#include "webgpu.h"
55

66
typedef enum WGPUNativeSType {
77
// Start at 6 to prevent collisions with webgpu STypes
88
WGPUSType_DeviceExtras = 0x60000001,
9+
WGPUSType_AdapterExtras = 0x60000002,
910
WGPUNativeSType_Force32 = 0x7FFFFFFF
1011
} WGPUNativeSType;
1112

12-
13-
typedef struct WGPUDeviceExtras {
14-
WGPUChainedStruct chain;
15-
uint32_t maxBindGroups;
16-
const char* label;
17-
const char* tracePath;
18-
} WGPUDeviceExtras;
13+
typedef enum WGPUNativeFeature {
14+
WGPUNativeFeature_TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 0x10000000
15+
} WGPUNativeFeature;
1916

2017
typedef enum WGPULogLevel {
2118
WGPULogLevel_Off = 0x00000000,
@@ -27,6 +24,30 @@ typedef enum WGPULogLevel {
2724
WGPULogLevel_Force32 = 0x7FFFFFFF
2825
} WGPULogLevel;
2926

27+
typedef struct WGPUAdapterExtras {
28+
WGPUChainedStruct chain;
29+
WGPUBackendType backend;
30+
} WGPUAdapterExtras;
31+
32+
typedef struct WGPUDeviceExtras {
33+
WGPUChainedStruct chain;
34+
uint32_t maxTextureDimension1D;
35+
uint32_t maxTextureDimension2D;
36+
uint32_t maxTextureDimension3D;
37+
uint32_t maxTextureArrayLayers;
38+
uint32_t maxBindGroups;
39+
uint32_t maxDynamicStorageBuffersPerPipelineLayout;
40+
uint32_t maxStorageBuffersPerShaderStage;
41+
uint32_t maxStorageBufferBindingSize;
42+
43+
WGPUNativeFeature nativeFeatures;
44+
45+
const char* label;
46+
const char* tracePath;
47+
} WGPUDeviceExtras;
48+
49+
50+
3051
typedef void (*WGPULogCallback)(WGPULogLevel level, const char *msg);
3152

3253
void wgpuDevicePoll(WGPUDevice device, bool force_wait);
@@ -39,4 +60,4 @@ uint32_t wgpuGetVersion(void);
3960

4061
void wgpuRenderPassEncoderSetPushConstants(WGPURenderPassEncoder encoder, WGPUShaderStage stages, uint32_t offset, uint32_t sizeBytes, void* const data);
4162

42-
#endif
63+
#endif

0 commit comments

Comments
 (0)