| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [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 "VkSurfaceKHR.hpp" |
| 16 | |
| Antonio Maiorano | 42fd159 | 2020-04-27 11:30:40 -0400 | [diff] [blame] | 17 | #include "Vulkan/VkDestroy.hpp" |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 18 | |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 19 | #include <algorithm> |
| 20 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 21 | namespace { |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 22 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 23 | static 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 Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 26 | }; |
| 27 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 28 | static const VkPresentModeKHR presentModes[] = { |
| Chris Forbes | f466eb5 | 2019-12-10 08:51:17 -0800 | [diff] [blame] | 29 | // 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 Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 34 | VK_PRESENT_MODE_FIFO_KHR, |
| Chris Forbes | f466eb5 | 2019-12-10 08:51:17 -0800 | [diff] [blame] | 35 | VK_PRESENT_MODE_MAILBOX_KHR, |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 36 | }; |
| 37 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 38 | } // namespace |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 39 | |
| Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 40 | namespace vk { |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 41 | |
| Nicolas Capens | c329881 | 2021-10-05 14:31:31 -0400 | [diff] [blame] | 42 | VkResult PresentImage::createImage(VkDevice device, const VkImageCreateInfo &createInfo) |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 43 | { |
| Nicolas Capens | 70178a7 | 2021-10-01 13:21:36 -0400 | [diff] [blame] | 44 | VkImage image; |
| 45 | VkResult status = vkCreateImage(device, &createInfo, nullptr, &image); |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 46 | if(status != VK_SUCCESS) |
| 47 | { |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 48 | return status; |
| 49 | } |
| 50 | |
| Nicolas Capens | 70178a7 | 2021-10-01 13:21:36 -0400 | [diff] [blame] | 51 | this->image = Cast(image); |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 52 | |
| 53 | return status; |
| 54 | } |
| 55 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 56 | VkResult PresentImage::allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo &allocateInfo) |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 57 | { |
| 58 | ASSERT(image); |
| 59 | |
| Nicolas Capens | 70178a7 | 2021-10-01 13:21:36 -0400 | [diff] [blame] | 60 | VkDeviceMemory deviceMemory; |
| 61 | VkResult status = vkAllocateMemory(device, &allocateInfo, nullptr, &deviceMemory); |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 62 | if(status != VK_SUCCESS) |
| 63 | { |
| Peng Huang | 87c78ac | 2021-12-23 10:49:44 +0000 | [diff] [blame] | 64 | release(); |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 65 | return status; |
| 66 | } |
| 67 | |
| Nicolas Capens | 70178a7 | 2021-10-01 13:21:36 -0400 | [diff] [blame] | 68 | imageMemory = Cast(deviceMemory); |
| 69 | vkBindImageMemory(device, *image, deviceMemory, 0); |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 70 | imageStatus = AVAILABLE; |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 71 | |
| Nicolas Capens | 70178a7 | 2021-10-01 13:21:36 -0400 | [diff] [blame] | 72 | return VK_SUCCESS; |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 73 | } |
| 74 | |
| Nicolas Capens | c329881 | 2021-10-05 14:31:31 -0400 | [diff] [blame] | 75 | void PresentImage::release() |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 76 | { |
| 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 | |
| 92 | VkImage PresentImage::asVkImage() const |
| 93 | { |
| Alexis Hetu | 2d77aea | 2019-06-17 13:43:50 -0400 | [diff] [blame] | 94 | return image ? static_cast<VkImage>(*image) : VkImage({ VK_NULL_HANDLE }); |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 95 | } |
| 96 | |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 97 | uint32_t SurfaceKHR::getSurfaceFormatsCount(const void *pSurfaceInfoPNext) const |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 98 | { |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 99 | return static_cast<uint32_t>(sizeof(surfaceFormats) / sizeof(surfaceFormats[0])); |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 100 | } |
| 101 | |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 102 | VkResult SurfaceKHR::getSurfaceFormats(const void *pSurfaceInfoPNext, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) const |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 103 | { |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 104 | uint32_t count = getSurfaceFormatsCount(pSurfaceInfoPNext); |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 105 | |
| 106 | uint32_t i; |
| 107 | for(i = 0; i < std::min(*pSurfaceFormatCount, count); i++) |
| 108 | { |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 109 | pSurfaceFormats[i].surfaceFormat = surfaceFormats[i]; |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | *pSurfaceFormatCount = i; |
| 113 | |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 114 | if(*pSurfaceFormatCount < count) |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 115 | { |
| 116 | return VK_INCOMPLETE; |
| 117 | } |
| 118 | |
| 119 | return VK_SUCCESS; |
| 120 | } |
| 121 | |
| 122 | uint32_t SurfaceKHR::getPresentModeCount() const |
| 123 | { |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 124 | return static_cast<uint32_t>(sizeof(presentModes) / sizeof(presentModes[0])); |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 125 | } |
| 126 | |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 127 | VkResult 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 Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 139 | if(*pPresentModeCount < count) |
| Hernan Liatis | c6eb41b | 2019-02-22 11:12:59 -0800 | [diff] [blame] | 140 | { |
| 141 | return VK_INCOMPLETE; |
| 142 | } |
| 143 | |
| 144 | return VK_SUCCESS; |
| 145 | } |
| 146 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 147 | void SurfaceKHR::associateSwapchain(SwapchainKHR *swapchain) |
| Hernan Liatis | 43be716 | 2019-03-08 17:57:41 -0800 | [diff] [blame] | 148 | { |
| Alexis Hetu | 7d96f51 | 2019-06-13 18:23:56 -0400 | [diff] [blame] | 149 | associatedSwapchain = swapchain; |
| Hernan Liatis | 43be716 | 2019-03-08 17:57:41 -0800 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | void SurfaceKHR::disassociateSwapchain() |
| 153 | { |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 154 | associatedSwapchain = nullptr; |
| Hernan Liatis | 43be716 | 2019-03-08 17:57:41 -0800 | [diff] [blame] | 155 | } |
| 156 | |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 157 | bool SurfaceKHR::hasAssociatedSwapchain() |
| Hernan Liatis | 43be716 | 2019-03-08 17:57:41 -0800 | [diff] [blame] | 158 | { |
| Alexis Hetu | 63ae924 | 2019-06-06 13:52:15 -0400 | [diff] [blame] | 159 | return (associatedSwapchain != nullptr); |
| Hernan Liatis | 43be716 | 2019-03-08 17:57:41 -0800 | [diff] [blame] | 160 | } |
| 161 | |
| Chris Forbes | b52384b | 2019-08-28 12:01:29 -0700 | [diff] [blame] | 162 | VkResult SurfaceKHR::getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects) const |
| 163 | { |
| Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 164 | if(!pRects) |
| Chris Forbes | b52384b | 2019-08-28 12:01:29 -0700 | [diff] [blame] | 165 | { |
| 166 | *pRectCount = 1; |
| 167 | return VK_SUCCESS; |
| 168 | } |
| 169 | |
| Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 170 | if(*pRectCount < 1) |
| Chris Forbes | b52384b | 2019-08-28 12:01:29 -0700 | [diff] [blame] | 171 | { |
| 172 | return VK_INCOMPLETE; |
| 173 | } |
| 174 | |
| 175 | VkSurfaceCapabilitiesKHR capabilities; |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 176 | getSurfaceCapabilities(nullptr, &capabilities, nullptr); |
| Chris Forbes | b52384b | 2019-08-28 12:01:29 -0700 | [diff] [blame] | 177 | |
| Ben Clayton | 45c697a | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 178 | pRects[0].offset = { 0, 0 }; |
| Chris Forbes | b52384b | 2019-08-28 12:01:29 -0700 | [diff] [blame] | 179 | pRects[0].extent = capabilities.currentExtent; |
| 180 | *pRectCount = 1; |
| 181 | |
| 182 | return VK_SUCCESS; |
| 183 | } |
| 184 | |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 185 | void SurfaceKHR::setCommonSurfaceCapabilities(const void *pSurfaceInfoPNext, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities, void *pSurfaceCapabilitiesPNext) |
| Antonio Maiorano | 5128643 | 2021-02-19 09:56:47 -0500 | [diff] [blame] | 186 | { |
| 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 Capens | a4232c1 | 2021-12-06 11:22:22 -0500 | [diff] [blame] | 197 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | |
| Antonio Maiorano | 5128643 | 2021-02-19 09:56:47 -0500 | [diff] [blame] | 198 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | |
| 199 | VK_IMAGE_USAGE_TRANSFER_DST_BIT | |
| Nicolas Capens | a9e93a8 | 2021-12-06 11:18:33 -0500 | [diff] [blame] | 200 | VK_IMAGE_USAGE_SAMPLED_BIT | |
| 201 | VK_IMAGE_USAGE_STORAGE_BIT; |
| Antonio Maiorano | 5128643 | 2021-02-19 09:56:47 -0500 | [diff] [blame] | 202 | } |
| 203 | |
| Shahbaz Youssefi | ea3fc74 | 2022-10-23 22:41:06 -0400 | [diff] [blame] | 204 | } // namespace vk |