• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 "XlibSurfaceKHR.hpp"
16 
17 #include "Vulkan/VkDeviceMemory.hpp"
18 #include "Vulkan/VkImage.hpp"
19 
20 namespace vk {
21 
XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR * pCreateInfo,void * mem)22 XlibSurfaceKHR::XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem)
23     : pDisplay(pCreateInfo->dpy)
24     , window(pCreateInfo->window)
25 {
26 	int screen = DefaultScreen(pDisplay);
27 	gc = libX11->XDefaultGC(pDisplay, screen);
28 
29 	XVisualInfo xVisual;
30 	Status status = libX11->XMatchVisualInfo(pDisplay, screen, 32, TrueColor, &xVisual);
31 	bool match = (status != 0 && xVisual.blue_mask == 0xFF);
32 	visual = match ? xVisual.visual : libX11->XDefaultVisual(pDisplay, screen);
33 }
34 
destroySurface(const VkAllocationCallbacks * pAllocator)35 void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
36 {
37 }
38 
ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR * pCreateInfo)39 size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo)
40 {
41 	return 0;
42 }
43 
getSurfaceCapabilities(VkSurfaceCapabilitiesKHR * pSurfaceCapabilities) const44 void XlibSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
45 {
46 	SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
47 
48 	XWindowAttributes attr;
49 	libX11->XGetWindowAttributes(pDisplay, window, &attr);
50 	VkExtent2D extent = { static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height) };
51 
52 	pSurfaceCapabilities->currentExtent = extent;
53 	pSurfaceCapabilities->minImageExtent = extent;
54 	pSurfaceCapabilities->maxImageExtent = extent;
55 }
56 
attachImage(PresentImage * image)57 void XlibSurfaceKHR::attachImage(PresentImage *image)
58 {
59 	XWindowAttributes attr;
60 	libX11->XGetWindowAttributes(pDisplay, window, &attr);
61 
62 	VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
63 
64 	int bytes_per_line = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
65 	char *buffer = static_cast<char *>(image->getImageMemory()->getOffsetPointer(0));
66 
67 	XImage *xImage = libX11->XCreateImage(pDisplay, visual, attr.depth, ZPixmap, 0, buffer, extent.width, extent.height, 32, bytes_per_line);
68 
69 	imageMap[image] = xImage;
70 }
71 
detachImage(PresentImage * image)72 void XlibSurfaceKHR::detachImage(PresentImage *image)
73 {
74 	auto it = imageMap.find(image);
75 	if(it != imageMap.end())
76 	{
77 		XImage *xImage = it->second;
78 		xImage->data = nullptr;  // the XImage does not actually own the buffer
79 		XDestroyImage(xImage);
80 		imageMap.erase(image);
81 	}
82 }
83 
present(PresentImage * image)84 VkResult XlibSurfaceKHR::present(PresentImage *image)
85 {
86 	auto it = imageMap.find(image);
87 	if(it != imageMap.end())
88 	{
89 		XImage *xImage = it->second;
90 
91 		if(xImage->data)
92 		{
93 			XWindowAttributes attr;
94 			libX11->XGetWindowAttributes(pDisplay, window, &attr);
95 			VkExtent2D windowExtent = { static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height) };
96 			VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
97 
98 			if(windowExtent.width != extent.width || windowExtent.height != extent.height)
99 			{
100 				return VK_ERROR_OUT_OF_DATE_KHR;
101 			}
102 
103 			libX11->XPutImage(pDisplay, window, gc, xImage, 0, 0, 0, 0, extent.width, extent.height);
104 		}
105 	}
106 
107 	return VK_SUCCESS;
108 }
109 
110 }  // namespace vk