zgpu

git clone git://git.electrosoup.com/zgpu
Log | Files | Refs | Submodules | README

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 };