commit ebcb28db0fb23a7e6e145e90d501a54205e4f4c6
parent 1c586261735d810e29d99a1070ea06d959077057
Author: Christian Ermann <christianermann@gmail.com>
Date: Sun, 1 Jun 2025 15:50:18 -0700
Add shaders
Diffstat:
11 files changed, 608 insertions(+), 18 deletions(-)
diff --git a/src/bind_group_layout.zig b/src/bind_group_layout.zig
@@ -0,0 +1,81 @@
+const c = @import("c.zig").c;
+const ChainedStruct = @import("common.zig").ChainedStruct;
+const StringView = @import("common.zig").StringView;
+const Texture = @import("texture.zig").Texture;
+const TextureView = @import("texture_view.zig").TextureView;
+
+pub const BindGroupLayout = opaque {
+ const Descriptor = extern struct {
+ next: ?*ChainedStruct = null,
+ label: StringView,
+ entry_count: usize,
+ entries: ?[*]const Entry,
+ };
+
+ const Entry = extern struct {
+ next: ?*ChainedStruct = null,
+ binding: u32,
+ visibility: ShaderStage,
+ buffer: BufferBindingLayout,
+ sampler: SamplerBindingLayout,
+ texture: TextureBindingLayout,
+ storage_texture: StorageTextureBindingLayout,
+
+ const ShaderStage = packed struct(u64) {
+ vertex: bool = false,
+ fragment: bool = false,
+ compute: bool = false,
+ _padding: u61 = 0,
+ };
+
+ const BufferBindingLayout = extern struct {
+ next: ?*ChainedStruct = null,
+ type: BufferBindingType,
+ has_dynamic_offset: bool,
+ min_binding_size: u64,
+
+ const BufferBindingType = enum(u32) {
+ binding_not_used = 0x00000000,
+ undefined = 0x00000001,
+ uniform = 0x00000002,
+ storage = 0x00000003,
+ read_only_storage = 0x00000004,
+ };
+ };
+
+ const SamplerBindingLayout = extern struct {
+ next: ?*ChainedStruct = null,
+ type: SamplerBindingType,
+
+ const SamplerBindingType = enum(u32) {
+ binding_not_used = 0x00000000,
+ undefined = 0x00000001,
+ filtering = 0x00000002,
+ non_filtering = 0x00000003,
+ comparison = 0x00000004,
+ };
+ };
+
+ const TextureBindingLayout = extern struct {
+ next: ?*ChainedStruct = null,
+ sample_type: Texture.SampleType,
+ view_dimension: TextureView.Dimension,
+ multisampled: bool,
+ };
+
+ const StorageTextureBindingLayout = extern struct {
+ next: ?*ChainedStruct = null,
+ access: StorageTextureAccess,
+ format: Texture.Format,
+ view_dimension: TextureView.Dimension,
+
+ const StorageTextureAccess = enum(u32) {
+ binding_not_used = 0x00000000,
+ undefined = 0x00000001,
+ write_only = 0x00000002,
+ read_only = 0x00000003,
+ read_write = 0x00000004,
+ };
+ };
+ };
+};
diff --git a/src/callback.zig b/src/callback.zig
@@ -1,4 +1,5 @@
const std = @import("std");
+const Device = @import("device.zig").Device;
const StringView = @import("common.zig").StringView;
fn CallbackType1(comptime T: type) type {
@@ -29,17 +30,17 @@ pub fn Callback1(
}.wrapped_callback;
}
-fn CallbackType2(comptime T: type) type {
+fn DeviceCallbackType(comptime T: type) type {
const enum_type = switch (@typeInfo(T)) {
.@"fn" => |f| f.params[0].type.?,
else => unreachable,
};
- return fn (enum_type, StringView, ?*anyopaque, ?*anyopaque) callconv(.C) void;
+ return fn (*const Device, enum_type, StringView, ?*anyopaque, ?*anyopaque) callconv(.C) void;
}
-pub fn Callback2(
+pub fn DeviceCallback(
user_callback: anytype,
-) CallbackType2(@TypeOf(user_callback)) {
+) DeviceCallbackType(@TypeOf(user_callback)) {
const enum_type = switch (@typeInfo(@TypeOf(user_callback))) {
.@"fn" => |f| f.params[0].type.?,
else => @compileError("callback must be a function"),
@@ -47,11 +48,13 @@ pub fn Callback2(
return struct {
const callback = user_callback;
fn wrapped_callback(
+ device: *const Device,
enum_value: enum_type,
message: StringView,
userdata1: ?*anyopaque,
userdata2: ?*anyopaque,
) callconv(.C) void {
+ _ = device;
_ = userdata1;
_ = userdata2;
callback(enum_value, message.toSlice());
diff --git a/src/common.zig b/src/common.zig
@@ -67,6 +67,12 @@ pub const StringView = extern struct {
}
};
+pub const OptionalBool = enum(u32) {
+ false = 0x00000000,
+ true = 0x00000001,
+ undefined = 0x00000002,
+};
+
pub const CallbackMode = enum(u32) {
wait_any_only = 0x00000001,
allow_process_events = 0x00000002,
@@ -96,3 +102,21 @@ pub const Color = extern struct {
b: f64,
a: f64,
};
+
+pub const IndexFormat = enum(u32) {
+ undefined = 0x00000000,
+ uint16 = 0x00000001,
+ uint32 = 0x00000002,
+};
+
+pub const CompareFunction = enum(u32) {
+ undefined = 0x00000000,
+ never = 0x00000001,
+ less = 0x00000002,
+ equal = 0x00000003,
+ less_equal = 0x00000004,
+ greater = 0x00000005,
+ not_equal = 0x00000006,
+ greater_equal = 0x00000007,
+ always = 0x00000008,
+};
diff --git a/src/device.zig b/src/device.zig
@@ -4,7 +4,10 @@ const c = @import("c.zig").c;
const CallbackMode = @import("common.zig").CallbackMode;
const ChainedStruct = @import("common.zig").ChainedStruct;
const CommandEncoder = @import("command_encoder.zig").CommandEncoder;
+const PipelineLayout = @import("pipeline_layout.zig").PipelineLayout;
const Queue = @import("queue.zig").Queue;
+const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
+const ShaderModule = @import("shader_module.zig").ShaderModule;
const StringView = @import("common.zig").StringView;
pub const FeatureName = enum(u32) {
@@ -74,6 +77,7 @@ pub const DeviceLostReason = enum(u32) {
};
pub const DeviceLostCallback = fn (
+ device: *const Device,
reason: DeviceLostReason,
message: StringView,
userdata1: ?*anyopaque,
@@ -96,7 +100,8 @@ pub const ErrorType = enum(u32) {
unknown = 0x00000005,
};
-pub const ErrorCallback = fn (
+pub const UncapturedErrorCallback = fn (
+ device: *const Device,
@"type": ErrorType,
message: StringView,
userdata1: ?*anyopaque,
@@ -105,7 +110,7 @@ pub const ErrorCallback = fn (
pub const UncapturedErrorCallbackInfo = extern struct {
next: ?*const ChainedStruct = null,
- callback: ?*const ErrorCallback,
+ callback: ?*const UncapturedErrorCallback,
userdata1: ?*anyopaque,
userdata2: ?*anyopaque,
};
@@ -140,16 +145,44 @@ pub const Device = opaque {
));
}
+ pub fn createRenderPipeline(
+ device: *Device,
+ descriptor: *const RenderPipeline.Descriptor,
+ ) ?*RenderPipeline {
+ return @ptrCast(c.wgpuDeviceCreateRenderPipeline(
+ @ptrCast(device),
+ @ptrCast(descriptor),
+ ));
+ }
+
+ pub fn createPipelineLayout(
+ device: *Device,
+ descriptor: *const PipelineLayout.Descriptor,
+ ) ?*PipelineLayout {
+ return @ptrCast(c.wgpuDeviceCreatePipelineLayout(
+ @ptrCast(device),
+ @ptrCast(descriptor),
+ ));
+ }
+
+ pub fn createShaderModule(
+ device: *Device,
+ descriptor: *const ShaderModule.Descriptor,
+ ) ?*ShaderModule {
+ return @ptrCast(c.wgpuDeviceCreateShaderModule(
+ @ptrCast(device),
+ @ptrCast(descriptor),
+ ));
+ }
+
// createBindGroup
// createBindGroupLayout
// createBuffer
- // createCommandEncoder
// createComputePipeline
// createComputePipelineAsync
// createPipelineLayout
// createQuerySet
// createRenderBundleEncoder
- // createRenderPipeline
// createRenderPipelineAsync
// createSampler
// createShaderModule
@@ -157,7 +190,6 @@ pub const Device = opaque {
// destroy
// enumerateFeatures
// getLimits
- // getQueue
// hasFeature
// popErrorScope
// pushErrorScope
diff --git a/src/logging.zig b/src/logging.zig
@@ -5,7 +5,7 @@ const StringView = @import("common.zig").StringView;
pub const LogLevel = enum(u32) {
off = 0x00000000,
- err = 0x00000001,
+ @"error" = 0x00000001,
warn = 0x00000002,
info = 0x00000003,
debug = 0x00000004,
diff --git a/src/main.zig b/src/main.zig
@@ -1,17 +1,17 @@
const std = @import("std");
+const Callback1 = @import("callback.zig").Callback1;
+const DeviceCallback = @import("callback.zig").DeviceCallback;
+const CommandBuffer = @import("command_buffer.zig").CommandBuffer;
+const Device = @import("device.zig");
const glfw = @import("glfw.zig");
const Instance = @import("instance.zig").Instance;
const Logging = @import("logging.zig");
-const Device = @import("device.zig");
-const Callback1 = @import("callback.zig").Callback1;
-const Callback2 = @import("callback.zig").Callback2;
-const CommandBuffer = @import("command_buffer.zig").CommandBuffer;
const StringView = @import("common.zig").StringView;
-pub fn zgpu_log_callback(level: Logging.LogLevel, message: []const u8) void {
+fn zgpu_log_callback(level: Logging.LogLevel, message: []const u8) void {
switch (level) {
- .err => {
+ .@"error" => {
std.log.err("[wgpu] {s}", .{message});
},
.warn => {
@@ -109,13 +109,13 @@ pub fn main() !void {
.label = StringView.fromSlice("Example Default Queue"),
},
.device_lost_callback_info = .{
- .callback = Callback2(zgpu_device_lost_callback),
+ .callback = DeviceCallback(zgpu_device_lost_callback),
.mode = .allow_spontaneous,
.userdata1 = null,
.userdata2 = null,
},
.uncaptured_error_callback_info = .{
- .callback = Callback2(zgpu_error_callback),
+ .callback = DeviceCallback(zgpu_error_callback),
.userdata1 = null,
.userdata2 = null,
},
@@ -137,6 +137,105 @@ pub fn main() !void {
.present_mode = .fifo,
});
+ const vs =
+ \\ @vertex fn main(
+ \\ @builtin(vertex_index) vtx_idx : u32
+ \\ ) -> @builtin(position) vec4<f32> {
+ \\ let x = f32(i32(vtx_idx) - 1);
+ \\ let y = f32(i32(vtx_idx & 1u) * 2 - 1);
+ \\ return vec4<f32>(x, y, 0.0, 1.0);
+ \\ }
+ ;
+ const vs_module = device.createShaderModule(&.{
+ .next = .{ .wgsl = &.{ .code = StringView.fromSlice(vs) } },
+ .label = StringView.fromSlice("Example Vertex Shader"),
+ }) orelse {
+ std.log.err("failed to compile vertex shader", .{});
+ std.process.exit(1);
+ };
+ defer vs_module.release();
+
+ const fs =
+ \\ @fragment fn main() -> @location(0) vec4<f32> {
+ \\ return vec4<f32>(1.0, 0.0, 0.0, 1.0);
+ \\ }
+ ;
+ const fs_module = device.createShaderModule(&.{
+ .next = .{ .wgsl = &.{ .code = StringView.fromSlice(fs) } },
+ .label = StringView.fromSlice("Example Fragment Shader"),
+ }) orelse {
+ std.log.err("failed to compile fragment shader", .{});
+ std.process.exit(1);
+ };
+ defer fs_module.release();
+
+ const pipeline_layout = device.createPipelineLayout(&.{
+ .label = StringView.fromSlice("Example Pipeline Layout"),
+ .bind_group_layout_count = 0,
+ .bind_group_layouts = null,
+ }).?;
+ defer pipeline_layout.release();
+
+ const pipeline = device.createRenderPipeline(&.{
+ .label = StringView.fromSlice("Example Render Pipeline"),
+ .layout = pipeline_layout,
+ .vertex = .{
+ .module = vs_module,
+ .entry_point = StringView.fromSlice("main"),
+ .constant_count = 0,
+ .constants = null,
+ .buffer_count = 0,
+ .buffers = null,
+ },
+ .primitive = .{
+ .topology = .triangle_list,
+ .strip_index_format = .undefined,
+ .front_face = .ccw,
+ .cull_mode = .none,
+ .unclipped_depth = false,
+ },
+ .depth_stencil = null,
+ .multisample = .{
+ .count = 1,
+ .mask = 0xFFFFFFFF,
+ .alpha_to_coverage_enabled = false,
+ },
+ .fragment_state = &.{
+ .module = fs_module,
+ .entry_point = StringView.fromSlice("main"),
+ .constant_count = 0,
+ .constants = null,
+ .target_count = 1,
+ .targets = &.{
+ .{
+ .format = .bgra8_unorm,
+ .blend = &.{
+ .color = .{
+ .operation = .add,
+ .src_factor = .one,
+ .dst_factor = .zero,
+ },
+ .alpha = .{
+ .operation = .add,
+ .src_factor = .one,
+ .dst_factor = .zero,
+ },
+ },
+ .write_mask = .{
+ .red = true,
+ .green = true,
+ .blue = true,
+ .alpha = true,
+ },
+ },
+ },
+ },
+ }) orelse {
+ std.log.err("failed to create render pipeline", .{});
+ std.process.exit(1);
+ };
+ defer pipeline.release();
+
while (!window.shouldClose()) {
glfw.pollEvents();
const current_texture = surface.getCurrentTexture();
@@ -176,6 +275,10 @@ pub fn main() !void {
.occlusion_query_set = null,
.timestamp_writes = null,
});
+
+ pass.setPipeline(pipeline);
+ pass.draw(3, 1, 0, 0);
+
defer pass.release();
defer pass.end();
}
diff --git a/src/pipeline_layout.zig b/src/pipeline_layout.zig
@@ -0,0 +1,20 @@
+const c = @import("c.zig").c;
+const BindGroupLayout = @import("bind_group_layout.zig").BindGroupLayout;
+const ChainedStruct = @import("common.zig").ChainedStruct;
+const StringView = @import("common.zig").StringView;
+
+pub const PipelineLayout = opaque {
+ pub const Descriptor = extern struct {
+ next: ?*ChainedStruct = null,
+ label: StringView,
+ bind_group_layout_count: u64,
+ bind_group_layouts: ?*const BindGroupLayout,
+ };
+
+ pub fn release(pipeline_layout: *PipelineLayout) void {
+ c.wgpuPipelineLayoutRelease(@ptrCast(pipeline_layout));
+ }
+
+ // setLabel
+ // reference
+};
diff --git a/src/render_pass.zig b/src/render_pass.zig
@@ -2,6 +2,7 @@ const c = @import("c.zig").c;
const ChainedStruct = @import("common.zig").ChainedStruct;
const Color = @import("common.zig").Color;
const LoadOp = @import("common.zig").LoadOp;
+const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
const StoreOp = @import("common.zig").StoreOp;
const StringView = @import("common.zig").StringView;
const TextureView = @import("texture_view.zig").TextureView;
@@ -59,4 +60,30 @@ pub const RenderPassEncoder = opaque {
pub fn end(encoder: *RenderPassEncoder) void {
c.wgpuRenderPassEncoderEnd(@ptrCast(encoder));
}
+
+ pub fn setPipeline(
+ encoder: *RenderPassEncoder,
+ pipeline: *RenderPipeline,
+ ) void {
+ c.wgpuRenderPassEncoderSetPipeline(
+ @ptrCast(encoder),
+ @ptrCast(pipeline),
+ );
+ }
+
+ pub fn draw(
+ encoder: *RenderPassEncoder,
+ vertex_count: u32,
+ instance_count: u32,
+ first_vertex: u32,
+ first_instance: u32,
+ ) void {
+ c.wgpuRenderPassEncoderDraw(
+ @ptrCast(encoder),
+ vertex_count,
+ instance_count,
+ first_vertex,
+ first_instance,
+ );
+ }
};
diff --git a/src/render_pipeline.zig b/src/render_pipeline.zig
@@ -0,0 +1,247 @@
+const c = @import("c.zig").c;
+const ChainedStruct = @import("common.zig").ChainedStruct;
+const CompareFunction = @import("common.zig").CompareFunction;
+const IndexFormat = @import("common.zig").IndexFormat;
+const OptionalBool = @import("common.zig").OptionalBool;
+const PipelineLayout = @import("pipeline_layout.zig").PipelineLayout;
+const ShaderModule = @import("shader_module.zig").ShaderModule;
+const StringView = @import("common.zig").StringView;
+const Texture = @import("texture.zig").Texture;
+
+const VertexState = extern struct {
+ next: ?*ChainedStruct = null,
+ module: *ShaderModule,
+ entry_point: StringView,
+ constant_count: usize,
+ constants: ?[*]const ConstantEntry,
+ buffer_count: usize,
+ buffers: ?[*]const VertexBufferLayout,
+
+ const VertexBufferLayout = extern struct {
+ step_mode: VertexStepMode,
+ array_stride: u64,
+ attribute_count: usize,
+ attributes: ?[*]VertexAttribute,
+
+ const VertexStepMode = enum(u32) {
+ vertex_buffer_not_used = 0x00000000,
+ undefined = 0x00000001,
+ vertex = 0x00000002,
+ instance = 0x00000003,
+ };
+
+ const VertexAttribute = extern struct {
+ format: VertexFormat,
+ offset: u64,
+ shader_location: u32,
+ };
+
+ const VertexFormat = enum(u32) {
+ uint8 = 0x00000001,
+ uint8x2 = 0x00000002,
+ uint8x4 = 0x00000003,
+ sint8 = 0x00000004,
+ sint8x2 = 0x00000005,
+ sint8x4 = 0x00000006,
+ unorm8 = 0x00000007,
+ unorm8x2 = 0x00000008,
+ unorm8x4 = 0x00000009,
+ snorm = 0x0000000A,
+ snorm8x2 = 0x0000000B,
+ snorm8x4 = 0x0000000C,
+ uint16 = 0x0000000D,
+ uint16x2 = 0x0000000E,
+ uint16x4 = 0x0000000F,
+ sint16 = 0x00000010,
+ sint16x2 = 0x00000011,
+ sint16x4 = 0x00000012,
+ unorm16 = 0x00000013,
+ unorm16x2 = 0x00000014,
+ unorm16x4 = 0x00000015,
+ snorm16 = 0x00000016,
+ snorm16x2 = 0x00000017,
+ snorm16x4 = 0x00000018,
+ float16 = 0x00000019,
+ float16x2 = 0x0000001A,
+ float16x4 = 0x0000001B,
+ float32 = 0x0000001C,
+ float32x2 = 0x0000001D,
+ float32x3 = 0x0000001E,
+ float32x4 = 0x0000001F,
+ uint32 = 0x00000020,
+ uint32x2 = 0x00000021,
+ uint32x3 = 0x00000022,
+ uint32x4 = 0x00000023,
+ sint32 = 0x00000024,
+ sint32x2 = 0x00000025,
+ sint32x3 = 0x00000026,
+ sint32x4 = 0x00000027,
+ unorm10_10_10_2 = 0x00000028,
+ unorm8x4_brga = 0x00000029,
+ };
+ };
+};
+
+const FragmentState = extern struct {
+ next: ?*ChainedStruct = null,
+ module: *ShaderModule,
+ entry_point: StringView,
+ constant_count: usize,
+ constants: ?[*]const ConstantEntry,
+ target_count: usize,
+ targets: ?[*]const ColorTargetState,
+
+ const ColorTargetState = extern struct {
+ next: ?*ChainedStruct = null,
+ format: Texture.Format,
+ blend: ?*const BlendState,
+ write_mask: ColorWriteMask,
+
+ const BlendState = extern struct {
+ color: BlendComponent,
+ alpha: BlendComponent,
+ };
+
+ const BlendComponent = extern struct {
+ operation: BlendOperation,
+ src_factor: BlendFactor,
+ dst_factor: BlendFactor,
+ };
+
+ const BlendOperation = enum(u32) {
+ undefined = 0x00000000,
+ add = 0x00000001,
+ subtract = 0x00000002,
+ reverse_subtract = 0x00000003,
+ min = 0x00000004,
+ max = 0x00000005,
+ };
+
+ const BlendFactor = enum(u32) {
+ undefined = 0x00000000,
+ zero = 0x00000001,
+ one = 0x00000002,
+ src = 0x00000003,
+ one_minus_src = 0x00000004,
+ src_alpha = 0x00000005,
+ one_minus_src_alpha = 0x00000006,
+ dst = 0x00000007,
+ one_minus_dst = 0x00000008,
+ dst_alpha = 0x00000009,
+ one_minus_dst_alpha = 0x0000000A,
+ src_alpha_saturated = 0x0000000B,
+ constant = 0x0000000C,
+ one_minus_constant = 0x0000000D,
+ src1 = 0x0000000E,
+ one_minus_src1 = 0x0000000F,
+ src1_alpha = 0x00000010,
+ one_minus_src1_alpha = 0x00000011,
+ };
+
+ const ColorWriteMask = packed struct(u64) {
+ red: bool = false,
+ green: bool = false,
+ blue: bool = false,
+ alpha: bool = false,
+ _padding: u60 = 0,
+ };
+ };
+};
+
+const ConstantEntry = extern struct {
+ next: ?*ChainedStruct = null,
+ key: StringView,
+ value: f64,
+};
+
+const PrimitiveState = extern struct {
+ next: ?*ChainedStruct = null,
+ topology: PrimitiveTopology,
+ strip_index_format: IndexFormat,
+ front_face: FrontFace,
+ cull_mode: CullMode,
+ unclipped_depth: bool,
+
+ const PrimitiveTopology = enum(u32) {
+ undefined = 0x00000000,
+ point_list = 0x00000001,
+ line_list = 0x00000002,
+ line_strip = 0x00000003,
+ triangle_list = 0x00000004,
+ triangle_strip = 0x00000005,
+ };
+
+ const FrontFace = enum(u32) {
+ undefined = 0x00000000,
+ ccw = 0x00000001,
+ cw = 0x00000002,
+ };
+
+ const CullMode = enum(u32) {
+ undefined = 0x00000000,
+ none = 0x00000001,
+ front = 0x00000002,
+ back = 0x00000003,
+ };
+};
+
+const DepthStencilState = extern struct {
+ next: ?*ChainedStruct = null,
+ format: Texture.Format,
+ depth_write_enabled: OptionalBool,
+ depth_compare: CompareFunction,
+ stencil_front: StencilFaceState,
+ stencil_back: StencilFaceState,
+ stencil_read_mask: u32,
+ stencil_write_mask: u32,
+ depth_bias: i32,
+ depth_bias_slope_scale: f32,
+ depth_bias_clamp: f32,
+
+ const StencilFaceState = extern struct {
+ compare: CompareFunction,
+ fail_op: StencilOperation,
+ depth_fail_op: StencilOperation,
+ pass_op: StencilOperation,
+ };
+
+ const StencilOperation = enum(u32) {
+ undefined = 0x00000000,
+ keep = 0x00000001,
+ zero = 0x00000002,
+ replace = 0x00000003,
+ invert = 0x00000004,
+ increment_clamp = 0x00000005,
+ decrement_clamp = 0x00000006,
+ increment_wrap = 0x00000007,
+ decrement_wrap = 0x00000008,
+ };
+};
+
+const MultisampleState = extern struct {
+ next: ?*ChainedStruct = null,
+ count: u32,
+ mask: u32,
+ alpha_to_coverage_enabled: bool,
+};
+
+pub const RenderPipeline = opaque {
+ pub const Descriptor = extern struct {
+ next: ?*ChainedStruct = null,
+ label: StringView,
+ layout: ?*const PipelineLayout,
+ vertex: VertexState,
+ primitive: PrimitiveState,
+ depth_stencil: ?*const DepthStencilState,
+ multisample: MultisampleState,
+ fragment_state: ?*const FragmentState,
+ };
+
+ pub fn release(pipeline: *RenderPipeline) void {
+ c.wgpuRenderPipelineRelease(@ptrCast(pipeline));
+ }
+
+ // getBindGroupLayout
+ // setLabel
+ // reference
+};
diff --git a/src/shader_module.zig b/src/shader_module.zig
@@ -0,0 +1,43 @@
+const c = @import("c.zig").c;
+const ChainedStruct = @import("common.zig").ChainedStruct;
+const PipelineLayout = @import("pipeline_layout.zig").PipelineLayout;
+const StringView = @import("common.zig").StringView;
+
+pub const ShaderModule = opaque {
+ pub const Descriptor = extern struct {
+ next: Next = .{ .generic = null },
+ label: StringView,
+
+ pub const Next = extern union {
+ generic: ?*const ChainedStruct,
+ spirv: *const SourceSPIRV,
+ wgsl: *const SourceWGSL,
+ };
+ };
+
+ const SourceSPIRV = extern struct {
+ chain: ChainedStruct = .{
+ .next = null,
+ .struct_type = .shader_source_spirv,
+ },
+ code_size: u32,
+ code: ?[*]const u32,
+ };
+
+ const SourceWGSL = extern struct {
+ chain: ChainedStruct = .{
+ .next = null,
+ .struct_type = .shader_source_wgsl,
+ },
+ code: StringView,
+ };
+
+ pub fn release(module: *ShaderModule) void {
+ c.wgpuShaderModuleRelease(@ptrCast(module));
+ }
+
+ // getCompilationInfo
+ // setLabel
+ // reference
+ // release
+};
diff --git a/src/texture.zig b/src/texture.zig
@@ -116,6 +116,16 @@ pub const Texture = opaque {
_padding: u59 = 0,
};
+ pub const SampleType = enum(u32) {
+ binding_not_used = 0x00000000,
+ undefined = 0x00000001,
+ float = 0x00000002,
+ unfilterable_float = 0x00000003,
+ depth = 0x00000004,
+ sint = 0x00000005,
+ uint = 0x00000006,
+ };
+
pub fn createView(
texture: *Texture,
descriptor: *const TextureView.Descriptor,