• 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 #include "pan_bo.h"
40 
41 /* FIXME: make sure those values are correct */
42 #define PANVK_MAX_TEXTURES     (1 << 16)
43 #define PANVK_MAX_IMAGES       (1 << 8)
44 #define PANVK_MAX_SAMPLERS     (1 << 16)
45 #define PANVK_MAX_UBOS         255
46 
47 void
panvk_GetDescriptorSetLayoutSupport(VkDevice _device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,VkDescriptorSetLayoutSupport * pSupport)48 panvk_GetDescriptorSetLayoutSupport(VkDevice _device,
49                                     const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
50                                     VkDescriptorSetLayoutSupport *pSupport)
51 {
52    VK_FROM_HANDLE(panvk_device, device, _device);
53 
54    pSupport->supported = false;
55 
56    VkDescriptorSetLayoutBinding *bindings;
57    VkResult result =
58       vk_create_sorted_bindings(pCreateInfo->pBindings,
59                                 pCreateInfo->bindingCount,
60                                 &bindings);
61    if (result != VK_SUCCESS) {
62       vk_error(device, result);
63       return;
64    }
65 
66    unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
67    unsigned dynoffset_idx = 0, img_idx = 0;
68 
69    for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
70       const VkDescriptorSetLayoutBinding *binding = &bindings[i];
71 
72       switch (binding->descriptorType) {
73       case VK_DESCRIPTOR_TYPE_SAMPLER:
74          sampler_idx += binding->descriptorCount;
75          break;
76       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
77          sampler_idx += binding->descriptorCount;
78          tex_idx += binding->descriptorCount;
79          break;
80       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
81       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
82       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
83          tex_idx += binding->descriptorCount;
84          break;
85       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
86          dynoffset_idx += binding->descriptorCount;
87          FALLTHROUGH;
88       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
89          ubo_idx += binding->descriptorCount;
90          break;
91       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
92          dynoffset_idx += binding->descriptorCount;
93          FALLTHROUGH;
94       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
95          break;
96       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
97       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
98          img_idx += binding->descriptorCount;
99          break;
100       default:
101          unreachable("Invalid descriptor type");
102       }
103    }
104 
105    /* The maximum values apply to all sets attached to a pipeline since all
106     * sets descriptors have to be merged in a single array.
107     */
108    if (tex_idx > PANVK_MAX_TEXTURES / MAX_SETS ||
109        sampler_idx > PANVK_MAX_SAMPLERS / MAX_SETS ||
110        ubo_idx > PANVK_MAX_UBOS / MAX_SETS ||
111        img_idx > PANVK_MAX_IMAGES / MAX_SETS)
112       return;
113 
114    pSupport->supported = true;
115 }
116 
117 /*
118  * Pipeline layouts.  These have nothing to do with the pipeline.  They are
119  * just multiple descriptor set layouts pasted together.
120  */
121 
122 VkResult
panvk_CreatePipelineLayout(VkDevice _device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)123 panvk_CreatePipelineLayout(VkDevice _device,
124                            const VkPipelineLayoutCreateInfo *pCreateInfo,
125                            const VkAllocationCallbacks *pAllocator,
126                            VkPipelineLayout *pPipelineLayout)
127 {
128    VK_FROM_HANDLE(panvk_device, device, _device);
129    struct panvk_pipeline_layout *layout;
130    struct mesa_sha1 ctx;
131 
132    layout = vk_pipeline_layout_zalloc(&device->vk, sizeof(*layout),
133                                       pCreateInfo);
134    if (layout == NULL)
135       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
136 
137    _mesa_sha1_init(&ctx);
138 
139    unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
140    unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0;
141    for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
142       const struct panvk_descriptor_set_layout *set_layout =
143          vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
144 
145       layout->sets[set].sampler_offset = sampler_idx;
146       layout->sets[set].tex_offset = tex_idx;
147       layout->sets[set].ubo_offset = ubo_idx;
148       layout->sets[set].dyn_ubo_offset = dyn_ubo_idx;
149       layout->sets[set].dyn_ssbo_offset = dyn_ssbo_idx;
150       layout->sets[set].img_offset = img_idx;
151       sampler_idx += set_layout->num_samplers;
152       tex_idx += set_layout->num_textures;
153       ubo_idx += set_layout->num_ubos;
154       dyn_ubo_idx += set_layout->num_dyn_ubos;
155       dyn_ssbo_idx += set_layout->num_dyn_ssbos;
156       img_idx += set_layout->num_imgs;
157 
158       for (unsigned b = 0; b < set_layout->binding_count; b++) {
159          const struct panvk_descriptor_set_binding_layout *binding_layout =
160             &set_layout->bindings[b];
161 
162          if (binding_layout->immutable_samplers) {
163             for (unsigned s = 0; s < binding_layout->array_size; s++) {
164                struct panvk_sampler *sampler = binding_layout->immutable_samplers[s];
165 
166                _mesa_sha1_update(&ctx, &sampler->desc, sizeof(sampler->desc));
167             }
168          }
169          _mesa_sha1_update(&ctx, &binding_layout->type, sizeof(binding_layout->type));
170          _mesa_sha1_update(&ctx, &binding_layout->array_size, sizeof(binding_layout->array_size));
171          _mesa_sha1_update(&ctx, &binding_layout->shader_stages, sizeof(binding_layout->shader_stages));
172       }
173    }
174 
175    for (unsigned range = 0; range < pCreateInfo->pushConstantRangeCount; range++) {
176       layout->push_constants.size =
177          MAX2(pCreateInfo->pPushConstantRanges[range].offset +
178               pCreateInfo->pPushConstantRanges[range].size,
179               layout->push_constants.size);
180    }
181 
182    layout->num_samplers = sampler_idx;
183    layout->num_textures = tex_idx;
184    layout->num_ubos = ubo_idx;
185    layout->num_dyn_ubos = dyn_ubo_idx;
186    layout->num_dyn_ssbos = dyn_ssbo_idx;
187    layout->num_imgs = img_idx;
188 
189    /* Some NIR texture operations don't require a sampler, but Bifrost/Midgard
190     * ones always expect one. Add a dummy sampler to deal with this limitation.
191     */
192    if (layout->num_textures) {
193       layout->num_samplers++;
194       for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++)
195          layout->sets[set].sampler_offset++;
196    }
197 
198    _mesa_sha1_final(&ctx, layout->sha1);
199 
200    *pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
201    return VK_SUCCESS;
202 }
203 
204 VkResult
panvk_CreateDescriptorPool(VkDevice _device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)205 panvk_CreateDescriptorPool(VkDevice _device,
206                            const VkDescriptorPoolCreateInfo *pCreateInfo,
207                            const VkAllocationCallbacks *pAllocator,
208                            VkDescriptorPool *pDescriptorPool)
209 {
210    VK_FROM_HANDLE(panvk_device, device, _device);
211    struct panvk_descriptor_pool *pool;
212 
213    pool = vk_object_zalloc(&device->vk, pAllocator,
214                            sizeof(struct panvk_descriptor_pool),
215                            VK_OBJECT_TYPE_DESCRIPTOR_POOL);
216    if (!pool)
217       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
218 
219    pool->max.sets = pCreateInfo->maxSets;
220 
221    for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
222       unsigned desc_count = pCreateInfo->pPoolSizes[i].descriptorCount;
223 
224       switch(pCreateInfo->pPoolSizes[i].type) {
225       case VK_DESCRIPTOR_TYPE_SAMPLER:
226          pool->max.samplers += desc_count;
227          break;
228       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
229          pool->max.combined_image_samplers += desc_count;
230          break;
231       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
232          pool->max.sampled_images += desc_count;
233          break;
234       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
235          pool->max.storage_images += desc_count;
236          break;
237       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
238          pool->max.uniform_texel_bufs += desc_count;
239          break;
240       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
241          pool->max.storage_texel_bufs += desc_count;
242          break;
243       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
244          pool->max.input_attachments += desc_count;
245          break;
246       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
247          pool->max.uniform_bufs += desc_count;
248          break;
249       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
250          pool->max.storage_bufs += desc_count;
251          break;
252       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
253          pool->max.uniform_dyn_bufs += desc_count;
254          break;
255       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
256          pool->max.storage_dyn_bufs += desc_count;
257          break;
258       default:
259          unreachable("Invalid descriptor type");
260       }
261    }
262 
263    *pDescriptorPool = panvk_descriptor_pool_to_handle(pool);
264    return VK_SUCCESS;
265 }
266 
267 void
panvk_DestroyDescriptorPool(VkDevice _device,VkDescriptorPool _pool,const VkAllocationCallbacks * pAllocator)268 panvk_DestroyDescriptorPool(VkDevice _device,
269                             VkDescriptorPool _pool,
270                             const VkAllocationCallbacks *pAllocator)
271 {
272    VK_FROM_HANDLE(panvk_device, device, _device);
273    VK_FROM_HANDLE(panvk_descriptor_pool, pool, _pool);
274 
275    if (pool)
276       vk_object_free(&device->vk, pAllocator, pool);
277 }
278 
279 VkResult
panvk_ResetDescriptorPool(VkDevice _device,VkDescriptorPool _pool,VkDescriptorPoolResetFlags flags)280 panvk_ResetDescriptorPool(VkDevice _device,
281                           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       panfrost_bo_unreference(set->desc_bo);
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,
308                          VkDescriptorPool descriptorPool,
309                          uint32_t count,
310                          const VkDescriptorSet *pDescriptorSets)
311 {
312    VK_FROM_HANDLE(panvk_device, device, _device);
313    VK_FROM_HANDLE(panvk_descriptor_pool, pool, descriptorPool);
314 
315    for (unsigned i = 0; i < count; i++) {
316       VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
317 
318       if (set)
319          panvk_descriptor_set_destroy(device, pool, set);
320    }
321    return VK_SUCCESS;
322 }
323 
324 VkResult
panvk_CreateDescriptorUpdateTemplate(VkDevice _device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)325 panvk_CreateDescriptorUpdateTemplate(VkDevice _device,
326                                      const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
327                                      const VkAllocationCallbacks *pAllocator,
328                                      VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
329 {
330    panvk_stub();
331    return VK_SUCCESS;
332 }
333 
334 void
panvk_DestroyDescriptorUpdateTemplate(VkDevice _device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)335 panvk_DestroyDescriptorUpdateTemplate(VkDevice _device,
336                                       VkDescriptorUpdateTemplate descriptorUpdateTemplate,
337                                       const VkAllocationCallbacks *pAllocator)
338 {
339    panvk_stub();
340 }
341 
342 void
panvk_UpdateDescriptorSetWithTemplate(VkDevice _device,VkDescriptorSet descriptorSet,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const void * pData)343 panvk_UpdateDescriptorSetWithTemplate(VkDevice _device,
344                                       VkDescriptorSet descriptorSet,
345                                       VkDescriptorUpdateTemplate descriptorUpdateTemplate,
346                                       const void *pData)
347 {
348    panvk_stub();
349 }
350 
351 VkResult
panvk_CreateSamplerYcbcrConversion(VkDevice device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)352 panvk_CreateSamplerYcbcrConversion(VkDevice device,
353                                    const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
354                                    const VkAllocationCallbacks *pAllocator,
355                                    VkSamplerYcbcrConversion *pYcbcrConversion)
356 {
357    panvk_stub();
358    return VK_SUCCESS;
359 }
360 
361 void
panvk_DestroySamplerYcbcrConversion(VkDevice device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)362 panvk_DestroySamplerYcbcrConversion(VkDevice device,
363                                     VkSamplerYcbcrConversion ycbcrConversion,
364                                     const VkAllocationCallbacks *pAllocator)
365 {
366    panvk_stub();
367 }
368