blob: 07fcdb675272d413a84c222f22c8f25b63916175 [file] [log] [blame]
Hernan Liatisc6eb41b2019-02-22 11:12:59 -08001// 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 "VkSurfaceKHR.hpp"
16
Antonio Maiorano42fd1592020-04-27 11:30:40 -040017#include "Vulkan/VkDestroy.hpp"
Alexis Hetu63ae9242019-06-06 13:52:15 -040018
Hernan Liatisc6eb41b2019-02-22 11:12:59 -080019#include <algorithm>
20
Ben Clayton45c697a2019-12-17 20:38:03 +000021namespace {
Alexis Hetu63ae9242019-06-06 13:52:15 -040022
Ben Clayton45c697a2019-12-17 20:38:03 +000023static const VkSurfaceFormatKHR surfaceFormats[] = {
24 { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
25 { VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
Alexis Hetu63ae9242019-06-06 13:52:15 -040026};
27
Ben Clayton45c697a2019-12-17 20:38:03 +000028static const VkPresentModeKHR presentModes[] = {
Chris Forbesf466eb52019-12-10 08:51:17 -080029 // FIXME(b/124265819): Make present modes behave correctly. Currently we use XPutImage
30 // with no synchronization, which behaves more like VK_PRESENT_MODE_IMMEDIATE_KHR. We
31 // should convert to using the Present extension, which allows us to request presentation
32 // at particular msc values. Will need a similar solution on Windows - possibly interact
33 // with DXGI directly.
Alexis Hetu63ae9242019-06-06 13:52:15 -040034 VK_PRESENT_MODE_FIFO_KHR,
Chris Forbesf466eb52019-12-10 08:51:17 -080035 VK_PRESENT_MODE_MAILBOX_KHR,
Alexis Hetu63ae9242019-06-06 13:52:15 -040036};
37
Ben Clayton45c697a2019-12-17 20:38:03 +000038} // namespace
Alexis Hetu63ae9242019-06-06 13:52:15 -040039
Nicolas Capens157ba262019-12-10 17:49:14 -050040namespace vk {
Hernan Liatisc6eb41b2019-02-22 11:12:59 -080041
Nicolas Capensc3298812021-10-05 14:31:31 -040042VkResult PresentImage::createImage(VkDevice device, const VkImageCreateInfo &createInfo)
Alexis Hetu63ae9242019-06-06 13:52:15 -040043{
Nicolas Capens70178a72021-10-01 13:21:36 -040044 VkImage image;
45 VkResult status = vkCreateImage(device, &createInfo, nullptr, &image);
Alexis Hetu63ae9242019-06-06 13:52:15 -040046 if(status != VK_SUCCESS)
47 {
Alexis Hetu63ae9242019-06-06 13:52:15 -040048 return status;
49 }
50
Nicolas Capens70178a72021-10-01 13:21:36 -040051 this->image = Cast(image);
Alexis Hetu63ae9242019-06-06 13:52:15 -040052
53 return status;
54}
55
Ben Clayton45c697a2019-12-17 20:38:03 +000056VkResult PresentImage::allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo &allocateInfo)
Alexis Hetu63ae9242019-06-06 13:52:15 -040057{
58 ASSERT(image);
59
Nicolas Capens70178a72021-10-01 13:21:36 -040060 VkDeviceMemory deviceMemory;
61 VkResult status = vkAllocateMemory(device, &allocateInfo, nullptr, &deviceMemory);
Alexis Hetu63ae9242019-06-06 13:52:15 -040062 if(status != VK_SUCCESS)
63 {
Peng Huang87c78ac2021-12-23 10:49:44 +000064 release();
Alexis Hetu63ae9242019-06-06 13:52:15 -040065 return status;
66 }
67
Nicolas Capens70178a72021-10-01 13:21:36 -040068 imageMemory = Cast(deviceMemory);
69 vkBindImageMemory(device, *image, deviceMemory, 0);
Alexis Hetu63ae9242019-06-06 13:52:15 -040070 imageStatus = AVAILABLE;
Alexis Hetu63ae9242019-06-06 13:52:15 -040071
Nicolas Capens70178a72021-10-01 13:21:36 -040072 return VK_SUCCESS;
Alexis Hetu63ae9242019-06-06 13:52:15 -040073}
74
Nicolas Capensc3298812021-10-05 14:31:31 -040075void PresentImage::release()
Alexis Hetu63ae9242019-06-06 13:52:15 -040076{
77 if(imageMemory)
78 {
79 vk::destroy(static_cast<VkDeviceMemory>(*imageMemory), nullptr);
80 imageMemory = nullptr;
81 }
82
83 if(image)
84 {
85 vk::destroy(static_cast<VkImage>(*image), nullptr);
86 image = nullptr;
87 }
88
89 imageStatus = NONEXISTENT;
90}
91
92VkImage PresentImage::asVkImage() const
93{
Alexis Hetu2d77aea2019-06-17 13:43:50 -040094 return image ? static_cast<VkImage>(*image) : VkImage({ VK_NULL_HANDLE });
Alexis Hetu63ae9242019-06-06 13:52:15 -040095}
96
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -040097uint32_t SurfaceKHR::getSurfaceFormatsCount(const void *pSurfaceInfoPNext) const
Hernan Liatisc6eb41b2019-02-22 11:12:59 -080098{
Alexis Hetu63ae9242019-06-06 13:52:15 -040099 return static_cast<uint32_t>(sizeof(surfaceFormats) / sizeof(surfaceFormats[0]));
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800100}
101
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -0400102VkResult SurfaceKHR::getSurfaceFormats(const void *pSurfaceInfoPNext, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) const
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800103{
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -0400104 uint32_t count = getSurfaceFormatsCount(pSurfaceInfoPNext);
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800105
106 uint32_t i;
107 for(i = 0; i < std::min(*pSurfaceFormatCount, count); i++)
108 {
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -0400109 pSurfaceFormats[i].surfaceFormat = surfaceFormats[i];
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800110 }
111
112 *pSurfaceFormatCount = i;
113
Alexis Hetu63ae9242019-06-06 13:52:15 -0400114 if(*pSurfaceFormatCount < count)
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800115 {
116 return VK_INCOMPLETE;
117 }
118
119 return VK_SUCCESS;
120}
121
122uint32_t SurfaceKHR::getPresentModeCount() const
123{
Alexis Hetu63ae9242019-06-06 13:52:15 -0400124 return static_cast<uint32_t>(sizeof(presentModes) / sizeof(presentModes[0]));
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800125}
126
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800127VkResult SurfaceKHR::getPresentModes(uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) const
128{
129 uint32_t count = getPresentModeCount();
130
131 uint32_t i;
132 for(i = 0; i < std::min(*pPresentModeCount, count); i++)
133 {
134 pPresentModes[i] = presentModes[i];
135 }
136
137 *pPresentModeCount = i;
138
Alexis Hetu63ae9242019-06-06 13:52:15 -0400139 if(*pPresentModeCount < count)
Hernan Liatisc6eb41b2019-02-22 11:12:59 -0800140 {
141 return VK_INCOMPLETE;
142 }
143
144 return VK_SUCCESS;
145}
146
Ben Clayton45c697a2019-12-17 20:38:03 +0000147void SurfaceKHR::associateSwapchain(SwapchainKHR *swapchain)
Hernan Liatis43be7162019-03-08 17:57:41 -0800148{
Alexis Hetu7d96f512019-06-13 18:23:56 -0400149 associatedSwapchain = swapchain;
Hernan Liatis43be7162019-03-08 17:57:41 -0800150}
151
152void SurfaceKHR::disassociateSwapchain()
153{
Alexis Hetu63ae9242019-06-06 13:52:15 -0400154 associatedSwapchain = nullptr;
Hernan Liatis43be7162019-03-08 17:57:41 -0800155}
156
Alexis Hetu63ae9242019-06-06 13:52:15 -0400157bool SurfaceKHR::hasAssociatedSwapchain()
Hernan Liatis43be7162019-03-08 17:57:41 -0800158{
Alexis Hetu63ae9242019-06-06 13:52:15 -0400159 return (associatedSwapchain != nullptr);
Hernan Liatis43be7162019-03-08 17:57:41 -0800160}
161
Chris Forbesb52384b2019-08-28 12:01:29 -0700162VkResult SurfaceKHR::getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects) const
163{
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500164 if(!pRects)
Chris Forbesb52384b2019-08-28 12:01:29 -0700165 {
166 *pRectCount = 1;
167 return VK_SUCCESS;
168 }
169
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500170 if(*pRectCount < 1)
Chris Forbesb52384b2019-08-28 12:01:29 -0700171 {
172 return VK_INCOMPLETE;
173 }
174
175 VkSurfaceCapabilitiesKHR capabilities;
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -0400176 getSurfaceCapabilities(nullptr, &capabilities, nullptr);
Chris Forbesb52384b2019-08-28 12:01:29 -0700177
Ben Clayton45c697a2019-12-17 20:38:03 +0000178 pRects[0].offset = { 0, 0 };
Chris Forbesb52384b2019-08-28 12:01:29 -0700179 pRects[0].extent = capabilities.currentExtent;
180 *pRectCount = 1;
181
182 return VK_SUCCESS;
183}
184
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -0400185void SurfaceKHR::setCommonSurfaceCapabilities(const void *pSurfaceInfoPNext, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities, void *pSurfaceCapabilitiesPNext)
Antonio Maiorano51286432021-02-19 09:56:47 -0500186{
187 pSurfaceCapabilities->minImageCount = 1;
188 pSurfaceCapabilities->maxImageCount = 0;
189
190 pSurfaceCapabilities->maxImageArrayLayers = 1;
191
192 pSurfaceCapabilities->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
193 pSurfaceCapabilities->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
194 pSurfaceCapabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
195 pSurfaceCapabilities->supportedUsageFlags =
196 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
Nicolas Capensa4232c12021-12-06 11:22:22 -0500197 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
Antonio Maiorano51286432021-02-19 09:56:47 -0500198 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
199 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
Nicolas Capensa9e93a82021-12-06 11:18:33 -0500200 VK_IMAGE_USAGE_SAMPLED_BIT |
201 VK_IMAGE_USAGE_STORAGE_BIT;
Antonio Maiorano51286432021-02-19 09:56:47 -0500202}
203
Shahbaz Youssefiea3fc742022-10-23 22:41:06 -0400204} // namespace vk