blob: 4c797e165aff5148c58efd2c0a7b2e6de766bae2 [file] [log] [blame]
Alexis Hetu8f631c82018-11-15 15:11:36 -05001// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "VkFramebuffer.hpp"
Alexis Hetu9fbaf692018-11-19 11:30:43 -050016#include "VkImageView.hpp"
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050017#include "VkRenderPass.hpp"
Alexis Hetu9fbaf692018-11-19 11:30:43 -050018#include <memory.h>
Ben Clayton2ed93ab2019-12-17 20:38:03 +000019#include <algorithm>
Alexis Hetu8f631c82018-11-15 15:11:36 -050020
Nicolas Capens157ba262019-12-10 17:49:14 -050021namespace vk {
Alexis Hetu8f631c82018-11-15 15:11:36 -050022
Ben Clayton2ed93ab2019-12-17 20:38:03 +000023Framebuffer::Framebuffer(const VkFramebufferCreateInfo *pCreateInfo, void *mem)
24 : attachmentCount(pCreateInfo->attachmentCount)
25 , attachments(reinterpret_cast<ImageView **>(mem))
26 , extent{ pCreateInfo->width, pCreateInfo->height, pCreateInfo->layers }
Alexis Hetu8f631c82018-11-15 15:11:36 -050027{
Alexis Hetu9fbaf692018-11-19 11:30:43 -050028 for(uint32_t i = 0; i < attachmentCount; i++)
29 {
Alexis Hetubd4cf812019-06-14 15:14:07 -040030 attachments[i] = vk::Cast(pCreateInfo->pAttachments[i]);
Alexis Hetu9fbaf692018-11-19 11:30:43 -050031 }
Alexis Hetu8f631c82018-11-15 15:11:36 -050032}
33
Ben Clayton2ed93ab2019-12-17 20:38:03 +000034void Framebuffer::destroy(const VkAllocationCallbacks *pAllocator)
Alexis Hetu8f631c82018-11-15 15:11:36 -050035{
Alexis Hetu9fbaf692018-11-19 11:30:43 -050036 vk::deallocate(attachments, pAllocator);
37}
38
Ben Clayton2ed93ab2019-12-17 20:38:03 +000039void Framebuffer::clear(const RenderPass *renderPass, uint32_t clearValueCount, const VkClearValue *pClearValues, const VkRect2D &renderArea)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050040{
Alexis Hetubfdb95a2019-01-24 16:42:22 -050041 ASSERT(attachmentCount == renderPass->getAttachmentCount());
Alexis Hetu9fbaf692018-11-19 11:30:43 -050042
Alexis Hetubfdb95a2019-01-24 16:42:22 -050043 const uint32_t count = std::min(clearValueCount, attachmentCount);
Nicolas Capens81bc9d92019-12-16 15:05:57 -050044 for(uint32_t i = 0; i < count; i++)
Alexis Hetu9fbaf692018-11-19 11:30:43 -050045 {
Chris Forbes605f8632019-08-23 09:13:19 -070046 const VkAttachmentDescription attachment = renderPass->getAttachment(i);
47
48 VkImageAspectFlags aspectMask = Format(attachment.format).getAspects();
Nicolas Capens81bc9d92019-12-16 15:05:57 -050049 if(attachment.loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
Chris Forbes605f8632019-08-23 09:13:19 -070050 aspectMask &= VK_IMAGE_ASPECT_STENCIL_BIT;
Nicolas Capens81bc9d92019-12-16 15:05:57 -050051 if(attachment.stencilLoadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
Chris Forbes605f8632019-08-23 09:13:19 -070052 aspectMask &= ~VK_IMAGE_ASPECT_STENCIL_BIT;
53
Nicolas Capens81bc9d92019-12-16 15:05:57 -050054 if(!aspectMask || !renderPass->isAttachmentUsed(i))
Chris Forbes65b1e972019-05-13 11:01:56 -070055 {
56 continue;
57 }
58
Nicolas Capens81bc9d92019-12-16 15:05:57 -050059 if(renderPass->isMultiView())
Alexis Hetubfdb95a2019-01-24 16:42:22 -050060 {
Chris Forbes605f8632019-08-23 09:13:19 -070061 attachments[i]->clearWithLayerMask(pClearValues[i], aspectMask, renderArea,
Ben Clayton2ed93ab2019-12-17 20:38:03 +000062 renderPass->getAttachmentViewMask(i));
Alexis Hetubfdb95a2019-01-24 16:42:22 -050063 }
Chris Forbes605f8632019-08-23 09:13:19 -070064 else
Alexis Hetubfdb95a2019-01-24 16:42:22 -050065 {
Chris Forbes605f8632019-08-23 09:13:19 -070066 attachments[i]->clear(pClearValues[i], aspectMask, renderArea);
Alexis Hetubfdb95a2019-01-24 16:42:22 -050067 }
Alexis Hetu9fbaf692018-11-19 11:30:43 -050068 }
Alexis Hetu8f631c82018-11-15 15:11:36 -050069}
70
Ben Clayton2ed93ab2019-12-17 20:38:03 +000071void Framebuffer::clearAttachment(const RenderPass *renderPass, uint32_t subpassIndex, const VkClearAttachment &attachment, const VkClearRect &rect)
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050072{
Chris Forbesd6dc4b72019-08-23 08:23:27 -070073 VkSubpassDescription subpass = renderPass->getSubpass(subpassIndex);
74
Nicolas Capens81bc9d92019-12-16 15:05:57 -050075 if(attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050076 {
Chris Forbesc72c8d72019-08-28 10:38:55 -070077 ASSERT(attachment.colorAttachment < subpass.colorAttachmentCount);
78 uint32_t attachmentIndex = subpass.pColorAttachments[attachment.colorAttachment].attachment;
79
Nicolas Capens81bc9d92019-12-16 15:05:57 -050080 if(attachmentIndex != VK_ATTACHMENT_UNUSED)
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050081 {
Chris Forbesc72c8d72019-08-28 10:38:55 -070082 ASSERT(attachmentIndex < attachmentCount);
83 ImageView *imageView = attachments[attachmentIndex];
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050084
Nicolas Capens81bc9d92019-12-16 15:05:57 -050085 if(renderPass->isMultiView())
Chris Forbes02d4c0d2019-08-21 12:04:34 -070086 {
Chris Forbes2e5042a2019-08-23 09:03:48 -070087 imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
Ben Clayton2ed93ab2019-12-17 20:38:03 +000088 renderPass->getViewMask(subpassIndex));
Chris Forbes02d4c0d2019-08-21 12:04:34 -070089 }
90 else
Chris Forbes2e5042a2019-08-23 09:03:48 -070091 {
92 imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
93 }
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050094 }
95 }
Nicolas Capens81bc9d92019-12-16 15:05:57 -050096 else if(attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050097 {
Chris Forbes503d1962019-11-11 09:18:06 -080098 uint32_t attachmentIndex = subpass.pDepthStencilAttachment->attachment;
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050099
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500100 if(attachmentIndex != VK_ATTACHMENT_UNUSED)
Chris Forbes2e5042a2019-08-23 09:03:48 -0700101 {
Chris Forbes503d1962019-11-11 09:18:06 -0800102 ASSERT(attachmentIndex < attachmentCount);
103 ImageView *imageView = attachments[attachmentIndex];
104
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500105 if(renderPass->isMultiView())
Chris Forbes503d1962019-11-11 09:18:06 -0800106 {
107 imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect,
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000108 renderPass->getViewMask(subpassIndex));
Chris Forbes503d1962019-11-11 09:18:06 -0800109 }
110 else
111 {
112 imageView->clear(attachment.clearValue, attachment.aspectMask, rect);
113 }
Chris Forbes2e5042a2019-08-23 09:03:48 -0700114 }
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500115 }
116}
117
Chris Forbes7c33e882019-02-21 14:58:28 -0800118ImageView *Framebuffer::getAttachment(uint32_t index) const
119{
120 return attachments[index];
121}
122
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000123void Framebuffer::resolve(const RenderPass *renderPass, uint32_t subpassIndex)
Alexis Hetu54ec7592019-03-20 14:37:16 -0400124{
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000125 auto const &subpass = renderPass->getSubpass(subpassIndex);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400126 if(subpass.pResolveAttachments)
127 {
128 for(uint32_t i = 0; i < subpass.colorAttachmentCount; i++)
129 {
130 uint32_t resolveAttachment = subpass.pResolveAttachments[i].attachment;
131 if(resolveAttachment != VK_ATTACHMENT_UNUSED)
132 {
Chris Forbes2e5042a2019-08-23 09:03:48 -0700133 ImageView *imageView = attachments[subpass.pColorAttachments[i].attachment];
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500134 if(renderPass->isMultiView())
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700135 {
Chris Forbes2e5042a2019-08-23 09:03:48 -0700136 imageView->resolveWithLayerMask(attachments[resolveAttachment],
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000137 renderPass->getViewMask(subpassIndex));
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700138 }
139 else
140 {
Chris Forbes2e5042a2019-08-23 09:03:48 -0700141 imageView->resolve(attachments[resolveAttachment]);
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700142 }
Alexis Hetu54ec7592019-03-20 14:37:16 -0400143 }
144 }
145 }
146}
147
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000148size_t Framebuffer::ComputeRequiredAllocationSize(const VkFramebufferCreateInfo *pCreateInfo)
Alexis Hetu8f631c82018-11-15 15:11:36 -0500149{
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000150 return pCreateInfo->attachmentCount * sizeof(void *);
Alexis Hetu8f631c82018-11-15 15:11:36 -0500151}
152
Nicolas Capens157ba262019-12-10 17:49:14 -0500153} // namespace vk