if(handle)
device.get_destroy_queue().destroy(handle);
- VkImageView vk_attachments[FrameFormat::MAX_ATTACHMENTS] = { };
+ VkImageView vk_attachments[FrameFormat::MAX_ATTACHMENTS*2] = { };
unsigned i = 0;
+ bool any_resolve = false;
for(const Framebuffer::Attachment &a: self.attachments)
{
bool use_tex_view = (a.tex->view_type==VK_IMAGE_VIEW_TYPE_2D || (a.tex->view_type==VK_IMAGE_VIEW_TYPE_2D_ARRAY && a.layer<0));
else
throw logic_error("unexpected framebuffer configuration");
+ if(a.resolve)
+ {
+ a.resolve->refresh_mip_views();
+ vk_attachments[self.format.size()+i] = a.resolve->mip_view_handles[0];
+ any_resolve = true;
+ }
+
++i;
}
VkFramebufferCreateInfo framebuffer_info = { };
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebuffer_info.renderPass = handle_cast<::VkRenderPass>(render_pass.handle);
- framebuffer_info.attachmentCount = self.format.size();
+ framebuffer_info.attachmentCount = self.format.size()*(1+any_resolve);
framebuffer_info.pAttachments = handle_cast<::VkImageView *>(vk_attachments);
framebuffer_info.width = self.width;
framebuffer_info.height = self.height;
void VulkanFramebuffer::prepare_image_layouts(bool discard) const
{
for(const Framebuffer::Attachment &a: static_cast<const Framebuffer *>(this)->attachments)
+ {
a.tex->change_layout(a.level, get_vulkan_attachment_layout(get_components(a.tex->get_format())), (discard && a.layer<0));
+ if(a.resolve)
+ a.resolve->change_layout(a.level, get_vulkan_attachment_layout(get_components(a.resolve->get_format())), discard);
+ }
}
void VulkanFramebuffer::set_debug_name(const string &name)
uint64_t RenderPass::compute_hash() const
{
- bool discard = (!clear_values && discard_fb_contents);
- uint64_t result = hash<64>(static_cast<uint8_t>(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<uint8_t>(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);
{
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<VkRenderPassCreateInfo>();
- VkSubpassDescription *const &subpass = sb.add<VkSubpassDescription>();
- VkAttachmentDescription *const &attachments = sb.add<VkAttachmentDescription>(format.size());
- VkAttachmentReference *const &color_refs = sb.add<VkAttachmentReference>(color_count);
- VkAttachmentReference *const &depth_stencil_ref = sb.add<VkAttachmentReference>(has_depth);
- VkSubpassDependency *const &dependency = sb.add<VkSubpassDependency>(to_present);
-
- VkSampleCountFlagBits vk_samples = static_cast<VkSampleCountFlagBits>(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<VkRenderPassCreateInfo2>();
+ VkSubpassDescription2 *const &subpass = sb.add<VkSubpassDescription2>();
+ VkAttachmentDescription2 *const &attachments = sb.add<VkAttachmentDescription2>(format.size()*(1+resolve));
+ VkAttachmentReference2 *const &color_refs = sb.add<VkAttachmentReference2>(color_count*(1+resolve));
+ VkAttachmentReference2 *const &depth_stencil_ref = sb.add<VkAttachmentReference2>(has_depth*(1+resolve));
+ VkSubpassDescriptionDepthStencilResolve *const &depth_stencil_resolve = sb.add<VkSubpassDescriptionDepthStencilResolve>(has_depth && resolve);
+ VkSubpassDependency2 *const &dependency = sb.add<VkSubpassDependency2>(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<VkImageLayout>(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<VkFormat>(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<VkSampleCountFlagBits>(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;