diff --git a/src/rendering/vulkan/Bindings.zig b/src/rendering/vulkan/Bindings.zig index fb28671..a3c571d 100644 --- a/src/rendering/vulkan/Bindings.zig +++ b/src/rendering/vulkan/Bindings.zig @@ -6,12 +6,70 @@ const Device = @import("device.zig").Device; const ProfileMark = @import("../../common/profiler.zig").ProfileMark; const settings = @import("settings.zig"); const Swapchain = @import("swapchain.zig").Swapchain; +const descriptor = @import("descriptor.zig"); +var s_layout = vk.DescriptorSetLayout.null_handle; +var s_pool = vk.DescriptorPool.null_handle; var s_sets = std.mem.zeroes([settings.resource_sets]vk.DescriptorSet); var s_writes = std.mem.zeroes([settings.Bid.Count]vk.WriteDescriptorSet); var s_bindings = std.mem.zeroes([settings.Bid.Count]Binding); var s_dirty = std.mem.zeroes([settings.Bid.Count]i32); +const bindings = [_]settings.Bid{ + settings.Bid.TextureTable.T1D, + settings.Bid.TextureTable.T2D, + settings.Bid.TextureTable.T3D, + settings.Bid.TextureTable.TCube, + settings.Bid.TextureTable.T2DArray, + settings.Bid.Globals, + settings.Bid.SceneLuminance, + settings.Bid.RWSceneLuminance, + settings.Bid.HistogramBuffer, + settings.Bid.ExposureBuffer, +}; + +pub const set_layout_bindings = LayoutBindings(); +fn LayoutBindings() [bindings.len]vk.DescriptorSetLayoutBinding { + assert(bindings.len == settings.Bid.Count); + inline for (set_layout_bindings) |*b, i| { + b.* = .{ + .binding = bindings[i].id, + .descriptor_type = bindings[i].desc_type, + .descriptor_count = bindings[i].count, + .stage_flags = bindings[i].stages, + }; + } +} + +const pm_init = ProfileMark.init("Bindings.init"); +pub fn init(device: *const Device) !void { + pm_init.begin(); + defer pm_init.end(); + + errdefer deinit(device); + s_layout = try descriptor.Set.Layout.init(device, set_layout_bindings); + s_pool = try descriptor.Pool.init(device, descriptor.Pool.sizes); + + for (s_sets) |*set| { + set.* = try descriptor.Set.init(device, s_pool, s_layout); + } +} + +pub fn deinit(device: *const Device) void { + if (s_pool != .null_handle) { + for (s_sets) |*set| { + descriptor.Set.deinit(device, s_pool, set); + set.* = .null_handle; + } + + descriptor.Set.Layout.deinit(device, s_pool); + s_pool = .null_handle; + } + + descriptor.Set.Layout.deinit(device, s_layout); + s_layout = .null_handle; +} + const pm_update = ProfileMark.init("Bindings.update"); pub fn update(device: *const Device, swapchain: *const Swapchain) void { pm_update.begin(); @@ -32,6 +90,11 @@ pub fn getSet(swapchain: *const Swapchain) vk.DescriptorSet { return s_sets[sync_index]; } +pub fn getSetLayout() vk.DescriptorSetLayout { + assert(s_layout != .null_handle); + return s_layout; +} + const pm_flush = ProfileMark.init("Bindings.flush"); pub fn flush(device: *const Device, swapchain: *const Swapchain) void { pm_flush.begin(); diff --git a/src/rendering/vulkan/Command.zig b/src/rendering/vulkan/Command.zig index b61d369..36d7300 100644 --- a/src/rendering/vulkan/Command.zig +++ b/src/rendering/vulkan/Command.zig @@ -224,9 +224,9 @@ pub const Buffer = struct { assert(self.handle != .null_handle); assert(self.gfx or self.comp); assert(pass.pipeline != .null_handle); - device.dispatch.cmdBindPipeline(self.handle, pass.bindpoint, pass.pipeline); + device.dispatch.cmdBindPipeline(self.handle, pass.bind_point, pass.pipeline); const set = Bindings.getSet(swapchain); - self.bindDescSets(device, pass.bindpoint, pass.layout, 1, @ptrCast([*]const vk.DescriptorSet, &set)); + self.bindDescSets(device, pass.bind_point, pass.layout, 1, @ptrCast([*]const vk.DescriptorSet, &set)); } const pm_buffer_beginrenderpass = ProfileMark.init("Command.Buffer.beginRenderPass"); diff --git a/src/rendering/vulkan/MainPass.zig b/src/rendering/vulkan/MainPass.zig index f66de60..a8bc47a 100644 --- a/src/rendering/vulkan/MainPass.zig +++ b/src/rendering/vulkan/MainPass.zig @@ -22,7 +22,7 @@ const PushConstants = struct { pub fn init(device: *const Device, swapchain: *Swapchain) !void { errdefer { std.debug.print("Failed to init MainPass", .{}); - deinit(); + deinit(device); } // try ScreenBlit.init() @@ -32,9 +32,9 @@ pub fn init(device: *const Device, swapchain: *Swapchain) !void { // try UIPass.init(); } -pub fn deinit() void { +pub fn deinit(device: *const Device) void { // ScreenBlit.deinit() - DepthPass.deinit(); + DepthPass.deinit(device); OpaquePass.deinit(); // Exposure.deinit(); // UIPass.deinit(); @@ -69,7 +69,7 @@ const DepthPass = struct { var s_pass: Pass = undefined; pub fn init(device: *const Device, swapchain: *Swapchain) !void { - errdefer DepthPass.deinit(); + errdefer DepthPass.deinit(device); const depth_buffer = Targets.getDepthBuffer(swapchain); @@ -114,7 +114,7 @@ const DepthPass = struct { .push_constant_bytes = @sizeOf(PushConstants), .shaders = &shaders, .render_pass = s_render_pass, - .subpass = -1, + .subpass = null, .vert_layout = .{ .bindings = &vert_bindings, .attributes = &vert_attributes, @@ -134,11 +134,11 @@ const DepthPass = struct { .attachment_count = 0, }, }; - try Pass.init(&s_pass, &createInfo); + try s_pass.init(device, &createInfo); } - pub fn deinit() void { - s_pass.deinit(); + pub fn deinit(device: *const Device) void { + s_pass.deinit(device); } pub fn setup() void {} diff --git a/src/rendering/vulkan/Pass.zig b/src/rendering/vulkan/Pass.zig index f148a92..1516f3b 100644 --- a/src/rendering/vulkan/Pass.zig +++ b/src/rendering/vulkan/Pass.zig @@ -1,19 +1,25 @@ +const std = @import("std"); +const assert = std.debug.assert; const vk = @import("vulkan"); +const Device = @import("device.zig").Device; +const Bindings = @import("Bindings.zig"); +const pipeline = @import("pipeline.zig"); + const Self = @This(); pipeline: vk.Pipeline, layout: vk.PipelineLayout, -bindpoint: vk.PipelineBindPoint, +bind_point: vk.PipelineBindPoint, stage_flags: vk.ShaderStageFlags, -push_constant_bytes: i32, +push_constant_bytes: u32, -const VertexLayout = struct { +pub const VertexLayout = struct { bindings: []vk.VertexInputBindingDescription, attributes: []vk.VertexInputAttributeDescription, }; -const BlendState = struct { +pub const BlendState = struct { color_wite_mask: vk.ColorComponentFlags, blend_enable: bool, src_color_blend_factor: vk.BlendFactor, @@ -24,7 +30,7 @@ const BlendState = struct { alpha_blend_op: vk.BlendOp, }; -const FixedFuncs = struct { +pub const FixedFuncs = struct { viewport: vk.Viewport, scissor: vk.Rect2D, topology: vk.PrimitiveTopology, @@ -42,20 +48,76 @@ const FixedFuncs = struct { pub const Description = struct { // Graphics and compute - push_constant_bytes: i32, + push_constant_bytes: u32, shaders: []vk.PipelineShaderStageCreateInfo, // Graphics only render_pass: vk.RenderPass, - subpass: i32, + subpass: ?u32, vert_layout: VertexLayout, fixed_funcs: FixedFuncs, }; -pub fn init(self: *Self, desc: *const Description) !void { - _ = self; - _ = desc; +pub fn init(self: *Self, device: *const Device, desc: *const Description) !void { + self.* = std.mem.zeroes(Self); + + var stage_flags = vk.ShaderStageFlags{}; + for (desc.shaders) |shader| { + stage_flags = stage_flags.merge(shader.stage); + } + + var bind_point = vk.PipelineBindPoint.graphics; + if (stage_flags.compute_bit) { + bind_point = .compute; + } + + const k_rt_stages = vk.ShaderStageFlags{ + .raygen_bit_khr = true, + .any_hit_bit_khr = true, + .closest_hit_bit_khr = true, + .miss_bit_khr = true, + .intersection_bit_khr = true, + .callable_bit_khr = true, + }; + + if (stage_flags.intersect(k_rt_stages).toInt() != 0) { + bind_point = .ray_tracing_khr; + } + + const set_layouts = [_]vk.DescriptorSetLayout{ + Bindings.getSetLayout(), + }; + + const ranges = [_]vk.PushConstantRange{ + .{ + .stage_flags = stage_flags, + .size = desc.push_constant_bytes, + .offset = 0, + }, + }; + + self.bind_point = bind_point; + self.stage_flags = stage_flags; + self.push_constant_bytes = desc.push_constant_bytes; + assert(desc.push_constant_bytes <= 256); + + errdefer self.deinit(device); + self.layout = try pipeline.Layout.init(device, &set_layouts, &ranges); + + switch (bind_point) { + .compute => { + assert(desc.shaders.len == 1); + self.pipeline = try pipeline.newComp(device, self.layout, &desc.shaders[0]); + }, + .graphics => { + assert(desc.shaders.len == 2); + self.pipeline = try pipeline.newGfx(device, &desc.fixed_funcs, &desc.vert_layout, self.layout, desc.render_pass, desc.subpass, desc.shaders); + }, + else => assert(false), + } } -pub fn deinit(self: *Self) void { - _ = self; +pub fn deinit(self: *Self, device: *const Device) void { + pipeline.Layout.deinit(device, self.layout); + pipeline.deinit(device, self.pipeline); + self.* = std.mem.zeroes(Self); } diff --git a/src/rendering/vulkan/Renderer.zig b/src/rendering/vulkan/Renderer.zig index ce20f44..95e7172 100644 --- a/src/rendering/vulkan/Renderer.zig +++ b/src/rendering/vulkan/Renderer.zig @@ -110,7 +110,7 @@ pub fn deinit(self: Self) void { // TODO: delete lightmap pack - MainPass.deinit(); + MainPass.deinit(&self.device); // self.imSys.deinit(); // self.meshSys.deinit(); diff --git a/src/rendering/vulkan/Shader.zig b/src/rendering/vulkan/Shader.zig index a5952a8..b27fd10 100644 --- a/src/rendering/vulkan/Shader.zig +++ b/src/rendering/vulkan/Shader.zig @@ -10,3 +10,7 @@ pub fn init(info: *const vk.PipelineShaderStageCreateInfo, file_path: []const u8 _ = section; _ = thingie; } + +pub fn deinit(shader: *const vk.PipelineShaderStageCreateInfo) void { + _ = shader; +} diff --git a/src/rendering/vulkan/descriptor.zig b/src/rendering/vulkan/descriptor.zig new file mode 100644 index 0000000..871c98e --- /dev/null +++ b/src/rendering/vulkan/descriptor.zig @@ -0,0 +1,100 @@ +const assert = @import("std").debug.assert; +const vk = @import("vulkan"); + +const ProfileMark = @import("../../common/profiler.zig").ProfileMark; +const Device = @import("device.zig").Device; + +const pm_writeimagetable = ProfileMark.init("descriptor.writeImageTable"); +pub fn writeImageTable(device: *const Device, set: vk.DescriptorSet, binding: i32, desc_type: vk.DescriptorType, bindings: []const vk.DescriptorImageInfo) void { + pm_writeimagetable.begin(); + defer pm_writeimagetable.end(); + + device.dispatch.updateDescriptorSets(device.handle, 1, @ptrCast([*]const vk.WriteDescriptorSet, &.{ + .descriptor_type = desc_type, + .dst_set = set, + .dst_binding = binding, + .dst_array_element = 0, + .descriptor_count = bindings.len, + .p_image_info = bindings.ptr, + }), 0, null); +} + +const pm_writebuffertable = ProfileMark.init("descriptor.writeBufferTable"); +pub fn writeBufferTable(device: *const Device, set: vk.DescriptorSet, binding: i32, desc_type: vk.DescriptorType, bindings: []const vk.DescriptorBufferInfo) void { + assert(set != .null_handle); + assert(@enumToInt(desc_type) >= @enumToInt(vk.DescriptorType.uniform_texel_buffer)); + assert(@enumToInt(desc_type) <= @enumToInt(vk.DescriptorType.storage_buffer_dynamic)); + + pm_writebuffertable.begin(); + defer pm_writebuffertable.end(); + + device.dispatch.updateDescriptorSets(device.handle, 1, @ptrCast([*]vk.WriteDescriptorSet, &.{ + .descriptor_type = type, + .dst_set = set, + .dst_binding = binding, + .dst_array_element = 0, + .descriptor_count = bindings.len, + .p_buffer_info = bindings.ptr, + }), 0, null); +} + +pub const Set = struct { + pub fn init(device: *const Device, pool: vk.DescriptorPool, layout: vk.DescriptorSetLayout) !void { + assert(pool != .null_handle); + assert(layout != .null_handle); + return try device.dispatch.allocateDescriptorSets(device.handle, &.{ + .descriptor_pool = pool, + .descriptor_set_count = 1, + .p_set_layouts = @ptrCast([*]const vk.DescriptorSetLayout, &layout), + }); + } + + pub fn deinit(device: *const Device, pool: vk.DescriptorPool, set: vk.DescriptorSet) void { + assert(pool != .null_handle); + if (set != .null_handle) { + try device.dispatch.freeDescriptorSets(device.handle, pool, 1, @ptrCast([*]const vk.DescriptorSet, &set)); + } + } + + pub const Layout = struct { + pub fn init(device: *const Device, bindings: []const vk.DescriptorSetLayoutBinding, flags: vk.DescriptorSetLayoutCreateFlags) !vk.DescriptorSetLayout { + return try device.dispatch.createDescriptorSetLayout(device.handle, &.{ + .flags = flags, + .binding_count = bindings.len, + .p_bindings = bindings.ptr, + }, null); + } + + pub fn deinit(device: *const Device, handle: vk.DescriptorSetLayout) void { + if (handle != .null_handle) { + return device.destroyDescriptorSetLayout(device.handle, handle, null); + } + } + }; +}; + +pub const Pool = struct { + pub fn init(device: *const Device, max_sets: i32, sizes: []const vk.DescriptorPoolSize) !vk.DescriptorPool { + assert(max_sets > 0); + return try device.dispatch.createDescriptorPool(device.hande, &.{ + .flags = .{ .create_free_descriptor_set_bit = true }, + .max_sets = max_sets, + .pool_size_count = sizes.len, + .p_pool_sizes = sizes.ptr, + }, null); + } + + pub fn deinit(device: *const Device, pool: vk.DescriptorPool) void { + if (pool != .null_handle) { + device.dispatch.destroyDescriptorPool(device.handle, pool, null); + } + } + + const pm_pool_reset = ProfileMark.init("descriptor.Pool.reset"); + pub fn reset(device: *const Device, pool: vk.DescriptorPool) !void { + pm_pool_reset.begin(); + defer pm_pool_reset.end(); + assert(pool != .null_handle); + try device.dispatch.resetDescriptorPool(device.handle, pool, .{}); + } +}; diff --git a/src/rendering/vulkan/device.zig b/src/rendering/vulkan/device.zig index 4dd2bb4..67baa43 100644 --- a/src/rendering/vulkan/device.zig +++ b/src/rendering/vulkan/device.zig @@ -49,6 +49,7 @@ pub const DeviceDispatch = vk.DeviceWrapper(.{ .createRenderPass = true, .destroyRenderPass = true, .createGraphicsPipelines = true, + .createComputePipelines = true, .destroyPipeline = true, .createFramebuffer = true, .destroyFramebuffer = true, diff --git a/src/rendering/vulkan/pipeline.zig b/src/rendering/vulkan/pipeline.zig index d67b757..06b292d 100644 --- a/src/rendering/vulkan/pipeline.zig +++ b/src/rendering/vulkan/pipeline.zig @@ -2,17 +2,33 @@ const std = @import("std"); const assert = std.debug.assert; const vk = @import("vulkan"); +const vec = @import("vec"); +const Vec2f = vec.Vec2f; +const Vec3f = vec.Vec3f; +const Vec4f = vec.Vec4f; + +const Vec2i = vec.Vec2i; +const Vec3i = vec.Vec3i; +const Vec4i = vec.Vec4i; + const Device = @import("device.zig").Device; +const FixedFuncs = @import("Pass.zig").FixedFuncs; +const VertexLayout = @import("Pass.zig").VertexLayout; pub const Layout = struct { - pub fn init(device: *const Device, set_layouts: []*const vk.DescriptorSetLayout, ranges: []*const vk.PushConstantRange) !vk.PipelineLayout { + pub fn init(device: *const Device, set_layouts: []const vk.DescriptorSetLayout, ranges: []const vk.PushConstantRange) !vk.PipelineLayout { return try device.dispatch.createPipelineLayout(device.handle, &.{ - .set_layout_count = set_layouts.len, + .flags = .{}, + .set_layout_count = @intCast(u32, set_layouts.len), .p_set_layouts = set_layouts.ptr, - .push_constant_range_count = ranges.len, + .push_constant_range_count = @intCast(u32, ranges.len), .p_push_constant_ranges = ranges.ptr, }, null); } + + pub fn deinit(device: *const Device, layout: vk.PipelineLayout) void { + device.dispatch.destroyPipelineLayout(device.handle, layout, null); + } }; pub const VertType = enum { @@ -28,13 +44,13 @@ pub const VertType = enum { pub fn size(t: VertType) i32 { return switch (t) { .float => @sizeOf(f32), - .float2 => @sizeOf(Float2), - .float3 => @sizeOf(Float3), - .float4 => @sizeOf(Float4), + .float2 => @sizeOf(Vec2f), + .float3 => @sizeOf(Vec3f), + .float4 => @sizeOf(Vec4f), .int => @sizeOf(i32), - .int2 => @sizeOf(Int2), - .int3 => @sizeOf(Int3), - .int4 => @sizeOf(Int4), + .int2 => @sizeOf(Vec2i), + .int3 => @sizeOf(Vec3i), + .int4 => @sizeOf(Vec4i), else => assert(false), }; } @@ -53,3 +69,144 @@ pub const VertType = enum { }; } }; + +pub fn newGfx(device: *const Device, fixed_funcs: *const FixedFuncs, vert_layout: *const VertexLayout, layout: vk.PipelineLayout, render_pass: vk.RenderPass, subpass: ?u32, shaders: []const vk.PipelineShaderStageCreateInfo) !vk.Pipeline { + assert(layout != .null_handle); + assert(render_pass != .null_handle); + + const vertex_input_info = vk.PipelineVertexInputStateCreateInfo{ + .flags = .{}, + .vertex_binding_description_count = @intCast(u32, vert_layout.bindings.len), + .p_vertex_binding_descriptions = vert_layout.bindings.ptr, + .vertex_attribute_description_count = @intCast(u32, vert_layout.attributes.len), + .p_vertex_attribute_descriptions = vert_layout.attributes.ptr, + }; + + const input_assembly = vk.PipelineInputAssemblyStateCreateInfo{ + .flags = .{}, + .primitive_restart_enable = 0, + .topology = fixed_funcs.topology, + }; + + const viewport_state = vk.PipelineViewportStateCreateInfo{ + .flags = .{}, + .viewport_count = 1, + .p_viewports = @ptrCast([*]const vk.Viewport, &fixed_funcs.viewport), + .scissor_count = 1, + .p_scissors = @ptrCast([*]const vk.Rect2D, &fixed_funcs.scissor), + }; + + const rasterizer = vk.PipelineRasterizationStateCreateInfo{ + .flags = .{}, + .depth_clamp_enable = @boolToInt(fixed_funcs.depth_clamp), + .rasterizer_discard_enable = 0, + .depth_bias_constant_factor = 0, + .depth_bias_enable = 0, + .depth_bias_clamp = 0, + .depth_bias_slope_factor = 0, + .polygon_mode = fixed_funcs.polygon_mode, + .cull_mode = fixed_funcs.cull_mode, + .front_face = fixed_funcs.front_face, + .line_width = 1, + }; + + const multisampling = vk.PipelineMultisampleStateCreateInfo{ + .flags = .{}, + .sample_shading_enable = 0, + .min_sample_shading = 0, + .p_sample_mask = null, + .alpha_to_coverage_enable = 0, + .alpha_to_one_enable = 0, + .rasterization_samples = .{ .@"1_bit" = true }, + }; + + const depth_stencil = vk.PipelineDepthStencilStateCreateInfo{ + .flags = .{}, + .depth_test_enable = @boolToInt(fixed_funcs.depth_test_enable), + .depth_bounds_test_enable = 0, + .stencil_test_enable = 0, + .front = std.mem.zeroes(vk.StencilOpState), + .back = std.mem.zeroes(vk.StencilOpState), + .depth_write_enable = @boolToInt(fixed_funcs.depth_write_enable), + .depth_compare_op = fixed_funcs.depth_compare_op, + .min_depth_bounds = 0, + .max_depth_bounds = 1, + }; + + var color_blend_attachments = std.mem.zeroes([8]vk.PipelineColorBlendAttachmentState); + if (fixed_funcs.attachments) |attachments| { + for (attachments) |attachment, i| { + color_blend_attachments[i] = vk.PipelineColorBlendAttachmentState{ + .blend_enable = @boolToInt(attachment.blend_enable), + .src_color_blend_factor = attachment.src_color_blend_factor, + .dst_color_blend_factor = attachment.dst_color_blend_factor, + .color_blend_op = attachment.color_blend_op, + .src_alpha_blend_factor = attachment.src_alpha_blend_factor, + .dst_alpha_blend_factor = attachment.dst_alpha_blend_factor, + .alpha_blend_op = attachment.alpha_blend_op, + .color_write_mask = attachment.color_wite_mask, + }; + } + } + + const color_blending = vk.PipelineColorBlendStateCreateInfo{ + .flags = .{}, + .logic_op_enable = 0, + .logic_op = .clear, + .blend_constants = std.mem.zeroes([4]f32), + .attachment_count = fixed_funcs.attachments.?.len, + .p_attachments = &color_blend_attachments, + }; + + const dynamic_states = [_]vk.DynamicState{ + .viewport, + .scissor, + }; + + const dynamic_state_info = vk.PipelineDynamicStateCreateInfo{ + .flags = .{}, + .dynamic_state_count = dynamic_states.len, + .p_dynamic_states = &dynamic_states, + }; + + const pipeline_info = vk.GraphicsPipelineCreateInfo{ + .flags = .{}, + .stage_count = @intCast(u32, shaders.len), + .p_stages = shaders.ptr, + .p_vertex_input_state = &vertex_input_info, + .p_input_assembly_state = &input_assembly, + .p_tessellation_state = null, + .p_viewport_state = &viewport_state, + .p_rasterization_state = &rasterizer, + .p_multisample_state = &multisampling, + .p_depth_stencil_state = &depth_stencil, + .p_color_blend_state = &color_blending, + .p_dynamic_state = &dynamic_state_info, + .layout = layout, + .render_pass = render_pass, + .base_pipeline_handle = .null_handle, + .base_pipeline_index = 0, + .subpass = subpass orelse 0, + }; + + var pipelines: [*]vk.Pipeline = undefined; + _ = try device.dispatch.createGraphicsPipelines(device.handle, .null_handle, 1, @ptrCast([*]const vk.GraphicsPipelineCreateInfo, &pipeline_info), null, pipelines); + return pipelines[0]; +} + +pub fn newComp(device: *const Device, layout: vk.PipelineLayout, shader: *const vk.PipelineShaderStageCreateInfo) !vk.Pipeline { + assert(layout != .null_handle); + + var pipelines: [*]vk.Pipeline = undefined; + _ = try device.dispatch.createComputePipelines(device.handle, .null_handle, 1, @ptrCast([*]const vk.ComputePipelineCreateInfo, &.{ + .flags = .{}, + .stage = shader, + .layout = layout, + }), null, pipelines); + + return pipelines[0]; +} + +pub fn deinit(device: *const Device, pipeline: vk.Pipeline) void { + device.dispatch.destroyPipeline(device.handle, pipeline, null); +} diff --git a/src/rendering/vulkan/settings.zig b/src/rendering/vulkan/settings.zig index e9f1fd5..34e17a2 100644 --- a/src/rendering/vulkan/settings.zig +++ b/src/rendering/vulkan/settings.zig @@ -30,31 +30,31 @@ pub const Bid = struct { stages: vk.ShaderStageFlags, pub const TextureTable = struct { - const T1D = Bid{ + pub const T1D = Bid{ .id = 0, .desc_type = .combined_image_sampler, .count = 64, .stages = .{ .fragment_bit = true, .compute_bit = true }, }; - const T2D = Bid{ + pub const T2D = Bid{ .id = T1D.id + 1, .desc_type = .combined_image_sampler, .count = 512, .stages = .{ .fragment_bit = true, .compute_bit = true }, }; - const T3D = Bid{ + pub const T3D = Bid{ .id = T2D.id + 1, .desc_type = .combined_image_sampler, .count = 64, .stages = .{ .fragment_bit = true, .compute_bit = true }, }; - const TCube = Bid{ + pub const TCube = Bid{ .id = T3D.id + 1, .desc_type = .combined_image_sampler, .count = 64, .stages = .{ .fragment_bit = true, .compute_bit = true }, }; - const T2DArray = Bid{ + pub const T2DArray = Bid{ .id = TCube.id + 1, .desc_type = .combined_image_sampler, .count = 64, @@ -62,26 +62,31 @@ pub const Bid = struct { }; }; - const Globals = Bid{ + pub const Globals = Bid{ .id = TextureTable.T2DArray.id + 1, .desc_type = .uniform_buffer, - .stages = .{}.complement(), // all + .stages = vk.ShaderStageFlags.complement(.{}), // all }; - const SceneLuminance = Bid{ + pub const SceneLuminance = Bid{ .id = Globals.id + 1, .desc_type = .combined_image_sampler, .stages = .{ .fragment_bit = true, .compute_bit = true }, }; - const HistogramBuffer = Bid{ + pub const RWSceneLuminance = Bid{ .id = SceneLuminance.id + 1, .desc_type = .storage_image, .stages = .{ .compute_bit = true }, }; - const ExposureBuffer = Bid{ + pub const HistogramBuffer = Bid{ + .id = RWSceneLuminance.id + 1, + .desc_type = .storage_image, + .stages = .{ .compute_bit = true }, + }; + pub const ExposureBuffer = Bid{ .id = HistogramBuffer.id + 1, .desc_type = .storage_buffer, .stages = .{ .fragment_bit = true, .compute_bit = true }, }; - const Count = ExposureBuffer.id + 1; + pub const Count = ExposureBuffer.id + 1; };