diff --git a/vulkan/convert.comp.glsl b/vulkan/convert.comp.glsl index 5811268..e041ad0 100644 --- a/vulkan/convert.comp.glsl +++ b/vulkan/convert.comp.glsl @@ -2,23 +2,23 @@ #extension GL_EXT_shader_8bit_storage : require -layout (local_size_x = 32, local_size_y = 32) in; - layout (constant_id = 0) const int CHANNELS = 3; -layout (push_constant) uniform Constants -{ +layout (local_size_x = 32, local_size_y = 32) in; + +layout (push_constant) uniform Constants { uint x; uint y; } PC; -layout (set = 0, binding = 0, rgba32f) uniform image2D dst; +layout (set = 1, binding = 0, rgba32f) uniform image2D dst; -layout (set = 0, binding = 1) buffer input_array +layout (set = 1, binding = 1) buffer input_array { uint8_t src[]; }; + void main() { uint x = gl_GlobalInvocationID.x; @@ -33,23 +33,23 @@ void main() { uint index = x + y * PC.x; - vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0); + vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0); imageStore(dst, ivec2(x, y), col); } else if(CHANNELS == 2) { uint index = (x + y * PC.x) * 2; - float f = uint(src[index]) / 255.0; - float a = uint(src[index+1]) / 255.0; - vec4 col = vec4(f, f, f, a); + float f = uint(src[index]) / 255.0; + float a = uint(src[index+1]) / 255.0; + vec4 col = vec4(f, f, f, a); imageStore(dst, ivec2(x, y), col); } else if(CHANNELS == 3) { uint index = (x + y * PC.x) * 3; - vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0); + vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0); imageStore(dst, ivec2(x, y), col); } } diff --git a/vulkan/vulkan.d b/vulkan/vulkan.d index 5af56d2..588c5ec 100644 --- a/vulkan/vulkan.d +++ b/vulkan/vulkan.d @@ -35,7 +35,12 @@ alias DescSetLayout = VkDescriptorSetLayout; alias PipelineLayout = VkPipelineLayout; alias DescLayoutBinding = VkDescriptorSetLayoutBinding; alias DescWrite = VkWriteDescriptorSet; -alias DescSet = VkDescriptorSet; + +struct DescSet +{ + VkDescriptorSet handle; + u32 dynamic_count; +} bool g_VLAYER_SUPPORT = false; @@ -488,12 +493,12 @@ struct Vulkan bool recreate_swapchain; VkRenderPass render_pass; - VkFramebuffer[] framebuffers; - u32 image_index; + VkFramebuffer framebuffer; Descriptor[] present_images; - Descriptor depth_image; - Format present_image_format; + u32 image_index; + Descriptor draw_image; + Descriptor depth_image; VkCommandPool[FRAME_OVERLAP] cmd_pools; VkCommandBuffer[FRAME_OVERLAP] cmds; @@ -516,6 +521,8 @@ struct Vulkan PipelineHandles[] pipeline_handles; u32 pipeline_count; VkPipeline[FRAME_OVERLAP] last_pipelines; + DescSetLayout global_set_layout; + DescSet global_set; MappedBuffer!(u8) transfer_buf; @@ -534,19 +541,77 @@ struct Vulkan f32[4] color_clear; f32[4] depth_clear; - @property VkCommandPool cmd_pool() => this.cmd_pools[this.frame_index]; - @property VkCommandBuffer cmd() => this.cmds[this.frame_index]; - @property VkSemaphore acquire_sem() => this.acquire_sems[this.frame_index]; - @property VkSemaphore* acquire_sem_ptr() => this.acquire_sems.ptr + this.frame_index; - @property VkFence render_fence() => this.render_fences[this.frame_index]; - @property VkFence* render_fence_ptr() => this.render_fences.ptr + this.frame_index; - @property VkPipeline last_pipeline() => this.last_pipelines[this.frame_index]; - @property VkPipeline last_pipeline(VkPipeline pipeline) => this.last_pipelines[this.frame_index] = pipeline; - @property VkSemaphore submit_sem() => this.submit_sems[this.image_index]; - @property ref Descriptor present_image() => this.present_images[this.image_index]; - @property Descriptor* present_image_ptr() => this.present_images.ptr + this.image_index; - @property VkFramebuffer framebuffer() => this.framebuffers[this.image_index]; - @property Arena* frame_arena() => &this.frame_arenas[this.frame_index]; + @property VkCommandPool + cmd_pool() + { + return this.cmd_pools[this.frame_index]; + } + + @property VkCommandBuffer + cmd() + { + return this.cmds[this.frame_index]; + } + + @property VkSemaphore + acquire_sem() + { + return this.acquire_sems[this.frame_index]; + } + + @property VkSemaphore* + acquire_sem_ptr() + { + return this.acquire_sems.ptr + this.frame_index; + } + + @property VkFence + render_fence() + { + return this.render_fences[this.frame_index]; + } + + @property VkFence* + render_fence_ptr() + { + return this.render_fences.ptr + this.frame_index; + } + + @property VkPipeline + last_pipeline() + { + return this.last_pipelines[this.frame_index]; + } + + @property VkPipeline + last_pipeline(VkPipeline pipeline) + { + return this.last_pipelines[this.frame_index] = pipeline; + } + + @property VkSemaphore + submit_sem() + { + return this.submit_sems[this.image_index]; + } + + @property ref Descriptor + present_image() + { + return this.present_images[this.image_index]; + } + + @property Descriptor* + present_image_ptr() + { + return this.present_images.ptr + this.image_index; + } + + Arena* + FrameArena() + { + return &this.frame_arenas[this.frame_index]; + } alias queues this; } @@ -599,7 +664,7 @@ CreateDescSetLayout(DescLayoutBinding[] bindings) } DescSet -AllocDescSet(DescSetLayout layout) +AllocDescSet(DescSetLayout layout, u32 dynamic_count = 0) { VkDescriptorSetAllocateInfo alloc_info = { sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, @@ -608,15 +673,15 @@ AllocDescSet(DescSetLayout layout) descriptorPool: g_vk.active_pool, }; - DescSet set; - VkResult result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set); + DescSet set = { dynamic_count: dynamic_count }; + VkResult result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set.handle); if(result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL) { PushDescriptorPool(); alloc_info.descriptorPool = g_vk.active_pool; - result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set); + result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set.handle); VkCheckA("vkAllocateDescriptorSets failure", result); } @@ -628,17 +693,23 @@ CreatePipelineLayout(T)(T layouts, u32 push_const_size, bool compute = false) if { VkShaderStageFlagBits stage = (compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); - u32 desc_layouts_length = 1; - DescSetLayout* desc_layouts; + DescSetLayout[] desc_layouts; static if(is(T: DescSetLayout)) { - desc_layouts = &layouts; + desc_layouts = Alloc!(DescSetLayout)(g_vk.FrameArena(), 2); + desc_layouts[0] = g_vk.global_set_layout; + desc_layouts[1] = layouts; } else static if(is(T: DescSetLayout[])) { - desc_layouts_length = cast(u32)layouts.length; - desc_layouts = layouts.ptr; + desc_layouts = Alloc!(DescSetLayout)(g_vk.FrameArena(), layouts.length + 1); + desc_layouts[0] = g_vk.global_set_layout; + + foreach(i; 0 .. layouts.length) + { + desc_layouts[i+1] = layouts[i]; + } } VkPushConstantRange const_range = { @@ -649,8 +720,8 @@ CreatePipelineLayout(T)(T layouts, u32 push_const_size, bool compute = false) if VkPipelineLayoutCreateInfo layout_info = { sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - setLayoutCount: desc_layouts_length, - pSetLayouts: desc_layouts, + setLayoutCount: cast(u32)desc_layouts.length, + pSetLayouts: desc_layouts.ptr, pushConstantRangeCount: (push_const_size > 0 ? 1 : 0), pPushConstantRanges: (push_const_size > 0 ? &const_range : null), }; @@ -760,7 +831,7 @@ BeginFrame() result = vkResetFences(g_vk.device, 1, g_vk.render_fence_ptr); VkCheckA("BeginFrame failure: vkResetFences error", result); - Reset(g_vk.frame_arena); + Reset(g_vk.FrameArena()); // ?? dont know why this is 3 (should have commented it) for(u64 i = 0; i < 3; i += 1) @@ -809,9 +880,11 @@ SetClearColors(f32[4] color_clear, f32[4] depth_clear) void BeginRendering() { - Transition(g_vk.cmd, g_vk.present_image_ptr, IL.ColorAttach); + Transition(g_vk.cmd, &g_vk.draw_image, IL.ColorAttach); Transition(g_vk.cmd, &g_vk.depth_image, IL.DepthAttach); + Transition(g_vk.cmd, g_vk.present_image_ptr, IL.TransferDst); + VkClearValue[2] clear_color = [ { color: { float32: g_vk.color_clear } }, { color: { float32: g_vk.depth_clear } }, @@ -849,21 +922,9 @@ GetAspect() } void -PrepComputeImage(Descriptor* descriptor) +PrepComputeDrawImage() { - Transition(g_vk.cmd, descriptor, IL.General); -} - -void -CopyToPresentImage(Descriptor* descriptor, UVec2 extent) -{ - Transition(g_vk.cmd, descriptor, IL.TransferSrc); - Transition(g_vk.cmd, g_vk.present_image_ptr, IL.TransferDst); - - VkExtent2D src_extent = { width: extent.x, height: extent.y }; - VkExtent2D dst_extent = { width: g_vk.swapchain_extent.width, height: g_vk.swapchain_extent.height }; - - Copy(g_vk.cmd, descriptor, g_vk.present_image_ptr, src_extent, dst_extent); + Transition(g_vk.cmd, &g_vk.draw_image, IL.General); } void @@ -875,10 +936,27 @@ FinishRendering() void SubmitAndPresent() { + scope(exit) + { + g_vk.last_pipeline = null; + g_vk.frame_index = (g_vk.frame_index + 1) % FRAME_OVERLAP; + } + + VkImage image = g_vk.present_image.image.image; VkSemaphore acquire_sem = g_vk.acquire_sem; VkSemaphore submit_sem = g_vk.submit_sem; - Transition(g_vk.cmd, g_vk.present_image_ptr, IL.PresentSrc); + Transition(g_vk.cmd, &g_vk.draw_image, IL.TransferSrc); + + VkExtent2D extent = { + width: g_vk.swapchain_extent.width, + height: g_vk.swapchain_extent.height, + }; + + // TODO: Find out how to copy from same dimension images (pretty sure its not blitting) + Copy(g_vk.cmd, &g_vk.draw_image, image, IL.TransferDst, extent, extent); + + Transition(g_vk.cmd, image, IL.TransferDst, IL.PresentSrc); VkResult result = vkEndCommandBuffer(g_vk.cmd); VkCheckA("FinishFrame failure: vkEndCommandBuffer error", result); @@ -938,9 +1016,6 @@ SubmitAndPresent() { g_vk.frame_started = false; } - - g_vk.last_pipeline = null; - g_vk.frame_index = (g_vk.frame_index + 1) % FRAME_OVERLAP; } void @@ -1326,7 +1401,7 @@ CreateBufferView(Descriptor* desc) } void -PushConstants(T)(Pipeline pipeline_id, T* pc, bool compute = false) +PushConstants(T)(Pipeline pipeline_id, T* pc) { assert(pipeline_id > 0, "PushConstants pipeline_id == 0"); PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_id; @@ -1335,7 +1410,7 @@ PushConstants(T)(Pipeline pipeline_id, T* pc, bool compute = false) VK_SHADER_STAGE_COMPUTE_BIT); vkCmdPushConstants( - compute ? g_vk.comp_cmd : g_vk.cmd, + g_vk.cmd, pipeline.layout, stage, 0, @@ -1503,21 +1578,50 @@ Bind(Pipeline pipeline_handle, DescSet[] sets, bool compute = false) { assert(pipeline_handle > 0, "Bind failure: pipeline is 0"); - VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); + VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle; BindPipeline(cmd, pipeline); u32[] offsets; + if(g_vk.global_set.dynamic_count > 0) + { + offsets = Alloc!(u32)(g_vk.FrameArena(), g_vk.global_set.dynamic_count); + } + + vkCmdBindDescriptorSets( + cmd, + pipeline.type, + pipeline.layout, + 0, + 1, + &g_vk.global_set.handle, + cast(u32)offsets.length, + offsets.ptr + ); + + u32 offset_count; + VkDescriptorSet[] handles = Alloc!(VkDescriptorSet)(g_vk.FrameArena(), sets.length); + + foreach(i, set; sets) + { + handles[i] = set.handle; + offset_count += set.dynamic_count; + } + + if(offset_count > 0) + { + offsets = Alloc!(u32)(g_vk.FrameArena(), offset_count); + } vkCmdBindDescriptorSets( cmd, pipeline.type, pipeline.layout, - 0, - cast(u32)sets.length, - sets.ptr, - 0, - null + 1, + cast(u32)handles.length, + handles.ptr, + cast(u32)offsets.length, + offsets.ptr ); } @@ -1536,19 +1640,41 @@ Bind(Pipeline pipeline_handle, DescSet set, bool compute = false) { assert(pipeline_handle > 0, "Bind failure: pipeline is 0"); - VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); + VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd); PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle; BindPipeline(cmd, pipeline); + u32[] offsets; + if(g_vk.global_set.dynamic_count > 0) + { + offsets = Alloc!(u32)(g_vk.FrameArena(), g_vk.global_set.dynamic_count); + } + vkCmdBindDescriptorSets( cmd, pipeline.type, pipeline.layout, 0, 1, - &set, - 0, - null + &g_vk.global_set.handle, + cast(u32)offsets.length, + offsets.ptr + ); + + if(set.dynamic_count > 0) + { + offsets = Alloc!(u32)(g_vk.FrameArena(), set.dynamic_count); + } + + vkCmdBindDescriptorSets( + cmd, + pipeline.type, + pipeline.layout, + 1, + 1, + &set.handle, + cast(u32)offsets.length, + offsets.ptr ); } @@ -1730,7 +1856,7 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info) VkPipelineRenderingCreateInfo rendering_info = { sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, colorAttachmentCount: 1, - pColorAttachmentFormats: cast(VkFormat*)&g_vk.present_image_format, + pColorAttachmentFormats: cast(VkFormat*)&g_vk.draw_image.image.format, depthAttachmentFormat: g_vk.depth_image.image.format, }; @@ -1928,8 +2054,8 @@ ClearDepth(f32[4] color = [0.0, 0.0, 0.0, 0.0]) void ClearColor(f32[4] color) { - Transition(g_vk.cmd, g_vk.present_image_ptr, IL.TransferDst); - ClearColor(g_vk.present_image_ptr, color); + Transition(g_vk.cmd, &g_vk.draw_image, IL.TransferDst); + ClearColor(&g_vk.draw_image, color); } void @@ -2027,11 +2153,11 @@ PushDescriptorPool() void PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc) { - Arena* arena = g_vk.frame_arena; + Arena* arena = g_vk.FrameArena(); write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write.descriptorType = desc.type; - write.dstSet = set; + write.dstSet = set.handle; write.dstBinding = desc.binding; write.descriptorCount = 1; write.dstArrayElement = desc.index; @@ -2073,7 +2199,7 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc) void Write(DescSet set, Descriptor[] descs) { - Arena* arena = g_vk.frame_arena; + Arena* arena = g_vk.FrameArena(); VkWriteDescriptorSet[] writes = Alloc!(VkWriteDescriptorSet)(arena, descs.length); @@ -2105,7 +2231,7 @@ WriteConvDescriptor(Buffer* buf) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: g_vk.conv_desc_set, + dstSet: g_vk.conv_desc_set.handle, dstBinding: 1, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -2125,7 +2251,7 @@ WriteConvDescriptor(ImageView* view) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: g_vk.conv_desc_set, + dstSet: g_vk.conv_desc_set.handle, dstBinding: 0, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, @@ -2146,13 +2272,7 @@ Dispatch(VkCommandBuffer cmd) void Dispatch() { - Dispatch(g_vk.comp_cmd); -} - -void -WaitForCompute() -{ - vkWaitForFences(g_vk.device, 1, &g_vk.comp_fence, VK_TRUE, u64.max); + Dispatch(g_vk.cmd); } bool @@ -2299,12 +2419,13 @@ CreateSampler(Descriptor* desc, DescInfo* info) void CreateDrawImages() { - g_vk.present_image_format = cast(Format)GetDrawImageFormat(); - Format depth_format = cast(Format)VK_FORMAT_D32_SFLOAT; + Format draw_format = cast(Format)GetDrawImageFormat(); + Format depth_format = cast(Format)VK_FORMAT_D32_SFLOAT; u32 w = g_vk.swapchain_extent.width; u32 h = g_vk.swapchain_extent.height; + CreateDescriptor(&g_vk.draw_image, DescInfo(type: DT.StorageImage, format: draw_format, usage: IU.Draw, w: w, h: h, binding: 0)); CreateDescriptor(&g_vk.depth_image, DescInfo(type: DT.Image, format: depth_format, usage: IU.Depth, w: w, h: h, binding: 0)); } @@ -2312,7 +2433,7 @@ bool CreateSwapchain() { bool success = true; - Arena* arena = g_vk.frame_arena; + Arena* arena = g_vk.FrameArena(); VkSurfaceCapabilitiesKHR cap; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vk.physical_device, g_vk.surface, &cap); @@ -2406,37 +2527,33 @@ RecreateSwapchain() vkDeviceWaitIdle(g_vk.device); Destroy(g_vk.swapchain, g_vk.present_images, g_vk.device); + Destroy(&g_vk.draw_image); Destroy(&g_vk.depth_image); - foreach(i; 0 .. g_vk.framebuffers.length) - { - vkDestroyFramebuffer(g_vk.device, g_vk.framebuffers[i], null); - } + vkDestroyFramebuffer(g_vk.device, g_vk.framebuffer, null); CreateSwapchain(); CreateDrawImages(); - CreateFramebuffers(); + Write(g_vk.global_set, &g_vk.draw_image); + CreateFramebuffer(); g_vk.recreate_swapchain = false; } void -CreateFramebuffers() +CreateFramebuffer() { - foreach(i; 0 .. g_vk.framebuffers.length) - { - VkFramebufferCreateInfo framebuffer_info = { - sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - renderPass: g_vk.render_pass, - attachmentCount: 2, - pAttachments: [g_vk.present_images[i].image.view, g_vk.depth_image.image.view], - width: g_vk.swapchain_extent.width, - height: g_vk.swapchain_extent.height, - layers: 1, - }; + VkFramebufferCreateInfo framebuffer_info = { + sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + renderPass: g_vk.render_pass, + attachmentCount: 2, + pAttachments: [g_vk.draw_image.image.view, g_vk.depth_image.image.view], + width: g_vk.swapchain_extent.width, + height: g_vk.swapchain_extent.height, + layers: 1, + }; - VkResult result = vkCreateFramebuffer(g_vk.device, &framebuffer_info, null, &g_vk.framebuffers[i]); - VkCheckA("vkCreateFramebuffer failure", result); - } + VkResult result = vkCreateFramebuffer(g_vk.device, &framebuffer_info, null, &g_vk.framebuffer); + VkCheckA("vkCreateFramebuffer failure", result); } void @@ -2564,7 +2681,7 @@ PrintShaderDisassembly(Pipeline pipeline_id, VkShaderStageFlagBits stage) VkResult result = vkGetShaderInfoAMD(g_vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, null); if(result == VK_SUCCESS) { - u8[] buf = Alloc!(u8)(g_vk.frame_arena, size); + u8[] buf = Alloc!(u8)(g_vk.FrameArena(), size); vkGetShaderInfoAMD(g_vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, buf.ptr); Logf("DISASSEMBLY:\n%r", buf); } @@ -3236,8 +3353,24 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) if(success) { - PushDescriptorPool(); + PushDescriptorPool(); + if(success) + { + DescLayoutBinding[2] layout_bindings = [ + { binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL }, + { binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL }, + ]; + + g_vk.global_set_layout = CreateDescSetLayout(layout_bindings); + g_vk.global_set = AllocDescSet(g_vk.global_set_layout); + + Write(g_vk.global_set, [g_vk.draw_image]); + } + } + + if(success) + { g_vk.pipeline_handles = Alloc!(PipelineHandles)(&g_vk.arena, 128); g_vk.pipeline_count += 1; @@ -3245,15 +3378,15 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) g_vk.transfer_buf = CreateMappedBuffer!(u8)(BT.Staging, transfer_size); VkDescriptorSetLayoutBinding[2] layout_bindings = [ - { binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT }, + { binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT }, { binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT }, ]; - g_vk.conv_desc_layout = CreateDescSetLayout(layout_bindings); - g_vk.conv_desc_set = AllocDescSet(g_vk.conv_desc_layout); + g_vk.conv_desc_layout = CreateDescSetLayout(layout_bindings); + g_vk.conv_desc_set = AllocDescSet(g_vk.conv_desc_layout); g_vk.conv_pipeline_layout = CreatePipelineLayout(g_vk.conv_desc_layout, ConvPushConst.sizeof, true); - u32 channels; + u32 channels = 1; SpecEntry[1] entries = [ { constantID: 0, @@ -3272,19 +3405,18 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) }, }; - channels = 1; - g_vk.r_to_rgba_pipeline = CreateComputePipeline(&conv_info); + g_vk.r_to_rgba_pipeline = CreateComputePipeline(&conv_info); - channels = 2; - g_vk.rg_to_rgba_pipeline = CreateComputePipeline(&conv_info); + channels = 2; + g_vk.rg_to_rgba_pipeline = CreateComputePipeline(&conv_info); - channels = 3; + channels = 3; g_vk.rgb_to_rgba_pipeline = CreateComputePipeline(&conv_info); VkAttachmentDescription[2] attach_descriptions = [ { - format: g_vk.present_images[0].image.format, + format: g_vk.draw_image.image.format, samples: VK_SAMPLE_COUNT_1_BIT, loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, storeOp: VK_ATTACHMENT_STORE_OP_STORE, @@ -3343,9 +3475,7 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) VkResult result = vkCreateRenderPass(g_vk.device, &pass_info, null, &g_vk.render_pass); VkCheckA("vkCreateRenderPass failure", result); - g_vk.framebuffers = Alloc!(VkFramebuffer)(&g_vk.arena, g_vk.present_images.length); - - CreateFramebuffers(); + CreateFramebuffer(); } assert(success, "Error initializing vulkan");