• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 "DisplaySurfaceKHR.hpp"
16 
17 #include "Vulkan/VkDeviceMemory.hpp"
18 #include "Vulkan/VkImage.hpp"
19 
20 #include <fcntl.h>
21 #include <string.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include <xf86drm.h>
25 
26 namespace vk {
27 
GetDisplayModeProperties(uint32_t * pPropertyCount,VkDisplayModePropertiesKHR * pProperties)28 VkResult DisplaySurfaceKHR::GetDisplayModeProperties(uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)
29 {
30 	*pPropertyCount = 1;
31 
32 	if(pProperties)
33 	{
34 		int fd = open("/dev/dri/card0", O_RDWR);
35 		drmModeRes *res = drmModeGetResources(fd);
36 		drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]);
37 		pProperties->displayMode = (uintptr_t)connector->modes[0].name;
38 		pProperties->parameters.visibleRegion.width = connector->modes[0].hdisplay;
39 		pProperties->parameters.visibleRegion.height = connector->modes[0].vdisplay;
40 		pProperties->parameters.refreshRate = connector->modes[0].vrefresh * 1000;
41 		drmModeFreeConnector(connector);
42 		drmModeFreeResources(res);
43 		close(fd);
44 	}
45 
46 	return VK_SUCCESS;
47 }
48 
GetDisplayPlaneCapabilities(VkDisplayPlaneCapabilitiesKHR * pCapabilities)49 VkResult DisplaySurfaceKHR::GetDisplayPlaneCapabilities(VkDisplayPlaneCapabilitiesKHR *pCapabilities)
50 {
51 	int fd = open("/dev/dri/card0", O_RDWR);
52 	drmModeRes *res = drmModeGetResources(fd);
53 	drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]);
54 	pCapabilities->supportedAlpha = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
55 	pCapabilities->minSrcPosition.x = 0;
56 	pCapabilities->minSrcPosition.y = 0;
57 	pCapabilities->maxSrcPosition.x = 0;
58 	pCapabilities->maxSrcPosition.y = 0;
59 	pCapabilities->minSrcExtent.width = connector->modes[0].hdisplay;
60 	pCapabilities->minSrcExtent.height = connector->modes[0].vdisplay;
61 	pCapabilities->maxSrcExtent.width = connector->modes[0].hdisplay;
62 	pCapabilities->maxSrcExtent.height = connector->modes[0].vdisplay;
63 	pCapabilities->minDstPosition.x = 0;
64 	pCapabilities->minDstPosition.y = 0;
65 	pCapabilities->maxDstPosition.x = 0;
66 	pCapabilities->maxDstPosition.y = 0;
67 	pCapabilities->minDstExtent.width = connector->modes[0].hdisplay;
68 	pCapabilities->minDstExtent.height = connector->modes[0].vdisplay;
69 	pCapabilities->maxDstExtent.width = connector->modes[0].hdisplay;
70 	pCapabilities->maxDstExtent.height = connector->modes[0].vdisplay;
71 	drmModeFreeConnector(connector);
72 	drmModeFreeResources(res);
73 	close(fd);
74 
75 	return VK_SUCCESS;
76 }
77 
GetDisplayPlaneSupportedDisplays(uint32_t * pDisplayCount,VkDisplayKHR * pDisplays)78 VkResult DisplaySurfaceKHR::GetDisplayPlaneSupportedDisplays(uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)
79 {
80 	*pDisplayCount = 1;
81 
82 	if(pDisplays)
83 	{
84 		int fd = open("/dev/dri/card0", O_RDWR);
85 		drmModeRes *res = drmModeGetResources(fd);
86 		*pDisplays = res->connectors[0];
87 		drmModeFreeResources(res);
88 		close(fd);
89 	}
90 
91 	return VK_SUCCESS;
92 }
93 
GetPhysicalDeviceDisplayPlaneProperties(uint32_t * pPropertyCount,VkDisplayPlanePropertiesKHR * pProperties)94 VkResult DisplaySurfaceKHR::GetPhysicalDeviceDisplayPlaneProperties(uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)
95 {
96 	*pPropertyCount = 1;
97 
98 	if(pProperties)
99 	{
100 		int fd = open("/dev/dri/card0", O_RDWR);
101 		drmModeRes *res = drmModeGetResources(fd);
102 		pProperties->currentDisplay = res->connectors[0];
103 		pProperties->currentStackIndex = 0;
104 		drmModeFreeResources(res);
105 		close(fd);
106 	}
107 
108 	return VK_SUCCESS;
109 }
110 
GetPhysicalDeviceDisplayProperties(uint32_t * pPropertyCount,VkDisplayPropertiesKHR * pProperties)111 VkResult DisplaySurfaceKHR::GetPhysicalDeviceDisplayProperties(uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)
112 {
113 	*pPropertyCount = 1;
114 
115 	if(pProperties)
116 	{
117 		int fd = open("/dev/dri/card0", O_RDWR);
118 		drmModeRes *res = drmModeGetResources(fd);
119 		drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]);
120 		pProperties->display = res->connectors[0];
121 		pProperties->displayName = "monitor";
122 		pProperties->physicalDimensions.width = connector->mmWidth;
123 		pProperties->physicalDimensions.height = connector->mmHeight;
124 		if(pProperties->physicalDimensions.width <= 0 || pProperties->physicalDimensions.height <= 0)
125 		{
126 			pProperties->physicalDimensions.width = connector->modes[0].hdisplay * 25.4 / 96;
127 			pProperties->physicalDimensions.height = connector->modes[0].vdisplay * 25.4 / 96;
128 		}
129 		pProperties->physicalResolution.width = connector->modes[0].hdisplay;
130 		pProperties->physicalResolution.height = connector->modes[0].vdisplay;
131 		pProperties->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
132 		pProperties->planeReorderPossible = VK_FALSE;
133 		pProperties->persistentContent = VK_FALSE;
134 		drmModeFreeConnector(connector);
135 		drmModeFreeResources(res);
136 		close(fd);
137 	}
138 
139 	return VK_SUCCESS;
140 }
141 
DisplaySurfaceKHR(const VkDisplaySurfaceCreateInfoKHR * pCreateInfo,void * mem)142 DisplaySurfaceKHR::DisplaySurfaceKHR(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, void *mem)
143 {
144 	fd = open("/dev/dri/card0", O_RDWR);
145 	drmModeRes *res = drmModeGetResources(fd);
146 	connector_id = res->connectors[0];
147 	drmModeFreeResources(res);
148 	drmModeConnector *connector = drmModeGetConnector(fd, connector_id);
149 	encoder_id = connector->encoder_id;
150 	memcpy(&mode_info, &connector->modes[0], sizeof(drmModeModeInfo));
151 	drmModeFreeConnector(connector);
152 	drmModeEncoder *encoder = drmModeGetEncoder(fd, encoder_id);
153 	crtc_id = encoder->crtc_id;
154 	drmModeFreeEncoder(encoder);
155 
156 	crtc = drmModeGetCrtc(fd, crtc_id);
157 
158 	struct drm_mode_create_dumb creq;
159 	memset(&creq, 0, sizeof(struct drm_mode_create_dumb));
160 	creq.width = mode_info.hdisplay;
161 	creq.height = mode_info.vdisplay;
162 	creq.bpp = 32;
163 	drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
164 
165 	handle = creq.handle;
166 	width = creq.width;
167 	height = creq.height;
168 	pitch = creq.pitch;
169 	size = creq.size;
170 
171 	drmModeAddFB(fd, width, height, 24, 32, pitch, handle, &fb_id);
172 
173 	struct drm_mode_map_dumb mreq;
174 	memset(&mreq, 0, sizeof(struct drm_mode_map_dumb));
175 	mreq.handle = handle;
176 	drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
177 
178 	fb_buffer = static_cast<uint8_t *>(mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, mreq.offset));
179 }
180 
destroySurface(const VkAllocationCallbacks * pAllocator)181 void DisplaySurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
182 {
183 	munmap(fb_buffer, size);
184 
185 	drmModeRmFB(fd, fb_id);
186 
187 	struct drm_mode_destroy_dumb dreq;
188 	memset(&dreq, 0, sizeof(struct drm_mode_destroy_dumb));
189 	dreq.handle = handle;
190 	drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
191 
192 	drmModeSetCrtc(fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &connector_id, 1, &crtc->mode);
193 	drmModeFreeCrtc(crtc);
194 
195 	close(fd);
196 }
197 
ComputeRequiredAllocationSize(const VkDisplaySurfaceCreateInfoKHR * pCreateInfo)198 size_t DisplaySurfaceKHR::ComputeRequiredAllocationSize(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo)
199 {
200 	return 0;
201 }
202 
getSurfaceCapabilities(VkSurfaceCapabilitiesKHR * pSurfaceCapabilities) const203 VkResult DisplaySurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
204 {
205 	setCommonSurfaceCapabilities(pSurfaceCapabilities);
206 
207 	VkExtent2D extent = { width, height };
208 
209 	pSurfaceCapabilities->currentExtent = extent;
210 	pSurfaceCapabilities->minImageExtent = extent;
211 	pSurfaceCapabilities->maxImageExtent = extent;
212 	return VK_SUCCESS;
213 }
214 
attachImage(PresentImage * image)215 void DisplaySurfaceKHR::attachImage(PresentImage *image)
216 {
217 }
218 
detachImage(PresentImage * image)219 void DisplaySurfaceKHR::detachImage(PresentImage *image)
220 {
221 }
222 
present(PresentImage * image)223 VkResult DisplaySurfaceKHR::present(PresentImage *image)
224 {
225 	image->getImage()->copyTo(fb_buffer, pitch);
226 	drmModeSetCrtc(fd, crtc_id, fb_id, 0, 0, &connector_id, 1, &mode_info);
227 
228 	return VK_SUCCESS;
229 }
230 
231 }  // namespace vk
232