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