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
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,
125 &(VkImageCreateInfo
) {
126 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
127 .imageType
= VK_IMAGE_TYPE_2D
,
128 .format
= pCreateInfo
->imageFormat
,
130 .width
= pCreateInfo
->imageExtent
.width
,
131 .height
= pCreateInfo
->imageExtent
.height
,
137 /* FIXME: Need a way to use X tiling to allow scanout */
138 .tiling
= VK_IMAGE_TILING_OPTIMAL
,
139 .usage
= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
,
144 image
= anv_image_from_handle(image_h
);
145 surface
= &image
->primary_surface
;
147 anv_AllocMemory(_device
,
148 &(VkMemoryAllocInfo
) {
149 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
,
150 .allocationSize
= image
->size
,
151 .memoryTypeIndex
= 0,
155 memory
= anv_device_memory_from_handle(memory_h
);
157 anv_BindImageMemory(VK_NULL_HANDLE
, anv_image_to_handle(image
),
160 ret
= anv_gem_set_tiling(device
, memory
->bo
.gem_handle
,
161 surface
->stride
, I915_TILING_X
);
163 result
= vk_error(VK_ERROR_UNKNOWN
);
167 int fd
= anv_gem_handle_to_fd(device
, memory
->bo
.gem_handle
);
169 result
= vk_error(VK_ERROR_UNKNOWN
);
175 xcb_pixmap_t pixmap
= xcb_generate_id(chain
->conn
);
178 xcb_dri3_pixmap_from_buffer_checked(chain
->conn
,
182 pCreateInfo
->imageExtent
.width
,
183 pCreateInfo
->imageExtent
.height
,
187 chain
->images
[i
].image
= image
;
188 chain
->images
[i
].memory
= memory
;
189 chain
->images
[i
].pixmap
= pixmap
;
190 image
->swap_chain
= chain
;
192 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
195 chain
->gc
= xcb_generate_id(chain
->conn
);
197 result
= vk_error(VK_ERROR_UNKNOWN
);
201 cookie
= xcb_create_gc(chain
->conn
,
204 XCB_GC_GRAPHICS_EXPOSURES
,
205 (uint32_t []) { 0 });
206 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
208 *pSwapChain
= anv_swap_chain_to_handle(chain
);
216 VkResult
anv_DestroySwapChainWSI(
217 VkSwapChainWSI _chain
)
219 ANV_FROM_HANDLE(anv_swap_chain
, chain
, _chain
);
221 anv_device_free(chain
->device
, chain
);
226 VkResult
anv_GetSwapChainInfoWSI(
227 VkSwapChainWSI _chain
,
228 VkSwapChainInfoTypeWSI infoType
,
232 ANV_FROM_HANDLE(anv_swap_chain
, chain
, _chain
);
234 VkSwapChainImageInfoWSI
*images
;
238 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI
:
239 size
= sizeof(*images
) * chain
->count
;
240 if (pData
&& *pDataSize
< size
)
241 return VK_ERROR_INVALID_VALUE
;
248 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
249 images
[i
].image
= anv_image_to_handle(chain
->images
[i
].image
);
250 images
[i
].memory
= anv_device_memory_to_handle(chain
->images
[i
].memory
);
256 return VK_UNSUPPORTED
;
260 VkResult
anv_QueuePresentWSI(
262 const VkPresentInfoWSI
* pPresentInfo
)
264 ANV_FROM_HANDLE(anv_image
, image
, pPresentInfo
->image
);
266 struct anv_swap_chain
*chain
= image
->swap_chain
;
267 xcb_void_cookie_t cookie
;
270 assert(pPresentInfo
->sType
== VK_STRUCTURE_TYPE_PRESENT_INFO_WSI
);
273 return vk_error(VK_ERROR_INVALID_VALUE
);
276 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
277 if (image
== chain
->images
[i
].image
) {
278 pixmap
= chain
->images
[i
].pixmap
;
283 if (pixmap
== XCB_NONE
)
284 return vk_error(VK_ERROR_INVALID_VALUE
);
286 cookie
= xcb_copy_area(chain
->conn
,
293 chain
->extent
.height
);
294 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
296 xcb_flush(chain
->conn
);