implementing proper pipeline cache
This commit is contained in:
+72
-28
@@ -8,6 +8,7 @@ const VkError = @import("error_set.zig").VkError;
|
||||
const Device = @import("Device.zig");
|
||||
const PipelineCache = @import("PipelineCache.zig");
|
||||
const PipelineLayout = @import("PipelineLayout.zig");
|
||||
const RenderPass = @import("RenderPass.zig");
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .pipeline;
|
||||
@@ -108,6 +109,13 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
||||
var color_attachments: ?[]vk.PipelineColorBlendAttachmentState = null;
|
||||
errdefer if (color_attachments) |value| allocator.free(value);
|
||||
|
||||
const dynamic_state = try parseDynamicState(info.p_dynamic_state);
|
||||
const rasterizer_discard_enable = if (info.p_rasterization_state) |state|
|
||||
state.rasterizer_discard_enable == .true
|
||||
else
|
||||
false;
|
||||
const has_color_attachments, const has_depth_stencil_attachment = try renderPassAttachmentState(info);
|
||||
|
||||
return .{
|
||||
.owner = device,
|
||||
.vtable = undefined,
|
||||
@@ -144,8 +152,12 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
||||
},
|
||||
.viewport_state = .{
|
||||
.viewports = blk: {
|
||||
if (rasterizer_discard_enable or dynamic_state.viewport) {
|
||||
break :blk null;
|
||||
}
|
||||
if (info.p_viewport_state) |viewport_state| {
|
||||
if (viewport_state.p_viewports) |p_viewports| {
|
||||
if (viewport_state.viewport_count != 0) {
|
||||
const p_viewports = viewport_state.p_viewports orelse return VkError.ValidationFailed;
|
||||
const copy = allocator.dupe(vk.Viewport, p_viewports[0..viewport_state.viewport_count]) catch return VkError.OutOfHostMemory;
|
||||
viewports = copy;
|
||||
break :blk viewports;
|
||||
@@ -154,8 +166,12 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
||||
break :blk null;
|
||||
},
|
||||
.scissor = blk: {
|
||||
if (rasterizer_discard_enable or dynamic_state.scissor) {
|
||||
break :blk null;
|
||||
}
|
||||
if (info.p_viewport_state) |viewport_state| {
|
||||
if (viewport_state.p_scissors) |p_scissors| {
|
||||
if (viewport_state.scissor_count != 0) {
|
||||
const p_scissors = viewport_state.p_scissors orelse return VkError.ValidationFailed;
|
||||
const copy = allocator.dupe(vk.Rect2D, p_scissors[0..viewport_state.scissor_count]) catch return VkError.OutOfHostMemory;
|
||||
scissors = copy;
|
||||
break :blk scissors;
|
||||
@@ -171,9 +187,17 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
||||
.line_width = if (info.p_rasterization_state) |state| state.line_width else return VkError.ValidationFailed,
|
||||
},
|
||||
.color_blend = blk: {
|
||||
if (rasterizer_discard_enable or !has_color_attachments) {
|
||||
break :blk .{
|
||||
.attachments = null,
|
||||
.constants = .{ 0.0, 0.0, 0.0, 0.0 },
|
||||
};
|
||||
}
|
||||
|
||||
if (info.p_color_blend_state) |state| {
|
||||
break :blk .{
|
||||
.attachments = if (state.p_attachments) |attachments| blk_attachments: {
|
||||
.attachments = if (state.attachment_count != 0) blk_attachments: {
|
||||
const attachments = state.p_attachments orelse return VkError.ValidationFailed;
|
||||
color_attachments = allocator.dupe(vk.PipelineColorBlendAttachmentState, attachments[0..state.attachment_count]) catch return VkError.OutOfHostMemory;
|
||||
break :blk_attachments color_attachments;
|
||||
} else null,
|
||||
@@ -186,36 +210,56 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
||||
.constants = .{ 0.0, 0.0, 0.0, 0.0 },
|
||||
};
|
||||
},
|
||||
.depth_stencil = if (info.p_depth_stencil_state) |state| state.* else null,
|
||||
.dynamic_state = blk: {
|
||||
var state: DynamicState = .{};
|
||||
|
||||
if (info.p_dynamic_state) |dynamic_state| {
|
||||
if (dynamic_state.p_dynamic_states) |states| {
|
||||
for (states[0..dynamic_state.dynamic_state_count]) |info_state| {
|
||||
switch (info_state) {
|
||||
.viewport => state.viewport = true,
|
||||
.scissor => state.scissor = true,
|
||||
.line_width => state.line_width = true,
|
||||
.depth_bias => state.depth_bias = true,
|
||||
.blend_constants => state.blend_constants = true,
|
||||
.depth_bounds => state.depth_bounds = true,
|
||||
.stencil_compare_mask => state.stencil_compare_mask = true,
|
||||
.stencil_write_mask => state.stencil_write_mask = true,
|
||||
.stencil_reference => state.stencil_reference = true,
|
||||
else => return VkError.Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break :blk state;
|
||||
},
|
||||
.depth_stencil = if (rasterizer_discard_enable or !has_depth_stencil_attachment)
|
||||
null
|
||||
else if (info.p_depth_stencil_state) |state|
|
||||
state.*
|
||||
else
|
||||
null,
|
||||
.dynamic_state = dynamic_state,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn parseDynamicState(info: ?*const vk.PipelineDynamicStateCreateInfo) VkError!DynamicState {
|
||||
var state: DynamicState = .{};
|
||||
const dynamic_state = info orelse return state;
|
||||
if (dynamic_state.dynamic_state_count == 0) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const states = dynamic_state.p_dynamic_states orelse return VkError.ValidationFailed;
|
||||
for (states[0..dynamic_state.dynamic_state_count]) |info_state| {
|
||||
switch (info_state) {
|
||||
.viewport => state.viewport = true,
|
||||
.scissor => state.scissor = true,
|
||||
.line_width => state.line_width = true,
|
||||
.depth_bias => state.depth_bias = true,
|
||||
.blend_constants => state.blend_constants = true,
|
||||
.depth_bounds => state.depth_bounds = true,
|
||||
.stencil_compare_mask => state.stencil_compare_mask = true,
|
||||
.stencil_write_mask => state.stencil_write_mask = true,
|
||||
.stencil_reference => state.stencil_reference = true,
|
||||
else => return VkError.Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
fn renderPassAttachmentState(info: *const vk.GraphicsPipelineCreateInfo) VkError!struct { bool, bool } {
|
||||
if (info.render_pass == .null_handle) {
|
||||
return .{ true, true };
|
||||
}
|
||||
|
||||
const render_pass = try NonDispatchable(RenderPass).fromHandleObject(info.render_pass);
|
||||
return .{
|
||||
try render_pass.subpassHasColorAttachments(info.subpass),
|
||||
try render_pass.subpassHasDepthStencilAttachment(info.subpass),
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
switch (self.mode) {
|
||||
.compute => {},
|
||||
|
||||
Reference in New Issue
Block a user