1 /*
2 * Copyright © 2021 Valve Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Mike Blumenkrantz <[email protected]>
25 */
26
27 #ifndef ZINK_KOPPER_H
28 #define ZINK_KOPPER_H
29
30 #include "kopper_interface.h"
31 #include "util/u_queue.h"
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 struct zink_batch_usage;
38
39 /* number of times a swapchain can be read without forcing readback mode */
40 #define ZINK_READBACK_THRESHOLD 3
41
42 struct kopper_swapchain_image {
43 bool init;
44 bool readback_needs_update;
45 bool dt_has_data;
46 int age;
47 VkImage image;
48 struct zink_resource *acquired;
49 struct pipe_resource *readback;
50 VkSemaphore acquire;
51 VkImageLayout layout;
52 };
53
54 struct kopper_swapchain {
55 struct kopper_swapchain *next;
56 VkSwapchainKHR swapchain;
57
58 unsigned last_present;
59 unsigned num_images;
60 uint32_t last_present_prune;
61 struct hash_table *presents;
62 VkSwapchainCreateInfoKHR scci;
63 unsigned num_acquires;
64 unsigned max_acquires;
65 unsigned async_presents;
66 struct util_queue_fence present_fence;
67 struct zink_batch_usage *batch_uses;
68 struct kopper_swapchain_image *images;
69 };
70
71 enum kopper_type {
72 KOPPER_X11,
73 KOPPER_WAYLAND,
74 KOPPER_WIN32
75 };
76
77 struct kopper_displaytarget
78 {
79 unsigned refcount;
80 VkFormat formats[2];
81 unsigned width;
82 unsigned height;
83 unsigned stride;
84 void *loader_private;
85
86 VkSurfaceKHR surface;
87 uint32_t present_modes; //VkPresentModeKHR bitmask
88 struct kopper_swapchain *swapchain;
89 struct kopper_swapchain *old_swapchain;
90
91 struct kopper_loader_info info;
92
93 VkSurfaceCapabilitiesKHR caps;
94 VkImageFormatListCreateInfo format_list;
95 enum kopper_type type;
96 bool is_kill;
97 VkPresentModeKHR present_mode;
98 unsigned readback_counter;
99
100 bool age_locked; //disables buffer age during readback
101 };
102
103 struct zink_kopper_present_info {
104 VkPresentInfoKHR info;
105 VkPresentRegionsKHR rinfo;
106 VkPresentRegionKHR region;
107 VkRectLayerKHR regions[64];
108 uint32_t image;
109 struct kopper_swapchain *swapchain;
110 struct zink_resource *res;
111 VkSemaphore sem;
112 bool indefinite_acquire;
113 };
114
115 struct zink_context;
116 struct zink_screen;
117 struct zink_resource;
118
119 static inline bool
zink_kopper_has_srgb(const struct kopper_displaytarget * cdt)120 zink_kopper_has_srgb(const struct kopper_displaytarget *cdt)
121 {
122 return cdt->formats[1] != VK_FORMAT_UNDEFINED;
123 }
124
125 static inline bool
zink_kopper_last_present_eq(const struct kopper_displaytarget * cdt,uint32_t idx)126 zink_kopper_last_present_eq(const struct kopper_displaytarget *cdt, uint32_t idx)
127 {
128 return cdt->swapchain->last_present == idx;
129 }
130
131 static inline bool
zink_kopper_acquired(const struct kopper_displaytarget * cdt,uint32_t idx)132 zink_kopper_acquired(const struct kopper_displaytarget *cdt, uint32_t idx)
133 {
134 return idx != UINT32_MAX && cdt->swapchain->images[idx].acquired;
135 }
136
kopper_get_zink_screen(struct pipe_screen * screen)137 static inline struct pipe_screen * kopper_get_zink_screen(struct pipe_screen *screen)
138 {
139 struct pipe_screen *pscreen = screen->get_driver_pipe_screen ?
140 screen->get_driver_pipe_screen(screen) : screen;
141 return pscreen;
142 }
143
144 void
145 zink_kopper_update_last_written(struct zink_resource *res);
146
147 struct kopper_displaytarget *
148 zink_kopper_displaytarget_create(struct zink_screen *screen, unsigned tex_usage,
149 enum pipe_format format, unsigned width,
150 unsigned height, unsigned alignment,
151 const void *loader_private, unsigned *stride);
152 void
153 zink_kopper_displaytarget_destroy(struct zink_screen *screen, struct kopper_displaytarget *cdt);
154
155
156 bool
157 zink_kopper_acquire(struct zink_context *ctx, struct zink_resource *res, uint64_t timeout);
158 VkSemaphore
159 zink_kopper_acquire_submit(struct zink_screen *screen, struct zink_resource *res);
160 VkSemaphore
161 zink_kopper_present(struct zink_screen *screen, struct zink_resource *res);
162 void
163 zink_kopper_present_queue(struct zink_screen *screen, struct zink_resource *res, unsigned nrects, struct pipe_box *boxes);
164 bool
165 zink_kopper_acquire_readback(struct zink_context *ctx, struct zink_resource *res, struct zink_resource **readback);
166 bool
167 zink_kopper_present_readback(struct zink_context *ctx, struct zink_resource *res);
168 void
169 zink_kopper_readback_update(struct zink_context *ctx, struct zink_resource *res);
170 void
171 zink_kopper_deinit_displaytarget(struct zink_screen *screen, struct kopper_displaytarget *cdt);
172 bool
173 zink_kopper_update(struct pipe_screen *pscreen, struct pipe_resource *pres, int *w, int *h);
174 bool
175 zink_kopper_is_cpu(const struct pipe_screen *pscreen);
176 void
177 zink_kopper_fixup_depth_buffer(struct zink_context *ctx);
178 bool
179 zink_kopper_check(struct pipe_resource *pres);
180 void
181 zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource *pres, int interval);
182 int
183 zink_kopper_query_buffer_age(struct pipe_context *pctx, struct pipe_resource *pres);
184 void
185 zink_kopper_prune_batch_usage(struct kopper_displaytarget *cdt, const struct zink_batch_usage *u);
186 void
187 zink_kopper_set_readback_needs_update(struct zink_resource *res);
188
189 #ifdef __cplusplus
190 }
191 #endif
192
193 #endif
194