diff --git a/vulkan.d b/vulkan.d index c992793..2e81f4b 100644 --- a/vulkan.d +++ b/vulkan.d @@ -3,6 +3,8 @@ import vulkan_logging; import vulkan_util; import std.stdio; import std.algorithm.comparison; +import std.algorithm.searching : canFind; +import std.traits : isPointer; import core.stdc.string : strcmp, memcpy; import core.stdc.stdio : Printf = printf; import std.format : sformat; @@ -222,33 +224,27 @@ enum ImageLayout : VkImageLayout alias IL = ImageLayout; -struct Image -{ - VkImage image; - VmaAllocation alloc; - Format format; - VkImageLayout layout; - u32 w; - u32 h; - bool depth_image; - ImageUsage usage; -} - struct BufferView { Buffer base; VkBufferView view; + Format format; alias base this; } struct ImageView { - Image base; - VkImageView view; - ImageLayout shader_layout; - - alias base this; + VkImage image; + VkImageView view; + VmaAllocation alloc; + Format format; + ImageUsage usage; + ImageLayout shader_layout; + ImageLayout layout; + u32 w; + u32 h; + u32 ch; } struct Buffer @@ -262,18 +258,46 @@ struct Descriptor { union { - Buffer buf; - Image image; - ImageView view; - BufferView buf_view; + Buffer buffer; + ImageView image; + BufferView buffer_view; VkSampler sampler; - } + }; DescType type; u32 binding; u32 index; - bool array_elem; } +static assert(Descriptor.buffer.buffer.offsetof == Descriptor.buffer_view.base.buffer.offsetof); + +struct DescInfo +{ + DescType type; + u32 binding; + u32 index; + Format format; + union + { + struct + { + u32 w, h, ch; + ImageUsage usage; + }; + struct + { + u64 size; + BufferType buffer_type; + bool host_visible; + }; + struct + { + MipmapMode mipmap_mode; + }; + }; +} + +alias Desc = Descriptor; + enum MipmapMode : VkSamplerMipmapMode { Nearest = VK_SAMPLER_MIPMAP_MODE_NEAREST, @@ -434,7 +458,7 @@ struct Vulkan VkRenderPass render_pass; VkFramebuffer framebuffer; - ImageView[] present_images; + Descriptor[] present_images; u32 image_index; Descriptor draw_image; @@ -535,7 +559,7 @@ struct Vulkan return this.submit_sems[this.image_index]; } - @property ref ImageView + @property ref Descriptor present_image() { return this.present_images[this.image_index]; @@ -662,15 +686,7 @@ CreatePipelineLayout(T)(T layouts, u32 push_const_size, bool compute = false) if } void -CreateBuffer(Descriptor* desc, BufferType type, u64 size, bool host_visible, DescType desc_type, u32 binding) -{ - desc.type = desc_type; - desc.binding = binding; - CreateBuffer(&desc.buf, type, size, host_visible); -} - -void -CreateBuffer(Buffer* buf, BufferType type, u64 size, bool host_visible) +CreateBuffer(Buffer* buffer, BufferType type, u64 size, bool host_visible) { assert(type != BT.None, "CreateBuffer failure: type is None"); @@ -705,11 +721,11 @@ CreateBuffer(Buffer* buf, BufferType type, u64 size, bool host_visible) } VmaAllocationInfo vma_info; - VkResult result = vmaCreateBuffer(g_vk.vma, &buffer_info, &alloc_info, &buf.buffer, &buf.alloc, &vma_info); + VkResult result = vmaCreateBuffer(g_vk.vma, &buffer_info, &alloc_info, &buffer.buffer, &buffer.alloc, &vma_info); // TODO: handle errors here then reallocate buffer VkCheck("CreateBuffer failure: vmaCreateBuffer error", result); - buf.size = size; + buffer.size = size; } void @@ -805,7 +821,7 @@ BeginRendering() Transition(g_vk.cmd, &g_vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); Transition(g_vk.cmd, &g_vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); - VkImage image = g_vk.present_image.image; + VkImage image = g_vk.present_image.image.image; Transition(g_vk.cmd, image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkClearValue[2] clear_color = [ @@ -846,12 +862,6 @@ GetAspect() return cast(f32)(g_vk.swapchain_extent.width) / cast(f32)(g_vk.swapchain_extent.height); } -void -PrepAuxImage(ImageView* view) -{ - Transition(g_vk.cmd, view, VK_IMAGE_LAYOUT_GENERAL); -} - void PrepComputeDrawImage() { @@ -873,19 +883,19 @@ SubmitAndPresent() g_vk.frame_index = (g_vk.frame_index + 1) % FRAME_OVERLAP; } - VkImage image = g_vk.present_image.image; + 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.draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); VkExtent2D extent = { - width: g_vk.swapchain_extent.width, + 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.view.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); + Copy(g_vk.cmd, &g_vk.draw_image, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); Transition(g_vk.cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); @@ -1007,16 +1017,16 @@ ImmSubmitFinish() } bool -ImmSubmit(Image* image, VkBufferImageCopy copy, void function(Image*, VkBufferImageCopy) fn) +ImmSubmit(Descriptor* desc, VkBufferImageCopy copy, void function(Descriptor*, VkBufferImageCopy) fn) { bool success = ImmSubmitStart(); if(success) { - fn(image, copy); + fn(desc, copy); VkResult result = vkEndCommandBuffer(g_vk.imm_cmd); - success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result); + success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result); } if(success) @@ -1028,16 +1038,16 @@ ImmSubmit(Image* image, VkBufferImageCopy copy, void function(Image*, VkBufferIm } bool -ImmSubmit(Buffer* buf, VkBufferCopy copy, void function(Buffer*, VkBufferCopy) fn) +ImmSubmit(Descriptor* desc, VkBufferCopy copy, void function(Descriptor*, VkBufferCopy) fn) { bool success = ImmSubmitStart(); if(success) { - fn(buf, copy); + fn(desc, copy); VkResult result = vkEndCommandBuffer(g_vk.imm_cmd); - success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result); + success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result); } if(success) @@ -1061,70 +1071,111 @@ WaitForTransfers() } void -CreateImageView(Descriptor* view, u32 w, u32 h, u32 ch, u8[] data, DescType type = DT.Image, u32 binding, u32 index) +CreateDescriptor(T = u8[])(Descriptor* desc, DescInfo info, T data = null) if(is(T: u8[]) || isPointer!(T)) { - view.array_elem = true; - view.index = index; - CreateImageView(view, w, h, ch, data, type, binding); + enum DescType[] image_types = [DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach]; + enum DescType[] texel_types = [DT.UniformTexelBuf, DT.StorageTexelBuf]; + enum DescType[] buffer_types = [DT.Uniform, DT.DynamicUniform, DT.Storage, DT.DynamicStorage]; + + desc.type = info.type; + desc.binding = info.binding; + desc.index = info.index; + + if(canFind(image_types, info.type)) + { + desc.image.usage = info.usage; + desc.image.format = info.format; + desc.image.layout = IL.Undefined; + desc.image.w = info.w; + desc.image.h = info.h; + desc.image.ch = info.ch; + + static if(is(T: u8[])) + { + if(data.length) + { + CreateImageView(desc, data); + } + else + { + CreateImageView(desc); + } + } + else + { + CreateImageView(desc); + } + } + else if(canFind(texel_types, info.type)) + { + desc.buffer_view.size = info.size; + desc.buffer_view.format = info.format; + + CreateBufferView(desc); + + if(data) + { + Transfer(desc, data); + } + } + else if(canFind(buffer_types, info.type)) + { + CreateBuffer(&desc.buffer, info.buffer_type, info.size, info.host_visible); + + if(data) + { + Transfer(desc, data); + } + } + else if(info.type == DT.Sampler) + { + CreateSampler(desc, info.mipmap_mode); + } + else assert(false, "Unknown descriptor type in CreateDescriptor"); } void -CreateImageView(Descriptor* view, u32 w, u32 h, u32 ch, u8[] data, DescType type = DT.Image, u32 binding) +CreateImageView(Descriptor* desc, u8[] data) { - ImageDescCheck(type); - view.type = type; - view.binding = binding; - CreateImageView(&view.view, w, h, ch, data); -} + CreateImageView(desc); -void -CreateImageViewTex(Descriptor* desc, u32 w, u32 h, DescType type = DT.Image, u32 binding, u32 index) -{ - desc.array_elem = true; - desc.index = index; - CreateImageViewTex(desc, w, h, type, binding); -} - -void -CreateImageViewTex(Descriptor* desc, u32 w, u32 h, DescType type = DT.Image, u32 binding) -{ - ImageDescCheck(type); - desc.type = type; - desc.binding = binding; - CreateImageView(&desc.view, w, h, FMT.RGBA_UNORM, IU.Texture); -} - -void -CreateImageView(ImageView* view, u32 w, u32 h, u32 ch, u8[] data) -{ - CreateImageView(view, w, h, FMT.RGBA_UNORM, IU.Texture); - - if(ch == 4) + if(desc.image.ch == 4) { - bool result = Transfer(view, data, w, h); + bool result = Transfer!(true)(desc, data); assert(result); } else { Descriptor buf; - CreateBuffer(&buf, BT.Storage, w * h * ch, false, DT.Storage, 1); - bool result = Transfer(&buf.buf, data); + CreateDescriptor(&buf, DescInfo( + type: DT.Storage, + buffer_type: BT.Storage, + size: desc.image.w * desc.image.h * desc.image.ch, + binding: 1, + )); + bool result = Transfer(&buf.buffer, data); assert(result, "CreateImageView failure: Buffer Transfer error"); Descriptor conv_view; - CreateImageView(&conv_view, w, h, FMT.RGBA_F32, IU.Convert, DT.StorageImage, 0); + CreateDescriptor(&conv_view, DescInfo( + type: DT.StorageImage, + w: desc.image.w, + h: desc.image.h, + format: FMT.RGBA_F32, + usage: IU.Convert, + )); Write(g_vk.conv_desc_set, [conv_view, buf]); BeginComputePass(); - Pipeline pipeline = ch == 1 ? g_vk.r_to_rgba_pipeline : - ch == 2 ? g_vk.rg_to_rgba_pipeline : - g_vk.rgb_to_rgba_pipeline; + Pipeline pipeline = desc.image.ch == 1 ? g_vk.r_to_rgba_pipeline : + desc.image.ch == 2 ? g_vk.rg_to_rgba_pipeline : + g_vk.rgb_to_rgba_pipeline; Bind(pipeline, g_vk.conv_desc_set, true); - ConvPushConst pc = { x: w, y: h }; + ConvPushConst pc = { x: desc.image.w, y: desc.image.h }; vkCmdPushConstants( g_vk.comp_cmd, @@ -1139,12 +1190,12 @@ CreateImageView(ImageView* view, u32 w, u32 h, u32 ch, u8[] data) Dispatch(g_vk.comp_cmd); - Transition(g_vk.comp_cmd, view, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + Transition(g_vk.comp_cmd, desc, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - VkExtent2D extent = { width: w, height: h }; - Copy(g_vk.comp_cmd, &conv_view.view.base, &view.base, extent, extent); + VkExtent2D extent = { width: desc.image.w, height: desc.image.h }; + Copy(g_vk.comp_cmd, &conv_view, desc, extent, extent); - Transition(g_vk.comp_cmd, view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + Transition(g_vk.comp_cmd, desc, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); FinishComputePass(); @@ -1157,26 +1208,8 @@ CreateImageView(ImageView* view, u32 w, u32 h, u32 ch, u8[] data) } } - void -CreateImageView(Descriptor* desc, u32 w, u32 h, Format format, ImageUsage usage, DescType type, u32 binding, u32 index) -{ - desc.array_elem = true; - desc.index = index; - CreateImageView(desc, w, h, format, usage, type, binding); -} - -void -CreateImageView(Descriptor* desc, u32 w, u32 h, Format format, ImageUsage usage, DescType type, u32 binding) -{ - ImageDescCheck(type); - desc.type = type; - desc.binding = binding; - CreateImageView(&desc.view, w, h, format, usage); -} - -void -CreateImageView(ImageView* view, u32 w, u32 h, Format format, ImageUsage usage) +CreateImageView(Descriptor* desc) { VmaAllocationCreateInfo alloc_info = { usage: VMA_MEMORY_USAGE_GPU_ONLY, @@ -1188,14 +1221,14 @@ CreateImageView(ImageView* view, u32 w, u32 h, Format format, ImageUsage usage) imageType: VK_IMAGE_TYPE_2D, mipLevels: 1, arrayLayers: 1, - format: format, + format: desc.image.format, tiling: VK_IMAGE_TILING_OPTIMAL, initialLayout: VK_IMAGE_LAYOUT_UNDEFINED, - usage: usage, + usage: desc.image.usage, samples: VK_SAMPLE_COUNT_1_BIT, extent: { - width: w, - height: h, + width: desc.image.w, + height: desc.image.h, depth: 1, }, }; @@ -1208,42 +1241,37 @@ CreateImageView(ImageView* view, u32 w, u32 h, Format format, ImageUsage usage) image_info.pQueueFamilyIndices = indices.ptr; } - VkResult result = vmaCreateImage(g_vk.vma, &image_info, &alloc_info, &view.image, &view.alloc, null); + VkResult result = vmaCreateImage(g_vk.vma, &image_info, &alloc_info, &desc.image.image, &desc.image.alloc, null); // TODO: handle errors and realloc VkCheck("CreateImageView failure: vmaCreateImage error", result); VkImageViewCreateInfo view_info = { sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - image: view.image, + image: desc.image.image, viewType: VK_IMAGE_VIEW_TYPE_2D, - format: format, + format: desc.image.format, subresourceRange: { - aspectMask: (usage == IU.Depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), + aspectMask: (desc.image.usage == IU.Depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), levelCount: 1, layerCount: 1, }, }; - result = vkCreateImageView(g_vk.device, &view_info, null, &view.view); + result = vkCreateImageView(g_vk.device, &view_info, null, &desc.image.view); // TODO: also handle here VkCheck("CreateImageView failure: vkCreateImageView error", result); - view.layout = VK_IMAGE_LAYOUT_UNDEFINED; - view.format = format; - view.w = w; - view.h = h; - view.depth_image = usage == IU.Depth; - view.usage = usage; - - if(usage == IU.Draw || usage == IU.Depth || usage == IU.Convert) + if(desc.image.usage == IU.Draw || desc.image.usage == IU.Depth || desc.image.usage == IU.Convert) { - view.shader_layout = IL.General; + desc.image.shader_layout = IL.General; } - else if(usage == IU.Texture) + else if(desc.image.usage == IU.Texture) { - view.shader_layout = IL.ReadOnly; + desc.image.shader_layout = IL.ReadOnly; } else assert(false, "Unimplemented usage"); + + desc.image.layout = IL.Undefined; } void @@ -1290,22 +1318,19 @@ FinishComputePass() } void -CreateBufferView(Descriptor* desc, u64 size, Format format, DescType type, u32 binding) +CreateBufferView(Descriptor* desc) { - CreateBuffer(&desc.buf_view.base, BT.BufferView, size, false); + CreateBuffer(&desc.buffer_view.base, BT.BufferView, desc.buffer_view.size, false); VkBufferViewCreateInfo info = { sType: VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, - buffer: desc.buf_view.buffer, - format: format, - range: size, + buffer: desc.buffer_view.buffer, + format: desc.buffer_view.format, + range: desc.buffer_view.size, }; - VkResult result = vkCreateBufferView(g_vk.device, &info, null, &desc.buf_view.view); + VkResult result = vkCreateBufferView(g_vk.device, &info, null, &desc.buffer_view.view); VkCheckA("CreateBufferView failure: vkCreateBufferView failed", result); - - desc.binding = binding; - desc.buf_view.size = size; } void @@ -1349,54 +1374,20 @@ ImageBarrier() } bool -Transfer(T)(Buffer* buf, T[] data) +Transfer(T, U)(T* dst, U[] data) { + static if(is(T: Descriptor)) + { + Buffer* buffer = &dst.buffer; + } + else static if(is(T: Buffer)) + { + Buffer* buffer = dst; + } + else static assert(false, "Invalid type for transfer target"); + u8[] u8_data = (cast(u8*)(data.ptr))[0 .. T.sizeof * data.length]; - return Transfer(buf, u8_data); -} - -bool -Transfer(Buffer* buf, u8[] data) -{ - bool success = TransferReady(); - - u64 copied = 0; - while(copied != data.length && success) - { - if(copied != 0) - { - success = TransferReady(); - if(!success) - { - break; - } - } - - u64 transfer_length = cast(u64)g_vk.transfer_buf.data.length; - u64 data_length = cast(u64)data.length - copied; - u64 copy_length = transfer_length > data_length ? data_length : transfer_length; - - g_vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length]; - - auto fn = function(Buffer* buf, VkBufferCopy copy) - { - vkCmdCopyBuffer(g_vk.imm_cmd, g_vk.transfer_buf.buffer, buf.buffer, 1, ©); - }; - - VkBufferCopy copy = { - srcOffset: 0, - dstOffset: copied, - size: copy_length, - }; - - success = ImmSubmit(buf, copy, fn); - - copied += copy_length; - } - - WaitForTransfers(); - - return success; + return Transfer(buffer, u8_data); } bool @@ -1437,13 +1428,7 @@ TransferReady() } bool -Transfer(ImageView* view, u8[] data, u32 w, u32 h) -{ - return Transfer(&view.base, data, w, h); -} - -bool -Transfer(Image* image, u8[] data, u32 w, u32 h) +Transfer(bool image)(Descriptor* desc, u8[] data) { bool success = true; @@ -1451,37 +1436,52 @@ Transfer(Image* image, u8[] data, u32 w, u32 h) while(copied != data.length) { u64 transfer_length = cast(u64)g_vk.transfer_buf.data.length; - u64 data_length = cast(u64)data.length - copied; - u64 copy_length = transfer_length > data_length ? data_length : transfer_length; + u64 data_length = cast(u64)data.length - copied; + u64 copy_length = transfer_length > data_length ? data_length : transfer_length; g_vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length]; - auto fn = function(Image* image, VkBufferImageCopy copy) - { - Transition(g_vk.imm_cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + static if(image) + { + auto fn = function(Descriptor* desc, VkBufferImageCopy copy) + { + Transition(g_vk.imm_cmd, desc, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - vkCmdCopyBufferToImage(g_vk.imm_cmd, g_vk.transfer_buf.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©); - - Transition(g_vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - }; + vkCmdCopyBufferToImage(g_vk.imm_cmd, g_vk.transfer_buf.buffer, desc.image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©); - VkBufferImageCopy copy = { - bufferRowLength: w, - bufferImageHeight: h, - imageSubresource: { - aspectMask: VK_IMAGE_ASPECT_COLOR_BIT, - layerCount: 1, - }, - imageExtent: { - width: w, - height: h, - depth: 1, - }, - bufferOffset: copied, - }; + Transition(g_vk.imm_cmd, desc, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + }; - success = ImmSubmit(image, copy, fn); + VkBufferImageCopy copy = { + bufferRowLength: desc.image.w, + bufferImageHeight: desc.image.h, + imageSubresource: { + aspectMask: VK_IMAGE_ASPECT_COLOR_BIT, + layerCount: 1, + }, + imageExtent: { + width: desc.image.w, + height: desc.image.h, + depth: 1, + }, + bufferOffset: copied, + }; + } + else + { + auto fn = function(Descriptor* desc, VkBufferCopy copy) + { + vkCmdCopyBuffer(g_vk.imm_cmd, g_vk.transfer_buf.buffer, desc.buffer.buffer, 1, ©); + }; + VkBufferCopy copy = { + srcOffset: 0, + dstOffset: copied, + size: copy_length, + }; + } + + success = ImmSubmit(desc, copy, fn); copied += copy_length; } @@ -1491,15 +1491,15 @@ Transfer(Image* image, u8[] data, u32 w, u32 h) } void -Copy(VkCommandBuffer cmd, Image* src, Image* dst, VkExtent2D src_ext, VkExtent2D dst_ext) +Copy(VkCommandBuffer cmd, Descriptor* src, Descriptor* dst, VkExtent2D src_ext, VkExtent2D dst_ext) { - Copy(cmd, src.image, dst.image, src.layout, dst.layout, src_ext, dst_ext); + Copy(cmd, src.image.image, dst.image.image, src.image.layout, dst.image.layout, src_ext, dst_ext); } void -Copy(VkCommandBuffer cmd, Image* src, VkImage dst, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext) +Copy(VkCommandBuffer cmd, Descriptor* src, VkImage dst, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext) { - Copy(cmd, src.image, dst, src.layout, dst_layout, src_ext, dst_ext); + Copy(cmd, src.image.image, dst, src.image.layout, dst_layout, src_ext, dst_ext); } void @@ -1696,6 +1696,12 @@ ResetScissor(VkCommandBuffer cmd = cast(VkCommandBuffer)VK_NULL_HANDLE) vkCmdSetScissor(cmd, 0, 1, &scissor); } +void +Transition(VkCommandBuffer cmd, Descriptor* desc, VkImageLayout new_layout) +{ + ImageDescCheck(desc); + Transition(cmd, desc.image.image, desc.image.layout, new_layout); +} void Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout) @@ -1727,47 +1733,23 @@ Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkI vkCmdPipelineBarrier2(cmd, &dep_info); } -void +bool ImageDescCheck(Descriptor* desc) { - ImageDescCheck(desc.type); + return ImageDescCheck(desc.type); } -void +bool ImageDescCheck(DescType desc_type) { - debug - { - bool match; - enum types = [DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach]; - static foreach(type; types) - { - match |= desc_type == type; - } + bool match; + enum types = [DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach]; + static foreach(type; types) + { + match |= desc_type == type; + } - assert(match, "Unable to transition non image"); - } -} - -void -Transition(VkCommandBuffer cmd, Descriptor* desc, VkImageLayout new_layout) -{ - ImageDescCheck(desc); - Transition(cmd, &desc.view, new_layout); -} - -void -Transition(VkCommandBuffer cmd, ImageView* view, VkImageLayout new_layout) -{ - Transition(cmd, view.image, view.layout, new_layout); - view.layout = new_layout; -} - -void -Transition(VkCommandBuffer cmd, Image* image, VkImageLayout new_layout) -{ - Transition(cmd, image.image, image.layout, new_layout); - image.layout = new_layout; + return match; } bool @@ -1787,7 +1769,8 @@ bool CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info) { PipelineHandles* pipeline = NewPipeline(); - pipeline.type = VK_PIPELINE_BIND_POINT_GRAPHICS; + + pipeline.type = VK_PIPELINE_BIND_POINT_GRAPHICS; pipeline.layout = build_info.layout; VkDynamicState[4] dyn_state = [ @@ -1798,88 +1781,88 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info) ]; VkPipelineDynamicStateCreateInfo dyn_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - pDynamicStates: dyn_state.ptr, + sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + pDynamicStates: dyn_state.ptr, dynamicStateCount: cast(u32)dyn_state.length, }; VkPipelineInputAssemblyStateCreateInfo assembly_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - topology: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + sType: VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + topology: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, primitiveRestartEnable: VK_FALSE, }; VkPipelineRasterizationStateCreateInfo rasterization_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - cullMode: VK_CULL_MODE_BACK_BIT, + sType: VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + cullMode: VK_CULL_MODE_BACK_BIT, polygonMode: VK_POLYGON_MODE_FILL, - lineWidth: 1.0, - frontFace: cast(VkFrontFace)build_info.front_face, + lineWidth: 1.0, + frontFace: cast(VkFrontFace)build_info.front_face, }; VkPipelineMultisampleStateCreateInfo multisample_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - rasterizationSamples: VK_SAMPLE_COUNT_1_BIT, - minSampleShading: 1.0, + sType: VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + rasterizationSamples: VK_SAMPLE_COUNT_1_BIT, + minSampleShading: 1.0, alphaToCoverageEnable: VK_FALSE, - alphaToOneEnable: VK_FALSE, + alphaToOneEnable: VK_FALSE, }; VkPipelineDepthStencilStateCreateInfo depth_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - depthTestEnable: VK_TRUE, - depthWriteEnable: VK_TRUE, - depthCompareOp: VK_COMPARE_OP_GREATER_OR_EQUAL, + sType: VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + depthTestEnable: VK_TRUE, + depthWriteEnable: VK_TRUE, + depthCompareOp: VK_COMPARE_OP_GREATER_OR_EQUAL, depthBoundsTestEnable: VK_FALSE, - stencilTestEnable: VK_FALSE, - minDepthBounds: 0.0, - maxDepthBounds: 1.0, + stencilTestEnable: VK_FALSE, + minDepthBounds: 0.0, + maxDepthBounds: 1.0, }; VkPipelineRenderingCreateInfo rendering_info = { sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - colorAttachmentCount: 1, - pColorAttachmentFormats: cast(VkFormat*)&g_vk.draw_image.view.format, - depthAttachmentFormat: g_vk.depth_image.view.format, + colorAttachmentCount: 1, + pColorAttachmentFormats: cast(VkFormat*)&g_vk.draw_image.image.format, + depthAttachmentFormat: g_vk.depth_image.image.format, }; VkPipelineColorBlendAttachmentState blend_state = { - colorWriteMask: VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - blendEnable: VK_TRUE, + colorWriteMask: VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + blendEnable: VK_TRUE, srcColorBlendFactor: build_info.src_color, dstColorBlendFactor: build_info.dst_color, - colorBlendOp: build_info.color_op, + colorBlendOp: build_info.color_op, srcAlphaBlendFactor: build_info.src_alpha, dstAlphaBlendFactor: build_info.dst_alpha, - alphaBlendOp: build_info.alpha_op, + alphaBlendOp: build_info.alpha_op, }; VkPipelineColorBlendStateCreateInfo blend_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - logicOpEnable: VK_FALSE, - logicOp: VK_LOGIC_OP_COPY, + sType: VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + logicOpEnable: VK_FALSE, + logicOp: VK_LOGIC_OP_COPY, attachmentCount: 1, - pAttachments: &blend_state, + pAttachments: &blend_state, }; VkVertexInputBindingDescription vertex_input_desc = { - binding: 0, + binding: 0, inputRate: cast(VkVertexInputRate)build_info.input_rate, - stride: build_info.input_rate_stride, + stride: build_info.input_rate_stride, }; VkPipelineVertexInputStateCreateInfo input_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - vertexBindingDescriptionCount: 1, - pVertexBindingDescriptions: &vertex_input_desc, + sType: VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + vertexBindingDescriptionCount: 1, + pVertexBindingDescriptions: &vertex_input_desc, vertexAttributeDescriptionCount: cast(u32)build_info.vertex_attributes.length, - pVertexAttributeDescriptions: build_info.vertex_attributes.ptr, + pVertexAttributeDescriptions: build_info.vertex_attributes.ptr, }; VkPipelineViewportStateCreateInfo viewport_info = { - sType: VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + sType: VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, viewportCount: 1, - scissorCount: 1, + scissorCount: 1, }; VkPipelineShaderStageCreateInfo[2] shader_info = [ @@ -1915,10 +1898,10 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info) __traits(getMember, shader_info.ptr + 1, "module") = vert_module; VkSpecializationInfo vert_spec_info = { - dataSize: build_info.vert_spec.size, + dataSize: build_info.vert_spec.size, mapEntryCount: cast(u32)build_info.vert_spec.entries.length, - pMapEntries: build_info.vert_spec.entries.ptr, - pData: build_info.vert_spec.data, + pMapEntries: build_info.vert_spec.entries.ptr, + pData: build_info.vert_spec.data, }; if(build_info.vert_spec.entries.length > 0) @@ -1927,10 +1910,10 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info) } VkSpecializationInfo frag_spec_info = { - dataSize: build_info.frag_spec.size, + dataSize: build_info.frag_spec.size, mapEntryCount: cast(u32)build_info.frag_spec.entries.length, - pMapEntries: build_info.frag_spec.entries.ptr, - pData: build_info.frag_spec.data, + pMapEntries: build_info.frag_spec.entries.ptr, + pData: build_info.frag_spec.data, }; if(build_info.frag_spec.entries.length > 0) @@ -1939,20 +1922,20 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info) } VkGraphicsPipelineCreateInfo create_info = { - sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - pNext: &rendering_info, - pVertexInputState: &input_info, + sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + pNext: &rendering_info, + pVertexInputState: &input_info, pInputAssemblyState: &assembly_info, - pViewportState: &viewport_info, + pViewportState: &viewport_info, pRasterizationState: &rasterization_info, - pMultisampleState: &multisample_info, - pColorBlendState: &blend_info, - pDepthStencilState: &depth_info, - pDynamicState: &dyn_info, - stageCount: cast(u32)shader_info.length, - pStages: shader_info.ptr, - renderPass: g_vk.render_pass, - layout: build_info.layout, + pMultisampleState: &multisample_info, + pColorBlendState: &blend_info, + pDepthStencilState: &depth_info, + pDynamicState: &dyn_info, + stageCount: cast(u32)shader_info.length, + pStages: shader_info.ptr, + renderPass: g_vk.render_pass, + layout: build_info.layout, }; VkResult result = vkCreateGraphicsPipelines(g_vk.device, null, 1, &create_info, null, &pipeline.handle); @@ -1968,7 +1951,7 @@ Pipeline CreateComputePipeline(CompPipelineInfo* comp_info) { VkComputePipelineCreateInfo info = { - sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, layout: comp_info.layout, stage: { sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, @@ -1984,10 +1967,10 @@ CreateComputePipeline(CompPipelineInfo* comp_info) __traits(getMember, &info.stage, "module") = comp_module; VkSpecializationInfo spec_info = { - dataSize: comp_info.spec.size, + dataSize: comp_info.spec.size, mapEntryCount: cast(u32)comp_info.spec.entries.length, - pMapEntries: comp_info.spec.entries.ptr, - pData: comp_info.spec.data, + pMapEntries: comp_info.spec.entries.ptr, + pData: comp_info.spec.data, }; if(comp_info.spec.entries.length > 0) @@ -1996,7 +1979,7 @@ CreateComputePipeline(CompPipelineInfo* comp_info) } PipelineHandles* pipeline = NewPipeline(); - pipeline.type = VK_PIPELINE_BIND_POINT_COMPUTE; + pipeline.type = VK_PIPELINE_BIND_POINT_COMPUTE; pipeline.layout = comp_info.layout; Pipeline pipeline_handle = pipeline.index; @@ -2043,24 +2026,17 @@ ClearColor(f32[4] color) void ClearColor(Descriptor* desc, f32[4] color) -{ - ImageDescCheck(desc); - ClearColor(&desc.view, color); -} - -void -ClearColor(ImageView* view, f32[4] color) { VkImageSubresourceRange clear_range = { - aspectMask: (view.depth_image ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), + aspectMask: (desc.image.usage == IU.Depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), levelCount: 1, layerCount: 1, }; vkCmdClearColorImage( g_vk.cmd, - view.image, - view.layout, + desc.image.image, + desc.image.layout, cast(VkClearColorValue*)color, 1, &clear_range @@ -2150,11 +2126,7 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc) write.dstSet = set.handle; write.dstBinding = desc.binding; write.descriptorCount = 1; - - if(desc.array_elem) - { - write.dstArrayElement = desc.index; - } + write.dstArrayElement = desc.index; switch(desc.type) with(DescType) { @@ -2162,22 +2134,22 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc) { VkDescriptorImageInfo* info = Alloc!(VkDescriptorImageInfo)(arena); - info.imageView = desc.view.view; - info.imageLayout = desc.view.shader_layout; + info.imageView = desc.image.view; + info.imageLayout = desc.image.shader_layout; write.pImageInfo = info; } break; case Uniform, Storage: { VkDescriptorBufferInfo* info = Alloc!(VkDescriptorBufferInfo)(arena); - info.buffer = desc.buf.buffer; + info.buffer = desc.buffer.buffer; info.offset = cast(VkDeviceSize)0; - info.range = cast(VkDeviceSize)desc.buf.size; + info.range = cast(VkDeviceSize)desc.buffer.size; write.pBufferInfo = info; } break; case UniformTexelBuf, StorageTexelBuf: { - write.pTexelBufferView = &desc.buf_view.view; + write.pTexelBufferView = &desc.buffer_view.view; } break; case Sampler: { @@ -2371,8 +2343,8 @@ SelectSwapchainFormats() g_vk.present_mode = present_mode; } -Descriptor -CreateSampler(MipmapMode mode, u32 binding) +void +CreateSampler(Descriptor* desc, MipmapMode mode) { VkPhysicalDeviceProperties props; vkGetPhysicalDeviceProperties(g_vk.physical_device, &props); @@ -2391,15 +2363,8 @@ CreateSampler(MipmapMode mode, u32 binding) mipmapMode: mode, }; - Descriptor sampler = { - type: DT.Sampler, - binding: binding, - }; - - VkResult result = vkCreateSampler(g_vk.device, &sampler_info, null, &sampler.sampler); + VkResult result = vkCreateSampler(g_vk.device, &sampler_info, null, &desc.sampler); VkCheckA("vkCreateSampler failure", result); - - return sampler; } bool @@ -2413,8 +2378,8 @@ CreateDrawImages() u32 w = g_vk.swapchain_extent.width; u32 h = g_vk.swapchain_extent.height; - CreateImageView(&g_vk.draw_image, w, h, draw_format, IU.Draw, DT.StorageImage, 0); - CreateImageView(&g_vk.depth_image, w, h, depth_format, IU.Depth, DT.Image, 0); + 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)); return success; } @@ -2438,37 +2403,37 @@ CreateSwapchain() u32 h = clamp(cast(u32)g_vk.res[1], cap.minImageExtent.height, cap.maxImageExtent.height); VkSwapchainCreateInfoKHR info = { - sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, imageArrayLayers: 1, - imageUsage: IU.Swapchain, - compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - clipped: VK_TRUE, + imageUsage: IU.Swapchain, + compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + clipped: VK_TRUE, imageSharingMode: VK_SHARING_MODE_EXCLUSIVE, - minImageCount: cap.minImageCount + 1, - surface: g_vk.surface, - imageFormat: g_vk.surface_format.format, - imageColorSpace: g_vk.surface_format.colorSpace, + minImageCount: cap.minImageCount + 1, + surface: g_vk.surface, + imageFormat: g_vk.surface_format.format, + imageColorSpace: g_vk.surface_format.colorSpace, + preTransform: cap.currentTransform, + presentMode: g_vk.present_mode, imageExtent: { width: w, height: h, }, - preTransform: cap.currentTransform, - presentMode: g_vk.present_mode, }; VkResult result = vkCreateSwapchainKHR(g_vk.device, &info, null, &g_vk.swapchain); - success = VkCheck("vkCreateSwapchainKHR failure", result); + success = VkCheck("vkCreateSwapchainKHR failure", result); u32 count; vkGetSwapchainImagesKHR(g_vk.device, g_vk.swapchain, &count, null); - VkImage[] images = Alloc!(VkImage)(arena, count); + VkImage[] images = Alloc!(VkImage)(arena, count); vkGetSwapchainImagesKHR(g_vk.device, g_vk.swapchain, &count, images.ptr); VkImageView[] views = Alloc!(VkImageView)(arena, count); - g_vk.present_images = Alloc!(ImageView)(&g_vk.arena, count); + g_vk.present_images = Alloc!(Descriptor)(&g_vk.arena, count); VkImageViewCreateInfo view_info = { - sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, viewType: VK_IMAGE_VIEW_TYPE_2D, components: { r: VK_COMPONENT_SWIZZLE_IDENTITY, @@ -2477,26 +2442,25 @@ CreateSwapchain() a: VK_COMPONENT_SWIZZLE_IDENTITY, }, subresourceRange: { - aspectMask: VK_IMAGE_ASPECT_COLOR_BIT, - baseMipLevel: 0, - levelCount: 1, + aspectMask: VK_IMAGE_ASPECT_COLOR_BIT, + baseMipLevel: 0, + levelCount: 1, baseArrayLayer: 0, - layerCount: 1, + layerCount: 1, }, }; - VkFramebufferCreateInfo framebuffer_info = { - sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - }; + VkFramebufferCreateInfo framebuffer_info = { sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; - foreach(i, image; g_vk.present_images) + foreach(i; 0 .. g_vk.present_images.length) { - g_vk.present_images[i].image = images[i]; - g_vk.present_images[i].format = cast(Format)g_vk.surface_format.format; - view_info.image = images[i]; + g_vk.present_images[i].image.image = images[i]; + g_vk.present_images[i].image.format = cast(Format)g_vk.surface_format.format; + + view_info.image = images[i]; view_info.format = g_vk.surface_format.format; - result = vkCreateImageView(g_vk.device, &view_info, null, &g_vk.present_images[i].view); + result = vkCreateImageView(g_vk.device, &view_info, null, &g_vk.present_images[i].image.view); success = VkCheck("vkCreateImageView failure", result); } @@ -2537,7 +2501,7 @@ CreateFramebuffer() sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, renderPass: g_vk.render_pass, attachmentCount: 2, - pAttachments: [g_vk.draw_image.view.view, g_vk.depth_image.view.view], + 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, @@ -2571,33 +2535,33 @@ Destroy(Descriptor* desc) } break; case DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach: { - if(desc.view.view) + if(desc.image.view) { - vkDestroyImageView(g_vk.device, desc.view.view, null); + vkDestroyImageView(g_vk.device, desc.image.view, null); } - if(desc.view.image) + if(desc.image.image) { - vmaDestroyImage(g_vk.vma, desc.view.image, desc.view.alloc); + vmaDestroyImage(g_vk.vma, desc.image.image, desc.image.alloc); } } break; case DT.UniformTexelBuf, DT.StorageTexelBuf: { - if(desc.buf_view.view) + if(desc.buffer_view.view) { - vkDestroyBufferView(g_vk.device, desc.buf_view.view, null); + vkDestroyBufferView(g_vk.device, desc.buffer_view.view, null); } - if(desc.buf_view.buffer) + if(desc.buffer_view.buffer) { - vmaDestroyBuffer(g_vk.vma, desc.buf_view.buffer, desc.buf_view.alloc); + vmaDestroyBuffer(g_vk.vma, desc.buffer_view.buffer, desc.buffer_view.alloc); } } break; case DT.Uniform, DT.DynamicUniform, DT.Storage, DT.DynamicStorage: { - if(desc.buf.buffer) + if(desc.buffer.buffer) { - vmaDestroyBuffer(g_vk.vma, desc.buf.buffer, desc.buf.alloc); + vmaDestroyBuffer(g_vk.vma, desc.buffer.buffer, desc.buffer.alloc); } } break; default: assert(false, "Unsupported descriptor Destroy call"); @@ -2643,13 +2607,13 @@ Destroy(VkSurfaceKHR surface, VkInstance instance) } void -Destroy(VkSwapchainKHR swapchain, ImageView[] views, VkDevice device) +Destroy(VkSwapchainKHR swapchain, Descriptor[] images, VkDevice device) { - foreach(view; views) + foreach(ref image; images) { - if(view.view) + if(image.image.view) { - vkDestroyImageView(device, view.view, null); + vkDestroyImageView(device, image.image.view, null); } } @@ -3341,60 +3305,60 @@ Init(PlatformHandles platform_handles, u64 permanent_mem, u64 frame_mem) VkAttachmentDescription[2] attach_descriptions = [ { - format: g_vk.draw_image.view.format, - samples: VK_SAMPLE_COUNT_1_BIT, - loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, - storeOp: VK_ATTACHMENT_STORE_OP_STORE, - stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE, + 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, + stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE, stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE, - initialLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - finalLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + initialLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + finalLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, }, { - format: g_vk.depth_image.view.format, - samples: VK_SAMPLE_COUNT_1_BIT, - loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, - storeOp: VK_ATTACHMENT_STORE_OP_STORE, + format: g_vk.depth_image.image.format, + samples: VK_SAMPLE_COUNT_1_BIT, + loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, + storeOp: VK_ATTACHMENT_STORE_OP_STORE, initialLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - finalLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + finalLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, }, ]; VkAttachmentReference color_ref = { attachment: 0, - layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, }; VkAttachmentReference depth_ref = { attachment: 1, - layout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + layout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, }; VkSubpassDescription subpass = { - pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS, - colorAttachmentCount: 1, - pColorAttachments: &color_ref, + pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS, + colorAttachmentCount: 1, + pColorAttachments: &color_ref, pDepthStencilAttachment: &depth_ref, }; VkSubpassDependency self_dependency = { - srcSubpass: 0, - dstSubpass: 0, - srcStageMask: VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - dstStageMask: VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - srcAccessMask: VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, - dstAccessMask: VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + srcSubpass: 0, + dstSubpass: 0, + srcStageMask: VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + dstStageMask: VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + srcAccessMask: VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + dstAccessMask: VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, dependencyFlags: VK_DEPENDENCY_BY_REGION_BIT, }; VkRenderPassCreateInfo pass_info = { - sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, attachmentCount: cast(u32)attach_descriptions.length, - pAttachments: attach_descriptions.ptr, - subpassCount: 1, - pSubpasses: &subpass, + pAttachments: attach_descriptions.ptr, + subpassCount: 1, + pSubpasses: &subpass, dependencyCount: 1, - pDependencies: &self_dependency, + pDependencies: &self_dependency, }; VkResult result = vkCreateRenderPass(g_vk.device, &pass_info, null, &g_vk.render_pass);