• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include "Vulkan/VkDestroy.hpp"
18 
19 #include <algorithm>
20 
21 namespace {
22 
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 },
26 };
27 
28 static const VkPresentModeKHR presentModes[] = {
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.
34 	VK_PRESENT_MODE_FIFO_KHR,
35 	VK_PRESENT_MODE_MAILBOX_KHR,
36 };
37 
38 }  // namespace
39 
40 namespace vk {
41 
createImage(VkDevice device,const VkImageCreateInfo & createInfo)42 VkResult PresentImage::createImage(VkDevice device, const VkImageCreateInfo &createInfo)
43 {
44 	VkImage image;
45 	VkResult status = vkCreateImage(device, &createInfo, nullptr, &image);
46 	if(status != VK_SUCCESS)
47 	{
48 		return status;
49 	}
50 
51 	this->image = Cast(image);
52 
53 	return status;
54 }
55 
allocateAndBindImageMemory(VkDevice device,const VkMemoryAllocateInfo & allocateInfo)56 VkResult PresentImage::allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo &allocateInfo)
57 {
58 	ASSERT(image);
59 
60 	VkDeviceMemory deviceMemory;
61 	VkResult status = vkAllocateMemory(device, &allocateInfo, nullptr, &deviceMemory);
62 	if(status != VK_SUCCESS)
63 	{
64 		release();
65 		return status;
66 	}
67 
68 	imageMemory = Cast(deviceMemory);
69 	vkBindImageMemory(device, *image, deviceMemory, 0);
70 	imageStatus = AVAILABLE;
71 
72 	return VK_SUCCESS;
73 }
74 
release()75 void PresentImage::release()
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 
asVkImage() const92 VkImage PresentImage::asVkImage() const
93 {
94 	return image ? static_cast<VkImage>(*image) : VkImage({ VK_NULL_HANDLE });
95 }
96 
getSurfaceFormatsCount() const97 uint32_t SurfaceKHR::getSurfaceFormatsCount() const
98 {
99 	return static_cast<uint32_t>(sizeof(surfaceFormats) / sizeof(surfaceFormats[0]));
100 }
101 
getSurfaceFormats(uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats) const102 VkResult SurfaceKHR::getSurfaceFormats(uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) const
103 {
104 	uint32_t count = getSurfaceFormatsCount();
105 
106 	uint32_t i;
107 	for(i = 0; i < std::min(*pSurfaceFormatCount, count); i++)
108 	{
109 		pSurfaceFormats[i] = surfaceFormats[i];
110 	}
111 
112 	*pSurfaceFormatCount = i;
113 
114 	if(*pSurfaceFormatCount < count)
115 	{
116 		return VK_INCOMPLETE;
117 	}
118 
119 	return VK_SUCCESS;
120 }
121 
getPresentModeCount() const122 uint32_t SurfaceKHR::getPresentModeCount() const
123 {
124 	return static_cast<uint32_t>(sizeof(presentModes) / sizeof(presentModes[0]));
125 }
126 
getPresentModes(uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes) const127 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 
139 	if(*pPresentModeCount < count)
140 	{
141 		return VK_INCOMPLETE;
142 	}
143 
144 	return VK_SUCCESS;
145 }
146 
associateSwapchain(SwapchainKHR * swapchain)147 void SurfaceKHR::associateSwapchain(SwapchainKHR *swapchain)
148 {
149 	associatedSwapchain = swapchain;
150 }
151 
disassociateSwapchain()152 void SurfaceKHR::disassociateSwapchain()
153 {
154 	associatedSwapchain = nullptr;
155 }
156 
hasAssociatedSwapchain()157 bool SurfaceKHR::hasAssociatedSwapchain()
158 {
159 	return (associatedSwapchain != nullptr);
160 }
161 
getPresentRectangles(uint32_t * pRectCount,VkRect2D * pRects) const162 VkResult SurfaceKHR::getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects) const
163 {
164 	if(!pRects)
165 	{
166 		*pRectCount = 1;
167 		return VK_SUCCESS;
168 	}
169 
170 	if(*pRectCount < 1)
171 	{
172 		return VK_INCOMPLETE;
173 	}
174 
175 	VkSurfaceCapabilitiesKHR capabilities;
176 	getSurfaceCapabilities(&capabilities);
177 
178 	pRects[0].offset = { 0, 0 };
179 	pRects[0].extent = capabilities.currentExtent;
180 	*pRectCount = 1;
181 
182 	return VK_SUCCESS;
183 }
184 
setCommonSurfaceCapabilities(VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)185 void SurfaceKHR::setCommonSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
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 |
197 	    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
198 	    VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
199 	    VK_IMAGE_USAGE_TRANSFER_DST_BIT |
200 	    VK_IMAGE_USAGE_SAMPLED_BIT |
201 	    VK_IMAGE_USAGE_STORAGE_BIT;
202 }
203 
204 }  // namespace vk