vk/query.c: Use the casting functions
[mesa.git] / src / vulkan / x11.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "private.h"
25
26 #include <xcb/xcb.h>
27 #include <xcb/dri3.h>
28 #include <xcb/present.h>
29
30 static const VkFormat formats[] = {
31 VK_FORMAT_B5G6R5_UNORM,
32 VK_FORMAT_B8G8R8A8_UNORM,
33 VK_FORMAT_B8G8R8A8_SRGB,
34 };
35
36 VkResult anv_GetDisplayInfoWSI(
37 VkDisplayWSI display,
38 VkDisplayInfoTypeWSI infoType,
39 size_t* pDataSize,
40 void* pData)
41 {
42 VkDisplayFormatPropertiesWSI *properties = pData;
43 size_t size;
44
45 if (pDataSize == NULL)
46 return VK_ERROR_INVALID_POINTER;
47
48 switch (infoType) {
49 case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI:
50 size = sizeof(properties[0]) * ARRAY_SIZE(formats);
51
52 if (pData == NULL) {
53 *pDataSize = size;
54 return VK_SUCCESS;
55 }
56
57 if (*pDataSize < size)
58 return vk_error(VK_ERROR_INVALID_VALUE);
59
60 *pDataSize = size;
61
62 for (uint32_t i = 0; i < ARRAY_SIZE(formats); i++)
63 properties[i].swapChainFormat = formats[i];
64
65 return VK_SUCCESS;
66
67 default:
68 return VK_UNSUPPORTED;
69 }
70 }
71
72 struct anv_swap_chain {
73 struct anv_device * device;
74 xcb_connection_t * conn;
75 xcb_window_t window;
76 xcb_gc_t gc;
77 VkExtent2D extent;
78 uint32_t count;
79 struct {
80 struct anv_image * image;
81 struct anv_device_memory * memory;
82 xcb_pixmap_t pixmap;
83 } images[0];
84 };
85
86 VkResult anv_CreateSwapChainWSI(
87 VkDevice _device,
88 const VkSwapChainCreateInfoWSI* pCreateInfo,
89 VkSwapChainWSI* pSwapChain)
90 {
91 struct anv_device *device = (struct anv_device *) _device;
92 struct anv_swap_chain *chain;
93 xcb_void_cookie_t cookie;
94 VkResult result;
95 size_t size;
96 int ret;
97
98 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI);
99
100 size = sizeof(*chain) + pCreateInfo->imageCount * sizeof(chain->images[0]);
101 chain = anv_device_alloc(device, size, 8,
102 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
103 if (chain == NULL)
104 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
105
106 chain->device = device;
107 chain->conn = (xcb_connection_t *) pCreateInfo->pNativeWindowSystemHandle;
108 chain->window = (xcb_window_t) (uintptr_t) pCreateInfo->pNativeWindowHandle;
109 chain->count = pCreateInfo->imageCount;
110 chain->extent = pCreateInfo->imageExtent;
111
112 for (uint32_t i = 0; i < chain->count; i++) {
113 struct anv_image *image;
114 struct anv_surface *surface;
115 struct anv_device_memory *memory;
116
117 anv_image_create((VkDevice) device,
118 &(struct anv_image_create_info) {
119 .force_tile_mode = true,
120 .tile_mode = XMAJOR,
121 .vk_info =
122 &(VkImageCreateInfo) {
123 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
124 .imageType = VK_IMAGE_TYPE_2D,
125 .format = pCreateInfo->imageFormat,
126 .extent = {
127 .width = pCreateInfo->imageExtent.width,
128 .height = pCreateInfo->imageExtent.height,
129 .depth = 1
130 },
131 .mipLevels = 1,
132 .arraySize = 1,
133 .samples = 1,
134 /* FIXME: Need a way to use X tiling to allow scanout */
135 .tiling = VK_IMAGE_TILING_OPTIMAL,
136 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
137 .flags = 0,
138 }},
139 (VkImage *) &image);
140
141 surface = &image->primary_surface;
142
143 anv_AllocMemory((VkDevice) device,
144 &(VkMemoryAllocInfo) {
145 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
146 .allocationSize = image->size,
147 },
148 (VkDeviceMemory *) &memory);
149
150 anv_BindObjectMemory(VK_NULL_HANDLE,
151 VK_OBJECT_TYPE_IMAGE,
152 (VkImage) image,
153 (VkDeviceMemory) memory, 0);
154
155 ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
156 surface->stride, I915_TILING_X);
157 if (ret) {
158 result = vk_error(VK_ERROR_UNKNOWN);
159 goto fail;
160 }
161
162 int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle);
163 if (fd == -1) {
164 result = vk_error(VK_ERROR_UNKNOWN);
165 goto fail;
166 }
167
168 uint32_t bpp = 32;
169 uint32_t depth = 24;
170 xcb_pixmap_t pixmap = xcb_generate_id(chain->conn);
171
172 cookie =
173 xcb_dri3_pixmap_from_buffer_checked(chain->conn,
174 pixmap,
175 chain->window,
176 image->size,
177 pCreateInfo->imageExtent.width,
178 pCreateInfo->imageExtent.height,
179 surface->stride,
180 depth, bpp, fd);
181
182 chain->images[i].image = image;
183 chain->images[i].memory = memory;
184 chain->images[i].pixmap = pixmap;
185 image->swap_chain = chain;
186
187 xcb_discard_reply(chain->conn, cookie.sequence);
188 }
189
190 chain->gc = xcb_generate_id(chain->conn);
191 if (!chain->gc) {
192 result = vk_error(VK_ERROR_UNKNOWN);
193 goto fail;
194 }
195
196 cookie = xcb_create_gc(chain->conn,
197 chain->gc,
198 chain->window,
199 XCB_GC_GRAPHICS_EXPOSURES,
200 (uint32_t []) { 0 });
201 xcb_discard_reply(chain->conn, cookie.sequence);
202
203 *pSwapChain = (VkSwapChainWSI) chain;
204
205 return VK_SUCCESS;
206
207 fail:
208 return result;
209 }
210
211 VkResult anv_DestroySwapChainWSI(
212 VkSwapChainWSI swapChain)
213 {
214 struct anv_swap_chain *chain = (struct anv_swap_chain *) swapChain;
215 struct anv_device *device = chain->device;
216
217 anv_device_free(device, chain);
218
219 return VK_SUCCESS;
220 }
221
222 VkResult anv_GetSwapChainInfoWSI(
223 VkSwapChainWSI swapChain,
224 VkSwapChainInfoTypeWSI infoType,
225 size_t* pDataSize,
226 void* pData)
227 {
228 struct anv_swap_chain *chain = (struct anv_swap_chain *) swapChain;
229 VkSwapChainImageInfoWSI *images;
230 size_t size;
231
232 switch (infoType) {
233 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI:
234 size = sizeof(*images) * chain->count;
235 if (pData && *pDataSize < size)
236 return VK_ERROR_INVALID_VALUE;
237
238 *pDataSize = size;
239 if (!pData)
240 return VK_SUCCESS;
241
242 images = pData;
243 for (uint32_t i = 0; i < chain->count; i++) {
244 images[i].image = (VkImage) chain->images[i].image;
245 images[i].memory = (VkDeviceMemory) chain->images[i].memory;
246 }
247
248 return VK_SUCCESS;
249
250 default:
251 return VK_UNSUPPORTED;
252 }
253 }
254
255 VkResult anv_QueuePresentWSI(
256 VkQueue queue_,
257 const VkPresentInfoWSI* pPresentInfo)
258 {
259 struct anv_image *image = (struct anv_image *) pPresentInfo->image;
260 struct anv_swap_chain *chain = image->swap_chain;
261 xcb_void_cookie_t cookie;
262 xcb_pixmap_t pixmap;
263
264 assert(pPresentInfo->sType == VK_STRUCTURE_TYPE_PRESENT_INFO_WSI);
265
266 if (chain == NULL)
267 return vk_error(VK_ERROR_INVALID_VALUE);
268
269 pixmap = XCB_NONE;
270 for (uint32_t i = 0; i < chain->count; i++) {
271 if ((VkImage) chain->images[i].image == pPresentInfo->image) {
272 pixmap = chain->images[i].pixmap;
273 break;
274 }
275 }
276
277 if (pixmap == XCB_NONE)
278 return vk_error(VK_ERROR_INVALID_VALUE);
279
280 cookie = xcb_copy_area(chain->conn,
281 pixmap,
282 chain->window,
283 chain->gc,
284 0, 0,
285 0, 0,
286 chain->extent.width,
287 chain->extent.height);
288 xcb_discard_reply(chain->conn, cookie.sequence);
289
290 xcb_flush(chain->conn);
291
292 return VK_SUCCESS;
293 }