28fc5cb74ac631be98a33c3b965866c2eede13ee
[platform/core/uifw/vulkan-wsi-tizen.git] / wsi / tizen / surface_properties.cpp
1 /*
2  * Copyright (c) 2017-2019, 2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 extern "C" {
26 #include <wayland-client.h>
27 #include <linux-dmabuf-unstable-v1-client-protocol.h>
28 }
29
30 #include <cassert>
31 #include <cstdlib>
32 #include <algorithm>
33 #include <array>
34 #include <string.h>
35 #include "surface_properties.hpp"
36 #include "layer/private_data.hpp"
37
38 #define NELEMS(x) (sizeof(x) / sizeof(x[0]))
39
40 namespace wsi
41 {
42 namespace tizen
43 {
44
45 surface_properties &surface_properties::get_instance()
46 {
47    static surface_properties instance;
48    return instance;
49 }
50
51 VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
52                                                       VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
53 {
54    /* Image count limits */
55    pSurfaceCapabilities->minImageCount = 2;
56    /* There is no maximum theoretically speaking */
57    pSurfaceCapabilities->maxImageCount = UINT32_MAX;
58
59    /* Surface extents */
60    pSurfaceCapabilities->currentExtent = { 0xffffffff, 0xffffffff };
61    pSurfaceCapabilities->minImageExtent = { 1, 1 };
62
63    /* TODO: Ask the device for max - for now setting the max from the GPU, may be ask the display somehow*/
64    VkPhysicalDeviceProperties dev_props;
65    layer::instance_private_data::get(physical_device).disp.GetPhysicalDeviceProperties(physical_device, &dev_props);
66
67    pSurfaceCapabilities->maxImageExtent = { dev_props.limits.maxImageDimension2D,
68                                             dev_props.limits.maxImageDimension2D };
69    pSurfaceCapabilities->maxImageArrayLayers = 1;
70
71    /* Surface transforms */
72    pSurfaceCapabilities->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
73    pSurfaceCapabilities->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
74
75    /* TODO: Composite alpha */
76    pSurfaceCapabilities->supportedCompositeAlpha = static_cast<VkCompositeAlphaFlagBitsKHR>(
77       VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR | VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
78       VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR | VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR);
79
80    /* Image usage flags */
81    pSurfaceCapabilities->supportedUsageFlags =
82       VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
83       VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
84
85    return VK_SUCCESS;
86 }
87
88 VkResult surface_properties::get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
89                                                  uint32_t *surfaceFormatCount, VkSurfaceFormatKHR *surfaceFormats)
90 {
91
92    VkResult res = VK_SUCCESS;
93    /* TODO: Hardcoding a list of sensible formats, may be query it from compositor later. */
94    static std::array<const VkFormat, 2> formats = { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB };
95
96    assert(surfaceFormatCount != nullptr);
97    res = VK_SUCCESS;
98    if (nullptr == surfaceFormats)
99    {
100       *surfaceFormatCount = formats.size();
101    }
102    else
103    {
104       if (formats.size() > *surfaceFormatCount)
105       {
106          res = VK_INCOMPLETE;
107       }
108
109       *surfaceFormatCount = std::min(*surfaceFormatCount, static_cast<uint32_t>(formats.size()));
110       for (uint32_t i = 0; i < *surfaceFormatCount; ++i)
111       {
112          surfaceFormats[i].format = formats[i];
113          surfaceFormats[i].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
114       }
115    }
116
117    return res;
118 }
119
120 VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
121                                                        uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes)
122 {
123
124    VkResult res = VK_SUCCESS;
125    /* TODO: Check that FIFO is okay on Wayland */
126    static std::array<const VkPresentModeKHR, 2> modes = {
127       VK_PRESENT_MODE_FIFO_KHR,
128       VK_PRESENT_MODE_MAILBOX_KHR,
129    };
130
131    assert(pPresentModeCount != nullptr);
132
133    if (nullptr == pPresentModes)
134    {
135       *pPresentModeCount = modes.size();
136    }
137    else
138    {
139       if (modes.size() > *pPresentModeCount)
140       {
141          res = VK_INCOMPLETE;
142       }
143       *pPresentModeCount = std::min(*pPresentModeCount, static_cast<uint32_t>(modes.size()));
144       for (uint32_t i = 0; i < *pPresentModeCount; ++i)
145       {
146          pPresentModes[i] = modes[i];
147       }
148    }
149
150    return res;
151 }
152
153 static const char *required_device_extensions[] = {
154    VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
155    VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
156    VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME,
157    VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
158    VK_KHR_MAINTENANCE1_EXTENSION_NAME,
159    VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
160    VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
161    VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
162    VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
163 };
164
165 static std::unique_ptr<util::extension_list> populate_device_extensions()
166 {
167    std::unique_ptr<util::extension_list> ret(new util::extension_list(util::allocator::get_generic()));
168    ret->add(required_device_extensions, NELEMS(required_device_extensions));
169
170    return ret;
171 }
172
173 const util::extension_list &surface_properties::get_required_device_extensions()
174 {
175    static std::unique_ptr<util::extension_list> device_extensions = populate_device_extensions();
176    return *device_extensions;
177 }
178
179 bool surface_properties::physical_device_supported(VkPhysicalDevice dev)
180 {
181    static util::extension_list device_extensions{util::allocator::get_generic()};
182    device_extensions.add(dev);
183
184    static util::extension_list required_extensions{util::allocator::get_generic()};
185    required_extensions.add(required_device_extensions, NELEMS(required_device_extensions));
186
187    return device_extensions.contains(required_extensions);
188 }
189
190 /* TODO: Check for zwp_linux_dmabuf_v1 protocol in display */
191 VkBool32 GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physical_device, uint32_t queue_index,
192                                                         struct wl_display *display)
193 {
194    return VK_TRUE;
195 }
196
197 PFN_vkVoidFunction surface_properties::get_proc_addr(const char *name)
198 {
199    if (strcmp(name, "vkGetPhysicalDeviceWaylandPresentationSupportKHR") == 0)
200    {
201       return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWaylandPresentationSupportKHR);
202    }
203    return nullptr;
204 }
205 } // namespace tizen
206 } // namespace wsi