summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-06-10 11:23:44 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-06-10 11:23:44 -0400
commit2506c1af519ed14836986ecf2674636fa8b37947 (patch)
treeed9270b9160582ef8fd1a7f0cb01e30921655e6f
parent11454fb99a9dc1c959e58828f447d1fb2e9f3d9d (diff)
pke: vulkan dynamic rendering + update imgui
-rw-r--r--Makefile2
-rw-r--r--editor/editor.cpp4
-rw-r--r--src/window.cpp795
m---------sub/imgui0
4 files changed, 400 insertions, 401 deletions
diff --git a/Makefile b/Makefile
index 0db983d..8f01766 100644
--- a/Makefile
+++ b/Makefile
@@ -97,7 +97,7 @@ DST_SHADERS = \
$(DIR_OBJ)/shaders/ui-base.frag.spv \
.PHONY: default
-default: options .WAIT $(DIR_EXE)/pke-editor $(DIR_EXE)/libpke-example.a $(DIR_EXE)/pke-runtime ;
+default: options .WAIT $(DIR_EXE)/pke-editor $(DIR_OBJ)/libpke-example.$(LIB_EXT) $(DIR_EXE)/pke-runtime ;
.PHONY: prepare
prepare: config.h
diff --git a/editor/editor.cpp b/editor/editor.cpp
index 13debfe..959d772 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -1021,8 +1021,8 @@ bool RecordImGui_GenerateMTSDFGlyphModal() {
ImGui::Separator();
if (ImGui::Button("Generate")) {
- di = std::filesystem::directory_iterator {"assets/glyphs"};
- for (const std::filesystem::directory_entry &sde : di) {
+ std::filesystem::directory_iterator d2{"assets/glyphs"};
+ for (const std::filesystem::directory_entry &sde : d2) {
if (sde.is_regular_file() && std::regex_search(sde.path().c_str(), reg_svg_file)) {
GenerateMTSDFGlyph(&msdf_glyph_settings, sde.path().stem().c_str());
}
diff --git a/src/window.cpp b/src/window.cpp
index dd871f6..4cab2b4 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -96,7 +96,6 @@ struct PKVK_Present {
VkDescriptorSetLayout descriptor_set_layout;
VkPipelineLayout pipeline_layout;
VkPipeline pipeline;
- VkRenderPass render_pass;
VkDescriptorPool descriptor_pool;
VkDescriptorSet *descriptor_sets;
VkCommandBuffer *command_buffers;
@@ -105,7 +104,6 @@ struct PKVK_Present {
VkFence *fences_in_flight;
VkImage *images;
VkImageView *image_views;
- VkFramebuffer *framebuffers;
} pkvk_present;
// TODO consider creating a depth pre-pass
@@ -120,8 +118,6 @@ VkImageView *depthImageViews = nullptr;
VkDeviceMemory depthImagesMemory;
struct PKVK_3D {
- VkRenderPass render_pass;
- VkFramebuffer *framebuffers = nullptr;
VkDeviceMemory images_memory;
VkImageView *image_views = nullptr;
VkImage *render_images = nullptr;
@@ -131,8 +127,6 @@ struct PKVK_3D {
} pkvk_3d;
struct PKVK_2D {
- VkRenderPass render_pass;
- VkFramebuffer *framebuffers = nullptr;
VkImage *images = nullptr;
VkImageView *image_views = nullptr;
VkDeviceMemory images_memory;
@@ -197,6 +191,13 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugReport(VkDebugReportFlagsEXT flags, V
return VK_FALSE;
}
+// 2025-06-10 TODO this should be called in more places or not called at all.
+// It's possible we won't ever actually need to use this call if we never
+// target a device that doesn't support depth+stencil (e.g. older android).
+bool pkvk_is_depth_only_format(VkFormat format) {
+ return format == VK_FORMAT_D16_UNORM || format == VK_FORMAT_D32_SFLOAT;
+}
+
unsigned int FindMemoryTypeIndex(uint32_t typeFilter, VkMemoryPropertyFlags memPropertyFlags) {
for (uint32_t i = 0; i < vkPhysicalDeviceMemoryProperties.memoryTypeCount; i++) {
if ((typeFilter & (1 << i)) && (vkPhysicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & memPropertyFlags) == memPropertyFlags) {
@@ -989,7 +990,6 @@ void InitVulkan() {
VkDeviceCreateInfo vkDeviceCreateInfo;
vkDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
- vkDeviceCreateInfo.pNext = nullptr;
vkDeviceCreateInfo.flags = 0;
vkDeviceCreateInfo.queueCreateInfoCount = 2;
vkDeviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos;
@@ -1001,6 +1001,12 @@ void InitVulkan() {
vkDeviceCreateInfo.ppEnabledExtensionNames = REQUIRED_EXTENSIONS.data();
vkDeviceCreateInfo.pEnabledFeatures = &requestedFeatures;
+ VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures{};
+ vkDeviceCreateInfo.pNext = &dynamicRenderingFeatures;
+ dynamicRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES;
+ dynamicRenderingFeatures.pNext = NULL;
+ dynamicRenderingFeatures.dynamicRendering = VK_TRUE;
+
vkResult = vkCreateDevice(vkPhysicalDevice, &vkDeviceCreateInfo, vkAllocator, &vkDevice);
if (vkResult != VK_SUCCESS) {
printf("Failed to create VkInstance! : %d\n", vkResult);
@@ -1018,9 +1024,9 @@ void InitVulkan() {
// surface formats
{
const VkFormat acceptableDepthFormats[3] = {
- VK_FORMAT_D32_SFLOAT,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
+ VK_FORMAT_D32_SFLOAT,
};
depthFormat = FindSupportedFormat(3, acceptableDepthFormats, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
}
@@ -1326,7 +1332,7 @@ void CreateSwapchain() {
renderTargetImageCI.format = depthFormat;
renderTargetImageCI.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
vkImageViewCreateInfo.format = depthFormat;
- vkImageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ vkImageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
// depth images
depthImages = pk_new<VkImage>(swapchainLength, MemBkt_Vulkan);
@@ -1403,151 +1409,6 @@ void UpdateCamera() {
ActiveCamera->stale = PkeCameraStaleFlags{0};
}
-void CreateRenderPass() {
- /* 2025-01-29 JCB
- * I refactored this so that VkAttachmentDescription was an array and that
- * wasn't totally necessary. It does have the advantage of 1:1-ing with the
- * VkAttachmentReference, but it means you have to just know what each index
- * is. Here's a legend since the code is no longer self-documenting.
- * 0: render target (fragment)
- * 1: color resolve (multisampling)
- * 2: depth
- * See also: CreateFramebuffers(): the same ordering can be observed.
- */
- VkAttachmentDescription attachment_descriptions[3];
- memset(attachment_descriptions, 0, sizeof(VkAttachmentDescription) * 3);
- VkAttachmentReference attachment_refs[3];
- memset(attachment_refs, 0, sizeof(VkAttachmentReference) * 3);
- VkSubpassDependency subpass_dependencies[2];
- memset(subpass_dependencies, 0, sizeof(VkSubpassDependency) * 2);
-
- for (long i = 0; i < 3; ++i) {
- attachment_refs[i].attachment = i;
- }
- for (long i = 0; i < 2; ++i) {
- subpass_dependencies[i].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
- }
-
- // color (fragment)
- attachment_descriptions[0].flags = {};
- attachment_descriptions[0].format = vkSurfaceFormatKHR.format;
- attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
- attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
-
- // color (fragment)
- attachment_refs[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
- VkSubpassDescription subpass;
- subpass.flags = {};
- subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpass.inputAttachmentCount = 0;
- subpass.pInputAttachments = nullptr;
- subpass.colorAttachmentCount = 1;
- subpass.pColorAttachments = &attachment_refs[0];
- subpass.pResolveAttachments = nullptr;
- subpass.pDepthStencilAttachment = nullptr;
- subpass.preserveAttachmentCount = 0;
- subpass.pPreserveAttachments = nullptr;
-
- subpass_dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
- subpass_dependencies[0].dstSubpass = 0U;
- subpass_dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- subpass_dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- subpass_dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
- subpass_dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
- subpass_dependencies[1].srcSubpass = 0U;
- subpass_dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
- subpass_dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- subpass_dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- subpass_dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- subpass_dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
-
- VkRenderPassCreateInfo renderPassInfo;
- renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- renderPassInfo.pNext = nullptr;
- renderPassInfo.flags = {};
- renderPassInfo.attachmentCount = 1;
- renderPassInfo.pAttachments = &attachment_descriptions[0];
- renderPassInfo.subpassCount = 1;
- renderPassInfo.pSubpasses = &subpass;
- renderPassInfo.dependencyCount = 2;
- renderPassInfo.pDependencies = subpass_dependencies;
-
- if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &pkvk_present.render_pass) != VK_SUCCESS) {
- throw "failed to create present render pass!";
- }
-
- // color resolve
- attachment_refs[1].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- subpass.pResolveAttachments = &attachment_refs[1];
-
- // color
- attachment_descriptions[0].samples = global_sample_count;
- attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- // color resolve
- attachment_descriptions[1] = attachment_descriptions[0];
- attachment_descriptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
- attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-
- subpass_dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- subpass_dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- subpass_dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- subpass_dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
- subpass_dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- subpass_dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- subpass_dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- subpass_dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-
- renderPassInfo.attachmentCount = 2;
-
- if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &pkvk_2d.render_pass) != VK_SUCCESS) {
- throw "failed to create 2d render pass!";
- }
-
- // color
- attachment_descriptions[0].samples = global_sample_count;
- attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- // depth
- attachment_descriptions[2] = attachment_descriptions[0];
- attachment_descriptions[2].format = depthFormat;
- attachment_descriptions[2].samples = global_sample_count;
- attachment_descriptions[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- attachment_descriptions[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attachment_descriptions[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- attachment_descriptions[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
- attachment_descriptions[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- attachment_descriptions[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
- // depth
- attachment_refs[2].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- subpass.pDepthStencilAttachment = &attachment_refs[2];
-
- subpass_dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- subpass_dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- subpass_dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- subpass_dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
- subpass_dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- subpass_dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- subpass_dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- subpass_dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-
- renderPassInfo.attachmentCount = 3;
-
- if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &pkvk_3d.render_pass) != VK_SUCCESS) {
- throw "failed to create 3d render pass!";
- }
-}
-
void CreatePresentDescriptorSetLayout() {
VkDescriptorSetLayoutBinding imageSamplerLayoutBinding;
imageSamplerLayoutBinding.binding = 0;
@@ -1759,7 +1620,6 @@ void CreatePresentPipeline() {
VkGraphicsPipelineCreateInfo pipelineInfo;
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
- pipelineInfo.pNext = nullptr;
pipelineInfo.flags = {};
pipelineInfo.stageCount = 2;
pipelineInfo.pStages = shaderStages;
@@ -1775,11 +1635,19 @@ void CreatePresentPipeline() {
pipelineInfo.pDynamicState = &dynamicState;
pipelineInfo.layout = pkvk_present.pipeline_layout;
- pipelineInfo.renderPass = pkvk_present.render_pass;
+ pipelineInfo.renderPass = VK_NULL_HANDLE; // dynamic rendering
pipelineInfo.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineInfo.basePipelineIndex = {};
+ VkPipelineRenderingCreateInfo renderingInfo{};
+ pipelineInfo.pNext = &renderingInfo;
+ renderingInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
+ renderingInfo.colorAttachmentCount = 1;
+
+ VkFormat color_format = vkSurfaceFormatKHR.format;
+ renderingInfo.pColorAttachmentFormats = &color_format;
+
/* 2023-12-22 JCB
* This happens just before needed because we want to let this
* thread run while background threads load the assets.
@@ -1798,66 +1666,6 @@ void CreatePresentPipeline() {
vkDestroyShaderModule(vkDevice, vertShader, vkAllocator);
}
-void CreateFramebuffers() {
- assert(pkvk_present.framebuffers == nullptr || pkvk_present.framebuffers == CAFE_BABE(VkFramebuffer));
- assert(pkvk_3d.framebuffers == nullptr || pkvk_3d.framebuffers == CAFE_BABE(VkFramebuffer));
- assert(pkvk_2d.framebuffers == nullptr || pkvk_2d.framebuffers == CAFE_BABE(VkFramebuffer));
- pkvk_present.framebuffers = pk_new<VkFramebuffer>(swapchainLength, MemBkt_Vulkan);
- pkvk_3d.framebuffers = pk_new<VkFramebuffer>(swapchainLength, MemBkt_Vulkan);
- pkvk_2d.framebuffers = pk_new<VkFramebuffer>(swapchainLength, MemBkt_Vulkan);
-
- VkFramebufferCreateInfo framebufferInfo;
- framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
- framebufferInfo.pNext = nullptr;
- framebufferInfo.flags = {};
- framebufferInfo.renderPass = pkvk_present.render_pass;
- framebufferInfo.attachmentCount = 1;
- framebufferInfo.pAttachments = nullptr;
- framebufferInfo.width = Extent.width;
- framebufferInfo.height = Extent.height;
- framebufferInfo.layers = 1;
-
- for (long i = 0; i < swapchainLength; ++i) {
- VkImageView attachments[] = {
- pkvk_present.image_views[i]
- };
- framebufferInfo.pAttachments = attachments;
- auto result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &pkvk_present.framebuffers[i]);
- if (result != VK_SUCCESS) {
- throw "failed to create present framebuffer";
- }
- }
-
- framebufferInfo.attachmentCount = 2;
- framebufferInfo.renderPass = pkvk_2d.render_pass;
- for (long i = 0; i < swapchainLength; ++i) {
- VkImageView attachments[] = {
- pkvk_2d.image_views[i],
- pkvk_2d.image_views_color_resolve[i],
- };
- framebufferInfo.pAttachments = attachments;
- auto result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &pkvk_2d.framebuffers[i]);
- if (result != VK_SUCCESS) {
- throw "failed to create 2d overlay framebuffer";
- }
- }
-
- framebufferInfo.attachmentCount = 3;
- framebufferInfo.renderPass = pkvk_3d.render_pass;
- for (long i = 0; i < swapchainLength; ++i) {
- VkImageView attachments[] = {
- pkvk_3d.image_views[i],
- pkvk_3d.image_views_color_resolve[i],
- depthImageViews[i],
- };
- framebufferInfo.pAttachments = attachments;
- auto result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &pkvk_3d.framebuffers[i]);
- if (result != VK_SUCCESS) {
- throw "failed to create render framebuffer";
- }
- }
-}
-
void CreateCommandPool() {
VkCommandPoolCreateInfo poolInfo;
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@@ -2500,10 +2308,10 @@ void CreateGraphicsPipelines() {
vkGraphicsPipelineCreateInfo[2].layout = pkePipelines.pipe_layouts.named.txtr;
vkGraphicsPipelineCreateInfo[3].layout = pkePipelines.pipe_layouts.named.base;
- vkGraphicsPipelineCreateInfo[0].renderPass = pkvk_3d.render_pass;
- vkGraphicsPipelineCreateInfo[1].renderPass = pkvk_3d.render_pass;
- vkGraphicsPipelineCreateInfo[2].renderPass = pkvk_2d.render_pass;
- vkGraphicsPipelineCreateInfo[3].renderPass = pkvk_2d.render_pass;
+ vkGraphicsPipelineCreateInfo[0].renderPass = VK_NULL_HANDLE; // dynamic rendering
+ vkGraphicsPipelineCreateInfo[1].renderPass = VK_NULL_HANDLE; // dynamic rendering
+ vkGraphicsPipelineCreateInfo[2].renderPass = VK_NULL_HANDLE; // dynamic rendering
+ vkGraphicsPipelineCreateInfo[3].renderPass = VK_NULL_HANDLE; // dynamic rendering
vkGraphicsPipelineCreateInfo[0].pVertexInputState = &vkPipelineVertexInputStateCreateInfo_txtr;
vkGraphicsPipelineCreateInfo[1].pVertexInputState = &vkPipelineVertexInputStateCreateInfo_txtr;
@@ -2528,12 +2336,34 @@ void CreateGraphicsPipelines() {
vkPipelineShaderStageCreateInfo_ui_base[0].module = UploadShader(asset_handle_vert_ui_base);
vkPipelineShaderStageCreateInfo_ui_base[1].module = UploadShader(asset_handle_frag_ui_base);
+ VkPipelineRenderingCreateInfo renderingInfo{};
+ vkGraphicsPipelineCreateInfo[0].pNext = &renderingInfo;
+ vkGraphicsPipelineCreateInfo[1].pNext = &renderingInfo;
+ vkGraphicsPipelineCreateInfo[2].pNext = &renderingInfo;
+ vkGraphicsPipelineCreateInfo[3].pNext = &renderingInfo;
+ renderingInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
+
+ std::array<VkFormat, 3> color_formats;
+ color_formats.at(0) = vkSurfaceFormatKHR.format;
+ color_formats.at(1) = depthFormat;
+ color_formats.at(2) = depthFormat;
+ renderingInfo.colorAttachmentCount = 1;
+ renderingInfo.pColorAttachmentFormats = color_formats.data();
+ renderingInfo.depthAttachmentFormat = color_formats.at(1);
+ if (!pkvk_is_depth_only_format(depthFormat)) {
+ renderingInfo.stencilAttachmentFormat = color_formats.at(2);
+ }
+
vkResult = vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, 1, &vkGraphicsPipelineCreateInfo[0], vkAllocator, &pkePipelines.pipelines.named.entity_standard);
assert(vkResult == VK_SUCCESS);
+
vkResult = vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, 1, &vkGraphicsPipelineCreateInfo[1], vkAllocator, &pkePipelines.pipelines.named.entity_wireframe);
assert(vkResult == VK_SUCCESS);
+
+ renderingInfo.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
vkResult = vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, 1, &vkGraphicsPipelineCreateInfo[2], vkAllocator, &pkePipelines.pipelines.named.font_glyph);
assert(vkResult == VK_SUCCESS);
+
vkResult = vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, 1, &vkGraphicsPipelineCreateInfo[3], vkAllocator, &pkePipelines.pipelines.named.ui_base);
assert(vkResult == VK_SUCCESS);
assert(pkePipelines.pipelines.named.entity_standard != VK_NULL_HANDLE);
@@ -3071,7 +2901,6 @@ void CreateImGui() {
ImGui_ImplVulkan_InitInfo initInfo = {};
initInfo.Allocator = vkAllocator;
initInfo.CheckVkResultFn = ImGuiCheckVkResult;
- // initInfo.ColorAttachmentFormat = VkFormat::VK_FORMAT_B8G8R8A8_SRGB;
initInfo.DescriptorPool = imGuiDescriptorPool;
initInfo.Device = vkDevice;
initInfo.ImageCount = swapchainLength;
@@ -3082,9 +2911,17 @@ void CreateImGui() {
initInfo.PipelineCache = {};
initInfo.Queue = pkvk_shared.queue.graphics;
initInfo.QueueFamily = graphicsFamilyIndex;
- initInfo.RenderPass = pkvk_present.render_pass;
+ initInfo.RenderPass = VK_NULL_HANDLE; // dynamic rendering
initInfo.Subpass = 0;
- initInfo.UseDynamicRendering = false;
+ initInfo.UseDynamicRendering = true;
+
+ VkPipelineRenderingCreateInfo renderingInfo{};
+ VkFormat color_format = vkSurfaceFormatKHR.format;
+
+ renderingInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
+ renderingInfo.colorAttachmentCount = 1;
+ renderingInfo.pColorAttachmentFormats = &color_format;
+ initInfo.PipelineRenderingCreateInfo = renderingInfo;
ImGui_ImplVulkan_Init(&initInfo);
pke_window_did_init_imgui = true;
@@ -3120,6 +2957,28 @@ void CreateImGui() {
// ImGui_ImplVulkan_DestroyFontUploadObjects();
}
+void pkvk_transition_image_layout(VkCommandBuffer command_buffer,
+ VkImage image,
+ VkPipelineStageFlags src_stage_mask,
+ VkPipelineStageFlags dst_stage_mask,
+ VkAccessFlags src_access_mask,
+ VkAccessFlags dst_access_mask,
+ VkImageLayout old_layout,
+ VkImageLayout new_layout,
+ VkImageSubresourceRange const &subresource_range) {
+ VkImageMemoryBarrier barrier{};
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.srcAccessMask = src_access_mask;
+ barrier.dstAccessMask = dst_access_mask;
+ barrier.oldLayout = old_layout;
+ barrier.newLayout = new_layout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image;
+ barrier.subresourceRange = subresource_range;
+ vkCmdPipelineBarrier(command_buffer, src_stage_mask, dst_stage_mask, 0, 0, VK_NULL_HANDLE, 0, VK_NULL_HANDLE, 1, &barrier);
+}
+
void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
vkResetCommandBuffer(commandBuffer, 0);
@@ -3136,23 +2995,9 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
VkClearColorValue clearColorTransparent = {{0.0f, 0.0f, 0.0f, 0.0f}};
VkClearColorValue clearColorBlack = {{0.0f, 0.0f, 0.0f, 1.0f}};
- VkClearValue clearValues[3];
- clearValues[0].color = clearColorBlack;
- clearValues[1].color = clearColorBlack;
- clearValues[2].depthStencil.depth = 1.0;
- clearValues[2].depthStencil.stencil = 0;
-
- VkRenderPassBeginInfo renderPassInfo;
- renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
- renderPassInfo.renderPass = pkvk_3d.render_pass;
- renderPassInfo.framebuffer = pkvk_3d.framebuffers[imageIndex];
- renderPassInfo.renderArea.offset = {0, 0};
- renderPassInfo.renderArea.extent = Extent;
- renderPassInfo.clearValueCount = 3;
- renderPassInfo.pClearValues = clearValues;
- renderPassInfo.pNext = VK_NULL_HANDLE;
-
- vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
+ VkClearValue clearTransparent = { .color = clearColorTransparent };
+ VkClearValue clearBlack = { .color = clearColorBlack };
+ VkClearValue clearDepth = { .depthStencil = { 1.f, 0 } };
VkViewport viewport;
viewport.x = 0.0f;
@@ -3166,162 +3011,344 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
scissor.offset = {0, 0};
scissor.extent = Extent;
- vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
- vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
-
VkDeviceSize offsets[1] = {0U};
- using GrBindsIterFn = pk_tmpln_1<void, CompGrBinds*, void*>;
- GrBindsIterFn gr_binds_iter_cb{};
- gr_binds_iter_cb.func = [commandBuffer, imageIndex](CompGrBinds *binder) {
- VkDeviceSize offsets[1] = {0U};
- if (binder->grBindsHandle == GrBindsHandle_MAX)
- return;
- if (!binder->vkPipelineLayout)
- return;
- if (binder->instanceBD.bindingCount < 1) {
- return;
- }
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->graphicsPipeline);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0, 1, &binder->vkDescriptorSets[imageIndex], 0, {});
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, &UniformBuffers[imageIndex], offsets);
- vkCmdBindIndexBuffer(commandBuffer, binder->indexBD.buffer, binder->indexBD.offsets[0], VK_INDEX_TYPE_UINT16);
-
- vkCmdBindVertexBuffers(commandBuffer, binder->vertexBD.firstBinding, binder->vertexBD.bindingCount, &binder->vertexBD.buffer, binder->vertexBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->normalsBD.firstBinding, binder->normalsBD.bindingCount, &binder->normalsBD.buffer, binder->normalsBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->uvBD.firstBinding, binder->uvBD.bindingCount, &binder->uvBD.buffer, binder->uvBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->instanceBD.firstBinding, binder->instanceBD.bindingCount, &binder->instanceBD.buffer, binder->instanceBD.offsets);
-
- vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCounter, 0, 0, 0);
-
- if (pkeSettings.isRenderingDebug) {
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.ubo_txtr, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
+ VkImageSubresourceRange range{};
+ range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ range.baseMipLevel = 0;
+ range.levelCount = VK_REMAINING_MIP_LEVELS;
+ range.baseArrayLayer = 0;
+ range.layerCount = VK_REMAINING_ARRAY_LAYERS;
+
+ VkImageSubresourceRange depth_range{range};
+ depth_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+
+ // 0 : color
+ // 1 : color+resolve
+ // 2 : depth/stencil
+ std::array<VkRenderingAttachmentInfo,3> color_attachments;
+ for (long unsigned int i = 0; i < color_attachments.size(); ++i) {
+ color_attachments[i].sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
+ color_attachments[i].pNext = VK_NULL_HANDLE;
+ color_attachments[i].imageView = VK_NULL_HANDLE;
+ color_attachments[i].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ color_attachments[i].resolveMode = VK_RESOLVE_MODE_NONE;
+ color_attachments[i].resolveImageView = VK_NULL_HANDLE;
+ color_attachments[i].resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ color_attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ color_attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ color_attachments[i].clearValue = clearBlack;
+ }
+
+ VkRenderingInfo renderingInfo;
+ renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
+ renderingInfo.pNext = VK_NULL_HANDLE;
+ renderingInfo.flags = 0;
+ renderingInfo.renderArea.offset = {0, 0};
+ renderingInfo.renderArea.extent = Extent;
+ renderingInfo.layerCount = 1;
+ renderingInfo.viewMask = 0;
+
+ // 3d pass
+ {
+ // color
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_3d.render_images[imageIndex],
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ range
+ );
+ // color resolve
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_3d.images_color_resolve[imageIndex],
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ range
+ );
+ // depth
+ pkvk_transition_image_layout(
+ commandBuffer, depthImages[imageIndex],
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+ VK_ACCESS_NONE,
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ depth_range
+ );
+
+ color_attachments[1].imageView = pkvk_3d.image_views[imageIndex];
+ color_attachments[1].clearValue = clearBlack;
+ color_attachments[1].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
+ color_attachments[1].resolveImageView = pkvk_3d.image_views_color_resolve[imageIndex];
+ color_attachments[1].resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ color_attachments[2].imageView = depthImageViews[imageIndex];
+ color_attachments[2].imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ color_attachments[2].resolveMode = VK_RESOLVE_MODE_NONE;
+ color_attachments[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ color_attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ color_attachments[2].clearValue = clearDepth;
+
+ // skip [0], since we have a resolve on this pass
+ renderingInfo.colorAttachmentCount = 1;
+ renderingInfo.pColorAttachments = &color_attachments.at(1);
+ renderingInfo.pDepthAttachment = &color_attachments.at(2);
+ if (!pkvk_is_depth_only_format(depthFormat)) {
+ renderingInfo.pStencilAttachment = &color_attachments.at(2);
+ }
+
+ vkCmdBeginRendering(commandBuffer, &renderingInfo);
+
+ vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
+ vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
+
+ using GrBindsIterFn = pk_tmpln_1<void, CompGrBinds*, void*>;
+ GrBindsIterFn gr_binds_iter_cb{};
+ gr_binds_iter_cb.func = [commandBuffer, imageIndex](CompGrBinds *binder) {
+ VkDeviceSize offsets[1] = {0U};
+ if (binder->grBindsHandle == GrBindsHandle_MAX)
+ return;
+ if (!binder->vkPipelineLayout)
+ return;
+ if (binder->instanceBD.bindingCount < 1) {
+ return;
+ }
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->graphicsPipeline);
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0, 1, &binder->vkDescriptorSets[imageIndex], 0, {});
+ vkCmdBindVertexBuffers(commandBuffer, 0, 1, &UniformBuffers[imageIndex], offsets);
+ vkCmdBindIndexBuffer(commandBuffer, binder->indexBD.buffer, binder->indexBD.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdBindVertexBuffers(commandBuffer, binder->physVertBD.firstBinding, 1, &binder->physVertBD.buffer, binder->physVertBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->physNormBD.firstBinding, 1, &binder->physNormBD.buffer, binder->physVertBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->physUvBD.firstBinding, 1, &binder->physUvBD.buffer, binder->physVertBD.offsets);
- vkCmdBindIndexBuffer(commandBuffer, binder->physIndxBD.buffer, binder->physIndxBD.offsets[0], VK_INDEX_TYPE_UINT16);
+ vkCmdBindVertexBuffers(commandBuffer, binder->vertexBD.firstBinding, binder->vertexBD.bindingCount, &binder->vertexBD.buffer, binder->vertexBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->normalsBD.firstBinding, binder->normalsBD.bindingCount, &binder->normalsBD.buffer, binder->normalsBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->uvBD.firstBinding, binder->uvBD.bindingCount, &binder->uvBD.buffer, binder->uvBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->instanceBD.firstBinding, binder->instanceBD.bindingCount, &binder->instanceBD.buffer, binder->instanceBD.offsets);
- vkCmdDrawIndexed(commandBuffer, binder->physIndxBD.bindingCount, binder->instanceCounter, 0, 0, 0);
- }
- };
- pk_bkt_arr_iterate(ECS_GetGrBinds(), &GrBindsIterFn::invoke, &gr_binds_iter_cb);
+ vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCounter, 0, 0, 0);
- if (pkeDebugHitbox.instanceBuffer != VK_NULL_HANDLE) {
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.ubo_txtr, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, &UniformBuffers[imageIndex], offsets);
+ if (pkeSettings.isRenderingDebug) {
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.ubo_txtr, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
- // TODO don't hardcode firstBinding
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, &pkeDebugHitbox.vertexBuffer, offsets);
- vkCmdBindVertexBuffers(commandBuffer, 1, 1, &pkeDebugHitbox.normalsBuffer, offsets);
- vkCmdBindVertexBuffers(commandBuffer, 2, 1, &pkeDebugHitbox.uvBuffer, offsets);
- vkCmdBindIndexBuffer(commandBuffer, pkeDebugHitbox.indexBuffer, offsets[0], VK_INDEX_TYPE_UINT16);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physVertBD.firstBinding, 1, &binder->physVertBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physNormBD.firstBinding, 1, &binder->physNormBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physUvBD.firstBinding, 1, &binder->physUvBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindIndexBuffer(commandBuffer, binder->physIndxBD.buffer, binder->physIndxBD.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdBindVertexBuffers(commandBuffer, 3, 1, &pkeDebugHitbox.instanceBuffer, offsets);
- vkCmdDrawIndexed(commandBuffer, pkeDebugHitbox.indexCount, pkeDebugHitbox.instanceCount, 0, 0, pkeDebugHitbox.instanceStartingIndex);
- }
+ vkCmdDrawIndexed(commandBuffer, binder->physIndxBD.bindingCount, binder->instanceCounter, 0, 0, 0);
+ }
+ };
+ pk_bkt_arr_iterate(ECS_GetGrBinds(), &GrBindsIterFn::invoke, &gr_binds_iter_cb);
- vkCmdEndRenderPass(commandBuffer);
+ if (pkeDebugHitbox.instanceBuffer != VK_NULL_HANDLE) {
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.ubo_txtr, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
+ vkCmdBindVertexBuffers(commandBuffer, 0, 1, &UniformBuffers[imageIndex], offsets);
- // 2d overlay pass
- renderPassInfo.renderPass = pkvk_2d.render_pass;
- renderPassInfo.framebuffer = pkvk_2d.framebuffers[imageIndex];
- renderPassInfo.clearValueCount = 1;
- clearValues[0].color = clearColorTransparent;
+ // TODO don't hardcode firstBinding
+ vkCmdBindVertexBuffers(commandBuffer, 0, 1, &pkeDebugHitbox.vertexBuffer, offsets);
+ vkCmdBindVertexBuffers(commandBuffer, 1, 1, &pkeDebugHitbox.normalsBuffer, offsets);
+ vkCmdBindVertexBuffers(commandBuffer, 2, 1, &pkeDebugHitbox.uvBuffer, offsets);
+ vkCmdBindIndexBuffer(commandBuffer, pkeDebugHitbox.indexBuffer, offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
- vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
- vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
+ vkCmdBindVertexBuffers(commandBuffer, 3, 1, &pkeDebugHitbox.instanceBuffer, offsets);
+ vkCmdDrawIndexed(commandBuffer, pkeDebugHitbox.indexCount, pkeDebugHitbox.instanceCount, 0, 0, pkeDebugHitbox.instanceStartingIndex);
+ }
- // 2d overlay grbinds
- pke_ui_graphics_bindings *ui_gr = pke_ui_get_graphics_bindings();
- if (ui_gr != nullptr && ui_gr->instance_counter > 0)
- {
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.ui_base);
- vkCmdBindIndexBuffer(commandBuffer, ui_gr->bd_index.buffer, ui_gr->bd_index.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdBindVertexBuffers(commandBuffer, ui_gr->bd_vertex.firstBinding, ui_gr->bd_vertex.bindingCount, &ui_gr->bd_vertex.buffer, ui_gr->bd_vertex.offsets);
- vkCmdBindVertexBuffers(commandBuffer, ui_gr->bd_uv.firstBinding, ui_gr->bd_uv.bindingCount, &ui_gr->bd_uv.buffer, ui_gr->bd_uv.offsets);
- vkCmdBindVertexBuffers(commandBuffer, ui_gr->bd_instance.firstBinding, ui_gr->bd_instance.bindingCount, &ui_gr->bd_instance.buffer, ui_gr->bd_instance.offsets);
- vkCmdDrawIndexed(commandBuffer, ui_gr->index_count, ui_gr->instance_counter, 0, 0, 0);
- }
-
- // 2d - font glyphs
- FontTypeIndex count;
- FontType *fts = FontType_GetFonts(count);
- for (FontTypeIndex i = FontTypeIndex{0}; i < count; ++i)
+ vkCmdEndRendering(commandBuffer);
+ }
+
+ // 2d pass
{
- FontType *ft = &fts[(FontTypeIndex_T)i];
- if (ft->bindings.instance_counter == 0)
- continue;
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.font_glyph);
+ // color
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_2d.images[imageIndex],
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ range
+ );
+ // color resolve
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_2d.images_color_resolve[imageIndex],
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ range
+ );
+
+ color_attachments[1].imageView = pkvk_2d.image_views[imageIndex];
+ color_attachments[1].clearValue = clearTransparent;
+ color_attachments[1].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; // TODO verify
+ color_attachments[1].resolveImageView = pkvk_2d.image_views_color_resolve[imageIndex];
+ color_attachments[1].resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ // skip [0], since we have a resolve on this pass
+ renderingInfo.colorAttachmentCount = 1;
+ renderingInfo.pColorAttachments = &color_attachments.at(1);
+ renderingInfo.pDepthAttachment = VK_NULL_HANDLE;
+ renderingInfo.pStencilAttachment = VK_NULL_HANDLE;
+
+ vkCmdBeginRendering(commandBuffer, &renderingInfo);
+
+ vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
+ vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
+
+ // 2d overlay grbinds
+ pke_ui_graphics_bindings *ui_gr = pke_ui_get_graphics_bindings();
+ if (ui_gr != nullptr && ui_gr->instance_counter > 0)
+ {
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.ui_base);
+ vkCmdBindIndexBuffer(commandBuffer, ui_gr->bd_index.buffer, ui_gr->bd_index.offsets[0], VK_INDEX_TYPE_UINT16);
+ vkCmdBindVertexBuffers(commandBuffer, ui_gr->bd_vertex.firstBinding, ui_gr->bd_vertex.bindingCount, &ui_gr->bd_vertex.buffer, ui_gr->bd_vertex.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, ui_gr->bd_uv.firstBinding, ui_gr->bd_uv.bindingCount, &ui_gr->bd_uv.buffer, ui_gr->bd_uv.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, ui_gr->bd_instance.firstBinding, ui_gr->bd_instance.bindingCount, &ui_gr->bd_instance.buffer, ui_gr->bd_instance.offsets);
+ vkCmdDrawIndexed(commandBuffer, ui_gr->index_count, ui_gr->instance_counter, 0, 0, 0);
+ }
+
+ // 2d - font glyphs
+ FontTypeIndex count;
+ FontType *fts = FontType_GetFonts(count);
+ for (FontTypeIndex i = FontTypeIndex{0}; i < count; ++i)
+ {
+ FontType *ft = &fts[(FontTypeIndex_T)i];
+ if (ft->bindings.instance_counter == 0)
+ continue;
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.font_glyph);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.txtr, 0, 1, &ft->gr.vkDescriptorSet, 0, {});
- vkCmdBindIndexBuffer(commandBuffer, ft->bindings.bd_index.buffer, ft->bindings.bd_index.offsets[0], VK_INDEX_TYPE_UINT16);
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.txtr, 0, 1, &ft->gr.vkDescriptorSet, 0, {});
+ vkCmdBindIndexBuffer(commandBuffer, ft->bindings.bd_index.buffer, ft->bindings.bd_index.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_vertex.firstBinding, ft->bindings.bd_vertex.bindingCount, &ft->bindings.bd_vertex.buffer, ft->bindings.bd_vertex.offsets);
- vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_uv.firstBinding, ft->bindings.bd_uv.bindingCount, &ft->bindings.bd_uv.buffer, ft->bindings.bd_uv.offsets);
- vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_atlas_size.firstBinding, ft->bindings.bd_atlas_size.bindingCount, &ft->bindings.bd_atlas_size.buffer, ft->bindings.bd_atlas_size.offsets);
- vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_instance.firstBinding, ft->bindings.bd_instance.bindingCount, &ft->bindings.bd_instance.buffer, ft->bindings.bd_instance.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_vertex.firstBinding, ft->bindings.bd_vertex.bindingCount, &ft->bindings.bd_vertex.buffer, ft->bindings.bd_vertex.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_uv.firstBinding, ft->bindings.bd_uv.bindingCount, &ft->bindings.bd_uv.buffer, ft->bindings.bd_uv.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_atlas_size.firstBinding, ft->bindings.bd_atlas_size.bindingCount, &ft->bindings.bd_atlas_size.buffer, ft->bindings.bd_atlas_size.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_instance.firstBinding, ft->bindings.bd_instance.bindingCount, &ft->bindings.bd_instance.buffer, ft->bindings.bd_instance.offsets);
- vkCmdDrawIndexed(commandBuffer, ft->bindings.index_count, ft->bindings.instance_counter, 0, 0, 0);
+ vkCmdDrawIndexed(commandBuffer, ft->bindings.index_count, ft->bindings.instance_counter, 0, 0, 0);
+ }
+
+ vkCmdEndRendering(commandBuffer);
}
- vkCmdEndRenderPass(commandBuffer);
// present pass
- renderPassInfo.renderPass = pkvk_present.render_pass;
- renderPassInfo.framebuffer = pkvk_present.framebuffers[imageIndex];
- renderPassInfo.clearValueCount = 1;
- clearValues[0].color = clearColorBlack;
-
- vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
- vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
- vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkvk_present.pipeline);
-
- // reminder that present.vert is a triangle
-
- // 3d
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkvk_present.pipeline_layout, 0, 1, &pkvk_present.descriptor_sets[(imageIndex * 2)], 0, nullptr);
- vkCmdDraw(commandBuffer, 3, 1, 0, 0);
-
- // 2d
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkvk_present.pipeline_layout, 0, 1, &pkvk_present.descriptor_sets[(imageIndex * 2) + 1], 0, nullptr);
- vkCmdDraw(commandBuffer, 3, 1, 0, 0);
-
- // ImGui
- bool any = false;
- for (uint32_t i = 0; i < LoadedPkePlugins.next; ++i) {
- if (LoadedPkePlugins[i].OnImGuiRender != nullptr) {
- any = true;
- break;
- }
- }
- // TODO move this 'any' check to happen on plugin load and store in global?
- if (any) {
- ImGui_ImplVulkan_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
+ {
+ // present color
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_present.images[imageIndex],
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ range
+ );
+
+ // 3d color
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_3d.images_color_resolve[imageIndex],
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ range
+ );
+
+ // 2d color
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_2d.images_color_resolve[imageIndex],
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ range
+ );
+
+ color_attachments[0].imageView = pkvk_present.image_views[imageIndex];
+ color_attachments[0].clearValue = clearBlack;
+
+ renderingInfo.colorAttachmentCount = 1;
+ renderingInfo.pColorAttachments = &color_attachments.at(0);
+ renderingInfo.pDepthAttachment = VK_NULL_HANDLE;
+ renderingInfo.pStencilAttachment = VK_NULL_HANDLE;
+
+ vkCmdBeginRendering(commandBuffer, &renderingInfo);
+
+ vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
+ vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
+
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkvk_present.pipeline);
+
+ // reminder that present.vert is a triangle
+
+ // 3d
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkvk_present.pipeline_layout, 0, 1, &pkvk_present.descriptor_sets[(imageIndex * 2)], 0, nullptr);
+ vkCmdDraw(commandBuffer, 3, 1, 0, 0);
+
+ // 2d
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkvk_present.pipeline_layout, 0, 1, &pkvk_present.descriptor_sets[(imageIndex * 2) + 1], 0, nullptr);
+ vkCmdDraw(commandBuffer, 3, 1, 0, 0);
+
+ // ImGui
+ bool any = false;
for (uint32_t i = 0; i < LoadedPkePlugins.next; ++i) {
if (LoadedPkePlugins[i].OnImGuiRender != nullptr) {
- LoadedPkePlugins[i].OnImGuiRender();
+ any = true;
+ break;
}
}
- ImGui::Render();
- auto drawData = ImGui::GetDrawData();
- const bool isMinimized = drawData->DisplaySize.x <= 0.0f || drawData->DisplaySize.y <= 0.0f;
- if (isMinimized) return;
+ // TODO move this 'any' check to happen on plugin load and store in global?
+ if (any) {
+ ImGui_ImplVulkan_NewFrame();
+ ImGui_ImplGlfw_NewFrame();
+ ImGui::NewFrame();
+ for (uint32_t i = 0; i < LoadedPkePlugins.next; ++i) {
+ if (LoadedPkePlugins[i].OnImGuiRender != nullptr) {
+ LoadedPkePlugins[i].OnImGuiRender();
+ }
+ }
+ ImGui::Render();
+ auto drawData = ImGui::GetDrawData();
+ const bool isMinimized = drawData->DisplaySize.x <= 0.0f || drawData->DisplaySize.y <= 0.0f;
+ if (isMinimized) return;
- ImGui_ImplVulkan_RenderDrawData(drawData, commandBuffer);
- }
+ ImGui_ImplVulkan_RenderDrawData(drawData, commandBuffer);
+ }
- vkCmdEndRenderPass(commandBuffer);
+ vkCmdEndRendering(commandBuffer);
- result = vkEndCommandBuffer(commandBuffer);
- if (result != VK_SUCCESS) {
- throw "failed to record command buffer!";
+ // color
+ pkvk_transition_image_layout(
+ commandBuffer, pkvk_present.images[imageIndex],
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_NONE,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ range
+ );
}
+
+ vkEndCommandBuffer(commandBuffer);
}
void DestroySyncObjects() {
@@ -3374,27 +3401,6 @@ void DestroyPresentPipeline() {
}
void DestroySwapchain() {
- if (pkvk_2d.framebuffers != nullptr && pkvk_2d.framebuffers != CAFE_BABE(VkFramebuffer)) {
- for (long i = 0; i < swapchainLength; ++i) {
- vkDestroyFramebuffer(vkDevice, pkvk_2d.framebuffers[i], vkAllocator);
- }
- pk_delete<VkFramebuffer>(pkvk_2d.framebuffers, swapchainLength, MemBkt_Vulkan);
- pkvk_2d.framebuffers = CAFE_BABE(VkFramebuffer);
- }
- if (pkvk_3d.framebuffers != nullptr && pkvk_3d.framebuffers != CAFE_BABE(VkFramebuffer)) {
- for (long i = 0; i < swapchainLength; ++i) {
- vkDestroyFramebuffer(vkDevice, pkvk_3d.framebuffers[i], vkAllocator);
- }
- pk_delete<VkFramebuffer>(pkvk_3d.framebuffers, swapchainLength, MemBkt_Vulkan);
- pkvk_3d.framebuffers = CAFE_BABE(VkFramebuffer);
- }
- if (pkvk_present.framebuffers != nullptr && pkvk_present.framebuffers != CAFE_BABE(VkFramebuffer)) {
- for (long i = 0; i < swapchainLength; ++i) {
- vkDestroyFramebuffer(vkDevice, pkvk_present.framebuffers[i], vkAllocator);
- }
- pk_delete<VkFramebuffer>(pkvk_present.framebuffers, swapchainLength, MemBkt_Vulkan);
- pkvk_present.framebuffers = CAFE_BABE(VkFramebuffer);
- }
if (depthImageViews != nullptr && depthImageViews != CAFE_BABE(VkImageView)) {
for (long i = 0; i < swapchainLength; ++i) {
vkDestroyImageView(vkDevice, depthImageViews[i], vkAllocator);
@@ -3520,7 +3526,6 @@ void RecreateSwapchain() {
}
UpdatePresentDescriptorSets();
UpdateCamera();
- CreateFramebuffers();
if (prevSwapchainLength != swapchainLength) {
DestroyDebugDescriptors();
DestroyUniformBuffers();
@@ -3556,12 +3561,10 @@ void CreateWindow(PKEWindowProperties wp) {
InitVulkan();
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
CreateSwapchain();
- CreateRenderPass();
CreatePresentDescriptorSetLayout();
CreatePresentPipeline();
UpdatePresentDescriptorSets();
UpdateCamera();
- CreateFramebuffers();
CreateCommandPool();
CreatePresentCommandBuffers();
CreateCommandBuffers();
@@ -3630,9 +3633,6 @@ void DestroyWindow() {
vkDestroyDescriptorPool(vkDevice, imGuiDescriptorPool, vkAllocator);
vkDestroyDescriptorSetLayout(vkDevice, pkvk_present.descriptor_set_layout, vkAllocator);
- vkDestroyRenderPass(vkDevice, pkvk_2d.render_pass, vkAllocator);
- vkDestroyRenderPass(vkDevice, pkvk_3d.render_pass, vkAllocator);
- vkDestroyRenderPass(vkDevice, pkvk_present.render_pass, vkAllocator);
vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator);
vkDestroySampler(vkDevice, global_sampler, vkAllocator);
vkDestroyDevice(vkDevice, vkAllocator);
@@ -3738,7 +3738,6 @@ void Render() {
vkResetFences(vkDevice, 1, &pkvk_present.fences_in_flight[CURRENT_FRAME]);
- vkResetCommandBuffer(pkvk_present.command_buffers[CURRENT_FRAME], 0);
RecordCommandBuffer(pkvk_present.command_buffers[CURRENT_FRAME], imageIndex);
VkSemaphore waitSemaphores[] = {pkvk_present.semaphores_image_available[CURRENT_FRAME]};
diff --git a/sub/imgui b/sub/imgui
-Subproject 3cdf3f9411b20cc877bab399279c9bc450185ef
+Subproject eaac68ca2ce404137d7a1e7d8f74fafbfe30f50