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 #include "vk_descriptor_set_layout.h"
12
13 #include "tu_sampler.h"
14
15 /* The hardware supports up to 8 descriptor sets since A7XX.
16 * Note: This is the maximum across generations, not the maximum for a
17 * particular generation so it should only be used for allocation.
18 */
19 #define MAX_SETS 8
20
21 /* I have no idea what the maximum size is, but the hardware supports very
22 * large numbers of descriptors (at least 2^16). This limit is based on
23 * CP_LOAD_STATE6, which has a 28-bit field for the DWORD offset, so that
24 * we don't have to think about what to do if that overflows, but really
25 * nothing is likely to get close to this.
26 */
27 #define MAX_SET_SIZE ((1 << 28) * 4)
28
29 struct tu_descriptor_set_binding_layout
30 {
31 VkDescriptorType type;
32
33 /* Number of array elements in this binding */
34 uint32_t array_size;
35
36 /* The size in bytes of each Vulkan descriptor. */
37 uint32_t size;
38
39 uint32_t offset;
40
41 /* Byte offset in the array of dynamic descriptors (offsetted by
42 * tu_pipeline_layout::set::dynamic_offset_start).
43 */
44 uint32_t dynamic_offset_offset;
45
46 /* Offset in the tu_descriptor_set_layout of the immutable samplers, or 0
47 * if there are no immutable samplers. */
48 uint32_t immutable_samplers_offset;
49
50 /* Offset in the tu_descriptor_set_layout of the ycbcr samplers, or 0
51 * if there are no immutable samplers. */
52 uint32_t ycbcr_samplers_offset;
53
54 /* Shader stages that use this binding */
55 uint32_t shader_stages;
56 };
57
58 struct tu_descriptor_set_layout
59 {
60 struct vk_descriptor_set_layout vk;
61
62 /* The create flags for this descriptor set layout */
63 VkDescriptorSetLayoutCreateFlags flags;
64
65 /* Number of bindings in this descriptor set */
66 uint32_t binding_count;
67
68 /* Total size of the descriptor set with room for all array entries */
69 uint32_t size;
70
71 /* Shader stages affected by this descriptor set */
72 uint16_t shader_stages;
73
74 /* Size of dynamic offset descriptors used by this descriptor set */
75 uint16_t dynamic_offset_size;
76
77 bool has_immutable_samplers;
78 bool has_variable_descriptors;
79 bool has_inline_uniforms;
80
81 struct tu_bo *embedded_samplers;
82
83 /* Bindings in this descriptor set */
84 struct tu_descriptor_set_binding_layout binding[0];
85 };
86 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_set_layout, vk.base,
87 VkDescriptorSetLayout,
88 VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
89
90 struct tu_pipeline_layout
91 {
92 struct vk_object_base base;
93
94 struct
95 {
96 struct tu_descriptor_set_layout *layout;
97 uint32_t size;
98 } set[MAX_SETS];
99
100 uint32_t num_sets;
101 uint32_t push_constant_size;
102
103 unsigned char sha1[20];
104 };
105 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_pipeline_layout, base, VkPipelineLayout,
106 VK_OBJECT_TYPE_PIPELINE_LAYOUT)
107
108 void tu_pipeline_layout_init(struct tu_pipeline_layout *layout);
109
110 struct tu_descriptor_set
111 {
112 struct vk_object_base base;
113
114 /* Link to descriptor pool's desc_sets list . */
115 struct list_head pool_link;
116
117 struct tu_descriptor_set_layout *layout;
118 struct tu_descriptor_pool *pool;
119 uint32_t size;
120
121 uint64_t va;
122 /* Pointer to the GPU memory for the set for non-push descriptors, or pointer
123 * to a host memory copy for push descriptors.
124 */
125 uint32_t *mapped_ptr;
126
127 /* Size of the host memory allocation for push descriptors */
128 uint32_t host_size;
129
130 uint32_t *dynamic_descriptors;
131 };
132 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_set, base, VkDescriptorSet,
133 VK_OBJECT_TYPE_DESCRIPTOR_SET)
134
135 struct tu_descriptor_pool_entry
136 {
137 uint32_t offset;
138 uint32_t size;
139 struct tu_descriptor_set *set;
140 };
141
142 struct tu_descriptor_pool
143 {
144 struct vk_object_base base;
145
146 struct tu_bo *bo;
147 uint64_t current_offset;
148 uint64_t size;
149
150 uint8_t *host_memory_base;
151 uint8_t *host_memory_ptr;
152 uint8_t *host_memory_end;
153 uint8_t *host_bo;
154
155 struct list_head desc_sets;
156
157 uint32_t entry_count;
158 uint32_t max_entry_count;
159 struct tu_descriptor_pool_entry entries[0];
160 };
161 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_pool, base, VkDescriptorPool,
162 VK_OBJECT_TYPE_DESCRIPTOR_POOL)
163
164 struct tu_descriptor_update_template_entry
165 {
166 VkDescriptorType descriptor_type;
167
168 /* The number of descriptors to update */
169 uint32_t descriptor_count;
170
171 /* Into mapped_ptr or dynamic_descriptors, in units of the respective array
172 */
173 uint32_t dst_offset;
174
175 /* In dwords. Not valid/used for dynamic descriptors */
176 uint32_t dst_stride;
177
178 uint32_t buffer_offset;
179
180 /* Only valid for combined image samplers and samplers */
181 uint16_t has_sampler;
182
183 /* In bytes */
184 size_t src_offset;
185 size_t src_stride;
186
187 /* For push descriptors */
188 const struct tu_sampler *immutable_samplers;
189 };
190
191 struct tu_descriptor_update_template
192 {
193 struct vk_object_base base;
194
195 uint32_t entry_count;
196 VkPipelineBindPoint bind_point;
197 struct tu_descriptor_update_template_entry entry[0];
198 };
199 VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_update_template, base,
200 VkDescriptorUpdateTemplate,
201 VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
202
203 void
204 tu_update_descriptor_sets(const struct tu_device *device,
205 VkDescriptorSet overrideSet,
206 uint32_t descriptorWriteCount,
207 const VkWriteDescriptorSet *pDescriptorWrites,
208 uint32_t descriptorCopyCount,
209 const VkCopyDescriptorSet *pDescriptorCopies);
210
211 void
212 tu_update_descriptor_set_with_template(
213 const struct tu_device *device,
214 struct tu_descriptor_set *set,
215 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
216 const void *pData);
217
218 static inline const struct tu_sampler *
tu_immutable_samplers(const struct tu_descriptor_set_layout * set,const struct tu_descriptor_set_binding_layout * binding)219 tu_immutable_samplers(const struct tu_descriptor_set_layout *set,
220 const struct tu_descriptor_set_binding_layout *binding)
221 {
222 return (struct tu_sampler *) ((const char *) set +
223 binding->immutable_samplers_offset);
224 }
225
226 static inline const struct vk_ycbcr_conversion_state *
tu_immutable_ycbcr_samplers(const struct tu_descriptor_set_layout * set,const struct tu_descriptor_set_binding_layout * binding)227 tu_immutable_ycbcr_samplers(const struct tu_descriptor_set_layout *set,
228 const struct tu_descriptor_set_binding_layout *binding)
229 {
230 if (!binding->ycbcr_samplers_offset)
231 return NULL;
232
233 return (
234 struct vk_ycbcr_conversion_state *) ((const char *) set +
235 binding->ycbcr_samplers_offset);
236 }
237
238 #endif /* TU_DESCRIPTOR_SET_H */
239