Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 1 | // 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 Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 16 | #include "VkImageView.hpp" |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 17 | #include "VkRenderPass.hpp" |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 18 | #include <memory.h> |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 19 | #include <algorithm> |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 20 | |
Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 21 | namespace vk { |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 22 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 23 | Framebuffer::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 Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 27 | { |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 28 | for(uint32_t i = 0; i < attachmentCount; i++) |
| 29 | { |
Alexis Hetu | bd4cf81 | 2019-06-14 15:14:07 -0400 | [diff] [blame] | 30 | attachments[i] = vk::Cast(pCreateInfo->pAttachments[i]); |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 31 | } |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 32 | } |
| 33 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 34 | void Framebuffer::destroy(const VkAllocationCallbacks *pAllocator) |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 35 | { |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 36 | vk::deallocate(attachments, pAllocator); |
| 37 | } |
| 38 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 39 | void Framebuffer::clear(const RenderPass *renderPass, uint32_t clearValueCount, const VkClearValue *pClearValues, const VkRect2D &renderArea) |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 40 | { |
Alexis Hetu | bfdb95a | 2019-01-24 16:42:22 -0500 | [diff] [blame] | 41 | ASSERT(attachmentCount == renderPass->getAttachmentCount()); |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 42 | |
Alexis Hetu | bfdb95a | 2019-01-24 16:42:22 -0500 | [diff] [blame] | 43 | const uint32_t count = std::min(clearValueCount, attachmentCount); |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 44 | for(uint32_t i = 0; i < count; i++) |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 45 | { |
Chris Forbes | 605f863 | 2019-08-23 09:13:19 -0700 | [diff] [blame] | 46 | const VkAttachmentDescription attachment = renderPass->getAttachment(i); |
| 47 | |
| 48 | VkImageAspectFlags aspectMask = Format(attachment.format).getAspects(); |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 49 | if(attachment.loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR) |
Chris Forbes | 605f863 | 2019-08-23 09:13:19 -0700 | [diff] [blame] | 50 | aspectMask &= VK_IMAGE_ASPECT_STENCIL_BIT; |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 51 | if(attachment.stencilLoadOp != VK_ATTACHMENT_LOAD_OP_CLEAR) |
Chris Forbes | 605f863 | 2019-08-23 09:13:19 -0700 | [diff] [blame] | 52 | aspectMask &= ~VK_IMAGE_ASPECT_STENCIL_BIT; |
| 53 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 54 | if(!aspectMask || !renderPass->isAttachmentUsed(i)) |
Chris Forbes | 65b1e97 | 2019-05-13 11:01:56 -0700 | [diff] [blame] | 55 | { |
| 56 | continue; |
| 57 | } |
| 58 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 59 | if(renderPass->isMultiView()) |
Alexis Hetu | bfdb95a | 2019-01-24 16:42:22 -0500 | [diff] [blame] | 60 | { |
Chris Forbes | 605f863 | 2019-08-23 09:13:19 -0700 | [diff] [blame] | 61 | attachments[i]->clearWithLayerMask(pClearValues[i], aspectMask, renderArea, |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 62 | renderPass->getAttachmentViewMask(i)); |
Alexis Hetu | bfdb95a | 2019-01-24 16:42:22 -0500 | [diff] [blame] | 63 | } |
Chris Forbes | 605f863 | 2019-08-23 09:13:19 -0700 | [diff] [blame] | 64 | else |
Alexis Hetu | bfdb95a | 2019-01-24 16:42:22 -0500 | [diff] [blame] | 65 | { |
Chris Forbes | 605f863 | 2019-08-23 09:13:19 -0700 | [diff] [blame] | 66 | attachments[i]->clear(pClearValues[i], aspectMask, renderArea); |
Alexis Hetu | bfdb95a | 2019-01-24 16:42:22 -0500 | [diff] [blame] | 67 | } |
Alexis Hetu | 9fbaf69 | 2018-11-19 11:30:43 -0500 | [diff] [blame] | 68 | } |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 69 | } |
| 70 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 71 | void Framebuffer::clearAttachment(const RenderPass *renderPass, uint32_t subpassIndex, const VkClearAttachment &attachment, const VkClearRect &rect) |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 72 | { |
Chris Forbes | d6dc4b7 | 2019-08-23 08:23:27 -0700 | [diff] [blame] | 73 | VkSubpassDescription subpass = renderPass->getSubpass(subpassIndex); |
| 74 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 75 | if(attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 76 | { |
Chris Forbes | c72c8d7 | 2019-08-28 10:38:55 -0700 | [diff] [blame] | 77 | ASSERT(attachment.colorAttachment < subpass.colorAttachmentCount); |
| 78 | uint32_t attachmentIndex = subpass.pColorAttachments[attachment.colorAttachment].attachment; |
| 79 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 80 | if(attachmentIndex != VK_ATTACHMENT_UNUSED) |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 81 | { |
Chris Forbes | c72c8d7 | 2019-08-28 10:38:55 -0700 | [diff] [blame] | 82 | ASSERT(attachmentIndex < attachmentCount); |
| 83 | ImageView *imageView = attachments[attachmentIndex]; |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 84 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 85 | if(renderPass->isMultiView()) |
Chris Forbes | 02d4c0d | 2019-08-21 12:04:34 -0700 | [diff] [blame] | 86 | { |
Chris Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 87 | imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect, |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 88 | renderPass->getViewMask(subpassIndex)); |
Chris Forbes | 02d4c0d | 2019-08-21 12:04:34 -0700 | [diff] [blame] | 89 | } |
| 90 | else |
Chris Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 91 | { |
| 92 | imageView->clear(attachment.clearValue, attachment.aspectMask, rect); |
| 93 | } |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 94 | } |
| 95 | } |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 96 | else if(attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 97 | { |
Chris Forbes | 503d196 | 2019-11-11 09:18:06 -0800 | [diff] [blame] | 98 | uint32_t attachmentIndex = subpass.pDepthStencilAttachment->attachment; |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 99 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 100 | if(attachmentIndex != VK_ATTACHMENT_UNUSED) |
Chris Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 101 | { |
Chris Forbes | 503d196 | 2019-11-11 09:18:06 -0800 | [diff] [blame] | 102 | ASSERT(attachmentIndex < attachmentCount); |
| 103 | ImageView *imageView = attachments[attachmentIndex]; |
| 104 | |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 105 | if(renderPass->isMultiView()) |
Chris Forbes | 503d196 | 2019-11-11 09:18:06 -0800 | [diff] [blame] | 106 | { |
| 107 | imageView->clearWithLayerMask(attachment.clearValue, attachment.aspectMask, rect.rect, |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 108 | renderPass->getViewMask(subpassIndex)); |
Chris Forbes | 503d196 | 2019-11-11 09:18:06 -0800 | [diff] [blame] | 109 | } |
| 110 | else |
| 111 | { |
| 112 | imageView->clear(attachment.clearValue, attachment.aspectMask, rect); |
| 113 | } |
Chris Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 114 | } |
Alexis Hetu | 1cd31ea | 2019-01-17 17:14:57 -0500 | [diff] [blame] | 115 | } |
| 116 | } |
| 117 | |
Chris Forbes | 7c33e88 | 2019-02-21 14:58:28 -0800 | [diff] [blame] | 118 | ImageView *Framebuffer::getAttachment(uint32_t index) const |
| 119 | { |
| 120 | return attachments[index]; |
| 121 | } |
| 122 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 123 | void Framebuffer::resolve(const RenderPass *renderPass, uint32_t subpassIndex) |
Alexis Hetu | 54ec759 | 2019-03-20 14:37:16 -0400 | [diff] [blame] | 124 | { |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 125 | auto const &subpass = renderPass->getSubpass(subpassIndex); |
Alexis Hetu | 54ec759 | 2019-03-20 14:37:16 -0400 | [diff] [blame] | 126 | 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 Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 133 | ImageView *imageView = attachments[subpass.pColorAttachments[i].attachment]; |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 134 | if(renderPass->isMultiView()) |
Chris Forbes | 02d4c0d | 2019-08-21 12:04:34 -0700 | [diff] [blame] | 135 | { |
Chris Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 136 | imageView->resolveWithLayerMask(attachments[resolveAttachment], |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 137 | renderPass->getViewMask(subpassIndex)); |
Chris Forbes | 02d4c0d | 2019-08-21 12:04:34 -0700 | [diff] [blame] | 138 | } |
| 139 | else |
| 140 | { |
Chris Forbes | 2e5042a | 2019-08-23 09:03:48 -0700 | [diff] [blame] | 141 | imageView->resolve(attachments[resolveAttachment]); |
Chris Forbes | 02d4c0d | 2019-08-21 12:04:34 -0700 | [diff] [blame] | 142 | } |
Alexis Hetu | 54ec759 | 2019-03-20 14:37:16 -0400 | [diff] [blame] | 143 | } |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 148 | size_t Framebuffer::ComputeRequiredAllocationSize(const VkFramebufferCreateInfo *pCreateInfo) |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 149 | { |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 150 | return pCreateInfo->attachmentCount * sizeof(void *); |
Alexis Hetu | 8f631c8 | 2018-11-15 15:11:36 -0500 | [diff] [blame] | 151 | } |
| 152 | |
Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 153 | } // namespace vk |