2 * Copyright © 2015 Intel Corporation
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:
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
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
26 #include <xcb/present.h>
30 static const VkFormat formats
[] = {
31 VK_FORMAT_B5G6R5_UNORM
,
32 VK_FORMAT_B8G8R8A8_UNORM
,
33 VK_FORMAT_B8G8R8A8_SRGB
,
36 static const VkSurfacePresentModePropertiesWSI present_modes
[] = {
37 { VK_PRESENT_MODE_MAILBOX_WSI
},
41 x11_get_window_supported(struct anv_wsi_implementation
*impl
,
42 struct anv_physical_device
*physical_device
,
43 const VkSurfaceDescriptionWindowWSI
*window
,
47 stub_return(VK_SUCCESS
);
51 x11_get_surface_info(struct anv_wsi_implementation
*impl
,
52 struct anv_device
*device
,
53 VkSurfaceDescriptionWindowWSI
*window
,
54 VkSurfaceInfoTypeWSI infoType
,
55 size_t* pDataSize
, void* pData
)
57 if (pDataSize
== NULL
)
58 return vk_error(VK_ERROR_INVALID_POINTER
);
61 case VK_SURFACE_INFO_TYPE_PROPERTIES_WSI
: {
62 VkSurfacePropertiesWSI
*props
= pData
;
65 *pDataSize
= sizeof(*props
);
69 assert(*pDataSize
>= sizeof(*props
));
71 props
->minImageCount
= 2;
72 props
->maxImageCount
= 4;
73 props
->currentExtent
= (VkExtent2D
) { -1, -1 };
74 props
->minImageExtent
= (VkExtent2D
) { 1, 1 };
75 props
->maxImageExtent
= (VkExtent2D
) { INT16_MAX
, INT16_MAX
};
76 props
->supportedTransforms
= VK_SURFACE_TRANSFORM_NONE_BIT_WSI
;
77 props
->currentTransform
= VK_SURFACE_TRANSFORM_NONE_WSI
;
78 props
->maxImageArraySize
= 1;
79 props
->supportedUsageFlags
=
80 VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT
|
81 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
;
86 case VK_SURFACE_INFO_TYPE_FORMATS_WSI
:
88 *pDataSize
= sizeof(formats
);
92 assert(*pDataSize
>= sizeof(formats
));
93 memcpy(pData
, formats
, *pDataSize
);
97 case VK_SURFACE_INFO_TYPE_PRESENT_MODES_WSI
:
99 *pDataSize
= sizeof(present_modes
);
103 assert(*pDataSize
>= sizeof(present_modes
));
104 memcpy(pData
, present_modes
, *pDataSize
);
108 return vk_error(VK_ERROR_INVALID_VALUE
);
112 struct x11_swap_chain
{
113 struct anv_swap_chain base
;
115 xcb_connection_t
* conn
;
119 uint32_t image_count
;
122 struct anv_image
* image
;
123 struct anv_device_memory
* memory
;
129 x11_get_swap_chain_info(struct anv_swap_chain
*anv_chain
,
130 VkSwapChainInfoTypeWSI infoType
,
131 size_t* pDataSize
, void* pData
)
133 struct x11_swap_chain
*chain
= (struct x11_swap_chain
*)anv_chain
;
137 case VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI
: {
138 VkSwapChainImagePropertiesWSI
*images
= pData
;
140 size
= chain
->image_count
* sizeof(*images
);
147 assert(size
<= *pDataSize
);
148 for (uint32_t i
= 0; i
< chain
->image_count
; i
++)
149 images
[i
].image
= anv_image_to_handle(chain
->images
[i
].image
);
157 return vk_error(VK_ERROR_INVALID_VALUE
);
162 x11_acquire_next_image(struct anv_swap_chain
*anv_chain
,
164 VkSemaphore semaphore
,
165 uint32_t *image_index
)
167 struct x11_swap_chain
*chain
= (struct x11_swap_chain
*)anv_chain
;
169 anv_finishme("Implement real blocking AcquireNextImage");
170 *image_index
= chain
->next_image
;
171 chain
->next_image
= (chain
->next_image
+ 1) % chain
->image_count
;
176 x11_queue_present(struct anv_swap_chain
*anv_chain
,
177 struct anv_queue
*queue
,
178 uint32_t image_index
)
180 struct x11_swap_chain
*chain
= (struct x11_swap_chain
*)anv_chain
;
182 xcb_void_cookie_t cookie
;
184 xcb_pixmap_t pixmap
= chain
->images
[image_index
].pixmap
;
186 if (pixmap
== XCB_NONE
)
187 return vk_error(VK_ERROR_INVALID_VALUE
);
189 cookie
= xcb_copy_area(chain
->conn
,
196 chain
->extent
.height
);
197 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
199 xcb_flush(chain
->conn
);
205 x11_destroy_swap_chain(struct anv_swap_chain
*chain
)
207 anv_device_free(chain
->device
, chain
);
213 x11_create_swap_chain(struct anv_wsi_implementation
*impl
,
214 struct anv_device
*device
,
215 const VkSwapChainCreateInfoWSI
*pCreateInfo
,
216 struct anv_swap_chain
**swap_chain_out
)
218 struct x11_swap_chain
*chain
;
219 xcb_void_cookie_t cookie
;
222 assert(pCreateInfo
->pSurfaceDescription
->sType
==
223 VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_WSI
);
224 VkSurfaceDescriptionWindowWSI
*vk_window
=
225 (VkSurfaceDescriptionWindowWSI
*)pCreateInfo
->pSurfaceDescription
;
226 assert(vk_window
->platform
== VK_PLATFORM_XCB_WSI
);
228 int num_images
= pCreateInfo
->minImageCount
;
230 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI
);
232 size_t size
= sizeof(*chain
) + num_images
* sizeof(chain
->images
[0]);
233 chain
= anv_device_alloc(device
, size
, 8,
234 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
236 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
238 chain
->base
.device
= device
;
239 chain
->base
.destroy
= x11_destroy_swap_chain
;
240 chain
->base
.get_swap_chain_info
= x11_get_swap_chain_info
;
241 chain
->base
.acquire_next_image
= x11_acquire_next_image
;
242 chain
->base
.queue_present
= x11_queue_present
;
244 VkPlatformHandleXcbWSI
*vk_xcb_handle
= vk_window
->pPlatformHandle
;
246 chain
->conn
= (xcb_connection_t
*) vk_xcb_handle
->connection
;
247 chain
->window
= (xcb_window_t
) (uintptr_t)vk_window
->pPlatformWindow
;
248 chain
->extent
= pCreateInfo
->imageExtent
;
249 chain
->image_count
= num_images
;
250 chain
->next_image
= 0;
252 for (uint32_t i
= 0; i
< chain
->image_count
; i
++) {
253 VkDeviceMemory memory_h
;
255 struct anv_image
*image
;
256 struct anv_surface
*surface
;
257 struct anv_device_memory
*memory
;
259 anv_image_create(anv_device_to_handle(device
),
260 &(struct anv_image_create_info
) {
261 .force_tile_mode
= true,
265 &(VkImageCreateInfo
) {
266 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
267 .imageType
= VK_IMAGE_TYPE_2D
,
268 .format
= pCreateInfo
->imageFormat
,
270 .width
= pCreateInfo
->imageExtent
.width
,
271 .height
= pCreateInfo
->imageExtent
.height
,
277 /* FIXME: Need a way to use X tiling to allow scanout */
278 .tiling
= VK_IMAGE_TILING_OPTIMAL
,
279 .usage
= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
,
284 image
= anv_image_from_handle(image_h
);
285 assert(anv_format_is_color(image
->format
));
287 surface
= &image
->color_surface
;
289 anv_AllocMemory(anv_device_to_handle(device
),
290 &(VkMemoryAllocInfo
) {
291 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
,
292 .allocationSize
= image
->size
,
293 .memoryTypeIndex
= 0,
297 memory
= anv_device_memory_from_handle(memory_h
);
299 anv_BindImageMemory(VK_NULL_HANDLE
, anv_image_to_handle(image
),
302 int ret
= anv_gem_set_tiling(device
, memory
->bo
.gem_handle
,
303 surface
->stride
, I915_TILING_X
);
305 result
= vk_errorf(VK_ERROR_UNKNOWN
, "set_tiling failed: %m");
309 int fd
= anv_gem_handle_to_fd(device
, memory
->bo
.gem_handle
);
311 result
= vk_errorf(VK_ERROR_UNKNOWN
, "handle_to_fd failed: %m");
317 xcb_pixmap_t pixmap
= xcb_generate_id(chain
->conn
);
320 xcb_dri3_pixmap_from_buffer_checked(chain
->conn
,
324 pCreateInfo
->imageExtent
.width
,
325 pCreateInfo
->imageExtent
.height
,
329 chain
->images
[i
].image
= image
;
330 chain
->images
[i
].memory
= memory
;
331 chain
->images
[i
].pixmap
= pixmap
;
333 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
336 chain
->gc
= xcb_generate_id(chain
->conn
);
338 result
= vk_error(VK_ERROR_UNKNOWN
);
342 cookie
= xcb_create_gc(chain
->conn
,
345 XCB_GC_GRAPHICS_EXPOSURES
,
346 (uint32_t []) { 0 });
347 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
349 *swap_chain_out
= &chain
->base
;
358 anv_x11_init_wsi(struct anv_instance
*instance
)
360 struct anv_wsi_implementation
*impl
;
362 impl
= anv_instance_alloc(instance
, sizeof(*impl
), 8,
363 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
365 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
367 impl
->get_window_supported
= x11_get_window_supported
;
368 impl
->get_surface_info
= x11_get_surface_info
;
369 impl
->create_swap_chain
= x11_create_swap_chain
;
371 instance
->wsi_impl
[VK_PLATFORM_XCB_WSI
] = impl
;
377 anv_x11_finish_wsi(struct anv_instance
*instance
)
379 anv_instance_free(instance
, instance
->wsi_impl
[VK_PLATFORM_XCB_WSI
]);