blob: 6440ab116c4b292170d8754ed7a3c1047aa8f6cd [file] [log] [blame]
Hernan Liatisc7943e92019-02-25 19:29:54 -08001// Copyright 2019 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 "VkSwapchainKHR.hpp"
16
Hernan Liatisc7943e92019-02-25 19:29:54 -080017#include "Vulkan/VkDeviceMemory.hpp"
Alexis Hetu63ae9242019-06-06 13:52:15 -040018#include "Vulkan/VkFence.hpp"
19#include "Vulkan/VkImage.hpp"
20#include "Vulkan/VkSemaphore.hpp"
Hernan Liatisc7943e92019-02-25 19:29:54 -080021
Hernan Liatisd00375a2019-02-26 11:19:27 -080022#include <algorithm>
Alexis Hetu63ae9242019-06-06 13:52:15 -040023#include <cstring>
Hernan Liatisd00375a2019-02-26 11:19:27 -080024
Nicolas Capens157ba262019-12-10 17:49:14 -050025namespace vk {
Hernan Liatisc7943e92019-02-25 19:29:54 -080026
Ben Clayton45c697a2019-12-17 20:38:03 +000027SwapchainKHR::SwapchainKHR(const VkSwapchainCreateInfoKHR *pCreateInfo, void *mem)
28 : surface(vk::Cast(pCreateInfo->surface))
29 , images(reinterpret_cast<PresentImage *>(mem))
30 , imageCount(pCreateInfo->minImageCount)
31 , retired(false)
Hernan Liatisc7943e92019-02-25 19:29:54 -080032{
Ben Clayton45c697a2019-12-17 20:38:03 +000033 memset(reinterpret_cast<void *>(images), 0, imageCount * sizeof(PresentImage));
Hernan Liatisc7943e92019-02-25 19:29:54 -080034}
35
36void SwapchainKHR::destroy(const VkAllocationCallbacks *pAllocator)
37{
Alexis Hetu63ae9242019-06-06 13:52:15 -040038 for(uint32_t i = 0; i < imageCount; i++)
Hernan Liatisc7943e92019-02-25 19:29:54 -080039 {
Ben Clayton45c697a2019-12-17 20:38:03 +000040 PresentImage &currentImage = images[i];
Alexis Hetu63ae9242019-06-06 13:52:15 -040041 if(currentImage.exists())
Hernan Liatisc7943e92019-02-25 19:29:54 -080042 {
Alexis Hetu63ae9242019-06-06 13:52:15 -040043 surface->detachImage(&currentImage);
44 currentImage.clear();
Hernan Liatisc7943e92019-02-25 19:29:54 -080045 }
46 }
Hernan Liatis43be7162019-03-08 17:57:41 -080047
48 if(!retired)
49 {
Alexis Hetu63ae9242019-06-06 13:52:15 -040050 surface->disassociateSwapchain();
Hernan Liatis43be7162019-03-08 17:57:41 -080051 }
Alexis Hetu63ae9242019-06-06 13:52:15 -040052
53 vk::deallocate(images, pAllocator);
Hernan Liatisc7943e92019-02-25 19:29:54 -080054}
55
56size_t SwapchainKHR::ComputeRequiredAllocationSize(const VkSwapchainCreateInfoKHR *pCreateInfo)
57{
Alexis Hetu63ae9242019-06-06 13:52:15 -040058 return pCreateInfo->minImageCount * sizeof(PresentImage);
Hernan Liatisc7943e92019-02-25 19:29:54 -080059}
60
Hernan Liatis43be7162019-03-08 17:57:41 -080061void SwapchainKHR::retire()
62{
63 if(!retired)
64 {
65 retired = true;
Alexis Hetu63ae9242019-06-06 13:52:15 -040066 surface->disassociateSwapchain();
Hernan Liatis43be7162019-03-08 17:57:41 -080067
Alexis Hetu63ae9242019-06-06 13:52:15 -040068 for(uint32_t i = 0; i < imageCount; i++)
Hernan Liatis43be7162019-03-08 17:57:41 -080069 {
Ben Clayton45c697a2019-12-17 20:38:03 +000070 PresentImage &currentImage = images[i];
Alexis Hetu63ae9242019-06-06 13:52:15 -040071 if(currentImage.isAvailable())
Hernan Liatis43be7162019-03-08 17:57:41 -080072 {
Alexis Hetu63ae9242019-06-06 13:52:15 -040073 surface->detachImage(&currentImage);
74 currentImage.clear();
Hernan Liatis43be7162019-03-08 17:57:41 -080075 }
76 }
77 }
78}
79
Hernan Liatisc7943e92019-02-25 19:29:54 -080080void SwapchainKHR::resetImages()
81{
Alexis Hetu63ae9242019-06-06 13:52:15 -040082 for(uint32_t i = 0; i < imageCount; i++)
Hernan Liatisc7943e92019-02-25 19:29:54 -080083 {
Alexis Hetu63ae9242019-06-06 13:52:15 -040084 images[i].clear();
Hernan Liatisc7943e92019-02-25 19:29:54 -080085 }
86}
87
Alexis Hetu63ae9242019-06-06 13:52:15 -040088VkResult SwapchainKHR::createImages(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo)
Hernan Liatisc7943e92019-02-25 19:29:54 -080089{
90 resetImages();
91
92 VkImageCreateInfo imageInfo = {};
93 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
94
Alexis Hetu63ae9242019-06-06 13:52:15 -040095 if(pCreateInfo->flags & VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR)
Hernan Liatisc7943e92019-02-25 19:29:54 -080096 {
97 imageInfo.flags |= VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT;
98 }
99
Alexis Hetu63ae9242019-06-06 13:52:15 -0400100 if(pCreateInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR)
Hernan Liatisc7943e92019-02-25 19:29:54 -0800101 {
102 imageInfo.flags |= VK_IMAGE_CREATE_PROTECTED_BIT;
103 }
104
105 imageInfo.imageType = VK_IMAGE_TYPE_2D;
Alexis Hetu63ae9242019-06-06 13:52:15 -0400106 imageInfo.format = pCreateInfo->imageFormat;
107 imageInfo.extent.height = pCreateInfo->imageExtent.height;
108 imageInfo.extent.width = pCreateInfo->imageExtent.width;
Hernan Liatisc7943e92019-02-25 19:29:54 -0800109 imageInfo.extent.depth = 1;
110 imageInfo.mipLevels = 1;
Alexis Hetu63ae9242019-06-06 13:52:15 -0400111 imageInfo.arrayLayers = pCreateInfo->imageArrayLayers;
Hernan Liatisc7943e92019-02-25 19:29:54 -0800112 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
113 imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
Alexis Hetu63ae9242019-06-06 13:52:15 -0400114 imageInfo.usage = pCreateInfo->imageUsage;
115 imageInfo.sharingMode = pCreateInfo->imageSharingMode;
116 imageInfo.pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices;
117 imageInfo.queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount;
Hernan Liatisc7943e92019-02-25 19:29:54 -0800118 imageInfo.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
119
Alexis Hetu63ae9242019-06-06 13:52:15 -0400120 VkMemoryAllocateInfo allocInfo = {};
121 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
122 allocInfo.allocationSize = 0;
123 allocInfo.memoryTypeIndex = 0;
124
Hernan Liatisc7943e92019-02-25 19:29:54 -0800125 VkResult status;
Alexis Hetu63ae9242019-06-06 13:52:15 -0400126 for(uint32_t i = 0; i < imageCount; i++)
Hernan Liatisc7943e92019-02-25 19:29:54 -0800127 {
Ben Clayton45c697a2019-12-17 20:38:03 +0000128 PresentImage &currentImage = images[i];
Alexis Hetu63ae9242019-06-06 13:52:15 -0400129
130 status = currentImage.allocateImage(device, imageInfo);
Hernan Liatisc7943e92019-02-25 19:29:54 -0800131 if(status != VK_SUCCESS)
132 {
133 return status;
134 }
135
Alexis Hetu63ae9242019-06-06 13:52:15 -0400136 allocInfo.allocationSize = currentImage.getImage()->getMemoryRequirements().size;
Hernan Liatisc7943e92019-02-25 19:29:54 -0800137
Alexis Hetu63ae9242019-06-06 13:52:15 -0400138 status = currentImage.allocateAndBindImageMemory(device, allocInfo);
Hernan Liatisc7943e92019-02-25 19:29:54 -0800139 if(status != VK_SUCCESS)
140 {
141 return status;
142 }
143
Alexis Hetu63ae9242019-06-06 13:52:15 -0400144 surface->attachImage(&currentImage);
Hernan Liatisc7943e92019-02-25 19:29:54 -0800145 }
146
147 return VK_SUCCESS;
148}
149
Hernan Liatisd00375a2019-02-26 11:19:27 -0800150uint32_t SwapchainKHR::getImageCount() const
151{
Alexis Hetu63ae9242019-06-06 13:52:15 -0400152 return imageCount;
Hernan Liatisd00375a2019-02-26 11:19:27 -0800153}
154
155VkResult SwapchainKHR::getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) const
156{
Hernan Liatisd00375a2019-02-26 11:19:27 -0800157 uint32_t i;
Alexis Hetu63ae9242019-06-06 13:52:15 -0400158 for(i = 0; i < std::min(*pSwapchainImageCount, imageCount); i++)
Hernan Liatisd00375a2019-02-26 11:19:27 -0800159 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400160 pSwapchainImages[i] = images[i].asVkImage();
Hernan Liatisd00375a2019-02-26 11:19:27 -0800161 }
162
163 *pSwapchainImageCount = i;
164
Alexis Hetu63ae9242019-06-06 13:52:15 -0400165 if(*pSwapchainImageCount < imageCount)
Hernan Liatisd00375a2019-02-26 11:19:27 -0800166 {
167 return VK_INCOMPLETE;
168 }
169
170 return VK_SUCCESS;
171}
172
Ben Clayton45c697a2019-12-17 20:38:03 +0000173VkResult SwapchainKHR::getNextImage(uint64_t timeout, Semaphore *semaphore, Fence *fence, uint32_t *pImageIndex)
Hernan Liatis6b12a502019-03-01 15:06:13 -0800174{
Alexis Hetu63ae9242019-06-06 13:52:15 -0400175 for(uint32_t i = 0; i < imageCount; i++)
Hernan Liatis6b12a502019-03-01 15:06:13 -0800176 {
Ben Clayton45c697a2019-12-17 20:38:03 +0000177 PresentImage &currentImage = images[i];
Alexis Hetu63ae9242019-06-06 13:52:15 -0400178 if(currentImage.isAvailable())
Hernan Liatis6b12a502019-03-01 15:06:13 -0800179 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400180 currentImage.setStatus(DRAWING);
Hernan Liatis6b12a502019-03-01 15:06:13 -0800181 *pImageIndex = i;
182
183 if(semaphore)
184 {
Alexis Hetu7d96f512019-06-13 18:23:56 -0400185 semaphore->signal();
Hernan Liatis6b12a502019-03-01 15:06:13 -0800186 }
187
188 if(fence)
189 {
Alexis Hetu7d96f512019-06-13 18:23:56 -0400190 fence->complete();
Hernan Liatis6b12a502019-03-01 15:06:13 -0800191 }
192
193 return VK_SUCCESS;
194 }
195 }
196
197 return VK_NOT_READY;
198}
199
Antonio Maiorano26c6c4a2019-10-17 15:33:47 -0400200VkResult SwapchainKHR::present(uint32_t index)
Hernan Liatis6b12a502019-03-01 15:06:13 -0800201{
Ben Clayton45c697a2019-12-17 20:38:03 +0000202 auto &image = images[index];
Alexis Hetu63ae9242019-06-06 13:52:15 -0400203 image.setStatus(PRESENTING);
Antonio Maiorano26c6c4a2019-10-17 15:33:47 -0400204 VkResult result = surface->present(&image);
Alexis Hetu63ae9242019-06-06 13:52:15 -0400205 image.setStatus(AVAILABLE);
Hernan Liatis43be7162019-03-08 17:57:41 -0800206
207 if(retired)
208 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400209 surface->detachImage(&image);
210 image.clear();
Hernan Liatis43be7162019-03-08 17:57:41 -0800211 }
Antonio Maiorano26c6c4a2019-10-17 15:33:47 -0400212
213 return result;
Hernan Liatis6b12a502019-03-01 15:06:13 -0800214}
215
Nicolas Capens157ba262019-12-10 17:49:14 -0500216} // namespace vk