X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fbackends%2Fvulkan%2Frenderpass.cpp;fp=source%2Fbackends%2Fvulkan%2Frenderpass.cpp;h=fb2389e5c8736d9078bba13a18748fb996e65a2d;hb=d841d557eec57575adc856a8b081042861dab9e8;hp=0000000000000000000000000000000000000000;hpb=1b4d387b74b2108f3926796d8115bee134fbf7f1;p=libs%2Fgl.git diff --git a/source/backends/vulkan/renderpass.cpp b/source/backends/vulkan/renderpass.cpp new file mode 100644 index 00000000..fb2389e5 --- /dev/null +++ b/source/backends/vulkan/renderpass.cpp @@ -0,0 +1,151 @@ +#include +#include "device.h" +#include "framebuffer.h" +#include "renderpass.h" +#include "structurebuilder.h" +#include "vulkan.h" + +using namespace std; + +namespace Msp { +namespace GL { + +void RenderPass::update(Device &device) +{ + Rect fb_rect = framebuffer->get_rect(); + render_area = fb_rect.intersect(render_area); + discard_fb_contents = (clear && render_area==fb_rect); + handle = device.get_pipeline_cache().get_render_pass(*this); +} + +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))); + for(FrameAttachment a: framebuffer->get_format()) + result = hash_update<64>(result, a); + + return result; +} + +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; + unsigned i = 0; + for(FrameAttachment a: format) + { + 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].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].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].finalLayout = external_layout; + + if(subpass_layout==VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + { + color_ptr->attachment = i; + color_ptr->layout = subpass_layout; + ++color_ptr; + } + else + { + depth_stencil_ref->attachment = i; + depth_stencil_ref->layout = subpass_layout; + } + + ++i; + } + + 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; + + render_pass_info->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info->attachmentCount = format.size(); + render_pass_info->pAttachments = attachments; + render_pass_info->subpassCount = 1; + render_pass_info->pSubpasses = subpass; + + if(to_present) + { + dependency->srcSubpass = 0; + dependency->dstSubpass = VK_SUBPASS_EXTERNAL; + dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency->srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; + dependency->dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + dependency->dstAccessMask = 0; + + render_pass_info->dependencyCount = 1; + render_pass_info->pDependencies = dependency; + } +} + +void RenderPass::fill_begin_info(vector &buffer) const +{ + const FrameFormat &format = framebuffer->get_format(); + + StructureBuilder sb(buffer, 2); + VkRenderPassBeginInfo *const &begin_info = sb.add(1); + VkClearValue *const &vk_clear_values = sb.add(format.size()); + + begin_info->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + begin_info->renderPass = handle_cast<::VkRenderPass>(handle); + begin_info->framebuffer = handle_cast<::VkFramebuffer>(framebuffer->handle); + + begin_info->renderArea.offset.x = render_area.left; + begin_info->renderArea.offset.y = render_area.bottom; + begin_info->renderArea.extent.width = render_area.width; + begin_info->renderArea.extent.height = render_area.height; + + if(clear_values) + { + unsigned i = 0; + for(FrameAttachment a: format) + { + if(get_attach_point(a)==get_attach_point(DEPTH_ATTACHMENT)) + vk_clear_values[i].depthStencil.depth = clear_values[i].depth_stencil.depth; + else if(get_attach_point(a)==get_attach_point(STENCIL_ATTACHMENT)) + vk_clear_values[i].depthStencil.stencil = clear_values[i].depth_stencil.stencil; + else + { + vk_clear_values[i].color.float32[0] = clear_values[i].color.r; + vk_clear_values[i].color.float32[1] = clear_values[i].color.g; + vk_clear_values[i].color.float32[2] = clear_values[i].color.b; + vk_clear_values[i].color.float32[3] = clear_values[i].color.a; + } + ++i; + } + + begin_info->clearValueCount = format.size(); + begin_info->pClearValues = vk_clear_values; + } +} + +} // namespace GL +} // namespace Msp