• 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.h"
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 
allocateImage(VkDevice device,const VkImageCreateInfo & createInfo)42 VkResult PresentImage::allocateImage(VkDevice device, const VkImageCreateInfo &createInfo)
43 {
44 	VkImage *vkImagePtr = reinterpret_cast<VkImage *>(allocate(sizeof(VkImage), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
45 	if(!vkImagePtr)
46 	{
47 		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
48 	}
49 
50 	VkResult status = vkCreateImage(device, &createInfo, nullptr, vkImagePtr);
51 	if(status != VK_SUCCESS)
52 	{
53 		deallocate(vkImagePtr, DEVICE_MEMORY);
54 		return status;
55 	}
56 
57 	image = Cast(*vkImagePtr);
58 	deallocate(vkImagePtr, DEVICE_MEMORY);
59 
60 	return status;
61 }
62 
allocateAndBindImageMemory(VkDevice device,const VkMemoryAllocateInfo & allocateInfo)63 VkResult PresentImage::allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo &allocateInfo)
64 {
65 	ASSERT(image);
66 
67 	VkDeviceMemory *vkDeviceMemoryPtr = reinterpret_cast<VkDeviceMemory *>(
68 	    allocate(sizeof(VkDeviceMemory), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
69 	if(!vkDeviceMemoryPtr)
70 	{
71 		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
72 	}
73 
74 	VkResult status = vkAllocateMemory(device, &allocateInfo, nullptr, vkDeviceMemoryPtr);
75 	if(status != VK_SUCCESS)
76 	{
77 		deallocate(vkDeviceMemoryPtr, DEVICE_MEMORY);
78 		return status;
79 	}
80 
81 	imageMemory = Cast(*vkDeviceMemoryPtr);
82 	vkBindImageMemory(device, *image, *vkDeviceMemoryPtr, 0);
83 
84 	imageStatus = AVAILABLE;
85 	deallocate(vkDeviceMemoryPtr, DEVICE_MEMORY);
86 
87 	return status;
88 }
89 
clear()90 void PresentImage::clear()
91 {
92 	if(imageMemory)
93 	{
94 		vk::destroy(static_cast<VkDeviceMemory>(*imageMemory), nullptr);
95 		imageMemory = nullptr;
96 	}
97 
98 	if(image)
99 	{
100 		vk::destroy(static_cast<VkImage>(*image), nullptr);
101 		image = nullptr;
102 	}
103 
104 	imageStatus = NONEXISTENT;
105 }
106 
asVkImage() const107 VkImage PresentImage::asVkImage() const
108 {
109 	return image ? static_cast<VkImage>(*image) : VkImage({ VK_NULL_HANDLE });
110 }
111 
getSurfaceCapabilities(VkSurfaceCapabilitiesKHR * pSurfaceCapabilities) const112 void SurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
113 {
114 	pSurfaceCapabilities->minImageCount = 1;
115 	pSurfaceCapabilities->maxImageCount = 0;
116 
117 	pSurfaceCapabilities->maxImageArrayLayers = 1;
118 
119 	pSurfaceCapabilities->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
120 	pSurfaceCapabilities->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
121 	pSurfaceCapabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
122 	pSurfaceCapabilities->supportedUsageFlags =
123 	    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
124 	    VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
125 	    VK_IMAGE_USAGE_TRANSFER_DST_BIT |
126 	    VK_IMAGE_USAGE_SAMPLED_BIT;
127 }
128 
getSurfaceFormatsCount() const129 uint32_t SurfaceKHR::getSurfaceFormatsCount() const
130 {
131 	return static_cast<uint32_t>(sizeof(surfaceFormats) / sizeof(surfaceFormats[0]));
132 }
133 
getSurfaceFormats(uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats) const134 VkResult SurfaceKHR::getSurfaceFormats(uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) const
135 {
136 	uint32_t count = getSurfaceFormatsCount();
137 
138 	uint32_t i;
139 	for(i = 0; i < std::min(*pSurfaceFormatCount, count); i++)
140 	{
141 		pSurfaceFormats[i] = surfaceFormats[i];
142 	}
143 
144 	*pSurfaceFormatCount = i;
145 
146 	if(*pSurfaceFormatCount < count)
147 	{
148 		return VK_INCOMPLETE;
149 	}
150 
151 	return VK_SUCCESS;
152 }
153 
getPresentModeCount() const154 uint32_t SurfaceKHR::getPresentModeCount() const
155 {
156 	return static_cast<uint32_t>(sizeof(presentModes) / sizeof(presentModes[0]));
157 }
158 
getPresentModes(uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes) const159 VkResult SurfaceKHR::getPresentModes(uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) const
160 {
161 	uint32_t count = getPresentModeCount();
162 
163 	uint32_t i;
164 	for(i = 0; i < std::min(*pPresentModeCount, count); i++)
165 	{
166 		pPresentModes[i] = presentModes[i];
167 	}
168 
169 	*pPresentModeCount = i;
170 
171 	if(*pPresentModeCount < count)
172 	{
173 		return VK_INCOMPLETE;
174 	}
175 
176 	return VK_SUCCESS;
177 }
178 
associateSwapchain(SwapchainKHR * swapchain)179 void SurfaceKHR::associateSwapchain(SwapchainKHR *swapchain)
180 {
181 	associatedSwapchain = swapchain;
182 }
183 
disassociateSwapchain()184 void SurfaceKHR::disassociateSwapchain()
185 {
186 	associatedSwapchain = nullptr;
187 }
188 
hasAssociatedSwapchain()189 bool SurfaceKHR::hasAssociatedSwapchain()
190 {
191 	return (associatedSwapchain != nullptr);
192 }
193 
getPresentRectangles(uint32_t * pRectCount,VkRect2D * pRects) const194 VkResult SurfaceKHR::getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects) const
195 {
196 	if(!pRects)
197 	{
198 		*pRectCount = 1;
199 		return VK_SUCCESS;
200 	}
201 
202 	if(*pRectCount < 1)
203 	{
204 		return VK_INCOMPLETE;
205 	}
206 
207 	VkSurfaceCapabilitiesKHR capabilities;
208 	getSurfaceCapabilities(&capabilities);
209 
210 	pRects[0].offset = { 0, 0 };
211 	pRects[0].extent = capabilities.currentExtent;
212 	*pRectCount = 1;
213 
214 	return VK_SUCCESS;
215 }
216 
217 }  // namespace vk