1 /*
2 * Copyright © 2016 Bas Nieuwenhuizen
3 * SPDX-License-Identifier: MIT
4 */
5
6 #ifndef TU_DESCRIPTOR_SET_H
7 #define TU_DESCRIPTOR_SET_H
8
9 #include "tu_common.h"
10
11 /* The hardware supports 5 descriptor sets, but we reserve 1 for dynamic
12 * descriptors and input attachments.
13 */
14 #define MAX_SETS 4
15
16 struct tu_descriptor_set_binding_layout
17 {
18 VkDescriptorType type;
19
20 /* Number of array elements in this binding */
21 uint32_t array_size;
22
23 /* The size in bytes of each Vulkan descriptor. */
24 uint32_t size;
25
26 uint32_t offset;
27
28 /* Byte offset in the array of dynamic descriptors (offsetted by
29 * tu_pipeline_layout::set::dynamic_offset_start).
30 */
31 uint32_t dynamic_offset_offset;
32
33 /* Offset in the tu_descriptor_set_layout of the immutable samplers, or 0
34 * if there are no immutable samplers. */
35 uint32_t immutable_samplers_offset;
36
37 /* Offset in the tu_descriptor_set_layout of the ycbcr samplers, or 0
38 * if there are no immutable samplers. */
39 uint32_t ycbcr_samplers_offset;
40
41 /* Shader stages that use this binding */
42 uint32_t shader_stages;
43 };
44
45 struct tu_descriptor_set_layout
46 {
47 struct vk_object_base base;
48
49 /* Descriptor set layouts can be destroyed at almost any time */
50 uint32_t ref_cnt;
51
52 /* The create flags for this descriptor set layout */
53 VkDescriptorSetLayoutCreateFlags flags;
54
55 /* Number of bindings in this descriptor set */
56 uint32_t binding_count;
57
58 /* Total size of the descriptor set with room for all array entries */
59 uint32_t size;
60
61 /* Shader stages affected by this descriptor set */
62 uint16_t shader_stages;
63
64 /* Size of dynamic offset descriptors used by this descriptor set */
65 uint16_t dynamic_offset_size;
66
67 bool has_immutable_samplers;
68 bool has_variable_descriptors;
69
70 /* Bindings in this descriptor set */
71 struct tu_descriptor_set_binding_layout binding[0];
72 };
73 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_set_layout, base,
74 VkDescriptorSetLayout,
75 VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
76
77 struct tu_pipeline_layout
78 {
79 struct vk_object_base base;
80
81 struct
82 {
83 struct tu_descriptor_set_layout *layout;
84 uint32_t size;
85 uint32_t dynamic_offset_start;
86 } set[MAX_SETS];
87
88 uint32_t num_sets;
89 uint32_t push_constant_size;
90 uint32_t dynamic_offset_size;
91
92 unsigned char sha1[20];
93 };
94 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_pipeline_layout, base, VkPipelineLayout,
95 VK_OBJECT_TYPE_PIPELINE_LAYOUT)
96
97 struct tu_descriptor_set
98 {
99 struct vk_object_base base;
100
101 /* Link to descriptor pool's desc_sets list . */
102 struct list_head pool_link;
103
104 struct tu_descriptor_set_layout *layout;
105 struct tu_descriptor_pool *pool;
106 uint32_t size;
107
108 uint64_t va;
109 uint32_t *mapped_ptr;
110
111 uint32_t *dynamic_descriptors;
112 };
113 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_set, base, VkDescriptorSet,
114 VK_OBJECT_TYPE_DESCRIPTOR_SET)
115
116 struct tu_descriptor_pool_entry
117 {
118 uint32_t offset;
119 uint32_t size;
120 struct tu_descriptor_set *set;
121 };
122
123 struct tu_descriptor_pool
124 {
125 struct vk_object_base base;
126
127 struct tu_bo *bo;
128 uint64_t current_offset;
129 uint64_t size;
130
131 uint8_t *host_memory_base;
132 uint8_t *host_memory_ptr;
133 uint8_t *host_memory_end;
134 uint8_t *host_bo;
135
136 struct list_head desc_sets;
137
138 uint32_t entry_count;
139 uint32_t max_entry_count;
140 struct tu_descriptor_pool_entry entries[0];
141 };
142 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_pool, base, VkDescriptorPool,
143 VK_OBJECT_TYPE_DESCRIPTOR_POOL)
144
145 struct tu_descriptor_update_template_entry
146 {
147 VkDescriptorType descriptor_type;
148
149 /* The number of descriptors to update */
150 uint32_t descriptor_count;
151
152 /* Into mapped_ptr or dynamic_descriptors, in units of the respective array
153 */
154 uint32_t dst_offset;
155
156 /* In dwords. Not valid/used for dynamic descriptors */
157 uint32_t dst_stride;
158
159 uint32_t buffer_offset;
160
161 /* Only valid for combined image samplers and samplers */
162 uint16_t has_sampler;
163
164 /* In bytes */
165 size_t src_offset;
166 size_t src_stride;
167
168 /* For push descriptors */
169 const struct tu_sampler *immutable_samplers;
170 };
171
172 struct tu_descriptor_update_template
173 {
174 struct vk_object_base base;
175
176 uint32_t entry_count;
177 VkPipelineBindPoint bind_point;
178 struct tu_descriptor_update_template_entry entry[0];
179 };
180 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_update_template, base,
181 VkDescriptorUpdateTemplate,
182 VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
183
184 struct tu_sampler_ycbcr_conversion {
185 struct vk_object_base base;
186
187 VkFormat format;
188 VkSamplerYcbcrModelConversion ycbcr_model;
189 VkSamplerYcbcrRange ycbcr_range;
190 VkComponentMapping components;
191 VkChromaLocation chroma_offsets[2];
192 VkFilter chroma_filter;
193 };
194 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_sampler_ycbcr_conversion, base, VkSamplerYcbcrConversion,
195 VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION)
196
197 void tu_descriptor_set_layout_destroy(struct tu_device *device,
198 struct tu_descriptor_set_layout *layout);
199
200 static inline void
tu_descriptor_set_layout_ref(struct tu_descriptor_set_layout * layout)201 tu_descriptor_set_layout_ref(struct tu_descriptor_set_layout *layout)
202 {
203 assert(layout && layout->ref_cnt >= 1);
204 p_atomic_inc(&layout->ref_cnt);
205 }
206
207 static inline void
tu_descriptor_set_layout_unref(struct tu_device * device,struct tu_descriptor_set_layout * layout)208 tu_descriptor_set_layout_unref(struct tu_device *device,
209 struct tu_descriptor_set_layout *layout)
210 {
211 assert(layout && layout->ref_cnt >= 1);
212 if (p_atomic_dec_zero(&layout->ref_cnt))
213 tu_descriptor_set_layout_destroy(device, layout);
214 }
215
216 void
217 tu_update_descriptor_sets(const struct tu_device *device,
218 VkDescriptorSet overrideSet,
219 uint32_t descriptorWriteCount,
220 const VkWriteDescriptorSet *pDescriptorWrites,
221 uint32_t descriptorCopyCount,
222 const VkCopyDescriptorSet *pDescriptorCopies);
223
224 void
225 tu_update_descriptor_set_with_template(
226 const struct tu_device *device,
227 struct tu_descriptor_set *set,
228 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
229 const void *pData);
230
231 static inline const struct tu_sampler *
tu_immutable_samplers(const struct tu_descriptor_set_layout * set,const struct tu_descriptor_set_binding_layout * binding)232 tu_immutable_samplers(const struct tu_descriptor_set_layout *set,
233 const struct tu_descriptor_set_binding_layout *binding)
234 {
235 return (void *) ((const char *) set + binding->immutable_samplers_offset);
236 }
237
238 static inline const struct tu_sampler_ycbcr_conversion *
tu_immutable_ycbcr_samplers(const struct tu_descriptor_set_layout * set,const struct tu_descriptor_set_binding_layout * binding)239 tu_immutable_ycbcr_samplers(const struct tu_descriptor_set_layout *set,
240 const struct tu_descriptor_set_binding_layout *binding)
241 {
242 if (!binding->ycbcr_samplers_offset)
243 return NULL;
244
245 return (void *) ((const char *) set + binding->ycbcr_samplers_offset);
246 }
247
248 #endif /* TU_DESCRIPTOR_SET_H */
249