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_TRANSIENT (1 << 30) //transient fb attachment
47
48 struct mem_key {
49 unsigned seen_count;
50 struct {
51 unsigned heap_index;
52 VkMemoryRequirements reqs;
53 } key;
54 };
55
56 struct zink_resource_object {
57 struct pipe_reference reference;
58
59 VkPipelineStageFlagBits access_stage;
60 VkAccessFlags access;
61 bool unordered_barrier;
62
63 unsigned persistent_maps; //if nonzero, requires vkFlushMappedMemoryRanges during batch use
64 struct zink_descriptor_refs desc_set_refs;
65
66 struct util_dynarray tmp;
67
68 union {
69 VkBuffer buffer;
70 VkImage image;
71 };
72
73 VkSampleLocationsInfoEXT zs_evaluate;
74 bool needs_zs_evaluate;
75
76 bool storage_init; //layout was set for image
77 bool transfer_dst;
78 bool is_buffer;
79 VkImageAspectFlags modifier_aspect;
80
81 struct zink_bo *bo;
82 VkDeviceSize offset, size, alignment;
83 VkImageCreateFlags vkflags;
84 VkImageUsageFlags vkusage;
85
86 bool host_visible;
87 bool coherent;
88 };
89
90 struct zink_resource {
91 struct threaded_resource base;
92
93 enum pipe_format internal_format:16;
94
95 struct zink_resource_object *obj;
96 struct zink_resource_object *scanout_obj; //TODO: remove for wsi
97 bool scanout_obj_init;
98 union {
99 struct {
100 struct util_range valid_buffer_range;
101 uint32_t vbo_bind_mask : PIPE_MAX_ATTRIBS;
102 uint8_t ubo_bind_count[2];
103 uint8_t so_bind_count;
104 bool so_valid;
105 uint32_t ubo_bind_mask[PIPE_SHADER_TYPES];
106 uint32_t ssbo_bind_mask[PIPE_SHADER_TYPES];
107 };
108 struct {
109 VkFormat format;
110 VkImageLayout layout;
111 VkImageAspectFlags aspect;
112 bool optimal_tiling;
113 uint8_t fb_binds;
114 };
115 };
116 uint32_t sampler_binds[PIPE_SHADER_TYPES];
117 uint16_t image_bind_count[2]; //gfx, compute
118 uint16_t write_bind_count[2]; //gfx, compute
119 uint16_t bindless[2]; //tex, img
120 union {
121 uint16_t bind_count[2]; //gfx, compute
122 uint32_t all_binds;
123 };
124
125 union {
126 struct {
127 struct hash_table bufferview_cache;
128 simple_mtx_t bufferview_mtx;
129 };
130 struct {
131 struct hash_table surface_cache;
132 simple_mtx_t surface_mtx;
133 };
134 };
135
136 bool dmabuf_acquire;
137 struct sw_displaytarget *dt;
138 unsigned dt_stride;
139
140 uint8_t modifiers_count;
141 uint64_t *modifiers;
142 };
143
144 struct zink_transfer {
145 struct threaded_transfer base;
146 struct pipe_resource *staging_res;
147 unsigned offset;
148 unsigned depthPitch;
149 };
150
151 static inline struct zink_resource *
zink_resource(struct pipe_resource * r)152 zink_resource(struct pipe_resource *r)
153 {
154 return (struct zink_resource *)r;
155 }
156
157 bool
158 zink_screen_resource_init(struct pipe_screen *pscreen);
159
160 void
161 zink_context_resource_init(struct pipe_context *pctx);
162
163 void
164 zink_get_depth_stencil_resources(struct pipe_resource *res,
165 struct zink_resource **out_z,
166 struct zink_resource **out_s);
167 VkMappedMemoryRange
168 zink_resource_init_mem_range(struct zink_screen *screen, struct zink_resource_object *obj, VkDeviceSize offset, VkDeviceSize size);
169 void
170 zink_resource_setup_transfer_layouts(struct zink_context *ctx, struct zink_resource *src, struct zink_resource *dst);
171
172 void
173 zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *resource_object);
174
175 void
176 debug_describe_zink_resource_object(char *buf, const struct zink_resource_object *ptr);
177
178 static inline void
zink_resource_object_reference(struct zink_screen * screen,struct zink_resource_object ** dst,struct zink_resource_object * src)179 zink_resource_object_reference(struct zink_screen *screen,
180 struct zink_resource_object **dst,
181 struct zink_resource_object *src)
182 {
183 struct zink_resource_object *old_dst = dst ? *dst : NULL;
184
185 if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
186 (debug_reference_descriptor)debug_describe_zink_resource_object))
187 zink_destroy_resource_object(screen, old_dst);
188 if (dst) *dst = src;
189 }
190
191 VkBuffer
192 zink_resource_tmp_buffer(struct zink_screen *screen, struct zink_resource *res, unsigned offset_add, unsigned add_binds, unsigned *offset);
193
194 bool
195 zink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource *res);
196
197 static inline bool
zink_resource_has_binds(const struct zink_resource * res)198 zink_resource_has_binds(const struct zink_resource *res)
199 {
200 return res->all_binds > 0;
201 }
202
203 #ifndef __cplusplus
204 #include "zink_bo.h"
205
206 static inline bool
zink_resource_usage_is_unflushed(const struct zink_resource * res)207 zink_resource_usage_is_unflushed(const struct zink_resource *res)
208 {
209 return zink_bo_has_unflushed_usage(res->obj->bo);
210 }
211
212 static inline bool
zink_resource_usage_is_unflushed_write(const struct zink_resource * res)213 zink_resource_usage_is_unflushed_write(const struct zink_resource *res)
214 {
215 return zink_batch_usage_is_unflushed(res->obj->bo->writes);
216 }
217
218
219 static inline bool
zink_resource_usage_matches(const struct zink_resource * res,const struct zink_batch_state * bs)220 zink_resource_usage_matches(const struct zink_resource *res, const struct zink_batch_state *bs)
221 {
222 return zink_bo_usage_matches(res->obj->bo, bs);
223 }
224
225 static inline bool
zink_resource_has_usage(const struct zink_resource * res)226 zink_resource_has_usage(const struct zink_resource *res)
227 {
228 return zink_bo_has_usage(res->obj->bo);
229 }
230
231 static inline bool
zink_resource_has_unflushed_usage(const struct zink_resource * res)232 zink_resource_has_unflushed_usage(const struct zink_resource *res)
233 {
234 return zink_bo_has_unflushed_usage(res->obj->bo);
235 }
236
237 static inline bool
zink_resource_usage_check_completion(struct zink_screen * screen,struct zink_resource * res,enum zink_resource_access access)238 zink_resource_usage_check_completion(struct zink_screen *screen, struct zink_resource *res, enum zink_resource_access access)
239 {
240 return zink_bo_usage_check_completion(screen, res->obj->bo, access);
241 }
242
243 static inline void
zink_resource_usage_wait(struct zink_context * ctx,struct zink_resource * res,enum zink_resource_access access)244 zink_resource_usage_wait(struct zink_context *ctx, struct zink_resource *res, enum zink_resource_access access)
245 {
246 zink_bo_usage_wait(ctx, res->obj->bo, access);
247 }
248
249 static inline void
zink_resource_usage_set(struct zink_resource * res,struct zink_batch_state * bs,bool write)250 zink_resource_usage_set(struct zink_resource *res, struct zink_batch_state *bs, bool write)
251 {
252 zink_bo_usage_set(res->obj->bo, bs, write);
253 }
254
255 static inline bool
zink_resource_object_usage_unset(struct zink_resource_object * obj,struct zink_batch_state * bs)256 zink_resource_object_usage_unset(struct zink_resource_object *obj, struct zink_batch_state *bs)
257 {
258 return zink_bo_usage_unset(obj->bo, bs);
259 }
260
261 #endif
262 #endif
263