1 /*
2  * Copyright © 2016 Bas Nieuwenhuizen
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  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef TU_DESCRIPTOR_SET_H
25 #define TU_DESCRIPTOR_SET_H
26 
27 #include <vulkan/vulkan.h>
28 
29 /* The hardware supports 5 descriptor sets, but we reserve 1 for dynamic
30  * descriptors and input attachments.
31  */
32 #define MAX_SETS 4
33 
34 struct tu_descriptor_set_binding_layout
35 {
36    VkDescriptorType type;
37 
38    /* Number of array elements in this binding */
39    uint32_t array_size;
40 
41    /* The size in bytes of each Vulkan descriptor. */
42    uint32_t size;
43 
44    uint32_t offset;
45 
46    /* Byte offset in the array of dynamic descriptors (offsetted by
47     * tu_pipeline_layout::set::dynamic_offset_start).
48     */
49    uint32_t dynamic_offset_offset;
50 
51    /* Offset in the tu_descriptor_set_layout of the immutable samplers, or 0
52     * if there are no immutable samplers. */
53    uint32_t immutable_samplers_offset;
54 
55    /* Offset in the tu_descriptor_set_layout of the ycbcr samplers, or 0
56     * if there are no immutable samplers. */
57    uint32_t ycbcr_samplers_offset;
58 
59    /* Shader stages that use this binding */
60    uint32_t shader_stages;
61 };
62 
63 struct tu_descriptor_set_layout
64 {
65    struct vk_object_base base;
66 
67    /* Descriptor set layouts can be destroyed at almost any time */
68    uint32_t ref_cnt;
69 
70    /* The create flags for this descriptor set layout */
71    VkDescriptorSetLayoutCreateFlags flags;
72 
73    /* Number of bindings in this descriptor set */
74    uint32_t binding_count;
75 
76    /* Total size of the descriptor set with room for all array entries */
77    uint32_t size;
78 
79    /* Shader stages affected by this descriptor set */
80    uint16_t shader_stages;
81 
82    /* Size of dynamic offset descriptors used by this descriptor set */
83    uint16_t dynamic_offset_size;
84 
85    bool has_immutable_samplers;
86    bool has_variable_descriptors;
87 
88    /* Bindings in this descriptor set */
89    struct tu_descriptor_set_binding_layout binding[0];
90 };
91 
92 struct tu_device;
93 
94 void tu_descriptor_set_layout_destroy(struct tu_device *device,
95                                       struct tu_descriptor_set_layout *layout);
96 
97 static inline void
tu_descriptor_set_layout_ref(struct tu_descriptor_set_layout * layout)98 tu_descriptor_set_layout_ref(struct tu_descriptor_set_layout *layout)
99 {
100    assert(layout && layout->ref_cnt >= 1);
101    p_atomic_inc(&layout->ref_cnt);
102 }
103 
104 static inline void
tu_descriptor_set_layout_unref(struct tu_device * device,struct tu_descriptor_set_layout * layout)105 tu_descriptor_set_layout_unref(struct tu_device *device,
106                                struct tu_descriptor_set_layout *layout)
107 {
108    assert(layout && layout->ref_cnt >= 1);
109    if (p_atomic_dec_zero(&layout->ref_cnt))
110       tu_descriptor_set_layout_destroy(device, layout);
111 }
112 
113 struct tu_pipeline_layout
114 {
115    struct vk_object_base base;
116 
117    struct
118    {
119       struct tu_descriptor_set_layout *layout;
120       uint32_t size;
121       uint32_t dynamic_offset_start;
122    } set[MAX_SETS];
123 
124    uint32_t num_sets;
125    uint32_t push_constant_size;
126    uint32_t dynamic_offset_size;
127 };
128 
129 static inline const struct tu_sampler *
tu_immutable_samplers(const struct tu_descriptor_set_layout * set,const struct tu_descriptor_set_binding_layout * binding)130 tu_immutable_samplers(const struct tu_descriptor_set_layout *set,
131                       const struct tu_descriptor_set_binding_layout *binding)
132 {
133    return (void *) ((const char *) set + binding->immutable_samplers_offset);
134 }
135 
136 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)137 tu_immutable_ycbcr_samplers(const struct tu_descriptor_set_layout *set,
138                             const struct tu_descriptor_set_binding_layout *binding)
139 {
140    if (!binding->ycbcr_samplers_offset)
141       return NULL;
142 
143    return (void *) ((const char *) set + binding->ycbcr_samplers_offset);
144 }
145 
146 #endif /* TU_DESCRIPTOR_SET_H */
147