diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d42faa5..b2b94f39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/ - `WGPUNativeLimits::maxMultiviewViewCount` @lisyarus - `WGPUNativeFeature_StorageTextureArrayNonUniformIndexing`, `WGPUNativeFeature_Multiview`, `WGPUNativeFeature_ShaderFloat32Atomic`, `WGPUNativeFeature_TextureAtomic`, `WGPUNativeFeature_TextureFormatP010`, `WGPUNativeFeature_PipelineCache`, `WGPUNativeFeature_ShaderInt64AtomicMinMax`, `WGPUNativeFeature_ShaderInt64AtomicAllOps`, `WGPUNativeFeature_TextureInt64Atomic`, `WGPUNativeFeature_ShaderBarycentrics`, `WGPUNativeFeature_SelectiveMultiview`, `WGPUNativeFeature_MultisampleArray`, `WGPUNativeFeature_CooperativeMatrix`, `WGPUNativeFeature_ShaderPerVertex`, `WGPUNativeFeature_ShaderDrawIndex`, `WGPUNativeFeature_AccelerationStructureBindingArray`, `WGPUNativeFeature_MemoryDecorationCoherent`, `WGPUNativeFeature_MemoryDecorationVolatile` @lisyarus - `wgpuCommandEncoderClearTexture` @lisyarus +- `wgpuDeviceCreateShaderModuleTrusted` @lisyarus ### Removed diff --git a/ffi/wgpu.h b/ffi/wgpu.h index aea7b896..3d3e8fde 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -1471,6 +1471,35 @@ typedef struct WGPUImageSubresourceRange { uint32_t arrayLayerCount; } WGPUImageSubresourceRange WGPU_STRUCTURE_ATTRIBUTE; +/** + * Describes how shader bound checks should be performed. + */ +typedef WGPUFlags WGPUShaderRuntimeChecks; + +static const WGPUShaderRuntimeChecks WGPUShaderRuntimeChecks_None = 0x0000000000000000; +/** + * Enforce bounds checks in shaders, even if the underlying driver doesn’t support doing so natively. + */ +static const WGPUShaderRuntimeChecks WGPUShaderRuntimeChecks_BoundsChecks = 0x0000000000000001; +/** + * If not set, the caller MUST ensure that all passed shaders do not contain any infinite loops. + */ +static const WGPUShaderRuntimeChecks WGPUShaderRuntimeChecks_ForceLoopBounding = 0x0000000000000002; +/** + * If not set, the caller MUST ensure that in all passed shaders every function operating on a ray + * query must obey these rules (functions using wgsl naming). + */ +static const WGPUShaderRuntimeChecks WGPUShaderRuntimeChecks_RayQueryInitializationTracking = 0x0000000000000004; +/** + * If not set, task shaders will not validate that the mesh shader grid they dispatch is within legal limits. + */ +static const WGPUShaderRuntimeChecks WGPUShaderRuntimeChecks_TaskShaderDispatchTracking = 0x0000000000000008; +/** + * If not set, mesh shaders won’t clamp the output primitives’ vertex indices, which can lead to + * undefined behavior and arbitrary memory access. + */ +static const WGPUShaderRuntimeChecks WGPUShaderRuntimeChecks_MeshShaderPrimitiveIndicesClamp = 0x0000000000000010; + #ifdef __cplusplus extern "C" { @@ -1543,6 +1572,8 @@ extern "C" void wgpuCommandEncoderClearTexture(WGPUCommandEncoder commandEncoder, WGPUTexture texture, WGPUImageSubresourceRange const * range); + WGPUShaderModule wgpuDeviceCreateShaderModuleTrusted(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor, WGPUShaderRuntimeChecks runtimeChecks); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/conv.rs b/src/conv.rs index 3411c537..5dd7312c 100644 --- a/src/conv.rs +++ b/src/conv.rs @@ -2017,6 +2017,24 @@ pub fn map_primitive_state( } } +pub fn map_shader_runtime_checks( + value: native::WGPUShaderRuntimeChecks, +) -> wgt::ShaderRuntimeChecks { + wgt::ShaderRuntimeChecks { + bounds_checks: (value & native::WGPUShaderRuntimeChecks_BoundsChecks) != 0, + force_loop_bounding: (value & native::WGPUShaderRuntimeChecks_ForceLoopBounding) != 0, + ray_query_initialization_tracking: (value + & native::WGPUShaderRuntimeChecks_RayQueryInitializationTracking) + != 0, + task_shader_dispatch_tracking: (value + & native::WGPUShaderRuntimeChecks_TaskShaderDispatchTracking) + != 0, + mesh_shader_primitive_indices_clamp: (value + & native::WGPUShaderRuntimeChecks_MeshShaderPrimitiveIndicesClamp) + != 0, + } +} + pub fn from_u64_bits>(value: u64) -> Option { if value > u32::MAX.into() { return None; diff --git a/src/lib.rs b/src/lib.rs index 7a349c62..8814ab94 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,8 @@ use conv::{ from_u64_bits, map_adapter_type, map_backend_type, map_bind_group_entry, map_bind_group_layout_entry, map_device_descriptor, map_instance_backend_flags, map_instance_descriptor, map_pipeline_layout_descriptor, map_query_set_descriptor, - map_query_set_index, map_shader_module, map_surface, map_surface_configuration, - CreateSurfaceParams, + map_query_set_index, map_shader_module, map_shader_runtime_checks, map_surface, + map_surface_configuration, CreateSurfaceParams, }; use parking_lot::Mutex; use smallvec::SmallVec; @@ -2453,10 +2453,11 @@ pub unsafe extern "C" fn wgpuDeviceCreateSampler( })) } -#[no_mangle] -pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( +unsafe fn create_shader_module_impl( device: native::WGPUDevice, descriptor: Option<&native::WGPUShaderModuleDescriptor>, + runtime_checks: wgt::ShaderRuntimeChecks, + fn_ident: &'static str, ) -> native::WGPUShaderModule { let (device_id, context, error_sink) = { let device = device.as_ref().expect("invalid device"); @@ -2474,12 +2475,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( ) { Ok(source) => source, Err(cause) => { - handle_error( - error_sink, - cause, - desc_label, - "wgpuDeviceCreateShaderModule", - ); + handle_error(error_sink, cause, desc_label, fn_ident); return Arc::into_raw(Arc::new(WGPUShaderModuleImpl { context: context.clone(), @@ -2490,18 +2486,13 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( let desc = wgc::pipeline::ShaderModuleDescriptor { label: desc_label, - runtime_checks: wgt::ShaderRuntimeChecks::default(), + runtime_checks, }; let (shader_module_id, error) = context.device_create_shader_module(device_id, &desc, source, None); if let Some(cause) = error { - handle_error( - error_sink, - cause, - desc.label, - "wgpuDeviceCreateShaderModule", - ); + handle_error(error_sink, cause, desc.label, fn_ident); } Arc::into_raw(Arc::new(WGPUShaderModuleImpl { @@ -2510,6 +2501,33 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( })) } +#[no_mangle] +pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( + device: native::WGPUDevice, + descriptor: Option<&native::WGPUShaderModuleDescriptor>, +) -> native::WGPUShaderModule { + create_shader_module_impl( + device, + descriptor, + wgt::ShaderRuntimeChecks::default(), + "wgpuDeviceCreateShaderModule", + ) +} + +#[no_mangle] +pub unsafe extern "C" fn wgpuDeviceCreateShaderModuleTrusted( + device: native::WGPUDevice, + descriptor: Option<&native::WGPUShaderModuleDescriptor>, + runtime_checks: native::WGPUShaderRuntimeChecks, +) -> native::WGPUShaderModule { + create_shader_module_impl( + device, + descriptor, + map_shader_runtime_checks(runtime_checks), + "wgpuDeviceCreateShaderModuleTrusted", + ) +} + #[no_mangle] pub unsafe extern "C" fn wgpuDeviceCreateTexture( device: native::WGPUDevice,