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
);
51 if (pData
&& *pDataSize
< size
)
52 return vk_error(VK_ERROR_INVALID_VALUE
);
55 for (uint32_t i
= 0; i
< ARRAY_SIZE(formats
); i
++)
56 properties
[i
].swapChainFormat
= formats
[i
];
61 return VK_UNSUPPORTED
;
65 struct anv_swap_chain
{
66 struct anv_device
* device
;
67 xcb_connection_t
* conn
;
73 struct anv_image
* image
;
74 struct anv_device_memory
* memory
;
79 VkResult
anv_CreateSwapChainWSI(
81 const VkSwapChainCreateInfoWSI
* pCreateInfo
,
82 VkSwapChainWSI
* pSwapChain
)
84 struct anv_device
*device
= (struct anv_device
*) _device
;
85 struct anv_swap_chain
*chain
;
86 xcb_void_cookie_t cookie
;
91 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI
);
93 size
= sizeof(*chain
) + pCreateInfo
->imageCount
* sizeof(chain
->images
[0]);
94 chain
= anv_device_alloc(device
, size
, 8,
95 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
97 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
99 chain
->device
= device
;
100 chain
->conn
= (xcb_connection_t
*) pCreateInfo
->pNativeWindowSystemHandle
;
101 chain
->window
= (xcb_window_t
) (uintptr_t) pCreateInfo
->pNativeWindowHandle
;
102 chain
->count
= pCreateInfo
->imageCount
;
103 chain
->extent
= pCreateInfo
->imageExtent
;
105 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
106 struct anv_image
*image
;
107 struct anv_device_memory
*memory
;
109 anv_image_create((VkDevice
) device
,
110 &(VkImageCreateInfo
) {
111 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
112 .imageType
= VK_IMAGE_TYPE_2D
,
113 .format
= pCreateInfo
->imageFormat
,
115 .width
= pCreateInfo
->imageExtent
.width
,
116 .height
= pCreateInfo
->imageExtent
.height
,
122 /* FIXME: Need a way to use X tiling to allow scanout */
123 .tiling
= VK_IMAGE_TILING_OPTIMAL
,
124 .usage
= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
,
127 &(struct anv_image_create_info
) {
132 anv_AllocMemory((VkDevice
) device
,
133 &(VkMemoryAllocInfo
) {
134 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
,
135 .allocationSize
= image
->size
,
137 (VkDeviceMemory
*) &memory
);
139 anv_QueueBindObjectMemory(VK_NULL_HANDLE
,
140 VK_OBJECT_TYPE_IMAGE
,
142 (VkDeviceMemory
) memory
, 0);
144 ret
= anv_gem_set_tiling(device
, memory
->bo
.gem_handle
,
145 image
->stride
, I915_TILING_X
);
147 result
= vk_error(VK_ERROR_UNKNOWN
);
151 int fd
= anv_gem_handle_to_fd(device
, memory
->bo
.gem_handle
);
153 result
= vk_error(VK_ERROR_UNKNOWN
);
159 xcb_pixmap_t pixmap
= xcb_generate_id(chain
->conn
);
162 xcb_dri3_pixmap_from_buffer_checked(chain
->conn
,
166 pCreateInfo
->imageExtent
.width
,
167 pCreateInfo
->imageExtent
.height
,
171 chain
->images
[i
].image
= image
;
172 chain
->images
[i
].memory
= memory
;
173 chain
->images
[i
].pixmap
= pixmap
;
174 image
->swap_chain
= chain
;
176 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
179 chain
->gc
= xcb_generate_id(chain
->conn
);
181 result
= vk_error(VK_ERROR_UNKNOWN
);
185 cookie
= xcb_create_gc(chain
->conn
,
188 XCB_GC_GRAPHICS_EXPOSURES
,
189 (uint32_t []) { 0 });
190 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
192 *pSwapChain
= (VkSwapChainWSI
) chain
;
200 VkResult
anv_DestroySwapChainWSI(
201 VkSwapChainWSI swapChain
)
203 struct anv_swap_chain
*chain
= (struct anv_swap_chain
*) swapChain
;
204 struct anv_device
*device
= chain
->device
;
206 anv_device_free(device
, chain
);
211 VkResult
anv_GetSwapChainInfoWSI(
212 VkSwapChainWSI swapChain
,
213 VkSwapChainInfoTypeWSI infoType
,
217 struct anv_swap_chain
*chain
= (struct anv_swap_chain
*) swapChain
;
218 VkSwapChainImageInfoWSI
*images
;
222 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI
:
223 size
= sizeof(*images
) * chain
->count
;
224 if (pData
&& *pDataSize
< size
)
225 return VK_ERROR_INVALID_VALUE
;
232 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
233 images
[i
].image
= (VkImage
) chain
->images
[i
].image
;
234 images
[i
].memory
= (VkDeviceMemory
) chain
->images
[i
].memory
;
240 return VK_UNSUPPORTED
;
244 VkResult
anv_QueuePresentWSI(
246 const VkPresentInfoWSI
* pPresentInfo
)
248 struct anv_image
*image
= (struct anv_image
*) pPresentInfo
->image
;
249 struct anv_swap_chain
*chain
= image
->swap_chain
;
250 xcb_void_cookie_t cookie
;
253 assert(pPresentInfo
->sType
== VK_STRUCTURE_TYPE_PRESENT_INFO_WSI
);
256 return vk_error(VK_ERROR_INVALID_VALUE
);
259 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
260 if ((VkImage
) chain
->images
[i
].image
== pPresentInfo
->image
) {
261 pixmap
= chain
->images
[i
].pixmap
;
266 if (pixmap
== XCB_NONE
)
267 return vk_error(VK_ERROR_INVALID_VALUE
);
269 cookie
= xcb_copy_area(chain
->conn
,
276 chain
->extent
.height
);
277 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
279 xcb_flush(chain
->conn
);