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
24 #include "anv_private.h"
28 #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 VkResult
anv_GetDisplayInfoWSI(
38 VkDisplayInfoTypeWSI infoType
,
42 VkDisplayFormatPropertiesWSI
*properties
= pData
;
45 if (pDataSize
== NULL
)
46 return VK_ERROR_INVALID_POINTER
;
49 case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI
:
50 size
= sizeof(properties
[0]) * ARRAY_SIZE(formats
);
57 if (*pDataSize
< size
)
58 return vk_error(VK_ERROR_INVALID_VALUE
);
62 for (uint32_t i
= 0; i
< ARRAY_SIZE(formats
); i
++)
63 properties
[i
].swapChainFormat
= formats
[i
];
68 return VK_UNSUPPORTED
;
72 struct anv_swap_chain
{
73 struct anv_device
* device
;
74 xcb_connection_t
* conn
;
80 struct anv_image
* image
;
81 struct anv_device_memory
* memory
;
86 VkResult
anv_CreateSwapChainWSI(
88 const VkSwapChainCreateInfoWSI
* pCreateInfo
,
89 VkSwapChainWSI
* pSwapChain
)
91 ANV_FROM_HANDLE(anv_device
, device
, _device
);
93 struct anv_swap_chain
*chain
;
94 xcb_void_cookie_t cookie
;
99 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI
);
101 size
= sizeof(*chain
) + pCreateInfo
->imageCount
* sizeof(chain
->images
[0]);
102 chain
= anv_device_alloc(device
, size
, 8,
103 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
105 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
107 chain
->device
= device
;
108 chain
->conn
= (xcb_connection_t
*) pCreateInfo
->pNativeWindowSystemHandle
;
109 chain
->window
= (xcb_window_t
) (uintptr_t) pCreateInfo
->pNativeWindowHandle
;
110 chain
->count
= pCreateInfo
->imageCount
;
111 chain
->extent
= pCreateInfo
->imageExtent
;
113 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
114 VkDeviceMemory memory_h
;
116 struct anv_image
*image
;
117 struct anv_surface
*surface
;
118 struct anv_device_memory
*memory
;
120 anv_image_create(_device
,
121 &(struct anv_image_create_info
) {
122 .force_tile_mode
= true,
126 &(VkImageCreateInfo
) {
127 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
128 .imageType
= VK_IMAGE_TYPE_2D
,
129 .format
= pCreateInfo
->imageFormat
,
131 .width
= pCreateInfo
->imageExtent
.width
,
132 .height
= pCreateInfo
->imageExtent
.height
,
138 /* FIXME: Need a way to use X tiling to allow scanout */
139 .tiling
= VK_IMAGE_TILING_OPTIMAL
,
140 .usage
= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
,
145 image
= anv_image_from_handle(image_h
);
146 assert(anv_format_is_color(image
->format
));
148 surface
= &image
->color_surface
;
150 anv_AllocMemory(_device
,
151 &(VkMemoryAllocInfo
) {
152 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
,
153 .allocationSize
= image
->size
,
154 .memoryTypeIndex
= 0,
158 memory
= anv_device_memory_from_handle(memory_h
);
160 anv_BindImageMemory(VK_NULL_HANDLE
, anv_image_to_handle(image
),
163 ret
= anv_gem_set_tiling(device
, memory
->bo
.gem_handle
,
164 surface
->stride
, I915_TILING_X
);
166 result
= vk_errorf(VK_ERROR_UNKNOWN
, "set_tiling failed: %m");
170 int fd
= anv_gem_handle_to_fd(device
, memory
->bo
.gem_handle
);
172 result
= vk_errorf(VK_ERROR_UNKNOWN
, "handle_to_fd failed: %m");
178 xcb_pixmap_t pixmap
= xcb_generate_id(chain
->conn
);
181 xcb_dri3_pixmap_from_buffer_checked(chain
->conn
,
185 pCreateInfo
->imageExtent
.width
,
186 pCreateInfo
->imageExtent
.height
,
190 chain
->images
[i
].image
= image
;
191 chain
->images
[i
].memory
= memory
;
192 chain
->images
[i
].pixmap
= pixmap
;
193 image
->swap_chain
= chain
;
195 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
198 chain
->gc
= xcb_generate_id(chain
->conn
);
200 result
= vk_error(VK_ERROR_UNKNOWN
);
204 cookie
= xcb_create_gc(chain
->conn
,
207 XCB_GC_GRAPHICS_EXPOSURES
,
208 (uint32_t []) { 0 });
209 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
211 *pSwapChain
= anv_swap_chain_to_handle(chain
);
219 VkResult
anv_DestroySwapChainWSI(
220 VkSwapChainWSI _chain
)
222 ANV_FROM_HANDLE(anv_swap_chain
, chain
, _chain
);
224 anv_device_free(chain
->device
, chain
);
229 VkResult
anv_GetSwapChainInfoWSI(
230 VkSwapChainWSI _chain
,
231 VkSwapChainInfoTypeWSI infoType
,
235 ANV_FROM_HANDLE(anv_swap_chain
, chain
, _chain
);
237 VkSwapChainImageInfoWSI
*images
;
241 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI
:
242 size
= sizeof(*images
) * chain
->count
;
243 if (pData
&& *pDataSize
< size
)
244 return VK_ERROR_INVALID_VALUE
;
251 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
252 images
[i
].image
= anv_image_to_handle(chain
->images
[i
].image
);
253 images
[i
].memory
= anv_device_memory_to_handle(chain
->images
[i
].memory
);
259 return VK_UNSUPPORTED
;
263 VkResult
anv_QueuePresentWSI(
265 const VkPresentInfoWSI
* pPresentInfo
)
267 ANV_FROM_HANDLE(anv_image
, image
, pPresentInfo
->image
);
269 struct anv_swap_chain
*chain
= image
->swap_chain
;
270 xcb_void_cookie_t cookie
;
273 assert(pPresentInfo
->sType
== VK_STRUCTURE_TYPE_PRESENT_INFO_WSI
);
276 return vk_error(VK_ERROR_INVALID_VALUE
);
279 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
280 if (image
== chain
->images
[i
].image
) {
281 pixmap
= chain
->images
[i
].pixmap
;
286 if (pixmap
== XCB_NONE
)
287 return vk_error(VK_ERROR_INVALID_VALUE
);
289 cookie
= xcb_copy_area(chain
->conn
,
296 chain
->extent
.height
);
297 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
299 xcb_flush(chain
->conn
);