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 struct anv_device
*device
= (struct anv_device
*) _device
;
92 struct anv_swap_chain
*chain
;
93 xcb_void_cookie_t cookie
;
98 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI
);
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
);
104 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
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
;
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
;
117 anv_image_create((VkDevice
) device
,
118 &(struct anv_image_create_info
) {
119 .force_tile_mode
= true,
122 &(VkImageCreateInfo
) {
123 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
124 .imageType
= VK_IMAGE_TYPE_2D
,
125 .format
= pCreateInfo
->imageFormat
,
127 .width
= pCreateInfo
->imageExtent
.width
,
128 .height
= pCreateInfo
->imageExtent
.height
,
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
,
141 surface
= &image
->primary_surface
;
143 anv_AllocMemory((VkDevice
) device
,
144 &(VkMemoryAllocInfo
) {
145 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
,
146 .allocationSize
= image
->size
,
148 (VkDeviceMemory
*) &memory
);
150 anv_QueueBindObjectMemory(VK_NULL_HANDLE
,
151 VK_OBJECT_TYPE_IMAGE
,
153 (VkDeviceMemory
) memory
, 0);
155 ret
= anv_gem_set_tiling(device
, memory
->bo
.gem_handle
,
156 surface
->stride
, I915_TILING_X
);
158 result
= vk_error(VK_ERROR_UNKNOWN
);
162 int fd
= anv_gem_handle_to_fd(device
, memory
->bo
.gem_handle
);
164 result
= vk_error(VK_ERROR_UNKNOWN
);
170 xcb_pixmap_t pixmap
= xcb_generate_id(chain
->conn
);
173 xcb_dri3_pixmap_from_buffer_checked(chain
->conn
,
177 pCreateInfo
->imageExtent
.width
,
178 pCreateInfo
->imageExtent
.height
,
182 chain
->images
[i
].image
= image
;
183 chain
->images
[i
].memory
= memory
;
184 chain
->images
[i
].pixmap
= pixmap
;
185 image
->swap_chain
= chain
;
187 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
190 chain
->gc
= xcb_generate_id(chain
->conn
);
192 result
= vk_error(VK_ERROR_UNKNOWN
);
196 cookie
= xcb_create_gc(chain
->conn
,
199 XCB_GC_GRAPHICS_EXPOSURES
,
200 (uint32_t []) { 0 });
201 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
203 *pSwapChain
= (VkSwapChainWSI
) chain
;
211 VkResult
anv_DestroySwapChainWSI(
212 VkSwapChainWSI swapChain
)
214 struct anv_swap_chain
*chain
= (struct anv_swap_chain
*) swapChain
;
215 struct anv_device
*device
= chain
->device
;
217 anv_device_free(device
, chain
);
222 VkResult
anv_GetSwapChainInfoWSI(
223 VkSwapChainWSI swapChain
,
224 VkSwapChainInfoTypeWSI infoType
,
228 struct anv_swap_chain
*chain
= (struct anv_swap_chain
*) swapChain
;
229 VkSwapChainImageInfoWSI
*images
;
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
;
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
;
251 return VK_UNSUPPORTED
;
255 VkResult
anv_QueuePresentWSI(
257 const VkPresentInfoWSI
* pPresentInfo
)
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
;
264 assert(pPresentInfo
->sType
== VK_STRUCTURE_TYPE_PRESENT_INFO_WSI
);
267 return vk_error(VK_ERROR_INVALID_VALUE
);
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
;
277 if (pixmap
== XCB_NONE
)
278 return vk_error(VK_ERROR_INVALID_VALUE
);
280 cookie
= xcb_copy_area(chain
->conn
,
287 chain
->extent
.height
);
288 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
290 xcb_flush(chain
->conn
);