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 47void 48panvk_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 122VkResult 123panvk_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 204VkResult 205panvk_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 267void 268panvk_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 279VkResult 280panvk_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 289static void 290panvk_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 306VkResult 307panvk_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 324VkResult 325panvk_CreateDescriptorUpdateTemplate(VkDevice _device, 326 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, 327 const VkAllocationCallbacks *pAllocator, 328 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) 329{ 330 panvk_stub(); 331 return VK_SUCCESS; 332} 333 334void 335panvk_DestroyDescriptorUpdateTemplate(VkDevice _device, 336 VkDescriptorUpdateTemplate descriptorUpdateTemplate, 337 const VkAllocationCallbacks *pAllocator) 338{ 339 panvk_stub(); 340} 341 342void 343panvk_UpdateDescriptorSetWithTemplate(VkDevice _device, 344 VkDescriptorSet descriptorSet, 345 VkDescriptorUpdateTemplate descriptorUpdateTemplate, 346 const void *pData) 347{ 348 panvk_stub(); 349} 350 351VkResult 352panvk_CreateSamplerYcbcrConversion(VkDevice device, 353 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 354 const VkAllocationCallbacks *pAllocator, 355 VkSamplerYcbcrConversion *pYcbcrConversion) 356{ 357 panvk_stub(); 358 return VK_SUCCESS; 359} 360 361void 362panvk_DestroySamplerYcbcrConversion(VkDevice device, 363 VkSamplerYcbcrConversion ycbcrConversion, 364 const VkAllocationCallbacks *pAllocator) 365{ 366 panvk_stub(); 367} 368