Experiment with subpasses
This commit is contained in:
parent
27689b8cda
commit
bd725421b6
12 changed files with 1848 additions and 41 deletions
13
assets/models/tescoPiwo.mtl
Normal file
13
assets/models/tescoPiwo.mtl
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Blender 4.2.0 MTL File: 'tescoPiwo.blend'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl Material.001
|
||||||
|
Ns 360.000000
|
||||||
|
Ka 0.500000 0.500000 0.500000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 3
|
||||||
|
map_Kd tescoPiwoTexture.png
|
||||||
|
map_Bump -bm 1.000000 /home/przmk/Downloads/Downloads/tescoPiwoNormal.png
|
1751
assets/models/tescoPiwo.obj
Normal file
1751
assets/models/tescoPiwo.obj
Normal file
File diff suppressed because it is too large
Load diff
BIN
assets/textures/tescoPiwoNormal.png
Normal file
BIN
assets/textures/tescoPiwoNormal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
BIN
assets/textures/tescoPiwoTexture.png
Normal file
BIN
assets/textures/tescoPiwoTexture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 179 KiB |
12
build.zig
12
build.zig
|
@ -1,6 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl = @import("libs/sdl/build.zig");
|
const sdl = @import("sdl");
|
||||||
const vkgen = @import("vulkan_zig");
|
const vkgen = @import("vulkan");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
|
@ -20,7 +20,7 @@ pub fn build(b: *std.Build) void {
|
||||||
// --- Dependencies ---
|
// --- Dependencies ---
|
||||||
|
|
||||||
// Vulkan
|
// Vulkan
|
||||||
const vkzig_dep = b.dependency("vulkan_zig", .{
|
const vkzig_dep = b.dependency("vulkan", .{
|
||||||
.registry = @as([]const u8, b.pathFromRoot("./vk.xml")),
|
.registry = @as([]const u8, b.pathFromRoot("./vk.xml")),
|
||||||
});
|
});
|
||||||
const vkzig_bindings = vkzig_dep.module("vulkan-zig");
|
const vkzig_bindings = vkzig_dep.module("vulkan-zig");
|
||||||
|
@ -34,12 +34,12 @@ pub fn build(b: *std.Build) void {
|
||||||
);
|
);
|
||||||
shader_comp.add("shader_frag", "src/shaders/shader.frag", .{});
|
shader_comp.add("shader_frag", "src/shaders/shader.frag", .{});
|
||||||
shader_comp.add("shader_vert", "src/shaders/shader.vert", .{});
|
shader_comp.add("shader_vert", "src/shaders/shader.vert", .{});
|
||||||
shader_comp.add("shader_frag", "src/shaders/second.frag", .{});
|
shader_comp.add("second_frag", "src/shaders/second.frag", .{});
|
||||||
shader_comp.add("shader_vert", "src/shaders/second.vert", .{});
|
shader_comp.add("second_vert", "src/shaders/second.vert", .{});
|
||||||
exe.root_module.addImport("shaders", shader_comp.getModule());
|
exe.root_module.addImport("shaders", shader_comp.getModule());
|
||||||
|
|
||||||
// SDL2
|
// SDL2
|
||||||
const sdl_sdk = sdl.init(b, null, null);
|
const sdl_sdk = sdl.init(b, .{});
|
||||||
sdl_sdk.link(exe, .dynamic, sdl.Library.SDL2);
|
sdl_sdk.link(exe, .dynamic, sdl.Library.SDL2);
|
||||||
exe.root_module.addImport("sdl2", sdl_sdk.getWrapperModuleVulkan(vkzig_bindings));
|
exe.root_module.addImport("sdl2", sdl_sdk.getWrapperModuleVulkan(vkzig_bindings));
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.zmath = .{ .path = "libs/zmath" },
|
.zmath = .{ .path = "libs/zmath" },
|
||||||
.zstbi = .{ .path = "libs/zstbi" },
|
.zstbi = .{ .path = "libs/zstbi" },
|
||||||
.vulkan_zig = .{
|
.sdl = .{ .path = "libs/sdl" },
|
||||||
.url = "https://github.com/Snektron/vulkan-zig/archive/18f38ef2b7ae394734bd8b28d43f120f2b9567c1.tar.gz",
|
.vulkan = .{
|
||||||
.hash = "1220530d62adb3f7ab87bacde31c302955a5803db52e302a0c7f8e107ca03f7aeca5",
|
.url = "https://github.com/Snektron/vulkan-zig/archive/f7b21d034f527765f62935de1b62855033621989.tar.gz",
|
||||||
|
.hash = "12201e484e173e70634e664864763223427703e677f28c63ebec9332513c8ca5121c",
|
||||||
},
|
},
|
||||||
.obj = .{
|
.obj = .{
|
||||||
.url = "https://github.com/chip2n/zig-obj/archive/58f524ed6834790b29ac1e97b2f9e6b7de7b5346.tar.gz",
|
.url = "https://github.com/chip2n/zig-obj/archive/58f524ed6834790b29ac1e97b2f9e6b7de7b5346.tar.gz",
|
||||||
|
|
2
libs/sdl
2
libs/sdl
|
@ -1 +1 @@
|
||||||
Subproject commit 9663dc70c19b13afcb4b9f596c928d7b2838e548
|
Subproject commit 172a84e7b5ce7d4891b8b970c68f4532f96aa7e9
|
|
@ -329,7 +329,7 @@ pub inline fn boolx16(
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
|
|
||||||
pub inline fn veclen(comptime T: type) comptime_int {
|
pub inline fn veclen(comptime T: type) comptime_int {
|
||||||
return @typeInfo(T).Vector.len;
|
return @typeInfo(T).vector.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn splat(comptime T: type, value: f32) T {
|
pub inline fn splat(comptime T: type, value: f32) T {
|
||||||
|
@ -413,14 +413,14 @@ pub inline fn storeArr4(arr: *[4]f32, v: F32x4) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn arr3Ptr(ptr: anytype) *const [3]f32 {
|
pub inline fn arr3Ptr(ptr: anytype) *const [3]f32 {
|
||||||
comptime assert(@typeInfo(@TypeOf(ptr)) == .Pointer);
|
comptime assert(@typeInfo(@TypeOf(ptr)) == .pointer);
|
||||||
const T = std.meta.Child(@TypeOf(ptr));
|
const T = std.meta.Child(@TypeOf(ptr));
|
||||||
comptime assert(T == F32x4);
|
comptime assert(T == F32x4);
|
||||||
return @as(*const [3]f32, @ptrCast(ptr));
|
return @as(*const [3]f32, @ptrCast(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn arrNPtr(ptr: anytype) [*]const f32 {
|
pub inline fn arrNPtr(ptr: anytype) [*]const f32 {
|
||||||
comptime assert(@typeInfo(@TypeOf(ptr)) == .Pointer);
|
comptime assert(@typeInfo(@TypeOf(ptr)) == .pointer);
|
||||||
const T = std.meta.Child(@TypeOf(ptr));
|
const T = std.meta.Child(@TypeOf(ptr));
|
||||||
comptime assert(T == Mat or T == F32x4 or T == F32x8 or T == F32x16);
|
comptime assert(T == Mat or T == F32x4 or T == F32x8 or T == F32x16);
|
||||||
return @as([*]const f32, @ptrCast(ptr));
|
return @as([*]const f32, @ptrCast(ptr));
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub fn main() !void {
|
||||||
var angle: f32 = 0.0;
|
var angle: f32 = 0.0;
|
||||||
const move_speed: f32 = 1000;
|
const move_speed: f32 = 1000;
|
||||||
|
|
||||||
const model_handle = try vulkan_renderer.createMeshModel("teapot.obj");
|
const model_handle = try vulkan_renderer.createMeshModel("tescoPiwo.obj");
|
||||||
|
|
||||||
mainLoop: while (true) {
|
mainLoop: while (true) {
|
||||||
while (sdl.pollEvent()) |ev| {
|
while (sdl.pollEvent()) |ev| {
|
||||||
|
|
|
@ -2,12 +2,21 @@
|
||||||
|
|
||||||
// Colour output from subpass 1
|
// Colour output from subpass 1
|
||||||
layout(input_attachment_index = 0, binding = 0) uniform subpassInput inputColour;
|
layout(input_attachment_index = 0, binding = 0) uniform subpassInput inputColour;
|
||||||
|
|
||||||
// Depth output from subpass 1
|
// Depth output from subpass 1
|
||||||
layout(input_attachment_index = 1, binding = 1) uniform subpassInput inputDepth;
|
layout(input_attachment_index = 1, binding = 1) uniform subpassInput inputDepth;
|
||||||
|
|
||||||
layout(location = 0) out vec4 colour;
|
layout(location = 0) out vec4 colour;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
colour = subpassLoad(inputColour).rgba;
|
int xHalf = 800 / 2;
|
||||||
|
if (gl_FragCoord.x > xHalf) {
|
||||||
|
float lowerBound = 0.98;
|
||||||
|
float upperBound = 1;
|
||||||
|
|
||||||
|
float depth = subpassLoad(inputDepth).r;
|
||||||
|
float depthColourScaled = 1.0f - ((depth - lowerBound) / (upperBound - lowerBound));
|
||||||
|
colour = vec4(subpassLoad(inputColour).rgb * depthColourScaled, 1.0f);
|
||||||
|
} else {
|
||||||
|
colour = subpassLoad(inputColour).rgba;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
vec2 positions[3] = vec2[](
|
vec2 positions[3] = vec2[](
|
||||||
vec2(3.0, -1.0),
|
vec2(3.0, -1.0),
|
||||||
vec2(-1.0, -1.0),
|
vec2(-1.0, -1.0),
|
||||||
vec2(-1.0, 3.0),
|
vec2(-1.0, 3.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
|
@ -101,7 +101,7 @@ pub const VulkanRenderer = struct {
|
||||||
input_descriptor_pool: vk.DescriptorPool,
|
input_descriptor_pool: vk.DescriptorPool,
|
||||||
descriptor_sets: []vk.DescriptorSet,
|
descriptor_sets: []vk.DescriptorSet,
|
||||||
sampler_descriptor_sets: std.ArrayList(vk.DescriptorSet),
|
sampler_descriptor_sets: std.ArrayList(vk.DescriptorSet),
|
||||||
input_descriptor_sets: std.ArrayList(vk.DescriptorSet),
|
input_descriptor_sets: []vk.DescriptorSet,
|
||||||
|
|
||||||
vp_uniform_buffer: []vk.Buffer,
|
vp_uniform_buffer: []vk.Buffer,
|
||||||
vp_uniform_buffer_memory: []vk.DeviceMemory,
|
vp_uniform_buffer_memory: []vk.DeviceMemory,
|
||||||
|
@ -167,7 +167,6 @@ pub const VulkanRenderer = struct {
|
||||||
try self.createCommandPool();
|
try self.createCommandPool();
|
||||||
|
|
||||||
self.sampler_descriptor_sets = try std.ArrayList(vk.DescriptorSet).initCapacity(self.allocator, self.swapchain_images.len);
|
self.sampler_descriptor_sets = try std.ArrayList(vk.DescriptorSet).initCapacity(self.allocator, self.swapchain_images.len);
|
||||||
self.input_descriptor_sets = try std.ArrayList(vk.DescriptorSet).initCapacity(self.allocator, self.swapchain_images.len);
|
|
||||||
|
|
||||||
try self.createCommandBuffers();
|
try self.createCommandBuffers();
|
||||||
try self.createTextureSampler();
|
try self.createTextureSampler();
|
||||||
|
@ -330,6 +329,7 @@ pub const VulkanRenderer = struct {
|
||||||
self.device.destroyDescriptorSetLayout(self.sampler_set_layout, null);
|
self.device.destroyDescriptorSetLayout(self.sampler_set_layout, null);
|
||||||
self.device.destroyDescriptorSetLayout(self.input_set_layout, null);
|
self.device.destroyDescriptorSetLayout(self.input_set_layout, null);
|
||||||
self.sampler_descriptor_sets.deinit();
|
self.sampler_descriptor_sets.deinit();
|
||||||
|
self.allocator.free(self.input_descriptor_sets);
|
||||||
|
|
||||||
for (0..self.swapchain_images.len) |i| {
|
for (0..self.swapchain_images.len) |i| {
|
||||||
self.device.destroyBuffer(self.vp_uniform_buffer[i], null);
|
self.device.destroyBuffer(self.vp_uniform_buffer[i], null);
|
||||||
|
@ -354,6 +354,8 @@ pub const VulkanRenderer = struct {
|
||||||
|
|
||||||
self.allocator.free(self.swapchain_framebuffers);
|
self.allocator.free(self.swapchain_framebuffers);
|
||||||
|
|
||||||
|
self.device.destroyPipeline(self.second_pipeline, null);
|
||||||
|
self.device.destroyPipelineLayout(self.second_pipeline_layout, null);
|
||||||
self.device.destroyPipeline(self.graphics_pipeline, null);
|
self.device.destroyPipeline(self.graphics_pipeline, null);
|
||||||
self.device.destroyPipelineLayout(self.pipeline_layout, null);
|
self.device.destroyPipelineLayout(self.pipeline_layout, null);
|
||||||
self.device.destroyRenderPass(self.render_pass, null);
|
self.device.destroyRenderPass(self.render_pass, null);
|
||||||
|
@ -556,7 +558,7 @@ pub const VulkanRenderer = struct {
|
||||||
fn createRenderPass(self: *Self) !void {
|
fn createRenderPass(self: *Self) !void {
|
||||||
// -- Attachments --
|
// -- Attachments --
|
||||||
|
|
||||||
const subpasses: [2]vk.SubpassDescription = undefined;
|
var subpasses: [2]vk.SubpassDescription = undefined;
|
||||||
|
|
||||||
// Subpass 1 attachments and references (input attachments)
|
// Subpass 1 attachments and references (input attachments)
|
||||||
|
|
||||||
|
@ -569,7 +571,7 @@ pub const VulkanRenderer = struct {
|
||||||
.{ .color_attachment_bit = true },
|
.{ .color_attachment_bit = true },
|
||||||
);
|
);
|
||||||
const colour_attachment: vk.AttachmentDescription = .{
|
const colour_attachment: vk.AttachmentDescription = .{
|
||||||
.format = colour_format,
|
.format = colour_format.?,
|
||||||
.samples = .{ .@"1_bit" = true },
|
.samples = .{ .@"1_bit" = true },
|
||||||
.load_op = .clear,
|
.load_op = .clear,
|
||||||
.store_op = .dont_care,
|
.store_op = .dont_care,
|
||||||
|
@ -657,7 +659,7 @@ pub const VulkanRenderer = struct {
|
||||||
// Need to determine when layout transitions occur using subpass dependencies
|
// Need to determine when layout transitions occur using subpass dependencies
|
||||||
const subpass_dependencies = [_]vk.SubpassDependency{
|
const subpass_dependencies = [_]vk.SubpassDependency{
|
||||||
// Conversion from VK_IMAGE_LAYOUT_UNDEFINED to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
// Conversion from VK_IMAGE_LAYOUT_UNDEFINED to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
vk.SubpassDependency{
|
.{
|
||||||
// Transition must happen after...
|
// Transition must happen after...
|
||||||
.src_subpass = vk.SUBPASS_EXTERNAL, // Subpass index (VK_SUBPASS_EXTERNAL = outside of renderpass)
|
.src_subpass = vk.SUBPASS_EXTERNAL, // Subpass index (VK_SUBPASS_EXTERNAL = outside of renderpass)
|
||||||
.src_stage_mask = .{ .bottom_of_pipe_bit = true }, // Pipeline stage
|
.src_stage_mask = .{ .bottom_of_pipe_bit = true }, // Pipeline stage
|
||||||
|
@ -677,7 +679,7 @@ pub const VulkanRenderer = struct {
|
||||||
.dst_access_mask = .{ .shader_read_bit = true },
|
.dst_access_mask = .{ .shader_read_bit = true },
|
||||||
},
|
},
|
||||||
// Conversion from VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
// Conversion from VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||||
vk.SubpassDependency{
|
.{
|
||||||
// Transition must happen after...
|
// Transition must happen after...
|
||||||
.src_subpass = 0,
|
.src_subpass = 0,
|
||||||
.src_stage_mask = .{ .color_attachment_output_bit = true },
|
.src_stage_mask = .{ .color_attachment_output_bit = true },
|
||||||
|
@ -840,7 +842,7 @@ pub const VulkanRenderer = struct {
|
||||||
self.extent.height,
|
self.extent.height,
|
||||||
self.depth_format,
|
self.depth_format,
|
||||||
.optimal,
|
.optimal,
|
||||||
.{ .depth_stencil_attachment_bit = true },
|
.{ .depth_stencil_attachment_bit = true, .input_attachment_bit = true },
|
||||||
.{ .device_local_bit = true },
|
.{ .device_local_bit = true },
|
||||||
&self.depth_buffer_image_memory[i],
|
&self.depth_buffer_image_memory[i],
|
||||||
);
|
);
|
||||||
|
@ -867,14 +869,14 @@ pub const VulkanRenderer = struct {
|
||||||
// -- Shader stage creation information --
|
// -- Shader stage creation information --
|
||||||
|
|
||||||
// Vertex stage creation information
|
// Vertex stage creation information
|
||||||
const vertex_shader_create_info: vk.PipelineShaderStageCreateInfo = .{
|
var vertex_shader_create_info: vk.PipelineShaderStageCreateInfo = .{
|
||||||
.stage = .{ .vertex_bit = true },
|
.stage = .{ .vertex_bit = true },
|
||||||
.module = vert,
|
.module = vert,
|
||||||
.p_name = "main",
|
.p_name = "main",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fragment stage creation information
|
// Fragment stage creation information
|
||||||
const fragment_shader_create_info: vk.PipelineShaderStageCreateInfo = .{
|
var fragment_shader_create_info: vk.PipelineShaderStageCreateInfo = .{
|
||||||
.stage = .{ .fragment_bit = true },
|
.stage = .{ .fragment_bit = true },
|
||||||
.module = frag,
|
.module = frag,
|
||||||
.p_name = "main",
|
.p_name = "main",
|
||||||
|
@ -920,7 +922,7 @@ pub const VulkanRenderer = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// -- Vertex input --
|
// -- Vertex input --
|
||||||
const vertex_input_create_info: vk.PipelineVertexInputStateCreateInfo = .{
|
var vertex_input_create_info: vk.PipelineVertexInputStateCreateInfo = .{
|
||||||
.vertex_binding_description_count = 1,
|
.vertex_binding_description_count = 1,
|
||||||
.p_vertex_binding_descriptions = @ptrCast(&binding_description), // List of vertex binding descriptions (data spacing, stride info)
|
.p_vertex_binding_descriptions = @ptrCast(&binding_description), // List of vertex binding descriptions (data spacing, stride info)
|
||||||
.vertex_attribute_description_count = @intCast(attribute_descriptions.len),
|
.vertex_attribute_description_count = @intCast(attribute_descriptions.len),
|
||||||
|
@ -1026,7 +1028,7 @@ pub const VulkanRenderer = struct {
|
||||||
self.pipeline_layout = try self.device.createPipelineLayout(&pipeline_layout_create_info, null);
|
self.pipeline_layout = try self.device.createPipelineLayout(&pipeline_layout_create_info, null);
|
||||||
|
|
||||||
// -- Depth stencil testing --
|
// -- Depth stencil testing --
|
||||||
const depth_stencil_create_info: vk.PipelineDepthStencilStateCreateInfo = .{
|
var depth_stencil_create_info: vk.PipelineDepthStencilStateCreateInfo = .{
|
||||||
.depth_test_enable = vk.TRUE, // Enable checking depth to determine fragment write
|
.depth_test_enable = vk.TRUE, // Enable checking depth to determine fragment write
|
||||||
.depth_write_enable = vk.TRUE, // Enable writing to depth buffer to replace all values
|
.depth_write_enable = vk.TRUE, // Enable writing to depth buffer to replace all values
|
||||||
.depth_compare_op = .less, // Comparison operation that allows an overwrite (is in front)
|
.depth_compare_op = .less, // Comparison operation that allows an overwrite (is in front)
|
||||||
|
@ -1039,7 +1041,7 @@ pub const VulkanRenderer = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// -- Graphics pipeline creation --
|
// -- Graphics pipeline creation --
|
||||||
const pipeline_create_info: vk.GraphicsPipelineCreateInfo = .{
|
var pipeline_create_info: vk.GraphicsPipelineCreateInfo = .{
|
||||||
.stage_count = @intCast(shader_create_infos.len), // Number of shader stages
|
.stage_count = @intCast(shader_create_infos.len), // Number of shader stages
|
||||||
.p_stages = &shader_create_infos, // List of shader stages
|
.p_stages = &shader_create_infos, // List of shader stages
|
||||||
.p_vertex_input_state = &vertex_input_create_info,
|
.p_vertex_input_state = &vertex_input_create_info,
|
||||||
|
@ -1070,13 +1072,13 @@ pub const VulkanRenderer = struct {
|
||||||
// Second pass shaders
|
// Second pass shaders
|
||||||
const second_vert_shader_module = try self.device.createShaderModule(&.{
|
const second_vert_shader_module = try self.device.createShaderModule(&.{
|
||||||
.code_size = shaders.second_vert.len,
|
.code_size = shaders.second_vert.len,
|
||||||
.p_code = @ptrCast(&shaders.shader_vert),
|
.p_code = @ptrCast(&shaders.second_vert),
|
||||||
}, null);
|
}, null);
|
||||||
defer self.device.destroyShaderModule(second_vert_shader_module, null);
|
defer self.device.destroyShaderModule(second_vert_shader_module, null);
|
||||||
|
|
||||||
const second_frag_shader_module = try self.device.createShaderModule(&.{
|
const second_frag_shader_module = try self.device.createShaderModule(&.{
|
||||||
.code_size = shaders.second_frag.len,
|
.code_size = shaders.second_frag.len,
|
||||||
.p_code = @ptrCast(&shaders.shader_frag),
|
.p_code = @ptrCast(&shaders.second_frag),
|
||||||
}, null);
|
}, null);
|
||||||
defer self.device.destroyShaderModule(second_frag_shader_module, null);
|
defer self.device.destroyShaderModule(second_frag_shader_module, null);
|
||||||
|
|
||||||
|
@ -1084,7 +1086,7 @@ pub const VulkanRenderer = struct {
|
||||||
vertex_shader_create_info.module = second_vert_shader_module;
|
vertex_shader_create_info.module = second_vert_shader_module;
|
||||||
fragment_shader_create_info.module = second_frag_shader_module;
|
fragment_shader_create_info.module = second_frag_shader_module;
|
||||||
|
|
||||||
const second_shader_stages = []vk.PipelineShaderStageCreateInfo{ vertex_shader_create_info, fragment_shader_create_info };
|
const second_shader_stages = [_]vk.PipelineShaderStageCreateInfo{ vertex_shader_create_info, fragment_shader_create_info };
|
||||||
|
|
||||||
// No vertex data for second pass
|
// No vertex data for second pass
|
||||||
vertex_input_create_info.vertex_binding_description_count = 0;
|
vertex_input_create_info.vertex_binding_description_count = 0;
|
||||||
|
@ -1098,7 +1100,7 @@ pub const VulkanRenderer = struct {
|
||||||
// Create new pipeline layout
|
// Create new pipeline layout
|
||||||
const second_pipeline_layout_create_info: vk.PipelineLayoutCreateInfo = .{
|
const second_pipeline_layout_create_info: vk.PipelineLayoutCreateInfo = .{
|
||||||
.set_layout_count = 1,
|
.set_layout_count = 1,
|
||||||
.p_set_layouts = @ptrCast(self.input_set_layout),
|
.p_set_layouts = @ptrCast(&self.input_set_layout),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.second_pipeline_layout = try self.device.createPipelineLayout(&second_pipeline_layout_create_info, null);
|
self.second_pipeline_layout = try self.device.createPipelineLayout(&second_pipeline_layout_create_info, null);
|
||||||
|
@ -1107,6 +1109,15 @@ pub const VulkanRenderer = struct {
|
||||||
pipeline_create_info.p_stages = &second_shader_stages;
|
pipeline_create_info.p_stages = &second_shader_stages;
|
||||||
pipeline_create_info.layout = self.second_pipeline_layout;
|
pipeline_create_info.layout = self.second_pipeline_layout;
|
||||||
pipeline_create_info.subpass = 1;
|
pipeline_create_info.subpass = 1;
|
||||||
|
|
||||||
|
// Create second pipeline
|
||||||
|
_ = try self.device.createGraphicsPipelines(
|
||||||
|
.null_handle,
|
||||||
|
1,
|
||||||
|
@ptrCast(&pipeline_create_info),
|
||||||
|
null,
|
||||||
|
@ptrCast(&self.second_pipeline),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createFramebuffers(self: *Self) !void {
|
fn createFramebuffers(self: *Self) !void {
|
||||||
|
@ -1282,7 +1293,7 @@ pub const VulkanRenderer = struct {
|
||||||
|
|
||||||
// Create input attachment pool
|
// Create input attachment pool
|
||||||
const input_pool_create_info: vk.DescriptorPoolCreateInfo = .{
|
const input_pool_create_info: vk.DescriptorPoolCreateInfo = .{
|
||||||
.max_sets = self.swapchain_images.len,
|
.max_sets = @intCast(self.swapchain_images.len),
|
||||||
.pool_size_count = @intCast(input_pool_sizes.len),
|
.pool_size_count = @intCast(input_pool_sizes.len),
|
||||||
.p_pool_sizes = &input_pool_sizes,
|
.p_pool_sizes = &input_pool_sizes,
|
||||||
};
|
};
|
||||||
|
@ -1341,6 +1352,8 @@ pub const VulkanRenderer = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createInputDescriptorSets(self: *Self) !void {
|
fn createInputDescriptorSets(self: *Self) !void {
|
||||||
|
self.input_descriptor_sets = try self.allocator.alloc(vk.DescriptorSet, self.swapchain_images.len);
|
||||||
|
|
||||||
// Fill array of layouts ready for set creation
|
// Fill array of layouts ready for set creation
|
||||||
var set_layouts = try self.allocator.alloc(vk.DescriptorSetLayout, self.swapchain_images.len);
|
var set_layouts = try self.allocator.alloc(vk.DescriptorSetLayout, self.swapchain_images.len);
|
||||||
defer self.allocator.free(set_layouts);
|
defer self.allocator.free(set_layouts);
|
||||||
|
@ -1352,46 +1365,50 @@ pub const VulkanRenderer = struct {
|
||||||
const set_alloc_info: vk.DescriptorSetAllocateInfo = .{
|
const set_alloc_info: vk.DescriptorSetAllocateInfo = .{
|
||||||
.descriptor_pool = self.input_descriptor_pool,
|
.descriptor_pool = self.input_descriptor_pool,
|
||||||
.descriptor_set_count = @intCast(self.swapchain_images.len),
|
.descriptor_set_count = @intCast(self.swapchain_images.len),
|
||||||
.p_set_layouts = &set_layouts,
|
.p_set_layouts = set_layouts.ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allocate descriptor sets
|
// Allocate descriptor sets
|
||||||
try self.device.allocateDescriptorSets(&set_alloc_info, self.input_descriptor_sets.items.ptr);
|
try self.device.allocateDescriptorSets(&set_alloc_info, self.input_descriptor_sets.ptr);
|
||||||
|
|
||||||
// Update each descriptor set with input attachment
|
// Update each descriptor set with input attachment
|
||||||
for (0..self.swapchain_images.len) |i| {
|
for (0..self.swapchain_images.len) |i| {
|
||||||
// Colour attachment descriptor
|
// Colour attachment descriptor
|
||||||
const colour_attachment_descriptor: vk.DescriptorImageInfo = .{
|
const colour_attachment_descriptor: vk.DescriptorImageInfo = .{
|
||||||
.image_layout = .read_only_optimal,
|
.image_layout = .shader_read_only_optimal,
|
||||||
.image_view = self.colour_buffer_image_view[i],
|
.image_view = self.colour_buffer_image_view[i],
|
||||||
.sampler = .null_handle,
|
.sampler = .null_handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Colour attachment descriptor write
|
// Colour attachment descriptor write
|
||||||
const colour_write: vk.WriteDescriptorSet = .{
|
const colour_write: vk.WriteDescriptorSet = .{
|
||||||
.dst_set = self.input_descriptor_sets.items[i],
|
.dst_set = self.input_descriptor_sets[i],
|
||||||
.dst_binding = 0,
|
.dst_binding = 0,
|
||||||
.dst_array_element = 0,
|
.dst_array_element = 0,
|
||||||
.descriptor_type = .input_attachment,
|
.descriptor_type = .input_attachment,
|
||||||
.descriptor_count = 1,
|
.descriptor_count = 1,
|
||||||
.p_image_info = @ptrCast(&colour_attachment_descriptor),
|
.p_image_info = @ptrCast(&colour_attachment_descriptor),
|
||||||
|
.p_buffer_info = undefined,
|
||||||
|
.p_texel_buffer_view = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Depth attachment descriptor
|
// Depth attachment descriptor
|
||||||
const depth_attachment_descriptor: vk.DescriptorImageInfo = .{
|
const depth_attachment_descriptor: vk.DescriptorImageInfo = .{
|
||||||
.image_layout = .read_only_optimal,
|
.image_layout = .shader_read_only_optimal,
|
||||||
.image_view = self.depth_buffer_image_view[i],
|
.image_view = self.depth_buffer_image_view[i],
|
||||||
.sampler = .null_handle,
|
.sampler = .null_handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Depth attachment descriptor write
|
// Depth attachment descriptor write
|
||||||
const depth_write: vk.WriteDescriptorSet = .{
|
const depth_write: vk.WriteDescriptorSet = .{
|
||||||
.dst_set = self.input_descriptor_sets.items[i],
|
.dst_set = self.input_descriptor_sets[i],
|
||||||
.dst_binding = 1,
|
.dst_binding = 1,
|
||||||
.dst_array_element = 0,
|
.dst_array_element = 0,
|
||||||
.descriptor_type = .input_attachment,
|
.descriptor_type = .input_attachment,
|
||||||
.descriptor_count = 1,
|
.descriptor_count = 1,
|
||||||
.p_image_info = @ptrCast(&depth_attachment_descriptor),
|
.p_image_info = @ptrCast(&depth_attachment_descriptor),
|
||||||
|
.p_buffer_info = undefined,
|
||||||
|
.p_texel_buffer_view = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
// List of input descriptor set writes
|
// List of input descriptor set writes
|
||||||
|
@ -1424,7 +1441,8 @@ pub const VulkanRenderer = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const clear_values = [_]vk.ClearValue{
|
const clear_values = [_]vk.ClearValue{
|
||||||
.{ .color = .{ .float_32 = [4]f32{ 0.6, 0.65, 0.4, 1.0 } } },
|
.{ .color = .{ .float_32 = .{ 0.0, 0.0, 0.0, 0.0 } } },
|
||||||
|
.{ .color = .{ .float_32 = .{ 0.6, 0.65, 0.4, 1.0 } } },
|
||||||
.{ .depth_stencil = .{ .depth = 1.0, .stencil = 1 } },
|
.{ .depth_stencil = .{ .depth = 1.0, .stencil = 1 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1498,6 +1516,21 @@ pub const VulkanRenderer = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start second subpass
|
||||||
|
command_buffer.nextSubpass(.@"inline");
|
||||||
|
|
||||||
|
command_buffer.bindPipeline(.graphics, self.second_pipeline);
|
||||||
|
command_buffer.bindDescriptorSets(
|
||||||
|
.graphics,
|
||||||
|
self.second_pipeline_layout,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
@ptrCast(&self.input_descriptor_sets[current_image]),
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
command_buffer.draw(3, 1, 0, 0);
|
||||||
|
|
||||||
// End render pass
|
// End render pass
|
||||||
command_buffer.endRenderPass();
|
command_buffer.endRenderPass();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue