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
16struct 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
45struct 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};
73VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_set_layout, base,
74                               VkDescriptorSetLayout,
75                               VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
76
77struct 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};
94VK_DEFINE_NONDISP_HANDLE_CASTS(tu_pipeline_layout, base, VkPipelineLayout,
95                               VK_OBJECT_TYPE_PIPELINE_LAYOUT)
96
97struct 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};
113VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_set, base, VkDescriptorSet,
114                               VK_OBJECT_TYPE_DESCRIPTOR_SET)
115
116struct tu_descriptor_pool_entry
117{
118   uint32_t offset;
119   uint32_t size;
120   struct tu_descriptor_set *set;
121};
122
123struct 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};
142VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_pool, base, VkDescriptorPool,
143                               VK_OBJECT_TYPE_DESCRIPTOR_POOL)
144
145struct 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
172struct 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};
180VK_DEFINE_NONDISP_HANDLE_CASTS(tu_descriptor_update_template, base,
181                               VkDescriptorUpdateTemplate,
182                               VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
183
184struct 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};
194VK_DEFINE_NONDISP_HANDLE_CASTS(tu_sampler_ycbcr_conversion, base, VkSamplerYcbcrConversion,
195                               VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION)
196
197void tu_descriptor_set_layout_destroy(struct tu_device *device,
198                                      struct tu_descriptor_set_layout *layout);
199
200static inline void
201tu_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
207static inline void
208tu_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
216void
217tu_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
224void
225tu_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
231static inline const struct tu_sampler *
232tu_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
238static inline const struct tu_sampler_ycbcr_conversion *
239tu_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