• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Collabora Ltd.
3  *
4  * Derived from:
5  * Copyright © 2016 Red Hat.
6  * Copyright © 2016 Bas Nieuwenhuizen
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  */
27 #include "panvk_private.h"
28 
29 #include <assert.h>
30 #include <fcntl.h>
31 #include <stdbool.h>
32 #include <string.h>
33 #include <unistd.h>
34 
35 #include "util/mesa-sha1.h"
36 #include "vk_descriptors.h"
37 #include "vk_util.h"
38 
39 /* FIXME: make sure those values are correct */
40 #define PANVK_MAX_TEXTURES (1 << 16)
41 #define PANVK_MAX_IMAGES   (1 << 8)
42 #define PANVK_MAX_SAMPLERS (1 << 16)
43 #define PANVK_MAX_UBOS     255
44 
45 void
panvk_GetDescriptorSetLayoutSupport(VkDevice _device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,VkDescriptorSetLayoutSupport * pSupport)46 panvk_GetDescriptorSetLayoutSupport(
47    VkDevice _device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
48    VkDescriptorSetLayoutSupport *pSupport)
49 {
50    VK_FROM_HANDLE(panvk_device, device, _device);
51 
52    pSupport->supported = false;
53 
54    VkDescriptorSetLayoutBinding *bindings;
55    VkResult result = vk_create_sorted_bindings(
56       pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings);
57    if (result != VK_SUCCESS) {
58       vk_error(device, result);
59       return;
60    }
61 
62    unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
63    unsigned img_idx = 0;
64    UNUSED unsigned dynoffset_idx = 0;
65 
66    for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
67       const VkDescriptorSetLayoutBinding *binding = &bindings[i];
68 
69       switch (binding->descriptorType) {
70       case VK_DESCRIPTOR_TYPE_SAMPLER:
71          sampler_idx += binding->descriptorCount;
72          break;
73       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
74          sampler_idx += binding->descriptorCount;
75          tex_idx += binding->descriptorCount;
76          break;
77       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
78       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
79       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
80          tex_idx += binding->descriptorCount;
81          break;
82       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
83          dynoffset_idx += binding->descriptorCount;
84          FALLTHROUGH;
85       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
86          ubo_idx += binding->descriptorCount;
87          break;
88       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
89          dynoffset_idx += binding->descriptorCount;
90          FALLTHROUGH;
91       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
92          break;
93       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
94       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
95          img_idx += binding->descriptorCount;
96          break;
97       default:
98          unreachable("Invalid descriptor type");
99       }
100    }
101 
102    /* The maximum values apply to all sets attached to a pipeline since all
103     * sets descriptors have to be merged in a single array.
104     */
105    if (tex_idx > PANVK_MAX_TEXTURES / MAX_SETS ||
106        sampler_idx > PANVK_MAX_SAMPLERS / MAX_SETS ||
107        ubo_idx > PANVK_MAX_UBOS / MAX_SETS ||
108        img_idx > PANVK_MAX_IMAGES / MAX_SETS)
109       return;
110 
111    pSupport->supported = true;
112 }
113 
114 /*
115  * Pipeline layouts.  These have nothing to do with the pipeline.  They are
116  * just multiple descriptor set layouts pasted together.
117  */
118 
119 VkResult
panvk_CreatePipelineLayout(VkDevice _device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)120 panvk_CreatePipelineLayout(VkDevice _device,
121                            const VkPipelineLayoutCreateInfo *pCreateInfo,
122                            const VkAllocationCallbacks *pAllocator,
123                            VkPipelineLayout *pPipelineLayout)
124 {
125    VK_FROM_HANDLE(panvk_device, device, _device);
126    struct panvk_pipeline_layout *layout;
127    struct mesa_sha1 ctx;
128 
129    layout =
130       vk_pipeline_layout_zalloc(&device->vk, sizeof(*layout), pCreateInfo);
131    if (layout == NULL)
132       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
133 
134    _mesa_sha1_init(&ctx);
135 
136    unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
137    unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0;
138    for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
139       const struct panvk_descriptor_set_layout *set_layout =
140          vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
141 
142       layout->sets[set].sampler_offset = sampler_idx;
143       layout->sets[set].tex_offset = tex_idx;
144       layout->sets[set].ubo_offset = ubo_idx;
145       layout->sets[set].dyn_ubo_offset = dyn_ubo_idx;
146       layout->sets[set].dyn_ssbo_offset = dyn_ssbo_idx;
147       layout->sets[set].img_offset = img_idx;
148       sampler_idx += set_layout->num_samplers;
149       tex_idx += set_layout->num_textures;
150       ubo_idx += set_layout->num_ubos;
151       dyn_ubo_idx += set_layout->num_dyn_ubos;
152       dyn_ssbo_idx += set_layout->num_dyn_ssbos;
153       img_idx += set_layout->num_imgs;
154 
155       for (unsigned b = 0; b < set_layout->binding_count; b++) {
156          const struct panvk_descriptor_set_binding_layout *binding_layout =
157             &set_layout->bindings[b];
158 
159          if (binding_layout->immutable_samplers) {
160             for (unsigned s = 0; s < binding_layout->array_size; s++) {
161                struct panvk_sampler *sampler =
162                   binding_layout->immutable_samplers[s];
163 
164                _mesa_sha1_update(&ctx, &sampler->desc, sizeof(sampler->desc));
165             }
166          }
167          _mesa_sha1_update(&ctx, &binding_layout->type,
168                            sizeof(binding_layout->type));
169          _mesa_sha1_update(&ctx, &binding_layout->array_size,
170                            sizeof(binding_layout->array_size));
171          _mesa_sha1_update(&ctx, &binding_layout->shader_stages,
172                            sizeof(binding_layout->shader_stages));
173       }
174    }
175 
176    for (unsigned range = 0; range < pCreateInfo->pushConstantRangeCount;
177         range++) {
178       layout->push_constants.size =
179          MAX2(pCreateInfo->pPushConstantRanges[range].offset +
180                  pCreateInfo->pPushConstantRanges[range].size,
181               layout->push_constants.size);
182    }
183 
184    layout->num_samplers = sampler_idx;
185    layout->num_textures = tex_idx;
186    layout->num_ubos = ubo_idx;
187    layout->num_dyn_ubos = dyn_ubo_idx;
188    layout->num_dyn_ssbos = dyn_ssbo_idx;
189    layout->num_imgs = img_idx;
190 
191    /* Some NIR texture operations don't require a sampler, but Bifrost/Midgard
192     * ones always expect one. Add a dummy sampler to deal with this limitation.
193     */
194    if (layout->num_textures) {
195       layout->num_samplers++;
196       for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++)
197          layout->sets[set].sampler_offset++;
198    }
199 
200    _mesa_sha1_final(&ctx, layout->sha1);
201 
202    *pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
203    return VK_SUCCESS;
204 }
205 
206 VkResult
panvk_CreateDescriptorPool(VkDevice _device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)207 panvk_CreateDescriptorPool(VkDevice _device,
208                            const VkDescriptorPoolCreateInfo *pCreateInfo,
209                            const VkAllocationCallbacks *pAllocator,
210                            VkDescriptorPool *pDescriptorPool)
211 {
212    VK_FROM_HANDLE(panvk_device, device, _device);
213    struct panvk_descriptor_pool *pool;
214 
215    pool = vk_object_zalloc(&device->vk, pAllocator,
216                            sizeof(struct panvk_descriptor_pool),
217                            VK_OBJECT_TYPE_DESCRIPTOR_POOL);
218    if (!pool)
219       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
220 
221    pool->max.sets = pCreateInfo->maxSets;
222 
223    for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
224       unsigned desc_count = pCreateInfo->pPoolSizes[i].descriptorCount;
225 
226       switch (pCreateInfo->pPoolSizes[i].type) {
227       case VK_DESCRIPTOR_TYPE_SAMPLER:
228          pool->max.samplers += desc_count;
229          break;
230       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
231          pool->max.combined_image_samplers += desc_count;
232          break;
233       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
234          pool->max.sampled_images += desc_count;
235          break;
236       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
237          pool->max.storage_images += desc_count;
238          break;
239       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
240          pool->max.uniform_texel_bufs += desc_count;
241          break;
242       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
243          pool->max.storage_texel_bufs += desc_count;
244          break;
245       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
246          pool->max.input_attachments += desc_count;
247          break;
248       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
249          pool->max.uniform_bufs += desc_count;
250          break;
251       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
252          pool->max.storage_bufs += desc_count;
253          break;
254       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
255          pool->max.uniform_dyn_bufs += desc_count;
256          break;
257       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
258          pool->max.storage_dyn_bufs += desc_count;
259          break;
260       default:
261          unreachable("Invalid descriptor type");
262       }
263    }
264 
265    *pDescriptorPool = panvk_descriptor_pool_to_handle(pool);
266    return VK_SUCCESS;
267 }
268 
269 void
panvk_DestroyDescriptorPool(VkDevice _device,VkDescriptorPool _pool,const VkAllocationCallbacks * pAllocator)270 panvk_DestroyDescriptorPool(VkDevice _device, VkDescriptorPool _pool,
271                             const VkAllocationCallbacks *pAllocator)
272 {
273    VK_FROM_HANDLE(panvk_device, device, _device);
274    VK_FROM_HANDLE(panvk_descriptor_pool, pool, _pool);
275 
276    if (pool)
277       vk_object_free(&device->vk, pAllocator, pool);
278 }
279 
280 VkResult
panvk_ResetDescriptorPool(VkDevice _device,VkDescriptorPool _pool,VkDescriptorPoolResetFlags flags)281 panvk_ResetDescriptorPool(VkDevice _device, VkDescriptorPool _pool,
282                           VkDescriptorPoolResetFlags flags)
283 {
284    VK_FROM_HANDLE(panvk_descriptor_pool, pool, _pool);
285    memset(&pool->cur, 0, sizeof(pool->cur));
286    return VK_SUCCESS;
287 }
288 
289 static void
panvk_descriptor_set_destroy(struct panvk_device * device,struct panvk_descriptor_pool * pool,struct panvk_descriptor_set * set)290 panvk_descriptor_set_destroy(struct panvk_device *device,
291                              struct panvk_descriptor_pool *pool,
292                              struct panvk_descriptor_set *set)
293 {
294    vk_free(&device->vk.alloc, set->textures);
295    vk_free(&device->vk.alloc, set->samplers);
296    vk_free(&device->vk.alloc, set->ubos);
297    vk_free(&device->vk.alloc, set->dyn_ubos);
298    vk_free(&device->vk.alloc, set->dyn_ssbos);
299    vk_free(&device->vk.alloc, set->img_fmts);
300    vk_free(&device->vk.alloc, set->img_attrib_bufs);
301    if (set->desc_bo)
302       panvk_priv_bo_destroy(set->desc_bo, NULL);
303    vk_object_free(&device->vk, NULL, set);
304 }
305 
306 VkResult
panvk_FreeDescriptorSets(VkDevice _device,VkDescriptorPool descriptorPool,uint32_t count,const VkDescriptorSet * pDescriptorSets)307 panvk_FreeDescriptorSets(VkDevice _device, VkDescriptorPool descriptorPool,
308                          uint32_t count, const VkDescriptorSet *pDescriptorSets)
309 {
310    VK_FROM_HANDLE(panvk_device, device, _device);
311    VK_FROM_HANDLE(panvk_descriptor_pool, pool, descriptorPool);
312 
313    for (unsigned i = 0; i < count; i++) {
314       VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
315 
316       if (set)
317          panvk_descriptor_set_destroy(device, pool, set);
318    }
319    return VK_SUCCESS;
320 }
321 
322 VkResult
panvk_CreateSamplerYcbcrConversion(VkDevice device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)323 panvk_CreateSamplerYcbcrConversion(
324    VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
325    const VkAllocationCallbacks *pAllocator,
326    VkSamplerYcbcrConversion *pYcbcrConversion)
327 {
328    panvk_stub();
329    return VK_SUCCESS;
330 }
331 
332 void
panvk_DestroySamplerYcbcrConversion(VkDevice device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)333 panvk_DestroySamplerYcbcrConversion(VkDevice device,
334                                     VkSamplerYcbcrConversion ycbcrConversion,
335                                     const VkAllocationCallbacks *pAllocator)
336 {
337    panvk_stub();
338 }
339