Render and COmpute Pipelines now use a gloc and is tracked by Arena
This commit is contained in:
parent
af210e2fb2
commit
a06b040a29
@ -65,7 +65,7 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
|
|
||||||
const gloc = grena.gpuAllocator();
|
const gloc = grena.gpuAllocator();
|
||||||
|
|
||||||
const add_pip = try GpuCompute.init(device, @embedFile("shaders/add.wgsl"), .{ .bindings = &.{
|
const add_pip = try GpuCompute.init(gloc, @embedFile("shaders/add.wgsl"), .{ .bindings = &.{
|
||||||
.{ .element_size = @sizeOf(f16) },
|
.{ .element_size = @sizeOf(f16) },
|
||||||
.{ .element_size = @sizeOf(f16) },
|
.{ .element_size = @sizeOf(f16) },
|
||||||
.{ .element_size = @sizeOf(f16) },
|
.{ .element_size = @sizeOf(f16) },
|
||||||
|
|||||||
@ -10,6 +10,10 @@ const GpuTextureView = gpu.GpuTextureView;
|
|||||||
const width: u32 = 512;
|
const width: u32 = 512;
|
||||||
const height: u32 = 512;
|
const height: u32 = 512;
|
||||||
|
|
||||||
|
// Note: Everything using a GpuAllocator in init from an GpuAllocatorArena is safely
|
||||||
|
// tied to it which will automatically release them when deinit the arena itself.
|
||||||
|
// You can also manually call x.deinit() if desired.
|
||||||
|
|
||||||
pub fn main(init: std.process.Init) !void {
|
pub fn main(init: std.process.Init) !void {
|
||||||
const allocator = init.gpa;
|
const allocator = init.gpa;
|
||||||
|
|
||||||
@ -24,7 +28,7 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
|
|
||||||
// 3. Load Render Pipeline
|
// 3. Load Render Pipeline
|
||||||
const circle_rp = try GpuRender.init(
|
const circle_rp = try GpuRender.init(
|
||||||
device, // Change to gloc + track them
|
gloc,
|
||||||
@embedFile("shaders/circle.wgsl"),
|
@embedFile("shaders/circle.wgsl"),
|
||||||
.{ .bindings = &.{}, .texture_format = .RGBA8Unorm, .topology = .TriangleStrip },
|
.{ .bindings = &.{}, .texture_format = .RGBA8Unorm, .topology = .TriangleStrip },
|
||||||
);
|
);
|
||||||
@ -55,7 +59,6 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
|
|
||||||
// 9. Write a simple ppm image
|
// 9. Write a simple ppm image
|
||||||
try savePpm(init.io, "circle.ppm", width, height, pixels);
|
try savePpm(init.io, "circle.ppm", width, height, pixels);
|
||||||
std.debug.print("Successfully rendered circle to circle.ppm!\n", .{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn savePpm(io: std.Io, filename: []const u8, w: u32, h: u32, rgba_pixels: []const u8) !void {
|
fn savePpm(io: std.Io, filename: []const u8, w: u32, h: u32, rgba_pixels: []const u8) !void {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
|
|
||||||
// 3. Load the WGSL compute pipeline
|
// 3. Load the WGSL compute pipeline
|
||||||
const add_cp = try GpuCompute.init(
|
const add_cp = try GpuCompute.init(
|
||||||
device,
|
gloc,
|
||||||
@embedFile("shaders/add.wgsl"),
|
@embedFile("shaders/add.wgsl"),
|
||||||
.{ .bindings = &.{
|
.{ .bindings = &.{
|
||||||
.{ .element_size = @sizeOf(f16) },
|
.{ .element_size = @sizeOf(f16) },
|
||||||
|
|||||||
@ -8,6 +8,10 @@ pub const VTable = struct {
|
|||||||
freeTexture: *const fn (ctx: *anyopaque, buf_raw: c.WGPUTexture) void,
|
freeTexture: *const fn (ctx: *anyopaque, buf_raw: c.WGPUTexture) void,
|
||||||
allocTextureView: *const fn (ctx: *anyopaque, texture: c.WGPUTexture, desc: c.WGPUTextureViewDescriptor) anyerror!c.WGPUTextureView,
|
allocTextureView: *const fn (ctx: *anyopaque, texture: c.WGPUTexture, desc: c.WGPUTextureViewDescriptor) anyerror!c.WGPUTextureView,
|
||||||
freeTextureView: *const fn (ctx: *anyopaque, buf_raw: c.WGPUTextureView) void,
|
freeTextureView: *const fn (ctx: *anyopaque, buf_raw: c.WGPUTextureView) void,
|
||||||
|
allocRenderPipeline: *const fn (ctx: *anyopaque, desc: c.WGPURenderPipelineDescriptor) anyerror!c.WGPURenderPipeline,
|
||||||
|
freeRenderPipeline: *const fn (ctx: *anyopaque, buf_raw: c.WGPURenderPipeline) void,
|
||||||
|
allocComputePipeline: *const fn (ctx: *anyopaque, desc: c.WGPUComputePipelineDescriptor) anyerror!c.WGPUComputePipeline,
|
||||||
|
freeComputePipeline: *const fn (ctx: *anyopaque, buf_raw: c.WGPUComputePipeline) void,
|
||||||
};
|
};
|
||||||
|
|
||||||
device: GpuDevice,
|
device: GpuDevice,
|
||||||
@ -18,22 +22,38 @@ pub fn allocBuffer(self: @This(), desc: c.WGPUBufferDescriptor) !c.WGPUBuffer {
|
|||||||
return self.vtable.allocBuffer(self.ptr, desc);
|
return self.vtable.allocBuffer(self.ptr, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeBuffer(self: @This(), buf_raw: c.WGPUBuffer) void {
|
pub fn freeBuffer(self: @This(), raw: c.WGPUBuffer) void {
|
||||||
self.vtable.freeBuffer(self.ptr, buf_raw);
|
self.vtable.freeBuffer(self.ptr, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocTexture(self: @This(), desc: c.WGPUTextureDescriptor) !c.WGPUTexture {
|
pub fn allocTexture(self: @This(), desc: c.WGPUTextureDescriptor) !c.WGPUTexture {
|
||||||
return self.vtable.allocTexture(self.ptr, desc);
|
return self.vtable.allocTexture(self.ptr, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeTexture(self: @This(), buf_raw: c.WGPUTexture) void {
|
pub fn freeTexture(self: @This(), raw: c.WGPUTexture) void {
|
||||||
self.vtable.freeTexture(self.ptr, buf_raw);
|
self.vtable.freeTexture(self.ptr, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocTextureView(self: @This(), texture: c.WGPUTexture, desc: c.WGPUTextureViewDescriptor) !c.WGPUTextureView {
|
pub fn allocTextureView(self: @This(), texture: c.WGPUTexture, desc: c.WGPUTextureViewDescriptor) !c.WGPUTextureView {
|
||||||
return self.vtable.allocTextureView(self.ptr, texture, desc);
|
return self.vtable.allocTextureView(self.ptr, texture, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeTextureView(self: @This(), buf_raw: c.WGPUTextureView) void {
|
pub fn freeTextureView(self: @This(), raw: c.WGPUTextureView) void {
|
||||||
self.vtable.freeTextureView(self.ptr, buf_raw);
|
self.vtable.freeTextureView(self.ptr, raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allocRenderPipeline(self: @This(), desc: c.WGPURenderPipelineDescriptor) !c.WGPURenderPipeline {
|
||||||
|
return self.vtable.allocRenderPipeline(self.ptr, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn freeRenderPipeline(self: @This(), raw: c.WGPURenderPipeline) void {
|
||||||
|
self.vtable.freeRenderPipeline(self.ptr, raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allocComputePipeline(self: @This(), desc: c.WGPUComputePipelineDescriptor) !c.WGPUComputePipeline {
|
||||||
|
return self.vtable.allocComputePipeline(self.ptr, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn freeComputePipeline(self: @This(), raw: c.WGPUComputePipeline) void {
|
||||||
|
self.vtable.freeComputePipeline(self.ptr, raw);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@ device: GpuDevice,
|
|||||||
tracked_buffers: std.AutoHashMap(c.WGPUBuffer, c.WGPUBufferDescriptor),
|
tracked_buffers: std.AutoHashMap(c.WGPUBuffer, c.WGPUBufferDescriptor),
|
||||||
tracked_textures: std.AutoHashMap(c.WGPUTexture, c.WGPUTextureDescriptor),
|
tracked_textures: std.AutoHashMap(c.WGPUTexture, c.WGPUTextureDescriptor),
|
||||||
tracked_views: std.AutoHashMap(c.WGPUTextureView, c.WGPUTextureViewDescriptor),
|
tracked_views: std.AutoHashMap(c.WGPUTextureView, c.WGPUTextureViewDescriptor),
|
||||||
|
tracked_renders: std.AutoHashMap(c.WGPURenderPipeline, c.WGPURenderPipelineDescriptor),
|
||||||
|
tracked_computes: std.AutoHashMap(c.WGPUComputePipeline, c.WGPUComputePipelineDescriptor),
|
||||||
allocated_vram_bytes: u64 = 0,
|
allocated_vram_bytes: u64 = 0,
|
||||||
|
|
||||||
pub fn init(cpu_allocator: std.mem.Allocator, device: GpuDevice) @This() {
|
pub fn init(cpu_allocator: std.mem.Allocator, device: GpuDevice) @This() {
|
||||||
@ -16,26 +18,38 @@ pub fn init(cpu_allocator: std.mem.Allocator, device: GpuDevice) @This() {
|
|||||||
.tracked_buffers = .init(cpu_allocator),
|
.tracked_buffers = .init(cpu_allocator),
|
||||||
.tracked_textures = .init(cpu_allocator),
|
.tracked_textures = .init(cpu_allocator),
|
||||||
.tracked_views = .init(cpu_allocator),
|
.tracked_views = .init(cpu_allocator),
|
||||||
|
.tracked_computes = .init(cpu_allocator),
|
||||||
|
.tracked_renders = .init(cpu_allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
|
const gloc = self.gpuAllocator();
|
||||||
|
|
||||||
var it_buffer = self.tracked_buffers.keyIterator();
|
var it_buffer = self.tracked_buffers.keyIterator();
|
||||||
while (it_buffer.next()) |buf_ptr| {
|
while (it_buffer.next()) |buf_ptr|
|
||||||
c.wgpuBufferDestroy(buf_ptr.*);
|
gloc.freeBuffer(buf_ptr.*);
|
||||||
c.wgpuBufferRelease(buf_ptr.*);
|
|
||||||
}
|
|
||||||
self.tracked_buffers.deinit();
|
self.tracked_buffers.deinit();
|
||||||
|
|
||||||
var it_texture = self.tracked_textures.keyIterator();
|
var it_tex = self.tracked_textures.keyIterator();
|
||||||
while (it_texture.next()) |tex_ptr|
|
while (it_tex.next()) |buf_ptr|
|
||||||
c.wgpuTextureRelease(tex_ptr.*);
|
gloc.freeTexture(buf_ptr.*);
|
||||||
self.tracked_textures.deinit();
|
self.tracked_textures.deinit();
|
||||||
|
|
||||||
var it_view = self.tracked_views.keyIterator();
|
var it_view = self.tracked_views.keyIterator();
|
||||||
while (it_view.next()) |view_ptr|
|
while (it_view.next()) |buf_ptr|
|
||||||
c.wgpuTextureViewRelease(view_ptr.*);
|
gloc.freeTextureView(buf_ptr.*);
|
||||||
self.tracked_views.deinit();
|
self.tracked_views.deinit();
|
||||||
|
|
||||||
|
var it_render = self.tracked_renders.keyIterator();
|
||||||
|
while (it_render.next()) |buf_ptr|
|
||||||
|
gloc.freeRenderPipeline(buf_ptr.*);
|
||||||
|
self.tracked_renders.deinit();
|
||||||
|
|
||||||
|
var it_compute = self.tracked_computes.keyIterator();
|
||||||
|
while (it_compute.next()) |buf_ptr|
|
||||||
|
gloc.freeComputePipeline(buf_ptr.*);
|
||||||
|
self.tracked_computes.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type-erased immutable interface wrapper
|
/// Returns the type-erased immutable interface wrapper
|
||||||
@ -50,12 +64,20 @@ pub fn gpuAllocator(self: *@This()) GpuAllocator {
|
|||||||
.freeTexture = freeTexture,
|
.freeTexture = freeTexture,
|
||||||
.allocTextureView = allocTextureView,
|
.allocTextureView = allocTextureView,
|
||||||
.freeTextureView = freeTextureView,
|
.freeTextureView = freeTextureView,
|
||||||
|
.allocRenderPipeline = allocRenderPipeline,
|
||||||
|
.freeRenderPipeline = freeRenderPipeline,
|
||||||
|
.allocComputePipeline = allocComputePipeline,
|
||||||
|
.freeComputePipeline = freeComputePipeline,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: I use ensureTotalCapacity so I know that try self.tracked_x.put will not fail!
|
||||||
|
// Like that I dont have to use errdefer to release what I just allocated in VRAM
|
||||||
|
|
||||||
fn allocBuffer(ctx: *anyopaque, desc: c.WGPUBufferDescriptor) anyerror!c.WGPUBuffer {
|
fn allocBuffer(ctx: *anyopaque, desc: c.WGPUBufferDescriptor) anyerror!c.WGPUBuffer {
|
||||||
const self: *@This() = @ptrCast(@alignCast(ctx));
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
try self.tracked_buffers.ensureTotalCapacity(self.tracked_buffers.count() + 1);
|
||||||
|
|
||||||
if (desc.size > self.device.limits.maxBufferSize)
|
if (desc.size > self.device.limits.maxBufferSize)
|
||||||
return error.SingleBufferExceedsLimit;
|
return error.SingleBufferExceedsLimit;
|
||||||
@ -63,15 +85,11 @@ fn allocBuffer(ctx: *anyopaque, desc: c.WGPUBufferDescriptor) anyerror!c.WGPUBuf
|
|||||||
if (desc.size + self.allocated_vram_bytes > self.device.config.vram_bytes_limit)
|
if (desc.size + self.allocated_vram_bytes > self.device.config.vram_bytes_limit)
|
||||||
return error.ExceedsVramBudget;
|
return error.ExceedsVramBudget;
|
||||||
|
|
||||||
const buf = c.wgpuDeviceCreateBuffer(self.device.device, &desc) orelse return error.BufferAlloc;
|
const raw = c.wgpuDeviceCreateBuffer(self.device.device, &desc) orelse return error.BufferAlloc;
|
||||||
errdefer {
|
|
||||||
c.wgpuBufferDestroy(buf);
|
|
||||||
c.wgpuBufferRelease(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
try self.tracked_buffers.put(buf, desc);
|
self.tracked_buffers.putAssumeCapacity(raw, desc);
|
||||||
self.allocated_vram_bytes += desc.size;
|
self.allocated_vram_bytes += desc.size;
|
||||||
return buf;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeBuffer(ctx: *anyopaque, raw: c.WGPUBuffer) void {
|
fn freeBuffer(ctx: *anyopaque, raw: c.WGPUBuffer) void {
|
||||||
@ -86,6 +104,7 @@ fn freeBuffer(ctx: *anyopaque, raw: c.WGPUBuffer) void {
|
|||||||
|
|
||||||
fn allocTexture(ctx: *anyopaque, desc: c.WGPUTextureDescriptor) anyerror!c.WGPUTexture {
|
fn allocTexture(ctx: *anyopaque, desc: c.WGPUTextureDescriptor) anyerror!c.WGPUTexture {
|
||||||
const self: *@This() = @ptrCast(@alignCast(ctx));
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
try self.tracked_textures.ensureTotalCapacity(self.tracked_textures.count() + 1);
|
||||||
|
|
||||||
const format: GpuTextureFormat = @enumFromInt(desc.format);
|
const format: GpuTextureFormat = @enumFromInt(desc.format);
|
||||||
const bytes_size = desc.size.width * desc.size.height * format.bytesPerPixel();
|
const bytes_size = desc.size.width * desc.size.height * format.bytesPerPixel();
|
||||||
@ -95,11 +114,11 @@ fn allocTexture(ctx: *anyopaque, desc: c.WGPUTextureDescriptor) anyerror!c.WGPUT
|
|||||||
if (bytes_size + self.allocated_vram_bytes > self.device.config.vram_bytes_limit)
|
if (bytes_size + self.allocated_vram_bytes > self.device.config.vram_bytes_limit)
|
||||||
return error.ExceedsVramBudget;
|
return error.ExceedsVramBudget;
|
||||||
|
|
||||||
const texture = c.wgpuDeviceCreateTexture(self.device.device, &desc) orelse return error.Texture;
|
const raw = c.wgpuDeviceCreateTexture(self.device.device, &desc) orelse return error.Texture;
|
||||||
|
|
||||||
try self.tracked_textures.put(texture, desc);
|
self.tracked_textures.putAssumeCapacity(raw, desc);
|
||||||
self.allocated_vram_bytes += bytes_size;
|
self.allocated_vram_bytes += bytes_size;
|
||||||
return texture;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeTexture(ctx: *anyopaque, raw: c.WGPUTexture) void {
|
fn freeTexture(ctx: *anyopaque, raw: c.WGPUTexture) void {
|
||||||
@ -117,9 +136,10 @@ fn freeTexture(ctx: *anyopaque, raw: c.WGPUTexture) void {
|
|||||||
|
|
||||||
fn allocTextureView(ctx: *anyopaque, texture: c.WGPUTexture, desc: c.WGPUTextureViewDescriptor) anyerror!c.WGPUTextureView {
|
fn allocTextureView(ctx: *anyopaque, texture: c.WGPUTexture, desc: c.WGPUTextureViewDescriptor) anyerror!c.WGPUTextureView {
|
||||||
const self: *@This() = @ptrCast(@alignCast(ctx));
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
const view = c.wgpuTextureCreateView(texture, &desc) orelse return error.View;
|
try self.tracked_views.ensureTotalCapacity(self.tracked_views.count() + 1);
|
||||||
try self.tracked_views.put(view, desc);
|
const raw = c.wgpuTextureCreateView(texture, &desc) orelse return error.View;
|
||||||
return view;
|
self.tracked_views.putAssumeCapacity(raw, desc);
|
||||||
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeTextureView(ctx: *anyopaque, raw: c.WGPUTextureView) void {
|
fn freeTextureView(ctx: *anyopaque, raw: c.WGPUTextureView) void {
|
||||||
@ -127,3 +147,31 @@ fn freeTextureView(ctx: *anyopaque, raw: c.WGPUTextureView) void {
|
|||||||
if (self.tracked_views.remove(raw))
|
if (self.tracked_views.remove(raw))
|
||||||
c.wgpuTextureViewRelease(raw);
|
c.wgpuTextureViewRelease(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn allocRenderPipeline(ctx: *anyopaque, desc: c.WGPURenderPipelineDescriptor) anyerror!c.WGPURenderPipeline {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
try self.tracked_renders.ensureTotalCapacity(self.tracked_renders.count() + 1);
|
||||||
|
const raw = c.wgpuDeviceCreateRenderPipeline(self.device.device, &desc) orelse return error.Pipeline;
|
||||||
|
self.tracked_renders.putAssumeCapacity(raw, desc);
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn freeRenderPipeline(ctx: *anyopaque, raw: c.WGPURenderPipeline) void {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
if (self.tracked_renders.remove(raw))
|
||||||
|
c.wgpuRenderPipelineRelease(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allocComputePipeline(ctx: *anyopaque, desc: c.WGPUComputePipelineDescriptor) anyerror!c.WGPUComputePipeline {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
try self.tracked_computes.ensureTotalCapacity(self.tracked_computes.count() + 1);
|
||||||
|
const raw = c.wgpuDeviceCreateComputePipeline(self.device.device, &desc) orelse return error.Pipeline;
|
||||||
|
self.tracked_computes.putAssumeCapacity(raw, desc);
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn freeComputePipeline(ctx: *anyopaque, raw: c.WGPUComputePipeline) void {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
if (self.tracked_computes.remove(raw))
|
||||||
|
c.wgpuComputePipelineRelease(raw);
|
||||||
|
}
|
||||||
|
|||||||
@ -20,30 +20,30 @@ pub const ComputeDef = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pip: c.WGPUComputePipeline,
|
pip: c.WGPUComputePipeline,
|
||||||
|
gloc: GpuAllocator,
|
||||||
def: ComputeDef,
|
def: ComputeDef,
|
||||||
|
|
||||||
pub fn init(device: GpuDevice, wgsl: []const u8, def: ComputeDef) !@This() {
|
pub fn init(gloc: GpuAllocator, wgsl: []const u8, def: ComputeDef) !@This() {
|
||||||
var wgsl_src = c.WGPUShaderSourceWGSL{
|
var wgsl_src = c.WGPUShaderSourceWGSL{
|
||||||
.chain = .{ .sType = c.WGPUSType_ShaderSourceWGSL },
|
.chain = .{ .sType = c.WGPUSType_ShaderSourceWGSL },
|
||||||
.code = sv(wgsl),
|
.code = sv(wgsl),
|
||||||
};
|
};
|
||||||
const shader = c.wgpuDeviceCreateShaderModule(device.device, &.{
|
const shader = c.wgpuDeviceCreateShaderModule(gloc.device.device, &.{
|
||||||
.nextInChain = @ptrCast(&wgsl_src),
|
.nextInChain = @ptrCast(&wgsl_src),
|
||||||
}) orelse return error.Shader;
|
}) orelse return error.Shader;
|
||||||
defer c.wgpuShaderModuleRelease(shader);
|
defer c.wgpuShaderModuleRelease(shader);
|
||||||
|
|
||||||
const pip = c.wgpuDeviceCreateComputePipeline(device.device, &.{
|
const pip = try gloc.allocComputePipeline(.{ .compute = .{ .module = shader, .entryPoint = sv("main") } });
|
||||||
.compute = .{ .module = shader, .entryPoint = sv("main") },
|
|
||||||
}) orelse return error.Pipeline;
|
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
.gloc = gloc,
|
||||||
.pip = pip,
|
.pip = pip,
|
||||||
.def = def,
|
.def = def,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: @This()) void {
|
pub fn deinit(self: @This()) void {
|
||||||
c.wgpuComputePipelineRelease(self.pip);
|
self.gloc.freeComputePipeline(self.pip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the compute pass with arbitrary buffer bindings via a tuple.
|
/// Execute the compute pass with arbitrary buffer bindings via a tuple.
|
||||||
|
|||||||
@ -32,15 +32,16 @@ const GpuPrimitiveTopology = enum(c_uint) {
|
|||||||
Force32 = 0x7FFFFFFF,
|
Force32 = 0x7FFFFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gloc: GpuAllocator,
|
||||||
pip: c.WGPURenderPipeline,
|
pip: c.WGPURenderPipeline,
|
||||||
def: GpuRenderDef,
|
def: GpuRenderDef,
|
||||||
|
|
||||||
pub fn init(device: GpuDevice, wgsl: []const u8, def: GpuRenderDef) !@This() {
|
pub fn init(gloc: GpuAllocator, wgsl: []const u8, def: GpuRenderDef) !@This() {
|
||||||
var wgsl_src = c.WGPUShaderSourceWGSL{
|
var wgsl_src = c.WGPUShaderSourceWGSL{
|
||||||
.chain = .{ .sType = c.WGPUSType_ShaderSourceWGSL },
|
.chain = .{ .sType = c.WGPUSType_ShaderSourceWGSL },
|
||||||
.code = sv(wgsl),
|
.code = sv(wgsl),
|
||||||
};
|
};
|
||||||
const shader = c.wgpuDeviceCreateShaderModule(device.device, &.{
|
const shader = c.wgpuDeviceCreateShaderModule(gloc.device.device, &.{
|
||||||
.nextInChain = @ptrCast(&wgsl_src),
|
.nextInChain = @ptrCast(&wgsl_src),
|
||||||
}) orelse return error.Shader;
|
}) orelse return error.Shader;
|
||||||
defer c.wgpuShaderModuleRelease(shader);
|
defer c.wgpuShaderModuleRelease(shader);
|
||||||
@ -66,7 +67,7 @@ pub fn init(device: GpuDevice, wgsl: []const u8, def: GpuRenderDef) !@This() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 3. Compile the Complete Render Pipeline
|
// 3. Compile the Complete Render Pipeline
|
||||||
const pip = c.wgpuDeviceCreateRenderPipeline(device.device, &.{
|
const pip = try gloc.allocRenderPipeline(.{
|
||||||
.vertex = .{
|
.vertex = .{
|
||||||
.module = shader,
|
.module = shader,
|
||||||
.entryPoint = sv(def.vertex_entry),
|
.entryPoint = sv(def.vertex_entry),
|
||||||
@ -83,16 +84,17 @@ pub fn init(device: GpuDevice, wgsl: []const u8, def: GpuRenderDef) !@This() {
|
|||||||
.alphaToCoverageEnabled = 0,
|
.alphaToCoverageEnabled = 0,
|
||||||
},
|
},
|
||||||
.fragment = &fragment_state,
|
.fragment = &fragment_state,
|
||||||
}) orelse return error.Pipeline;
|
});
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
.gloc = gloc,
|
||||||
.pip = pip,
|
.pip = pip,
|
||||||
.def = def,
|
.def = def,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: @This()) void {
|
pub fn deinit(self: @This()) void {
|
||||||
c.wgpuRenderPipelineRelease(self.pip);
|
self.gloc.freeRenderPipeline(self.pip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the render pass targeting a specific frame texture view.
|
/// Execute the render pass targeting a specific frame texture view.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user