1 /*
2 * Copyright 2018 Collabora Ltd.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #ifndef ZINK_RESOURCE_H
25 #define ZINK_RESOURCE_H
26
27 struct pipe_screen;
28 struct sw_displaytarget;
29 struct zink_batch;
30 struct zink_context;
31 struct zink_bo;
32
33 #include "util/hash_table.h"
34 #include "util/simple_mtx.h"
35 #include "util/u_transfer.h"
36 #include "util/u_range.h"
37 #include "util/u_dynarray.h"
38 #include "util/u_threaded_context.h"
39
40 #include "zink_batch.h"
41 #include "zink_descriptors.h"
42
43 #include <vulkan/vulkan.h>
44
45 #define ZINK_MAP_TEMPORARY (PIPE_MAP_DRV_PRV << 0)
46 #define ZINK_BIND_DMABUF (1u << 29)
47 #define ZINK_BIND_TRANSIENT (1u << 30) //transient fb attachment
48 #define ZINK_BIND_VIDEO (1u << 31)
49
50 struct mem_key {
51 unsigned seen_count;
52 struct {
53 unsigned heap_index;
54 VkMemoryRequirements reqs;
55 } key;
56 };
57
58 struct zink_resource_object {
59 struct pipe_reference reference;
60
61 VkPipelineStageFlagBits access_stage;
62 VkAccessFlags access;
63 bool unordered_read;
64 bool unordered_write;
65
66 unsigned persistent_maps; //if nonzero, requires vkFlushMappedMemoryRanges during batch use
67 struct zink_descriptor_refs desc_set_refs;
68
69 VkBuffer storage_buffer;
70
71 union {
72 VkBuffer buffer;
73 VkImage image;
74 };
75
76 VkSampleLocationsInfoEXT zs_evaluate;
77 bool needs_zs_evaluate;
78
79 bool storage_init; //layout was set for image
80 bool transfer_dst;
81 bool render_target;
82 bool is_buffer;
83 bool exportable;
84
85 /* TODO: this should be a union */
86 int handle;
87 struct zink_bo *bo;
88 // struct {
89 struct kopper_displaytarget *dt;
90 uint32_t dt_idx;
91 uint32_t last_dt_idx;
92 VkSemaphore present;
93 bool new_dt;
94 bool indefinite_acquire;
95 // }
96
97
98 VkDeviceSize offset, size, alignment;
99 VkImageCreateFlags vkflags;
100 VkImageUsageFlags vkusage;
101 VkFormatFeatureFlags vkfeats;
102 uint64_t modifier;
103 VkImageAspectFlags modifier_aspect;
104 VkSamplerYcbcrConversion sampler_conversion;
105 unsigned plane_offsets[3];
106 unsigned plane_strides[3];
107 unsigned plane_count;
108
109 bool host_visible;
110 bool coherent;
111 bool is_aux;
112 };
113
114 struct zink_resource {
115 struct threaded_resource base;
116
117 enum pipe_format internal_format:16;
118
119 struct zink_resource_object *obj;
120 union {
121 struct {
122 struct util_range valid_buffer_range;
123 uint32_t vbo_bind_mask : PIPE_MAX_ATTRIBS;
124 uint8_t ubo_bind_count[2];
125 uint8_t ssbo_bind_count[2];
126 uint8_t vbo_bind_count;
127 uint8_t so_bind_count; //not counted in all_binds
128 bool so_valid;
129 uint32_t ubo_bind_mask[PIPE_SHADER_TYPES];
130 uint32_t ssbo_bind_mask[PIPE_SHADER_TYPES];
131 };
132 struct {
133 VkSparseImageMemoryRequirements sparse;
134 VkFormat format;
135 VkImageLayout layout;
136 VkImageAspectFlags aspect;
137 bool optimal_tiling;
138 bool need_2D;
139 bool valid;
140 uint8_t fb_binds; //not counted in all_binds
141 };
142 };
143 uint32_t sampler_binds[PIPE_SHADER_TYPES];
144 uint32_t image_binds[PIPE_SHADER_TYPES];
145 uint16_t sampler_bind_count[2]; //gfx, compute
146 uint16_t image_bind_count[2]; //gfx, compute
147 uint16_t write_bind_count[2]; //gfx, compute
148 uint16_t bindless[2]; //tex, img
149 union {
150 uint16_t bind_count[2]; //gfx, compute
151 uint32_t all_binds;
152 };
153
154 VkPipelineStageFlagBits gfx_barrier;
155 VkAccessFlagBits barrier_access[2]; //gfx, compute
156
157 union {
158 struct {
159 struct hash_table bufferview_cache;
160 simple_mtx_t bufferview_mtx;
161 };
162 struct {
163 struct hash_table surface_cache;
164 simple_mtx_t surface_mtx;
165 };
166 };
167
168 bool swapchain;
169 bool dmabuf_acquire;
170 bool dmabuf;
171 unsigned dt_stride;
172
173 uint8_t modifiers_count;
174 uint64_t *modifiers;
175 enum pipe_format drm_format;
176 };
177
178 struct zink_transfer {
179 struct threaded_transfer base;
180 struct pipe_resource *staging_res;
181 unsigned offset;
182 unsigned depthPitch;
183 };
184
185 static inline struct zink_resource *
zink_resource(struct pipe_resource * r)186 zink_resource(struct pipe_resource *r)
187 {
188 return (struct zink_resource *)r;
189 }
190
191 bool
192 zink_screen_resource_init(struct pipe_screen *pscreen);
193
194 void
195 zink_context_resource_init(struct pipe_context *pctx);
196
197 void
198 zink_get_depth_stencil_resources(struct pipe_resource *res,
199 struct zink_resource **out_z,
200 struct zink_resource **out_s);
201 VkMappedMemoryRange
202 zink_resource_init_mem_range(struct zink_screen *screen, struct zink_resource_object *obj, VkDeviceSize offset, VkDeviceSize size);
203 void
204 zink_resource_setup_transfer_layouts(struct zink_context *ctx, struct zink_resource *src, struct zink_resource *dst);
205
206 void
207 zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *resource_object);
208
209 void
210 debug_describe_zink_resource_object(char *buf, const struct zink_resource_object *ptr);
211
212 static inline void
zink_resource_object_reference(struct zink_screen * screen,struct zink_resource_object ** dst,struct zink_resource_object * src)213 zink_resource_object_reference(struct zink_screen *screen,
214 struct zink_resource_object **dst,
215 struct zink_resource_object *src)
216 {
217 struct zink_resource_object *old_dst = dst ? *dst : NULL;
218
219 if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
220 (debug_reference_descriptor)debug_describe_zink_resource_object))
221 zink_destroy_resource_object(screen, old_dst);
222 if (dst) *dst = src;
223 }
224
225 bool
226 zink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource *res);
227
228 static inline bool
zink_resource_has_binds(const struct zink_resource * res)229 zink_resource_has_binds(const struct zink_resource *res)
230 {
231 return res->all_binds > 0;
232 }
233
234 static inline bool
zink_is_swapchain(const struct zink_resource * res)235 zink_is_swapchain(const struct zink_resource *res)
236 {
237 return res->swapchain;
238 }
239
240 #ifndef __cplusplus
241 #include "zink_bo.h"
242
243 static inline bool
zink_resource_usage_is_unflushed(const struct zink_resource * res)244 zink_resource_usage_is_unflushed(const struct zink_resource *res)
245 {
246 return zink_bo_has_unflushed_usage(res->obj->bo);
247 }
248
249 static inline bool
zink_resource_usage_is_unflushed_write(const struct zink_resource * res)250 zink_resource_usage_is_unflushed_write(const struct zink_resource *res)
251 {
252 return zink_batch_usage_is_unflushed(res->obj->bo->writes);
253 }
254
255
256 static inline bool
zink_resource_usage_matches(const struct zink_resource * res,const struct zink_batch_state * bs)257 zink_resource_usage_matches(const struct zink_resource *res, const struct zink_batch_state *bs)
258 {
259 return zink_bo_usage_matches(res->obj->bo, bs);
260 }
261
262 static inline bool
zink_resource_has_usage(const struct zink_resource * res)263 zink_resource_has_usage(const struct zink_resource *res)
264 {
265 return zink_bo_has_usage(res->obj->bo);
266 }
267
268 static inline bool
zink_resource_has_unflushed_usage(const struct zink_resource * res)269 zink_resource_has_unflushed_usage(const struct zink_resource *res)
270 {
271 return zink_bo_has_unflushed_usage(res->obj->bo);
272 }
273
274 static inline bool
zink_resource_usage_check_completion(struct zink_screen * screen,struct zink_resource * res,enum zink_resource_access access)275 zink_resource_usage_check_completion(struct zink_screen *screen, struct zink_resource *res, enum zink_resource_access access)
276 {
277 return zink_bo_usage_check_completion(screen, res->obj->bo, access);
278 }
279
280 static inline void
zink_resource_usage_wait(struct zink_context * ctx,struct zink_resource * res,enum zink_resource_access access)281 zink_resource_usage_wait(struct zink_context *ctx, struct zink_resource *res, enum zink_resource_access access)
282 {
283 zink_bo_usage_wait(ctx, res->obj->bo, access);
284 }
285
286 static inline void
zink_resource_usage_set(struct zink_resource * res,struct zink_batch_state * bs,bool write)287 zink_resource_usage_set(struct zink_resource *res, struct zink_batch_state *bs, bool write)
288 {
289 zink_bo_usage_set(res->obj->bo, bs, write);
290 }
291
292 static inline bool
zink_resource_object_usage_unset(struct zink_resource_object * obj,struct zink_batch_state * bs)293 zink_resource_object_usage_unset(struct zink_resource_object *obj, struct zink_batch_state *bs)
294 {
295 return zink_bo_usage_unset(obj->bo, bs);
296 }
297
298 #endif
299 #endif
300