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
,
147 .memoryTypeIndex
= 0,
149 (VkDeviceMemory
*) &memory
);
151 anv_BindObjectMemory(VK_NULL_HANDLE
,
152 VK_OBJECT_TYPE_IMAGE
,
154 (VkDeviceMemory
) memory
, 0);
156 ret
= anv_gem_set_tiling(device
, memory
->bo
.gem_handle
,
157 surface
->stride
, I915_TILING_X
);
159 result
= vk_error(VK_ERROR_UNKNOWN
);
163 int fd
= anv_gem_handle_to_fd(device
, memory
->bo
.gem_handle
);
165 result
= vk_error(VK_ERROR_UNKNOWN
);
171 xcb_pixmap_t pixmap
= xcb_generate_id(chain
->conn
);
174 xcb_dri3_pixmap_from_buffer_checked(chain
->conn
,
178 pCreateInfo
->imageExtent
.width
,
179 pCreateInfo
->imageExtent
.height
,
183 chain
->images
[i
].image
= image
;
184 chain
->images
[i
].memory
= memory
;
185 chain
->images
[i
].pixmap
= pixmap
;
186 image
->swap_chain
= chain
;
188 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
191 chain
->gc
= xcb_generate_id(chain
->conn
);
193 result
= vk_error(VK_ERROR_UNKNOWN
);
197 cookie
= xcb_create_gc(chain
->conn
,
200 XCB_GC_GRAPHICS_EXPOSURES
,
201 (uint32_t []) { 0 });
202 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
204 *pSwapChain
= (VkSwapChainWSI
) chain
;
212 VkResult
anv_DestroySwapChainWSI(
213 VkSwapChainWSI swapChain
)
215 struct anv_swap_chain
*chain
= (struct anv_swap_chain
*) swapChain
;
216 struct anv_device
*device
= chain
->device
;
218 anv_device_free(device
, chain
);
223 VkResult
anv_GetSwapChainInfoWSI(
224 VkSwapChainWSI swapChain
,
225 VkSwapChainInfoTypeWSI infoType
,
229 struct anv_swap_chain
*chain
= (struct anv_swap_chain
*) swapChain
;
230 VkSwapChainImageInfoWSI
*images
;
234 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI
:
235 size
= sizeof(*images
) * chain
->count
;
236 if (pData
&& *pDataSize
< size
)
237 return VK_ERROR_INVALID_VALUE
;
244 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
245 images
[i
].image
= (VkImage
) chain
->images
[i
].image
;
246 images
[i
].memory
= (VkDeviceMemory
) chain
->images
[i
].memory
;
252 return VK_UNSUPPORTED
;
256 VkResult
anv_QueuePresentWSI(
258 const VkPresentInfoWSI
* pPresentInfo
)
260 struct anv_image
*image
= (struct anv_image
*) pPresentInfo
->image
;
261 struct anv_swap_chain
*chain
= image
->swap_chain
;
262 xcb_void_cookie_t cookie
;
265 assert(pPresentInfo
->sType
== VK_STRUCTURE_TYPE_PRESENT_INFO_WSI
);
268 return vk_error(VK_ERROR_INVALID_VALUE
);
271 for (uint32_t i
= 0; i
< chain
->count
; i
++) {
272 if ((VkImage
) chain
->images
[i
].image
== pPresentInfo
->image
) {
273 pixmap
= chain
->images
[i
].pixmap
;
278 if (pixmap
== XCB_NONE
)
279 return vk_error(VK_ERROR_INVALID_VALUE
);
281 cookie
= xcb_copy_area(chain
->conn
,
288 chain
->extent
.height
);
289 xcb_discard_reply(chain
->conn
, cookie
.sequence
);
291 xcb_flush(chain
->conn
);