diff --git a/assets/shaders/convert.comp.spv b/assets/shaders/convert.comp.spv index c8447df..7023756 100644 Binary files a/assets/shaders/convert.comp.spv and b/assets/shaders/convert.comp.spv differ diff --git a/assets/shaders/full_screen_triangle.vert.spv b/assets/shaders/full_screen_triangle.vert.spv index c353e8c..1a4ea85 100644 Binary files a/assets/shaders/full_screen_triangle.vert.spv and b/assets/shaders/full_screen_triangle.vert.spv differ diff --git a/assets/shaders/gradient.comp.spv b/assets/shaders/gradient.comp.spv index 035a46b..f0d9fd6 100644 Binary files a/assets/shaders/gradient.comp.spv and b/assets/shaders/gradient.comp.spv differ diff --git a/assets/shaders/gui.frag.spv b/assets/shaders/gui.frag.spv index 4f894f9..d9f1e3d 100644 Binary files a/assets/shaders/gui.frag.spv and b/assets/shaders/gui.frag.spv differ diff --git a/assets/shaders/gui.vert.spv b/assets/shaders/gui.vert.spv index a899b9b..42d46a6 100644 Binary files a/assets/shaders/gui.vert.spv and b/assets/shaders/gui.vert.spv differ diff --git a/assets/shaders/oit.frag.spv b/assets/shaders/oit.frag.spv index 4f54526..63f2b83 100644 Binary files a/assets/shaders/oit.frag.spv and b/assets/shaders/oit.frag.spv differ diff --git a/assets/shaders/pbr.frag.spv b/assets/shaders/pbr.frag.spv index e69ab73..cb35262 100644 Binary files a/assets/shaders/pbr.frag.spv and b/assets/shaders/pbr.frag.spv differ diff --git a/assets/shaders/pbr.vert.spv b/assets/shaders/pbr.vert.spv index c0ddc20..6b77a51 100644 Binary files a/assets/shaders/pbr.vert.spv and b/assets/shaders/pbr.vert.spv differ diff --git a/assets/shaders/triangle.frag.spv b/assets/shaders/triangle.frag.spv index ca7b677..bf13751 100644 Binary files a/assets/shaders/triangle.frag.spv and b/assets/shaders/triangle.frag.spv differ diff --git a/assets/shaders/triangle.vert.spv b/assets/shaders/triangle.vert.spv index 7ce0591..f324bce 100644 Binary files a/assets/shaders/triangle.vert.spv and b/assets/shaders/triangle.vert.spv differ diff --git a/build.sh b/build.sh index cf91ba1..e11c140 100755 --- a/build.sh +++ b/build.sh @@ -4,7 +4,7 @@ set -eu # SHADERS shader_compiler="glslc" -shader_flags="--target-spv=spv1.6 -std=460 --target-env=vulkan1.3" +shader_flags="--target-spv=spv1.5 -std=460 --target-env=vulkan1.3" shader_out="-oassets/shaders/" mkdir -p assets/shaders diff --git a/src/gears/game.d b/src/gears/game.d index dafc018..5c93eb5 100644 --- a/src/gears/game.d +++ b/src/gears/game.d @@ -108,22 +108,16 @@ InitGame(PlatformWindow* window) UVec2 ext = GetExtent(&g.rd); - CreateImageView(&g.rd, &g.draw_image, ext.x, ext.y, GetDrawImageFormat(&g.rd), IU.Draw, false); - CreateImageView(&g.rd, &g.depth_image, ext.x, ext.y, FMT.D_SF32, IU.Depth, true); CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage); GfxPipelineInfo triangle_info = { vertex_shader: "shaders/triangle.vert.spv", frag_shader: "shaders/triangle.frag.spv", - draw_image: &g.draw_image, - depth_image: &g.depth_image, }; GfxPipelineInfo ui_info = { vertex_shader: "shaders/gui.vert.spv", frag_shader: "shaders/gui.frag.spv", - draw_image: &g.draw_image, - depth_image: &g.depth_image, input_rate: IR.Instance, input_rate_stride: UIVertex.sizeof, vertex_attributes: [ @@ -137,8 +131,6 @@ InitGame(PlatformWindow* window) GfxPipelineInfo pbr_info = { vertex_shader: "shaders/pbr.vert.spv", frag_shader: "shaders/pbr.frag.spv", - draw_image: &g.draw_image, - depth_image: &g.depth_image, input_rate_stride: Vertex.sizeof, vertex_attributes: [ { binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 }, @@ -152,8 +144,6 @@ InitGame(PlatformWindow* window) GfxPipelineInfo oit_info = { vertex_shader: "shaders/full_screen_triangle.vert.spv", frag_shader: "shaders/oit.frag.spv", - draw_image: &g.draw_image, - depth_image: &g.depth_image, }; CompPipelineInfo gradient_info = { @@ -250,8 +240,6 @@ Cycle(Game* g) ProcessInputs(g, &g.camera); - ResizeDrawImageIfNeeded(&g.rd, &g.draw_image); - ResizeDrawImageIfNeeded(&g.rd, &g.depth_image); ResizeDrawImageIfNeeded(&g.rd, &g.aux_image); UpdateAuxImage(&g.rd, &g.aux_image); @@ -282,7 +270,7 @@ Cycle(Game* g) g.globals.res.y = ext.y; SetUniform(&g.rd, &g.globals); - BeginRendering(&g.rd, &g.draw_image, &g.depth_image); + BeginRendering(&g.rd); Bind(&g.rd, &g.ui_pipeline); @@ -323,7 +311,7 @@ Cycle(Game* g) //FinishRendering(&g.rd); - SubmitAndPresent(&g.rd, &g.draw_image); + SubmitAndPresent(&g.rd); } pragma(inline): void diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index 70ffd45..1e86bc7 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -61,6 +61,7 @@ const char*[] VK_BASE_DEVICE_EXTENSIONS = [ cast(char*)VK_KHR_SWAPCHAIN_EXTENSION_NAME, cast(char*)VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, cast(char*)VK_KHR_8BIT_STORAGE_EXTENSION_NAME, + cast(char*)VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, ]; const char*[] VK_AMD_DEVICE_EXTENSIONS = [ @@ -150,9 +151,9 @@ struct GlobalUniforms Mat4 projection_view = Mat4Identity(); Vec4 light_color; Vec4 ambient_color; - vec3 light_direction; + Vec3 light_direction; f32 padding; - vec2 res; + Vec2 res; } struct Image @@ -219,8 +220,6 @@ struct GfxPipelineInfo Attribute[] vertex_attributes; Specialization vert_spec; Specialization frag_spec; - ImageView* draw_image; - ImageView* depth_image; bool self_dependency; } @@ -307,7 +306,7 @@ struct Vulkan VkExtent3D swapchain_extent; VkRenderPass render_pass; - VkFramebuffer[] framebuffers; + VkFramebuffer framebuffer; ImageView[] present_images; u32 image_index; @@ -418,6 +417,7 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem) if (success) success = InitDescriptors(&vk); if (success) InitBuffers(&vk); if (success) success = InitConversionPipeline(&vk); + if (success) InitFramebufferAndRenderPass(&vk); assert(success, "Error initializing vulkan"); @@ -671,6 +671,12 @@ BeginFrame(Vulkan* vk) void BeginRendering(Vulkan* vk) { + Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + Transition(vk.cmds[vk.frame_index], &vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + + VkImage image = CurrentImage(vk); + Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + VkClearValue clear_color = { color: { float32: [0.0, 0.0, 0.0, 1.0], @@ -680,13 +686,16 @@ BeginRendering(Vulkan* vk) VkRenderPassBeginInfo pass_info = { sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, renderPass: vk.render_pass, - framebuffer: vk.framebuffers[vk.image_index], + framebuffer: vk.framebuffer, renderArea: { offset: { x: 0, y: 0, }, - extent: vk.swapchain_extent, + extent: { + width: vk.swapchain_extent.width, + height: vk.swapchain_extent.height, + }, }, clearValueCount: 1, pClearValues: &clear_color, @@ -738,7 +747,7 @@ FinishRendering(Vulkan* vk) } void -SubmitAndPresent(Vulkan* vk, ImageView* draw_image) +SubmitAndPresent(Vulkan* vk) { scope(exit) { @@ -750,7 +759,7 @@ SubmitAndPresent(Vulkan* vk, ImageView* draw_image) VkSemaphore acquire_sem = vk.acquire_sems[vk.frame_index]; VkSemaphore submit_sem = vk.submit_sems[vk.image_index]; - Transition(vk.cmds[vk.frame_index], draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); VkExtent2D extent = { width: vk.swapchain_extent.width, @@ -758,27 +767,43 @@ SubmitAndPresent(Vulkan* vk, ImageView* draw_image) }; // TODO: Find out how to copy from same dimension images (pretty sure its not blitting) - Copy(vk.cmds[vk.frame_index], &draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); + Copy(vk.cmds[vk.frame_index], &vk.draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); VkResult result = vkEndCommandBuffer(vk.cmds[vk.frame_index]); VkCheckA("FinishFrame failure: vkEndCommandBuffer error", result); - VkPipelineStage stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - - VkSubmitInfo submit_info = { - sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, - waitSemaphoreCount: 1, - pWaitSemaphores: &acquire_sem, - pWaitDstStageMask: &stage, - commandBufferCount: 1, - pCommandBuffers: vk.cmds.ptr + vk.frame_index, - signalSemaphoreCount: 1, - pSignalSemaphores: &submit_sem, + VkCommandBufferSubmitInfo cmd_info = { + sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, + commandBuffer: vk.cmds[vk.frame_index], }; - result = vkQueueSubmit(vk.queues.gfx_queue, 1, &submit_info, vk.render_fences[vk.frame_index]); + VkSemaphoreSubmitInfo wait_info = { + sType: VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, + semaphore: acquire_sem, + stageMask: VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + value: 1, + }; + + VkSemaphoreSubmitInfo signal_info = { + sType: VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, + semaphore: submit_sem, + stageMask: VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, + value: 1, + }; + + VkSubmitInfo2 submit_info = { + sType: VK_STRUCTURE_TYPE_SUBMIT_INFO_2, + waitSemaphoreInfoCount: 1, + pWaitSemaphoreInfos: &wait_info, + signalSemaphoreInfoCount: 1, + pSignalSemaphoreInfos: &signal_info, + commandBufferInfoCount: 1, + pCommandBufferInfos: &cmd_info, + }; + + result = vkQueueSubmit2(vk.queues.gfx_queue, 1, &submit_info, vk.render_fences[vk.frame_index]); VkCheckA("FinishFrame failure: vkQueueSubmit2 error", result); VkPresentInfoKHR present_info = { @@ -1146,18 +1171,22 @@ PushConstants(Vulkan* vk, PushConst* pc) void ImageBarrier(Vulkan* vk) { - vkCmdPipelineBarrier( - vk.cmds[vk.frame_index], - VK_PIPELINE_STAGE_2_TRANSFER_BIT, - VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, - VK_DEPENDENCY_BY_REGION_BIT, - 1, - &barrier, - 0, - null, - 0, - null - ); + VkMemoryBarrier2 barrier = { + sType: VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + srcStageMask: VK_PIPELINE_STAGE_2_TRANSFER_BIT, + srcAccessMask: VK_ACCESS_2_TRANSFER_WRITE_BIT, + dstStageMask: VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + dstAccessMask: VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT, + }; + + VkDependencyInfo dependency = { + sType: VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + dependencyFlags: VK_DEPENDENCY_BY_REGION_BIT, + memoryBarrierCount: 1, + pMemoryBarriers: &barrier, + }; + + vkCmdPipelineBarrier2(vk.cmds[vk.frame_index], &dependency); } bool @@ -1311,8 +1340,7 @@ Copy(VkCommandBuffer cmd, Image* src, VkImage dst, VkImageLayout dst_layout, VkE pragma(inline): void Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext) { - VkImageBlit2 blit = { - sType: VK_STRUCTURE_TYPE_IMAGE_BLIT_2, + VkImageBlit blit = { srcOffsets: [ { x: 0, y: 0 }, { x: cast(i32)src_ext.width, y: cast(i32)src_ext.height, z: 1 }, @@ -1335,18 +1363,16 @@ Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, Vk }, }; - VkBlitImageInfo2 blit_info = { - sType: VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, - srcImage: src, - srcImageLayout: src_layout, - dstImage: dst, - dstImageLayout: dst_layout, - filter: VK_FILTER_LINEAR, - regionCount: 1, - pRegions: &blit, - }; - - vkCmdBlitImage2(cmd, &blit_info); + vkCmdBlitImage( + cmd, + src, + src_layout, + dst, + dst_layout, + 1, + &blit, + VK_FILTER_LINEAR + ); } void @@ -1393,23 +1419,6 @@ Bind(Vulkan* vk, PipelineHandle* pipeline) pragma(inline): void Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout) { - // TODO: continue from here - VkPipelineStageFlags src_stage, dst_stage; - VkAccessFlagBits src_access, dst_access; - - switch(current_layout) - { - case VK_IMAGE_LAYOUT_UNDEFINED: - { - src_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - } break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - { - src_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; - src_mask = VK_ACCESS_FLAG_TRANSFER_WRITE_BIT; - } break; - } - VkImageMemoryBarrier2 barrier = { sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, srcStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, @@ -1469,11 +1478,11 @@ BuildShader(Vulkan* vk, u8[] bytes) } void -InitFramebufferAndRenderpass(Vulkan* vk, ImageView* draw_image, ImageView* depth_image) +InitFramebufferAndRenderPass(Vulkan* vk) { VkAttachmentDescription[] attach_descriptions = [ { - format: draw_image.format, + format: vk.draw_image.format, samples: VK_SAMPLE_COUNT_1_BIT, loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, storeOp: VK_ATTACHMENT_STORE_OP_STORE, @@ -1483,7 +1492,8 @@ InitFramebufferAndRenderpass(Vulkan* vk, ImageView* draw_image, ImageView* depth finalLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, }, { - format: depth_image.format, + samples: VK_SAMPLE_COUNT_1_BIT, + format: vk.depth_image.format, initialLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, finalLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, }, @@ -1532,21 +1542,15 @@ InitFramebufferAndRenderpass(Vulkan* vk, ImageView* draw_image, ImageView* depth VkFramebufferCreateInfo framebuffer_info = { sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, renderPass: vk.render_pass, - attachmentCount: 1, + attachmentCount: 2, + pAttachments: [vk.draw_image.view, vk.depth_image.view], width: vk.swapchain_extent.width, height: vk.swapchain_extent.height, layers: 1, }; - vk.framebuffers = AllocArray!(VkFramebuffer)(&vk.arena, vk.present_images.length); - - foreach(i, image; vk.present_images) - { - framebuffer_info.pAttachments = &image.view; - - result = vkCreateFramebuffer(vk.device, &framebuffer_info, null, &vk.framebuffers[i]); - VkCheckA("vkCreateFramebuffer failure", result); - } + result = vkCreateFramebuffer(vk.device, &framebuffer_info, null, &vk.framebuffer); + VkCheckA("vkCreateFramebuffer failure", result); } Pipeline @@ -1713,6 +1717,7 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) stageCount: cast(u32)shader_info.length, pStages: shader_info.ptr, layout: vk.pipeline_layout, + renderPass: vk.render_pass, }; VkResult result = vkCreateGraphicsPipelines(vk.device, null, 1, &create_info, null, &pipeline.handle); @@ -2625,6 +2630,7 @@ CreateSwapchain(Vulkan* vk) foreach(i, image; vk.present_images) { vk.present_images[i].image = images[i]; + vk.present_images[i].format = cast(Format)vk.surface_format.format; view_info.image = images[i]; view_info.format = vk.surface_format.format; @@ -2751,8 +2757,14 @@ InitDevice(Vulkan* vk) count += 1; } + VkPhysicalDeviceSynchronization2Features synchronization2 = { + sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + synchronization2: VK_TRUE, + }; + VkPhysicalDeviceVulkan12Features features_12 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + pNext: &synchronization2, descriptorIndexing: VK_TRUE, bufferDeviceAddress: VK_TRUE, descriptorBindingUniformBufferUpdateAfterBind: VK_TRUE, @@ -2841,12 +2853,9 @@ CheckDeviceFeatures(VkPhysicalDevice device) { VkPhysicalDeviceFeatures2 features2 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; VkPhysicalDeviceVulkan12Features features_12 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES }; - VkPhysicalDeviceVulkan13Features features_13 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES }; features2.pNext = &features_12; vkGetPhysicalDeviceFeatures2(device, &features2); - features2.pNext = &features_13; - vkGetPhysicalDeviceFeatures2(device, &features2); VkPhysicalDeviceFeatures features = features2.features; bool result = true; @@ -2872,9 +2881,6 @@ CheckDeviceFeatures(VkPhysicalDevice device) result &= cast(bool)features_12.timelineSemaphore; result &= cast(bool)features_12.storageBuffer8BitAccess; - result &= cast(bool)features_13.synchronization2; - result &= cast(bool)features_13.dynamicRendering; - return result; } diff --git a/src/gears/vulkan_funcs.d b/src/gears/vulkan_funcs.d index 18c44f1..5a19d5e 100644 --- a/src/gears/vulkan_funcs.d +++ b/src/gears/vulkan_funcs.d @@ -83,13 +83,16 @@ PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets = null; PFN_vkDestroyDevice vkDestroyDevice = null; PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = null; PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = null; +PFN_vkQueueSubmit2 vkQueueSubmit2 = null; PFN_vkDestroyImage vkDestroyImage = null; +PFN_vkCmdBlitImage vkCmdBlitImage = null; PFN_vkDestroyImageView vkDestroyImageView = null; PFN_vkDestroyCommandPool vkDestroyCommandPool = null; PFN_vkDestroySemaphore vkDestroySemaphore = null; PFN_vkDestroyFence vkDestroyFence = null; PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = null; PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = null; +PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2 = null; PFN_vkDestroyPipeline vkDestroyPipeline = null; PFN_vkWaitForFences vkWaitForFences = null; PFN_vkBeginCommandBuffer vkBeginCommandBuffer = null; @@ -163,6 +166,7 @@ LoadDeviceFunctions(Vulkan* vk) vkDestroyRenderPass = cast(PFN_vkDestroyRenderPass)vkGetDeviceProcAddr(vk.device, "vkDestroyRenderPass"); vkCreateImage = cast(PFN_vkCreateImage)vkGetDeviceProcAddr(vk.device, "vkCreateImage"); vkCreateImageView = cast(PFN_vkCreateImageView)vkGetDeviceProcAddr(vk.device, "vkCreateImageView"); + vkQueueSubmit2 = cast(PFN_vkQueueSubmit2KHR)vkGetDeviceProcAddr(vk.device, "vkQueueSubmit2KHR"); vkCreateBufferView = cast(PFN_vkCreateBufferView)vkGetDeviceProcAddr(vk.device, "vkCreateBufferView"); vkGetSwapchainImagesKHR = cast(PFN_vkGetSwapchainImagesKHR)vkGetDeviceProcAddr(vk.device, "vkGetSwapchainImagesKHR"); vkGetDeviceQueue = cast(PFN_vkGetDeviceQueue)vkGetDeviceProcAddr(vk.device, "vkGetDeviceQueue"); @@ -170,6 +174,7 @@ LoadDeviceFunctions(Vulkan* vk) vkAllocateCommandBuffers = cast(PFN_vkAllocateCommandBuffers)vkGetDeviceProcAddr(vk.device, "vkAllocateCommandBuffers"); vkCreateCommandPool = cast(PFN_vkCreateCommandPool)vkGetDeviceProcAddr(vk.device, "vkCreateCommandPool"); vkCmdPipelineBarrier = cast(PFN_vkCmdPipelineBarrier)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier"); + vkCmdPipelineBarrier2 = cast(PFN_vkCmdPipelineBarrier2KHR)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier2KHR"); vkCreateFence = cast(PFN_vkCreateFence)vkGetDeviceProcAddr(vk.device, "vkCreateFence"); vkCreateDescriptorPool = cast(PFN_vkCreateDescriptorPool)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorPool"); vkCreateDescriptorSetLayout = cast(PFN_vkCreateDescriptorSetLayout)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorSetLayout"); @@ -203,6 +208,7 @@ LoadDeviceFunctions(Vulkan* vk) vkCmdBindIndexBuffer = cast(PFN_vkCmdBindIndexBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdBindIndexBuffer"); vkCmdBindVertexBuffers = cast(PFN_vkCmdBindVertexBuffers)vkGetDeviceProcAddr(vk.device, "vkCmdBindVertexBuffers"); vkCmdDrawIndexed = cast(PFN_vkCmdDrawIndexed)vkGetDeviceProcAddr(vk.device, "vkCmdDrawIndexed"); + vkCmdBlitImage = cast(PFN_vkCmdBlitImage)vkGetDeviceProcAddr(vk.device, "vkCmdBlitImage"); vkCmdCopyBufferToImage = cast(PFN_vkCmdCopyBufferToImage)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBufferToImage"); vkCmdCopyBuffer = cast(PFN_vkCmdCopyBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBuffer"); vkResetFences = cast(PFN_vkResetFences)vkGetDeviceProcAddr(vk.device, "vkResetFences");