instance.zig (7128B)
1 const std = @import("std"); 2 3 const c = @import("c.zig").c; 4 const Adapter = @import("adapter.zig").Adapter; 5 const CallbackMode = @import("common.zig").CallbackMode; 6 const ChainedStruct = @import("common.zig").ChainedStruct; 7 const StringView = @import("common.zig").StringView; 8 const Surface = @import("surface.zig").Surface; 9 10 const RequestAdapterStatus = enum(u32) { 11 success = 0x00000001, 12 instance_dropped = 0x00000002, 13 unavailable = 0x00000003, 14 @"error" = 0x00000004, 15 unknown = 0x00000005, 16 }; 17 18 const RequestAdapterError = error{ 19 InstanceDropped, 20 Unavailable, 21 Error, 22 Unknown, 23 }; 24 25 pub const RequestAdapterOptions = extern struct { 26 next: ?*const ChainedStruct = null, 27 28 feature_level: FeatureLevel, 29 power_preference: PowerPreference, 30 force_fallback_adapter: bool, 31 backend_type: BackendType, 32 compatible_surface: ?*Surface, 33 34 const FeatureLevel = enum(u32) { 35 compatibility = 0x00000001, 36 core = 0x00000002, 37 }; 38 39 const PowerPreference = enum(u32) { 40 undefined = 0x00000000, 41 low_power = 0x00000001, 42 high_performance = 0x00000002, 43 }; 44 45 const BackendType = enum(u32) { 46 undefined = 0x00000000, 47 null = 0x00000001, 48 webgpu = 0x00000002, 49 d3d11 = 0x00000003, 50 d3d12 = 0x00000004, 51 metal = 0x00000005, 52 vulkan = 0x00000006, 53 opengl = 0x00000007, 54 opengles = 0x00000008, 55 }; 56 }; 57 58 pub const RequestAdapterCallbackInfo = extern struct { 59 next: ?*const ChainedStruct = null, 60 mode: CallbackMode, 61 callback: *const RequestAdapterCallback, 62 userdata1: ?*anyopaque, 63 userdata2: ?*anyopaque, 64 }; 65 66 pub const RequestAdapterCallback = fn ( 67 status: RequestAdapterStatus, 68 adapter: ?*Adapter, 69 message: StringView, 70 userdata1: ?*anyopaque, 71 userdata2: ?*anyopaque, 72 ) callconv(.C) void; 73 74 pub const Instance = opaque { 75 pub const Descriptor = extern struct { 76 pub const Next = extern union { 77 generic: ?*const ChainedStruct, 78 extras: *const Extras, 79 }; 80 next: Next = .{ .generic = null }, 81 features: Capabilities, 82 }; 83 84 pub const Extras = extern struct { 85 chain: ChainedStruct = .{ 86 .next = null, 87 .struct_type = .instance_extras, 88 }, 89 backends: Backends, 90 flags: Flags, 91 dx12_compiler: DX12Compiler, 92 gles3_minor_version: GLES3MinorVersion, 93 gl_fence_behavior: GLFenceBehavior, 94 dxil_path: ?[*:0]const u8, 95 dxc_path: ?[*:0]const u8, 96 dxc_max_shader_model: DXCMaxShaderModel, 97 98 pub const Backends = enum(u32) { 99 all = 0x00000000, 100 vulkan = 0x00000001, 101 gl = 0x00000002, 102 metal = 0x00000004, 103 dx12 = 0x00000008, 104 dx11 = 0x00000010, 105 browser_webgpu = 0x00000020, 106 primary = 0x0000002D, 107 secondary = 0x00000012, 108 }; 109 110 pub const Flags = enum(u32) { 111 default = 0x00000000, 112 debug = 0x00000001, 113 validation = 0x00000002, 114 discard_hal_labels = 0x00000004, 115 }; 116 117 pub const DX12Compiler = enum(u32) { 118 undefined = 0x00000000, 119 fxc = 0x00000001, 120 dxc = 0x00000002, 121 }; 122 123 pub const GLES3MinorVersion = enum(u32) { 124 automatic = 0x00000000, 125 version0 = 0x00000001, 126 version1 = 0x00000002, 127 version2 = 0x00000003, 128 }; 129 130 pub const GLFenceBehavior = enum(u32) { 131 normal = 0x00000000, 132 auto_finish = 0x00000001, 133 }; 134 135 pub const DXCMaxShaderModel = enum(u32) { 136 dxc_max_shader_model_v6_0 = 0x00000000, 137 dxc_max_shader_model_v6_1 = 0x00000001, 138 dxc_max_shader_model_v6_2 = 0x00000002, 139 dxc_max_shader_model_v6_3 = 0x00000003, 140 dxc_max_shader_model_v6_4 = 0x00000004, 141 dxc_max_shader_model_v6_5 = 0x00000005, 142 dxc_max_shader_model_v6_6 = 0x00000006, 143 dxc_max_shader_model_v6_7 = 0x00000007, 144 }; 145 }; 146 147 pub const Capabilities = extern struct { 148 next: ?*const ChainedStruct = null, 149 timed_wait_any_enable: bool, 150 timed_wait_any_max_count: usize, 151 }; 152 153 pub fn create(descriptor: ?*const Descriptor) ?*Instance { 154 return @ptrCast(c.wgpuCreateInstance(@ptrCast(descriptor))); 155 } 156 157 pub fn release(instance: *Instance) void { 158 c.wgpuInstanceRelease(@ptrCast(instance)); 159 } 160 161 pub fn createSurface( 162 instance: *Instance, 163 descriptor: *const Surface.Descriptor, 164 ) ?*Surface { 165 return @ptrCast(c.wgpuInstanceCreateSurface( 166 @ptrCast(instance), 167 @ptrCast(descriptor), 168 )); 169 } 170 171 pub fn requestAdapter( 172 instance: *Instance, 173 options: *const RequestAdapterOptions, 174 ) !*Adapter { 175 const RequestAdapterResponse = struct { 176 complete: bool = false, 177 status: RequestAdapterStatus, 178 adapter: ?*Adapter, 179 180 pub fn callback( 181 status: RequestAdapterStatus, 182 adapter: ?*Adapter, 183 message: StringView, 184 userdata1: ?*anyopaque, 185 userdata2: ?*anyopaque, 186 ) callconv(.C) void { 187 _ = userdata2; 188 const self: *@This() = @alignCast(@ptrCast(userdata1)); 189 switch (status) { 190 .success => {}, 191 else => { 192 std.log.err( 193 "failed to request adapter - {s}", 194 .{message.toSlice()}, 195 ); 196 }, 197 } 198 self.* = .{ 199 .status = status, 200 .adapter = adapter, 201 .complete = true, 202 }; 203 } 204 }; 205 206 var response: RequestAdapterResponse = undefined; 207 const callback = RequestAdapterCallbackInfo{ 208 .next = null, 209 .mode = .allow_spontaneous, 210 .callback = &RequestAdapterResponse.callback, 211 .userdata1 = &response, 212 .userdata2 = null, 213 }; 214 _ = c.wgpuInstanceRequestAdapter( 215 @ptrCast(instance), 216 @ptrCast(options), 217 @as(*const c.WGPURequestAdapterCallbackInfo, @ptrCast(&callback)).*, 218 ); 219 while (!response.complete) { 220 std.time.sleep(std.time.ns_per_s * 0.1); 221 } 222 switch (response.status) { 223 .success => return response.adapter.?, 224 .instance_dropped => { 225 return RequestAdapterError.InstanceDropped; 226 }, 227 .unavailable => { 228 return RequestAdapterError.Unavailable; 229 }, 230 .@"error" => { 231 return RequestAdapterError.Error; 232 }, 233 .unknown => { 234 return RequestAdapterError.Unknown; 235 }, 236 } 237 } 238 239 // hasWGSLLanguageFeature(...) 240 // reference(...) 241 };