From 2f8929d5fb89e26e1984587865dcbe744215feaf Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 14 Jun 2026 15:37:47 +1000 Subject: [PATCH] use dynamic rendering instead of render passes --- vulkan/vulkan.d | 147 ++++++++++++++++++++++++------------------ vulkan/vulkan_funcs.d | 6 ++ 2 files changed, 92 insertions(+), 61 deletions(-) diff --git a/vulkan/vulkan.d b/vulkan/vulkan.d index 4d60ba9..48f93f1 100644 --- a/vulkan/vulkan.d +++ b/vulkan/vulkan.d @@ -831,22 +831,41 @@ BeginRendering() { color: { float32: g_vk.depth_clear } }, ]; - VkRenderPassBeginInfo pass_info = { - sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - renderPass: g_vk.render_pass, - framebuffer: g_vk.framebuffer, - renderArea: { - offset: { x: 0, y: 0 }, - extent: { - width: g_vk.swapchain_extent.width, - height: g_vk.swapchain_extent.height, - }, - }, - clearValueCount: cast(u32)clear_color.length, - pClearValues: clear_color.ptr, - }; + VkRenderingAttachmentInfo[2] attach_descriptions = [ + { + sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + imageView: g_vk.draw_image.image.view, + imageLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, + storeOp: VK_ATTACHMENT_STORE_OP_STORE, + clearValue: { color: { float32: g_vk.color_clear } }, + }, + { + sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + imageView: g_vk.depth_image.image.view, + imageLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, + storeOp: VK_ATTACHMENT_STORE_OP_STORE, + clearValue: { color: { float32: g_vk.depth_clear } }, + }, + ]; - vkCmdBeginRenderPass(g_vk.cmd, &pass_info, VK_SUBPASS_CONTENTS_INLINE); + VkRenderingInfo render_info = { + sType: VK_STRUCTURE_TYPE_RENDERING_INFO, + layerCount: 1, + colorAttachmentCount: 1, + pColorAttachments: &attach_descriptions[0], + pDepthAttachment: &attach_descriptions[1], + renderArea: { + offset: { x: 0, y: 0 }, + extent: { + width: g_vk.swapchain_extent.width, + height: g_vk.swapchain_extent.height, + }, + } + }; + + vkCmdBeginRendering(g_vk.cmd, &render_info); } u32[2] @@ -883,7 +902,7 @@ CopyToPresentImage(Descriptor* descriptor, UVec2 extent) void FinishRendering() { - vkCmdEndRenderPass(g_vk.cmd); + vkCmdEndRendering(g_vk.cmd); } void @@ -2901,9 +2920,9 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) version(Windows) { VkWin32SurfaceCreateInfoKHR surface_info = { - sType: VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, + sType: VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, hinstance: g_vk.platform_handles.instance, - hwnd: g_vk.platform_handles.handle, + hwnd: g_vk.platform_handles.handle, }; VkResult result = vkCreateWin32SurfaceKHR(g_vk.instance, &surface_info, null, &g_vk.surface); @@ -3078,8 +3097,8 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) } discrete_candidate = cast(bool)discrete; - candidate = current; - physical_device = dev; + candidate = current; + physical_device = dev; } if(physical_device) @@ -3088,50 +3107,56 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) f32 priority = 1.0f; count = 1; - queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[0].queueFamilyIndex = candidate.gfx_index; - queue_info[0].queueCount = 1; + queue_info[0].queueCount = 1; queue_info[0].pQueuePriorities = &priority; - queue_info[0].flags = 0; + queue_info[0].flags = 0; if(!candidate.single_queue) { - queue_info[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[1].queueFamilyIndex = candidate.tfer_index; - queue_info[1].queueCount = 1; + queue_info[1].queueCount = 1; queue_info[1].pQueuePriorities = &priority; - queue_info[1].flags = 0; + queue_info[1].flags = 0; count += 1; } + VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering = { + sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + pNext: null, + dynamicRendering: VK_TRUE, + }; + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extended_dynamic_state = { - sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, - pNext: null, + sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, + pNext: &dynamic_rendering, extendedDynamicState: VK_TRUE, }; VkPhysicalDeviceSynchronization2Features synchronization2 = { - sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, - pNext: &extended_dynamic_state, + sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + pNext: &extended_dynamic_state, 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, - descriptorBindingSampledImageUpdateAfterBind: VK_TRUE, - descriptorBindingStorageImageUpdateAfterBind: VK_TRUE, - descriptorBindingStorageBufferUpdateAfterBind: VK_TRUE, + sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + pNext: &synchronization2, + descriptorIndexing: VK_TRUE, + bufferDeviceAddress: VK_TRUE, + descriptorBindingUniformBufferUpdateAfterBind: VK_TRUE, + descriptorBindingSampledImageUpdateAfterBind: VK_TRUE, + descriptorBindingStorageImageUpdateAfterBind: VK_TRUE, + descriptorBindingStorageBufferUpdateAfterBind: VK_TRUE, descriptorBindingStorageTexelBufferUpdateAfterBind: VK_TRUE, - descriptorBindingPartiallyBound: VK_TRUE, - shaderSampledImageArrayNonUniformIndexing: VK_TRUE, - shaderUniformBufferArrayNonUniformIndexing: VK_TRUE, - runtimeDescriptorArray: VK_TRUE, - storageBuffer8BitAccess: VK_TRUE, + descriptorBindingPartiallyBound: VK_TRUE, + shaderSampledImageArrayNonUniformIndexing: VK_TRUE, + shaderUniformBufferArrayNonUniformIndexing: VK_TRUE, + runtimeDescriptorArray: VK_TRUE, + storageBuffer8BitAccess: VK_TRUE, }; VkPhysicalDeviceVulkan11Features features_11 = { @@ -3144,22 +3169,22 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) pNext: &features_11, features: { shaderUniformBufferArrayDynamicIndexing: VK_TRUE, - shaderSampledImageArrayDynamicIndexing: VK_TRUE, + shaderSampledImageArrayDynamicIndexing: VK_TRUE, shaderStorageBufferArrayDynamicIndexing: VK_TRUE, - shaderStorageImageArrayDynamicIndexing: VK_TRUE, - samplerAnisotropy: VK_TRUE, - fragmentStoresAndAtomics: VK_TRUE, + shaderStorageImageArrayDynamicIndexing: VK_TRUE, + samplerAnisotropy: VK_TRUE, + fragmentStoresAndAtomics: VK_TRUE, }, }; VkDeviceCreateInfo device_info = { - sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - pNext: &features, + sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + pNext: &features, ppEnabledExtensionNames: VK_DEVICE_EXTENSIONS.ptr, - enabledExtensionCount: cast(u32)VK_DEVICE_EXTENSIONS.length, - queueCreateInfoCount: count, - pQueueCreateInfos: queue_info.ptr, - pEnabledFeatures: null, + enabledExtensionCount: cast(u32)VK_DEVICE_EXTENSIONS.length, + queueCreateInfoCount: count, + pQueueCreateInfos: queue_info.ptr, + pEnabledFeatures: null, }; VkResult result = vkCreateDevice(physical_device, &device_info, null, &g_vk.device); @@ -3205,16 +3230,16 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) { VmaVulkanFunctions vk_functions = { vkGetInstanceProcAddr: vkGetInstanceProcAddr, - vkGetDeviceProcAddr: vkGetDeviceProcAddr, + vkGetDeviceProcAddr: vkGetDeviceProcAddr, }; VmaAllocatorCreateInfo info = { - flags: VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, + flags: VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, vulkanApiVersion: VK_MAKE_API_VERSION(0, 1, 2, 0), pVulkanFunctions: &vk_functions, - physicalDevice: g_vk.physical_device, - device: g_vk.device, - instance: g_vk.instance, + physicalDevice: g_vk.physical_device, + device: g_vk.device, + instance: g_vk.instance, }; VkResult result = vmaCreateAllocator(&info, &g_vk.vma); @@ -3243,12 +3268,12 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem) }; VkCommandBufferAllocateInfo cmd_info = { - sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, commandBufferCount: 1, - level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, + level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, }; - u32 sem_count = cast(u32)g_vk.present_images.length; + u32 sem_count = cast(u32)g_vk.present_images.length; g_vk.submit_sems = Alloc!(VkSemaphore)(arena, sem_count); VkResult result; diff --git a/vulkan/vulkan_funcs.d b/vulkan/vulkan_funcs.d index 82f321e..3842fdd 100644 --- a/vulkan/vulkan_funcs.d +++ b/vulkan/vulkan_funcs.d @@ -125,11 +125,15 @@ PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT; PFN_vkCmdSetStencilReference vkCmdSetStencilReference; PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; +PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR; +PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR; alias vkQueueSubmit2 = vkQueueSubmit2KHR; alias vkCmdPipelineBarrier2 = vkCmdPipelineBarrier2KHR; alias vkCmdSetStencilTestEnable = vkCmdSetStencilTestEnableEXT; alias vkCmdSetStencilOp = vkCmdSetStencilOpEXT; +alias vkCmdBeginRendering = vkCmdBeginRenderingKHR; +alias vkCmdEndRendering = vkCmdEndRenderingKHR; static string LoadDeviceFunc(alias fn)() @@ -228,6 +232,8 @@ LoadDeviceFunctions() mixin(LoadDeviceFunc!(vkCmdSetStencilReference)); mixin(LoadDeviceFunc!(vkCmdSetStencilCompareMask)); mixin(LoadDeviceFunc!(vkCmdSetStencilWriteMask)); + mixin(LoadDeviceFunc!(vkCmdBeginRenderingKHR)); + mixin(LoadDeviceFunc!(vkCmdEndRenderingKHR)); version(AMD_GPU) version(VULKAN_DEBUG) {