X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fbackends%2Fvulkan%2Frenderpass.cpp;fp=source%2Fbackends%2Fvulkan%2Frenderpass.cpp;h=8459b3a99c37a01b93fe6869b2ee6e116ed22e39;hp=fb2389e5c8736d9078bba13a18748fb996e65a2d;hb=89d543c07ba80430baebcba19f9a353b25cd8ab4;hpb=295a0851bd3bcfba75c3e6a94b63cd8f5ee4ea53 diff --git a/source/backends/vulkan/renderpass.cpp b/source/backends/vulkan/renderpass.cpp index fb2389e5..8459b3a9 100644 --- a/source/backends/vulkan/renderpass.cpp +++ b/source/backends/vulkan/renderpass.cpp @@ -20,8 +20,11 @@ void RenderPass::update(Device &device) uint64_t RenderPass::compute_hash() const { - bool discard = (!clear_values && discard_fb_contents); - uint64_t result = hash<64>(static_cast(clear | (discard*2) | (to_present*4))); + const FrameFormat &format = framebuffer->get_format(); + bool discard = (clear && !clear_values && discard_fb_contents); + bool resolve = framebuffer->has_resolve_attachments(); + uint64_t result = hash<64>(static_cast(clear | (discard<<1) | (resolve<<2) | (to_present<<3))); + result = hash_round<64>(result, format.get_samples()); for(FrameAttachment a: framebuffer->get_format()) result = hash_update<64>(result, a); @@ -32,68 +35,96 @@ void RenderPass::fill_creation_info(vector &buffer) const { const FrameFormat &format = framebuffer->get_format(); - bool discard = (!clear_values && discard_fb_contents); bool has_depth = any_of(format.begin(), format.end(), [](FrameAttachment a){ return get_components(get_attachment_pixelformat(a))==DEPTH_COMPONENT; }); unsigned color_count = format.size()-has_depth; - - StructureBuilder sb(buffer, 6); - VkRenderPassCreateInfo *const &render_pass_info = sb.add(); - VkSubpassDescription *const &subpass = sb.add(); - VkAttachmentDescription *const &attachments = sb.add(format.size()); - VkAttachmentReference *const &color_refs = sb.add(color_count); - VkAttachmentReference *const &depth_stencil_ref = sb.add(has_depth); - VkSubpassDependency *const &dependency = sb.add(to_present); - - VkSampleCountFlagBits vk_samples = static_cast(get_vulkan_samples(format.get_samples())); - - VkAttachmentReference *color_ptr = color_refs; + bool resolve = framebuffer->has_resolve_attachments(); + + StructureBuilder sb(buffer, 7); + VkRenderPassCreateInfo2 *const &render_pass_info = sb.add(); + VkSubpassDescription2 *const &subpass = sb.add(); + VkAttachmentDescription2 *const &attachments = sb.add(format.size()*(1+resolve)); + VkAttachmentReference2 *const &color_refs = sb.add(color_count*(1+resolve)); + VkAttachmentReference2 *const &depth_stencil_ref = sb.add(has_depth*(1+resolve)); + VkSubpassDescriptionDepthStencilResolve *const &depth_stencil_resolve = sb.add(has_depth && resolve); + VkSubpassDependency2 *const &dependency = sb.add(to_present); + + VkAttachmentReference2 *color_ptr = color_refs; + VkAttachmentReference2 *ds_ptr = depth_stencil_ref; unsigned i = 0; - for(FrameAttachment a: format) - { + auto fill_attachment = [=, &color_ptr, &ds_ptr, &i](FrameAttachment a, VkSampleCountFlagBits samples, bool discard){ VkImageLayout subpass_layout = static_cast(get_vulkan_attachment_layout(get_components(get_attachment_pixelformat(a)))); VkImageLayout external_layout = (to_present ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : subpass_layout); + attachments[i].sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2; attachments[i].format = static_cast(get_vulkan_pixelformat(get_attachment_pixelformat(a))); - attachments[i].samples = vk_samples; - attachments[i].loadOp = (clear ? discard ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD); + attachments[i].samples = samples; + attachments[i].loadOp = (discard ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD); attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[i].initialLayout = ((clear && discard) ? VK_IMAGE_LAYOUT_UNDEFINED : external_layout); + attachments[i].initialLayout = (discard ? VK_IMAGE_LAYOUT_UNDEFINED : external_layout); attachments[i].finalLayout = external_layout; if(subpass_layout==VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { + color_ptr->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2; color_ptr->attachment = i; color_ptr->layout = subpass_layout; ++color_ptr; } else { - depth_stencil_ref->attachment = i; - depth_stencil_ref->layout = subpass_layout; + ds_ptr->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2; + ds_ptr->attachment = i; + ds_ptr->layout = subpass_layout; } ++i; + }; + + bool discard = (clear && !clear_values && discard_fb_contents); + VkSampleCountFlagBits vk_samples = static_cast(get_vulkan_samples(format.get_samples())); + for(FrameAttachment a: format) + fill_attachment(a, vk_samples, discard); + + if(resolve) + { + ++ds_ptr; + for(FrameAttachment a: format) + fill_attachment(a, VK_SAMPLE_COUNT_1_BIT, true); } + subpass->sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2; subpass->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass->colorAttachmentCount = color_count; if(color_count) subpass->pColorAttachments = color_refs; if(has_depth) subpass->pDepthStencilAttachment = depth_stencil_ref; + if(resolve) + { + subpass->pResolveAttachments = color_refs+color_count; + + if(has_depth) + { + depth_stencil_resolve->sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE; + depth_stencil_resolve->depthResolveMode = VK_RESOLVE_MODE_MIN_BIT; + depth_stencil_resolve->pDepthStencilResolveAttachment = depth_stencil_ref+1; + subpass->pNext = depth_stencil_resolve; + } + } - render_pass_info->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info->attachmentCount = format.size(); + render_pass_info->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2; + render_pass_info->attachmentCount = format.size()*(1+resolve); render_pass_info->pAttachments = attachments; render_pass_info->subpassCount = 1; render_pass_info->pSubpasses = subpass; if(to_present) { + dependency->sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2; dependency->srcSubpass = 0; dependency->dstSubpass = VK_SUBPASS_EXTERNAL; dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;